41 DELTA_T_ADC_TDC_MAX = 20.0;
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");
48 HIT_TIME_WINDOW = 60.0;
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");
55 gPARMS->SetDefaultParameter(
"SC:ADC_THRESHOLD", ADC_THRESHOLD,
56 "Software pulse integral threshold");
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.");
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.");
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");
85 static pthread_mutex_t print_mutex = PTHREAD_MUTEX_INITIALIZER;
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()){
90 print_messages =
true;
91 runs_announced.insert(runnumber);
93 pthread_mutex_unlock(&print_mutex);
98 jerr <<
"Cannot get DApplication from JEventLoop!" << endl;
102 vector<vector<DVector3> >sc_norm;
103 vector<vector<DVector3> >sc_pos;
106 MAX_SECTORS = sc_pos.size();
108 jerr <<
"Cannot load Start Counter geometry information!" << endl;
111 if(print_messages) jout <<
"In DSCHit_factory, loading constants..." << endl;
114 map<string,double> scale_factors;
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"];
121 jerr <<
"Unable to get SC_ADC_ASCALE from /START_COUNTER/digi_scales !"
124 if (scale_factors.find(
"SC_ADC_TSCALE") != scale_factors.end())
125 t_scale = scale_factors[
"SC_ADC_TSCALE"];
127 jerr <<
"Unable to get SC_ADC_TSCALE from /START_COUNTER/digi_scales !"
131 map<string,double> 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"];
138 jerr <<
"Unable to get SC_BASE_TIME_OFFSET from /START_COUNTER/base_time_offset !" << endl;
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"];
143 jerr <<
"Unable to get SC_BASE_TIME_OFFSET from /START_COUNTER/base_time_offset !" << endl;
147 if (eventLoop->GetCalib(
"/START_COUNTER/gains", a_gains))
148 jout <<
"Error loading /START_COUNTER/gains !" << endl;
150 if (eventLoop->GetCalib(
"/START_COUNTER/pedestals",
a_pedestals))
151 jout <<
"Error loading /START_COUNTER/pedestals !" << endl;
153 if (eventLoop->GetCalib(
"/START_COUNTER/adc_timing_offsets",
adc_time_offsets))
154 jout <<
"Error loading /START_COUNTER/adc_timing_offsets !" << endl;
156 if (eventLoop->GetCalib(
"/START_COUNTER/tdc_timing_offsets",
tdc_time_offsets))
157 jout <<
"Error loading /START_COUNTER/tdc_timing_offsets !" << endl;
159 if(eventLoop->GetCalib(
"START_COUNTER/timewalk_parms_v2", timewalk_parameters))
160 jout <<
"Error loading /START_COUNTER/timewalk_parms_v2 !" << endl;
181 vector<const DSCDigiHit*> digihits;
186 loop->GetSingle(locTTabUtilities);
189 vector<DSCHit *>temp_schits;
191 for (
unsigned int i = 0; i < digihits.size(); i++) {
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);
202 if(CHECK_FADC_ERRORS && !locTTabUtilities->CheckFADC250_NoErrors(digihit->
QF))
208 if (fabs(t_fadc) > HIT_TIME_WINDOW)
continue;
218 if(nsamples_pedestal == 0) {
219 jerr <<
"DSCDigiHit with nsamples_pedestal == 0 ! Event = " << eventnumber << endl;
225 if( (digihit->
pedestal>0) && locTTabUtilities->CheckFADC250_PedestalOK(digihit->
QF) ) {
226 pedestal = (double)digihit->
pedestal/nsamples_pedestal;
233 A -= pedestal*nsamples_integral;
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();
245 hit->has_TDC =
false;
246 hit->has_fADC =
true;
248 hit->t = hit->t_fADC;
249 hit->pulse_height = pulse_peak;
251 hit->AddAssociatedObject(digihit);
253 temp_schits.push_back(hit);
261 vector<const DSCTDCDigiHit*> tdcdigihits;
262 loop->Get(tdcdigihits);
265 for (
unsigned int i = 0; i < tdcdigihits.size(); i++) {
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);
275 unsigned int id = digihit->
sector - 1;
283 if (fabs(T) < HIT_TIME_WINDOW) {
284 DSCHit *hit = FindMatch(temp_schits,digihit->
sector, T);
285 if (hit ==
nullptr) {
289 hit->
t_fADC= numeric_limits<double>::quiet_NaN();
291 temp_schits.push_back(hit);
297 if (USE_TIMEWALK_CORRECTION && (hit->
dE > 0.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];
314 T -= C1*(pow(A/A_THRESH, C2) - pow(A0/A_THRESH, C2));
319 hit->AddAssociatedObject(digihit);
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]);
328 else if (temp_schits[i]->has_fADC && temp_schits[i]->has_TDC){
329 _data.push_back(temp_schits[i]);
331 else delete temp_schits[i];
345 DSCHit *best_match =
nullptr;
349 for(
unsigned int i = 0; i < schits.size(); i++)
353 if (! isfinite(hit->
t_fADC))
356 if (hit->
sector != sector)
359 double delta_T = fabs(hit->
t - T);
360 if (delta_T > DELTA_T_ADC_TDC_MAX)
363 if (best_match !=
nullptr)
365 if (delta_T < fabs(best_match->
t - T))
367 }
else best_match = hit;
395 const int in_sector)
const
399 if ( (in_sector < 0) || (in_sector >= MAX_SECTORS))
401 sprintf(str,
"Bad sector # requested in DSCHit_factory::GetConstant()!"
402 " requested=%d , should be %ud", in_sector, MAX_SECTORS);
404 throw JException(str);
407 return the_table[in_sector];
415 if ( (in_digihit->
sector < 0) || (in_digihit->
sector >= MAX_SECTORS))
417 sprintf(str,
"Bad sector # requested in DSCHit_factory::GetConstant()!"
418 " requested=%d , should be %ud",
419 in_digihit->
sector, MAX_SECTORS);
421 throw JException(str);
424 return the_table[in_digihit->
sector];
428 const DSCHit *in_hit)
const
433 if ( (in_hit->
sector < 0) || (in_hit->
sector >= MAX_SECTORS))
435 sprintf(str,
"Bad sector # requested in DSCHit_factory::GetConstant()!"
436 " requested=%d , should be %ud",
437 in_hit->
sector, MAX_SECTORS);
439 throw JException(str);
442 return the_table[in_hit->
sector];
uint32_t pedestal
pedestal info used by FPGA (if any)
bool DSCHit_fadc_cmp(const DSCDigiHit *a, const DSCDigiHit *b)
if(locHist_BCALShowerPhiVsZ!=NULL)
jerror_t erun(void)
Called everytime run number changes, provided brun has been called.
int sector
sector number 1-24
uint32_t QF
Quality Factor from FPGA algorithms.
sprintf(text,"Post KinFit Cut")
const double GetConstant(const vector< double > &the_table, const int in_sector) const
DSCHit * FindMatch(vector< DSCHit * > &schits, int sector, double T)
jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber)
Called every event.
jerror_t init(void)
Called once at program start.
uint32_t pulse_integral
identified pulse integral as returned by FPGA algorithm
bool DSCHit_tdc_cmp(const DSCTDCDigiHit *a, const DSCTDCDigiHit *b)
uint32_t nsamples_integral
number of samples used in integral
jerror_t fini(void)
Called after last event of last event source has been processed.
DGeometry * GetDGeometry(unsigned int run_number)
uint32_t pulse_time
identified pulse time as returned by FPGA algorithm
vector< double > a_pedestals
vector< double > tdc_time_offsets
uint32_t nsamples_pedestal
number of samples used in pedestal
static TH1I * pedestal[nChan]
uint32_t pulse_peak
maximum sample in pulse
vector< double > adc_time_offsets
bool GetStartCounterGeom(vector< vector< DVector3 > > &pos, vector< vector< DVector3 > > &norm) const
jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber)
Called everytime a new run number is detected.