53{
   57  
   58  
   59  
   60  
   61  
   63  JLimit_t& numberOfEvents =          inputFile.getLimit();
 
   65  string             detectorFile;
   66  Double_t           TMax_ns;
   71  int                filterLevel;
   72  int                muteChannel;
   73  bool               twoDim;
   74  bool               monitorOccupancy;
   75  bool               notJoin;
   76 
   77  try { 
   78 
   79    JParser<> zap(
"Auxiliary program to estimate PMT and hit multiplicities.");
 
   80    
   91    zap[
'F'] = 
make_field(filterLevel, 
"0 = raw data; 1 = filtered data; 2+ = only clean frames") = 1;
 
   92    zap[
'D'] = 
make_field(twoDim, 
"2D mode for background subtraction");
 
   93    zap[
'O'] = 
make_field(monitorOccupancy, 
"produces 2D PMT vs multiplicity plots");
 
   94    zap[
'j'] = 
make_field(notJoin, 
"do not join consecutive hits on same PMT (diagnostic purpose)");
 
   95 
   96    zap(argc, argv);
   97  }
   98  catch(const exception &error) {
   99    FATAL(error.what() << endl);
 
  100  }
  101 
  102  
  103  
  104  
  105  
  106 
  108  bool hasTriggerParameters = true;
  109 
  110  try {
  112    NOTICE(
"Get trigger parameters from input." << endl);
 
  113  }
  115    ERROR(
"No trigger parameters from input." << endl);
 
  116    hasTriggerParameters = false;
  117 
  118  }
  119 
  120  
  121  int prescale = 1;
  122 
  123  if (hasTriggerParameters) {
  124 
  125    
  126    
  127    if (parameters.writeL1.prescale > 0  && (selector == "JDAQTimeslice" || selector == "JDAQTimesliceL1") &&
  128        parameters.TMaxLocal_ns < TMax_ns) {
  129      FATAL(
"TMax_ns (-T) " << TMax_ns << 
" ns is larger than in the trigger " << parameters.TMaxLocal_ns << 
" ns." << endl);
 
  130    }
  131    
  132    if (selector == "JDAQTimeslice") {
  133      
  134      prescale = (parameters.writeL1.prescale != 0) ? parameters.writeL1.prescale : parameters.writeL0.prescale;
  135    }
  136 
  137    if (selector == "JDAQTimesliceL0") {
  138      prescale = parameters.writeL0.prescale;
  139    }
  140 
  141    if (selector == "JDAQTimesliceL1") {
  142      prescale = parameters.writeL1.prescale;
  143    }
  144    
  145    if (selector == "JDAQTimesliceSN") {
  146      prescale = parameters.writeSN.prescale;
  147    }
  148 
  149  }
  150 
  151  if (prescale == 0) { 
  152    FATAL(
"[R] According to trigger parameters, the " << selector << 
" stream should be empty.");
 
  153  } else {
  154    NOTICE(
"[R] Prescale factor is " << prescale << endl);
 
  155  }
  156 
  158    FATAL(
"Invalid time over threshold " << totVeto_ns   << endl); 
 
  159  }
  160    
  161  
  162  
  163  
  164  
  166 
  167  try {
  169  }
  172  }
  173 
  175    FATAL(
"Empty detector." << endl);
 
  176 
  179  
  181 
  183 
  185 
  186 
  187  
  188  
  189  
  190  
  192  NOTICE(
"[R] Tmax       [ns] "       << TMax_ns               << endl);
 
  193  NOTICE(
"[R] Rate range [Hz] "       << rateVeto_Hz           << endl);
 
  194  NOTICE(
"[R] ToT range  [ns] "       << totVeto_ns            << endl);
 
  195  NOTICE(
"[R] Timeslice stream      " << selector              << endl);
 
  196  NOTICE(
"[R] Detector file has " << detSize << 
" DOMs." << endl);
 
  197  
  198  
  199  
  200  
  201 
  202  
  203  TH1D* h_livetime = new TH1D("LiveTime", "Livetime", 1 + detSize, 0.0, 1.0 + detSize); 
  204  
  205  int ibin = 1;
  206  h_livetime->GetXaxis()->SetBinLabel(ibin++, "Nominal");
  207  for (JDetector::iterator module = 
detector.begin(); module != 
detector.end(); ++module) {
 
  208    if (!module->empty()) {
  209      h_livetime->GetXaxis()->SetBinLabel(ibin++, TString(
getLabel(*module)));
 
  210    }
  211  }
  212 
  213  h_livetime->GetYaxis()->SetTitle("Livetime (s)");
  214 
  215 
  216  
  218  const double xmin = -0.5;
 
  219  const double xmax = nx - 0.5;
 
  220    
  223  JManager_t 
