48#include <TLorentzVector.h>
65using std::ostringstream;
70using std::setprecision;
114int 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";
850 LOG(
"gevscan",
pINFO) <<
"Reading event sample filename";
854 <<
"Unspecified input filename - Exiting";
861 LOG(
"gevscan",
pINFO) <<
"Reading err log file name";
867 LOG(
"gevdump",
pINFO) <<
"Reading number of events to analyze";
869 if (nev.find(
",") != string::npos) {
872 LOG(
"gevdump",
pFATAL) <<
"Invalid syntax";
887 <<
"Unspecified number of events to analyze - Use all";
904 parser.
OptionExists(
"check-energy-momentum-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");
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";
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE,...
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils.
Command line argument parser.
string ArgAsString(char opt)
bool OptionExists(char opt)
was option set?
vector< long > ArgAsLongTokens(char opt, string delimeter)
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
STDHEP-like event record entry that can fit a particle or a nucleus.
bool IsOffMassShell(void) const
double Charge(void) const
Chrg that corresponds to the PDG code.
const TLorentzVector * X4(void) const
int LastDaughter(void) const
double Px(void) const
Get Px.
double E(void) const
Get energy.
double Pz(void) const
Get Pz.
double Py(void) const
Get Py.
GHepStatus_t Status(void) const
int FirstDaughter(void) const
static void SetPrintLevel(int print_level)
MINOS-style ntuple record. Each such ntuple record holds a generated EventRecord object....
bool ExistsInPDGCodeList(int pdg_code) const
void push_back(int pdg_code)
static PDGLibrary * Instance(void)
TParticlePDG * Find(int pdgc, bool must_exist=true)
void ReadFromCommandLine(int argc, char **argv)
static RunOpt * Instance(void)
void CheckEnergyMomentumConservation(void)
bool gOptCheckChargeConservation
void CheckForPseudoParticlesInFinState(void)
bool gOptCheckForNumFinStateNucleonsInconsistentWithTarget
void CheckDecayerConsistency(void)
bool gOptCheckForPseudoParticlesInFinState
bool CheckRootFilename(string filename)
void CheckForOffMassShellParticlesInFinState(void)
bool gOptCheckDecayerConsistency
void GetCommandLineArgs(int argc, char **argv)
NtpMCEventRecord * gMCRec
void CheckVertexDistribution(void)
bool gOptCheckEnergyMomentumConservation
void CheckChargeConservation(void)
bool gOptCheckForOffMassShellParticlesInFinState
bool gOptAddEventPrintoutInErrLog
void CheckForNumFinStateNucleonsInconsistentWithTarget(void)
bool gOptCheckVertexDistribution
bool IsPseudoParticle(int pdgc)
double Density(double r, int A, double ring=0.)
THE MAIN GENIE PROJECT NAMESPACE
@ kIStFinalStateNuclearRemnant
enum genie::EGHepStatus GHepStatus_t
enum genie::ENtpMCFormat NtpMCFormat_t