48 #include <TLorentzVector.h>
65 using std::ostringstream;
70 using std::setprecision;
75 using namespace genie;
76 using namespace genie::constants;
114 int main(
int argc,
char ** argv)
124 LOG(
"gevscan",
pINFO) <<
"Input tree header: " << *thdr;
128 <<
"*** Unsupported event-tree format : "
134 gEventTree = dynamic_cast <TTree *> (file.Get(
"gtree"));
148 LOG(
"gevdump",
pFATAL) <<
"Invalid event range";
157 ostringstream logfile;
163 gErrLog <<
"# ..................................................................................." << endl;
165 gErrLog <<
"# ..................................................................................." << endl;
201 LOG(
"gevscan",
pNOTICE) <<
"Checking energy/momentum conservation...";
204 gErrLog <<
"# Events failing the energy-momentum conservation test:" << endl;
219 LOG(
"gevscan",
pINFO) <<
"Checking event.... " << i;
221 double E_init = 0, E_fin = 0;
222 double px_init = 0, px_fin = 0;
223 double py_init = 0, py_fin = 0;
224 double pz_init = 0, pz_fin = 0;
227 TIter event_iter(&event);
228 while ( (p = dynamic_cast<GHepParticle *>(event_iter.Next())) ) {
251 bool E_conserved = TMath::Abs(E_init - E_fin) <
epsilon;
252 bool px_conserved = TMath::Abs(px_init - px_fin) <
epsilon;
253 bool py_conserved = TMath::Abs(py_init - py_fin) <
epsilon;
254 bool pz_conserved = TMath::Abs(pz_init - pz_fin) <
epsilon;
256 bool ok = E_conserved &&
263 <<
" ** Energy-momentum non-conservation in event: " << i
287 <<
" events failing the energy/momentum conservation test";
292 LOG(
"gevscan",
pNOTICE) <<
"Checking charge conservation...";
295 gErrLog <<
"# Events failing the charge conservation test:" << endl;
310 LOG(
"gevscan",
pINFO) <<
"Checking event.... " << i;
320 <<
"Event in nuclear target - Skipping test...";
327 TIter event_iter(&event);
328 while ( (p = dynamic_cast<GHepParticle *>(event_iter.Next())) ) {
343 bool ok = TMath::Abs(Q_init - Q_fin) <
epsilon;
346 <<
" ** Charge non-conservation in event: " << i
370 <<
" events failing the charge conservation test";
376 <<
"Checking for pseudo-particles appearing in final state...";
379 gErrLog <<
"# Events with pseudo-particles in final state:" << endl;
394 LOG(
"gevscan",
pINFO) <<
"Checking event.... " << i;
397 TIter event_iter(&event);
399 while ( (p = dynamic_cast<GHepParticle *>(event_iter.Next())) ) {
413 <<
" ** Pseudo-particle final state particle in event: " << i
437 <<
" events with pseudo-particles in final state";
443 <<
"Checking for off-mass-shell particles appearing in the final state...";
446 gErrLog <<
"# Events with off-mass-shell particles in final state:" << endl;
461 LOG(
"gevscan",
pINFO) <<
"Checking event.... " << i;
464 TIter event_iter(&event);
466 while ( (p = dynamic_cast<GHepParticle *>(event_iter.Next())) ) {
479 <<
" ** Off-mass-shell final state particle in event: " << i
503 <<
" events with off-mass-shell particles in final state";
509 <<
"Checking for number of final state nucleons inconsistent with target...";
512 gErrLog <<
"# Events with number of final state nucleons inconsistent with target:" << endl;
527 LOG(
"gevscan",
pINFO) <<
"Checking event.... " << i;
533 <<
"Event not in nuclear target - Skipping test...";
544 for(
int d = fd; d <= ld; d++) {
545 p =
event.Particle(d);
554 TIter event_iter(&event);
555 while ( (p = dynamic_cast<GHepParticle *>(event_iter.Next())) ) {
564 <<
"Before intranuclear hadron transport: Z = " << Z <<
", N = " << N;
570 while ( (p = dynamic_cast<GHepParticle *>(event_iter.Next())) ) {
578 <<
"In the final state: Z = " << Zf <<
", N = " << Nf;
580 bool ok = (Zf <= Z && Nf <= N);
583 <<
" ** Number of final state nucleons inconsistent with target in event: " << i
609 <<
" events with a number of final state nucleons inconsistent with target";
615 <<
"Checking intra-nuclear vertex distribution...";
618 gErrLog <<
"# Intranuclear vertex distribution check:" << endl;
622 TH1D * r_distr_mc =
new TH1D(
"r_distr_mc",
"", 150,0,30);
623 TH1D * r_distr_expected =
new TH1D(
"r_distr_expected",
"",150,0,30);
636 LOG(
"gevscan",
pINFO) <<
"Checking event.... " << i;
642 <<
"Event not in nuclear target - Skipping...";
645 if(Z == -1 && A == -1) {
651 if(Z != nucltgt->
Z() || A != nucltgt->
A()) {
653 <<
"Event not in nuclear target seen first - Skipping...";
657 double r = probe->
X4()->Vect().Mag();
669 for(
int ir = 1; ir <= r_distr_expected->GetNbinsX(); ir++) {
670 double r = r_distr_expected->GetBinCenter(ir);
672 double nexp = 4*
kPi*r*r*rho;
673 r_distr_expected->SetBinContent(ir,nexp);
677 double N = r_distr_mc->GetEntries();
678 r_distr_expected -> Scale (N / r_distr_expected -> Integral());
681 double pvalue = r_distr_mc->Chi2Test(r_distr_expected,
"WWP");
682 LOG(
"gevscan",
pNOTICE) <<
"p-value {\\chi^2 test} = " << pvalue;
686 gErrLog <<
"Problem! p-value = " << pvalue << endl;
688 gErrLog <<
"OK! p-value = " << pvalue << endl;
693 TFile f(
"./check_vtx.root",
"recreate");
694 r_distr_mc ->
Write();
695 r_distr_expected ->
Write();
703 gErrLog <<
"Can not run test with current sample" << endl;
720 <<
"Checking decayer consistency...";
723 gErrLog <<
"# Decayer consistency check:" << endl;
727 bool allowdup =
false;
738 LOG(
"gevscan",
pINFO) <<
"Checking event.... " << i;
741 TIter event_iter(&event);
742 while ( (p = dynamic_cast<GHepParticle *>(event_iter.Next())) ) {
754 PDGCodeList::const_iterator iter;
755 for(iter = final_state_particles.begin();
756 iter != final_state_particles.end(); ++iter)
767 if(particles_in_both_lists.size() == 0) {
768 mesg <<
"OK.\n" <<
"No particle seen both in the final state and to have decayed.";
771 mesg <<
"Problem!\n" << particles_in_both_lists.size() <<
" particles seen both final state and to have decayed.";
777 <<
"Particles seen in final state: " << final_state_particles;
779 <<
"Particles seen to have decayed: " << decayed_particles;
781 <<
"Particles seen in both lists: " << particles_in_both_lists;
785 gErrLog <<
"\nParticles seen in final state:" << final_state_particles << endl;
786 gErrLog <<
"\nParticles seen to have decayed:" << decayed_particles << endl;
787 gErrLog <<
"\nParticles seen in both lists:" << particles_in_both_lists << endl;
793 gErrLog <<
"\nExample events: " << endl;
795 for(iter = particles_in_both_lists.begin();
796 iter != particles_in_both_lists.end(); ++iter)
798 int pdgc_bothlists = *iter;
801 bool have_example =
false;
804 have_example = (iev_decay != -1 && iev_fs != -1);
805 if(have_example)
break;
810 TIter event_iter(&event);
811 while ( (p = dynamic_cast<GHepParticle *>(event_iter.Next())) ) {
813 if(pdgc != pdgc_bothlists)
continue;
822 <<
": Decayed in event " << iev_decay
823 <<
". Seen in final state in event " << iev_fs <<
"." << endl;
827 gErrLog <<
"Event " << iev_decay <<
":";
831 gErrLog <<
"Event: " << iev_fs <<
":";
842 LOG(
"gevscan",
pNOTICE) <<
"*** Parsing command line arguments";
849 if( parser.OptionExists(
'f') ) {
850 LOG(
"gevscan",
pINFO) <<
"Reading event sample filename";
854 <<
"Unspecified input filename - Exiting";
860 if( parser.OptionExists(
'o') ) {
861 LOG(
"gevscan",
pINFO) <<
"Reading err log file name";
866 if ( parser.OptionExists(
'n') ) {
867 LOG(
"gevdump",
pINFO) <<
"Reading number of events to analyze";
868 string nev = parser.ArgAsString(
'n');
869 if (nev.find(
",") != string::npos) {
870 vector<long> vecn = parser.ArgAsLongTokens(
'n',
",");
872 LOG(
"gevdump",
pFATAL) <<
"Invalid syntax";
887 <<
"Unspecified number of events to analyze - Use all";
893 parser.OptionExists(
"add-event-printout-in-error-log");
895 if(parser.OptionExists(
"max-num-of-errors-shown")) {
900 bool all = parser.OptionExists(
"all");
904 parser.OptionExists(
"check-energy-momentum-conservation");
906 parser.OptionExists(
"check-charge-conservation");
908 parser.OptionExists(
"check-for-num-of-final-state-nucleons-inconsistent-with-target");
910 parser.OptionExists(
"check-for-pseudoparticles-in-final-state");
912 parser.OptionExists(
"check-for-off-mass-shell-particles-in-final-state");
914 parser.OptionExists(
"check-vertex-distribution");
916 parser.OptionExists(
"check-decayer-consistency");
922 <<
"\n\n" <<
"Syntax:" <<
"\n"
923 <<
" gevscan -f sample.root [-n n1[,n2]] [-o errlog] [check names]\n";
928 if(filename.size() == 0)
return false;
930 bool is_accessible = ! (gSystem->AccessPathName(filename.c_str()));
931 if (!is_accessible) {
933 <<
"The input ROOT file [" << filename <<
"] is not accessible";
void CheckDecayerConsistency(void)
static void SetPrintLevel(int print_level)
void CheckEnergyMomentumConservation(void)
bool gOptCheckVertexDistribution
NtpMCRecHeader hdr
record header
bool gOptCheckForPseudoParticlesInFinState
double E(void) const
Get energy.
double Density(double r, int A, double ring=0.)
int FirstDaughter(void) const
MINOS-style ntuple record. Each such ntuple record holds a generated EventRecord object. Ntuples of this type are intended for feeding GENIE events into other applications (for example the GEANT4 based MC generation framework of an experiment) if no direct interface exists.
void ReadFromCommandLine(int argc, char **argv)
NtpMCEventRecord * gMCRec
bool ExistsInPDGCodeList(int pdg_code) const
double Pz(void) const
Get Pz.
GHepStatus_t Status(void) const
int main(int argc, char **argv)
double Px(void) const
Get Px.
int LastDaughter(void) const
void CheckForOffMassShellParticlesInFinState(void)
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
static constexpr double A
void CheckForPseudoParticlesInFinState(void)
double Charge(void) const
Chrg that corresponds to the PDG code.
bool CheckRootFilename(string filename)
void CheckForNumFinStateNucleonsInconsistentWithTarget(void)
void CheckVertexDistribution(void)
bool gOptCheckForNumFinStateNucleonsInconsistentWithTarget
bool gOptCheckChargeConservation
bool IsOffMassShell(void) const
void CheckChargeConservation(void)
bool gOptCheckForOffMassShellParticlesInFinState
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
bool gOptCheckDecayerConsistency
static PDGLibrary * Instance(void)
static RunOpt * Instance(void)
bool gOptCheckEnergyMomentumConservation
const TLorentzVector * X4(void) const
bool IsPseudoParticle(int pdgc)
bool gOptAddEventPrintoutInErrLog
TParticlePDG * Find(int pdgc, bool must_exist=true)
Command line argument parser.
enum genie::ENtpMCFormat NtpMCFormat_t
void GetCommandLineArgs(int argc, char **argv)
void Clear(Option_t *opt="")
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
STDHEP-like event record entry that can fit a particle or a nucleus.
void push_back(int pdg_code)
enum genie::EGHepStatus GHepStatus_t
double Py(void) const
Get Py.