H(
new TH1D(
"%_H", NULL, nx, xmin, xmax)); 
H->Sumw2();
 
  224  JManager_t P(new TH1D("%_P", NULL, nx, xmin, xmax)); P->Sumw2();
  225  
  226  JManager2D_t HT(new TH2D("%_HT", NULL, nx, xmin, xmax, 100, -TMax_ns, +TMax_ns));
  227 
  228  TH2D* CO_proto = new TH2D("%_CO", NULL, NUMBER_OF_PMTS, 0.5, 0.5 + NUMBER_OF_PMTS, NUMBER_OF_PMTS, -0.5, -0.5 + NUMBER_OF_PMTS);
  229 
  230  if (monitorOccupancy) {
  233  } 
  234 
  235  JManager2D_t CO(CO_proto);
  236        
  237  
  238  const int sn_mul_min = 6;
  239  TH1D* time_distr = new TH1D("T_distr", "Coincidence (M > 6) distribution in timeslice", 100, 0, 1e8); 
  240 
  241  
  242  
  243  
  244  
  245  
  247  
  248  
  249  
  250  int count_HRV = 0; 
  251  int count_FAF = 0; 
  252  int count_URV = 0; 
  253 
  254  int treeMismatchCount = 0;
  255  
  256  
  257  
  258  
  259  
  261 
  263 
  265  
  269 
  271  
  272  
  273  bool   hasMCHeader   = true ;
  274  bool   isMupage      = false;
  275  double liveTimeMC    = 0    ;
  276  double liveTimeMCErr = 0    ;
  277  
  279  
  280  try {
  282  }
  284    hasMCHeader = false;
  285  }
  286  
  287  NOTICE(
"[R] File source is " << (hasMCHeader ? 
"MC" : 
"DAQ") << 
"." << endl);
 
  288  if (hasMCHeader) {
  291    if (liveTimeMC > 0) {
  292      isMupage = true;
  293      NOTICE(
"[R] mupage live time is (" << liveTimeMC << 
" +/- " << liveTimeMCErr << 
") s." << endl);
 
  294    } else {
  295      NOTICE(
"[R] aanet header found but mupage live time is zero. Likely not a mupage file.");
 
  296    } 
  297  }
  298 
  299  
  300 
  301  int runNumber = 0;
  302 
  303  if (summaryFile.hasNext()) { 
  304    runNumber = summaryFile.getEntry(0)->getRunNumber();
  305    NOTICE(
"[R] Processing run #" << runNumber << endl);
 
  306    summaryFile.rewind();
  307  }
  308  
  309  
  310  
  311  
  312  
  313  for ( ; in.hasNext() && counter != inputFile.getLimit(); ++counter) {
  314 
  315    STATUS(
"Entry: " << setw(10) << counter  << 
'\r');
 
  316 
  318    const Long64_t          index     = summaryFile.find(*timeslice);
  319    JDAQSummaryslice*       summary   = (index != -1 ? summaryFile.getEntry(index) : NULL);
 
  320    
  321    summaryRouter.
update(summary);
 
  322 
  323    
  324    if (summary != NULL) {
  326        ++treeMismatchCount;
  327        ERROR(
"[R>T] Frame indices do not match [counter=" << counter << 
", timeslice=" << timeslice->
getFrameIndex() << 
", summaryslice=" << summary->
getFrameIndex() << 
"]" << endl);
 
  328        if (treeMismatchCount > 1) {
  329          FATAL(
"ROOT TTrees not aligned. Run #" << runNumber << endl);
 
  330        }
  331        continue;
  332      }
  333    }
  334 
  335    
  336    
  337    
  338    for (JDAQTimeslice::const_iterator super_frame = timeslice->begin(); super_frame != timeslice->end(); ++super_frame) {
  339      
  340      
  341      
  342      
  343  
  344      int moduleID = super_frame->getModuleID();
  345 
  346      if (!router.hasModule(moduleID)) {
  347        
  348        continue;
  349      }
  350        
  352 
  353      
  354      
  355      
  356      
  359      
  360      if (summary == NULL) { 
  361        WARNING(
"[R>T>F] Missing summary for timeslice." << endl);
 
  362        
  365        }
  366        
  367        
  369        
  370      } else {
  371 
  372        
  373 
  375 
  376        if (!summaryRouter.
hasSummaryFrame(super_frame->getModuleIdentifier())) {
 
  377          summaryRouter.print(cout); 
  378          FATAL(
"[R>D>F] Summary frame not found, module = " << super_frame->getModuleID() << endl);
 
  379        } else {
  380          summary_frame = summaryRouter.
getSummaryFrame(super_frame->getModuleID());
 
  381        }
  382        
  383        
  385          rate_Hz[i] = summary_frame.
getRate(i);
 
  386        }
  387        
  388        
  390        
  391      }
  392      
  393      
  394      
  395      
  396      
  397      
  399          WARNING(
"[R>D>F] DAQ status not okay in timeslice #" << timeslice->
getFrameIndex() << 
", DOM=" << super_frame->getModuleID() << endl);
 
  400          continue;
  401      }
  402     
  404      bool moduleLiveTime = 0;
  405      
  406      
  407      for (vector<double>::const_iterator r = rate_Hz.begin(); !moduleLiveTime && r != rate_Hz.end(); ++r) {
  408        if ((*r) > 0) {
  409          moduleLiveTime = 1;
  410        } 
  411      }
  412     
  415      int frame_URV_count = 0; 
  416 
  418        if ((veto[i] = (veto[i] || !rateVeto_Hz(rate_Hz[i])))) {
  419          frame_URV_count++;
  420        }
  421      }
  422 
  423      count_HRV += frame_HRV_count;
  424      count_FAF += frame_FAF_count;
  425      count_URV += frame_URV_count;
  426 
  427      int frame_VETO_count = frame_HRV_count + frame_FAF_count + frame_URV_count;
  428 
  429      
  430      if (filterLevel >= 2 && frame_VETO_count > 0) {
  431        moduleLiveTime = 0;
  432        fill(veto.begin(), veto.end(), true);
  433      } else if (filterLevel >= 1 && frame_HRV_count + frame_FAF_count > 0) {
  436        }
  437      }
  438 
  439      
  440      
  441      if (muteChannel != -1) {
  442 
  443        
  444        int mute_VETO_count = 
  447          !rateVeto_Hz(rate_Hz[muteChannel]  );
  448        
  449        if (mute_VETO_count == frame_VETO_count) {
  450          moduleLiveTime = 1;
  451          fill(veto.begin(), veto.end(), false);
  452        }
  453        
  454        veto[muteChannel] = true;
  455        
  456      }   
  457      
  458      
  459      const JModuleAddress& address = router.getAddress(super_frame->getModuleID());
 
  461      const TString         moduleLabel   = 
