GeomConverter/src/org/lcsim/geometry/compact/converter/lcdd
diff -N HPSEcal.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ HPSEcal.java 13 Apr 2011 00:13:10 -0000 1.1
@@ -0,0 +1,137 @@
+package org.lcsim.geometry.compact.converter.lcdd;
+
+import static java.lang.Math.atan;
+import static java.lang.Math.cos;
+import static java.lang.Math.sin;
+import static java.lang.Math.tan;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.lcsim.geometry.compact.converter.lcdd.util.Define;
+import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
+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.Trapezoid;
+import org.lcsim.geometry.compact.converter.lcdd.util.Volume;
+
+/**
+ * LCDD model for the HPS inner ECal.
+ *
+ * The dimensions element defines x1, x2, y1, y2, and z as half the full dimension.
+ *
+ * The layout element defines the placement of the crystals. The beamgap defines the
+ * offset from the beamline in the Y coordinate, in the natural Geant4 coordinate system.
+ * The nx attribute defines the number of crystals in the X coordinate. The ny attribute
+ * defines the number of crystals in Y, on each side of the beamline.
+ *
+ * @author Jeremy McCormick
+ * @version $Id: HPSEcal.java,v 1.1 2011/04/13 00:13:10 jeremy Exp $
+ */
+public class HPSEcal extends LCDDSubdetector
+{
+ HPSEcal(Element node) throws JDOMException
+ {
+ super(node);
+ }
+
+ /* (non-Javadoc)
+ * @see org.lcsim.geometry.compact.converter.lcdd.LCDDSubdetector#addToLCDD(org.lcsim.geometry.compact.converter.lcdd.util.LCDD, org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector)
+ */
+ void addToLCDD(LCDD lcdd, SensitiveDetector sens) throws JDOMException
+ {
+ // Get the half-dimensions of the calorimeter crystal.
+ Element dimensions = node.getChild("dimensions");
+ double dx1 = dimensions.getAttribute("x1").getDoubleValue();
+ double dx2 = dimensions.getAttribute("x2").getDoubleValue();
+ double dy1 = dimensions.getAttribute("y1").getDoubleValue();
+ double dy2 = dimensions.getAttribute("y2").getDoubleValue();
+ double dz = dimensions.getAttribute("z").getDoubleValue();
+
+ System.out.println("x1="+dx1);
+ System.out.println("x2="+dx2);
+ System.out.println("y1="+dy1);
+ System.out.println("y2="+dy2);
+ System.out.println("z="+dz);
+
+ Element mat = node.getChild("material");
+ String materialName = mat.getAttributeValue("name");
+
+ Element layout = node.getChild("layout");
+ double beamgap = layout.getAttribute("beamgap").getDoubleValue();
+ int nx = layout.getAttribute("nx").getIntValue();
+ int ny = layout.getAttribute("ny").getIntValue();
+
+ System.out.println("beamgap="+beamgap);
+ System.out.println("nx="+nx);
+ System.out.println("ny="+ny);
+
+ Trapezoid crystalTrap = new Trapezoid("crystal_trap", dx1, dx2, dy1, dy2, dz);
+ Volume crystalLogVol = new Volume("crystal_volume", crystalTrap, lcdd.getMaterial(materialName));
+
+ lcdd.add(crystalTrap);
+ lcdd.add(crystalLogVol);
+
+ Define define = lcdd.getDefine();
+ Volume mother = lcdd.pickMotherVolume(this);
+
+ // Slope of the trapezoid side in X.
+ double s = (dx2-dx1)/(2*dz);
+
+ // Angle of the side of the trapezoid w.r.t. center line in X. Rotation about Y axis.
+ double dthetay = atan(s);
+
+ // Distance between (virtual) angular origin and center of trapezoid.
+ double z0 = dx1/s+dz;
+
+ // Always 0. (no rotation about Z)
+ double thetaz = 0;
+
+ //boolean evenx = (nx % 2 == 0);
+ boolean oddx = (nx % 2 != 0);
+
+ if (!oddx)
+ throw new RuntimeException("No soup for you!");
+
+ double thetax = 0;
+ double ycenter = 0;
+ double zcorrtot = 0;
+ double xcorrtot = 0;
+
+ for (int ix=0; ix<nx; ix++)
+ {
+ System.out.println("ix="+ix);
+
+ double thetay = 2*ix*dthetay;
+ double zcorr = dx1*(sin(2*ix*dthetay)+sin(2*(ix-1)*dthetay));
+ double xcorr = zcorr*tan((2*ix-1)*dthetay);
+ double xcenter = z0*sin(2*ix*dthetay)+xcorr+xcorrtot;
+ double zcenter = z0*(1-cos(2*ix*dthetay))+zcorr+zcorrtot;
+
+ System.out.println("xcorr="+xcorr);
+ System.out.println("xcorrtot="+xcorrtot);
+ System.out.println("xcenter="+xcenter);
+ System.out.println("zcenter="+zcenter);
+ System.out.println("zcorr="+zcorr);
+ System.out.println("zcorrtot="+zcorrtot);
+ System.out.println("thetay="+thetay);
+ System.out.println();
+
+ Position ipos =
+ new Position("crystal"+ix+"_pos", xcenter, ycenter, zcenter);
+ Rotation irot =
+ new Rotation("crystal"+ix+"_rot", thetax, -thetay, thetaz);
+
+ define.addPosition(ipos);
+ define.addRotation(irot);
+
+ // Place crystal.
+ PhysVol crystalPlacement = new PhysVol(crystalLogVol, mother, ipos, irot);
+
+ // Increment running X and Z totals.
+ xcorrtot += xcorr;
+ zcorrtot += zcorr;
+ }
+ }
+}
\ No newline at end of file