View Javadoc

1   package org.lcsim.geometry.segmentation;
2   
3   import hep.physics.vec.Hep3Vector;
4   
5   import java.util.ArrayList;
6   
7   import org.jdom.DataConversionException;
8   import org.jdom.Element;
9   import org.lcsim.detector.identifier.IExpandedIdentifier;
10  import org.lcsim.geometry.layer.Layer;
11  import org.lcsim.geometry.layer.Layering;
12  import org.lcsim.geometry.subdetector.BarrelEndcapFlag;
13  import org.lcsim.geometry.util.IDDescriptor;
14  
15  /**
16   * This segmentation is a global XY Cartesian grid. It is appropriate for
17   * segmenting planar endcaps with a uniform grid in global XY coordinates.
18   * 
19   * @author jeremym
20   */
21  public class GlobalGridXY extends AbstractCartesianGrid
22  {
23      private int xIndex = -1;
24      private int yIndex = -1;
25      private static final String[] fieldNames = {"x", "y"};
26  
27      public GlobalGridXY(Element node) throws DataConversionException
28      {
29          super(node);
30  
31          if (node.getAttribute("gridSizeX") != null)
32          {
33              gridSizeX = node.getAttribute("gridSizeX").getDoubleValue();
34              cellSizes.add(0, gridSizeX);
35          }
36          else
37          {
38              throw new RuntimeException("Missing gridSizeX parameter.");
39          }
40  
41          if (node.getAttribute("gridSizeY") != null)
42          {
43              gridSizeY = node.getAttribute("gridSizeY").getDoubleValue();
44              cellSizes.add(1, gridSizeY);
45          }
46          else
47          {
48              throw new RuntimeException("Missing gridSizeY parameter.");
49          }
50      }
51      
52      public String[] getSegmentationFieldNames() {
53          return fieldNames;
54      }
55  
56      protected void computePosition()
57      {
58          computeGlobalX();
59          computeGlobalY();
60          computeGlobalZ();
61      }
62  
63      private void computeGlobalX()
64      {
65          globalPosition[0] = (((double) getValue(xIndex)) + 0.5) * gridSizeX;
66      }
67  
68      private void computeGlobalY()
69      {
70          globalPosition[1] = (((double) getValue(yIndex)) + 0.5) * gridSizeY;
71      }
72  
73      /**
74       * Compute and cache the global Z of the hit.
75       */
76      private void computeGlobalZ()
77      {
78          Layering layers = getSubdetector().getLayering();
79          int sliceIdx = getValue("slice");
80          int layerIdx = getValue("layer");
81          Layer layer = layers.getLayer(layerIdx);
82  
83          globalPosition[2] = layers.getDistanceToLayer(layerIdx) + layer.computeDistanceToSliceMid(sliceIdx);
84  
85          // Flip sign to negative for south endcap.
86          if (getBarrelEndcapFlag() == BarrelEndcapFlag.ENDCAP_SOUTH)
87          {
88              globalPosition[2] = -globalPosition[2];
89          }
90      }
91  
92      protected void setSegmentationValues(IExpandedIdentifier geomId, Hep3Vector positionVec)
93      {
94          geomId.setValue(xIndex, getXBin(positionVec.x()));
95          geomId.setValue(yIndex, getYBin(positionVec.y()));
96      }
97  
98      protected void setupGeomFields(IDDescriptor id)
99      {
100         if (geomFields == null)
101         {
102             geomFields = new ArrayList<Integer>();
103 
104             xIndex = id.indexOf("x");
105             yIndex = id.indexOf("y");
106             layerIndex = id.indexOf("layer");
107             try
108             {
109                 sliceIndex = id.indexOf("slice");
110             }
111             catch (IllegalArgumentException x)
112             {
113                 System.err.println("The slice field does not exist in this IDDecoder.");
114                 sliceIndex = -1;
115             }
116 
117             // Exclude "x" and "y" fields in field list.
118             for (int i = 0; i < id.fieldCount(); i++)
119             {
120                 String fname = id.fieldName(i);
121                 if (!fname.equals("x") && !fname.equals("y"))
122                 {
123                     geomFields.add(i);
124                 }
125             }
126         }
127     }
128 
129     public long[] getNeighbourIDs(int layerRange, int xRange, int yRange)
130     {
131         return getNeighbourIDs(layerRange, xRange, yRange, xIndex, yIndex);
132     }
133 
134     public int getXBin(double x)
135     {
136         return getBin(x, gridSizeX);
137     }
138 
139     public int getYBin(double y)
140     {
141         return getBin(y, gridSizeY);
142     }
143 
144     /**
145      * Similar to super-class implementation but doesn't need to do a global to
146      * local transform into the target shape's coordinate system.
147      */
148     /*
149     public long findCellContainingXYZ(double x, double y, double z) 
150     {
151         Hep3Vector pos = new BasicHep3Vector(x,y,z);
152         IDetectorElement de = getSubdetector().getDetectorElement().findDetectorElement(pos);
153         if (de == null)
154         {
155             throw new RuntimeException("No DetectorElement was found at " + pos + ".");
156         }
157         if (!de.getGeometry().getPhysicalVolume().isSensitive())
158         {
159             throw new RuntimeException("The volume " + de.getName() + " is not sensitive.");
160         }        
161         ExpandedIdentifier geomId = new ExpandedIdentifier(de.getExpandedIdentifier());
162         setSegmentationValues(geomId, pos);
163         return getSubdetector().getDetectorElement().getIdentifierHelper().pack(geomId).getValue();
164     }    
165      */
166 
167     protected void computeLocalPosition()
168     {
169     }
170 
171     // TODO: Implement this method.
172     public boolean boundsCheck(long rawId)
173     {
174         return false;
175     }
176 
177     /*
178     public boolean boundsCheck(long rawId)
179     {
180         IIdentifier geomId = makeGeometryIdentifier(rawId);
181         IIdentifierHelper helper = getSubdetector().getDetectorElement().getIdentifierHelper();
182         IIdentifier id = new Identifier(rawId);
183         int xVal = helper.getValue(id, xIndex);
184         int yVal = helper.getValue(id, yIndex);
185         IDetectorElementContainer deSrch = getSubdetector().getDetectorElement().findDetectorElement(geomId);
186         if (deSrch == null || deSrch.size() == 0)
187         {
188             return false;
189         }
190         IDetectorElement de = deSrch.get(0);
191 
192         double xPos = computeCoordinate(xVal, gridSizeX);
193         double yPos = computeCoordinate(yVal, gridSizeY);
194 
195         double zPos = getSubdetector().getLayering().getDistanceToLayerSensorMid(getLayer());
196         // Flip sign to negative for south endcap.
197         if (getBarrelEndcapFlag() == BarrelEndcapFlag.ENDCAP_SOUTH)
198         {
199             zPos = -zPos;
200         }        
201 
202         // Check that coordinate is inside sensor (doesn't check the z coordinate!).
203         ISolid sensor = de.getGeometry().getLogicalVolume().getSolid();
204         if (sensor.inside(new BasicHep3Vector(xPos, yPos, zPos)) == Inside.INSIDE)
205         {
206             return true;
207         }
208         else
209         {
210             return false;
211         }
212     }
213      */
214 
215     /*
216     OLD METHOD
217     private void computeGlobalZ()
218     {
219         // Make an id only containing geometric fields and no segmentation fields.
220         IExpandedIdentifier geomIdExp = detector.getDetectorElement().getIdentifierHelper().unpack(new Identifier(this.getDecoder().getID()), geomFields);
221         IIdentifier geomId = detector.getDetectorElement().getIdentifierHelper().pack(geomIdExp);
222 
223         // Search for the the DetectorElement associated with the geometry id.
224         List<IDetectorElement> deSearch = detector.getDetectorElement().findDetectorElement(geomId);
225 
226         // Check if the lookup failed.
227         if (deSearch == null || deSearch.size() == 0)
228         {
229             throw new RuntimeException("Failed to find DetectorElement with geometry id <" + geomIdExp.toString() + "> !");
230         }
231 
232         // Set the DetectorElement to use for local to global transform.
233         IDetectorElement sensor = deSearch.get(0);
234 
235         globalPosition[2] = sensor.getGeometry().getPosition().z();
236     } 
237 
238      */
239 }