184{
187
188
189
190
191
193 JLimit_t& numberOfEvents = inputFile.getLimit();
195 string detectorFile;
198
199 try {
200
201 JParser<> zap(
"Example program to verify Monte Carlo data.");
202
209
210 zap(argc, argv);
211 }
212 catch(const exception &error) {
213 FATAL(error.what() << endl);
214 }
215
216
217
218
219
220
222
223 if (detectorFile != "") {
224
225 try {
227 }
230 }
231 }
232
234
236
237
238
239
240
241
243
244 NOTICE(
"Apply detector offset " << offset << endl);
245
247
248
249
250
251
252
254
255 NOTICE(
"JDomino: Instrumented volume dimensions (x, y, r, zmin, zmax): " << inst_vol << endl);
256
257
258
259
260
261
263
266
267
268
275 }
276 const int nx = (int) ((xmax - xmin) / 0.1);
277
278 const Double_t T[] = { -50.0, -20.0, -10.0, -5.0, -2.0, 0.0, +2.0, +5.0, +10.0, +15.0, +20.0, +30.0, +40.0, +50.0,
279 +75.0, +100.0, +150.0, +200.0, +250.0, +300.0, +400.0, +500.0, 1000.0 };
280
281
282
283
284
285 TH1D hits("hits", NULL, 100, 0.0, 8.0);
286 TH1D trks("trks", NULL, 10001, -5000.5, 5000.5);
287 TH1D job ("job" , NULL, 10001, -5000.5, 5000.5);
288
289 TProfile hits_per_E_in ("hits_per_E_in", "average number of hits per E_{#nu} inside instrumented volume", nx, xmin, xmax);
290 TProfile hits_per_E_out("hits_per_E_out", "average number of hits per E_{#nu} outside instrumented volume", nx, xmin, xmax);
291
293
294 JManager_t npe_per_type(new TH1D("npe[%]", NULL, 5000, 0.5, 5000.5), '%', ios::fmtflags(ios::showpos));
295
296 TH1D npe_per_pmt ("pmt", NULL, 100001, -0.5, 100000.5);
297
298
299
300
301
302
303 TH2D nuExD("nuExD", NULL, nx, xmin, xmax, 100, 0.0, 1000.0);
304 TH2D* nuExD_tmp = (TH2D*) nuExD.Clone("nuExD.tmp");
305
306 TH2D nuExc("nuExc", NULL, nx, xmin, xmax, 100, -1.0, +1.0);
307 TH2D* nuExc_tmp = (TH2D*) nuExc.Clone("nuExc.tmp");
308
309 TH2D nuDxc("nuDxc", NULL, 50, 0.0, 1000.0, 100, -1.0, +1.0);
310 TH2D* nuDxc_tmp = (TH2D*) nuDxc.Clone("nuDxc.tmp");
311
312 TH2D nuDxU("nuDxU", NULL, 50, 0.0, 1000.0, 100, -1.0, +1.0);
313 TH2D* nuDxU_tmp = (TH2D*) nuDxU.Clone("nuDxU.tmp");
314
315 TH2D nuDxT(
"nuDxT", NULL, 50, 0.0, 1000.0,
getSize(T) - 1, T);
316 TH2D* nuDxT_tmp = (TH2D*) nuDxT.Clone("nuDxT.tmp");
317
318 nuExD.Sumw2();
319 nuExc.Sumw2();
320 nuDxc.Sumw2();
321 nuDxU.Sumw2();
322 nuDxT.Sumw2();
323
324
325
326
327
328
329 TH2D muExR("muExR", NULL, nx, xmin, xmax, 30, 0.0, 300.0);
330 TH2D* muExR_tmp = (TH2D*) muExR.Clone("muExR.tmp");
331
332 TH2D muRxU("muRxU", NULL, 15, 0.0, 300.0, 100, -1.0, +1.0);
333 TH2D* muRxU_tmp = (TH2D*) muRxU.Clone("muRxU.tmp");
334
335 TH2D muRxT(
"muRxT", NULL, 15, 0.0, 300.0,
getSize(T) - 1, T);
336 TH2D* muRxT_tmp = (TH2D*) muRxT.Clone("muRxT.tmp");
337
338 muExR.Sumw2();
339 muRxU.Sumw2();
340 muRxT.Sumw2();
341
342
343
344
345
346
348
350
351 const Evt*
event = inputFile.
next();
352
353 double NPE = 0.0;
354
355 for (vector<Hit>::const_iterator hit = event->mc_hits.begin(); hit != event->mc_hits.end(); ++hit) {
357 }
358
359 hits.Fill(log10((Double_t) event->mc_hits.size()));
360
361 for (vector<Trk>::const_iterator track = event->mc_trks.begin(); track != event->mc_trks.end(); ++track) {
362 trks.Fill(track->type);
363 }
364
366
369 }
370
372
373 map_type npe_pmt;
374 map_type npe_type;
375
376
377
378
379
380
381 for (vector<Hit>::const_iterator hit = event->mc_hits.begin(); hit != event->mc_hits.end(); ++hit) {
382
383 const int type = hit->type;
384 const double t1 =
getTime(*hit);
385 const double npe =
getNPE (*hit);
386
387 npe_pmt[hit->pmt_id].put(npe);
388
389 npe_type[0] .put(npe);
390 npe_type[type].put(npe);
391
392 if (hit_types.empty() || hit_types.count(type) != 0) {
393
394 vector<Trk>::const_iterator track = find_if(event->mc_trks.begin(),
395 event->mc_trks.end(),
396 make_predicate(&
Trk::id, hit->origin));
397
398 if (track == event->mc_trks.end()) {
399 ERROR(
"Hit " << *hit <<
" has no origin." << endl);
400 continue;
401 }
402
403 if (count_if(event->mc_trks.begin(),
404 event->mc_trks.end(),
405 make_predicate(&
Trk::id, hit->origin)) > 1) {
406 ERROR(
"Hit " << *hit <<
" has ambiguous origin." << endl);
407 continue;
408 }
409
410 job.Fill((double) track->type, npe);
411
412 if (router.hasPMT(hit->pmt_id)) {
413
414 const JPMT& pmt = router.getPMT(hit->pmt_id);
415
417
419
420 const double E = muon.
getE();
421 const double x = log10(E);
423 const double t0 = muon.
getT (pmt);
424 const double ct1 = muon.
getDot (pmt);
425
426 muExR.Fill(x, R, getMuonWeight(E, npe));
427 muRxU.Fill(R, ct1, getMuonWeight(E, R, npe));
428 muRxT.Fill(R, t1 - t0, getMuonWeight(E, R, npe));
429
431
432 const double E = neutrino.
getE();
433 const double x = log10(E);
435 const double t0 = vertex.
getT(pmt);
437 const double ct1 = vertex.
getDot(pmt);
438
439 nuExD.Fill(x, D, getNeutrinoWeight(E, npe));
440 nuExc.Fill(x, ct0, getNeutrinoWeight(E, npe));
441 nuDxc.Fill(D, ct0, getNeutrinoWeight(E, D, npe));
442 nuDxU.Fill(D, ct1, getNeutrinoWeight(E, D, npe));
443 nuDxT.Fill(D, t1 - t0, getNeutrinoWeight(E, D, npe));
444 }
445 }
446 }
447 }
448
449
450
451
452
453
454 for (map_type::const_iterator i = npe_pmt.begin(); i != npe_pmt.end(); ++i) {
455 npe_per_pmt.Fill(i->second.getTotal());
456 }
457
458 for (map_type::const_iterator i = npe_type.begin(); i != npe_type.end(); ++i) {
459 npe_per_type[i->first]->Fill(i->second.getTotal());
460 }
461
462
463
464
465
466
467 for (vector<Trk>::const_iterator track = event->mc_trks.begin(); track != event->mc_trks.end(); ++track) {
468
470
472
473 const double E = muon.
getE();
474 const double x = log10(E);
475
476 for (JDetector::const_iterator module =
detector.begin(); module !=
detector.end(); ++module) {
477
479
480 muExR_tmp->Fill(x, R, module->size());
481
482 if (R < muRxU.GetXaxis()->GetXmax()) {
483 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
484 muRxU_tmp->Fill(R, muon.
getDot(*pmt));
485 }
486 }
487
488 if (R < muRxT.GetXaxis()->GetXmax()) {
489 for (Int_t iy = 1; iy <= muRxT_tmp->GetYaxis()->GetNbins(); ++iy) {
490 muRxT_tmp->Fill(R, muRxT_tmp->GetYaxis()->GetBinCenter(iy), muRxT_tmp->GetYaxis()->GetBinWidth(iy));
491 }
492 }
493 }
494 }
495 }
496
497
498
499
500
501
503
504 const double E = neutrino.
getE();
505 const double x = log10(E);
506
507 if (inst_vol.is_inside(vertex))
508 hits_per_E_in .Fill(x, NPE);
509 else
510 hits_per_E_out.Fill(x, NPE);
511
512 for (JDetector::const_iterator module =
detector.begin(); module !=
detector.end(); ++module) {
513
515 const double ct0 = neutrino.
getDot(module->getPosition());
516
517 nuExD_tmp->Fill(x, D, module->size());
518 nuExc_tmp->Fill(x, ct0, module->size());
519 nuDxc_tmp->Fill(D, ct0, module->size());
520
521 if (D < nuDxU.GetXaxis()->GetXmax()) {
522 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
523 nuDxU_tmp->Fill(D, neutrino.
getDot(*pmt));
524 }
525 }
526
527 if (D < nuDxT.GetXaxis()->GetXmax()) {
528 for (Int_t iy = 1; iy <= nuDxT_tmp->GetYaxis()->GetNbins(); ++iy) {
529 nuDxT_tmp->Fill(D, nuDxT_tmp->GetYaxis()->GetBinCenter(iy), nuDxT_tmp->GetYaxis()->GetBinWidth(iy));
530 }
531 }
532 }
533 }
534 }
535
537
538
539
540
541
542
543 TH1D *job_sorted = makeSortedH1(&job, "hits_by_pdg");
544 TH1D *trks_sorted = makeSortedH1(&trks, "trks_sorted");
545
547
548 const Double_t W = 1.0 / ((Double_t) inputFile.
getCounter());
549
550 for (TH1D* p : { &hits, &npe_per_pmt, &job, &trks, job_sorted, trks_sorted }) {
551 p->Scale(W);
552 }
553
554 for (JManager_t::iterator i = npe_per_type.begin(); i != npe_per_type.end(); ++i) {
555 i->second->Scale(W);
556 }
557
558 nuExD.Divide(nuExD_tmp);
559 nuExc.Divide(nuExc_tmp);
560 nuDxc.Divide(nuDxc_tmp);
561 nuDxU.Divide(nuDxU_tmp);
562 nuDxT.Divide(nuDxT_tmp);
563
564 muExR.Divide(muExR_tmp);
565 muRxU.Divide(muRxU_tmp);
566 muRxT.Divide(muRxT_tmp);
567 }
568
569
570
571
572
573
575
576 out << hits << job << *job_sorted << trks << *trks_sorted << hits_per_E_in << hits_per_E_out << npe_per_type << npe_per_pmt;
577
578 out << nuExD << nuExc << nuDxc << nuDxU << nuDxT;
579 out << muExR << muRxU << muRxT;
580
581 out.Write();
582 out.Close();
583}
#define DEBUG(A)
Message macros.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
bool is_valid(T JHead::*pd) const
Check validity of given data member in JHead.
Router for direct addressing of PMT data in detector data structure.
Data structure for PMT geometry, calibration and status.
double getDistance(const JVector3D &pos) const
Get distance.
const JPosition3D & getPosition() const
Get position.
double getDot(const JAxis3D &axis) const
Get cosine angle of impact of Cherenkov light on PMT.
double getT(const JVector3D &pos) const
Get arrival time of Cherenkov light at given position.
JVertex3D getVertex() const
Get vertex of this track.
double getE() const
Get energy.
double getDistance(const JVector3D &pos) const
Get distance to point.
double getT(const JVector3D &pos) const
Get arrival time of Cherenkov light at given position.
double getDot(const JAxis3D &axis) const
Get cosine angle of impact of Cherenkov light on PMT.
Utility class to parse command line options.
Auxiliary class to manage set of compatible ROOT objects (e.g. histograms) using unique keys.
General purpose class for object reading from a list of file names.
virtual bool hasNext() override
Check availability of next element.
counter_type getCounter() const
Get counter.
virtual const pointer_type & next() override
Get next element.
JTrack3E getTrack(const Trk &track)
Get track.
bool has_neutrino(const Evt &evt)
Test whether given event has an incoming neutrino.
JPosition3D getPosition(const Vec &pos)
Get position.
bool is_muon(const Trk &track)
Test whether given track is a (anti-)muon.
double getNPE(const Hit &hit)
Get true charge of hit.
Vec getOffset(const JHead &header)
Get offset.
const Trk & get_neutrino(const Evt &evt)
Get incoming neutrino.
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
size_t getSize(T(&array)[N])
Get size of c-array.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Head getHeader(const JMultipleFileScanner_t &file_list)
Get Monte Carlo header.
const char * getTime()
Get current local time conform ISO-8601 standard.
std::map< int, range_type > map_type
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.
JRange_t E
Energy range [GeV].
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Auxiliary class for defining the range of iterations of objects.
static counter_type max()
Get maximum counter value.
The Vec class is a straightforward 3-d vector, which also works in pyroot.