40 #include <TLorentzVector.h> 48 #include "Conventions/GBuild.h" 71 using std::ostringstream;
72 using namespace genie;
79 int pdgc,
const TLorentzVector & x4,
const TLorentzVector & p4,
80 double A,
double Z,
double nRpi,
double nRnuc,
const bool useOset,
const bool altOset,
const bool xsecNNCorr,
string INukeMode)
94 bool is_kaon = pdgc ==
kPdgKP;
97 if(!is_pion && !is_nucleon && !is_kaon && !is_gamma)
return 0.;
107 double momentum = p4.Vect().Mag();
108 double ring = (momentum>0) ? 1.240/momentum : 0;
110 if(A<=20) { ring /= 2.; }
117 if(INukeMode==
"hN2015")
119 if (is_pion ) { ring *= nRpi; }
120 else if (is_nucleon ) { ring *= nRnuc; }
121 else if (is_gamma || is_kaon || useOset) { ring = 0.;}
125 if (is_pion || is_kaon ) { ring *= nRpi; }
126 else if (is_nucleon ) { ring *= nRnuc; }
127 else if (is_gamma ) { ring = 0.; }
131 double rnow = x4.Vect().Mag();
137 double ke = (p4.Energy() - p4.M()) /
units::MeV;
144 double ppcnt = (double) Z/ (
double)
A;
147 if (is_pion and (INukeMode ==
"hN2015") and useOset and ke < 350.0)
150 { sigtot = fHadroData2015 -> XSecPipp_Tot() -> Evaluate(ke)*ppcnt;
151 sigtot+= fHadroData2015 -> XSecPipn_Tot() -> Evaluate(ke)*(1-ppcnt);}
153 { sigtot = fHadroData2015 -> XSecPi0p_Tot() -> Evaluate(ke)*ppcnt;
154 sigtot+= fHadroData2015 -> XSecPi0n_Tot() -> Evaluate(ke)*(1-ppcnt);}
156 { sigtot = fHadroData2015 -> XSecPipn_Tot() -> Evaluate(ke)*ppcnt;
157 sigtot+= fHadroData2015 -> XSecPipp_Tot() -> Evaluate(ke)*(1-ppcnt);}
160 sigtot = fHadroData2015 -> XSecPp_Tot() -> Evaluate(ke)*ppcnt;
165 double R0 = 1.25 * TMath::Power(A,1./3.) + 2.0 * 0.65;
166 double Mp = pLib->
Find(2212)->Mass();
167 double M = pLib->
Find(pdgc)->Mass();
170 if (Z*hc/137./x4.Vect().Mag() > E)
173 double Bc = z*Z*hc/137./R0;
175 double f = TMath::ACos(TMath::Power(x,0.5)) - TMath::Power(x*(1-x),0.5);
176 double B = 0.63*z*Z*TMath::Power((M/Mp)/E,0.5);
177 double Pc = TMath::Exp(-B*f);
180 sigtot+= fHadroData2015 -> XSecPn_Tot() -> Evaluate(ke)*(1-ppcnt);
182 double E0 = TMath::Power(A,0.2)*12.;
183 if (INukeMode==
"hN2015"){
if(ke<E0){sigtot=0.0;}}
187 sigtot = fHadroData2015 -> XSecPn_Tot() -> Evaluate(ke)*ppcnt;
188 sigtot+= fHadroData2015 -> XSecNn_Tot() -> Evaluate(ke)*(1-ppcnt);
189 double E0 = TMath::Power(A,0.2)*12.;
190 if (INukeMode==
"hN2015"){
if(ke<E0){sigtot=0.0;}}
193 { sigtot = fHadroData2015 -> XSecKpN_Tot() -> Evaluate(ke);
196 { sigtot = fHadroData2015 -> XSecGamp_fs() -> Evaluate(ke)*ppcnt;
197 sigtot+= fHadroData2015 -> XSecGamn_fs() -> Evaluate(ke)*(1-ppcnt);}
209 if (xsecNNCorr and is_nucleon)
214 if(sigtot<1
E-6){sigtot=1
E-6;}
217 double lamda = 1. / (rho * sigtot);
220 if( ! TMath::Finite(lamda) ) {
233 int pdgc,
const TLorentzVector & x4,
const TLorentzVector & p4,
double A)
248 if(!is_deltapp)
return 0.;
251 double rnow = x4.Vect().Mag();
256 double ke = (p4.Energy() - p4.M()) /
units::MeV;
257 ke = TMath::Max(1500., ke);
258 ke = TMath::Min( 0., ke);
263 else if (ke<1000) sig=40;
270 double lamda = 1. / (rho * sig);
273 if( ! TMath::Finite(lamda) ) {
281 int pdgc,
const TLorentzVector & x4,
const TLorentzVector & p4,
double A,
double Z,
282 double mfp_scale_factor,
double nRpi,
double nRnuc,
double NR,
double R0)
301 double R = NR * R0 * TMath::Power(A, 1./3.);
303 TVector3 dr3 = p4.Vect().Unit();
304 TLorentzVector dr4(dr3,0);
307 <<
"Calculating survival probability for hadron with PDG code = " << pdgc
308 <<
" and momentum = " << p4.P() <<
" GeV";
310 <<
"mfp scale = " << mfp_scale_factor
311 <<
", nRpi = " << nRpi <<
", nRnuc = " << nRnuc <<
", NR = " << NR
312 <<
", R0 = " << R0 <<
" fm";
314 TLorentzVector x4_curr(x4);
317 double rnow = x4_curr.Vect().Mag();
318 if (rnow > (R+step))
break;
320 x4_curr += (step*dr4);
321 rnow = x4_curr.Vect().Mag();
324 double mfp_twk = mfp * mfp_scale_factor;
326 double dprob = (mfp_twk>0) ? TMath::Exp(-step/mfp_twk) : 0.;
336 LOG(
"INukeUtils",
pDEBUG) <<
"Psurv = " << prob;
342 const TLorentzVector & x4,
const TLorentzVector & p4,
343 double A,
double NR,
double R0)
349 double R = NR * R0 * TMath::Power(A, 1./3.);
352 TVector3 dr3 = p4.Vect().Unit();
353 TLorentzVector dr4(dr3,0);
355 TLorentzVector x4_curr(x4);
359 double rnow = x4_curr.Vect().Mag();
360 x4_curr += (step*dr4);
362 rnow = x4_curr.Vect().Mag();
369 int pdgc,
const TLorentzVector & x4,
const TLorentzVector & p4,
370 double A,
double Z,
double NR,
double R0)
379 double R = NR * R0 * TMath::Power(A, 1./3.);
382 TVector3 dr3 = p4.Vect().Unit();
383 TLorentzVector dr4(dr3,0);
385 TLorentzVector x4_curr(x4);
390 double rnow = x4_curr.Vect().Mag();
391 x4_curr += (step*dr4);
393 rnow = x4_curr.Vect().Mag();
396 d_mfp += (step/lambda);
414 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ 416 <<
"Stepping particle [" << p->
Name() <<
"] by dr = " << step <<
" fm";
420 TVector3 dr = p->
P4()->Vect().Unit();
423 TLorentzVector dx4(dr,dt);
424 TLorentzVector x4new = *(p->
X4()) + dx4;
426 if(nuclear_radius > 0.) {
431 double r = x4new.Vect().Mag();
432 double rmax = nuclear_radius+epsilon;
435 <<
"Particle was stepped too far away (r = " << r <<
" fm)";
437 <<
"Placing it " << epsilon
438 <<
" fm outside the nucleus (r' = " << rmax <<
" fm)";
444 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ 462 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ 464 <<
"PreEquilibrium() is invoked for a : " << p->
Name()
465 <<
" whose kinetic energy is : " << p->
KinE();
472 bool allow_dup =
true;
475 double ppcnt = (double) RemnZ / (
double) RemnA;
479 double pKE = p->
KinE();
480 double c = 1 + (0.08 / pKE);
481 TVector3 pP3_2 = p->
P4()->Vect() *
c;
482 TVector3 pP3_1 = p->
P4()->Vect() - pP3_2;
484 TLorentzVector clusP4_1( pP3_1, 0.080);
485 TLorentzVector clusP4_2( pP3_2, pKE - 0.080 );
487 TLorentzVector clusX4(*p->
X4());
494 LOG(
"INukeUtils",
pDEBUG) <<
"cluster formation check";
495 LOG(
"INukeUtils",
pDEBUG) <<
"particle p0: E = " << p->
E() <<
" , px = " << p->
Px() <<
" , py = " << p->
Py() <<
" , pz = " << p->
Pz();
496 LOG(
"INukeUtils",
pDEBUG) <<
"particle p1: E = " << p1->
E() <<
" , px = " << p1->
Px() <<
" , py = " << p1->
Py() <<
" , pz = " << p1->
Pz();
497 LOG(
"INukeUtils",
pDEBUG) <<
"particle p2: E = " << p2->
E() <<
" , px = " << p2->
Px() <<
" , py = " << p2->
Py() <<
" , pz = " << p2->
Pz();
498 LOG(
"INukeUtils",
pDEBUG) <<
"conservation: dE = " << p->
E()-p1->
E()-p2->
E() <<
" dpx = " << p->
Px()-p1->
Px()-p2->
Px() <<
" dpy = " << p->
Py()-p1->
Py()-p2->
Py() <<
" dpz = " << p->
Pz()-p1->
Pz()-p2->
Pz() ;
500 RemnP4 -= clusP4_1 + clusP4_2 - *p->
P4();
525 if(rnd->
RndFsi().Rndm()<ppcnt)
534 ppcnt = (double) RemnZ / (
double) RemnA;
541 TVector3 pBuf = p->
P4()->Vect();
542 double mBuf = p->
Mass();
543 double eBuf = TMath::Sqrt(pBuf.Mag2() + mBuf*mBuf);
544 TLorentzVector tSum(pBuf,eBuf);
547 for(pdg_iter=++(list.begin());pdg_iter!=list.end();++pdg_iter)
549 target.SetHitNucPdg(*pdg_iter);
551 mBuf = pLib->
Find(*pdg_iter)->Mass();
553 pBuf = FermiFac * Nuclmodel->
Momentum3();
554 eBuf = TMath::Sqrt(pBuf.Mag2() + mBuf*mBuf);
555 tSum += TLorentzVector(pBuf,eBuf);
556 RemnP4 -= TLorentzVector(pBuf,eBuf-mBuf);
558 TLorentzVector dP4 = tSum + TLorentzVector(TVector3(0,0,0),-mSum);
565 if(success)
LOG(
"INukeUtils",
pINFO) <<
"Successful phase space decay for pre-equilibrium nucleus FSI event";
569 exception.
SetReason(
"Phase space generation of pre-equilibrium nucleus final state failed, details above");
664 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ 666 <<
"Equilibrium() is invoked for a : " << p->
Name()
667 <<
" whose kinetic energy is : " << p->
KinE();
674 bool allow_dup =
true;
678 double ppcnt = (double) RemnZ / (
double) RemnA;
688 if(rnd->
RndFsi().Rndm()<ppcnt)
697 ppcnt = (double) RemnZ / (
double) RemnA;
700 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ 702 <<
"Remnant nucleus (A,Z) = (" << RemnA <<
", " << RemnZ <<
")";
709 TVector3 pBuf = p->
P4()->Vect();
710 double mBuf = p->
Mass();
711 double eBuf = TMath::Sqrt(pBuf.Mag2() + mBuf*mBuf);
712 TLorentzVector tSum(pBuf,eBuf);
715 for(pdg_iter=++(list.begin());pdg_iter!=list.end();++pdg_iter)
717 target.SetHitNucPdg(*pdg_iter);
719 mBuf = pLib->
Find(*pdg_iter)->Mass();
721 pBuf = FermiFac * Nuclmodel->
Momentum3();
722 eBuf = TMath::Sqrt(pBuf.Mag2() + mBuf*mBuf);
723 tSum += TLorentzVector(pBuf,eBuf);
724 RemnP4 -= TLorentzVector(pBuf,eBuf-mBuf);
726 TLorentzVector dP4 = tSum + TLorentzVector(TVector3(0,0,0),-mSum);
732 if (success)
LOG(
"INukeUtils",
pINFO) <<
"successful pre-equilibrium interaction";
736 exception.
SetReason(
"Phase space generation of compound nucleus final state failed, details above");
743 GHepRecord* ev,
int pcode,
int tcode,
int scode,
int s2code,
double C3CM,
756 double M1, M2, M3, M4;
757 double E3L, P3L, E4L, P4L;
758 TVector3 tP1L, tPtot, tbeta, tbetadir, tTrans, tVect;
759 TVector3 tP1zCM, tP2zCM, tP3L, tP4L;
771 M1 = pLib->
Find(pcode)->Mass();
772 M2 = pLib->
Find(tcode)->Mass();
773 M3 = pLib->
Find(scode)->Mass();
774 M4 = pLib->
Find(s2code)->Mass();
777 TLorentzVector t4P1L = *p->
P4();
778 TLorentzVector t4P2L = *t->
P4();
781 double bindE = 0.025;
784 LOG(
"TwoBodyCollision",
pNOTICE) <<
"M1 = " << t4P1L.M() <<
" , M2 = " << t4P2L.M();
785 LOG(
"TwoBodyCollision",
pNOTICE) <<
"E1 = " << t4P1L.E() <<
" , E2 = " << t4P2L.E();
787 if ( (p->
Energy()-p->
Mass()) < bindE ){bindE = 0.;}
790 if((pcode==2112||pcode==2212)&&(t4P1L.E()-M1)<.1) bindE = 0.0;
791 if((pcode==211||pcode==-211||pcode==111)&&(t4P1L.E()-M1)<.08) bindE = 0.0;
792 if((pcode==321)&&(t4P1L.E()-M1)<.1) bindE = 0.0;
795 TLorentzVector t4P3L, t4P4L;
798 P3L = t4P3L.Vect().Mag();
799 P4L = t4P4L.Vect().Mag();
804 <<
"TwoBodyKinematics fails: C3CM, P3 = " << C3CM <<
" " 805 << P3L <<
" " << E3L <<
"\n" <<
" P4 = " 806 << P4L <<
" " << E4L ;
811 P3L = t4P3L.Vect().Mag();
812 P4L = t4P4L.Vect().Mag();
816 <<
"C3CM, P3 = " << C3CM <<
" " 817 << P3L <<
" " << E3L <<
"\n" <<
" P4 = " 818 << P4L <<
" " << E4L ;
821 if(!(TMath::Finite(P3L)) || P3L<.001)
824 <<
"Particle 3 momentum small or non-finite: " << P3L
825 <<
"\n" <<
"--> Assigning .001 as new momentum";
827 E3L = TMath::Sqrt(P3L*P3L + M3*M3);
829 if(!(TMath::Finite(P4L)) || P4L<.001)
832 <<
"Particle 4 momentum small or non-finite: " << P4L
833 <<
"\n" <<
"--> Assigning .001 as new momentum";
835 E4L = TMath::Sqrt(P4L*P4L + M4*M4);
854 <<
"t4P2L= " << t4P2L.E() <<
" " << t4P2L.Z()
855 <<
" RemnP4= " << RemnP4.E() <<
" " << RemnP4.Z() ;
881 LOG(
"INukeUtils",
pINFO) <<
"Successful 2 body collision";
887 double M3,
double M4, TLorentzVector t4P1L, TLorentzVector t4P2L,
888 TLorentzVector &t4P3L, TLorentzVector &t4P4L,
double C3CM, TLorentzVector &RemnP4,
double bindE)
908 double E1L, E2L, P1L, P2L, E3L, P3L;
912 double E1CM, E2CM, E3CM, P3CM;
915 double theta1, theta2, theta5, P1zL, P2zL, P1tL, P2tL;
916 TVector3 tbeta, tbetadir, tTrans, tVect;
917 TVector3 tP1zCM, tP2zCM, vP3L;
918 TLorentzVector t4P1buf, t4P2buf, t4Ptot;
927 if (C3CM < -1. || C3CM > 1.)
return false;
930 S3CM = TMath::Sqrt(1.0 - C3CM*C3CM);
941 t4Ptot = t4P1buf + t4P2buf;
943 LOG(
"INukeUtils",
pINFO) <<
"M1 "<<t4P1L.M()<<
", M2 "<<t4P2L.M();
944 LOG(
"INukeUtils",
pINFO) <<
"E1L "<<E1L<<
", E1CM "<<E1CM;
945 LOG(
"INukeUtils",
pINFO) <<
"bindE = " << bindE;
955 LOG(
"INukeUtils",
pNOTICE) <<
"TwoBodyKinematics Failed: Forbidden by binding energy";
956 LOG(
"INukeUtils",
pNOTICE) <<
"E1L, E2L, M3, M4 : "<< E1L <<
", "<< E2L <<
", "<< M3 <<
", "<< M4;
957 t4P3L.SetPxPyPzE(0,0,0,0);
958 t4P4L.SetPxPyPzE(0,0,0,0);
964 tbeta = t4Ptot.Vect() * (1.0 / (E1L + E2L));
965 tbetadir = tbeta.Unit();
967 gm = 1.0 / TMath::Sqrt(1.0 - beta*beta);
970 theta1 = t4P1buf.Angle(tbeta);
971 theta2 = t4P2buf.Angle(tbeta);
972 P1zL = P1L*TMath::Cos(theta1);
973 P2zL = P2L*TMath::Cos(theta2);
974 P1tL = TMath::Sqrt(P1L*P1L - P1zL*P1zL);
975 P2tL = -TMath::Sqrt(P2L*P2L - P2zL*P2zL);
977 if(TMath::Abs((tVect - tbetadir).Mag())<.01) tVect.SetXYZ(0,1,0);
978 theta5 = tVect.Angle(tbetadir);
979 tTrans = (tVect - TMath::Cos(theta5)*tbetadir).Unit();
982 E1CM = gm*E1L - gm*beta*P1zL;
983 tP1zCM = gm*P1zL*tbetadir - gm*tbeta*E1L;
984 E2CM = gm*E2L - gm*beta*P2zL;
985 tP2zCM = gm*P2zL*tbetadir - gm*tbeta*E2L;
989 LOG(
"INukeUtils",
pINFO) <<
"M1 "<<t4P1L.M()<<
", M2 "<<t4P2L.M();
990 LOG(
"INukeUtils",
pINFO) <<
"E1L "<<E1L<<
", E1CM "<<E1CM;
991 LOG(
"INukeUtils",
pINFO) <<
"P1zL "<<P1zL<<
", P1zCM "<<tP1zCM.Mag()<<
", P1tL "<<P1tL;
992 LOG(
"INukeUtils",
pINFO) <<
"E2L "<<E2L<<
", E2CM "<<E2CM;
993 LOG(
"INukeUtils",
pINFO) <<
"P2zL "<<P2zL<<
", P2zCM "<<tP2zCM.Mag()<<
", P2tL "<<P2tL;
994 LOG(
"INukeUtils",
pINFO) <<
"C3CM "<<C3CM;
997 E3CM = (Et*Et + M3*M3 - M4*M4) / (2.0 * Et);
1000 if(E3CM*E3CM - M3*M3<0 || E3CM<0 || Et<0)
1002 if (Et<0)
LOG(
"INukeUtils",
pNOTICE) <<
"TwoBodyKinematics Failed: Total energy is negative";
1003 if (E3CM<M3)
LOG(
"INukeUtils",
pNOTICE) <<
"TwoBodyKinematics Failed: Scattered Particle 3 CM energy is too small";
1004 if (E3CM*E3CM - M3*M3<0)
LOG(
"INukeUtils",
pNOTICE) <<
"TwoBodyKinematics Failed: Scattered Particle 3 CM momentum is nonreal";
1005 t4P3L.SetPxPyPzE(0,0,0,0);
1006 t4P4L.SetPxPyPzE(0,0,0,0);
1009 P3CM = TMath::Sqrt(E3CM*E3CM - M3*M3);
1012 P3zL = gm*beta*E3CM + gm*P3CM*C3CM;
1015 P3L = TMath::Sqrt(P3zL*P3zL + P3tL*P3tL);
1016 E3L = TMath::Sqrt(P3L*P3L + M3*M3);
1020 double E4CM = Et-E3CM;
1021 double P4zL = gm*beta*E4CM - gm*P3CM*C3CM;
1022 double P4tL = -1.*P3tL;
1023 double P4L = TMath::Sqrt(P4zL*P4zL + P4tL*P4tL);
1024 double E4L = TMath::Sqrt(P4L*P4L + M4*M4);
1026 LOG(
"INukeUtils",
pINFO) <<
"M3 "<< M3 <<
", M4 "<< M4;
1027 LOG(
"INukeUtils",
pINFO) <<
"E3L "<<E3L<<
", E3CM "<<E3CM;
1028 LOG(
"INukeUtils",
pINFO) <<
"P3zL "<<P3zL<<
", P3tL "<<P3tL;
1029 LOG(
"INukeUtils",
pINFO) <<
"C3L "<<P3zL/P3L;
1030 LOG(
"INukeUtils",
pINFO) <<
"Check:";
1031 LOG(
"INukeUtils",
pINFO) <<
"E4L "<<E4L<<
", E4CM "<<E4CM;
1032 LOG(
"INukeUtils",
pINFO) <<
"P4zL "<<P4zL<<
", P4tL "<<P4tL;
1033 LOG(
"INukeUtils",
pINFO) <<
"P4L "<<P4L;
1034 LOG(
"INukeUtils",
pINFO) <<
"C4L "<<P4zL/P4L;
1036 double echeck = E1L + E2L - (E3L + E4L);
1037 double pzcheck = P1zL+ P2zL - (P3zL + P4zL);
1038 double ptcheck = P1tL+ P2tL - (P3tL + P4tL);
1040 LOG(
"INukeUtils",
pINFO) <<
"Check 4-momentum conservation - Energy "<<echeck<<
", z momentum "<<pzcheck <<
", transverse momentum " << ptcheck ;
1045 if(!(TMath::Finite(P3L)) || P3L<.001)
1048 <<
"Particle 3 momentum small or non-finite: " << P3L
1049 <<
"\n" <<
"--> Assigning .001 as new momentum";
1053 E3L = TMath::Sqrt(P3L*P3L + M3*M3);
1059 vP3L = P3zL*tbetadir + P3tL*tTrans;
1060 vP3L.Rotate(PHI3,tbetadir);
1062 t4P3L.SetVect(vP3L);
1065 t4P4L = t4P1buf + t4P2buf - t4P3L;
1066 t4P4L-= TLorentzVector(0,0,0,bindE);
1073 if(t4P4L.Mag2()<0 || t4P4L.E()<0)
1075 LOG(
"INukeUtils",
pNOTICE)<<
"TwoBodyKinematics Failed: Target mass or energy is negative";
1076 t4P3L.SetPxPyPzE(0,0,0,0);
1077 t4P4L.SetPxPyPzE(0,0,0,0);
1081 if (bindE!=0) RemnP4 += TLorentzVector(0,0,0,bindE);
1087 bool DoFermi,
double FermiFac,
double FermiMomentum,
const NuclearModelI* Nuclmodel)
1099 double M1, M2, M3, M4, M5;
1100 double P1L, P2L, P3L, P4L, P5L;
1101 double E1L, E2L, E3L, E4L, E5L;
1102 double E1CM, E2CM, P3tL;
1103 double PizL, PitL, PiL, EiL;
1104 double EiCM, P4CM2, E4CM2, E5CM2, P3CM, E3CM;
1105 double beta, gm, beta2, gm2;
1106 double P3zL, P4zL, P4tL, P5zL, P5tL;
1107 double Et, M, theta1, theta2;
1109 double theta3, theta4, phi3, phi4, theta5;
1110 TVector3 tP2L, tP1L, tPtot, tbeta, tbetadir, tTrans, tP4L, tP5L;
1111 TVector3 tP1zCM, tP2zCM, tP3L, tPiL, tbeta2, tbetadir2, tVect, tTrans2;
1120 M2 = pLib->
Find(tcode)->Mass();
1131 target.SetHitNucPdg(tcode);
1133 tP2L = FermiFac * Nuclmodel->
Momentum3();
1135 E2L = TMath::Sqrt(tP2L.Mag2() + M2*M2);
1139 tP2L.SetXYZ(0.0, 0.0, 0.0);
1147 P1L = TMath::Sqrt(E1L*E1L - M1*M1);
1148 tP1L = p->
P4()->Vect();
1149 tPtot = tP1L + tP2L;
1151 tbeta = tPtot * (1.0 / (E1L + E2L));
1152 tbetadir = tbeta.Unit();
1154 gm = 1.0 / TMath::Sqrt(1.0 - beta*beta);
1156 theta1 = tP1L.Angle(tbeta);
1157 theta2 = tP2L.Angle(tbeta);
1158 P1zL = P1L*TMath::Cos(theta1);
1159 P2zL = P2L*TMath::Cos(theta2);
1160 tVect.SetXYZ(1,0,0);
1161 if(TMath::Abs((tVect - tbetadir).Mag())<.01) tVect.SetXYZ(0,1,0);
1162 theta5 = tVect.Angle(tbetadir);
1163 tTrans = (tVect - TMath::Cos(theta5)*tbetadir).Unit();
1165 E1CM = gm*E1L - gm*beta*P1zL;
1166 tP1zCM = gm*P1zL*tbetadir - gm*tbeta*E1L;
1167 E2CM = gm*E2L - gm*beta*P2zL;
1168 tP2zCM = gm*P2zL*tbetadir - gm*tbeta*E2L;
1170 M = (rnd->
RndFsi().Rndm()*(Et - M3 - M4 - M5)) + (M4 + M5);
1171 E3CM = (Et*Et + M3*M3 - M*M)/(2*Et);
1173 if(E3CM*E3CM - M3*M3<0)
1176 <<
"PionProduction P3 has non-real momentum - retry kinematics";
1177 LOG(
"INukeUtils",
pNOTICE) <<
"Energy, masses of 3 fs particales:" 1178 << E3CM <<
" " << M3 <<
" " <<
" " << M4 <<
" " << M5;
1180 exception.
SetReason(
"PionProduction particle 3 has non-real momentum");
1184 P3CM = TMath::Sqrt(E3CM*E3CM - M3*M3);
1191 P3zL = gm*beta*E3CM + gm*P3CM*TMath::Cos(theta3);
1192 P3tL = P3CM*TMath::Sin(theta3);
1193 PizL = gm*beta*EiCM - gm*P3CM*TMath::Cos(theta3);
1194 PitL = -P3CM*TMath::Sin(theta3);
1196 P3L = TMath::Sqrt(P3zL*P3zL + P3tL*P3tL);
1197 PiL = TMath::Sqrt(PizL*PizL + PitL*PitL);
1198 E3L = TMath::Sqrt(P3L*P3L + M3*M3);
1199 EiL = TMath::Sqrt(PiL*PiL + M*M);
1202 if(!(TMath::Finite(P3L)) || P3L < .001)
1205 <<
"Particle 3 " << M3 <<
" momentum small or non-finite: " << P3L
1206 <<
"\n" <<
"--> Assigning .001 as new momentum";
1210 E3L = TMath::Sqrt(P3L*P3L + M3*M3);
1213 tP3L = P3zL*tbetadir + P3tL*tTrans;
1214 tPiL = PizL*tbetadir + PitL*tTrans;
1215 tP3L.Rotate(phi3,tbetadir);
1216 tPiL.Rotate(phi3,tbetadir);
1219 tbeta2 = tPiL * (1.0 / EiL);
1220 tbetadir2 = tbeta2.Unit();
1221 beta2 = tbeta2.Mag();
1222 gm2 = 1.0 / TMath::Sqrt(1.0 - beta2*beta2);
1224 E4CM2 = (M*M + M4*M4 - M5*M5) / (2*M);
1226 P4CM2 = TMath::Sqrt(E4CM2*E4CM2 - M4*M4);
1228 tVect.SetXYZ(1,0,0);
1229 if(TMath::Abs((tVect - tbetadir2).Mag())<.01) tVect.SetXYZ(0,1,0);
1230 theta5 = tVect.Angle(tbetadir2);
1231 tTrans2 = (tVect - TMath::Cos(theta5)*tbetadir2).Unit();
1233 P4zL = gm2*beta2*E4CM2 + gm2*P4CM2*TMath::Cos(theta4);
1234 P4tL = P4CM2*TMath::Sin(theta4);
1235 P5zL = gm2*beta2*E5CM2 - gm2*P4CM2*TMath::Cos(theta4);
1238 P4L = TMath::Sqrt(P4zL*P4zL + P4tL*P4tL);
1239 P5L = TMath::Sqrt(P5zL*P5zL + P5tL*P5tL);
1240 E4L = TMath::Sqrt(P4L*P4L + M4*M4);
1241 E5L = TMath::Sqrt(P5L*P5L + M5*M5);
1244 if(!(TMath::Finite(P4L)) || P4L < .001)
1247 <<
"Particle 4 " << M4 <<
" momentum small or non-finite: " << P4L
1248 <<
"\n" <<
"--> Assigning .001 as new momentum";
1252 E4L = TMath::Sqrt(P4L*P4L + M4*M4);
1254 if(!(TMath::Finite(P5L)) || P5L < .001)
1257 <<
"Particle 5 " << M5 <<
" momentum small or non-finite: " << P5L
1258 <<
"\n" <<
"--> Assigning .001 as new momentum";
1262 E5L = TMath::Sqrt(P5L*P5L + M5*M5);
1265 tP4L = P4zL*tbetadir2 + P4tL*tTrans2;
1266 tP5L = P5zL*tbetadir2 + P5tL*tTrans2;
1267 tP4L.Rotate(phi4,tbetadir2);
1268 tP5L.Rotate(phi4,tbetadir2);
1274 <<
"PionProduction fails because of Pauli blocking - retry kinematics";
1276 exception.
SetReason(
"PionProduction final state not determined");
1290 TLorentzVector(tP3L,E3L);
1291 TLorentzVector(tP4L,E4L);
1292 TLorentzVector(tP5L,E5L);
1316 TLorentzVector &RemnP4,
bool DoFermi,
double FermiFac,
double FermiMomentum,
const NuclearModelI* Nuclmodel)
1337 int pcode = p->
Pdg();
1339 int p1code = p->
Pdg();
1341 int p3code = 0, p4code = 0, p5code = 0;
1357 double kine = 1000*p->
KinE();
1365 double xsec2pi0n = TMath::Max(0.,TMath::Exp(8.82 - (573.2/(kine-107.3))));
1368 double xsecpippimn = TMath::Max(0.,TMath::Exp(11.06 - (985.9/(kine-88.2))));
1371 double xsecpimpi0p = TMath::Max(0.,TMath::Exp(9.58 - (1229.4/(kine-60.5))));
1372 double totpimp = xsec2pi0n + xsecpippimn + xsecpimpi0p;
1378 double xsec2pipn = TMath::Max(0.,TMath::Exp(5.64 - (222.6/(kine-150.))));
1381 double xsecpippi0p = TMath::Max(0.,TMath::Exp(7.95 - (852.6/(kine-77.8))));
1382 double totpipp = xsec2pipn + xsecpippi0p;
1384 if (totpimp<=0 && totpipp<=0) {
1385 LOG(
"INukeUtils",
pNOTICE) <<
"InelasticHN called below threshold energy";
1391 double xsecp, xsecn;
1393 case kPdgPi0: xsecp = 0.5 * (totpimp + totpipp); xsecn = xsecp;
break;
1394 case kPdgPiP: xsecp = totpipp; xsecn = totpimp;
break;
1395 case kPdgPiM: xsecp = totpimp; xsecn = totpipp;
break;
1397 LOG(
"INukeUtils",
pWARN) <<
"InelasticHN cannot handle probe: " 1400 exception.
SetReason(
"PionProduction final state not determined");
1409 xsecn *= RemnA-RemnZ;
1413 double rand = rnd->
RndFsi().Rndm() * (xsecp + xsecn);
1415 { rand /= RemnZ; ptarg =
true;}
1417 { rand -= xsecp; rand /= RemnA-RemnZ; ptarg =
false;}
1422 if (((ptarg==
true)&&(p1code==
kPdgPiP))
1423 || ((ptarg==
false)&&(p1code==
kPdgPiM)))
1425 if (rand < xsec2pipn)
1437 else if (((ptarg==
false)&&(p1code==
kPdgPiP))
1438 || ((ptarg==
true)&&(p1code==
kPdgPiM)))
1440 if (rand < xsec2pi0n)
1446 else if (rand < (xsec2pi0n + xsecpippimn))
1461 rand = rnd->
RndFsi().Rndm();
1462 if (rand < 191./270.)
1468 else if (rand < 7./135.)
1485 exception.
SetReason(
"PionProduction final state not determined");
1493 double tote = p->
Energy();
1494 double pMass = pLib->
Find(2212)->Mass();
1495 double nMass = pLib->
Find(2112)->Mass();
1496 double etapp2ppPi0 =
1498 double etapp2pnPip =
1500 pMass+nMass,pLib->
Find(211)->Mass());
1501 double etapn2nnPip =
1503 double etapn2ppPim =
1506 if ((etapp2ppPi0<=0.)&&(etapp2pnPip<=0.)&&(etapn2nnPip<=0.)&&(etapn2ppPim<=0.)) {
1507 LOG(
"INukeUtils",
pNOTICE) <<
"PionProduction() called below threshold energy";
1509 exception.
SetReason(
"PionProduction final state not possible - below threshold");
1515 double xsecppPi0=0,xsecpnPiP=0,xsecnnPiP=0,xsecppPiM=0;
1517 xsecppPi0 = 4511*(1-.91*TMath::Exp(-TMath::Power((etapp2ppPi0-.705),2)));
1518 xsecppPi0 *= (1-TMath::Exp(-TMath::Power((.556*etapp2ppPi0),3.5)));
1519 xsecppPi0 *= (1-TMath::Exp(-56.897/(etapp2ppPi0*etapp2ppPi0)));
1520 xsecppPi0 = TMath::Max(0.,xsecppPi0);}
1523 xsecpnPiP = 18840*(1-.808*TMath::Exp(-TMath::Power((etapp2pnPip-.371),2)));
1524 xsecpnPiP *= (1-TMath::Exp(-TMath::Power((.568*etapp2pnPip),3.2)));
1525 xsecpnPiP *= (1-TMath::Exp(-39.818/(etapp2pnPip*etapp2pnPip)));
1526 xsecpnPiP = TMath::Max(0.,xsecpnPiP);}
1529 xsecnnPiP = 7670*(1-.479*TMath::Exp(-TMath::Power((etapn2nnPip-.947),2)));
1530 xsecnnPiP *= (1-TMath::Exp(-TMath::Power((.35*etapn2nnPip),3.2)));
1531 xsecnnPiP *= (1-TMath::Exp(-71.53/(etapn2nnPip*etapn2nnPip)));
1532 xsecnnPiP = TMath::Max(0.,xsecnnPiP);}
1535 xsecppPiM = 7670*(1-.479*TMath::Exp(-TMath::Power((etapn2ppPim-.947),2)));
1536 xsecppPiM *= (1-TMath::Exp(-TMath::Power((.35*etapn2ppPim),3.2)));
1537 xsecppPiM *= (1-TMath::Exp(-71.53/(etapn2ppPim*etapn2ppPim)));
1538 xsecppPiM = TMath::Max(0.,xsecppPiM);}
1541 double sigma10 = TMath::Max(0.,xsecpnPiP - xsecppPi0);
1542 double sigma01 = TMath::Max(0.,xsecppPiM + xsecnnPiP - xsecppPi0);
1544 double xsecpnPi0 = .5*(sigma10 + sigma01);
1545 xsecpnPi0 = TMath::Max(xsecpnPi0,0.);
1547 LOG(
"INukeUtils",
pDEBUG) <<
'\n' <<
"Cross section values: "<<
'\n' 1548 << xsecppPi0 <<
" PP pi0" <<
'\n' 1549 << xsecpnPiP <<
" PN pi+" <<
'\n' 1550 << xsecnnPiP <<
" NN pi+" <<
'\n' 1551 << xsecpnPi0 <<
" PN pi0";
1553 double xsecp=0,xsecn=0;
1555 case kPdgProton: xsecp=xsecppPi0+xsecpnPiP; xsecn=xsecppPiM+xsecnnPiP+xsecpnPi0;
break;
1556 case kPdgNeutron: xsecp=xsecppPiM+xsecnnPiP+xsecpnPi0; xsecn=xsecppPi0+xsecpnPiP;
break;
1558 LOG(
"INukeUtils",
pWARN) <<
"InelasticHN cannot handle probe: " 1567 xsecn *= RemnA-RemnZ;
1571 double rand = rnd->
RndFsi().Rndm() * (xsecp + xsecn);
1573 { rand /= RemnZ; ptarg =
true;}
1575 { rand -= xsecp; rand /= RemnA-RemnZ; ptarg =
false;}
1609 <<
"Unable to handle probe (=" << p1code <<
") in InelasticHN()";
1616 LOG(
"INukeUtils",
pNOTICE) <<
"PionProduction() failed : no nucleons to produce pions";
1624 LOG(
"INukeUtils",
pNOTICE) <<
"PionProduction() failed : too few protons in nucleus";
1626 exception.
SetReason(
"PionProduction fails - too few protons available");
1652 LOG(
"INukeUtils",
pDEBUG) <<
"Remnant (A,Z) = (" <<RemnA<<
','<<RemnZ<<
')';
1654 RemnP4 -= *s1->
P4() + *s2->
P4() + *s3->
P4() - *p->
P4();
1659 exception.
SetReason(
"PionProduction final state not determined");
1666 double Mtwopart,
double Mpi)
1676 double Scm = Minc*Minc + Mtarg*Mtarg + 2*Mtarg*nrg;
1678 eta= TMath::Power(Scm,2) + TMath::Power(Mtwopart,4) + TMath::Power(Mpi,4);
1679 eta-= 2*TMath::Power(Mtwopart*Mpi,2);
1680 eta-= 2*Scm*TMath::Power(Mtwopart,2);
1681 eta-= 2*Scm*TMath::Power(Mpi,2);
1682 eta = TMath::Power(eta/Scm,1./2.);
1685 eta=TMath::Max(eta,0.);
1699 LOG(
"INukeUtils",
pINFO) <<
"*** Performing a Phase Space Decay";
1700 assert(pdgv.size() > 1);
1702 LOG(
"INukeUtils",
pINFO) <<
"probe mass: M = " << p->
Mass();
1706 ostringstream state_sstream;
1707 state_sstream <<
"( ";
1710 double * mass =
new double[pdgv.size()];
1711 double mass_sum = 0;
1712 for(pdg_iter = pdgv.begin(); pdg_iter != pdgv.end(); ++pdg_iter) {
1713 int pdgc = *pdg_iter;
1718 state_sstream << nm <<
" ";
1720 state_sstream <<
")";
1722 TLorentzVector * pd = p->
GetP4();
1729 double availE = pd->Energy() + mass_sum;
1730 if(is_nuc||is_kaon) availE -= p->
Mass();
1734 <<
"size, mass_sum, availE, pd mass, energy = " << pdgv.size() <<
" " 1735 << mass_sum <<
" " << availE <<
" " << p->
Mass() <<
" " << p->
Energy() ;
1738 double dE = mass_sum;
1739 if(is_nuc||is_kaon) dE -= p->
Mass();
1740 TLorentzVector premnsub(0,0,0,dE);
1744 <<
"Final state = " << state_sstream.str() <<
" has N = " << pdgv.size()
1745 <<
" particles / total mass = " << mass_sum;
1750 TGenPhaseSpace GenPhaseSpace;
1751 bool permitted = GenPhaseSpace.SetDecay(*pd, pdgv.size(), mass);
1754 <<
" *** Phase space decay is not permitted \n" 1755 <<
" Total particle mass = " << mass_sum <<
"\n" 1772 for(
int k=0;
k<200;
k++) {
1773 double w = GenPhaseSpace.Generate();
1774 wmax = TMath::Max(wmax,w);
1779 <<
"Max phase space gen. weight @ current hadronic interaction: " << wmax;
1786 bool accept_decay=
false;
1787 unsigned int itry=0;
1789 while(!accept_decay)
1796 <<
"Couldn't generate an unweighted phase space decay after " 1797 << itry <<
" attempts";
1803 double w = GenPhaseSpace.Generate();
1804 double gw = wmax * rnd->
RndFsi().Rndm();
1808 <<
"Decay weight = " << w <<
" > max decay weight = " << wmax;
1811 LOG(
"INukeUtils",
pNOTICE) <<
"Decay weight = " << w <<
" / R = " << gw;
1812 accept_decay = (gw<=
w);
1820 LOG(
"INukeUtils",
pNOTICE) <<
"mother index = " << mom;
1824 TLorentzVector * v4 = p->
GetX4();
1826 double checkpx = p->
Px();
1827 double checkpy = p->
Py();
1828 double checkpz = p->
Pz();
1829 double checkE = p->
E();
1833 for(pdg_iter = pdgv.begin(); pdg_iter != pdgv.end(); ++pdg_iter) {
1836 int pdgc = *pdg_iter;
1840 TLorentzVector * p4fin = GenPhaseSpace.GetDecay(i++);
1847 double En = p4fin->Energy();
1854 double dE_leftover = TMath::Min(NucRmvE, KE);
1857 double pmag_old = p4fin->P();
1858 double pmag_new = TMath::Sqrt(TMath::Max(0.,En*En-M*M));
1859 double scale = pmag_new / pmag_old;
1860 double pxn = scale * p4fin->Px();
1861 double pyn = scale * p4fin->Py();
1862 double pzn = scale * p4fin->Pz();
1864 TLorentzVector p4n(pxn,pyn,pzn,En);
1875 if (p4n.Vect().Mag()>=0.001)
1877 GHepParticle new_particle(pdgc, ist_pi, mom,-1,-1,-1, p4n, *v4);
1885 LOG(
"INukeUtils",
pINFO)<<
"Momentum too small; assigning 0.001 as new momentum";
1887 double phi = 2*
kPi*rnd->
RndFsi().Rndm();
1888 double omega = 2*rnd->
RndFsi().Rndm();
1891 double E4n = TMath::Sqrt(0.001*0.001+M*M);
1892 p4n.SetPxPyPzE(0.001,0,0,E4n);
1893 p4n.Rotate(TMath::ACos(1-omega),TVector3(0,0,1));
1894 p4n.Rotate(phi,TVector3(1,0,0));
1896 RemnP4 -= (p4n - TLorentzVector(0,0,0,M));
1898 GHepParticle new_particle(pdgc, ist, mom,-1,-1,-1, p4n, *v4);
1904 GHepParticle new_particle(pdgc, ist, mom,-1,-1,-1, p4n, *v4);
1910 double dpx = (1-
scale)*p4fin->Px();
1911 double dpy = (1-
scale)*p4fin->Py();
1912 double dpz = (1-
scale)*p4fin->Pz();
1913 TLorentzVector premnadd(dpx,dpy,dpz,dE_leftover);
1917 LOG(
"INukeUtils",
pNOTICE) <<
"check conservation: Px = " << checkpx <<
" Py = " << checkpy
1918 <<
" Pz = " << checkpz <<
" E = " << checkE;
1929 const double &pionKineticEnergy,
1930 const double &density,
1932 const double &protonFraction,
1933 const bool &isTableChosen
1939 if (iNukeOset == NULL)
1944 static const std::string dataDir = (gSystem->Getenv(
"GINUKEHADRONDATA")) ?
1945 string(gSystem->Getenv(
"GINUKEHADRONDATA")) :
1946 string(gSystem->Getenv(
"GENIE")) +
1947 string(
"/data/evgen/intranuke/");
1949 static const std::string dataFile = dataDir +
"tot_xsec/" 1950 "intranuke-xsection-pi+N-Oset.dat";
1959 iNukeOset->
setupOset (density, pionKineticEnergy, pionPDG, protonFraction);
const int kPdgP33m1232_DeltaPP
double MeanFreePath_Delta(int pdgc, const TLorentzVector &x4, const TLorentzVector &p4, double A)
Mean free path (Delta++ test)
An exception thrown by SimulateHadronState for kinematics problems. TwoBodyCollision/Kinematics used ...
void SetFirstMother(int m)
virtual int ParticlePosition(int pdg, GHepStatus_t i, int start=0) const
TLorentzVector * GetX4(void) const
TRandom3 & RndFsi(void) const
rnd number generator used by intranuclear cascade monte carlos
static INukeNucleonCorr * getInstance()
get single instance of INukeNucleonCorr; create if necessary
#include "Numerical/GSFunc.h"
static INukeHadroData2015 * Instance(void)
double E(void) const
Get energy.
static RandomGen * Instance()
Access instance.
double Density(double r, int A, double ring=0.)
Table-based implementation of Oset model.
enum genie::EGHepStatus GHepStatus_t
bool TwoBodyKinematics(double M3, double M4, TLorentzVector tP1L, TLorentzVector tP2L, TLorentzVector &tP3L, TLorentzVector &tP4L, double C3CM, TLorentzVector &RemnP4, double bindE=0)
bool ThreeBodyKinematics(GHepRecord *ev, GHepParticle *p, int tcode, GHepParticle *s1, GHepParticle *s2, GHepParticle *s3, bool DoFermi=false, double FermiFac=0, double FermiMomentum=0, const NuclearModelI *Nuclmodel=(const NuclearModelI *) 0)
string P4AsString(const TLorentzVector *p)
static const unsigned int kMaxUnweightDecayIterations
Pure abstract base class. Defines the NuclearModelI interface to be implemented by any physics model ...
double Mass(Resonance_t res)
resonance mass (GeV)
void SetMomentum(const TLorentzVector &p4)
double Mass(void) const
Mass that corresponds to the PDG code.
double MeanFreePath(int pdgc, const TLorentzVector &x4, const TLorentzVector &p4, double A, double Z, double nRpi=0.5, double nRnuc=1.0, const bool useOset=false, const bool altOset=false, const bool xsecNNCorr=false, string INukeMode="XX2015")
Mean free path (pions, nucleons)
A singleton holding random number generator classes. All random number generation in GENIE should tak...
double Pz(void) const
Get Pz.
double Energy(void) const
Get energy.
bool PhaseSpaceDecay(GHepRecord *ev, GHepParticle *p, const PDGCodeList &pdgv, TLorentzVector &RemnP4, double NucRmvE, EINukeMode mode=kIMdHA)
general phase space decay method
double Px(void) const
Get Px.
int LastMother(void) const
int FirstMother(void) const
string Name(void) const
Name that corresponds to the PDG code.
void PreEquilibrium(GHepRecord *ev, GHepParticle *p, int &RemnA, int &RemnZ, TLorentzVector &RemnP4, bool DoFermi, double FermiFac, const NuclearModelI *Nuclmodel, double NucRmvE, EINukeMode mode=kIMdHN)
const int kPdgCompNuclCluster
static double fMinKinEnergy
void SetPosition(const TLorentzVector &v4)
double getTotalCrossSection() const
return total = (qel+cex+abs) cross section
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
void SetReason(string reason)
TLorentzVector * GetP4(void) const
A Neutrino Interaction Target. Is a transparent encapsulation of quite different physical systems suc...
bool TwoBodyKinematics(double M3, double M4, TLorentzVector tP1L, TLorentzVector tP2L, TLorentzVector &tP3L, TLorentzVector &tP4L, double C3CM, TLorentzVector &RemnP4, double bindE=0)
void StepParticle(GHepParticle *p, double step, double nuclear_radius=-1.)
Step particle.
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)
virtual GHepParticle * TargetNucleus(void) const
Misc GENIE control constants.
double ProbSurvival(int pdgc, const TLorentzVector &x4, const TLorentzVector &p4, double A, double Z, double mfp_scale_factor=1.0, double nRpi=0.5, double nRnuc=1.0, double NR=3, double R0=1.4)
Hadron survival probability.
virtual void setupOset(const double &density, const double &pionTk, const int &pionPDG, const double &protonFraction)=0
use to set up Oset class (assign pion Tk, nuclear density etc)
double sigmaTotalOset(const double &pionKineticEnergy, const double &density, const int &pionPDG, const double &protonFraction, const bool &isTableChosen=true)
double CalculateEta(double Minc, double ke, double Mtarg, double Mtwopart, double Mpi)
void SetRemovalEnergy(double Erm)
double KinE(bool mass_from_pdg=false) const
Get kinetic energy.
static PDGLibrary * Instance(void)
double Dist2Exit(const TLorentzVector &x4, const TLorentzVector &p4, double A, double NR=3, double R0=1.4)
Distance to exit.
void SetLastMother(int m)
Singleton class to load & serve a TDatabasePDG.
TLorentzVector * X4(void) const
void Equilibrium(GHepRecord *ev, GHepParticle *p, int &RemnA, int &RemnZ, TLorentzVector &RemnP4, bool DoFermi, double FermiFac, const NuclearModelI *Nuclmodel, double NucRmvE, EINukeMode mode=kIMdHN)
void SetStatus(GHepStatus_t s)
virtual TVector3 Momentum3(void) const
bool IsNeutronOrProton(int pdgc)
TParticlePDG * Find(int pdgc)
virtual bool GenerateNucleon(const Target &) const =0
virtual void AddParticle(const GHepParticle &p)
double Dist2ExitMFP(int pdgc, const TLorentzVector &x4, const TLorentzVector &p4, double A, double Z, double NR=3, double R0=1.4)
Distance to exit.
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.
string X4AsString(const TLorentzVector *x)
TLorentzVector * P4(void) const
static double fMaxKinEnergyHN
GENIE's GHEP MC event record.
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.
string Vec3AsString(const TVector3 *vec)
Root of GENIE utility namespaces.
cet::coded_exception< error, detail::translate > exception
void push_back(int pdg_code)
double Py(void) const
Get Py.