1 package org.lcsim.geometry.segmentation;
2
3 import org.jdom.DataConversionException;
4 import org.jdom.Element;
5 import org.lcsim.geometry.util.IDDescriptor;
6 import org.lcsim.geometry.util.IDEncoder;
7
8
9
10
11
12
13
14 public class ProjectiveCylinder extends BarrelCylinderSegmentationBase
15 {
16 private int thetaBins;
17 private int phiBins;
18
19 private int thetaIndex;
20 private int phiIndex;
21 private int barrelIndex = -1;
22 private int systemIndex = -1;
23
24 private static final String fieldNames[] = {"phi", "theta"};
25
26 ProjectiveCylinder(Element node) throws DataConversionException
27 {
28 super(node);
29 thetaBins = node.getAttribute("thetaBins").getIntValue();
30 phiBins = node.getAttribute("phiBins").getIntValue();
31 }
32
33 public String[] getSegmentationFieldNames() {
34 return fieldNames;
35 }
36
37 public double getCellSizeU()
38 {
39 return getTheta();
40 }
41
42 public double getCellSizeV()
43 {
44 return getPhi();
45 }
46
47
48
49
50 public double getPhi()
51 {
52 return Math.PI * 2 * (getValue(phiIndex) + 0.5) / phiBins;
53 }
54
55
56
57
58 public double getTheta()
59 {
60 return Math.PI * (getValue(thetaIndex) + 0.5) / thetaBins;
61 }
62
63 public double getX()
64 {
65 return getDistanceToSensitive(getLayer()) * Math.cos(getPhi());
66 }
67
68 public double getY()
69 {
70 return getDistanceToSensitive(getLayer()) * Math.sin(getPhi());
71 }
72
73 public double getZ()
74 {
75 double cosTheta = Math.cos(getTheta());
76 return getDistanceToSensitive(getLayer()) * cosTheta / Math.sqrt(1 - cosTheta * cosTheta);
77 }
78
79 public void setIDDescription(IDDescriptor id)
80 {
81 super.setIDDescription(id);
82
83 phiIndex = id.indexOf("phi");
84 thetaIndex = id.indexOf("theta");
85 barrelIndex = id.indexOf("barrel");
86 systemIndex = id.indexOf("system");
87 }
88
89 public boolean supportsNeighbours()
90 {
91 return true;
92 }
93
94 public long[] getNeighbourIDs(int deltaLayer, int deltaTheta, int deltaPhi)
95 {
96 IDEncoder encoder = new IDEncoder(descriptor);
97 encoder.setValues(values);
98
99 int nMax = (2*deltaLayer + 1)*(2*deltaTheta + 1)*(2*deltaPhi + 1) - 1;
100 int size = 0;
101 long[] result = new long[nMax];
102 for (int i = -deltaLayer; i <= deltaLayer; i++)
103 {
104 int l = values[layerIndex] + i;
105
106 if (l<0 || l>= getNumberOfLayers() ) continue;
107 encoder.setValue(layerIndex,l);
108
109 for (int j = -deltaTheta; j <= deltaTheta; j++)
110 {
111 int t = values[thetaIndex] + j;
112
113 if (t<0 || t>=thetaBins) continue;
114 encoder.setValue(thetaIndex,t);
115
116 for (int k = -deltaPhi; k <= deltaPhi; k++)
117 {
118 if (i==0 && j==0 && k==0) continue;
119
120 int p = values[phiIndex] + k;
121 if(p<0) p+=phiBins;
122 if(p>=phiBins) p-=phiBins;
123
124 result[size++] = encoder.setValue(phiIndex, p);
125 }
126 }
127 }
128 if (size < result.length)
129 {
130 long[] temp = new long[size];
131 System.arraycopy(result, 0, temp, 0, size);
132 result = temp;
133 }
134 return result;
135 }
136
137 public int getThetaBins()
138 {
139 return thetaBins;
140 }
141
142 public int getPhiBins()
143 {
144 return phiBins;
145 }
146
147
148
149
150
151
152
153
154
155
156
157 public long findCellContainingXYZ(double x, double y, double z)
158 {
159
160
161 if(z<getZMin()) return 0;
162 if(z>getZMax()) return 0;
163 double rho = Math.sqrt(x*x+y*y);
164 if(rho<getRMin()) return 0;
165 if(rho>getRMax()) return 0;
166
167
168 int ilay = getLayerBin(rho);
169
170 double phi = Math.atan2(y, x);
171 if (phi < 0)
172 phi += 2 * Math.PI;
173 int iphi = (int) (phi * phiBins / (2 * Math.PI));
174
175 double theta = Math.atan2(rho, z);
176 int itheta = (int) (theta * thetaBins / Math.PI);
177
178 IDEncoder enc = new IDEncoder(descriptor);
179 enc.setValue(layerIndex, ilay);
180 enc.setValue(thetaIndex, itheta);
181 enc.setValue(phiIndex, iphi);
182 enc.setValue(barrelIndex, 0);
183 enc.setValue(systemIndex, detector.getSystemID());
184 long resultID = enc.getID();
185
186 return resultID;
187 }
188 }