46                                 {
   50 
   51  string inputLigier;
   52  string ligierFireDrill;
   53  string inputFileName;
   54  string outputLigier;
   55  JTag outputTag, tagFireDrill;
 
   56  string outputFileName;
   57  int nEntries;
   58  size_t nBufferedTimeslices;
   60 
   61  string detectorFile;
   62  string domDetectorFile;
   63 
   65  int numberOfTimeouts = 1e3; 
   66  int queueLength = 100; 
   67  int windowLength = 5; 
   68 
   69  int TMax_ns = 10; 
   70  int preTriggerThreshold = 4; 
   72  double TVeto_ns = 1000; 
   75 
   76  string summaryFile = ""; 
   77  int statPrintInterval_s = 30; 
   78 
   79  try {
   80 
   82    string properties_description = "\n";
   83 
   85 
   87    properties_description.append("\ttimeout_us: timeout for input [us]\n");
   89    properties_description.append("\tnumberOfTimeouts: number of timeouts before stop\n");
   91    properties_description.append("\tqueueLength: number of timeslices of trigger queue\n");
   93    properties_description.append("\twindowLength: number of timeslices of trigger sliding window\n");
   94 
   96    properties_description.append("\tTMax_ns: coincidence time window [ns]\n");
   98    properties_description.append("\tpreTriggerThreshold: muon veto multiplicity threshold\n");
  100    properties_description.append("\ttotSelector_ns: hit selector\n");
  102    properties_description.append("\tTVeto_ns: muon veto time interval [ns]\n");
  104    properties_description.append("\tM: multiplicity range for SN coincidence level\n");
  106    properties_description.append("\tM_BDT: multiplicity range for SN coincidence level (with BDT)\n");
  107 
  109    properties_description.append("\tsummaryFile: summary output file\n");
  111    properties_description.append("\tstatPrintInterval_s: statistics & file print interval [s]");
  112 
  113    JParser<> zap(
"Supernova realtime processor");
 
  114 
  115    zap[
'H'] = 
make_field(inputLigier, 
"Input Ligier server") = 
"";
 
  116    zap[
'l'] = 
make_field(ligierFireDrill, 
"Ligier server for the fire drill") = 
"";
 
  117    zap[
'g'] = 
make_field(tagFireDrill, 
"Ligier tag for the fire drill") = 
JTag(
"FDRILL");
 
  119    zap[
'L'] = 
make_field(outputLigier, 
"Output Ligier server") = 
"";
 
  120    zap[
'T'] = 
make_field(outputTag, 
"Output tag for the json messages") = 
JTag();
 
  121    zap[
'o'] = 
make_field(outputFileName, 
"Output json file name (no output to Ligier)") = 
"";
 
  122    zap[
'n'] = 
make_field(nEntries, 
"Number of entries to write") = -1;
 
  123    zap[
'N'] = 
make_field(nBufferedTimeslices, 
"Maximum number of timeslices to save in DOM ID map") = 200;
 
  128 
  129    zap(argc, argv);
  130 
  131  }
  132 
  133  catch(const exception &error) {
  134    FATAL(error.what() << endl);
 
  135  }
  136 
  137  if (queueLength <= windowLength) {
  138    FATAL(
"Length of the trigger window must be smaller than the queue.");
 
  139  }
  140 
  141 
  143 
  145 
  146  
  147  
  148  
  149 
  152 
  153  try {
  155  }
  158  }
  159 
  160  try {
  161    load(domDetectorFile, domDetector);
 
  162  }
  165  }
  166 
  168 
  170 
  172 
  173  const int detectorSize = 
