Commit in GeomConverter/src/org/lcsim/geometry/compact/converter/lcdd on MAIN | |||
HPSTracker.java | +462 | added 1.1 |
LCDD for new HPS tracker module geometry
diff -N HPSTracker.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ HPSTracker.java 11 Jan 2012 23:12:04 -0000 1.1 @@ -0,0 +1,462 @@
+package org.lcsim.geometry.compact.converter.lcdd; + +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.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.Volume; + +/** + * An LCDD converter for a Silicon endcap tracker model based on Bill Cooper's design from + * <a href="http://ilcagenda.linearcollider.org/materialDisplay.py?contribId=58&sessionId=1&materialId=slides&confId=2784">Boulder SiD Workshop 2008</a>. + * + * @author jeremym + */ +public class HPSTracker extends LCDDSubdetector { + + Map<String, ModuleParameters> moduleParameters = new HashMap<String, ModuleParameters>(); + Map<String, Volume> modules = new HashMap<String, Volume>(); + Material vacuum; + //static VisAttributes blah = null; + + public HPSTracker(Element node) throws JDOMException + { + super(node); + } + + void addToLCDD(LCDD lcdd, SensitiveDetector sd) throws JDOMException + { + // DEBUG + //blah = new VisAttributes("TkrTestVisXYZ"); + //blah.setColor((float)1.0,(float)0.,(float)0.,(float)1.0); + //lcdd.add(blah); + ///////////////////// + + int sysId = node.getAttribute("id").getIntValue(); + String subdetName = node.getAttributeValue("name"); + vacuum = lcdd.getMaterial("Vacuum"); + boolean reflect; + + if (node.getAttribute("reflect") != null) { + reflect = node.getAttribute("reflect").getBooleanValue(); + } else { + reflect = true; + } + + boolean flipSA=false; + if ( node.getAttribute( "flipSA" ) != null ) + { + flipSA = node.getAttribute( "flipSA" ).getBooleanValue(); + } + + 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), sd, lcdd)); + } + + for (Iterator i = node.getChildren("layer").iterator(); i.hasNext();) { + + Element layerElement = (Element) i.next(); + int layerId = layerElement.getAttribute("id").getIntValue(); + int ringCount = 0; + 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"); + + Volume moduleVolume = modules.get(module); + if (moduleVolume == null) { + throw new RuntimeException("Module " + module + " was not found."); + } + + double x, y, z; + z = zLayer; + x = xStart; + + for (int k = 0; k < nx; k++) { + y = yStart; + for (int kk = 0; kk < ny; kk++) { + String moduleBaseName = subdetName + "_layer" + layerId + "_module" + moduleNumber; + + Position p = new Position(moduleBaseName + "_position"); + + p.setX(x); + p.setY(y); + p.setZ(z+ dz); + Rotation rot = new Rotation(moduleBaseName + "_rotation"); + rot.setX(-Math.PI / 2); + rot.setY(Math.PI / 2+phi0); + rot.setZ(0); + + lcdd.add(p); + lcdd.add(rot); + + PhysVol pv = new PhysVol(moduleVolume, lcdd.getTrackingVolume(), p, rot); + pv.addPhysVolID("system", sysId); + + pv.addPhysVolID("barrel", 0); + pv.addPhysVolID("layer", layerId); + pv.addPhysVolID("module", moduleNumber); + ++moduleNumber; + if (reflect) { + Position pr = new Position(moduleBaseName + "_reflect_position"); + pr.setX(x); + pr.setY(-y); + pr.setZ(z + dz); + Rotation rotr = new Rotation(moduleBaseName + "_reflect_rotation"); + double rphi0=phi0; + if(flipSA) rphi0=-rphi0; + rotr.setX(-Math.PI / 2); + rotr.setY(Math.PI / 2+rphi0); + rotr.setZ(0); + + lcdd.add(pr); + lcdd.add(rotr); + + //System.out.println("Reflecting "+ x+" "+y+" "+z); + PhysVol pvr = new PhysVol(moduleVolume, lcdd.getTrackingVolume(), pr, rotr); + pvr.addPhysVolID("system", sysId); + pvr.addPhysVolID("barrel", 0); + pvr.addPhysVolID("layer", layerId); + pvr.addPhysVolID("module", moduleNumber); + + } + dz = -dz; + y += yStep; + ++moduleNumber; + } + x += xStep; + } + } + } + } + + private Volume makeModule(ModuleParameters params, SensitiveDetector sd, LCDD lcdd) + { + double thickness = params.getThickness(); + double x, y; + x = params.getDimension(0); + y = params.getDimension(1); + + Box box = new Box(params.getName() + "Box", x, y, thickness); + lcdd.add(box); + + Volume moduleVolume = new Volume(params.getName() + "Volume", box, vacuum); + makeModuleComponents(moduleVolume, params, sd, lcdd); + //moduleVolume.setVisAttributes(blah); + lcdd.add(moduleVolume); + + if (params.getVis() != null) { + moduleVolume.setVisAttributes(lcdd.getVisAttributes(params.getVis())); + } + + return moduleVolume; + } + + private void makeModuleComponents( + Volume moduleVolume, + ModuleParameters moduleParameters, + SensitiveDetector sd, + LCDD lcdd) + { + Box envelope = (Box) lcdd.getSolid(moduleVolume.getSolidRef()); + + double moduleX = envelope.getX(); + double moduleY = envelope.getY(); + + //System.out.println("moduleX="+moduleX); + //System.out.println("moduleY="+moduleY); + + double posZ = -moduleParameters.getThickness() / 2; + + String moduleName = moduleVolume.getVolumeName(); + + int sensor = 0; + for (ModuleComponentParameters component : moduleParameters) { + //System.out.println("making component..."); + + double thickness = component.getThickness(); + + Material material = null; + try { + material = lcdd.getMaterial(component.getMaterialName()); + } catch (JDOMException except) { + throw new RuntimeException(except); + } + boolean sensitive = component.isSensitive(); + int componentNumber = component.getComponentNumber(); + + posZ += thickness / 2; + + //System.out.println("posY="+posY); + + String componentName = moduleName + "_component" + componentNumber; + + //System.out.println("componentBox = " + moduleX + ", " + moduleY + "," + thickness); + Box componentBox = new Box(componentName + "Box", moduleX, moduleY, thickness); + lcdd.add(componentBox); + + Volume componentVolume = new Volume(componentName, componentBox, material); + + Position position = new Position(componentName + "_position", 0., 0., posZ); + lcdd.add(position); + Rotation rotation = new Rotation(componentName + "_rotation"); + lcdd.add(rotation); + + PhysVol pv = new PhysVol(componentVolume, moduleVolume, position, rotation); + pv.addPhysVolID("component", componentNumber); + + if (sensitive) { + if (sensor > 1) { + throw new RuntimeException("Maximum of 2 sensors per module."); + } + + // Build an child sensor volume to allow dead areas. + + String sensorName = componentName + "Sensor" + sensor; + + double sensorX = component.getDimensionX(); + //System.out.println("sensorX="+sensorX); + if (sensorX > moduleX) + throw new RuntimeException("Sensor X dimension " + sensorX + " is too big for module."); + + double sensorY = component.getDimensionY(); + //System.out.println("sensorY="+sensorY); + if (sensorY > moduleY) + throw new RuntimeException("Sensor Y dimension " + sensorY + " is too big for module."); + + //System.out.println("sensorBox = "+sensorX+", " + sensorY + ", " + thickness); + Box sensorBox = new Box(sensorName + "Box", sensorX, sensorY, thickness); + lcdd.add(sensorBox); + + Volume sensorVol = new Volume(sensorName, sensorBox, material); + sensorVol.setSensitiveDetector(sd); + //sensorVol.setVisAttributes(blah); + lcdd.add(sensorVol); + + Position sensorPosition = new Position(sensorName+"Position",0,0,0); + lcdd.add(sensorPosition); + Rotation sensorRotation = new Rotation(sensorName+"Rotation",0,0,0); + lcdd.add(sensorRotation); + + PhysVol sensorPhysVol = new PhysVol(sensorVol, componentVolume, sensorPosition, sensorRotation); + sensorPhysVol.addPhysVolID("sensor", sensor); + + ++sensor; + } + + // Add component volume after (possible) sensor child volume. + lcdd.add(componentVolume); + + // Set vis attributes of component. + if (component.getVis() != null) { + componentVolume.setVisAttributes(lcdd.getVisAttributes(component.getVis())); + } + + // Step to next component placement position. + posZ += thickness / 2; + } + } + + public boolean isTracker() + { + return true; + } + + 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