Jpp  18.0.0-rc.2
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Functions
software/JSirene/JDomino.cc File Reference

Example program to verify Monte Carlo data. More...

#include <string>
#include <iostream>
#include <iomanip>
#include <map>
#include <sstream>
#include "TROOT.h"
#include "TFile.h"
#include "TH1D.h"
#include "TH2D.h"
#include "TProfile.h"
#include "km3net-dataformat/offline/Head.hh"
#include "km3net-dataformat/offline/Evt.hh"
#include "JAAnet/JHead.hh"
#include "JAAnet/JHeadToolkit.hh"
#include "JAAnet/JAAnetToolkit.hh"
#include "JDetector/JDetector.hh"
#include "JDetector/JDetectorToolkit.hh"
#include "JDetector/JPMTRouter.hh"
#include "JGeometry3D/JCylinder3D.hh"
#include "JSupport/JMultipleFileScanner.hh"
#include "JSupport/JMonteCarloFileSupportkit.hh"
#include "JSupport/JSupport.hh"
#include "JROOT/JManager.hh"
#include "JGizmo/JGizmoToolkit.hh"
#include "JTools/JWeight.hh"
#include "JROOT/JRootToolkit.hh"
#include "JPhysics/JPDFToolkit.hh"
#include "JLang/JException.hh"
#include "JLang/JPredicate.hh"
#include "JLang/JLangToolkit.hh"
#include "Jeep/JPrint.hh"
#include "Jeep/JParser.hh"
#include "Jeep/JMessage.hh"

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Detailed Description

Example program to verify Monte Carlo data.

Author
mdejong

Definition in file software/JSirene/JDomino.cc.

Function Documentation

int main ( int  argc,
char **  argv 
)

Definition at line 183 of file software/JSirene/JDomino.cc.

