1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include <stdlib.h> |
14 | #include <stdio.h> |
15 | #include <math.h> |
16 | |
17 | #include <hddm_s.h> |
18 | #include <geant3.h> |
19 | #include <bintree.h> |
20 | extern s_HDDM_t* thisInputEvent; |
21 | |
22 | |
23 | #define ATTEN_LENGTH1e6 1e6 |
24 | #define C_EFFECTIVE15. 15. |
25 | #define WIDTH_OF_BLOCK4. 4. |
26 | #define LENGTH_OF_BLOCK45. 45. |
27 | #define TWO_HIT_RESOL75. 75. |
28 | #define MAX_HITS100 100 |
29 | #define THRESH_MEV30. 30. |
30 | #define ACTIVE_RADIUS120.e6 120.e6 |
31 | #define CENTRAL_ROW29 29 |
32 | #define CENTRAL_COLUMN29 29 |
33 | |
34 | |
35 | binTree_t* gapEMcalTree = 0; |
36 | static int cellCount = 0; |
37 | static int showerCount = 0; |
38 | |
39 | |
40 | |
41 | |
42 | void hitGapEMcal (float xin[4], float xout[4], |
43 | float pin[5], float pout[5], float dEsum, |
44 | int track, int stack, int history, int ipart) |
45 | { |
46 | float x[3], t; |
47 | float xgcal[3]; |
48 | float zeroHat[] = {0,0,0}; |
49 | |
50 | x[0] = (xin[0] + xout[0])/2; |
51 | x[1] = (xin[1] + xout[1])/2; |
52 | x[2] = (xin[2] + xout[2])/2; |
53 | t = (xin[3] + xout[3])/2 * 1e9; |
54 | transformCoord(zeroHat,"local",xgcal,"gCAL")transformcoord_(zeroHat,"local",xgcal,"gCAL",strlen("local"), strlen("gCAL")); |
55 | |
56 | |
57 | |
58 | if ((history == 0) && (pin[3] > THRESH_MEV30./1e3)) |
59 | { |
60 | s_GcalTruthShowers_t* showers; |
61 | float r = sqrt(xin[0]*xin[0]+xin[1]*xin[1]); |
62 | float phi = atan2(xin[1],xin[0]); |
63 | int mark = (1<<30) + showerCount; |
64 | void** twig = getTwig(&gapEMcalTree, mark); |
65 | if (*twig == 0) |
66 | { |
67 | s_GapEMcal_t* cal = *twig = make_s_GapEMcal(); |
68 | cal->gcalTruthShowers = showers = make_s_GcalTruthShowers(1); |
69 | int a = thisInputEvent->physicsEvents->in[0].reactions->in[0].vertices->in[0].products->mult; |
70 | showers->in[0].primary = (stack <= a); |
71 | showers->in[0].track = track; |
72 | showers->in[0].z = xin[2]; |
73 | showers->in[0].r = r; |
74 | showers->in[0].phi = phi; |
75 | showers->in[0].t = xin[3]*1e9; |
76 | showers->in[0].px = pin[0]*pin[4]; |
77 | showers->in[0].py = pin[1]*pin[4]; |
78 | showers->in[0].pz = pin[2]*pin[4]; |
79 | showers->in[0].E = pin[3]; |
80 | showers->in[0].ptype = ipart; |
81 | showers->mult = 1; |
82 | showerCount++; |
83 | } |
84 | } |
85 | |
86 | |
87 | |
88 | if (dEsum > 0) |
89 | { |
90 | int nhit; |
91 | s_GcalHits_t* hits; |
92 | int module = getmodule_(); |
93 | float dist = LENGTH_OF_BLOCK45.-xgcal[2]; |
94 | float dEcorr = dEsum * exp(-dist/ATTEN_LENGTH1e6); |
95 | float tcorr = t + dist/C_EFFECTIVE15.; |
96 | int mark = ((module+1)<<16); |
97 | void** twig = getTwig(&gapEMcalTree, mark); |
98 | if (*twig == 0) |
99 | { |
100 | s_GapEMcal_t* cal = *twig = make_s_GapEMcal(); |
101 | s_GcalCells_t* cells = make_s_GcalCells(1); |
102 | cells->mult = 1; |
103 | cells->in[0].module = module; |
104 | cells->in[0].gcalHits = hits = make_s_GcalHits(MAX_HITS100); |
105 | cal->gcalCells = cells; |
106 | cellCount++; |
107 | } |
108 | else |
109 | { |
110 | s_GapEMcal_t* cal = *twig; |
111 | hits = cal->gcalCells->in[0].gcalHits; |
112 | } |
113 | |
114 | for (nhit = 0; nhit < hits->mult; nhit++) |
115 | { |
116 | if (fabs(hits->in[nhit].t - tcorr) < TWO_HIT_RESOL75.) |
117 | { |
118 | break; |
119 | } |
120 | } |
121 | if (nhit < hits->mult) |
122 | { |
123 | hits->in[nhit].t = |
124 | (hits->in[nhit].t * hits->in[nhit].E + tcorr*dEcorr) |
125 | / (hits->in[nhit].E += dEcorr); |
126 | } |
127 | else if (nhit < MAX_HITS100) |
128 | { |
129 | hits->in[nhit].t = tcorr; |
130 | hits->in[nhit].E = dEcorr; |
131 | hits->mult++; |
132 | } |
133 | else |
134 | { |
135 | fprintf(stderrstderr,"HDGeant error in hitgapEMcal: "); |
136 | fprintf(stderrstderr,"max hit count %d exceeded, truncating!\n",MAX_HITS100); |
137 | exit(2); |
138 | } |
139 | } |
140 | } |
141 | |
142 | |
143 | |
144 | void hitgapemcal_(float* xin, float* xout, |
145 | float* pin, float* pout, float* dEsum, |
146 | int* track, int* stack, int* history, int* ipart) |
147 | { |
148 | hitGapEMcal(xin,xout,pin,pout,*dEsum,*track,*stack,*history, *ipart); |
149 | } |
150 | |
151 | |
152 | |
153 | |
154 | s_GapEMcal_t* pickGapEMcal () |
155 | { |
156 | s_GapEMcal_t* box; |
157 | s_GapEMcal_t* item; |
158 | |
159 | #if TESTING_CAL_CONTAINMENT |
160 | double Etotal = 0; |
161 | #endif |
162 | if ((cellCount == 0) && (showerCount == 0)) |
163 | { |
164 | return HDDM_NULL(void*)&hddm_s_nullTarget; |
165 | } |
166 | |
167 | box = make_s_GapEMcal(); |
168 | box->gcalCells = make_s_GcalCells(cellCount); |
169 | box->gcalTruthShowers = make_s_GcalTruthShowers(showerCount); |
170 | while (item = (s_GapEMcal_t*) pickTwig(&gapEMcalTree)) |
| 1 | Loop condition is true. Entering loop body | |
|
| 6 | | Loop condition is true. Entering loop body | |
|
| 11 | | Loop condition is true. Entering loop body | |
|
171 | { |
172 | s_GcalCells_t* cells = item->gcalCells; |
173 | int cell; |
174 | s_GcalTruthShowers_t* showers = item->gcalTruthShowers; |
175 | int shower; |
176 | for (cell=0; cell < cells->mult; ++cell) |
| 2 | | Loop condition is false. Execution continues on line 215 | |
|
| 7 | | Loop condition is false. Execution continues on line 215 | |
|
| 12 | | Loop condition is true. Entering loop body | |
|
177 | { |
178 | int m = box->gcalCells->mult; |
179 | int mok = 0; |
180 | |
181 | s_GcalHits_t* hits = cells->in[cell].gcalHits; |
182 | |
183 | |
184 | int i,iok; |
185 | for (iok=i=0; i < hits->mult; i++) |
| 13 | | Loop condition is false. Execution continues on line 199 | |
|
186 | { |
187 | if (hits->in[i].E >= THRESH_MEV30./1e3) |
188 | { |
189 | #if TESTING_CAL_CONTAINMENT |
190 | Etotal += hits->in[i].E; |
191 | #endif |
192 | if (iok < i) |
193 | { |
194 | hits->in[iok] = hits->in[i]; |
195 | } |
196 | ++iok; |
197 | } |
198 | } |
199 | if (iok) |
| |
200 | { |
201 | hits->mult = iok; |
202 | box->gcalCells->in[m] = cells->in[cell]; |
203 | box->gcalCells->mult++; |
204 | } |
205 | else if (hits != HDDM_NULL(void*)&hddm_s_nullTarget) |
| |
206 | { |
207 | FREE(hits)free(hits); |
| 16 | | Within the expansion of the macro 'FREE':
| |
|
208 | } |
209 | if (hits != HDDM_NULL(void*)&hddm_s_nullTarget) |
| |
210 | { |
211 | FREE(hits)free(hits); |
| 18 | | Within the expansion of the macro 'FREE':
|
a | Attempt to free released memory |
|
212 | } |
213 | } |
214 | |
215 | for (shower=0; shower < showers->mult; ++shower) |
| 3 | | Loop condition is false. Execution continues on line 220 | |
|
| 8 | | Loop condition is false. Execution continues on line 220 | |
|
216 | { |
217 | int m = box->gcalTruthShowers->mult++; |
218 | box->gcalTruthShowers->in[m] = showers->in[shower]; |
219 | } |
220 | if (cells != HDDM_NULL(void*)&hddm_s_nullTarget) |
| |
| |
221 | { |
222 | FREE(cells)free(cells); |
223 | } |
224 | if (showers != HDDM_NULL(void*)&hddm_s_nullTarget) |
| |
| |
225 | { |
226 | FREE(showers)free(showers); |
227 | } |
228 | FREE(item)free(item); |
229 | } |
230 | |
231 | cellCount = showerCount = 0; |
232 | |
233 | if ((box->gcalCells != HDDM_NULL(void*)&hddm_s_nullTarget) && |
234 | (box->gcalCells->mult == 0)) |
235 | { |
236 | FREE(box->gcalCells)free(box->gcalCells); |
237 | box->gcalCells = HDDM_NULL(void*)&hddm_s_nullTarget; |
238 | } |
239 | if ((box->gcalTruthShowers != HDDM_NULL(void*)&hddm_s_nullTarget) && |
240 | (box->gcalTruthShowers->mult == 0)) |
241 | { |
242 | FREE(box->gcalTruthShowers)free(box->gcalTruthShowers); |
243 | box->gcalTruthShowers = HDDM_NULL(void*)&hddm_s_nullTarget; |
244 | } |
245 | if ((box->gcalCells->mult == 0) && |
246 | (box->gcalTruthShowers->mult == 0)) |
247 | { |
248 | FREE(box)free(box); |
249 | box = HDDM_NULL(void*)&hddm_s_nullTarget; |
250 | } |
251 | #if TESTING_CAL_CONTAINMENT |
252 | printf("GCal energy sum: %f\n",Etotal); |
253 | #endif |
254 | return box; |
255 | } |