projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/geometry/compact/converter/lcdd
--- projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014.java 2014-04-10 07:51:46 UTC (rev 3092)
+++ projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014.java 2014-04-11 17:20:31 UTC (rev 3093)
@@ -1,5 +1,12 @@
package org.lcsim.geometry.compact.converter.lcdd;
+import hep.physics.vec.BasicHep3Matrix;
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Matrix;
+import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.VecOp;
+
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -7,14 +14,18 @@
import org.jdom.Element;
import org.jdom.JDOMException;
-import org.lcsim.geometry.compact.converter.lcdd.LCDDSubdetector;
+import org.lcsim.detector.ITransform3D;
+import org.lcsim.detector.Rotation3D;
+import org.lcsim.detector.RotationGeant;
+import org.lcsim.detector.Transform3D;
+import org.lcsim.detector.Translation3D;
import org.lcsim.geometry.compact.converter.lcdd.util.Box;
import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
import org.lcsim.geometry.compact.converter.lcdd.util.Material;
+import org.lcsim.geometry.compact.converter.lcdd.util.PhysVol;
+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.Solids;
-import org.lcsim.geometry.compact.converter.lcdd.util.Structure;
-import org.lcsim.geometry.compact.converter.lcdd.util.VisAttributes;
import org.lcsim.geometry.compact.converter.lcdd.util.Volume;
/**
@@ -28,12 +39,34 @@
public class HPSTracker2014 extends LCDDSubdetector
{
private boolean _debug = true;
+ public static final double inch = 25.4;
+ private final double sensor_length= 98.33;
+ private final double sensor_width = 38.3399;
+ private final double sensor_thickness = 0.32;
+ private final double hybrid_length = 55.0; // excluding the "tung" where the sensor lays on
+ private final double hybrid_width = sensor_width;
+ private final double hybrid_width_L46 = 45.34;
+ private final double hybrid_thickness = 4.0/64.0*inch;
+ //TODO Check these numbers
+ private final double CF_thickness = 0.150;
+ private final double kapton_thickness = 0.050;
+
+
+
+
+
+
public HPSTracker2014(Element node) throws JDOMException
{
super(node);
}
+
+ public boolean isTracker() {
+ return true;
+ }
+
/**
* Build the LCDD for the subdetector.
* @param lcdd The LCDD file being created.
@@ -41,6 +74,21 @@
*/
public void addToLCDD(LCDD lcdd, SensitiveDetector sens) throws JDOMException
{
+
+ /** General comments
+ // Roll: rotation around x
+ // pitch: rotation around y
+ // yaw: rotation around z
+
+ // kinematic mounts:
+ // ball (constraints x,y,z)
+ // vee (constraints pitch & yaw)
+ // flat (constraints roll)
+ **/
+
+
+
+
// ID of the detector.
int id = this.node.getAttribute("id").getIntValue();
@@ -52,88 +100,906 @@
}
// Pick the mother volume (tracking volume).
- Volume tracking_volume = lcdd.pickMotherVolume(this);
+ Volume trackingVolume = lcdd.pickMotherVolume(this);
- // Build tracking box
- Box trackingBox = new Box("trackingBox", 60., 20, 110.); //cm
- lcdd.add(trackingBox);
- // Create
- Volume trackingBoxVolume = new Volume("trackingBoxVolume", trackingBox, lcdd.getMaterial("Vacuum"));
- lcdd.add(trackingBoxVolume);
+
+
+ // create the box around the support plate: "support box"
+
+ final double support_length = 15.0*inch; // along z
+ final double support_width = 9.25*inch; // along x
+ final double support_height = 2.5*inch + 1.5*inch; // along y TODO made this up!
+
+
+ String volName = "support";
+ Box box = new Box(volName + "Box", support_width, support_height , support_length);
+ lcdd.add(box);
+ Volume supportVolume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+ Position pos = new Position( volName + "_position", 0,0,0);
+ Rotation rot = new Rotation( volName + "_rotation",0,0,0);
+ lcdd.add(pos);
+ lcdd.add(rot);
+ PhysVol supportPV = new PhysVol(supportVolume, trackingVolume, pos, rot);
- // Loop over the support plates
- for(Iterator iter_support = node.getChildren("support_plate").iterator(); iter_support.hasNext();) {
-
- // Get the next support
- Element support_element = (Element) iter_support.next();
-
- // Get a reference element to the modules that will be placed on this support plate
- List<Element> modules = support_element.getChildren("module");
+ VolWrapper supportWrap = new VolWrapper();
+ supportWrap.vol = supportVolume;
+ supportWrap.name = volName;
+ supportWrap.pos_vol = pos;
+ supportWrap.rot_vol = rot;
+
+
+
+
+ // create the support plate inside the support box
+
+ // build the position of the support plate in the support box volume
+ // easy since the support box position is arbitrary here.
+ Hep3Vector ball_pos_support_plate = new BasicHep3Vector(support_width/2.0-0.625*inch, -1.0*support_height/2.0 + 0.755*inch, support_length/2.0 - 0.25*inch);
+ Hep3Vector vee_pos_support_plate = new BasicHep3Vector(-1.0*ball_pos_support_plate.x(),ball_pos_support_plate.y(),ball_pos_support_plate.z());
+ Hep3Vector flat_pos_support_plate = new BasicHep3Vector(0.0,ball_pos_support_plate.y(),-0.5*support_length + 0.25*inch);
+
+ VolWrapper supportPlateWrap = makeSupportPlate(supportWrap, ball_pos_support_plate, vee_pos_support_plate, flat_pos_support_plate, lcdd, sens );
+
- if(_debug) {
- print(String.format("%d modules for support plate name %s", modules.size(),support_element.getAttribute("name").getValue()));
- for(Element module : modules) {
- print(String.format("module layer %d", module.getAttribute("layer").getIntValue()));
- }
+ // create the module from positions of module ball, vee and flat w.r.t. support plate survey points
+
+ final double module_ball_local_u = 7.7*inch;
+ final double module_ball_local_v = 11.625*inch;
+ // place module mounting surface at support plate surface
+ // the kin mount on support plate is sunk into plate TODO check this!!
+ final double module_ball_local_w = -0.3195*inch;
+ Hep3Vector ball_pos_mod_local = new BasicHep3Vector(module_ball_local_u,module_ball_local_v,module_ball_local_w);
+
+ final double module_vee_local_u = (support_width - (7.7+0.625)*inch ) - 0.625*inch;
+ final double module_vee_local_v = module_ball_local_v;
+ final double module_vee_local_w = module_ball_local_w;
+ Hep3Vector vee_pos_mod_local = new BasicHep3Vector(module_vee_local_u,module_vee_local_v,module_vee_local_w);
+
+ final double module_flat_local_u = (module_ball_local_u - module_vee_local_u) / 2.0 + module_vee_local_u;
+ final double module_flat_local_v = module_ball_local_v + 0.5*inch;
+ final double module_flat_local_w = module_ball_local_w;
+ Hep3Vector flat_pos_mod_local = new BasicHep3Vector(module_flat_local_u,module_flat_local_v,module_flat_local_w);
+
+
+ print(String.format("ball_pos_mod_local %s", ball_pos_mod_local.toString()));
+ print(String.format("vee_pos_mod_local %s", vee_pos_mod_local.toString()));
+ print(String.format("flat_pos_mod_local %s", flat_pos_mod_local.toString()));
+
+ // create the coordinate system of the support plate
+ CoordSysDef support_plate_coord = new CoordSysDef(ball_pos_support_plate, vee_pos_support_plate, flat_pos_support_plate);
+ Transform3D trans_support_plate_to_support = getTransformation(support_plate_coord);
+
+ // transform to support frame
+ Hep3Vector ball_pos_mod = trans_support_plate_to_support.transformed(ball_pos_mod_local);
+ Hep3Vector ball_pos_mod_rot = trans_support_plate_to_support.rotated(ball_pos_mod_local);
+ Hep3Vector ball_pos_mod_tr = trans_support_plate_to_support.translated(ball_pos_mod_local);
+ Hep3Vector vee_pos_mod = trans_support_plate_to_support.transformed(vee_pos_mod_local);
+ Hep3Vector flat_pos_mod = trans_support_plate_to_support.transformed(flat_pos_mod_local);
+
+ print(String.format("ball_pos_mod_rot %s", ball_pos_mod_rot.toString()));
+ print(String.format("ball_pos_mod_tr %s", ball_pos_mod_tr.toString()));
+ print(String.format("ball_pos_mod %s", ball_pos_mod.toString()));
+ print(String.format("vee_pos_mod %s", vee_pos_mod.toString()));
+ print(String.format("flat_pos_mod %s", flat_pos_mod.toString()));
+
+ // make the module
+ VolWrapper moduleWrap = makeModule(supportWrap, ball_pos_mod, vee_pos_mod, flat_pos_mod,lcdd, sens);
+ supportWrap.daughters.add(moduleWrap);
+
+ // add support volume to lcdd
+ lcdd.add(supportVolume);
+
+
+
+ /*
+
+ // Get corrections to survey ball positions from compact file to support plate positions (from e.g. survey)
+ Map<String, Hep3Vector> corr_balls = new HashMap<String,Hep3Vector>(); // save for debugging
+ for(Iterator i = node.getChildren("support_plate").iterator(); i.hasNext();) {
+ Element e = (Element)i.next();
+ if(e.getAttributeValue("name").equals("SupportPlateL1-3bot")) {
+ for(Iterator ii = e.getChildren("position").iterator(); ii.hasNext();) {
+ Element element = (Element) ii.next();
+ String name = element.getAttribute("name").getValue();
+ // get vector correction
+ Hep3Vector corr = new BasicHep3Vector(element.getAttribute("x").getDoubleValue(), element.getAttribute("y").getDoubleValue(), element.getAttribute("z").getDoubleValue());
+ if( name.equals("ball")) {
+ VecOp.add(ball_pos, corr);
+ corr_balls.put("ball", corr);
+ }
+ else if( name.equals("vee")) {
+ VecOp.add(vee_pos, corr);
+ corr_balls.put("vee", corr);
+ }
+ else if( name.equals("flat")) {
+ VecOp.add(flat_pos, corr);
+ corr_balls.put("flat", corr);
+ }
+ else {
+ print(String.format("wrong alignment name for support plate: \"%s\"", name));
+ System.exit(1);
+ }
+ } //ii
}
-
- // Roll: rotation around x
- // pitch: rotation around y
- // yaw: rotation around z
-
- // kinematic mounts:
- // ball (constraints x,y,z)
- // vee (constraints pitch & yaw)
- // flat (constraints roll)
-
- // We should build the support plate here
- // All positions w.r.t. tracking box
- double support_plate_length = 50.0;
- double support_plate_width = 20.0;
-
- // position of ball (primary constraint: position x,y,z)
- double support_plate_ball_x = 0.;
- double support_plate_ball_y = 5.;
- double support_plate_ball_z = -70.;
-
- // position of vee (secondary constraint: pitch & yaw)
- double support_plate_vee_x = 0.;
- double support_plate_vee_y = 0.;
- double support_plate_vee_z = 0.;
-
- // position of flat (tertiary constraint: roll)
- double support_plate_flat_x = 0.;
- double support_plate_flat_y = 0.;
- double support_plate_flat_z = 0.;
-
- // local corrections to each surveyed ball positions
- double support_plate_dx = support_element.getChild("alignment").getAttribute("x").getDoubleValue();
- double support_plate_dy = support_element.getChild("alignment").getAttribute("y").getDoubleValue();
- double support_plate_dz = support_element.getChild("alignment").getAttribute("z").getDoubleValue();
- double support_plate_drx = support_element.getChild("alignment").getAttribute("rx").getDoubleValue();
- double support_plate_dry = support_element.getChild("alignment").getAttribute("ry").getDoubleValue();
- double support_plate_drz = support_element.getChild("alignment").getAttribute("rz").getDoubleValue();
-
- // Build the coordinate system for the support plate
-
-
-
-
+ } //i
+
-
-
-
+ // Find the local alignment corrections to the support plate
+ Hep3Vector local_translation = new BasicHep3Vector(0,0,0);
+ Hep3Vector local_rotation = new BasicHep3Vector(0,0,0);
+ for(Iterator i = node.getChildren("support_plate").iterator(); i.hasNext();) {
+ Element e = (Element)i.next();
+ if(e.getAttributeValue("name").equals("SupportPlateL1-3bot")) {
+ for(Iterator ii = e.getChildren("alignment").iterator(); ii.hasNext();) {
+ Element element = (Element) ii.next();
+ local_translation = new BasicHep3Vector(element.getAttribute("x").getDoubleValue(), element.getAttribute("y").getDoubleValue(), element.getAttribute("z").getDoubleValue());
+ local_rotation = new BasicHep3Vector(element.getAttribute("rx").getDoubleValue(), element.getAttribute("ry").getDoubleValue(), element.getAttribute("rz").getDoubleValue());
+
+ } //ii
+ }
+ } //i
+
+
+
+
+
+
+
+
+
+
+ */
+
+
+
+
+ }
+
+
+
+ private VolWrapper makeSupportPlate(VolWrapper supportWrap,
+ Hep3Vector ball_pos_support_plate,
+ Hep3Vector vee_pos_support_plate,
+ Hep3Vector flat_pos_support_plate, LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+
+ final double support_plate_height = 3.0/8.0*inch;
+ final double support_plate_length = 15.0*inch;
+ final double support_plate_width = 9.25*inch;
+
+
+
+ String volName = "supportplate";
+ Box box = new Box(volName + "Box", support_plate_width, support_plate_height , support_plate_length);
+ lcdd.add(box);
+ Volume supportPlateVolume = new Volume(volName + "_volume", box, lcdd.getMaterial("Aluminum"));
+
+
+ // create the coordinate system
+ CoordSysDef support_plate_coord = new CoordSysDef(ball_pos_support_plate, vee_pos_support_plate, flat_pos_support_plate);
+
+ print(String.format("support_plate ball %s", ball_pos_support_plate.toString()));
+ print(String.format("support_plate vee %s", vee_pos_support_plate.toString()));
+ print(String.format("support_plate flat %s", flat_pos_support_plate.toString()));
+ print(String.format("support_plate:\n%s", support_plate_coord.toString()));
+
+ // Find the LCDD position and rotation of this support plate
+ Transform3D trans_support_plate_to_support = getTransformation(support_plate_coord.origin(), support_plate_coord.u(), support_plate_coord.v(), support_plate_coord.w());
+ double du = support_plate_width/2.0-0.625*inch; //
+ double dv = support_plate_length/2.0 - 0.25*inch;
+ double dw = support_plate_height/2.0 - 0.3195*inch; // TODO how far is the kin mount sunk into the plate?
+ Hep3Vector box_center_support_plate_local = new BasicHep3Vector(du, dv, dw);
+ Hep3Vector box_center_support_plate = trans_support_plate_to_support.transformed(box_center_support_plate_local);
+
+ print(String.format("box_center_support_plate_local %s", box_center_support_plate_local.toString()));
+ print(String.format("box_center_support_plate %s", box_center_support_plate.toString()));
+
+
+ Position pos = new Position(volName + "_position",box_center_support_plate.x(), box_center_support_plate.y(), box_center_support_plate.z());
+ //Find LCDD rotation angles from coordinate system unit vectors
+ Hep3Vector lcdd_rot_angles = new BasicHep3Vector(0,0,0); //getLCDDRotation(support_plate_coord);
+ Rotation rot = new Rotation(volName + "_rotation",lcdd_rot_angles.x(), lcdd_rot_angles.y(), lcdd_rot_angles.z());
+ lcdd.add(pos);
+ lcdd.add(rot);
+ PhysVol supportPlatePV = new PhysVol(supportPlateVolume, supportWrap.vol, pos, rot);
+ // add volume to lcdd
+
+ supportPlateVolume.setVisAttributes(lcdd.getVisAttributes("SupportPlateVis"));
+
+ lcdd.add(supportPlateVolume);
+
+ VolWrapper supportPlateWrap = new VolWrapper();
+ supportPlateWrap.mother = supportWrap;
+ supportPlateWrap.vol = supportPlateVolume;
+ supportPlateWrap.name = volName;
+ supportPlateWrap.pos_vol = pos;
+ supportPlateWrap.rot_vol = rot;
+ supportWrap.daughters.add(supportPlateWrap);
+
+ return supportPlateWrap;
+
+ }
+
+
+ private VolWrapper makeModule(VolWrapper supportWrap, Hep3Vector ball_pos_mod, Hep3Vector vee_pos_mod, Hep3Vector flat_pos_mod, LCDD lcdd, SensitiveDetector sens) throws JDOMException
+ {
+
+ print(String.format("----- makeModule() ------"));
+
+
+ String moduleName = "module";
+ //find the bounding box for the module
+ //TODO get this box from Shawn
+ final double x = 7*inch; // ~along sensors
+ final double y = 1.0*inch; // ~perpendicular to sensors
+ final double z = 2.5*inch; // ~height from support plate
+ Box box = new Box(moduleName + "_box", x, y, z);
+ lcdd.add(box);
+ Volume moduleVolume = new Volume(moduleName + "_volume", box, lcdd.getMaterial("Vacuum"));
+
+
+ // create the coordinate system of the module in the support frame
+ CoordSysDef module_coord = new CoordSysDef(ball_pos_mod, vee_pos_mod, flat_pos_mod);
+ print(String.format("module_coord:\n%s", module_coord.toString()));
+
+ VolWrapper moduleWrap = new VolWrapper();
+ moduleWrap.name = moduleName;
+ moduleWrap.vol = moduleVolume;
+ moduleWrap.mother = supportWrap;
+ moduleWrap.coord = module_coord;
+ Hep3Vector box_center_local = new BasicHep3Vector(x/2.0-0.25*inch, y/2.0-0.224*inch, z/2.0);
+ moduleWrap.center = box_center_local;
+
+
+
+ // Find the LCDD position and rotation of this module
+ Transform3D trans = getTransformation(module_coord); //.origin(), module_coord.u(), module_coord.v(), module_coord.w());
+ // vector to the center of module box from ball position/origin
+ Hep3Vector box_center = trans.transformed(box_center_local);
+ //Position pos = new Position(volName + "_position",box_center.x(), box_center.y(), box_center.z());
+ Position pos = new Position(moduleName + "_position",box_center.x(), box_center.y(), box_center.z());
+ //Find LCDD rotation angles from coordinate system unit vectors
+ Hep3Vector lcdd_rot_angles = new BasicHep3Vector(Math.PI/2.0,0,0); //getLCDDRotation(survey_coord);
+ //Hep3Vector lcdd_rot_angles = new BasicHep3Vector(0,0,0); //getLCDDRotation(survey_coord);
+ Rotation rot = new Rotation(moduleName + "_rotation",lcdd_rot_angles.x(), lcdd_rot_angles.y(), lcdd_rot_angles.z());
+ lcdd.add(pos);
+ lcdd.add(rot);
+
+ PhysVol physVolume = new PhysVol(moduleVolume, supportWrap.vol, pos, rot);
+ supportWrap.daughters.add(moduleWrap);
+ moduleWrap.pv = physVolume;
+ moduleWrap.pos_vol = pos;
+ moduleWrap.rot_vol = rot;
+
+
+ print(String.format("module box center local %s",box_center_local.toString()));
+ print(String.format("module box center %s",box_center.toString()));
+
+
+
+ //Create the half modules
+
+ // Find the coordinate system of the half-module w.r.t. to the module survey points
+ // We are going to know the sensor center position w.r.t. module frame make half-module bounding box w.r.t. sensor center
+
+ // Place half-module dummy coordinate system
+ // ball is at sensor corner on hybrid side at the bottom surface of the CF
+ final double ball_pos_halfmod_local_u = 4.818*inch - sensor_length/2.0;
+ final double ball_pos_halfmod_local_v = 0.224*inch - ( sensor_thickness + kapton_thickness + CF_thickness );
+ final double ball_pos_halfmod_local_w = 1.543*inch - sensor_width/2;
+
+ final double vee_pos_halfmod_local_u = ball_pos_halfmod_local_u + sensor_length;
+ final double vee_pos_halfmod_local_v = ball_pos_halfmod_local_v;
+ final double vee_pos_halfmod_local_w = ball_pos_halfmod_local_w ;
+
+ final double flat_pos_halfmod_local_u = ball_pos_halfmod_local_u;
+ final double flat_pos_halfmod_local_v = ball_pos_halfmod_local_v;
+ final double flat_pos_halfmod_local_w = ball_pos_halfmod_local_w + sensor_width;
+
+
+ Hep3Vector ball_pos_halfmod_local = new BasicHep3Vector(ball_pos_halfmod_local_u, ball_pos_halfmod_local_v, ball_pos_halfmod_local_w);
+ Hep3Vector vee_pos_halfmod_local = new BasicHep3Vector(vee_pos_halfmod_local_u, vee_pos_halfmod_local_v,vee_pos_halfmod_local_w);
+ Hep3Vector flat_pos_halfmod_local = new BasicHep3Vector(flat_pos_halfmod_local_u, flat_pos_halfmod_local_v,flat_pos_halfmod_local_w);
+
+
+ if(this._debug) {
+ print(String.format("ball_pos_halfmod_local %s", ball_pos_halfmod_local.toString()));
+ print(String.format("vee_pos_halfmod_local %s", vee_pos_halfmod_local.toString()));
+ print(String.format("flat_pos_halfmod_local %s", flat_pos_halfmod_local.toString()));
}
+ VolWrapper halfModuleWrap = makeHalfModule(moduleWrap, ball_pos_halfmod_local, vee_pos_halfmod_local, flat_pos_halfmod_local,lcdd,sens);
+ // add module volume to lcdd file
+ moduleVolume.setVisAttributes(lcdd.getVisAttributes("ModuleVis"));
+
+ lcdd.add(moduleVolume);
+
+
+
+
+ return moduleWrap;
+ }
+
+
+ private VolWrapper makeHalfModule(VolWrapper moduleWrap, Hep3Vector ball_pos_halfmod, Hep3Vector vee_pos_halfmod, Hep3Vector flat_pos_halfmod, LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+
+ if(_debug) {
+ print("--- makeHalfModule ---");
+ }
+
+
+ // the half-module box is built based on the location of the center of the sensor box
+ String halfModuleName = "halfmodule";
+ //find the bounding box for the half module
+ final double x = 4.818*inch + sensor_length/2.0; // ~along sensors, made this up TODO Fix this!
+ final double y = CF_thickness + kapton_thickness + hybrid_thickness; //~ perpendicular to sensors
+ final double z = hybrid_width; // ~height in direction ~perpendicular to the support plate
+
+ Box box = new Box(halfModuleName + "Box", x, y, z);
+ lcdd.add(box);
+ Volume halfModuleVolume = new Volume(halfModuleName + "_volume", box, lcdd.getMaterial("Vacuum"));
+
+ CoordSysDef half_module_coord = new CoordSysDef(ball_pos_halfmod, vee_pos_halfmod, flat_pos_halfmod);
+ // vector to the center of the half module box from ball position/origin
+ double box_center_local_x = x/2.0 - ball_pos_halfmod.x(); // half-module starts, by construction, at ball position x of module
+ double box_center_local_y = z/2.0;
+ double box_center_local_z = y/2.0;
+ Hep3Vector box_center_local = new BasicHep3Vector( box_center_local_x, box_center_local_y, box_center_local_z);
+ if(_debug) {
+ print(String.format("half-module_coord:\n%s", half_module_coord.toString()));
+ }
+
+
+ VolWrapper halfModuleWrap = new VolWrapper();
+ halfModuleWrap.name = halfModuleName;
+ halfModuleWrap.vol = halfModuleVolume;
+ halfModuleWrap.coord = half_module_coord;
+ halfModuleWrap.center = box_center_local;
+
+
+
+
+ // Find the LCDD position and rotation of this module
+ Transform3D transToModuleCoord = getTransformation(half_module_coord);
+ Hep3Vector box_center_module_coord = transToModuleCoord.transformed(box_center_local);
+ Hep3Vector box_center = VecOp.sub(box_center_module_coord, moduleWrap.center);
+ Position pos = new Position(halfModuleName + "_position",box_center.x(), box_center.y(), box_center.z());
+ //Position pos = new Position(volName + "_position",0,20.0,0);
+ Hep3Vector lcdd_rot_angles = new BasicHep3Vector(0,0,0); //getLCDDRotation(survey_coord);
+ Rotation rot = new Rotation(halfModuleName + "_rotation",lcdd_rot_angles.x(), lcdd_rot_angles.y(), lcdd_rot_angles.z());
+ lcdd.add(pos);
+ lcdd.add(rot);
+
+ PhysVol physVolume = new PhysVol(halfModuleVolume, moduleWrap.vol, pos, rot);
+ halfModuleWrap.pv = physVolume;
+ halfModuleWrap.pos_vol = pos;
+ halfModuleWrap.rot_vol = rot;
+ halfModuleWrap.mother = moduleWrap;
+ moduleWrap.daughters.add(halfModuleWrap);
+
+ if(_debug) {
+ print(String.format("half module box center local %s", box_center_local.toString()));
+ print(String.format("half module box center in module coord %s", box_center_module_coord.toString()));
+ print(String.format("module box center in module coord %s", moduleWrap.center.toString()));
+ print(String.format("half module box center in module box %s", box_center.toString()));
+ }
+
+ // create the half module components
+
+ // the sensor survey points are the same as the half-module except it's at the surface of the sensor by construction
+ Hep3Vector ball_pos_sensor_local = new BasicHep3Vector(0,0,CF_thickness + kapton_thickness + sensor_thickness);
+ Hep3Vector vee_pos_sensor_local = new BasicHep3Vector(sensor_length, ball_pos_sensor_local.y(), ball_pos_sensor_local.z());
+ Hep3Vector flat_pos_sensor_local = new BasicHep3Vector(ball_pos_sensor_local.x(), sensor_width, ball_pos_sensor_local.z());
+
+ makeHalfModuleComponents(halfModuleWrap,ball_pos_sensor_local,vee_pos_sensor_local,flat_pos_sensor_local, lcdd, sens);
+
+
+ halfModuleVolume.setVisAttributes(lcdd.getVisAttributes("HalfModuleVis"));
+
+ lcdd.add(halfModuleVolume);
+
+ return halfModuleWrap;
+
}
+ private void makeHalfModuleComponents(VolWrapper halfModuleWrap, Hep3Vector ball_pos_sensor_local, Hep3Vector vee_pos_sensor_local, Hep3Vector flat_pos_sensor_local, LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+
+ if(_debug) {
+ print("--- makeHalfModuleComponents ---");
+ }
+
+ // add sensor
+
+ int sensor_number = 0;
+ String sensorName = "halfmodule_sensor" + sensor_number;
+ // Create the box solid for the component.
+ Box sensor_box = new Box(sensorName + "_box",sensor_length,sensor_thickness, sensor_width);
+ lcdd.add(sensor_box);
+
+ // Create the volume for the module component.
+ Volume sensor_volume = new Volume(sensorName + "_volume", sensor_box,lcdd.getMaterial("Silicon"));
+
+ if(_debug) {
+ print(String.format("ball_pos_sensor_local %s", ball_pos_sensor_local.toString()));
+ print(String.format("vee_pos_sensor_local %s", vee_pos_sensor_local.toString()));
+ print(String.format("flat_pos_sensor_local %s", flat_pos_sensor_local.toString()));
+ }
+
+ CoordSysDef sensor_coord = new CoordSysDef(ball_pos_sensor_local, vee_pos_sensor_local, flat_pos_sensor_local);
+ print(String.format("sensor_coord:\n%s", sensor_coord.toString()));
+
+
+ // Find the LCDD position and rotation of this module
+ Transform3D transToHalfModuleCoord = getTransformation(sensor_coord);
+ Hep3Vector sensor_box_center_local = new BasicHep3Vector(sensor_length/2.0, sensor_width/2.0, -1.0*sensor_thickness/2.0);
+ Hep3Vector sensor_box_center_half_module_coord = transToHalfModuleCoord.transformed(sensor_box_center_local);
+ Hep3Vector sensor_box_center = VecOp.sub(sensor_box_center_half_module_coord, halfModuleWrap.center);
+ Position pos = new Position(sensorName + "_position",sensor_box_center.x(), sensor_box_center.z(), sensor_box_center.y());
+ //Position pos = new Position(volName + "_position",0,20.0,0);
+ Hep3Vector lcdd_rot_angles = new BasicHep3Vector(0,0,0); //getLCDDRotation(survey_coord);
+ Rotation rot = new Rotation(sensorName + "_rotation",lcdd_rot_angles.x(), lcdd_rot_angles.y(), lcdd_rot_angles.z());
+ lcdd.add(pos);
+ lcdd.add(rot);
+
+
+
+ PhysVol sensor_physvol = new PhysVol(sensor_volume, halfModuleWrap.vol, pos, rot);
+ sensor_volume.setSensitiveDetector(sens);
+ sensor_physvol.addPhysVolID("sensor", sensor_number);
+ sensor_physvol.addPhysVolID("system", 0);
+ sensor_physvol.addPhysVolID("barrel", 0);
+ sensor_physvol.addPhysVolID("layer", 0);
+ sensor_physvol.addPhysVolID("module", 0);
+
+
+
+
+
+ VolWrapper sensorWrap = new VolWrapper();
+ sensorWrap.name = sensorName;
+ sensorWrap.pv = sensor_physvol;
+ sensorWrap.vol = sensor_volume;
+ sensorWrap.pos_vol = pos;
+ sensorWrap.rot_vol = rot;
+ sensorWrap.mother = halfModuleWrap;
+ sensorWrap.center = sensor_box_center_local;
+ sensorWrap.coord = sensor_coord;
+ halfModuleWrap.daughters.add(sensorWrap);
+
+
+ sensor_volume.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+
+ lcdd.add(sensor_volume);
+
+
+ if(_debug) {
+ print(String.format("sensor box center local %s", sensor_box_center_local.toString()));
+ print(String.format("sensor box center in half module coord %s", sensor_box_center_half_module_coord.toString()));
+ print(String.format("half module box center in half module coord %s", halfModuleWrap.center.toString()));
+ print(String.format("sensor box center in half module box %s", sensor_box_center.toString()));
+ }
+
+
+
+
+ // add the hybrid
+
+ String hybrid_name = "halfmodule_hybrid" + sensor_number;
+ // Create the box solid for the component.
+ Box hybrid_box = new Box(hybrid_name + "_box",hybrid_length,hybrid_thickness, hybrid_width);
+ lcdd.add(hybrid_box);
+
+ // Create the volume for the module component.
+ Volume hybrid_volume = new Volume(hybrid_name + "_volume", hybrid_box,lcdd.getMaterial("G10"));
+
+ // Place at the height of the kapton and back-to-back to sensor
+ final double hybrid_box_center_x = sensor_box_center.x() - sensor_length/2.0 - hybrid_length/2.0;
+ final double hybrid_box_center_y = sensor_box_center.z() - sensor_thickness/2.0 + hybrid_thickness/2.0;
+ final double hybrid_box_center_z = sensor_box_center.y();
+ print(String.format("sensor box x %f sensor length %f hybrid length %f => hybrid_box_center_x %f",sensor_box_center.x(), sensor_length, hybrid_length, hybrid_box_center_x));
+ print(String.format("sensor box y %f sensor th %f hybrid th %f => hybrid_box_center_y %f",sensor_box_center.z(), sensor_thickness, hybrid_thickness, hybrid_box_center_y));
+ pos = new Position(hybrid_name + "_position",hybrid_box_center_x, hybrid_box_center_y, hybrid_box_center_z);
+ rot = new Rotation(hybrid_name + "_rotation", 0, 0, 0);
+ lcdd.add(pos);
+ lcdd.add(rot);
+ PhysVol hybrid_physvol = new PhysVol(hybrid_volume, halfModuleWrap.vol, pos, rot);
+
+ VolWrapper hybridWrap = new VolWrapper();
+ hybridWrap.name = hybrid_name;
+ hybridWrap.pv = hybrid_physvol;
+ hybridWrap.vol = hybrid_volume;
+ hybridWrap.pos_vol = pos;
+ hybridWrap.rot_vol = rot;
+ hybridWrap.mother = halfModuleWrap;
+ halfModuleWrap.daughters.add(hybridWrap);
+
+ hybrid_volume.setVisAttributes(lcdd.getVisAttributes("HybridVis"));
+
+ lcdd.add(hybrid_volume);
+
+
+
+
+ // add the kapton
+ // fill the entire sensor length and width with kapton
+
+ String kapton_name = "halfmodule_kapton" + sensor_number;
+ // Create the box solid for the component.
+ Box kapton_box = new Box(kapton_name + "_box",sensor_length,kapton_thickness, sensor_width);
+ lcdd.add(kapton_box);
+
+ // Create the volume for the module component.
+ Volume kapton_volume = new Volume(kapton_name + "_volume", kapton_box,lcdd.getMaterial("Kapton"));
+ pos = new Position(kapton_name + "_position", sensor_box_center.x(), sensor_box_center.z() - sensor_thickness/2.0 - kapton_thickness/2.0, sensor_box_center.y());
+ rot = new Rotation(kapton_name + "_rotation", 0, 0, 0);
+ lcdd.add(pos);
+ lcdd.add(rot);
+ PhysVol kapton_physvol = new PhysVol(kapton_volume, halfModuleWrap.vol, pos, rot);
+
+ VolWrapper kaptonWrap = new VolWrapper();
+ kaptonWrap.name = kapton_name;
+ kaptonWrap.pv = kapton_physvol;
+ kaptonWrap.vol = kapton_volume;
+ kaptonWrap.pos_vol = pos;
+ kaptonWrap.rot_vol = rot;
+ kaptonWrap.mother = halfModuleWrap;
+ halfModuleWrap.daughters.add(kaptonWrap);
+
+ kapton_volume.setVisAttributes(lcdd.getVisAttributes("KaptonVis"));
+
+ lcdd.add(kapton_volume);
+
+
+
+ String cf_name = "halfmodule_carbonfiber" + sensor_number;
+ // Create the box solid for the component.
+ Box cf_box = new Box(cf_name + "_box",sensor_length,CF_thickness, sensor_width);
+ lcdd.add(cf_box);
+
+ // Create the volume for the module component.
+ Volume cf_volume = new Volume(cf_name + "_volume", cf_box,lcdd.getMaterial("CarbonFiber"));
+ pos = new Position(cf_name + "_position", sensor_box_center.x(), sensor_box_center.z() - sensor_thickness/2.0 - kapton_thickness - CF_thickness/2.0, sensor_box_center.y());
+ rot = new Rotation(cf_name + "_rotation", 0, 0, 0);
+ lcdd.add(pos);
+ lcdd.add(rot);
+ PhysVol cf_physvol = new PhysVol(cf_volume, halfModuleWrap.vol, pos, rot);
+
+ VolWrapper cfWrap = new VolWrapper();
+ cfWrap.name = cf_name;
+ cfWrap.pv = cf_physvol;
+ cfWrap.vol = cf_volume;
+ cfWrap.pos_vol = pos;
+ cfWrap.rot_vol = rot;
+ cfWrap.mother = halfModuleWrap;
+ halfModuleWrap.daughters.add(cfWrap);
+
+ cf_volume.setVisAttributes(lcdd.getVisAttributes("CarbonFiberVis"));
+
+ lcdd.add(cf_volume);
+
+
+
+ print(String.format("sensor box y %f",sensor_box_center.z()));
+ print(String.format("kapton box y %f",sensor_box_center.z() - sensor_thickness/2.0 - kapton_thickness/2.0));
+ print(String.format("cf box y %f",sensor_box_center.z() - sensor_thickness/2.0 - kapton_thickness - CF_thickness/2.0));
+
+
+
+
+
+
+ }
+
+
+
+
+
+
+ private VolWrapper makeEnvelope(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+
+ Volume trackingVolume = lcdd.getTrackingVolume();
+
+
+ String volName = "envelope";
+ int componentNumber = 0;
+ String envelopeName = "envelope";
+ final double trackingEnvelopeBoxLength = 50.5*inch;
+ final double trackingEnvelopeBoxWidth = 16.0*inch;
+ final double trackingEnvelopeBoxHeight = 8.0*inch;
+ Box envelopeBox = new Box(envelopeName + "Box", trackingEnvelopeBoxLength, trackingEnvelopeBoxWidth, trackingEnvelopeBoxHeight);
+ lcdd.add(envelopeBox);
+ Volume envelopeVolume = new Volume(envelopeName + "_volume", envelopeBox, lcdd.getMaterial("Vacuum"));
+ Position envelopePosition = new Position(envelopeName + "_position",0, 0, 0);
+ Rotation envelopeRotation = new Rotation(envelopeName + "_rotation",0, 0, 0);
+ lcdd.add(envelopePosition);
+ lcdd.add(envelopeRotation);
+
+
+ PhysVol envelopePV = new PhysVol(envelopeVolume, trackingVolume, envelopePosition, envelopeRotation);
+ envelopePV.addPhysVolID(envelopeName, 0);
+
+
+ VolWrapper envWrap = new VolWrapper();
+ envWrap.name = volName;
+ envWrap.pv = envelopePV;
+ envWrap.vol = envelopeVolume;
+ envWrap.pos_vol = envelopePosition;
+ envWrap.rot_vol = envelopeRotation;
+
+
+ // now add the base plate solid
+
+ volName = "envelope";
+ componentNumber = 0;
+ String envelopePlateName = volName + "_base" + componentNumber;
+ Material envelopePlateMaterial = lcdd.getMaterial("Aluminum"); //Oxide"); // TODO fix material!
+ final double envelopePlateLength = trackingEnvelopeBoxLength;
+ final double envelopePlateWidth = trackingEnvelopeBoxWidth;
+ final double envelopePlateHeight = 0.3125*inch;
+ Box envelopePlateBox = new Box(envelopePlateName + "Box", envelopePlateLength, envelopePlateWidth, envelopePlateHeight);
+ lcdd.add(envelopePlateBox);
+
+ Volume envelopePlateVolume = new Volume(envelopePlateName + "_volume", envelopePlateBox, envelopePlateMaterial);
+
+ Position envelopePlatePosition = new Position(envelopePlateName + "_position", 0, 0, 0);
+ Rotation envelopePlateRotation = new Rotation(envelopePlateName + "_rotation", 0, 0, 0);
+ lcdd.add(envelopePlatePosition);
+ lcdd.add(envelopePlateRotation);
+
+ //PhysVol envelopePlatePV = new PhysVol(envelopePlateVolume, lcdd.pickMotherVolume(this) /*envelopeVolume*/, envelopePlatePosition, envelopePlateRotation);
+ PhysVol envelopePlatePV = new PhysVol(envelopePlateVolume, envelopeVolume, envelopePlatePosition, envelopePlateRotation);
+ envelopePlatePV.addPhysVolID(envelopePlateName, 0);
+ lcdd.add(envelopePlateVolume);
+ lcdd.add(envelopeVolume);
+
+ VolWrapper plateWrap = new VolWrapper();
+ plateWrap.name = envelopePlateName;
+ plateWrap.vol = envelopePlateVolume;
+ plateWrap.pv = envelopePlatePV;
+ plateWrap.pos_vol = envelopePlatePosition;
+ plateWrap.rot_vol = envelopePlateRotation;
+ plateWrap.mother = envWrap;
+ envWrap.daughters.add(plateWrap);
+
+
+ return envWrap;
+
+ }
+
+ private VolWrapper makeSupportPlate(VolWrapper envWrapper, LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+
+ // Add a new support plate inside the envelope
+ // TODO add a volume aroundit
+
+ //final double length = (50.5 - 3.5 - 0.5)*inch;
+ //final double width = (16.0 - 1.0*2)*inch;
+ //final double envelopePlateHeight = 0.3125*inch;
+
+
+ String volName = "supportplate";
+ int componentNumber = 0;
+ final double length = 15.0*inch;
+ final double width = 9.25*inch;
+ final double height = 3.0/8.0*inch;
+ Box box = new Box(volName + "Box", length, width, height);
+ lcdd.add(box);
+ Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Aluminum"));
+ Position position = new Position(volName + "_position",0, 0, 0);
+ Rotation rotation = new Rotation(volName + "_rotation",0, 0, 0);
+ lcdd.add(position);
+ lcdd.add(rotation);
+
+ PhysVol pv = new PhysVol(volume, lcdd.pickMotherVolume(this) /*envWrapper.vol*/, /*lcdd.pickMotherVolume(this)*/ /*envelopeVolume*/ position, rotation);
+ pv.addPhysVolID(volName, 0);
+ lcdd.add(volume);
+
+ VolWrapper supportPlateWrap = new VolWrapper();
+ supportPlateWrap.name = volName;
+ supportPlateWrap.vol = volume;
+ supportPlateWrap.pos_vol = position;
+ supportPlateWrap.rot_vol = rotation;
+ supportPlateWrap.mother = envWrapper;
+ envWrapper.daughters.add(supportPlateWrap);
+
+ return supportPlateWrap;
+
+
+
+
+ /*
+
+
+
+
+
+
+ // calculate the transform to the envelope
+ Hep3Vector ball_pos = new BasicHep3Vector(-0.5*envelopePlateLength + 3.5*inch, -0.5*envelopePlateWidth, -1.0*envelopePlateHeight + 0.755);
+ Hep3Vector vee_pos = new BasicHep3Vector(ball_pos.x(), 0.5*envelopePlateWidth, ball_pos.z());
+ Hep3Vector flat_pos = new BasicHep3Vector(0.5*envelopePlateLength - 0.5*inch, 0., ball_pos.z());
+
+
+ // create the coordinate system
+ CoordSysDef envelope_coord = new CoordSysDef(ball_pos, vee_pos, flat_pos);
+
+ // Find the transform between the two frames
+ Transform3D trackingToEnvelopeTransform = getTransformation(envelope_coord);
+ //getTransformation(envelope_coord.origin(), envelope_coord.u(), envelope_coord.v(), envelope_coord.w());
+ RotationGeant trackingToEnvelopeRotation = new RotationGeant(Math.PI, 0, Math.PI/2.0);
+
+ // Get translation and rotation from mother to local
+ //Rotation componentRotation = getLCDDRotation(trackingToEnvelopeTransform, componentName);
+
+ //Hep3Vector box_vec = new BasicHep3Vector(trackingEnvelopeBoxLength, trackingEnvelopeBoxWidth, trackingEnvelopeBoxHeight);
+
+
+ //Hep3Vector box_vec_mother = trackingToEnvelopeTransform.inverse().transformed(box_vec_local);
+
+ if(_debug) {
+ print(String.format("Envelope survey ball positions in mother:"));
+ print(String.format("ball at %s",ball_pos.toString()));
+ print(String.format("vee at %s",vee_pos.toString()));
+ print(String.format("flat at %s",flat_pos.toString()));
+ print(String.format("Resulting envelope coord system:\n%s",envelope_coord.toString()));
+ //print(String.format("box vec local %s",box_vec_local.toString()));
+ print(String.format("transformation \n%s",trackingToEnvelopeTransform.inverse().toString()));
+ //print(String.format("box vec mother %s",box_vec_mother.toString()));
+ }
+
+ */
+
+ }
+
+
+ private static class VolWrapper {
+ public String name;
+ Volume vol = null;
+ PhysVol pv = null;
+ Position pos_vol = null;
+ Rotation rot_vol = null;
+ VolWrapper mother = null;
+ List<VolWrapper> daughters = new ArrayList<VolWrapper>();
+ CoordSysDef coord = null;
+ Hep3Vector center = null;
+ public VolWrapper() {
+ }
+ }
+
private void print(String str) {
System.out.printf("%s: %s\n", this.getClass().getSimpleName(),str);
}
+
+ private Transform3D getTransformation(CoordSysDef coordSys) {
+ return getTransformation(coordSys.origin(), coordSys.u(), coordSys.v(), coordSys.w());
+ }
+
+ /**
+ * Find @ITransform3D to the coordinate system defined by the input.
+ * @param origin of new coordinate system
+ * @param u unit vector
+ * @param v unit vector
+ * @param w unit vector
+ * @return resulting 3D transform
+ */
+ private Transform3D getTransformation(Hep3Vector origin, Hep3Vector u, Hep3Vector v, Hep3Vector w) {
+ // Find the transform between the two frames - use transform classes here (not really needed)
+ Translation3D translation = new Translation3D(origin.x(), origin.y(), origin.z());
+ //RotationGeant trackingToEnvelopeRotation = new RotationGeant(0, 0, 0);
+ Rotation3D rotation = new Rotation3D(
+ new BasicHep3Matrix(
+ u.x(),v.x(),w.x(),
+ u.y(),v.y(),w.y(),
+ u.z(),v.z(),w.z()
+ ));
+ Transform3D envelopeToSupportTransform = new Transform3D(translation, rotation);
+ return envelopeToSupportTransform;
+ }
+
+ private Position getLCDDPosition(ITransform3D transform, String name) {
+ Position componentPosition = new Position(name + "_position",
+ transform.getTranslation().x(),
+ transform.getTranslation().y(),
+ transform.getTranslation().z());
+ return componentPosition;
+ }
+
+ private Rotation getLCDDRotation(Transform3D transform, String name) {
+ Hep3Matrix rotationMatrix = transform.getRotation().getRotationMatrix();
+ // Extract the rotation angles from the combined matrix
+ // Assumes rotation matrix built A = RzRyRx
+ double rotation_z = Math.atan2(rotationMatrix.e(2, 0), rotationMatrix.e(2, 1));
+ double rotation_y = Math.acos(rotationMatrix.e(2, 2));
+ double rotation_x = -1.0 * Math.atan2(rotationMatrix.e(0, 2), rotationMatrix.e(1, 2));
+
+ Rotation componentRotation = new Rotation(name + "_rotation",rotation_x, rotation_y, rotation_z);
+ return componentRotation;
+ }
+
+
+ private static class CoordSysDef {
+ private Hep3Vector origin;
+ private Hep3Vector u;
+ private Hep3Vector v;
+ private Hep3Vector w;
+
+ public CoordSysDef(Hep3Vector org, Hep3Vector unit_x, Hep3Vector unit_y, Hep3Vector unit_z) {
+ origin = org;
+ u = unit_x;
+ v = unit_y;
+ w = unit_z;
+ }
+
[truncated at 1000 lines; 68 more skipped]