1 package org.lcsim.geometry.compact.converter.lcdd;
2
3 import static java.lang.Math.cos;
4 import static java.lang.Math.sin;
5
6 import java.util.HashMap;
7 import java.util.Iterator;
8 import java.util.Map;
9
10 import org.jdom.Element;
11 import org.jdom.JDOMException;
12 import org.lcsim.geometry.compact.converter.lcdd.util.Box;
13 import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
14 import org.lcsim.geometry.compact.converter.lcdd.util.Material;
15 import org.lcsim.geometry.compact.converter.lcdd.util.PhysVol;
16 import org.lcsim.geometry.compact.converter.lcdd.util.Position;
17 import org.lcsim.geometry.compact.converter.lcdd.util.Rotation;
18 import org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector;
19 import org.lcsim.geometry.compact.converter.lcdd.util.Solids;
20 import org.lcsim.geometry.compact.converter.lcdd.util.Structure;
21 import org.lcsim.geometry.compact.converter.lcdd.util.Tube;
22 import org.lcsim.geometry.compact.converter.lcdd.util.VisAttributes;
23 import org.lcsim.geometry.compact.converter.lcdd.util.Volume;
24
25
26
27
28
29
30
31
32
33 public class SiTrackerBarrel extends LCDDSubdetector
34 {
35 Map<String, Volume> modules = new HashMap<String, Volume>();
36
37 public SiTrackerBarrel(Element node) throws JDOMException
38 {
39 super(node);
40 }
41
42
43
44
45
46
47 public void addToLCDD(LCDD lcdd, SensitiveDetector sens) throws JDOMException
48 {
49
50 int id = this.node.getAttribute("id").getIntValue();
51
52
53 String detector_name = this.node.getAttributeValue("name");
54
55
56 Material air = lcdd.getMaterial("Air");
57
58
59 Solids solids = lcdd.getSolids();
60
61
62 Structure structure = lcdd.getStructure();
63
64
65 Volume tracking_volume = lcdd.pickMotherVolume(this);
66
67 VisAttributes vis = null;
68 if (node.getAttribute("vis") != null)
69 vis = lcdd.getVisAttributes(node.getAttributeValue("vis"));
70
71
72 for (Iterator i = node.getChildren("module").iterator(); i.hasNext();)
73 {
74 Element module = (Element) i.next();
75 String module_name = module.getAttributeValue("name");
76 Volume module_envelope;
77 try
78 {
79 module_envelope = buildModule(node, module_name, lcdd, sens, vis);
80 modules.put(module_name, module_envelope);
81 }
82 catch (Exception x)
83 {
84 throw new RuntimeException(x);
85 }
86 }
87
88
89 for (Iterator i = node.getChildren("layer").iterator(); i.hasNext();)
90 {
91
92 Element layer_element = (Element) i.next();
93
94 int layern = layer_element.getAttribute("id").getIntValue();
95
96
97 String module_name = layer_element.getAttributeValue("module");
98
99
100 Volume module_envelope = modules.get(module_name);
101
102
103 Element barrel_envelope = layer_element.getChild("barrel_envelope");
104
105
106 double ir = barrel_envelope.getAttribute("inner_r").getDoubleValue();
107
108
109 double or = barrel_envelope.getAttribute("outer_r").getDoubleValue();
110
111
112 double oz = barrel_envelope.getAttribute("z_length").getDoubleValue();
113
114
115 String layer_name = detector_name + "_layer" + layern;
116
117
118
119
120 Tube layer_tube = new Tube(layer_name + "_tube");
121 layer_tube.setRMin(ir);
122 layer_tube.setRMax(or);
123 layer_tube.setZ(oz);
124 solids.addContent(layer_tube);
125
126
127 Volume layer_volume = new Volume(layer_name);
128 layer_volume.setMaterial(air);
129 layer_volume.setSolid(layer_tube);
130
131
132 Element rphi_layout = layer_element.getChild("rphi_layout");
133
134
135 double phi0 = rphi_layout.getAttribute("phi0").getDoubleValue();
136
137
138 int nphi = rphi_layout.getAttribute("nphi").getIntValue();
139 assert (nphi > 0);
140
141
142 double phi_tilt = rphi_layout.getAttribute("phi_tilt").getDoubleValue();
143
144
145 double rc = rphi_layout.getAttribute("rc").getDoubleValue();
146
147
148 double rphi_dr = 0.0;
149 if (rphi_layout.getAttribute("dr") != null)
150 {
151 rphi_dr = rphi_layout.getAttribute("dr").getDoubleValue();
152 }
153
154
155 double phi_incr = (Math.PI * 2) / nphi;
156
157
158 double phic = 0;
159 phic += phi0;
160
161
162 Element z_layout = layer_element.getChild("z_layout");
163
164
165 double z0 = z_layout.getAttribute("z0").getDoubleValue();
166
167
168 double nz = z_layout.getAttribute("nz").getIntValue();
169 assert (nz > 0);
170
171
172 double z_dr = z_layout.getAttribute("dr").getDoubleValue();
173
174
175
176
177 double z_incr = (2.0 * z0) / (nz - 1);
178
179
180 double module_z = -z0;
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197 int module = 0;
198
199
200 for (int ii = 0; ii < nphi; ii++)
201 {
202
203 double dx = z_dr * cos(phic + phi_tilt);
204
205
206 double dy = z_dr * sin(phic + phi_tilt);
207
208
209 double x = rc * cos(phic);
210
211
212 double y = rc * sin(phic);
213
214
215 for (int j = 0; j < nz; j++)
216 {
217
218 String module_place_name = detector_name + "_layer" + layern + "_phi" + ii + "_z" + j;
219
220 double z = module_z;
221
222
223
224
225
226
227
228
229
230
231
232 Position module_position = new Position(module_place_name + "_position");
233 module_position.setX(x);
234 module_position.setY(y);
235 module_position.setZ(z);
236 lcdd.getDefine().addPosition(module_position);
237
238
239 Rotation module_rotation = new Rotation(module_place_name + "_rotation");
240 double rotx = Math.PI / 2;
241 double roty = -((Math.PI / 2) - phic - phi_tilt);
242 double rotz = 0;
243 module_rotation.setX(rotx);
244 module_rotation.setY(roty);
245 module_rotation.setZ(rotz);
246 lcdd.getDefine().addRotation(module_rotation);
247
248
249
250
251
252
253 PhysVol module_physvol = new PhysVol(module_envelope);
254 module_physvol.setPosition(module_position);
255 module_physvol.setRotation(module_rotation);
256
257
258 module_physvol.addPhysVolID("module", module);
259 ++module;
260 layer_volume.addPhysVol(module_physvol);
261
262
263 x += dx;
264 y += dy;
265
266
267 dx *= -1;
268 dy *= -1;
269
270
271 module_z += z_incr;
272
273
274 }
275
276
277 phic += phi_incr;
278
279
280 rc += rphi_dr;
281
282
283 rphi_dr *= -1;
284
285
286 module_z = -z0;
287 }
288
289 setRegion(lcdd, layer_element, layer_volume);
290 setLimitSet(lcdd, layer_element, layer_volume);
291
292
293
294
295
296
297
298
299
300
301
302
303 structure.addVolume(layer_volume);
304
305
306 PhysVol layer_envelope_physvol = new PhysVol(layer_volume);
307
308
309 layer_envelope_physvol.addPhysVolID("system", id);
310
311
312 layer_envelope_physvol.addPhysVolID("barrel", 0);
313
314
315 layer_envelope_physvol.addPhysVolID("layer", layern);
316
317
318 tracking_volume.addPhysVol(layer_envelope_physvol);
319 }
320 }
321
322
323
324
325
326
327
328
329
330 Volume buildModule(Element detector, String name, LCDD lcdd, SensitiveDetector sens, VisAttributes vis) throws Exception
331 {
332 String detector_name = detector.getAttributeValue("name");
333 Volume module_volume = null;
334
335 int sensor_number = 0;
336
337 VisAttributes visOff = lcdd.getVisAttributes("InvisibleNoDaughters");
338
339
340 for (Iterator i = detector.getChildren("module").iterator(); i.hasNext();)
341 {
342 Element module_element = (Element) i.next();
343
344 if (module_element.getAttributeValue("name").compareTo(name) == 0)
345 {
346 Element module_envelope_element = module_element.getChild("module_envelope");
347
348 String module_name = detector_name + "_" + module_element.getAttributeValue("name");
349
350
351 double module_length = module_envelope_element.getAttribute("length").getDoubleValue();
352 double module_width = module_envelope_element.getAttribute("width").getDoubleValue();
353 double module_thickness = module_envelope_element.getAttribute("thickness").getDoubleValue();
354 Box module_box = new Box(module_name + "_box");
355 module_box.setX(module_width);
356 module_box.setY(module_length);
357 module_box.setZ(module_thickness);
358 lcdd.getSolids().addSolid(module_box);
359
360
361 module_volume = new Volume(module_name);
362 module_volume.setMaterial(lcdd.getMaterial("Air"));
363 module_volume.setSolid(module_box);
364
365
366 int ncomponents = 0;
367 for (Iterator j = module_element.getChildren("module_component").iterator(); j.hasNext(); ++ncomponents)
368 {
369 Element component_element = (Element) j.next();
370
371 boolean sensitive = ((component_element.getAttribute("sensitive") == null) ? false : component_element.getAttribute("sensitive").getBooleanValue());
372
373 String component_name = module_name + "_component" + ncomponents;
374
375
376
377
378
379
380
381 double component_length = component_element.getAttribute("length").getDoubleValue();
382 double component_width = component_element.getAttribute("width").getDoubleValue();
383 double component_thickness = component_element.getAttribute("thickness").getDoubleValue();
384 Box component_box = new Box(component_name + "_box");
385 component_box.setX(component_width);
386 component_box.setY(component_length);
387 component_box.setZ(component_thickness);
388 lcdd.getSolids().addSolid(component_box);
389
390
391 Volume component_volume = new Volume(component_name);
392 Material component_material = lcdd.getMaterial(component_element.getAttributeValue("material"));
393 component_volume.setMaterial(component_material);
394 component_volume.setSolid(component_box);
395
396 lcdd.getStructure().addVolume(component_volume);
397
398 PhysVol component_physvol = new PhysVol(component_volume);
399
400
401
402 if (component_element.getChild("position") != null)
403 {
404 Element pos_elem = component_element.getChild("position");
405
406 Position component_position = new Position(component_name + "_position");
407
408 if (pos_elem.getAttribute("x") != null)
409 {
410 component_position.setX(pos_elem.getAttribute("x").getDoubleValue());
411 }
412
413 if (pos_elem.getAttribute("y") != null)
414 {
415 component_position.setY(pos_elem.getAttribute("y").getDoubleValue());
416 }
417
418 if (pos_elem.getAttribute("z") != null)
419 {
420 component_position.setZ(pos_elem.getAttribute("z").getDoubleValue());
421 }
422
423 lcdd.getDefine().addPosition(component_position);
424 component_physvol.setPosition(component_position);
425 }
426
427
428
429 if (component_element.getChild("rotation") != null)
430 {
431 Element rot_elem = component_element.getChild("rotation");
432
433 Rotation component_rotation = new Rotation(component_name + "_rotation");
434
435 if (rot_elem.getAttribute("x") != null)
436 {
437 component_rotation.setX(rot_elem.getAttribute("x").getDoubleValue());
438 }
439
440 if (rot_elem.getAttribute("y") != null)
441 {
442 component_rotation.setY(rot_elem.getAttribute("y").getDoubleValue());
443 }
444
445 if (rot_elem.getAttribute("z") != null)
446 {
447 component_rotation.setZ(rot_elem.getAttribute("z").getDoubleValue());
448 }
449
450 component_physvol.setRotation(component_rotation);
451
452 lcdd.getDefine().addRotation(component_rotation);
453 }
454
455 if (sensitive)
456 {
457 component_volume.setSensitiveDetector(sens);
458 component_physvol.addPhysVolID("sensor", sensor_number);
459 ++sensor_number;
460 }
461
462 setRegion(lcdd, component_element, component_volume);
463 setLimitSet(lcdd, component_element, component_volume);
464
465 component_volume.setVisAttributes(visOff);
466
467 module_volume.addPhysVol(component_physvol);
468 }
469
470 if (vis != null)
471 module_volume.setVisAttributes(vis);
472 break;
473 }
474 }
475
476 if (module_volume == null)
477 {
478 throw new RuntimeException("Failed to find module " + name);
479 }
480
481
482 lcdd.getStructure().addVolume(module_volume);
483
484 return module_volume;
485 }
486
487 public boolean isTracker()
488 {
489 return true;
490 }
491 }