detector.size();
 
  174 
  176 
  177  
  178  
  179  
  180 
  182 
  183  typedef priority_queue<trigger_type, vector<trigger_type>, greater<trigger_type> > queue_type;
  184 
  185  typedef deque<trigger_type> window_type;
  186 
  187 
  188 
  192 
  193  queue_type  trgQueue;
  194  window_type trgWindow;
  195  rates_type  rates;
  196  npmt_type   pmts;
  197  veto_type   veto;
  199 
  201 
  202  long int counter_live_ts = 0;
  203  long int counter_lost_ts = 0;
  204 
  206 
  207  
  209  int nWrittenEntries = 0;
  210  if (outputFileName != ""){
  212  }
  213 
  214  
  215  
  216  
  217 
  218  try {
  219 
  220    
  221 
  225 
  229 
  230    if (inputFileName != "") {
  234 
  235    }
  236    else if (inputLigier != "") {
  238 
  239      
  240      
  241      const double asyncTimeout_us = 1000.0;
  242 
  245    }
  246    else { 
FATAL(
"Need either a root file or a ligier as input!" << endl); }
 
  247 
  249    if (outputLigier != "") {
  251    }
  252 
  254 
  255    if (ligierFireDrill != "") {
  258 
  259      fireDrill.MyId("JGetMessage");
  260      fireDrill.Subscribe(buffer);
  261      fireDrill.SendMeAlways();
  262    }
  263 
  265    if (outputFileName != "") {
  267    }
  268 
  269    
  270 
  271    int RUN = 0;
  272    int timesliceSize = 0;
  273 
  274    
  275    int startedFireDrill = false;
  278    ifstream fireDrillData;
  279    int fireDrillTimeslice = 0;
  280    double fireDrillOffsetTime, timeFireDrill, MultFireDrill, RFireDrill, CThetaFireDrill, TotalToTFireDrill, DeltaTFireDrill;
  281    int timeSinceLastFireDrill = 10000;
  282 
  283    for (int i = 0; i != numberOfTimeouts; ) {
  284 
  286 
  288 
  289        DEBUG(timeslice->getDAQHeader() << endl);
 
  290        timesliceSize = timeslice->size();
  291 
  292        
  293        
  294        
  295 
  296        const int r = timeslice->getRunNumber();
  297 
  298        if (r != RUN) {
  299 
  300          if (RUN != 0) {
  301 
  302            NOTICE(
"RUN CHANGE" << endl);
 
  303 
  304            while (trgQueue.size() > 0) { trgQueue.pop(); }
  305 
  306            trgWindow.clear();
  307 
  308            rates.clear();
  309 
  310            pmts.clear();
  311 
  312            veto.clear();
  313 
  314            doms.clear();
  315 
  316          }
  317 
  318          RUN = r;
  319 
  320        }
  321 
  322        
  323        
  324        
  325 
  327 
  329 
  331 
  333 
  334          for (JDAQSummaryslice::const_iterator summary_frame = summary->begin();
  335               summary_frame != summary->end();
  336               ++summary_frame) {
  337 
  338            int DOMID = summary_frame->getModuleID();
  339 
  341              rates[frame_index][DOMID] += summary_frame->getRate(ipmt, 1.0/1000);
  342            }
  343 
  344            doms[frame_index].push_back(DOMID);
  345 
  346            
  347            if (doms.size() > nBufferedTimeslices){
  348              doms.erase(doms.begin()->first);
  349            }
  350 
  351            pmts[frame_index] += summary_frame->countActiveChannels();
  352          }
  353 
  354        }
  355 
  357 
  359 
  360          DEBUG(
"EVT " << event->getDAQHeader() << endl);
 
  361 
  362          int frame_index = event->getFrameIndex();
  363 
  364          veto[frame_index].push_back(
JVeto(*event, hitRouter));
 
  365 
  366        }
  367 
  368        
  369        
  370        
  371 
  372        JDataSN preTrigger(TMax_ns, preTriggerThreshold);
 
  373 
  374        preTrigger(timeslice, moduleRouter, totSelector_ns, domDetector);
  375 
  377 
  379 
  381        trigger_final.frameIndex = 
trigger.frameIndex;
 
  382        trigger_final.timeUTC = 
