GeomConverter/src/org/lcsim/geometry/compact/converter/lcdd
diff -u -r1.2 -r1.3
--- PolyhedraEndcapCalorimeter3.java 21 Sep 2010 18:48:16 -0000 1.2
+++ PolyhedraEndcapCalorimeter3.java 21 Sep 2010 21:59:58 -0000 1.3
@@ -1,6 +1,6 @@
/**
* @author Jeremy McCormick <[log in to unmask]>
- * @version $Id: PolyhedraEndcapCalorimeter3.java,v 1.2 2010/09/21 18:48:16 jeremy Exp $
+ * @version $Id: PolyhedraEndcapCalorimeter3.java,v 1.3 2010/09/21 21:59:58 jeremy Exp $
*/
package org.lcsim.geometry.compact.converter.lcdd;
@@ -23,6 +23,10 @@
import org.lcsim.geometry.layer.LayerStack;
import org.lcsim.geometry.layer.Layering;
+/**
+ * This class implements the LCDD binding for a calorimeter with a cone hollow section,
+ * e.g. for Muon Collider calorimeter designs.
+ */
public class PolyhedraEndcapCalorimeter3 extends LCDDSubdetector
{
public PolyhedraEndcapCalorimeter3(Element node) throws JDOMException
@@ -32,17 +36,18 @@
}
public void addToLCDD(LCDD lcdd, SensitiveDetector sens) throws JDOMException
- {
+ {
+ // Get important references from LCDD.
Solids solids = lcdd.getSolids();
Structure structure = lcdd.getStructure();
Volume motherVolume = lcdd.pickMotherVolume(this);
Material air = lcdd.getMaterial("Air");
- Define define = lcdd.getDefine();
- Rotation identityRotation = define.getRotation("identity_rot");
+ // Get subdetector name and id.
String subdetectorName = node.getAttributeValue("name");
int id = node.getAttribute("id").getIntValue();
+ // Get the basic parameters from the XML.
Element dimensions = node.getChild("dimensions");
double zmin = dimensions.getAttribute("zmin").getDoubleValue();
double rmin = dimensions.getAttribute("rmin").getDoubleValue();
@@ -50,24 +55,14 @@
int numsides = dimensions.getAttribute("numsides").getIntValue();
double innerAngle = dimensions.getAttribute("angle").getDoubleValue();
- //System.out.println("detector...");
- //System.out.println("rmin = " + rmin);
- //System.out.println("rmax = " + rmax);
- //System.out.println("angle = " + innerAngle);
-
// Make layering to get thickness.
- // FIXME: This should happen automatically.
LayerStack layers = Layering.makeLayering(this.node).getLayerStack();
+ // Get thickness of calorimeter in z dimension determined by layering.
double thickness = layers.getTotalThickness();
-
- //System.out.println("thickness="+thickness);
-
+
// Compute radius at last zplane of envelope.
- double r3 = thickness * Math.tan(innerAngle);
-
- //System.out.println("r3="+r3);
- //System.out.println();
+ double r3 = thickness * Math.tan(innerAngle);
// Setup envelope volume so that rmin increases along +z.
ArrayList<ZPlane> zplanes = new ArrayList<ZPlane>();
@@ -78,39 +73,36 @@
Polyhedra envelopePolyhedra = new Polyhedra(
subdetectorName + "_envelope_polyhedra",
numsides,
- zplanes);
-
+ zplanes);
solids.addSolid(envelopePolyhedra);
- Volume envelopeVolume = new Volume(subdetectorName + "_volume", envelopePolyhedra, air);
- // Orientation of polyhedras with flat side down.
- double zrot = Math.PI / numsides;
+ // Make the calorimeter envelope volume.
+ Volume envelopeVolume = new Volume(subdetectorName + "_volume", envelopePolyhedra, air);
- // The absolute z coordinate of the layer front face.
+ // Compute z rotation for envelope with flat side down.
+ double moduleInnerAngle = (Math.PI * 2) / numsides;
+ double leftover = (Math.PI / 2) % moduleInnerAngle;
+ double zrot = moduleInnerAngle / 2 - leftover;
+
+ // Set the absolute z coordinate of the layer front face for layer loop.
double layerZ = zmin;
// The rmin of the layer which will decrease along z.
double layerRmin = rmin;
- // Loop over layers.
+ // Loop over and build the layers into the detector envelope.
for (int i=0, l=layers.getNumberOfLayers(); i<l; i++)
- {
- //System.out.println("layer" + i);
- //System.out.println(" zmin = " + layerZ);
-
+ {
// Get this layer's thickness.
double layerThickness = layers.getLayer(i).getThickness();
- //System.out.println(" layerThickness = " + layerThickness);
-
- // Increment inner radius by dx as rmin of layer increases along z.
+ // Compute change in layer inner radius.
double layerdx = Math.tan(innerAngle) * layerThickness;
- layerRmin += layerdx;
- //System.out.println(" dx = " + layerdx);
- //System.out.println(" rmin = " + layerRmin);
-
- // Make layer polyhedra.
+ // Add dx to inner radius.
+ layerRmin += layerdx;
+
+ // Make the layer's polyhedra.
ArrayList<ZPlane> layerZplanes = new ArrayList<ZPlane>();
ZPlane layerFrontZPlane = new ZPlane(layerRmin, rmax, layerZ);
ZPlane layerBackZPlane = new ZPlane(layerRmin, rmax, layerZ + layerThickness);
@@ -128,13 +120,15 @@
Volume layerVolume =
new Volume(subdetectorName + "_layer" + i + "_volume", layerPolyhedra, air);
- // Build slices in the layer.
+ // Build slices into the layer volume.
double sliceZ = layerZ;
int sliceCount = 0;
for (LayerSlice slice : layers.getLayer(i).getSlices())
{
+ // Get the slice's thickness.
double sliceThickness = slice.getThickness();
+ // Make the slice's polyhedra shape.
ArrayList<ZPlane> sliceZplanes = new ArrayList<ZPlane>();
ZPlane sliceFrontZPlane = new ZPlane(layerRmin, rmax, sliceZ);
ZPlane sliceBackZPlane = new ZPlane(layerRmin, rmax, sliceZ + sliceThickness);
@@ -157,8 +151,13 @@
lcdd.getMaterial(slice.getMaterial().getName()));
structure.addContent(sliceVolume);
+ // Set slice volume's sensitive detector.
+ if (slice.isSensitive())
+ sliceVolume.setSensitiveDetector(sens);
+
// Make slice physical volume.
PhysVol slicePhysVol = new PhysVol(sliceVolume);
+ slicePhysVol.addPhysVolID("slice", sliceCount);
// Add slice physical volume to layer.
layerVolume.addPhysVol(slicePhysVol);
@@ -175,7 +174,8 @@
// Make layer placement into envelope.
PhysVol layerPhysVol = new PhysVol(layerVolume);
- envelopeVolume.addPhysVol(layerPhysVol);
+ layerPhysVol.addPhysVolID("layer", i);
+ envelopeVolume.addPhysVol(layerPhysVol);
// Set z to edge of next layer.
layerZ += layerThickness;
@@ -209,4 +209,9 @@
endcapNegativePhysVol.setRotation(negativeEndcapRotation);
motherVolume.addPhysVol(endcapNegativePhysVol);
}
+
+ public boolean isCalorimeter()
+ {
+ return true;
+ }
}
\ No newline at end of file