46int main(
int argc,
char* argv[]) {
52 string ligierFireDrill;
55 JTag outputTag, tagFireDrill;
56 string outputFileName;
58 size_t nBufferedTimeslices;
62 string domDetectorFile;
65 int numberOfTimeouts = 1e3;
66 int queueLength = 100;
70 int preTriggerThreshold = 4;
72 double TVeto_ns = 1000;
76 string summaryFile =
"";
77 int statPrintInterval_s = 30;
82 string properties_description =
"\n";
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");
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");
109 properties_description.append(
"\tsummaryFile: summary output file\n");
111 properties_description.append(
"\tstatPrintInterval_s: statistics & file print interval [s]");
113 JParser<> zap(
"Supernova realtime processor");
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;
133 catch(
const exception &error) {
134 FATAL(error.what() << endl);
137 if (queueLength <= windowLength) {
138 FATAL(
"Length of the trigger window must be smaller than the queue.");
161 load(domDetectorFile, domDetector);
173 const int detectorSize =
detector.size();
183 typedef priority_queue<trigger_type, vector<trigger_type>, greater<trigger_type> > queue_type;
185 typedef deque<trigger_type> window_type;
194 window_type trgWindow;
202 long int counter_live_ts = 0;
203 long int counter_lost_ts = 0;
209 int nWrittenEntries = 0;
210 if (outputFileName !=
""){
230 if (inputFileName !=
"") {
236 else if (inputLigier !=
"") {
241 const double asyncTimeout_us = 1000.0;
246 else {
FATAL(
"Need either a root file or a ligier as input!" << endl); }
249 if (outputLigier !=
"") {
255 if (ligierFireDrill !=
"") {
259 fireDrill.
MyId(
"JGetMessage");
265 if (outputFileName !=
"") {
272 int timesliceSize = 0;
275 int startedFireDrill =
false;
278 ifstream fireDrillData;
279 int fireDrillTimeslice = 0;
280 double fireDrillOffsetTime, timeFireDrill, MultFireDrill, RFireDrill, CThetaFireDrill, TotalToTFireDrill, DeltaTFireDrill;
281 int timeSinceLastFireDrill = 10000;
283 for (
int i = 0; i != numberOfTimeouts; ) {
289 DEBUG(timeslice->getDAQHeader() << endl);
290 timesliceSize = timeslice->size();
296 const int r = timeslice->getRunNumber();
302 NOTICE(
"RUN CHANGE" << endl);
304 while (trgQueue.size() > 0) { trgQueue.pop(); }
334 for (JDAQSummaryslice::const_iterator summary_frame = summary->begin();
335 summary_frame != summary->end();
338 int DOMID = summary_frame->getModuleID();
341 rates[frame_index][DOMID] += summary_frame->getRate(ipmt, 1.0/1000);
344 doms[frame_index].push_back(DOMID);
347 if (doms.size() > nBufferedTimeslices){
348 doms.erase(doms.begin()->first);
351 pmts[frame_index] += summary_frame->countActiveChannels();
360 DEBUG(
"EVT " << event->getDAQHeader() << endl);
362 int frame_index =
event->getFrameIndex();
364 veto[frame_index].push_back(
JVeto(*event, hitRouter));
372 JDataSN preTrigger(TMax_ns, preTriggerThreshold);
374 preTrigger(timeslice, moduleRouter, totSelector_ns, domDetector);
388 if (!startedFireDrill){
390 timeSinceLastFireDrill += 0.1;
395 fireDrillFile.resize(prefix.
getSize());
396 fireDrill.
GetFullData(fireDrillFile.data(), fireDrillFile.size());
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;
414 if (startedFireDrill) {
416 double tmin = 0.1*fireDrillTimeslice;
417 double tmax = tmin + 0.1;
419 if (fireDrillTimeslice == 0) {
420 fireDrillData >> timeFireDrill >> MultFireDrill >> CThetaFireDrill >> RFireDrill >> TotalToTFireDrill >> DeltaTFireDrill;
421 timeFireDrill += fireDrillOffsetTime;
426 double event_time = (sn_it==
trigger.end()) ? 100 : sn_it->getPeak().time/1.0e9;
429 while (fireDrillData && timeFireDrill < tmax) {
432 while(event_time < timeFireDrill-tmin && sn_it !=
trigger.end()) {
433 trigger_final.push_back(*sn_it);
435 if (sn_it !=
trigger.end()) event_time = sn_it->getPeak().time/1.0e9;
438 if (sn_it >
trigger.begin() && event_time > timeFireDrill-tmin) sn_it -= 1;
441 if (timeFireDrill >= tmin && timeFireDrill < tmax) {
444 int frame_number = timeslice->getFrameIndex();
445 int dom_id = doms[frame_number][(int)
getRandom(0,(
int)doms[frame_number].size())];
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);
455 fireDrillData >> timeFireDrill >> MultFireDrill >> CThetaFireDrill >> RFireDrill >> TotalToTFireDrill >> DeltaTFireDrill;
456 timeFireDrill += fireDrillOffsetTime;
461 while(sn_it !=
trigger.end()) {
462 trigger_final.push_back(*sn_it);
466 fireDrillTimeslice++;
470 startedFireDrill =
false;
471 fireDrillFile.clear();
472 timeSinceLastFireDrill = 0;
473 fireDrillData.close();
478 trgQueue.push(trigger_final);
484 if ( trgQueue.size() >= (
unsigned) queueLength ) {
486 while ( trgWindow.size() <= (
unsigned) windowLength ) {
488 trigger_type pending = trgQueue.top();
490 if ( trgWindow.size() == 0 || pending > trgWindow.back() ) {
492 trgWindow.push_back( pending );
507 NOTICE(
"Filling trigger queue: " << trgQueue.size() <<
"/" << queueLength <<
'\r');
511 else if ( inputFileName !=
"" ) {
514 if ( trgQueue.size() > 0 ) {
515 while ( trgQueue.size() > 0 ) {
516 trgWindow.push_back(trgQueue.top());
520 else if ( trgWindow.size() < (
unsigned) windowLength ) {
521 i = numberOfTimeouts;
525 NOTICE(
"timeout " << setw(3) << i << endl);
530 if (trgWindow.size() >= (
unsigned) windowLength) {
537 int trg_cc_counts = 0;
538 int trg_cc_modules = 0;
541 int trg_ev_counts = 0;
542 int trg_ev_modules = 0;
550 int trg_cc_counts_nofakes = 0;
551 int trg_cc_modules_nofakes = 0;
554 int trg_ev_counts_nofakes = 0;
555 int trg_ev_modules_nofakes = 0;
559 for (
int its = 0; its < windowLength; its++) {
561 const int frame_index = trgWindow[its].frameIndex;
564 if (veto.count(frame_index)) {
565 vetoSet = veto.at(frame_index);
571 set<int> cc_vec = trgWindow[its].getModules(F_M1);
572 set<int> ev_vec = trgWindow[its].getModules(F_MV);
578 for (
auto &trg: trgWindow[its]){
580 if (!trg.getPeak().fake) trg_cc_counts_nofakes++;
581 for (
auto &snc: trg){
583 cc_vec_nofakes.insert(snc.moduleID);
588 if (!trg.getPeak().fake) trg_ev_counts_nofakes++;
589 for (
auto &snc: trg){
591 ev_vec_nofakes.insert(snc.moduleID);
597 cc_modules.insert(cc_vec.begin(), cc_vec.end());
598 ev_modules.insert(ev_vec.begin(), ev_vec.end());
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());
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);
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);
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);
627 trg_cc_modules = cc_modules.size();
628 trg_ev_modules = ev_modules.size();
630 trg_cc_modules_nofakes = cc_modules_nofakes.size();
631 trg_ev_modules_nofakes = ev_modules_nofakes.size();
635 int currentFrame = trgWindow[0].frameIndex;
638 trgWindow.pop_front();
642 ++stats[trg_cc_counts];
646 int activeModules = -1;
647 double detectorRate = 0.0;
649 if (!rates.empty() &&
650 rates.count(currentFrame)) {
655 p != rates.at(currentFrame).end(); p++ ) {
657 detectorRate += p->second;
659 activeModules += (p->second > 0);
664 activeModules = timesliceSize;
671 string daq_time =
to_string(currentTime);
688 string msg = jd.dump();
695 if (multiplicities.size() != multiplicities_nofakes.size()){
715 if (outputFileName !=
""){
716 if (nWrittenEntries < nEntries || nEntries == -1) {
738 if ( (counter_live_ts % ((
int)(statPrintInterval_s / frameTime_s)) == 0 ) ) {
740 double livetime = counter_live_ts * frameTime_s;
746 NOTICE(
"=> discarded out-of-order timeslices = " << counter_lost_ts << endl);
748 if (summaryFile !=
"") {
749 ofstream of(summaryFile.c_str());
760 ERROR(error.what() << endl);
763 if (outputFileName !=
"") {
outputFile.close(); }