1 package org.lcsim.geometry.compact.converter.lcdd.util;
2
3 import java.io.InputStream;
4 import java.util.HashMap;
5 import java.util.Iterator;
6 import java.util.List;
7 import java.util.Map;
8
9 import org.jdom.Attribute;
10 import org.jdom.Document;
11 import org.jdom.Element;
12 import org.jdom.JDOMException;
13 import org.jdom.Namespace;
14 import org.jdom.input.SAXBuilder;
15 import org.lcsim.geometry.compact.converter.lcdd.LCDDSubdetector;
16 import org.lcsim.material.XMLMaterialManager;
17
18
19
20
21
22 public class LCDD extends Element {
23 private Map materials = new HashMap();
24 Volume worldVolume = null;
25 Volume trackingVolume = null;
26 LCDDMaterialHelper matHelper = new LCDDMaterialHelper(XMLMaterialManager.getDefaultMaterialManager());
27
28 public LCDD() {
29 super("lcdd");
30
31 build();
32 }
33
34 private void build() {
35 addNamespaceDeclaration(Namespace.getNamespace("lcdd", "http://www.lcsim.org/schemas/lcdd/1.0"));
36
37 setAttribute("noNamespaceSchemaLocation", "http://www.lcsim.org/schemas/lcdd/1.0/lcdd.xsd", Namespace.getNamespace("xs", "http://www.w3.org/2001/XMLSchema-instance"));
38
39 Header header = new Header();
40 addContent(header);
41
42 Element iddict = new Element("iddict");
43 addContent(iddict);
44
45 Element sensitiveDetectors = new Element("sensitive_detectors");
46 addContent(sensitiveDetectors);
47
48 Element limits = new Element("limits");
49 addContent(limits);
50
51 Element regions = new Element("regions");
52 addContent(regions);
53
54 Element display = new Element("display");
55 addContent(display);
56
57
58
59
60
61
62
63
64
65
66
67
68
69 Element gdml = new Element("gdml");
70 addContent(gdml);
71
72 gdml.addContent(new Define());
73
74 gdml.addContent(new Element("materials"));
75
76 Solids solids = new Solids();
77 gdml.addContent(solids);
78
79 Structure structure = new Structure();
80 gdml.addContent(structure);
81
82 Box worldSolid = new Box("world_box");
83 worldSolid.setAttribute("x", "world_x");
84 worldSolid.setAttribute("y", "world_y");
85 worldSolid.setAttribute("z", "world_z");
86 solids.addSolid(worldSolid);
87
88 this.worldVolume = new Volume("world_volume");
89 worldVolume.setSolid(worldSolid);
90 structure.setWorldVolume(worldVolume);
91
92 Tube trackingSolid = new Tube("tracking_cylinder");
93 trackingSolid.setAttribute("rmax", "tracking_region_radius");
94 trackingSolid.setAttribute("z", "2*tracking_region_zmax");
95 trackingSolid.setAttribute("deltaphi", String.valueOf(2 * Math.PI));
96 solids.addSolid(trackingSolid);
97
98 this.trackingVolume = new Volume("tracking_volume");
99 trackingVolume.setSolid(trackingSolid);
100 structure.setTrackingVolume(trackingVolume);
101 worldVolume.addPhysVol(new PhysVol(trackingVolume));
102
103 Element setup = new Element("setup");
104 setup.setAttribute("name", "Default");
105 setup.setAttribute("version", "1.0");
106 Element world = new Element("world");
107 world.setAttribute("ref", worldVolume.getRefName());
108 setup.addContent(world);
109 gdml.addContent(setup);
110
111 Element fields = new Element("fields");
112 addContent(fields);
113 }
114
115 private final Material getWorldMaterial() {
116 Material m = null;
117 try {
118
119 m = this.getMaterial("WorldMaterial");
120 } catch (JDOMException x) {
121 try {
122
123 m = this.getMaterial("Air");
124 } catch (JDOMException x2) {
125
126 throw new RuntimeException(x);
127 }
128 }
129 return m;
130 }
131
132 private final Material getTrackingMaterial() {
133 Material m = null;
134 try {
135
136 m = this.getMaterial("TrackingMaterial");
137 } catch (JDOMException x) {
138 try {
139
140 m = this.getMaterial("Air");
141 } catch (JDOMException x2) {
142
143 throw new RuntimeException(x);
144 }
145 }
146 return m;
147 }
148
149 public void cleanUp() throws JDOMException {
150 Structure structure = getStructure();
151 Volume trackingVolume = structure.getTrackingVolume();
152 trackingVolume.setMaterial(getTrackingMaterial());
153
154
155 structure.removeContent(trackingVolume);
156 structure.addContent(trackingVolume);
157
158 Region trackingRegion = new Region("TrackingRegion");
159 trackingRegion.setThreshold(1);
160 trackingRegion.setStoreSecondaries(true);
161 addRegion(trackingRegion);
162 trackingVolume.setRegion(trackingRegion);
163
164 Volume worldVolume = structure.getWorldVolume();
165 worldVolume.setMaterial(getWorldMaterial());
166
167
168 structure.removeContent(worldVolume);
169 structure.addContent(worldVolume);
170
171
172 VisAttributes worldVis = new VisAttributes("WorldVis");
173 worldVis.setVisible(false);
174 this.getWorldVolume().setVisAttributes(worldVis);
175 this.add(worldVis);
176
177
178 VisAttributes trackingVis = new VisAttributes("TrackingVis");
179 trackingVis.setVisible(false);
180 this.getTrackingVolume().setVisAttributes(trackingVis);
181 this.add(trackingVis);
182 }
183
184 public Solids getSolids() {
185 return (Solids) getChild("gdml").getChild("solids");
186 }
187
188 public Solid getSolid(String name) {
189 Solid solid = null;
190 for (Object object : getSolids().getChildren()) {
191 solid = (Solid) object;
192 if (solid != null) {
193 if (solid.getAttributeValue("name").compareTo(name) == 0) {
194 return solid;
195 }
196 }
197 }
198 return null;
199 }
200
201 public void add(Constant constant) {
202 getDefine().addConstant(constant);
203 }
204
205 public void add(Matrix matrix) {
206 getDefine().addMatrix(matrix);
207 }
208
209 public void add(Position position) {
210 getDefine().addPosition(position);
211 }
212
213 public void add(Rotation rotation) {
214 getDefine().addRotation(rotation);
215 }
216
217 public void add(Solid solid) {
218 getSolids().addSolid(solid);
219 }
220
221 public void add(Volume volume) {
222 getStructure().addVolume(volume);
223 }
224
225 public void add(Region region) {
226 getChild("regions").addContent(region);
227 }
228
229 public void add(IDSpec spec) {
230 getChild("iddict").addContent(spec);
231 }
232
233 public void add(LimitSet limitset) {
234 getChild("limits").addContent(limitset);
235 }
236
237 public void add(VisAttributes vis) {
238 getChild("display").addContent(vis);
239 }
240
241 public VisAttributes getVisAttributes(String name) {
242 VisAttributes vis = null;
243 for (Iterator i = getChild("display").getChildren("vis").iterator(); i.hasNext();) {
244 VisAttributes thisvis = (VisAttributes) i.next();
245 if (thisvis.getRefName().compareTo(name) == 0) {
246 vis = thisvis;
247 break;
248 }
249 }
250 return vis;
251 }
252
253 public Structure getStructure() {
254 return (Structure) getChild("gdml").getChild("structure");
255 }
256
257
258 public Material getMaterial(String name) throws JDOMException {
259
260
261 Material mat = (Material) materials.get(name);
262
263
264
265
266
267
268
269
270
271
272 if (mat == null) {
273
274
275
276 matHelper.resolveLCDDMaterialReference(name, this);
277 }
278
279
280 mat = (Material) materials.get(name);
281
282 if (mat == null) {
283
284 throw new JDOMException("Material " + name + " was not found.");
285 }
286
287 return mat;
288 }
289
290 public Define getDefine() {
291 return (Define) getChild("gdml").getChild("define");
292 }
293
294 public Header getHeader() {
295 return (Header) getChild("header");
296 }
297
298 public void addMaterial(Material material) {
299 if (materials.get(material.getRefName()) == null) {
300 getChild("gdml").getChild("materials").addContent(material);
301 materials.put(material.getRefName(), material);
302 }
303 }
304
305 public void addElement(Element element) {
306 if (getElement(element.getAttributeValue("name")) == null) {
307 getChild("gdml").getChild("materials").addContent(element);
308 }
309 }
310
311 public Element getElement(String elemName) {
312 Element e = null;
313 for (Object o : getChild("gdml").getChild("materials").getChildren("element")) {
314 Element ee = (Element) o;
315 if (ee.getAttributeValue("name").contentEquals(elemName)) {
316 e = ee;
317 break;
318 }
319 }
320 return e;
321 }
322
323 public void addIDSpec(IDSpec spec) {
324 getChild("iddict").addContent(spec);
325 }
326
327 public void addSensitiveDetector(SensitiveDetector det) {
328 getChild("sensitive_detectors").addContent(det);
329 }
330
331 public void add(Field field) {
332 getChild("fields").addContent(field);
333 }
334
335 public void setGlobalField(Field field) {
336 Element fields = getChild("fields");
337 fields.addContent(field);
338
339 Element fieldRef = new Element("fieldref");
340 fieldRef.setAttribute("ref", field.getRefName());
341
342 Element globalField = new Element("global_field");
343 globalField.addContent(fieldRef);
344 fields.addContent(globalField);
345 }
346
347 public void addRegion(Region region) {
348 getChild("regions").addContent(region);
349 }
350
351 public Element getRegions() {
352 return getChild("regions");
353 }
354
355 public Region getRegion(String name) {
356 Region region = null;
357 for (Iterator i = getChild("regions").getChildren("region").iterator(); i.hasNext();) {
358 Region thisregion = (Region) i.next();
359 if (thisregion.getRefName().compareTo(name) == 0) {
360 region = thisregion;
361 break;
362 }
363 }
364 return region;
365 }
366
367
368
369
370
371
372
373
374
375
376 public Volume pickMotherVolume(LCDDSubdetector subdet) {
377 Attribute insideAttrib = subdet.getElement().getAttribute("insideTrackingVolume");
378 boolean inside = false;
379
380 try {
381 if (insideAttrib == null) {
382 if (subdet.isTracker()) {
383 inside = true;
384 } else {
385 inside = false;
386 }
387 } else {
388 inside = insideAttrib.getBooleanValue();
389 }
390 } catch (org.jdom.DataConversionException dce) {
391 throw new RuntimeException("Error converting insideTrackingVolume attribute.", dce);
392 }
393
394 Volume motherVolume = (inside ? getStructure().getTrackingVolume() : getStructure().getWorldVolume());
395
396 if (motherVolume == null) {
397 throw new RuntimeException("Picked a null mother volume.");
398 }
399
400
401
402
403 return motherVolume;
404 }
405
406 public void addLimitSet(LimitSet limitset) {
407 getChild("limits").addContent(limitset);
408 }
409
410 public LimitSet getLimitSet(String name) {
411 LimitSet limitset = null;
412 for (Iterator i = getChild("limits").getChildren("limitset").iterator(); i.hasNext();) {
413 LimitSet thislimitset = (LimitSet) i.next();
414 if (thislimitset.getRefName().compareTo(name) == 0) {
415 limitset = thislimitset;
416 break;
417 }
418 }
419 return limitset;
420 }
421
422 public Volume getWorldVolume() {
423 return this.worldVolume;
424 }
425
426 public Volume getTrackingVolume() {
427 return this.trackingVolume;
428 }
429
430 public Volume getVolume(String name) {
431 for (Iterator i = getChild("structure").getChildren("volume").iterator(); i.hasNext();) {
432 Volume vol = (Volume) i.next();
433 if (vol.getRefName().compareTo(name) == 0) {
434 return vol;
435 }
436 }
437 return null;
438 }
439
440
441
442
443
444
445 public void mergeGDML(InputStream in) {
446
447
448 SAXBuilder builder = new SAXBuilder();
449 Document doc = null;
450 try {
451 doc = builder.build(in);
452 } catch (Exception x) {
453 throw new RuntimeException(x);
454 }
455
456 Element root = doc.getRootElement();
457
458 if (!root.getName().equals("gdml")) {
459 throw new RuntimeException("Document is not a valid GDML file.");
460 }
461
462 Element gdml = getChild("gdml");
463
464
465
466 Element targetWorld = null;
467 Element targetTracking = null;
468 for (Object o : gdml.getChild("structure").getChildren()) {
469 Element e = (Element) o;
470 if (e.getAttributeValue("name").equals("world_volume")) {
471 targetWorld = e;
472 } else if (e.getAttributeValue("name").equals("tracking_volume")) {
473 targetTracking = e;
474 }
475 }
476
477
478 for (Object o1 : root.getChildren()) {
479 Element section = (Element) o1;
480
481
482
483
484 if (!section.getName().equals("setup")) {
485 Element target = gdml.getChild(section.getName());
486
487
488 for (Object o2 : section.getChildren()) {
489 Element element = (Element) o2;
490
491
492 if (element.getName().equals("volume") && (element.getAttributeValue("name").equals("world_volume") || element.getAttributeValue("name").equals("tracking_volume"))) {
493 Element targetVol = null;
494
495 if (element.getAttributeValue("name").equals("world_volume")) {
496 targetVol = targetWorld;
497 } else if (element.getAttributeValue("name").equals("tracking_volume")) {
498 targetVol = targetTracking;
499 }
500
501 for (Object o : element.getChildren("physvol")) {
502 Element physvol = (Element) o;
503 boolean skip = false;
504 if (targetTracking != null && physvol.getChild("volumeref").getAttributeValue("ref").equals("tracking_volume"))
505 skip = true;
506 if (!skip)
507 targetVol.addContent((Element) physvol.clone());
508 }
509 }
510
511 else {
512
513 List targetElements = target.getChildren(element.getName());
514 boolean dup = false;
515 for (Object o : targetElements) {
516 Element targetElement = (Element) o;
517 if (targetElement.getAttributeValue("name").equals(element.getAttributeValue("name"))) {
518 dup = true;
519 break;
520 }
521 }
522
523 if (!dup)
524 target.addContent((Element) element.clone());
525 }
526 }
527 }
528 }
529 }
530 }