Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DCCALHit_factory.cc
Go to the documentation of this file.
1 /*
2  * File: DCCALHit_factory.cc
3  *
4  * Created on 11/25/18 by A.S.
5  */
6 
7 #include <iostream>
8 #include <iomanip>
9 using namespace std;
10 
11 #include "CCAL/DCCALDigiHit.h"
12 #include "CCAL/DCCALGeometry.h"
13 #include "CCAL/DCCALHit_factory.h"
14 
15 #include "DAQ/Df250PulseIntegral.h"
16 #include "DAQ/Df250PulsePedestal.h"
17 
18 #include "DAQ/Df250Config.h"
19 #include "TTAB/DTTabUtilities.h"
20 
21 using namespace jana;
22 
23 //----------------
24 // Constructor
25 //----------------
27 
28  HIT_DEBUG = 0;
29  DB_PEDESTAL = 1; // 1 - take from DB
30  // 0 - event-by-event pedestal subtraction
31 
32  gPARMS->SetDefaultParameter("CCAL:HIT_DEBUG", HIT_DEBUG);
33  gPARMS->SetDefaultParameter("CCAL:DB_PEDESTAL", DB_PEDESTAL);
34 
35 }
36 
37 
38 //------------------
39 // init
40 //------------------
41 jerror_t DCCALHit_factory::init(void)
42 {
43  // initialize calibration tables
44  vector< vector<double > > gains_tmp(DCCALGeometry::kCCALBlocksTall,
45  vector<double>(DCCALGeometry::kCCALBlocksWide));
46  vector< vector<double > > pedestals_tmp(DCCALGeometry::kCCALBlocksTall,
47  vector<double>(DCCALGeometry::kCCALBlocksWide));
48 
49  vector< vector<double > > time_offsets_tmp(DCCALGeometry::kCCALBlocksTall,
50  vector<double>(DCCALGeometry::kCCALBlocksWide));
51  vector< vector<double > > adc_offsets_tmp(DCCALGeometry::kCCALBlocksTall,
52  vector<double>(DCCALGeometry::kCCALBlocksWide));
53 
54  gains = gains_tmp;
55  pedestals = pedestals_tmp;
56  time_offsets = time_offsets_tmp;
57  adc_offsets = adc_offsets_tmp;
58 
59 
60  adc_en_scale = 0;
61  adc_time_scale = 0;
62 
63  base_time = 0;
64 
65 
66  return NOERROR;
67 }
68 
69 //------------------
70 // brun
71 //------------------
72 jerror_t DCCALHit_factory::brun(jana::JEventLoop *eventLoop, int32_t runnumber)
73 {
74 
75  // Only print messages for one thread whenever run number change
76  static pthread_mutex_t print_mutex = PTHREAD_MUTEX_INITIALIZER;
77  static set<int> runs_announced;
78  pthread_mutex_lock(&print_mutex);
79  // bool print_messages = false;
80  if(runs_announced.find(runnumber) == runs_announced.end()){
81  // print_messages = true;
82  runs_announced.insert(runnumber);
83  }
84  pthread_mutex_unlock(&print_mutex);
85 
86  // extract the CCAL Geometry
87  vector<const DCCALGeometry*> ccalGeomVect;
88  eventLoop->Get( ccalGeomVect );
89  if (ccalGeomVect.size() < 1)
90  return OBJECT_NOT_AVAILABLE;
91  const DCCALGeometry& ccalGeom = *(ccalGeomVect[0]);
92 
93 
94  vector< double > ccal_gains_ch;
95  vector< double > ccal_pedestals_ch;
96  vector< double > time_offsets_ch;
97  vector< double > adc_offsets_ch;
98 
99  // load scale factors
100  map<string,double> scale_factors;
101 
102  if (eventLoop->GetCalib("/CCAL/digi_scales", scale_factors))
103  jout << "Error loading /CCAL/digi_scales !" << endl;
104  if (scale_factors.find("ADC_EN_SCALE") != scale_factors.end())
105  adc_en_scale = scale_factors["ADC_EN_SCALE"];
106  else
107  jerr << "Unable to get ADC_EN_SCALE from /CCAL/digi_scales !" << endl;
108  if (scale_factors.find("ADC_TIME_SCALE") != scale_factors.end())
109  adc_time_scale = scale_factors["ADC_TIME_SCALE"];
110  else
111  jerr << "Unable to get ADC_TIME_SCALE from /CCAL/digi_scales !" << endl;
112 
113  map<string,double> base_time_offset;
114  if (eventLoop->GetCalib("/CCAL/base_time_offset",base_time_offset))
115  jout << "Error loading /CCAL/base_time_offset !" << endl;
116  if (base_time_offset.find("BASE_TIME") != base_time_offset.end())
117  base_time = base_time_offset["BASE_TIME"];
118  else
119  jerr << "Unable to get BASE_TIME from /CCAL/base_time_offset !" << endl;
120 
121 
122  if (eventLoop->GetCalib("/CCAL/gains", ccal_gains_ch))
123  jout << "DCCALHit_factory: Error loading /CCAL/gains !" << endl;
124  if (eventLoop->GetCalib("/CCAL/pedestals", ccal_pedestals_ch))
125  jout << "DCCALHit_factory: Error loading /CCAL/pedestals !" << endl;
126 
127  if (eventLoop->GetCalib("/CCAL/timing_offsets", time_offsets_ch))
128  jout << "Error loading /CCAL/timing_offsets !" << endl;
129  if (eventLoop->GetCalib("/CCAL/adc_offsets", adc_offsets_ch))
130  jout << "Error loading /CCAL/adc_offsets !" << endl;
131 
132 
133  LoadCCALConst(gains, ccal_gains_ch, ccalGeom);
134  LoadCCALConst(pedestals, ccal_pedestals_ch, ccalGeom);
135  LoadCCALConst(time_offsets, time_offsets_ch, ccalGeom);
136  LoadCCALConst(adc_offsets, adc_offsets_ch, ccalGeom);
137 
138 
139  if(HIT_DEBUG == 1){
140 
141 
142  cout << endl;
143  cout << " ------- Gains -----------" << endl;
144 
145  for(int ii = 0; ii < 12; ii++){
146  for(int jj = 0; jj < 12; jj++){
147  cout << " " << gains[ii][jj];
148  }
149  cout << endl;
150  }
151 
152  cout << endl;
153  cout << " ------- Pedestals -----------" << endl;
154 
155  for(int ii = 0; ii < 12; ii++){
156  for(int jj = 0; jj < 12; jj++){
157  cout << " " << pedestals[ii][jj];
158  }
159  cout << endl;
160  }
161 
162  cout << endl;
163  cout << " ------- Timing offsets -----------" << endl;
164 
165  for(int ii = 0; ii < 12; ii++){
166  for(int jj = 0; jj < 12; jj++){
167  cout << " " << time_offsets[ii][jj];
168  }
169  cout << endl;
170  }
171 
172  cout << endl;
173  cout << " ------- ADC offsets -----------" << endl;
174 
175  for(int ii = 0; ii < 12; ii++){
176  for(int jj = 0; jj < 12; jj++){
177  cout << " " << adc_offsets[ii][jj];
178  }
179  cout << endl;
180  }
181 
182  cout << endl;
183  cout << "ADC_EN_SCALE = " << adc_en_scale << endl;
184  cout << "ADC_TIME_SCALE = " << adc_time_scale << endl;
185 
186  cout << endl;
187 
188  cout << "BASE_TIME_OFFSET = " << base_time << endl;
189 
190  cout << endl;
191 
192  }
193 
194  return NOERROR;
195 }
196 
197 //------------------
198 // evnt
199 //------------------
200 jerror_t DCCALHit_factory::evnt(JEventLoop *loop, uint64_t eventnumber)
201 {
202  /// Generate DCCALHit object for each DCCALDigiHit object.
203  /// This is where the first set of calibration constants
204  /// is applied to convert from digitzed units into natural
205  /// units.
206  ///
207  /// Note that this code does NOT get called for simulated
208  /// data in HDDM format. The HDDM event source will copy
209  /// the precalibrated values directly into the _data vector.
210 
211 
212  // extract the CCAL Geometry
213  vector<const DCCALGeometry*> ccalGeomVect;
214  eventLoop->Get( ccalGeomVect );
215  if (ccalGeomVect.size() < 1)
216  return OBJECT_NOT_AVAILABLE;
217  const DCCALGeometry& ccalGeom = *(ccalGeomVect[0]);
218 
219 
220  vector<const DCCALDigiHit*> digihits;
221 
222  loop->Get(digihits);
223 
224  for (unsigned int i = 0; i < digihits.size(); i++) {
225 
226  const DCCALDigiHit *digihit = digihits[i];
227 
228  double nsamples_integral = digihit->nsamples_integral;
229  double nsamples_pedestal = digihit->nsamples_pedestal;
230 
231 
232  // Currently use pedestals from the DB. We'll switch to the
233  // event-by-event pedestal subtraction later
234 
235  double pedestal = 0;
236 
237  if(DB_PEDESTAL == 1)
238  pedestal = pedestals[digihit->row][digihit->column];
239  else {
240  pedestal = (double)digihit->pedestal/nsamples_pedestal;
241  }
242 
243 
244  double integratedPedestal = pedestal * nsamples_integral;
245  double pulse_amplitude = digihit->pulse_peak - pedestal;
246 
247  double pulse_int = (double)digihit->pulse_integral;
248  double pulse_time = (double)digihit->pulse_time;
249 
250 
251  if(HIT_DEBUG == 1)
252  cout << "Row = " << digihit->row << "Column = " << digihit->column <<
253  " pulse_int = " << pulse_int << " integratedPedestal = " << integratedPedestal <<
254  " Pedestal = " << pedestal << endl;
255 
256  double pulse_int_ped_subt = adc_en_scale * gains[digihit->row][digihit->column] * (pulse_int - integratedPedestal);
257  double pulse_time_correct = adc_time_scale * pulse_time + base_time - time_offsets[digihit->row][digihit->column] +
258  adc_offsets[digihit->row][digihit->column];
259 
260 
261  if(pulse_int_ped_subt > 0 && pulse_time > 0){
262 
263  // Build hit object
264  DCCALHit *hit = new DCCALHit;
265 
266  hit->row = digihit->row;
267  hit->column = digihit->column;
268 
269  hit->E = pulse_int_ped_subt;
270  hit->t = pulse_time_correct;
271 
272  // Get position of blocks on front face. (This should really come from
273  // hdgeant directly so the poisitions can be shifted in mcsmear.)
274  DVector2 pos = ccalGeom.positionOnFace(hit->row, hit->column);
275  hit->x = pos.X();
276  hit->y = pos.Y();
277 
278  if(pulse_amplitude > 0){
279  hit->intOverPeak = (pulse_int - integratedPedestal)/pulse_amplitude;
280  } else
281  hit->intOverPeak = 0;
282 
283  hit->AddAssociatedObject(digihit);
284  _data.push_back(hit);
285 
286  } // Good hit
287 
288  }
289 
290  return NOERROR;
291 }
292 
293 //------------------
294 // erun
295 //------------------
297 {
298  return NOERROR;
299 }
300 
301 //------------------
302 // fini
303 //------------------
305 {
306  return NOERROR;
307 }
308 
309 
310 void DCCALHit_factory::LoadCCALConst(ccal_constants_t &table, const vector<double> &ccal_const_ch,
311  const DCCALGeometry &ccalGeom){
312 
313  char str[256];
314 
315  // if (ccalGeom.numActiveBlocks() != CCAL_MAX_CHANNELS) {
316  // sprintf(str, "CCAL geometry is wrong size! channels=%d (should be %d)",
317  // ccalGeom.numActiveBlocks(), CCAL_MAX_CHANNELS);
318  // throw JException(str);
319  // }
320 
321 
322  for (int ch = 0; ch < static_cast<int>(ccal_const_ch.size()); ch++) {
323 
324  // make sure that we don't try to load info for channels that don't exist
325  if (ch == ccalGeom.numActiveBlocks())
326  break;
327 
328  int row = ccalGeom.row(ch);
329  int col = ccalGeom.column(ch);
330 
331  // results from DCCALGeometry should be self consistent, but add in some
332  // sanity checking just to be sure
333 
334  if (ccalGeom.isBlockActive(row,col) == false) {
335  sprintf(str, "DCCALHit: Loading CCAL constant for inactive channel! "
336  "row=%d, col=%d", row, col);
337  throw JException(str);
338  }
339 
340  table[row][col] = ccal_const_ch[ch];
341  }
342 
343 }
344 
345 
346 
float t
Definition: DCCALHit.h:27
float x
Definition: DCCALHit.h:24
DVector2 positionOnFace(int row, int column) const
jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber)
Called everytime a new run number is detected.
int row
Definition: DCCALHit.h:22
char str[256]
jerror_t fini(void)
Called after last event of last event source has been processed.
TVector2 DVector2
Definition: DVector2.h:9
int column
Definition: DCCALHit.h:23
uint32_t pulse_integral
identified pulse integral as returned by FPGA algorithm
Definition: DCCALDigiHit.h:20
sprintf(text,"Post KinFit Cut")
void LoadCCALConst(ccal_constants_t &table, const vector< double > &ccal_const_ch, const DCCALGeometry &ccalGeom)
static const int kCCALBlocksWide
Definition: DCCALGeometry.h:25
uint32_t pedestal
pedestal info used by FPGA (if any)
Definition: DCCALDigiHit.h:22
int column(int channel) const
Definition: DCCALGeometry.h:47
jerror_t init(void)
Called once at program start.2.
jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber)
Called every event.
vector< vector< double > > ccal_constants_t
float E
Definition: DCCALHit.h:26
static const int kCCALBlocksTall
Definition: DCCALGeometry.h:26
uint32_t nsamples_integral
number of samples used in integral
Definition: DCCALDigiHit.h:24
uint32_t nsamples_pedestal
number of samples used in pedestal
Definition: DCCALDigiHit.h:25
static TH1I * pedestal[nChan]
uint32_t pulse_peak
maximum sample in pulse
Definition: DCCALDigiHit.h:26
int row(int channel) const
Definition: DCCALGeometry.h:46
uint32_t pulse_time
identified pulse time as returned by FPGA algorithm
Definition: DCCALDigiHit.h:21
bool isBlockActive(int row, int column) const
jerror_t erun(void)
Called everytime run number changes, provided brun has been called.
float y
Definition: DCCALHit.h:25
int numActiveBlocks() const
Definition: DCCALGeometry.h:38
float intOverPeak
Definition: DCCALHit.h:28