1 package org.lcsim.detector.converter.compact;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7
8 import org.jdom.Attribute;
9 import org.jdom.DataConversionException;
10 import org.jdom.Element;
11 import org.lcsim.detector.DetectorElement;
12 import org.lcsim.detector.DetectorIdentifierHelper;
13 import org.lcsim.detector.IDetectorElement;
14 import org.lcsim.detector.ILogicalVolume;
15 import org.lcsim.detector.IPhysicalVolume;
16 import org.lcsim.detector.IPhysicalVolumePath;
17 import org.lcsim.detector.IRotation3D;
18 import org.lcsim.detector.ITransform3D;
19 import org.lcsim.detector.LogicalVolume;
20 import org.lcsim.detector.PhysicalVolume;
21 import org.lcsim.detector.RotationGeant;
22 import org.lcsim.detector.RotationPassiveXYZ;
23 import org.lcsim.detector.Transform3D;
24 import org.lcsim.detector.Translation3D;
25 import org.lcsim.detector.DetectorIdentifierHelper.SystemMap;
26 import org.lcsim.detector.identifier.ExpandedIdentifier;
27 import org.lcsim.detector.identifier.IExpandedIdentifier;
28 import org.lcsim.detector.identifier.IIdentifier;
29 import org.lcsim.detector.identifier.IIdentifierDictionary;
30 import org.lcsim.detector.identifier.IIdentifierHelper;
31 import org.lcsim.detector.identifier.IdentifierDictionaryManager;
32 import org.lcsim.detector.identifier.IdentifierUtil;
33 import org.lcsim.detector.material.IMaterial;
34 import org.lcsim.detector.material.MaterialStore;
35 import org.lcsim.detector.solids.Box;
36 import org.lcsim.detector.solids.Trap;
37 import org.lcsim.detector.solids.Trd;
38 import org.lcsim.detector.solids.Tube;
39 import org.lcsim.detector.tracker.silicon.SiSensor;
40 import org.lcsim.detector.tracker.silicon.SiTrackerIdentifierHelper;
41 import org.lcsim.detector.tracker.silicon.SiTrackerModule;
42 import org.lcsim.geometry.compact.Detector;
43 import org.lcsim.geometry.compact.Subdetector;
44 import org.lcsim.geometry.compact.converter.SiTrackerModuleComponentParameters;
45 import org.lcsim.geometry.compact.converter.SiTrackerModuleParameters;
46 import org.lcsim.geometry.subdetector.SiTrackerEndcap;
47
48
49
50
51
52
53
54
55 public class SiTrackerEndcapConverter extends AbstractSubdetectorConverter implements ISubdetectorConverter
56 {
57 public SiTrackerEndcapConverter()
58 {
59 }
60
61 public IIdentifierHelper makeIdentifierHelper( Subdetector subdetector, SystemMap systemMap )
62 {
63 return new SiTrackerIdentifierHelper( subdetector.getDetectorElement(),
64 makeIdentifierDictionary( subdetector ),
65 systemMap );
66 }
67
68 public void convert( Subdetector subdet, Detector detector )
69 {
70 Map< String, SiTrackerModuleParameters > moduleParameters = new HashMap< String, SiTrackerModuleParameters >();
71
72 IPhysicalVolume trackingPV = detector.getTrackingVolume();
73 ILogicalVolume trackingLV = trackingPV.getLogicalVolume();
74
75 Element node = subdet.getNode();
76
77 IDetectorElement endcapDE = subdet.getDetectorElement();
78
79 DetectorIdentifierHelper helper = ( DetectorIdentifierHelper ) endcapDE.getIdentifierHelper();
80 int nfields = helper.getIdentifierDictionary().getNumberOfFields();
81
82 IDetectorElement endcapPosDE = null;
83 IDetectorElement endcapNegDE = null;
84 try
85 {
86
87 IExpandedIdentifier endcapPosId = new ExpandedIdentifier( nfields );
88 endcapPosId.setValue( helper.getFieldIndex( "system" ), subdet.getSystemID() );
89 endcapPosId.setValue( helper.getFieldIndex( "barrel" ), helper.getEndcapPositiveValue() );
90 endcapPosDE = new DetectorElement( subdet.getName() + "_positive", endcapDE );
91 endcapPosDE.setIdentifier( helper.pack( endcapPosId ) );
92
93
94 IExpandedIdentifier endcapNegId = new ExpandedIdentifier( nfields );
95 endcapNegId.setValue( helper.getFieldIndex( "system" ), subdet.getSystemID() );
96 endcapNegId.setValue( helper.getFieldIndex( "barrel" ), helper.getEndcapNegativeValue() );
97 endcapNegDE = new DetectorElement( subdet.getName() + "_negative", endcapDE );
98 endcapNegDE.setIdentifier( helper.pack( endcapNegId ) );
99
100 }
101 catch ( Exception x )
102 {
103 throw new RuntimeException( x );
104 }
105
106
107 for ( Object n : node.getChildren( "module" ) )
108 {
109 Element e = ( Element ) n;
110 moduleParameters.put( e.getAttributeValue( "name" ), new SiTrackerModuleParameters( e ) );
111 }
112
113 for ( Object o : node.getChildren( "layer" ) )
114 {
115 Element layerElement = ( Element ) o;
116
117 int nwedges;
118 try
119 {
120 nwedges = layerElement.getAttribute( "nwedges" ).getIntValue();
121 }
122 catch ( DataConversionException x )
123 {
124 throw new RuntimeException( x );
125 }
126
127 double innerR, outerR, innerZ, thickness;
128 int layern;
129 try
130 {
131 layern = layerElement.getAttribute( "id" ).getIntValue();
132 innerR = layerElement.getAttribute( "inner_r" ).getDoubleValue();
133 outerR = layerElement.getAttribute( "outer_r" ).getDoubleValue();
134 innerZ = layerElement.getAttribute( "inner_z" ).getDoubleValue();
135 thickness = layerElement.getAttribute( "thickness" ).getDoubleValue();
136 }
137 catch ( DataConversionException x )
138 {
139 throw new RuntimeException( x );
140 }
141
142 ILogicalVolume layerLV = makeLayer(
143 detector,
144 subdet,
145 innerR,
146 outerR,
147 thickness,
148 nwedges,
149 layerElement,
150 moduleParameters );
151
152 double layerZ = innerZ + thickness / 2;
153
154
155 ITransform3D layerTrans = new Transform3D( new Translation3D( 0, 0, layerZ ) );
156 String layerName = layerLV.getName() + "_positive";
157 new PhysicalVolume( layerTrans, layerName, layerLV, trackingLV, layern );
158 String layerPath = "/" + trackingPV.getName() + "/" + layerName;
159 IDetectorElement layerDE = new DetectorElement( layerLV.getName(), endcapPosDE, detector.getNavigator()
160 .getPath( layerPath ) );
161
162
163 ITransform3D layerTransReflect = new Transform3D( new Translation3D( 0, 0, -layerZ ),
164 new RotationPassiveXYZ( 0, Math.PI, 0 ) );
165 String layerNameReflect = layerLV.getName() + "_negative";
166 new PhysicalVolume( layerTransReflect, layerNameReflect, layerLV, trackingLV, layern );
167 String layerPathReflect = "/" + trackingPV.getName() + "/" + layerNameReflect;
168 IDetectorElement layerDEReflect = new DetectorElement( layerNameReflect, endcapNegDE, detector
169 .getNavigator().getPath( layerPathReflect ) );
170
171
172 for ( IPhysicalVolume wedge : layerLV.getDaughters() )
173 {
174
175 String wedgePath = layerPath + "/" + wedge.getName();
176 String wedgeName = layerName + "_wedge" + wedge.getCopyNumber();
177 IDetectorElement wedgeDE = new DetectorElement( wedgeName, layerDE, detector.getNavigator().getPath(
178 wedgePath ) );
179
180
181 String wedgePathReflect = layerPathReflect + "/" + wedge.getName();
182 String wedgeNameReflect = layerNameReflect + "_wedge" + wedge.getCopyNumber();
183 IDetectorElement wedgeDEReflect = new DetectorElement( wedgeNameReflect, layerDEReflect, detector
184 .getNavigator().getPath( wedgePathReflect ) );
185
186
187 for ( IPhysicalVolume module : wedge.getLogicalVolume().getDaughters() )
188 {
189
190 String modulePath = wedgePath + "/" + module.getName();
191 String moduleName = wedgeName + "_module" + module.getCopyNumber();
192 IDetectorElement moduleDE = new SiTrackerModule( moduleName, wedgeDE, detector.getNavigator()
193 .getPath( modulePath ).toString(), module.getCopyNumber() );
194
195
196 String modulePathReflect = wedgePathReflect + "/" + module.getName();
197 String moduleNameReflect = wedgeNameReflect + "_module" + module.getCopyNumber();
198 IDetectorElement moduleDEReflect = new SiTrackerModule( moduleNameReflect, wedgeDEReflect, detector
199 .getNavigator().getPath( modulePathReflect ).toString(), module.getCopyNumber() );
200 }
201 }
202 }
203
204 try
205 {
206 setupSensorDetectorElements( subdet );
207 }
208 catch ( Exception x )
209 {
210 throw new RuntimeException( x );
211 }
212 }
213
214 private ILogicalVolume makeWedge( Detector detector,
215 Subdetector subdet,
216 double innerR,
217 double outerR,
218 double thickness,
219 int nwedges,
220 int layern )
221 {
222 IMaterial material = detector.getTrackingVolume().getLogicalVolume().getMaterial();
223
224 String name = subdet.getName() + "_layer" + layern + "_wedge";
225
226 double wedge_margin = 0.0001;
227
228
229 double dz = ( outerR - innerR ) / 2;
230 double dy1, dy2;
231 dy1 = dy2 = thickness / 2;
232 double dx1, dx2;
233 double dphi = Math.PI / nwedges;
234 dx1 = innerR * Math.tan( dphi ) - wedge_margin / Math.cos( dphi );
235 dx2 = outerR * Math.tan( dphi ) - wedge_margin / Math.cos( dphi );
236
237 Trd wedgeTrd = new Trd( name, dx1, dx2, dy1, dy2, dz );
238
239 ILogicalVolume wedgeLV = new LogicalVolume( name, wedgeTrd, material );
240
241 return wedgeLV;
242 }
243
244 private ILogicalVolume makeLayer( Detector detector,
245 Subdetector subdet,
246 double innerR,
247 double outerR,
248 double thickness,
249 int nwedges,
250 Element layerElement,
251 Map< String, SiTrackerModuleParameters > moduleParameters )
252 {
253 int layern;
254 try
255 {
256 layern = layerElement.getAttribute( "id" ).getIntValue();
257 }
258 catch ( DataConversionException x )
259 {
260 throw new RuntimeException( x );
261 }
262
263 IMaterial material = detector.getTrackingVolume().getLogicalVolume().getMaterial();
264 String layerName = subdet.getName() + "_layer" + layern;
265
266 double dphi = Math.PI / nwedges;
267
268 double tubeInnerR, tubeOuterR;
269 tubeInnerR = innerR;
270 tubeOuterR = outerR / Math.cos( dphi );
271
272 Tube layerTube = new Tube( layerName, tubeInnerR, tubeOuterR, thickness / 2 );
273
274
275 ILogicalVolume layerLV = new LogicalVolume( layerName, layerTube, material );
276
277
278 ILogicalVolume wedgeLV = makeWedge( detector, subdet, innerR, outerR, thickness, nwedges, layern );
279
280 Attribute moduleref = layerElement.getAttribute( "module" );
281
282 if ( moduleref == null )
283 throw new RuntimeException( "module reference is missing for layer number " + layern );
284
285 SiTrackerModuleParameters module = moduleParameters.get( moduleref.getValue() );
286
287
288 makeModules( subdet, wedgeLV, layerElement.getChild( "module_parameters" ), module, layern );
289
290
291 double r = ( innerR + outerR ) / 2;
292
293 for ( int i = 0; i < nwedges; i++ )
294 {
295 double phi = i * 2 * Math.PI / nwedges;
296 double x = r * Math.cos( phi );
297 double y = r * Math.sin( phi );
298
299 Translation3D p = new Translation3D( x, y, 0 );
300 IRotation3D rot = new RotationGeant( -Math.PI / 2, -Math.PI / 2 - phi, 0. );
301 Transform3D transform = new Transform3D( p, rot );
302 new PhysicalVolume( transform, "wedge" + i, wedgeLV, layerLV, i );
303 }
304
305 return layerLV;
306 }
307
308 private void makeModules( Subdetector subdet,
309 ILogicalVolume wedgeLV,
310 Element moduleElement,
311 SiTrackerModuleParameters module,
312 int layern )
313 {
314 double r_size;
315 try
316 {
317 r_size = moduleElement.getAttribute( "r_size" ).getDoubleValue();
318 }
319 catch ( DataConversionException x )
320 {
321 throw new RuntimeException( x );
322 }
323
324 double phi_size_max;
325 try
326 {
327 phi_size_max = moduleElement.getAttribute( "phi_size_max" ).getDoubleValue();
328 }
329 catch ( DataConversionException x )
330 {
331 throw new RuntimeException( x );
332 }
333
334 Trd wedgeTrd = ( Trd ) wedgeLV.getSolid();
335 double dz = ( ( Trd ) wedgeLV.getSolid() ).getZHalfLength();
336 double dx1 = wedgeTrd.getXHalfLength1();
337 double dx2 = wedgeTrd.getXHalfLength2();
338 double dy = wedgeTrd.getYHalfLength1();
339 double deltax = dx2 - dx1;
340 double side_slope = deltax / ( 2 * dz );
341
342 double module_margin = 0.0001;
343
344 double box_margin = module_margin;
345 double side_angle = Math.atan( side_slope );
346 double trap_margin_1 = module_margin * ( 1.0 / Math.cos( side_angle ) - Math.sin( side_angle ) );
347 double trap_margin_2 = module_margin * ( 1.0 / Math.cos( side_angle ) + Math.sin( side_angle ) );
348
349 List< Double > zcenters = new ArrayList< Double >();
350 List< Double > zsizes = new ArrayList< Double >();
351 List< Double > xsizes1 = new ArrayList< Double >();
352 List< Double > xsizes2 = new ArrayList< Double >();
353
354 {
355 double zcurr = dz;
356 while ( zcurr - r_size > -dz )
357 {
358 double zmax = zcurr;
359 double zmin = zcurr - r_size;
360 zcenters.add( ( zmin + zmax ) / 2 );
361 zsizes.add( ( zmax - zmin ) / 2 );
362
363 double xsize1 = dx1 + side_slope * ( zmin + dz );
364 double xsize2 = dx1 + side_slope * ( zmax + dz );
365
366 xsizes1.add( xsize1 );
367 xsizes2.add( xsize2 );
368
369 zcurr -= r_size;
370 }
371 double zmax = zcurr;
372 double zmin = -dz;
373 zcenters.add( ( zmin + zmax ) / 2 );
374 zsizes.add( ( zmax - zmin ) / 2 );
375 double xsize1 = dx1 + side_slope * ( zmin + dz );
376 double xsize2 = dx1 + side_slope * ( zmax + dz );
377 xsizes1.add( xsize1 );
378 xsizes2.add( xsize2 );
379 }
380
381 IMaterial sliceMaterial = wedgeLV.getMaterial();
382
383 double zsize_last = 0.0;
384 double xsize1_min = phi_size_max / 2;
385 double xsize_box = 0.0;
386 int nboxes = 0;
387
388 int imodule = 0;
389
390 for ( int i = zcenters.size() - 1; i >= 0; i-- )
391 {
392
393 if ( zsizes.get( i ) != zsize_last )
394 {
395 zsize_last = zsizes.get( i );
396 xsize1_min = phi_size_max / 2;
397 xsize_box = 0.0;
398 nboxes = 0;
399 }
400
401 int ntraps = ( int ) Math.ceil( 2 * ( xsizes1.get( i ) - nboxes * xsize_box ) / phi_size_max );
402
403
404 if ( ntraps > 2 )
405 {
406 double delta_x = xsizes2.get( i ) - xsizes1.get( i );
407
408 if ( phi_size_max > delta_x )
409 {
410 xsize_box = delta_x * ( int ) Math.floor( phi_size_max / delta_x );
411 }
412 else
413 {
414 xsize_box = delta_x / ( int ) Math.floor( delta_x / phi_size_max );
415 }
416
417 if ( xsize_box > 0.0 )
418 {
419 nboxes = ( int ) Math.floor( ( xsizes1.get( i ) - 2 * xsize1_min ) / xsize_box );
420 }
421 ntraps = 2;
422 }
423
424 double xmin = -nboxes * xsize_box;
425 double xmax = xmin + 2 * xsize_box;
426
427 for ( int ibox = 0; ibox < nboxes; ibox++ )
428 {
429
430 double xcenter = ( xmin + xmax ) / 2;
431 xmin += 2 * xsize_box;
432 xmax += 2 * xsize_box;
433
434 String sliceName = "module" + imodule;
435
436 Box sliceBox = new Box( sliceName, xsize_box - box_margin, dy, zsizes.get( i ) - box_margin );
437
438 ILogicalVolume sliceLV = new LogicalVolume( sliceName, sliceBox, sliceMaterial );
439
440
441 makeBoxModule( sliceLV, module, imodule );
442
443 Transform3D trans = new Transform3D( new Translation3D( xcenter, 0, zcenters.get( i ) ) );
444
445 new PhysicalVolume( trans, sliceName, sliceLV, wedgeLV, imodule );
446
447 imodule++;
448 }
449
450
451 if ( ntraps == 1 )
452 {
453 String sliceName = "module" + imodule;
454
455 Trd sliceTrd = new Trd( sliceName,
456 xsizes1.get( i ) - trap_margin_1,
457 xsizes2.get( i ) - trap_margin_2,
458 dy,
459 dy,
460 zsizes.get( i ) - box_margin );
461
462 ILogicalVolume sliceLV = new LogicalVolume( sliceName, sliceTrd, sliceMaterial );
463
464
465 makeTrdModule( sliceLV, module, imodule );
466
467 Transform3D trans = new Transform3D( new Translation3D( 0, 0, zcenters.get( i ) ) );
468
469 new PhysicalVolume( trans, sliceName, sliceLV, wedgeLV, imodule );
470
471 imodule++;
472 }
473
474
475 if ( ntraps == 2 )
476 {
477
478 double xoffset = xsize_box * nboxes;
479
480 double average_margin_1 = ( box_margin + trap_margin_1 ) / 2;
481 double average_margin_2 = ( box_margin + trap_margin_2 ) / 2;
482
483 double xsize1 = ( xsizes1.get( i ) - xoffset ) / ntraps - average_margin_1;
484 if ( xsize1_min == 0.0 )
485 xsize1_min = xsize1;
486 double xsize2 = ( xsizes2.get( i ) - xoffset ) / ntraps - average_margin_2;
487
488 double xcenter = ( xsize1 + xsize2 ) / 2 + xoffset + box_margin;
489 double theta = Math.abs( Math.atan( side_slope / 2 ) );
490
491 for ( int ix = -1; ix <= 1; ix = ix + 2 )
492 {
493
494 String sliceName = "module" + imodule;
495
496 Trap sliceTrap = new Trap( sliceName,
497 zsizes.get( i ) - box_margin,
498 theta * ix,
499 0.0,
500 dy,
501 xsize1,
502 xsize1,
503 0.0,
504 dy,
505 xsize2,
506 xsize2,
507 0.0 );
508
509 ILogicalVolume sliceLV = new LogicalVolume( sliceName, sliceTrap, sliceMaterial );
510
511 makeTrapModule( sliceLV, module, imodule );
512
513 Transform3D trans = new Transform3D( new Translation3D( ix * xcenter, 0, zcenters.get( i ) ) );
514
515 new PhysicalVolume( trans, sliceName, sliceLV, wedgeLV, imodule );
516
517 imodule++;
518 }
519 }
520 }
521 }
522
523 public void makeBoxModule( ILogicalVolume module, SiTrackerModuleParameters moduleParameters, int moduleTypeId )
524 {
525 Box moduleBox = ( Box ) module.getSolid();
526 double posY = -moduleBox.getYHalfLength();
527 double moduleX = moduleBox.getXHalfLength();
528 double moduleZ = moduleBox.getZHalfLength();
529
530
531
532
533
534 for ( SiTrackerModuleComponentParameters component : moduleParameters )
535 {
536 double thickness = component.getThickness();
537 IMaterial material = MaterialStore.getInstance().get( component.getMaterialName() );
538 boolean sensitive = component.isSensitive();
539 int componentNumber = component.getComponentNumber();
540
541 posY += thickness / 2;
542
543 String componentName = "module" + moduleTypeId + "_component" + componentNumber;
544
545 Box sliceBox = new Box( componentName + "_box", moduleX, thickness / 2, moduleZ );
546
547 ILogicalVolume volume = new LogicalVolume( componentName, sliceBox, material );
548
549 Transform3D trans = new Transform3D( new Translation3D( 0, posY, 0 ) );
550
551 PhysicalVolume pv = new PhysicalVolume( trans, componentName, volume, module, componentNumber );
552 pv.setSensitive( sensitive );
553
554 posY += thickness / 2;
555 }
556 }
557
558 public void makeTrdModule( ILogicalVolume module, SiTrackerModuleParameters moduleParameters, int moduleTypeId )
559 {
560 Trd trd = ( Trd ) module.getSolid();
561 double x1 = trd.getXHalfLength1();
562 double x2 = trd.getXHalfLength2();
563 double y1 = trd.getYHalfLength1();
564 double z = trd.getZHalfLength();
565
566
567
568
569
570
571 double posY = -y1;
572
573 for ( SiTrackerModuleComponentParameters component : moduleParameters )
574 {
575 double thickness = component.getThickness();
576 IMaterial material = MaterialStore.getInstance().get( component.getMaterialName() );
577 boolean sensitive = component.isSensitive();
578 int componentNumber = component.getComponentNumber();
579
580 posY += thickness / 2;
581
582 String componentName = "module" + moduleTypeId + "_component" + componentNumber;
583
584 Trd sliceTrd = new Trd( componentName, x1, x2, thickness / 2, thickness / 2, z );
585
586 ILogicalVolume volume = new LogicalVolume( componentName, sliceTrd, material );
587
588 Transform3D trans = new Transform3D( new Translation3D( 0, posY, 0 ) );
589
590 PhysicalVolume pv = new PhysicalVolume( trans, componentName, volume, module, componentNumber );
591 pv.setSensitive( sensitive );
592
593 posY += thickness / 2;
594 }
595 }
596
597 public void makeTrapModule( ILogicalVolume module, SiTrackerModuleParameters moduleParameters, int moduleTypeId )
598 {
599 Trap trap = ( Trap ) module.getSolid();
600 double a1 = trap.getAlpha1();
601 double a2 = trap.getAlpha2();
602 double x1 = trap.getXHalfLength1();
603 double x2 = trap.getXHalfLength2();
604 double x3 = trap.getXHalfLength3();
605 double x4 = trap.getXHalfLength4();
606 double y1 = trap.getYHalfLength1();
607 double z = trap.getZHalfLength();
608 double theta = trap.getTheta();
609 double phi = trap.getPhi();
610 double posY = -y1;
611
612
613
614
615
616
617
618
619 for ( SiTrackerModuleComponentParameters component : moduleParameters )
620 {
621 double thickness = component.getThickness();
622 IMaterial material = MaterialStore.getInstance().get( component.getMaterialName() );
623 boolean sensitive = component.isSensitive();
624 int componentNumber = component.getComponentNumber();
625
626 posY += thickness / 2;
627
628 String componentName = "module" + moduleTypeId + "_component" + componentNumber;
629
630 Trap sliceTrap = new Trap( componentName,
631 z,
632 theta,
633 phi,
634 thickness / 2,
635 x1,
636 x2,
637 a1,
638 thickness / 2,
639 x3,
640 x4,
641 a2 );
642
643 ILogicalVolume volume = new LogicalVolume( componentName, sliceTrap, material );
644
645 Transform3D trans = new Transform3D( new Translation3D( 0, posY, 0 ) );
646
647 PhysicalVolume pv = new PhysicalVolume( trans, componentName, volume, module, componentNumber );
648 pv.setSensitive( sensitive );
649
650 posY += thickness / 2;
651 }
652 }
653
654 public Class getSubdetectorType()
655 {
656 return SiTrackerEndcap.class;
657 }
658
659
660 private void setupSensorDetectorElements( Subdetector subdet ) throws Exception
661 {
662 SiTrackerIdentifierHelper id_helper = ( SiTrackerIdentifierHelper ) subdet.getDetectorElement()
663 .getIdentifierHelper();
664
665 if ( id_helper == null )
666 throw new RuntimeException( "helper is null!!!!!!!!!" );
667
668 int moduleId = 0;
669
670 for ( IDetectorElement endcap : subdet.getDetectorElement().getChildren() )
671 {
672 for ( IDetectorElement layer : endcap.getChildren() )
673 {
674 int nwedges = layer.getChildren().size();
675 for ( IDetectorElement wedge : layer.getChildren() )
676 {
677 for ( IDetectorElement module : wedge.getChildren() )
678 {
679 IPhysicalVolumePath modulePath = module.getGeometry().getPath();
680
681 IPhysicalVolume modulePhysVol = modulePath.getLeafVolume();
682
683 int sensorId = 0;
684 for ( IPhysicalVolume pv : modulePhysVol.getLogicalVolume().getDaughters() )
685 {
686
687 if ( pv.isSensitive() )
688 {
689 IIdentifierDictionary iddict = IdentifierDictionaryManager.getInstance()
690 .getIdentifierDictionary( subdet.getReadout().getName() );
691
692 ExpandedIdentifier expId = new ExpandedIdentifier( iddict.getNumberOfFields() );
693
694
695 expId.setValue( iddict.getFieldIndex( "system" ), subdet.getSystemID() );
696
697
698 if ( id_helper.isEndcapPositive( endcap.getIdentifier() ) )
699 {
700 expId.setValue( iddict.getFieldIndex( "barrel" ), id_helper
701 .getEndcapPositiveValue() );
702 }
703 else if ( id_helper.isEndcapNegative( endcap.getIdentifier() ) )
704 {
705 expId.setValue( iddict.getFieldIndex( "barrel" ), id_helper
706 .getEndcapNegativeValue() );
707 }
708 else
709 {
710 throw new RuntimeException( endcap.getName() + " - not pos or neg endcap!" );
711 }
712
713
714
715
716
717 expId.setValue( iddict.getFieldIndex( "layer" ), layer.getGeometry().getPath()
718 .getLeafVolume().getCopyNumber() );
719
720
721 expId.setValue( iddict.getFieldIndex( "wedge" ), wedge.getGeometry().getPath()
722 .getLeafVolume().getCopyNumber() );
723
724
725 expId.setValue( iddict.getFieldIndex( "module" ), ( ( SiTrackerModule ) module )
726 .getModuleId() );
727
728
729 expId.setValue( iddict.getFieldIndex( "sensor" ), sensorId );
730
731
732
733 IIdentifier id = iddict.pack( expId );
734
735 String sensorPath = modulePath.toString() + "/" + pv.getName();
736 String sensorName = endcap.getName() + "_layer" + layer.getGeometry()
737 .getPhysicalVolume().getCopyNumber() + "_wedge" + wedge.getGeometry().getPath()
738 .getLeafVolume().getCopyNumber() + "_module" + ( ( SiTrackerModule ) module )
739 .getModuleId() + "_sensor" + sensorId;
740
741
742
743
744
745 SiSensor sensor = new SiSensor( sensorId, sensorName, module, sensorPath, id );
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830 ++sensorId;
831 }
832 }
833 ++moduleId;
834 }
835 }
836 }
837 }
838 }
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879 }