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