202{
  206 
  210  string             detectorFile;
  211  Double_t           TMax_ns;
  213  array <double, 3>  totRange_ns;
  216  double             deadTime_us;
  218  string             background;
  221    
  222  try { 
  223 
  224    JParser<> zap(
"Auxiliary program to determine PMT parameters from K40 data.");
 
  225    
  226    zap[
'f'] = 
make_field(inputFile,      
"input file.");
 
  229    zap[
'a'] = 
make_field(detectorFile,   
"detector file.");
 
  230    zap[
'T'] = 
make_field(TMax_ns,        
"time window [ns].")                           = 20.0;
 
  232    zap[
't'] = 
make_field(totRange_ns,    
"PMT time-over-threshold range [ns].")         = { 4.0, 7.0, ToTmax_ns };
 
  233    zap[
'b'] = 
make_field(background,     
"background estimation method.")               = rates_t, count_t, tails_t, rndms_t;
 
  236    zap[
'D'] = 
make_field(deadTime_us,    
"L1 dead time (us)")                           = 0.0;
 
  240     
  241    zap(argc, argv);
  242  }
  243  catch(const exception &error) {
  244    FATAL(error.what() << endl);
 
  245  }
  246 
  247  
  248  
  249  
  250 
  251 
  252  if (selector == JDAQTimesliceL2::Class_Name() ||
  253      selector == JDAQTimesliceSN::Class_Name()) {
  254    FATAL(
"Option -C <selector> " << selector << 
" not compatible with calibration method." << endl);
 
  255  }
  256 
  257  if (selector == JDAQTimeslice  ::Class_Name() ||
  258      selector == JDAQTimesliceL1::Class_Name()) {
  259  
  261 
  262    try {
  264    }
  266      FATAL(
"No trigger parameters from input:" << error.
what() << endl);
 
  267    }
  268 
  269    if ((selector == JDAQTimeslice  ::Class_Name() && parameters.writeL1.prescale > 0) ||
  270        (selector == JDAQTimesliceL1::Class_Name())) {
  271 
  272      if (parameters.TMaxLocal_ns < TMax_ns) {
  273        FATAL(
"Option -T <TMax_ns> = " << TMax_ns << 
" is larger than in the trigger " << parameters.TMaxLocal_ns << endl);
 
  274      }
  275 
  276      if (background == rndms_t ||
  277          background == count_t) {
  278        FATAL(
"Option -C <selector> " << selector << 
" incompatible with option -b <background> " << background << endl);
 
  279      }
  280    }
  281  }
  282 
  284    FATAL(
"Invalid option -M <multiplicity> " << multiplicity << endl);
 
  285  }
  286 
  287  if (totRange_ns[0] > totRange_ns[1] ||
  288      totRange_ns[1] > totRange_ns[2]) {
  289    FATAL(
"Invalid option -t <totRange_ns> " << 
JEEPZ() << totRange_ns << endl);
 
  290  }
  291 
  292  if (background == tails_t) {
  293 
  295      FATAL(
"Invalid option -B <Tail_ns> " << Tail_ns << endl);
 
  296    }
  297 
  299      FATAL(
"Invalid option -B <Tail_ns> " << Tail_ns << 
"; upper limit larger than option -T <TMax_ns> " << TMax_ns << endl);
 
  300    }
  301  }
  302 
  303  
  304  
  305  
  306 
  308 
  309  try {
  311  }
  314  }
  315 
  317    FATAL(
"Empty detector." << endl);
 
  318  }
  319 
  321 
  322  
  323  
  324  
  325 
  327 
  329    t0.push_back(i * 2 * TMax_ns);
  330  }
  331 
  332  
  333  
  334  
  335 
  337  
  338  const int    NPE = 1;
  340                      /
  342  
  343 
  344  
  345  
  346  
  347 
  349 
  350  const Double_t ymin = -floor(TMax_ns) + 0.5;
  351  const Double_t ymax = +floor(TMax_ns) - 0.5;
  352  const Int_t    ny   = (Int_t) ((ymax - ymin) / 1.0);
  353 
  354  for (JDetector::iterator module = 
detector.begin(); module != 
detector.end(); ++module) {
 
  355  
  356    const JModuleAddress& address = router.getAddress(module->getID());
 
  357 
  358    if (!module->empty()) {
  359 
  360      NOTICE(
"Booking histograms for module " << module->getID() << endl);
 
  361 
  363    }
  364  }
  365 
  366 
  370 
  372 
  373  const double deadTime_ns  =  deadTime_us * 1e3;
  374 
  375 
  377 
  379 
  381 
  382  for (JMultipleFileScanner_t::const_iterator i = inputFile.begin(); i != inputFile.end(); ++i) {
  383 
  384    STATUS(
"Processing: " << *i << endl);
 
  385 
  387 
  390 
  391    for (
JDAQHeader header; in.hasNext() && counter != numberOfEvents; ++counter) {
 
  392 
  393      STATUS(
"event: " << setw(10) << counter << 
'\r'); 
DEBUG(endl);
 
  394 
  396 
  399 
  401 
  403      }
  404 
  405      if (background == rates_t) {
  406 
  408 
  409        if (timeslice->
getFrameIndex() != summary.getSummaryslice()->getFrameIndex()) {
 
  410 
  411          ERROR(
"Frame indices do not match at "  
  412                << "[counter = "      << counter                                    << "]" 
  414                << "[summaryslice = " << summary.getSummaryslice()->getFrameIndex() << "]" << endl);
  415 
  416          continue;
  417        }
  418      }
  419 
  420      for (JDAQTimeslice::const_iterator frame = timeslice->begin(); frame != timeslice->end(); ++frame) {
  421 
  422        if (router.hasModule(frame->getModuleID())) {
  423 
  424          const JModule& module = router.getModule(frame->getModuleID());
 
  425 
  426          
  427          
  428          
  429 
  432 
  433          if        (background == count_t) {
  434 
  437            }
  438 
  439          } else if (background == tails_t) {
  440 
  441            
  442 
  443          } else if (background == rndms_t) {
  444 
  445            
  446 
  447          } else if (background == rates_t) {
  448 
  449            if (summary.hasSummaryFrame(frame->getModuleID())) {
  450 
  451              const JDAQSummaryFrame& sum = summary.getSummaryFrame(frame->getModuleID());
 
  452 
  454                rate_Hz[i] = sum.
getRate (i) *RTU;
 
  456              }
  457 
  458            } else {
  459 
  460              FATAL(
"Summary frame of module " << frame->getModuleID() << 
" not found at frame index " << timeslice->
getFrameIndex() << endl);
 
  461            }
  462          }
  463 
  465        
  466          
  467          
  468 
  472                !rateRange_Hz(rate_Hz[i])) {
  473              veto[i] = true;
  474            }
  475          }
  476 
  477          const JHistogram&     histogram     = zmap[router.getAddress(frame->getModuleID()).first];
  478          const JCombinatorics& combinatorics = histogram.getCombinatorics();
 
  479 
  480          TH2D* h2s = histogram.h2s;
  481          TH1D* h1b = histogram.h1b;
  482          TH1D* h1L = histogram.h1L;
  483 
  484          
  485          
  486          
  487 
  488          JSuperFrame2D_t& buffer = JSuperFrame2D_t::demultiplex(*frame, module);
  489 
  490          buffer.preprocess(option, match);
  491 
  492          for (JSuperFrame2D_t::iterator i = buffer.begin(); i != buffer.end(); ++i) {
  493            if (veto[i->getPMTAddress()]) {
  494              i->reset();
  495            }
  496          }
  497 
  498          JSuperFrame1D_t& 
