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