165{
169
173 string detectorFile;
174 Double_t TMax_ns;
176 array <double, 3> totRange_ns;
179 double deadTime_us;
181 string background;
184
185 try {
186
187 JParser<> zap(
"Auxiliary program to determine PMT parameters from K40 data.");
188
189 zap[
'f'] =
make_field(inputFile,
"input file.");
192 zap[
'a'] =
make_field(detectorFile,
"detector file.");
193 zap[
'T'] =
make_field(TMax_ns,
"time window [ns].") = 20.0;
195 zap[
't'] =
make_field(totRange_ns,
"PMT time-over-threshold range [ns].") = { 4.0, 7.0, ToTmax_ns };
196 zap[
'b'] =
make_field(background,
"background estimation method.") = rates_t, count_t, tails_t, rndms_t;
199 zap[
'D'] =
make_field(deadTime_us,
"L1 dead time (us)") = 0.0;
203
204 zap(argc, argv);
205 }
206 catch(const exception &error) {
207 FATAL(error.what() << endl);
208 }
209
210
211
212
213
214
215 if (selector == JDAQTimesliceL2::Class_Name() ||
216 selector == JDAQTimesliceSN::Class_Name()) {
217 FATAL(
"Option -C <selector> " << selector <<
" not compatible with calibration method." << endl);
218 }
219
220 if (selector == JDAQTimeslice ::Class_Name() ||
221 selector == JDAQTimesliceL1::Class_Name()) {
222
224
225 try {
227 }
229 FATAL(
"No trigger parameters from input:" << error.
what() << endl);
230 }
231
232 if ((selector == JDAQTimeslice ::Class_Name() && parameters.writeL1.prescale > 0) ||
233 (selector == JDAQTimesliceL1::Class_Name())) {
234
235 if (parameters.TMaxLocal_ns < TMax_ns) {
236 FATAL(
"Option -T <TMax_ns> = " << TMax_ns <<
" is larger than in the trigger " << parameters.TMaxLocal_ns << endl);
237 }
238
239 if (background == rndms_t ||
240 background == count_t) {
241 FATAL(
"Option -C <selector> " << selector <<
" incompatible with option -b <background> " << background << endl);
242 }
243 }
244 }
245
247 FATAL(
"Invalid option -M <multiplicity> " << multiplicity << endl);
248 }
249
250 if (totRange_ns[0] > totRange_ns[1] ||
251 totRange_ns[1] > totRange_ns[2]) {
252 FATAL(
"Invalid option -t <totRange_ns> " <<
JEEPZ() << totRange_ns << endl);
253 }
254
255 if (background == tails_t) {
256
258 FATAL(
"Invalid option -B <Tail_ns> " << Tail_ns << endl);
259 }
260
262 FATAL(
"Invalid option -B <Tail_ns> " << Tail_ns <<
"; upper limit larger than option -T <TMax_ns> " << TMax_ns << endl);
263 }
264 }
265
266
267
268
269
271
272 try {
274 }
277 }
278
280 FATAL(
"Empty detector." << endl);
281 }
282
284
285
286
287
288
290
292 t0.push_back(i * 2 * TMax_ns);
293 }
294
295
296
297
298
300
301 const int NPE = 1;
303 /
305
306
307
308
309
310
312
313 const Double_t ymin = -floor(TMax_ns) + 0.5;
314 const Double_t ymax = +floor(TMax_ns) - 0.5;
315 const Int_t ny = (Int_t) ((ymax - ymin) / 1.0);
316
317 for (JDetector::iterator module =
detector.begin(); module !=
detector.end(); ++module) {
318
319 const JModuleAddress& address = router.getAddress(module->getID());
320
321 if (!module->empty()) {
322
323 NOTICE(
"Booking histograms for module " << module->getID() << endl);
324
326 }
327 }
328
329
333
335
336 const double deadTime_ns = deadTime_us * 1e3;
337
338
340
342
344
345 for (JMultipleFileScanner_t::const_iterator i = inputFile.begin(); i != inputFile.end(); ++i) {
346
347 STATUS(
"Processing: " << *i << endl);
348
350
353
354 for (
JDAQHeader header; in.hasNext() && counter != numberOfEvents; ++counter) {
355
356 STATUS(
"event: " << setw(10) << counter <<
'\r');
DEBUG(endl);
357
359
362
364
366 }
367
368 if (background == rates_t) {
369
371
373
374 ERROR(
"Frame indices do not match at "
375 << "[counter = " << counter << "]"
377 << "[summaryslice = " << summary.getFrameIndex() << "]" << endl);
378
379 continue;
380 }
381 }
382
383 for (JDAQTimeslice::const_iterator frame = timeslice->begin(); frame != timeslice->end(); ++frame) {
384
385 if (router.hasModule(frame->getModuleID())) {
386
387 const JModule& module = router.getModule(frame->getModuleID());
388
389
390
391
392
395
396 if (background == count_t) {
397
400 }
401
402 } else if (background == tails_t) {
403
404
405
406
407 } else if (background == rndms_t) {
408
409
410
411 } else if (background == rates_t) {
412
413 if (summary.hasSummaryFrame(frame->getModuleID())) {
414
415 const JDAQSummaryFrame& sum = summary.getSummaryFrame(frame->getModuleID());
416
418 rate_Hz[i] = sum.
getRate(i) * RTU;
419 }
420
421 } else {
422
423 FATAL(
"Summary frame of module " << frame->getModuleID() <<
" not found at frame index " << timeslice->
getFrameIndex() << endl);
424 }
425 }
426
428
429
430
431
435 !rateRange_Hz(rate_Hz[i])) {
436 veto[i] = true;
437 }
438 }
439
440 const JHistogram& histogram = zmap[router.getAddress(frame->getModuleID()).first];
441 const JCombinatorics& combinatorics = histogram.getCombinatorics();
442
443 TH2D* h2s = histogram.h2s;
444 TH1D* h1b = histogram.h1b;
445 TH1D* h1L = histogram.h1L;
446
447
448
449
450
451 JSuperFrame2D_t& buffer = JSuperFrame2D_t::demultiplex(*frame, module);
452
453 buffer.preprocess(option, match);
454
455 for (JSuperFrame2D_t::iterator i = buffer.begin(); i != buffer.end(); ++i) {
456 if (veto[i->getPMTAddress()]) {
457 i->reset();
458 }
459 }
460
461 JSuperFrame1D_t&
data = JSuperFrame1D_t::multiplex(buffer);
462
464
465 size_t ns = 0;
466
467 for (JSuperFrame2D_t::iterator i = buffer.begin(); i != buffer.end(); ++i) {
468 ns += i->size();
469 }
470
471 cout << "Module: "
472 << setw(10) << frame->getModuleID() << ' '
474 << setw(4) << frame->size() << ' '
475 << setw(4) << ns << ' '
476 << setw(4) <<
data.size() << endl;
477 }
478
479
480
481
482 size_t numberOfSignalEvents = 0;
483
484 double t1 = numeric_limits<double>::lowest();
485
486 for (vector<hit_type>::const_iterator p =
data.begin(); p !=
data.end(); ) {
487
488 vector<hit_type>::const_iterator q = p;
489
490 while (++q !=
data.end() && q->getT() - p->getT() <= TMax_ns) {}
491
493
494 if (multiplicity(N)) {
495
496 numberOfSignalEvents += 1;
497
498 if (p->getT() > t1 + deadTime_ns) {
499
500 for (vector<hit_type>::const_iterator __p = p; __p != q; ++__p) {
501 for (vector<hit_type>::const_iterator __q = __p; ++__q != q; ) {
502
503 if ((__p->getToT() >= totRange_ns[0]) &&
504 (__q->getToT() >= totRange_ns[0]) &&
505 (__p->getToT() >= totRange_ns[1] ||
506 __q->getToT() >= totRange_ns[1]) &&
507 (__p->getToT() <= totRange_ns[2]) &&
508 (__q->getToT() <= totRange_ns[2])) {
509
510 h2s->Fill((
double) combinatorics.
getIndex(__p->getPMT(),__q->getPMT()),
512 }
513 }
514 }
515
516 t1 = p->getT();
517 }
518 }
519
520 p = q;
521 }
522
523
524
525
526 if (background == rndms_t) {
527
529 *i =
hit_type(i->getPMT(),
JHit(i->getT() + t0[i->getPMT()], i->getToT()));
530 }
531
533
534 double t1 = numeric_limits<double>::lowest();
535
536 for (vector<hit_type>::const_iterator p =
data.begin(); p !=
data.end(); ) {
537
538 vector<hit_type>::const_iterator q = p;
539
540 while (++q !=
data.end() && q->getT() - p->getT() <= TMax_ns) {}
541
543
544 if (multiplicity(N)) {
545
546 if (p->getT() > t1 + deadTime_ns) {
547
548 for (vector<hit_type>::const_iterator __p = p; __p != q; ++__p) {
549 for (vector<hit_type>::const_iterator __q = __p; ++__q != q; ) {
550
551 if ((__p->getToT() >= totRange_ns[0]) &&
552 (__q->getToT() >= totRange_ns[0]) &&
553 (__p->getToT() >= totRange_ns[1] ||
554 __q->getToT() >= totRange_ns[1]) &&
555 (__p->getToT() <= totRange_ns[2]) &&
556 (__q->getToT() <= totRange_ns[2])) {
557
558 h1b->Fill((
double) combinatorics.
getIndex(p->getPMT(),q->getPMT()), 1.0);
559 }
560 }
561 }
562
563 t1 = p->getT();
564 }
565 }
566
567 p = q;
568 }
569
570 } else if (background == rates_t ||
571 background == count_t) {
572
573 double Rs = 0.0;
574
576 if (!veto[i]) {
577 Rs += rate_Hz[i];
578 }
579 }
580
583
584 if (!veto[i] && !veto[
j]) {
585
586 const double R1 = rate_Hz[i];
587 const double R2 = rate_Hz[
j];
588
589
590
591
592
593
594 const double N =
getP((
R1) * 2 * TMax_ns * 1e-9,
595 (R2) * 2 * TMax_ns * 1e-9,
596 (Rs -
R1 - R2) * 2 * TMax_ns * 1e-9,
599
600 h1b->Fill((
double) combinatorics.
getIndex(i,
j), N);
601 }
602 }
603 }
604 }
605
606
607
608
609
611
613
614 const int pmt1 = combinatorics.
getPair(i).first;
615 const int pmt2 = combinatorics.
getPair(i).second;
616
617 if (!veto[pmt1] && !veto[pmt2]) {
618 h1L->Fill(i, livetime_s);
619 }
620 }
621 }
622 }
623 }
624 }
626
627 if (background == tails_t) {
628
629 const double R = (2.0*TMax_ns) / ((ymax - ymin)/ny);
630
632
633 if (hr->is_valid()) {
634
635 TH2D* h2s = hr->h2s;
636 TH1D* h1b = hr->h1b;
637
638 for (int ix = 1; ix <= h1b->GetXaxis()->GetNbins(); ++ix) {
639
640 double Y = 0.0;
641 double W = 0.0;
642 int N = 0;
643
644 for (int iy = 1; iy <= h2s->GetYaxis()->GetNbins(); ++iy) {
645
646 const double y = h2s->GetYaxis()->GetBinCenter(iy) ;
647
648 if (Tail_ns(fabs(y))) {
649 Y += h2s->GetBinContent(ix,iy);
650 W += h2s->GetBinError (ix,iy) * h2s->GetBinError(ix,iy);
651 N += 1;
652 }
653 }
654
655 h1b->SetBinContent(ix, Y/N * R);
656 h1b->SetBinError (ix, sqrt(W/N) * R);
657 }
658 }
659 }
660 }
661
662
663
664
665
667
669 weights_hist.GetXaxis()->SetBinLabel(2,
WS_t);
670 weights_hist.GetXaxis()->SetBinLabel(3,
WB_t);
671
673 weights_hist.Fill(
WS_t, (ymax - ymin)/ny);
674 weights_hist.Fill(
WB_t, 2.0*TMax_ns);
675
676 out << weights_hist;
677
679 if (i->is_valid()) {
680 out << *(i->h2s);
681 out << *(i->h1b);
682 out << *(i->h1L);
683 }
684 }
685
686 out.Write();
687 out.Close();
688}
#define DEBUG(A)
Message macros.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Address of module in detector data structure.
int first
index of module in detector data structure
Router for direct addressing of module data in detector data structure.
Data structure for a composite optical module.
virtual const char * what() const override
Get error message.
Auxiliary class for multiplexing object iterators.
Utility class to parse command line options.
Object reading from a list of files.
File router for fast addressing of summary data.
Reduced data structure for L0 hit.
1-dimensional frame with time calibrated data from one optical module.
2-dimensional frame with time calibrated data from one optical module.
int getDetectorID() const
Get detector identifier.
int getRunNumber() const
Get run number.
int getFrameIndex() const
Get frame index.
const JDAQFrameStatus & getDAQFrameStatus() const
Get DAQ frame status.
Data storage class for rate measurements of all PMTs in one module.
double getRate(const int tdc, const double factor=1.0) const
Get count rate.
static const char *const WB_t
Named bin for value of TMax_ns in JCalibrateK40.
double getP(const double E1, const double E2, const double ED, const int M_min, const int M_max)
Get coincidence probability of two PMTs within one module due to random background.
static const char *const weights_hist_t
Histogram naming.
static const char *const WS_t
Named bin for time residual bin width.
static const char *const W1_overall_t
Named bin for duration of the run.
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
bool putObject(TDirectory &dir, const TObject &object)
Write object to ROOT directory.
std::set< JROOTClassSelector > getROOTClassSelection(const bool option=false)
Get ROOT class selection.
Long64_t counter_type
Type definition for counter.
JTriggerParameters getTriggerParameters(const JMultipleFileScanner_t &file_list)
Get trigger parameters.
bool getDAQStatus(const JDAQFrameStatus &frame, const JStatus &status)
Test status of DAQ.
bool getPMTStatus(const JStatus &status)
Test status of PMT.
KM3NeT DAQ data structures and auxiliaries.
double getFrameTime()
Get frame time duration.
static const int NUMBER_OF_PMTS
Total number of PMTs in module.
Transmission with position.
PMT analogue signal processor.
virtual double getNPE(const double tot_ns) const override
Get number of photo-electrons.
double getIntegralOfChargeProbability(const double xmin, const double xmax, const int NPE) const
Get integral of probability.
Auxiliary data structure for streaming of STL containers.
Auxiliary class to select ROOT class based on class name.
static counter_type max()
Get maximum counter value.
Auxiliary base class for list of file names.
Auxiliary class for specifying the way of pre-processing of hits.
static std::vector< JPreprocessor > getOptions()
Get options.
@ filter_t
filter consecutive hits according match criterion