89{
   93 
   95  JLimit_t&          numberOfEvents = inputFile.getLimit();
 
   97  string             detectorFile;
   98  bool               overwriteDetector;
   99  double             TMaxLocal_ns;
  100  int                numberOfTimeslices;
  101  double             binWidth_ns;
  102  double             deadTime_us;
  103  double             Pmin;
  107 
  108  try { 
  109 
  110    JParser<> zap(
"Example program to search for correlations between triggered events and timeslice data.");
 
  111    
  112    zap[
'f'] = 
make_field(inputFile,           
"input file.");
 
  114    zap[
'a'] = 
make_field(detectorFile,         
"detector file.");
 
  115    zap[
'A'] = 
make_field(overwriteDetector,    
"overwrite detector file provided through '-a' with module (PMT) status.");
 
  117    zap[
'T'] = 
make_field(TMaxLocal_ns,        
"time window for local coincidences (L1),")                 = 20.0;
 
  118    zap[
'N'] = 
make_field(numberOfTimeslices,  
"time slice difference between triggered event and L1.")    = 100;
 
  119    zap[
'W'] = 
make_field(binWidth_ns,         
"bin width for output histograms." )                        = 10e3;
 
  120    zap[
'D'] = 
make_field(deadTime_us,         
"L1 dead time (us)")                                        = 200.0;
 
  121    zap[
'p'] = 
make_field(Pmin,                
"minimal probability for background to be signal.")         = 1.0e-7;
 
  125 
  126    zap(argc, argv);
  127  }
  128  catch(const exception& error) {
  129    FATAL(error.what() << endl);
 
  130  }
  131 
  132 
  134 
  135  try {
  137  }
  140  }
  141 
  143    FATAL(
"Empty detector " << detectorFile << endl);
 
  144  }
  145  
  147 
  149  const double BOOST        =  20.0;                                        
  150  const double deadTime_ns  =  deadTime_us * 1e3;
  151 
  152  NOTICE(
"Time window " << 
FIXED(7,1) << TMax_ns << 
" [ns]" << endl);
 
  153 
  155  
  158  vector  <hit_type> 
data;  
 
  159  
  161 
  162  const Double_t 
xmin = -(numberOfTimeslices + 1) * 
getFrameTime() - 0.5*binWidth_ns;
 
  163  const Double_t 
xmax = +(numberOfTimeslices + 1) * 
getFrameTime() + 0.5*binWidth_ns;
 
  164  const Int_t    nx   = (Int_t) ((xmax - xmin) / binWidth_ns);
  165  
  166  JManager_t manager(new TH1D("M_%", NULL, nx, xmin, xmax));
  167 
  169  
  171 
  173  
  174  if (selector == "") {
  175 
  181    } else {
  182      FATAL(
"No timeslice data." << endl);
 
  183    }
  184 
  185    NOTICE(
"Selected class " << ps->getClassName() << endl);
 
  186 
  187  } else {
  188 
  189    ps = zmap[selector];
  190    
  191    ps->configure(inputFile);
  192  }
  193 
  194  ps->setLimit(inputFile.getLimit());
  195 
  197 
  198  map_type buffer;
  199    
  201 
  202    if (in.getCounter()%1000 == 0) {
  203      STATUS(
"event: " << setw(10) << in.getCounter() << 
'\r'); 
DEBUG(endl);
 
  204    }
  205 
  207 
  208    
  209    
  210    double t0 = 0.0;
  211    size_t n0 = 0;
  212    
  214      if (router.hasModule(hit->getModuleID())) {
  215        t0 += 
getTime(*hit, router.getPMT(*hit));
 
  216        n0 += 1;
  217      }
  218    }
  219    
  220    t0 /= n0;
  222    
  223    buffer[event->getFrameIndex()].push_back(t0);
  224  }
  226 
  227 
  228  while (ps->hasNext()) {
  229    
  230    if (ps->getCounter()%1000 == 0) {
  231      STATUS(
"event: " << setw(10) << ps->getCounter() << 
'\r'); 
DEBUG(endl);
 
  232    }
  233 
  235 
  236    map_type::const_iterator p = buffer.lower_bound(timeslice->
getFrameIndex() - numberOfTimeslices);
 
  237    map_type::const_iterator q = buffer.upper_bound(timeslice->
getFrameIndex() + numberOfTimeslices);
 
  238 
  239    int number_of_events = 0;
  240 
  241    for (map_type::const_iterator i = p; i != q; ++i) {
  242      number_of_events += i->second.size();
  243    }
  244 
  245    if (number_of_events == 0) {
  246      continue;
  247    }
  248    
  249    for (JDAQTimeslice::const_iterator frame = timeslice->begin(); frame != timeslice->end(); ++frame) {
  250 
  251      if (router.hasModule(frame->getModuleID())) {
  252 
  254 
  255        buildL1(*frame, router.getModule(frame->getModuleID()), back_inserter(data));
  256 
  257        TH1D*  h1 = manager[frame->getModuleID()];
  258 
  259        double t1 = numeric_limits<double>::lowest();
  260 
  261        for (vector<hit_type>::const_iterator hit = 
data.begin(); hit != 
data.end(); ++hit) {
 
  262          
  263          const double t2 = *hit + frame->getFrameIndex() * 
getFrameTime();
 
  264          
  265          if (t2 > t1 + deadTime_ns) {
  266 
  267            for (map_type::const_iterator i = p; i != q; ++i) {
  268              for (map_type::mapped_type::const_iterator t0 = i->second.begin(); t0 != i->second.end(); ++t0) {
  269                h1->Fill(t2 - *t0);
  270              }
  271            }
  272 
  273            t1 = t2;
  274          }
  275        }
  276      }
  277    }
  278  }
  280 
  281 
  282  
  283 
  284  TF1 
