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.