trigger.timeUTC;
 
  383 
  384        
  385        
  386        
  387 
  388        if (!startedFireDrill){
  389 
  390          timeSinceLastFireDrill += 0.1;
  391 
  392          
  393          int drill = fireDrill.CheckHead(prefix);
  394          if (drill){
  395            fireDrillFile.resize(prefix.
getSize());
 
  396            fireDrill.GetFullData(fireDrillFile.data(), fireDrillFile.size());
  397          }
  398 
  399          
  400          
  401          if (fireDrillFile.size()>0 && timeSinceLastFireDrill > 100) { 
  402            startedFireDrill = true;
  403            fireDrillOffsetTime = 0.05; 
  404            fireDrillTimeslice = 0;
  405            string fireDrillFileName(fireDrillFile.begin()+1, fireDrillFile.end()-1); 
  406            fireDrillData.open(fireDrillFileName.c_str());
  407            timeFireDrill = -100;
  408          } else {
  410          }
  411        } 
  412 
  413        
  414        if (startedFireDrill) {
  415 
  416          double tmin = 0.1*fireDrillTimeslice;
  417          double tmax = tmin + 0.1;
  418 
  419          if (fireDrillTimeslice == 0) { 
  420            fireDrillData >> timeFireDrill >> MultFireDrill >> CThetaFireDrill >> RFireDrill >> TotalToTFireDrill >> DeltaTFireDrill; 
  421            timeFireDrill += fireDrillOffsetTime;
  422          }
  423 
  424          
  426          double event_time = (sn_it==
trigger.end()) ? 100 : sn_it->getPeak().time/1.0e9; 
 
  427 
  428          
  429          while (fireDrillData && timeFireDrill < tmax) {
  430 
  431            
  432            while(event_time < timeFireDrill-tmin && sn_it != 
trigger.end()) {
 
  433              trigger_final.push_back(*sn_it);
  434              sn_it++;
  435              if (sn_it != 
trigger.end()) event_time = sn_it->getPeak().time/1.0e9;
 
  436            }
  437 
  438            if (sn_it > 
trigger.begin() && event_time > timeFireDrill-tmin) sn_it -= 1; 
 
  439 
  440            
  441            if (timeFireDrill >= tmin && timeFireDrill < tmax) {
  442 
  443              
  444              int frame_number = timeslice->getFrameIndex();
  445              int dom_id = doms[frame_number][(int) 
getRandom(0,(
int)doms[frame_number].size())];
 
  446              
  447              JCoincidenceSN sn((timeFireDrill-tmin)*1e9, (
int) MultFireDrill, 
dom_id, 0, CThetaFireDrill, RFireDrill, DeltaTFireDrill, TotalToTFireDrill, -1, 
true);
 
  449              sncluster.push_back(sn); 
  450              trigger_final.push_back(sncluster); 
  451 
  452            }
  453 
  454            
  455            fireDrillData >> timeFireDrill >> MultFireDrill >> CThetaFireDrill >> RFireDrill >> TotalToTFireDrill >> DeltaTFireDrill; 
  456            timeFireDrill += fireDrillOffsetTime;
  457 
  458          }
  459 
  460          
  461          while(sn_it != 
trigger.end()) {
 
  462            trigger_final.push_back(*sn_it);
  463            sn_it++;
  464          }
  465 
  466          fireDrillTimeslice++; 
  467 
  468          
  469          if (!fireDrillData){
  470            startedFireDrill = false;
  471            fireDrillFile.clear();
  472            timeSinceLastFireDrill = 0;
  473            fireDrillData.close();
  474          }
  475        
  476        }
  477 
  478        trgQueue.push(trigger_final);
  479 
  480        
  481        
  482        
  483 
  484        if ( trgQueue.size() >= (unsigned) queueLength ) {
  485 
  486          while ( trgWindow.size() <= (unsigned) windowLength ) {
  487 
  488            trigger_type pending = trgQueue.top();
  489 
  490            if ( trgWindow.size() == 0 || pending > trgWindow.back() ) {
  491 
  492              trgWindow.push_back( pending );
  493 
  494              counter_live_ts++;
  495 
  496            }
  497            else {
  498              
  499              counter_lost_ts++;
  500            }
  501 
  502            trgQueue.pop();
  503 
  504          }
  505        }
  506        else {
  507          NOTICE(
"Filling trigger queue: " << trgQueue.size() << 
"/" << queueLength << 
'\r');
 
  508        }
  509      }
  510 
  511      else if ( inputFileName != "" ) {
  512        
  513        
  514        if ( trgQueue.size() > 0 ) {
  515          while ( trgQueue.size() > 0 ) {
  516            trgWindow.push_back(trgQueue.top());
  517            trgQueue.pop();
  518          }
  519        }
  520        else if ( trgWindow.size() < (unsigned) windowLength ) {
  521          i = numberOfTimeouts;
  522        }
  523      }
  524      else {
  525        NOTICE(
"timeout " << setw(3) << i << endl);
 
  526 
  527        ++i;
  528      }
  529 
  530      if (trgWindow.size() >= (unsigned) windowLength) {
  531 
  532        
  533 
  536 
  537        int trg_cc_counts   = 0;
  538        int trg_cc_modules  = 0;
  540 
  541        int trg_ev_counts   = 0;
  542        int trg_ev_modules  = 0;
  544 
  545        
  546 
  549 
  550        int trg_cc_counts_nofakes   = 0;
  551        int trg_cc_modules_nofakes  = 0;
  553 
  554        int trg_ev_counts_nofakes   = 0;
  555        int trg_ev_modules_nofakes  = 0;
  557 
  558        
  559        for (int its = 0; its < windowLength; its++) {
  560 
  561          const int frame_index = trgWindow[its].frameIndex;
  562 
  564          if (veto.count(frame_index)) {
  565            vetoSet = veto.at(frame_index);
  566          }
  567 
  570 
  571          set<int> cc_vec = trgWindow[its].getModules(F_M1);
 
  572          set<int> ev_vec = trgWindow[its].getModules(F_MV);
 
  573 
  574          
  577 
  578          for (auto &trg: trgWindow[its]){
  579            if (F_M1(trg)){
  580              if (!trg.getPeak().fake) trg_cc_counts_nofakes++;
  581              for (auto &snc: trg){
  582                if (!snc.fake){
  583                  cc_vec_nofakes.insert(snc.moduleID);
  584                }
  585              }
  586            }
  587            if (F_MV(trg)){
  588              if (!trg.getPeak().fake) trg_ev_counts_nofakes++;
  589              for (auto &snc: trg){
  590                if (!snc.fake){
  591                  ev_vec_nofakes.insert(snc.moduleID);
  592                }
  593              }
  594            }
  595          }
  596 
  597          cc_modules.insert(cc_vec.begin(), cc_vec.end());
  598          ev_modules.insert(ev_vec.begin(), ev_vec.end());
  599 
  600          cc_modules_nofakes.insert(cc_vec_nofakes.begin(), cc_vec_nofakes.end());
  601          ev_modules_nofakes.insert(ev_vec_nofakes.begin(), ev_vec_nofakes.end());
  602 
  603          trg_cc_counts += count_if(trgWindow[its].begin(), trgWindow[its].end(), F_M1);
  604          trg_ev_counts += count_if(trgWindow[its].begin(), trgWindow[its].end(), F_MV);
  605 
  606          
  607          for (auto &trg: trgWindow[its]){
  608            auto sn_candidate = trg.getPeak();
  609            if (F_MV_BDT(sn_candidate)){
  610              multiplicities.push_back(sn_candidate.multiplicity);
  611              observables.push_back(sn_candidate.total_ToT);
  612              observables.push_back(sn_candidate.deltaT);
  613              observables.push_back(sn_candidate.mean_dir_norm);
  614              observables.push_back(sn_candidate.mean_dir_ctheta);
  615 
  616              if (!sn_candidate.fake){
  617                multiplicities_nofakes.push_back(sn_candidate.multiplicity);
  618                observables_nofakes.push_back(sn_candidate.total_ToT);
  619                observables_nofakes.push_back(sn_candidate.deltaT);
  620                observables_nofakes.push_back(sn_candidate.mean_dir_norm);
  621                observables_nofakes.push_back(sn_candidate.mean_dir_ctheta);
  622              }
  623            }
  624          }
  625        }
  626 
  627        trg_cc_modules = cc_modules.size();
  628        trg_ev_modules = ev_modules.size();
  629 
  630        trg_cc_modules_nofakes = cc_modules_nofakes.size();
  631        trg_ev_modules_nofakes = ev_modules_nofakes.size();
  632 
  633        
  634 
  635        int currentFrame             = trgWindow[0].frameIndex;
  637 
  638        trgWindow.pop_front();
  639 
  640        
  641 
  642        ++stats[trg_cc_counts];
  643 
  644        
  645 
  646        int    activeModules =  -1;
  647        double detectorRate  = 0.0;
  648 
  649        if (!rates.empty()          &&
  650            rates.count(currentFrame)) {
  651 
  652          activeModules = 0;
  653 
  655               p != rates.at(currentFrame).end(); p++ ) {
  656 
  657            detectorRate  += p->second;
  658 
  659            activeModules += (p->second > 0);
  660 
  661          }
  662        } else {
  663 
  664          activeModules = timesliceSize;
  665 
  666        }
  667 
  668        
  669 
  671        string daq_time = 