data = JSuperFrame1D_t::multiplex(buffer);
 
  499 
  500          DEBUG(
"Number of hits " << timeslice->
getFrameIndex() << 
":" << frame->getModuleID() << 
' ' << frame->size() << 
' ' << 
data.size() << endl);
 
  501 
  502          
  503          
  504 
  505          size_t numberOfSignalEvents = 0;
  506 
  507          double t1 = numeric_limits<double>::lowest();
  508          
  509          for (vector<hit_type>::const_iterator p = 
data.begin(); p != 
data.end(); ) {
 
  510            
  511            vector<hit_type>::const_iterator q = p;
  512            
  513            while (++q != 
data.end() && q->getT() - p->getT() <= TMax_ns) {}
 
  514 
  516 
  517            if (multiplicity(N)) {
  518            
  519              numberOfSignalEvents += 1;
  520 
  521              if (p->getT() > t1 + deadTime_ns) {
  522            
  523                for (vector<hit_type>::const_iterator __p = p; __p != q; ++__p) {
  524                  for (vector<hit_type>::const_iterator __q = __p; ++__q != q; ) {
  525 
  526                    if ((__p->getToT() >= totRange_ns[0])    &&
  527                        (__q->getToT() >= totRange_ns[0])    &&
  528                        (__p->getToT() >= totRange_ns[1] ||
  529                         __q->getToT() >= totRange_ns[1])    &&
  530                        (__p->getToT() <= totRange_ns[2])    &&
  531                        (__q->getToT() <= totRange_ns[2])) {
  532 
  533                      h2s->Fill((
double) combinatorics.
getIndex(__p->getPMT(),__q->getPMT()), 
 
  535                    }
  536                  }
  537                }
  538 
  539                t1 = p->getT();
  540              }
  541            }
  542 
  543            p = q;
  544          }
  545 
  546          
  547          
  548 
  549          if        (background == rndms_t) {
  550 
  552              *i = 
hit_type(i->getPMT(), 
JHit(i->getT() + t0[i->getPMT()], i->getToT()));
 
  553            }
  554            
  556 
  557            double t1 = numeric_limits<double>::lowest();
  558 
  559            for (vector<hit_type>::const_iterator p = 
data.begin(); p != 
data.end(); ) {
 
  560            
  561              vector<hit_type>::const_iterator q = p;
  562               
  563              while (++q != 
data.end() && q->getT() - p->getT() <= TMax_ns) {}
 
  564 
  566 
  567              if (multiplicity(N)) {
  568 
  569                if (p->getT() > t1 + deadTime_ns) {
  570 
  571                  for (vector<hit_type>::const_iterator __p = p; __p != q; ++__p) {
  572                    for (vector<hit_type>::const_iterator __q = __p; ++__q != q; ) {
  573                  
  574                      if ((__p->getToT() >= totRange_ns[0])    &&
  575                          (__q->getToT() >= totRange_ns[0])    &&
  576                          (__p->getToT() >= totRange_ns[1] ||
  577                           __q->getToT() >= totRange_ns[1])    &&
  578                          (__p->getToT() <= totRange_ns[2])    &&
  579                          (__q->getToT() <= totRange_ns[2])) {
  580 
  581                        h1b->Fill((
double) combinatorics.
getIndex(p->getPMT(),q->getPMT()), 1.0);
 
  582                      }
  583                    }
  584                  }
  585 
  586                  t1 = p->getT();
  587                }
  588              }
  589 
  590              p = q;
  591            }
  592 
  593          } else if (background == rates_t ||
  594                     background == count_t) {
  595 
  596            double Rs = 0.0;                                       
  597            
  599              if (!veto[i]) {
  600                Rs += rate_Hz[i];                                  
  601              }
  602            }
  603            
  606                
  607                if (!veto[i] && !veto[
j]) {
 
  608 
  609                  const double R1 = rate_Hz[i];                    
 
  610                  const double R2 = rate_Hz[
j];                    
 
  611 
  612                  
  613                  
  614                  
  615                  
  616 
  617                  const double N = 
getP((
R1)           * 2 * TMax_ns * 1e-9,
 
  618                                        (R2)           * 2 * TMax_ns * 1e-9,
  619                                        (Rs - 
R1 - R2) * 2 * TMax_ns * 1e-9,
 
  622 
  623                  h1b->Fill((
double) combinatorics.
getIndex(i,
j), N);
 
  624                }
  625              }
  626            }
  627          }
  628 
  629          
  630          
  631          
  632        
  634 
  636 
  637            const int pmt1 = combinatorics.
