Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DPSCHit_factory.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: DPSCHit_factory.cc
4 // Created: Wed Oct 15 16:45:33 EDT 2014
5 // Creator: staylor (on Linux gluon05.jlab.org 2.6.32-358.18.1.el6.x86_64 x86_64)
6 //
7 
8 #include <iostream>
9 #include <iomanip>
10 #include <cmath>
11 #include <vector>
12 #include <limits>
13 using namespace std;
14 
15 #include "DPSCHit_factory.h"
16 #include "DPSCDigiHit.h"
17 #include "DPSCTDCDigiHit.h"
18 #include <DAQ/Df250PulsePedestal.h>
19 #include <DAQ/Df250PulseIntegral.h>
20 using namespace jana;
21 
22 
23 //------------------
24 // init
25 //------------------
26 jerror_t DPSCHit_factory::init(void)
27 {
28  DELTA_T_ADC_TDC_MAX = 4.0; // ns
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; // ADC integral counts
33  gPARMS->SetDefaultParameter("PSCHit:ADC_THRESHOLD",ADC_THRESHOLD,
34  "pedestal-subtracted pulse integral threshold");
35 
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");
38 
39  /// set the base conversion scales
40  a_scale = 0.0001;
41  t_scale = 0.0625; // 62.5 ps/count
42  t_base = 0.; // ns
43  t_tdc_base = 0.;
44 
45  return NOERROR;
46 }
47 
48 //------------------
49 // brun
50 //------------------
51 jerror_t DPSCHit_factory::brun(jana::JEventLoop *eventLoop, int32_t runnumber)
52 {
53  // Only print messages for one thread whenever run number change
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);
61  }
62  pthread_mutex_unlock(&print_mutex);
63 
64  /// Read in calibration constants
65  if(print_messages) jout << "In DPSCHit_factory, loading constants..." << endl;
66 
67  // extract the PS Geometry
68  vector<const DPSGeometry*> psGeomVect;
69  eventLoop->Get( psGeomVect );
70  if (psGeomVect.size() < 1)
71  return OBJECT_NOT_AVAILABLE;
72  const DPSGeometry& psGeom = *(psGeomVect[0]);
73 
74  // load scale factors
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"];
80  else
81  jerr << "Unable to get PSC_ADC_ASCALE from /PHOTON_BEAM/pair_spectrometer/digi_scales !"
82  << endl;
83  if (scale_factors.find("PSC_ADC_TSCALE") != scale_factors.end())
84  t_scale = scale_factors["PSC_ADC_TSCALE"];
85  else
86  jerr << "Unable to get PSC_ADC_TSCALE from /PHOTON_BEAM/pair_spectrometer/digi_scales !"
87  << endl;
88 
89  // load base time offset
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"];
95  else
96  jerr << "Unable to get PS_COARSE_BASE_TIME_OFFSET from /PHOTON_BEAM/pair_spectrometer/base_time_offset !" << endl;
97  //
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"];
100  else
101  jerr << "Unable to get PS_COARSE_TDC_BASE_TIME_OFFSET from /PHOTON_BEAM/pair_spectrometer/base_time_offset !" << endl;
102 
103  /// Read in calibration constants
104  vector<double> raw_adc_pedestals;
105  vector<double> raw_adc_gains;
106  vector<double> raw_adc_offsets;
107  vector<double> raw_tdc_offsets;
108 
109  // load constant tables
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;
118 
119 
120  FillCalibTable(adc_pedestals, raw_adc_pedestals, psGeom);
121  FillCalibTable(adc_gains, raw_adc_gains, psGeom);
122  FillCalibTable(adc_time_offsets, raw_adc_offsets, psGeom);
123  FillCalibTable(tdc_time_offsets, raw_tdc_offsets, psGeom);
124 
125  // load timewalk corrections
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;
128 
129  return NOERROR;
130 }
131 
132 //------------------
133 // evnt
134 //------------------
135 jerror_t DPSCHit_factory::evnt(JEventLoop *loop, uint64_t eventnumber)
136 {
137  /// Generate DPSCHit object for each DPSCDigiHit object.
138  /// This is where the first set of calibration constants
139  /// is applied to convert from digitzed units into natural
140  /// units.
141  ///
142  /// Note that this code does NOT get called for simulated
143  /// data in HDDM format. The HDDM event source will copy
144  /// the precalibrated values directly into the _data vector.
145 
146  // extract the PS Geometry
147  vector<const DPSGeometry*> psGeomVect;
148  eventLoop->Get(psGeomVect);
149  if (psGeomVect.size() < 1)
150  return OBJECT_NOT_AVAILABLE;
151  const DPSGeometry& psGeom = *(psGeomVect[0]);
152 
153  const DTTabUtilities* locTTabUtilities = nullptr;
154  loop->GetSingle(locTTabUtilities);
155 
156  // First, make hits out of all fADC250 hits
157  vector<const DPSCDigiHit*> digihits;
158  loop->Get(digihits);
159  char str[256];
160 
161  for (unsigned int i=0; i < digihits.size(); i++) {
162  const DPSCDigiHit *digihit = digihits[i];
163 
164  // Make sure channel id is in valid range
165  const int PSC_MAX_CHANNELS = psGeom.NUM_COARSE_COLUMNS*psGeom.NUM_ARMS;
166  if( (digihit->counter_id <= 0) || (digihit->counter_id > PSC_MAX_CHANNELS)) {
167  sprintf(str, "DPSCDigiHit sector out of range! sector=%d (should be 1-%d)",
168  digihit->counter_id, PSC_MAX_CHANNELS);
169  throw JException(str);
170  }
171 
172  // Throw away hits with firmware errors (post-summer 2016 firmware)
173  if(CHECK_FADC_ERRORS && !locTTabUtilities->CheckFADC250_NoErrors(digihit->QF))
174  continue;
175 
176  // Get pedestal, prefer associated event pedestal if it exists,
177  // otherwise, use the average pedestal from CCDB
178  double pedestal = GetConstant(adc_pedestals,digihit,psGeom);
179  double nsamples_integral = (double)digihit->nsamples_integral;
180  double nsamples_pedestal = (double)digihit->nsamples_pedestal;
181 
182  // nsamples_pedestal should always be positive for valid data - err on the side of caution for now
183  if(nsamples_pedestal == 0) {
184  jerr << "DPSCDigiHit with nsamples_pedestal == 0 ! Event = " << eventnumber << endl;
185  continue;
186  }
187 
188  // digihit->pedestal is the sum of "nsamples_pedestal" samples
189  // Calculate the average pedestal per sample
190  if ( (digihit->pedestal>0) && locTTabUtilities->CheckFADC250_PedestalOK(digihit->QF) ) {
191  pedestal = (double)digihit->pedestal/nsamples_pedestal;
192  }
193 
194  // Subtract pedestal from pulse peak
195  if (digihit->pulse_time == 0 || digihit->pedestal == 0 || digihit->pulse_peak == 0) continue;
196  double pulse_peak = digihit->pulse_peak - pedestal;
197 
198  // Subtract pedestal from pulse integral
199  double A = (double)digihit->pulse_integral;
200  A -= pedestal*nsamples_integral;
201 
202  // Throw away hits with small pedestal-subtracted integrals
203  if (A < ADC_THRESHOLD) continue;
204 
205  // Apply calibration constants
206  double T = (double)digihit->pulse_time;
207 
208  DPSCHit *hit = new DPSCHit;
209  hit->arm = GetArm(digihit->counter_id,psGeom.NUM_COARSE_COLUMNS);
210  hit->module = GetModule(digihit->counter_id,psGeom.NUM_COARSE_COLUMNS);
211  hit->integral = A;
212  hit->pulse_peak = pulse_peak;
213  hit->npe_fadc = A * a_scale * GetConstant(adc_gains, digihit, psGeom);
214  hit->time_fadc = t_scale * T - GetConstant(adc_time_offsets, digihit, psGeom) + t_base;
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; // will get set to true below if appropriate
219 
220  hit->AddAssociatedObject(digihit);
221 
222  _data.push_back(hit);
223  }
224 
225  // Second, loop over TDC hits, matching them to the
226  // existing fADC hits where possible and updating
227  // their time information. If no match is found, then
228  // create a new hit with just the TDC info.
229  vector<const DPSCTDCDigiHit*> tdcdigihits;
230  loop->Get(tdcdigihits);
231 
232  for(unsigned int i=0; i<tdcdigihits.size(); i++) {
233  const DPSCTDCDigiHit *digihit = tdcdigihits[i];
234 
235  // calculate geometry information
236  DPSGeometry::Arm arm = GetArm(digihit->counter_id,psGeom.NUM_COARSE_COLUMNS);
237  int module = GetModule(digihit->counter_id,psGeom.NUM_COARSE_COLUMNS);
238 
239  // Apply calibration constants here
240  double T = locTTabUtilities->Convert_DigiTimeToNs_F1TDC(digihit) - GetConstant(tdc_time_offsets, digihit, psGeom) + t_tdc_base;
241  // Look for existing hits to see if there is a match
242  // or create new one if there is no match
243  DPSCHit *hit = FindMatch(arm, module, T);
244  if (hit == nullptr) {
245  hit = new DPSCHit;
246  hit->arm = arm;
247  hit->module = module;
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();
252  hit->has_fADC = false;
253  _data.push_back(hit);
254  }
255  hit->time_tdc = T;
256  hit->has_TDC = true;
257  // apply time-walk corrections
258  if (hit->pulse_peak > 0) {
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];
264  }
265  else {
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];
270  }
271  double P = hit->pulse_peak;
272  T -= c1*(pow(P/thresh,c2) - pow(P_0/thresh,c2));
273  }
274  hit->t = T;
275 
276  hit->AddAssociatedObject(digihit);
277  }
278 
279  return NOERROR;
280 }
281 
282 //------------------
283 // FindMatch
284 //------------------
286 {
287  DPSCHit* best_match = nullptr;
288 
289  // Loop over existing hits (from fADC) and look for a match
290  // in both the sector and the time.
291  for(unsigned int i=0; i<_data.size(); i++) {
292  DPSCHit *hit = _data[i];
293 
294  if(!hit->has_fADC) continue; // only match to fADC hits, not bachelor TDC hits
295  if(hit->arm != arm) continue;
296  if(hit->module != module) continue;
297 
298  double delta_T = fabs(T - hit->t);
299  if(delta_T > DELTA_T_ADC_TDC_MAX) continue;
300 
301  return hit;
302 
303  // if there are multiple hits, pick the one that is closest in time
304  if(best_match != nullptr) {
305  if(delta_T < fabs(best_match->t - T))
306  best_match = hit;
307  } else {
308  best_match = hit;
309  }
310 
311  }
312 
313  return best_match;
314 }
315 
316 // The translation table has PSC channels labaled as paddles 1-16
317 // The PSCHit class labels hits as
318 // arm: North/South (0/1)
319 // module: 1-8
320 const DPSGeometry::Arm DPSCHit_factory::GetArm(const int counter_id,const int num_counters_per_arm) const {
321  return counter_id <= num_counters_per_arm ? DPSGeometry::kNorth : DPSGeometry::kSouth;
322 }
323 const int DPSCHit_factory::GetModule(const int counter_id,const int num_counters_per_arm) const {
324  return counter_id <= num_counters_per_arm ? counter_id : counter_id - num_counters_per_arm;
325 }
326 
327 //------------------
328 // erun
329 //------------------
330 jerror_t DPSCHit_factory::erun(void)
331 {
332  return NOERROR;
333 }
334 
335 //------------------
336 // fini
337 //------------------
338 jerror_t DPSCHit_factory::fini(void)
339 {
340  return NOERROR;
341 }
342 
343 //------------------
344 // FillCalibTable
345 //------------------
346 void DPSCHit_factory::FillCalibTable(psc_digi_constants_t &table, vector<double> &raw_table,
347  const DPSGeometry &psGeom)
348 {
349  char str[256];
350  const int PSC_MAX_CHANNELS = psGeom.NUM_COARSE_COLUMNS*psGeom.NUM_ARMS;
351  int channel = 0;
352 
353  // reset the table before filling it
354  table.clear();
355 
356  // initialize table
357  for(int column=0; column<psGeom.NUM_COARSE_COLUMNS; column++)
358  table.push_back( pair<double,double>() );
359 
360  // the constants are stored in the CCDB as a 1D array
361  // with the first 8 channels being the north arm,
362  // and the second 8 channels being the south arm
363  for(int column=0; column<psGeom.NUM_COARSE_COLUMNS; column++) {
364  if( column+psGeom.NUM_COARSE_COLUMNS > PSC_MAX_CHANNELS) { // sanity check
365  sprintf(str, "Too many channels for PSC table! channel=%d (should be %d)",
366  channel, PSC_MAX_CHANNELS);
367  cerr << str << endl;
368  throw JException(str);
369  }
370 
371  table[column] = pair<double,double>(raw_table[column],raw_table[column+psGeom.NUM_COARSE_COLUMNS]);
372  channel += 2;
373  }
374 
375  // check to make sure that we loaded enough channels
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);
379  cerr << str << endl;
380  throw JException(str);
381  }
382 }
383 
384 //------------------------------------
385 // GetConstant
386 // Allow a few different interfaces
387 //
388 // PSC Geometry as defined in the Translation Table:
389 // arm: North/South (0/1)
390 // module: 1-8
391 // Note the different counting schemes used
392 //------------------------------------
393 const double DPSCHit_factory::GetConstant( const psc_digi_constants_t &the_table,
394  const DPSGeometry::Arm in_arm, const int in_module,
395  const DPSGeometry &psGeom ) const
396 {
397  char str[256];
398 
399  if( (in_arm != DPSGeometry::kNorth) && (in_arm != DPSGeometry::kSouth)) {
400  sprintf(str, "Bad arm requested in DPSCHit_factory::GetConstant()! requested=%d , should be 0-%d",
401  static_cast<int>(in_arm), static_cast<int>(DPSGeometry::kSouth));
402  cerr << str << endl;
403  throw JException(str);
404  }
405  if( (in_module <= 0) || (in_module > psGeom.NUM_COARSE_COLUMNS)) {
406  sprintf(str, "Bad module # requested in DPSCHit_factory::GetConstant()! requested=%d , should be 1-%d", in_module, psGeom.NUM_COARSE_COLUMNS);
407  cerr << str << endl;
408  throw JException(str);
409  }
410 
411  // the tables are indexed by module, with the different values for the two arms
412  // stored in the two fields of the pair
413  if(in_arm == DPSGeometry::kNorth) {
414  return the_table[in_module-1].first;
415  } else {
416  return the_table[in_module-1].second;
417  }
418 }
419 
420 const double DPSCHit_factory::GetConstant( const psc_digi_constants_t &the_table,
421  const DPSCHit *in_hit, const DPSGeometry &psGeom ) const
422 {
423  char str[256];
424 
425  if( (in_hit->arm != DPSGeometry::kNorth) && (in_hit->arm != DPSGeometry::kSouth)) {
426  sprintf(str, "Bad arm requested in DPSCHit_factory::GetConstant()! requested=%d , should be 0-%d",
427  static_cast<int>(in_hit->arm), static_cast<int>(DPSGeometry::kSouth));
428  cerr << str << endl;
429  throw JException(str);
430  }
431  if( (in_hit->module <= 0) || (in_hit->module > psGeom.NUM_COARSE_COLUMNS)) {
432  sprintf(str, "Bad module # requested in DPSCHit_factory::GetConstant()! requested=%d , should be 1-%d", in_hit->module, psGeom.NUM_COARSE_COLUMNS);
433  cerr << str << endl;
434  throw JException(str);
435  }
436 
437  // the tables are indexed by module, with the different values for the two arms
438  // stored in the two fields of the pair
439  if(in_hit->arm == DPSGeometry::kNorth) {
440  return the_table[in_hit->module-1].first;
441  } else {
442  return the_table[in_hit->module-1].second;
443  }
444 }
445 
446 const double DPSCHit_factory::GetConstant( const psc_digi_constants_t &the_table,
447  const DPSCDigiHit *in_digihit, const DPSGeometry &psGeom) const
448 {
449  char str[256];
450  // calculate geometry information
451  DPSGeometry::Arm arm = GetArm(in_digihit->counter_id,psGeom.NUM_COARSE_COLUMNS);
452  int module = GetModule(in_digihit->counter_id,psGeom.NUM_COARSE_COLUMNS);
453 
454  if( (module <= 0) || (module > psGeom.NUM_COARSE_COLUMNS)) {
455  sprintf(str, "Bad module # requested in DPSCHit_factory::GetConstant()! requested=%d , should be 1-%d", module, psGeom.NUM_COARSE_COLUMNS);
456  cerr << str << endl;
457  throw JException(str);
458  }
459 
460  // the tables are indexed by module, with the different values for the two arms
461  // stored in the two fields of the pair
462  if(arm == DPSGeometry::kNorth) {
463  return the_table[module-1].first;
464  } else {
465  return the_table[module-1].second;
466  }
467 }
468 
469 const double DPSCHit_factory::GetConstant( const psc_digi_constants_t &the_table,
470  const DPSCTDCDigiHit *in_digihit, const DPSGeometry &psGeom ) const
471 {
472  char str[256];
473  // calculate geometry information
474  DPSGeometry::Arm arm = GetArm(in_digihit->counter_id,psGeom.NUM_COARSE_COLUMNS);
475  int module = GetModule(in_digihit->counter_id,psGeom.NUM_COARSE_COLUMNS);
476 
477  if( (module <= 0) || (module > psGeom.NUM_COARSE_COLUMNS)) {
478  sprintf(str, "Bad module # requested in DPSCHit_factory::GetConstant()! requested=%d , should be 1-%d", module, psGeom.NUM_COARSE_COLUMNS);
479  cerr << str << endl;
480  throw JException(str);
481  }
482 
483  // the tables are indexed by module, with the different values for the two arms
484  // stored in the two fields of the pair
485  if(arm == DPSGeometry::kNorth) {
486  return the_table[module-1].first;
487  } else {
488  return the_table[module-1].second;
489  }
490 }
491 
vector< pair< double, double > > psc_digi_constants_t
double Convert_DigiTimeToNs_F1TDC(const JObject *locTDCDigiHit) const
int module
Definition: DPSCHit.h:20
bool CheckFADC250_NoErrors(uint32_t QF) const
uint32_t QF
Quality Factor from FPGA algorithms.
Definition: DPSCDigiHit.h:22
if(locHist_BCALShowerPhiVsZ!=NULL)
static const int NUM_ARMS
Definition: DPSGeometry.h:22
double pulse_peak
Definition: DPSCHit.h:23
jerror_t init(void)
Called once at program start.
char str[256]
double integral
Definition: DPSCHit.h:22
uint32_t pulse_integral
identified pulse integral as returned by FPGA algorithm
Definition: DPSCDigiHit.h:19
uint32_t nsamples_pedestal
number of samples used in pedestal
Definition: DPSCDigiHit.h:24
sprintf(text,"Post KinFit Cut")
DPSGeometry::Arm arm
Definition: DPSCHit.h:19
const int GetModule(const int counter_id, const int num_counters_per_arm) const
double t
Definition: DPSCHit.h:21
jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber)
Called every event.
bool has_TDC
Definition: DPSCHit.h:27
Double_t c1[2][NMODULES]
Definition: tw_corr.C:68
jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber)
Called everytime a new run number is detected.
bool has_fADC
Definition: DPSCHit.h:27
void FillCalibTable(psc_digi_constants_t &table, vector< double > &raw_table, const DPSGeometry &tofGeom)
Double_t c2[2][NMODULES]
Definition: tw_corr.C:69
uint32_t nsamples_integral
number of samples used in integral
Definition: DPSCDigiHit.h:23
double npe_fadc
Definition: DPSCHit.h:26
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
Definition: DPSGeometry.h:25
uint32_t pulse_time
identified pulse time as returned by FPGA algorithm
Definition: DPSCDigiHit.h:20
double time_tdc
Definition: DPSCHit.h:24
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
Definition: DPSCDigiHit.h:25
uint32_t pedestal
pedestal info used by FPGA (if any)
Definition: DPSCDigiHit.h:21
int counter_id
Definition: DPSCDigiHit.h:18
jerror_t erun(void)
Called everytime run number changes, provided brun has been called.
vector< double > adc_time_offsets
double time_fadc
Definition: DPSCHit.h:25
const double GetConstant(const psc_digi_constants_t &the_table, const DPSGeometry::Arm in_arm, const int in_module, const DPSGeometry &psGeom) const