GeomConverter/src/org/lcsim/geometry/compact/converter/lcdd
diff -u -r1.12 -r1.13
--- SiTrackerEndcap.java 5 May 2008 20:43:22 -0000 1.12
+++ SiTrackerEndcap.java 5 May 2008 21:25:19 -0000 1.13
@@ -9,7 +9,6 @@
import org.jdom.DataConversionException;
import org.jdom.Element;
import org.jdom.JDOMException;
-import org.lcsim.detector.solids.GeomOp3D;
import org.lcsim.geometry.compact.converter.lcdd.util.Box;
import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
import org.lcsim.geometry.compact.converter.lcdd.util.Material;
@@ -26,23 +25,23 @@
{
Map<String,ModuleParameters> moduleParameters = new HashMap<String,ModuleParameters>();
SensitiveDetector sd = null;
-
+
public SiTrackerEndcap(Element node) throws JDOMException
{
super(node);
}
-
+
public void addToLCDD(LCDD lcdd, SensitiveDetector sens) throws JDOMException
- {
+ {
if (sens == null)
throw new RuntimeException("SD is null");
-
+
this.sd = sens;
for (Object n : node.getChildren("module"))
{
- Element e = (Element)n;
- moduleParameters.put(e.getAttributeValue("name"), new ModuleParameters(e));
+ Element e = (Element)n;
+ moduleParameters.put(e.getAttributeValue("name"), new ModuleParameters(e));
}
int sysId = node.getAttribute("id").getIntValue();
@@ -50,8 +49,8 @@
for (Object o : node.getChildren("layer"))
{
- Element layerElement = (Element)o;
-
+ Element layerElement = (Element)o;
+
int nwedges;
try
{
@@ -61,7 +60,7 @@
{
throw new RuntimeException(x);
}
-
+
double innerR, outerR, innerZ, thickness;
int layerN;
try
@@ -70,33 +69,33 @@
innerR = layerElement.getAttribute("inner_r").getDoubleValue();
outerR = layerElement.getAttribute("outer_r").getDoubleValue();
innerZ = layerElement.getAttribute("inner_z").getDoubleValue();
- thickness = layerElement.getAttribute("thickness").getDoubleValue();
+ thickness = layerElement.getAttribute("thickness").getDoubleValue();
}
catch (DataConversionException x)
{
throw new RuntimeException(x);
- }
-
+ }
+
String layerName = subdetName + "_layer" + layerN;
-
+
Volume layerVolume = makeLayer(node, layerElement, layerN, innerR, outerR, thickness, nwedges, lcdd);
-
+
lcdd.add(layerVolume);
-
+
Rotation rotation = new Rotation(layerName + "_rotation");
Position position = new Position(layerName + "_position");
double layerZ = innerZ + thickness/2;
position.setZ(layerZ);
-
+
lcdd.add(rotation);
lcdd.add(position);
-
+
// Positive endcap.
PhysVol posEC = new PhysVol(layerVolume, lcdd.getTrackingVolume(), position, rotation);
posEC.addPhysVolID("system", sysId);
posEC.addPhysVolID("barrel", 1); // Positive endcap flag.
posEC.addPhysVolID("layer", layerN);
-
+
// Negative endcap.
Rotation rotationReflect = new Rotation(layerName + "_rotation_reflect");
rotationReflect.setY(Math.PI);
@@ -109,50 +108,49 @@
negEC.addPhysVolID("barrel", 2); // Negative endcap flag.
negEC.addPhysVolID("layer", layerN);
}
-
+
moduleParameters = null;
}
-
+
private Volume makeLayer(
- Element subdetElement,
- Element layerElement,
- int layerN,
- double innerR,
- double outerR,
- double thickness,
+ Element subdetElement,
+ Element layerElement,
+ int layerN,
+ double innerR,
+ double outerR,
+ double thickness,
int nwedges,
LCDD lcdd)
{
double dphi = Math.PI / nwedges;
-
+
String subdetName = subdetElement.getAttributeValue("name");
-
+
String layerName = subdetName + "_layer" + layerN;
-
+
double tubeInnerR, tubeOuterR;
tubeInnerR = innerR;
tubeOuterR = outerR / Math.cos(dphi);
-
+
// FIXME: The z dimension should go in as a half length, but GDML does not use Geant4's convention.
Tube layerTube = new Tube(layerName + "_tube", tubeInnerR, tubeOuterR, thickness/2);
-
+
lcdd.add(layerTube);
-
+
Material material;
- try
- {
+ try {
material = lcdd.getMaterial("Air");
}
catch (JDOMException x)
{
throw new RuntimeException(x);
}
-
- Volume layerLV = new Volume(layerName, layerTube, material);
-
+
+ Volume layerLV = new Volume(layerName, layerTube, material);
+
Volume wedgeLV = makeWedge(subdetElement, layerElement, innerR, outerR, thickness, nwedges, layerN, lcdd);
lcdd.add(wedgeLV);
-
+
double r = (innerR + outerR) / 2;
String wedgeName = wedgeLV.getVolumeName();
for (int i=0; i<nwedges; i++)
@@ -160,34 +158,34 @@
double phi = i * 2 * Math.PI / nwedges;
double x = r * Math.cos(phi);
double y = r * Math.sin(phi);
-
+
Position p = new Position(wedgeName + i + "_position");
p.setX(x);
p.setY(y);
Rotation rot = new Rotation(wedgeName + i + "_rotation");
rot.setX(-Math.PI/2);
rot.setY(-Math.PI/2 - phi);
-
+
lcdd.add(p);
lcdd.add(rot);
-
+
PhysVol wedgePV = new PhysVol(wedgeLV, layerLV, p, rot);
- wedgePV.addPhysVolID("wedge", i);
+ wedgePV.addPhysVolID("wedge", i);
}
-
+
// Set the layer envelope to invisible to help Geant4 visualization.
//if (lcdd.getVisAttributes("InvisibleWithDaughters") != null)
//{
// layerLV.setVisAttributes(lcdd.getVisAttributes("InvisibleWithDaughters"));
//}
-
+
return layerLV;
}
-
+
Volume makeWedge(Element subdetElement, Element layerElement, double innerR, double outerR, double thickness, int nwedges, int layerN, LCDD lcdd)
{
Material material;
- try
+ try
{
material = lcdd.getMaterial("Air");
}
@@ -195,10 +193,10 @@
{
throw new RuntimeException(x);
}
-
+
String subdetName = subdetElement.getAttributeValue("name");
String name = subdetName + "_layer" + layerN + "_wedge";
-
+
double dz = (outerR - innerR) / 2;
double dy1, dy2;
dy1 = dy2 = thickness / 2;
@@ -206,25 +204,25 @@
double dphi = Math.PI / nwedges;
dx1 = innerR * Math.tan(dphi);
dx2 = outerR * Math.tan(dphi);
-
+
Trapezoid wedgeTrd = new Trapezoid(name + "_trapezoid",dx1,dx2,dy1,dy2,dz);
-
+
lcdd.add(wedgeTrd);
-
+
Volume wedgeLV = new Volume(name, wedgeTrd, material);
Attribute moduleref = layerElement.getAttribute("module");
if (moduleref == null)
- throw new RuntimeException("module reference is missing for layer number " + layerN);
+ throw new RuntimeException("module reference is missing for layer number " + layerN);
ModuleParameters module = moduleParameters.get(moduleref.getValue());
-
+
makeModules(subdetElement, wedgeLV, layerElement.getChild("module_parameters"), module, layerN, lcdd);
-
+
return wedgeLV;
}
-
+
private void makeModules(Element subdetElement, Volume wedgeLV, Element moduleParameters, ModuleParameters module, int layerN, LCDD lcdd)
{
double r_size;
@@ -236,7 +234,7 @@
{
throw new RuntimeException(x);
}
-
+
double phi_size_max;
try
{
@@ -246,7 +244,7 @@
{
throw new RuntimeException(x);
}
-
+
Trapezoid moduleTrd = (Trapezoid)lcdd.getSolid(wedgeLV.getSolidRef());
double dz = moduleTrd.z();
double dx1 = moduleTrd.x1();
@@ -254,12 +252,12 @@
double dy = moduleTrd.y1();
double deltax = dx2 - dx1;
double side_slope = deltax / (2*dz);
-
+
List<Double> zcenters = new ArrayList<Double>();
List<Double> zsizes = new ArrayList<Double>();
List<Double> xsizes1 = new ArrayList<Double>();
List<Double> xsizes2 = new ArrayList<Double>();
-
+
{
double zcurr = dz;
while (zcurr - r_size >= -dz)
@@ -268,13 +266,13 @@
double zmin = zcurr-r_size;
zcenters.add((zmin+zmax)/2);
zsizes.add((zmax-zmin)/2);
-
+
double xsize1 = dx1 + side_slope*(zmin+dz);
double xsize2 = dx1 + side_slope*(zmax+dz);
-
+
xsizes1.add(xsize1);
xsizes2.add(xsize2);
-
+
zcurr -= r_size;
}
double zmax = zcurr;
@@ -286,9 +284,9 @@
xsizes1.add(xsize1);
xsizes2.add(xsize2);
}
-
+
Material sliceMaterial;
- try
+ try
{
sliceMaterial = lcdd.getMaterial("Air");
}
@@ -296,17 +294,17 @@
{
throw new RuntimeException(x);
}
-
+
double xsize1_min = 0.0;
double xsize_box = 0.0;
int nboxes = 0;
-
+
int imodule = 0;
-
+
for (int i=zcenters.size()-1; i >= 0; i--)
- {
+ {
int ntraps = (int)Math.ceil( 2*(xsizes1.get(i) - nboxes*xsize_box) / phi_size_max );
-
+
// Squares to fill extra space
if (ntraps > 2)
{
@@ -314,138 +312,131 @@
nboxes++;
ntraps = 2;
}
-
+
double xmin = -nboxes*xsize_box;
double xmax = xmin+2*xsize_box;
-
+
for (int ibox = 0; ibox < nboxes; ibox++)
- {
+ {
double xcenter = (xmin+xmax)/2;
xmin += 2*xsize_box;
xmax += 2*xsize_box;
-
+
String sliceName = subdetElement.getAttributeValue("name") + "_layer" + layerN + "_module" + imodule;
-
+
// FIXME: Multiply by 2 to conform to GDML convention of dividing inputs by 2.
Box sliceBox = new Box(sliceName + "_box");
- sliceBox.setX(xsize_box*2 - GeomOp3D.DISTANCE_TOLERANCE);
+ sliceBox.setX(xsize_box*2);
sliceBox.setY(dy*2);
- sliceBox.setZ(zsizes.get(i)*2 - GeomOp3D.DISTANCE_TOLERANCE);
+ sliceBox.setZ(zsizes.get(i)*2);
lcdd.add(sliceBox);
-
+
Volume sliceLV = new Volume(sliceName, sliceBox, sliceMaterial);
-
+
// Make the box module.
makeBoxModule(sliceLV, module, lcdd);
-
+
lcdd.add(sliceLV);
-
+
Position p = new Position(sliceName + "_position");
p.setX(xcenter);
p.setZ(zcenters.get(i));
lcdd.add(p);
Rotation rot = new Rotation(sliceName + "_rotation");
lcdd.add(rot);
-
+
PhysVol slicePV = new PhysVol(sliceLV, wedgeLV, p, rot);
slicePV.addPhysVolID("module", imodule);
-
+
imodule++;
}
-
+
// Small symmetric trapezoids
if (ntraps == 1)
{
String sliceName = subdetElement.getAttributeValue("name") + "_layer" + layerN + "_module" + imodule;
-
- Trapezoid sliceTrd = new Trapezoid(sliceName+"_trapezoid",
- xsizes1.get(i) - GeomOp3D.DISTANCE_TOLERANCE, xsizes2.get(i) - GeomOp3D.DISTANCE_TOLERANCE, dy, dy,
- zsizes.get(i) - GeomOp3D.DISTANCE_TOLERANCE);
+
+ Trapezoid sliceTrd = new Trapezoid(sliceName+"_trapezoid", xsizes1.get(i), xsizes2.get(i), dy, dy, zsizes.get(i));
lcdd.add(sliceTrd);
-
+
Volume sliceLV = new Volume(sliceName, sliceTrd, sliceMaterial);
makeTrdModule(sliceLV, module, lcdd);
lcdd.add(sliceLV);
-
+
Position p = new Position(sliceName + "_position");
p.setZ(zcenters.get(i));
lcdd.add(p);
-
+
Rotation rot = new Rotation(sliceName + "_rotation");
lcdd.add(rot);
-
+
PhysVol slicePV = new PhysVol(sliceLV, wedgeLV, p, rot);
slicePV.addPhysVolID("module", imodule);
-
+
imodule++;
}
-
+
// Split trapezoids
if (ntraps == 2)
{
-
+
double xoffset = xsize_box*nboxes;
-
+
double xsize1 = (xsizes1.get(i)-xoffset)/ntraps;
if (xsize1_min == 0.0) xsize1_min = xsize1;
double xsize2 = (xsizes2.get(i)-xoffset)/ntraps;
-
+
double xcenter = (xsize1+xsize2)/2 + xoffset;
double theta = Math.abs(Math.atan(side_slope/2));
-
+
for (int ix = -1; ix <=1; ix=ix+2)
{
String sliceName = subdetElement.getAttributeValue("name") + "_layer" + layerN + "_module" + imodule;
-
- Trap sliceTrap = new Trap(sliceName+"_trap",zsizes.get(i) - GeomOp3D.DISTANCE_TOLERANCE,
- theta*ix,0.0,dy,
- xsize1 - GeomOp3D.DISTANCE_TOLERANCE,xsize1 - GeomOp3D.DISTANCE_TOLERANCE,
- 0.0,dy,
- xsize2 - GeomOp3D.DISTANCE_TOLERANCE,xsize2 - GeomOp3D.DISTANCE_TOLERANCE,0.0);
+
+ Trap sliceTrap = new Trap(sliceName+"_trap",zsizes.get(i),theta*ix,0.0,dy,xsize1,xsize1,0.0,dy,xsize2,xsize2,0.0);
lcdd.add(sliceTrap);
-
+
Volume sliceLV = new Volume(sliceName, sliceTrap, sliceMaterial);
makeTrapModule(sliceLV, module, lcdd);
lcdd.add(sliceLV);
-
+
Position p = new Position(sliceName + "_position");
p.setX(ix*xcenter);
p.setZ(zcenters.get(i));
lcdd.add(p);
Rotation rot = new Rotation(sliceName + "_rotation");
lcdd.add(rot);
-
+
PhysVol slicePV = new PhysVol(sliceLV, wedgeLV, p, rot);
slicePV.addPhysVolID("module", imodule);
-
+
imodule++;
}
}
}
}
-
+
void makeBoxModule(Volume moduleVolume, ModuleParameters moduleParameters, LCDD lcdd)
{
Box moduleBox = (Box)lcdd.getSolid(moduleVolume.getSolidRef());
-
+
double moduleX = moduleBox.getX();
double posY = -(moduleBox.getY() / 2);
- double moduleZ = moduleBox.getZ();
-
+ double moduleZ = moduleBox.getZ();
+
String moduleName = moduleVolume.getVolumeName();
-
+
int sensor=0;
for (ModuleComponentParameters component : moduleParameters)
{
double thickness = component.getThickness();
Material material = null;
- try
- {
+ try {
material = lcdd.getMaterial(component.getMaterialName());
}
catch (JDOMException x)
@@ -454,18 +445,18 @@
}
boolean sensitive = component.isSensitive();
int componentNumber = component.getComponentNumber();
-
+
posY += thickness / 2;
-
+
String componentName = moduleName + "_component" + componentNumber;
-
+
Box sliceBox = new Box(componentName + "_box", moduleX, thickness, moduleZ);
lcdd.add(sliceBox);
-
+
Volume volume = new Volume(componentName, sliceBox, material);
lcdd.add(volume);
-
- Position position = new Position(componentName + "_position", 0., posY, 0.);
+
+ Position position = new Position(componentName + "_position", 0., posY, 0.);
lcdd.add(position);
Rotation rotation = new Rotation(componentName + "_rotation");
rotation.setY(Math.PI);
@@ -482,33 +473,32 @@
volume.setSensitiveDetector(this.sd);
pv.addPhysVolID("sensor", sensor);
++sensor;
- }
-
+ }
+
posY += thickness / 2;
- }
+ }
}
-
+
void makeTrdModule(Volume moduleVolume, ModuleParameters moduleParameters, LCDD lcdd)
{
Trapezoid trd = (Trapezoid)lcdd.getSolid(moduleVolume.getSolidRef());
-
+
double x1 = trd.x1();
double x2 = trd.x2();
double y1 = trd.y1();
double z = trd.z();
-
+
double posY = -y1;
-
+
String moduleName = moduleVolume.getVolumeName();
-
+
int sensor=0;
for (ModuleComponentParameters component : moduleParameters)
{
double thickness = component.getThickness();
-
+
Material material = null;
- try
- {
+ try {
material = lcdd.getMaterial(component.getMaterialName());
}
catch (JDOMException x)
@@ -516,26 +506,26 @@
throw new RuntimeException(x);
}
boolean sensitive = component.isSensitive();
- int componentNumber = component.getComponentNumber();
-
+ int componentNumber = component.getComponentNumber();
+
posY += thickness / 2;
-
+
String componentName = moduleName + "_component" + componentNumber;
-
+
Trapezoid sliceTrd = new Trapezoid(componentName + "_trd", x1, x2, thickness/2, thickness/2, z);
lcdd.add(sliceTrd);
-
+
Volume volume = new Volume(componentName, sliceTrd, material);
lcdd.add(volume);
-
+
Position position = new Position(componentName + "_position",0.,posY,0);
lcdd.add(position);
Rotation rotation = new Rotation(componentName + "_rotation");
lcdd.add(rotation);
-
+
PhysVol pv = new PhysVol(volume, moduleVolume, position, rotation);
pv.addPhysVolID("component", componentNumber);
-
+
if (sensitive)
{
if (sensor > 1)
@@ -546,15 +536,15 @@
volume.setSensitiveDetector(this.sd);
++sensor;
}
-
+
posY += thickness / 2;
- }
+ }
}
-
+
public void makeTrapModule(Volume module, ModuleParameters moduleParameters, LCDD lcdd)
{
Trap trap = (Trap)lcdd.getSolid(module.getSolidRef());
-
+
double a1 = trap.getAlpha1();
double a2 = trap.getAlpha2();
double x1 = trap.getXHalfLength1();
@@ -565,17 +555,16 @@
double z = trap.getZHalfLength();
double theta = trap.getTheta();
double phi = trap.getPhi();
-
+
double posY = -y1;
-
+
int sensor = 0;
for (ModuleComponentParameters component : moduleParameters)
{
double thickness = component.getThickness();
Material material = null;
- try
- {
+ try {
material = lcdd.getMaterial(component.getMaterialName());
}
catch (JDOMException x)
@@ -584,22 +573,22 @@
}
boolean sensitive = component.isSensitive();
int componentNumber = component.getComponentNumber();
-
+
posY += thickness / 2;
-
- String componentName = module.getVolumeName() + "_component" + componentNumber;
-
+
+ String componentName = module.getVolumeName() + "_component" + componentNumber;
+
Trap sliceTrap = new Trap(componentName + "_trap", z, theta, phi, thickness/2, x1, x2, a1, thickness/2, x3, x4, a2);
lcdd.add(sliceTrap);
-
+
Volume volume = new Volume(componentName, sliceTrap, material);
lcdd.add(volume);
-
+
Position position = new Position(componentName + "_position",0,posY,0);
lcdd.add(position);
Rotation rotation = new Rotation(componentName + "_rotation");
lcdd.add(rotation);
-
+
PhysVol pv = new PhysVol(volume, module, position, rotation);
pv.addPhysVolID("component", componentNumber);
@@ -612,17 +601,17 @@
volume.setSensitiveDetector(this.sd);
pv.addPhysVolID("sensor", sensor);
++sensor;
- }
-
+ }
+
posY += thickness / 2;
- }
+ }
}
-
+
public boolean isTracker()
{
return true;
}
-
+
// FIXME: Duplicates class in org.lcsim.detector.converter.compact.SiTrackerEndcapConverter to avoid dependency.
public static class ModuleComponentParameters
{
@@ -630,7 +619,7 @@
double thickness;
boolean sensitive;
int componentNumber;
-
+
public ModuleComponentParameters(double thickness, String materialName, int componentNumber, boolean sensitive)
{
this.thickness = thickness;
@@ -638,31 +627,31 @@
this.sensitive = sensitive;
this.componentNumber = componentNumber;
}
-
+
public double getThickness()
{
return thickness;
}
-
+
public String getMaterialName()
{
return materialName;
}
-
+
public boolean isSensitive()
{
return sensitive;
}
-
+
public int getComponentNumber()
{
return componentNumber;
}
}
-
- // FIXME: Duplicates class in org.lcsim.detector.converter.compact.SiTrackerEndcapConverter to avoid dependency.
+
+ // FIXME: Duplicates class in org.lcsim.detector.converter.compact.SiTrackerEndcapConverter to avoid dependency.
public static class ModuleParameters
- extends ArrayList<ModuleComponentParameters>
+ extends ArrayList<ModuleComponentParameters>
{
double thickness=0.;
String name;
@@ -672,15 +661,14 @@
int cntr=0;
for (Object o : element.getChildren("module_component"))
{
- try
- {
-
+ try {
+
Element e = (Element)o;
-
+
double thickness = e.getAttribute("thickness").getDoubleValue();
-
+
String materialName = e.getAttributeValue("material");
-
+
boolean sensitive = false;
if (e.getAttribute("sensitive") != null)
sensitive = e.getAttribute("sensitive").getBooleanValue();
@@ -694,7 +682,7 @@
}
calculateThickness();
}
-
+
public void calculateThickness()
{
thickness = 0.; // reset thickness
@@ -703,11 +691,11 @@
thickness += p.getThickness();
}
}
-
+
public double getThickness()
{
return thickness;
}
}
-
-}
\ No newline at end of file
+
+}