Bug Summary

File:/home/sdobbs/work/clang/halld_recon/src/libraries/START_COUNTER/DSCHit_factory.cc
Warning:line 99, column 30
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -main-file-name DSCHit_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/START_COUNTER -I libraries/START_COUNTER -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/START_COUNTER/DSCHit_factory.cc
1// $Id$
2//
3// File: DSCHit_factory.cc
4// Created: Tue Aug 6 12:53:32 EDT 2013
5// Creator: davidl (on Darwin harriet.jlab.org 11.4.2 i386)
6//
7
8
9#include <iostream>
10#include <iomanip>
11#include <limits>
12#include <cmath>
13using namespace std;
14
15#include <START_COUNTER/DSCDigiHit.h>
16#include <START_COUNTER/DSCTDCDigiHit.h>
17#include <DAQ/Df250PulsePedestal.h>
18#include <DAQ/Df250PulseIntegral.h>
19#include <DAQ/Df250Config.h>
20#include "DSCHit_factory.h"
21
22using namespace jana;
23
24bool DSCHit_fadc_cmp(const DSCDigiHit *a,const DSCDigiHit *b)
25{
26 if (a->sector==b->sector) return (a->pulse_time<b->pulse_time);
27 return (a->sector<b->sector);
28}
29
30bool DSCHit_tdc_cmp(const DSCTDCDigiHit *a,const DSCTDCDigiHit *b)
31{
32 if (a->sector==b->sector) return (a->time<b->time);
33 return (a->sector<b->sector);
34}
35
36//------------------
37// init
38//------------------
39jerror_t DSCHit_factory::init(void)
40{
41 DELTA_T_ADC_TDC_MAX = 20.0; // ns
42 //DELTA_T_ADC_TDC_MAX = 50.0; // ns
43 //DELTA_T_ADC_TDC_MAX = 3600.0; // ns
44 gPARMS->SetDefaultParameter("SC:DELTA_T_ADC_TDC_MAX", DELTA_T_ADC_TDC_MAX,
45 "Maximum difference in ns between a (calibrated) fADC time and"
46 " F1TDC time for them to be matched in a single hit");
47
48 HIT_TIME_WINDOW = 60.0; //ns
49 gPARMS->SetDefaultParameter("SC:HIT_TIME_WINDOW", HIT_TIME_WINDOW,
50 "Time window of trigger corrected TDC time in which a hit in"
51 " in the TDC will match to a hit in the fADC to form an ST hit");
52
53 //ADC_THRESHOLD = 200.; // adc counts (= 50 mV threshold)
54 ADC_THRESHOLD = 120.; // adc counts (= 10 Mv threshold)
55 gPARMS->SetDefaultParameter("SC:ADC_THRESHOLD", ADC_THRESHOLD,
56 "Software pulse integral threshold");
57
58 USE_TIMEWALK_CORRECTION = 1.;
59 gPARMS->SetDefaultParameter("SC:USE_TIMEWALK_CORRECTION", USE_TIMEWALK_CORRECTION,
60 "Flag to decide if timewalk corrections should be applied.");
61
62 REQUIRE_ADC_TDC_MATCH=true;
63 gPARMS->SetDefaultParameter("SC:REQUIRE_ADC_TDC_MATCH",
64 REQUIRE_ADC_TDC_MATCH,
65 "Flag to decide if a match between adc and tdc hits is required.");
66
67 /// set the base conversion scales
68 a_scale = 0.0001;
69 t_scale = 0.0625; // 62.5 ps/count
70 t_base = 0.; // ns
71 t_tdc_base = 0.;
72
73 CHECK_FADC_ERRORS = true;
74 gPARMS->SetDefaultParameter("SC:CHECK_FADC_ERRORS", CHECK_FADC_ERRORS, "Set to 1 to reject hits with fADC250 errors, ser to 0 to keep these hits");
75
76 return NOERROR;
77}
78
79//------------------
80// brun
81//------------------
82jerror_t DSCHit_factory::brun(jana::JEventLoop *eventLoop, int32_t runnumber)
83{
84 // Only print messages for one thread whenever run number change
85 static pthread_mutex_t print_mutex = PTHREAD_MUTEX_INITIALIZER{ { 0, 0, 0, 0, 0, 0, 0, { 0, 0 } } };
86 static set<int> runs_announced;
87 pthread_mutex_lock(&print_mutex);
88 bool print_messages = false;
89 if(runs_announced.find(runnumber) == runs_announced.end()){
1
Assuming the condition is false
2
Taking false branch
90 print_messages = true;
91 runs_announced.insert(runnumber);
92 }
93 pthread_mutex_unlock(&print_mutex);
94
95 /// Load geometry - just need the number of sectors
96 DApplication* dapp = dynamic_cast<DApplication*>(eventLoop->GetJApplication());
3
'dapp' initialized here
97 if(!dapp)
4
Assuming 'dapp' is null
5
Taking true branch
98 jerr << "Cannot get DApplication from JEventLoop!" << endl;
99 DGeometry* locGeometry = dapp->GetDGeometry(runnumber);
6
Called C++ object pointer is null
100
101 // Get start counter geometry
102 vector<vector<DVector3> >sc_norm;
103 vector<vector<DVector3> >sc_pos;
104 MAX_SECTORS=0;
105 if (locGeometry->GetStartCounterGeom(sc_pos, sc_norm))
106 MAX_SECTORS = sc_pos.size();
107 else
108 jerr << "Cannot load Start Counter geometry information!" << endl;
109
110 /// Read in calibration constants
111 if(print_messages) jout << "In DSCHit_factory, loading constants..." << endl;
112
113 // load scale factors
114 map<string,double> scale_factors;
115 // a_scale (SC_ADC_SCALE)
116 if (eventLoop->GetCalib("/START_COUNTER/digi_scales", scale_factors))
117 jout << "Error loading /START_COUNTER/digi_scales !" << endl;
118 if (scale_factors.find("SC_ADC_ASCALE") != scale_factors.end())
119 a_scale = scale_factors["SC_ADC_ASCALE"];
120 else
121 jerr << "Unable to get SC_ADC_ASCALE from /START_COUNTER/digi_scales !"
122 << endl;
123 // t_scale (SC_ADC_SCALE)
124 if (scale_factors.find("SC_ADC_TSCALE") != scale_factors.end())
125 t_scale = scale_factors["SC_ADC_TSCALE"];
126 else
127 jerr << "Unable to get SC_ADC_TSCALE from /START_COUNTER/digi_scales !"
128 << endl;
129
130 // load base time offset
131 map<string,double> base_time_offset;
132 // t_base (SC_BASE_TIME_OFFSET)
133 if (eventLoop->GetCalib("/START_COUNTER/base_time_offset",base_time_offset))
134 jout << "Error loading /START_COUNTER/base_time_offset !" << endl;
135 if (base_time_offset.find("SC_BASE_TIME_OFFSET") != base_time_offset.end())
136 t_base = base_time_offset["SC_BASE_TIME_OFFSET"];
137 else
138 jerr << "Unable to get SC_BASE_TIME_OFFSET from /START_COUNTER/base_time_offset !" << endl;
139 // t_tdc_base (SC_TDC_BASE_TIME_OFFSET)
140 if (base_time_offset.find("SC_TDC_BASE_TIME_OFFSET") != base_time_offset.end())
141 t_tdc_base = base_time_offset["SC_TDC_BASE_TIME_OFFSET"];
142 else
143 jerr << "Unable to get SC_BASE_TIME_OFFSET from /START_COUNTER/base_time_offset !" << endl;
144
145 // load constant tables
146 // a_gains (gains)
147 if (eventLoop->GetCalib("/START_COUNTER/gains", a_gains))
148 jout << "Error loading /START_COUNTER/gains !" << endl;
149 // a_pedestals (pedestals)
150 if (eventLoop->GetCalib("/START_COUNTER/pedestals", a_pedestals))
151 jout << "Error loading /START_COUNTER/pedestals !" << endl;
152 // adc_time_offsets (adc_timing_offsets)
153 if (eventLoop->GetCalib("/START_COUNTER/adc_timing_offsets", adc_time_offsets))
154 jout << "Error loading /START_COUNTER/adc_timing_offsets !" << endl;
155 // tdc_time_offsets (tdc_timing_offsets)
156 if (eventLoop->GetCalib("/START_COUNTER/tdc_timing_offsets", tdc_time_offsets))
157 jout << "Error loading /START_COUNTER/tdc_timing_offsets !" << endl;
158 // timewalk_parameters (timewalk_parms)
159 if(eventLoop->GetCalib("START_COUNTER/timewalk_parms_v2", timewalk_parameters))
160 jout << "Error loading /START_COUNTER/timewalk_parms_v2 !" << endl;
161
162
163 return NOERROR;
164}
165
166//------------------
167// evnt
168//------------------
169jerror_t DSCHit_factory::evnt(JEventLoop *loop, uint64_t eventnumber)
170{
171 /// Generate DSCHit object for each DSCDigiHit object.
172 /// This is where the first set of calibration constants
173 /// is applied to convert from digitzed units into natural
174 /// units.
175 ///
176 /// Note that this code does NOT get called for simulated
177 /// data in HDDM format. The HDDM event source will copy
178 /// the precalibrated values directly into the _data vector.
179
180 // First, make hits out of all fADC250 hits
181 vector<const DSCDigiHit*> digihits;
182 loop->Get(digihits);
183 sort(digihits.begin(),digihits.end(),DSCHit_fadc_cmp);
184
185 const DTTabUtilities* locTTabUtilities = nullptr;
186 loop->GetSingle(locTTabUtilities);
187
188 char str[256];
189 vector<DSCHit *>temp_schits;
190
191 for (unsigned int i = 0; i < digihits.size(); i++) {
192 const DSCDigiHit *digihit = digihits[i];
193
194 // Make sure sector is in valid range
195 if( (digihit->sector <= 0) && (digihit->sector > MAX_SECTORS)) {
196 sprintf(str, "DSCDigiHit sector out of range! sector=%d (should be 1-%d)",
197 digihit->sector, MAX_SECTORS);
198 throw JException(str);
199 }
200
201 // Throw away hits with firmware errors (post-summer 2016 firmware)
202 if(CHECK_FADC_ERRORS && !locTTabUtilities->CheckFADC250_NoErrors(digihit->QF))
203 continue;
204 if (digihit->pulse_time == 0 || digihit->pedestal == 0 || digihit->pulse_peak == 0) continue;
205 // Find the time from the pulse and apply calibration constants
206 double T = (double)digihit->pulse_time;
207 double t_fadc= t_scale * T - adc_time_offsets[digihit->sector-1] + t_base;
208 if (fabs(t_fadc) > HIT_TIME_WINDOW) continue;
209
210 // Initialize pedestal to one found in CCDB, but override it
211 // with one found in event if is available (?)
212 // For now, only keep events with a correct pedestal
213 double pedestal = a_pedestals[digihit->sector-1];
214 double nsamples_integral = digihit->nsamples_integral;
215 double nsamples_pedestal = digihit->nsamples_pedestal;
216
217 // nsamples_pedestal should always be positive for valid data - err on the side of caution for now
218 if(nsamples_pedestal == 0) {
219 jerr << "DSCDigiHit with nsamples_pedestal == 0 ! Event = " << eventnumber << endl;
220 continue;
221 }
222
223 // digihit->pedestal is the sum of "nsamples_pedestal" samples
224 // Calculate the average pedestal per sample
225 if( (digihit->pedestal>0) && locTTabUtilities->CheckFADC250_PedestalOK(digihit->QF) ) {
226 pedestal = (double)digihit->pedestal/nsamples_pedestal;
227 }
228 // Subtract pedestal from pulse peak
229 double pulse_peak = digihit->pulse_peak - pedestal;
230
231 // Subtract pedestal from pulse integral
232 double A = (double)digihit->pulse_integral;
233 A -= pedestal*nsamples_integral;
234
235 //if ( ((double)digihit->pulse_integral) < ADC_THRESHOLD) continue; // Will comment out until this is set to something useful by default
236
237 DSCHit *hit = new DSCHit;
238 // Sectors are numbered from 1-30
239 hit->sector = digihit->sector;
240
241 hit->dE = a_scale * a_gains[digihit->sector-1] * A;
242 hit->t_fADC = t_fadc;
243 hit->t_TDC = numeric_limits<double>::quiet_NaN();
244
245 hit->has_TDC = false;
246 hit->has_fADC = true;
247
248 hit->t = hit->t_fADC; // set time from fADC in case no TDC hit
249 hit->pulse_height = pulse_peak;
250
251 hit->AddAssociatedObject(digihit);
252
253 temp_schits.push_back(hit);
254 }
255
256
257 // Next, loop over TDC hits, matching them to the
258 // existing fADC hits where possible and updating
259 // their time information. If no match is found, then
260 // create a new hit with just the TDC info.
261 vector<const DSCTDCDigiHit*> tdcdigihits;
262 loop->Get(tdcdigihits);
263 sort(tdcdigihits.begin(),tdcdigihits.end(),DSCHit_tdc_cmp);
264
265 for (unsigned int i = 0; i < tdcdigihits.size(); i++) {
266 const DSCTDCDigiHit *digihit = tdcdigihits[i];
267
268 // Make sure sector is in valid range
269 if((digihit->sector <= 0) && (digihit->sector > MAX_SECTORS)) {
270 sprintf(str, "DSCDigiHit sector out of range! sector=%d (should be 1-%d)",
271 digihit->sector, MAX_SECTORS);
272 throw JException(str);
273 }
274
275 unsigned int id = digihit->sector - 1;
276 double T = locTTabUtilities->Convert_DigiTimeToNs_F1TDC(digihit) - tdc_time_offsets[id] + t_tdc_base;
277
278 // Look for existing hits to see if there is a match
279 // or create new one if there is no match
280 // Require that the trigger corrected TDC time fall within
281 // a reasonable time window so that when a hit is associated with
282 // a hit in the TDC and not the ADC it is a "decent" TDC hit
283 if (fabs(T) < HIT_TIME_WINDOW) {
284 DSCHit *hit = FindMatch(temp_schits,digihit->sector, T);
285 if (hit == nullptr) {
286 hit = new DSCHit;
287 hit->sector = digihit->sector;
288 hit->dE = 0.0;
289 hit->t_fADC= numeric_limits<double>::quiet_NaN();
290 hit->has_fADC=false;
291 temp_schits.push_back(hit);
292 }
293
294 hit->has_TDC=true;
295 hit->t_TDC=T;
296
297 if (USE_TIMEWALK_CORRECTION && (hit->dE > 0.0) ) {
298 // Correct for time walk
299 // The correction is the form t=t_tdc- C1 (A^C2 - A0^C2)
300 // double A = hit->dE;
301 // double C1 = timewalk_parameters[id][1];
302 // double C2 = timewalk_parameters[id][2];
303 // double A0 = timewalk_parameters[id][3];
304 // T -= C1*(pow(A,C2) - pow(A0,C2));
305
306 // Correct for timewalk using pulse peak instead of pulse integral
307 double A = hit->pulse_height;
308 // double C0 = timewalk_parameters[id][0];
309 double C1 = timewalk_parameters[id][1];
310 double C2 = timewalk_parameters[id][2];
311 double A_THRESH = timewalk_parameters[id][3];
312 double A0 = timewalk_parameters[id][4];
313 // do correction
314 T -= C1*(pow(A/A_THRESH, C2) - pow(A0/A_THRESH, C2));
315 }
316
317 hit->t=T;
318
319 hit->AddAssociatedObject(digihit);
320 } // Hit time window cut
321
322 }
323
324 for (unsigned int i=0;i<temp_schits.size();i++){
325 if (REQUIRE_ADC_TDC_MATCH==false){
326 _data.push_back(temp_schits[i]);
327 }
328 else if (temp_schits[i]->has_fADC && temp_schits[i]->has_TDC){
329 _data.push_back(temp_schits[i]);
330 }
331 else delete temp_schits[i];
332 }
333
334
335
336
337 return NOERROR;
338}
339
340//------------------
341// FindMatch
342//------------------
343DSCHit* DSCHit_factory::FindMatch(vector<DSCHit*>&schits,int sector, double T)
344{
345 DSCHit *best_match = nullptr;
346
347 // Loop over existing hits (from fADC) and look for a match
348 // in both the sector and the time.
349 for(unsigned int i = 0; i < schits.size(); i++)
350 {
351 DSCHit *hit = schits[i];
352
353 if (! isfinite(hit->t_fADC))
354 continue; // only match to fADC hits, not bachelor TDC hits
355
356 if (hit->sector != sector)
357 continue; // require identical sectors fired
358
359 double delta_T = fabs(hit->t - T);
360 if (delta_T > DELTA_T_ADC_TDC_MAX)
361 continue;
362
363 if (best_match != nullptr)
364 {
365 if (delta_T < fabs(best_match->t - T))
366 best_match = hit;
367 } else best_match = hit;
368 }
369
370 return best_match;
371}
372
373//------------------
374// erun
375//------------------
376jerror_t DSCHit_factory::erun(void)
377{
378 return NOERROR;
379}
380
381//------------------
382// fini
383//------------------
384jerror_t DSCHit_factory::fini(void)
385{
386 return NOERROR;
387}
388
389
390//------------------------------------
391// GetConstant
392// Allow a few different interfaces
393//------------------------------------
394const double DSCHit_factory::GetConstant(const vector<double> &the_table,
395 const int in_sector) const
396{
397 char str[256];
398
399 if ( (in_sector < 0) || (in_sector >= MAX_SECTORS))
400 {
401 sprintf(str, "Bad sector # requested in DSCHit_factory::GetConstant()!"
402 " requested=%d , should be %ud", in_sector, MAX_SECTORS);
403 cerr << str << endl;
404 throw JException(str);
405 }
406
407 return the_table[in_sector];
408}
409
410const double DSCHit_factory::GetConstant(const vector<double> &the_table,
411 const DSCDigiHit *in_digihit) const
412{
413 char str[256];
414
415 if ( (in_digihit->sector < 0) || (in_digihit->sector >= MAX_SECTORS))
416 {
417 sprintf(str, "Bad sector # requested in DSCHit_factory::GetConstant()!"
418 " requested=%d , should be %ud",
419 in_digihit->sector, MAX_SECTORS);
420 cerr << str << endl;
421 throw JException(str);
422 }
423
424 return the_table[in_digihit->sector];
425}
426
427const double DSCHit_factory::GetConstant(const vector<double> &the_table,
428 const DSCHit *in_hit) const
429{
430
431 char str[256];
432
433 if ( (in_hit->sector < 0) || (in_hit->sector >= MAX_SECTORS))
434 {
435 sprintf(str, "Bad sector # requested in DSCHit_factory::GetConstant()!"
436 " requested=%d , should be %ud",
437 in_hit->sector, MAX_SECTORS);
438 cerr << str << endl;
439 throw JException(str);
440 }
441
442 return the_table[in_hit->sector];
443}
444/*
445 const double DSCHit_factory::GetConstant(const vector<double> &the_table,
446 const DTranslationTable *ttab,
447 const int in_rocid,
448 const int in_slot,
449 const int in_channel) const
450 {
451 char str[256];
452
453 DTranslationTable::csc_t daq_index = { in_rocid, in_slot, in_channel };
454 DTranslationTable::DChannelInfo channel_info = ttab->GetDetectorIndex(daq_index);
455
456 if( (channel_info.sc.sector <= 0)
457 || (channel_info.sc.sector > static_cast<unsigned int>(MAX_SECTORS))) {
458 sprintf(str, "Bad sector # requested in DSCHit_factory::GetConstant()!"
459 " requested=%d , should be %ud",
460 channel_info.sc.sector, MAX_SECTORS);
461 cerr << str << endl;
462 throw JException(str);
463 }
464
465 return the_table[channel_info.sc.sector];
466 }
467 */