14 #include "evt/Head.hh" 
   54   inline double getMuonWeight(
const double E,
 
   71   inline double getMuonWeight(
const double E,
 
   79     return R * exp(+R/l_att) * getMuonWeight(E, npe);
 
   90   inline double getNeutrinoWeight(
const double E,
 
  105   inline double getNeutrinoWeight(
const double E,
 
  109     static const double l_att = 45.0;                    
 
  111     return D*D * exp(+D/l_att) * getNeutrinoWeight(E, npe);
 
  126     return first.second > second.second;
 
  137   inline TH1D* makeSortedH1(TH1D* in, 
const TString& name)
 
  146     for (Int_t ix = 1; ix <= in->GetXaxis()->GetNbins(); ++ix) {
 
  148       const Int_t    x = (Int_t) in->GetXaxis()->GetBinCenter(ix);
 
  149       const Double_t y = in->GetBinContent(ix);
 
  152         data.push_back(make_pair(x, y));
 
  158     sort(data.begin(), data.end(), compare);
 
  162     TH1D* out = 
new TH1D(name, NULL, data.size(), -0.5, data.size() - 0.5);
 
  164     for (Int_t i = 0; i < (Int_t) data.size(); i++) {
 
  166       const Int_t ix = i + 1;
 
  168       out->GetXaxis()->SetBinLabel(ix, 
MAKE_CSTRING(fixed << setprecision(0) << data[i].first));
 
  169       out->SetBinContent(ix, data[i].second);
 
  183 int main(
int argc, 
char **argv)
 
  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);
 
  266   const double xmin = log10(header.cut_nu.Emin);
 
  267   const double xmax = log10(header.cut_nu.Emax);
 
  268   const int    nx   = (int) ((xmax - xmin) / 0.1);
 
  270   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,
 
  271                          +75.0, +100.0, +150.0, +200.0, +250.0, +300.0, +400.0, +500.0, 1000.0 };  
 
  277   TH1D hits(
"hits", NULL,    100,     0.0,      8.0);                
 
  278   TH1D trks(
"trks", NULL,  10001, -5000.5,   5000.5);                
 
  279   TH1D job (
"job" , NULL,  10001, -5000.5,   5000.5);                
 
  281   TProfile hits_per_E_in (
"hits_per_E_in",  
"average number of hits per E_{#nu} inside  instrumented volume", nx, xmin, xmax);
 
  282   TProfile hits_per_E_out(
"hits_per_E_out", 
"average number of hits per E_{#nu} outside instrumented volume", nx, xmin, xmax);
 
  286   JManager_t npe_per_type(
new TH1D(
"npe[%]", NULL, 5000, 0.5, 5000.5), 
'%', ios::fmtflags(ios::showpos));
 
  288   TH1D       npe_per_pmt (
"pmt", NULL, 100001, -0.5, 100000.5);      
 
  295   TH2D  nuExD(
"nuExD", NULL, nx, xmin,  xmax, 100,  0.0, 1000.0);    
 
  296   TH2D* nuExD_tmp = (TH2D*) nuExD.Clone(
"nuExD.tmp");                
 
  298   TH2D  nuExc(
"nuExc", NULL, nx, xmin,  xmax, 100, -1.0,   +1.0);    
 
  299   TH2D* nuExc_tmp = (TH2D*) nuExc.Clone(
"nuExc.tmp");                
 
  301   TH2D  nuDxc(
"nuDxc", NULL, 50, 0.0, 1000.0, 100, -1.0,   +1.0);    
 
  302   TH2D* nuDxc_tmp = (TH2D*) nuDxc.Clone(
"nuDxc.tmp");                
 
  304   TH2D  nuDxU(
"nuDxU", NULL, 50, 0.0, 1000.0, 100, -1.0,   +1.0);    
 
  305   TH2D* nuDxU_tmp = (TH2D*) nuDxU.Clone(
"nuDxU.tmp");                
 
  307   TH2D  nuDxT(
"nuDxT", NULL, 50, 0.0, 1000.0, 
getSize(T) - 1, T);    
 
  308   TH2D* nuDxT_tmp = (TH2D*) nuDxT.Clone(
"nuDxT.tmp");                
 
  321   TH2D  muExR(
"muExR", NULL, nx, xmin,  xmax,  30,  0.0,  300.0);    
 
  322   TH2D* muExR_tmp = (TH2D*) muExR.Clone(
"muExR.tmp");                
 
  324   TH2D  muRxU(
"muRxU", NULL, 15, 0.0,  300.0, 100, -1.0,   +1.0);    
 
  325   TH2D* muRxU_tmp = (TH2D*) muRxU.Clone(
"muRxU.tmp");                
 
  327   TH2D  muRxT(
"muRxT", NULL, 15, 0.0,  300.0, 
getSize(T) - 1, T);    
 
  328   TH2D* muRxT_tmp = (TH2D*) muRxT.Clone(
"muRxT.tmp");                
 
  339   while (inputFile.hasNext()) {
 
  341     STATUS(
"event: " << setw(10) << inputFile.getCounter() << 
'\r'); 
DEBUG(endl);
 
  343     const Evt* 
event = inputFile.next();
 
  351     hits.Fill(log10((Double_t) 
event->mc_hits.size()));
 
  354       trks.Fill(track->type);
 
  363     const JVertex3D vertex = neutrino.getVertex();
 
  375       const int    type = hit->type;
 
  376       const double t1   = hit->pure_t;
 
  377       const double npe  = hit->pure_a;
 
  379       npe_pmt[hit->pmt_id].put(npe);
 
  381       npe_type[0]   .put(npe);
 
  382       npe_type[type].put(npe);    
 
  384       if (hit_types.empty() || hit_types.count(type) != 0) {
 
  387                                                     event->mc_trks.end(),
 
  390         if (track == 
event->mc_trks.end()) {
 
  391           ERROR(
"Hit " << *hit << 
" has no origin." << endl);
 
  395         if (count_if(
event->mc_trks.begin(),
 
  396                      event->mc_trks.end(),
 
  398           ERROR(
"Hit " << *hit << 
" has ambiguous origin." << endl);
 
  402         job.Fill((
double) track->type, npe);
 
  404         if (router.hasPMT(hit->pmt_id)) {
 
  406           const JPMT&  pmt  = router.getPMT(hit->pmt_id);
 
  410             const JTrack3E muon = 
getTrack(*track);
 
  412             const double E   = muon.getE();
 
  413             const double x   = log10(E);
 
  414             const double R   = muon.getDistance(pmt);
 
  415             const double t0  = muon.getT       (pmt);
 
  416             const double ct1 = muon.getDot     (pmt);
 
  418             muExR.Fill(x, R,       getMuonWeight(E, npe));
 
  419             muRxU.Fill(R, ct1,     getMuonWeight(E, R, npe));
 
  420             muRxT.Fill(R, t1 - t0, getMuonWeight(E, R, npe));
 
  424             const double E   = neutrino.getE();
 
  425             const double x   = log10(E);
 
  426             const double D   = vertex.getDistance(pmt);
 
  427             const double t0  = vertex.getT(pmt);
 
  428             const double ct0 = neutrino.getDot(pmt.getPosition());
 
  429             const double ct1 = vertex.getDot(pmt);
 
  431             nuExD.Fill(x, D,       getNeutrinoWeight(E, npe));
 
  432             nuExc.Fill(x, ct0,     getNeutrinoWeight(E, npe));
 
  433             nuDxc.Fill(D, ct0,     getNeutrinoWeight(E, D, npe));
 
  434             nuDxU.Fill(D, ct1,     getNeutrinoWeight(E, D, npe));
 
  435             nuDxT.Fill(D, t1 - t0, getNeutrinoWeight(E, D, npe));
 
  446     for (map_type::const_iterator i = npe_pmt.begin(); i != npe_pmt.end(); ++i) {
 
  447       npe_per_pmt.Fill(i->second.getTotal());                     
 
  450     for (map_type::const_iterator i = npe_type.begin(); i != npe_type.end(); ++i) {
 
  451       npe_per_type[i->first]->Fill(i->second.getTotal());         
 
  463         const JTrack3E muon = 
getTrack(*track);
 
  465         const double E   = muon.getE();
 
  466         const double x   = log10(E);
 
  468         for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
 
  470           const double R   = muon.getDistance(*module);
 
  472           muExR_tmp->Fill(x, R, module->size());
 
  474           if (R < muRxU.GetXaxis()->GetXmax()) {
 
  475             for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
 
  476               muRxU_tmp->Fill(R, muon.getDot(*pmt));
 
  480           if (R < muRxT.GetXaxis()->GetXmax()) {
 
  481             for (Int_t iy = 1; iy <= muRxT_tmp->GetYaxis()->GetNbins(); ++iy) {
 
  482               muRxT_tmp->Fill(R, muRxT_tmp->GetYaxis()->GetBinCenter(iy), muRxT_tmp->GetYaxis()->GetBinWidth(iy));
 
  496       const double E   = neutrino.getE();
 
  497       const double x   = log10(E);
 
  499       if (inst_vol.is_inside(vertex))
 
  500         hits_per_E_in .Fill(x, NPE);
 
  502         hits_per_E_out.Fill(x, NPE);
 
  504       for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
 
  506         const double D   = vertex.getDistance(*module);
 
  507         const double ct0 = neutrino.getDot(module->getPosition());
 
  509         nuExD_tmp->Fill(x, D,   module->size());
 
  510         nuExc_tmp->Fill(x, ct0, module->size());
 
  511         nuDxc_tmp->Fill(D, ct0, module->size());
 
  513         if (D < nuDxU.GetXaxis()->GetXmax()) {
 
  514           for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
 
  515             nuDxU_tmp->Fill(D, neutrino.getDot(*pmt));
 
  519         if (D < nuDxT.GetXaxis()->GetXmax()) {
 
  520           for (Int_t iy = 1; iy <= nuDxT_tmp->GetYaxis()->GetNbins(); ++iy) {
 
  521             nuDxT_tmp->Fill(D, nuDxT_tmp->GetYaxis()->GetBinCenter(iy), nuDxT_tmp->GetYaxis()->GetBinWidth(iy));
 
  535   TH1D *job_sorted  = makeSortedH1(&job,  
"hits_by_pdg"); 
 
  536   TH1D *trks_sorted = makeSortedH1(&trks, 
"trks_sorted"); 
 
  538   if (inputFile.getCounter() != 0) {
 
  540     const Double_t W = 1.0 / ((Double_t) inputFile.getCounter());
 
  542     for (TH1D* buffer[] = { &hits, &npe_per_pmt, &job, &trks, job_sorted, trks_sorted, NULL }, **i = buffer; *i != NULL; ++i) {
 
  546     for (JManager_t::iterator i = npe_per_type.begin(); i != npe_per_type.end(); ++i) {
 
  550     nuExD.Divide(nuExD_tmp);
 
  551     nuExc.Divide(nuExc_tmp);
 
  552     nuDxc.Divide(nuDxc_tmp);
 
  553     nuDxU.Divide(nuDxU_tmp);
 
  554     nuDxT.Divide(nuDxT_tmp);
 
  556     muExR.Divide(muExR_tmp);
 
  557     muRxU.Divide(muRxU_tmp);
 
  558     muRxT.Divide(muRxT_tmp);
 
  568   out << hits << job << *job_sorted << trks << *trks_sorted << hits_per_E_in << hits_per_E_out << npe_per_type << npe_per_pmt;
 
  570   out << nuExD << nuExc << nuDxc << nuDxU << nuDxT;
 
  571   out << muExR << muRxU << muRxT;
 
Utility class to parse command line options. 
 
static const JGeane gWater(2.67e-1 *JTOOLS::DENSITY_SEA_WATER, 3.4e-4 *JTOOLS::DENSITY_SEA_WATER)
Function object for Energy loss of muon in sea water. 
 
JPredicate< JResult_t T::*, JComparison::eq > make_predicate(JResult_t T::*member, const JResult_t value)
Helper method to create predicate for data member. 
 
JTrack3E getTrack(const Trk &track)
Get track. 
 
double geanc()
Equivalent muon track length per unit shower energy. 
 
Auxiliary class to manage set of histograms. 
 
bool has_neutrino(const Evt &evt)
Test whether given event has an incoming neutrino. 
 
bool is_muon(const Trk &track)
Test whether given track is a (anti-)muon. 
 
double getB() const 
Get energy loss constant. 
 
Structure to store the ToT mean and standard deviation of the hits produced by a nanobeacon in a sour...
 
#define MAKE_CSTRING(A)
Make C-string. 
 
Empty structure for specification of parser element that is initialised (i.e. 
 
Dynamic ROOT object management. 
 
size_t getSize(T(&array)[N])
Get size of c-array. 
 
Data structure for detector geometry and calibration. 
 
Head getHeader(const JMultipleFileScanner_t &file_list)
Get Monte Carlo header. 
 
JLimit JLimit_t
Type definition of limit. 
 
I/O formatting auxiliaries. 
 
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object 
 
void load(const JString &file_name, JDetector &detector)
Load detector from input file. 
 
Direct access to PMT in detector data structure. 
 
General purpose messaging. 
 
Scanning of objects from multiple files according a format that follows from the extension of each fi...
 
Utility class to parse command line options. 
 
ROOT TTree parameter settings. 
 
const JLimit & getLimit() const 
Get limit. 
 
const Trk & get_neutrino(const Evt &evt)
Get incoming neutrino. 
 
#define DEBUG(A)
Message macros. 
 
int main(int argc, char *argv[])