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 
  264  double xmin = 2.0;
  265  double xmax = 8.0;
  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);
 
  434            const double D   = vertex.getDistance(pmt);
  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 
  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  } 
  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.
 
double getE() const
Get energy.
 
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.
 
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.