View Javadoc

1   package org.lcsim.geometry.compact.converter.lcdd;
2   
3   import static java.lang.Math.PI;
4   import static java.lang.Math.cos;
5   import static java.lang.Math.sin;
6   import static java.lang.Math.tan;
7   
8   import org.jdom.Element;
9   import org.jdom.JDOMException;
10  import org.lcsim.geometry.compact.converter.lcdd.util.Define;
11  import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
12  import org.lcsim.geometry.compact.converter.lcdd.util.Material;
13  import org.lcsim.geometry.compact.converter.lcdd.util.PhysVol;
14  import org.lcsim.geometry.compact.converter.lcdd.util.Position;
15  import org.lcsim.geometry.compact.converter.lcdd.util.Rotation;
16  import org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector;
17  import org.lcsim.geometry.compact.converter.lcdd.util.Solids;
18  import org.lcsim.geometry.compact.converter.lcdd.util.Structure;
19  import org.lcsim.geometry.compact.converter.lcdd.util.Trapezoid;
20  import org.lcsim.geometry.compact.converter.lcdd.util.Volume;
21  import org.lcsim.geometry.layer.Layering;
22  
23  /**
24   * This class generates the LCDD for the SidHcal design.
25   * 
26   * TODO Add URL for design reference.
27   * 
28   * @author Jeremy McCormick <jeremym@slac.stanford.edu>
29   * @version $Id: SidHcal.java,v 1.2 2010/04/27 17:39:11 jeremy Exp $
30   */
31  public class SidHcal extends LCDDSubdetector
32  {
33      public SidHcal(Element node) throws JDOMException
34      {
35          super(node);
36          this.node = node;
37      }
38  
39      public void addToLCDD(LCDD lcdd, SensitiveDetector sens) throws JDOMException
40      {
41          // Get some important LCDD references.
42          Solids solids = lcdd.getSolids();
43          Structure structure = lcdd.getStructure();
44          Volume motherVolume = lcdd.pickMotherVolume(this);
45          Material air = lcdd.getMaterial("Air");
46          Define define = lcdd.getDefine();
47          
48          // Subdetector name and ID.
49          String detName = node.getAttributeValue("name");
50          int id = node.getAttribute("id").getIntValue();
51          
52          // Create layering object for this subdetector.
53          Layering layering = Layering.makeLayering(this.node);
54  
55          // Total thickness of subdetector.
56          double staveThickness = layering.getLayerStack().getTotalThickness();
57          
58          // Subdetector envelope dimensions.
59          Element dimensions = node.getChild("dimensions");
60          double detZ = dimensions.getAttribute("z").getDoubleValue();
61          double rmin = dimensions.getAttribute("rmin").getDoubleValue();
62          int nsides = dimensions.getAttribute("numsides").getIntValue();
63          double gap = dimensions.getAttribute("gap").getDoubleValue();
64          
65          // Rotation of the envelope to make flat side down.
66          double zrot = PI / nsides;
67          Rotation rot = new Rotation(detName + "_rotation");
68          rot.setZ(zrot);
69          define.addRotation(rot);
70                          
71          double innerAngle = PI * 2 / nsides;
72          double halfInnerAngle = innerAngle / 2;
73          double innerFaceLength = rmin * tan(halfInnerAngle) * 2;
74          
75          // Box stave outer solid.
76          Trapezoid sectATrdOuter = new Trapezoid(detName + "_staveA_outer");
77          sectATrdOuter.setY2(detZ/2);
78          sectATrdOuter.setY1(detZ/2);
79          sectATrdOuter.setZ(staveThickness/2);
80          sectATrdOuter.setX1(innerFaceLength/2);
81          sectATrdOuter.setX2(innerFaceLength/2);
82          solids.addSolid(sectATrdOuter);
83                  
84          // Box stave outer volume.        
85          Volume staveAVolumeOuter = new Volume(detName + "_staveA_outer_vol");
86          staveAVolumeOuter.setMaterial(air);
87          staveAVolumeOuter.setSolid(sectATrdOuter);        
88          
89          // Box stave inner solid.
90          Trapezoid sectATrdInner = new Trapezoid(detName + "_staveA_inner");
91          sectATrdInner.setY2(detZ/2);
92          sectATrdInner.setY1(detZ/2);
93          sectATrdInner.setZ(staveThickness/2);
94          sectATrdInner.setX1(innerFaceLength/2 - gap);
95          sectATrdInner.setX2(innerFaceLength/2 - gap);
96          solids.addSolid(sectATrdInner);
97          
98          // Box stave inner volume.        
99          Volume staveAVolumeInner = new Volume(detName + "_staveA_inner_vol");
100         staveAVolumeInner.setMaterial(air);
101         staveAVolumeInner.setSolid(sectATrdInner);
102         structure.addVolume(staveAVolumeInner);
103         
104         // Place inner box stave inside of outer to make skin.
105         PhysVol staveAPhysVol = new PhysVol(staveAVolumeInner);
106         staveAVolumeOuter.addPhysVol(staveAPhysVol);
107         
108         // Add box stave outer volume to structure.
109         structure.addVolume(staveAVolumeOuter);
110                        
111         // Trap stave outer solid.        
112         double trdBottomHalf = rmin * tan(PI/nsides);
113         double trdTopHalf = rmin * tan(PI/nsides) + staveThickness * sin (PI/nsides * 2);
114         double trdHalfThickness = (staveThickness * cos((PI/nsides) * 2)) / 2;
115         Trapezoid sectBTrdOuter = new Trapezoid(detName + "_staveB_outer");
116         sectBTrdOuter.setY2(detZ/2);
117         sectBTrdOuter.setY1(detZ/2);
118         sectBTrdOuter.setZ(trdHalfThickness);
119         sectBTrdOuter.setX1(trdBottomHalf);
120         sectBTrdOuter.setX2(trdTopHalf);
121         solids.addSolid(sectBTrdOuter);
122         
123         // Trap stave outer volume.        
124         Volume staveBVolumeOuter = new Volume(detName + "_staveB_outer_vol");
125         staveBVolumeOuter.setMaterial(air);
126         staveBVolumeOuter.setSolid(sectBTrdOuter);        
127         
128         // Box stave inner solid.
129         Trapezoid sectBTrdInner = new Trapezoid(detName + "_staveB_inner");
130         sectBTrdInner.setY2(detZ/2);
131         sectBTrdInner.setY1(detZ/2);
132         sectBTrdInner.setZ(trdHalfThickness);
133         sectBTrdInner.setX1(trdBottomHalf - gap);
134         sectBTrdInner.setX2(trdTopHalf - gap);
135         solids.addSolid(sectBTrdInner);
136         
137         // Trap stave inner volume.
138         Volume staveBVolumeInner = new Volume(detName + "_staveB_inner_vol");
139         staveBVolumeInner.setMaterial(air);
140         staveBVolumeInner.setSolid(sectBTrdInner);
141         structure.addVolume(staveBVolumeInner);
142         
143         // Place inner box stave inside of outer to make skin.
144         PhysVol staveBPhysVol = new PhysVol(staveBVolumeInner);
145         staveBVolumeOuter.addPhysVol(staveBPhysVol);
146         
147         // Add trap stave outer volume to structure.
148         structure.addVolume(staveBVolumeOuter);
149                         
150         // Place the box staves.
151         placeStaves(motherVolume, define, detName, rmin + staveThickness / 2, nsides, innerAngle, staveAVolumeOuter, 0);
152         
153         // Place the trap staves.
154         placeStaves(motherVolume, define, detName, rmin + trdHalfThickness, nsides, innerAngle, staveBVolumeOuter, 2 * PI / nsides);
155     }
156 
157     private void placeStaves(Volume motherVolume, Define define, String detName, double rMid, int nsides, double innerAngle, Volume staveVolume, double startRot)
158     {
159         // Setup initial parameters for box stave placement and rotation.
160         double rotY = startRot;
161         double rotX = PI / 2;
162         double posX = -rMid * sin(rotY);
163         double posY = rMid * cos(rotY);
164         int moduleNumber = 0;
165         
166         // Place box staves.
167         for (int i=0; i<nsides; i++)
168         {            
169             Position position = new Position(staveVolume.getVolumeName() + "_module" + moduleNumber + "_position");
170             position.setX(posX);
171             position.setY(posY);
172 
173             Rotation rotation = new Rotation(staveVolume.getVolumeName() + "_module" + moduleNumber + "_rotation");
174             rotation.setX(rotX);
175             rotation.setY(rotY);
176 
177             define.addPosition(position);
178             define.addRotation(rotation);
179             
180             PhysVol sectPhysVol = new PhysVol(staveVolume);
181             sectPhysVol.setPosition(position);
182             sectPhysVol.setRotation(rotation);
183 
184             motherVolume.addPhysVol(sectPhysVol);
185             sectPhysVol.addPhysVolID("stave", 0);
186             sectPhysVol.addPhysVolID("module", moduleNumber);
187                                  
188             // Increment the parameters for next stave.
189             rotY -= innerAngle * 2;
190             posX = -rMid * sin(rotY);
191             posY = rMid * cos(rotY);            
192             moduleNumber += 2;            
193         }
194     }
195 }