File: | /home/sdobbs/work/clang/halld_recon/src/libraries/TOF/DTOFPoint_factory.cc |
Warning: | line 427, column 16 Access to field 'plane' results in a dereference of a null pointer (loaded from variable 'loctofhit') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | // $Id$ | ||||
2 | // | ||||
3 | // File: DTOFPoint_factory.cc | ||||
4 | // Created: Tue Oct 18 09:50:52 EST 2005 | ||||
5 | // Creator: remitche (on Linux mantrid00 2.4.20-18.8smp i686) | ||||
6 | // | ||||
7 | // Modified: Wed Feb 12 13:23:42 EST 2014 B. Zihlamnn | ||||
8 | // use new TOF geometry with narrow long paddles | ||||
9 | // and short paddles #22 and #23 for both north and south | ||||
10 | // | ||||
11 | |||||
12 | #include <cassert> | ||||
13 | #include <cmath> | ||||
14 | using namespace std; | ||||
15 | |||||
16 | #include "DTOFPoint_factory.h" | ||||
17 | |||||
18 | bool Compare_TOFSpacetimeHitMatches_Distance(const DTOFPoint_factory::tof_spacetimehitmatch_t& locTOFSpacetimeHitMatch1, const DTOFPoint_factory::tof_spacetimehitmatch_t& locTOFSpacetimeHitMatch2) | ||||
19 | { | ||||
20 | if(locTOFSpacetimeHitMatch2.dBothPositionsWellDefinedFlag != locTOFSpacetimeHitMatch1.dBothPositionsWellDefinedFlag) | ||||
21 | return locTOFSpacetimeHitMatch1.dBothPositionsWellDefinedFlag; //one hit position is well defined and the other is not | ||||
22 | return (locTOFSpacetimeHitMatch1.delta_r < locTOFSpacetimeHitMatch2.delta_r); | ||||
23 | }; | ||||
24 | |||||
25 | bool Compare_TOFPoint_Time(const DTOFPoint *locTOFPoint1, const DTOFPoint *locTOFPoint2) { | ||||
26 | return locTOFPoint1->t < locTOFPoint2->t; | ||||
27 | } | ||||
28 | |||||
29 | //------------------ | ||||
30 | // brun | ||||
31 | //------------------ | ||||
32 | jerror_t DTOFPoint_factory::brun(JEventLoop *loop, int32_t runnumber) | ||||
33 | { | ||||
34 | loop->GetSingle(dTOFGeometry); | ||||
35 | |||||
36 | map<string, double> tofparms; | ||||
37 | string locTOFParmsTable = dTOFGeometry->Get_CCDB_DirectoryName() + "/tof_parms"; | ||||
38 | if( !loop->GetCalib(locTOFParmsTable.c_str(), tofparms)) | ||||
39 | { | ||||
40 | //cout<<"DTOFPoint_factory: loading values from TOF data base"<<endl; | ||||
41 | //HALFPADDLE = tofparms["TOF_HALFPADDLE"]; | ||||
42 | E_THRESHOLD = tofparms["TOF_E_THRESHOLD"]; | ||||
43 | ATTEN_LENGTH = tofparms["TOF_ATTEN_LENGTH"]; | ||||
44 | } | ||||
45 | else | ||||
46 | { | ||||
47 | cout << "DTOFPoint_factory: Error loading values from TOF data base" <<endl; | ||||
48 | //HALFPADDLE = 126; // set to some reasonable value | ||||
49 | E_THRESHOLD = 0.0005; | ||||
50 | ATTEN_LENGTH = 400.; | ||||
51 | } | ||||
52 | |||||
53 | string locTOFPropSpeedTable = dTOFGeometry->Get_CCDB_DirectoryName() + "/propagation_speed"; | ||||
54 | if(eventLoop->GetCalib(locTOFPropSpeedTable.c_str(), propagation_speed)) | ||||
55 | jout << "Error loading " << locTOFPropSpeedTable << " !" << endl; | ||||
56 | string locTOFPaddleResolTable = dTOFGeometry->Get_CCDB_DirectoryName() + "/paddle_resolutions"; | ||||
57 | if(eventLoop->GetCalib(locTOFPaddleResolTable.c_str(), paddle_resolutions)) | ||||
58 | jout << "Error loading " << locTOFPaddleResolTable << " !" << endl; | ||||
59 | |||||
60 | // for applying attentuation to half lenfgth paddles | ||||
61 | string locTOFAttenLengthTable = dTOFGeometry->Get_CCDB_DirectoryName() + "/attenuation_lengths"; | ||||
62 | if(eventLoop->GetCalib(locTOFAttenLengthTable.c_str(), AttenuationLengths)) | ||||
63 | jout << "Error loading " << locTOFAttenLengthTable << " !" << endl; | ||||
64 | |||||
65 | |||||
66 | HALFPADDLE = dTOFGeometry->Get_HalfLongBarLength(); | ||||
67 | HALFPADDLE_ONESIDED = dTOFGeometry->Get_HalfShortBarLength(); | ||||
68 | double locBeamHoleWidth = dTOFGeometry->Get_LongBarLength() - 2.0*dTOFGeometry->Get_ShortBarLength(); | ||||
69 | ONESIDED_PADDLE_MIDPOINT_MAG = HALFPADDLE_ONESIDED + locBeamHoleWidth/2.0; | ||||
70 | |||||
71 | NUM_BARS = dTOFGeometry->Get_NBars(); | ||||
72 | |||||
73 | dPositionMatchCut_DoubleEnded = 9.0; //1.5*BARWIDTH | ||||
74 | // dTimeMatchCut_PositionWellDefined = 1.0; | ||||
75 | dTimeMatchCut_PositionWellDefined = 10.0; | ||||
76 | dTimeMatchCut_PositionNotWellDefined = 10.0; | ||||
77 | |||||
78 | return NOERROR; | ||||
79 | } | ||||
80 | |||||
81 | DTOFPoint_factory::tof_spacetimehit_t* DTOFPoint_factory::Get_TOFSpacetimeHitResource(void) | ||||
82 | { | ||||
83 | tof_spacetimehit_t* locTOFSpacetimeHit; | ||||
84 | if(dTOFSpacetimeHitPool_Available.empty()) | ||||
85 | { | ||||
86 | locTOFSpacetimeHit = new tof_spacetimehit_t; | ||||
87 | dTOFSpacetimeHitPool_All.push_back(locTOFSpacetimeHit); | ||||
88 | } | ||||
89 | else | ||||
90 | { | ||||
91 | locTOFSpacetimeHit = dTOFSpacetimeHitPool_Available.back(); | ||||
92 | dTOFSpacetimeHitPool_Available.pop_back(); | ||||
93 | } | ||||
94 | return locTOFSpacetimeHit; | ||||
95 | } | ||||
96 | |||||
97 | //------------------ | ||||
98 | // evnt | ||||
99 | //------------------ | ||||
100 | jerror_t DTOFPoint_factory::evnt(JEventLoop *loop, uint64_t eventnumber) | ||||
101 | { | ||||
102 | // delete pool size if too large, preventing memory-leakage-like behavor. | ||||
103 | if(dTOFSpacetimeHitPool_All.size() > MAX_TOFSpacetimeHitPoolSize) | ||||
104 | { | ||||
105 | for(size_t loc_i = MAX_TOFSpacetimeHitPoolSize; loc_i < dTOFSpacetimeHitPool_All.size(); ++loc_i) | ||||
106 | delete dTOFSpacetimeHitPool_All[loc_i]; | ||||
107 | dTOFSpacetimeHitPool_All.resize(MAX_TOFSpacetimeHitPoolSize); | ||||
108 | } | ||||
109 | dTOFSpacetimeHitPool_Available = dTOFSpacetimeHitPool_All; | ||||
110 | |||||
111 | vector<const DTOFPaddleHit*> locTOFHitVector; | ||||
112 | loop->Get(locTOFHitVector); | ||||
113 | |||||
114 | // create the hit spacetime information | ||||
115 | deque<tof_spacetimehit_t*> locTOFSpacetimeHits_Horizontal, locTOFSpacetimeHits_Vertical; | ||||
116 | set<tof_spacetimehit_t*> locUnusedTOFSpacetimeHits; | ||||
117 | for(size_t loc_i = 0; loc_i < locTOFHitVector.size(); ++loc_i) | ||||
118 | { | ||||
119 | const DTOFPaddleHit* locTOFHit = locTOFHitVector[loc_i]; | ||||
120 | if(!((locTOFHit->E_north > E_THRESHOLD) || (locTOFHit->E_south > E_THRESHOLD))) | ||||
121 | continue; | ||||
122 | |||||
123 | if(locTOFHit->orientation) //horizontal | ||||
124 | { | ||||
125 | tof_spacetimehit_t* locSpacetimeHit = Build_TOFSpacetimeHit_Horizontal(locTOFHit); | ||||
126 | locTOFSpacetimeHits_Horizontal.push_back(locSpacetimeHit); | ||||
127 | locUnusedTOFSpacetimeHits.insert(locSpacetimeHit); | ||||
128 | } | ||||
129 | else //vertical | ||||
130 | { | ||||
131 | tof_spacetimehit_t* locSpacetimeHit = Build_TOFSpacetimeHit_Vertical(locTOFHit); | ||||
132 | locTOFSpacetimeHits_Vertical.push_back(locSpacetimeHit); | ||||
133 | locUnusedTOFSpacetimeHits.insert(locSpacetimeHit); | ||||
134 | } | ||||
135 | } | ||||
136 | |||||
137 | |||||
138 | //find matches between planes and sort them by delta-r | ||||
139 | deque<tof_spacetimehitmatch_t> locTOFSpacetimeHitMatches; //use list for sorting, vector for resource pool | ||||
140 | for(size_t loc_i = 0; loc_i < locTOFSpacetimeHits_Horizontal.size(); ++loc_i) | ||||
141 | { | ||||
142 | tof_spacetimehit_t* locTOFSpacetimeHit_Horizontal = locTOFSpacetimeHits_Horizontal[loc_i]; | ||||
143 | for(size_t loc_j = 0; loc_j < locTOFSpacetimeHits_Vertical.size(); ++loc_j) | ||||
144 | { | ||||
145 | tof_spacetimehit_t* locTOFSpacetimeHit_Vertical = locTOFSpacetimeHits_Vertical[loc_j]; | ||||
146 | |||||
147 | tof_spacetimehitmatch_t locTOFSpacetimeHitMatch; | ||||
148 | if(!Match_Hits(locTOFSpacetimeHit_Horizontal, locTOFSpacetimeHit_Vertical, locTOFSpacetimeHitMatch)) | ||||
149 | continue; //not a match | ||||
150 | |||||
151 | locTOFSpacetimeHitMatches.push_back(locTOFSpacetimeHitMatch); | ||||
152 | } | ||||
153 | } | ||||
154 | std::sort(locTOFSpacetimeHitMatches.begin(), locTOFSpacetimeHitMatches.end(), Compare_TOFSpacetimeHitMatches_Distance); //sort matches by delta_r | ||||
155 | |||||
156 | |||||
157 | // create DTOFPoints, in order of best matches (by delta_r) | ||||
158 | for(size_t loc_i = 0; loc_i < locTOFSpacetimeHitMatches.size(); ++loc_i) | ||||
159 | { | ||||
160 | tof_spacetimehit_t* locTOFSpacetimeHit_Horizontal = locTOFSpacetimeHitMatches[loc_i].dTOFSpacetimeHit_Horizontal; | ||||
161 | if(locUnusedTOFSpacetimeHits.find(locTOFSpacetimeHit_Horizontal) == locUnusedTOFSpacetimeHits.end()) | ||||
162 | continue; //hit used in a previous successful match | ||||
163 | |||||
164 | tof_spacetimehit_t* locTOFSpacetimeHit_Vertical = locTOFSpacetimeHitMatches[loc_i].dTOFSpacetimeHit_Vertical; | ||||
165 | if(locUnusedTOFSpacetimeHits.find(locTOFSpacetimeHit_Vertical) == locUnusedTOFSpacetimeHits.end()) | ||||
166 | continue; //hit used in a previous successful match | ||||
167 | |||||
168 | Create_MatchedTOFPoint(locTOFSpacetimeHit_Horizontal, locTOFSpacetimeHit_Vertical); | ||||
169 | |||||
170 | //remove used hits from the unused list | ||||
171 | locUnusedTOFSpacetimeHits.erase(locTOFSpacetimeHit_Horizontal); | ||||
172 | locUnusedTOFSpacetimeHits.erase(locTOFSpacetimeHit_Vertical); | ||||
173 | } | ||||
174 | |||||
175 | // Loop over unused/unmatched TOF Spacetime hits, and create separate DTOFPoint's for them | ||||
176 | set<tof_spacetimehit_t*>::iterator locSetIterator = locUnusedTOFSpacetimeHits.begin(); | ||||
177 | for(; locSetIterator != locUnusedTOFSpacetimeHits.end(); ++locSetIterator) | ||||
178 | Create_UnMatchedTOFPoint(*locSetIterator); | ||||
179 | |||||
180 | // make sure all the hits are sorted by time (why not?) | ||||
181 | // this helps with reproducibiliy problems... | ||||
182 | std::sort(_data.begin(), _data.end(), Compare_TOFPoint_Time); | ||||
183 | |||||
184 | |||||
185 | return NOERROR; | ||||
186 | } | ||||
187 | |||||
188 | DTOFPoint_factory::tof_spacetimehit_t* DTOFPoint_factory::Build_TOFSpacetimeHit_Horizontal(const DTOFPaddleHit* locTOFHit) | ||||
189 | { | ||||
190 | tof_spacetimehit_t* locTOFSpacetimeHit = Get_TOFSpacetimeHitResource(); | ||||
191 | locTOFSpacetimeHit->TOFHit = locTOFHit; | ||||
192 | |||||
193 | int bar = locTOFHit->bar; | ||||
194 | int id = NUM_BARS + locTOFHit->bar - 1; | ||||
195 | double v = propagation_speed[id]; | ||||
196 | |||||
197 | if((locTOFHit->bar < dTOFGeometry->Get_FirstShortBar()) || (locTOFHit->bar > dTOFGeometry->Get_LastShortBar())) //double-ended bars | ||||
198 | { | ||||
199 | locTOFSpacetimeHit->dIsDoubleEndedBar = true; | ||||
200 | locTOFSpacetimeHit->dIsSingleEndedNorthPaddle = false; | ||||
201 | locTOFSpacetimeHit->y = dTOFGeometry->bar2y(bar); | ||||
202 | if(locTOFHit->meantime != locTOFHit->meantime) | ||||
203 | { | ||||
204 | //NaN: only one energy hit above threshold on the double-ended bar | ||||
205 | locTOFSpacetimeHit->dPositionWellDefinedFlag = false; | ||||
206 | locTOFSpacetimeHit->x = 0.0; | ||||
207 | if(locTOFHit->E_north > E_THRESHOLD) | ||||
208 | locTOFSpacetimeHit->t = locTOFHit->t_north - HALFPADDLE/v; | ||||
209 | else | ||||
210 | locTOFSpacetimeHit->t = locTOFHit->t_south - HALFPADDLE/v; | ||||
211 | |||||
212 | locTOFSpacetimeHit->pos_cut = 1000.0; | ||||
213 | locTOFSpacetimeHit->t_cut = dTimeMatchCut_PositionNotWellDefined; | ||||
214 | } | ||||
215 | else | ||||
216 | { | ||||
217 | locTOFSpacetimeHit->dPositionWellDefinedFlag = true; | ||||
218 | locTOFSpacetimeHit->x = locTOFHit->pos; | ||||
219 | locTOFSpacetimeHit->t = locTOFHit->meantime; | ||||
220 | locTOFSpacetimeHit->pos_cut = dPositionMatchCut_DoubleEnded; | ||||
221 | locTOFSpacetimeHit->t_cut = dTimeMatchCut_PositionWellDefined; | ||||
222 | } | ||||
223 | |||||
224 | //printf("h: x %f y %f\n",locTOFSpacetimeHit->x,locTOFSpacetimeHit->y); | ||||
225 | return locTOFSpacetimeHit; | ||||
226 | } | ||||
227 | |||||
228 | //single-ended bars | ||||
229 | locTOFSpacetimeHit->dIsDoubleEndedBar = false; | ||||
230 | locTOFSpacetimeHit->dPositionWellDefinedFlag = false; | ||||
231 | locTOFSpacetimeHit->pos_cut = 1000.0; | ||||
232 | locTOFSpacetimeHit->t_cut = dTimeMatchCut_PositionNotWellDefined; | ||||
233 | |||||
234 | if(locTOFHit->t_south != 0.) | ||||
235 | { | ||||
236 | locTOFSpacetimeHit->dIsSingleEndedNorthPaddle = false; | ||||
237 | locTOFSpacetimeHit->y = dTOFGeometry->bar2y(bar,1); | ||||
238 | locTOFSpacetimeHit->x = -1.0*ONESIDED_PADDLE_MIDPOINT_MAG; | ||||
239 | locTOFSpacetimeHit->t = locTOFHit->t_south - HALFPADDLE_ONESIDED/v; | ||||
240 | } | ||||
241 | else | ||||
242 | { | ||||
243 | locTOFSpacetimeHit->dIsSingleEndedNorthPaddle = true; | ||||
244 | locTOFSpacetimeHit->y = dTOFGeometry->bar2y(bar,0); | ||||
245 | locTOFSpacetimeHit->x = ONESIDED_PADDLE_MIDPOINT_MAG; | ||||
246 | locTOFSpacetimeHit->t = locTOFHit->t_north - HALFPADDLE_ONESIDED/v; | ||||
247 | } | ||||
248 | |||||
249 | //printf("h: x %f y %f\n",locTOFSpacetimeHit->x,locTOFSpacetimeHit->y); | ||||
250 | return locTOFSpacetimeHit; | ||||
251 | } | ||||
252 | |||||
253 | DTOFPoint_factory::tof_spacetimehit_t* DTOFPoint_factory::Build_TOFSpacetimeHit_Vertical(const DTOFPaddleHit* locTOFHit) | ||||
254 | { | ||||
255 | tof_spacetimehit_t* locTOFSpacetimeHit = Get_TOFSpacetimeHitResource(); | ||||
256 | locTOFSpacetimeHit->TOFHit = locTOFHit; | ||||
257 | |||||
258 | int bar = locTOFHit->bar; | ||||
259 | int id = locTOFHit->bar - 1; | ||||
260 | double v = propagation_speed[id]; | ||||
261 | |||||
262 | if((locTOFHit->bar < dTOFGeometry->Get_FirstShortBar()) || (locTOFHit->bar > dTOFGeometry->Get_LastShortBar())) | ||||
263 | { | ||||
264 | //double-ended bars | ||||
265 | locTOFSpacetimeHit->dIsDoubleEndedBar = true; | ||||
266 | locTOFSpacetimeHit->dIsSingleEndedNorthPaddle = false; | ||||
267 | locTOFSpacetimeHit->x = dTOFGeometry->bar2y(bar); | ||||
268 | if(locTOFHit->meantime != locTOFHit->meantime) | ||||
269 | { | ||||
270 | //NaN: only one energy hit above threshold on the double-ended bar | ||||
271 | locTOFSpacetimeHit->dPositionWellDefinedFlag = false; | ||||
272 | locTOFSpacetimeHit->y = 0.0; | ||||
273 | if(locTOFHit->E_north > E_THRESHOLD) | ||||
274 | locTOFSpacetimeHit->t = locTOFHit->t_north - HALFPADDLE/v; | ||||
275 | else | ||||
276 | locTOFSpacetimeHit->t = locTOFHit->t_south - HALFPADDLE/v; | ||||
277 | locTOFSpacetimeHit->pos_cut = 1000.0; | ||||
278 | locTOFSpacetimeHit->t_cut = dTimeMatchCut_PositionNotWellDefined; | ||||
279 | } | ||||
280 | else | ||||
281 | { | ||||
282 | locTOFSpacetimeHit->dPositionWellDefinedFlag = true; | ||||
283 | locTOFSpacetimeHit->y = locTOFHit->pos; | ||||
284 | locTOFSpacetimeHit->t = locTOFHit->meantime; | ||||
285 | locTOFSpacetimeHit->pos_cut = dPositionMatchCut_DoubleEnded; | ||||
286 | locTOFSpacetimeHit->t_cut = dTimeMatchCut_PositionWellDefined; | ||||
287 | } | ||||
288 | |||||
289 | //printf("h: x %f y %f\n",locTOFSpacetimeHit->x,locTOFSpacetimeHit->y); | ||||
290 | return locTOFSpacetimeHit; | ||||
291 | } | ||||
292 | |||||
293 | //single-ended bars | ||||
294 | locTOFSpacetimeHit->dIsDoubleEndedBar = false; | ||||
295 | locTOFSpacetimeHit->dPositionWellDefinedFlag = false; | ||||
296 | locTOFSpacetimeHit->pos_cut = 1000.0; | ||||
297 | locTOFSpacetimeHit->t_cut = dTimeMatchCut_PositionNotWellDefined; | ||||
298 | if(locTOFHit->t_south != 0.) | ||||
299 | { | ||||
300 | locTOFSpacetimeHit->dIsSingleEndedNorthPaddle = false; | ||||
301 | locTOFSpacetimeHit->x = dTOFGeometry->bar2y(bar,0); | ||||
302 | locTOFSpacetimeHit->y = -1.0*ONESIDED_PADDLE_MIDPOINT_MAG; | ||||
303 | locTOFSpacetimeHit->t = locTOFHit->t_south - HALFPADDLE_ONESIDED/v; | ||||
304 | } | ||||
305 | else | ||||
306 | { | ||||
307 | locTOFSpacetimeHit->dIsSingleEndedNorthPaddle = true; | ||||
308 | locTOFSpacetimeHit->x = dTOFGeometry->bar2y(bar,1); | ||||
309 | locTOFSpacetimeHit->y = ONESIDED_PADDLE_MIDPOINT_MAG; | ||||
310 | locTOFSpacetimeHit->t = locTOFHit->t_north - HALFPADDLE_ONESIDED/v; | ||||
311 | } | ||||
312 | |||||
313 | //printf("h: x %f y %f\n",locTOFSpacetimeHit->x,locTOFSpacetimeHit->y); | ||||
314 | return locTOFSpacetimeHit; | ||||
315 | } | ||||
316 | |||||
317 | bool DTOFPoint_factory::Match_Hits(tof_spacetimehit_t* locTOFSpacetimeHit_Horizontal, tof_spacetimehit_t* locTOFSpacetimeHit_Vertical, tof_spacetimehitmatch_t& locTOFSpacetimeHitMatch) | ||||
318 | { | ||||
319 | //make sure that single-ended paddles don't match each other | ||||
320 | if((!locTOFSpacetimeHit_Vertical->dIsDoubleEndedBar) && (!locTOFSpacetimeHit_Horizontal->dIsDoubleEndedBar)) | ||||
321 | return false; //unphysical | ||||
322 | |||||
323 | //make sure that (e.g. horizontal) single-ended paddles don't match (e.g. vertical) paddles on the opposite side | ||||
324 | if(!locTOFSpacetimeHit_Horizontal->dIsDoubleEndedBar) | ||||
325 | { | ||||
326 | //horizontal is single-ended | ||||
327 | if(locTOFSpacetimeHit_Horizontal->dIsSingleEndedNorthPaddle) | ||||
328 | { | ||||
329 | //horizontal is on north (+x) side | ||||
330 | if(locTOFSpacetimeHit_Vertical->TOFHit->bar < dTOFGeometry->Get_FirstShortBar()) | ||||
331 | return false; //vertical is on south (-x) side: CANNOT MATCH | ||||
332 | } | ||||
333 | else | ||||
334 | { | ||||
335 | //horizontal is on south (-x) side | ||||
336 | if(locTOFSpacetimeHit_Vertical->TOFHit->bar > dTOFGeometry->Get_LastShortBar()) | ||||
337 | return false; //vertical is on north (+x) side: CANNOT MATCH | ||||
338 | } | ||||
339 | } | ||||
340 | else if(!locTOFSpacetimeHit_Vertical->dIsDoubleEndedBar) | ||||
341 | { | ||||
342 | //vertical is single-ended | ||||
343 | if(locTOFSpacetimeHit_Vertical->dIsSingleEndedNorthPaddle) | ||||
344 | { | ||||
345 | //vertical is on north (+y) side | ||||
346 | if(locTOFSpacetimeHit_Horizontal->TOFHit->bar < dTOFGeometry->Get_FirstShortBar()) | ||||
347 | return false; //horizontal is on south (-y) side: CANNOT MATCH | ||||
348 | } | ||||
349 | else | ||||
350 | { | ||||
351 | //vertical is on south (-y) side | ||||
352 | if(locTOFSpacetimeHit_Horizontal->TOFHit->bar > dTOFGeometry->Get_LastShortBar()) | ||||
353 | return false; //horizontal is on north (+y) side: CANNOT MATCH | ||||
354 | } | ||||
355 | } | ||||
356 | |||||
357 | //If the position along BOTH paddles is not well defined, cannot tell whether these hits match or not | ||||
358 | //If the hit multiplicity was low, could just generate all matches | ||||
359 | //However, the hit multiplicity is generally very high due to hits near the beamline: would have TOF hits everywhere | ||||
360 | //Therefore, don't keep as match: register separately, let track / tof matching salvage the situation | ||||
361 | if((!locTOFSpacetimeHit_Horizontal->dPositionWellDefinedFlag) && (!locTOFSpacetimeHit_Vertical->dPositionWellDefinedFlag)) | ||||
362 | return false; //have no idea whether these hits go together: assume they don't | ||||
363 | |||||
364 | float locDeltaX = locTOFSpacetimeHit_Horizontal->x - locTOFSpacetimeHit_Vertical->x; | ||||
365 | if(fabs(locDeltaX) > locTOFSpacetimeHit_Horizontal->pos_cut) | ||||
366 | return false; | ||||
367 | |||||
368 | float locDeltaY = locTOFSpacetimeHit_Horizontal->y - locTOFSpacetimeHit_Vertical->y; | ||||
369 | if(fabs(locDeltaY) > locTOFSpacetimeHit_Vertical->pos_cut) | ||||
370 | return false; | ||||
371 | |||||
372 | float locDeltaT = locTOFSpacetimeHit_Horizontal->t - locTOFSpacetimeHit_Vertical->t; | ||||
373 | float locTimeCut = (locTOFSpacetimeHit_Horizontal->t_cut > locTOFSpacetimeHit_Vertical->t_cut) ? locTOFSpacetimeHit_Horizontal->t_cut : locTOFSpacetimeHit_Vertical->t_cut; | ||||
374 | if(fabs(locDeltaT) > locTimeCut) | ||||
375 | return false; | ||||
376 | |||||
377 | locTOFSpacetimeHitMatch.delta_t = locDeltaT; | ||||
378 | locTOFSpacetimeHitMatch.delta_r = sqrt(locDeltaX*locDeltaX + locDeltaY*locDeltaY); | ||||
379 | locTOFSpacetimeHitMatch.dTOFSpacetimeHit_Horizontal = locTOFSpacetimeHit_Horizontal; | ||||
380 | locTOFSpacetimeHitMatch.dTOFSpacetimeHit_Vertical = locTOFSpacetimeHit_Vertical; | ||||
381 | locTOFSpacetimeHitMatch.dBothPositionsWellDefinedFlag = (locTOFSpacetimeHit_Horizontal->dPositionWellDefinedFlag == locTOFSpacetimeHit_Vertical->dPositionWellDefinedFlag); | ||||
382 | |||||
383 | return true; | ||||
384 | } | ||||
385 | |||||
386 | void DTOFPoint_factory::Create_MatchedTOFPoint(const tof_spacetimehit_t* locTOFSpacetimeHit_Horizontal, const tof_spacetimehit_t* locTOFSpacetimeHit_Vertical) | ||||
387 | { | ||||
388 | const DTOFPaddleHit* locTOFHit_Horizontal = locTOFSpacetimeHit_Horizontal->TOFHit; | ||||
389 | const DTOFPaddleHit* locTOFHit_Vertical = locTOFSpacetimeHit_Vertical->TOFHit; | ||||
390 | |||||
391 | int id_vert = locTOFHit_Vertical->bar - 1; | ||||
392 | int id_horiz = NUM_BARS + locTOFHit_Horizontal->bar - 1; | ||||
393 | double locVMatchTErr = paddle_resolutions[id_vert]; // paddle time resolutions | ||||
394 | double locHMatchTErr = paddle_resolutions[id_horiz]; | ||||
395 | double locMatchTErr = 0.; | ||||
396 | |||||
397 | //reconstruct TOF hit information, using information from the best bar: one or both of the bars may have a PMT signal below threshold | ||||
398 | float locMatchX, locMatchY, locMatchZ, locMatchdE, locMatchT, locMatchdE1, locMatchdE2; | ||||
399 | if(locTOFSpacetimeHit_Horizontal->dPositionWellDefinedFlag && locTOFSpacetimeHit_Vertical->dPositionWellDefinedFlag) | ||||
| |||||
400 | { | ||||
401 | //both bars have both PMT signals above threshold | ||||
402 | //is x/y resolution from energy calibration better than x/y resolution from paddle edges? | ||||
403 | locMatchX = locTOFSpacetimeHit_Horizontal->x; | ||||
404 | locMatchY = locTOFSpacetimeHit_Vertical->y; | ||||
405 | locMatchZ = dTOFGeometry->Get_CenterMidPlane(); //z: midpoint between tof planes | ||||
406 | locMatchT = 0.5*(locTOFSpacetimeHit_Horizontal->t + locTOFSpacetimeHit_Vertical->t); | ||||
407 | locMatchdE = 0.5*(locTOFHit_Horizontal->dE + locTOFHit_Vertical->dE); | ||||
408 | locMatchTErr = 0.5 * sqrt(locVMatchTErr*locVMatchTErr + locHMatchTErr*locHMatchTErr); | ||||
409 | locMatchdE1 = locTOFHit_Vertical->dE; | ||||
410 | locMatchdE2 = locTOFHit_Horizontal->dE; | ||||
411 | //cout<<"dE / dE1 /dE2 == "<<locMatchdE<<" / "<<locMatchdE1<<" / "<<locMatchdE2<<endl; | ||||
412 | |||||
413 | } | ||||
414 | else if(locTOFSpacetimeHit_Horizontal->dPositionWellDefinedFlag
| ||||
415 | { | ||||
416 | //the vertical position from the vertical paddle is not well defined | ||||
417 | locMatchX = locTOFSpacetimeHit_Horizontal->x; | ||||
418 | locMatchY = locTOFSpacetimeHit_Horizontal->y; | ||||
419 | locMatchT = locTOFSpacetimeHit_Horizontal->t; | ||||
420 | locMatchZ = dTOFGeometry->Get_CenterHorizPlane(); //z: center of horizontal plane | ||||
421 | locMatchdE = locTOFHit_Horizontal->dE; | ||||
422 | locMatchTErr = locHMatchTErr; | ||||
423 | locMatchdE2 = locTOFHit_Horizontal->dE; | ||||
424 | |||||
425 | const DTOFHit* loctofhit; | ||||
426 | locTOFHit_Vertical->GetSingle(loctofhit); | ||||
427 | int id = loctofhit->plane*NUM_BARS*2 + loctofhit->bar-1 + loctofhit->end*NUM_BARS; | ||||
| |||||
428 | float atten1 = AttenuationLengths[id][0]; | ||||
429 | float atten2 = AttenuationLengths[id][1]; | ||||
430 | float locd = TMath::Abs(locMatchY) - 15.; // only attenuate close to end of paddle not to center. | ||||
431 | float corr = 1; | ||||
432 | if (locd>0){ | ||||
433 | corr = (TMath::Exp(-locd/atten1) + TMath::Exp(-locd/atten2))/2.; | ||||
434 | } | ||||
435 | locMatchdE1 = loctofhit->dE * corr; | ||||
436 | //cout<<"Vertical: dE1 "<<locMatchdE1<<" = "<<loctofhit->dE<<" * "<<corr<<endl; | ||||
437 | } | ||||
438 | else if(locTOFSpacetimeHit_Vertical->dPositionWellDefinedFlag) | ||||
439 | { | ||||
440 | //the horizontal position from the horizontal paddle is not well defined | ||||
441 | locMatchX = locTOFSpacetimeHit_Vertical->x; | ||||
442 | locMatchY = locTOFSpacetimeHit_Vertical->y; | ||||
443 | locMatchT = locTOFSpacetimeHit_Vertical->t; | ||||
444 | locMatchZ = dTOFGeometry->Get_CenterVertPlane(); //z: center of vertical plane | ||||
445 | locMatchdE = locTOFHit_Vertical->dE; | ||||
446 | locMatchTErr = locVMatchTErr; | ||||
447 | locMatchdE1 = locTOFHit_Vertical->dE; | ||||
448 | |||||
449 | const DTOFHit* loctofhit; | ||||
450 | locTOFHit_Horizontal->GetSingle(loctofhit); | ||||
451 | int id = loctofhit->plane*NUM_BARS*2 + loctofhit->bar-1 + loctofhit->end*NUM_BARS; | ||||
452 | float atten1 = AttenuationLengths[id][0]; | ||||
453 | float atten2 = AttenuationLengths[id][1]; | ||||
454 | float locd = TMath::Abs(locMatchX) - 15.; // only attenuate close to end of paddle not to center. | ||||
455 | float corr = 1; | ||||
456 | if (locd>0){ | ||||
457 | corr = (TMath::Exp(-locd/atten1) + TMath::Exp(-locd/atten2))/2.; | ||||
458 | } | ||||
459 | locMatchdE2 = loctofhit->dE * corr; | ||||
460 | //cout<<"Horizontal: dE2 "<<locMatchdE2<<" = "<<loctofhit->dE<<" * "<<corr<<endl; | ||||
461 | |||||
462 | } | ||||
463 | else { | ||||
464 | return; | ||||
465 | } | ||||
466 | |||||
467 | DTOFPoint* locTOFPoint = new DTOFPoint; | ||||
468 | locTOFPoint->AddAssociatedObject(locTOFHit_Horizontal); | ||||
469 | locTOFPoint->AddAssociatedObject(locTOFHit_Vertical); | ||||
470 | locTOFPoint->pos.SetXYZ(locMatchX, locMatchY, locMatchZ); | ||||
471 | locTOFPoint->t = locMatchT; | ||||
472 | locTOFPoint->tErr = locMatchTErr; | ||||
473 | locTOFPoint->dE = locMatchdE; | ||||
474 | locTOFPoint->dE1 = locMatchdE1; | ||||
475 | locTOFPoint->dE2 = locMatchdE2; | ||||
476 | |||||
477 | locTOFPoint->dHorizontalBar = locTOFHit_Horizontal->bar; | ||||
478 | locTOFPoint->dVerticalBar = locTOFHit_Vertical->bar; | ||||
479 | |||||
480 | //Status: 0 if no hit (or none above threshold), 1 if only North hit above threshold, 2 if only South hit above threshold, 3 if both hits above threshold | ||||
481 | locTOFPoint->dHorizontalBarStatus = int(locTOFHit_Horizontal->E_north > E_THRESHOLD) + 2*int(locTOFHit_Horizontal->E_south > E_THRESHOLD); | ||||
482 | locTOFPoint->dVerticalBarStatus = int(locTOFHit_Vertical->E_north > E_THRESHOLD) + 2*int(locTOFHit_Vertical->E_south > E_THRESHOLD); | ||||
483 | |||||
484 | _data.push_back(locTOFPoint); | ||||
485 | } | ||||
486 | |||||
487 | void DTOFPoint_factory::Create_UnMatchedTOFPoint(const tof_spacetimehit_t* locTOFSpacetimeHit) | ||||
488 | { | ||||
489 | const DTOFPaddleHit* locPaddleHit = locTOFSpacetimeHit->TOFHit; | ||||
490 | bool locIsHorizontalBarFlag = (locPaddleHit->orientation == 1); | ||||
491 | float locPointZ = locIsHorizontalBarFlag ? dTOFGeometry->Get_CenterHorizPlane() : dTOFGeometry->Get_CenterVertPlane(); | ||||
492 | |||||
493 | int id_vert = locPaddleHit->bar - 1; | ||||
494 | int id_horiz = NUM_BARS + locPaddleHit->bar - 1; | ||||
495 | double locVTErr = paddle_resolutions[id_vert]; // paddle time resolutions | ||||
496 | double locHTErr = paddle_resolutions[id_horiz]; | ||||
497 | |||||
498 | double locTErr = locIsHorizontalBarFlag ? locHTErr : locVTErr; | ||||
499 | |||||
500 | if(locTOFSpacetimeHit->dPositionWellDefinedFlag) | ||||
501 | { | ||||
502 | //Position is well defined | ||||
503 | DTOFPoint* locTOFPoint = new DTOFPoint; | ||||
504 | locTOFPoint->AddAssociatedObject(locPaddleHit); | ||||
505 | |||||
506 | locTOFPoint->pos.SetXYZ(locTOFSpacetimeHit->x, locTOFSpacetimeHit->y, locPointZ); | ||||
507 | locTOFPoint->t = locTOFSpacetimeHit->t; | ||||
508 | locTOFPoint->tErr = locTErr; | ||||
509 | locTOFPoint->dE = locPaddleHit->dE; | ||||
510 | |||||
511 | locTOFPoint->dHorizontalBar = locIsHorizontalBarFlag ? locPaddleHit->bar : 0; | ||||
512 | locTOFPoint->dVerticalBar = locIsHorizontalBarFlag ? 0 : locPaddleHit->bar; | ||||
513 | |||||
514 | //Status: 0 if no hit (or none above threshold), 1 if only North hit above threshold, 2 if only South hit above threshold, 3 if both hits above threshold | ||||
515 | locTOFPoint->dHorizontalBarStatus = locIsHorizontalBarFlag ? 3 : 0; | ||||
516 | locTOFPoint->dVerticalBarStatus = locIsHorizontalBarFlag ? 0 : 3; | ||||
517 | |||||
518 | if (locTOFPoint->dHorizontalBar){ | ||||
519 | locTOFPoint->dE2 = locPaddleHit->dE; | ||||
520 | locTOFPoint->dE1 = 0.; | ||||
521 | } else{ | ||||
522 | locTOFPoint->dE2 = 0.; | ||||
523 | locTOFPoint->dE1 = locPaddleHit->dE; | ||||
524 | } | ||||
525 | |||||
526 | _data.push_back(locTOFPoint); | ||||
527 | } | ||||
528 | else | ||||
529 | { | ||||
530 | //position not well defined: save anyway: | ||||
531 | //Will use track matching to define position in the other direction | ||||
532 | //Then, will update the hit energy and time based on that position | ||||
533 | |||||
534 | DTOFPoint* locTOFPoint = new DTOFPoint; | ||||
535 | locTOFPoint->AddAssociatedObject(locPaddleHit); | ||||
536 | |||||
537 | float locPointX = locTOFSpacetimeHit->x; | ||||
538 | float locPointY = locTOFSpacetimeHit->y; | ||||
539 | locTOFPoint->pos.SetXYZ(locPointX, locPointY, locPointZ); | ||||
540 | locTOFPoint->t = locTOFSpacetimeHit->t; | ||||
541 | locTOFPoint->tErr = locTErr; | ||||
542 | |||||
543 | bool locNorthAboveThresholdFlag = (locPaddleHit->E_north > E_THRESHOLD); | ||||
544 | |||||
545 | locTOFPoint->dHorizontalBar = locIsHorizontalBarFlag ? locPaddleHit->bar : 0; | ||||
546 | locTOFPoint->dVerticalBar = locIsHorizontalBarFlag ? 0 : locPaddleHit->bar; | ||||
547 | |||||
548 | int locBarStatus = locNorthAboveThresholdFlag ? 1 : 2; | ||||
549 | locTOFPoint->dHorizontalBarStatus = locIsHorizontalBarFlag ? locBarStatus : 0; | ||||
550 | locTOFPoint->dVerticalBarStatus = locIsHorizontalBarFlag ? 0 : locBarStatus; | ||||
551 | |||||
552 | //Energy: Propagate to paddle mid-point | ||||
553 | double locDeltaXToMidPoint = locTOFSpacetimeHit->dIsDoubleEndedBar ? HALFPADDLE : HALFPADDLE_ONESIDED; | ||||
554 | float locEnergy = locNorthAboveThresholdFlag ? locPaddleHit->E_north : locPaddleHit->E_south; | ||||
555 | locEnergy *= exp(locDeltaXToMidPoint/ATTEN_LENGTH); | ||||
556 | locTOFPoint->dE = locEnergy; | ||||
557 | |||||
558 | // IGNORE NOW | ||||
559 | return; | ||||
560 | |||||
561 | _data.push_back(locTOFPoint); | ||||
562 | } | ||||
563 | } | ||||
564 | |||||
565 | jerror_t DTOFPoint_factory::fini(void) | ||||
566 | { | ||||
567 | for(size_t loc_i = 0; loc_i < dTOFSpacetimeHitPool_All.size(); ++loc_i) | ||||
568 | delete dTOFSpacetimeHitPool_All[loc_i]; | ||||
569 | return NOERROR; | ||||
570 | } |
1 | // $Id: JObject.h 1709 2006-04-26 20:34:03Z davidl $ |
2 | // |
3 | // File: JObject.h |
4 | // Created: Wed Aug 17 10:57:09 EDT 2005 |
5 | // Creator: davidl (on Darwin wire129.jlab.org 7.8.0 powerpc) |
6 | // |
7 | |
8 | #ifndef _JObject_ |
9 | #define _JObject_ |
10 | |
11 | #include <cstdio> |
12 | #include <sstream> |
13 | #include <cassert> |
14 | #include <map> |
15 | #include <vector> |
16 | #include <set> |
17 | #include <string> |
18 | #include <cstdint> |
19 | #include <type_traits> |
20 | #include <typeinfo> |
21 | #include <stdint.h> |
22 | using std::pair; |
23 | using std::map; |
24 | using std::set; |
25 | using std::vector; |
26 | using std::string; |
27 | using std::stringstream; |
28 | |
29 | // The following is here just so we can use ROOT's THtml class to generate documentation. |
30 | #include "cint.h" |
31 | |
32 | |
33 | /// The JObject class is a base class for all data classes. |
34 | /// (See JFactory and JFactory_base for algorithm classes.) |
35 | /// |
36 | /// |
37 | /// The following line should be included in the public definition of all |
38 | /// classes which inherit from JObject with the argument being the name of the |
39 | /// class without any quotes. |
40 | /// e.g. for a class named "MyClass" : |
41 | /// |
42 | /// public: |
43 | /// JOBJECT_PUBLIC(MyClass); |
44 | /// |
45 | /// This will define a virtual method <i>className()</i> and a static |
46 | /// method <i>static_className()</i> that are used by JANA to identify |
47 | /// the object's last generation in the inheritance chain by name. This |
48 | /// also allows for possible upgrades to JANA in the future without |
49 | /// requiring classes that inherit from JObject to be redefined explicity. |
50 | #define JOBJECT_PUBLIC(T)virtual const char* className(void) const {return static_className ();} static const char* static_className(void) {return "T";} virtual JObject* Clone() const {return CloneObject<T>( *this ) ;} \ |
51 | virtual const char* className(void) const {return static_className();} \ |
52 | static const char* static_className(void) {return #T;} \ |
53 | virtual JObject* Clone() const {return CloneObject<T>( *this );} |
54 | |
55 | |
56 | |
57 | // Place everything in JANA namespace |
58 | namespace jana{ |
59 | |
60 | class JFactory_base; |
61 | class JEventLoop; |
62 | |
63 | class JObject{ |
64 | |
65 | public: |
66 | JOBJECT_PUBLIC(JObject)virtual const char* className(void) const {return static_className ();} static const char* static_className(void) {return "JObject" ;} virtual JObject* Clone() const {return CloneObject<JObject >( *this );}; |
67 | |
68 | typedef unsigned long long oid_t; |
69 | |
70 | JObject() : id((oid_t)this),append_types(false),factory(NULL__null) {} |
71 | JObject( oid_t aId ) : id( aId ),append_types(false),factory(NULL__null) {} |
72 | |
73 | virtual ~JObject(){ |
74 | for(unsigned int i=0; i<auto_delete.size(); i++)delete auto_delete[i]; |
75 | } |
76 | |
77 | // Copy constructor |
78 | JObject(const JObject& o) : |
79 | id( (oid_t)this ), append_types(o.append_types), associated( |
80 | o.associated), auto_delete(), messagelog( |
81 | o.messagelog), factory(o.factory) { |
82 | // Deep copy the objects in auto_delete vector |
83 | for( auto obj : o.auto_delete ) { |
84 | auto_delete.push_back( obj->Clone() ); |
85 | } |
86 | } |
87 | |
88 | // Move constructor |
89 | JObject( const JObject&& o ) : id( (oid_t)this ), append_types(o.append_types), associated( |
90 | std::move(o.associated)), auto_delete(std::move(o.auto_delete)), messagelog( std::move( |
91 | o.messagelog)), factory(o.factory) { |
92 | factory = nullptr; |
93 | } |
94 | |
95 | // Assignment operator |
96 | JObject& operator=( const JObject& o) { |
97 | if( this == &o ) return *this; |
98 | append_types = o.append_types; |
99 | associated = o.associated; |
100 | messagelog = o.messagelog; |
101 | factory = o.factory; |
102 | auto_delete.clear(); |
103 | for( auto obj : o.auto_delete ) { |
104 | auto_delete.push_back( obj->Clone() ); |
105 | } |
106 | return *this; |
107 | } |
108 | |
109 | // Define template static method for cloning the object of this type. This would get called from a |
110 | // virtual method define for each subclass to polymorphically clone the objects. |
111 | template<typename TYPE> |
112 | static typename std::enable_if< |
113 | (std::is_abstract <TYPE>::value || !std::is_copy_constructible<TYPE>::value), JObject*>::type CloneObject( |
114 | const TYPE& obj) { |
115 | // For abstract method it will return null pointer, and probably will cause problems. But |
116 | // there sohuld not be any object of abstract class to start with. |
117 | return nullptr; |
118 | } |
119 | template<typename TYPE> |
120 | static typename std::enable_if< |
121 | (!std::is_abstract <TYPE>::value |
122 | && std::is_copy_constructible <TYPE>::value ), JObject*>::type CloneObject( |
123 | const TYPE& obj) { |
124 | // For non-abstract class create a new object using the copy constructor of the class |
125 | // given in the template argument. |
126 | return new TYPE(obj); |
127 | } |
128 | |
129 | /// Test if this object is of type T by checking its className() against T::static_className() |
130 | template<typename T> bool IsA(const T *t) const {return dynamic_cast<const T*>(this)!=0L;} |
131 | |
132 | /// Test if this object is of type T (or a descendant) by attempting a dynamic cast |
133 | template<typename T> bool IsAT(const T *t) const {return dynamic_cast<const T*>(this)!=0L;} |
134 | |
135 | // Methods for handling associated objects |
136 | inline void AddAssociatedObject(const JObject *obj); |
137 | inline void AddAssociatedObjectAutoDelete(JObject *obj, bool auto_delete=true); |
138 | inline void RemoveAssociatedObject(const JObject *obj); |
139 | inline void ClearAssociatedObjects(void); |
140 | inline bool IsAssociated(const JObject* locObject) const {return (associated.find(locObject) != associated.end());} |
141 | template<typename T> void Get(vector<const T*> &ptrs, string classname="", int max_depth=1000000) const ; |
142 | template<typename T> void GetT(vector<const T*> &ptrs) const ; |
143 | template<typename T> void GetSingle(const T* &ptrs, string classname="") const ; |
144 | template<typename T> void GetSingleT(const T* &ptrs) const ; |
145 | template<typename T> void GetAssociatedAncestors(set<const JObject*> &already_checked, int &max_depth, set<const T*> &objs_found, string classname="") const; |
146 | template<typename T> void GetAssociatedDescendants(JEventLoop *loop, vector<const T*> &associatedTo, int max_depth=1000000); |
147 | void GetAssociatedDescendants(JEventLoop *loop, vector<const JObject*> &associatedTo, int max_depth=1000000); |
148 | |
149 | template<typename T,typename S> void CopyToVector(T itbegin, T itend, vector<const S*> &v) const; |
150 | |
151 | // Methods for handling pretty formatting for dumping to the screen or file |
152 | virtual void toStrings(vector<pair<string,string> > &items)const; |
153 | template<typename T> void AddString(vector<pair<string,string> > &items, const char *name, const char *format, const T &val) const; |
154 | |
155 | // Methods for attaching and retrieving log messages to/from object |
156 | void AddLog(string &message) const {messagelog.push_back(message);} |
157 | void AddLog(vector<string> &messages) const {messagelog.insert(messagelog.end(), messages.begin(), messages.end());} |
158 | void GetLog(vector<string> &messagelog) const {messagelog = this->messagelog;} |
159 | |
160 | // Misc methods |
161 | bool GetAppendTypes(void) const {return append_types;} ///< Get state of append_types flag (for AddString) |
162 | void SetAppendTypes(bool append_types){this->append_types=append_types;} ///< Set state of append_types flag (for AddString) |
163 | void SetFactoryPointer(JFactory_base *factory){this->factory=factory;} |
164 | JFactory_base * GetFactoryPointer(void) const {return factory;} |
165 | string GetName(void) const {return string(className());} |
166 | string GetTag(void) const ; |
167 | string GetNameTag(void) const {return GetName() + (GetTag()=="" ? "":":") + GetTag();} |
168 | |
169 | oid_t id; |
170 | |
171 | private: |
172 | |
173 | bool append_types; |
174 | set<const JObject*> associated; |
175 | // map<const JObject*, string> associated; replaced with set in jana 0.7.7 |
176 | vector<JObject*> auto_delete; |
177 | mutable vector<string> messagelog; |
178 | JFactory_base *factory; |
179 | |
180 | }; |
181 | |
182 | #if !defined(__CINT__) && !defined(__CLING__) |
183 | |
184 | |
185 | //-------------------------- |
186 | // AddAssociatedObject |
187 | //-------------------------- |
188 | void JObject::AddAssociatedObject(const JObject *obj) |
189 | { |
190 | /// Add a JObject to the list of associated objects |
191 | |
192 | assert(obj!=NULL)((obj!=__null) ? static_cast<void> (0) : __assert_fail ( "obj!=__null", "/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JObject.h" , 192, __PRETTY_FUNCTION__)); |
193 | |
194 | associated.insert(obj); |
195 | //associated[obj] = obj->className(); |
196 | } |
197 | |
198 | //-------------------------- |
199 | // AddAssociatedObjectAutoDelete |
200 | //-------------------------- |
201 | void JObject::AddAssociatedObjectAutoDelete(JObject *obj, bool auto_delete) |
202 | { |
203 | /// Add a JObject to the list of associated objects. If the auto_delete |
204 | /// flag is true, then automatically delete it when this object is |
205 | /// deleted. Otherwise, this behaves identically to the AddAssociatedObject |
206 | /// method. |
207 | /// |
208 | /// Note that if the object is removed via RemoveAssociatedObject(...) |
209 | /// then the object is NOT deleted. BUT, if the entire list of associated |
210 | /// objects is cleared via ClearAssociatedObjects, then the object will |
211 | /// be deleted. |
212 | |
213 | AddAssociatedObject(obj); |
214 | |
215 | if(auto_delete)this->auto_delete.push_back(obj); |
216 | } |
217 | |
218 | //-------------------------- |
219 | // RemoveAssociatedObject |
220 | //-------------------------- |
221 | void JObject::RemoveAssociatedObject(const JObject *obj) |
222 | { |
223 | /// Remove the specified JObject from the list of associated |
224 | /// objects. This will NOT delete the object even if the |
225 | /// object was added with the AddAssociatedObjectAutoDelete(...) |
226 | /// method with the auto_delete flag set. |
227 | |
228 | // map<const JObject*, string>::iterator iter = associated.find(obj); |
229 | auto iter = associated.find(obj); |
230 | |
231 | if(iter!=associated.end()){ |
232 | associated.erase(iter); |
233 | } |
234 | } |
235 | |
236 | //-------------------------- |
237 | // ClearAssociatedObjects |
238 | //-------------------------- |
239 | void JObject::ClearAssociatedObjects(void) |
240 | { |
241 | /// Remove all associated objects from the associated objects list. |
242 | /// This will also delete any objects that were added via the |
243 | /// AddAssociatedObjectAutoDelete(...) method with the auto_delete |
244 | /// flag set. |
245 | |
246 | // Clear pointers to associated objects |
247 | associated.clear(); |
248 | |
249 | // Delete objects in the auto_delete list |
250 | for(unsigned int i=0; i<auto_delete.size(); i++)delete auto_delete[i]; |
251 | auto_delete.clear(); |
252 | } |
253 | |
254 | //-------------------------- |
255 | // CopyToVector |
256 | // |
257 | // This litte utility method is here because the g++ 4.4.7 |
258 | // compiler was complaining about the declaration of |
259 | // set<const T*>::iterator it; in the Get method. Very strange |
260 | // but this at least avoids ever having to declare the variable. |
261 | //-------------------------- |
262 | template<typename T,typename S> |
263 | void JObject::CopyToVector(T itbegin, T itend, vector<const S*> &v) const |
264 | { |
265 | for(T it=itbegin; it!=itend; it++) v.push_back(*it); |
266 | } |
267 | |
268 | //-------------------------- |
269 | // Get |
270 | //-------------------------- |
271 | template<typename T> |
272 | void JObject::Get(vector<const T*> &ptrs, string classname, int max_depth) const |
273 | { |
274 | /// Fill the given vector with pointers to the associated objects of the |
275 | /// type on which the vector is based. The objects are chosen by matching |
276 | /// their class names (obtained via JObject::className()) either to the |
277 | /// one provided in classname or to T::static_className() if classname is |
278 | /// an empty string. Associations will be searched to a level of max_depth |
279 | /// to find all objects of the requested type. By default, max_depth is |
280 | /// set to a very large number so that all associations are found. To |
281 | /// limit the search to only objects directly associated with this one, |
282 | /// set max_depth to either "0" or "1". |
283 | /// |
284 | /// The contents of ptrs are cleared upon entry. |
285 | |
286 | if(classname=="")classname=T::static_className(); |
287 | |
288 | // Use the GetAssociatedAncestors method which may call itself |
289 | // recursively to search all levels of association (at or |
290 | // below this object. Objects for which this is an associated |
291 | // object are not checked for). |
292 | set<const JObject*> already_checked; |
293 | set<const T*> objs_found; |
294 | int my_max_depth = max_depth; |
295 | GetAssociatedAncestors(already_checked, my_max_depth, objs_found, classname); |
296 | |
297 | // Copy results into caller's container |
298 | ptrs.clear(); |
299 | CopyToVector(objs_found.begin(), objs_found.end(), ptrs); |
300 | // set<const T*>::iterator it; |
301 | // for(it=objs_found.begin(); it!=objs_found.end(); it++){ |
302 | // ptrs.push_back(*it); |
303 | // } |
304 | } |
305 | |
306 | //-------------------------- |
307 | // GetAssociatedAncestors |
308 | //-------------------------- |
309 | template<typename T> |
310 | void JObject::GetAssociatedAncestors(set<const JObject*> &already_checked, int &max_depth, set<const T*> &objs_found, string classname) const |
311 | { |
312 | /// Get associated objects of the specified type (either "T" or classname). |
313 | /// Check also for associated objects of any associated objects |
314 | /// to a level of max_depth associations. This method calls itself |
315 | /// recursively so care is taken to only check the associated objects |
316 | /// of each object encountered only once. |
317 | /// |
318 | /// The "already_checked" parameter should be passed in as an empty container |
319 | /// that is used to keep track of which objects had their direct associations |
320 | /// checked. "max_depth" indicates the maximum level of associations to check |
321 | /// (n.b. both "0" and "1" means only check direct associations.) This must |
322 | /// be passed as a reference to an existing int since it is modified in order |
323 | /// to keep track of the current depth in the recursive calls. Set max_depth |
324 | /// to a very high number (like 1000000) to check all associations. The |
325 | /// "objs_found" container will contain the actual associated objects found. |
326 | /// The objects are chosen by matching their class names (obtained via |
327 | /// JObject::className()) either to the one provided in "classname" or to |
328 | /// T::static_className() if classname is an empty string. |
329 | |
330 | if(already_checked.find(this) == already_checked.end()) already_checked.insert(this); |
331 | |
332 | if(classname=="")classname=T::static_className(); |
333 | max_depth--; |
334 | |
335 | //map<const JObject*, string>::const_iterator iter = associated.begin(); |
336 | for( auto obj : associated ){ |
337 | |
338 | // Add to list if appropriate |
339 | if( classname == obj->className() ){ |
340 | objs_found.insert( dynamic_cast<const T*>(obj) ); |
341 | } |
342 | |
343 | // Check this object's associated objects if appropriate |
344 | if(max_depth<=0) continue; |
345 | if(already_checked.find(obj) != already_checked.end()) continue; |
346 | already_checked.insert(obj); |
347 | obj->GetAssociatedAncestors(already_checked, max_depth, objs_found, classname); |
348 | } |
349 | |
350 | max_depth++; |
351 | } |
352 | |
353 | //-------------------------- |
354 | // GetAssociatedDescendants |
355 | //-------------------------- |
356 | template<typename T> |
357 | void GetAssociatedDescendants(JEventLoop *loop, vector<const T*> &associatedTo, int max_depth=1000000) |
358 | { |
359 | /// Find objects of type "T" for which this object appears in its |
360 | /// associated ancestors list. (This is kind of the opposite of |
361 | /// the "Get()" method.) |
362 | /// |
363 | /// WARNING: this must build and search the ancestor list of EVERY |
364 | /// object produced by EVERY factory. It is an expensive method |
365 | /// to call. Use it with great caution! |
366 | /// |
367 | /// WARNING: this only searches objects that have already been |
368 | /// created. It will not activate factories they may eventually |
369 | /// claim this as an associated object so the list returned may |
370 | /// be incomplete. |
371 | /// |
372 | /// WARNING: this templated method works by first calling the |
373 | /// JObject form and then dynamically casting each of those to see |
374 | /// if they of type "T". This makes this an even more expensive |
375 | /// call. Again, use with great caution!! |
376 | |
377 | vector<const JObject*> ajobjs; |
378 | GetAssociatedDescendants(loop, ajobjs, max_depth); |
379 | for(uint32_t i=0; i<ajobjs.size(); i++){ |
380 | const T *ptr = dynamic_cast<const T*>(ajobjs[i]); |
381 | if(ptr != NULL__null) associatedTo.push_back(ptr); |
382 | } |
383 | } |
384 | |
385 | //-------------------------- |
386 | // GetT |
387 | //-------------------------- |
388 | template<typename T> |
389 | void JObject::GetT(vector<const T*> &ptrs) const |
390 | { |
391 | /// Fill the given vector with pointers to the associated |
392 | /// JObjects of the type on which the vector is based. This is |
393 | /// similar to the Get() method except objects are selected |
394 | /// by attempting a dynamic_cast to type const T*. This allows |
395 | /// one to select a list of all objects who have a type T |
396 | /// somewhere in their inheritance chain. |
397 | /// |
398 | /// A potential issue with this method is that the dynamic_cast |
399 | /// does not always work correctly for objects created via a |
400 | /// plugin when the cast occurs outside of the plugin or |
401 | /// vice versa. |
402 | /// |
403 | /// The contents of ptrs are cleared upon entry. |
404 | |
405 | ptrs.clear(); |
406 | |
407 | //map<const JObject*, string>::const_iterator iter = associated.begin(); |
408 | //for(; iter!=associated.end(); iter++){ |
409 | for( auto obj : associated ){ |
410 | const T *ptr = dynamic_cast<const T*>(obj); |
411 | if(ptr != NULL__null)ptrs.push_back(ptr); |
412 | } |
413 | } |
414 | |
415 | //------------- |
416 | // GetSingle |
417 | //------------- |
418 | template<class T> |
419 | void JObject::GetSingle(const T* &t, string classname) const |
420 | { |
421 | /// This is a convenience method that can be used to get a pointer to the single |
422 | /// associate object of type T. |
423 | /// |
424 | /// The objects are chosen by matching their class names |
425 | /// (obtained via JObject::className()) either |
426 | /// to the one provided in classname or to T::static_className() |
427 | /// if classname is an empty string. |
428 | /// |
429 | /// If no object of the specified type is found, a NULL pointer is |
430 | /// returned. |
431 | |
432 | t = NULL__null; |
433 | |
434 | if(classname=="")classname=T::static_className(); |
435 | |
436 | //map<const JObject*, string>::const_iterator iter = associated.begin(); |
437 | //for(; iter!=associated.end(); iter++){ |
438 | for( auto obj : associated ){ |
439 | if( classname == obj->className() ){ |
440 | t = dynamic_cast<const T*>(obj); |
441 | if(t!=NULL__null)return; |
442 | } |
443 | } |
444 | } |
445 | |
446 | //------------- |
447 | // GetSingleT |
448 | //------------- |
449 | template<class T> |
450 | void JObject::GetSingleT(const T* &t) const |
451 | { |
452 | /// This is a convenience method that can be used to get a pointer to the single |
453 | /// associate object of type T. |
454 | /// |
455 | /// This is similar to the GetSingle() method except objects are selected |
456 | /// by attempting a dynamic_cast to type const T*. This allows |
457 | /// one to select a list of all objects who have a type T |
458 | /// somewhere in their inheritance chain. |
459 | /// The objects are chosen by matching their class names |
460 | /// (obtained via JObject::className()) either |
461 | /// to the one provided in classname or to T::static_className() |
462 | /// if classname is an empty string. |
463 | /// |
464 | /// If no object of the specified type is found, a NULL pointer is |
465 | /// returned. |
466 | |
467 | t = NULL__null; |
468 | |
469 | //map<const JObject*, string>::const_iterator iter = associated.begin(); |
470 | //for(; iter!=associated.end(); iter++){ |
471 | for( auto obj : associated ){ |
472 | t = dynamic_cast<const T*>(obj); |
473 | if(t!=NULL__null)return; |
474 | } |
475 | } |
476 | |
477 | //-------------------------- |
478 | // toStrings |
479 | //-------------------------- |
480 | inline void JObject::toStrings(vector<pair<string,string> > &items) const |
481 | { |
482 | /// Fill the given "items" vector with items representing the (important) |
483 | /// data members of this object. The structure of "items" is a vector |
484 | /// of pairs. The "first" element of the pair is the name of the item |
485 | /// as it should be displayed when dumping the item to the screen. For |
486 | /// example, one may wish to include units using a string like "r (cm)". |
487 | /// The "second" element of the pair is a formatted string containing the |
488 | /// value as it should be displayed. |
489 | /// |
490 | /// To facilitate this, the AddString() method exists which allows |
491 | /// items to be added with the desired formatting using a single line. |
492 | /// |
493 | /// This is a virtual method that is expected (but not required) |
494 | /// to be implemented by all classes that inherit from JObject. |
495 | |
496 | AddString(items, "JObject", "0x%08x", (unsigned long)this); |
497 | } |
498 | |
499 | //-------------------------- |
500 | // AddString |
501 | //-------------------------- |
502 | template<typename T> |
503 | void JObject::AddString(vector<pair<string,string> > &items, const char *name, const char *format, const T &val) const |
504 | { |
505 | /// Write the given value (val) to a string using the sprintf style formatting |
506 | /// string (format) and add it to the given vector (items) with the column |
507 | /// name "name". This is intended for use in the toStrings() method of |
508 | /// classes that inherit from JObject. |
509 | /// |
510 | /// The append_type flag provides a facility for recording the data type |
511 | /// and value with default formatting into items. This can be used |
512 | /// by a generic convertor (not part of JANA) to auto-generate a |
513 | /// representation of this object for use in some other persistence |
514 | /// package (e.g. ROOT files). |
515 | /// |
516 | /// If the append_types flag is set then the data type of "val" is |
517 | /// automatically appended with a colon (:) separator to the |
518 | /// name (first) part of the pair. In addition, "val" is converted |
519 | /// using stringstream and appended as well, also with a colon (:) |
520 | /// separator. For example, if the value of name passed in is "px" |
521 | /// and T is of type double, then the first member of the pair |
522 | /// appended to items will be something like "px:double:1.23784" |
523 | /// which can be decifered later to get the name, type, and value |
524 | /// of the data member. |
525 | /// |
526 | /// By default, the append_types flag is not set and the name part |
527 | /// of the pair is a straight copy of the name argument that is |
528 | /// passed in. |
529 | |
530 | char str[256]; |
531 | sprintf(str, format, val); |
532 | |
533 | stringstream ss; |
534 | ss<<name; |
535 | if(append_types){ |
536 | if(typeid(T)==typeid(int)){ |
537 | ss<<":int:"<<val; |
538 | }else if(typeid(T)==typeid(int32_t)){ |
539 | ss<<":int:"<<val; |
540 | }else if(typeid(T)==typeid(unsigned int)){ |
541 | ss<<":uint:"<<val; |
542 | }else if(typeid(T)==typeid(uint32_t)){ |
543 | ss<<":uint:"<<val; |
544 | }else if(typeid(T)==typeid(long)){ |
545 | ss<<":long:"<<val; |
546 | }else if(typeid(T)==typeid(int64_t)){ |
547 | ss<<":long:"<<val; |
548 | }else if(typeid(T)==typeid(unsigned long)){ |
549 | ss<<":ulong:"<<val; |
550 | }else if(typeid(T)==typeid(uint64_t)){ |
551 | ss<<":ulong:"<<val; |
552 | }else if(typeid(T)==typeid(short)){ |
553 | ss<<":short:"<<val; |
554 | }else if(typeid(T)==typeid(int16_t)){ |
555 | ss<<":short:"<<val; |
556 | }else if(typeid(T)==typeid(unsigned short)){ |
557 | ss<<":ushort:"<<val; |
558 | }else if(typeid(T)==typeid(uint16_t)){ |
559 | ss<<":ushort:"<<val; |
560 | }else if(typeid(T)==typeid(float)){ |
561 | ss<<":float:"<<val; |
562 | }else if(typeid(T)==typeid(double)){ |
563 | ss<<":double:"<<val; |
564 | }else if(typeid(T)==typeid(string)){ |
565 | ss<<":string:"<<val; |
566 | }else if(typeid(T)==typeid(const char*)){ |
567 | ss<<":string:"<<val; |
568 | }else if(typeid(T)==typeid(char*)){ |
569 | ss<<":string:"<<val; |
570 | }else{ |
571 | ss<<":unknown:"<<str; |
572 | } |
573 | } |
574 | |
575 | pair<string, string> item; |
576 | item.first = ss.str(); |
577 | item.second = string(str); |
578 | items.push_back(item); |
579 | } |
580 | |
581 | #endif // __CINT__ __CLING__ |
582 | |
583 | |
584 | } // Close JANA namespace |
585 | |
586 | #endif // _JObject_ |
587 |