89{
93
95 JLimit_t& numberOfEvents = inputFile.getLimit();
97 string detectorFile;
98 bool overwriteDetector;
99 double TMaxLocal_ns;
100 int numberOfTimeslices;
101 double binWidth_ns;
102 double deadTime_us;
103 double Pmin;
107
108 try {
109
110 JParser<> zap(
"Example program to search for correlations between triggered events and timeslice data.");
111
112 zap[
'f'] =
make_field(inputFile,
"input file.");
114 zap[
'a'] =
make_field(detectorFile,
"detector file.");
115 zap[
'A'] =
make_field(overwriteDetector,
"overwrite detector file provided through '-a' with module (PMT) status.");
117 zap[
'T'] =
make_field(TMaxLocal_ns,
"time window for local coincidences (L1),") = 20.0;
118 zap[
'N'] =
make_field(numberOfTimeslices,
"time slice difference between triggered event and L1.") = 100;
119 zap[
'W'] =
make_field(binWidth_ns,
"bin width for output histograms." ) = 10e3;
120 zap[
'D'] =
make_field(deadTime_us,
"L1 dead time (us)") = 200.0;
121 zap[
'p'] =
make_field(Pmin,
"minimal probability for background to be signal.") = 1.0e-7;
125
126 zap(argc, argv);
127 }
128 catch(const exception& error) {
129 FATAL(error.what() << endl);
130 }
131
132
134
135 try {
137 }
140 }
141
143 FATAL(
"Empty detector " << detectorFile << endl);
144 }
145
147
149 const double BOOST = 20.0;
150 const double deadTime_ns = deadTime_us * 1e3;
151
152 NOTICE(
"Time window " <<
FIXED(7,1) << TMax_ns <<
" [ns]" << endl);
153
155
158 vector <hit_type>
data;
159
161
162 const Double_t
xmin = -(numberOfTimeslices + 1) *
getFrameTime() - 0.5*binWidth_ns;
163 const Double_t
xmax = +(numberOfTimeslices + 1) *
getFrameTime() + 0.5*binWidth_ns;
164 const Int_t nx = (Int_t) ((xmax - xmin) / binWidth_ns);
165
166 JManager_t manager(new TH1D("M_%", NULL, nx, xmin, xmax));
167
169
171
173
174 if (selector == "") {
175
181 } else {
182 FATAL(
"No timeslice data." << endl);
183 }
184
185 NOTICE(
"Selected class " << ps->getClassName() << endl);
186
187 } else {
188
189 ps = zmap[selector];
190
191 ps->configure(inputFile);
192 }
193
194 ps->setLimit(inputFile.getLimit());
195
197
198 map_type buffer;
199
201
202 if (in.getCounter()%1000 == 0) {
203 STATUS(
"event: " << setw(10) << in.getCounter() <<
'\r');
DEBUG(endl);
204 }
205
207
208
209
210 double t0 = 0.0;
211 size_t n0 = 0;
212
214 if (router.hasModule(hit->getModuleID())) {
215 t0 +=
getTime(*hit, router.getPMT(*hit));
216 n0 += 1;
217 }
218 }
219
220 t0 /= n0;
222
223 buffer[event->getFrameIndex()].push_back(t0);
224 }
226
227
228 while (ps->hasNext()) {
229
230 if (ps->getCounter()%1000 == 0) {
231 STATUS(
"event: " << setw(10) << ps->getCounter() <<
'\r');
DEBUG(endl);
232 }
233
235
236 map_type::const_iterator p = buffer.lower_bound(timeslice->
getFrameIndex() - numberOfTimeslices);
237 map_type::const_iterator q = buffer.upper_bound(timeslice->
getFrameIndex() + numberOfTimeslices);
238
239 int number_of_events = 0;
240
241 for (map_type::const_iterator i = p; i != q; ++i) {
242 number_of_events += i->second.size();
243 }
244
245 if (number_of_events == 0) {
246 continue;
247 }
248
249 for (JDAQTimeslice::const_iterator frame = timeslice->begin(); frame != timeslice->end(); ++frame) {
250
251 if (router.hasModule(frame->getModuleID())) {
252
254
255 buildL1(*frame, router.getModule(frame->getModuleID()), back_inserter(data));
256
257 TH1D* h1 = manager[frame->getModuleID()];
258
259 double t1 = numeric_limits<double>::lowest();
260
261 for (vector<hit_type>::const_iterator hit =
data.begin(); hit !=
data.end(); ++hit) {
262
263 const double t2 = *hit + frame->getFrameIndex() *
getFrameTime();
264
265 if (t2 > t1 + deadTime_ns) {
266
267 for (map_type::const_iterator i = p; i != q; ++i) {
268 for (map_type::mapped_type::const_iterator t0 = i->second.begin(); t0 != i->second.end(); ++t0) {
269 h1->Fill(t2 - *t0);
270 }
271 }
272
273 t1 = t2;
274 }
275 }
276 }
277 }
278 }
280
281
282
283
284 TF1
f1(
"f1",
"[0]*exp(-0.5*(x-[1])*(x-[1])/([2]*[2])) + [3]");
285
286 string option = "L";
287
289 option += "Q";
290 }
291
292
294
295 for (JDetector::const_iterator module =
detector.begin(); module !=
detector.end(); ++module) {
296
297 if (module->getFloor() != 0) {
298
299 status[module->getID()] = DEFAULT;
300
301 JManager_t::iterator p = manager.find(module->getID());
302
303 if (p == manager.end() || p->second->GetEntries() == 0) {
304
305 status[module->getID()] = NODATA;
306
307 continue;
308 }
309
310 TH1D* h1 = p->second;
311
312
313
314 Double_t ymax = 0.0;
315 Double_t x0 = 0.0;
316 Double_t
sigma = 250.0;
317 Double_t ymin = 0.0;
318
319 for (int i = 1; i != h1->GetNbinsX(); ++i) {
320
321 const Double_t
x = h1->GetBinCenter (i);
322 const Double_t
y = h1->GetBinContent(i);
323
324 if (y > ymax) {
327 }
328
330 }
331
332 ymin /= h1->GetNbinsX();
333
334 f1.SetParameter(0, ymax);
335 f1.SetParameter(1, x0);
336 if (binWidth_ns < sigma)
337 f1.SetParameter(2, sigma);
338 else
339 f1.FixParameter(2, binWidth_ns/sqrt(12.0));
340 f1.SetParameter(3, ymin);
341
342 for (Int_t i = 0; i !=
f1.GetNpar(); ++i) {
343 f1.SetParError(i, 0.0);
344 }
345
346
347
348 h1->Fit(&f1, option.c_str(), "same", x0 - 5 * sigma, x0 + 5 * sigma);
349
350 if (fabs(
f1.GetParameter(1)) <= 0.5*getFrameTime() &&
351 f1.GetParameter(0) >=
f1.GetParameter(3)) {
352
353 status[module->getID()] = IN_SYNC;
354 }
355
356 double fm = fmod(
f1.GetParameter(1), getFrameTime());
357
360
362 << setw(10) << module->getID() << ' '
363 <<
FIXED(15,3) <<
f1.GetParameter(1) <<
' '
364 <<
FIXED(12,3) <<
f1.GetParameter(0) <<
' '
365 <<
FIXED(12,3) <<
f1.GetParameter(3) <<
' '
366 <<
FIXED(12,3) << fm <<
' '
367 << status[module->getID()] << endl);
368
369
370
373
374 for (Int_t i = 1, ns = -(numberOfTimeslices + 1); i <= h1->GetNbinsX(); ++i) {
375
376 const Double_t
x = h1->GetBinCenter (i);
377 const Double_t
y = h1->GetBinContent(i);
378
379 while (x > (ns + 1) *
getFrameTime() - BOOST * TMax_ns) {
380 ++ns;
381 }
382
384 sn[ns].put(y);
385 else if (fabs(x - ns *
getFrameTime()) < BOOST * TMax_ns)
386 bg[ns].put(y);
387 }
388
390
391 const Double_t
y = getBackground(i->second, bg[i->first]);
392 const Double_t P = TMath::PoissonI(i->second.getTotal(), y);
393
394 if (
debug >=
debug_t || status[module->getID()] != IN_SYNC) {
395 cout << "Module/peak " << setw(10) << module->getID() << ' '
396 << setw(4) << i->first << ' '
397 << "["
399 << ","
401 << "]"
402 << " S/N = "
403 <<
FIXED(7,1) << i->second.getTotal() <<
" / "
406 << (i->second.getTotal() > y && P < Pmin && i->first != 0 ? "***" : "") << endl;
407 }
408
409 if (i->second.getTotal() > y && P < Pmin)
410 ++i;
411 else
412 sn.erase(i++);
413 }
414
415 if (!(sn.size() == 1 &&
416 sn.begin()->first == 0)) {
417
418 status[module->getID()] = (sn.size() == 1 ? OUT_SYNC :
ERROR);
419
420 ERROR(
"Module/error "
421 << setw(10) << module->getID() << ' '
422 << "number of peaks " << sn.size() << ' '
423 <<
"peak " << (sn.size() == 1 ?
MAKE_CSTRING(sn.begin()->first) :
"?") <<
' '
424 << status[module->getID()] << endl);
425 }
426 }
427 }
428
429 if (overwriteDetector) {
430
432
434
435 if (i->second != IN_SYNC &&
436 i->second != NODATA) {
437
438 NOTICE(
"Module " << setw(8) << i->first <<
" set out-of-sync." << endl);
439
441
442 module.getStatus().set(MODULE_OUT_OF_SYNC);
443
444 for (JModule::iterator pmt = module.begin(); pmt != module.end(); ++pmt) {
446 }
447 }
448 }
449
451 }
452
455 }
456
457 int nin = 0;
458 int nout = 0;
459
461 if (i->second == IN_SYNC) {
462 ++nin;
463 }
464 if (i->second != IN_SYNC &&
465 i->second != NODATA) {
466 ++nout;
467 }
468 }
469
470 NOTICE(
"Number of modules out/in sync " << nout <<
'/' << nin << endl);
471
472 QAQC(nin <<
' ' << nout << endl);
473
474 return 0;
475}
#define DEBUG(A)
Message macros.
#define QAQC(A)
QA/QC output macro.
int qaqc
QA/QC file descriptor.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
#define MAKE_CSTRING(A)
Make C-string.
Simple wrapper around JModuleRouter class for direct addressing of PMT data in detector data structur...
Data structure for a composite optical module.
Auxialiary class to assert type conversion.
The template JSinglePointer class can be used to hold a pointer to an object.
Utility class to parse command line options.
Auxiliary class to manage set of compatible ROOT objects (e.g. histograms) using unique keys.
Template definition for direct access of elements in ROOT TChain.
int getFrameIndex() const
Get frame index.
JTriggerCounter_t next()
Increment trigger counter.
const JPolynome f1(1.0, 2.0, 3.0)
Function.
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
void store(const std::string &file_name, const JDetector &detector)
Store detector to output file.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
std::set< JROOTClassSelector > getROOTClassSelection(const bool option=false)
Get ROOT class selection.
const char * getTime()
Get current local time conform ISO-8601 standard.
KM3NeT DAQ data structures and auxiliaries.
double getFrameTime()
Get frame time duration.
double getMaximalTime(const double R_Hz)
Get maximal time for given rate.
std::map< int, range_type > map_type
static const int OUT_OF_SYNC
Enable (disable) synchronous signal from this PMT if this status bit is 0 (1);.
Auxiliary data structure for floating point format specification.
Auxiliary class for a type holder.
Auxiliary class to select ROOT class based on class name.
Auxiliary class to select JTreeScanner based on ROOT class name.
Auxiliary class for defining the range of iterations of objects.
static counter_type max()
Get maximum counter value.
Auxiliary data structure for L1 build parameters.
Auxiliary data structure for floating point format specification.