1 package org.lcsim.detector.converter.compact;
2
3 import java.util.HashMap;
4 import java.util.Iterator;
5 import java.util.Map;
6
7 import org.jdom.Element;
8 import org.jdom.JDOMException;
9 import org.lcsim.detector.DetectorElement;
10 import org.lcsim.detector.DetectorIdentifierHelper;
11 import org.lcsim.detector.IDetectorElement;
12 import org.lcsim.detector.IPhysicalVolume;
13 import org.lcsim.detector.IPhysicalVolumePath;
14 import org.lcsim.detector.LogicalVolume;
15 import org.lcsim.detector.PhysicalVolume;
16 import org.lcsim.detector.RotationGeant;
17 import org.lcsim.detector.Transform3D;
18 import org.lcsim.detector.Translation3D;
19 import org.lcsim.detector.DetectorIdentifierHelper.SystemMap;
20 import org.lcsim.detector.identifier.ExpandedIdentifier;
21 import org.lcsim.detector.identifier.IExpandedIdentifier;
22 import org.lcsim.detector.identifier.IIdentifier;
23 import org.lcsim.detector.identifier.IIdentifierDictionary;
24 import org.lcsim.detector.identifier.IIdentifierHelper;
25 import org.lcsim.detector.identifier.IdentifierUtil;
26 import org.lcsim.detector.material.IMaterial;
27 import org.lcsim.detector.material.MaterialStore;
28 import org.lcsim.detector.solids.Trd;
29 import org.lcsim.detector.tracker.silicon.SiSensor;
30 import org.lcsim.detector.tracker.silicon.SiTrackerIdentifierHelper;
31 import org.lcsim.detector.tracker.silicon.SiTrackerModule;
32 import org.lcsim.geometry.compact.Detector;
33 import org.lcsim.geometry.compact.Subdetector;
34 import org.lcsim.geometry.compact.converter.SiTrackerModuleComponentParameters;
35 import org.lcsim.geometry.compact.converter.SiTrackerModuleParameters;
36 import org.lcsim.geometry.subdetector.SiTrackerEndcap2;
37
38
39
40
41
42
43
44
45 public class SiTrackerEndcap2Converter extends AbstractSubdetectorConverter implements ISubdetectorConverter
46 {
47 Map<String, SiTrackerModuleParameters> moduleParameters = new HashMap<String, SiTrackerModuleParameters>();
48 Map<String, LogicalVolume> modules = new HashMap<String, LogicalVolume>();
49 IMaterial vacuum;
50
51 public IIdentifierHelper makeIdentifierHelper(Subdetector subdetector, SystemMap systemMap)
52 {
53 return new SiTrackerIdentifierHelper(subdetector.getDetectorElement(), makeIdentifierDictionary(subdetector),
54 systemMap);
55 }
56
57 public void convert(Subdetector subdet, Detector detector)
58 {
59 try
60 {
61 Element node = subdet.getNode();
62 String subdetName = node.getAttributeValue("name");
63 vacuum = MaterialStore.getInstance().get("Air");
64
65 boolean reflect;
66 if (node.getAttribute("reflect") != null)
67 reflect = node.getAttribute("reflect").getBooleanValue();
68 else
69 reflect = true;
70
71 IDetectorElement subdetDetElem = subdet.getDetectorElement();
72 DetectorIdentifierHelper helper = (DetectorIdentifierHelper)subdetDetElem.getIdentifierHelper();
73 int nfields = helper.getIdentifierDictionary().getNumberOfFields();
74 IDetectorElement endcapPos = null;
75 IDetectorElement endcapNeg = null;
76 try
77 {
78
79 IExpandedIdentifier endcapPosId = new ExpandedIdentifier(nfields);
80 endcapPosId.setValue(helper.getFieldIndex("system"), subdet.getSystemID());
81 endcapPosId.setValue(helper.getFieldIndex("barrel"), helper.getEndcapPositiveValue());
82 endcapPos = new DetectorElement(subdet.getName() + "_positive", subdetDetElem);
83 endcapPos.setIdentifier(helper.pack(endcapPosId));
84
85
86 if (reflect)
87 {
88 IExpandedIdentifier endcapNegId = new ExpandedIdentifier(nfields);
89 endcapNegId.setValue(helper.getFieldIndex("system"), subdet.getSystemID());
90 endcapNegId.setValue(helper.getFieldIndex("barrel"), helper.getEndcapNegativeValue());
91 endcapNeg = new DetectorElement(subdet.getName() + "_negative", subdetDetElem);
92 endcapNeg.setIdentifier(helper.pack(endcapNegId));
93 }
94
95 }
96 catch (Exception x)
97 {
98 throw new RuntimeException(x);
99 }
100
101 for (Iterator i = node.getChildren("module").iterator(); i.hasNext();)
102 {
103 Element module = (Element)i.next();
104 String moduleName = module.getAttributeValue("name");
105 moduleParameters.put(moduleName, new SiTrackerModuleParameters(module));
106 modules.put(moduleName, makeModule(moduleParameters.get(moduleName)));
107 }
108
109 for (Iterator i = node.getChildren("layer").iterator(); i.hasNext();)
110 {
111 Element layerElement = (Element)i.next();
112
113 int layerId = layerElement.getAttribute("id").getIntValue();
114
115
116 IExpandedIdentifier layerPosId = new ExpandedIdentifier(nfields);
117 layerPosId.setValue(helper.getFieldIndex("system"), subdet.getSystemID());
118 layerPosId.setValue(helper.getFieldIndex("barrel"), helper.getEndcapPositiveValue());
119 layerPosId.setValue(helper.getFieldIndex("layer"), layerId);
120 IDetectorElement layerPos =
121 new DetectorElement(endcapPos.getName() + "_layer" + layerId, endcapPos, helper
122 .pack(layerPosId));
123
124
125 IDetectorElement layerNeg = null;
126 if (reflect)
127 {
128 IExpandedIdentifier layerNegId = new ExpandedIdentifier(nfields);
129 layerNegId.setValue(helper.getFieldIndex("system"), subdet.getSystemID());
130 layerNegId.setValue(helper.getFieldIndex("barrel"), helper.getEndcapNegativeValue());
131 layerNegId.setValue(helper.getFieldIndex("layer"), layerId);
132 layerNeg =
133 new DetectorElement(endcapNeg.getName() + "_layer" + layerId, endcapNeg, helper
134 .pack(layerNegId));
135 }
136
137 int moduleNumber = 0;
138 for (Iterator j = layerElement.getChildren("ring").iterator(); j.hasNext();)
139 {
140 Element ringElement = (Element)j.next();
141 double r = ringElement.getAttribute("r").getDoubleValue();
142 double phi0 = 0;
143 if (ringElement.getAttribute("phi0") != null)
144 {
145 phi0 = ringElement.getAttribute("phi0").getDoubleValue();
146 }
147 double zstart = ringElement.getAttribute("zstart").getDoubleValue();
148 double dz = Math.abs(ringElement.getAttribute("dz").getDoubleValue());
149 int nmodules = ringElement.getAttribute("nmodules").getIntValue();
150 String module = ringElement.getAttributeValue("module");
151 LogicalVolume moduleVolume = modules.get(module);
152 if (moduleVolume == null)
153 throw new RuntimeException("Module " + module + " was not found.");
154 double iphi = (2 * Math.PI) / nmodules;
155 double phi = phi0;
156 for (int k = 0; k < nmodules; k++ )
157 {
158 String moduleBaseName = subdetName + "_layer" + layerId + "_module" + moduleNumber;
159
160 double x = r * Math.cos(phi);
161 double y = r * Math.sin(phi);
162
163
164 Translation3D p = new Translation3D(x, y, zstart + dz);
165 RotationGeant rot = new RotationGeant(-Math.PI / 2, -Math.PI / 2 - phi, 0);
166 new PhysicalVolume(new Transform3D(p, rot), moduleBaseName, moduleVolume, detector
167 .getTrackingVolume().getLogicalVolume(), k);
168 String path = "/" + detector.getTrackingVolume().getName() + "/" + moduleBaseName;
169 IDetectorElement modulePos = new SiTrackerModule(moduleBaseName, layerPos, path, moduleNumber);
170
171
172 if (reflect)
173 {
174 Translation3D pr = new Translation3D(x, y, -zstart - dz);
175 RotationGeant rotr = new RotationGeant(-Math.PI / 2, -Math.PI / 2 - phi, Math.PI);
176
177 String path2 =
178 "/" + detector.getTrackingVolume().getName() + "/" + moduleBaseName + "_reflected";
179 new PhysicalVolume(new Transform3D(pr, rotr), moduleBaseName + "_reflected", moduleVolume,
180 detector.getTrackingVolume().getLogicalVolume(), k);
181 new SiTrackerModule(moduleBaseName + "_reflected", layerNeg, path2, moduleNumber);
182 }
183
184 dz = -dz;
185 phi += iphi;
186 ++moduleNumber;
187 }
188 }
189 }
190 }
191 catch (JDOMException except)
192 {
193 throw new RuntimeException(except);
194 }
195
196
197 setupSensorDetectorElements(subdet);
198 }
199
200 private LogicalVolume makeModule(SiTrackerModuleParameters params)
201 {
202 double thickness = params.getThickness();
203 double dx1, dx2, dy1, dy2, dz;
204 dy1 = dy2 = thickness / 2;
205 dx1 = params.getDimension(0);
206 dx2 = params.getDimension(1);
207 dz = params.getDimension(2);
208 Trd envelope = new Trd(params.getName() + "Trd", dx1, dx2, dy1, dy2, dz);
209 LogicalVolume volume = new LogicalVolume(params.getName() + "Volume", envelope, vacuum);
210 makeModuleComponents(volume, params);
211 return volume;
212 }
213
214 private void makeModuleComponents(LogicalVolume moduleVolume, SiTrackerModuleParameters moduleParameters)
215 {
216 Trd trd = (Trd)moduleVolume.getSolid();
217
218 double x1 = trd.getXHalfLength1();
219 double x2 = trd.getXHalfLength2();
220 double y1 = trd.getYHalfLength1();
221 double z = trd.getZHalfLength();
222
223 double posY = -y1;
224
225 String moduleName = moduleVolume.getName();
226
227 int sensor = 0;
228 for (SiTrackerModuleComponentParameters component : moduleParameters)
229 {
230 double thickness = component.getThickness();
231
232 IMaterial material = MaterialStore.getInstance().get(component.getMaterialName());
233 if (material == null)
234 {
235 throw new RuntimeException("The material " + component.getMaterialName()
236 + " does not exist in the materials database.");
237 }
238 boolean sensitive = component.isSensitive();
239 int componentNumber = component.getComponentNumber();
240
241 posY += thickness / 2;
242
243 String componentName = moduleName + "_component" + componentNumber;
244
245 Trd sliceTrd = new Trd(componentName + "_trd", x1, x2, thickness / 2, thickness / 2, z);
246
247 LogicalVolume volume = new LogicalVolume(componentName, sliceTrd, material);
248
249 double zrot = 0;
250 if (sensitive)
251 {
252 if (sensor > 1)
253 {
254 throw new RuntimeException("Exceeded maximum of 2 sensors per module.");
255 }
256
257 if (sensor == 0)
258 {
259 zrot = Math.PI;
260 }
261 ++sensor;
262 }
263 Translation3D position = new Translation3D(0., posY, 0);
264 RotationGeant rotation = new RotationGeant(0, 0, zrot);
265 PhysicalVolume pv =
266 new PhysicalVolume(new Transform3D(position, rotation), componentName, volume, moduleVolume,
267 componentNumber);
268 pv.setSensitive(sensitive);
269
270 posY += thickness / 2;
271 }
272 }
273
274 private void setupSensorDetectorElements(Subdetector subdet)
275 {
276 SiTrackerIdentifierHelper helper = (SiTrackerIdentifierHelper)subdet.getDetectorElement().getIdentifierHelper();
277
278 for (IDetectorElement endcap : subdet.getDetectorElement().getChildren())
279 {
280 for (IDetectorElement layer : endcap.getChildren())
281 {
282 for (IDetectorElement module : layer.getChildren())
283 {
284 IPhysicalVolume modulePhysVol = module.getGeometry().getPhysicalVolume();
285 IPhysicalVolumePath modulePath = module.getGeometry().getPath();
286 int sensorId = 0;
287 for (IPhysicalVolume pv : modulePhysVol.getLogicalVolume().getDaughters())
288 {
289 if (pv.isSensitive())
290 {
291 IIdentifierDictionary iddict =
292 subdet.getDetectorElement().getIdentifierHelper().getIdentifierDictionary();
293
294 ExpandedIdentifier expId = new ExpandedIdentifier(iddict.getNumberOfFields());
295 expId.setValue(iddict.getFieldIndex("system"), subdet.getSystemID());
296
297 if (helper.isEndcapPositive(endcap.getIdentifier()))
298 {
299 expId.setValue(iddict.getFieldIndex("barrel"), helper.getEndcapPositiveValue());
300 }
301 else if (helper.isEndcapNegative(endcap.getIdentifier()))
302 {
303 expId.setValue(iddict.getFieldIndex("barrel"), helper.getEndcapNegativeValue());
304 }
305 else
306 {
307 throw new RuntimeException(endcap.getName() + " is not a positive or negative endcap!");
308 }
309 expId.setValue(iddict.getFieldIndex("layer"), layer.getIdentifierHelper().getValue(
310 layer.getIdentifier(), "layer"));
311 expId.setValue(iddict.getFieldIndex("module"), ((SiTrackerModule)module).getModuleId());
312 expId.setValue(iddict.getFieldIndex("sensor"), sensorId);
313
314 IIdentifier id = iddict.pack(expId);
315
316 String sensorPath = modulePath.toString() + "/" + pv.getName();
317 String sensorName = module.getName() + "_sensor" + sensorId;
318
319 SiSensor sensor = new SiSensor(sensorId, sensorName, module, sensorPath, id);
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363 ++sensorId;
364 }
365 }
366 }
367 }
368 }
369 }
370
371 public Class getSubdetectorType()
372 {
373 return SiTrackerEndcap2.class;
374 }
375 }