GSimpleNtpFlux.cxx
Go to the documentation of this file.
1 //____________________________________________________________________________
2 /*
3  Copyright (c) 2003-2020, The GENIE Collaboration
4  For the full text of the license visit http://copyright.genie-mc.org
5 
6  Robert Hatcher <rhatcher@fnal.gov>
7  Fermi National Accelerator Laboratory
8 */
9 //____________________________________________________________________________
10 
11 #include <cstdlib>
12 #include <fstream>
13 #include <sstream>
14 #include <cassert>
15 #include <limits.h>
16 #include <algorithm>
17 
18 #include <TFile.h>
19 #include <TChain.h>
20 #include <TChainElement.h>
21 #include <TSystem.h>
22 #include <TStopwatch.h>
23 
25 #include "Framework/Conventions/GBuild.h"
26 
28 
37 
38 using std::endl;
39 
40 #include <vector>
41 #include <algorithm>
42 #include <iomanip>
43 #include "TRegexp.h"
44 #include "TString.h"
45 
48 
49 //#define __GENIE_LOW_LEVEL_MESG_ENABLED__
50 // next line won't work for NOvA: ROOT's Error() != DefaultErrorHandler
51 //#define USE_INDEX_FOR_META
52 
53 using namespace genie;
54 using namespace genie::flux;
55 
61 
62 // static storage
63 UInt_t genie::flux::GSimpleNtpMeta::mxfileprint = UINT_MAX;
64 
65 //____________________________________________________________________________
67  GFluxExposureI(genie::flux::kPOTs)
68 {
69  this->Initialize();
70 }
71 //___________________________________________________________________________
72 GSimpleNtpFlux::~GSimpleNtpFlux()
73 {
74  this->CleanUp();
75 }
76 //___________________________________________________________________________
78 {
79  // complete the GFluxExposureI interface
80  return UsedPOTs();
81 }
82 //___________________________________________________________________________
83 long int GSimpleNtpFlux::NFluxNeutrinos(void) const
84 {
85  ///< number of flux neutrinos looped so far
86  return fNNeutrinos;
87 }
88 //___________________________________________________________________________
90 {
91 // Get next (unweighted) flux ntuple entry on the specified detector location
92 //
94  while ( true ) {
95  // Check for end of flux ntuple
96  bool end = this->End();
97  if ( end ) {
98  LOG("Flux", pNOTICE) << "GenerateNext signaled End() ";
99  return false;
100  }
101 
102  // Get next weighted flux ntuple entry
103  bool nextok = this->GenerateNext_weighted();
104  if ( fGenWeighted ) return nextok;
105  if ( ! nextok ) continue;
106  if ( fAlreadyUnwgt ) return true;
107 
108  /* RWH - debug purposes
109  if ( fNCycles == 0 ) {
110  LOG("Flux", pNOTICE)
111  << "Got flux entry: " << fIEntry
112  << " - Cycle: "<< fICycle << "/ infinite";
113  } else {
114  LOG("Flux", pNOTICE)
115  << "Got flux entry: "<< fIEntry
116  << " - Cycle: "<< fICycle << "/"<< fNCycles;
117  }
118  */
119 
120  // Get fractional weight & decide whether to accept curr flux neutrino
121  double f = this->Weight() / fMaxWeight;
122  //LOG("Flux", pNOTICE)
123  // << "Curr flux neutrino fractional weight = " << f;
124  if (f > 1.) {
125  fMaxWeight = this->Weight() * 1.01; // bump the weight
126  LOG("Flux", pERROR)
127  << "** Fractional weight = " << f
128  << " > 1 !! Bump fMaxWeight estimate to " << fMaxWeight
129  << GetCurrentEntry();
130  std::cout << std::flush;
131  }
132  double r = (f < 1.) ? rnd->RndFlux().Rndm() : 0;
133  bool accept = ( r < f );
134  if ( accept ) {
135 
136 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
137  LOG("Flux", pNOTICE)
138  << "Generated beam neutrino: "
139  << "\n pdg-code: " << fCurEntry->pdg
140  << "\n p4: " << utils::print::P4AsShortString(&(fP4))
141  << "\n x4: " << utils::print::X4AsString(&(fX4));
142 #endif
143 
144  fWeight = 1.;
145  return true;
146  }
147 
148  //LOG("Flux", pNOTICE)
149  // << "** Rejecting current flux neutrino based on the flux weight only";
150  }
151  return false;
152 }
153 //___________________________________________________________________________
155 {
156 // Get next (weighted) flux ntuple entry
157 //
158 
159  // Check whether a flux ntuple has been loaded
160  if ( ! fNuFluxTree ) {
161  LOG("Flux", pFATAL)
162  << "The flux driver has not been properly configured";
163  // return false; // don't do this - creates an infinite loop!
164  exit(1);
165  }
166 
167  // Reuse an entry?
168  //std::cout << " ***** iuse " << fIUse << " nuse " << fNUse
169  // << " ientry " << fIEntry << " nentry " << fNEntries
170  // << " icycle " << fICycle << " ncycle " << fNCycles << std::endl;
171  if ( fIUse < fNUse && fIEntry >= 0 ) {
172  // Reuse this entry
173  fIUse++;
174  } else {
175  // Reset previously generated neutrino code / 4-p / 4-x
176  this->ResetCurrent();
177  // Move on, read next flux ntuple entry
178  ++fIEntry;
179  ++fNEntriesUsed; // count total # used
180  if ( fIEntry >= fNEntries ) {
181  // Ran out of entries @ the current cycle of this flux file
182  // Check whether more (or infinite) number of cycles is requested
183  if (fICycle < fNCycles || fNCycles == 0 ) {
184  fICycle++;
185  fIEntry=0;
186  } else {
187  LOG("Flux", pWARN)
188  << "No more entries in input flux neutrino ntuple, cycle "
189  << fICycle << " of " << fNCycles;
190  fEnd = true;
191  //assert(0);
192  return false;
193  }
194  }
195 
196  int nbytes = fNuFluxTree->GetEntry(fIEntry);
197  UInt_t metakey = fCurEntry->metakey;
198  if ( fAllFilesMeta && ( fCurMeta->metakey != metakey ) ) {
199  UInt_t oldkey = fCurMeta->metakey;
200 #ifdef USE_INDEX_FOR_META
201  int nbmeta = fNuMetaTree->GetEntryWithIndex(metakey);
202 #else
203  // unordered indices makes ROOT call Error() which might,
204  // if not DefaultErrorHandler, be fatal.
205  // so find the right one by a simple linear search.
206  // not a large burden since it only happens infrequently and
207  // the list is normally quite short.
208  int nmeta = fNuMetaTree->GetEntries();
209  int nbmeta = 0;
210  for (int imeta = 0; imeta < nmeta; ++imeta ) {
211  nbmeta = fNuMetaTree->GetEntry(imeta);
212  if ( fCurMeta->metakey == metakey ) break;
213  }
214  // next condition should never happen
215  if ( fCurMeta->metakey != metakey ) {
216  fCurMeta = 0; // didn't find it!?
217  LOG("Flux",pERROR) << "Failed to find right metakey=" << metakey
218  << " (was " << oldkey << ") out of " << nmeta
219  << " entries";
220  }
221 #endif
222  LOG("Flux",pDEBUG) << "Get meta " << metakey
223  << " (was " << oldkey << ") "
224  << fCurMeta->metakey
225  << " nb " << nbytes << " " << nbmeta;
226 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
227  LOG("Flux",pDEBUG) << "Get meta " << *fCurMeta;
228 #endif
229  }
230 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
231  Int_t ifile = fNuFluxTree->GetFileNumber();
232  LOG("Flux",pDEBUG)
233  << "got " << fNNeutrinos << " nu, using fIEntry " << fIEntry
234  << " ifile " << ifile << " nbytes " << nbytes
235  << *fCurEntry << *fCurMeta;
236 #endif
237 
238  fIUse = 1;
239 
240  // here we might want to do flavor oscillations or simple mappings
241  //RWH modify: fPdgC = fCurEntry->pdg;
242 
243  // Check neutrino pdg against declared list of neutrino species declared
244  // by the current instance of the NuMI neutrino flux driver.
245  // No undeclared neutrino species will be accepted at this point as GENIE
246  // has already been configured to handle the specified list.
247  // Make sure that the appropriate list of flux neutrino species was set at
248  // initialization via GSimpleNtpFlux::SetFluxParticles(const PDGCodeList &)
249 
250  // update the # POTs, sum of weights & number of neutrinos
251  // do this HERE (before rejecting flavors that users might be weeding out)
252  // in order to keep the POT accounting correct. This allows one to get
253  // the right normalization for generating only events from the intrinsic
254  // nu_e entries.
256  fSumWeight += this->Weight();
257  fNNeutrinos++;
258 
260  /// user might modify list via SetFluxParticles() in order to reject certain
261  /// flavors, even if they're found in the file. So don't make a big fuss.
262  /// Spit out a single message and then stop reporting that flavor as problematic.
263  int badpdg = fCurEntry->pdg;
264  if ( ! fPdgCListRej->ExistsInPDGCodeList(badpdg) ) {
265  fPdgCListRej->push_back(badpdg);
266  LOG("Flux", pWARN)
267  << "Encountered neutrino specie (" << badpdg
268  << ") that wasn't in SetFluxParticles() list, "
269  << "\nDeclared list of neutrino species: " << *fPdgCList;
270  }
271  return false;
272  }
273 
274  }
275 
276  // Update the curr neutrino p4/x4 lorentz vector
277  double Ev = fCurEntry->E;
278  fP4.SetPxPyPzE(fCurEntry->px,fCurEntry->py,fCurEntry->pz,Ev);
279  double t0 = ((fIncludeVtxt) ? fCurEntry->vtxt : 0 );
280  fX4.SetXYZT(fCurEntry->vtxx,fCurEntry->vtxy,fCurEntry->vtxz,t0);
281 
282  fWeight = fCurEntry->wgt;
283 
284  if (Ev > fMaxEv) {
285  LOG("Flux", pWARN)
286  << "Flux neutrino energy exceeds declared maximum neutrino energy"
287  << "\nEv = " << Ev << "(> Ev{max} = " << fMaxEv << ")";
288  }
289 
290  // if desired, move to user specified user coord z
291  if ( TMath::Abs(fZ0) < 1.0e30 ) this->MoveToZ0(fZ0);
292 
293 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
294  LOG("Flux", pINFO)
295  << "Generated neutrino: " << fIEntry
296 #ifdef NOT_YET
297  << " run " << fCurNuMI->evtno
298  << " evtno " << fCurNuMI->evtno
299  << " entryno " << fCurNuMI->entryno
300 #endif
301  << "\n pdg-code: " << fCurEntry->pdg << " wgt " << fCurEntry->wgt
302  << "\n p4: " << utils::print::P4AsShortString(&fP4)
303  << "\n x4: " << utils::print::X4AsString(&fX4);
304 #endif
305  if ( Ev > fMaxEv ) {
306  LOG("Flux", pFATAL)
307  << "Generated neutrino had E_nu = " << Ev << " > " << fMaxEv
308  << " maximum ";
309  assert(0);
310  }
311 
312  return true;
313 }
314 //___________________________________________________________________________
316 {
317  // return distance (user units) between dk point and start position
318  // these are in beam units
319  return fCurEntry->dist;
320 }
321 //___________________________________________________________________________
322 void GSimpleNtpFlux::MoveToZ0(double z0usr)
323 {
324  // move ray origin to specified user z0
325  // move beam coord entry correspondingly
326 
327  double pzusr = fP4.Pz();
328  if ( TMath::Abs(pzusr) < 1.0e-30 ) {
329  // neutrino is moving almost entirely in x-y plane
330  LOG("Flux", pWARN)
331  << "MoveToZ0(" << z0usr << ") not possible due to pz_usr (" << pzusr << ")";
332  return;
333  }
334 
335  double scale = (z0usr - fX4.Z()) / pzusr;
336  //LOG("Flux",pDEBUG)
337  // << "MoveToZ0: before x4=(" << fX4.X() << "," << fX4.Y() << "," << fX4.Z()
338  // << ") z0=" << z0usr << " pzusr=" << pzusr
339  // << " p4=(" << fP4.Px() << "," << fP4.Py() << "," << fP4.Pz() << ")";
340  fX4 += (scale*fP4);
341  //LOG("Flux",pDEBUG)
342  // << "MoveToZ0: after (" << fX4.X() << "," << fX4.Y() << "," << fX4.Z()
343  // << ")";
344 
345  // this scaling works for distances, but not the time component
346  fX4.SetT(0);
347 
348 }
349 
350 //___________________________________________________________________________
352 {
353  // do this if flux window changes or # of files changes
354 
355  if (!fNuFluxTree) return; // not yet fully configured
356 
357  fEffPOTsPerNu = ( (double)fFilePOTs / (double)fNEntries );
358 }
359 
360 //___________________________________________________________________________
361 double GSimpleNtpFlux::UsedPOTs(void) const
362 {
363 // Compute current number of flux POTs
364 
365  if (!fNuFluxTree) {
366  LOG("Flux", pWARN)
367  << "The flux driver has not been properly configured";
368  return 0;
369  }
370  return fAccumPOTs;
371 }
372 
373 //___________________________________________________________________________
374 void GSimpleNtpFlux::LoadBeamSimData(const std::vector<string>& patterns,
375  const std::string& config )
376 {
377 // Loads a beam simulation root file into the GSimpleNtpFlux driver.
378 
379  fNuFluxFilePatterns = patterns;
380  std::vector<int> nfiles_from_pattern;
381 
382  // create a (sorted) set of file names
383  // this also helps ensure that the same file isn't listed multiple times
384  std::set<std::string> fnames;
385 
386  LOG("Flux", pINFO) << "LoadBeamSimData was passed " << patterns.size()
387  << " patterns";
388 
389  for (size_t ipatt = 0; ipatt < patterns.size(); ++ipatt ) {
390  string pattern = patterns[ipatt];
391  nfiles_from_pattern.push_back(0);
392  LOG("Flux", pINFO)
393  << "Loading flux tree from ROOT file pattern ["
394  << std::setw(3) << ipatt << "] \"" << pattern << "\"";
395 
396  // !WILDCARD only works for file name ... NOT directory
397  string dirname = gSystem->UnixPathName(gSystem->WorkingDirectory());
398  size_t slashpos = pattern.find_last_of("/");
399  size_t fbegin;
400  if ( slashpos != std::string::npos ) {
401  dirname = pattern.substr(0,slashpos);
402  LOG("Flux", pDEBUG) << "Look for flux using directory " << dirname;
403  fbegin = slashpos + 1;
404  } else { fbegin = 0; }
405 
406  void* dirp = gSystem->OpenDirectory(gSystem->ExpandPathName(dirname.c_str()));
407  if ( dirp ) {
409  pattern.substr(fbegin,pattern.size()-fbegin);
410  TRegexp re(basename.c_str(),kTRUE);
411  const char* onefile;
412  while ( ( onefile = gSystem->GetDirEntry(dirp) ) ) {
413  TString afile = onefile;
414  if ( afile=="." || afile==".." ) continue;
415  if ( basename!=afile && afile.Index(re) == kNPOS ) continue;
416  std::string fullname = dirname + "/" + afile.Data();
417  fnames.insert(fullname);
418  nfiles_from_pattern[ipatt]++;
419  }
420  gSystem->FreeDirectory(dirp);
421  } // legal directory
422  } // loop over patterns
423 
424  size_t indx = 0;
425  std::set<string>::const_iterator sitr = fnames.begin();
426  for ( ; sitr != fnames.end(); ++sitr, ++indx) {
427  string filename = *sitr;
428  //std::cout << " [" << std::setw(3) << indx << "] \""
429  // << filename << "\"" << std::endl;
430  bool isok = true;
431  // this next test only works for local files, so we can't do that
432  // if we want to stream via xrootd
433  // ! (gSystem->AccessPathName(filename.c_str()));
434  if ( ! isok ) continue;
435  // open the file to see what it contains
436  LOG("Flux", pINFO) << "Load file " << filename;
437 
438  TFile* tf = TFile::Open(filename.c_str(),"READ");
439  TTree* etree = (TTree*)tf->Get("flux");
440  if ( etree ) {
441  TTree* mtree = (TTree*)tf->Get("meta");
442  // add the file to the chain
443  LOG("Flux", pDEBUG) << "AddFile " << filename
444  << " etree " << etree << " meta " << mtree;
445  this->AddFile(etree,mtree,filename);
446 
447  } // found a GSimpleNtpEntry "flux" tree
448  tf->Close();
449  delete tf;
450  } // loop over sorted file names
451 
452  // this will open all files and read headers!!
453  fNEntries = fNuFluxTree->GetEntries();
454 
455  if ( fNEntries == 0 ) {
456  LOG("Flux", pERROR)
457  << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
458  LOG("Flux", pERROR)
459  << "Loaded flux tree contains " << fNEntries << " entries";
460  LOG("Flux", pERROR)
461  << "Was passed the file patterns: ";
462  for (size_t ipatt = 0; ipatt < patterns.size(); ++ipatt ) {
463  string pattern = patterns[ipatt];
464  LOG("Flux", pERROR)
465  << " [" << std::setw(3) << ipatt <<"] " << pattern;
466  }
467  LOG("Flux", pERROR)
468  << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
469  } else {
470  LOG("Flux", pNOTICE)
471  << "Loaded flux tree contains " << fNEntries << " entries"
472  << " from " << fnames.size() << " unique files";
473  for (size_t ipatt = 0; ipatt < patterns.size(); ++ipatt ) {
474  string pattern = patterns[ipatt];
475  LOG("Flux", pINFO)
476  << " pattern: " << pattern << " yielded "
477  << nfiles_from_pattern[ipatt] << " files";
478  }
479  }
480 
481  int sba_status[3] = { -999, -999, -999 };
482  // "entry" branch isn't optional ... contains the neutrino info
483 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,0)
484  sba_status[0] =
485 #endif
486  fNuFluxTree->SetBranchAddress("entry",&fCurEntry);
487 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,0)
488  if ( sba_status[0] < 0 ) {
489  LOG("Flux", pFATAL)
490  << "flux chain has no \"entry\" branch " << sba_status[0];
491  assert(0);
492  }
493 #endif
494  //TBranch* bentry = fNuFluxTree->GetBranch("entry");
495  //bentry->SetAutoDelete(false);
496 
497  if ( OptionalAttachBranch("numi") ) {
498 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,0)
499  sba_status[1] =
500 #endif
501  fNuFluxTree->SetBranchAddress("numi",&fCurNuMI);
502  //TBranch* bnumi = fNuFluxTree->GetBranch("numi");
503  //bnumi->SetAutoDelete(false);
504  } else { delete fCurNuMI; fCurNuMI = 0; }
505 
506  if ( OptionalAttachBranch("aux") ) {
507 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,0)
508  sba_status[2] =
509 #endif
510  fNuFluxTree->SetBranchAddress("aux",&fCurAux);
511  //TBranch* baux = fNuFluxTree->GetBranch("aux");
512  //baux->SetAutoDelete(false);
513  } else { delete fCurAux; fCurAux = 0; }
514 
515  LOG("Flux", pDEBUG)
516  << " SetBranchAddress status: "
517  << " \"entry\"=" << sba_status[0]
518  << " \"numi\"=" << sba_status[1]
519  << " \"aux\"=" << sba_status[2];
520 
521  // attach requested branches
522 
523  if (fMaxWeight<=0) {
524  LOG("Flux", pDEBUG)
525  << "Run ProcessMeta() as part of LoadBeamSimData";
526  this->ProcessMeta();
527  }
528 
529  // current ntuple cycle # (flux ntuples may be recycled)
530  fICycle = 0;
531  // pick a starting entry index [0:fNEntries-1]
532  // pretend we just used up the the previous one
534  fIUse = 9999999;
535  fIEntry = rnd->RndFlux().Integer(fNEntries) - 1;
536  if ( config.find("no-offset-index") != string::npos ) {
537  LOG("Flux",pINFO) << "Config saw \"no-offset-index\"";
538  fIEntry = -1;
539  }
540  LOG("Flux",pINFO) << "Start with entry fIEntry=" << fIEntry;
541 
542  // don't count things we used to estimate max weight
543  fNEntriesUsed = 0;
544  fSumWeight = 0;
545  fNNeutrinos = 0;
546  fAccumPOTs = 0;
547 
548  LOG("Flux",pDEBUG) << "about to CalcEffPOTsPerNu";
549  this->CalcEffPOTsPerNu();
550 
551 }
552 //___________________________________________________________________________
553 void GSimpleNtpFlux::GetBranchInfo(std::vector<std::string>& branchNames,
554  std::vector<std::string>& branchClassNames,
555  std::vector<void**>& branchObjPointers)
556 {
557  // allow flux driver to report back current status and/or ntuple entry
558  // info for possible recording in the output file by supplying
559  // the class name, and a pointer to the object that will be filled
560  // as well as a suggested name for the branch.
561 
562  if ( fCurEntry ) {
563  branchNames.push_back("simple");
564  branchClassNames.push_back("genie::flux::GSimpleNtpEntry");
565  branchObjPointers.push_back((void**)&fCurEntry);
566  }
567 
568  if ( fCurNuMI ) {
569  branchNames.push_back("numi");
570  branchClassNames.push_back("genie::flux::GSimpleNtpNuMI");
571  branchObjPointers.push_back((void**)&fCurNuMI);
572  }
573 
574  if ( fCurAux ) {
575  branchNames.push_back("aux");
576  branchClassNames.push_back("genie::flux::GSimpleNtpAux");
577  branchObjPointers.push_back((void**)&fCurAux);
578  }
579 }
581 
582 //___________________________________________________________________________
584 {
585 
586  fAlreadyUnwgt = false;
587  fFilePOTs = 0;
588  double minwgt = +1.0e10;
589  double maxwgt = -1.0e10;
590  double maxenu = 0.0;
591 
592  // PDGLibrary* pdglib = PDGLibrary::Instance(); // get initialized now
593 
594  if ( fAllFilesMeta ) {
595  fNuMetaTree->SetBranchAddress("meta",&fCurMeta);
596 #ifdef USE_INDEX_FOR_META
597  int nindices = fNuMetaTree->BuildIndex("metakey"); // key used to tie entries to meta data
598  LOG("Flux", pDEBUG) << "ProcessMeta() BuildIndex nindices " << nindices;
599 #endif
600  int nmeta = fNuMetaTree->GetEntries();
601  for (int imeta = 0; imeta < nmeta; ++imeta ) {
602  fNuMetaTree->GetEntry(imeta);
603 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
604  LOG("Flux", pNOTICE) << "ProcessMeta() ifile " << imeta
605  << " (of " << fNFiles
606  << ") " << *fCurMeta;
607 #endif
608  minwgt = TMath::Min(minwgt,fCurMeta->minWgt);
609  maxwgt = TMath::Max(maxwgt,fCurMeta->maxWgt);
610  maxenu = TMath::Max(maxenu,fCurMeta->maxEnergy);
611  fFilePOTs += fCurMeta->protons;
612  for (size_t i = 0; i < fCurMeta->pdglist.size(); ++i)
613  fPdgCList->push_back(fCurMeta->pdglist[i]);
614  }
615  if ( minwgt == 1.0 && maxwgt == 1.0 ) fAlreadyUnwgt = true;
616  fMaxWeight = maxwgt;
617  this->SetMaxEnergy(maxenu);
618 
619  } else {
620  //
621  LOG("Flux", pFATAL) << "ProcessMeta() not all files have metadata";
622  // for now PUNT ... eventually could scan all the entries
623  }
624 
625 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
626  LOG("Flux", pNOTICE) << "ProcessMeta() Maximum flux weight = " << fMaxWeight
627  << ", energy = " << fMaxEv
628  << ", AlreadyUnwgt=" << (fAlreadyUnwgt?"true":"false");
629 #endif
630 
631  fCurMeta->Reset();
632  fIFileNumber = -999;
633 
634 }
635 //___________________________________________________________________________
637 {
638  fMaxEv = TMath::Max(0.,Ev);
639 
640  LOG("Flux", pINFO)
641  << "Declared maximum flux neutrino energy: " << fMaxEv;
642 }
643 //___________________________________________________________________________
644 void GSimpleNtpFlux::SetEntryReuse(long int nuse)
645 {
646 // With nuse > 1 then the same entry in the file is used "nuse" times
647 // before moving on to the next entry in the ntuple
648 
649  fNUse = TMath::Max(1L, nuse);
650 }
651 //___________________________________________________________________________
652 void GSimpleNtpFlux::GetFluxWindow(TVector3& p0, TVector3& p1, TVector3& p2) const
653 {
654  // return flux window points
655 
656  p0 = TVector3(fCurMeta->windowBase[0],
657  fCurMeta->windowBase[1],
658  fCurMeta->windowBase[2]);
659  p1 = p0 + TVector3(fCurMeta->windowDir1[0],
660  fCurMeta->windowDir1[1],
661  fCurMeta->windowDir1[2]);
662  p2 = p0 + TVector3(fCurMeta->windowDir2[0],
663  fCurMeta->windowDir2[1],
664  fCurMeta->windowDir2[2]);
665 
666 }
667 
668 //___________________________________________________________________________
670 {
671  LOG("Flux", pNOTICE) << "CurrentEntry:" << *fCurEntry;
672 }
673 //___________________________________________________________________________
674 void GSimpleNtpFlux::Clear(Option_t * opt)
675 {
676 // Clear the driver state
677 //
678  LOG("Flux", pWARN) << "GSimpleNtpFlux::Clear(" << opt << ") called";
679  // do it in all cases, but EVGDriver/GMCJDriver will pass "CycleHistory"
680 
681  fICycle = 0;
682 
683  fSumWeight = 0;
684  fNNeutrinos = 0;
685  fAccumPOTs = 0;
686 
687 }
688 //___________________________________________________________________________
689 void GSimpleNtpFlux::GenerateWeighted(bool gen_weighted)
690 {
691 // Set whether to generate weighted rays
692 //
693  fGenWeighted = gen_weighted;
694 }
695 //___________________________________________________________________________
697 {
698  LOG("Flux", pINFO) << "Initializing GSimpleNtpFlux driver";
699 
700  fMaxEv = 0;
701  fEnd = false;
702 
704  fCurNuMI = new GSimpleNtpNuMI;
705  fCurAux = new GSimpleNtpAux;
706  fCurMeta = new GSimpleNtpMeta;
707 
708  fCurEntryCopy = 0;
709  fCurNuMICopy = 0;
710  fCurAuxCopy = 0;
711 
712  fNuFluxTree = new TChain("flux");
713  fNuMetaTree = new TChain("meta");
714 
715  //fNuFluxFilePatterns = "";
716  fNuFluxBranchRequest = "entry,numi,aux"; // all branches
717 
718  fNFiles = 0;
719 
720  fNEntries = 0;
721  fIEntry = -1;
722  fIFileNumber = 0;
723  fICycle = 0;
724  fNUse = 1;
725  fIUse = 999999;
726 
727  fFilePOTs = 0;
728 
729  fMaxWeight = -1;
730 
731  fSumWeight = 0;
732  fNNeutrinos = 0;
733  fNEntriesUsed = 0;
734  fEffPOTsPerNu = 0;
735  fAccumPOTs = 0;
736 
737  fGenWeighted = false;
738  fAllFilesMeta = true;
739  fAlreadyUnwgt = false;
740 
741  fIncludeVtxt = false;
742 
743  this->SetDefaults();
744  this->ResetCurrent();
745 }
746 //___________________________________________________________________________
748 {
749 
750 // - Set the default flux neutrino start z position at use flux window
751 // - Set number of cycles to 1
752 
753  LOG("Flux", pINFO) << "Setting default GSimpleNtpFlux driver options";
754 
755  this->SetUpstreamZ (-3.4e38); // way upstream ==> use flux window
756  this->SetNumOfCycles (0);
757  this->SetEntryReuse (1);
758 }
759 //___________________________________________________________________________
761 {
762 // reset running values of neutrino pdg-code, 4-position & 4-momentum
763 // and the input ntuple leaves
764 
765  if (fCurEntry) fCurEntry->Reset();
766  if (fCurNuMI) fCurNuMI->Reset();
767  if (fCurAux) fCurAux->Reset();
768  //allow caching//if (fCurMeta) fCurMeta->Reset();
769 }
770 //___________________________________________________________________________
772 {
773  LOG("Flux", pINFO) << "Cleaning up...";
774 
775  if (fPdgCList) delete fPdgCList;
776  if (fPdgCListRej) delete fPdgCListRej;
777  if (fCurEntry) delete fCurEntry;
778  if (fCurNuMI) delete fCurNuMI;
779  if (fCurAux) delete fCurAux;
780  if (fCurMeta) delete fCurMeta;
781 
782  if (fNuFluxTree) delete fNuFluxTree;
783  if (fNuMetaTree) delete fNuMetaTree;
784 
785  LOG("Flux", pNOTICE)
786  << " flux file cycles: " << fICycle << " of " << fNCycles
787  << ", entry " << fIEntry << " use: " << fIUse << " of " << fNUse;
788 }
789 
790 //___________________________________________________________________________
791 void GSimpleNtpFlux::AddFile(TTree* fluxtree, TTree* metatree, string fname)
792 {
793  // Add a file to the chain
794  if ( ! fluxtree ) return;
795 
796  ULong64_t nentries = fluxtree->GetEntries();
797 
798  int stat = fNuFluxTree->AddFile(fname.c_str());
799  if ( metatree ) fNuMetaTree->AddFile(fname.c_str());
800  else fAllFilesMeta = false;
801 
802  LOG("Flux",pINFO)
803  << "flux->AddFile() of " << nentries
804  << " " << ((metatree)?"[+meta]":"[no-meta]")
805  << " [status=" << stat << "]"
806  << " entries in file: " << fname;
807 
808  if ( stat != 1 ) return;
809 
810  fNFiles++;
811 
812 }
813 
814 //___________________________________________________________________________
815 
817 {
818 
819  if ( fNuFluxBranchRequest.find(name) == string::npos ) {
820  LOG("Flux", pINFO)
821  << "no request for \"" << name <<"\" branch ";
822  return false;
823  }
824 
825  if ( ( fNuFluxTree->GetBranch(name.c_str()) ) ) return true;
826 
827  LOG("Flux", pINFO)
828  << "no \"" << name << "\" branch in the \"flux\" tree";
829  return false;
830 }
831 
832 //___________________________________________________________________________
834 
836 {
837  wgt = 0.;
838  vtxx = 0.;
839  vtxy = 0.;
840  vtxz = 0.;
841  vtxt = 0.;
842  dist = 0.;
843  px = 0.;
844  py = 0.;
845  pz = 0.;
846  E = 0.;
847 
848  pdg = 0;
849  metakey = 0;
850 }
851 
852 void GSimpleNtpEntry::Print(const Option_t* /* opt */ ) const
853 {
854  std::cout << *this << std::endl;
855 }
856 
857 //___________________________________________________________________________
859 
861 {
862  tpx = tpy = tpz = 0.;
863  vx = vy = vz = 0.;
864  pdpx = pdpy = pdpz = 0.;
865  pppx = pppy = pppz = 0.;
866 
867  ndecay = 0;
868  ptype = 0;
869  ppmedium = 0;
870  tptype = 0;
871  run = -1;
872  evtno = -1;
873  entryno = -1;
874 }
875 
876 void GSimpleNtpNuMI::Print(const Option_t* /* opt */ ) const
877 {
878  std::cout << *this << std::endl;
879 }
880 
881 //___________________________________________________________________________
883 
885 {
886  auxint.clear();
887  auxdbl.clear();
888 }
889 
890 void GSimpleNtpAux::Print(const Option_t* /* opt */ ) const
891 {
892  std::cout << *this << std::endl;
893 }
894 
895 //___________________________________________________________________________
896 
897 
899  : TObject() //, nflavors(0), flavor(0)
900 {
901  Reset();
902 }
903 
905 {
906  Reset();
907 }
908 
910 {
911 
912  pdglist.clear();
913  maxEnergy = 0.;
914  minWgt = 0.;
915  maxWgt = 0.;
916  protons = 0.;
917  windowBase[0] = 0.;
918  windowBase[1] = 0.;
919  windowBase[2] = 0.;
920  windowDir1[0] = 0.;
921  windowDir1[1] = 0.;
922  windowDir1[2] = 0.;
923  windowDir2[0] = 0.;
924  windowDir2[1] = 0.;
925  windowDir2[2] = 0.;
926 
927  auxintname.clear();
928  auxdblname.clear();
929  infiles.clear();
930 
931  seed = 0;
932  metakey = 0;
933 }
934 
935 void GSimpleNtpMeta::AddFlavor(Int_t nupdg)
936 {
937  bool found = false;
938  for (size_t i=0; i < pdglist.size(); ++i)
939  if ( pdglist[i] == nupdg) found = true;
940  if ( ! found ) pdglist.push_back(nupdg);
941 
942  /* // OLD fashion array
943  bool found = false;
944  for (int i=0; i < nflavors; ++i) if ( flavor[i] == nupdg ) found = true;
945  if ( ! found ) {
946  Int_t* old_list = flavor;
947  flavor = new Int_t[nflavors+1];
948  for (int i=0; i < nflavors; ++i) flavor[i] = old_list[i];
949  flavor[nflavors] = nupdg;
950  nflavors++;
951  delete [] old_list;
952  }
953  */
954 }
955 
956 void GSimpleNtpMeta::Print(const Option_t* /* opt */ ) const
957 {
958  std::cout << *this << std::endl;
959 }
960 
961 //___________________________________________________________________________
962 
963 
964 namespace genie {
965 namespace flux {
966 
967  ostream & operator << (
968  ostream & stream, const genie::flux::GSimpleNtpEntry & entry)
969  {
970  stream << "\nGSimpleNtpEntry "
971  << " PDG " << entry.pdg
972  << " wgt " << entry.wgt
973  << " ( metakey " << entry.metakey << " )"
974  << "\n vtx [" << entry.vtxx << "," << entry.vtxy << ","
975  << entry.vtxz << ", t=" << entry.vtxt << "] dist " << entry.dist
976  << "\n p4 [" << entry.px << "," << entry.py << ","
977  << entry.pz << "," << entry.E << "]";
978  return stream;
979  }
980 
981 
982 ostream & operator << (ostream & stream,
983  const genie::flux::GSimpleNtpNuMI & numi)
984 {
985  stream << "\nGSimpleNtpNuMI "
986  << "run " << numi.run
987  << " evtno " << numi.evtno
988  << " entryno " << numi.entryno
989  << "\n ndecay " << numi.ndecay << " ptype " << numi.ptype
990  << "\n tptype " << numi.tptype << " ppmedium " << numi.ppmedium
991  << "\n tp[xyz] [" << numi.tpx << "," << numi.tpy << "," << numi.tpz << "]"
992  << "\n v[xyz] [" << numi.vx << "," << numi.vy << "," << numi.vz << "]"
993  << "\n pd[xyz] [" << numi.pdpx << "," << numi.pdpy << "," << numi.pdpz << "]"
994  << "\n pp[xyz] [" << numi.pppx << "," << numi.pppy << "," << numi.pppz << "]"
995  ;
996  return stream;
997 }
998 
999  ostream & operator << (
1000  ostream & stream, const genie::flux::GSimpleNtpAux & aux)
1001  {
1002  stream << "\nGSimpleNtpAux ";
1003  size_t nInt = aux.auxint.size();
1004  stream << "\n ints: ";
1005  for (size_t ijInt=0; ijInt < nInt; ++ijInt)
1006  stream << " " << aux.auxint[ijInt];
1007  size_t nDbl = aux.auxdbl.size();
1008  stream << "\n doubles: ";
1009  for (size_t ijDbl=0; ijDbl < nDbl; ++ijDbl)
1010  stream << " " << aux.auxdbl[ijDbl];
1011 
1012  return stream;
1013  }
1014 
1015  ostream & operator << (
1016  ostream & stream, const genie::flux::GSimpleNtpMeta & meta)
1017  {
1018  size_t nf = meta.pdglist.size();
1019  stream << "\nGSimpleNtpMeta " << nf << " flavors: ";
1020  for (size_t i=0; i<nf; ++i) stream << " " << meta.pdglist[i];
1021 
1022  //stream << "\nGSimpleNtpMeta " << meta.nflavors
1023  // << " flavors: ";
1024  //for (int i=0; i< meta.nflavors; ++i) stream << " " << meta.flavor[i];
1025 
1026  stream << "\n maxEnergy " << meta.maxEnergy
1027  << " min/maxWgt " << meta.minWgt << "/" << meta.maxWgt
1028  << " protons " << meta.protons
1029  << " metakey " << meta.metakey
1030  << "\n windowBase [" << meta.windowBase[0] << ","
1031  << meta.windowBase[1] << "," << meta.windowBase[2] << "]"
1032  << "\n windowDir1 [" << meta.windowDir1[0] << ","
1033  << meta.windowDir1[1] << "," << meta.windowDir1[2] << "]"
1034  << "\n windowDir2 [" << meta.windowDir2[0] << ","
1035  << meta.windowDir2[1] << "," << meta.windowDir2[2] << "]";
1036 
1037  size_t nInt = meta.auxintname.size();
1038  if ( nInt > 0 ) stream << "\n aux ints: ";
1039  for (size_t ijInt=0; ijInt < nInt; ++ijInt)
1040  stream << " " << meta.auxintname[ijInt];
1041 
1042  size_t nDbl = meta.auxdblname.size();
1043  if ( nDbl > 0 ) stream << "\n aux doubles: ";
1044  for (size_t ijDbl=0; ijDbl < nDbl; ++ijDbl)
1045  stream << " " << meta.auxdblname[ijDbl];
1046 
1047  size_t nfiles = meta.infiles.size();
1048  stream << "\n " << nfiles << " input files: ";
1049  UInt_t nprint = TMath::Min(UInt_t(nfiles),
1051  for (UInt_t ifiles=0; ifiles < nprint; ++ifiles)
1052  stream << "\n " << meta.infiles[ifiles];
1053 
1054  stream << "\n input seed: " << meta.seed;
1055 
1056  return stream;
1057  }
1058 
1059 
1060 }//flux
1061 }//genie
1062 
1063 //___________________________________________________________________________
1064 
1066 {
1067 
1068  std::ostringstream s;
1069  PDGCodeList::const_iterator itr = fPdgCList->begin();
1070  for ( ; itr != fPdgCList->end(); ++itr) s << (*itr) << " ";
1071  s << "[rejected: ";
1072  itr = fPdgCListRej->begin();
1073  for ( ; itr != fPdgCListRej->end(); ++itr) s << (*itr) << " ";
1074  s << " ] ";
1075 
1076  std::ostringstream fpattout;
1077  for (size_t i = 0; i < fNuFluxFilePatterns.size(); ++i)
1078  fpattout << "\n [" << std::setw(3) << i << "] " << fNuFluxFilePatterns[i];
1079 
1080  std::ostringstream flistout;
1081  std::vector<std::string> flist = GetFileList();
1082  for (size_t i = 0; i < flist.size(); ++i)
1083  flistout << "\n [" << std::setw(3) << i << "] " << flist[i];
1084 
1085  LOG("Flux", pNOTICE)
1086  << "GSimpleNtpFlux Config:"
1087  << "\n Enu_max " << fMaxEv
1088  << "\n pdg-codes: " << s.str() << "\n "
1089  << "\"flux\" " << fNEntries << " entries, "
1090  << "\"meta\" " << fNFiles << " entries"
1091  << " (FilePOTs " << fFilePOTs << ") in files:"
1092  << flistout.str()
1093  << "\n from file patterns: "
1094  << fpattout.str()
1095  << "\n wgt max=" << fMaxWeight
1096  << "\n Z0 pushback " << fZ0
1097  << "\n used entry " << fIEntry << " " << fIUse << "/" << fNUse
1098  << " times, in " << fICycle << "/" << fNCycles << " cycles"
1099  << "\n SumWeight " << fSumWeight << " for " << fNNeutrinos << " neutrinos"
1100  << " with " << fNEntriesUsed << " entries read"
1101  << "\n EffPOTsPerNu " << fEffPOTsPerNu << " AccumPOTs " << fAccumPOTs
1102  << "\n GenWeighted \"" << (fGenWeighted?"true":"false") << "\""
1103  << " AlreadyUnwgt \"" << (fAlreadyUnwgt?"true":"false") << "\""
1104  << " AllFilesMeta \"" << (fAllFilesMeta?"true":"false") << "\"";
1105 
1106 }
1107 
1108 //___________________________________________________________________________
1109 std::vector<std::string> GSimpleNtpFlux::GetFileList()
1110 {
1111  std::vector<std::string> flist;
1112  TObjArray *fileElements=fNuFluxTree->GetListOfFiles();
1113  TIter next(fileElements);
1114  TChainElement *chEl=0;
1115  while (( chEl=(TChainElement*)next() )) {
1116  flist.push_back(chEl->GetTitle());
1117  }
1118  return flist;
1119 }
1120 
1121 //___________________________________________________________________________
static QCString name
Definition: declinfo.cpp:673
double UsedPOTs(void) const
of protons-on-target used
void GetFluxWindow(TVector3 &p1, TVector3 &p2, TVector3 &p3) const
3 points define a plane in beam coordinate
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
code to link reconstructed objects back to the MC truth information
Double_t E
energy in lab frame
GSimpleNtpAux * fCurAux
current "aux" branch extra info
Int_t fIFileNumber
which file for the current entry
void Clear(Option_t *opt)
reset state variables based on opt
virtual long int NFluxNeutrinos() const
of rays generated
std::vector< string > fNuFluxFilePatterns
(potentially wildcarded) path(s)
string P4AsShortString(const TLorentzVector *p)
Definition: PrintUtils.cxx:45
long int fNNeutrinos
number of flux neutrinos thrown so far
QList< Entry > entry
void AddFile(TTree *fluxtree, TTree *metatree, string fname)
void PrintCurrent(void)
print current entry from leaves
THE MAIN GENIE PROJECT NAMESPACE
Definition: AlgCmp.h:25
GSimpleNtpMeta * fCurMeta
current meta data
#define pERROR
Definition: Messenger.h:59
Double_t pdpx
nu parent momentum at time of decay
void SetEntryReuse(long int nuse=1)
of times to use entry before moving to next
long int fIUse
current # of times an entry has been used
Double_t px
x momentum in lab frame (GeV)
static RandomGen * Instance()
Access instance.
Definition: RandomGen.cxx:71
A GENIE flux driver using a simple ntuple format.
double fSumWeight
sum of weights for nus thrown so far
std::string string
Definition: nybbler.cc:12
Double_t vtxy
y position in lab frame
Double_t vx
vertex position of hadron/muon decay
Double_t maxEnergy
maximum energy
#define pFATAL
Definition: Messenger.h:56
opt
Definition: train.py:196
std::vector< std::string > auxintname
tagname of aux ints associated w/ entry
bool ExistsInPDGCodeList(int pdg_code) const
intermediate_table::const_iterator const_iterator
Int_t tptype
parent particle type at target exit
bool End(void)
true if no more flux nu&#39;s can be thrown (eg reaching end of beam sim ntuples)
std::vector< Double_t > auxdbl
additional doubles associated w/ entry
Definition: tf_graph.h:23
virtual void SetNumOfCycles(long int ncycle)
limit cycling through input files
string filename
Definition: train.py:213
Double_t windowDir1[3]
dx,dy,dz of window direction 1
A singleton holding random number generator classes. All random number generation in GENIE should tak...
Definition: RandomGen.h:29
std::vector< Int_t > auxint
additional ints associated w/ entry
virtual TTree * GetMetaDataTree()
void Print(const Option_t *opt="") const
Double_t protons
represented number of protons-on-target
void GenerateWeighted(bool gen_weighted)
set whether to generate weighted or unweighted neutrinos
Int_t seed
random seed used in generation
void MoveToZ0(double z0)
move ray origin to user coord Z0
virtual void SetUpstreamZ(double z0)
Double_t vtxt
time of ray start (seconds)
Double_t windowDir2[3]
dx,dy,dz of window direction 2
const genie::flux::GSimpleNtpEntry * GetCurrentEntry(void)
GSimpleNtpEntry.
Double_t pppx
nu parent momentum at production point
std::vector< Int_t > pdglist
list of neutrino flavors
void ProcessMeta(void)
scan for max flux energy, weight
bool OptionalAttachBranch(std::string bname)
PDGCodeList * fPdgCList
list of neutrino pdg-codes to generate
bool fIncludeVtxt
does fX4 include CurEntry.vtxt or 0
const double e
Double_t windowBase[3]
x,y,z position of window base point
std::vector< std::string > GetFileList()
list of files currently part of chain
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:96
TLorentzVector fX4
reconstituted position vector
bool fAllFilesMeta
do all files in chain have meta data
Double_t fFilePOTs
of protons-on-target represented by all files
static Config * config
Definition: config.cpp:1054
bool fGenWeighted
does GenerateNext() give weights?
Double_t vtxz
z position in lab frame
QTextStream & flush(QTextStream &s)
GENIE interface for uniform flux exposure iterface.
Double_t minWgt
minimum weight
Int_t ppmedium
tracking medium where parent was produced
void Initialize(void)
virtual double GetTotalExposure() const
GFluxExposureI interface.
GSimpleNtpNuMI * fCurNuMICopy
current "numi" branch extra info
#define pINFO
Definition: Messenger.h:62
long int fNEntriesUsed
number of entries read from files
bool GenerateNext(void)
generate the next flux neutrino (return false in err)
std::vector< std::string > infiles
list of input files
long int fNCycles
times to cycle through the ntuple(s)
void PrintConfig()
print the current configuration
Double_t tpx
parent particle px at target exit
void SetMaxEnergy(double Ev)
specify maximum flx neutrino energy
GSimpleNtpNuMI * fCurNuMI
current "numi" branch extra info
int fNFiles
number of files in chain
virtual void GetBranchInfo(std::vector< std::string > &branchNames, std::vector< std::string > &branchClassNames, std::vector< void ** > &branchObjPointers)
#define pWARN
Definition: Messenger.h:60
double fMaxWeight
max flux neutrino weight in input file
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
PDGCodeList * fPdgCListRej
list of nu pdg-codes seen but rejected
double fWeight
current neutrino weight
TChain * fNuMetaTree
TTree // REF ONLY.
GSimpleNtpEntry * fCurEntry
current entry
Double_t maxWgt
maximum weight
TLorentzVector fP4
reconstituted p4 vector
UInt_t metakey
index key to tie to individual entries
ClassImp(EDep::TEventChangeManager) namespace
bool fAlreadyUnwgt
are input files already unweighted
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
Long64_t fIEntry
current flux ntuple entry
Long64_t fNEntries
number of flux ntuple entries
Double_t vtxx
x position in lab frame (meters)
friend ostream & operator<<(ostream &stream, const GSimpleNtpMeta &info)
std::string pattern
Definition: regex_t.cc:35
Double_t pz
z momentum in lab frame
GSimpleNtpAux * fCurAuxCopy
current "aux" branch extra info
long int fNUse
how often to use same entry in a row
Double_t dist
distance from hadron decay
GSimpleNtpEntry * fCurEntryCopy
current entry
double fEffPOTsPerNu
what a entry is worth ...
#define pNOTICE
Definition: Messenger.h:61
double GetDecayDist() const
dist (user units) from dk to current pos
string fNuFluxBranchRequest
list of requested branches "entry,numi,au"
bool fEnd
end condition reached
TRandom3 & RndFlux(void) const
rnd number generator used by flux drivers
Definition: RandomGen.h:71
string X4AsString(const TLorentzVector *x)
Definition: PrintUtils.cxx:57
virtual void LoadBeamSimData(const std::vector< string > &filenames, const std::string &det_loc)
double fMaxEv
maximum energy
UInt_t metakey
key to meta data
void Print(const Option_t *opt="") const
Double_t py
y momentum in lab frame
double Weight(void)
returns the flux neutrino weight (if any)
double fAccumPOTs
POTs used so far.
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
#define FLUXDRIVERREG4(_nsa, _nsb, _name, _fqname)
static QCString * s
Definition: config.cpp:1042
void Print(const Option_t *opt="") const
QTextStream & endl(QTextStream &s)
void push_back(int pdg_code)
Definition: PDGCodeList.cxx:58
static UInt_t mxfileprint
allow user to limit # of files to print
std::vector< std::string > auxdblname
tagname of aux doubles associated w/ entry
TChain * fNuFluxTree
TTree // REF ONLY.
#define pDEBUG
Definition: Messenger.h:63
void Print(const Option_t *opt="") const
Int_t ptype
parent type (PDG)