View Javadoc

1   package org.lcsim.geometry.segmentation;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import org.jdom.DataConversionException;
7   import org.jdom.Element;
8   import org.lcsim.detector.IDetectorElement;
9   import org.lcsim.detector.IDetectorElementContainer;
10  import org.lcsim.detector.identifier.IExpandedIdentifier;
11  import org.lcsim.detector.identifier.ExpandedIdentifier;
12  import org.lcsim.detector.identifier.IIdentifier;
13  import org.lcsim.detector.identifier.IIdentifierHelper;
14  import org.lcsim.detector.identifier.Identifier;
15  import org.lcsim.detector.solids.Trd;
16  import org.lcsim.geometry.util.IDDescriptor;
17  import org.lcsim.geometry.util.BaseIDDecoder;
18  import org.lcsim.geometry.util.IDEncoder;
19  import org.lcsim.geometry.subdetector.AbstractPolyhedraCalorimeter;
20  
21  /**
22   * XZ Cartesian grid segmentation.
23   * 
24   * @author cassell
25   */
26  public class RegularNgonCartesianGridXZ extends CartesianGridXZ
27  {
28      private double gridSizeX = 0;
29      private double gridSizeZ = 0;
30      private int nmodules = 12;
31  
32      private int xIndex = -1;
33      private int zIndex = -1;
34      private int moduleIndex = -1;
35      private int barrelIndex = -1;
36  
37      private int nzbins = 0;
38      private int zbinmax = 0;
39      private int zbinmin = 0;
40      private int[] nvalidx;
41      private boolean[] borderCellIsDuplicate;
42  
43      private double xhl0 = 0.;
44      private double xslope = 0.;
45  
46      private int ecsign = -1;
47      
48      private static final String fieldNames[] = {"x", "z"};
49  
50      public RegularNgonCartesianGridXZ(Element node) throws DataConversionException
51      {
52          super(node);
53  
54          if (node.getAttribute("gridSizeX") != null)
55          {
56              gridSizeX = node.getAttribute("gridSizeX").getDoubleValue();
57              cellSizes.add(0, gridSizeX);
58          }
59          else
60          {
61              throw new RuntimeException("Missing gridSizeX parameter.");
62          }
63  
64          if (node.getAttribute("gridSizeZ") != null)
65          {
66              gridSizeZ = node.getAttribute("gridSizeZ").getDoubleValue();
67              cellSizes.add(1, gridSizeZ);
68          }
69          else
70          {
71              throw new RuntimeException("Missing gridSizeZ parameter.");
72          }
73      }
74      
75      public String[] getSegmentationFieldNames() {
76          return fieldNames;
77      }
78  
79      public long[] getNeighbourIDs(int layerRange, int xRange, int zRange)
80      {
81          if (this.getDecoder().getID() == 0)
82              throw new RuntimeException("No current ID is set.");
83          if (sensitiveSlices == null)
84              initSensitiveSlices();
85          IDEncoder gnEncoder = new IDEncoder(descriptor);
86          BaseIDDecoder gnDecoder = new BaseIDDecoder(descriptor);
87          gnEncoder.setValues(values);
88          gnDecoder.setID(gnEncoder.getID());
89          IDEncoder dupEncoder = new IDEncoder(descriptor);
90          BaseIDDecoder dupDecoder = new BaseIDDecoder(descriptor);
91          dupEncoder.setValues(values);
92          dupDecoder.setID(dupEncoder.getID());
93  
94          // Get number of layers.
95          int nlayers = this.getNumberOfLayers();
96  
97          // Initialize the border arrays the first time in
98          if (nvalidx == null)
99          {
100             initializeBorders();
101         }
102         // Set values for current id.
103         int currLayer = gnDecoder.getValue(layerIndex);
104         int currX = gnDecoder.getValue(xIndex);
105         int currZ = gnDecoder.getValue(zIndex);
106         int currModule = gnDecoder.getValue(moduleIndex);
107         // Create return array.
108         List<Long> neighbors = new ArrayList<Long>();
109 
110         // Loop over Z range.
111         for (int iz = -zRange; iz <= zRange; iz++)
112         {
113             // Compute y value.
114             int neighborZ = currZ + iz;
115             if (neighborZ >= zbinmin && neighborZ <= zbinmax)
116             {
117                 gnEncoder.setValue(zIndex, neighborZ);
118                 int Zindex = neighborZ + nzbins / 2;
119                 // Loop over X range.
120                 for (int ix = -xRange; ix <= xRange; ix++)
121                 {
122                     // Need to check border
123                     int neighborX = currX + ix;
124                     int neighborModule = currModule;
125                     int dupX = neighborX;
126                     int dupModule = neighborModule;
127                     boolean dup = false;
128                     if (neighborX < -nvalidx[Zindex] + 1)
129                     {
130                         if (neighborX == -nvalidx[Zindex])
131                         {
132                             if (borderCellIsDuplicate[Zindex])
133                             {
134                                 dup = true;
135                                 dupX = -neighborX - 1;
136                                 dupModule = (nmodules + neighborModule - ecsign) % nmodules;
137                             }
138                         }
139                         else
140                         {
141                             neighborModule = (nmodules + neighborModule - ecsign) % nmodules;
142                             neighborX = 2 * nvalidx[Zindex] + neighborX;
143                             if (borderCellIsDuplicate[Zindex])
144                                 neighborX--;
145                         }
146                     }
147                     else if (neighborX > nvalidx[Zindex] - 2)
148                     {
149                         if (neighborX == nvalidx[Zindex] - 1)
150                         {
151                             if (borderCellIsDuplicate[Zindex])
152                             {
153                                 dup = true;
154                                 dupX = -neighborX - 1;
155                                 dupModule = (nmodules + neighborModule + ecsign) % nmodules;
156                             }
157                         }
158                         else
159                         {
160                             neighborModule = (nmodules + neighborModule + ecsign) % nmodules;
161                             neighborX = -2 * nvalidx[Zindex] + neighborX;
162                             if (borderCellIsDuplicate[Zindex])
163                                 neighborX++;
164                         }
165                     }
166                     gnEncoder.setValue(xIndex, neighborX);
167                     gnEncoder.setValue(moduleIndex, neighborModule);
168                     // Loop over layer range.
169                     for (int ilayer = -layerRange; ilayer <= layerRange; ilayer++)
170                     {
171                         // Compute layer value.
172                         int neighborLayer = currLayer + ilayer;
173 
174                         if (neighborLayer >= 0 && neighborLayer < nlayers)
175                         {
176 
177                             // Set the neighbor fields.
178                             gnEncoder.setValue(layerIndex, neighborLayer);
179                             // Add the neighbor id to the return array.
180                             if (sliceIndex >= 0)
181                             {
182                                 // Loop over sensitive slices
183                                 for (int is = 0; is < sensitiveSlices[neighborLayer].size(); is++)
184                                 {
185                                     // Set the slic field.
186                                     gnEncoder.setValue(sliceIndex, ((Integer) (sensitiveSlices[neighborLayer].get(is)))
187                                             .intValue());
188 
189                                     if (this.getDecoder().getID() != gnEncoder.getID())
190                                         neighbors.add(gnEncoder.getID());
191                                     // If we have a duplicate cell, add it
192                                     if (dup)
193                                     {
194                                         dupEncoder.setValue(zIndex, neighborZ);
195                                         dupEncoder.setValue(xIndex, dupX);
196                                         dupEncoder.setValue(layerIndex, neighborLayer);
197                                         dupEncoder.setValue(moduleIndex, dupModule);
198                                         dupEncoder.setValue(sliceIndex, ((Integer) (sensitiveSlices[neighborLayer]
199                                                 .get(is))).intValue());
200                                         neighbors.add(dupEncoder.getID());
201                                     }
202                                 }
203                             }
204                             else
205                             {
206                                 if (this.getDecoder().getID() != gnEncoder.getID())
207                                     neighbors.add(gnEncoder.getID());
208                                 // If we have a duplicate cell, add it
209                                 if (dup)
210                                 {
211                                     dupEncoder.setValue(zIndex, neighborZ);
212                                     dupEncoder.setValue(xIndex, dupX);
213                                     dupEncoder.setValue(layerIndex, neighborLayer);
214                                     dupEncoder.setValue(moduleIndex, dupModule);
215                                     neighbors.add(dupEncoder.getID());
216                                 }
217 
218                             }
219                         }
220                     }
221                 }
222             }
223         }
224 
225         long result[] = new long[neighbors.size()];
226         int i = 0;
227         for (Long id : neighbors)
228         {
229             result[i] = id;
230             i++;
231         }
232         return result;
233     }
234 
235     protected void initializeBorders()
236     {
237         nmodules = ((AbstractPolyhedraCalorimeter) getSubdetector()).getNumberOfSides();
238         IIdentifierHelper helper = detector.getDetectorElement().getIdentifierHelper();
239         // Current packed id.
240         IIdentifier currId = new Identifier(this.getDecoder().getID());
241         // Create an ExpandedIdentifier for the current id.
242         IExpandedIdentifier thisId = helper.unpack(currId);
243         IIdentifier id = new Identifier(this.getDecoder().getID());
244         ExpandedIdentifier testId = new ExpandedIdentifier(thisId);
245         int barrelVal = helper.getValue(id, barrelIndex);
246         ecsign = 1;
247         if (barrelVal == 2)
248             ecsign = -1;
249         testId.setValue(xIndex, 0);
250         IIdentifier geomId = makeGeometryIdentifier(helper.pack(testId).getValue());
251         IDetectorElementContainer deSrch = getSubdetector().getDetectorElement().findDetectorElement(geomId);
252         IDetectorElement de = deSrch.get(0);
253         if (de.getGeometry().getLogicalVolume().getSolid() instanceof Trd)
254         {
255             Trd sensorTrd = (Trd) de.getGeometry().getLogicalVolume().getSolid();
256             double zhl = sensorTrd.getZHalfLength();
257             double xhl1 = sensorTrd.getXHalfLength1();
258             double xhl2 = sensorTrd.getXHalfLength2();
259             xhl0 = (xhl1 + xhl2) / 2.;
260             xslope = (xhl2 - xhl0) * gridSizeZ / zhl;
261             nzbins = 2 * ((int) (zhl / gridSizeZ) + 1);
262             zbinmax = nzbins / 2 - 1;
263             zbinmin = -nzbins / 2;
264             nvalidx = new int[nzbins];
265             borderCellIsDuplicate = new boolean[nzbins];
266             for (int zi = 0; zi < nzbins; zi++)
267             {
268                 int zbin = zi - nzbins / 2;
269                 double xhl = xhl0 + xslope * (zbin + .5);
270                 nvalidx[zi] = (int) (xhl / gridSizeX) + 1;
271                 double bcw = (nvalidx[zi] * gridSizeX - xhl) / gridSizeX;
272                 borderCellIsDuplicate[zi] = false;
273                 if (bcw < .5)
274                     borderCellIsDuplicate[zi] = true;
275             }
276         }
277         else
278         {
279             throw new RuntimeException("Don't know how to bounds check solid " + de.getGeometry().getLogicalVolume()
280                     .getSolid().getName() + ".");
281         }
282     }
283 
284     protected void setupGeomFields(IDDescriptor id)
285     {
286         super.setupGeomFields(id);
287         xIndex = id.indexOf("x");
288         zIndex = id.indexOf("z");
289         moduleIndex = id.indexOf("module");
290         layerIndex = id.indexOf("layer");
291         barrelIndex = id.indexOf("barrel");
292 
293     }
294 
295 }