1 package org.lcsim.geometry.compact.converter.lcdd;
2
3 import java.util.Iterator;
4
5 import org.jdom.Element;
6 import org.jdom.JDOMException;
7 import org.lcsim.geometry.compact.converter.lcdd.util.Define;
8 import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
9 import org.lcsim.geometry.compact.converter.lcdd.util.Material;
10 import org.lcsim.geometry.compact.converter.lcdd.util.PhysVol;
11 import org.lcsim.geometry.compact.converter.lcdd.util.PolyhedraRegular;
12 import org.lcsim.geometry.compact.converter.lcdd.util.Position;
13 import org.lcsim.geometry.compact.converter.lcdd.util.Rotation;
14 import org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector;
15 import org.lcsim.geometry.compact.converter.lcdd.util.Solids;
16 import org.lcsim.geometry.compact.converter.lcdd.util.Structure;
17 import org.lcsim.geometry.compact.converter.lcdd.util.Volume;
18 import org.lcsim.geometry.layer.LayerStack;
19 import org.lcsim.geometry.layer.Layering;
20
21 public class PolyhedraEndcapCalorimeter2 extends LCDDSubdetector
22 {
23 public PolyhedraEndcapCalorimeter2(Element node) throws JDOMException
24 {
25 super(node);
26 this.node = node;
27 }
28
29 public void addToLCDD(LCDD lcdd, SensitiveDetector sens) throws JDOMException
30 {
31 Solids solids = lcdd.getSolids();
32 Structure structure = lcdd.getStructure();
33 Volume motherVolume = lcdd.pickMotherVolume(this);
34 Material air = lcdd.getMaterial("Air");
35 Define define = lcdd.getDefine();
36 Rotation identityRotation = define.getRotation("identity_rot");
37 Element staves = node.getChild("staves");
38
39 String subdetectorName = node.getAttributeValue("name");
40 int id = node.getAttribute("id").getIntValue();
41
42 if (node.getChild("dimensions") == null)
43 throw new RuntimeException("PolhedraEndcapCalorimeter2 " + subdetectorName
44 + " is missing required <dimensions> element.");
45
46 Element dimensions = node.getChild("dimensions");
47 double zmin = dimensions.getAttribute("zmin").getDoubleValue();
48 double rmin = dimensions.getAttribute("rmin").getDoubleValue();
49 double rmax = dimensions.getAttribute("rmax").getDoubleValue();
50 int numsides = dimensions.getAttribute("numsides").getIntValue();
51
52 LayerStack layers = Layering.makeLayering(this.node).getLayerStack();
53
54
55
56 rmax = rmax*Math.cos(Math.PI/numsides);
57
58 double subdetectorThickness = org.lcsim.geometry.layer.LayerFromCompactCnv.computeDetectorTotalThickness(node);
59
60 PolyhedraRegular envelopeSolid = new PolyhedraRegular(subdetectorName + "_envelope", numsides, rmin, rmax, subdetectorThickness);
61 solids.addSolid(envelopeSolid);
62 Volume envelopeVolume = new Volume(subdetectorName + "_volume", envelopeSolid, air);
63
64 int layerNumber = 0;
65 int layerType = 0;
66 double layerZ = -subdetectorThickness/2;
67 for (Iterator<Element> i = node.getChildren("layer").iterator(); i.hasNext();)
68 {
69 Element layerElement = i.next();
70 double layerThickness = layers.getLayer(layerNumber).getThickness();
71 String layerTypeName = subdetectorName + "_layer" + layerType;
72 if (layerElement.getAttribute("repeat") == null)
73 {
74 throw new RuntimeException("Missing the repeat number in layering for " + subdetectorName);
75 }
76 PolyhedraRegular layerSolid = new PolyhedraRegular(layerTypeName + "_solid", numsides, rmin, rmax, layerThickness);
77 solids.addSolid(layerSolid);
78 Volume layerVolume = new Volume(layerTypeName + "_volume", layerSolid, air);
79
80 int sliceNumber = 0;
81 double sliceZ = -layerThickness/2;
82 for (Iterator j = layerElement.getChildren("slice").iterator(); j.hasNext();)
83 {
84 String sliceName = layerTypeName + "_slice" + sliceNumber;
85 Element sliceElement = (Element) j.next();
86 if (sliceElement.getAttribute("thickness") == null)
87 throw new RuntimeException("Missing thickness attribute.");
88 double sliceThickness = sliceElement.getAttribute("thickness").getDoubleValue();
89 if (sliceElement.getAttribute("material") == null)
90 throw new RuntimeException("Missing material attribute.");
91 String materialName = sliceElement.getAttribute("material").getValue();
92 Material sliceMaterial = lcdd.getMaterial(materialName);
93 PolyhedraRegular sliceSolid = new PolyhedraRegular(sliceName + "_solid", numsides, rmin, rmax, sliceThickness);
94 solids.addSolid(sliceSolid);
95 Volume sliceVolume = new Volume(sliceName + "_volume", sliceSolid, sliceMaterial);
96 if (sliceElement.getAttribute("sensitive") != null)
97 {
98 if (sliceElement.getAttribute("sensitive").getBooleanValue() == true)
99 {
100 sliceVolume.setSensitiveDetector(sens);
101 }
102 }
103
104
105 this.setVisAttributes(lcdd, sliceElement, sliceVolume);
106
107
108
109
110 structure.addVolume(sliceVolume);
111 sliceZ += sliceThickness/2;
112 Position slicePosition = new Position(sliceName + "_position", 0, 0, sliceZ);
113 define.addPosition(slicePosition);
114 sliceZ += sliceThickness/2;
115 PhysVol slicePhysVol = new PhysVol(sliceVolume, layerVolume, slicePosition, identityRotation);
116 slicePhysVol.addPhysVolID("slice", sliceNumber);
117 sliceNumber++;
118 }
119
120
121 if (layerElement.getAttribute("vis") != null)
122 {
123 layerVolume.setVisAttributes(lcdd.getVisAttributes(layerElement.getAttributeValue("vis")));
124 }
125
126 sliceNumber = 0;
127 structure.addVolume(layerVolume);
128 int repeat = (int)layerElement.getAttribute("repeat").getDoubleValue();
129 if (repeat <= 0)
130 throw new RuntimeException("The repeat value of " + repeat + " is invalid.");
131 for ( int j=0; j<repeat; j++)
132 {
133 String physLayerName = subdetectorName + "_layer" + layerNumber;
134 layerZ += layerThickness/2;
135 Position layerPosition = new Position(physLayerName + "_position", 0, 0, layerZ);
136 define.addPosition(layerPosition);
137 PhysVol layerPhysVol = new PhysVol(layerVolume, envelopeVolume, layerPosition, identityRotation);
138 layerPhysVol.addPhysVolID("layer", layerNumber);
139 layerZ += layerThickness/2;
140 ++layerNumber;
141 }
142 ++layerType;
143 }
144
145
146 structure.addVolume(envelopeVolume);
147
148
149 setAttributes(lcdd, node, envelopeVolume);
150
151
152
153 double zrot = Math.PI / numsides;
154 PhysVol physvol = new PhysVol(envelopeVolume);
155 physvol.setZ(zmin+subdetectorThickness/2);
156 physvol.addPhysVolID("system",id);
157 physvol.addPhysVolID("barrel",1);
158 Rotation positiveEndcapRotation = new Rotation(subdetectorName + "_positive");
159 positiveEndcapRotation.setZ(zrot);
160 lcdd.getDefine().addRotation(positiveEndcapRotation);
161 physvol.setRotation(positiveEndcapRotation);
162 motherVolume.addPhysVol(physvol);
163
164
165
166
167 boolean reflect = true;
168 if (node.getAttribute("reflect") != null )
169 {
170 reflect = node.getAttribute("reflect").getBooleanValue();
171 }
172
173 if (reflect)
174 {
175 PhysVol physvol2 = new PhysVol(envelopeVolume);
176 physvol2.setZ(-zmin-subdetectorThickness/2);
177 Rotation negativeEndcapRotation = new Rotation(subdetectorName + "_negative");
178 lcdd.getDefine().addRotation(negativeEndcapRotation);
179 negativeEndcapRotation.setX(Math.PI);
180 negativeEndcapRotation.setZ(zrot);
181
182 physvol2.setRotation(negativeEndcapRotation);
183 physvol2.addPhysVolID("system",id);
184 physvol2.addPhysVolID("barrel",2);
185 motherVolume.addPhysVol(physvol2);
186 }
187 }
188
189 public boolean isCalorimeter()
190 {
191 return true;
192 }
193 }