GeomConverter/src/org/lcsim/detector/converter/compact
diff -N PolyhedraEndcapCalorimeterConverter.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ PolyhedraEndcapCalorimeterConverter.java 29 Feb 2008 01:09:08 -0000 1.1
@@ -0,0 +1,290 @@
+package org.lcsim.detector.converter.compact;
+
+import static java.lang.Math.tan;
+
+import java.util.Iterator;
+
+import org.jdom.Attribute;
+import org.jdom.Element;
+import org.lcsim.detector.DetectorElement;
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.ILogicalVolume;
+import org.lcsim.detector.IPhysicalVolume;
+import org.lcsim.detector.IRotation3D;
+import org.lcsim.detector.ITranslation3D;
+import org.lcsim.detector.LogicalVolume;
+import org.lcsim.detector.PhysicalVolume;
+import org.lcsim.detector.RotationPassiveXYZ;
+import org.lcsim.detector.Transform3D;
+import org.lcsim.detector.Translation3D;
+import org.lcsim.detector.material.IMaterial;
+import org.lcsim.detector.material.MaterialStore;
+import org.lcsim.detector.solids.Trd;
+import org.lcsim.geometry.compact.Detector;
+import org.lcsim.geometry.compact.Subdetector;
+import org.lcsim.geometry.layer.LayerStack;
+import org.lcsim.geometry.subdetector.PolyhedraEndcapCalorimeter;
+
+public class PolyhedraEndcapCalorimeterConverter
+extends AbstractSubdetectorConverter
+{
+ public void convert(Subdetector subdet, Detector detector)
+ {
+ Element node = subdet.getNode();
+
+ String detName = node.getAttributeValue("name");
+
+ Element dimensions = node.getChild("dimensions");
+ double zmin, rmin, rmax;
+ int numsides;
+
+ try {
+ zmin = dimensions.getAttribute("zmin").getDoubleValue();
+ rmin = dimensions.getAttribute("rmin").getDoubleValue();
+ rmax = dimensions.getAttribute("rmax").getDoubleValue();
+ numsides = dimensions.getAttribute("numsides").getIntValue();
+ }
+ catch (Exception x)
+ {
+ throw new RuntimeException(x);
+ }
+
+ double subdetectorThickness;
+ try {
+ subdetectorThickness = org.lcsim.geometry.layer.LayerFromCompactCnv.computeDetectorTotalThickness(node);
+ }
+ catch (Exception x)
+ {
+ throw new RuntimeException(x);
+ }
+
+ double innerAngle = Math.PI * 2 / numsides;
+ double halfInnerAngle = innerAngle/2;
+ double innerFaceLength = rmin * tan(halfInnerAngle) * 2;
+ double outerFaceLength = rmax * tan(halfInnerAngle) * 2;
+ double radialThickness = rmax - rmin;
+
+ Trd sectTrd =
+ new Trd(detName + "_stave_trapezoid",
+ innerFaceLength/2,
+ outerFaceLength/2,
+ subdetectorThickness/2,
+ subdetectorThickness/2,
+ radialThickness/2);
+
+ IMaterial air = MaterialStore.getInstance().get("Air");
+
+ ILogicalVolume sectVolume = new LogicalVolume(detName + "_stave", sectTrd, air);
+
+ LayerStack layers = subdet.getLayering().getLayerStack();
+
+ int layer_number = 0;
+ double layer_position_y = subdetectorThickness / 2;
+
+ for (Iterator i = node.getChildren("layer").iterator(); i.hasNext();)
+ {
+ Element layer_element = (Element) i.next();
+
+ int repeat;
+ try {
+ repeat = layer_element.getAttribute("repeat").getIntValue();
+ }
+ catch (Exception x)
+ {
+ throw new RuntimeException(x);
+ }
+
+ 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;
+
+ Translation3D layer_position = new Translation3D(0,layer_position_y,0);
+
+ double layerInnerFaceLength = innerFaceLength;//-LAYER_ENVELOPE_TOLERANCE;
+ double layerOuterFaceLength = outerFaceLength;//-LAYER_ENVELOPE_TOLERANCE;
+ double layerRadialThickness = radialThickness;//-LAYER_ENVELOPE_TOLERANCE;
+
+ // Layer trapezoid.
+ Trd layer_trd = new Trd(
+ layer_name + "_trapezoid",
+ layerInnerFaceLength,
+ layerOuterFaceLength,
+ layer_thickness,
+ layer_thickness,
+ layerRadialThickness);
+
+ ILogicalVolume layer_volume =
+ new LogicalVolume(
+ layer_name,
+ layer_trd,
+ 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 = false;
+ try {
+ sensitive = s != null && s.getBooleanValue();
+ }
+ catch (Exception x)
+ {
+ throw new RuntimeException(x);
+ }
+
+ double slice_thickness;
+ try {
+ slice_thickness = slice_element.getAttribute("thickness").getDoubleValue();
+ }
+ catch (Exception x)
+ {
+ throw new RuntimeException(x);
+ }
+
+ // Apply tolerance factor to given slice thickness.
+ //slice_thickness -= SLICE_TOLERANCE;
+
+ slice_position_y -= slice_thickness / 2;
+
+ Translation3D slicePosition = new Translation3D(0,slice_position_y,0);
+
+ double sliceInnerFaceLength = layerInnerFaceLength;// - SLICE_ENVELOPE_TOLERANCE;
+ double sliceOuterFaceLength = layerOuterFaceLength;// - SLICE_ENVELOPE_TOLERANCE;
+ double sliceRadialThickness = layerRadialThickness;// - SLICE_ENVELOPE_TOLERANCE;
+
+ Trd sliceTrd = new Trd(
+ slice_name + "_trapezoid",
+ sliceInnerFaceLength/2,
+ sliceOuterFaceLength/2,
+ slice_thickness/2,
+ slice_thickness/2,
+ sliceRadialThickness/2);
+
+ ILogicalVolume sliceVolume =
+ new LogicalVolume(
+ slice_name,
+ sliceTrd,
+ MaterialStore.getInstance().get(slice_element.getAttributeValue("material")));
+
+ PhysicalVolume slicePhysVol =
+ new PhysicalVolume(
+ new Transform3D(slicePosition),
+ slice_name,
+ sliceVolume,
+ layer_volume,
+ 0);
+
+ if (sensitive) slicePhysVol.setSensitive(true);
+
+ // The slice thickness is the original, NOT adjusted for tolerance,
+ // so that the center of the slice is in the right place with tolerance
+ // gaps on either side.
+ slice_position_y -= slice_thickness / 2;
+
+ // Increment the slice counter.
+ ++slice_number;
+ }
+
+ new PhysicalVolume(
+ new Transform3D(layer_position),
+ layer_name,
+ layer_volume,
+ sectVolume,
+ 0);
+
+ layer_position_y -= layer_thickness / 2;
+
+ // DEBUG
+ //layer_position_y -= INTER_LAYER_GAP;
+
+ ++layer_number;
+ }
+ // DEBUG - Uncomment to build only one layer.
+ //break;
+ }
+
+
+ ILogicalVolume motherVolume = detector.getDetectorElement().getGeometry().getLogicalVolume();
+
+ double sectCenter = rmin + radialThickness / 2;
+ double sectZ = zmin + subdetectorThickness / 2;
+
+ for ( int i=0; i < numsides; i++)
+ {
+ double phi = 2*Math.PI*((double)i)/numsides;
+ double zc = -phi + Math.PI/2;
+ double x = sectCenter*Math.cos(phi);
+ double y = sectCenter*Math.sin(phi);
+
+ ITranslation3D position = new Translation3D(x,y,sectZ);
+ IRotation3D rotation = new RotationPassiveXYZ(Math.PI/2, 0, zc);
+
+ IPhysicalVolume sectPhysVol =
+ new PhysicalVolume(
+ new Transform3D(position, rotation),
+ detName + "_stave_positive" + i,
+ sectVolume,
+ motherVolume,
+ 0);
+
+ new DetectorElement(sectPhysVol.getName(), subdet.getDetectorElement(), "/" + sectPhysVol.getName());
+
+ boolean reflect;
+ try {
+ reflect = node.getAttribute("reflect").getBooleanValue();
+ }
+ catch (Exception t)
+ {
+ throw new RuntimeException(t);
+ }
+
+ if (reflect)
+ {
+ IRotation3D reflectRotation = new RotationPassiveXYZ(-Math.PI/2, 0, zc);
+ ITranslation3D reflectPosition = new Translation3D(-x, -y, -zmin - subdetectorThickness/2);
+
+ IPhysicalVolume physVolReflect =
+ new PhysicalVolume(
+ new Transform3D(reflectPosition, reflectRotation),
+ detName + "_stave_reflect" + i,
+ sectVolume,
+ motherVolume,
+ 0);
+
+ new DetectorElement(physVolReflect.getName(), subdet.getDetectorElement(), "/" + physVolReflect.getName());
+ }
+ }
+
+ for (IDetectorElement module : subdet.getDetectorElement().getChildren())
+ {
+ for (IPhysicalVolume layer : module.getGeometry().getLogicalVolume().getDaughters())
+ {
+ for (IPhysicalVolume slice : layer.getLogicalVolume().getDaughters())
+ {
+ if (slice.isSensitive())
+ {
+ String sliceDetElemName = module.getName() + "_" + layer.getName() + "_" + slice.getName();
+ new DetectorElement(
+ sliceDetElemName,
+ module,
+ "/" + module.getGeometry().getPhysicalVolume().getName() + "/" + layer.getName() + "/" + slice.getName());
+ }
+ }
+ }
+ }
+ }
+
+ public Class getSubdetectorType()
+ {
+ return PolyhedraEndcapCalorimeter.class;
+ }
+}
GeomConverter/src/org/lcsim/detector/converter/compact
diff -u -r1.37 -r1.38
--- DetectorConverter.java 15 Feb 2008 02:14:51 -0000 1.37
+++ DetectorConverter.java 29 Feb 2008 01:09:08 -0000 1.38
@@ -91,6 +91,7 @@
addSubdetectorConverter( new PolyconeSupportConverter() );
addSubdetectorConverter( new SiTrackerEndcapConverter() );
addSubdetectorConverter( new PolyhedraBarrelCalorimeterConverter() );
+ addSubdetectorConverter( new PolyhedraEndcapCalorimeterConverter() );
}
private void addSubdetectorConverter(ISubdetectorConverter s)
GeomConverter/src/org/lcsim/geometry/subdetector
diff -u -r1.7 -r1.8
--- PolyhedraEndcapCalorimeter.java 14 Sep 2007 23:57:09 -0000 1.7
+++ PolyhedraEndcapCalorimeter.java 29 Feb 2008 01:09:08 -0000 1.8
@@ -8,6 +8,8 @@
import org.jdom.Element;
import org.jdom.JDOMException;
+import org.lcsim.detector.converter.heprep.DetectorElementToHepRepConverter;
+
import hep.graphics.heprep.HepRep;
import hep.graphics.heprep.HepRepFactory;
import hep.graphics.heprep.HepRepInstance;
@@ -59,6 +61,12 @@
public void appendHepRep(HepRepFactory factory, HepRep heprep)
{
+ DetectorElementToHepRepConverter.convert(getDetectorElement(), factory, heprep, 0, -1);
+ }
+
+ /*
+ public void appendHepRep(HepRepFactory factory, HepRep heprep)
+ {
HepRepInstanceTree instanceTree = heprep.getInstanceTreeTop("Detector","1.0");
HepRepTypeTree typeTree = heprep.getTypeTree("DetectorType","1.0");
HepRepType barrel = typeTree.getType("Endcap");
@@ -130,6 +138,7 @@
flip = -1;
}
}
+*/
public boolean isEndcap()
{
GeomConverter/test/org/lcsim/geometry/subdetector
diff -u -r1.2 -r1.3
--- PolyhedraEndcapCalorimeterTest.java 16 May 2007 23:27:38 -0000 1.2
+++ PolyhedraEndcapCalorimeterTest.java 29 Feb 2008 01:09:08 -0000 1.3
@@ -3,8 +3,11 @@
import java.io.InputStream;
import junit.framework.TestCase;
import junit.framework.TestSuite;
+
+import org.lcsim.detector.converter.heprep.DetectorElementToHepRepConverter;
import org.lcsim.geometry.GeometryReader;
import org.lcsim.geometry.compact.Detector;
+import org.lcsim.util.test.TestUtil.TestOutputFile;
/**
*
@@ -42,7 +45,8 @@
return new TestSuite(PolyhedraEndcapCalorimeterTest.class);
}
- public void test_PolyhedraEndcapCalorimeter()
+ public void testHepRep() throws Exception
{
+ DetectorElementToHepRepConverter.writeHepRep(new TestOutputFile("PolyhedraEndcapCalorimeterTest.heprep").getAbsolutePath());
}
}
\ No newline at end of file