getPair(i).first;
 
  638            const int pmt2 = combinatorics.
getPair(i).second;
 
  639 
  640            if (!veto[pmt1] && !veto[pmt2]) {
  641              h1L->Fill(i, livetime_s);
  642            }
  643          }
  644        }
  645      }
  646    }
  647  }
  649 
  650  if (background == tails_t ) {
  651 
  652    const double R = (2.0*TMax_ns) / ((ymax - ymin)/ny);
  653 
  655 
  656      if (hr->is_valid()) {
  657 
  658        TH2D* h2s = hr->h2s;
  659        TH1D* h1b = hr->h1b;
  660 
  661        for (int ix = 1; ix <= h1b->GetXaxis()->GetNbins(); ++ix) {
  662 
  663          double Y = 0.0;                          
  664          double W = 0.0;                          
  665          int    N = 0;                            
  666 
  667          for (int iy = 1; iy <= h2s->GetYaxis()->GetNbins(); ++iy) {
  668 
  669            const double y = h2s->GetYaxis()->GetBinCenter(iy) ;
 
  670 
  671            if (Tail_ns(fabs(y))) { 
  672              Y += h2s->GetBinContent(ix,iy);
  673              W += h2s->GetBinError  (ix,iy) * h2s->GetBinError(ix,iy);
  674              N += 1;
  675            }
  676          }
  677 
  678          h1b->SetBinContent(ix,      Y/N  * R);
  679          h1b->SetBinError  (ix, sqrt(W/N) * R);
  680        }
  681      }
  682    }
  683  }
  684 
  685  
  686  
  687  
  688 
  690 
  692  weights_hist.GetXaxis()->SetBinLabel(2, 
WS_t);                 
 
  693  weights_hist.GetXaxis()->SetBinLabel(3, 
WB_t);                 
 
  694 
  696  weights_hist.Fill(
WS_t,         (ymax - ymin)/ny);             
 
  697  weights_hist.Fill(
WB_t,         2.0*TMax_ns);                  
 
  698 
  699  out << weights_hist;
  700 
  702    if (i->is_valid()) {
  703      out << *(i->h2s);
  704      out << *(i->h1b);
  705      out << *(i->h1L);
  706    }
  707  }
  708 
  709  out.Write();
  710  out.Close();
  711}
#define DEBUG(A)
Message macros.
 
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
 
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
 
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.
 
JRate_t getValue(const int tdc) const
Get value.
 
static const char *const WB_t
Named bin for value of TMax_ns in JCalibrateK40.
 
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.
 
double getP(const double expval, bool hit)
Get Poisson probability to observe a hit or not for given expectation value for the number of hits.
 
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.
 
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