Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DTPOLHit_factory.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <iomanip>
3 #include <limits>
4 #include <cmath>
5 
6 #include <TRIGGER/DL1Trigger.h>
10 #include <DAQ/Df250Config.h>
11 #include "DTPOLHit_factory.h"
12 
13 using namespace std;
14 using namespace jana;
15 
16 // static consts need initialization
18 const double DTPOLHit_factory::INNER_RADIUS = 22. / 2; // From "ACTIVE INNER DIAMETER" in catalog
19 const double DTPOLHit_factory::OUTER_RADIUS = 70. / 2; // From "ACTIVE OUTER DIAMETER" in catalog
20 const double DTPOLHit_factory::RING_DIVISION = (OUTER_RADIUS - INNER_RADIUS ) / DTPOLHit_factory::NRINGS;
21 
22 // Order hits by sector/ring. If same sector/ring, use ADC time to order hits.
24  if (a->sector==b->sector) return (a->pulse_time<b->pulse_time);
25  return (a->sector<b->sector);
26 }
28  if (a->ring==b->ring) return (a->pulse_time<b->pulse_time);
29  return (a->ring<b->ring);
30 }
31 
32 //------------------
33 // init
34 //------------------
35 jerror_t DTPOLHit_factory::init(void)
36 {
37  ADC_THRESHOLD = 40.0;
38  gPARMS->SetDefaultParameter("TPOLHit:ADC_THRESHOLD", ADC_THRESHOLD,
39  "ADC pulse-height threshold");
40 
41  /// set the base conversion scales
42  a_scale = 0.0001;
43  t_scale = 0.0625; // 62.5 ps/count
44 
45  return NOERROR;
46 }
47 
48 //------------------
49 // brun
50 //------------------
51 jerror_t DTPOLHit_factory::brun(jana::JEventLoop *eventLoop, int32_t runnumber)
52 {
53  /// Read in calibration constants
54  //jout << "In DTPOLHit_factory, loading constants..." << endl;
55  // load scale factors
56  /*map<string,double> scale_factors;
57  // a_scale (SC_ADC_SCALE)
58  if (eventLoop->GetCalib("/TPOL/digi_scales", scale_factors))
59  jout << "Error loading /TPOL/digi_scales !" << endl;
60  if (scale_factors.find("TPOL_ADC_ASCALE") != scale_factors.end())
61  a_scale = scale_factors["TPOL_ADC_ASCALE"];
62  else
63  jerr << "Unable to get TPOL_ADC_ASCALE from /TPOL/digi_scales !"
64  << endl;
65  // t_scale (SC_ADC_SCALE)
66  if (scale_factors.find("TPOL_ADC_TSCALE") != scale_factors.end())
67  t_scale = scale_factors["TPOL_ADC_TSCALE"];
68  else
69  jerr << "Unable to get TPOL_ADC_TSCALE from /TPOL/digi_scales !"
70  << endl;
71 
72  // load base time offset
73  map<string,double> base_time_offset;
74  if (eventLoop->GetCalib("/TPOL/base_time_offset",base_time_offset))
75  jout << "Error loading /TPOL/base_time_offset !" << endl;
76  if (base_time_offset.find("TPOL_BASE_TIME_OFFSET") != base_time_offset.end())
77  t_base = base_time_offset["TPOL_BASE_TIME_OFFSET"];
78  else
79  jerr << "Unable to get TPOL_BASE_TIME_OFFSET from /TPOL/base_time_offset !" << endl;
80 
81  // load constant tables
82  // a_gains (gains)
83  if (eventLoop->GetCalib("/TPOL/gains", a_gains))
84  jout << "Error loading /TPOL/gains !" << endl;
85  // a_pedestals (pedestals)
86  if (eventLoop->GetCalib("/TPOL/pedestals", a_pedestals))
87  jout << "Error loading /TPOL/pedestals !" << endl;
88  // adc_time_offsets (adc_timing_offsets)
89  if (eventLoop->GetCalib("/TPOL/adc_timing_offsets", adc_time_offsets))
90  jout << "Error loading /TPOL/adc_timing_offsets !" << endl;*/
91  return NOERROR;
92 }
93 
94 
95 
96 //------------------
97 // evnt
98 //------------------
99 jerror_t DTPOLHit_factory::evnt(JEventLoop *loop, uint64_t eventnumber)
100 {
101  /// Generate DTPOLHit object for each DTPOLSectorDigiHit
102  /// and DTPOLRingDigiHit object.
103  /// This is where the first set of calibration constants
104  /// is applied to convert from digitzed units into natural
105  /// units.
106  ///
107  /// Note that this code does NOT get called for simulated
108  /// data in HDDM format. The HDDM event source will copy
109  /// the precalibrated values directly into the _data vector.
110  //
111  // Get fADC250 hits
112  /*vector<const DTPOLSectorDigiHit*> sectordigihits;
113  loop->Get(sectordigihits);
114  sort(sectordigihits.begin(),sectordigihits.end(),DTPOLSectorHit_fadc_cmp);
115  vector<const DTPOLRingDigiHit*> ringdigihits;
116  loop->Get(ringdigihits);
117  sort(ringdigihits.begin(),ringdigihits.end(),DTPOLRingHit_fadc_cmp);
118  char str[256];
119  // Loop over SECTOR hits
120  for (unsigned int i = 0; i < sectordigihits.size(); i++){
121  //
122  const DTPOLSectorDigiHit *sectordigihit = sectordigihits[i];
123  const Df250PulsePedestal* PPobj = NULL;
124  sectordigihit->GetSingle(PPobj);
125  double pulse_peak = 0.0; double pedestal = 0.0;
126  if (PPobj != NULL){
127  if (PPobj->pedestal == 0 || PPobj->pulse_peak == 0) continue;
128  pedestal = PPobj->pedestal;
129  pulse_peak = PPobj->pulse_peak - PPobj->pedestal;
130  }
131  if (pulse_peak < ADC_THRESHOLD) continue;
132  // Make sure sector is in valid range
133  if( sectordigihit->sector <= 0 || sectordigihit->sector > DTPOLHit_factory::NSECTORS){
134  sprintf(str, "DTPOLSectorDigiHit sector out of range! sector=%d (should be 1-%d)",
135  sectordigihit->sector, DTPOLHit_factory::NSECTORS);
136  throw JException(str);
137  }
138  // Initialize pedestal to one found in CCDB, but override it
139  // with one found in event if is available
140  //double pedestal = a_pedestals[sectordigihit->sector-1];
141  const Df250PulseIntegral *pulse_integral = NULL;
142  sectordigihit->GetSingle(pulse_integral);
143  double pedestal_sum = 0.0;
144  if (pulse_integral != NULL) {
145  double single_sample_ped = (double)pulse_integral->pedestal;
146  double nsamples_integral = (double)pulse_integral->nsamples_integral;
147  double nsamples_pedestal = (double)pulse_integral->nsamples_pedestal;
148  pedestal_sum = single_sample_ped * nsamples_integral/nsamples_pedestal;
149  }
150  // Apply calibration constants here
151  double A = (double)sectordigihit->pulse_integral;
152  double T = (double)sectordigihit->pulse_time;
153  if (T == 0.0 || pedestal == 0.0) continue;
154  double dA = A - pedestal_sum;
155  DTPOLHit *hit = new DTPOLHit;
156  hit->sector = sectordigihit->sector;
157  hit->ring = 0;
158  hit->pulse_peak = pulse_peak;
159  hit->integral = dA;
160  hit->dE = dA; // This will be scaled to energy units later
161  //hit->t = t_scale * T - adc_time_offsets[hit->sector-1] + t_base;
162  hit->t = t_scale*T;
163  hit->AddAssociatedObject(sectordigihit);
164  _data.push_back(hit);
165  }*/
166  /*
167  // Apply calibration constants to convert pulse integrals to energy
168  // units
169  for (unsigned int i=0;i<_data.size();i++)
170  {
171  _data[i]->dE*=a_scale * a_gains[_data[i]->sector-1];
172 }
173 */
174  // get trigger type
175  const DL1Trigger *trig_words = NULL;
176  uint32_t trig_mask, fp_trig_mask;
177  try {
178  loop->GetSingle(trig_words);
179  } catch(...) {};
180  if (trig_words) {
181  trig_mask = trig_words->trig_mask;
182  fp_trig_mask = trig_words->fp_trig_mask;
183  }
184  else {
185  trig_mask = 0;
186  fp_trig_mask = 0;
187  }
188  int trig_bits = fp_trig_mask > 0 ? 10 + fp_trig_mask:trig_mask;
189  // skim PS triggers
190  if (trig_bits!=8) {
191  return NOERROR;
192  }
193  // get raw samples and make TPOL hits
194  vector<const Df250WindowRawData*> windowraws;
195  loop->Get(windowraws);
196  for(unsigned int i=0; i< windowraws.size(); i++){
197  const Df250WindowRawData *windowraw = windowraws[i];
198  if (windowraw->rocid!=84) continue; // choose rocPS2
199  if (!(windowraw->slot==13||windowraw->slot==14)) continue; // azimuthal sectors: 13,14; rings: 15,16
200  int slot = windowraw->slot;
201  int channel = windowraw->channel;
202  // Get a vector of the samples for this channel
203  const vector<uint16_t> &samplesvector = windowraw->samples;
204  unsigned int nsamples=samplesvector.size();
205  // loop over the samples to calculate integral, min, max
206  if (nsamples==0) jerr << "Raw samples vector is empty." << endl;
207  if (samplesvector[0] > 133.0) continue; // require first sample below readout threshold
208  double w_samp1 = 0.0; double w_min = 0.0; double w_max = 0.0; double w_integral = 0.0;
209  for (uint16_t c_samp=0; c_samp<nsamples; c_samp++) {
210  if (c_samp==0) { // use first sample for initialization
211  w_integral = samplesvector[0];
212  w_min = samplesvector[0];
213  w_max = samplesvector[0];
214  w_samp1 = samplesvector[0];
215  } else {
216  w_integral += samplesvector[c_samp];
217  if (w_min > samplesvector[c_samp]) w_min = samplesvector[c_samp];
218  if (w_max < samplesvector[c_samp]) w_max = samplesvector[c_samp];
219  }
220  }
221  double pulse_height = w_max - w_min;
222  if (pulse_height < ADC_THRESHOLD) continue;
223  DTPOLHit *hit = new DTPOLHit;
224  hit->sector = GetSector(slot,channel);
225  hit->phi = GetPhi(hit->sector);
226  hit->ring = 0;
227  hit->theta = 0;
228  hit->pulse_peak = pulse_height;
229  hit->integral = w_integral - nsamples*w_samp1;
230  hit->dE = pulse_height;
231  hit->t = t_scale*GetPulseTime(samplesvector,w_min,w_max,ADC_THRESHOLD);
232  _data.push_back(hit);
233  }
234  return NOERROR;
235 }
236 
237 //------------------
238 // erun
239 //------------------
241 {
242  return NOERROR;
243 }
244 
245 //------------------
246 // fini
247 //------------------
249 {
250  return NOERROR;
251 }
252 
253 int DTPOLHit_factory::GetSector(int slot,int channel)
254 {
255  int sector = 0;
256  if (slot == 13) sector = 25 - channel;
257  if (slot == 14) {
258  if (channel <= 8) sector = 9 - channel;
259  else sector = NSECTORS + 9 - channel;
260  }
261  // fix cable swap
262  if (sector == 9) sector = 6;
263  else if (sector == 6) sector = 9;
264  if (sector == 0) jerr << "sector did not change from initial value (0)." << endl;
265  return sector;
266 }
267 double DTPOLHit_factory::GetPhi(int sector)
268 {
269  double phi = -10.0;
270  if(sector <= 8) phi = (sector + 23)*SECTOR_DIVISION + 0.5*SECTOR_DIVISION;
271  if(sector >= 9) phi = (sector - 9)*SECTOR_DIVISION + 0.5*SECTOR_DIVISION;
272  return phi;
273 }
274 double DTPOLHit_factory::GetPulseTime(const vector<uint16_t> waveform,double w_min,double w_max,double minpeakheight)
275 {
276  // find the time to cross half peak height
277  int lastbelowsamp=0; double peakheight = w_max-w_min;
278  double threshold = w_min + peakheight/2.0;
279  double firstaboveheight=0, lastbelowheight=0;
280  double w_time=0;
281  if (peakheight > minpeakheight) {
282  for (uint16_t c_samp=0; c_samp<waveform.size(); c_samp++) {
283  if (waveform[c_samp]>threshold) {
284  firstaboveheight = waveform[c_samp];
285  lastbelowsamp = c_samp-1;
286  lastbelowheight = waveform[c_samp-1];
287  break;
288  }
289  }
290  w_time = lastbelowsamp + (threshold-lastbelowheight)/(firstaboveheight-lastbelowheight);
291  }
292  return 64.0*w_time;
293 }
294 //------------------------------------
295 // GetConstant
296 // Allow a few different interfaces
297 //------------------------------------
298 const double DTPOLHit_factory::GetConstant(const vector<double> &the_table,const int in_sector) const{
299  char str[256];
300 
301  if ( (in_sector < 0) || (in_sector >= DTPOLHit_factory::NSECTORS)){
302  sprintf(str, "Bad sector # requested in DTPOLHit_factory::GetConstant()!"
303  " requested=%d , should be %ud", in_sector, DTPOLHit_factory::NSECTORS);
304  cerr << str << endl;
305  throw JException(str);
306  }
307 
308  return the_table[in_sector];
309 }
310 
311 const double DTPOLHit_factory::GetConstant(const vector<double> &the_table,const DTPOLHit *in_hit) const {
312  char str[256];
313 
314  if ( (in_hit->sector < 0) || (in_hit->sector >= DTPOLHit_factory::NSECTORS)){
315  sprintf(str, "Bad sector # requested in DTPOLHit_factory::GetConstant()!"
316  " requested=%d , should be %ud",
318  cerr << str << endl;
319  throw JException(str);
320  }
321 
322  return the_table[in_hit->sector];
323 }
324 
int sector
Definition: DTPOLHit.h:11
const double SECTOR_DIVISION
char str[256]
jerror_t fini(void)
uint32_t trig_mask
Definition: DL1Trigger.h:18
uint32_t fp_trig_mask
Definition: DL1Trigger.h:19
int GetSector(int slot, int channel)
sprintf(text,"Post KinFit Cut")
double dE
Definition: DTPOLHit.h:17
int ring
Definition: DTPOLHit.h:13
jerror_t erun(void)
vector< uint16_t > samples
double pulse_peak
Definition: DTPOLHit.h:15
static const int NRINGS
const double GetConstant(const vector< double > &the_table, const int in_sector) const
const int NSECTORS
static const double INNER_RADIUS
double GetPhi(int sector)
double GetPulseTime(const vector< uint16_t > waveform, double w_min, double w_max, double minpeakheight)
double phi
Definition: DTPOLHit.h:12
bool DTPOLRingHit_fadc_cmp(const DTPOLRingDigiHit *a, const DTPOLRingDigiHit *b)
jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber)
double integral
Definition: DTPOLHit.h:16
bool DTPOLSectorHit_fadc_cmp(const DTPOLSectorDigiHit *a, const DTPOLSectorDigiHit *b)
static const double SECTOR_DIVISION
uint32_t channel
Definition: DDAQAddress.h:34
uint32_t rocid
Definition: DDAQAddress.h:32
double t
Definition: DTPOLHit.h:18
static const double RING_DIVISION
static const double OUTER_RADIUS
jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber)
double theta
Definition: DTPOLHit.h:14
uint32_t slot
Definition: DDAQAddress.h:33
jerror_t init(void)
static const int NSECTORS