View Javadoc

1   package org.lcsim.detector.converter.compact;
2   
3   import org.lcsim.detector.DetectorElement;
4   import org.lcsim.detector.DetectorIdentifierHelper;
5   import org.lcsim.detector.IDetectorElement;
6   import org.lcsim.detector.ILogicalVolume;
7   import org.lcsim.detector.IPhysicalVolume;
8   import org.lcsim.detector.IRotation3D;
9   import org.lcsim.detector.LogicalVolume;
10  import org.lcsim.detector.PhysicalVolume;
11  import org.lcsim.detector.RotationPassiveXYZ;
12  import org.lcsim.detector.Transform3D;
13  import org.lcsim.detector.Translation3D;
14  import org.lcsim.detector.identifier.ExpandedIdentifier;
15  import org.lcsim.detector.identifier.IIdentifier;
16  import org.lcsim.detector.identifier.IIdentifierDictionary;
17  import org.lcsim.detector.identifier.IIdentifierHelper;
18  import org.lcsim.detector.identifier.IdentifierContext;
19  import org.lcsim.detector.material.IMaterial;
20  import org.lcsim.detector.material.MaterialStore;
21  import org.lcsim.detector.solids.Tube;
22  import org.lcsim.geometry.compact.Detector;
23  import org.lcsim.geometry.compact.Subdetector;
24  import org.lcsim.geometry.layer.Layer;
25  import org.lcsim.geometry.layer.LayerSlice;
26  import org.lcsim.geometry.layer.Layering;
27  import org.lcsim.geometry.subdetector.DiskTracker;
28  
29  /**
30   * Convert a DiskTracker to the detailed geometry description.
31   * 
32   * @author Jeremy McCormick <jeremym@slac.stanford.edu>
33   * 
34   */
35  public class DiskTrackerConverter extends AbstractSubdetectorConverter implements ISubdetectorConverter
36  {
37      public void convert(Subdetector subdet, Detector detector)
38      {
39          ILogicalVolume mother = null;
40          if (subdet.isInsideTrackingVolume())
41          {
42              mother = detector.getTrackingVolume().getLogicalVolume();
43          }
44          else
45          {
46              mother = detector.getWorldVolume().getLogicalVolume();
47          }
48  
49          DiskTracker tracker = (DiskTracker)subdet;
50  
51          // Some DiskTracker subdetectors are used for support material
52          // so need to make sure Readout is not null before using it.
53          int systemNumber = 0;
54          DetectorIdentifierHelper helper = null;
55          if (subdet.getReadout() != null)
56          {
57              systemNumber = tracker.getSystemID();
58              helper = (DetectorIdentifierHelper)tracker.getDetectorElement().getIdentifierHelper();
59          }
60  
61          // Get the Subdetector name.
62          String subdetName = tracker.getName();
63  
64          // Create the two endcap containers.
65          DetectorElement endcapPos = new DetectorElement(subdetName + "_positive", tracker.getDetectorElement());
66          DetectorElement endcapNeg = null;
67          if (tracker.getReflect())
68          {
69              endcapNeg = new DetectorElement(subdetName + "_negative", tracker.getDetectorElement());
70          }
71  
72          // Rotation for reflection.
73          IRotation3D reflect = new RotationPassiveXYZ(0, Math.PI, 0);
74  
75          // Loop over the layers.
76          // int sensorNum = 0;
77          Layering layering = tracker.getLayering();
78          for (int i = 0; i < layering.getNumberOfLayers(); i++ )
79          {
80              // Layer parameters.
81              Layer layer = layering.getLayer(i);
82              double layerInnerRadius = tracker.getInnerR()[i];
83              double layerOuterRadius = tracker.getOuterR()[i];
84              double layerInnerZ = tracker.getInnerZ()[i];
85  
86              // Layer names.
87              String layerName = subdetName + "_layer" + i;
88              String posLayerName = layerName + "_pos";
89              String negLayerName = layerName + "_neg";
90  
91              // Create layer solid and LogicalVolume.
92              Tube layerTube = new Tube(layerName, layerInnerRadius, layerOuterRadius, layer.getThickness() / 2);
93              LogicalVolume layerLV =
94                      new LogicalVolume(layerName + "_volume", layerTube, detector.getDetectorElement().getGeometry()
95                              .getLogicalVolume().getMaterial());
96  
97              // Positive and negative PhysicalVolumes.
98              IPhysicalVolume posLayerPV =
99                      new PhysicalVolume(
100                                        new Transform3D(new Translation3D(0, 0, layerInnerZ + layer.getThickness() / 2)),
101                                        posLayerName, layerLV, mother, i);
102             IPhysicalVolume negLayerPV = null;
103             if (tracker.getReflect())
104             {
105                 negLayerPV =
106                         new PhysicalVolume(new Transform3D(new Translation3D(0., 0., -layerInnerZ
107                                 - layer.getThickness() / 2), reflect), negLayerName, layerLV, mother, i);
108 
109             }
110 
111             // Create the layer paths.
112             String posLayerPath = "/";
113             String negLayerPath = "/";
114             if (subdet.isInsideTrackingVolume())
115             {
116                 posLayerPath += detector.getTrackingVolume().getName() + "/";
117                 negLayerPath += detector.getTrackingVolume().getName() + "/";
118             }
119             posLayerPath += posLayerPV.getName();
120             if (negLayerPV != null ) {
121             	negLayerPath += negLayerPV.getName();
122             }
123 
124             // Create the layer DetectorElements.
125             IDetectorElement posLayerDE = new DetectorElement(posLayerPV.getName(), endcapPos, posLayerPath);
126             IDetectorElement negLayerDE = null;
127             if (negLayerPV != null)
128             {
129                 negLayerDE = new DetectorElement(negLayerPV.getName(), endcapNeg, negLayerPath);
130             }
131 
132             // Loop over the slices.
133             double sliceZ = -layer.getThickness() / 2;
134             for (int j = 0; j < layer.getNumberOfSlices(); j++ )
135             {
136                 // Get slice parameters.
137                 LayerSlice slice = layer.getSlice(j);
138                 double sliceThickness = slice.getThickness();
139                 IMaterial sliceMaterial = MaterialStore.getInstance().get(slice.getMaterial().getName());
140                 String sliceName = layerName + "_slice" + j;
141 
142                 // Create the solid and LogicalVolume.
143                 Tube sliceTube = new Tube(sliceName + "_tube", layerInnerRadius, layerOuterRadius, sliceThickness / 2);
144                 LogicalVolume sliceLV = new LogicalVolume(sliceName + "_volume", sliceTube, sliceMaterial);
145 
146                 // Increment to correct slice Z for this placement.
147                 sliceZ += sliceThickness / 2;
148 
149                 // Create the positive slice PhysicalVolume. Only one placement is necessary because
150                 // the negative and positive layers use the same LogicalVolume.
151                 PhysicalVolume slicePV =
152                         new PhysicalVolume(new Transform3D(new Translation3D(0, 0, sliceZ)), sliceName, sliceLV,
153                                            layerLV, j);
154 
155                 // Increment slice Z for next placement.
156                 sliceZ += sliceThickness / 2;
157 
158                 // Create Identifiers if this is a sensor.
159                 IIdentifier slicePosId = null;
160                 IIdentifier sliceNegId = null;
161                 if (slice.isSensitive())
162                 {
163                     slicePV.setSensitive(true);
164                     slicePosId = makeIdentifier(helper, systemNumber, helper.getEndcapPositiveValue(), i, j);
165                     sliceNegId = makeIdentifier(helper, systemNumber, helper.getEndcapNegativeValue(), i, j);
166 
167                     // Create the DetectorElement paths for the slices.
168                     String posPath = posLayerPath + "/" + sliceName;
169                     String negPath = negLayerPath + "/" + sliceName;
170 
171                     // Make DetectorElements.
172                     new DetectorElement(sliceName + "_pos", posLayerDE, posPath, slicePosId);
173                     if (tracker.getReflect())
174                     {
175                         new DetectorElement(sliceName + "_neg", negLayerDE, negPath, sliceNegId);
176                     }
177                 }
178 
179                 // Increment sensor number if slice was sensitive.
180                 // if (slice.isSensitive())
181                 // {
182                 // ++sensorNum;
183                 // }
184             }
185         }
186     }
187 
188     static IIdentifier makeIdentifier(IIdentifierHelper helper, int systemNumber, int barrel, int layer, int slice)
189     {
190         ExpandedIdentifier id = new ExpandedIdentifier(helper.getIdentifierDictionary().getNumberOfFields());
191         try
192         {
193             id.setValue(helper.getFieldIndex("system"), systemNumber);
194             id.setValue(helper.getFieldIndex("barrel"), barrel);
195             id.setValue(helper.getFieldIndex("layer"), layer);
196             if (helper.hasField("slice"))
197                 id.setValue(helper.getFieldIndex("slice"), slice);
198             return helper.pack(id);
199         }
200         catch (Exception x)
201         {
202             throw new RuntimeException(x);
203         }
204     }
205 
206     static IIdentifier makeLayerIdentifier(IIdentifierHelper helper, int systemNumber, int barrel, int layer)
207     {
208         ExpandedIdentifier id = new ExpandedIdentifier(helper.getIdentifierDictionary().getNumberOfFields());
209         try
210         {
211             id.setValue(helper.getFieldIndex("system"), systemNumber);
212             id.setValue(helper.getFieldIndex("barrel"), barrel);
213             id.setValue(helper.getFieldIndex("layer"), layer);
214             return helper.pack(id);
215         }
216         catch (Exception x)
217         {
218             throw new RuntimeException(x);
219         }
220     }
221 
222     /*
223     public void makeIdentifierContext(Subdetector subdet)
224     {
225         IIdentifierDictionary iddict = subdet.getDetectorElement().getIdentifierHelper().getIdentifierDictionary();
226 
227         int systemIndex = iddict.getFieldIndex("system");
228         int barrelIndex = iddict.getFieldIndex("barrel");
229         int layerIndex = iddict.getFieldIndex("layer");
230 
231         IdentifierContext systemContext = new IdentifierContext(new int[]{systemIndex});
232         IdentifierContext subdetContext = new IdentifierContext(new int[]{systemIndex,barrelIndex});
233         IdentifierContext layerContext = new IdentifierContext(new int[]{systemIndex,barrelIndex,layerIndex});
234 
235         iddict.addIdentifierContext("system", systemContext);
236         iddict.addIdentifierContext("subdetector", subdetContext);
237         iddict.addIdentifierContext("layer", layerContext);
238     }
239     */
240 
241     public Class getSubdetectorType()
242     {
243         return DiskTracker.class;
244     }
245 }