28 DELTA_T_ADC_TDC_MAX = 4.0;
29 gPARMS->SetDefaultParameter(
"PSCHit:DELTA_T_ADC_TDC_MAX", DELTA_T_ADC_TDC_MAX,
30 "Maximum difference in ns between a (calibrated) fADC time and"
31 " F1TDC time for them to be matched in a single hit");
32 ADC_THRESHOLD = 500.0;
33 gPARMS->SetDefaultParameter(
"PSCHit:ADC_THRESHOLD",ADC_THRESHOLD,
34 "pedestal-subtracted pulse integral threshold");
36 CHECK_FADC_ERRORS =
true;
37 gPARMS->SetDefaultParameter(
"PSCHit:CHECK_FADC_ERRORS", CHECK_FADC_ERRORS,
"Set to 1 to reject hits with fADC250 errors, ser to 0 to keep these hits");
54 static pthread_mutex_t print_mutex = PTHREAD_MUTEX_INITIALIZER;
55 static set<int> runs_announced;
56 pthread_mutex_lock(&print_mutex);
57 bool print_messages =
false;
58 if(runs_announced.find(runnumber) == runs_announced.end()){
59 print_messages =
true;
60 runs_announced.insert(runnumber);
62 pthread_mutex_unlock(&print_mutex);
65 if(print_messages) jout <<
"In DPSCHit_factory, loading constants..." << endl;
68 vector<const DPSGeometry*> psGeomVect;
69 eventLoop->Get( psGeomVect );
70 if (psGeomVect.size() < 1)
71 return OBJECT_NOT_AVAILABLE;
75 map<string,double> scale_factors;
76 if (eventLoop->GetCalib(
"/PHOTON_BEAM/pair_spectrometer/digi_scales", scale_factors))
77 jout <<
"Error loading /PHOTON_BEAM/pair_spectrometer/digi_scales !" << endl;
78 if (scale_factors.find(
"PSC_ADC_ASCALE") != scale_factors.end())
79 a_scale = scale_factors[
"PSC_ADC_ASCALE"];
81 jerr <<
"Unable to get PSC_ADC_ASCALE from /PHOTON_BEAM/pair_spectrometer/digi_scales !"
83 if (scale_factors.find(
"PSC_ADC_TSCALE") != scale_factors.end())
84 t_scale = scale_factors[
"PSC_ADC_TSCALE"];
86 jerr <<
"Unable to get PSC_ADC_TSCALE from /PHOTON_BEAM/pair_spectrometer/digi_scales !"
90 map<string,double> base_time_offset;
91 if (eventLoop->GetCalib(
"/PHOTON_BEAM/pair_spectrometer/base_time_offset",base_time_offset))
92 jout <<
"Error loading /PHOTON_BEAM/pair_spectrometer/base_time_offset !" << endl;
93 if (base_time_offset.find(
"PS_COARSE_BASE_TIME_OFFSET") != base_time_offset.end())
94 t_base = base_time_offset[
"PS_COARSE_BASE_TIME_OFFSET"];
96 jerr <<
"Unable to get PS_COARSE_BASE_TIME_OFFSET from /PHOTON_BEAM/pair_spectrometer/base_time_offset !" << endl;
98 if (base_time_offset.find(
"PS_COARSE_TDC_BASE_TIME_OFFSET") != base_time_offset.end())
99 t_tdc_base = base_time_offset[
"PS_COARSE_TDC_BASE_TIME_OFFSET"];
101 jerr <<
"Unable to get PS_COARSE_TDC_BASE_TIME_OFFSET from /PHOTON_BEAM/pair_spectrometer/base_time_offset !" << endl;
104 vector<double> raw_adc_pedestals;
105 vector<double> raw_adc_gains;
106 vector<double> raw_adc_offsets;
107 vector<double> raw_tdc_offsets;
110 if(eventLoop->GetCalib(
"/PHOTON_BEAM/pair_spectrometer/coarse/adc_pedestals", raw_adc_pedestals))
111 jout <<
"Error loading /PHOTON_BEAM/pair_spectrometer/coarse/adc_pedestals !" << endl;
112 if(eventLoop->GetCalib(
"/PHOTON_BEAM/pair_spectrometer/coarse/adc_gain_factors", raw_adc_gains))
113 jout <<
"Error loading /PHOTON_BEAM/pair_spectrometer/coarse/adc_gain_factors !" << endl;
114 if(eventLoop->GetCalib(
"/PHOTON_BEAM/pair_spectrometer/coarse/adc_timing_offsets", raw_adc_offsets))
115 jout <<
"Error loading /PHOTON_BEAM/pair_spectrometer/coarse/adc_timing_offsets !" << endl;
116 if(eventLoop->GetCalib(
"/PHOTON_BEAM/pair_spectrometer/coarse/tdc_timing_offsets", raw_tdc_offsets))
117 jout <<
"Error loading /PHOTON_BEAM/pair_spectrometer/coarse/tdc_timing_offsets !" << endl;
120 FillCalibTable(adc_pedestals, raw_adc_pedestals, psGeom);
121 FillCalibTable(adc_gains, raw_adc_gains, psGeom);
126 if (eventLoop->GetCalib(
"/PHOTON_BEAM/pair_spectrometer/tdc_timewalk_corrections", tw_parameters))
127 jout <<
"Error loading /PHOTON_BEAM/pair_spectrometer/tdc_timewalk_corrections !" << endl;
147 vector<const DPSGeometry*> psGeomVect;
148 eventLoop->Get(psGeomVect);
149 if (psGeomVect.size() < 1)
150 return OBJECT_NOT_AVAILABLE;
154 loop->GetSingle(locTTabUtilities);
157 vector<const DPSCDigiHit*> digihits;
161 for (
unsigned int i=0; i < digihits.size(); i++) {
167 sprintf(str,
"DPSCDigiHit sector out of range! sector=%d (should be 1-%d)",
169 throw JException(str);
178 double pedestal = GetConstant(adc_pedestals,digihit,psGeom);
183 if(nsamples_pedestal == 0) {
184 jerr <<
"DPSCDigiHit with nsamples_pedestal == 0 ! Event = " << eventnumber << endl;
191 pedestal = (double)digihit->
pedestal/nsamples_pedestal;
200 A -= pedestal*nsamples_integral;
203 if (A < ADC_THRESHOLD)
continue;
212 hit->pulse_peak = pulse_peak;
213 hit->npe_fadc = A * a_scale * GetConstant(adc_gains, digihit, psGeom);
215 hit->t = hit->time_fadc;
216 hit->time_tdc = numeric_limits<double>::quiet_NaN();
217 hit->has_fADC =
true;
218 hit->has_TDC =
false;
220 hit->AddAssociatedObject(digihit);
222 _data.push_back(hit);
229 vector<const DPSCTDCDigiHit*> tdcdigihits;
230 loop->Get(tdcdigihits);
232 for(
unsigned int i=0; i<tdcdigihits.size(); i++) {
243 DPSCHit *hit = FindMatch(arm, module, T);
244 if (hit ==
nullptr) {
248 hit->
time_fadc = numeric_limits<double>::quiet_NaN();
249 hit->
integral = numeric_limits<double>::quiet_NaN();
250 hit->
pulse_peak = numeric_limits<double>::quiet_NaN();
251 hit->
npe_fadc = numeric_limits<double>::quiet_NaN();
253 _data.push_back(hit);
259 if (tw_parameters[module - 1][0] == 0) {
260 c1 = tw_parameters[module - 1][3];
261 c2 = tw_parameters[module - 1][4];
262 thresh = tw_parameters[module - 1][5];
263 P_0 = tw_parameters[module - 1][6];
266 c1 = tw_parameters[module + 7][3];
267 c2 = tw_parameters[module + 7][4];
268 thresh = tw_parameters[module + 7][5];
269 P_0 = tw_parameters[module + 7][6];
272 T -=
c1*(pow(P/thresh,
c2) - pow(P_0/thresh,
c2));
276 hit->AddAssociatedObject(digihit);
291 for(
unsigned int i=0; i<_data.size(); i++) {
295 if(hit->
arm != arm)
continue;
296 if(hit->
module != module)
continue;
298 double delta_T = fabs(T - hit->
t);
299 if(delta_T > DELTA_T_ADC_TDC_MAX)
continue;
304 if(best_match !=
nullptr) {
305 if(delta_T < fabs(best_match->
t - T))
324 return counter_id <= num_counters_per_arm ? counter_id : counter_id - num_counters_per_arm;
358 table.push_back( pair<double,double>() );
365 sprintf(str,
"Too many channels for PSC table! channel=%d (should be %d)",
366 channel, PSC_MAX_CHANNELS);
368 throw JException(str);
376 if(channel != PSC_MAX_CHANNELS) {
377 sprintf(str,
"Not enough channels for PSC table! channel=%d (should be %d)",
378 channel, PSC_MAX_CHANNELS);
380 throw JException(str);
400 sprintf(str,
"Bad arm requested in DPSCHit_factory::GetConstant()! requested=%d , should be 0-%d",
403 throw JException(str);
406 sprintf(str,
"Bad module # requested in DPSCHit_factory::GetConstant()! requested=%d , should be 1-%d", in_module, psGeom.
NUM_COARSE_COLUMNS);
408 throw JException(str);
414 return the_table[in_module-1].first;
416 return the_table[in_module-1].second;
426 sprintf(str,
"Bad arm requested in DPSCHit_factory::GetConstant()! requested=%d , should be 0-%d",
429 throw JException(str);
434 throw JException(str);
440 return the_table[in_hit->
module-1].first;
442 return the_table[in_hit->
module-1].second;
455 sprintf(str,
"Bad module # requested in DPSCHit_factory::GetConstant()! requested=%d , should be 1-%d", module, psGeom.
NUM_COARSE_COLUMNS);
457 throw JException(str);
463 return the_table[module-1].first;
465 return the_table[module-1].second;
478 sprintf(str,
"Bad module # requested in DPSCHit_factory::GetConstant()! requested=%d , should be 1-%d", module, psGeom.
NUM_COARSE_COLUMNS);
480 throw JException(str);
486 return the_table[module-1].first;
488 return the_table[module-1].second;
vector< pair< double, double > > psc_digi_constants_t
double Convert_DigiTimeToNs_F1TDC(const JObject *locTDCDigiHit) const
bool CheckFADC250_NoErrors(uint32_t QF) const
uint32_t QF
Quality Factor from FPGA algorithms.
if(locHist_BCALShowerPhiVsZ!=NULL)
static const int NUM_ARMS
jerror_t init(void)
Called once at program start.
uint32_t pulse_integral
identified pulse integral as returned by FPGA algorithm
uint32_t nsamples_pedestal
number of samples used in pedestal
sprintf(text,"Post KinFit Cut")
const int GetModule(const int counter_id, const int num_counters_per_arm) const
jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber)
Called every event.
jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber)
Called everytime a new run number is detected.
void FillCalibTable(psc_digi_constants_t &table, vector< double > &raw_table, const DPSGeometry &tofGeom)
uint32_t nsamples_integral
number of samples used in integral
const DPSGeometry::Arm GetArm(const int counter_id, const int num_counters_per_arm) const
jerror_t fini(void)
Called after last event of last event source has been processed.
static const int NUM_COARSE_COLUMNS
uint32_t pulse_time
identified pulse time as returned by FPGA algorithm
bool CheckFADC250_PedestalOK(uint32_t QF) const
vector< double > tdc_time_offsets
DPSCHit * FindMatch(DPSGeometry::Arm arm, int module, double T)
static TH1I * pedestal[nChan]
uint32_t pulse_peak
maximum sample in pulse
uint32_t pedestal
pedestal info used by FPGA (if any)
jerror_t erun(void)
Called everytime run number changes, provided brun has been called.
vector< double > adc_time_offsets
const double GetConstant(const psc_digi_constants_t &the_table, const DPSGeometry::Arm in_arm, const int in_module, const DPSGeometry &psGeom) const