getLabel(module);
 
  462 
  463      
  464      if (moduleLiveTime) {
  465        h_livetime->Fill(moduleLabel, 
getFrameTime() * 1e-9 * moduleLiveTime);
 
  466      }  
  467      
  468      
  469      
  470      
  471      
  472      JSuperFrame2D_t& buffer = JSuperFrame2D_t::demultiplex(*super_frame, router.getModule(super_frame->getModuleID())); 
  473 
  474      if (!notJoin) {
  475        for (JSuperFrame2D_t::iterator i = buffer.begin(); i != buffer.end(); ++i) {
  476          i->join(match); 
  477        }
  478      }
  479      
  480      JSuperFrame1D_t& 
data = JSuperFrame1D_t::multiplex(buffer);
 
  481 
  482      filteredData.clear();
  483      
  484      for (vector<JHitR0>::const_iterator h = 
data.begin(); h != 
data.end(); ++h) {
 
  485        
  486        const int pmt = h->getPMT();
  487 
  488        
  489        if (!veto[pmt]                && 
  490            rateVeto_Hz(rate_Hz[pmt]) &&
  491            totVeto_ns(h->getToT()) )     {
  492          filteredData.push_back(*h);
  493        } 
  494      }
  495      
  496      
  497      
  498      if (filteredData.size() > 1) {
  499 
  500        TH1D* h_hit =  
H[moduleLabel];
 
  501        TH1D* h_pmt =  P[moduleLabel];
  502        
  503        TH2D* h2_hit = HT[moduleLabel];
  504        TH2D* h2_co  = CO[moduleLabel];
  505 
  506        sort(filteredData.begin(), filteredData.end());
  507      
  508        
  509        
  510        
  511        for (vector<JHitR0>::const_iterator p = filteredData.begin(); p != filteredData.end(); ) {
  512 
  513          vector<JHitR0>::const_iterator q = p;
  514        
  515          
  516          while (++q != filteredData.end() && q->getT() - p->getT() <= TMax_ns ) {}
  517        
  518          
  519          int hit_multiplicity = 
distance(p,q);
 
  521          for (vector<JHitR0>::const_iterator __p = p ; __p != q; ++__p ) { pmthit.insert(__p->getPMT()) ; }
  522          int pmt_multiplicity = pmthit.size() ;
  523        
  524          
  525          h_pmt->Fill(pmt_multiplicity);
  526          h_hit->Fill(hit_multiplicity);
  527 
  528          if (twoDim && hit_multiplicity > 1) { 
  529            const double W = 
factorial(hit_multiplicity, 2);
 
  530            for (vector<JHitR0>::const_iterator __p = p; __p != q; ++__p) {
  531              for (vector<JHitR0>::const_iterator __q = __p; ++__q != q; ) {
  533                h2_hit->Fill(hit_multiplicity, dt, 1.0/W);
  534              }
  535            }
  536          }
  537 
  538          if (monitorOccupancy) {
  541              TString pmtLabel(pmtAddress.
toString());
 
  542              h2_co->Fill(pmt_multiplicity, pmtLabel, 1.0/pmt_multiplicity);
  543            }
  544          }
  545          
  546          
  547          if (hit_multiplicity >= sn_mul_min) {
  548            time_distr->Fill(p->getT());
  549          }
  550 
  551          p = q; 
  552 
  553        }
  554 
  555      }      
  556 
  557    }
  558    
  559  }
  560    
  561  NOTICE(
"[R] " << counter << 
" timeslices processed." << endl);
 
  562  
  563  if (isMupage) {
  564    h_livetime->Scale(liveTimeMC / (
getFrameTime() * 1e-9 * counter * prescale));
 
  565  }
  566 
  567  
  568  double nominalLiveTime = (isMupage ? liveTimeMC : counter * 
getFrameTime() * 1e-9) / prescale;
 
  569  h_livetime->Fill("Nominal", nominalLiveTime);
  570  
  571  out.cd();
  572  
  573  int nLiveDOMs = 
