58 #include "Framework/Conventions/GBuild.h"
83 using std::ostringstream;
85 using namespace genie;
86 using namespace genie::utils;
87 using namespace genie::utils::intranuke2018;
88 using namespace genie::constants;
89 using namespace genie::controls;
116 <<
"************ Running hN2018 MODE INTRANUKE ************";
125 LOG(
"HNIntranuke2018",
pINFO) <<
"Done with this event";
134 LOG(
"HNIntranuke2018",
pERROR) <<
"** Null input!";
141 bool is_kaon = (pdgc==
kPdgKP);
144 if(!(is_pion || is_baryon || is_gamma || is_kaon))
146 LOG(
"HNIntranuke2018",
pERROR) <<
"** Cannot handle particle: " << p->
Name();
159 LOG(
"HNIntranuke2018",
pERROR) <<
"** Couldn't select a fate";
162 LOG(
"HNIntranuke2018",
pERROR) <<
"** Particle: " <<
"\n" << (*p);
181 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
183 <<
"Invoking InelasticHN() for a : " << p->
Name()
202 <<
"retry call to SimulateHadronicFinalState ";
223 <<
"Selecting hN fate for " << p->
Name() <<
" with KE = " << ke <<
" MeV";
226 unsigned int iter = 0;
245 if(pdgc==
kPdgPi0) frac_abs*= 0.665;
254 double tf = frac_cex +
259 double r = tf * rnd->
RndFsi().Rndm();
260 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
261 LOG(
"HNIntranuke2018",
pDEBUG) <<
"r = " << r <<
" (max = " << tf <<
")";
266 if(r < (cf += frac_cex ))
return kIHNFtCEx;
269 if(r < (cf += frac_abs ))
return kIHNFtAbs;
272 <<
"No selection after going through all fates! "
273 <<
"Total fraction = " << tf <<
" (r = " << r <<
")";
293 double tf = frac_elas +
297 double r = tf * rnd->
RndFsi().Rndm();
299 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
300 LOG(
"HNIntranuke2018",
pDEBUG) <<
"r = " << r <<
" (max = " << tf <<
")";
306 if(r < (cf += frac_cmp ))
return kIHNFtCmp;
309 <<
"No selection after going through all fates! "
310 <<
"Total fraction = " << tf <<
" (r = " << r <<
")";
332 double tf = frac_cex +
335 double r = tf * rnd->
RndFsi().Rndm();
336 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
337 LOG(
"HNIntranuke",
pDEBUG) <<
"r = " << r <<
" (max = " << tf <<
")";
342 if(r < (cf += frac_cex ))
return kIHNFtCEx;
346 <<
"No selection after going through all fates! "
347 <<
"Total fraction = " << tf <<
" (r = " << r <<
")";
371 if (np < 1 && nn < 1)
373 LOG(
"HNIntranuke2018",
pERROR) <<
"** Nothing left in nucleus!!! **";
381 if (fate ==
kIHNFtAbs) {
return ((nn>=1) && (np>=1)) ? 1. : 0.; }
395 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
397 <<
"AbsorbHN() is invoked for a : " << p->
Name()
422 int pcode, t1code, t2code, scode, s2code;
423 double M1, M2_1, M2_2, M3, M4;
424 double E1L, P1L, E2L, P2L, E3L, P3L, E4L, P4L;
429 double Theta1, Theta2, theta5;
431 double E1CM, E3CM, E4CM, P3CM;
432 double P3zL, P3tL, P4zL, P4tL;
434 TVector3 tP2_1L, tP2_2L, tP1L, tP2L, tPtot, P1zCM, P2zCM;
436 TVector3 bDir, tTrans, tbeta, tVect;
473 <<
"AbsorbHN() cannot handle probe: " << pdgc;
478 M1 = pLib->
Find(pcode) ->Mass();
479 M2_1 = pLib->
Find(t1code)->Mass();
480 M2_2 = pLib->
Find(t2code)->Mass();
481 M3 = pLib->
Find(scode) ->Mass();
482 M4 = pLib->
Find(s2code)->Mass();
487 target.SetHitNucPdg(t1code);
490 E2_1L = TMath::Sqrt(tP2_1L.Mag2() + M2_1*M2_1);
492 target.SetHitNucPdg(t2code);
495 E2_2L = TMath::Sqrt(tP2_2L.Mag2() + M2_2*M2_2);
499 tP2_1L.SetXYZ(0.0, 0.0, 0.0);
502 tP2_2L.SetXYZ(0.0, 0.0, 0.0);
517 S3CM = TMath::Sqrt(1.0 - C3CM*C3CM);
521 if(E1L<0.001) E1L=0.001;
522 P1L = TMath::Sqrt(E1L*E1L - M1*M1);
523 tP1L = p->
P4()->Vect();
524 tP2L = tP2_1L + tP2_2L;
530 Theta1 = tP1L.Angle(bDir);
531 Theta2 = tP2L.Angle(bDir);
534 P1zL = P1L*TMath::Cos(Theta1);
535 P2zL = P2L*TMath::Cos(Theta2);
537 if(TMath::Abs((tVect - bDir).Mag())<.01) tVect.SetXYZ(0,1,0);
538 theta5 = tVect.Angle(bDir);
539 tTrans = (tVect - TMath::Cos(theta5)*bDir).Unit();
542 tbeta = tPtot * (1.0 / (E1L + E2L));
544 gm = 1.0 / TMath::Sqrt(1.0 - beta*beta);
547 E1CM = gm*E1L - gm*beta*P1zL;
548 P1zCM = gm*P1zL*bDir - gm*tbeta*E1L;
549 E2CM = gm*E2L - gm*beta*P2zL;
550 P2zCM = gm*P2zL*bDir - gm*tbeta*E2L;
552 E3CM = (Et*Et + (M3*M3) - (M4*M4)) / (2.0*Et);
554 P3CM = TMath::Sqrt(E3CM*E3CM - M3*M3);
557 P3zL = gm*beta*E3CM + gm*P3CM*C3CM;
559 P4zL = gm*beta*E4CM + gm*P3CM*(-C3CM);
562 P3L = TMath::Sqrt(P3zL*P3zL + P3tL*P3tL);
563 P4L = TMath::Sqrt(P4zL*P4zL + P4tL*P4tL);
567 if(!(TMath::Finite(P3L))||P3L<.001)
570 <<
"Particle 3 " << M3 <<
" momentum small or non-finite: " << P3L
571 <<
"\n" <<
"--> Assigning .001 as new momentum";
575 E3L = TMath::Sqrt(P3L*P3L + M3*M3);
578 if(!(TMath::Finite(P4L))||P4L<.001)
581 <<
"Particle 4 " << M4 <<
" momentum small or non-finite: " << P4L
582 <<
"\n" <<
"--> Assigning .001 as new momentum";
586 E4L = TMath::Sqrt(P4L*P4L + M4*M4);
594 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
595 LOG(
"HNIntranuke2018",
pINFO) <<
"AbsorbHN failed: Pauli blocking";
605 LOG(
"HNIntranuke2018",
pINFO) <<
"AbsorbHN failed: Pauli blocking";
607 exception.
SetReason(
"hN absorption failed");
614 fRemnP4 -= TLorentzVector(tP2_1L,E2_1L);
615 fRemnP4 -= TLorentzVector(tP2_2L,E2_2L);
620 tP3L = P3zL*bDir + P3tL*tTrans;
621 tP4L = P4zL*bDir + P4tL*tTrans;
623 tP3L.Rotate(PHI3,bDir);
624 tP4L.Rotate(PHI3,bDir);
626 E3L = TMath::Sqrt(P3L*P3L + M3*M3);
627 E4L = TMath::Sqrt(P4L*P4L + M4*M4);
635 TLorentzVector t4P4L(tP4L,E4L);
641 TLorentzVector t4P3L(tP3L,E3L);
646 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
648 <<
"|p3| = " << (P3L) <<
", E3 = " << (E3L);
650 <<
"|p4| = " << (P4L) <<
", E4 = " << (E4L);
664 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
666 <<
"ElasHN() is invoked for a : " << p->
Name()
681 int pcode = p->
Pdg();
682 int tcode, scode, s2code;
721 double Mt = t->
Mass();
733 double tE = TMath::Sqrt(tP3L.Mag2() + Mt*Mt);
744 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
746 <<
"|p3| = " << P3L <<
", E3 = " << E3L;
748 <<
"|p4| = " << P4L <<
", E4 = " << E4L;
758 LOG(
"HNIntranuke2018",
pINFO) <<
"Elastic in hN failed calling TwoBodyCollision";
760 exception.
SetReason(
"hN scattering kinematics through TwoBodyCollision failed");
781 if (
utils::intranuke2018::PionProduction(ev,p,&s1,&s2,&s3,
fRemnA,
fRemnZ,
fRemnP4,
fDoFermi,
fFermiFac,
fFermiMomentum,
fNuclmodel))
795 LOG(
"HNIntranuke2018",
pNOTICE) <<
"Error: could not create pion production final state";
797 exception.
SetReason(
"PionProduction in hN failed");
808 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
810 <<
"GammaInelasticHN() is invoked for a : " << p->
Name()
826 int pcode = p->
Pdg();
832 <<
"Particle code: " << pcode <<
", target: " << tcode;
850 <<
"Error: could not determine particle final states";
858 <<
" final state: " << scode <<
" and " << s2code;
860 <<
" scattering angle: " << C3CM;
864 double Mt = t->
Mass();
875 double tE = TMath::Sqrt(tP3L.Mag2() + Mt*Mt);
886 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
888 <<
"|p3| = " << P3L <<
", E3 = " << E3L;
890 <<
"|p4| = " << P4L <<
", E4 = " << E4L;
935 <<
"*** Nothing left to interact with, escaping.";
991 LOG(
"HNIntranuke2018",
pWARN) <<
"R0 = " <<
fR0 <<
" fermi";
1002 LOG(
"HNIntranuke2018",
pWARN) <<
"DoFermi? = " << ((
fDoFermi)?(
true):(
false));
1021 double fractionElas = 1 - (fractionAbsorption + fractionCex);
1027 double totalFrac = fractionCex + fractionAbsorption + fractionElas;
1030 const double randomNumber = randomGenerator->
RndFsi().Rndm() * totalFrac;
1032 LOG(
"HNIntranuke2018",
pNOTICE) <<
"{ frac abs = " << fractionAbsorption;
1033 LOG(
"HNIntranuke2018",
pNOTICE) <<
" frac cex = " << fractionCex;
1034 LOG(
"HNIntranuke2018",
pNOTICE) <<
" frac elas = " << fractionElas <<
" }";
1036 if (randomNumber < fractionAbsorption && fRemnA > 1)
return kIHNFtAbs;
1037 else if (randomNumber < fractionAbsorption + fractionCex)
return kIHNFtCEx;
static string AsString(INukeMode_t mode)
An exception thrown by SimulateHadronState for kinematics problems. TwoBodyCollision/Kinematics used ...
void SetFirstMother(int m)
void PreEquilibrium(GHepRecord *ev, GHepParticle *p, int &RemnA, int &RemnZ, TLorentzVector &RemnP4, bool DoFermi, double FermiFac, const NuclearModelI *Nuclmodel, double NucRmvE, EINukeMode mode=kIMdHN)
virtual GHepParticle * Particle(int position) const
TRandom3 & RndFsi(void) const
rnd number generator used by intranuclear cascade monte carlos
double fFermiMomentum
whether or not particle collision is pauli blocked
INukeOset * currentInstance
double Frac(int hpdgc, INukeFateHN_t fate, double ke, int targA=0, int targZ=0) const
double E(void) const
Get energy.
static RandomGen * Instance()
Access instance.
const TLorentzVector * P4(void) const
double fDelRPion
factor by which Pion Compton wavelength gets multiplied to become nuclear size enhancement ...
double fEPreEq
threshold for pre-equilibrium reaction
double fNR
param multiplying the nuclear radius, determining how far to track hadrons beyond the "nuclear bounda...
double fFermiFac
testing parameter to modify fermi momentum
int fRemnA
remnant nucleus A
double FateWeight(int pdgc, INukeFateHN_t fate) const
void ElasHN(GHepRecord *ev, GHepParticle *p, INukeFateHN_t fate) const
bool PionProduction(GHepRecord *ev, GHepParticle *p, GHepParticle *s1, GHepParticle *s2, GHepParticle *s3, int &RemnA, int &RemnZ, TLorentzVector &RemnP4, bool DoFermi, double FermiFac, double FermiMomentum, const NuclearModelI *Nuclmodel)
double fChPionMFPScale
tweaking factors for tuning
Pure abstract base class. Defines the NuclearModelI interface to be implemented by any physics model ...
void SimulateHadronicFinalState(GHepRecord *ev, GHepParticle *p) const
bool HandleCompoundNucleusHN(GHepRecord *ev, GHepParticle *p) const
bool fXsecNNCorr
use nuclear medium correction for NN cross section
void SetMomentum(const TLorentzVector &p4)
bool IsInNucleus(const GHepParticle *p) const
void ProcessEventRecord(GHepRecord *event_rec) const
double Mass(void) const
Mass that corresponds to the PDG code.
static constexpr double MeV
double getAbsorptionFraction() const
return fraction of absorption events
double fNucAbsFac
absorption xsec correction factor (hN Mode)
A singleton holding random number generator classes. All random number generation in GENIE should tak...
const NuclearModelI * fNuclmodel
nuclear model used to generate fermi momentum
const TVector3 & Momentum3(void) const
int LastMother(void) const
void InelasticHN(GHepRecord *ev, GHepParticle *p) const
int FirstMother(void) const
string Name(void) const
Name that corresponds to the PDG code.
int HandleCompoundNucleus(GHepRecord *ev, GHepParticle *p, int mom) const
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
enum genie::EINukeFateHN_t INukeFateHN_t
double getCexFraction() const
return fraction of cex events
void SetReason(string reason)
A Neutrino Interaction Target. Is a transparent encapsulation of quite different physical systems suc...
INukeFateHN_t HadronFateOset() const
bool TwoBodyCollision(GHepRecord *ev, int pcode, int tcode, int scode, int s2code, double C3CM, GHepParticle *p, GHepParticle *t, int &RemnA, int &RemnZ, TLorentzVector &RemnP4, EINukeMode mode=kIMdHA)
Intranuke utility functions.
virtual GHepParticle * TargetNucleus(void) const
bool fDoFermi
whether or not to do fermi mom.
INukeFateHN_t HadronFateHN(const GHepParticle *p) const
double fNeutralPionMFPScale
double fNucCEXFac
charge exchange xsec correction factor (hN Mode)
void Equilibrium(GHepRecord *ev, GHepParticle *p, int &RemnA, int &RemnZ, TLorentzVector &RemnP4, bool DoFermi, double FermiFac, const NuclearModelI *Nuclmodel, double NucRmvE, EINukeMode mode=kIMdHN)
double fR0
effective nuclear size param
bool fDoCompoundNucleus
whether or not to do compound nucleus considerations
virtual void ProcessEventRecord(GHepRecord *event_rec) const
void SetRemovalEnergy(double Erm)
double KinE(bool mass_from_pdg=false) const
Get kinetic energy.
static PDGLibrary * Instance(void)
static INukeHadroData2018 * Instance(void)
void SetLastMother(int m)
Singleton class to load & serve a TDatabasePDG.
void SetStatus(GHepStatus_t s)
static string AsString(INukeFateHN_t fate)
bool fAltOset
NuWro's table-based implementation (not recommended)
void SetHitNucPdg(int pdgc)
INukeHadroData2018 * fHadroData2018
a collection of h+N,h+A data & calculations
double fDelRNucleon
factor by which Nucleon Compton wavelength gets multiplied to become nuclear size enhancement ...
bool IsNeutronOrProton(int pdgc)
double fHadStep
step size for intranuclear hadron transport
virtual void AddParticle(const GHepParticle &p)
TParticlePDG * Find(int pdgc, bool must_exist=true)
bool GetParamDef(const RgKey &name, T &p, const T &def) const
bool GetParam(const RgKey &name, T &p, bool is_top_call=true) const
void GammaInelasticHN(GHepRecord *ev, GHepParticle *p, INukeFateHN_t fate) const
double fNucRmvE
binding energy to subtract from cascade nucleons
static const unsigned int kRjMaxIterations
void AbsorbHN(GHepRecord *ev, GHepParticle *p, INukeFateHN_t fate) const
virtual bool GenerateNucleon(const Target &) const =0
GENIE's GHEP MC event record.
bool fUseOset
Oset model for low energy pion in hN.
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.
double IntBounce(const GHepParticle *p, int target, int s1, INukeFateHN_t fate)
int fRemnZ
remnant nucleus Z
TLorentzVector fRemnP4
P4 of remnant system.
const Algorithm * SubAlg(const RgKey ®istry_key) const