to_string(currentTime);
 
  672 
  673        
  687 
  688        string msg = jd.dump();
  689 
  691 
  692        
  693        
  694        string msg2 = "";
  695        if (multiplicities.size() != multiplicities_nofakes.size()){
  709 
  710          msg2 = jd.dump();
  711 
  713        }
  714 
  715        if (outputFileName != ""){
  716          if (nWrittenEntries < nEntries || nEntries == -1) {
  717            
  719            nWrittenEntries++;
  720          }
  721          else {
  722            
  724            break;
  725          }
  726        }
  727        else {
  728          
  729 
  730          if (out != NULL) {
  733          }
  734        }
  735 
  736        
  737 
  738        if ( (counter_live_ts % ((int)(statPrintInterval_s / frameTime_s)) == 0 ) ) {
  739 
  740          double livetime = counter_live_ts * frameTime_s;
 
  741 
  743 
  746          NOTICE(
"=> discarded out-of-order timeslices = " << counter_lost_ts << endl);
 
  747 
  748          if (summaryFile != "") {
  749            ofstream of(summaryFile.c_str());
  750            of << stats.toSummaryFile();
  751            of.close();
  752          }
  753 
  754        }
  755      }
  756    }
  757  }
  758 
  761  }
  762 
  763  if (outputFileName != 
"") { 
outputFile.close(); }
 
  764 
  765}
