GeomConverter/src/org/lcsim/geometry/compact/converter/lcdd
diff -N SiTrackerEndcap.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ SiTrackerEndcap.java 25 Oct 2007 20:07:11 -0000 1.1
@@ -0,0 +1,377 @@
+package org.lcsim.geometry.compact.converter.lcdd;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.Trap;
+import org.lcsim.geometry.compact.converter.lcdd.util.Trapezoid;
+import org.lcsim.geometry.compact.converter.lcdd.util.Tube;
+import org.lcsim.geometry.compact.converter.lcdd.util.Volume;
+
+public class SiTrackerEndcap
+extends LCDDSubdetector
+{
+ public SiTrackerEndcap(Element node) throws JDOMException
+ {
+ super(node);
+ }
+
+ public void addToLCDD(LCDD lcdd, SensitiveDetector sens) throws JDOMException
+ {
+ 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);
+ }
+
+ String subdetName = node.getAttributeValue("name");
+
+ String layerName = subdetName + "_layer" + layerN;
+
+ Volume layerVolume = makeLayer(node, layerElement, layerN, innerR, outerR, thickness, nwedges, lcdd);
+
+ lcdd.add(layerVolume);
+
+ Rotation rotation = new Rotation(layerName + "_rotation");
+ Position position = new Position(layerName + "_position");
+ double layerZ = innerZ + thickness/2;
+ position.setZ(layerZ);
+
+ lcdd.add(rotation);
+ lcdd.add(position);
+
+ PhysVol layerPV = new PhysVol(layerVolume, lcdd.getTrackingVolume(), position, rotation);
+
+ // DEBUG
+ break;
+ }
+ }
+
+ private Volume makeLayer(
+ Element subdetElement,
+ Element layerElement,
+ int layerN,
+ double innerR,
+ double outerR,
+ double thickness,
+ int nwedges,
+ LCDD lcdd)
+ {
+ double dphi = Math.PI / nwedges;
+
+ String subdetName = subdetElement.getAttributeValue("name");
+
+ String layerName = subdetName + "_layer" + layerN;
+
+ double tubeInnerR, tubeOuterR;
+ tubeInnerR = innerR;
+ tubeOuterR = outerR / Math.cos(dphi);
+
+ Tube layerTube = new Tube(layerName + "_tube", tubeInnerR, tubeOuterR, thickness/2);
+
+ lcdd.add(layerTube);
+
+ Material material;
+ try {
+ material = lcdd.getMaterial("Air");
+ }
+ catch (JDOMException x)
+ {
+ throw new RuntimeException(x);
+ }
+
+ Volume layerLV = new Volume(layerName, layerTube, material);
+
+ Volume wedgeLV = makeWedge(subdetElement, layerElement, innerR, outerR, thickness, nwedges, layerN, lcdd);
+
+ lcdd.add(wedgeLV);
+
+ double r = (innerR + outerR) / 2;
+ String wedgeName = wedgeLV.getVolumeName();
+ 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);
+
+ Position p = new Position(wedgeName + i + "_position");
+ p.setX(x);
+ p.setY(y);
+ Rotation rot = new Rotation(wedgeName + i + "_rotation");
+ rot.setX(-Math.PI/2);
+ rot.setY(Math.PI/2 - phi);
+
+ lcdd.add(p);
+ lcdd.add(rot);
+
+ new PhysVol(wedgeLV, layerLV, p, rot);
+
+ // DEBUG
+ break;
+ }
+
+ return layerLV;
+ }
+
+ Volume makeWedge(Element subdetElement, Element layerElement, double innerR, double outerR, double thickness, int nwedges, int layerN, LCDD lcdd)
+ {
+ Material material;
+ try
+ {
+ material = lcdd.getMaterial("Air");
+ }
+ catch (JDOMException x)
+ {
+ throw new RuntimeException(x);
+ }
+
+ String subdetName = subdetElement.getAttributeValue("name");
+ String name = subdetName + "_layer" + layerN + "_wedge";
+
+ double dz = (outerR - innerR) / 2;
+ double dy1, dy2;
+ dy1 = dy2 = thickness / 2;
+ double dx1, dx2;
+ double dphi = Math.PI / nwedges;
+ dx1 = outerR * Math.tan(dphi);
+ dx2 = innerR * Math.tan(dphi);
+
+ Trapezoid wedgeTrd = new Trapezoid(name + "_trapezoid",dx1*2,dx2*2,dy1*2,dy2*2,dz*2);
+
+ lcdd.add(wedgeTrd);
+
+ Volume wedgeLV = new Volume(name, wedgeTrd, material);
+
+ makeModules(subdetElement, wedgeLV, layerElement.getChild("module_parameters"), layerN, lcdd);
+
+ return wedgeLV;
+ }
+
+ private void makeModules(Element subdetElement, Volume wedgeLV, Element moduleElement, int layerN, LCDD lcdd)
+ {
+ 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);
+ }
+
+ Trapezoid moduleTrd = (Trapezoid)lcdd.getSolid(wedgeLV.getSolidRef());
+ double dz = moduleTrd.z();
+ double dx1 = moduleTrd.x1();
+ double dx2 = moduleTrd.x2();
+ double dy = moduleTrd.y1();
+ double deltax = dx1 - dx2;
+ 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 = dx2 + side_slope*(zmax+dz);
+ double xsize2 = dx2 + side_slope*(zmin+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 = dx2 + side_slope*(zmax+dz);
+ double xsize2 = dx2 + side_slope*(zmin+dz);
+ xsizes1.add(xsize1);
+ xsizes2.add(xsize2);
+ }
+
+ Material sliceMaterial;
+ try
+ {
+ sliceMaterial = lcdd.getMaterial("Air");
+ }
+ catch (JDOMException x)
+ {
+ throw new RuntimeException(x);
+ }
+
+ 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++)
+ {
+ System.out.println(ibox);
+
+ double xcenter = (xmin+xmax)/2;
+ xmin += 2*xsize_box;
+ xmax += 2*xsize_box;
+
+ String sliceName = subdetElement.getAttributeValue("name") + "_layer" + layerN + "_module" + imodule;
+
+ Box sliceBox = new Box(sliceName + "_box");
+ sliceBox.setX(xsize_box);
+ sliceBox.setY(dy);
+ sliceBox.setZ(zsizes.get(i));
+
+ Volume sliceLV = new Volume(sliceName, sliceBox, sliceMaterial);
+
+ Position p = new Position(sliceName + "_position");
+ lcdd.add(p);
+ Rotation rot = new Rotation(sliceName + "_rotation");
+ lcdd.add(rot);
+
+ new PhysVol(
+ sliceLV,
+ wedgeLV,
+ p,
+ rot);
+
+ imodule++;
+ }
+
+
+ // Small symmetric trapezoids
+ if (ntraps == 1)
+ {
+ String sliceName = subdetElement.getAttributeValue("name") + "_layer" + layerN + "_module" + imodule;
+
+ Trapezoid sliceTrd = new Trapezoid(sliceName+"_trapezoid", xsizes1.get(i), xsizes2.get(i), dy, dy, zsizes.get(i));
+ lcdd.add(sliceTrd);
+
+ Volume sliceLV = new Volume(sliceName, sliceTrd, sliceMaterial);
+ lcdd.add(sliceLV);
+
+ //Transform3D trans = new Transform3D(new Translation3D(0,0,zcenters.get(i)));
+ Position p = new Position(sliceName + "_position");
+ p.setZ(zcenters.get(i)/2);
+ lcdd.add(p);
+
+ Rotation rot = new Rotation(sliceName + "_rotation");
+ lcdd.add(rot);
+
+ new PhysVol(
+ sliceLV,
+ wedgeLV,
+ p,
+ rot);
+
+ 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 = subdetElement.getAttributeValue("name") + "_layer" + layerN + "_module" + imodule;
+
+ Trap sliceTrap = new Trap(sliceName+"_trap",zsizes.get(i),theta*ix,0.0,dy,xsize2,xsize2,0.0,dy,xsize1,xsize1,0.0);
+ lcdd.add(sliceTrap);
+
+ Volume sliceLV = new Volume(sliceName, sliceTrap, sliceMaterial);
+ lcdd.add(sliceLV);
+
+ Position p = new Position(sliceName + "_position");
+ p.setX(ix*xcenter);
+ p.setZ(zcenters.get(i));
+ lcdd.add(p);
+ Rotation rot = new Rotation(sliceName + "_rotation");
+ lcdd.add(rot);
+
+ new PhysVol(
+ sliceLV,
+ wedgeLV,
+ p,
+ rot);
+
+ imodule++;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file