GeomConverter/src/org/lcsim/geometry/compact/converter/lcdd
diff -u -r1.8 -r1.9
--- HPSEcal.java 14 Apr 2011 22:15:46 -0000 1.8
+++ HPSEcal.java 22 Apr 2011 01:06:23 -0000 1.9
@@ -20,21 +20,27 @@
/**
* LCDD model for the HPS inner ECal.
*
- * The dimensions element defines x1, x2, y1, y2, and z as half the full dimension of a crystal.
+ * Coordinate System Notes:
*
- * 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. For example, to
- * get 4 rows of crystals in Y, then ny would be 2.
+ * Beam travels in +X direction.
+ * Magnetic field is -Z (????).
+ * Y is the bend plane.
*
- * The position element has a z attribute that defines the distance from the origin
- * to the front face of the crystal array.
+ * The dimensions element defines the crystal HALF dimensions: x1, x2, y1, y2, and z.
+ *
+ * The layout element defines the placement of the crystals.
+ *
+ * <ul>
+ * <li>beamgap - offset from the beamline in the Y coordinate</li>
+ * <li>nx - number of crystals in X</li>
+ * <li>ny - number of crystals in Y along each side of beam</li>
+ * <li>dface - distance from origin to the face of the calorimeter along X</li>
+ * </ul>
*
* @author Jeremy McCormick
* @author Tim Nelson
*
- * @version $Id: HPSEcal.java,v 1.8 2011/04/14 22:15:46 jeremy Exp $
+ * @version $Id: HPSEcal.java,v 1.9 2011/04/22 01:06:23 jeremy Exp $
*/
public class HPSEcal extends LCDDSubdetector
{
@@ -51,42 +57,36 @@
void addToLCDD(LCDD lcdd, SensitiveDetector sens) throws JDOMException
{
- // Get the half-dimensions of the calorimeter crystal.
+ if (sens == null)
+ throw new RuntimeException("SensitiveDetector is null!");
+
+ // Crystal dimensions.
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);
-
+
+ // Crystal material.
Element mat = node.getChild("material");
String materialName = mat.getAttributeValue("name");
+ // Layout parameters.
Element layout = node.getChild("layout");
double beamgap = layout.getAttribute("beamgap").getDoubleValue();
int nx = layout.getAttribute("nx").getIntValue();
int ny = layout.getAttribute("ny").getIntValue();
double dface = layout.getAttribute("dface").getDoubleValue();
-
- System.out.println("beamgap="+beamgap);
- System.out.println("nx="+nx);
- System.out.println("ny="+ny);
- System.out.println("dface="+dface);
-
+
+ // Setup crystal logical volume.
Trapezoid crystalTrap = new Trapezoid("crystal_trap", dx1, dx2, dy1, dy2, dz);
Volume crystalLogVol = new Volume("crystal_volume", crystalTrap, lcdd.getMaterial(materialName));
+ crystalLogVol.setSensitiveDetector(sens);
lcdd.add(crystalTrap);
lcdd.add(crystalLogVol);
-
- Define define = lcdd.getDefine();
-
+
// Mother volume dimensions.
double mx, my, mz;
double margin = 1.1;
@@ -94,10 +94,9 @@
my = ny*Math.max(dy2, dy1)*margin;
mz = dz*margin;
- // Envelope box and logical volume for one section (upper and lower each use this for placement).
- // TODO Turn off visualization of envelope vol. Set daughters visible.
+ // Envelope box and logical volume for one section of ECal.
Box momBox = new Box("mom_box", mx*2, my*2, mz*2);
- Volume momVol = new Volume("mom_volume", momBox, lcdd.getMaterial("Air"));
+ Volume momVol = new Volume("mom_volume", momBox, lcdd.getMaterial("Air"));
lcdd.add(momBox);
lcdd.add(momVol);
@@ -136,7 +135,8 @@
double ycorrtot = 0;
double zcorrtoty = 0;
- //double fudgeFactor = .01;
+
+ Define define = lcdd.getDefine();
for (int iy=1; iy<=ny; iy++)
{
@@ -151,19 +151,20 @@
for (int ix=0; ix<=nx; ix++)
{
- // Factor for even/odd.
+ // Coefficient for even/odd crystal
int coeffx = 2*ix;
if (!oddx)
{
coeffx -= 1;
+ // For even number of crystals, the 0th is skipped.
if (ix==0)
continue;
}
+ // Set parameters for next crystal placement.
+ // FIXME Need documentation here.
double thetay = coeffx*dthetay;
double zcorrx = dx1*(2*sin(coeffx*dthetay));
- // NOTE Center point of trap front face along line instead of edge.
- // double zcorr = dx1*(sin(2*ix*dthetay))+sin(2*(ix-1)*dthetay));
double xcorr = zcorrx*tan((coeffx-1)*dthetay);
double xcenter = z0x*sin(coeffx*dthetay)+xcorr+xcorrtot+(crystalTolerance*ix);
double zcenter = z0y*(cos(coeffy*dthetax)-1)+z0x*(cos(coeffx*dthetay)-1)+zcorrx+zcorrtotx+zcorry+zcorrtoty;
@@ -173,6 +174,7 @@
String baseName = "crystal"+ix+"-"+iy;
+ // Transform of positive.
Position ipos =
new Position(baseName+"_pos_pos", xcenter, ycenter-my+tolerance, zcenter-mz+tolerance);
Rotation irot =
@@ -181,13 +183,17 @@
define.addPosition(ipos);
define.addRotation(irot);
- // Place crystal.
+ // Place positive crystal.
PhysVol posCrystalPlacement = new PhysVol(crystalLogVol, momVol, ipos, irot);
- // TODO Add PhysVolID.
+
+ // Add volume IDs.
+ posCrystalPlacement.addPhysVolID("ix", ix);
+ posCrystalPlacement.addPhysVolID("iy", iy);
- // Reflection to negative.
+ // Reflection to negative.
if (ix != 0)
{
+ // Transform of negative.
Position iposneg =
new Position(baseName+"_pos_neg", -xcenter, ycenter-my+tolerance, zcenter-mz+tolerance);
Rotation irotneg =
@@ -196,8 +202,12 @@
define.addPosition(iposneg);
define.addRotation(irotneg);
+ // Place negative crystal.
PhysVol negCrystalPlacement = new PhysVol(crystalLogVol, momVol, iposneg, irotneg);
- // TODO Add PhysVolID.
+
+ // Add volume IDs.
+ negCrystalPlacement.addPhysVolID("ix", ix);
+ negCrystalPlacement.addPhysVolID("iy", iy);
}
// Increment running X and Z totals and include tolerance to avoid overlaps.
@@ -218,13 +228,25 @@
Rotation mrottop = new Rotation(momVol.getVolumeName() + "_top_rot", 0, -Math.PI/2, (3*Math.PI)/2);
define.addPosition(mpostop);
define.addRotation(mrottop);
- new PhysVol(momVol, world, mpostop, mrottop);
-
+ PhysVol topSide = new PhysVol(momVol, world, mpostop, mrottop);
+ topSide.addPhysVolID("system", this.getSystemID());
+ topSide.addPhysVolID("side", 1);
+
// Place the bottom section.
Position mposbot = new Position(momVol.getVolumeName() + "_bot_pos", dface+mz, 0, -my-beamgap);
Rotation mrotbot = new Rotation(momVol.getVolumeName() + "_bot_rot", 0, -Math.PI/2, Math.PI/2);
define.addPosition(mposbot);
define.addRotation(mrotbot);
- new PhysVol(momVol, world, mposbot, mrotbot);
+ PhysVol botSide = new PhysVol(momVol, world, mposbot, mrotbot);
+ botSide.addPhysVolID("system", this.getSystemID());
+ botSide.addPhysVolID("side", -1);
+
+ // Make the section box invisible.
+ momVol.setVisAttributes(lcdd.getVisAttributes("InvisibleWithDaughters"));
+ }
+
+ public boolean isCalorimeter()
+ {
+ return true;
}
}
\ No newline at end of file