#define DEBUG(A)
Message macros.
 
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
 
#define gmake_property(A)
macros to convert (template) parameter to JPropertiesElement object
 
static const std::string active_pmts_name
 
static const std::string cc_name
 
static const std::string daq_time_name
 
static const std::string detid_name
 
static const std::string c_name
 
static const std::string m_name
 
static const std::string run_number_name
 
static const std::string observables_name
 
static const std::string detector_rate_name
 
static const std::string ev_name
 
static const std::string trigger_name
 
static const std::string active_doms_name
 
static const std::string frame_index_name
 
static const std::string multiplicities_name
 
Simple wrapper around JModuleRouter class for direct addressing of PMT data in detector data structur...
 
Router for direct addressing of module data in detector data structure.
 
Utility class to parse parameter values.
 
void setEndOfLine(const std::string &eol)
Set end of line characters.
 
virtual const char * what() const override
Get error message.
 
Interface of object iteration for a single data type.
 
virtual bool hasNext()=0
Check availability of next element.
 
virtual const pointer_type & next()=0
Get next element.
 
Auxiliary class for time values.
 
Object iteration through ControlHost.
 
int PutFullString(const JTag &tag, const std::string &buffer)
Send string.
 
int getSize() const
Get size.
 
JSubscriptionList & add(const JSubscription &subscription)
Add subscription.
 
Utility class to parse command line options.
 
Auxiliary class to manage a cluster of coincidences.
 
Auxiliary class to store reduced information of a coincidence on an optical module This class allows ...
 
Auxiliary class to build the supernova trigger dataset.
 
SN filter based on veto window.
 
SN filter based on multiplicity selection optional suppression of multi-module coincidences WARNING: ...
 
SN trigger statistics, the information is stored in the form of a count as a function of the trigger ...
 
Auxiliary class to apply the supernova trigger to SN data.
 
Auxiliary class to manage a set of vetoes.
 
Auxiliary class to define a veto time window on a set of optical modules.
 
Template definition for direct access of elements in ROOT TChain.
 
int getFrameIndex() const
Get frame index.
 
Data structure for UTC time.
 
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
 
std::string to_string(const T &value)
Convert value to string.
 
T getRandom()
Get random value.
 
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
 
std::vector< event_type > data_type
 
KM3NeT DAQ data structures and auxiliaries.
 
double getFrameTime()
Get frame time duration.
 
void setDAQLongprint(const bool option)
Set DAQ print option.
 
static const int NUMBER_OF_PMTS
Total number of PMTs in module.
 
Normalisation of MUPAGE events.
 
Data structure for measured coincidence rates of all pairs of PMTs in optical module.
 
Auxiliary class for all subscription.
 
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
 
Auxiliary class to select DAQ hits based on time-over-treshold value.
 
Timeslice data structure for SN data.