Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JSupernovaMonitor.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <iomanip>
3 #include <queue>
4 #include <string>
5 
6 #include "JDAQ/JDAQTimeslice.hh"
7 #include "JDAQ/JDAQEvent.hh"
9 #include "JDAQ/JDAQTags.hh"
10 
11 #include "JDetector/JDetector.hh"
13 
15 
16 #include "Jeep/JParser.hh"
17 #include "Jeep/JMessage.hh"
18 
20 
21 #include "JSupport/JSupport.hh"
22 
23 #include "JSupernova.hh"
24 
25 /**
26  * \file
27  *
28  * Online supernova monitor
29  * \author mlincett
30  */
31 int main(int argc, char* argv[]) {
32  using namespace std;
33  using namespace JPP;
34  using namespace KM3NETDAQ;
35 
36  string controlhost;
37  string ligier;
38  JTimeval timeout_us;
39  int numberOfTimeouts;
40  int debug;
41  int queueLength;
42  int windowLength;
43  int statPrintInterval_s;
44 
45  string detectorFile;
46  JROOTClassSelector selector;
47  string summaryFile;
48 
49  int TMax_ns;
50  int preTriggerThreshold;
51  JRange<int> M;
52  double TVeto_ns;
53 
54  try {
55 
56  JParser<> zap("Example program to test receiving of objects from ControlHost server.");
57 
58  zap['H'] = make_field(controlhost, "CH server (input)") = "localhost";
59  zap['L'] = make_field(ligier, "Ligier server (output)") = "";
60  zap['t'] = make_field(timeout_us) = 100000;
61  zap['n'] = make_field(numberOfTimeouts) = 100;
62  zap['a'] = make_field(detectorFile);
63  zap['C'] = make_field(selector) = getROOTClassSelection<JDAQTimesliceTypes_t>();
64  zap['Q'] = make_field(queueLength, "number of timeslices of trigger queue") = 100;
65  zap['W'] = make_field(windowLength, "number of timeslices of trigger sliding window") = 5;
66  zap['T'] = make_field(TMax_ns, "coincidence time window [ns]") = 10;
67  zap['M'] = make_field(M, "multiplicity range for SN coincidences") = JRange<int>(6,10);
68  zap['S'] = make_field(preTriggerThreshold, "muon veto multiplicity threshold") = 4;
69  zap['V'] = make_field(TVeto_ns, "muon veto time interval") = 1000;
70  zap['s'] = make_field(summaryFile, "summary output file");
71  zap['P'] = make_field(statPrintInterval_s, "statistics & file print interval [s]") = 30;
72  zap['d'] = make_field(debug) = 1;
73 
74  zap(argc, argv);
75 
76  }
77 
78  catch(const exception &error) {
79  FATAL(error.what() << endl);
80  }
81 
82  if (queueLength < windowLength) {
83  FATAL("Length of the trigger window must be smaller than the queue.");
84  }
85 
86 
88 
89  using namespace JSUPERNOVA;
90 
91  // -------------------------------
92  // load detector and build routers
93  // -------------------------------
94 
95  JDetector detector;
96 
97  try {
98  load(detectorFile, detector);
99  }
100  catch(const JException& error) {
101  FATAL(error);
102  }
103 
104  const JModuleRouter moduleRouter(detector);
105 
106  const int DETID = detector.getID();
107 
108  const int detectorSize = detector.size();
109 
110  // -------------------------------
111  // initialize processing queue
112  // -------------------------------
113 
114  typedef JTriggerSN trigger_type;
115 
116  typedef priority_queue<trigger_type, vector<trigger_type>, greater<trigger_type> > queue_type;
117 
118  typedef deque<trigger_type> window_type;
119 
120  typedef map<int, map<int, double> > rates_type;
121 
122  queue_type trgQueue;
123  window_type trgWindow;
124  rates_type moduleRates;
125 
126  JTriggerSNStats stats(detectorSize);
127 
128  long int counter_live_ts = 0;
129  long int counter_lost_ts = 0;
130 
131  double frameTime_s = getFrameTime() / 1.0e9;
132 
133  // -------------------------------
134  // main processing
135  // -------------------------------
136 
137  try {
138 
139  // setup input
140 
141  typedef JDAQTimesliceSN data_type;
142  typedef JDAQSummaryslice summary_type;
143 
144  JControlHostObjectIterator<data_type> in(controlhost, timeout_us, true);
145  JControlHostObjectIterator<summary_type> sm(controlhost, 1000.0, true);
146 
147  // setup output
148  JControlHost* out = NULL;
149 
150  if (ligier != "") {
151  out = new JControlHost(ligier);
152  out->MyId(argv[0]); // pid
153  }
154 
155  const string outputTag = "SNT";
156 
157  // setup state
158 
159  int RUN = 0;
160 
161  for (int i = 0; i != numberOfTimeouts; ) {
162 
163  if (in.hasNext()) {
164 
165  data_type* timeslice = in.next();
166 
167  DEBUG(timeslice->getDAQHeader() << endl);
168 
169  // -----------------
170  // run change reset
171  // -----------------
172 
173  const int r = timeslice->getRunNumber();
174 
175  if (r != RUN) {
176 
177  if (RUN != 0) {
178 
179  // a run change has been detected
180 
181  NOTICE("RUN CHANGE" << endl);
182 
183  while (trgQueue.size() > 0) { trgQueue.pop(); }
184 
185  trgWindow.clear();
186 
187  moduleRates.clear();
188 
189  }
190 
191  RUN = r;
192 
193  }
194 
195  while ( sm.hasNext() ) {
196 
197  JDAQSummaryslice* summary = sm.next();
198 
199  int index = summary->getFrameIndex();
200 
201  for (JDAQSummaryslice::const_iterator summary_frame = summary->begin(); summary_frame != summary->end(); ++summary_frame) {
202 
203  int DOMID = summary_frame->getModuleID();
204 
205  for (int ipmt = 0 ; ipmt < NUMBER_OF_PMTS ; ipmt++) {
206  moduleRates[index][DOMID] += summary_frame->getRate(ipmt, 1.0/1000);
207  }
208  }
209  }
210 
211  // -----------------
212  // process timeslice
213  // -----------------
214 
215  JDataSN preTrigger(TMax_ns, preTriggerThreshold);
216 
217  preTrigger(timeslice, moduleRouter);
218 
219  JTriggerSN trigger(M, TVeto_ns);
220 
221  trigger(preTrigger);
222 
223  trgQueue.push(trigger);
224 
225  //----------------
226  // compute trigger
227  //----------------
228 
229  if (trgQueue.size() >= (unsigned) queueLength) {
230 
231  while (trgWindow.size() <= (unsigned) windowLength) {
232 
233  trigger_type pending = trgQueue.top();
234 
235  if ( trgWindow.size() == 0 || pending > trgWindow.back() ) {
236 
237  trgWindow.push_back( pending );
238 
239  counter_live_ts++;
240 
241  } else {
242  // latecoming (out of order) timeslice
243  counter_lost_ts++;
244  }
245 
246  trgQueue.pop();
247 
248  }
249 
250  // build triggered modules
251 
252  set<int> triggeredModules;
253 
254  for (int its = 0; its < windowLength; its++) {
255 
256  set<int> current = trgWindow[its].getModules();
257 
258  triggeredModules.insert(current.begin(), current.end());
259 
260  }
261 
262  // trigger window slide of one element
263 
264  int currentFrame = trgWindow[0].frameIndex;
265  JDAQUTCExtended currentTime = trgWindow[0].timeUTC;
266 
267  trgWindow.pop_front();
268 
269  // calculate trigger
270 
271  int trigger = triggeredModules.size();
272 
273  ++stats[trigger];
274 
275  DEBUG("TRIGGER => TS = " << currentFrame << "; LEVEL = " << trigger << endl);
276 
277  // calculate active modules
278  int activeModules = -1;
279 
280  if (!moduleRates.empty() &&
281  moduleRates.count(currentFrame)) {
282 
283  activeModules = 0;
284 
285  for (map<int, double>::const_iterator p = moduleRates.at(currentFrame).begin();
286  p != moduleRates.at(currentFrame).end(); p++ ) {
287  if (p->second > 0) {
288  activeModules++;
289  }
290  }
291  }
292 
293 
294  if (out != NULL) {
295 
296 
297  JSummarySN summary(DETID, activeModules, RUN, currentFrame, currentTime, trigger);
298 
299  stringstream message;
300  message << summary;
301 
302  out->PutFullString(outputTag, message.str());
303  }
304 
305 
306  // print stats
307 
308  if ( (counter_live_ts % ((int)(statPrintInterval_s / frameTime_s)) == 0 ) ) {
309 
310  double livetime = counter_live_ts * frameTime_s;
311 
312  stats.setLiveTime(livetime);
313 
314  NOTICE(endl);
315  NOTICE(stats.toString());
316  NOTICE("=> discarded out-of-order timeslices = " << counter_lost_ts << endl);
317 
318  if (summaryFile != "") {
319  ofstream of(summaryFile.c_str());
320  of << stats.toSummaryFile();
321  of.close();
322  }
323 
324  }
325 
326  } else {
327  NOTICE("Filling trigger queue: " << trgQueue.size() << "/" << queueLength << '\r');
328  }
329 
330  } else {
331 
332  NOTICE("timeout " << setw(3) << i << endl);
333 
334  ++i;
335  }
336  }
337  }
338 
339  catch(const JSocketException& error) {
340  ERROR(error.what() << endl);
341  }
342 
343 }
Utility class to parse command line options.
Definition: JParser.hh:1410
SN trigger summary information.
Definition: JSupernova.hh:543
debug
Definition: JMessage.hh:27
Data structure for UTC time.
Data structure for detector geometry and calibration.
int getFrameIndex() const
Get frame index.
string toSummaryFile()
put statistics into printable form outputs trigger level - rate - error
Definition: JSupernova.hh:640
void setDAQLongprint(const bool option)
Set DAQ print option.
Definition: JDAQPrint.hh:28
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1836
string toString()
put statistics into printable form outputs trigger level - rate - error
Definition: JSupernova.hh:607
SN trigger statistics, the information is stored in the form of a count as a function of the trigger ...
Definition: JSupernova.hh:586
double getFrameTime()
Get frame time duration.
Definition: JDAQClock.hh:162
Auxiliary class to apply the supernova trigger to SN data.
Definition: JSupernova.hh:385
#define NOTICE(A)
Definition: JMessage.hh:62
#define ERROR(A)
Definition: JMessage.hh:64
void load(const JString &file_name, JDetector &detector)
Load detector from input file.
int debug
debug level
Definition: JSirene.cc:59
Timeslice data structure for SN data.
General purpose messaging.
#define FATAL(A)
Definition: JMessage.hh:65
Auxiliary class to build the supernova trigger dataset.
Definition: JSupernova.hh:121
Utility class to parse command line options.
ROOT TTree parameter settings.
Fixed parameters for KM3NeT DAQ.
void setLiveTime(const double lt)
Definition: JSupernova.hh:599
static const int NUMBER_OF_PMTS
Total number of PMTs in module.
Definition: JDAQ.hh:26
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:60
int main(int argc, char *argv[])
Definition: Main.cpp:15