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.SiTrackerFixedTarget2;
37
38
39
40
41
42
43
44 public class SiTrackerFixedTarget2Converter 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=true;
67 if ( node.getAttribute( "reflect" ) != null )
68 {
69 reflect = node.getAttribute( "reflect" ).getBooleanValue();
70 }
71
72
73 boolean flipSA=false;
74 if ( node.getAttribute( "flipSA" ) != null )
75 {
76 flipSA = node.getAttribute( "flipSA" ).getBooleanValue();
77 }
78
79 IDetectorElement subdetDetElem = subdet.getDetectorElement();
80 DetectorIdentifierHelper helper = ( DetectorIdentifierHelper ) subdetDetElem.getIdentifierHelper();
81 int nfields = helper.getIdentifierDictionary().getNumberOfFields();
82 IDetectorElement endcapPos = null;
83 IDetectorElement endcapNeg = 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.getBarrelValue() );
90 endcapPos = new DetectorElement( subdet.getName() + "_positive", subdetDetElem );
91 endcapPos.setIdentifier( helper.pack( endcapPosId ) );
92 if ( reflect )
93 {
94 IExpandedIdentifier endcapNegId = new ExpandedIdentifier( nfields );
95 endcapNegId.setValue( helper.getFieldIndex( "system" ), subdet.getSystemID() );
96 endcapNegId.setValue( helper.getFieldIndex( "barrel" ), helper.getBarrelValue() );
97 endcapNeg = new DetectorElement( subdet.getName() + "_negative", subdetDetElem );
98 endcapNeg.setIdentifier( helper.pack( endcapNegId ) );
99 }
100 }
101 catch ( Exception x )
102 {
103 throw new RuntimeException( x );
104 }
105
106 for ( Iterator i = node.getChildren( "module" ).iterator(); i.hasNext(); )
107 {
108 Element module = ( Element ) i.next();
109 String moduleName = module.getAttributeValue( "name" );
110 moduleParameters.put( moduleName, new SiTrackerModuleParameters( module ) );
111 modules.put( moduleName, makeModule( moduleParameters.get( moduleName ) ) );
112 }
113
114 for ( Iterator i = node.getChildren( "layer" ).iterator(); i.hasNext(); )
115 {
116 Element layerElement = ( Element ) i.next();
117
118 int layerId = layerElement.getAttribute( "id" ).getIntValue();
119
120
121 IExpandedIdentifier layerPosId = new ExpandedIdentifier( nfields );
122 layerPosId.setValue( helper.getFieldIndex( "system" ), subdet.getSystemID() );
123
124
125 layerPosId.setValue( helper.getFieldIndex( "barrel" ), helper.getBarrelValue() );
126 layerPosId.setValue( helper.getFieldIndex( "layer" ), layerId );
127 IDetectorElement layerPos = new DetectorElement( endcapPos.getName() + "_layer" + layerId,
128 endcapPos,
129 helper.pack( layerPosId ) );
130
131
132 IDetectorElement layerNeg = null;
133 if ( reflect )
134 {
135 IExpandedIdentifier layerNegId = new ExpandedIdentifier( nfields );
136 layerNegId.setValue( helper.getFieldIndex( "system" ), subdet.getSystemID() );
137 layerNegId.setValue( helper.getFieldIndex( "barrel" ), helper.getBarrelValue() );
138 layerNegId.setValue( helper.getFieldIndex( "layer" ), layerId );
139 layerNeg = new DetectorElement( endcapNeg.getName() + "_layer_reflected" + layerId,
140 endcapNeg,
141 helper.pack( layerNegId ) );
142 }
143
144 int moduleNumber = 0;
145 for ( Iterator j = layerElement.getChildren( "quadrant" ).iterator(); j.hasNext(); )
146 {
147 Element ringElement = ( Element ) j.next();
148 double xLayer = ringElement.getAttribute( "x" ).getDoubleValue();
149 double dx = ringElement.getAttribute( "dx" ).getDoubleValue();
150 double yStart = ringElement.getAttribute( "yStart" ).getDoubleValue();
151 double yStep = ringElement.getAttribute( "yStep" ).getDoubleValue();
152 int ny = ringElement.getAttribute( "ny" ).getIntValue();
153 double zStart = ringElement.getAttribute( "zStart" ).getDoubleValue();
154 int nz = ringElement.getAttribute( "nz" ).getIntValue();
155 double zStep = ringElement.getAttribute( "zStep" ).getDoubleValue();
156
157 double phi0 = 0;
158 if ( ringElement.getAttribute( "phi0" ) != null )
159 {
160 phi0 = ringElement.getAttribute( "phi0" ).getDoubleValue();
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 SiTrackerModuleParameters modPars = moduleParameters.get( module );
170
171 double x, y, z;
172 x = xLayer;
173 y = yStart;
174
175 for ( int k = 0; k < ny; k++ )
176 {
177 z = zStart;
178 for ( int kk = 0; kk < nz; kk++ )
179 {
180 String moduleBaseName = subdetName + "_layer" + layerId + "_module" + moduleNumber;
181
182
183 Translation3D p = new Translation3D( x + dx, y, z );
184 RotationGeant rot = new RotationGeant( Math.PI / 2 + phi0, 0, -Math.PI / 2 );
185 new PhysicalVolume( new Transform3D( p, rot ), moduleBaseName, moduleVolume, detector
186 .getTrackingVolume().getLogicalVolume(), 0 );
187 String path = "/" + detector.getTrackingVolume().getName() + "/" + moduleBaseName;
188 IDetectorElement modulePos = new SiTrackerModule( moduleBaseName,
189 layerPos,
190 path,
191 moduleNumber );
192 ++moduleNumber;
193
194
195 if ( reflect )
196 {
197 Translation3D pr = new Translation3D( x + dx, y, -z );
198 double rphi0=phi0;
199 if(flipSA) rphi0=-rphi0;
200 RotationGeant rotr = new RotationGeant( Math.PI / 2 + rphi0, 0, -Math.PI / 2 );
201
202 String path2 = "/" + detector.getTrackingVolume().getName() + "/" + moduleBaseName + "_reflected";
203 new PhysicalVolume( new Transform3D( pr, rotr ),
204 moduleBaseName + "_reflected",
205 moduleVolume,
206 detector.getTrackingVolume().getLogicalVolume(),
207 k );
208 new SiTrackerModule( moduleBaseName + "_reflected", layerNeg, path2, moduleNumber );
209
210 }
211
212 dx = -dx;
213 z += zStep;
214 ++moduleNumber;
215 }
216 y += yStep;
217 }
218 }
219 }
220 }
221 catch ( JDOMException except )
222 {
223 throw new RuntimeException( except );
224 }
225
226
227 setupSensorDetectorElements( subdet );
228 }
229
230 private LogicalVolume makeModule( SiTrackerModuleParameters params )
231 {
232 double thickness = params.getThickness();
233 double dx1, dx2, dy1, dy2, dz;
234 dy1 = dy2 = thickness / 2;
235 dx1 = params.getDimension( 0 );
236 dx2 = params.getDimension( 1 );
237 dz = params.getDimension( 2 );
238 Trd envelope = new Trd( params.getName() + "Trd", dx1, dx2, dy1, dy2, dz );
239 LogicalVolume volume = new LogicalVolume( params.getName() + "Volume", envelope, vacuum );
240 makeModuleComponents( volume, params );
241 return volume;
242 }
243
244 private void makeModuleComponents( LogicalVolume moduleVolume, SiTrackerModuleParameters moduleParameters )
245 {
246 Trd trd = ( Trd ) moduleVolume.getSolid();
247
248 double x1 = trd.getXHalfLength1();
249 double x2 = trd.getXHalfLength2();
250 double y1 = trd.getYHalfLength1();
251 double z = trd.getZHalfLength();
252
253 double posY = -y1;
254
255 String moduleName = moduleVolume.getName();
256
257 int sensor = 0;
258 for ( SiTrackerModuleComponentParameters component : moduleParameters )
259 {
260 double thickness = component.getThickness();
261
262 IMaterial material = MaterialStore.getInstance().get( component.getMaterialName() );
263 if ( material == null )
264 {
265 throw new RuntimeException( "The material " + component.getMaterialName() + " does not exist in the materials database." );
266 }
267 boolean sensitive = component.isSensitive();
268 int componentNumber = component.getComponentNumber();
269
270 posY += thickness / 2;
271
272 String componentName = moduleName + "_component" + componentNumber;
273
274 Trd sliceTrd = new Trd( componentName + "_trd", x1, x2, thickness / 2, thickness / 2, z );
275
276 LogicalVolume volume = new LogicalVolume( componentName, sliceTrd, material );
277
278 double zrot = 0;
279 if ( sensitive )
280 {
281 if ( sensor > 1 )
282 {
283 throw new RuntimeException( "Exceeded maximum of 2 sensors per module." );
284 }
285
286 if ( sensor == 0 )
287 {
288 zrot = Math.PI;
289 }
290 ++sensor;
291 }
292 Translation3D position = new Translation3D( 0., posY, 0 );
293 RotationGeant rotation = new RotationGeant( 0, 0, zrot );
294 PhysicalVolume pv = new PhysicalVolume( new Transform3D( position, rotation ),
295 componentName,
296 volume,
297 moduleVolume,
298 componentNumber );
299 pv.setSensitive( sensitive );
300
301 posY += thickness / 2;
302 }
303 }
304
305 private void setupSensorDetectorElements( Subdetector subdet )
306 {
307 SiTrackerIdentifierHelper helper = ( SiTrackerIdentifierHelper ) subdet.getDetectorElement()
308 .getIdentifierHelper();
309
310 for ( IDetectorElement endcap : subdet.getDetectorElement().getChildren() )
311 {
312 for ( IDetectorElement layer : endcap.getChildren() )
313 {
314 for ( IDetectorElement module : layer.getChildren() )
315 {
316 IPhysicalVolume modulePhysVol = module.getGeometry().getPhysicalVolume();
317 IPhysicalVolumePath modulePath = module.getGeometry().getPath();
318 int sensorId = 0;
319 for ( IPhysicalVolume pv : modulePhysVol.getLogicalVolume().getDaughters() )
320 {
321 if ( pv.isSensitive() )
322 {
323 IIdentifierDictionary iddict = subdet.getDetectorElement().getIdentifierHelper()
324 .getIdentifierDictionary();
325
326 ExpandedIdentifier expId = new ExpandedIdentifier( iddict.getNumberOfFields() );
327 expId.setValue( iddict.getFieldIndex( "system" ), subdet.getSystemID() );
328
329 if ( helper.isEndcapPositive( endcap.getIdentifier() ) )
330 {
331 expId.setValue( iddict.getFieldIndex( "barrel" ), helper.getEndcapPositiveValue() );
332 }
333 else if ( helper.isEndcapNegative( endcap.getIdentifier() ) )
334 {
335 expId.setValue( iddict.getFieldIndex( "barrel" ), helper.getEndcapNegativeValue() );
336 }
337 else if ( helper.isBarrel( endcap.getIdentifier() ) )
338 {
339 expId.setValue( iddict.getFieldIndex( "barrel" ), helper.getBarrelValue() );
340 }
341 else
342 {
343 throw new RuntimeException( endcap.getName() + " is not a positive or negative endcap!" );
344 }
345 expId.setValue( iddict.getFieldIndex( "layer" ), layer.getIdentifierHelper().getValue(
346 layer.getIdentifier(),
347 "layer" ) );
348 expId.setValue( iddict.getFieldIndex( "module" ), ( ( SiTrackerModule ) module )
349 .getModuleId() );
350 expId.setValue( iddict.getFieldIndex( "sensor" ), sensorId );
351
352 IIdentifier id = iddict.pack( expId );
353
354 String sensorPath = modulePath.toString() + "/" + pv.getName();
355 String sensorName = module.getName() + "_sensor" + sensorId;
356
357 SiSensor sensor = new SiSensor( sensorId, sensorName, module, sensorPath, id );
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
408
409
410
411
412
413
414
415
416
417
418 ++sensorId;
419 }
420 }
421 }
422 }
423 }
424 }
425
426 public Class getSubdetectorType()
427 {
428 return SiTrackerFixedTarget2.class;
429 }
430 }