184 {
185  using namespace std;
186  using namespace JPP;
187 
188  //-------------------------------------------------------------------------
189  // command-line arguments
190  //-------------------------------------------------------------------------
191 
192  JMultipleFileScanner<Evt> inputFile;
193  JLimit_t& numberOfEvents = inputFile.getLimit();
194  string outputFile;
195  string detectorFile;
196  set<int> hit_types;
197  int debug;
198 
199  try {
200 
201  JParser<> zap("Example program to verify Monte Carlo data.");
202 
203  zap['f'] = make_field(inputFile);
204  zap['n'] = make_field(numberOfEvents) = JLimit::max();
205  zap['o'] = make_field(outputFile) = "domino.root";
206  zap['a'] = make_field(detectorFile) = "";
207  zap['T'] = make_field(hit_types) = JPARSER::initialised();
208  zap['d'] = make_field(debug) = 2;
209 
210  zap(argc, argv);
211  }
212  catch(const exception &error) {
213  FATAL(error.what() << endl);
214  }
215 
216 
217  //-------------------------------------------------------------------------
218  // load detector file
219  //-------------------------------------------------------------------------
220 
222 
223  if (detectorFile != "") {
224 
225  try {
226  load(detectorFile, detector);
227  }
228  catch(const JException& error) {
229  FATAL(error);
230  }
231  }
232 
233  const JPMTRouter router(detector);
234 
235  const JHead header = getHeader(inputFile);
236 
237 
238  //-------------------------------------------------------------------------
239  // try to determine coordinate origin
240  //-------------------------------------------------------------------------
241 
242  JPosition3D center = get<JPosition3D>(header);
243 
244  NOTICE("Apply detector offset " << center << endl);
245 
246  detector -= center;
247 
248 
249  //-------------------------------------------------------------------------
250  // calculate instrumented volume
251  //-------------------------------------------------------------------------
252 
253  JCylinder3D inst_vol(detector.begin(), detector.end());
254 
255  NOTICE("JDomino: Instrumented volume dimensions (x, y, r, zmin, zmax): " << inst_vol << endl);
256 
257 
258  //-------------------------------------------------------------------------
259  // histogram binning
260  //-------------------------------------------------------------------------
261 
262  typedef map<int, JWeight> map_type;
263 
264  double xmin = 2.0;
265  double xmax = 8.0;
266 
267  // energy range is taken from -in order of priority- neutrino or muon data
268 
269  if (header.is_valid(&JHead::cut_nu)) {
270  xmin = log10(header.cut_nu.E.getLowerLimit());
271  xmax = log10(header.cut_nu.E.getUpperLimit());
272  } else if (header.is_valid(&JHead::cut_in)) {
273  xmin = log10(header.cut_in.E.getLowerLimit());
274  xmax = log10(header.cut_in.E.getUpperLimit());
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 }; // [ns]
280 
281  //-------------------------------------------------------------------------
282  // histograms for events
283  //-------------------------------------------------------------------------
284 
285  TH1D hits("hits", NULL, 100, 0.0, 8.0); // number of mc_hits per event
286  TH1D trks("trks", NULL, 10001, -5000.5, 5000.5); // number of track_in type's per event
287  TH1D job ("job" , NULL, 10001, -5000.5, 5000.5); // number of photo-electrons by track_in type
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 
292  typedef JManager<int, TH1D> JManager_t;
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); // number of photo-electrons per PMT
297 
298 
299  //-------------------------------------------------------------------------
300  // histograms for neutrino
301  //-------------------------------------------------------------------------
302 
303  TH2D nuExD("nuExD", NULL, nx, xmin, xmax, 100, 0.0, 1000.0); // Enu versus distance between vertex and PMT
304  TH2D* nuExD_tmp = (TH2D*) nuExD.Clone("nuExD.tmp"); // normalisation
305 
306  TH2D nuExc("nuExc", NULL, nx, xmin, xmax, 100, -1.0, +1.0); // Enu versus emission angle
307  TH2D* nuExc_tmp = (TH2D*) nuExc.Clone("nuExc.tmp"); // normalisation
308 
309  TH2D nuDxc("nuDxc", NULL, 50, 0.0, 1000.0, 100, -1.0, +1.0); // distance between vertex and PMT versus emission angle
310  TH2D* nuDxc_tmp = (TH2D*) nuDxc.Clone("nuDxc.tmp"); // normalisation
311 
312  TH2D nuDxU("nuDxU", NULL, 50, 0.0, 1000.0, 100, -1.0, +1.0); // distance between vertex and PMT versus incidence angle
313  TH2D* nuDxU_tmp = (TH2D*) nuDxU.Clone("nuDxU.tmp"); // normalisation
314 
315  TH2D nuDxT("nuDxT", NULL, 50, 0.0, 1000.0, getSize(T) - 1, T); // distance between vertex and PMT versus time residual
316  TH2D* nuDxT_tmp = (TH2D*) nuDxT.Clone("nuDxT.tmp"); // normalisation
317 
318  nuExD.Sumw2();
319  nuExc.Sumw2();
320  nuDxc.Sumw2();
321  nuDxU.Sumw2();
322  nuDxT.Sumw2();
323 
324 
325  //-------------------------------------------------------------------------
326  // histograms for muon
327  //-------------------------------------------------------------------------
328 
329  TH2D muExR("muExR", NULL, nx, xmin, xmax, 30, 0.0, 300.0); // Emu versus distance between muon and PMT
330  TH2D* muExR_tmp = (TH2D*) muExR.Clone("muExR.tmp"); // normalisation
331 
332  TH2D muRxU("muRxU", NULL, 15, 0.0, 300.0, 100, -1.0, +1.0); // distance between muon and PMT versus incidence angle
333  TH2D* muRxU_tmp = (TH2D*) muRxU.Clone("muRxU.tmp"); // normalisation
334 
335  TH2D muRxT("muRxT", NULL, 15, 0.0, 300.0, getSize(T) - 1, T); // distance between muon and PMT versus time residual
336  TH2D* muRxT_tmp = (TH2D*) muRxT.Clone("muRxT.tmp"); // normalisation
337 
338  muExR.Sumw2();
339  muRxU.Sumw2();
340  muRxT.Sumw2();
341 
342 
343  //-------------------------------------------------------------------------
344  // loop over events
345  //-------------------------------------------------------------------------
346 
347  while (inputFile.hasNext()) {
348 
349  STATUS("event: " << setw(10) << inputFile.getCounter() << '\r'); DEBUG(endl);
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) {
356  NPE += getNPE(*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 
365  JTrack3E neutrino;
366 
367  if (has_neutrino(*event)) {
368  neutrino = getTrack(get_neutrino(*event));
369  }
370 
371  const JVertex3D vertex = neutrino.getVertex();
372 
373  map_type npe_pmt; // temporary buffer to accumulate total npe's by individual PMTs
374  map_type npe_type; // temporary buffer to accumulate total npe's by hit origin track
375 
376 
377  //-------------------------------------------------------------------------
378  // loop over hits
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 
416  if (is_muon(*track)) {
417 
418  const JTrack3E muon = getTrack(*track);
419 
420  const double E = muon.getE();
421  const double x = log10(E);
422  const double R = muon.getDistance(pmt);
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 
430  } else if (has_neutrino(*event)) {
431 
432  const double E = neutrino.getE();
433  const double x = log10(E);
434  const double D = vertex.getDistance(pmt);
435  const double t0 = vertex.getT(pmt);
436  const double ct0 = neutrino.getDot(pmt.getPosition());
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  } // end if PMT of hit found in PMT router
447  } // end loop over hits
448 
449 
450  //-------------------------------------------------------------------------
451  // continue with logic for event, fill histograms common to all input files
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()); // npe / PMT
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()); // npe / type
460  }
461 
462 
463  //-------------------------------------------------------------------------
464  // normalisation of muon histograms
465  //-------------------------------------------------------------------------
466 
467  for (vector<Trk>::const_iterator track = event->mc_trks.begin(); track != event->mc_trks.end(); ++track) {
468 
469  if (is_muon(*track)) {
470 
471  const JTrack3E muon = getTrack(*track);
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 
478  const double R = muon.getDistance(*module);
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  // normalisation of neutrino histograms
500  //-------------------------------------------------------------------------
501 
502  if (has_neutrino(*event)) {
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 
514  const double D = vertex.getDistance(*module);
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  } // end loop over events
535 
536  STATUS(endl);
537 
538 
539  //-------------------------------------------------------------------------
540  // normalisation of histograms
541  //-------------------------------------------------------------------------
542 
543  TH1D *job_sorted = makeSortedH1(&job, "hits_by_pdg"); // hits by track_in particles (PDG codes) per event, sorted
544  TH1D *trks_sorted = makeSortedH1(&trks, "trks_sorted"); // track_in particles (PDG codes) per event, sorted
545 
546  if (inputFile.getCounter() != 0) {
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  // output
572  //-------------------------------------------------------------------------
573 
574  TFile out(outputFile.c_str(), "recreate");
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 }
Router for direct addressing of PMT data in detector data structure.
Definition: JPMTRouter.hh:35
const double xmax
Definition: JQuadrature.cc:24
Utility class to parse command line options.
Definition: JParser.hh:1514
General exception.
Definition: JException.hh:23
JPredicate< JResult_t T::*, JComparison::eq > make_predicate(JResult_t T::*member, const JResult_t value)
Helper method to create predicate for data member.
Definition: JPredicate.hh:128
then usage $script< input file >[option[primary[working directory]]] nWhere option can be E
Definition: JMuonPostfit.sh:36
JTrack3E getTrack(const Trk &track)
Get track.
#define STATUS(A)
Definition: JMessage.hh:63
bool has_neutrino(const Evt &evt)
Test whether given event has an incoming neutrino.
Detector data structure.
Definition: JDetector.hh:89
bool is_muon(const Trk &track)
Test whether given track is a (anti-)muon.
double getDot(const JAxis3D &axis) const
Get cosine angle of impact of Cherenkov light on PMT.
Definition: JVertex3D.hh:177
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:83
double getTime(const Hit &hit)
Get true time of hit.
string outputFile
double getDistance(const JVector3D &pos) const
Get distance to point.
Definition: JVector3D.hh:270
size_t getSize(T(&array)[N])
Get size of c-array.
Definition: JLangToolkit.hh:32
3D track with energy.
Definition: JTrack3E.hh:30
Head getHeader(const JMultipleFileScanner_t &file_list)
Get Monte Carlo header.
Auxiliary class for defining the range of iterations of objects.
Definition: JLimit.hh:41
Auxiliary class to manage set of compatible ROOT objects (e.g. histograms) using unique keys...
Definition: JManager.hh:43
Cylinder object.
Definition: JCylinder3D.hh:39
Detector file.
Definition: JHead.hh:226
double getE() const
Get energy.
Definition: JTrack3E.hh:93
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1989
set_variable E_E log10(E_{fit}/E_{#mu})"
do set_variable OUTPUT_DIRECTORY $WORKDIR T
Data structure for PMT geometry, calibration and status.
Definition: JPMT.hh:43
#define NOTICE(A)
Definition: JMessage.hh:64
#define ERROR(A)
Definition: JMessage.hh:66
const JPosition3D & getPosition() const
Get position.
Definition: JPosition3D.hh:130
double getT(const JVector3D &pos) const
Get arrival time of Cherenkov light at given position.
Definition: JTrack3D.hh:126
Monte Carlo run header.
Definition: JHead.hh:1221
#define FATAL(A)
Definition: JMessage.hh:67
int id
track identifier
Definition: Trk.hh:16
JVertex3D getVertex() const
Get vertex of this track.
Definition: JTrack3D.hh:99
then JCookie sh JDataQuality D $DETECTOR_ID R
Definition: JDataQuality.sh:41
const double xmin
Definition: JQuadrature.cc:23
double getDistance(const JVector3D &pos) const
Get distance.
Definition: JAxis3D.hh:213
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
General purpose class for object reading from a list of file names.
double getNPE(const Hit &hit)
Get true charge of hit.
Data structure for position in three dimensions.
Definition: JPosition3D.hh:36
const JLimit & getLimit() const
Get limit.
Definition: JLimit.hh:84
const Trk & get_neutrino(const Evt &evt)
Get incoming neutrino.
do set_variable DETECTOR_TXT $WORKDIR detector
double getT(const JVector3D &pos) const
Get arrival time of Cherenkov light at given position.
Definition: JVertex3D.hh:147
do echo Generating $dir eval D
Definition: JDrawLED.sh:53
double getDot(const JAxis3D &axis) const
Get cosine angle of impact of Cherenkov light on PMT.
Definition: JTrack3D.hh:170
int debug
debug level
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.
Definition: Evt.hh:20
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62