H.size();
 
  574  
  575  h_livetime->Write();
  576  
  577  
  578  
  579 
  580  P.Write(out);
  581  
  582  if (twoDim) {
  583    HT.Write(out);
  584  }
  585 
  586  if (monitorOccupancy) {
  587    CO.Write(out);
  588  }
  589 
  590  time_distr->Write();
  591 
  592  double rate_HRV = count_HRV / (1.0 * counter);
  593  double rate_FAF = count_FAF / (1.0 * counter);
  594  double rate_URV = count_URV / (1.0 * counter);
  595  double biolumIndex = (rate_HRV + rate_FAF) / (nLiveDOMs * NUMBER_OF_PMTS);
  596  NOTICE(
"[R] Average HRV count per timeslice: " << rate_HRV << endl);
 
  597  NOTICE(
"[R] Average FIFO-almost-full count per timeslice: " << rate_FAF << endl);
 
  598  NOTICE(
"[R] Average user rate veto count per timeslice: " << rate_URV << endl);
 
  599  NOTICE(
"[R] " << 
H.size() << 
" DOMs were active in the run." << endl);
 
  600  NOTICE(
"[R] Bioluminescence proxy index: " << biolumIndex << endl);
 
  601 
  603  
  604  out.Close();
  605 
  607  
  608  return (counter ? 0 : 1);
  609 
  610}
