View Javadoc

1   package org.lcsim.geometry.segmentation;
2   
3   import hep.physics.vec.BasicHep3Vector;
4   import hep.physics.vec.Hep3Vector;
5   
6   import java.util.ArrayList;
7   
8   import org.jdom.DataConversionException;
9   import org.jdom.Element;
10  import org.lcsim.detector.IDetectorElement;
11  import org.lcsim.detector.IDetectorElementContainer;
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.identifier.Identifier;
16  import org.lcsim.detector.solids.Box;
17  import org.lcsim.detector.solids.Inside;
18  import org.lcsim.geometry.util.IDDescriptor;
19  
20  /**
21   * This segmentation represents an XY Cartesian grid.  It can be used 
22   * to segment staves in a calorimeter that have box shaped layers. 
23   * 
24   * @author Jeremy McCormick <jeremym@slac.stanford.edu>
25   * @version $Id: CartesianGridXY.java,v 1.13 2013/01/24 22:24:20 jeremy Exp $
26   */
27  public class CartesianGridXY extends AbstractCartesianGrid
28  {
29      private int xIndex = -1;
30      private int yIndex = -1;
31      
32      private static final String fieldNames[] = {"x", "y"};
33  
34      public CartesianGridXY(Element node) throws DataConversionException
35      {
36          super(node);
37  
38          if (node.getAttribute("gridSizeX") != null)
39          {
40              gridSizeX = node.getAttribute("gridSizeX").getDoubleValue();
41              cellSizes.add(0, gridSizeX);
42          }
43          else
44          {
45              throw new RuntimeException("Missing gridSizeX parameter.");
46          }
47  
48          if (node.getAttribute("gridSizeY") != null)
49          {
50              gridSizeY = node.getAttribute("gridSizeY").getDoubleValue();
51              cellSizes.add(1, gridSizeY);
52          }
53          else
54          {
55              throw new RuntimeException("Missing gridSizeY parameter.");
56          }
57      }
58      
59      public String[] getSegmentationFieldNames() {
60          return fieldNames;
61      }
62  
63      public double getGridSizeX()
64      {
65          return gridSizeX;
66      }
67  
68      public double getGridSizeY()
69      {
70          return gridSizeY;
71      }
72  
73      public long[] getNeighbourIDs(int layerRange, int xRange, int yRange)
74      {
75          return getNeighbourIDs(layerRange, xRange, yRange, xIndex, yIndex);
76      }
77  
78      protected void setSegmentationValues(IExpandedIdentifier geomId, Hep3Vector localPositionVec)
79      {
80          geomId.setValue(xIndex, getXBin(localPositionVec.x()));
81          geomId.setValue(yIndex, getYBin(localPositionVec.y()));
82      }
83  
84      public int getXBin(double x)
85      {
86          return getBin(x, gridSizeX);
87      }
88  
89      public int getYBin(double y)
90      {
91          return getBin(y, gridSizeY);
92      }
93  
94      public boolean boundsCheck(long rawId)
95      {
96          IIdentifier geomId = makeGeometryIdentifier(rawId);
97          IIdentifierHelper helper = getSubdetector().getDetectorElement().getIdentifierHelper();
98          IIdentifier id = new Identifier(rawId);
99          int xVal = helper.getValue(id, xIndex);
100         int yVal = helper.getValue(id, yIndex);
101         IDetectorElementContainer deSrch = getSubdetector().getDetectorElement().findDetectorElement(geomId);
102         if (deSrch == null || deSrch.size() == 0)
103         {
104             return false;
105         }
106         IDetectorElement de = deSrch.get(0);
107         double xPos = computeCoordinate(xVal, gridSizeX);
108         double yPos = computeCoordinate(yVal, gridSizeY);
109         if (de.getGeometry().getLogicalVolume().getSolid() instanceof Box)
110         {
111             Box sensorBox = (Box) de.getGeometry().getLogicalVolume().getSolid();
112             // Check coordinate values against box bounds.
113             if (sensorBox.inside(new BasicHep3Vector(xPos, yPos, 0)) == Inside.INSIDE)
114             {
115                 return true;
116             }
117             // TODO: Handle edge case with partial cells.  (How???)
118             else
119             {
120                 return false;
121             }
122         }
123         else
124         {
125             throw new RuntimeException("Don't know how to bounds check solid " + de.getGeometry().getLogicalVolume()
126                     .getSolid().getName() + ".");
127         }
128     }
129 
130     public void setupGeomFields(IDDescriptor id)
131     {
132         if (geomFields == null)
133         {
134             geomFields = new ArrayList<Integer>();
135 
136             xIndex = id.indexOf("x");
137             yIndex = id.indexOf("y");
138             layerIndex = id.indexOf("layer");
139             try
140             {
141                 sliceIndex = id.indexOf("slice");
142             }
143             catch (IllegalArgumentException x)
144             {
145                 System.err.println("WARNING: The slice field does not exist in this IDDecoder!");
146                 sliceIndex = -1;
147             }
148 
149             // Set geometry field list.
150             for (int i = 0; i < id.fieldCount(); i++)
151             {
152                 String fname = id.fieldName(i);
153                 if (!fname.equals("x") && !fname.equals("y"))
154                 {
155                     geomFields.add(i);
156                 }
157             }
158         }
159     }
160 
161     private void computeLocalX()
162     {
163         localPosition[0] = (((double) getValue(xIndex)) + 0.5) * gridSizeX;
164     }
165 
166     private void computeLocalY()
167     {
168         localPosition[1] = (((double) getValue(yIndex)) + 0.5) * gridSizeY;
169     }
170 
171     protected void computeLocalPosition()
172     {
173         localPosition[0] = localPosition[1] = localPosition[2] = 0.0;
174         computeLocalX();
175         computeLocalY();
176     }
177 }