GeomConverter/src/org/lcsim/geometry/compact/converter/lcdd
diff -u -r1.1 -r1.2
--- HPSMuonCalorimeter.java 12 Sep 2012 23:30:45 -0000 1.1
+++ HPSMuonCalorimeter.java 4 Dec 2012 01:11:38 -0000 1.2
@@ -1,9 +1,5 @@
package org.lcsim.geometry.compact.converter.lcdd;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringTokenizer;
-
import org.jdom.Element;
import org.jdom.JDOMException;
import org.lcsim.geometry.compact.converter.lcdd.util.Box;
@@ -13,52 +9,11 @@
import org.lcsim.geometry.compact.converter.lcdd.util.Position;
import org.lcsim.geometry.compact.converter.lcdd.util.Rotation;
import org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector;
-import org.lcsim.geometry.compact.converter.lcdd.util.Trap;
import org.lcsim.geometry.compact.converter.lcdd.util.Volume;
/**
- *
- * To build:
- *
- * cd GeomConverter
- * mvn clean install -DskipTests=true
- *
- * To generate LCDD from test geometry:
- *
- * java -jar ./target/GeomConverter-2.5-SNAPSHOT-bin.jar -o lcdd ./testResources/org/lcsim/geometry/subdetector/HPSMuonCalorimeterTest.xml ./HPSMuonCalorimeterTest.lcdd
- *
- * Parameters (initially from python):
- *
- * vertseg_gap <= vertical gaps between hodoscopes e.g. scintillator strips
- * vertseg_num <= number of readout strips in first layer
- * vertseg_size <= vertical dimension of strip
- * from_target <= distance from front face to target
- * absorber_layers <= how many absorber layers?
- * absorber_thicknesses <= thickness of each absorber layer
- * gaps <= horizontal gap between each strips and absorber
- * sensor_thickness <= thickness of absorber
- * theta1 <= fan out angle in y of the vacuum box (?)
- * absorber_width <= 1st layer absorber width
- * fan_out <= make absorbers all the same width or fan them out as depth increases
- * connecting_width <= when fan_out is false then set how far in the connecting iron piece goes (?)
- * theta4 <= fan out angle
- * alum_plate_width <= width of the aluminum plate
- * alum_side_width <= width of the side wall of the vacuum system
- * alum_airgap <= gap between alum plate and iron chunks
- * al_extra[1-3] <= see diagram (???)
- * vac_pullz <= how far to extend the vacuum (-z) towards ecal
- * vac_pushz <= how far to extend the vacuum (+z) beyond muon detector
- *
- * Example XML:
- * <parameters vertseg_gap="0.01*cm" vertseg_num="8" vertseg_size="3.0*cm" from_target="185.0*cm" gap="0.2*cm"
- * sensor_thickness="1.0*cm" theta1="0.025" absorber_width="50.0*cm" fan_out="true"
- * connecting_width="40.0*cm" theta4="0.0873" />
- * <absorber_thicknesses>68.0 68.0 68.0 68.0 150.0 150.0 150.0</absorber_thicknesses>
- * <vacuum alum_plate_width="1.0*cm" alum_side_width="1.0*cm" alum_airgap="0.01*cm" al_extra1="35.0*cm"
- * al_extra2="20.0*cm" al_extra3="5.0*cm" />
- *
* @author jeremym
- * @version $Id: HPSMuonCalorimeter.java,v 1.1 2012/09/12 23:30:45 jeremy Exp $
+ * @version $Id: HPSMuonCalorimeter.java,v 1.2 2012/12/04 01:11:38 jeremy Exp $
*/
public class HPSMuonCalorimeter extends LCDDSubdetector {
@@ -70,154 +25,67 @@
String name = node.getAttributeValue("name");
int id = node.getAttribute("id").getIntValue();
+ Volume mother = lcdd.pickMotherVolume(this);
- // Get muon calorimeter parameters.
- Element parameters = node.getChild("parameters");
- double vertseg_gap = parameters.getAttribute("vertseg_gap").getDoubleValue();
- int vertseg_num = parameters.getAttribute("vertseg_num").getIntValue();
- double vertseg_size = parameters.getAttribute("vertseg_size").getDoubleValue();
- double from_target = parameters.getAttribute("from_target").getDoubleValue();
- double gap = parameters.getAttribute("gap").getDoubleValue();
- double sensor_thickness = parameters.getAttribute("sensor_thickness").getDoubleValue();
- double theta1 = parameters.getAttribute("theta1").getDoubleValue();
- double absorber_width = parameters.getAttribute("absorber_width").getDoubleValue();
- boolean fan_out = parameters.getAttribute("fan_out").getBooleanValue();
- double connecting_width = parameters.getAttribute("connecting_width").getDoubleValue();
- double theta4 = parameters.getAttribute("theta4").getDoubleValue();
-
- // Get the absorber thicknesses. These are hard-coded to be in mm because I don't know
- // how to convert the array on the fly to arbitrary units.
- String s = node.getChild("absorber_thicknesses").getText();
- StringTokenizer st = new StringTokenizer(s);
- List<Double> depth = new ArrayList<Double>();
- while (st.hasMoreElements()) {
- depth.add(Double.parseDouble((String)st.nextElement()));
- }
-
- // Get vacuum box parameters.
- Element vacuum = node.getChild("vacuum");
- double alum_plate_width = vacuum.getAttribute("alum_plate_width").getDoubleValue();
- double alum_side_width = vacuum.getAttribute("alum_side_width").getDoubleValue();
- double alum_airgap = vacuum.getAttribute("alum_airgap").getDoubleValue();
- double al_extra1 = vacuum.getAttribute("al_extra1").getDoubleValue();
- double al_extra2 = vacuum.getAttribute("al_extra2").getDoubleValue();
- double al_extra3 = vacuum.getAttribute("al_extra3").getDoubleValue();
-
- // Computed values.
- int nabsorbers = depth.size();
- double absorber_total_depth = 0.;
- for (Double a : depth) {
- absorber_total_depth += a;
- }
- double gaps_total_depth = (nabsorbers)*gap;
-
- //System.out.println("absorber_total_depth="+absorber_total_depth);
- //System.out.println("gaps_total_depth="+gaps_total_depth);
-
- // Total detector depth.
- double md_depth = absorber_total_depth + 2*gaps_total_depth - gap + nabsorbers*sensor_thickness;
- //System.out.println("md_depth="+md_depth);
-
- // Z position of muon detector.
- double vac_pullz = al_extra3;
- double vac_pushz = al_extra1;
- double muon_box_z = from_target + 0.5*md_depth - 0.5*Math.max(vac_pullz, al_extra3) + 0.5*Math.max(vac_pushz,al_extra1);
-
- //System.out.println("muon_box_z = " + muon_box_z);
-
- double md_mid = from_target - muon_box_z + 0.5*md_depth;
- //System.out.println("muon_mid = " + md_mid);
-
- double z = from_target - muon_box_z + depth.get(0)/2;
- //System.out.println("z="+z);
-
- double theta2 = Math.atan( (vertseg_num*vertseg_size+(vertseg_num-1)*vertseg_gap+(from_target+depth.get(0)+gap)*Math.tan(theta1) )/ (from_target+depth.get(0)+gap));
- double theta3 = Math.atan(absorber_width/(from_target));
- double theta = 0.5*(theta1+theta2);
-
- //System.out.println("theta2="+theta2);
- //System.out.println("theta3="+theta3);
- //System.out.println("theta="+theta);
-
- double tt1 = Math.tan(theta1);
- double tt2 = Math.tan(theta2);
- //System.out.println("theta3="+theta3);
- double tt3 = Math.tan(theta3);
- double tt4 = Math.tan(theta4);
- double tt34 = Math.tan( (theta3+theta4)/2 );
- double tt = Math.tan(theta);
-
- // Place crystals in world volume.
- Volume world = lcdd.pickMotherVolume(this);
-
- // Position of mother volume in the world.
- Position md_pos = new Position(name + "_pos", 0, 0, muon_box_z);
- lcdd.add(md_pos);
-
- // Compute dimensions of mother box.
- double md_x, md_y, md_z;
- double spacing = 20.;
- //System.out.println("tt3="+tt3);
- //System.out.println("md_x1="+((from_target+md_depth+al_extra1)*tt3+al_extra2));
- //System.out.println("md_x2="+(from_target+md_depth+vac_pushz)*tt3);
- md_x = Math.max((from_target+md_depth+al_extra1)*tt3+al_extra2,(from_target+md_depth+vac_pushz)*tt3)+spacing;
- md_y = (from_target+md_depth)*tt2+spacing;
- md_z = .5*md_depth+.5*Math.max(al_extra1,vac_pushz)+.5*Math.max(al_extra3,vac_pullz);
-
- //System.out.println("md_x = " + md_x);
- //System.out.println("md_y = " + md_y);
- //System.out.println("md_z = " + md_z);
-
- // Create mother box.
- Box muonBox = new Box(name + "_box", md_x*2, md_y*2, md_z*2);
- lcdd.add(muonBox);
-
- Material air = lcdd.getMaterial("Air");
-
- Volume md_vol = new Volume(name + "_vol", muonBox, air);
-
- Material iron = lcdd.getMaterial("Iron");
-
- Rotation rot = new Rotation(name+"_absorber_rot", 0, 0, Math.PI/2);
- lcdd.add(rot);
- for (int i=0; i<nabsorbers; i++) {
-
- double gz = z + muon_box_z;
- //System.out.println("gz="+gz);
+ for (Object layerObject : node.getChildren("layer")) {
+ Element layer = (Element)layerObject;
+ int layerId = layer.getAttribute("id").getIntValue();
- String base_name = name + "_layer" + i;
- String abs_base_name = base_name + "_abs_";
+ //System.out.println("making layer:" + layerId);
- Position top_pos = new Position(abs_base_name+"top_pos", 0, gz*tt, z);
- lcdd.add(top_pos);
-
- Trap abs_top_trap = new Trap(abs_base_name+"top_trap",
- .5*depth.get(i),
- -theta,
- 0.,
- ((gz-depth.get(i)/2)*tt3),
- .5*(gz-depth.get(i)/2)*(tt2-tt1),
- .5*(gz-depth.get(i)/2)*(tt2-tt1),
- 0.,
- ((gz+depth.get(i)/2)*tt3),
- .5*(gz+depth.get(i)/2)*(tt2-tt1),
- .5*(gz+depth.get(i)/2)*(tt2-tt1),
- 0);
- lcdd.add(abs_top_trap);
- Volume abs_top_vol = new Volume(abs_base_name+"vol", abs_top_trap, iron);
- lcdd.add(abs_top_vol);
- PhysVol abs_top_pv = new PhysVol(abs_top_vol, md_vol, top_pos, rot);
-
- // CONTINUE CODING HERE
-
- if (i != (nabsorbers - 1))
- z = z + .5*depth.get(i)+.5*depth.get(i+1)+2*gap+sensor_thickness;
- } // nabsorbers loop
+ int slice = 1;
+ for (Object boxObject : layer.getChildren("box")) {
+
+ //System.out.println("making shape: " + slice);
+
+ Element element = (Element)boxObject;
+
+ double x, y, z, px, py, pz, rx, ry, rz;
+
+ x = element.getAttribute("x").getDoubleValue();
+ y = element.getAttribute("y").getDoubleValue();
+ z = element.getAttribute("z").getDoubleValue();
+
+ px = element.getAttribute("px").getDoubleValue();
+ py = element.getAttribute("py").getDoubleValue();
+ pz = element.getAttribute("pz").getDoubleValue();
+
+ rx = element.getAttribute("rx").getDoubleValue();
+ ry = element.getAttribute("ry").getDoubleValue();
+ rz = element.getAttribute("rz").getDoubleValue();
+
+ String materialString = element.getAttributeValue("material");
+ Material material = lcdd.getMaterial(materialString);
+
+ boolean sensitive = element.getAttribute("sensitive").getBooleanValue();
+
+ String shapeBaseName = name + "_layer" + layerId + "_sublayer" + slice;
+
+ Box box = new Box(shapeBaseName + "_box", x, y, z);
+ lcdd.add(box);
+
+ Position pos = new Position(shapeBaseName + "_pos", px, py, pz);
+ lcdd.add(pos);
+
+ Rotation rot = new Rotation(shapeBaseName + "_rot", rx, ry, rz);
+ lcdd.add(rot);
+
+ Volume vol = new Volume(shapeBaseName + "_vol", box, material);
+ lcdd.add(vol);
+
+ //System.out.println("made volume: " + vol.getName());
+
+ if (sensitive) vol.setSensitiveDetector(sens);
+
+ PhysVol physVol = new PhysVol(vol, mother, pos, rot);
+ physVol.addPhysVolID("layer", layerId);
+ physVol.addPhysVolID("slice", slice);
+ physVol.addPhysVolID("system", id);
+
+ ++slice;
+ }
+ }
- lcdd.add(md_vol);
- Rotation md_rot = new Rotation(name + "_rot");
- lcdd.add(md_rot);
- PhysVol md_pv = new PhysVol(md_vol, world, md_pos, md_rot);
}
public boolean isCalorimeter() {