MiniballSort
Loading...
Searching...
No Matches
CDCalibrator.cc
Go to the documentation of this file.
1#include "CDCalibrator.hh"
2
3MiniballCDCalibrator::MiniballCDCalibrator( std::shared_ptr<MiniballSettings> myset ){
4
5 // First get the settings
6 set = myset;
7
8 // No calibration file by default
9 overwrite_cal = false;
10
11 // No input file at the start by default
12 flag_input_file = false;
13
14 // Progress bar starts as false
15 _prog_ = false;
16
17 // Start at MBS event 0
18 preveventid = 0;
19
20 // ------------------------------- //
21 // Initialise variables and flags //
22 // ------------------------------- //
23 build_window = set->GetEventWindow();
24
25 // Intialise the hist list
26 histlist = new TList();
27
28}
29
31
32 // Call for every new file
33 // Reset counters etc.
34
35 time_prev = 0;
36 time_min = 0;
37 time_max = 0;
38 time_first = 0;
39
40}
41
42void MiniballCDCalibrator::SetInputFile( std::vector<std::string> input_file_names ) {
43
45 input_tree = new TChain( "mb_sort" );
46 mbsinfo_tree = new TChain( "mbsinfo" );
47 for( unsigned int i = 0; i < input_file_names.size(); i++ ) {
48
49 input_tree->Add( input_file_names[i].data() );
50 mbsinfo_tree->Add( input_file_names[i].data() );
51
52 }
53
54 flag_input_file = true;
55
56 input_tree->SetBranchAddress( "data", &in_data );
57 mbsinfo_tree->SetBranchAddress( "mbsinfo", &mbs_info );
58 if (mbsinfo_tree->GetEntries()) mbsinfo_tree->BuildIndex("GetEventID()");
59
60 return;
61
62}
63
64void MiniballCDCalibrator::SetInputFile( std::string input_file_name ) {
65
66 // Open next Root input file.
67 input_file = new TFile( input_file_name.data(), "read" );
68 if( input_file->IsZombie() ) {
69
70 std::cout << "Cannot open " << input_file_name << std::endl;
71 return;
72
73 }
74
75 flag_input_file = true;
76
77 // Set the input tree
78 SetInputTree( (TTree*)input_file->Get("mb_sort") );
79 SetMBSInfoTree( (TTree*)input_file->Get("mbsinfo") );
80 StartFile();
81
82 return;
83
84}
85
86void MiniballCDCalibrator::SetInputTree( TTree *user_tree ){
87
88 // Find the tree and set branch addresses
89 input_tree = (TChain*)user_tree;
90 in_data = nullptr;
91 input_tree->SetBranchAddress( "data", &in_data );
92
93 return;
94
95}
96
97void MiniballCDCalibrator::SetMBSInfoTree( TTree *user_tree ){
98
99 // Find the tree and set branch addresses
100 mbsinfo_tree = (TChain*)user_tree;
101 mbs_info = nullptr;
102 mbsinfo_tree->SetBranchAddress( "mbsinfo", &mbs_info );
103
104 return;
105
106}
107
108void MiniballCDCalibrator::SetOutput( std::string output_file_name, bool cWrite ) {
109
110 // ------------------------------------------------------------------------ //
111 // Create output file and create events tree
112 // ------------------------------------------------------------------------ //
113 output_file = new TFile( output_file_name.data(), "recreate" );
114
115 // Hisograms in separate function
116 MakeHists();
117
118 // Output the calibration coefficients
119 std::string cal_file_name = output_file_name.substr( 0, output_file_name.find_last_of(".") );
120 cal_file_name += ".cal";
121 output_cal.open( cal_file_name.data(), std::ios::trunc );
122
123 // Write once at the start if in spy
124 if( cWrite ) output_file->Write();
125
126}
127
129
131
132 flag_close_event = false;
133 event_open = false;
134
135 hit_ctr = 0;
136
137 std::vector<float>().swap(cd_en_list);
138 std::vector<unsigned int>().swap(cd_Q_list);
139 std::vector<unsigned long long>().swap(cd_ts_list);
140 std::vector<unsigned char>().swap(cd_det_list);
141 std::vector<unsigned char>().swap(cd_sec_list);
142 std::vector<unsigned char>().swap(cd_side_list);
143 std::vector<unsigned char>().swap(cd_strip_list);
144
145 return;
146
147}
148
149
150int nextPowerOf2(unsigned int n) {
151 if (n == 0) return 1;
152
153 n--;
154 n |= n >> 1;
155 n |= n >> 2;
156 n |= n >> 4;
157 n |= n >> 8;
158 n |= n >> 16;
159
160 return n + 1;
161}
162
163
165
166 std::string hname, htitle;
167
168 // ------------- //
169 // CD histograms //
170 // ------------- //
171 cd_pen_nQ.resize( set->GetNumberOfCDDetectors() );
172 cd_nQ_pQ.resize( set->GetNumberOfCDDetectors() );
173
174 // Get sizes and scales
175 double maxEn = set->GetCDCalibratorMaxEnergy();
176 // read FEBEX gain and offset for reference p strip in first quadrant (febex_1_0_ptag) to get an idea of raw charge range
177 double maxRawEn = ( maxEn - cal->FebexOffset(1,0,ptag) ) / cal->FebexGain(1,0,ptag);
178 // round that value to the next power of two
179 int maxQ = nextPowerOf2(std::round(maxRawEn));
180 unsigned int Qbins = 8192;
181
182 if( set->GetNumberOfCaenAdcModules() > 0 ) {
183 maxQ = 4096;
184 Qbins = 4096;
185 }
186
187 else if( set->GetNumberOfFebexSfps() > 1 &&
188 set->GetNumberOfFebexBoards() > 0 &&
189 set->GetNumberOfFebexChannels() > 0 ) {
190
191 if( cal->FebexType( 1, 0, 0 ) == "Qshort" ) {
192 maxQ = 65536;
193 }
194 }
195
196 for( unsigned int i = 0; i < set->GetNumberOfCDDetectors(); ++i ) {
197
198 cd_pen_nQ[i].resize( set->GetNumberOfCDSectors() );
199 cd_nQ_pQ[i].resize( set->GetNumberOfCDSectors() );
200
201 for( unsigned int j = 0; j < set->GetNumberOfCDSectors(); ++j ) {
202
203 cd_nQ_pQ[i][j].resize( set->GetNumberOfCDPStrips() );
204
205 for( unsigned int k = 0; k < set->GetNumberOfCDPStrips(); ++k ) {
206
207 hname = "cd_" + std::to_string(i) + "_" + std::to_string(j);
208 hname += "_nQ_" + std::to_string(ntag) + "_pQ_" + std::to_string(k);
209 htitle = "CD n-side raw charge vs p-side raw charge for detector " + std::to_string(i);
210 htitle += ", sector " + std::to_string(j) + ", pid " + std::to_string(k);
211 htitle += ", nid " + std::to_string(ntag);
212 htitle += ";n-side raw charge (ADC units);p-side raw charge (ADC units);Counts";
213 cd_nQ_pQ[i][j][k] = new TH2F( hname.data(), htitle.data(),
214 Qbins, 0, maxQ, Qbins, 0, maxQ );
215 histlist->Add(cd_nQ_pQ[i][j][k]);
216
217 } // k
218
219 cd_pen_nQ[i][j].resize( set->GetNumberOfCDNStrips() );
220
221 for( unsigned int k = 0; k < set->GetNumberOfCDNStrips(); ++k ) {
222
223 hname = "cd_" + std::to_string(i) + "_" + std::to_string(j);
224 hname += "_pen_" + std::to_string(ptag) + "_nQ_" + std::to_string(k);
225 htitle = "CD p-side energy vs n-side raw charge for detector " + std::to_string(i);
226 htitle += ", sector " + std::to_string(j) + ", pid " + std::to_string(ptag);
227 htitle += ", nid " + std::to_string(k);
228 htitle += ";p-side energy (keV);n-side raw charge (ADC units);Counts";
229 cd_pen_nQ[i][j][k] = new TH2F( hname.data(), htitle.data(),
230 4000, 0, maxEn, Qbins, 0, maxQ );
231 histlist->Add(cd_pen_nQ[i][j][k]);
232
233 } // k
234
235 } // j
236
237 } // i
238
239
240 // flag to denote that hists are ready (used for spy)
241 hists_ready = true;
242
243 return;
244
245}
246
247// Reset histograms in the DataSpy
249
250 // Loop over the hist list
251 TIter next( histlist->MakeIterator() );
252 while( TObject *obj = next() ) {
253
254 if( obj->InheritsFrom( "TH2" ) )
255 ( (TH2*)obj )->Reset("ICESM");
256 else if( obj->InheritsFrom( "TH1" ) )
257 ( (TH1*)obj )->Reset("ICESM");
258
259 }
260
261 return;
262
263}
264
265bool MiniballCDCalibrator::FindCDChannels( int det, int sec, int side, int strip, int &adc, int &ch ) {
266
267 // Loop over ADCs
268 for( unsigned int m = 0; m < set->GetNumberOfCaenAdcModules(); ++m ) {
269
270 // Loop over channels
271 for( unsigned int c = 0; c < set->GetNumberOfCaenAdcChannels(); ++c ) {
272
273 // Check that it's a CD
274 if( !set->IsCD(m,c) ) continue;
275
276 // Check we have the correct CD detector
277 if( set->GetCDDetector(m,c) != det ) continue;
278
279 // Check we have the correct sector
280 if( set->GetCDSector(m,c) != sec ) continue;
281
282 // Check we have an P side (==0)
283 if( set->GetCDSide(m,c) != side ) continue;
284
285 // Check we have the correct strip
286 if( set->GetCDStrip(m,c) != strip ) continue;
287
288 // Then we got the right channel
289 adc = m;
290 ch = c;
291 return true;
292
293 } // c
294
295 } // m
296
297 std::cerr << "CD strip not found, det=" << det << ", sec=" << sec;
298 std::cerr << ", side=" << side << ", strip=" << strip << std::endl;
299 return false;
300
301}
302
303bool MiniballCDCalibrator::FindCDChannels( int det, int sec, int side, int strip, int &sfp, int &board, int &ch ) {
304
305 // Loop over SFPs
306 for( unsigned int s = 0; s < set->GetNumberOfFebexSfps(); ++s ) {
307
308 // Loop over boards
309 for( unsigned int m = 0; m < set->GetNumberOfFebexBoards(); ++m ) {
310
311 // Loop over channels
312 for( unsigned int c = 0; c < set->GetNumberOfFebexChannels(); ++c ) {
313
314 // Check that it's a CD
315 if( !set->IsCD(s,m,c) ) continue;
316
317 // Check we have the correct CD detector
318 if( set->GetCDDetector(s,m,c) != det ) continue;
319
320 // Check we have the correct sector
321 if( set->GetCDSector(s,m,c) != sec ) continue;
322
323 // Check we have the right side
324 if( set->GetCDSide(s,m,c) != side ) continue;
325
326 // Check we have the correct strip
327 if( set->GetCDStrip(s,m,c) != strip ) continue;
328
329 // Then we got the right channel
330 sfp = s;
331 board = m;
332 ch = c;
333 return true;
334
335 } // c
336
337 } // m
338
339 } // s
340
341 std::cerr << "CD strip not found, det=" << det << ", sec=" << sec;
342 std::cerr << ", side=" << side << ", strip=" << strip << std::endl;
343 return false;
344
345}
346
348
349 // Check if we have old or new DAQ
350 bool oldDAQ = false;
351 if( set->GetNumberOfCaenAdcModules() > 0 )
352 oldDAQ = true;
353
354 // Create a TF1 for the linear fit
355 auto pfit = std::make_unique<TF1>( "pfit", "[0]+[1]*x", 0, 1e9 );
356
357 // Some canvases to check fits
358 gErrorIgnoreLevel = kError;
359 std::vector<std::vector<std::unique_ptr<TCanvas>>> canv;
360 canv.resize( set->GetNumberOfCDDetectors() );
361
362 // Loop over detectors
363 for( unsigned int i = 0; i < set->GetNumberOfCDDetectors(); ++i ) {
364
365 canv[i].resize( set->GetNumberOfCDSectors() );
366
367 // Loop over the sectors
368 for( unsigned int j = 0; j < set->GetNumberOfCDSectors(); ++j ) {
369
370 std::string cname = "cdcal_p_" + std::to_string(i) + "_" + std::to_string(j);
371 canv[i][j] = std::make_unique<TCanvas>( cname.data(), cname.data(), 800, 1000 );
372
373 // Loop over all the strips
374 for( unsigned int k = 0; k < set->GetNumberOfCDPStrips(); ++k ) {
375
376 // Get the right histogram to do the fit
377 auto res = cd_nQ_pQ[i][j][k]->Fit( pfit.get(), "QWL" );
378 if( res != 0 ) continue;
379 double fit_gain = ngain / pfit->GetParameter(1);
380 double fit_offset = noffset - pfit->GetParameter(0) * fit_gain;
381
382 // If we have the n-side tag, set the gain and offset
383 if( k == ptag ) {
384 std::cout << "!! This is the p-side tag channel, cross-check check the parameters below !!" << std::endl;
385 pgain = fit_gain;
386 poffset = fit_offset;
387 }
388
389 // Get the output names for the calibration file
390 std::string cal_base;
391 std::string modchstr;
392 int fsfp, fmod, fch;
393 if( oldDAQ ) {
394
395 // Search for the correct ADC and channel combination
396 cal_base = "adc_";
397 if( !FindCDChannels( i, j, 0, k, fmod, fch ) )
398 continue;
399 modchstr = std::to_string(fmod) + "_" + std::to_string(fch);
400
401 } // old DAQ
402
403 else {
404
405 // Search for the correct ADC and channel combination
406 cal_base = "febex_";
407 if( !FindCDChannels( i, j, 0, k, fsfp, fmod, fch ) )
408 continue;
409 modchstr = std::to_string(fsfp) + "_" + std::to_string(fmod);
410 modchstr += "_" + std::to_string(fch);
411
412 } // new DAQ
413
414 // Add gain and offset
415 std::string gainstr = cal_base + modchstr + ".Gain: " + std::to_string( fit_gain );
416 std::string offsetstr = cal_base + modchstr + ".Offset: " + std::to_string( fit_offset );
417
418 // Write them to the file
419 std::cout << gainstr << std::endl;
420 std::cout << offsetstr << std::endl;
421 output_cal << gainstr << std::endl;
422 output_cal << offsetstr << std::endl;
423
424 // Print to a file
425 std::string pdfname = cname + ".pdf";
426 if( k == 0 && set->GetNumberOfCDPStrips() != 1 )
427 pdfname += "(";
428 else if( k > 0 && k == set->GetNumberOfCDPStrips() - 1 )
429 pdfname += ")";
430 canv[i][j]->Print( pdfname.data(), "pdf" );
431
432 } // k
433
434 } // j
435
436 } // i
437
438 // Reset warning level
439 gErrorIgnoreLevel = kInfo;
440
441 return;
442
443}
444
446
447 // Check if we have old or new DAQ
448 bool oldDAQ = false;
449 if( set->GetNumberOfCaenAdcModules() > 0 )
450 oldDAQ = true;
451
452 // Create a TF1 for the linear fit
453 auto nfit = std::make_unique<TF1>( "nfit", "[0]+[1]*x", 0, 1e9 );
454
455 // Some canvases to check fits
456 gErrorIgnoreLevel = kError;
457 std::vector<std::vector<std::unique_ptr<TCanvas>>> canv;
458 canv.resize( set->GetNumberOfCDDetectors() );
459
460 // Loop over detectors
461 for( unsigned int i = 0; i < set->GetNumberOfCDDetectors(); ++i ) {
462
463 canv[i].resize( set->GetNumberOfCDSectors() );
464
465 // Loop over the sectors
466 for( unsigned int j = 0; j < set->GetNumberOfCDSectors(); ++j ) {
467
468 std::string cname = "cdcal_n_" + std::to_string(i) + "_" + std::to_string(j);
469 canv[i][j] = std::make_unique<TCanvas>( cname.data(), cname.data(), 800, 1000 );
470
471 // Loop over all the strips
472 for( unsigned int k = 0; k < set->GetNumberOfCDNStrips(); ++k ) {
473
474 // Get the right histogram to do the fit
475 auto res = cd_pen_nQ[i][j][k]->Fit( nfit.get(), "QWL" );
476 if( res != 0 ) continue;
477 double fit_gain = 1.0 / nfit->GetParameter(1);
478 double fit_offset = -1.0 * nfit->GetParameter(0) * fit_gain;
479 //double fit_gain = 1.0;
480 //double fit_offset = 0.0;
481
482 // If we have the n-side tag, set the gain and offset
483 if( k == ntag ) {
484 ngain = fit_gain;
485 noffset = fit_offset;
486 }
487
488 // Get the output names for the calibration file
489 std::string cal_base;
490 std::string modchstr;
491 int fsfp, fmod, fch;
492 if( oldDAQ ) {
493
494 // Search for the correct ADC and channel combination
495 cal_base = "adc_";
496 if( !FindCDChannels( i, j, 1, k, fmod, fch ) )
497 continue;
498 modchstr = std::to_string(fmod) + "_" + std::to_string(fch);
499
500 } // old DAQ
501
502 else {
503
504 // Search for the correct ADC and channel combination
505 cal_base = "febex_";
506 if( !FindCDChannels( i, j, 1, k, fsfp, fmod, fch ) )
507 continue;
508 modchstr = std::to_string(fsfp) + "_" + std::to_string(fmod);
509 modchstr += "_" + std::to_string(fch);
510
511 } // new DAQ
512
513 // Add gain and offset
514 std::string gainstr = cal_base + modchstr + ".Gain: " + std::to_string( fit_gain );
515 std::string offsetstr = cal_base + modchstr + ".Offset: " + std::to_string( fit_offset );
516
517 // Write them to the file
518 std::cout << gainstr << std::endl;
519 std::cout << offsetstr << std::endl;
520 output_cal << gainstr << std::endl;
521 output_cal << offsetstr << std::endl;
522
523 // Print to a file
524 std::string pdfname = cname + ".pdf";
525 if( k == 0 && set->GetNumberOfCDNStrips() != 1 )
526 pdfname += "(";
527 else if( k > 0 && k == set->GetNumberOfCDNStrips() - 1 )
528 pdfname += ")";
529 canv[i][j]->Print( pdfname.data(), "pdf" );
530
531 } // k
532
533 } // j
534
535 } // i
536
537 // Reset warning level
538 gErrorIgnoreLevel = kInfo;
539
540 return;
541
542}
543
545
546 // Variables for the finder algorithm
547 std::vector<unsigned char> pindex;
548 std::vector<unsigned char> nindex;
549
550 // Loop over each detector and sector
551 for( unsigned int i = 0; i < set->GetNumberOfCDDetectors(); ++i ){
552
553 for( unsigned int j = 0; j < set->GetNumberOfCDSectors(); ++j ){
554
555 // Reset variables for a new detector element
556 pindex.clear();
557 nindex.clear();
558 std::vector<unsigned char>().swap(pindex);
559 std::vector<unsigned char>().swap(nindex);
560
561 // Calculate p/n side multiplicities and get indicies
562 for( unsigned int k = 0; k < cd_en_list.size(); ++k ){
563
564 // Test that we have the correct detector and quadrant
565 if( i != cd_det_list.at(k) || j != cd_sec_list.at(k) )
566 continue;
567
568 // Check max energy and push back the multiplicity
569 if( cd_side_list.at(k) == 0 )
570 pindex.push_back(k);
571
572 else if( cd_side_list.at(k) == 1 )
573 nindex.push_back(k);
574
575 } // k: all CD events
576
577 // Keep only multiplicity 1v1 events
578 if( pindex.size() != 1 || nindex.size() != 1 )
579 continue;
580
581 // Fill the hit in the right pixel
582 int pid = cd_strip_list[pindex[0]];
583 int nid = cd_strip_list[nindex[0]];
584 double pen = cd_en_list[pindex[0]];
585 double nen = cd_en_list[nindex[0]];
586 unsigned int pQ = cd_Q_list[pindex[0]];
587 unsigned int nQ = cd_Q_list[nindex[0]];
588
589 // skip events with very diiferent energies
590 if( nQ / pQ > 1.5 || pQ / nQ > 1.5 ) continue;
591
592 // For p-side tags
593 if( pid == ptag ) {
594
595 cd_pen_nQ[i][j][nid]->Fill( pen, nQ );
596
597 }
598
599 // For n-side tags
600 if( nid == ntag ) {
601
602 cd_nQ_pQ[i][j][pid]->Fill( nQ, pQ );
603
604 }
605
606 } // j
607
608 } // i
609
610
611}
612
614
616
617 if( input_tree->LoadTree(0) < 0 ){
618
619 std::cout << " CD Calibrator: nothing to do" << std::endl;
620 return 0;
621
622 }
623
624 // Get ready and go
625 Initialise();
626 n_entries = input_tree->GetEntries();
627 n_mbs_entries = mbsinfo_tree->GetEntries();
628
629 std::cout << " CD Calibrator: number of entries in input tree = ";
630 std::cout << n_entries << std::endl;
631
632 std::cout << "\tnumber of MBS Events/triggers in input tree = ";
633 std::cout << n_mbs_entries << std::endl;
634
635 // ------------------------------------------------------------------------ //
636 // Main loop over TTree to find events
637 // ------------------------------------------------------------------------ //
638 for( unsigned long i = 0; i < n_entries; ++i ) {
639
640 // First event, yes please!
641 if( i == 0 ){
642
643 input_tree->GetEntry(i);
646
647 // Try to get the MBS info event with the index
648 if( mbsinfo_tree->GetEntryWithIndex( myeventid ) < 0 &&
649 n_mbs_entries > 0 ) {
650
651 // Look for the matches MBS Info event if we didn't match automatically
652 for( unsigned long j = 0; j < n_mbs_entries; ++j ){
653
654 mbsinfo_tree->GetEntry(j);
655 if( mbs_info->GetEventID() == myeventid ) {
657 break;
658 }
659
660 // Panic if we failed!
661 if( j+1 == n_mbs_entries ) {
662 std::cerr << "Didn't find matching MBS Event IDs at start of the file: ";
663 std::cerr << myeventid << std::endl;
664 }
665
666 }
667
668 }
669
670 //std::cout << "MBS Trigger time = " << myeventtime << std::endl;
671
672 }
673
674 // Get the time of the event
675 if( set->GetMbsEventMode() ) {
676
679
680 }
681
682 else mytime = in_data->GetTime();
683
684 // check time stamp monotonically increases in time-ordered mode!
685 if( time_prev > mytime && !set->GetMbsEventMode() ) {
686
687 std::cout << "Out of order event in ";
688 std::cout << input_tree->GetName() << std::endl;
689
690 }
691
692 // check event id is increasing in MBS event ordered mode
693 if( preveventid > myeventid && set->GetMbsEventMode() ) {
694
695 std::cout << "Out of order MBS event " << myeventid;
696 std::cout << " < " << preveventid << std::endl;
697
698 }
699
700 // record time of this event
702
703 // assume this is above threshold initially
704 mythres = true;
705
706 // ------------------------------------------ //
707 // Find FEBEX data
708 // ------------------------------------------ //
709 if( in_data->IsFebex() ) {
710
711 // Get the data
713 mysfp = febex_data->GetSfp();
714 myboard = febex_data->GetBoard();
715 mych = febex_data->GetChannel();
716 mypileup = febex_data->IsPileup();
717 myclipped = febex_data->IsClipped();
718
719 // Update calibration always for CD calibrator
720 unsigned int adc_tmp_value;
721 if( cal->FebexType( mysfp, myboard, mych ) == "Qshort" )
722 adc_tmp_value = febex_data->GetQshort();
723 else if( cal->FebexType( mysfp, myboard, mych ) == "Qint" )
724 adc_tmp_value = febex_data->GetQint();
725 else adc_tmp_value = febex_data->GetQshort();
726
727 myenergy = cal->FebexEnergy( mysfp, myboard, mych, adc_tmp_value );
728
729 if( adc_tmp_value > cal->FebexThreshold( mysfp, myboard, mych ) )
730 mythres = true;
731 else mythres = false;
732
733 // Is it a particle from the CD?
734 if( set->IsCD( mysfp, myboard, mych ) && mythres ) {
735
736 // Increment counts and open the event
737 hit_ctr++;
738
739 // Clipped rejection and pileup rejection
740 if( ( !myclipped || !set->GetClippedRejection() ) &&
741 ( !mypileup || !set->GetPileupRejection() ) ) {
742
743 event_open = true;
744 cd_en_list.push_back( myenergy );
745 cd_Q_list.push_back( adc_tmp_value );
746 cd_ts_list.push_back( mytime );
747 cd_det_list.push_back( set->GetCDDetector( mysfp, myboard, mych ) );
748 cd_sec_list.push_back( set->GetCDSector( mysfp, myboard, mych ) );
749 cd_side_list.push_back( set->GetCDSide( mysfp, myboard, mych ) );
750 cd_strip_list.push_back( set->GetCDStrip( mysfp, myboard, mych ) );
751
752 }
753
754 }
755
756 }
757
758 // ------------------------------------------ //
759 // Find ADC data
760 // ------------------------------------------ //
761 if( in_data->IsAdc() ) {
762
763 // Get the data
765 myadc = adc_data->GetModule();
766 mych = adc_data->GetChannel();
767 myclipped = adc_data->IsClipped();
768
769 // Update calibration always for CD calibrator
770 unsigned int adc_tmp_value = adc_data->GetQshort();
771 myenergy = cal->AdcEnergy( myadc, mych, adc_tmp_value );
772
773 if( adc_tmp_value > cal->AdcThreshold( myadc, mych ) )
774 mythres = true;
775 else mythres = false;
776
777 // Is it a particle from the CD?
778 if( set->IsCD( myadc, mych ) && mythres ) {
779
780 // Increment counts and open the event
781 hit_ctr++;
782
783 if( !myclipped || !set->GetClippedRejection() ) {
784
785 event_open = true;
786 cd_en_list.push_back( myenergy );
787 cd_Q_list.push_back( adc_tmp_value );
788 cd_ts_list.push_back( mytime );
789 cd_det_list.push_back( set->GetCDDetector( myadc, mych ) );
790 cd_sec_list.push_back( set->GetCDSector( myadc, mych ) );
791 cd_side_list.push_back( set->GetCDSide( myadc, mych ) );
792 cd_strip_list.push_back( set->GetCDStrip( myadc, mych ) );
793
794 }
795
796 }
797
798 }
799
800 // Sort out the timing for the event window
801 // but only if it isn't an info event, i.e only for real data
802 if( !in_data->IsInfo() ) {
803
804 // if this is first datum included in Event
805 if( hit_ctr == 1 && mythres ) {
806
810
811 }
812
813 // Update min and max
814 if( mytime > time_max ) time_max = mytime;
815 else if( mytime < time_min ) time_min = mytime;
816
817 } // not info data
818
819 //------------------------------
820 // check if last datum from this event and do some cleanup
821 //------------------------------
822
823 if( input_tree->GetEntry(i+1) ) {
824
825 // Get the next MBS event ID
828
829 // If the next MBS event ID is the same, carry on
830 // If not, we have to go look for the next trigger time
831 if( myeventid != preveventid ) {
832
833 // Close the event
834 flag_close_event = true;
835
836 // And find the next MBS event ID
837 if( mbsinfo_tree->GetEntryWithIndex( myeventid ) < 0 &&
838 n_mbs_entries > 0 ) {
839
840 std::cerr << "MBS Event " << myeventid << " not found by index, looking up manually" << std::endl;
841
842 // Look for the matches MBS Info event if we didn't match automatically
843 for( unsigned long j = 0; j < n_mbs_entries; ++j ){
844
845 mbsinfo_tree->GetEntry(j);
846 if( mbs_info->GetEventID() == myeventid ) {
848 break;
849 }
850
851 // Panic if we failed!
852 if( j+1 == n_mbs_entries ) {
853 std::cerr << "Didn't find matching MBS Event IDs at start of the file: ";
854 std::cerr << myeventid << std::endl;
855 }
856 }
857
858 }
859
860 else myeventtime = mbs_info->GetTime();
861
862 }
863
864 // BELOW IS THE TIME-ORDERED METHOD!
865
866 // Get the time of the next event
867 if( set->GetMbsEventMode() ) {
868
871
872 }
873
874 else mytime = in_data->GetTime();
875
876 // Calculate time diff
878
879 // window = time_stamp_first + time_window
880 if( time_diff > build_window )
881 flag_close_event = true; // set flag to close this event
882
883 // we've gone on to the next file in the chain
884 else if( time_diff < 0 )
885 flag_close_event = true; // set flag to close this event
886
887 } // if next entry beyond time window: close event!
888
889
890 //----------------------------
891 // if close this event or last entry
892 //----------------------------
893 if( flag_close_event || (i+1) == n_entries ) {
894
895 //--------------------------------------------------
896 // clear values of arrays to store intermediate info
897 //--------------------------------------------------
899 Initialise();
900
901 } // if close event && hit_ctr > 0
902
903 // Progress bar
904 bool update_progress = false;
905 if( n_entries < 200 )
906 update_progress = true;
907 else if( i % (n_entries/100) == 0 || i+1 == n_entries )
908 update_progress = true;
909
910 if( update_progress ) {
911
912 // Percent complete
913 float percent = (float)(i+1)*100.0/(float)n_entries;
914
915 // Progress bar in GUI
916 if( _prog_ ) {
917
918 prog->SetPosition( percent );
919 gSystem->ProcessEvents();
920
921 }
922
923 // Progress bar in terminal
924 std::cout << " " << std::setw(6) << std::setprecision(4);
925 std::cout << percent << "% \r";
926 std::cout.flush();
927
928 }
929
930 } // End of main loop over TTree to process raw FEBEX data entries (for n_entries)
931
932
933 //--------------------------
934 // Do the fitting to get calibration coefficients
935 //--------------------------
936
937 std::cout << "\n\nUsing p-side strip " << (int)ptag << " as reference for calibrating n-sides" << std::endl;
939 std::cout << "\n\nUsing n-side strip " << (int)ntag << " as reference for calibrating p-sides" << std::endl;
941
942 //--------------------------
943 // Clean up
944 //--------------------------
945
946 std::cout << "\n MiniballCDCalibrator finished..." << std::endl;
947
948 return n_entries;
949
950}
int nextPowerOf2(unsigned int n)
long long int GetTime()
unsigned long long int GetEventID()
unsigned long long myeventid
MBS event id.
unsigned long long mytime
absolute timestamp
std::shared_ptr< TGProgressBar > prog
unsigned long long time_max
void SetOutput(std::string output_file_name, bool cWrite=false)
unsigned char myboard
febex board number
bool mythres
above threshold?
unsigned long hit_ctr
unsigned char mysfp
sfp number
float myenergy
calibrated energy
unsigned long long preveventid
previous MBS event id
std::vector< unsigned int > cd_Q_list
list of CD uncalibrated energies for ParticleFinder
long myhittime
hit time with respect to event time
unsigned long long time_first
std::vector< std::vector< std::vector< TH2F * > > > cd_pen_nQ
std::ofstream output_cal
MBSInfoPackets * mbs_info
unsigned char myadc
ADC module number.
std::shared_ptr< FebexData > febex_data
bool FindCDChannels(int det, int sec, int side, int strip, int &adc, int &ch)
std::vector< unsigned char > cd_side_list
list of CD side IDs; 0 = p, 1 = n
unsigned long long time_prev
bool mypileup
pileup flag?
MiniballCDCalibrator(std::shared_ptr< MiniballSettings > myset)
unsigned long n_entries
unsigned long FillHists()
unsigned char mych
channel number
void Initialise()
called for every event
std::vector< std::vector< std::vector< TH2F * > > > cd_nQ_pQ
std::shared_ptr< MiniballCalibration > cal
std::vector< unsigned char > cd_det_list
list of CD detector IDs
void SetInputFile(std::vector< std::string > input_file_names)
unsigned long n_mbs_entries
std::vector< float > cd_en_list
list of CD energies for ParticleFinder
std::vector< unsigned char > cd_strip_list
list of CD strip IDs
std::vector< unsigned char > cd_sec_list
list of CD sector IDs
void SetInputTree(TTree *user_tree)
bool myclipped
clipped flag?
void StartFile()
called for every file
unsigned long long myeventtime
MBS event time.
std::vector< unsigned long long > cd_ts_list
list of CD timestamps for ParticleFinder
std::shared_ptr< MiniballSettings > set
MiniballDataPackets * in_data
void SetMBSInfoTree(TTree *user_tree)
std::shared_ptr< AdcData > adc_data
unsigned long long time_min
TFile * output_file
Outputs.
TFile * input_file
Input tree.
bool flag_close_event
length of build window in ns
unsigned long long int GetEventID() const
bool IsInfo() const
std::shared_ptr< FebexData > GetFebexData() const
bool IsFebex() const
std::shared_ptr< AdcData > GetAdcData() const
long long int GetTime() const
std::shared_ptr< MiniballSettings > myset
Definition mb_sort.cc:137