Bug Summary

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')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -main-file-name DTOFPoint_factory.cc -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /w/halld-scifs17exp/home/sdobbs/clang/llvm-project/install/lib/clang/12.0.0 -D HAVE_CCDB -D HAVE_RCDB -D HAVE_EVIO -D HAVE_TMVA=1 -D RCDB_MYSQL=1 -D RCDB_SQLITE=1 -D SQLITE_USE_LEGACY_STRUCT=ON -I .Linux_CentOS7.7-x86_64-gcc4.8.5/libraries/TOF -I libraries/TOF -I . -I libraries -I libraries/include -I /w/halld-scifs17exp/home/sdobbs/clang/halld_recon/Linux_CentOS7.7-x86_64-gcc4.8.5/include -I external/xstream/include -I /usr/include/tirpc -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/root/root-6.08.06/include -I /w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/ccdb/ccdb_1.06.06/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/rcdb/rcdb_0.06.00/cpp/include -I /usr/include/mysql -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/sqlitecpp/SQLiteCpp-2.2.0^bs130/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/sqlite/sqlite-3.13.0^bs130/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/hdds/hdds-4.9.0/Linux_CentOS7.7-x86_64-gcc4.8.5/src -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/xerces-c/xerces-c-3.1.4/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/evio/evio-4.4.6/Linux-x86_64/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5 -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/x86_64-redhat-linux -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/backward -internal-isystem /usr/local/include -internal-isystem /w/halld-scifs17exp/home/sdobbs/clang/llvm-project/install/lib/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /home/sdobbs/work/clang/halld_recon/src -ferror-limit 19 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-01-21-110224-160369-1 -x c++ libraries/TOF/DTOFPoint_factory.cc

libraries/TOF/DTOFPoint_factory.cc

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>
14using namespace std;
15
16#include "DTOFPoint_factory.h"
17
18bool 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
25bool Compare_TOFPoint_Time(const DTOFPoint *locTOFPoint1, const DTOFPoint *locTOFPoint2) {
26 return locTOFPoint1->t < locTOFPoint2->t;
27}
28
29//------------------
30// brun
31//------------------
32jerror_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
81DTOFPoint_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//------------------
100jerror_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
188DTOFPoint_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
253DTOFPoint_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
317bool 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
386void 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)
1
Assuming field 'dPositionWellDefinedFlag' is true
2
Assuming field 'dPositionWellDefinedFlag' is false
3
Taking false branch
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
3.1
Field 'dPositionWellDefinedFlag' is true
3.1
Field 'dPositionWellDefinedFlag' is true
)
4
Taking true branch
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);
5
Calling 'JObject::GetSingle'
8
Returning from 'JObject::GetSingle'
427 int id = loctofhit->plane*NUM_BARS*2 + loctofhit->bar-1 + loctofhit->end*NUM_BARS;
9
Access to field 'plane' results in a dereference of a null pointer (loaded from variable 'loctofhit')
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
487void 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
565jerror_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}

/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JObject.h

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>
22using std::pair;
23using std::map;
24using std::set;
25using std::vector;
26using std::string;
27using 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
58namespace jana{
59
60class JFactory_base;
61class JEventLoop;
62
63class 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//--------------------------
188void 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//--------------------------
201void 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//--------------------------
221void 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//--------------------------
239void 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//--------------------------
262template<typename T,typename S>
263void 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//--------------------------
271template<typename T>
272void 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//--------------------------
309template<typename T>
310void 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//--------------------------
356template<typename T>
357void 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//--------------------------
388template<typename T>
389void 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//-------------
418template<class T>
419void 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;
6
Null pointer value stored to 'loctofhit'
433
434 if(classname=="")classname=T::static_className();
7
Taking false branch
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//-------------
449template<class T>
450void 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//--------------------------
480inline 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//--------------------------
502template<typename T>
503void 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