59#include "Framework/Conventions/GBuild.h"
84using std::ostringstream;
117 <<
"************ Running hN2025 MODE INTRANUKE ************";
121 LOG(
"HNIntranuke2025",
pINFO) <<
"Done with this event";
130 LOG(
"HNIntranuke2025",
pERROR) <<
"** Null input!";
137 bool is_kaon = (pdgc==
kPdgKP);
140 if(!(is_pion || is_baryon || is_gamma || is_kaon))
142 LOG(
"HNIntranuke2025",
pERROR) <<
"** Cannot handle particle: " << p->
Name();
155 LOG(
"HNIntranuke2025",
pERROR) <<
"** Couldn't select a fate";
158 LOG(
"HNIntranuke2025",
pERROR) <<
"** Particle: " <<
"\n" << (*p);
177#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
179 <<
"Invoking InelasticHN() for a : " << p->
Name()
186 else if(fate ==
kIHNFtCmp)
LOG(
"HNIntranuke2025",
pFATAL) <<
"The PreEquilibrium and Compound Nucleus code are experimental, should not be used";
199 <<
"retry call to SimulateHadronicFinalState ";
220 <<
"Selecting hN fate for " << p->
Name() <<
" with KE = " << ke <<
" MeV";
223 unsigned int iter = 0;
242 if(pdgc==
kPdgPi0) frac_abs*= 0.665;
251 double tf = frac_cex +
256 double r = tf * rnd->
RndFsi().Rndm();
257#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
258 LOG(
"HNIntranuke2025",
pDEBUG) <<
"r = " << r <<
" (max = " << tf <<
")";
263 if(r < (cf += frac_cex ))
return kIHNFtCEx;
266 if(r < (cf += frac_abs ))
return kIHNFtAbs;
269 <<
"No selection after going through all fates! "
270 <<
"Total fraction = " << tf <<
" (r = " << r <<
")";
290 double tf = frac_elas +
294 double r = tf * rnd->
RndFsi().Rndm();
296#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
297 LOG(
"HNIntranuke2025",
pDEBUG) <<
"r = " << r <<
" (max = " << tf <<
")";
303 if(r < (cf += frac_cmp ))
return kIHNFtCmp;
306 <<
"No selection after going through all fates! "
307 <<
"Total fraction = " << tf <<
" (r = " << r <<
")";
329 double tf = frac_cex +
332 double r = tf * rnd->
RndFsi().Rndm();
333#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
334 LOG(
"HNIntranuke",
pDEBUG) <<
"r = " << r <<
" (max = " << tf <<
")";
339 if(r < (cf += frac_cex ))
return kIHNFtCEx;
343 <<
"No selection after going through all fates! "
344 <<
"Total fraction = " << tf <<
" (r = " << r <<
")";
368 if (np < 1 && nn < 1)
370 LOG(
"HNIntranuke2025",
pERROR) <<
"** Nothing left in nucleus!!! **";
378 if (fate ==
kIHNFtAbs) {
return ((nn>=1) && (np>=1)) ? 1. : 0.; }
392#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
394 <<
"AbsorbHN() is invoked for a : " << p->
Name()
419 int pcode, t1code, t2code, scode, s2code;
420 double M1, M2_1, M2_2, M3, M4;
421 double E1L, P1L, E2L, P2L, E3L, P3L, E4L, P4L;
426 double Theta1, Theta2, theta5;
428 double E1CM, E3CM, E4CM, P3CM;
429 double P3zL, P3tL, P4zL, P4tL;
431 TVector3 tP2_1L, tP2_2L, tP1L, tP2L, tPtot, P1zCM, P2zCM;
433 TVector3 bDir, tTrans, tbeta, tVect;
470 <<
"AbsorbHN() cannot handle probe: " << pdgc;
475 M1 = pLib->
Find(pcode) ->Mass();
476 M2_1 = pLib->
Find(t1code)->Mass();
477 M2_2 = pLib->
Find(t2code)->Mass();
478 M3 = pLib->
Find(scode) ->Mass();
479 M4 = pLib->
Find(s2code)->Mass();
487 E2_1L = TMath::Sqrt(tP2_1L.Mag2() + M2_1*M2_1);
492 E2_2L = TMath::Sqrt(tP2_2L.Mag2() + M2_2*M2_2);
496 tP2_1L.SetXYZ(0.0, 0.0, 0.0);
499 tP2_2L.SetXYZ(0.0, 0.0, 0.0);
514 S3CM = TMath::Sqrt(1.0 - C3CM*C3CM);
518 if(E1L<0.001) E1L=0.001;
519 P1L = TMath::Sqrt(E1L*E1L - M1*M1);
520 tP1L = p->
P4()->Vect();
521 tP2L = tP2_1L + tP2_2L;
527 Theta1 = tP1L.Angle(bDir);
528 Theta2 = tP2L.Angle(bDir);
531 P1zL = P1L*TMath::Cos(Theta1);
532 P2zL = P2L*TMath::Cos(Theta2);
534 if(TMath::Abs((tVect - bDir).Mag())<.01) tVect.SetXYZ(0,1,0);
535 theta5 = tVect.Angle(bDir);
536 tTrans = (tVect - TMath::Cos(theta5)*bDir).Unit();
539 tbeta = tPtot * (1.0 / (E1L + E2L));
541 gm = 1.0 / TMath::Sqrt(1.0 - beta*beta);
544 E1CM = gm*E1L - gm*beta*P1zL;
545 P1zCM = gm*P1zL*bDir - gm*tbeta*E1L;
546 E2CM = gm*E2L - gm*beta*P2zL;
547 P2zCM = gm*P2zL*bDir - gm*tbeta*E2L;
549 E3CM = (Et*Et + (M3*M3) - (M4*M4)) / (2.0*Et);
551 P3CM = TMath::Sqrt(E3CM*E3CM - M3*M3);
554 P3zL = gm*beta*E3CM + gm*P3CM*C3CM;
556 P4zL = gm*beta*E4CM + gm*P3CM*(-C3CM);
559 P3L = TMath::Sqrt(P3zL*P3zL + P3tL*P3tL);
560 P4L = TMath::Sqrt(P4zL*P4zL + P4tL*P4tL);
564 if(!(TMath::Finite(P3L))||P3L<.001)
567 <<
"Particle 3 " << M3 <<
" momentum small or non-finite: " << P3L
568 <<
"\n" <<
"--> Assigning .001 as new momentum";
572 E3L = TMath::Sqrt(P3L*P3L + M3*M3);
575 if(!(TMath::Finite(P4L))||P4L<.001)
578 <<
"Particle 4 " << M4 <<
" momentum small or non-finite: " << P4L
579 <<
"\n" <<
"--> Assigning .001 as new momentum";
583 E4L = TMath::Sqrt(P4L*P4L + M4*M4);
591#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
592 LOG(
"HNIntranuke2025",
pINFO) <<
"AbsorbHN failed: Pauli blocking";
602 LOG(
"HNIntranuke2025",
pINFO) <<
"AbsorbHN failed: Pauli blocking";
604 exception.
SetReason(
"hN absorption failed");
611 fRemnP4 -= TLorentzVector(tP2_1L,E2_1L);
612 fRemnP4 -= TLorentzVector(tP2_2L,E2_2L);
617 tP3L = P3zL*bDir + P3tL*tTrans;
618 tP4L = P4zL*bDir + P4tL*tTrans;
620 tP3L.Rotate(PHI3,bDir);
621 tP4L.Rotate(PHI3,bDir);
623 E3L = TMath::Sqrt(P3L*P3L + M3*M3);
624 E4L = TMath::Sqrt(P4L*P4L + M4*M4);
632 TLorentzVector t4P4L(tP4L,E4L);
638 TLorentzVector t4P3L(tP3L,E3L);
643#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
645 <<
"|p3| = " << (P3L) <<
", E3 = " << (E3L);
647 <<
"|p4| = " << (P4L) <<
", E4 = " << (E4L);
661#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
663 <<
"ElasHN() is invoked for a : " << p->
Name()
678 int pcode = p->
Pdg();
679 int tcode, scode, s2code;
718 double Mt = t->
Mass();
730 double tE = TMath::Sqrt(tP3L.Mag2() + Mt*Mt);
741#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
743 <<
"|p3| = " << P3L <<
", E3 = " << E3L;
745 <<
"|p4| = " << P4L <<
", E4 = " << E4L;
755 LOG(
"HNIntranuke2025",
pINFO) <<
"Elastic in hN failed calling TwoBodyCollision";
757 exception.
SetReason(
"hN scattering kinematics through TwoBodyCollision failed");
778 if (
utils::intranuke2025::PionProduction(ev,p,&s1,&s2,&s3,
fRemnA,
fRemnZ,
fRemnP4,
fDoFermi,
fFermiFac,
fFermiMomentum,
fNuclmodel))
792 LOG(
"HNIntranuke2025",
pNOTICE) <<
"Error: could not create pion production final state";
794 exception.
SetReason(
"PionProduction in hN failed");
805#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
807 <<
"GammaInelasticHN() is invoked for a : " << p->
Name()
823 int pcode = p->
Pdg();
829 <<
"Particle code: " << pcode <<
", target: " << tcode;
847 <<
"Error: could not determine particle final states";
855 <<
" final state: " << scode <<
" and " << s2code;
857 <<
" scattering angle: " << C3CM;
861 double Mt = t->
Mass();
872 double tE = TMath::Sqrt(tP3L.Mag2() + Mt*Mt);
883#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
885 <<
"|p3| = " << P3L <<
", E3 = " << E3L;
887 <<
"|p4| = " << P4L <<
", E4 = " << E4L;
932 <<
"*** Nothing left to interact with, escaping.";
988 LOG(
"HNIntranuke2025",
pWARN) <<
"R0 = " <<
fR0 <<
" fermi";
999 LOG(
"HNIntranuke2025",
pWARN) <<
"DoFermi? = " << ((
fDoFermi)?(
true):(
false));
1018 double fractionElas = 1 - (fractionAbsorption + fractionCex);
1024 double totalFrac = fractionCex + fractionAbsorption + fractionElas;
1027 const double randomNumber = randomGenerator->
RndFsi().Rndm() * totalFrac;
1029 LOG(
"HNIntranuke2025",
pNOTICE) <<
"{ frac abs = " << fractionAbsorption;
1030 LOG(
"HNIntranuke2025",
pNOTICE) <<
" frac cex = " << fractionCex;
1031 LOG(
"HNIntranuke2025",
pNOTICE) <<
" frac elas = " << fractionElas <<
" }";
1033 if (randomNumber < fractionAbsorption && fRemnA > 1)
return kIHNFtAbs;
1034 else if (randomNumber < fractionAbsorption + fractionCex)
return kIHNFtCEx;
#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.
bool GetParam(const RgKey &name, T &p, bool is_top_call=true) const
bool GetParamDef(const RgKey &name, T &p, const T &def) const
const Algorithm * SubAlg(const RgKey ®istry_key) const
STDHEP-like event record entry that can fit a particle or a nucleus.
string Name(void) const
Name that corresponds to the PDG code.
int FirstMother(void) const
void SetMomentum(const TLorentzVector &p4)
void SetRescatterCode(int code)
void SetFirstMother(int m)
void SetLastMother(int m)
void SetRemovalEnergy(double Erm)
const TLorentzVector * P4(void) const
double Mass(void) const
Mass that corresponds to the PDG code.
int LastMother(void) const
void SetStatus(GHepStatus_t s)
double E(void) const
Get energy.
double KinE(bool mass_from_pdg=false) const
Get kinetic energy.
GENIE's GHEP MC event record.
virtual GHepParticle * TargetNucleus(void) const
virtual void AddParticle(const GHepParticle &p)
virtual GHepParticle * Particle(int position) const
INukeFateHN_t HadronFateOset() const
INukeFateHN_t HadronFateHN(const GHepParticle *p) const
void SimulateHadronicFinalState(GHepRecord *ev, GHepParticle *p) const
void ElasHN(GHepRecord *ev, GHepParticle *p, INukeFateHN_t fate) const
void ProcessEventRecord(GHepRecord *event_rec) const
double FateWeight(int pdgc, INukeFateHN_t fate) const
bool HandleCompoundNucleusHN(GHepRecord *ev, GHepParticle *p) const
int HandleCompoundNucleus(GHepRecord *ev, GHepParticle *p, int mom) const
void AbsorbHN(GHepRecord *ev, GHepParticle *p, INukeFateHN_t fate) const
void InelasticHN(GHepRecord *ev, GHepParticle *p) const
void GammaInelasticHN(GHepRecord *ev, GHepParticle *p, INukeFateHN_t fate) const
static INukeHadroData2025 * Instance(void)
static string AsString(INukeFateHN_t fate)
static string AsString(INukeMode_t mode)
double fChPionMFPScale
tweaking factors for tuning
double fDelRPion
factor by which Pion Compton wavelength gets multiplied to become nuclear size enhancement
int fRemnA
remnant nucleus A
double fNucAbsFac
absorption xsec correction factor (hN Mode)
int fRemnZ
remnant nucleus Z
double fHadStep
step size for intranuclear hadron transport
double fFermiMomentum
whether or not particle collision is pauli blocked
double fNR
param multiplying the nuclear radius, determining how far to track hadrons beyond the "nuclear bounda...
bool fUseOset
Oset model for low energy pion in hN.
bool fAltOset
NuWro's table-based implementation (not recommended)
double fNeutralPionMFPScale
TLorentzVector fRemnP4
P4 of remnant system.
double fFermiFac
testing parameter to modify fermi momentum
double fNucRmvE
binding energy to subtract from cascade nucleons
bool fXsecNNCorr
use nuclear medium correction for NN cross section
bool IsInNucleus(const GHepParticle *p) const
bool fDoCompoundNucleus
whether or not to do compound nucleus considerations
INukeHadroData2025 * fHadroData2025
a collection of h+N,h+A data & calculations
double fDelRNucleon
factor by which Nucleon Compton wavelength gets multiplied to become nuclear size enhancement
const NuclearModelI * fNuclmodel
nuclear model used to generate fermi momentum
virtual void ProcessEventRecord(GHepRecord *event_rec) const
double fNucCEXFac
charge exchange xsec correction factor (hN Mode)
bool fDoFermi
whether or not to do fermi mom.
double fR0
effective nuclear size param
double fEPreEq
threshold for pre-equilibrium reaction
Pure abstract base class. Defines the NuclearModelI interface to be implemented by any physics model ...
Singleton class to load & serve a TDatabasePDG.
static PDGLibrary * Instance(void)
TParticlePDG * Find(int pdgc, bool must_exist=true)
A singleton holding random number generator classes. All random number generation in GENIE should tak...
static RandomGen * Instance()
Access instance.
TRandom3 & RndFsi(void) const
rnd number generator used by intranuclear cascade monte carlos
A Neutrino Interaction Target. Is a transparent encapsulation of quite different physical systems suc...
void SetHitNucPdg(int pdgc)
An exception thrown by SimulateHadronState for kinematics problems. TwoBodyCollision/Kinematics used ...
void SetReason(string reason)
Misc GENIE control constants.
static const unsigned int kRjMaxIterations
bool IsNeutronOrProton(int pdgc)
static constexpr double MeV
Simple functions for loading and reading nucleus dependent keys from config files.
void Equilibrium(GHepRecord *ev, GHepParticle *p, int &RemnA, int &RemnZ, TLorentzVector &RemnP4, bool DoFermi, double FermiFac, const NuclearModelI *Nuclmodel, double NucRmvE, EINukeMode mode=kIMdHN)
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.
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)
Root of GENIE utility namespaces.
THE MAIN GENIE PROJECT NAMESPACE
enum genie::EINukeFateHN_t INukeFateHN_t
INukeOset * currentInstance