f1(
"f1", 
"[0]*exp(-0.5*(x-[1])*(x-[1])/([2]*[2])) + [3]");
 
  285    
  286  string option = "L";
  287 
  289    option += "Q";
  290  }
  291 
  292 
  294 
  295  for (JDetector::const_iterator module = 
detector.begin(); module != 
detector.end(); ++module) {
 
  296 
  297    if (module->getFloor() != 0) {
  298 
  299      status[module->getID()] = DEFAULT;
  300    
  301      JManager_t::iterator p = manager.find(module->getID());
  302 
  303      if (p == manager.end() || p->second->GetEntries() == 0) { 
  304      
  305        status[module->getID()] = NODATA;
  306 
  307        continue;
  308      }
  309 
  310      TH1D* h1 = p->second;
  311 
  312      
  313          
  314      Double_t ymax  =   0.0;
  315      Double_t x0    =   0.0;    
  316      Double_t 
sigma = 250.0;    
 
  317      Double_t ymin  =   0.0;
  318          
  319      for (int i = 1; i != h1->GetNbinsX(); ++i) {
  320      
  321        const Double_t 
x = h1->GetBinCenter (i);
 
  322        const Double_t 
y = h1->GetBinContent(i);
 
  323          
  324        if (y > ymax) {
  327        }
  328 
  330      }
  331 
  332      ymin /= h1->GetNbinsX();
  333        
  334      f1.SetParameter(0, ymax);
 
  335      f1.SetParameter(1, x0);
 
  336      if (binWidth_ns < sigma) 
  337        f1.SetParameter(2, sigma);
 
  338      else
  339        f1.FixParameter(2, binWidth_ns/sqrt(12.0));
 
  340      f1.SetParameter(3, ymin);
 
  341          
  342      for (Int_t i = 0; i != 
f1.GetNpar(); ++i) {
 
  343        f1.SetParError(i, 0.0);
 
  344      }
  345 
  346      
  347    
  348      h1->Fit(&f1, option.c_str(), "same", x0 - 5 * sigma, x0 + 5 * sigma);
  349 
  350      if (fabs(
f1.GetParameter(1)) <= 0.5*getFrameTime() &&    
 
  351          f1.GetParameter(0)       >= 
f1.GetParameter(3)) {    
 
  352 
  353        status[module->getID()] = IN_SYNC;
  354      }
  355 
  356      double fm = fmod(
f1.GetParameter(1), getFrameTime());
 
  357 
  360 
  362             << setw(10)    << module->getID()    << ' '
  363             << 
FIXED(15,3) << 
f1.GetParameter(1) << 
' ' 
  364             << 
FIXED(12,3) << 
f1.GetParameter(0) << 
' ' 
  365             << 
FIXED(12,3) << 
f1.GetParameter(3) << 
' ' 
  366             << 
FIXED(12,3) << fm                 << 
' ' 
  367             << status[module->getID()] << endl);
  368 
  369      
  370          
  373 
  374      for (Int_t i = 1, 
ns = -(numberOfTimeslices + 1); i <= h1->GetNbinsX(); ++i) {
 
  375 
  376        const Double_t 
x = h1->GetBinCenter (i);
 
  377        const Double_t 
y = h1->GetBinContent(i);
 
  378 
  381        }
  382            
  387      }
  388 
  390        
  391        const Double_t 
