Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OnlBbcEvent.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file OnlBbcEvent.cc
1 #include "OnlBbcEvent.h"
2 
3 //#include <BbcOut.h>
4 
5 //#include <getClass.h>
6 #include <Event/Event.h>
7 //#include <recoConsts.h>
8 
9 #include <TRandom.h>
10 #include <TString.h>
11 #include <TF1.h>
12 #include <TH1.h>
13 #include <TH2.h>
14 #include <TCanvas.h>
15 
16 #include <cmath>
17 #include <iostream>
18 #include <iomanip>
19 
20 using namespace std;
21 
22 // light velocity [cm/ns]
23 //static const float C = GSL_CONST_CGS_SPEED_OF_LIGHT / 1e9;
24 
26  verbose(0),
27  EventNumber(0),
28  calib_done(0),
29  p{nullptr,nullptr},
30  _tres(0.05),
31  ac(nullptr)
32 {
33  //set default values
34 
35  int nch = 256;
36  int nsamples = 31;
37  for (int ich=0; ich<nch; ich++)
38  {
39  //cout << "Creating bbcsig " << ich << endl;
40  bbcsig.push_back( OnlBbcSig(ich,nsamples) );
41 
42  // Do evt-by-evt pedestal using sample range below
43  bbcsig[ich].SetEventPed0Range(0,1);
44  }
45 
46  TString name, title;
47  for (int iarm = 0; iarm < 2; iarm++)
48  {
49  //
50  name = "hevt_bbct";
51  name += iarm;
52  title = "bbc times, arm ";
53  title += iarm;
54  hevt_bbct[iarm] = new TH1F(name, title, 2000, -50., 50.);
55  hevt_bbct[iarm]->SetLineColor(4);
56  }
57  h2_tmax[0] = new TH2F("h2_ttmax","time tmax vs ch",NSAMPLES,-0.5,NSAMPLES-0.5,128,0,128);
58  h2_tmax[0]->SetXTitle("sample");
59  h2_tmax[0]->SetYTitle("ch");
60  h2_tmax[1] = new TH2F("h2_qtmax","chg tmax vs ch",NSAMPLES,-0.5,NSAMPLES-0.5,128,0,128);
61  h2_tmax[1]->SetXTitle("sample");
62  h2_tmax[1]->SetYTitle("ch");
63 
64  for (int iboard=0; iboard<16; iboard++)
65  {
66  TRIG_SAMP[iboard] = -1;
67  }
68 
69  gaussian = nullptr;
70 
71  // read in our calibrations
72  const char *bbccalib = getenv("BBCCALIB");
73  if (!bbccalib)
74  {
75  std::cout << "BBCCALIB environment variable not set" << std::endl;
76  exit(1);
77  }
78  std::string gainfile = std::string(bbccalib) + "/" + "bbc_mip.calib";
79  Read_Charge_Calib( gainfile.c_str() );
80 
81  std::string tq_t0_offsetfile = std::string(bbccalib) + "/" + "bbc_tq_t0.calib";
82  Read_TQ_T0_Offsets( tq_t0_offsetfile.c_str() );
83 
84  std::string mondata_fname = std::string(bbccalib) + "/" + "BbcMonData.dat";
85  ifstream mondatafile( mondata_fname );
86  string label;
87  mondatafile >> label >> bz_offset;
88  std::cout << label << "\t" << bz_offset << std::endl;
89  mondatafile.close();
90 
91  Clear();
92 
93 }
94 
97 {
98  for (int iarm=0; iarm<2; iarm++)
99  {
100  delete hevt_bbct[iarm];
101  }
102 
103  delete h2_tmax[0];
104  delete h2_tmax[1];
105  delete ac;
106  delete gaussian;
107 
108 }
109 
111 {
112  h2_tmax[0]->Reset();
113  h2_tmax[1]->Reset();
114  calib_done = 0;
115 
116  Clear();
117  return 0;
118 }
119 
122 {
124  for ( int ipmt = 0; ipmt < BBC_N_PMT; ipmt++ )
125  {
126  iHit[ipmt] = 0;
127  armHitPmt[ipmt] = 0;
128  Charge[ipmt] = 0;
129  HitTime0[ipmt] = 0;
130  HitTime1[ipmt] = 0;
131  }
132 
133 
135  for ( int iarm = 0; iarm < 2; iarm++ )
136  {
137  nHitPmt[iarm] = 0;
138  ChargeSum[iarm] = 0;
139  ArmHitTime[iarm] = 0;
140  ArmHitTimeError[iarm] = 0;
141  f_bbcn[iarm] = 0;
142  }
144  ZVertex = 0.0;
145  ZVertexError = 0.0;
146  TimeZero = 0.0;
147  TimeZeroError = 0.0;
148 
149  // Arm Data
150  f_bbcn[0] = 0;
151  f_bbcn[1] = 0;
152  f_bbcq[0] = 0.;
153  f_bbcq[1] = 0.;
154  f_bbct[0] = -9999.;
155  f_bbct[1] = -9999.;
156  f_bbcte[0] = -9999.;
157  f_bbcte[1] = -9999.;
158  f_bbcz = NAN;
159  f_bbct0 = NAN;
160  hevt_bbct[0]->Reset();
161  hevt_bbct[1]->Reset();
162 
163  // PMT data
164  std::fill_n(f_pmtt0, 128, 1e12);
165  std::fill_n(f_pmtt1, 128, 1e12);
166  std::fill_n(f_pmtq, 128, 0.);
167 }
168 
170 {
171  // Get the relevant packets from the Event object and transfer the
172  // data to the subsystem-specific table.
173 
174  //int flag_err = 0;
175  for (int ipkt=0; ipkt<2; ipkt++)
176  {
177  int pktid = 1001 + ipkt; // packet id
178  p[ipkt] = event->getPacket( pktid );
179  //cout << "Found packet " << 2001+ipkt << "\t" << p[ipkt] << endl;
180 
181  if ( p[ipkt] )
182  {
183  for (int ich=0; ich<NCHPERPKT; ich++)
184  {
185  int feech = ipkt*NCHPERPKT + ich;
186  //cout << feech << endl;
187  for (int isamp=0; isamp<NSAMPLES; isamp++)
188  {
189  f_adc[feech][isamp] = p[ipkt]->iValue(isamp,ich);
190  f_samp[feech][isamp] = isamp;
191 
192  if ( f_adc[feech][isamp] <= 100 )
193  {
194  //flag_err = 1;
195  //cout << "BAD " << f_evt << "\t" << feech << "\t" << f_samp[feech][isamp]
196  // << "\t" << f_adc[feech][isamp] << endl;
197  }
198  }
199  }
200  }
201  else
202  {
203  //flag_err = 1;
204  //cout << "ERROR, evt " << f_evt << " Missing Packet " << pktid << endl;
205  }
206  }
207 
208  // Delete the packets
209  for (int ipkt=0; ipkt<2; ipkt++)
210  {
211  if ( p[ipkt]!=0 ) delete p[ipkt];
212  }
213 
214  EventNumber++;
215  return 0;
216 
217 }
218 
221 {
222  //cout << "In OnlBbcEvent::calculate()" << endl;
223  Clear();
224  if ( ! gaussian )
225  {
226  gaussian = new TF1("gaussian", "gaus", 0, 20);
227  gaussian->FixParameter(2, _tres); // set sigma to timing resolution
228  }
229 
230  for (int ich=0; ich<256; ich++)
231  {
232  bbcsig[ich].SetXY(f_samp[ich],f_adc[ich]);
233 
234  // determine the trig_samp board by board
235  int tq = (ich/8)%2; // 0 = T-channel, 1 = Q-channel
236  int pmtch = (ich/16)*8 + ich%8;
237 
238  double x, y;
239  bbcsig[ich].LocMax(x,y);
240  h2_tmax[tq]->Fill(x,pmtch);
241  }
242 
243  if ( h2_tmax[1]->GetEntries() == 128*100 )
244  {
245  TString name;
246  TH1 *h_trigsamp[16]{};
247  for (int iboard=0; iboard<16; iboard++)
248  {
249  name = "h_trigsamp"; name += iboard;
250  h_trigsamp[iboard] = h2_tmax[1]->ProjectionX( name, iboard*8 + 1, (iboard+1)*8 );
251  int maxbin = h_trigsamp[iboard]->GetMaximumBin();
252  TRIG_SAMP[iboard] = h_trigsamp[iboard]->GetBinCenter( maxbin );
253  //std::cout << "iboard " << iboard << "\t" << iboard*8+1 << "\t" << (iboard+1)*8 << "\t" << h_trigsamp[iboard]->GetEntries() << std::endl;
254  cout << "TRIG_SAMP" << iboard << "\t" << TRIG_SAMP[iboard] << endl;
255  }
256 
257  calib_done = 1;
258  }
259 
260  if ( calib_done == 0 )
261  {
262  return 0;
263  }
264  std::vector<float> hit_times[2]; // times of the hits in each [arm]
265 
266  //for (int ich=0; ich<NCH; ich++)
267  for (int ich=0; ich<256; ich++)
268  {
269  int board = ich/16; // south or north
270  //int quad = ich/64; // quadrant
271  int pmtch = (ich/16)*8 + ich%8;
272  int tq = (ich/8)%2; // 0 = T-channel, 1 = Q-channel
273 
274  if ( tq == 1 ) // Use dCFD method to get time for now in charge channels
275  {
276  //Double_t threshold = 4.0*sig->GetPed0RMS();
277  //
278  bbcsig[ich].GetSplineAmpl();
279  Double_t threshold = 0.5;
280  f_pmtt1[pmtch] = bbcsig[ich].dCFD( threshold );
281 
282  f_ampl[ich] = bbcsig[ich].GetAmpl();
283 
284  if ( f_ampl[ich]<24 || ( fabs( f_pmtt1[pmtch] ) >25 ) )
285  {
286  //f_t0[ich] = -9999.;
287  f_pmtt1[pmtch] = -9999.;
288  }
289  else
290  {
291  //if ( f_pmtt1[pmtch]<-50. && ich==255 ) cout << "hit_times " << ich << "\t" << f_pmtt1[pmtch] << endl;
292  //if ( arm==1 ) cout << "hit_times " << ich << "\t" << setw(10) << f_pmtt1[pmtch] << "\t" << board << "\t" << TRIG_SAMP[board] << endl;
293  f_pmtt1[pmtch] -= (TRIG_SAMP[board] - 2);
294  f_pmtt1[pmtch] *= 17.7623; // convert from sample to ns (1 sample = 1/56.299 MHz)
295  f_pmtt1[pmtch] = f_pmtt1[pmtch] - tq_t0_offsets[pmtch];
296 
297  }
298 
299  f_pmtq[pmtch] = f_ampl[ich]*gaincorr[pmtch];
300 
301  if ( EventNumber<3 && ich==255 && f_ampl[ich] )
302  {
303  cout << "dcfdcalc " << EventNumber << "\t" << ich << "\t" << f_pmtt1[pmtch] << "\t" << f_ampl[ich] << endl;
304  }
305  }
306  else // Use MBD method to get time in time channels
307  {
308  //Double_t threshold = 4.0*bbcsig[ich].GetPed0RMS();
309  //Double_t threshold = 0.5
310 
311  Double_t tdc = bbcsig[ich].MBD( TRIG_SAMP[board] );
312  //Double_t ampl = bbcsig[ich].GetSplineAmpl();
313  //if ( ich==0 ) cout << "XXX " << tdc << endl;
314 
315  if ( tdc<100 )
316  {
317  f_pmtt0[pmtch] = -9999.; // No Hit
318  }
319  else
320  {
321  //chiu Skip for now
322  // Convert TDC to ns
323  //f_pmtt0[pmtch] = tdc2time[ich]->Eval( tdc );
324  f_pmtt0[pmtch] = 12.5 - tdc*0.00189; // simple linear correction
325  //hit_times[arm].push_back( f_pmtt0[pmtch] );
326  //hevt_bbct[arm]->Fill( f_pmtt0[pmtch] );
327  //f_bbcn[arm]++;
328  }
329  }
330  }
331 
332  //cout << "nhits " << f_bbcn[0] << "\t" << f_bbcn[1] << endl;
333  //cout << "bbcte " << f_bbcte[0] << "\t" << f_bbcte[1] << endl;
334 
335  // calculate bbc global variables
336  for (int ipmt=0; ipmt<BBC_N_PMT; ipmt++)
337  {
338  int arm = ipmt/64;
339 
340  //if ( f_q[ipmt] > 20 && f_tq[ipmt] > 0. && f_tq[ipmt] < 35. )
341  //if ( f_tq[ipmt] > 0. && f_tq[ipmt] < 35. )
342  if ( fabs(f_pmtt1[ipmt]) < 25. )
343  {
344  hit_times[arm].push_back( f_pmtt1[ipmt] );
345  hevt_bbct[arm]->Fill( f_pmtt1[ipmt] );
346 
347  f_bbcn[arm]++;
348  ChargeSum[arm] += f_pmtq[ipmt]; // for now, calibration is 100
349 
350  }
351 
352  }
353 
354 
355  for (int iarm = 0; iarm < 2; iarm++)
356  {
357  if ( hit_times[iarm].empty() )
358  {
359  //cout << "hit_times size == 0" << endl;
360  continue;
361  }
362 
363  //cout << "EARLIEST " << iarm << endl;
364  //cout << "ERROR hit_times size == " << hit_times[iarm].size() << endl;
365 
366  std::sort(hit_times[iarm].begin(), hit_times[iarm].end());
367  float earliest = hit_times[iarm].at(0);
368  //cout << "earliest" << iarm << "\t" << earliest << endl;
369 
370  gaussian->SetParameter(0, 5);
371  //gaussian->SetParameter(1, earliest);
372  //gaussian->SetRange(6, earliest + 5 * 0.05);
373  gaussian->SetParameter(1,hevt_bbct[iarm]->GetMean());
374  gaussian->SetParameter(2,hevt_bbct[iarm]->GetRMS());
375  gaussian->SetRange(hevt_bbct[iarm]->GetMean()-5,hevt_bbct[iarm]->GetMean()+5);
376 
377  if ( verbose )
378  {
379  if ( ac == nullptr )
380  {
381  ac = new TCanvas("ac","ac",550*1.5,425*1.5);
382  ac->Divide(2,1);
383  }
384  ac->cd(iarm+1);
385  }
386 
387  hevt_bbct[iarm]->Fit(gaussian, "BNQLR");
388  if ( verbose ) hevt_bbct[iarm]->Draw();
389 
390  // f_bbct[iarm] = f_bbct[iarm] / f_bbcn[iarm];
391  f_bbct[iarm] = gaussian->GetParameter(1);
392  f_bbcte[iarm] = earliest;
393 
394  //_bbcout->AddBbcNS(iarm, f_bbcn[iarm], f_bbcq[iarm], f_bbct[iarm]);
395  }
396 
397  // Get Zvertex, T0
398  if (f_bbcn[0] > 0 && f_bbcn[1] > 0)
399  {
400  // Now calculate zvtx, t0 from best times
401  if ( verbose>10 ) cout << "t0\t" << f_bbct[0] << "\t" << f_bbct[1] << endl;
402  f_bbcz = (f_bbct[0] - f_bbct[1]) * TMath::C() * 1e-7 / 2.0; // in cm
403  f_bbct0 = (f_bbct[0] + f_bbct[1]) / 2.0;
404 
405  // correct z-vertex
406  f_bbcz += bz_offset;
407 
408  /*
409  // Use earliest time
410  //cout << "t0\t" << f_bbct[0] << "\t" << f_bbct[1] << endl;
411  //cout << "te\t" << f_bbcte[0] << "\t" << f_bbcte[1] << endl;
412  f_bbcz = (f_bbcte[0] - f_bbcte[1]) * TMath::C() * 1e-7 / 2.0; // in cm
413  f_bbct0 = (f_bbcte[0] + f_bbcte[1]) / 2.0;
414  */
415 
416  //cout << "bbcz " << f_bbcz << endl;
417  //_bbcout->set_Vertex(f_bbcz, 0.6);
418  //_bbcout->set_TimeZero(f_bbct0, 0.05);
419  }
420 
421 
422  return 0;
423 }
424 
425 
426 int OnlBbcEvent::Read_Charge_Calib(const char *gainfname)
427 {
428  std::ifstream gainfile( gainfname );
429 
430  cout << "Reading gains from " << gainfname << endl;
431  int ch;
432  float integ, integerr;
433  float peak, peakerr;
434  float width, widtherr;
435  float chi2ndf;
436  while ( gainfile >> ch >> integ >> peak >> width >> integerr >> peakerr >> widtherr >> chi2ndf )
437  {
438  gaincorr[ch] = 1.0/peak;
439 
440  //cout << ch << "\t" << peak << endl;
441  }
442 
443  gainfile.close();
444 
445  return 1;
446 }
447 
448 // Read in tq t0 offset calibrations
449 int OnlBbcEvent::Read_TQ_T0_Offsets(const char *t0cal_fname)
450 {
451  ifstream tcalibfile( t0cal_fname );
452 
453  cout << "Reading tq_t0 offset calibrations from " << t0cal_fname << endl;
454 
455  int pmtnum;
456  float meanerr;
457  float sigma;
458  float sigmaerr;
459  for (int ipmt=0; ipmt<BBC_N_PMT; ipmt++)
460  {
461  tcalibfile >> pmtnum >> tq_t0_offsets[ipmt] >> meanerr >> sigma >> sigmaerr;
462  if ( pmtnum != ipmt )
463  {
464  cerr << "ERROR, pmtnum != ipmt, " << pmtnum << "\t" << ipmt << endl;
465  }
466  }
467 
468  tcalibfile.close();
469 
470  return 1;
471 }
472 
473