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
25
26
27
28
29
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
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
49 String detName = node.getAttributeValue("name");
50 int id = node.getAttribute("id").getIntValue();
51
52
53 Layering layering = Layering.makeLayering(this.node);
54
55
56 double staveThickness = layering.getLayerStack().getTotalThickness();
57
58
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
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
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
85 Volume staveAVolumeOuter = new Volume(detName + "_staveA_outer_vol");
86 staveAVolumeOuter.setMaterial(air);
87 staveAVolumeOuter.setSolid(sectATrdOuter);
88
89
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
99 Volume staveAVolumeInner = new Volume(detName + "_staveA_inner_vol");
100 staveAVolumeInner.setMaterial(air);
101 staveAVolumeInner.setSolid(sectATrdInner);
102 structure.addVolume(staveAVolumeInner);
103
104
105 PhysVol staveAPhysVol = new PhysVol(staveAVolumeInner);
106 staveAVolumeOuter.addPhysVol(staveAPhysVol);
107
108
109 structure.addVolume(staveAVolumeOuter);
110
111
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
124 Volume staveBVolumeOuter = new Volume(detName + "_staveB_outer_vol");
125 staveBVolumeOuter.setMaterial(air);
126 staveBVolumeOuter.setSolid(sectBTrdOuter);
127
128
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
138 Volume staveBVolumeInner = new Volume(detName + "_staveB_inner_vol");
139 staveBVolumeInner.setMaterial(air);
140 staveBVolumeInner.setSolid(sectBTrdInner);
141 structure.addVolume(staveBVolumeInner);
142
143
144 PhysVol staveBPhysVol = new PhysVol(staveBVolumeInner);
145 staveBVolumeOuter.addPhysVol(staveBPhysVol);
146
147
148 structure.addVolume(staveBVolumeOuter);
149
150
151 placeStaves(motherVolume, define, detName, rmin + staveThickness / 2, nsides, innerAngle, staveAVolumeOuter, 0);
152
153
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
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
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
189 rotY -= innerAngle * 2;
190 posX = -rMid * sin(rotY);
191 posY = rMid * cos(rotY);
192 moduleNumber += 2;
193 }
194 }
195 }