192   JMultipleFileScanner<Evt> inputFile;
 
  201     JParser<> zap(
"Example program to verify Monte Carlo data.");
 
  204     zap[
'n'] = 
make_field(numberOfEvents)      = JLimit::max();
 
  212   catch(
const exception &error) {
 
  213     FATAL(error.what() << endl);
 
  225   if (detectorFile != 
"") {
 
  228       load(detectorFile, detector);
 
  230     catch(
const JException& error) {
 
  235   const JPMTRouter router(detector);
 
  244   JPosition3D center = get<JPosition3D>(header);
 
  246   NOTICE(
"Apply detector offset " << center << endl); 
 
  255   JCylinder3D inst_vol(detector.begin(), detector.end());
 
  257   NOTICE(
"JDomino: Instrumented volume dimensions (x, y, r, zmin, zmax): " << inst_vol << endl);
 
  278   const int nx   = (int) ((xmax - xmin) / 0.1);
 
  280   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,
 
  281                          +75.0, +100.0, +150.0, +200.0, +250.0, +300.0, +400.0, +500.0, 1000.0 };  
 
  287   TH1D hits(
"hits", NULL,    100,     0.0,      8.0);                
 
  288   TH1D trks(
"trks", NULL,  10001, -5000.5,   5000.5);                
 
  289   TH1D job (
"job" , NULL,  10001, -5000.5,   5000.5);                
 
  291   TProfile hits_per_E_in (
"hits_per_E_in",  
"average number of hits per E_{#nu} inside  instrumented volume", nx, xmin, xmax);
 
  292   TProfile hits_per_E_out(
"hits_per_E_out", 
"average number of hits per E_{#nu} outside instrumented volume", nx, xmin, xmax);
 
  296   JManager_t npe_per_type(
new TH1D(
"npe[%]", NULL, 5000, 0.5, 5000.5), 
'%', ios::fmtflags(ios::showpos));
 
  298   TH1D       npe_per_pmt (
"pmt", NULL, 100001, -0.5, 100000.5);      
 
  305   TH2D  nuExD(
"nuExD", NULL, nx, xmin,  xmax, 100,  0.0, 1000.0);    
 
  306   TH2D* nuExD_tmp = (TH2D*) nuExD.Clone(
"nuExD.tmp");                
 
  308   TH2D  nuExc(
"nuExc", NULL, nx, xmin,  xmax, 100, -1.0,   +1.0);    
 
  309   TH2D* nuExc_tmp = (TH2D*) nuExc.Clone(
"nuExc.tmp");                
 
  311   TH2D  nuDxc(
"nuDxc", NULL, 50, 0.0, 1000.0, 100, -1.0,   +1.0);    
 
  312   TH2D* nuDxc_tmp = (TH2D*) nuDxc.Clone(
"nuDxc.tmp");                
 
  314   TH2D  nuDxU(
"nuDxU", NULL, 50, 0.0, 1000.0, 100, -1.0,   +1.0);    
 
  315   TH2D* nuDxU_tmp = (TH2D*) nuDxU.Clone(
"nuDxU.tmp");                
 
  317   TH2D  nuDxT(
"nuDxT", NULL, 50, 0.0, 1000.0, 
getSize(T) - 1, T);    
 
  318   TH2D* nuDxT_tmp = (TH2D*) nuDxT.Clone(
"nuDxT.tmp");                
 
  331   TH2D  muExR(
"muExR", NULL, nx, xmin,  xmax,  30,  0.0,  300.0);    
 
  332   TH2D* muExR_tmp = (TH2D*) muExR.Clone(
"muExR.tmp");                
 
  334   TH2D  muRxU(
"muRxU", NULL, 15, 0.0,  300.0, 100, -1.0,   +1.0);    
 
  335   TH2D* muRxU_tmp = (TH2D*) muRxU.Clone(
"muRxU.tmp");                
 
  337   TH2D  muRxT(
"muRxT", NULL, 15, 0.0,  300.0, 
getSize(T) - 1, T);    
 
  338   TH2D* muRxT_tmp = (TH2D*) muRxT.Clone(
"muRxT.tmp");                
 
  349   while (inputFile.hasNext()) {
 
  351     STATUS(
"event: " << setw(10) << inputFile.getCounter() << 
'\r'); 
DEBUG(endl);
 
  353     const Evt* 
event = inputFile.next();
 
  361     hits.Fill(log10((Double_t) event->mc_hits.size()));
 
  364       trks.Fill(track->type);
 
  373     const JVertex3D vertex = neutrino.getVertex();
 
  385       const int    type = hit->type;
 
  386       const double t1   = hit->pure_t;
 
  387       const double npe  = hit->pure_a;
 
  389       npe_pmt[hit->pmt_id].put(npe);
 
  391       npe_type[0]   .put(npe);
 
  392       npe_type[type].put(npe);    
 
  394       if (hit_types.empty() || hit_types.count(type) != 0) {
 
  397                                                     event->mc_trks.end(),
 
  400         if (track == event->mc_trks.end()) {
 
  401           ERROR(
"Hit " << *hit << 
" has no origin." << endl);
 
  405         if (count_if(event->mc_trks.begin(),
 
  406                      event->mc_trks.end(),
 
  408           ERROR(
"Hit " << *hit << 
" has ambiguous origin." << endl);
 
  412         job.Fill((
double) track->type, npe);
 
  414         if (router.hasPMT(hit->pmt_id)) {
 
  416           const JPMT&  pmt  = router.getPMT(hit->pmt_id);
 
  420             const JTrack3E muon = 
getTrack(*track);
 
  422             const double E   = muon.getE();
 
  423             const double x   = log10(E);
 
  424             const double R   = muon.getDistance(pmt);
 
  425             const double t0  = muon.getT       (pmt);
 
  426             const double ct1 = muon.getDot     (pmt);
 
  428             muExR.Fill(x, R,       getMuonWeight(E, npe));
 
  429             muRxU.Fill(R, ct1,     getMuonWeight(E, R, npe));
 
  430             muRxT.Fill(R, t1 - t0, getMuonWeight(E, R, npe));
 
  434             const double E   = neutrino.getE();
 
  435             const double x   = log10(E);
 
  436             const double D   = vertex.getDistance(pmt);
 
  437             const double t0  = vertex.getT(pmt);
 
  438             const double ct0 = neutrino.getDot(pmt.getPosition());
 
  439             const double ct1 = vertex.getDot(pmt);
 
  441             nuExD.Fill(x, D,       getNeutrinoWeight(E, npe));
 
  442             nuExc.Fill(x, ct0,     getNeutrinoWeight(E, npe));
 
  443             nuDxc.Fill(D, ct0,     getNeutrinoWeight(E, D, npe));
 
  444             nuDxU.Fill(D, ct1,     getNeutrinoWeight(E, D, npe));
 
  445             nuDxT.Fill(D, t1 - t0, getNeutrinoWeight(E, D, npe));
 
  456     for (map_type::const_iterator i = npe_pmt.begin(); i != npe_pmt.end(); ++i) {
 
  457       npe_per_pmt.Fill(i->second.getTotal());                     
 
  460     for (map_type::const_iterator i = npe_type.begin(); i != npe_type.end(); ++i) {
 
  461       npe_per_type[i->first]->Fill(i->second.getTotal());         
 
  473         const JTrack3E muon = 
getTrack(*track);
 
  475         const double E   = muon.getE();
 
  476         const double x   = log10(E);
 
  478         for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
 
  480           const double R   = muon.getDistance(*module);
 
  482           muExR_tmp->Fill(x, R, module->size());
 
  484           if (R < muRxU.GetXaxis()->GetXmax()) {
 
  485             for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
 
  486               muRxU_tmp->Fill(R, muon.getDot(*pmt));
 
  490           if (R < muRxT.GetXaxis()->GetXmax()) {
 
  491             for (Int_t iy = 1; iy <= muRxT_tmp->GetYaxis()->GetNbins(); ++iy) {
 
  492               muRxT_tmp->Fill(R, muRxT_tmp->GetYaxis()->GetBinCenter(iy), muRxT_tmp->GetYaxis()->GetBinWidth(iy));
 
  506       const double E   = neutrino.getE();
 
  507       const double x   = log10(E);
 
  509       if (inst_vol.is_inside(vertex))
 
  510         hits_per_E_in .Fill(x, NPE);
 
  512         hits_per_E_out.Fill(x, NPE);
 
  514       for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
 
  516         const double D   = vertex.getDistance(*module);
 
  517         const double ct0 = neutrino.getDot(module->getPosition());
 
  519         nuExD_tmp->Fill(x, D,   module->size());
 
  520         nuExc_tmp->Fill(x, ct0, module->size());
 
  521         nuDxc_tmp->Fill(D, ct0, module->size());
 
  523         if (D < nuDxU.GetXaxis()->GetXmax()) {
 
  524           for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
 
  525             nuDxU_tmp->Fill(D, neutrino.getDot(*pmt));
 
  529         if (D < nuDxT.GetXaxis()->GetXmax()) {
 
  530           for (Int_t iy = 1; iy <= nuDxT_tmp->GetYaxis()->GetNbins(); ++iy) {
 
  531             nuDxT_tmp->Fill(D, nuDxT_tmp->GetYaxis()->GetBinCenter(iy), nuDxT_tmp->GetYaxis()->GetBinWidth(iy));
 
  545   TH1D *job_sorted  = makeSortedH1(&job,  
"hits_by_pdg"); 
 
  546   TH1D *trks_sorted = makeSortedH1(&trks, 
"trks_sorted"); 
 
  548   if (inputFile.getCounter() != 0) {
 
  550     const Double_t W = 1.0 / ((Double_t) inputFile.getCounter());
 
  552     for (TH1D* buffer[] = { &hits, &npe_per_pmt, &job, &trks, job_sorted, trks_sorted, NULL }, **i = buffer; *i != NULL; ++i) {
 
  556     for (JManager_t::iterator i = npe_per_type.begin(); i != npe_per_type.end(); ++i) {
 
  560     nuExD.Divide(nuExD_tmp);
 
  561     nuExc.Divide(nuExc_tmp);
 
  562     nuDxc.Divide(nuDxc_tmp);
 
  563     nuDxU.Divide(nuDxU_tmp);
 
  564     nuDxT.Divide(nuDxT_tmp);
 
  566     muExR.Divide(muExR_tmp);
 
  567     muRxU.Divide(muRxU_tmp);
 
  568     muRxT.Divide(muRxT_tmp);
 
  578   out << hits << job << *job_sorted << trks << *trks_sorted << hits_per_E_in << hits_per_E_out << npe_per_type << npe_per_pmt;
 
  580   out << nuExD << nuExc << nuDxc << nuDxU << nuDxT;
 
  581   out << muExR << muRxU << muRxT;