Commit in GeomConverter/src/org/lcsim on MAIN | |||
geometry/subdetector/HPSTracker.java | +32 | added 1.1 | |
detector/converter/compact/HPSTrackerConverter.java | +515 | added 1.1 | |
+547 |
work in progress on Java model for new HPS tracker module geom
diff -N HPSTracker.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ HPSTracker.java 13 Jan 2012 00:02:51 -0000 1.1 @@ -0,0 +1,32 @@
+package org.lcsim.geometry.subdetector; + +import hep.graphics.heprep.HepRep; +import hep.graphics.heprep.HepRepFactory; + +import org.jdom.Element; +import org.jdom.JDOMException; +import org.lcsim.detector.converter.heprep.DetectorElementToHepRepConverter; + +public class HPSTracker extends AbstractTracker +{ + HPSTracker(Element node) throws JDOMException + { + super(node); + } + + public void appendHepRep(HepRepFactory factory, HepRep heprep) + { + DetectorElementToHepRepConverter.convert(getDetectorElement(), factory, heprep, -1, false, getVisAttributes().getColor()); + } + + public boolean isEndcap() + { + return false; + } + + public boolean isBarrel() + { + return true; + } + +}
\ No newline at end of file
diff -N HPSTrackerConverter.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ HPSTrackerConverter.java 13 Jan 2012 00:02:51 -0000 1.1 @@ -0,0 +1,515 @@
+package org.lcsim.detector.converter.compact; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.jdom.DataConversionException; +import org.jdom.Element; +import org.jdom.JDOMException; +import org.lcsim.detector.DetectorElement; +import org.lcsim.detector.DetectorIdentifierHelper; +import org.lcsim.detector.DetectorIdentifierHelper.SystemMap; +import org.lcsim.detector.IDetectorElement; +import org.lcsim.detector.IPhysicalVolume; +import org.lcsim.detector.IPhysicalVolumePath; +import org.lcsim.detector.LogicalVolume; +import org.lcsim.detector.PhysicalVolume; +import org.lcsim.detector.RotationGeant; +import org.lcsim.detector.Transform3D; +import org.lcsim.detector.Translation3D; +import org.lcsim.detector.identifier.ExpandedIdentifier; +import org.lcsim.detector.identifier.IExpandedIdentifier; +import org.lcsim.detector.identifier.IIdentifier; +import org.lcsim.detector.identifier.IIdentifierDictionary; +import org.lcsim.detector.identifier.IIdentifierHelper; +import org.lcsim.detector.material.IMaterial; +import org.lcsim.detector.material.MaterialStore; +import org.lcsim.detector.solids.Box; +import org.lcsim.detector.solids.Trd; +import org.lcsim.detector.tracker.silicon.SiSensor; +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.HPSTracker; + +public class HPSTrackerConverter extends AbstractSubdetectorConverter +{ + Map<String, ModuleParameters> moduleParameters = new HashMap<String, ModuleParameters>(); + Map<String, LogicalVolume> modules = new HashMap<String, LogicalVolume>(); + IMaterial vacuum; + + public IIdentifierHelper makeIdentifierHelper(Subdetector subdetector, SystemMap systemMap) + { + return new SiTrackerIdentifierHelper(subdetector.getDetectorElement(), makeIdentifierDictionary(subdetector), systemMap); + } + + public void convert(Subdetector subdet, Detector detector) + { + System.out.println("HPSTrackerConverter: Converting..."); + try + { + Element node = subdet.getNode(); + String subdetName = node.getAttributeValue("name"); + vacuum = MaterialStore.getInstance().get("Air"); + + boolean reflect = true; + if (node.getAttribute("reflect") != null) + { + reflect = node.getAttribute("reflect").getBooleanValue(); + } + + boolean flipSA = false; + if (node.getAttribute("flipSA") != null) + { + flipSA = node.getAttribute("flipSA").getBooleanValue(); + } + + IDetectorElement subdetDetElem = subdet.getDetectorElement(); + DetectorIdentifierHelper helper = (DetectorIdentifierHelper) subdetDetElem.getIdentifierHelper(); + int nfields = helper.getIdentifierDictionary().getNumberOfFields(); + IDetectorElement endcapPos = null; + IDetectorElement endcapNeg = null; + try + { + // Positive endcap DE + IExpandedIdentifier endcapPosId = new ExpandedIdentifier(nfields); + endcapPosId.setValue(helper.getFieldIndex("system"), subdet.getSystemID()); + endcapPosId.setValue(helper.getFieldIndex("barrel"), helper.getBarrelValue()); + endcapPos = new DetectorElement(subdet.getName() + "_positive", subdetDetElem); + endcapPos.setIdentifier(helper.pack(endcapPosId)); + if (reflect) + { + IExpandedIdentifier endcapNegId = new ExpandedIdentifier(nfields); + endcapNegId.setValue(helper.getFieldIndex("system"), subdet.getSystemID()); + endcapNegId.setValue(helper.getFieldIndex("barrel"), helper.getBarrelValue()); + endcapNeg = new DetectorElement(subdet.getName() + "_negative", subdetDetElem); + endcapNeg.setIdentifier(helper.pack(endcapNegId)); + } + } + catch (Exception x) + { + throw new RuntimeException(x); + } + + for (Iterator i = node.getChildren("module").iterator(); i.hasNext();) + { + Element module = (Element) i.next(); + String moduleName = module.getAttributeValue("name"); + moduleParameters.put(moduleName, new ModuleParameters(module)); + modules.put(moduleName, makeModule(moduleParameters.get(moduleName))); + } + + for (Iterator i = node.getChildren("layer").iterator(); i.hasNext();) + { + Element layerElement = (Element) i.next(); + + int layerId = layerElement.getAttribute("id").getIntValue(); + + // Positive endcap layer. + IExpandedIdentifier layerPosId = new ExpandedIdentifier(nfields); + layerPosId.setValue(helper.getFieldIndex("system"), subdet.getSystemID()); + layerPosId.setValue(helper.getFieldIndex("barrel"), helper.getBarrelValue()); + layerPosId.setValue(helper.getFieldIndex("layer"), layerId); + IDetectorElement layerPos = new DetectorElement(endcapPos.getName() + "_layer" + layerId, endcapPos, helper.pack(layerPosId)); + + // Negative endcap layer. + IDetectorElement layerNeg = null; + if (reflect) + { + IExpandedIdentifier layerNegId = new ExpandedIdentifier(nfields); + layerNegId.setValue(helper.getFieldIndex("system"), subdet.getSystemID()); + layerNegId.setValue(helper.getFieldIndex("barrel"), helper.getBarrelValue()); + layerNegId.setValue(helper.getFieldIndex("layer"), layerId); + layerNeg = new DetectorElement(endcapNeg.getName() + "_layer_reflected" + layerId, endcapNeg, helper.pack(layerNegId)); + } + + int moduleNumber = 0; + for (Iterator j = layerElement.getChildren("quadrant").iterator(); j.hasNext();) + { + Element ringElement = (Element) j.next(); + double zLayer = ringElement.getAttribute("z").getDoubleValue(); + double dz = ringElement.getAttribute("dz").getDoubleValue(); + double xStart = ringElement.getAttribute("xStart").getDoubleValue(); + double xStep = ringElement.getAttribute("xStep").getDoubleValue(); + int nx = ringElement.getAttribute("nx").getIntValue(); + double yStart = ringElement.getAttribute("yStart").getDoubleValue(); + int ny = ringElement.getAttribute("ny").getIntValue(); + double yStep = ringElement.getAttribute("yStep").getDoubleValue(); + + double phi0 = 0; + if (ringElement.getAttribute("phi0") != null) + { + phi0 = ringElement.getAttribute("phi0").getDoubleValue(); + } + String module = ringElement.getAttributeValue("module"); + LogicalVolume moduleVolume = modules.get(module); + if (moduleVolume == null) + { + throw new RuntimeException("Module " + module + " was not found."); + } + + ModuleParameters modPars = moduleParameters.get(module); + + double x, y, z; + z = zLayer; + x = xStart; + // System.out.println("Making modules...nx=" + nx + ";ny=" + ny); + for (int k = 0; k < nx; k++ ) + { + y = yStart; + for (int kk = 0; kk < ny; kk++ ) + { + String moduleBaseName = subdetName + "_layer" + layerId + "_module" + moduleNumber; + + // Positive endcap module. + Translation3D p = new Translation3D(x, y, z + dz); + + //RotationGeant rot = new RotationGeant(-Math.PI / 2, Math.PI / 2 + phi0, 0); + RotationGeant rot = new RotationGeant(0, 0, 0); + new PhysicalVolume(new Transform3D(p, rot), moduleBaseName, moduleVolume, detector.getTrackingVolume().getLogicalVolume(), 0); + String path = "/" + detector.getTrackingVolume().getName() + "/" + moduleBaseName; + IDetectorElement modulePos = new SiTrackerModule(moduleBaseName, layerPos, path, moduleNumber); + ++moduleNumber; + + // System.out.println("Making module " + moduleBaseName + " @ " + layerPos.toString()); + if (reflect) + { + Translation3D pr = new Translation3D(x, -y, z + dz); + double rphi0 = phi0; + if (flipSA) + rphi0 = -rphi0; + + //RotationGeant rotr = new RotationGeant(-Math.PI / 2, Math.PI / 2 + rphi0, 0); + RotationGeant rotr = new RotationGeant(0, 0, 0); + + String path2 = "/" + detector.getTrackingVolume().getName() + "/" + moduleBaseName + "_reflected"; + new PhysicalVolume(new Transform3D(pr, rotr), moduleBaseName + "_reflected", moduleVolume, detector.getTrackingVolume().getLogicalVolume(), k); + new SiTrackerModule(moduleBaseName + "_reflected", layerNeg, path2, moduleNumber); + // System.out.println("Making module " + moduleBaseName + " @ " + layerNeg.toString()); + } + + dz = -dz; + y += yStep; + ++moduleNumber; + } + x += xStep; + } + } + } + } + catch (JDOMException except) + { + throw new RuntimeException(except); + } + + // Create DetectorElements for the sensors. + setupSensorDetectorElements(subdet); + } + + private LogicalVolume makeModule(ModuleParameters params) + { + double thickness = params.getThickness(); + double x, y; + x = params.getDimension(0); + y = params.getDimension(1); + + Box box = new Box(params.getName() + "Box", x / 2, y / 2, thickness / 2); + LogicalVolume volume = new LogicalVolume(params.getName() + "Volume", box, vacuum); + makeModuleComponents(volume, params); + return volume; + } + + private void makeModuleComponents(LogicalVolume moduleVolume, ModuleParameters moduleParameters) + { + double moduleX = moduleParameters.getDimension(0); + double moduleY = moduleParameters.getDimension(1); + + Box box = (Box)moduleVolume.getSolid(); + double moduleZ = box.getZHalfLength() * 2; + + double posZ = -moduleZ / 2; + + String moduleName = moduleVolume.getName(); + + int sensor = 0; + for (ModuleComponentParameters component : moduleParameters) + { + double componentThickness = component.getThickness(); + + IMaterial material = MaterialStore.getInstance().get(component.getMaterialName()); + if (material == null) + { + throw new RuntimeException("The material " + component.getMaterialName() + " does not exist in the materials database."); + } + boolean sensitive = component.isSensitive(); + int componentNumber = component.getComponentNumber(); + + posZ += componentThickness / 2; + + String componentName = moduleName + "_component" + componentNumber; + + Box componentBox = new Box(componentName + "Box", moduleX / 2, moduleY / 2, componentThickness / 2); + + LogicalVolume volume = new LogicalVolume(componentName, componentBox, material); + + double zrot = 0; + if (sensitive) + { + if (sensor > 1) + { + throw new RuntimeException("Exceeded maximum of 2 sensors per module."); + } + // Flip 180 deg for 1st sensor. + if (sensor == 0) + { + zrot = Math.PI; + } + ++sensor; + } + Translation3D position = new Translation3D(0., 0., posZ); + RotationGeant rotation = new RotationGeant(0, 0, zrot); + PhysicalVolume pv = new PhysicalVolume(new Transform3D(position, rotation), componentName, volume, moduleVolume, componentNumber); + pv.setSensitive(sensitive); + + posZ += componentThickness / 2; + } + } + + private void setupSensorDetectorElements(Subdetector subdet) + { + SiTrackerIdentifierHelper helper = (SiTrackerIdentifierHelper) subdet.getDetectorElement().getIdentifierHelper(); + + for (IDetectorElement endcap : subdet.getDetectorElement().getChildren()) + { + for (IDetectorElement layer : endcap.getChildren()) + { + for (IDetectorElement module : layer.getChildren()) + { + IPhysicalVolume modulePhysVol = module.getGeometry().getPhysicalVolume(); + IPhysicalVolumePath modulePath = module.getGeometry().getPath(); + int sensorId = 0; + for (IPhysicalVolume pv : modulePhysVol.getLogicalVolume().getDaughters()) + { + if (pv.isSensitive()) + { + IIdentifierDictionary iddict = subdet.getDetectorElement().getIdentifierHelper().getIdentifierDictionary(); + + ExpandedIdentifier expId = new ExpandedIdentifier(iddict.getNumberOfFields()); + expId.setValue(iddict.getFieldIndex("system"), subdet.getSystemID()); + + if (helper.isEndcapPositive(endcap.getIdentifier())) + { + expId.setValue(iddict.getFieldIndex("barrel"), helper.getEndcapPositiveValue()); + } + else if (helper.isEndcapNegative(endcap.getIdentifier())) + { + expId.setValue(iddict.getFieldIndex("barrel"), helper.getEndcapNegativeValue()); + } + else if (helper.isBarrel(endcap.getIdentifier())) + { + expId.setValue(iddict.getFieldIndex("barrel"), helper.getBarrelValue()); + } + else + { + throw new RuntimeException(endcap.getName() + " is not a positive or negative endcap!"); + } + expId.setValue(iddict.getFieldIndex("layer"), layer.getIdentifierHelper().getValue(layer.getIdentifier(), "layer")); + expId.setValue(iddict.getFieldIndex("module"), ((SiTrackerModule) module).getModuleId()); + expId.setValue(iddict.getFieldIndex("sensor"), sensorId); + + IIdentifier id = iddict.pack(expId); + + String sensorPath = modulePath.toString() + "/" + pv.getName(); + String sensorName = module.getName() + "_sensor" + sensorId; + + SiSensor sensor = new SiSensor(sensorId, sensorName, module, sensorPath, id); + + ++sensorId; + } + } + } + } + } + } + + public Class getSubdetectorType() + { + return HPSTracker.class; + } + + static class ModuleComponentParameters + { + protected String materialName; + protected double thickness; + protected boolean sensitive; + protected int componentNumber; + protected String vis; + protected double dimX, dimY; + + public ModuleComponentParameters(double dimX, double dimY, double thickness, String materialName, int componentNumber, boolean sensitive, String vis) + { + this.dimX = dimX; + this.dimY = dimY; + this.thickness = thickness; + this.materialName = materialName; + this.sensitive = sensitive; + this.componentNumber = componentNumber; + this.vis = vis; + } + + public double getThickness() + { + return thickness; + } + + public double getDimensionX() + { + return dimX; + } + + public double getDimensionY() + { + return dimY; + } + + public String getMaterialName() + { + return materialName; + } + + public boolean isSensitive() + { + return sensitive; + } + + public int getComponentNumber() + { + return componentNumber; + } + + public String getVis() + { + return vis; + } + } + + static class ModuleParameters extends ArrayList<ModuleComponentParameters> + { + double thickness; + String name; + double dimensions[] = new double[3]; + String vis; + + public ModuleParameters(Element element) + { + name = element.getAttributeValue("name"); + + if (element.getAttribute("vis") != null) + this.vis = element.getAttribute("vis").getValue(); + + // Optional dimension parameters (not always present). + if (element.getChild("trd") != null) + { + Element trd = element.getChild("trd"); + try + { + dimensions[0] = trd.getAttribute("x1").getDoubleValue(); + dimensions[1] = trd.getAttribute("x2").getDoubleValue(); + dimensions[2] = trd.getAttribute("z").getDoubleValue(); + } + catch (DataConversionException x) + { + throw new RuntimeException(x); + } + } + else if (element.getChild("box") != null) + { + Element box = element.getChild("box"); + try + { + dimensions[0] = box.getAttribute("x").getDoubleValue(); + dimensions[1] = box.getAttribute("y").getDoubleValue(); + } + catch (DataConversionException x) + { + throw new RuntimeException(x); + } + } + + 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(); + String componentVis = null; + if (e.getAttribute("vis") != null) + componentVis = e.getAttribute("vis").getValue(); + + // Sensors may have reduced dimensions for dead area. + double x = dimensions[0]; // default + double y = dimensions[1]; // default + if (sensitive && e.getChild("dimensions") != null) + { + Element dimensions = e.getChild("dimensions"); + x = dimensions.getAttribute("x").getDoubleValue(); + y = dimensions.getAttribute("y").getDoubleValue(); + // System.out.println("x,y="+x+","+y); + } + add(new ModuleComponentParameters(x, y, thickness, materialName, cntr, sensitive, componentVis)); + } + 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; + } + + public String getName() + { + return name; + } + + public double getDimension(int i) + { + if (i > (dimensions.length - 1) || i < 0) + throw new RuntimeException("Invalid dimensions index: " + i); + return dimensions[i]; + } + + public String getVis() + { + return vis; + } + } + +}
Use REPLY-ALL to reply to list
To unsubscribe from the LCD-CVS list, click the following link:
https://listserv.slac.stanford.edu/cgi-bin/wa?SUBED1=LCD-CVS&A=1