GeomConverter/src/org/lcsim/geometry/compact/converter/lcdd
diff -u -r1.14 -r1.15
--- EcalBarrel.java 19 Oct 2006 02:09:31 -0000 1.14
+++ EcalBarrel.java 26 Oct 2006 18:56:22 -0000 1.15
@@ -35,12 +35,20 @@
* that is similar to the "ecal02" subdetector in the Mokka database.
*
* @author Jeremy McCormick <[log in to unmask]>
- * @version $Id: EcalBarrel.java,v 1.14 2006/10/19 02:09:31 jeremy Exp $
+ * @version $Id: EcalBarrel.java,v 1.15 2006/10/26 18:56:22 jeremy Exp $
*/
public class EcalBarrel extends LCDDSubdetector
{
- // change to true if debugging this component
+ // Change to true if debugging.
private boolean _debug = false;
+
+ // 1 micron adjustment for geometric tolerances.
+ // This is used to downsize the stave. It is
+ // also applied to the box dimensions of the
+ // layers and slices. Because these are half
+ // measurements it results in a 2 micron tolerance
+ // for these components.
+ private double tolerance=0.001;
EcalBarrel(Element node) throws JDOMException
{
@@ -50,103 +58,107 @@
/** Add the EcalBarrel geometry to an LCDD instance. */
public void addToLCDD(LCDD lcdd, SensitiveDetector sens)
throws JDOMException
- {
+ {
+ // Get the define block of LCDD.
Define define = lcdd.getDefine();
+ // The name of the detector.
+ String name = node.getAttributeValue("name");
+
+ // The subdetector ID.
int id = node.getAttribute("id").getIntValue();
- // dimensions element
+ // Dimensions element.
Element dimensions = node.getChild("dimensions");
- // check required attributes
+ // Check for required attributes.
assert (dimensions != null);
assert (dimensions.getAttribute("numsides") != null);
assert (dimensions.getAttribute("rmin") != null);
assert (dimensions.getAttribute("z") != null);
- // number of sides
+ // Number of sides.
int nsides = dimensions.getAttribute("numsides").getIntValue();
- // inner radius to first surface of module
+ // Inner radius to front surface of barrel stave.
double inner_radius = dimensions.getAttribute("rmin")
.getDoubleValue();
-
- // module Z dimension, corresponding to Z of subdetector
+
+ // The stave's Z dimension, which sets the Z of the subdetector.
double module_y1 = dimensions.getAttribute("z").getDoubleValue();
double module_y2 = module_y1;
- // delta phi per module
+ // Compute the delta phi per section.
double dphi = PI * 2.0 / nsides;
double hphi = dphi / 2;
- // thickness of the subdetector
+ // Compute the total thickness of the subdetector.
double module_z = LayerFromCompactCnv
.computeDetectorTotalThickness(node);
- // center Y coord of a single module, untransformed
+ // Compute the center Y offset of a single module.
double module_y_offset = inner_radius + module_z / 2;
- // mother volume
+ // Get the mother volume.
Volume motherVolume = lcdd.pickMotherVolume(this);
-
- // name of the detector
- String name = node.getAttributeValue("name");
double totalThickness = org.lcsim.geometry.layer.LayerFromCompactCnv.computeDetectorTotalThickness(node);
- /* envelope volume */
+ // Create the polyhedra envelope for the subdetector.
PolyhedraRegular polyhedra = new PolyhedraRegular(
name + "_polyhedra",
- nsides, inner_radius, inner_radius+totalThickness, module_y1);
+ nsides, inner_radius, inner_radius+totalThickness+tolerance*2.0, module_y1);
lcdd.getSolids().addSolid(polyhedra);
+ // Create the volume for the envelope.
Volume envelopeVolume = new Volume(name + "_envelope");
envelopeVolume.setSolid(polyhedra);
Material air = lcdd.getMaterial("Air");
envelopeVolume.setMaterial(air);
- /* polyhedra rotation so it lays "flat" */
+ // Set the rotation to make a side lay "flat".
double zrot = Math.PI / nsides;
Rotation rot = new Rotation(name + "_rotation");
rot.setZ(zrot);
define.addRotation(rot);
+ // Create the physical volume of the subdetector.
PhysVol envelopePhysvol = new PhysVol(envelopeVolume);
envelopePhysvol.setRotation(rot);
envelopePhysvol.addPhysVolID("system",id);
envelopePhysvol.addPhysVolID("barrel",0);
- motherVolume.addPhysVol(envelopePhysvol);
+ motherVolume.addPhysVol(envelopePhysvol);
- // outer radius, which is really just inner_radius + thickness
+ // Compute the outer radius.
double outer_radius = inner_radius + module_z;
- // partial trapezoid measurements
+ // Compute trapezoid measurements.
double bo = tan(hphi) * outer_radius;
double bi = tan(hphi) * inner_radius;
- // double cz = module_z / ( cos(hphi));
- // side triangle calculations to get dx (from Norman)
+ // Compute the dx per layer, using side
+ // triangle calculations (from Norman Graf).
double gamma = (PI * 2) / nsides;
double dx = module_z / sin(gamma);
- // offset of a module derived from the dx term
+ // The offset of a stave, derived from the dx term.
double module_x_offset = dx / 2.0;
- // primary top and bottom face measurements of the trapezoid
+ // Compute the top and bottom face measurements.
double module_x2 = 2 * bo - dx;
double module_x1 = 2 * bi + dx;
-
- // trapezoid for the module
+
+ // Create the trapezoid for the stave.
Trapezoid module_trd = LCDDFactory.createTrapezoid(
- name + "_module_trd", module_x1, // outer side, the "short" X
- // side
- module_x2, // inner side, the "long" X side
- module_y1, // corresponds to subdetector (or module) Z
- module_y2, // ditto
- module_z); // thickness (in Y for top module, when it is reoriented)
+ name + "_module_trd",
+ module_x1-tolerance, // Outer side, i.e. the "short" X side.
+ module_x2-tolerance, // Inner side, i.e. the "long" X side.
+ module_y1-tolerance, // Corresponds to subdetector (or module) Z.
+ module_y2-tolerance, // "
+ module_z-tolerance); // Thickness, in Y for top stave, when rotated.
lcdd.add(module_trd);
- // logical volume for the module
+ // Create the logical volume for the stave.
Volume module_volume = LCDDFactory.createVolume(name + "_module", lcdd
.getMaterial("Air"), module_trd);
@@ -168,7 +180,7 @@
System.out.println("");
}
- // build the stave logical volume
+ // Build the stave logical volume.
try
{
buildBarrelStave(lcdd, this, sens, module_volume);
@@ -180,41 +192,49 @@
setVisAttributes(lcdd, node, module_volume);
- // add the module volume to LCDD
+ // Add the stave volume to LCDD.
lcdd.add(module_volume);
- // phi start for a module
+ // Phi start for a stave.
double phi = ((PI) / nsides);
-
- // make nsides modules
+
+ // Create nsides staves.
for (int i = 0; i < nsides; i++)
- {
- // add one to counter so module numbers are always positive
- int module_number = i + 1;
+ {
+ // Module number.
+ int module_number = i;
- // rotation of this module
+ // Rotation of the module.
Rotation rotation = LCDDFactory.createRotation(name + "_module"
+ module_number + "_rotation", PI * 0.5, phi, 0);
lcdd.add(rotation);
- // XY position calculation from Mokka's Geometry/Tesla/Ecal02.cc
- Position position = LCDDFactory.createPosition(name + "_module"
- + module_number + "_position", module_x_offset * cos(phi)
- - module_y_offset * sin(phi), module_x_offset * sin(phi)
- + module_y_offset * cos(phi), 0);
+ // Compute the stave position; derived from calculations in Mokka
+ // Geometry/Tesla/Ecal02.cc
+ double module_position_x = module_x_offset * cos(phi) - module_y_offset * sin(phi);
+ double module_position_y = module_x_offset * sin(phi) + module_y_offset * cos(phi);
+ double module_position_z = 0;
+
+ Position position = LCDDFactory.createPosition(
+ name + "_module" + module_number + "_position",
+ module_position_x, module_position_y, module_position_z);
lcdd.add(position);
- // place this module
+ // Place this module.
PhysVol pv = LCDDFactory.createPhysVol(module_volume, position,
rotation, null);
pv.addPhysVolID("module", module_number);
- //motherVolume.addPhysVol(pv);
+ // FIXME: put these ids on subdetector envelope when have it
+ pv.addPhysVolID("system", node.getAttribute("id").getIntValue());
+ pv.addPhysVolID("barrel", 0);
+
envelopeVolume.addPhysVol(pv);
// increment phi
- phi += dphi;
+ phi += dphi;
}
+
// Set region, limitset, and vis.
setVisAttributes(lcdd, node, envelopeVolume);
@@ -251,7 +271,10 @@
double z = trd.y1();
double trd_z = trd.z();
- // Parameters for computing the layer X dimension or trapezoid's X1 value.
+ // ------
+ // Parameters for computing the layer X dimension,
+ // e.g. trapezoid's X1 value.
+ // ------
// Adjacent angle of triangle.
double adj = (trd.x1() - trd.x2()) / 2;
@@ -279,7 +302,7 @@
double hphi = dphi / 2;
// Starting X dimension for the layer.
- double layer_dim_x = trd.x1();
+ double layer_dim_x = trd.x1();
if (_debug)
{
@@ -324,10 +347,12 @@
// Compute the X dimension for this layer.
double xcut = (layer_thickness / tan_beta) * 2;
layer_dim_x -= xcut;
-
- // Box of the layer.
+
+ // Box of the layer.
Box layer_box = LCDDFactory.createBox(layer_name + "_box",
- layer_dim_x, z, layer_thickness);
+ layer_dim_x - tolerance,
+ z - tolerance,
+ layer_thickness - tolerance);
lcdd.add(layer_box);
// Volume of the layer.
@@ -362,7 +387,9 @@
// Box of slice.
Box slice_box = LCDDFactory.createBox(slice_name + "_box",
- layer_dim_x, z, slice_thickness);
+ layer_dim_x - tolerance,
+ z - tolerance,
+ slice_thickness - tolerance);
lcdd.add(slice_box);
GeomConverter/src/org/lcsim/geometry/compact/converter/lcdd
diff -u -r1.11 -r1.12
--- PolyhedraEndcapCalorimeter.java 17 Oct 2006 23:45:03 -0000 1.11
+++ PolyhedraEndcapCalorimeter.java 26 Oct 2006 18:56:23 -0000 1.12
@@ -34,194 +34,193 @@
public class PolyhedraEndcapCalorimeter extends LCDDSubdetector
{
private Element node;
+
+ // 25 micron tolerance for staves and layers.
+ double tolerance=0.025;
+ // 1 micron tolerance between sublayers.
+ double slice_tolerance=0.001;
+
public PolyhedraEndcapCalorimeter(Element node) throws JDOMException
{
super(node);
this.node = node;
}
-
+
public void addToLCDD(LCDD lcdd, SensitiveDetector sens) throws JDOMException
{
if ( sens == null)
{
throw new IllegalArgumentException("PolyhedraBarrelCalorimeter <" + getName() + " has null SD.");
}
-
+
// Get important LCDD objects.
Solids solids = lcdd.getSolids();
Structure structure = lcdd.getStructure();
Volume motherVolume = lcdd.pickMotherVolume(this);
Material air = lcdd.getMaterial("Air");
Define define = lcdd.getDefine();
-
+
// Subdetector name and ID.
String detName = node.getAttributeValue("name");
int id = node.getAttribute("id").getIntValue();
-
+
// Subdetector envelope dimensions.
Element dimensions = node.getChild("dimensions");
double zmin = dimensions.getAttribute("zmin").getDoubleValue();
double rmin = dimensions.getAttribute("rmin").getDoubleValue();
double rmax = dimensions.getAttribute("rmax").getDoubleValue();
int numsides = dimensions.getAttribute("numsides").getIntValue();
-
+
// Rotation of polyhedra into correct frame.
double zrot = Math.PI / numsides;
Rotation envelopeRotation = new Rotation(detName + "_rotation");
envelopeRotation.setZ(zrot);
define.addRotation(envelopeRotation);
-
+
// Total thickness of the subdetector.
double subdetector_thickness = org.lcsim.geometry.layer.LayerFromCompactCnv.computeDetectorTotalThickness(node);
- //double zmax = zmin + layersThickness;
double radial_thickness = rmax - rmin;
double detZ = subdetector_thickness;
-
+
// The detector envelope volume.
PolyhedraRegular polyhedra = new PolyhedraRegular(
detName + "_polyhedra",
numsides, rmin, rmax, detZ);
solids.addSolid(polyhedra);
-
+
Volume envelopeVolume = new Volume(detName + "_envelope");
envelopeVolume.setSolid(polyhedra);
envelopeVolume.setMaterial(air);
-
+
// The stave's trapezoid.
double innerAngle = Math.PI * 2 / numsides;
double halfInnerAngle = innerAngle/2;
-
- Trapezoid sectTrd = new Trapezoid(detName + "_stave_trapezoid");
- sectTrd.setY2(subdetector_thickness);
- sectTrd.setY1(subdetector_thickness);
- sectTrd.setZ(radial_thickness);
-
double innerFaceLength = rmin * tan(halfInnerAngle) * 2;
- sectTrd.setX1(innerFaceLength);
double outerFaceLength = rmax * tan(halfInnerAngle) * 2;
- sectTrd.setX2(outerFaceLength);
-
+
+ Trapezoid sectTrd = new Trapezoid(detName + "_stave_trapezoid");
+ sectTrd.setY2(subdetector_thickness - tolerance);
+ sectTrd.setY1(subdetector_thickness - tolerance);
+ sectTrd.setZ(radial_thickness - tolerance);
+ sectTrd.setX1(innerFaceLength - tolerance);
+ sectTrd.setX2(outerFaceLength - tolerance);
+
solids.addSolid(sectTrd);
Volume sectVolume = new Volume(detName + "_stave");
sectVolume.setMaterial(air);
sectVolume.setSolid(sectTrd);
-
- /* build the box layers in the stave */
- //double layerOuterAngle = (PI - innerAngle) / 2;
- //double layerInnerAngle = (PI/2 - layerOuterAngle);
-
+
LayerStack layers = Layering.makeLayering(this.node).getLayerStack();
-
+
// Build the layers.
int layer_number = 0;
double layer_position_y = subdetector_thickness / 2;
for (Iterator i = node.getChildren("layer").iterator(); i.hasNext();)
{
Element layer_element = (Element) i.next();
-
+
int repeat = layer_element.getAttribute("repeat").getIntValue();
-
+
for ( int j=0; j<repeat; j++)
{
String layer_name = detName + "_stave_layer" + layer_number;;
-
+
double layer_thickness = layers.getLayer(layer_number).getThickness();
-
+
layer_position_y -= layer_thickness / 2;
-
+
// Layer position.
Position layer_position = new Position(layer_name + "_position");
layer_position.setY(layer_position_y);
define.addPosition(layer_position);
-
+
// Layer trapezoid.
Trapezoid layer_trd = new Trapezoid(layer_name + "_trapezoid");
- layer_trd.setX1(innerFaceLength);
- layer_trd.setX2(outerFaceLength);
- layer_trd.setY1(layer_thickness);
- layer_trd.setY2(layer_thickness);
- layer_trd.setZ(radial_thickness);
+ layer_trd.setX1(innerFaceLength - tolerance);
+ layer_trd.setX2(outerFaceLength - tolerance);
+ layer_trd.setY1(layer_thickness - tolerance);
+ layer_trd.setY2(layer_thickness - tolerance);
+ layer_trd.setZ(radial_thickness - tolerance);
solids.addSolid(layer_trd);
-
+
Volume layer_volume = new Volume(layer_name);
layer_volume.setSolid(layer_trd);
layer_volume.setMaterial(lcdd.getMaterial("Air"));
-
+
int slice_number = 0;
double slice_position_y = layer_thickness / 2;
for ( Iterator k = layer_element.getChildren("slice").iterator(); k.hasNext();)
{
Element slice_element = (Element)k.next();
-
+
String slice_name = layer_name + "_slice" + slice_number;
-
+
Attribute s = slice_element.getAttribute("sensitive");
boolean sensitive = s != null && s.getBooleanValue();
double slice_thickness = slice_element.getAttribute("thickness").getDoubleValue();
slice_position_y -= slice_thickness / 2;
-
+
Position slicePosition = new Position(slice_name + "_position");
slicePosition.setY(slice_position_y);
define.addPosition(slicePosition);
Trapezoid sliceTrd = new Trapezoid(slice_name + "_trapezoid");
- sliceTrd.setX1(innerFaceLength);
- sliceTrd.setX2(outerFaceLength);
- sliceTrd.setY1(slice_thickness);
- sliceTrd.setY2(slice_thickness);
- sliceTrd.setZ(radial_thickness);
+ sliceTrd.setX1(innerFaceLength - tolerance);
+ sliceTrd.setX2(outerFaceLength - tolerance);
+ sliceTrd.setY1(slice_thickness - slice_tolerance);
+ sliceTrd.setY2(slice_thickness - slice_tolerance);
+ sliceTrd.setZ(radial_thickness - tolerance);
solids.addSolid(sliceTrd);
-
+
Volume sliceVolume = new Volume(slice_name);
sliceVolume.setSolid(sliceTrd);
Material sliceMaterial = lcdd.getMaterial(slice_element.getAttributeValue("material"));
sliceVolume.setMaterial(sliceMaterial);
- if ( sensitive ) sliceVolume.setSensitiveDetector(sens);
-
+ if ( sensitive ) sliceVolume.setSensitiveDetector(sens);
+
setRegion(lcdd, slice_element, sliceVolume);
- setLimitSet(lcdd, slice_element, sliceVolume);
-
+ setLimitSet(lcdd, slice_element, sliceVolume);
+
setVisAttributes(lcdd, node, sliceVolume);
- structure.addVolume(sliceVolume);
-
+ structure.addVolume(sliceVolume);
+
PhysVol slicePhysVol = new PhysVol(sliceVolume);
slicePhysVol.setPosition(slicePosition);
slicePhysVol.addPhysVolID("slice", slice_number);
layer_volume.addPhysVol(slicePhysVol);
-
+
slice_position_y -= slice_thickness / 2;
-
- ++slice_number;
+
+ ++slice_number;
}
-
+
lcdd.add(layer_volume);
-
+
setRegion(lcdd, layer_element, layer_volume);
- setLimitSet(lcdd, layer_element, layer_volume);
- setVisAttributes(lcdd, node, layer_volume);
-
+ setLimitSet(lcdd, layer_element, layer_volume);
+ setVisAttributes(lcdd, node, layer_volume);
+
PhysVol layer_physvol = new PhysVol(layer_volume);
layer_physvol.setPosition(layer_position);
layer_physvol.addPhysVolID("layer", layer_number);
sectVolume.addPhysVol(layer_physvol);
-
+
layer_position_y -= layer_thickness / 2;
-
- ++layer_number;
+
+ ++layer_number;
}
}
-
+
// Add the section volume after layers created.
setVisAttributes(lcdd, node, sectVolume);
structure.addVolume(sectVolume);
-
+
// Place the sections.
double innerRotation = innerAngle;
double offsetRotation = -innerRotation / 2;
- //double placementRotation = -offsetRotation;
-
+
double sectCenterRadius = rmin + radial_thickness / 2;
double rotY = -offsetRotation;
double rotX = PI / 2;
@@ -230,40 +229,40 @@
for ( int i=0; i < numsides; i++)
{
int moduleNumber=i;
-
+
Position position = new Position(detName + "_stave0_module" + moduleNumber + "_position");
position.setX(posX);
position.setY(sectPosY);
-
+
Rotation rotation = new Rotation(detName + "_stave0_module" + moduleNumber + "_rotation");
rotation.setX(rotX);
rotation.setY(rotY);
-
+
define.addPosition(position);
define.addRotation(rotation);
-
+
PhysVol sectPhysVol = new PhysVol(sectVolume);
sectPhysVol.setPosition(position);
sectPhysVol.setRotation(rotation);
-
+
envelopeVolume.addPhysVol(sectPhysVol);
sectPhysVol.addPhysVolID("stave",0);
sectPhysVol.addPhysVolID("module",moduleNumber);
-
+
rotY -= innerRotation;
posX = -sectCenterRadius * sin(rotY);
sectPosY = sectCenterRadius * cos(rotY);
}
-
+
// Place the subdetector envelope.
PhysVol envelopePhysvol = new PhysVol(envelopeVolume);
envelopePhysvol.setZ(zmin + subdetector_thickness/2);
envelopePhysvol.addPhysVolID("system",id);
envelopePhysvol.setRotation(envelopeRotation);
envelopePhysvol.addPhysVolID("barrel",1);
-
+
motherVolume.addPhysVol(envelopePhysvol);
-
+
// Place the reflected subdetector envelope.
boolean reflect = node.getAttribute("reflect").getBooleanValue();
if (reflect)
@@ -272,7 +271,7 @@
envelopeRotationReflect.setX(Math.PI);
envelopeRotationReflect.setZ(zrot);
define.addRotation(envelopeRotationReflect);
-
+
PhysVol physvol2 = new PhysVol(envelopeVolume);
physvol2.setZ(-zmin-subdetector_thickness/2);
physvol2.setRotation(envelopeRotationReflect);
@@ -280,14 +279,14 @@
physvol2.addPhysVolID("barrel",2);
motherVolume.addPhysVol(physvol2);
}
-
+
// Add the envelope volume to LCDD once staves are all created.
setVisAttributes(lcdd, node, envelopeVolume);
structure.addVolume(envelopeVolume);
}
-
+
public boolean isCalorimeter()
{
return true;
}
-}
\ No newline at end of file
+}