1 package org.lcsim.geometry.compact;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.net.MalformedURLException;
7 import java.net.URL;
8 import java.util.ArrayList;
9 import java.util.HashMap;
10 import java.util.Iterator;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Map.Entry;
14 import java.util.Scanner;
15
16 import org.jdom.Document;
17 import org.jdom.Element;
18 import org.jdom.JDOMException;
19 import org.jdom.input.SAXBuilder;
20 import org.lcsim.geometry.util.BaseIDDecoder;
21 import org.lcsim.material.XMLMaterialManager;
22 import org.lcsim.units.clhep.Constants;
23 import org.lcsim.util.xml.ClasspathEntityResolver;
24 import org.lcsim.util.xml.ElementFactory;
25 import org.lcsim.util.xml.ElementFactory.ElementCreationException;
26 import org.lcsim.util.xml.JDOMExpressionFactory;
27
28 import Jama.Matrix;
29
30
31
32
33
34
35
36
37
38
39
40
41 public class CompactReader {
42 private ElementFactory factory;
43 private JDOMExpressionFactory expr;
44 private Document doc;
45 private XMLMaterialManager xmat;
46
47
48
49
50 public CompactReader() {
51 this(new CompactElementFactory());
52 }
53
54
55
56
57
58
59 public CompactReader(ElementFactory factory) {
60 this.factory = factory;
61 }
62
63
64
65
66
67
68
69
70
71
72
73 public Detector read(InputStream in) throws IOException, JDOMException, ElementCreationException {
74 expr = new JDOMExpressionFactory();
75
76
77 registerCLHEPConstants(expr);
78
79 SAXBuilder builder = new SAXBuilder();
80 builder.setFactory(expr);
81
82
83 builder.setValidation(true);
84 builder.setFeature("http://apache.org/xml/features/validation/schema", true);
85
86
87 builder.setEntityResolver(new ClasspathEntityResolver());
88
89 doc = builder.build(in);
90
91 Element compact = doc.getRootElement();
92 Detector det = factory.createElement(Detector.class, compact, null);
93
94 readHeader(compact, det);
95 readConstants(compact, det);
96 readMatrices(compact, det);
97 readRegions(compact, det);
98 readLimits(compact, det);
99 readMaterials(compact, det);
100 Map<String, Readout> readoutMap = readReadouts(compact, det);
101 readVisAttributes(compact, det);
102 readSubdetectors(compact, det, readoutMap);
103 readFields(compact, det);
104 readIncludes(compact, det);
105
106 return det;
107 }
108
109 private void readConstants(Element lccdd, Detector det) throws JDOMException, ElementCreationException {
110 Element define = lccdd.getChild("define");
111 for (Iterator i = define.getChildren("constant").iterator(); i.hasNext();) {
112 Element constant = (Element) i.next();
113 Constant c = factory.createElement(Constant.class, constant, null);
114 expr.addConstant(c.getName(), c.getValue());
115 det.addConstant(c);
116 }
117 }
118
119 private void readMatrices(Element compact, Detector det) {
120 Element define = compact.getChild("define");
121 for (Iterator iterator = define.getChildren("matrix").iterator(); iterator.hasNext();) {
122 Element element = (Element)iterator.next();
123 String name = element.getAttributeValue("name");
124 int coldim = Integer.parseInt(element.getAttributeValue("coldim"));
125 String rawValues = element.getAttributeValue("values");
126 Scanner scanner = new Scanner(rawValues);
127 List<double[]> rows = new ArrayList<double[]>();
128 while (scanner.hasNextDouble()) {
129 double[] row = new double[coldim];
130 for (int i=0; i<coldim; i++) {
131 double value = scanner.nextDouble();
132 row[i] = value;
133 }
134 rows.add(row);
135 }
136 double[][] array = new double[rows.size()][coldim];
137 for (int i=0, n=rows.size(); i<n; i++) {
138 array[i] = rows.get(i);
139 }
140 Matrix matrix = new Matrix(array);
141 det.addMatrix(name, matrix);
142 }
143 }
144
145 private void readHeader(Element lccdd, Detector det) throws JDOMException, ElementCreationException {
146 Element info = lccdd.getChild("info");
147 det.setHeader(factory.createElement(Header.class, info, null));
148 }
149
150 private void readRegions(Element lccdd, Detector det) throws JDOMException, ElementCreationException {
151 Element regions = lccdd.getChild("regions");
152 if (regions != null) {
153 for (Iterator i = regions.getChildren("region").iterator(); i.hasNext();) {
154 Element region = (Element) i.next();
155 Region r = factory.createElement(Region.class, region, null);
156 det.addRegion(r);
157 }
158 }
159 }
160
161 private void readLimits(Element lccdd, Detector det) throws JDOMException, ElementCreationException {
162 Element limits = lccdd.getChild("limits");
163 if (limits != null) {
164 for (Iterator i = limits.getChildren("limitset").iterator(); i.hasNext();) {
165 Element limitset = (Element) i.next();
166 LimitSet ls = factory.createElement(LimitSet.class, limitset, null);
167 det.addLimitSet(ls);
168 }
169 }
170 }
171
172 private Map<String, Readout> readReadouts(Element lccdd, Detector det) throws JDOMException, ElementCreationException {
173 Map<String, Readout> readoutMap = new HashMap<String, Readout>();
174 Element readouts = lccdd.getChild("readouts");
175 for (Iterator i = readouts.getChildren("readout").iterator(); i.hasNext();) {
176 Element readout = (Element) i.next();
177
178 Readout r = null;
179 try {
180 r = createReadout(readout);
181 } catch (Exception e) {
182 throw new RuntimeException(e);
183 }
184
185 readoutMap.put(r.getName(), r);
186 det.addReadout(r);
187 }
188 return readoutMap;
189 }
190
191 private Readout createReadout(Element readoutElement) throws Exception {
192 Readout readout = factory.createElement(Readout.class, readoutElement, null);
193 Element segmentation = readoutElement.getChild("segmentation");
194
195
196 if (segmentation != null) {
197 String type = segmentation.getAttributeValue("type");
198 Segmentation seg = factory.createElement(Segmentation.class, segmentation, type);
199 readout.setSegmentation(seg);
200 }
201
202 else {
203 readout.setIDDecoder(new BaseIDDecoder());
204 }
205
206 return readout;
207 }
208
209 private void readSubdetectors(Element lccdd, Detector det, Map<String, Readout> readoutMap) throws JDOMException, ElementCreationException {
210 Element detectors = lccdd.getChild("detectors");
211 for (Iterator i = detectors.getChildren("detector").iterator(); i.hasNext();) {
212 Element detector = (Element) i.next();
213 String type = detector.getAttributeValue("type");
214
215 Subdetector sub = factory.createElement(Subdetector.class, detector, type);
216 String readout = detector.getAttributeValue("readout");
217 if (readout != null) {
218 Readout r = readoutMap.get(readout);
219 if (r == null)
220 throw new JDOMException("Unknown readout " + readout);
221 sub.setReadout(r);
222 }
223
224 String visref = detector.getAttributeValue("vis");
225 if (visref != null) {
226 VisAttributes vis = det.getVisAttributes().get(visref);
227 if (vis == null)
228 throw new JDOMException("Unknown vis " + visref + " for subdetector " + sub.getName() + " in compact description.");
229 sub.setVisAttributes(vis);
230 }
231
232 det.addSubdetector(sub);
233 }
234 }
235
236 private void readFields(Element lccdd, Detector det) throws JDOMException, ElementCreationException {
237 Element fields = lccdd.getChild("fields");
238 if (fields != null) {
239 for (Iterator i = fields.getChildren("field").iterator(); i.hasNext();) {
240 Element f = (Element) i.next();
241 String type = f.getAttributeValue("type");
242
243 Field field = factory.createElement(Field.class, f, type);
244 det.addField(field);
245 }
246 }
247 }
248
249 private void readMaterials(org.jdom.Element compact, Detector det) {
250
251
252 XMLMaterialManager.setup();
253
254
255 if (compact.getChild("materials") != null) {
256 xmat = new XMLMaterialManager(compact.getChild("materials"));
257
258
259
260 }
261
262
263
264 det.setXMLMaterialManager(xmat);
265 }
266
267
268
269
270
271
272
273
274
275 private void readVisAttributes(Element lccdd, Detector det) throws JDOMException, ElementCreationException {
276
277 Element display = lccdd.getChild("display");
278 if (display != null) {
279 for (Iterator i = display.getChildren("vis").iterator(); i.hasNext();) {
280 Element vis = (Element) i.next();
281 assert (vis != null);
282 VisAttributes v = factory.createElement(VisAttributes.class, vis, null);
283 det.addVisAttributes(v);
284 }
285
286
287 VisAttributes invisible = new VisAttributes("InvisibleWithDaughters");
288 invisible.setVisible(false);
289 invisible.setShowDaughters(true);
290 det.addVisAttributes(invisible);
291
292
293 VisAttributes invisibleNoDau = new VisAttributes("InvisibleNoDaughters");
294 invisibleNoDau.setVisible(false);
295 invisibleNoDau.setShowDaughters(false);
296 det.addVisAttributes(invisibleNoDau);
297 }
298 }
299
300
301 public static void registerCLHEPConstants(JDOMExpressionFactory f) {
302 Constants constants = Constants.getInstance();
303 for (Entry<String, Double> unit : constants.entrySet()) {
304
305 f.addConstant(unit.getKey(), unit.getValue());
306 }
307 }
308
309 protected void resetDocument() {
310 doc = null;
311 }
312
313 public Document getDocument() {
314 return doc;
315 }
316
317 void readIncludes(Element lccdd, Detector det) {
318 Element includes = lccdd.getChild("includes");
319
320 if (includes == null)
321 return;
322
323 for (Object o : includes.getChildren("gdmlFile")) {
324 Element gdmlFile = (Element) o;
325
326 if (gdmlFile.getAttribute("ref") != null) {
327
328 String ref = gdmlFile.getAttributeValue("ref");
329
330
331
332 try {
333 det.addGDMLReference(new URL(ref));
334 } catch (Exception x) {
335 throw new RuntimeException(x);
336 }
337 } else if (gdmlFile.getAttribute("file") != null) {
338 File file = new File(gdmlFile.getAttributeValue("file"));
339 try {
340 URL url = new URL(file.toURI().toURL().toString());
341 det.addGDMLReference(url);
342 } catch (MalformedURLException e) {
343 throw new RuntimeException(e);
344 }
345 } else {
346 throw new RuntimeException("Missing ref or file attribute on gdmlFile element.");
347 }
348 }
349 }
350 }