#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.
 
JAANET::livetime livetime
 
Lookup table for PMT addresses in detector.
 
const JModuleAddressMap & get(const int id) const
Get module address map.
 
virtual const JModuleAddressMap & getDefaultModuleAddressMap() const =0
Get default module address map.
 
Lookup table for PMT addresses in optical module.
 
const JPMTAddressTranslator & getAddressTranslator(const int tdc) const
Get PMT address translator.
 
Address of module in detector data structure.
 
Router for direct addressing of module data in detector data structure.
 
Data structure for a composite optical module.
 
Data structure for PMT physical address.
 
std::string toString() const
Convert PMT physical address to string.
 
Auxiliary class for multiplexing object iterators.
 
Utility class to parse command line options.
 
Auxiliary class to manage set of compatible ROOT objects (e.g. histograms) using unique keys.
 
General purpose class for object reading from a list of file names.
 
Router for fast addressing of summary data in KM3NETDAQ::JDAQSummaryslice data structure as a functio...
 
bool hasSummaryFrame(const JDAQModuleIdentifier &module) const
Has summary frame.
 
const JDAQSummaryFrame & getSummaryFrame(const JDAQModuleIdentifier &module) const
Get summary frame.
 
void update(const JDAQSummaryslice *ps)
Update router.
 
Template definition for direct access of elements in ROOT TChain.
 
1-dimensional frame with time calibrated data from one optical module.
 
2-dimensional frame with time calibrated data from one optical module.
 
int getFrameIndex() const
Get frame index.
 
bool testFIFOStatus() const
Test FIFO status.
 
int countHighRateVeto() const
Count high-rate veto status.
 
const JDAQFrameStatus & getDAQFrameStatus() const
Get DAQ frame status.
 
int countFIFOStatus() const
Count FIFO status.
 
bool testHighRateVeto() const
Test high-rate veto status.
 
bool testDAQStatus() const
Test DAQ status of packets.
 
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.
 
std::string getLabel(const JLocation &location)
Get module label for monitoring and other applications.
 
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
 
JDetectorAddressMap & getDetectorAddressMap()
Get detector address map.
 
void setAxisLabels(TAxis *axis, const JModuleAddressMap &memo)
Set axis with PMT address labels.
 
long long int factorial(const long long int n)
Determine factorial.
 
static const double H
Planck constant [eV s].
 
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.
 
Head getHeader(const JMultipleFileScanner_t &file_list)
Get Monte Carlo header.
 
static const JModuleCounter getNumberOfModules
Function object to count unique modules.
 
KM3NeT DAQ data structures and auxiliaries.
 
double getFrameTime()
Get frame time duration.
 
static const int NUMBER_OF_PMTS
Total number of PMTs in module.
 
double numberOfSeconds
Live time [s].
 
double errorOfSeconds
Uncertainty on live time [s].
 
Auxiliary class to select ROOT class based on class name.
 
Auxiliary class for defining the range of iterations of objects.
 
static counter_type max()
Get maximum counter value.