1 package org.lcsim.recon.cat;
2
3 import java.util.*;
4
5 import org.lcsim.event.*;
6 import org.lcsim.util.Driver;
7 import org.lcsim.geometry.Subdetector;
8
9 import org.lcsim.recon.cat.util.Const;
10 import org.lcsim.recon.cat.util.NoSuchParameterException;
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 final public class GarfieldHitConverter extends Driver {
27
28
29
30 public GarfieldHitConverter() {}
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 public void set(String name, String value) {
46 if (name.equalsIgnoreCase("OUTPUT_COLLECTION_NAME")) {
47 outputCollectionName = value;
48 } else if (name.equalsIgnoreCase("INCLIDE_HIT_COLLECTION")) {
49 inputCollectionNames.add(value);
50 } else {
51 throw new NoSuchParameterException(name, this.getClass());
52 }
53 }
54
55
56
57
58
59
60
61
62
63
64
65
66 public void set(String name, boolean value) {
67 if (name.equalsIgnoreCase("INCLUDE_VXD")) {
68 modeUseVXD = value;
69 } else if (name.equalsIgnoreCase("OUTSIDE_IN")) {
70 modeFromOutsideIn = value;
71 } else {
72 throw new NoSuchParameterException(name, this.getClass());
73 }
74 }
75
76
77
78
79
80
81
82
83
84 public void set(String name) {set(name, true);}
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99 public void set(String name, double value) {
100 if (name.equalsIgnoreCase("DISTANCE_CUT")) {
101 distanceCut = value;
102 } else if (name.equalsIgnoreCase("BARREL_TILING")) {
103 barrelTiling = value;
104 } else if (name.equalsIgnoreCase("ENDCAP_TILING")) {
105 endcapTiling = value;
106 } else if (name.equalsIgnoreCase("SIMPLE_ERROR")) {
107 simpleError = value;
108 } else {
109 throw new NoSuchParameterException(name, this.getClass());
110 }
111 }
112
113
114
115
116
117
118 public void process(EventHeader event) {
119
120
121
122
123
124
125
126 ArrayList<GarfieldHit> listGarfieldHits = new ArrayList<GarfieldHit>();
127
128 double[] xx0 = new double[]{0.,0.,0.};
129 double[] xx1 = new double[]{0.,0.,0.};
130 int id = 0;
131
132 List<List<SimTrackerHit>> collections = event.get(SimTrackerHit.class);
133 for (List<SimTrackerHit> collection : collections) {
134 String collectionName = event.getMetaData(collection).getName();
135 if (inputCollectionNames.isEmpty() || inputCollectionNames.contains(collectionName)) {
136 for (SimTrackerHit hit: collection){
137
138 if ( (!modeUseVXD) && isVXD(hit)) continue;
139
140 if (findAdjacentHit(hit, listGarfieldHits)) continue;
141
142
143 double[] p=hit.getPoint();
144 int hLayer = hit.getLayer();
145 int newLayerID = getGarfieldLayerID(hit);
146
147 boolean isInEndCap = hit.getSubdetector().isEndcap();
148
149 GarfieldHit gh;
150 if (is3D(hit)){
151 gh = new GarfieldHit(p, simpleError, newLayerID, id);
152 } else if (isInEndCap && isEven(hLayer)){
153 xx0[0]=p[0];
154 xx0[1]=Math.ceil(p[1]/endcapTiling)*endcapTiling;
155 xx0[2]=p[2];
156 xx1[0]=p[0];
157 xx1[1]=(Math.ceil(p[1]/endcapTiling)-1)*endcapTiling;
158 xx1[2]=p[2];
159 gh = new GarfieldHit(xx0, xx1, simpleError, newLayerID, id);
160 gh.setEndcap(true);
161 } else if (isInEndCap && !isEven(hLayer)){
162 xx0[0]=Math.ceil(p[0]/endcapTiling)*endcapTiling;
163 xx0[1]=p[1];
164 xx0[2]=p[2];
165 xx1[0]=(Math.ceil(p[0]/endcapTiling)-1)*endcapTiling;
166 xx1[1]=p[1];
167 xx1[2]=p[2];
168 gh = new GarfieldHit(xx0, xx1, simpleError, newLayerID, id);
169 gh.setEndcap(true);
170 } else {
171 xx0[0]=p[0];
172 xx0[1]=p[1];
173 xx0[2]=barrelTrackerZ(p[2],0,hit.getLayer());
174 xx1[0]=p[0];
175 xx1[1]=p[1];
176 xx1[2]=barrelTrackerZ(p[2],1,hit.getLayer());
177 gh = new GarfieldHit(xx0, xx1, simpleError, newLayerID, id);
178 }
179 gh.addRawHit(hit);
180 listGarfieldHits.add(gh);
181 id++;
182 }
183 }
184 }
185
186
187
188 if (modeFromOutsideIn){
189 Collections.sort(listGarfieldHits, new Comparator() {
190 public int compare(Object o1, Object o2) {
191 return ((GarfieldHit)o2).getLayer() - ((GarfieldHit)o1).getLayer();
192 }
193 });
194 } else{
195 Collections.sort(listGarfieldHits, new Comparator() {
196 public int compare(Object o1, Object o2) {
197 return ((GarfieldHit)o1).getLayer() - ((GarfieldHit)o2).getLayer();
198 }
199 });
200 }
201
202
203 listGarfieldHits.trimToSize();
204 event.put(outputCollectionName, listGarfieldHits);
205 }
206
207
208
209
210
211
212
213
214
215
216
217
218 private boolean findAdjacentHit(SimTrackerHit newHit, ArrayList<GarfieldHit> oldHitList) {
219 boolean tooClose = false;
220 for (GarfieldHit gHit : oldHitList) {
221 List<SimTrackerHit> rawHits = (List<SimTrackerHit>)gHit.getRawHits();
222 for (SimTrackerHit oldHit : rawHits) {
223 if ( (newHit.getLayer() == oldHit.getLayer()) && (oldHit.getSubdetector().getSystemID() == newHit.getSubdetector().getSystemID()) ) {
224 double[] p1 = newHit.getPoint();
225 double[] p2 = oldHit.getPoint();
226 double alphaZ = 1.;
227 if (oldHit.getSubdetector().isBarrel() && !isVXD(oldHit)) alphaZ = 0.0001;
228 double d = Math.sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+alphaZ*(p1[2]-p2[2])*(p1[2]-p2[2]));
229 tooClose = (d < this.distanceCut);
230 }
231 if (tooClose) {
232 gHit.addRawHit(newHit);
233 return true;
234 }
235 }
236 }
237 return false;
238 }
239
240
241
242
243
244 private int getGarfieldLayerID(SimTrackerHit hit) {
245 int layer = hit.getLayer();
246 Subdetector sys = hit.getSubdetector();
247 if (sys == Const.det().VXD_BARREL.subdetector() || sys == Const.det().VXD_ENDCAP.subdetector()) {
248 layer = layer;
249 } else if (sys == Const.det().TRACKER_BARREL.subdetector()) {
250 layer = layer + Const.det().VXD_BARREL.nLayers();
251 } else if (sys == Const.det().TRACKER_ENDCAP.subdetector() || sys == Const.det().TRACKER_FORWARD.subdetector()) {
252 layer = layer + Const.det().VXD_BARREL.nLayers()
253 + Const.det().TRACKER_BARREL.nLayers();
254
255 }
256 return layer;
257 }
258
259
260 private double barrelTrackerZ(double z, int end, int layer){
261
262 double offset;
263 if (isEven(layer) || barrelTiling > 50.*Const.cm) offset = 0.;
264 else offset = 0.5*barrelTiling;
265 double zx = ((int) ((z-offset)/barrelTiling))*barrelTiling+offset;
266 double zy;
267 if (zx<z) zy = zx+ barrelTiling;
268 else zy = zx - barrelTiling;
269 if (end == 0) return zx;
270 else return zy;
271 }
272
273
274
275
276
277
278 private boolean is3D(SimTrackerHit hit){
279 return Const.det().is3D(hit.getSubdetector());
280 }
281
282 private boolean isEven(int i){return ((i % 2) == 0);}
283
284
285 private boolean isVXD(SimTrackerHit hit) {
286 return Const.det().isVXD(hit.getSubdetector());
287 }
288
289
290
291 List<String> inputCollectionNames = new ArrayList<String>(4);
292 String outputCollectionName = "GarfieldHits";
293
294 double distanceCut = 200. * Const.micrometer;
295
296 private double barrelTiling = 10. * Const.cm;
297 private double endcapTiling = 10. * Const.cm;
298
299 private double simpleError = 0.005 * Const.cm;
300
301 private boolean modeFromOutsideIn = true;
302 private boolean modeUseVXD = true;
303
304 }