1 package org.lcsim.detector.converter.compact;
2
3 import org.lcsim.detector.DetectorElement;
4 import org.lcsim.detector.ILogicalVolume;
5 import org.lcsim.detector.IPhysicalVolume;
6 import org.lcsim.detector.IPhysicalVolumeNavigator;
7 import org.lcsim.detector.IPhysicalVolumePath;
8 import org.lcsim.detector.LogicalVolume;
9 import org.lcsim.detector.PhysicalVolume;
10 import org.lcsim.detector.PhysicalVolumeNavigatorStore;
11 import org.lcsim.detector.identifier.ExpandedIdentifier;
12 import org.lcsim.detector.identifier.IExpandedIdentifier;
13 import org.lcsim.detector.identifier.IIdentifier;
14 import org.lcsim.detector.identifier.IIdentifierHelper;
15 import org.lcsim.detector.material.IMaterial;
16 import org.lcsim.detector.material.MaterialStore;
17 import org.lcsim.detector.solids.Tube;
18 import org.lcsim.geometry.compact.Detector;
19 import org.lcsim.geometry.compact.Subdetector;
20 import org.lcsim.geometry.layer.Layer;
21 import org.lcsim.geometry.layer.LayerSlice;
22 import org.lcsim.geometry.layer.Layering;
23 import org.lcsim.geometry.subdetector.BarrelEndcapFlag;
24 import org.lcsim.geometry.subdetector.CylindricalBarrelCalorimeter;
25
26 public class CylindricalBarrelCalorimeterConverter extends AbstractSubdetectorConverter implements
27 ISubdetectorConverter
28 {
29 public void convert( Subdetector subdet, Detector detector )
30 {
31
32 CylindricalBarrelCalorimeter cal = ( CylindricalBarrelCalorimeter ) subdet;
33
34
35 IPhysicalVolume world = detector.getWorldVolume();
36
37
38 IMaterial matWorld = world.getLogicalVolume().getMaterial();
39
40
41 ILogicalVolume envelope = buildEnvelope( cal, matWorld );
42
43
44 new PhysicalVolume( null, cal.getName(), envelope, world.getLogicalVolume(), subdet.getSystemID() );
45
46
47 IPhysicalVolumeNavigator nav = PhysicalVolumeNavigatorStore.getInstance().getDefaultNavigator();
48 IPhysicalVolumePath path = nav.getPath( cal.getName() );
49
50
51 ( ( DetectorElement ) cal.getDetectorElement() ).setSupport( path );
52
53
54 buildLayers( cal, envelope );
55 }
56
57 private ILogicalVolume buildEnvelope( CylindricalBarrelCalorimeter cal, IMaterial material )
58 {
59 Tube tube = new Tube( cal.getName() + "_envelope_tube", cal.getInnerRadius(), cal.getOuterRadius(), cal
60 .getZMax() );
61
62 LogicalVolume logvol = new LogicalVolume( cal.getName() + "_envelope", tube, material );
63
64 return logvol;
65 }
66
67 private void buildLayers( CylindricalBarrelCalorimeter cal, ILogicalVolume envelope )
68 {
69 IIdentifierHelper helper = cal.getDetectorElement().getIdentifierHelper();
70
71 Layering layering = cal.getLayering();
72 String name = cal.getName();
73
74 double zHalfLength = cal.getZMax();
75
76 int layerNumber = 0;
77
78 for ( int i = 0; i < layering.getNumberOfLayers(); i++ )
79 {
80 Layer layer = layering.getLayer( i );
81
82 double layerInnerRadius = layering.getDistanceToLayer( i );
83
84 String layerName = "layer" + i;
85
86 Tube tubeLayer = new Tube( name + "_layer" + i + "_tube", layerInnerRadius, layerInnerRadius + layer
87 .getThickness(), zHalfLength );
88
89 LogicalVolume lvLayer = new LogicalVolume( name + "_layer" + i, tubeLayer, envelope.getMaterial() );
90
91 new PhysicalVolume( null, layerName, lvLayer, envelope, i );
92
93 double sliceInnerRadius = layerInnerRadius;
94
95 int sensorNumber = 0;
96 for ( int j = 0; j < layer.getSlices().size(); j++ )
97 {
98 LayerSlice slice = layer.getSlice( j );
99
100 double sliceThickness = slice.getThickness();
101
102 String materialName = slice.getMaterial().getName();
103 IMaterial material = MaterialStore.getInstance().get( materialName );
104
105 String sliceName = "slice" + j;
106
107 Tube sliceLayer = new Tube( name + "_layer" + i + "_slice" + j + "_tube",
108 sliceInnerRadius,
109 sliceInnerRadius + sliceThickness,
110 zHalfLength );
111
112 LogicalVolume lvSlice = new LogicalVolume( name + "_layer" + i + "_slice" + j, sliceLayer, material );
113
114 PhysicalVolume pvSlice = new PhysicalVolume( null, sliceName, lvSlice, lvLayer, j );
115
116
117
118 if ( slice.isSensitive() )
119 {
120
121
122 if ( sensorNumber > 0 && !helper.hasField( "slice" ) )
123 {
124
125 break;
126 }
127
128 pvSlice.setSensitive( true );
129
130
131 String sensorPath = "/" + cal.getName() + "/" + layerName + "/" + sliceName;
132
133
134 IExpandedIdentifier expid = new ExpandedIdentifier( helper.getIdentifierDictionary()
135 .getNumberOfFields() );
136 if ( helper.hasField( "system" ) )
137 {
138 expid.setValue( helper.getFieldIndex( "system" ), cal.getSystemID() );
139 expid.setValue( helper.getFieldIndex( "barrel" ), BarrelEndcapFlag.BARREL.getFlag() );
140 expid.setValue( helper.getFieldIndex( "layer" ), i );
141 if ( helper.hasField( "slice" ) )
142 expid.setValue( helper.getFieldIndex( "slice" ), j );
143 IIdentifier id = helper.pack( expid );
144
145 new DetectorElement( cal.getName() + "_layer" + layerNumber + "_sensor" + sensorNumber, cal
146 .getDetectorElement(), sensorPath, id );
147 }
148
149 ++sensorNumber;
150 }
151
152 sliceInnerRadius += sliceThickness;
153 }
154
155 layerNumber += 1;
156 }
157 }
158
159 public void makeIdentifierContext( Subdetector subdet )
160 {
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186 }
187
188 public Class getSubdetectorType()
189 {
190 return CylindricalBarrelCalorimeter.class;
191 }
192 }