GeomConverter/src/org/lcsim/detector/converter/compact
diff -N SiTrackerEndcapConverterJM.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ SiTrackerEndcapConverterJM.java 6 Dec 2007 08:01:11 -0000 1.1
@@ -0,0 +1,869 @@
+package org.lcsim.detector.converter.compact;
+
+import hep.physics.matrix.BasicMatrix;
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.VecOp;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jdom.DataConversionException;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.lcsim.detector.DetectorElement;
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.ILogicalVolume;
+import org.lcsim.detector.IPhysicalVolume;
+import org.lcsim.detector.IPhysicalVolumePath;
+import org.lcsim.detector.IRotation3D;
+import org.lcsim.detector.ITransform3D;
+import org.lcsim.detector.ITranslation3D;
+import org.lcsim.detector.LogicalVolume;
+import org.lcsim.detector.PhysicalVolume;
+import org.lcsim.detector.Rotation3D;
+import org.lcsim.detector.RotationPassiveXYZ;
+import org.lcsim.detector.Transform3D;
+import org.lcsim.detector.Translation3D;
+import org.lcsim.detector.DetectorIdentifierHelper.SystemMap;
+import org.lcsim.detector.identifier.ExpandedIdentifier;
+import org.lcsim.detector.identifier.IIdentifier;
+import org.lcsim.detector.identifier.IIdentifierDictionary;
+import org.lcsim.detector.identifier.IIdentifierHelper;
+import org.lcsim.detector.identifier.IdentifierDictionaryManager;
+import org.lcsim.detector.identifier.IdentifierHelper;
+import org.lcsim.detector.identifier.IdentifierUtil;
+import org.lcsim.detector.identifier.IIdentifierDictionary.FieldNotFoundException;
+import org.lcsim.detector.identifier.IIdentifierDictionary.InvalidIndexException;
+import org.lcsim.detector.material.IMaterial;
+import org.lcsim.detector.material.MaterialStore;
+import org.lcsim.detector.solids.Box;
+import org.lcsim.detector.solids.IPolyhedron;
+import org.lcsim.detector.solids.Point3D;
+import org.lcsim.detector.solids.Polygon3D;
+import org.lcsim.detector.solids.Trap;
+import org.lcsim.detector.solids.Trd;
+import org.lcsim.detector.solids.Tube;
+import org.lcsim.detector.tracker.silicon.ChargeCarrier;
+import org.lcsim.detector.tracker.silicon.SiSensor;
+import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
+import org.lcsim.detector.tracker.silicon.SiStrips;
+import org.lcsim.detector.tracker.silicon.SiTrackerIdentifierHelper;
+import org.lcsim.detector.tracker.silicon.SiTrackerModule;
+import org.lcsim.geometry.compact.Detector;
+import org.lcsim.geometry.compact.Subdetector;
+import org.lcsim.geometry.subdetector.SiTrackerEndcap;
+
+/**
+ * Converter for SiTrackerEndcap.
+ *
+ * @author Jeremy McCormick, Tim Nelson
+ * @version $Id: SiTrackerEndcapConverterJM.java,v 1.1 2007/12/06 08:01:11 jeremy Exp $
+ */
+
+public class SiTrackerEndcapConverter
+extends AbstractSubdetectorConverter
+implements ISubdetectorConverter
+{
+ private ModuleParameters moduleParameters = null;
+
+ public IIdentifierHelper makeIdentifierHelper(Subdetector subdetector, SystemMap systemMap)
+ {
+ try {
+ return new SiTrackerIdentifierHelper(makeIdentifierDictionary(subdetector), systemMap);
+ }
+ catch (FieldNotFoundException x)
+ {
+ throw new RuntimeException(x);
+ }
+ catch (InvalidIndexException x)
+ {
+ throw new RuntimeException(x);
+ }
+ }
+
+ public void convert(Subdetector subdet, Detector detector)
+ {
+ IPhysicalVolume trackingPV = detector.getTrackingVolume();
+ ILogicalVolume trackingLV = trackingPV.getLogicalVolume();
+
+ Element node = subdet.getNode();
+
+ IDetectorElement endcapDE = new DetectorElement(subdet.getName(), detector.getDetectorElement());
+ subdet.setDetectorElement(endcapDE);
+
+ // Positive endcap DE.
+ IDetectorElement endcapPosDE = new DetectorElement(subdet.getName() + "_positive", endcapDE);
+
+ // Negative endcap DE.
+ IDetectorElement endcapNegDE = new DetectorElement(subdet.getName() + "_negative", endcapDE);
+
+ // Set static module parameters.
+ moduleParameters = new ModuleParameters(node.getChild("module"));
+
+ for (Object o : node.getChildren("layer"))
+ {
+ Element layerElement = (Element)o;
+
+ int nwedges;
+ try
+ {
+ nwedges = layerElement.getAttribute("nwedges").getIntValue();
+ }
+ catch (DataConversionException x)
+ {
+ throw new RuntimeException(x);
+ }
+
+ double innerR, outerR, innerZ, thickness;
+ int layern;
+ try
+ {
+ layern = layerElement.getAttribute("id").getIntValue();
+ innerR = layerElement.getAttribute("inner_r").getDoubleValue();
+ outerR = layerElement.getAttribute("outer_r").getDoubleValue();
+ innerZ = layerElement.getAttribute("inner_z").getDoubleValue();
+ thickness = layerElement.getAttribute("thickness").getDoubleValue();
+ }
+ catch (DataConversionException x)
+ {
+ throw new RuntimeException(x);
+ }
+
+ ILogicalVolume layerLV = makeLayer(detector,subdet,innerR,outerR,thickness,nwedges,layerElement);
+
+ double layerZ = innerZ + thickness / 2;
+
+ // Positive endcap layer.
+ ITransform3D layerTrans = new Transform3D(new Translation3D(0,0,layerZ));
+ String layerName = layerLV.getName() + "_positive";
+ new PhysicalVolume(layerTrans,layerName,layerLV,trackingLV,layern);
+ String layerPath = "/" + trackingPV.getName() + "/" + layerName;
+ IDetectorElement layerDE = new DetectorElement(layerLV.getName(),endcapPosDE,detector.getNavigator().getPath(layerPath));
+
+ // Negative endcap layer.
+ ITransform3D layerTransReflect = new Transform3D(new Translation3D(0,0,-layerZ), new RotationPassiveXYZ(0,Math.PI,0));
+ String layerNameReflect = layerLV.getName() + "_negative";
+ new PhysicalVolume(layerTransReflect,layerNameReflect,layerLV,trackingLV,layern);
+ String layerPathReflect = "/" + trackingPV.getName() + "/" + layerNameReflect;
+ IDetectorElement layerDEReflect = new DetectorElement(layerNameReflect,endcapNegDE,detector.getNavigator().getPath(layerPathReflect));
+
+ // Wedge DE.
+ for (IPhysicalVolume wedge : layerLV.getDaughters())
+ {
+ // Positive endcap.
+ String wedgePath = layerPath + "/" + wedge.getName();
+ String wedgeName = layerName + "_wedge" + wedge.getCopyNumber();
+ IDetectorElement wedgeDE = new DetectorElement(wedgeName,layerDE,detector.getNavigator().getPath(wedgePath));
+
+ // Negative endcap.
+ String wedgePathReflect = layerPathReflect + "/" + wedge.getName();
+ String wedgeNameReflect = layerNameReflect + "_wedge" + wedge.getCopyNumber();
+ IDetectorElement wedgeDEReflect = new DetectorElement(wedgeNameReflect,layerDEReflect,detector.getNavigator().getPath(wedgePathReflect));
+
+ // Module DEs.
+ for (IPhysicalVolume module : wedge.getLogicalVolume().getDaughters())
+ {
+ // Positive endcap module.
+ String modulePath = wedgePath + "/" + module.getName();
+ String moduleName = wedgeName + "_module" + module.getCopyNumber();
+ //IDetectorElement moduleDE = new DetectorElement(moduleName,wedgeDE,detector.getNavigator().getPath(modulePath));
+ IDetectorElement moduleDE = new SiTrackerModule(
+ moduleName,
+ wedgeDE,
+ detector.getNavigator().getPath(modulePath).toString(),
+ module.getCopyNumber());
+
+ // Negative endcap module.
+ String modulePathReflect = wedgePathReflect + "/" + module.getName();
+ String moduleNameReflect = wedgeNameReflect + "_module" + module.getCopyNumber();
+ //IDetectorElement moduleDEReflect = new DetectorElement(moduleNameReflect,wedgeDEReflect,detector.getNavigator().getPath(modulePathReflect));
+ IDetectorElement moduleDEReflect = new SiTrackerModule(
+ moduleNameReflect,
+ wedgeDEReflect,
+ detector.getNavigator().getPath(modulePathReflect).toString(),
+ module.getCopyNumber()
+ );
+
+ // Sensor DEs.
+ for (IPhysicalVolume component : module.getLogicalVolume().getDaughters())
+ {
+ if (component.isSensitive())
+ {
+ int sensorNum = component.getCopyNumber();
+
+ // Positive endcap component.
+ new SiSensor(
+ sensorNum,
+ moduleName + "_component" + sensorNum,
+ moduleDE,
+ detector.getNavigator().getPath(modulePath + "/" + component.getName()).toString());
+
+ // Negative endcap component. (should have same physical layout as positive)
+ new SiSensor(
+ sensorNum,
+ moduleNameReflect + "_component" + sensorNum,
+ moduleDEReflect,
+ detector.getNavigator().getPath(modulePathReflect + "/" + component.getName()).toString());
+ }
+ }
+ }
+ }
+ }
+
+ try
+ {
+ setupSensorDetectorElements(subdet);
+ }
+ catch (Exception x)
+ {
+ throw new RuntimeException(x);
+ }
+
+ // Set cached module parameters to null for GC.
+ moduleParameters = null;
+ }
+
+ private ILogicalVolume makeWedge(
+ Detector detector,
+ Subdetector subdet,
+ double innerR,
+ double outerR,
+ double thickness,
+ int nwedges,
+ int layern)
+ {
+ IMaterial material = detector.getTrackingVolume().getLogicalVolume().getMaterial();
+
+ String name = subdet.getName() + "_layer" + layern + "_wedge";
+
+ double dz = (outerR - innerR) / 2;
+ double dy1, dy2;
+ dy1 = dy2 = thickness / 2;
+ double dx1, dx2;
+ double dphi = Math.PI / nwedges;
+ dx1 = innerR * Math.tan(dphi);
+ dx2 = outerR * Math.tan(dphi);
+
+ Trd wedgeTrd = new Trd(name,dx1,dx2,dy1,dy2,dz);
+
+ ILogicalVolume wedgeLV = new LogicalVolume(name, wedgeTrd, material);
+
+ return wedgeLV;
+ }
+
+ private ILogicalVolume makeLayer(
+ Detector detector,
+ Subdetector subdet,
+ double innerR,
+ double outerR,
+ double thickness,
+ int nwedges,
+ Element layerElement
+ )
+ {
+ int layern;
+ try
+ {
+ layern = layerElement.getAttribute("id").getIntValue();
+ }
+ catch (DataConversionException x)
+ {
+ throw new RuntimeException(x);
+ }
+
+ IMaterial material = detector.getTrackingVolume().getLogicalVolume().getMaterial();
+ String layerName = subdet.getName() + "_layer" + layern;
+
+ double dphi = Math.PI / nwedges;
+
+ double tubeInnerR, tubeOuterR;
+ tubeInnerR = innerR;
+ tubeOuterR = outerR / Math.cos(dphi);
+
+ Tube layerTube = new Tube(layerName,tubeInnerR,tubeOuterR,thickness/2);
+
+ // Make the layer LV.
+ ILogicalVolume layerLV = new LogicalVolume(layerName,layerTube,material);
+
+ // Make the wedge LV.
+ ILogicalVolume wedgeLV = makeWedge(detector, subdet, innerR, outerR, thickness, nwedges, layern);
+
+ // Make the modules in the wedge.
+ makeModules(subdet, wedgeLV, layerElement.getChild("module_parameters"), layern);
+
+ // Place the wedges in the layer.
+ double r = (innerR + outerR) / 2;
+ //String wedgeName = wedgeLV.getName();
+ for (int i=0; i<nwedges; i++)
+ {
+ double phi = i * 2 * Math.PI / nwedges;
+ double x = r * Math.cos(phi);
+ double y = r * Math.sin(phi);
+
+ Translation3D p = new Translation3D(x,y,0);
+ Rotation3D rot = new RotationPassiveXYZ(-Math.PI/2,0.,-Math.PI/2 - phi);
+ Transform3D transform = new Transform3D(p,rot);
+ new PhysicalVolume(
+ transform,
+ "wedge" + i,
+ wedgeLV,
+ layerLV,
+ i);
+ }
+
+ return layerLV;
+ }
+
+
+ private void makeModules(Subdetector subdet, ILogicalVolume wedgeLV, Element moduleElement, int layern)
+ {
+ double r_size;
+ try
+ {
+ r_size = moduleElement.getAttribute("r_size").getDoubleValue();
+ }
+ catch (DataConversionException x)
+ {
+ throw new RuntimeException(x);
+ }
+
+ double phi_size_max;
+ try
+ {
+ phi_size_max = moduleElement.getAttribute("phi_size_max").getDoubleValue();
+ }
+ catch (DataConversionException x)
+ {
+ throw new RuntimeException(x);
+ }
+
+ Trd moduleTrd = (Trd)wedgeLV.getSolid();
+ double dz = ((Trd)wedgeLV.getSolid()).getZHalfLength();
+ double dx1 = moduleTrd.getXHalfLength1();
+ double dx2 = moduleTrd.getXHalfLength2();
+ double dy = moduleTrd.getYHalfLength1();
+ double deltax = dx2 - dx1;
+ double side_slope = deltax/(2*dz);
+
+ List<Double> zcenters = new ArrayList<Double>();
+ List<Double> zsizes = new ArrayList<Double>();
+ List<Double> xsizes1 = new ArrayList<Double>();
+ List<Double> xsizes2 = new ArrayList<Double>();
+
+ {
+ double zcurr = dz;
+ while (zcurr - r_size >= -dz)
+ {
+ double zmax = zcurr;
+ double zmin = zcurr-r_size;
+ zcenters.add((zmin+zmax)/2);
+ zsizes.add((zmax-zmin)/2);
+
+ double xsize1 = dx1 + side_slope*(zmin+dz);
+ double xsize2 = dx1 + side_slope*(zmax+dz);
+
+ xsizes1.add(xsize1);
+ xsizes2.add(xsize2);
+
+ zcurr -= r_size;
+ }
+ double zmax = zcurr;
+ double zmin = -dz;
+ zcenters.add((zmin+zmax)/2);
+ zsizes.add((zmax-zmin)/2);
+ double xsize1 = dx1 + side_slope*(zmin+dz);
+ double xsize2 = dx1 + side_slope*(zmax+dz);
+ xsizes1.add(xsize1);
+ xsizes2.add(xsize2);
+ }
+
+ IMaterial sliceMaterial = wedgeLV.getMaterial();
+
+ double xsize1_min = 0.0;
+ double xsize_box = 0.0;
+ int nboxes = 0;
+
+ int imodule = 0;
+
+ for (int i=zcenters.size()-1; i >= 0; i--)
+ {
+
+ int ntraps = (int)Math.ceil( 2*(xsizes1.get(i) - nboxes*xsize_box) / phi_size_max );
+
+
+ // Squares to fill extra space
+ if (ntraps > 2)
+ {
+ if (xsize_box == 0.0) xsize_box = xsizes1.get(i) - 2*xsize1_min;
+ nboxes++;
+ ntraps = 2;
+ }
+
+ double xmin = -nboxes*xsize_box;
+ double xmax = xmin+2*xsize_box;
+
+ for (int ibox = 0; ibox < nboxes; ibox++)
+ {
+
+ double xcenter = (xmin+xmax)/2;
+ xmin += 2*xsize_box;
+ xmax += 2*xsize_box;
+
+ String sliceName = "module" + imodule;
+
+ Box sliceBox = new Box(sliceName,xsize_box,dy,zsizes.get(i));
+
+ ILogicalVolume sliceLV = new LogicalVolume(sliceName, sliceBox, sliceMaterial);
+
+ // Build the module substructure.
+ makeBoxModule(sliceLV, imodule);
+
+ Transform3D trans = new Transform3D(new Translation3D(xcenter,0,zcenters.get(i)));
+
+ new PhysicalVolume(
+ trans,
+ sliceName,
+ sliceLV,
+ wedgeLV,
+ imodule);
+
+ imodule++;
+ }
+
+ // Small symmetric trapezoids
+ if (ntraps == 1)
+ {
+ String sliceName = "module" + imodule;
+
+ Trd sliceTrd = new Trd(sliceName,xsizes1.get(i),xsizes2.get(i),dy,dy,zsizes.get(i));
+
+ ILogicalVolume sliceLV = new LogicalVolume(sliceName, sliceTrd, sliceMaterial);
+
+ // Build the module substructure.
+ makeTrdModule(sliceLV, imodule);
+
+ Transform3D trans = new Transform3D(new Translation3D(0,0,zcenters.get(i)));
+
+ new PhysicalVolume(
+ trans,
+ sliceName,
+ sliceLV,
+ wedgeLV,
+ imodule);
+
+ imodule++;
+ }
+
+ // Split trapezoids
+ if (ntraps == 2)
+ {
+
+ double xoffset = xsize_box*nboxes;
+
+ double xsize1 = (xsizes1.get(i)-xoffset)/ntraps;
+ if (xsize1_min == 0.0) xsize1_min = xsize1;
+ double xsize2 = (xsizes2.get(i)-xoffset)/ntraps;
+
+ double xcenter = (xsize1+xsize2)/2 + xoffset;
+ double theta = Math.abs(Math.atan(side_slope/2));
+
+ for (int ix = -1; ix <=1; ix=ix+2)
+ {
+
+ String sliceName = "module" + imodule;
+
+ Trap sliceTrap = new Trap(sliceName,zsizes.get(i),theta*ix,0.0,dy,xsize1,xsize1,0.0,dy,xsize2,xsize2,0.0);
+
+ ILogicalVolume sliceLV = new LogicalVolume(sliceName, sliceTrap, sliceMaterial);
+
+ makeTrapModule(sliceLV, imodule);
+
+ Transform3D trans = new Transform3D(new Translation3D(ix*xcenter,0,zcenters.get(i)));
+
+ new PhysicalVolume(
+ trans,
+ sliceName,
+ sliceLV,
+ wedgeLV,
+ imodule);
+
+ imodule++;
+ }
+ }
+ }
+ }
+
+ public void makeBoxModule(ILogicalVolume module, int moduleTypeId)
+ {
+ Box moduleBox = (Box)module.getSolid();
+ double posY = -moduleBox.getYHalfLength();
+ double moduleX = moduleBox.getXHalfLength();
+ double moduleZ = moduleBox.getZHalfLength();
+
+ for (ModuleComponentParameters component : moduleParameters)
+ {
+ double thickness = component.getThickness();
+ IMaterial material = MaterialStore.getInstance().get(component.getMaterialName());
+ boolean sensitive = component.isSensitive();
+ int componentNumber = component.getComponentNumber();
+
+ posY += thickness / 2;
+
+ String componentName = "module" + moduleTypeId + "_component" + componentNumber;
+
+ Box sliceBox = new Box(componentName + "_box", moduleX, thickness / 2, moduleZ);
+
+ ILogicalVolume volume = new LogicalVolume(componentName, sliceBox, material);
+
+ Transform3D trans = new Transform3D(new Translation3D(0,posY,0));
+
+ PhysicalVolume pv = new PhysicalVolume(trans, componentName, volume, module, componentNumber);
+ pv.setSensitive(sensitive);
+
+ posY += thickness / 2;
+ }
+ }
+
+ public void makeTrdModule(ILogicalVolume module, int moduleTypeId)
+ {
+ Trd trd = (Trd)module.getSolid();
+ double x1 = trd.getXHalfLength1();
+ double x2 = trd.getXHalfLength2();
+ double y1 = trd.getYHalfLength1();
+ double z = trd.getZHalfLength();
+
+ double posY = -y1;
+
+ for (ModuleComponentParameters component : moduleParameters)
+ {
+ double thickness = component.getThickness();
+ IMaterial material = MaterialStore.getInstance().get(component.getMaterialName());
+ boolean sensitive = component.isSensitive();
+ int componentNumber = component.getComponentNumber();
+
+ posY += thickness / 2;
+
+ String componentName = "module" + moduleTypeId + "_component" + componentNumber;
+
+ Trd sliceTrd = new Trd(componentName, x1, x2, thickness/2, thickness/2, z);
+
+ ILogicalVolume volume = new LogicalVolume(componentName, sliceTrd, material);
+
+ Transform3D trans = new Transform3D(new Translation3D(0,posY,0));
+
+ PhysicalVolume pv = new PhysicalVolume(trans, componentName, volume, module, componentNumber);
+ pv.setSensitive(sensitive);
+
+ posY += thickness / 2;
+ }
+ }
+
+ public void makeTrapModule(ILogicalVolume module, int moduleTypeId)
+ {
+ Trap trap = (Trap)module.getSolid();
+ //double a1 = trap.getTanAlpha1();
+ //double a2 = trap.getTanAlpha2();
+ double a1 = trap.getAlpha1();
+ double a2 = trap.getAlpha2();
+ double x1 = trap.getXHalfLength1();
+ double x2 = trap.getXHalfLength2();
+ double x3 = trap.getXHalfLength3();
+ double x4 = trap.getXHalfLength4();
+ double y1 = trap.getYHalfLength1();
+ //double y2 = trap.getYHalfLength2();
+ double z = trap.getZHalfLength();
+ double theta = trap.getTheta();
+ double phi = trap.getPhi();
+
+ double posY = -y1;
+
+ for (ModuleComponentParameters component : moduleParameters)
+ {
+ double thickness = component.getThickness();
+ IMaterial material = MaterialStore.getInstance().get(component.getMaterialName());
+ boolean sensitive = component.isSensitive();
+ int componentNumber = component.getComponentNumber();
+
+ posY += thickness / 2;
+
+ String componentName = "module" + moduleTypeId + "_component" + componentNumber;
+
+ Trap sliceTrap = new Trap(componentName, z, theta, phi, thickness/2, x1, x2, a1, thickness/2, x3, x4, a2);
+
+ ILogicalVolume volume = new LogicalVolume(componentName, sliceTrap, material);
+
+ Transform3D trans = new Transform3D(new Translation3D(0,posY,0));
+
+ PhysicalVolume pv = new PhysicalVolume(trans, componentName, volume, module, componentNumber);
+ pv.setSensitive(sensitive);
+
+ posY += thickness / 2;
+ }
+ }
+
+ public Class getSubdetectorType()
+ {
+ return SiTrackerEndcap.class;
+ }
+
+ // TODO: Need to have SiTrackerIdentifierHelper available before this is called.
+ private void setupSensorDetectorElements(Subdetector subdet) throws Exception
+ {
+ IIdentifierHelper id_helper = new IdentifierHelper(IdentifierDictionaryManager.getInstance().getIdentifierDictionary(subdet.getReadout().getName()));
+
+ //SiTrackerIdentifierHelper id_helper = (SiTrackerIdentifierHelper)subdet.getDetectorElement().getIdentifierHelper();
+
+ int moduleId=0;
+
+ for ( IDetectorElement endcap : subdet.getDetectorElement().getChildren() )
+ {
+ for ( IDetectorElement layer : endcap.getChildren() )
+ {
+ int nwedges = layer.getChildren().size();
+ for ( IDetectorElement wedge : layer.getChildren() )
+ {
+ for ( IDetectorElement module : wedge.getChildren() )
+ {
+ IPhysicalVolumePath modulePath =
+ module.getGeometry().getPath();
+
+ IPhysicalVolume modulePhysVol =
+ modulePath.getLeafVolume();
+
+ int sensorId=0;
+ for ( IPhysicalVolume pv : modulePhysVol.getLogicalVolume().getDaughters())
+ {
+ // Create the identifier for this sensor.
+ if ( pv.isSensitive() )
+ {
+ IIdentifierDictionary iddict =
+ IdentifierDictionaryManager.getInstance().
+ getIdentifierDictionary( subdet.getReadout().getName() );
+
+ ExpandedIdentifier expId = new ExpandedIdentifier(iddict.getNumberOfFields());
+
+ try
+ {
+ // Set the System ID.
+ expId.setValue(iddict.getFieldIndex("system"), subdet.getSystemID());
+
+ // Set the barrel-endcap flag.
+ //if (id_helper.isEndcapPositive(endcap.getIdentifier()))
+ if (id_helper.getValue(endcap.getIdentifier(), "barrel") == 1)
+ {
+ //expId.setValue(iddict.getFieldIndex("barrel"), id_helper.getEndcapPositiveValue());
+ expId.setValue(iddict.getFieldIndex("barrel"), 1);
+ }
+ if (id_helper.getValue(endcap.getIdentifier(), "barrel") == 2)
+ //else if (id_helper.isEndcapNegative(endcap.getIdentifier()))
+ {
+ //expId.setValue(iddict.getFieldIndex("barrel"), id_helper.getEndcapNegativeValue());
+ expId.setValue(iddict.getFieldIndex("barrel"), 2);
+ }
+
+ // Set the layer number.
+ expId.setValue(iddict.getFieldIndex("layer"), layer.getGeometry().getPath().getLeafVolume().getCopyNumber());
+
+ // Set the wedge number.
+ expId.setValue(iddict.getFieldIndex("wedge"), wedge.getGeometry().getPath().getLeafVolume().getCopyNumber());
+
+ // Set the module id from the DetectorElement.
+ expId.setValue(iddict.getFieldIndex("module"),((SiTrackerModule)module).getModuleId());
+
+ // Set the sensor id for double-sided.
+ expId.setValue(iddict.getFieldIndex("sensor"),sensorId);
+ }
+ catch (FieldNotFoundException x)
+ {
+ throw new RuntimeException(x);
+ }
+
+ // Create the packed id using util method.
+ // No IdentifierHelper is available yet.
+ IIdentifier id = null;
+ try
+ {
+ id = IdentifierUtil.pack( iddict, expId );
+ }
+ catch (InvalidIndexException x)
+ {
+ throw new RuntimeException(x);
+ }
+
+ //System.out.println(pv.getName() + " is sens");
+ //System.out.println("path : " + modulePath.toString() + "/" + pv.getName());
+ String sensorPath = modulePath.toString() + "/" + pv.getName();
+ //String sensorName = subdet.getName() + "_layer" + layer.getGeometry().getPhysicalVolume().getCopyNumber() + "_module" + moduleId + "_sensor" + sensorId;
+ String sensorName = endcap.getName() +
+ "_layer" + layer.getGeometry().getPhysicalVolume().getCopyNumber() +
+ "_wedge" + wedge.getGeometry().getPath().getLeafVolume().getCopyNumber() +
+ "_module" + ((SiTrackerModule)module).getModuleId() + "_sensor" + sensorId;
+
+ //System.out.println(sensorName + " -> " + expId);
+ //System.out.println(sensorName + " -> " + id);
+ //System.out.println();
+
+ SiSensor sensor = new SiSensor(sensorId,sensorName,module,sensorPath,id);
+ //sensor.setIdentifier(id);
+
+ // Set up SiStrips for the sensors
+ IPolyhedron sensor_solid = (IPolyhedron)sensor.getGeometry().getLogicalVolume().getSolid();
+
+ Polygon3D inner_surface = sensor_solid.getFacesNormalTo(new BasicHep3Vector(0,-1,0)).get(0);
+ Polygon3D outer_surface = sensor_solid.getFacesNormalTo(new BasicHep3Vector(0,1,0)).get(0);
+// double strip_angle_magnitude = Math.PI/nwedges;
+
+ Polygon3D p_side;
+ Polygon3D n_side;
+ int side;
+
+ if (sensorId == 0) // inner sensor
+ {
+ p_side = inner_surface;
+ n_side = outer_surface;
+ side = 1;
+// strip_angle = strip_angle_magnitude;
+ }
+ else // outer sensor
+ {
+ p_side = outer_surface;
+ n_side = inner_surface;
+ side = -1;
+// strip_angle = -1*strip_angle_magnitude;
+ }
+
+ System.out.println("Plane of p_side polygon has... ");
+ System.out.println(" normal: "+p_side.getNormal());
+ System.out.println(" distance: "+p_side.getDistance());
+ for (Point3D point : p_side.getVertices())
+ {
+ System.out.println(" Vertex: "+point);
+ }
+
+ System.out.println("Plane of n_side polygon has... ");
+ System.out.println(" normal: "+n_side.getNormal());
+ System.out.println(" distance: "+n_side.getDistance());
+
+ // Bias the sensor
+ sensor.setBiasSurface(ChargeCarrier.HOLE,p_side);
+ sensor.setBiasSurface(ChargeCarrier.ELECTRON,n_side);
+
+ double strip_angle = Math.PI/nwedges;
+
+ System.out.println(" side = : "+side);
+
+ ITranslation3D electrodes_position = new Translation3D(VecOp.mult(-p_side.getDistance(),new BasicHep3Vector(0,0,1))); // translate to outside of polygon
+// ITranslation3D electrodes_position = new Translation3D(VecOp.mult(-p_side.getDistance(),p_side.getNormal())); // translate to p_side
+ IRotation3D electrodes_rotation = new RotationPassiveXYZ(side*(Math.PI/2),0,0*strip_angle); //
+ Transform3D electrodes_transform = new Transform3D(electrodes_position, electrodes_rotation);
+
+ System.out.println(" electrodes_transform translation: \n"+electrodes_transform.getTranslation().getTranslationVector());
+ System.out.println(" electrodes_transform rotation: \n"+electrodes_transform.getRotation().getRotationMatrix());
+
+ // Free calculation of sense electrodes, readout electrodes determined thereon
+ SiSensorElectrodes sense_electrodes = new SiStrips(ChargeCarrier.HOLE,0.025,sensor,electrodes_transform);
+ SiSensorElectrodes readout_electrodes = new SiStrips(ChargeCarrier.HOLE,0.050,(sense_electrodes.getNCells()+1)/2,sensor,electrodes_transform);
+
+ sensor.setSenseElectrodes(sense_electrodes);
+ sensor.setReadoutElectrodes(readout_electrodes);
+
+ double[][] transfer_efficiencies = { {0.986,0.419} };
+ sensor.setTransferEfficiencies(ChargeCarrier.HOLE,new BasicMatrix(transfer_efficiencies));
+
+ // Incremenet sensorID for double-sided.
+ ++sensorId;
+ }
+ }
+
+ ++moduleId;
+ }
+ }
+ }
+ }
+ }
+
+ public static class ModuleComponentParameters
+ {
+ String materialName;
+ double thickness;
+ boolean sensitive;
+ int componentNumber;
+
+ public ModuleComponentParameters(double thickness, String materialName, int componentNumber, boolean sensitive)
+ {
+ this.thickness = thickness;
+ this.materialName = materialName;
+ this.sensitive = sensitive;
+ this.componentNumber = componentNumber;
+ }
+
+ public double getThickness()
+ {
+ return thickness;
+ }
+
+ public String getMaterialName()
+ {
+ return materialName;
+ }
+
+ public boolean isSensitive()
+ {
+ return sensitive;
+ }
+
+ public int getComponentNumber()
+ {
+ return componentNumber;
+ }
+ }
+
+ public static class ModuleParameters
+ extends ArrayList<ModuleComponentParameters>
+ {
+ double thickness=0.;
+ String name;
+ public ModuleParameters(Element element)
+ {
+ name = element.getAttributeValue("name");
+ int cntr=0;
+ for (Object o : element.getChildren("module_component"))
+ {
+ try
+ {
+
+ Element e = (Element)o;
+
+ double thickness = e.getAttribute("thickness").getDoubleValue();
+
+ String materialName = e.getAttributeValue("material");
+
+ boolean sensitive = false;
+ if (e.getAttribute("sensitive") != null)
+ sensitive = e.getAttribute("sensitive").getBooleanValue();
+ add(new ModuleComponentParameters(thickness, materialName, cntr, sensitive));
+ }
+ catch (JDOMException x)
+ {
+ throw new RuntimeException(x);
+ }
+ ++cntr;
+ }
+ calculateThickness();
+ }
+
+ public void calculateThickness()
+ {
+ thickness = 0.; // reset thickness
+ for (ModuleComponentParameters p : this)
+ {
+ thickness += p.getThickness();
+ }
+ }
+
+ public double getThickness()
+ {
+ return thickness;
+ }
+ }
+}