46int main(
int argc,
char* argv[]) {
52 string ligierFireDrill;
55 JTag outputTag, tagFireDrill;
56 string outputFileName;
61 string domDetectorFile;
64 int numberOfTimeouts = 1e3;
65 int queueLength = 100;
69 int preTriggerThreshold = 4;
71 double TVeto_ns = 1000;
75 string summaryFile =
"";
76 int statPrintInterval_s = 30;
81 string properties_description =
"\n";
86 properties_description.append(
"\ttimeout_us: timeout for input [us]\n");
88 properties_description.append(
"\tnumberOfTimeouts: number of timeouts before stop\n");
90 properties_description.append(
"\tqueueLength: number of timeslices of trigger queue\n");
92 properties_description.append(
"\twindowLength: number of timeslices of trigger sliding window\n");
95 properties_description.append(
"\tTMax_ns: coincidence time window [ns]\n");
97 properties_description.append(
"\tpreTriggerThreshold: muon veto multiplicity threshold\n");
99 properties_description.append(
"\ttotSelector_ns: hit selector\n");
101 properties_description.append(
"\tTVeto_ns: muon veto time interval [ns]\n");
103 properties_description.append(
"\tM: multiplicity range for SN coincidence level\n");
105 properties_description.append(
"\tM_BDT: multiplicity range for SN coincidence level (with BDT)\n");
108 properties_description.append(
"\tsummaryFile: summary output file\n");
110 properties_description.append(
"\tstatPrintInterval_s: statistics & file print interval [s]");
112 JParser<> zap(
"Supernova realtime processor");
114 zap[
'H'] =
make_field(inputLigier,
"Input Ligier server") =
"";
115 zap[
'l'] =
make_field(ligierFireDrill,
"Ligier server for the fire drill") =
"";
116 zap[
'g'] =
make_field(tagFireDrill,
"Ligier tag for the fire drill") =
JTag(
"FDRILL");
118 zap[
'L'] =
make_field(outputLigier,
"Output Ligier server") =
"";
119 zap[
'T'] =
make_field(outputTag,
"Output tag for the json messages") =
JTag();
120 zap[
'o'] =
make_field(outputFileName,
"Output json file name (no output to Ligier)") =
"";
121 zap[
'n'] =
make_field(nEntries,
"Number of entries to write") = -1;
131 catch(
const exception &error) {
132 FATAL(error.what() << endl);
135 if (queueLength <= windowLength) {
136 FATAL(
"Length of the trigger window must be smaller than the queue.");
159 load(domDetectorFile, domDetector);
171 const int detectorSize =
detector.size();
181 typedef priority_queue<trigger_type, vector<trigger_type>, greater<trigger_type> > queue_type;
183 typedef deque<trigger_type> window_type;
192 window_type trgWindow;
200 long int counter_live_ts = 0;
201 long int counter_lost_ts = 0;
207 int nWrittenEntries = 0;
208 if (outputFileName !=
""){
228 if (inputFileName !=
"") {
234 else if (inputLigier !=
"") {
239 const double asyncTimeout_us = 1000.0;
244 else {
FATAL(
"Need either a root file or a ligier as input!" << endl); }
247 if (outputLigier !=
"") {
253 if (ligierFireDrill !=
"") {
257 fireDrill.
MyId(
"JGetMessage");
263 if (outputFileName !=
"") {
270 int timesliceSize = 0;
273 int startedFireDrill =
false;
276 ifstream fireDrillData;
277 int fireDrillTimeslice = 0;
278 double fireDrillOffsetTime, timeFireDrill, MultFireDrill, RFireDrill, CThetaFireDrill, TotalToTFireDrill, DeltaTFireDrill;
279 int timeSinceLastFireDrill = 10000;
281 for (
int i = 0; i != numberOfTimeouts; ) {
287 DEBUG(timeslice->getDAQHeader() << endl);
289 timesliceSize = timeslice->size();
295 const int r = timeslice->getRunNumber();
301 NOTICE(
"RUN CHANGE" << endl);
303 while (trgQueue.size() > 0) { trgQueue.pop(); }
331 for (JDAQSummaryslice::const_iterator summary_frame = summary->begin();
332 summary_frame != summary->end();
335 int DOMID = summary_frame->getModuleID();
338 rates[frame_index][DOMID] += summary_frame->getRate(ipmt, 1.0/1000);
341 doms[frame_index].push_back(DOMID);
343 pmts[frame_index] += summary_frame->countActiveChannels();
352 DEBUG(
"EVT " << event->getDAQHeader() << endl);
354 int frame_index =
event->getFrameIndex();
356 veto[frame_index].push_back(
JVeto(*event, hitRouter));
364 JDataSN preTrigger(TMax_ns, preTriggerThreshold);
366 preTrigger(timeslice, moduleRouter, totSelector_ns, domDetector);
380 if (!startedFireDrill){
382 timeSinceLastFireDrill += 0.1;
387 fireDrillFile.resize(prefix.
getSize());
388 fireDrill.
GetFullData(fireDrillFile.data(), fireDrillFile.size());
393 if (fireDrillFile.size()>0 && timeSinceLastFireDrill > 100) {
394 startedFireDrill =
true;
395 fireDrillOffsetTime = 0.05;
396 fireDrillTimeslice = 0;
397 string fireDrillFileName(fireDrillFile.begin()+1, fireDrillFile.end()-1);
398 fireDrillData.open(fireDrillFileName.c_str());
399 timeFireDrill = -100;
406 if (startedFireDrill) {
408 double tmin = 0.1*fireDrillTimeslice;
409 double tmax = tmin + 0.1;
411 if (fireDrillTimeslice == 0) {
412 fireDrillData >> timeFireDrill >> MultFireDrill >> CThetaFireDrill >> RFireDrill >> TotalToTFireDrill >> DeltaTFireDrill;
413 timeFireDrill += fireDrillOffsetTime;
418 double event_time = (sn_it==
trigger.end()) ? 100 : sn_it->getPeak().time/1.0e9;
421 while (fireDrillData && timeFireDrill < tmax) {
424 while(event_time < timeFireDrill-tmin && sn_it !=
trigger.end()) {
425 trigger_final.push_back(*sn_it);
427 if (sn_it !=
trigger.end()) event_time = sn_it->getPeak().time/1.0e9;
430 if (sn_it >
trigger.begin() && event_time > timeFireDrill-tmin) sn_it -= 1;
433 if (timeFireDrill >= tmin && timeFireDrill < tmax) {
436 int frame_number = timeslice->getFrameIndex();
437 int dom_id = doms[frame_number][(int)
getRandom(0,(
int)doms[frame_number].size())];
439 JCoincidenceSN sn((timeFireDrill-tmin)*1e9, (
int) MultFireDrill,
dom_id, 0, CThetaFireDrill, RFireDrill, DeltaTFireDrill, TotalToTFireDrill, -1,
true);
441 sncluster.push_back(sn);
442 trigger_final.push_back(sncluster);
447 fireDrillData >> timeFireDrill >> MultFireDrill >> CThetaFireDrill >> RFireDrill >> TotalToTFireDrill >> DeltaTFireDrill;
448 timeFireDrill += fireDrillOffsetTime;
453 while(sn_it !=
trigger.end()) {
454 trigger_final.push_back(*sn_it);
458 fireDrillTimeslice++;
462 startedFireDrill =
false;
463 fireDrillFile.clear();
464 timeSinceLastFireDrill = 0;
465 fireDrillData.close();
470 trgQueue.push(trigger_final);
476 if ( trgQueue.size() >= (
unsigned) queueLength ) {
478 while ( trgWindow.size() <= (
unsigned) windowLength ) {
480 trigger_type pending = trgQueue.top();
482 if ( trgWindow.size() == 0 || pending > trgWindow.back() ) {
484 trgWindow.push_back( pending );
499 NOTICE(
"Filling trigger queue: " << trgQueue.size() <<
"/" << queueLength <<
'\r');
503 else if ( inputFileName !=
"" ) {
506 if ( trgQueue.size() > 0 ) {
507 while ( trgQueue.size() > 0 ) {
508 trgWindow.push_back(trgQueue.top());
512 else if ( trgWindow.size() < (
unsigned) windowLength ) {
513 i = numberOfTimeouts;
517 NOTICE(
"timeout " << setw(3) << i << endl);
522 if (trgWindow.size() >= (
unsigned) windowLength) {
529 int trg_cc_counts = 0;
530 int trg_cc_modules = 0;
533 int trg_ev_counts = 0;
534 int trg_ev_modules = 0;
542 int trg_cc_counts_nofakes = 0;
543 int trg_cc_modules_nofakes = 0;
546 int trg_ev_counts_nofakes = 0;
547 int trg_ev_modules_nofakes = 0;
551 for (
int its = 0; its < windowLength; its++) {
553 const int frame_index = trgWindow[its].frameIndex;
556 if (veto.count(frame_index)) {
557 vetoSet = veto.at(frame_index);
563 set<int> cc_vec = trgWindow[its].getModules(F_M1);
564 set<int> ev_vec = trgWindow[its].getModules(F_MV);
570 for (
auto &trg: trgWindow[its]){
572 if (!trg.getPeak().fake) trg_cc_counts_nofakes++;
573 for (
auto &snc: trg){
575 cc_vec_nofakes.insert(snc.moduleID);
580 if (!trg.getPeak().fake) trg_ev_counts_nofakes++;
581 for (
auto &snc: trg){
583 ev_vec_nofakes.insert(snc.moduleID);
589 cc_modules.insert(cc_vec.begin(), cc_vec.end());
590 ev_modules.insert(ev_vec.begin(), ev_vec.end());
592 cc_modules_nofakes.insert(cc_vec_nofakes.begin(), cc_vec_nofakes.end());
593 ev_modules_nofakes.insert(ev_vec_nofakes.begin(), ev_vec_nofakes.end());
595 trg_cc_counts += count_if(trgWindow[its].begin(), trgWindow[its].end(), F_M1);
596 trg_ev_counts += count_if(trgWindow[its].begin(), trgWindow[its].end(), F_MV);
599 for (
auto &trg: trgWindow[its]){
600 auto sn_candidate = trg.getPeak();
601 if (F_MV_BDT(sn_candidate)){
602 multiplicities.push_back(sn_candidate.multiplicity);
603 observables.push_back(sn_candidate.total_ToT);
604 observables.push_back(sn_candidate.deltaT);
605 observables.push_back(sn_candidate.mean_dir_norm);
606 observables.push_back(sn_candidate.mean_dir_ctheta);
608 if (!sn_candidate.fake){
609 multiplicities_nofakes.push_back(sn_candidate.multiplicity);
610 observables_nofakes.push_back(sn_candidate.total_ToT);
611 observables_nofakes.push_back(sn_candidate.deltaT);
612 observables_nofakes.push_back(sn_candidate.mean_dir_norm);
613 observables_nofakes.push_back(sn_candidate.mean_dir_ctheta);
619 trg_cc_modules = cc_modules.size();
620 trg_ev_modules = ev_modules.size();
622 trg_cc_modules_nofakes = cc_modules_nofakes.size();
623 trg_ev_modules_nofakes = ev_modules_nofakes.size();
627 int currentFrame = trgWindow[0].frameIndex;
630 trgWindow.pop_front();
634 ++stats[trg_cc_counts];
638 int activeModules = -1;
639 double detectorRate = 0.0;
641 if (!rates.empty() &&
642 rates.count(currentFrame)) {
647 p != rates.at(currentFrame).end(); p++ ) {
649 detectorRate += p->second;
651 activeModules += (p->second > 0);
656 activeModules = timesliceSize;
663 string daq_time =
to_string(currentTime);
680 string msg = jd.dump();
687 if (multiplicities.size() != multiplicities_nofakes.size()){
707 if (outputFileName !=
""){
708 if (nWrittenEntries < nEntries || nEntries == -1) {
730 if ( (counter_live_ts % ((
int)(statPrintInterval_s / frameTime_s)) == 0 ) ) {
732 double livetime = counter_live_ts * frameTime_s;
738 NOTICE(
"=> discarded out-of-order timeslices = " << counter_lost_ts << endl);
740 if (summaryFile !=
"") {
741 ofstream of(summaryFile.c_str());
752 ERROR(error.what() << endl);
755 if (outputFileName !=
"") {
outputFile.close(); }