y = getBackground(i->second, bg[i->first]);
 
  392        const Double_t P = TMath::PoissonI(i->second.getTotal(), y);
  393 
  394        if (
debug >= 
debug_t || status[module->getID()] != IN_SYNC) {
 
  395          cout << "Module/peak " << setw(10) << module->getID() << ' '
  396               << setw(4) << i->first << ' '
  397               << "["
  399               << ","
  401               << "]"
  402               << " S/N = " 
  403               << 
FIXED(7,1) << i->second.getTotal() << 
" / " 
  406               << (i->second.getTotal() > y && P < Pmin && i->first != 0 ? "***" : "") << endl;
  407        }
  408        
  409        if (i->second.getTotal() > y && P < Pmin)
  410          ++i;               
  411        else
  412          sn.erase(i++);     
  413      }
  414 
  415      if (!(sn.size()         == 1 && 
  416            sn.begin()->first == 0)) {
  417 
  418        status[module->getID()] = (sn.size() == 1 ? OUT_SYNC : 
ERROR);
 
  419 
  420        ERROR(
"Module/error " 
  421              << setw(10)    << module->getID()    << ' '
  422              << "number of peaks " << sn.size()   << ' '
  423              << 
"peak " << (sn.size() == 1 ? 
MAKE_CSTRING(sn.begin()->first) : 
"?") << 
' '  
  424              << status[module->getID()] << endl);
  425      }
  426    }
  427  }
  428 
  429  if (overwriteDetector) {
  430 
  432 
  434 
  435      if (i->second != IN_SYNC && 
  436          i->second != NODATA) {
  437 
  438        NOTICE(
"Module " << setw(8) << i->first << 
" set out-of-sync." << endl);
 
  439 
  441 
  442        module.getStatus().set(MODULE_OUT_OF_SYNC);
  443        
  444        for (JModule::iterator pmt = module.begin(); pmt != module.end(); ++pmt) {
  446        }
  447      }
  448    }
  449 
  451  }
  452 
  455  }
  456 
  457  int nin  = 0;
  458  int nout = 0;
  459 
  461    if (i->second == IN_SYNC) {
  462      ++nin;
  463    }
  464    if (i->second != IN_SYNC && 
  465        i->second != NODATA) {
  466      ++nout;
  467    }
  468  }
  469 
  470  NOTICE(
"Number of modules out/in sync " << nout << 
'/' << nin << endl);
 
  471 
  472  QAQC(nin << 
' ' << nout << endl);
 
  473 
  474  return 0;
  475}
#define DEBUG(A)
Message macros.
 
#define QAQC(A)
QA/QC output macro.
 
int qaqc
QA/QC file descriptor.
 
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
 
#define MAKE_CSTRING(A)
Make C-string.
 
Simple wrapper around JModuleRouter class for direct addressing of PMT data in detector data structur...
 
Data structure for a composite optical module.
 
Auxialiary class to assert type conversion.
 
The template JSinglePointer class can be used to hold a pointer to an object.
 
Utility class to parse command line options.
 
Auxiliary class to manage set of compatible ROOT objects (e.g. histograms) using unique keys.
 
Template definition for direct access of elements in ROOT TChain.
 
int getFrameIndex() const
Get frame index.
 
JTriggerCounter_t next()
Increment trigger counter.
 
const JPolynome f1(1.0, 2.0, 3.0)
Function.
 
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
 
void store(const std::string &file_name, const JDetector &detector)
Store detector to output file.
 
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
 
std::set< JROOTClassSelector > getROOTClassSelection(const bool option=false)
Get ROOT class selection.
 
const char * getTime()
Get current local time conform ISO-8601 standard.
 
KM3NeT DAQ data structures and auxiliaries.
 
double getFrameTime()
Get frame time duration.
 
double getMaximalTime(const double R_Hz)
Get maximal time for given rate.
 
std::map< int, range_type > map_type
 
static const int OUT_OF_SYNC
Enable (disable) synchronous signal from this PMT if this status bit is 0 (1);.
 
Auxiliary data structure for floating point format specification.
 
Auxiliary class for a type holder.
 
Auxiliary class to select ROOT class based on class name.
 
Auxiliary class to select JTreeScanner based on ROOT class name.
 
Auxiliary class for defining the range of iterations of objects.
 
static counter_type max()
Get maximum counter value.
 
Auxiliary data structure for L1 build parameters.
 
Auxiliary data structure for floating point format specification.