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.identifier.ExpandedIdentifier;
9 import org.lcsim.detector.identifier.IExpandedIdentifier;
10 import org.lcsim.detector.identifier.IIdentifier;
11 import org.lcsim.detector.identifier.IIdentifierHelper;
12 import org.lcsim.detector.identifier.Identifier;
13 import org.lcsim.geometry.subdetector.AbstractPolyhedraCalorimeter;
14 import org.lcsim.geometry.util.BaseIDDecoder;
15 import org.lcsim.geometry.util.IDDescriptor;
16 import org.lcsim.geometry.util.IDEncoder;
17
18
19
20
21
22
23
24 public class RegularNgonCartesianGridXY extends CartesianGridXY
25 {
26 private double gridSizeX = 0;
27 private double gridSizeY = 0;
28 private int nmodules = 12;
29
30 private int xIndex = -1;
31 private int yIndex = -1;
32 private int moduleIndex = -1;
33
34 private int[] nvalidx;
35 private boolean[] borderCellIsDuplicate;
36
37 private static final String fieldNames[] = {"x", "y"};
38
39 public RegularNgonCartesianGridXY(Element node) throws DataConversionException
40 {
41 super(node);
42
43 if (node.getAttribute("gridSizeX") != null)
44 {
45 gridSizeX = node.getAttribute("gridSizeX").getDoubleValue();
46 cellSizes.add(0, gridSizeX);
47 }
48 else
49 {
50 throw new RuntimeException("Missing gridSizeX parameter.");
51 }
52
53 if (node.getAttribute("gridSizeY") != null)
54 {
55 gridSizeY = node.getAttribute("gridSizeY").getDoubleValue();
56 cellSizes.add(1, gridSizeY);
57 }
58 else
59 {
60 throw new RuntimeException("Missing gridSizeY parameter.");
61 }
62 }
63
64 public String[] getSegmentationFieldNames() {
65 return fieldNames;
66 }
67
68 public long[] getNeighbourIDs(int layerRange, int xRange, int yRange)
69 {
70 if (this.getDecoder().getID() == 0)
71 throw new RuntimeException("No current ID is set.");
72 if(sensitiveSlices == null)initSensitiveSlices();
73 IDEncoder gnEncoder = new IDEncoder(descriptor);
74 BaseIDDecoder gnDecoder = new BaseIDDecoder(descriptor);
75 gnEncoder.setValues(values);
76 gnDecoder.setID(gnEncoder.getID());
77 IDEncoder dupEncoder = new IDEncoder(descriptor);
78 BaseIDDecoder dupDecoder = new BaseIDDecoder(descriptor);
79 dupEncoder.setValues(values);
80 dupDecoder.setID(dupEncoder.getID());
81
82
83 int nlayers = this.getNumberOfLayers();
84
85
86 int currLayer = values[layerIndex];
87 int currX = gnDecoder.getValue(xIndex);
88 int currY = gnDecoder.getValue(yIndex);
89 int currModule = gnDecoder.getValue(moduleIndex);
90
91
92 if (nvalidx == null)
93 {
94 initializeBorders();
95 }
96
97 List<Long> neighbors = new ArrayList<Long>();
98
99
100 for (int ilayer=-layerRange; ilayer<=layerRange; ilayer++)
101 {
102
103 int neighborLayer = currLayer + ilayer;
104
105 if (neighborLayer >= 0 && neighborLayer < nlayers)
106 {
107 gnEncoder.setValue(layerIndex, neighborLayer);
108
109 for (int ix=-xRange; ix<=xRange; ix++)
110 {
111
112 int neighborX = currX + ix;
113 int neighborModule = currModule;
114 int dupX = neighborX;
115 int dupModule = neighborModule;
116 boolean dup = false;
117 if(neighborX < -nvalidx[neighborLayer]+1)
118 {
119 if(neighborX == -nvalidx[neighborLayer])
120 {
121 if(borderCellIsDuplicate[neighborLayer])
122 {
123 dup = true;
124 dupX = -neighborX -1;
125 dupModule = (nmodules + neighborModule -1)%nmodules;
126 }
127 }
128 else
129 {
130 neighborModule = (nmodules + neighborModule -1)%nmodules;
131 neighborX = 2*nvalidx[neighborLayer] + neighborX;
132 if(borderCellIsDuplicate[neighborLayer])neighborX--;
133 }
134 }
135 else if(neighborX > nvalidx[neighborLayer]-2)
136 {
137 if(neighborX == nvalidx[neighborLayer]-1)
138 {
139 if(borderCellIsDuplicate[neighborLayer])
140 {
141 dup = true;
142 dupX = -neighborX -1;
143 dupModule = (neighborModule +1)%nmodules;
144 }
145 }
146 else
147 {
148 neighborModule = (neighborModule +1)%nmodules;
149 neighborX = -2*nvalidx[neighborLayer] + neighborX;
150 if(borderCellIsDuplicate[neighborLayer])neighborX++;
151 }
152 }
153 gnEncoder.setValue(xIndex, neighborX);
154 gnEncoder.setValue(moduleIndex, neighborModule);
155
156 for (int iy=-yRange; iy<=yRange; iy++)
157 {
158
159 int neighborY = currY + iy;
160
161 gnEncoder.setValue(yIndex, neighborY);
162
163 if(sliceIndex >= 0)
164 {
165
166 for(int is = 0;is < sensitiveSlices[neighborLayer].size();is++)
167 {
168
169 gnEncoder.setValue(sliceIndex, ((Integer) (sensitiveSlices[neighborLayer].get(is))).intValue());
170
171 if( this.getDecoder().getID()!= gnEncoder.getID())neighbors.add(gnEncoder.getID());
172
173 if(dup)
174 {
175 dupEncoder.setValue(yIndex, neighborY);
176 dupEncoder.setValue(xIndex, dupX);
177 dupEncoder.setValue(layerIndex, neighborLayer);
178 dupEncoder.setValue(moduleIndex, dupModule);
179 dupEncoder.setValue(sliceIndex, ((Integer) (sensitiveSlices[neighborLayer].get(is))).intValue());
180 neighbors.add(dupEncoder.getID());
181 }
182 }
183 }
184 else
185 {
186 if( this.getDecoder().getID()!= gnEncoder.getID())neighbors.add(gnEncoder.getID());
187
188 if(dup)
189 {
190 dupEncoder.setValue(yIndex, neighborY);
191 dupEncoder.setValue(xIndex, dupX);
192 dupEncoder.setValue(layerIndex, neighborLayer);
193 dupEncoder.setValue(moduleIndex, dupModule);
194 neighbors.add(dupEncoder.getID());
195 }
196
197 }
198 }
199 }
200 }
201 }
202
203 long result[] = new long[neighbors.size()];
204 int i = 0;
205 for (Long id : neighbors)
206 {
207 result[i] = id;
208 i++;
209 }
210 return result;
211 }
212 protected void initializeBorders()
213 {
214 nmodules = ((AbstractPolyhedraCalorimeter)getSubdetector()).getNumberOfSides();
215 IIdentifierHelper helper = detector.getDetectorElement().getIdentifierHelper();
216
217 IIdentifier currId = new Identifier(this.getDecoder().getID());
218
219 IExpandedIdentifier thisId = helper.unpack(currId);
220
221
222 nvalidx = new int[this.getNumberOfLayers()];
223
224
225 borderCellIsDuplicate = new boolean[this.getNumberOfLayers()];
226 ExpandedIdentifier testId = new ExpandedIdentifier(thisId);
227 testId.setValue(moduleIndex,0);
228 long save = this.getDecoder().getID();
229 for(int layer=0;layer<this.getNumberOfLayers();layer++)
230 {
231 testId.setValue(layerIndex, layer);
232 this.getDecoder().setID(helper.pack(testId).getValue());
233 this.computeGlobalPosition();
234 double yc = this.globalPosition[1];
235 double xhl = yc*Math.tan(Math.PI/nmodules);
236 nvalidx[layer] = (int)(xhl/gridSizeX) + 1;
237 double bcw = (nvalidx[layer]*gridSizeX - xhl)/gridSizeX;
238 borderCellIsDuplicate[layer] = false;
239 if(bcw < .5)borderCellIsDuplicate[layer] = true;
240 }
241
242 this.getDecoder().setID(save);
243 this.computeGlobalPosition();
244 }
245 public void setupGeomFields(IDDescriptor id)
246 {
247 super.setupGeomFields(id);
248 xIndex = id.indexOf("x");
249 yIndex = id.indexOf("y");
250 layerIndex = id.indexOf("layer");
251 moduleIndex = id.indexOf("module");
252 }
253
254 }