Public Member Functions | Private Member Functions | Private Attributes | Friends | List of all members
genie::HAIntranuke2014 Class Reference

#include <HAIntranuke2014.h>

Inheritance diagram for genie::HAIntranuke2014:
genie::Intranuke2014 genie::EventRecordVisitorI genie::Algorithm

Public Member Functions

 HAIntranuke2014 ()
 
 HAIntranuke2014 (string config)
 
 ~HAIntranuke2014 ()
 
void ProcessEventRecord (GHepRecord *event_rec) const
 
- Public Member Functions inherited from genie::Intranuke2014
 Intranuke2014 ()
 
 Intranuke2014 (string name)
 
 Intranuke2014 (string name, string config)
 
 ~Intranuke2014 ()
 
void Configure (const Registry &config)
 Configure the algorithm. More...
 
void Configure (string param_set)
 Configure the algorithm. More...
 
- Public Member Functions inherited from genie::EventRecordVisitorI
virtual ~EventRecordVisitorI ()
 
- Public Member Functions inherited from genie::Algorithm
virtual ~Algorithm ()
 
virtual void FindConfig (void)
 Lookup configuration from the config pool. More...
 
virtual const RegistryGetConfig (void) const
 Get configuration registry. More...
 
RegistryGetOwnedConfig (void)
 Get a writeable version of an owned configuration Registry. More...
 
virtual const AlgIdId (void) const
 Get algorithm ID. More...
 
virtual AlgStatus_t GetStatus (void) const
 Get algorithm status. More...
 
virtual bool AllowReconfig (void) const
 
virtual AlgCmp_t Compare (const Algorithm *alg) const
 Compare with input algorithm. More...
 
virtual void SetId (const AlgId &id)
 Set algorithm ID. More...
 
virtual void SetId (string name, string config)
 
const AlgorithmSubAlg (const RgKey &registry_key) const
 
void AdoptConfig (void)
 
void AdoptSubstructure (void)
 
virtual void Print (ostream &stream) const
 Print algorithm info. More...
 

Private Member Functions

void LoadConfig (void)
 
void SimulateHadronicFinalState (GHepRecord *ev, GHepParticle *p) const
 
void SimulateHadronicFinalStateKinematics (GHepRecord *ev, GHepParticle *p) const
 
INukeFateHA_t HadronFateHA (const GHepParticle *p) const
 
void Inelastic (GHepRecord *ev, GHepParticle *p, INukeFateHA_t fate) const
 
void ElasHA (GHepRecord *ev, GHepParticle *p, INukeFateHA_t fate) const
 
void InelasticHA (GHepRecord *ev, GHepParticle *p, INukeFateHA_t fate) const
 
double PiBounce (void) const
 
double PnBounce (void) const
 
int HandleCompoundNucleus (GHepRecord *ev, GHepParticle *p, int mom) const
 

Private Attributes

int nuclA
 value of A for the target nucleus in hA mode More...
 
unsigned int fNumIterations
 

Friends

class IntranukeTester
 

Additional Inherited Members

- Protected Member Functions inherited from genie::Intranuke2014
void TransportHadrons (GHepRecord *ev) const
 
void GenerateVertex (GHepRecord *ev) const
 
bool NeedsRescattering (const GHepParticle *p) const
 
bool CanRescatter (const GHepParticle *p) const
 
bool IsInNucleus (const GHepParticle *p) const
 
void SetTrackingRadius (const GHepParticle *p) const
 
double GenerateStep (GHepRecord *ev, GHepParticle *p) const
 
- Protected Member Functions inherited from genie::EventRecordVisitorI
 EventRecordVisitorI ()
 
 EventRecordVisitorI (string name)
 
 EventRecordVisitorI (string name, string config)
 
- Protected Member Functions inherited from genie::Algorithm
 Algorithm ()
 
 Algorithm (string name)
 
 Algorithm (string name, string config)
 
void Initialize (void)
 
void DeleteConfig (void)
 
void DeleteSubstructure (void)
 
- Protected Attributes inherited from genie::Intranuke2014
double fTrackingRadius
 tracking radius for the nucleus in the current event More...
 
TGenPhaseSpace fGenPhaseSpace
 a phase space generator More...
 
INukeHadroData2014fHadroData2014
 a collection of h+N,h+A data & calculations More...
 
AlgFactoryfAlgf
 algorithm factory instance More...
 
const NuclearModelIfNuclmodel
 nuclear model used to generate fermi momentum More...
 
int fRemnA
 remnant nucleus A More...
 
int fRemnZ
 remnant nucleus Z More...
 
TLorentzVector fRemnP4
 P4 of remnant system. More...
 
GEvGenMode_t fGMode
 event generation mode (lepton+A, hadron+A, ...) More...
 
double fR0
 effective nuclear size param More...
 
double fNR
 param multiplying the nuclear radius, determining how far to track hadrons beyond the "nuclear boundary" More...
 
double fNucRmvE
 binding energy to subtract from cascade nucleons More...
 
double fDelRPion
 factor by which Pion Compton wavelength gets multiplied to become nuclear size enhancement More...
 
double fDelRNucleon
 factor by which Nucleon Compton wavelength gets multiplied to become nuclear size enhancement More...
 
double fHadStep
 step size for intranuclear hadron transport More...
 
double fNucAbsFac
 absorption xsec correction factor (hN Mode) More...
 
double fNucCEXFac
 charge exchange xsec correction factor (hN Mode) More...
 
double fEPreEq
 threshold for pre-equilibrium reaction More...
 
double fFermiFac
 testing parameter to modify fermi momentum More...
 
double fFreeStep
 produced particle free stem, in fm More...
 
double fFermiMomentum
 whether or not particle collision is pauli blocked More...
 
bool fDoFermi
 whether or not to do fermi mom. More...
 
bool fDoMassDiff
 whether or not to do mass diff. mode More...
 
bool fDoCompoundNucleus
 whether or not to do compound nucleus considerations More...
 
- Protected Attributes inherited from genie::Algorithm
bool fAllowReconfig
 
bool fOwnsConfig
 true if it owns its config. registry More...
 
bool fOwnsSubstruc
 true if it owns its substructure (sub-algs,...) More...
 
AlgId fID
 algorithm name and configuration set More...
 
RegistryfConfig
 config. (either owned or pointing to config pool) More...
 
AlgStatus_t fStatus
 algorithm execution status More...
 
AlgMapfOwnedSubAlgMp
 local pool for owned sub-algs (taken out of the factory pool) More...
 

Detailed Description

Definition at line 51 of file HAIntranuke2014.h.

Constructor & Destructor Documentation

HAIntranuke2014::HAIntranuke2014 ( )

Definition at line 93 of file HAIntranuke2014.cxx.

93  :
94 Intranuke2014("genie::HAIntranuke2014")
95 {
96 
97 }
HAIntranuke2014::HAIntranuke2014 ( string  config)

Definition at line 99 of file HAIntranuke2014.cxx.

99  :
100 Intranuke2014("genie::HAIntranuke2014",config)
101 {
102 
103 }
HAIntranuke2014::~HAIntranuke2014 ( )

Definition at line 105 of file HAIntranuke2014.cxx.

106 {
107 
108 }

Member Function Documentation

void HAIntranuke2014::ElasHA ( GHepRecord ev,
GHepParticle p,
INukeFateHA_t  fate 
) const
private

Definition at line 438 of file HAIntranuke2014.cxx.

440 {
441  // scatters particle within nucleus, copy of hN code meant to run only once
442  // in hA mode
443 
444 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
445  LOG("HAIntranuke2014", pDEBUG)
446  << "ElasHA() is invoked for a : " << p->Name()
447  << " whose fate is : " << INukeHadroFates::AsString(fate);
448 #endif
449 
450  if(fate!=kIHAFtElas)
451  {
452  LOG("HAIntranuke2014", pWARN)
453  << "ElasHA() cannot handle fate: " << INukeHadroFates::AsString(fate);
454  return;
455  }
456 
457  // check remnants
458  if(fRemnA<0 || fRemnZ<0) // best to stop it here and not try again.
459  {
460  LOG("HAIntranuke2014", pWARN) << "Invalid Nucleus! : (A,Z) = ("<<fRemnA<<','<<fRemnZ<<')';
462  ev->AddParticle(*p);
463  return;
464  }
465 
466  // vars for incoming particle, target, and scattered pdg codes
467  int pcode = p->Pdg();
468  double Mp = p->Mass();
469  double Mt = 0.;
470  if (ev->TargetNucleus()->A()==fRemnA)
471  { Mt = PDGLibrary::Instance()->Find(ev->TargetNucleus()->Pdg())->Mass(); }
472  else
473  {
474  Mt = fRemnP4.M();
475  }
476  TLorentzVector t4PpL = *p->P4();
477  TLorentzVector t4PtL = fRemnP4;
478  double C3CM = 0.0;
479 
480  // calculate scattering angle
481  if(pcode==kPdgNeutron||pcode==kPdgProton) C3CM = TMath::Cos(this->PnBounce());
482  else C3CM = TMath::Cos(this->PiBounce());
483 
484  // calculate final 4 momentum of probe
485  TLorentzVector t4P3L, t4P4L;
486 
487  if (!utils::intranuke2014::TwoBodyKinematics(Mp,Mt,t4PpL,t4PtL,t4P3L,t4P4L,C3CM,fRemnP4))
488  {
489  LOG("HAIntranuke2014", pNOTICE) << "ElasHA() failed";
491  exception.SetReason("TwoBodyKinematics failed in ElasHA");
492  throw exception;
493  }
494 
495  // Update probe particle
496  p->SetMomentum(t4P3L);
498 
499  // Update Remnant nucleus
500  fRemnP4 = t4P4L;
501  LOG("HAIntranuke2014",pINFO)
502  << "C3cm = " << C3CM;
503  LOG("HAIntranuke2014",pINFO)
504  << "|p3| = " << t4P3L.Vect().Mag() << ", E3 = " << t4P3L.E() << ",Mp = " << Mp;
505  LOG("HAIntranuke2014",pINFO)
506  << "|p4| = " << fRemnP4.Vect().Mag() << ", E4 = " << fRemnP4.E() << ",Mt = " << Mt;
507 
508  ev->AddParticle(*p);
509 
510 }
An exception thrown by SimulateHadronState for kinematics problems. TwoBodyCollision/Kinematics used ...
int fRemnZ
remnant nucleus Z
Definition: Intranuke2014.h:97
double Mass(Resonance_t res)
resonance mass (GeV)
void SetMomentum(const TLorentzVector &p4)
double Mass(void) const
Mass that corresponds to the PDG code.
bool TwoBodyKinematics(double M3, double M4, TLorentzVector tP1L, TLorentzVector tP2L, TLorentzVector &tP3L, TLorentzVector &tP4L, double C3CM, TLorentzVector &RemnP4, double bindE=0)
int Pdg(void) const
Definition: GHepParticle.h:64
string Name(void) const
Name that corresponds to the PDG code.
int fRemnA
remnant nucleus A
Definition: Intranuke2014.h:96
double PiBounce(void) const
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:87
virtual GHepParticle * TargetNucleus(void) const
Definition: GHepRecord.cxx:323
#define pINFO
Definition: Messenger.h:53
#define pWARN
Definition: Messenger.h:51
double PnBounce(void) const
static PDGLibrary * Instance(void)
Definition: PDGLibrary.cxx:45
void SetStatus(GHepStatus_t s)
Definition: GHepParticle.h:125
static string AsString(INukeFateHN_t fate)
TParticlePDG * Find(int pdgc)
Definition: PDGLibrary.cxx:63
virtual void AddParticle(const GHepParticle &p)
Definition: GHepRecord.cxx:526
const int kPdgProton
Definition: PDGCodes.h:62
int A(void) const
#define pNOTICE
Definition: Messenger.h:52
TLorentzVector * P4(void) const
Definition: GHepParticle.h:79
const int kPdgNeutron
Definition: PDGCodes.h:64
TLorentzVector fRemnP4
P4 of remnant system.
Definition: Intranuke2014.h:98
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
#define pDEBUG
Definition: Messenger.h:54
INukeFateHA_t HAIntranuke2014::HadronFateHA ( const GHepParticle p) const
private

Definition at line 216 of file HAIntranuke2014.cxx.

217 {
218 // Select a hadron fate in HA mode
219 //
220  RandomGen * rnd = RandomGen::Instance();
221 
222  // get pdgc code & kinetic energy in MeV
223  int pdgc = p->Pdg();
224  double ke = p->KinE() / units::MeV;
225 
226  LOG("HAIntranuke2014", pINFO)
227  << "Selecting hA fate for " << p->Name() << " with KE = " << ke << " MeV";
228 
229  // try to generate a hadron fate
230  unsigned int iter = 0;
231  while(iter++ < kRjMaxIterations) {
232 
233  // handle pions
234  //
235  if (pdgc==kPdgPiP || pdgc==kPdgPiM || pdgc==kPdgPi0) {
236 
237  double frac_cex = fHadroData2014->FracADep(pdgc, kIHAFtCEx, ke, nuclA);
238  double frac_elas = fHadroData2014->FracADep(pdgc, kIHAFtElas, ke, nuclA);
239  double frac_inel = fHadroData2014->FracADep(pdgc, kIHAFtInelas, ke, nuclA);
240  double frac_abs = fHadroData2014->FracADep(pdgc, kIHAFtAbs, ke, nuclA);
241  double frac_piprod = fHadroData2014->FracADep(pdgc, kIHAFtPiProd, ke, nuclA);
242  LOG("HAIntranuke2014", pDEBUG)
243  << "\n frac{" << INukeHadroFates::AsString(kIHAFtCEx) << "} = " << frac_cex
244  << "\n frac{" << INukeHadroFates::AsString(kIHAFtElas) << "} = " << frac_elas
245  << "\n frac{" << INukeHadroFates::AsString(kIHAFtInelas) << "} = " << frac_inel
246  << "\n frac{" << INukeHadroFates::AsString(kIHAFtAbs) << "} = " << frac_abs
247  << "\n frac{" << INukeHadroFates::AsString(kIHAFtPiProd) << "} = " << frac_piprod;
248 
249  // compute total fraction (can be <1 if fates have been switched off)
250  double tf = frac_cex +
251  frac_elas +
252  frac_inel +
253  frac_abs +
254  frac_piprod;
255 
256  double r = tf * rnd->RndFsi().Rndm();
257 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
258  LOG("HAIntranuke2014", pDEBUG) << "r = " << r << " (max = " << tf << ")";
259 #endif
260  double cf=0; // current fraction
261  if(r < (cf += frac_cex )) return kIHAFtCEx; // cex
262  if(r < (cf += frac_elas )) return kIHAFtElas; // elas
263  if(r < (cf += frac_inel )) return kIHAFtInelas; // inelas
264  if(r < (cf += frac_abs )) return kIHAFtAbs; // abs
265  if(r < (cf += frac_piprod )) return kIHAFtPiProd; // pi prod
266 
267  LOG("HAIntranuke2014", pWARN)
268  << "No selection after going through all fates! "
269  << "Total fraction = " << tf << " (r = " << r << ")";
270  }
271 
272  // handle nucleons
273  else if (pdgc==kPdgProton || pdgc==kPdgNeutron) {
274  double frac_cex = fHadroData2014->FracAIndep(pdgc, kIHAFtCEx, ke);
275  double frac_elas = fHadroData2014->FracAIndep(pdgc, kIHAFtElas, ke);
276  double frac_inel = fHadroData2014->FracAIndep(pdgc, kIHAFtInelas, ke);
277  double frac_abs = fHadroData2014->FracAIndep(pdgc, kIHAFtAbs, ke);
278  double frac_pipro = fHadroData2014->FracAIndep(pdgc, kIHAFtPiProd, ke);
279 
280  LOG("HAIntranuke2014", pDEBUG)
281  << "\n frac{" << INukeHadroFates::AsString(kIHAFtCEx) << "} = " << frac_cex
282  << "\n frac{" << INukeHadroFates::AsString(kIHAFtElas) << "} = " << frac_elas
283  << "\n frac{" << INukeHadroFates::AsString(kIHAFtInelas) << "} = " << frac_inel
284  << "\n frac{" << INukeHadroFates::AsString(kIHAFtAbs) << "} = " << frac_abs
285  << "\n frac{" << INukeHadroFates::AsString(kIHAFtPiProd) << "} = " << frac_pipro;
286 
287  // compute total fraction (can be <1 if fates have been switched off)
288  double tf = frac_cex +
289  frac_elas +
290  frac_inel +
291  frac_abs +
292  frac_pipro;
293 
294  double r = tf * rnd->RndFsi().Rndm();
295 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
296  LOG("HAIntranuke2014", pDEBUG) << "r = " << r << " (max = " << tf << ")";
297 #endif
298  double cf=0; // current fraction
299  if(r < (cf += frac_cex )) return kIHAFtCEx; // cex
300  if(r < (cf += frac_elas )) return kIHAFtElas; // elas
301  if(r < (cf += frac_inel )) return kIHAFtInelas; // inelas
302  if(r < (cf += frac_abs )) return kIHAFtAbs; // abs
303  if(r < (cf += frac_pipro )) return kIHAFtPiProd; // pi prod
304 
305  LOG("HAIntranuke2014", pWARN)
306  << "No selection after going through all fates! "
307  << "Total fraction = " << tf << " (r = " << r << ")";
308  }
309  // handle kaons
310  else if (pdgc==kPdgKP || pdgc==kPdgKM) {
311  double frac_inel = fHadroData2014->FracAIndep(pdgc, kIHAFtInelas, ke);
312  double frac_abs = fHadroData2014->FracAIndep(pdgc, kIHAFtAbs, ke);
313 
314  LOG("HAIntranuke2014", pDEBUG)
315  << "\n frac{" << INukeHadroFates::AsString(kIHAFtInelas) << "} = " << frac_inel
316  << "\n frac{" << INukeHadroFates::AsString(kIHAFtAbs) << "} = " << frac_abs;
317  // compute total fraction (can be <1 if fates have been switched off)
318  double tf = frac_inel +
319  frac_abs;
320  double r = tf * rnd->RndFsi().Rndm();
321 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
322  LOG("HAIntranuke2014", pDEBUG) << "r = " << r << " (max = " << tf << ")";
323 #endif
324  double cf=0; // current fraction
325  if(r < (cf += frac_inel )) return kIHAFtInelas; // inelas
326  if(r < (cf += frac_abs )) return kIHAFtAbs; // abs
327  }
328  }//iterations
329 
330  return kIHAFtUndefined;
331 }
TRandom3 & RndFsi(void) const
rnd number generator used by intranuclear cascade monte carlos
Definition: RandomGen.h:60
double FracADep(int hpdgc, INukeFateHA_t fate, double ke, int targA) const
static RandomGen * Instance()
Access instance.
Definition: RandomGen.cxx:79
static const double MeV
Definition: Units.h:130
INukeHadroData2014 * fHadroData2014
a collection of h+N,h+A data & calculations
Definition: Intranuke2014.h:93
Definition: tf_graph.h:23
A singleton holding random number generator classes. All random number generation in GENIE should tak...
Definition: RandomGen.h:30
int Pdg(void) const
Definition: GHepParticle.h:64
string Name(void) const
Name that corresponds to the PDG code.
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:87
const int kPdgKM
Definition: PDGCodes.h:147
const int kPdgKP
Definition: PDGCodes.h:146
const int kPdgPiP
Definition: PDGCodes.h:132
const int kPdgPi0
Definition: PDGCodes.h:134
#define pINFO
Definition: Messenger.h:53
#define pWARN
Definition: Messenger.h:51
int nuclA
value of A for the target nucleus in hA mode
double KinE(bool mass_from_pdg=false) const
Get kinetic energy.
static string AsString(INukeFateHN_t fate)
const int kPdgPiM
Definition: PDGCodes.h:133
double FracAIndep(int hpdgc, INukeFateHA_t fate, double ke) const
const int kPdgProton
Definition: PDGCodes.h:62
static const unsigned int kRjMaxIterations
Definition: Controls.h:27
const int kPdgNeutron
Definition: PDGCodes.h:64
#define pDEBUG
Definition: Messenger.h:54
int HAIntranuke2014::HandleCompoundNucleus ( GHepRecord ev,
GHepParticle p,
int  mom 
) const
privatevirtual

Implements genie::Intranuke2014.

Definition at line 1339 of file HAIntranuke2014.cxx.

1341 {
1342  // only relevant for hN mode
1343  return false;
1344 }
void HAIntranuke2014::Inelastic ( GHepRecord ev,
GHepParticle p,
INukeFateHA_t  fate 
) const
private

Definition at line 673 of file HAIntranuke2014.cxx.

675 {
676 
677  // Aaron Meyer (05/25/10)
678  //
679  // Called to handle all absorption and pi production reactions
680  //
681  // Nucleons -> Reaction approximated by exponential decay in p+n (sum) space,
682  // gaussian in p-n (difference) space
683  // -fit to hN simulations p C, Fe, Pb at 200, 800 MeV
684  // -get n from isospin, np-nn smaller by 2
685  // Pions -> Reaction approximated with a modified gaussian in p+n space,
686  // normal gaussian in p-n space
687  // -based on fits to multiplicity distributions of hN model
688  // for pi+ C, Fe, Pb at 250, 500 MeV
689  // -fit sum and diff of nn, np to Gaussian
690  // -get pi0 from isospin, np-nn smaller by 2
691  // -get pi- from isospin, np-nn smaller by 4
692  // -add 2-body absorption to better match McKeown data
693  // Kaons -> no guidance, use same code as pions.
694  //
695  // Normally distributed random number generated using Box-Muller transformation
696  //
697  // Pion production reactions rescatter pions in nucleus, otherwise unchanged from
698  // older versions of GENIE
699  //
700 
701 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
702  LOG("HAIntranuke2014", pDEBUG)
703  << "Inelastic() is invoked for a : " << p->Name()
704  << " whose fate is : " << INukeHadroFates::AsString(fate);
705 #endif
706 
707  bool allow_dup = true;
708  PDGCodeList list(allow_dup); // list of final state particles
709 
710  // only absorption/pipro fates allowed
711  if (fate == kIHAFtPiProd) {
712 
713  GHepParticle s1(*p);
714  GHepParticle s2(*p);
715  GHepParticle s3(*p);
716 
719 
720  if (success){
721  LOG ("HAIntranuke2014",pINFO) << " successful pion production fate";
722  // set status of particles and conserve charge/baryon number
723  s1.SetStatus(kIStStableFinalState); //should be redundant
724  // if (pdg::IsPion(s2->Pdg())) s2->SetStatus(kIStHadronInTheNucleus);
725  s2.SetStatus(kIStStableFinalState);
726  // if (pdg::IsPion(s3->Pdg())) s3->SetStatus(kIStHadronInTheNucleus);
727  s3.SetStatus(kIStStableFinalState);
728 
729  ev->AddParticle(s1);
730  ev->AddParticle(s2);
731  ev->AddParticle(s3);
732 
733  return;
734  }
735  else {
736  LOG("HAIntranuke2014", pNOTICE) << "Error: could not create pion production final state";
738  exception.SetReason("PionProduction kinematics failed - retry kinematics");
739  throw exception;
740  }
741  }
742 
743  else if (fate==kIHAFtAbs)
744 // tuned for pions - mixture of 2-body and many-body
745 // use same for kaons as there is no guidance
746  {
747  // Instances for reference
748  PDGLibrary * pLib = PDGLibrary::Instance();
749  RandomGen * rnd = RandomGen::Instance();
750 
751  double ke = p->KinE() / units::MeV;
752  int pdgc = p->Pdg();
753 
754  if (fRemnA<2)
755  {
756  LOG("HAIntranuke2014", pNOTICE) << "stop propagation - could not create absorption final state: too few particles";
758  ev->AddParticle(*p);
759  return;
760  }
761  if (fRemnZ<1 && (pdgc==kPdgPiM || pdgc==kPdgKM))
762  {
763  LOG("HAIntranuke2014", pNOTICE) << "stop propagation - could not create absorption final state: Pi- or K- cannot be absorbed by only neutrons";
765  ev->AddParticle(*p);
766  return;
767  }
768  if (fRemnA-fRemnZ<1 && (pdgc==kPdgPiP || pdgc==kPdgKP))
769  {
770  LOG("HAIntranuke2014", pINFO) << "stop propagation - could not create absorption final state: Pi+ or K+ cannot be absorbed by only protons";
772  ev->AddParticle(*p);
773  return;
774  }
775 
776  // for now, empirical split between multi-nucleon absorption and pi d -> N N
777  //
778  // added 03/21/11 - Aaron Meyer
779  //
780  if (pdg::IsPion(pdgc) && rnd->RndFsi().Rndm()<1.14*(.903-0.00189*fRemnA)*(1.35-0.00467*ke))
781  { // pi d -> N N, probability determined empirically with McKeown data
782 
783  INukeFateHN_t fate_hN=kIHNFtAbs;
784  int t1code,t2code,scode,s2code;
785  double ppcnt = (double) fRemnZ / (double) fRemnA; // % of protons
786 
787  // choose target nucleon
788  // -- fates weighted by values from Engel, Mosel...
789  if (pdgc==kPdgPiP) {
790  double Prob_pipd_pp=2.*ppcnt*(1.-ppcnt);
791  double Prob_pipnn_pn=.083*(1.-ppcnt)*(1.-ppcnt);
792  if (rnd->RndFsi().Rndm()*(Prob_pipd_pp+Prob_pipnn_pn)<Prob_pipd_pp){
793  t1code=kPdgNeutron; t2code=kPdgProton;
794  scode=kPdgProton; s2code=kPdgProton;}
795  else{
796  t1code=kPdgNeutron; t2code=kPdgNeutron;
797  scode=kPdgProton; s2code=kPdgNeutron;}
798  }
799  if (pdgc==kPdgPiM) {
800  double Prob_pimd_nn=2.*ppcnt*(1.-ppcnt);
801  double Prob_pimpp_pn=.083*ppcnt*ppcnt;
802  if (rnd->RndFsi().Rndm()*(Prob_pimd_nn+Prob_pimpp_pn)<Prob_pimd_nn){
803  t1code=kPdgProton; t2code=kPdgNeutron;
804  scode=kPdgNeutron; s2code=kPdgNeutron; }
805  else{
806  t1code=kPdgProton; t2code=kPdgProton;
807  scode=kPdgProton; s2code=kPdgNeutron;}
808  }
809  else { // pi0
810  double Prob_pi0d_pn=0.88*ppcnt*(1.-ppcnt); // 2 * .44
811  double Prob_pi0pp_pp=.14*ppcnt*ppcnt;
812  double Prob_pi0nn_nn=.14*(1.-ppcnt)*(1.-ppcnt);
813  if (rnd->RndFsi().Rndm()*(Prob_pi0d_pn+Prob_pi0pp_pp+Prob_pi0nn_nn)<Prob_pi0d_pn){
814  t1code=kPdgNeutron; t2code=kPdgProton;
815  scode=kPdgNeutron; s2code=kPdgProton; }
816  else if (rnd->RndFsi().Rndm()*(Prob_pi0d_pn+Prob_pi0pp_pp+Prob_pi0nn_nn)<(Prob_pi0d_pn+Prob_pi0pp_pp)){
817  t1code=kPdgProton; t2code=kPdgProton;
818  scode=kPdgProton; s2code=kPdgProton; }
819  else {
820  t1code=kPdgNeutron; t2code=kPdgNeutron;
821  scode=kPdgNeutron; s2code=kPdgNeutron; }
822  }
823  LOG("HAIntranuke2014",pINFO) << "choose 2 body absorption, probe, fs = " << pdgc <<" "<< scode <<" "<<s2code;
824  // assign proper masses
825  //double M1 = pLib->Find(pdgc) ->Mass();
826  double M2_1 = pLib->Find(t1code)->Mass();
827  double M2_2 = pLib->Find(t2code)->Mass();
828  //double M2 = M2_1 + M2_2;
829  double M3 = pLib->Find(scode) ->Mass();
830  double M4 = pLib->Find(s2code)->Mass();
831 
832  // handle fermi momentum
833  double E2_1L, E2_2L;
834  TVector3 tP2_1L, tP2_2L;
835  //TLorentzVector dNucl_P4;
836  Target target(ev->TargetNucleus()->Pdg());
837  if(fDoFermi)
838  {
839  target.SetHitNucPdg(t1code);
841  tP2_1L=fFermiFac * fNuclmodel->Momentum3();
842  E2_1L = TMath::Sqrt(tP2_1L.Mag2() + M2_1*M2_1);
843 
844  target.SetHitNucPdg(t2code);
846  tP2_2L=fFermiFac * fNuclmodel->Momentum3();
847  E2_2L = TMath::Sqrt(tP2_2L.Mag2() + M2_2*M2_2);
848 
849  //dNucl_P4=TLorentzVector(tP2_1L+tP2_2L,E2_1L+E2_2L);
850  }
851  else
852  {
853  tP2_1L.SetXYZ(0.0, 0.0, 0.0);
854  E2_1L = M2_1;
855 
856  tP2_2L.SetXYZ(0.0, 0.0, 0.0);
857  E2_2L = M2_2;
858  }
859  TLorentzVector dNucl_P4=TLorentzVector(tP2_1L+tP2_2L,E2_1L+E2_2L);
860 
861  double E2L = E2_1L + E2_2L;
862 
863  // adjust p to reflect scattering
864  // get random scattering angle
865  double C3CM = fHadroData2014->IntBounce(p,t1code,scode,fate_hN);
866  if (C3CM<-1.)
867  {
868  LOG("HAIntranuke2014", pWARN) << "Inelastic() failed: IntBounce returned bad angle - try again";
870  exception.SetReason("unphysical angle for hN scattering");
871  throw exception;
872  return;
873  }
874 
875  TLorentzVector t4P1L,t4P2L,t4P3L,t4P4L;
876  t4P1L=*p->P4();
877  t4P2L=TLorentzVector(TVector3(tP2_1L+tP2_2L),E2L);
878  double bindE=0.075; // set to fit McKeown data
879  //double bindE=0.0;
880  if (utils::intranuke2014::TwoBodyKinematics(M3,M4,t4P1L,t4P2L,t4P3L,t4P4L,C3CM,fRemnP4,bindE))
881  {
882  if (pdgc==kPdgPiP || pdgc==kPdgKP) fRemnZ++;
883  if (pdgc==kPdgPiM || pdgc==kPdgKM) fRemnZ--;
884  if (t1code==kPdgProton) fRemnZ--;
885  if (t2code==kPdgProton) fRemnZ--;
886  fRemnA-=2;
887 
888  fRemnP4-=dNucl_P4;
889 
890  // create t particles w/ appropriate momenta, code, and status
891  // Set target's mom to be the mom of the hadron that was cloned
892  GHepParticle* t1 = new GHepParticle(*p);
893  GHepParticle* t2 = new GHepParticle(*p);
894  t1->SetFirstMother(p->FirstMother());
895  t1->SetLastMother(p->LastMother());
896  t2->SetFirstMother(p->FirstMother());
897  t2->SetLastMother(p->LastMother());
898 
899  // adjust p to reflect scattering
900  t1->SetPdgCode(scode);
901  t1->SetMomentum(t4P3L);
902 
903  t2->SetPdgCode(s2code);
904  t2->SetMomentum(t4P4L);
905 
908 
909  ev->AddParticle(*t1);
910  ev->AddParticle(*t2);
911 
912  return;
913  }
914  else
915  {
916  LOG("HAIntranuke2014", pNOTICE) << "Inelastic in hA failed calling TwoBodyKineamtics";
918  exception.SetReason("Pion absorption kinematics through TwoBodyKinematics failed");
919  throw exception;
920 
921  }
922 
923  } // end pi d -> N N
924  else // multi-nucleon
925  {
926 
927  // declare some parameters for double gaussian and determine values chosen
928  // parameters for proton and pi+, others come from isospin transformations
929 
930  double ns0=0; // mean - sum of nucleons
931  double nd0=0; // mean - difference of nucleons
932  double Sig_ns=0; // std dev - sum
933  double Sig_nd=0; // std dev - diff
934  double gam_ns=0; // exponential decay rate (for nucleons)
935 
936  if ( pdg::IsNeutronOrProton (pdgc) ) // nucleon probe
937  {
938  // antisymmetric about Z=N
939  if (fRemnA-fRemnZ > fRemnZ)
940  nd0 = 135.227 * TMath::Exp(-7.124*(fRemnA-fRemnZ)/double(fRemnA)) - 2.762;
941  else
942  nd0 = -135.227 * TMath::Exp(-7.124* fRemnZ /double(fRemnA)) + 4.914;
943 
944  Sig_nd = 2.034 + fRemnA * 0.007846;
945 
946  double c1 = 0.041 + ke * 0.0001525;
947  double c2 = -0.003444 - ke * 0.00002324;
948 //change last factor from 30 to 15 so that gam_ns always larger than 0
949 //add check to be certain
950  double c3 = 0.064 - ke * 0.000015;
951  gam_ns = c1 * TMath::Exp(c2*fRemnA) + c3;
952  if(gam_ns<0.002) gam_ns = 0.002;
953  //gam_ns = 10.;
954  LOG("HAIntranuke2014", pINFO) << "nucleon absorption";
955  LOG("HAIntranuke2014", pINFO) << "--> mean diff distr = " << nd0 << ", stand dev = " << Sig_nd;
956  // LOG("HAIntranuke2014", pINFO) << "--> mean sum distr = " << ns0 << ", Stand dev = " << Sig_ns;
957  LOG("HAIntranuke2014", pINFO) << "--> gam_ns = " << gam_ns;
958  }
959  else if ( pdgc==kPdgPiP || pdgc==kPdgPi0 || pdgc==kPdgPiM) //pion probe
960  {
961  ns0 = .0001*(1.+ke/250.) * (fRemnA-10)*(fRemnA-10) + 3.5;
962  nd0 = (1.+ke/250.) - ((fRemnA/200.)*(1. + 2.*ke/250.));
963  Sig_ns = (10. + 4. * ke/250.)*TMath::Power(fRemnA/250.,0.9); //(1. - TMath::Exp(-0.02*fRemnA));
964  Sig_nd = 4*(1 - TMath::Exp(-0.03*ke));
965  LOG("HAIntranuke2014", pINFO) << "pion absorption";
966  LOG("HAIntranuke2014", pINFO) << "--> mean diff distr = " << nd0 << ", stand dev = " << Sig_nd;
967  LOG("HAIntranuke2014", pINFO) << "--> mean sum distr = " << ns0 << ", Stand dev = " << Sig_ns;
968  }
969  else if (pdgc==kPdgKP || pdgc==kPdgKM) // kaon probe
970  {
971  ns0 = (rnd->RndFsi().Rndm()>0.5?3:2);
972  nd0 = 1.;
973  Sig_ns = 0.1;
974  Sig_nd = 0.1;
975  LOG("HAIntranuke2014", pINFO) << "kaon absorption - set ns, nd later";
976  // LOG("HAIntranuke2014", pINFO) << "--> mean diff distr = " << nd0 << ", stand dev = " << Sig_nd;
977  // LOG("HAIntranuke2014", pINFO) << "--> mean sum distr = " << ns0 << ", Stand dev = " << Sig_ns;
978  }
979  else
980  {
981  LOG("HAIntranuke2014", pWARN) << "Inelastic() cannot handle absorption reaction for " << p->Name();
982  }
983 
984  // account for different isospin
985  if (pdgc==kPdgPi0 || pdgc==kPdgNeutron) nd0-=2.;
986  if (pdgc==kPdgPiM) nd0-=4.;
987 
988  int iter=0; // counter
989  int np=0,nn=0; // # of p, # of n
990  bool not_done=true;
991  double u1 = 0, u2 = 0;
992 
993  while (not_done)
994  {
995  // infinite loop check
996  if (iter>=100) {
997  LOG("HAIntranuke2014", pNOTICE) << "Error: could not choose absorption final state";
998  LOG("HAIntranuke2014", pNOTICE) << "--> mean diff distr = " << nd0 << ", stand dev = " << Sig_nd;
999  LOG("HAIntranuke2014", pNOTICE) << "--> mean sum distr = " << ns0 << ", Stand dev = " << Sig_ns;
1000  LOG("HAIntranuke2014", pNOTICE) << "--> gam_ns = " << gam_ns;
1001  LOG("HAIntranuke2014", pNOTICE) << "--> A = " << fRemnA << ", Z = " << fRemnZ << ", Energy = " << ke;
1003  exception.SetReason("Absorption choice of # of p,n failed");
1004  throw exception;
1005  }
1006  //here??
1007 
1008  // Box-Muller transform
1009  // Takes two uniform distribution random variables on (0,1]
1010  // Creates two normally distributed random variables on (0,inf)
1011 
1012  u1 = rnd->RndFsi().Rndm(); // uniform random variable 1
1013  u2 = rnd->RndFsi().Rndm(); // " " 2
1014  if (u1==0) u1 = rnd->RndFsi().Rndm();
1015  if (u2==0) u2 = rnd->RndFsi().Rndm(); // Just in case
1016 
1017  // normally distributed random variable
1018  double x2 = TMath::Sqrt(-2*TMath::Log(u1))*TMath::Sin(2*kPi*u2);
1019 
1020  double ns = 0;
1021 
1022  if ( pdg::IsNeutronOrProton (pdgc) ) //nucleon probe
1023  {
1024  ns = -TMath::Log(rnd->RndFsi().Rndm())/gam_ns; // exponential random variable
1025  }
1026  if ( pdg::IsKaon (pdgc) ) //charged kaon probe - either 2 or 3 nucleons to stay simple
1027  {
1028  ns = (rnd->RndFsi().Rndm()<0.5?2:3);
1029  }
1030  else if ( pdgc==kPdgPiP || pdgc==kPdgPi0 || pdgc==kPdgPiM) //pion probe
1031  {
1032  // Pion fit for sum takes for xs*exp((xs-x0)^2 / 2*sig_xs0)
1033  // Find random variable by first finding gaussian random variable
1034  // then throwing the value against a linear P.D.F.
1035  //
1036  // max is the maximum value allowed for the random variable (10 std + mean)
1037  // minimum allowed value is 0
1038 
1039  double max = ns0 + Sig_ns * 10;
1040  if(max>fRemnA) max=fRemnA;
1041  double x1 = 0;
1042  bool not_found = true;
1043  int iter2 = 0;
1044 
1045  while (not_found)
1046  {
1047  // infinite loop check
1048  if (iter2>=100)
1049  {
1050  LOG("HAIntranuke2014", pNOTICE) << "Error: stuck in random variable loop for ns";
1051  LOG("HAIntranuke2014", pNOTICE) << "--> mean of sum parent distr = " << ns0 << ", Stand dev = " << Sig_ns;
1052  LOG("HAIntranuke2014", pNOTICE) << "--> A = " << fRemnA << ", Z = " << fRemnZ << ", Energy = " << ke;
1053 
1055  exception.SetReason("Random number generator for choice of #p,n final state failed - unusual - redo kinematics");
1056  throw exception;
1057  }
1058 
1059  // calculate exponential random variable
1060  u1 = rnd->RndFsi().Rndm();
1061  u2 = rnd->RndFsi().Rndm();
1062  if (u1==0) u1 = rnd->RndFsi().Rndm();
1063  if (u2==0) u2 = rnd->RndFsi().Rndm();
1064  x1 = TMath::Sqrt(-2*TMath::Log(u1))*TMath::Cos(2*kPi*u2);
1065 
1066  ns = ns0 + Sig_ns * x1;
1067  if ( ns>max || ns<0 ) {iter2++; continue;}
1068  else if ( rnd->RndFsi().Rndm() > (ns/max) ) {iter2++; continue;}
1069  else {
1070  // accept this sum value
1071  not_found=false;
1072  }
1073  } //while(not_found)
1074  }//else pion
1075 
1076  double nd = nd0 + Sig_nd * x2; // difference (p-n) for both pion, nucleon probe
1077  if (pdgc==kPdgKP) // special for KP
1078  { if (ns==2) nd=0;
1079  if (ns>2) nd=1; }
1080 
1081  np = int((ns+nd)/2.+.5); // Addition of .5 for rounding correction
1082  nn = int((ns-nd)/2.+.5);
1083 
1084  LOG("HAIntranuke2014", pINFO) << "ns = "<<ns<<", nd = "<<nd<<", np = "<<np<<", nn = "<<nn;
1085  //LOG("HAIntranuke2014", pNOTICE) << "RemA = "<<fRemnA<<", RemZ = "<<fRemnZ<<", probe = "<<pdgc;
1086 
1087  /*if ((ns+nd)/2. < 0 || (ns-nd)/2. < 0) {iter++; continue;}
1088  else */
1089  //check for problems befor executing phase space 'decay'
1090  if (np < 0 || nn < 0 ) {iter++; continue;}
1091  else if (np + nn < 2. ) {iter++; continue;}
1092  else if ((np + nn == 2.) && pdg::IsNeutronOrProton (pdgc)) {iter++; continue;}
1093  else if (np > fRemnZ + ((pdg::IsProton(pdgc) || pdgc==kPdgPiP || pdgc==kPdgKP)?1:0)
1094  - ((pdgc==kPdgPiM || pdgc==kPdgKM)?1:0)) {iter++; continue;}
1095  else if (nn > fRemnA-fRemnZ + ((pdg::IsNeutron(pdgc)||pdgc==kPdgPiM||pdgc==kPdgKM)?1:0)
1096  - ((pdgc==kPdgPiP||pdgc==kPdgKP)?1:0)) {iter++; continue;}
1097  else {
1098  not_done=false; //success
1099  LOG("HAIntranuke2014",pINFO) << "success, iter = " << iter << " np, nn = " << np << " " << nn;
1100  if (np+nn>86) // too many particles, scale down
1101  {
1102  double frac = 85./double(np+nn);
1103  np = int(np*frac);
1104  nn = int(nn*frac);
1105  }
1106 
1107  if ( (np==fRemnZ +((pdg::IsProton (pdgc)||pdgc==kPdgPiP||pdgc==kPdgKP)?1:0)-(pdgc==kPdgPiM||pdgc==kPdgKM?1:0))
1108  &&(nn==fRemnA-fRemnZ+((pdg::IsNeutron(pdgc)||pdgc==kPdgPiM||pdgc==kPdgKM)?1:0)-(pdgc==kPdgPiP||pdgc==kPdgKP?1:0)) )
1109  { // leave at least one nucleon in the nucleus to prevent excess momentum
1110  if (rnd->RndFsi().Rndm()<np/(double)(np+nn)) np--;
1111  else nn--;
1112  }
1113 
1114  LOG("HAIntranuke2014", pNOTICE) << "Final state chosen; # protons : "
1115  << np << ", # neutrons : " << nn;
1116  }
1117  } //while(not_done)
1118 
1119  // change remnants to reflect probe
1120  if ( pdgc==kPdgProton || pdgc==kPdgPiP || pdgc==kPdgKP) fRemnZ++;
1121  if ( pdgc==kPdgPiM || pdgc==kPdgKM) fRemnZ--;
1122  if ( pdg::IsNeutronOrProton (pdgc) ) fRemnA++;
1123 
1124  // PhaseSpaceDecay forbids anything over 18 particles
1125  //
1126  // If over 18 particles, split into 5 groups and perform decay on each group
1127  // Anything over 85 particles reduced to 85 in previous step
1128  //
1129  // 4 of the nucleons are used as "probes" as well as original probe,
1130  // with each one sharing 1/5 of the total incident momentum
1131  //
1132  // Note: choosing 5 groups and distributing momentum evenly was arbitrary
1133  // Needs to be revised later
1134 
1135  if ((np+nn)>18)
1136  {
1137  // code lists
1138  PDGCodeList list0(allow_dup);
1139  PDGCodeList list1(allow_dup);
1140  PDGCodeList list2(allow_dup);
1141  PDGCodeList list3(allow_dup);
1142  PDGCodeList list4(allow_dup);
1143  PDGCodeList* listar[5] = {&list0, &list1, &list2, &list3, &list4};
1144 
1145  //set up HadronClusters
1146  // simple for now, each (of 5) hadron cluster has 1/5 of mom and KE
1147 
1148  double probM = pLib->Find(pdgc) ->Mass();
1149  TVector3 pP3 = p->P4()->Vect() * (1./5.);
1150  double probKE = p->P4()->E() -probM;
1151  double clusKE = probKE * (1./5.);
1152  TLorentzVector clusP4(pP3,clusKE); //no mass
1153 
1154  TLorentzVector X4(*p->X4());
1156 
1157  int mom = p->FirstMother();
1158 
1159  GHepParticle * p0 = new GHepParticle(kPdgCompNuclCluster,ist, mom,-1,-1,-1,clusP4,X4);
1160  GHepParticle * p1 = new GHepParticle(kPdgCompNuclCluster,ist, mom,-1,-1,-1,clusP4,X4);
1161  GHepParticle * p2 = new GHepParticle(kPdgCompNuclCluster,ist, mom,-1,-1,-1,clusP4,X4);
1162  GHepParticle * p3 = new GHepParticle(kPdgCompNuclCluster,ist, mom,-1,-1,-1,clusP4,X4);
1163  GHepParticle * p4 = new GHepParticle(kPdgCompNuclCluster,ist, mom,-1,-1,-1,clusP4,X4);
1164 
1165  // To conserve 4-momenta
1166  // fRemnP4 -= probP4 + protP4*np_p + neutP4*(4-np_p) - *p->P4();
1167  fRemnP4 -= 5.*clusP4 - *p->P4();
1168 
1169  for (int i=0;i<(np+nn);i++)
1170  {
1171  if (i<np)
1172  {
1173  listar[i%5]->push_back(kPdgProton);
1174  fRemnZ--;
1175  }
1176  else listar[i%5]->push_back(kPdgNeutron);
1177  fRemnA--;
1178  }
1179  for (int i=0;i<5;i++)
1180  {
1181  LOG("HAIntranuke2014", pINFO) << "List" << i << " size: " << listar[i]->size();
1182  if (listar[i]->size() <2)
1183  {
1185  exception.SetReason("too few particles for Phase Space decay - try again");
1186  throw exception;
1187  }
1188  }
1189 
1190  // commented out to better fit with absorption reactions
1191  // Add the fermi energy of the nucleons to the phase space
1192  /*if(fDoFermi)
1193  {
1194  GHepParticle* p_ar[5] = {cl, p1, p2, p3, p4};
1195  for (int i=0;i<5;i++)
1196  {
1197  Target target(ev->TargetNucleus()->Pdg());
1198  TVector3 pBuf = p_ar[i]->P4()->Vect();
1199  double mBuf = p_ar[i]->Mass();
1200  double eBuf = TMath::Sqrt(pBuf.Mag2() + mBuf*mBuf);
1201  TLorentzVector tSum(pBuf,eBuf);
1202  double mSum = 0.0;
1203  vector<int>::const_iterator pdg_iter;
1204  for(pdg_iter=++(listar[i]->begin());pdg_iter!=listar[i]->end();++pdg_iter)
1205  {
1206  target.SetHitNucPdg(*pdg_iter);
1207  fNuclmodel->GenerateNucleon(target);
1208  mBuf = pLib->Find(*pdg_iter)->Mass();
1209  mSum += mBuf;
1210  pBuf = fFermiFac * fNuclmodel->Momentum3();
1211  eBuf = TMath::Sqrt(pBuf.Mag2() + mBuf*mBuf);
1212  tSum += TLorentzVector(pBuf,eBuf);
1213  fRemnP4 -= TLorentzVector(pBuf,eBuf-mBuf);
1214  }
1215  TLorentzVector dP4 = tSum + TLorentzVector(TVector3(0,0,0),-mSum);
1216  p_ar[i]->SetMomentum(dP4);
1217  }
1218  }*/
1219 
1220  bool success1 = utils::intranuke2014::PhaseSpaceDecay(ev,p0,*listar[0],fRemnP4,fNucRmvE,kIMdHA);
1221  bool success2 = utils::intranuke2014::PhaseSpaceDecay(ev,p1,*listar[1],fRemnP4,fNucRmvE,kIMdHA);
1222  bool success3 = utils::intranuke2014::PhaseSpaceDecay(ev,p2,*listar[2],fRemnP4,fNucRmvE,kIMdHA);
1223  bool success4 = utils::intranuke2014::PhaseSpaceDecay(ev,p3,*listar[3],fRemnP4,fNucRmvE,kIMdHA);
1224  bool success5 = utils::intranuke2014::PhaseSpaceDecay(ev,p4,*listar[4],fRemnP4,fNucRmvE,kIMdHA);
1225  if(success1 && success2 && success3 && success4 && success5)
1226  {
1227  LOG("HAIntranuke2014", pINFO)<<"Successful many-body absorption - n>=18";
1228  }
1229  else
1230  {
1231  // try to recover
1232  LOG("HAIntranuke2014", pWARN) << "PhaseSpace decay fails for HadrCluster- recovery likely incorrect - rethrow event";
1234  ev->AddParticle(*p);
1235  fRemnA+=np+nn;
1236  fRemnZ+=np;
1237  if ( pdgc==kPdgProton || pdgc==kPdgPiP ) fRemnZ--;
1238  if ( pdgc==kPdgPiM ) fRemnZ++;
1239  if ( pdg::IsNeutronOrProton (pdgc) ) fRemnA--;
1240  /* exceptions::INukeException exception;
1241  exception.SetReason("Phase space generation of absorption final state failed");
1242  throw exception;
1243  */
1244  }
1245 
1246  // delete cl;
1247  delete p0;
1248  delete p1;
1249  delete p2;
1250  delete p3;
1251  delete p4;
1252 
1253  }
1254  else // less than 18 particles pion
1255  {
1256  if (pdgc==kPdgKP) list.push_back(kPdgKP); //normally conserve strangeness
1257  if (pdgc==kPdgKM) list.push_back(kPdgKM);
1258  for (int i=0;i<np;i++)
1259  {
1260  list.push_back(kPdgProton);
1261  fRemnA--;
1262  fRemnZ--;
1263  }
1264  for (int i=0;i<nn;i++)
1265  {
1266  list.push_back(kPdgNeutron);
1267  fRemnA--;
1268  }
1269 
1270  // Library instance for reference
1271  //PDGLibrary * pLib = PDGLibrary::Instance();
1272 
1273  // commented out to better fit with absorption reactions
1274  // Add the fermi energy of the nucleons to the phase space
1275  /*if(fDoFermi)
1276  {
1277  Target target(ev->TargetNucleus()->Pdg());
1278  TVector3 pBuf = p->P4()->Vect();
1279  double mBuf = p->Mass();
1280  double eBuf = TMath::Sqrt(pBuf.Mag2() + mBuf*mBuf);
1281  TLorentzVector tSum(pBuf,eBuf);
1282  double mSum = 0.0;
1283  vector<int>::const_iterator pdg_iter;
1284  for(pdg_iter=++(list.begin());pdg_iter!=list.end();++pdg_iter)
1285  {
1286  target.SetHitNucPdg(*pdg_iter);
1287  fNuclmodel->GenerateNucleon(target);
1288  mBuf = pLib->Find(*pdg_iter)->Mass();
1289  mSum += mBuf;
1290  pBuf = fFermiFac * fNuclmodel->Momentum3();
1291  eBuf = TMath::Sqrt(pBuf.Mag2() + mBuf*mBuf);
1292  tSum += TLorentzVector(pBuf,eBuf);
1293  fRemnP4 -= TLorentzVector(pBuf,eBuf-mBuf);
1294  }
1295  TLorentzVector dP4 = tSum + TLorentzVector(TVector3(0,0,0),-mSum);
1296  p->SetMomentum(dP4);
1297  }*/
1298 
1299  LOG("HAIntranuke2014", pDEBUG)
1300  << "Remnant nucleus (A,Z) = (" << fRemnA << ", " << fRemnZ << ")";
1301  LOG("HAIntranuke2014", pINFO) << " list size: " << np+nn;
1302  if (np+nn <2)
1303  {
1305  exception.SetReason("too few particles for Phase Space decay - try again");
1306  throw exception;
1307  }
1308  // GHepParticle * cl = new GHepParticle(*p);
1309  // cl->SetPdgCode(kPdgDecayNuclCluster);
1311  if (success)
1312  {
1313  LOG ("HAIntranuke2014",pINFO) << "Successful many-body absorption, n<=18";
1314  }
1315  else {
1316  // recover
1318  ev->AddParticle(*p);
1319  fRemnA+=np+nn;
1320  fRemnZ+=np;
1321  if ( pdgc==kPdgProton || pdgc==kPdgPiP ) fRemnZ--;
1322  if ( pdgc==kPdgPiM ) fRemnZ++;
1323  if ( pdg::IsNeutronOrProton (pdgc) ) fRemnA--;
1325  exception.SetReason("Phase space generation of absorption final state failed");
1326  throw exception;
1327  }
1328  }
1329  } // end multi-nucleon FS
1330  }
1331  else // not absorption/pipro
1332  {
1333  LOG("HAIntranuke2014", pWARN)
1334  << "Inelastic() can not handle fate: " << INukeHadroFates::AsString(fate);
1335  return;
1336  }
1337 }
An exception thrown by SimulateHadronState for kinematics problems. TwoBodyCollision/Kinematics used ...
void SetFirstMother(int m)
Definition: GHepParticle.h:131
bool IsPion(int pdgc)
Definition: PDGUtils.cxx:296
TRandom3 & RndFsi(void) const
rnd number generator used by intranuclear cascade monte carlos
Definition: RandomGen.h:60
static RandomGen * Instance()
Access instance.
Definition: RandomGen.cxx:79
static const double ns
Definition: Units.h:102
enum genie::EGHepStatus GHepStatus_t
static const double MeV
Definition: Units.h:130
int fRemnZ
remnant nucleus Z
Definition: Intranuke2014.h:97
INukeHadroData2014 * fHadroData2014
a collection of h+N,h+A data & calculations
Definition: Intranuke2014.h:93
void SetMomentum(const TLorentzVector &p4)
bool IsKaon(int pdgc)
Definition: PDGUtils.cxx:301
double fFermiMomentum
whether or not particle collision is pauli blocked
A singleton holding random number generator classes. All random number generation in GENIE should tak...
Definition: RandomGen.h:30
A list of PDG codes.
Definition: PDGCodeList.h:33
bool TwoBodyKinematics(double M3, double M4, TLorentzVector tP1L, TLorentzVector tP2L, TLorentzVector &tP3L, TLorentzVector &tP4L, double C3CM, TLorentzVector &RemnP4, double bindE=0)
int LastMother(void) const
Definition: GHepParticle.h:68
int Pdg(void) const
Definition: GHepParticle.h:64
int FirstMother(void) const
Definition: GHepParticle.h:67
string Name(void) const
Name that corresponds to the PDG code.
int fRemnA
remnant nucleus A
Definition: Intranuke2014.h:96
bool IsNeutron(int pdgc)
Definition: PDGUtils.cxx:311
const int kPdgCompNuclCluster
Definition: PDGCodes.h:188
const NuclearModelI * fNuclmodel
nuclear model used to generate fermi momentum
Definition: Intranuke2014.h:95
bool IsProton(int pdgc)
Definition: PDGUtils.cxx:306
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:87
const int kPdgKM
Definition: PDGCodes.h:147
A Neutrino Interaction Target. Is a transparent encapsulation of quite different physical systems suc...
Definition: Target.h:41
const int kPdgKP
Definition: PDGCodes.h:146
const int kPdgPiP
Definition: PDGCodes.h:132
const int kPdgPi0
Definition: PDGCodes.h:134
virtual GHepParticle * TargetNucleus(void) const
Definition: GHepRecord.cxx:323
#define pINFO
Definition: Messenger.h:53
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)
enum genie::EINukeFateHN_t INukeFateHN_t
#define pWARN
Definition: Messenger.h:51
double fFermiFac
testing parameter to modify fermi momentum
double fNucRmvE
binding energy to subtract from cascade nucleons
double KinE(bool mass_from_pdg=false) const
Get kinetic energy.
static PDGLibrary * Instance(void)
Definition: PDGLibrary.cxx:45
bool PhaseSpaceDecay(GHepRecord *ev, GHepParticle *p, const PDGCodeList &pdgv, TLorentzVector &RemnP4, double NucRmvE, EINukeMode mode=kIMdHA)
general phase space decay method
void SetLastMother(int m)
Definition: GHepParticle.h:132
Singleton class to load & serve a TDatabasePDG.
Definition: PDGLibrary.h:27
TLorentzVector * X4(void) const
Definition: GHepParticle.h:80
void SetStatus(GHepStatus_t s)
Definition: GHepParticle.h:125
virtual TVector3 Momentum3(void) const
Definition: NuclearModelI.h:59
static string AsString(INukeFateHN_t fate)
bool IsNeutronOrProton(int pdgc)
Definition: PDGUtils.cxx:321
TParticlePDG * Find(int pdgc)
Definition: PDGLibrary.cxx:63
const int kPdgPiM
Definition: PDGCodes.h:133
virtual bool GenerateNucleon(const Target &) const =0
virtual void AddParticle(const GHepParticle &p)
Definition: GHepRecord.cxx:526
const int kPdgProton
Definition: PDGCodes.h:62
#define pNOTICE
Definition: Messenger.h:52
TLorentzVector * P4(void) const
Definition: GHepParticle.h:79
const int kPdgNeutron
Definition: PDGCodes.h:64
static const double kPi
Definition: Constants.h:38
STDHEP-like event record entry that can fit a particle or a nucleus.
Definition: GHepParticle.h:40
TLorentzVector fRemnP4
P4 of remnant system.
Definition: Intranuke2014.h:98
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void push_back(int pdg_code)
Definition: PDGCodeList.cxx:67
double IntBounce(const GHepParticle *p, int target, int s1, INukeFateHN_t fate)
#define pDEBUG
Definition: Messenger.h:54
void SetPdgCode(int c)
bool fDoFermi
whether or not to do fermi mom.
void HAIntranuke2014::InelasticHA ( GHepRecord ev,
GHepParticle p,
INukeFateHA_t  fate 
) const
private

Definition at line 512 of file HAIntranuke2014.cxx.

514 {
515  // charge exch and inelastic - scatters particle within nucleus, hA version
516  // each are treated as quasielastic, particle scatters off single nucleon
517 
518 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
519  LOG("HAIntranuke2014", pDEBUG)
520  << "InelasticHA() is invoked for a : " << p->Name()
521  << " whose fate is : " << INukeHadroFates::AsString(fate);
522 #endif
523  if(ev->Probe() ) {
524  LOG("HAIntranuke2014", pINFO) << " probe KE = " << ev->Probe()->KinE();
525  }
526  if(fate!=kIHAFtCEx && fate!=kIHAFtInelas)
527  {
528  LOG("HAIntranuke2014", pWARN)
529  << "InelasticHA() cannot handle fate: " << INukeHadroFates::AsString(fate);
530  return;
531  }
532 
533  // Random number generator
534  RandomGen * rnd = RandomGen::Instance();
535 
536  // vars for incoming particle, target, and scattered pdg codes
537  int pcode = p->Pdg();
538  int tcode, scode, s2code;
539  double ppcnt = (double) fRemnZ / (double) fRemnA; // % of protons
540 
541  // Select a hadron fate in HN mode
542  INukeFateHN_t h_fate;
543  if (fate == kIHAFtCEx) h_fate = kIHNFtCEx;
544  else h_fate = kIHNFtElas;
545 
546  // Select a target randomly, weighted to #
547  // -- Unless, of course, the fate is CEx,
548  // -- in which case the target may be deterministic
549  // Also assign scattered particle code
550  if(fate==kIHAFtCEx)
551  {
552  if(pcode==kPdgPiP) {tcode = kPdgNeutron; scode = kPdgPi0; s2code = kPdgProton;}
553  else if(pcode==kPdgPiM) {tcode = kPdgProton; scode = kPdgPi0; s2code = kPdgNeutron;}
554  else if(pcode==kPdgPi0)
555  {
556  // for pi0
557  tcode = (rnd->RndFsi().Rndm()<=ppcnt)?(kPdgProton) :(kPdgNeutron);
558  scode = (tcode == kPdgProton) ?(kPdgPiP) :(kPdgPiM);
559  s2code = (tcode == kPdgProton) ?(kPdgNeutron):(kPdgProton);
560  }
561  else if(pcode==kPdgProton) {tcode = kPdgNeutron; scode = kPdgNeutron; s2code = kPdgProton;}
562  else if(pcode==kPdgNeutron){tcode = kPdgProton; scode = kPdgProton; s2code = kPdgNeutron;}
563  else
564  { LOG("HAIntranuke2014", pWARN) << "InelasticHA() cannot handle fate: "
566  << " for particle " << p->Name();
567  return;
568  }
569  }
570  else
571  {
572  tcode = (rnd->RndFsi().Rndm()<=ppcnt)?(kPdgProton):(kPdgNeutron);
573  // if(pcode == kPdgKP || pcode == kPdgKM) tcode = kPdgProton;
574  scode = pcode;
575  s2code = tcode;
576  }
577 
578  // check remnants
579  if ( fRemnA < 1 ) //we've blown nucleus apart, no need to retry anything - exit
580  {
581  LOG("HAIntranuke2014",pNOTICE) << "InelasticHA() stops : not enough nucleons";
583  ev->AddParticle(*p);
584  return;
585  }
586  else if ( fRemnZ + (((pcode==kPdgProton)||(pcode==kPdgPiP))?1:0) - (pcode==kPdgPiM?1:0)
587  < ((( scode==kPdgProton)||( scode==kPdgPiP)) ?1:0) - (scode ==kPdgPiM ?1:0)
588  + (((s2code==kPdgProton)||(s2code==kPdgPiP)) ?1:0) - (s2code==kPdgPiM ?1:0) )
589  {
590  LOG("HAIntranuke2014",pWARN) << "InelasticHA() failed : too few protons in nucleus";
592  ev->AddParticle(*p);
593  return; // another extreme case, best strategy is to exit and go to next event
594  }
595 
596  GHepParticle t(*p);
597  t.SetPdgCode(tcode);
598 
599  // set up fermi target
600  Target target(ev->TargetNucleus()->Pdg());
601  double tM = t.Mass();
602 
603  // handle fermi momentum
604  if(fDoFermi)
605  {
606  target.SetHitNucPdg(tcode);
608  TVector3 tP3 = fFermiFac * fNuclmodel->Momentum3();
609  double tE = TMath::Sqrt(tP3.Mag2()+ tM*tM);
610  t.SetMomentum(TLorentzVector(tP3,tE));
611  }
612  else
613  {
614  t.SetMomentum(0,0,0,tM);
615  }
616 
617  GHepParticle * cl = new GHepParticle(*p); // clone particle, to run IntBounce at proper energy
618  // calculate energy and momentum using invariant mass
619  double pM = p->Mass();
620  double E_p = ((*p->P4() + *t.P4()).Mag2() - tM*tM - pM*pM)/(2.0*tM);
621  double P_p = TMath::Sqrt(E_p*E_p - pM*pM);
622  cl->SetMomentum(TLorentzVector(P_p,0,0,E_p));
623  // momentum doesn't have to be in right direction, only magnitude
624  double C3CM = fHadroData2014->IntBounce(cl,tcode,scode,h_fate);
625  delete cl;
626  if (C3CM<-1.) // hope this doesn't occur too often - unphysical but we just pass it on
627  {
628  LOG("HAIntranuke2014", pWARN) << "unphysical angle chosen in InelasicHA - put particle outside nucleus";
630  ev->AddParticle(*p);
631  return;
632  }
633  double KE1L = p->KinE();
634  double KE2L = t.KinE();
635  LOG("HAIntranuke2014",pINFO)
636  << " KE1L = " << KE1L << " " << KE1L << " KE2L = " << KE2L;
637  GHepParticle cl1(*p);
638  GHepParticle cl2(t);
639  bool success = utils::intranuke2014::TwoBodyCollision(ev,pcode,tcode,scode,s2code,C3CM,
640  &cl1,&cl2,fRemnA,fRemnZ,fRemnP4,kIMdHA);
641  if(success)
642  {
643  double P3L = TMath::Sqrt(cl1.Px()*cl1.Px() + cl1.Py()*cl1.Py() + cl1.Pz()*cl1.Pz());
644  double P4L = TMath::Sqrt(cl2.Px()*cl2.Px() + cl2.Py()*cl2.Py() + cl2.Pz()*cl2.Pz());
645  double E3L = cl1.KinE();
646  double E4L = cl2.KinE();
647  LOG ("HAIntranuke2014",pINFO) << "Successful quasielastic scattering or charge exchange";
648  LOG("HAIntranuke",pINFO)
649  << "C3CM = " << C3CM << "\n P3L, E3L = "
650  << P3L << " " << E3L << " P4L, E4L = "<< P4L << " " << E4L ;
651  if(ev->Probe() ) { LOG("HAIntranuke",pINFO)
652  << "P4L = " << P4L << " ;E4L= " << E4L << "\n probe KE = " << ev->Probe()->KinE() << "\n";
653  }
654  if (ev->Probe() && (E3L>ev->Probe()->E()||E4L>ev->Probe()->E())) //is this redundant?
655  {
657  exception.SetReason("TwoBodyCollison gives KE> probe KE in hA simulation");
658  throw exception;
659  }
660  ev->AddParticle(cl1);
661  ev->AddParticle(cl2);
662 
663  LOG("HAIntranuke2014", pDEBUG) << "Nucleus : (A,Z) = ("<<fRemnA<<','<<fRemnZ<<')';
664  } else
665  {
667  exception.SetReason("TwoBodyCollison failed in hA simulation");
668  throw exception;
669  }
670 
671 }
An exception thrown by SimulateHadronState for kinematics problems. TwoBodyCollision/Kinematics used ...
TRandom3 & RndFsi(void) const
rnd number generator used by intranuclear cascade monte carlos
Definition: RandomGen.h:60
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.
double E(void) const
Get energy.
Definition: GHepParticle.h:90
static RandomGen * Instance()
Access instance.
Definition: RandomGen.cxx:79
int fRemnZ
remnant nucleus Z
Definition: Intranuke2014.h:97
INukeHadroData2014 * fHadroData2014
a collection of h+N,h+A data & calculations
Definition: Intranuke2014.h:93
void SetMomentum(const TLorentzVector &p4)
double Mass(void) const
Mass that corresponds to the PDG code.
A singleton holding random number generator classes. All random number generation in GENIE should tak...
Definition: RandomGen.h:30
virtual GHepParticle * Probe(void) const
Definition: GHepRecord.cxx:314
int Pdg(void) const
Definition: GHepParticle.h:64
string Name(void) const
Name that corresponds to the PDG code.
int fRemnA
remnant nucleus A
Definition: Intranuke2014.h:96
const NuclearModelI * fNuclmodel
nuclear model used to generate fermi momentum
Definition: Intranuke2014.h:95
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:87
A Neutrino Interaction Target. Is a transparent encapsulation of quite different physical systems suc...
Definition: Target.h:41
const int kPdgPiP
Definition: PDGCodes.h:132
const int kPdgPi0
Definition: PDGCodes.h:134
virtual GHepParticle * TargetNucleus(void) const
Definition: GHepRecord.cxx:323
#define pINFO
Definition: Messenger.h:53
enum genie::EINukeFateHN_t INukeFateHN_t
#define pWARN
Definition: Messenger.h:51
double fFermiFac
testing parameter to modify fermi momentum
double KinE(bool mass_from_pdg=false) const
Get kinetic energy.
void SetStatus(GHepStatus_t s)
Definition: GHepParticle.h:125
virtual TVector3 Momentum3(void) const
Definition: NuclearModelI.h:59
static string AsString(INukeFateHN_t fate)
const int kPdgPiM
Definition: PDGCodes.h:133
virtual bool GenerateNucleon(const Target &) const =0
virtual void AddParticle(const GHepParticle &p)
Definition: GHepRecord.cxx:526
const int kPdgProton
Definition: PDGCodes.h:62
#define pNOTICE
Definition: Messenger.h:52
TLorentzVector * P4(void) const
Definition: GHepParticle.h:79
const int kPdgNeutron
Definition: PDGCodes.h:64
STDHEP-like event record entry that can fit a particle or a nucleus.
Definition: GHepParticle.h:40
TLorentzVector fRemnP4
P4 of remnant system.
Definition: Intranuke2014.h:98
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
double IntBounce(const GHepParticle *p, int target, int s1, INukeFateHN_t fate)
#define pDEBUG
Definition: Messenger.h:54
bool fDoFermi
whether or not to do fermi mom.
void HAIntranuke2014::LoadConfig ( void  )
privatevirtual

Implements genie::Intranuke2014.

Definition at line 1346 of file HAIntranuke2014.cxx.

1347 {
1348 
1350  const Registry * gc = confp->GlobalParameterList();
1351 
1352  // load hadronic cross sections
1354 
1355  // fermi momentum setup
1357  fNuclmodel = dynamic_cast<const NuclearModelI *>
1358  (fAlgf->GetAlgorithm("genie::FGMBodekRitchie","Default"));
1359 
1360  // other intranuke config params
1361  fR0 = fConfig->GetDoubleDef ("R0", gc->GetDouble("NUCL-R0")); // fm
1362  fNR = fConfig->GetDoubleDef ("NR", gc->GetDouble("NUCL-NR"));
1363  fNucRmvE = fConfig->GetDoubleDef ("NucRmvE", gc->GetDouble("INUKE-NucRemovalE")); // GeV
1364  fDelRPion = fConfig->GetDoubleDef ("DelRPion", gc->GetDouble("HAINUKE-DelRPion"));
1365  fDelRNucleon = fConfig->GetDoubleDef ("DelRNucleon", gc->GetDouble("HAINUKE-DelRNucleon"));
1366  fHadStep = fConfig->GetDoubleDef ("HadStep", gc->GetDouble("INUKE-HadStep")); // fm
1367  fEPreEq = fConfig->GetDoubleDef ("EPreEq", gc->GetDouble("INUKE-Energy_Pre_Eq"));
1368  fNucAbsFac = fConfig->GetDoubleDef ("NucAbsFac", gc->GetDouble("INUKE-NucAbsFac"));
1369  fNucCEXFac = fConfig->GetDoubleDef ("NucCEXFac", gc->GetDouble("INUKE-NucCEXFac"));
1370  fFermiFac = fConfig->GetDoubleDef ("FermiFac", gc->GetDouble("INUKE-FermiFac"));
1371  fFermiMomentum = fConfig->GetDoubleDef ("FermiMomentum",gc->GetDouble("INUKE-FermiMomentum"));
1372  fDoFermi = fConfig->GetBoolDef ("DoFermi", gc->GetBool("INUKE-DoFermi"));
1373  fFreeStep = fConfig->GetDoubleDef ("FreeStep", gc->GetDouble("INUKE-FreeStep"));
1374  fDoCompoundNucleus = fConfig->GetBoolDef ("DoCompoundNucleus", gc->GetBool("INUKE-DoCompoundNucleus"));
1375 
1376  // report
1377  LOG("HAIntranuke2014", pINFO) << "Settings for INTRANUKE mode: " << INukeMode::AsString(kIMdHA);
1378  LOG("HAIntranuke2014", pINFO) << "R0 = " << fR0 << " fermi";
1379  LOG("HAIntranuke2014", pINFO) << "NR = " << fNR;
1380  LOG("HAIntranuke2014", pINFO) << "DelRPion = " << fDelRPion;
1381  LOG("HAIntranuke2014", pINFO) << "DelRNucleon = " << fDelRNucleon;
1382  LOG("HAIntranuke2014", pINFO) << "HadStep = " << fHadStep << " fermi";
1383  LOG("HAIntranuke2014", pINFO) << "EPreEq = " << fHadStep << " fermi";
1384  LOG("HAIntranuke2014", pINFO) << "NucAbsFac = " << fNucAbsFac;
1385  LOG("HAIntranuke2014", pINFO) << "NucCEXFac = " << fNucCEXFac;
1386  LOG("HAIntranuke2014", pINFO) << "FermiFac = " << fFermiFac;
1387  LOG("HAIntranuke2014", pINFO) << "FreeStep = " << fFreeStep; // free step in fm
1388  LOG("HAIntranuke2014", pINFO) << "FermiMomtm = " << fFermiMomentum;
1389  LOG("HAIntranuke2014", pINFO) << "DoFermi? = " << ((fDoFermi)?(true):(false));
1390  LOG("HAIntranuke2014", pINFO) << "DoCmpndNuc? = " << ((fDoCompoundNucleus)?(true):(false));
1391 }
static string AsString(INukeMode_t mode)
Definition: INukeMode.h:41
RgDbl GetDoubleDef(RgKey key, RgDbl def_opt, bool set_def=true)
Definition: Registry.cxx:549
AlgFactory * fAlgf
algorithm factory instance
Definition: Intranuke2014.h:94
double fNR
param multiplying the nuclear radius, determining how far to track hadrons beyond the "nuclear bounda...
A singleton class holding all configuration registries built while parsing all loaded XML configurati...
Definition: AlgConfigPool.h:41
double fEPreEq
threshold for pre-equilibrium reaction
double fR0
effective nuclear size param
Pure abstract base class. Defines the NuclearModelI interface to be implemented by any physics model ...
Definition: NuclearModelI.h:42
INukeHadroData2014 * fHadroData2014
a collection of h+N,h+A data & calculations
Definition: Intranuke2014.h:93
RgDbl GetDouble(RgKey key) const
Definition: Registry.cxx:488
double fFermiMomentum
whether or not particle collision is pauli blocked
double fDelRPion
factor by which Pion Compton wavelength gets multiplied to become nuclear size enhancement ...
double fFreeStep
produced particle free stem, in fm
const NuclearModelI * fNuclmodel
nuclear model used to generate fermi momentum
Definition: Intranuke2014.h:95
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:87
const Algorithm * GetAlgorithm(const AlgId &algid)
Definition: AlgFactory.cxx:86
#define pINFO
Definition: Messenger.h:53
Registry * GlobalParameterList(void) const
double fFermiFac
testing parameter to modify fermi momentum
double fNucCEXFac
charge exchange xsec correction factor (hN Mode)
double fNucRmvE
binding energy to subtract from cascade nucleons
bool fDoCompoundNucleus
whether or not to do compound nucleus considerations
static AlgFactory * Instance()
Definition: AlgFactory.cxx:75
A registry. Provides the container for algorithm configuration parameters.
Definition: Registry.h:66
RgBool GetBool(RgKey key) const
Definition: Registry.cxx:474
Registry * fConfig
config. (either owned or pointing to config pool)
Definition: Algorithm.h:122
double fDelRNucleon
factor by which Nucleon Compton wavelength gets multiplied to become nuclear size enhancement ...
RgBool GetBoolDef(RgKey key, RgBool def_opt, bool set_def=true)
Definition: Registry.cxx:539
double fNucAbsFac
absorption xsec correction factor (hN Mode)
double fHadStep
step size for intranuclear hadron transport
static AlgConfigPool * Instance()
static INukeHadroData2014 * Instance(void)
bool fDoFermi
whether or not to do fermi mom.
double HAIntranuke2014::PiBounce ( void  ) const
private

Definition at line 333 of file HAIntranuke2014.cxx.

334 {
335 // [adapted from neugen3 intranuke_bounce.F]
336 // [is a fortran stub / difficult to understand - needs to be improved]
337 //
338 // Generates theta in radians for elastic pion-nucleus scattering/
339 // Lookup table is based on Fig 17 of Freedman, Miller and Henley, Nucl.Phys.
340 // A389, 457 (1982)
341 //
342  const int nprob = 25;
343  double dintor = 0.0174533;
344  double denom = 47979.453;
345  double rprob[nprob] = {
346  5000., 4200., 3000., 2600., 2100., 1800., 1200., 750., 500., 230., 120.,
347  35., 9., 3., 11., 18., 29., 27., 20., 14., 10., 6., 2., 0.14, 0.19 };
348 
349  double angles[nprob];
350  for(int i=0; i<nprob; i++) angles[i] = 2.5*i;
351 
352  RandomGen * rnd = RandomGen::Instance();
353  double r = rnd->RndFsi().Rndm();
354 
355  double xsum = 0.;
356  double theta = 0.;
357  double binl = 0.;
358  double binh = 0.;
359  int tj = 0;
360  for(int i=0; i<60; i++) {
361  theta = i+0.5;
362  for(int j=0; j < nprob-1; j++) {
363  binl = angles[j];
364  binh = angles[j+1];
365  tj=j;
366  if(binl<=theta && binh>=theta) break;
367  tj=0;
368  }//j
369  int itj = tj;
370  double tfract = (theta-binl)/2.5;
371  double delp = rprob[itj+1] - rprob[itj];
372  xsum += (rprob[itj] + tfract*delp)/denom;
373  if(xsum>r) break;
374  theta = 0.;
375  }//i
376 
377  theta *= dintor;
378 
379  LOG("HAIntranuke2014", pNOTICE)
380  << "Generated pi+A elastic scattering angle = " << theta << " radians";
381 
382  return theta;
383 }
TRandom3 & RndFsi(void) const
rnd number generator used by intranuclear cascade monte carlos
Definition: RandomGen.h:60
static RandomGen * Instance()
Access instance.
Definition: RandomGen.cxx:79
A singleton holding random number generator classes. All random number generation in GENIE should tak...
Definition: RandomGen.h:30
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:87
#define pNOTICE
Definition: Messenger.h:52
double HAIntranuke2014::PnBounce ( void  ) const
private

Definition at line 385 of file HAIntranuke2014.cxx.

386 {
387 // [adapted from neugen3 intranuke_pnbounce.F]
388 // [is a fortran stub / difficult to understand - needs to be improved]
389 //
390 // Generates theta in radians for elastic nucleon-nucleus scattering.
391 // Use 800 MeV p+O16 as template in same (highly simplified) spirit as pi+A
392 // from table in Adams et al., PRL 1979. Guess value at 0-2 deg based on Ni
393 // data.
394 //
395  const int nprob = 20;
396  double dintor = 0.0174533;
397  double denom = 11967.0;
398  double rprob[nprob] = {
399  2400., 2350., 2200., 2000., 1728., 1261., 713., 312., 106., 35.,
400  6., 5., 10., 12., 11., 9., 6., 1., 1., 1. };
401 
402  double angles[nprob];
403  for(int i=0; i<nprob; i++) angles[i] = 1.0*i;
404 
405  RandomGen * rnd = RandomGen::Instance();
406  double r = rnd->RndFsi().Rndm();
407 
408  double xsum = 0.;
409  double theta = 0.;
410  double binl = 0.;
411  double binh = 0.;
412  int tj = 0;
413  for(int i=0; i< nprob; i++) {
414  theta = i+0.5;
415  for(int j=0; j < nprob-1; j++) {
416  binl = angles[j];
417  binh = angles[j+1];
418  tj=j;
419  if(binl<=theta && binh>=theta) break;
420  tj=0;
421  }//j
422  int itj = tj;
423  double tfract = (theta-binl)/2.5;
424  double delp = rprob[itj+1] - rprob[itj];
425  xsum += (rprob[itj] + tfract*delp)/denom;
426  if(xsum>r) break;
427  theta = 0.;
428  }//i
429 
430  theta *= dintor;
431 
432  LOG("HAIntranuke2014", pNOTICE)
433  << "Generated N+A elastic scattering angle = " << theta << " radians";
434 
435  return theta;
436 }
TRandom3 & RndFsi(void) const
rnd number generator used by intranuclear cascade monte carlos
Definition: RandomGen.h:60
static RandomGen * Instance()
Access instance.
Definition: RandomGen.cxx:79
A singleton holding random number generator classes. All random number generation in GENIE should tak...
Definition: RandomGen.h:30
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:87
#define pNOTICE
Definition: Messenger.h:52
void HAIntranuke2014::ProcessEventRecord ( GHepRecord event_rec) const
virtual

Reimplemented from genie::Intranuke2014.

Definition at line 110 of file HAIntranuke2014.cxx.

111 {
112  LOG("HAIntranuke2014", pNOTICE)
113  << "************ Running hA2014 MODE INTRANUKE ************";
114  GHepParticle * nuclearTarget = evrec -> TargetNucleus();
115  nuclA = nuclearTarget -> A();
116 
118 
119  LOG("HAIntranuke2014", pINFO) << "Done with this event";
120 }
virtual void ProcessEventRecord(GHepRecord *event_rec) const
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:87
#define pINFO
Definition: Messenger.h:53
int nuclA
value of A for the target nucleus in hA mode
static const double A
Definition: Units.h:82
#define pNOTICE
Definition: Messenger.h:52
STDHEP-like event record entry that can fit a particle or a nucleus.
Definition: GHepParticle.h:40
void HAIntranuke2014::SimulateHadronicFinalState ( GHepRecord ev,
GHepParticle p 
) const
privatevirtual

Implements genie::Intranuke2014.

Definition at line 122 of file HAIntranuke2014.cxx.

124 {
125 // Simulate a hadron interaction for the input particle p in HA mode
126 //
127  // check inputs
128  if(!p || !ev) {
129  LOG("HAIntranuke2014", pERROR) << "** Null input!";
130  return;
131  }
132 
133  // get particle code and check whether this particle can be handled
134  int pdgc = p->Pdg();
135  bool is_gamma = (pdgc==kPdgGamma);
136  bool is_pion = (pdgc==kPdgPiP || pdgc==kPdgPiM || pdgc==kPdgPi0);
137  bool is_kaon = (pdgc==kPdgKP || pdgc==kPdgKM);
138  bool is_baryon = (pdgc==kPdgProton || pdgc==kPdgNeutron);
139  bool is_handled = (is_baryon || is_pion || is_kaon || is_gamma);
140  if(!is_handled) {
141  LOG("HAIntranuke2014", pERROR) << "** Can not handle particle: " << p->Name();
142  return;
143  }
144 
145  // select a fate for the input particle
146  INukeFateHA_t fate = this->HadronFateHA(p);
147 
148  // store the fate
149  ev->Particle(p->FirstMother())->SetRescatterCode((int)fate);
150 
151  if(fate == kIHAFtUndefined) {
152  LOG("HAIntranuke2014", pERROR) << "** Couldn't select a fate";
154  ev->AddParticle(*p);
155  return;
156  }
157  LOG("HAIntranuke2014", pNOTICE)
158  << "Selected "<< p->Name() << " fate: "<< INukeHadroFates::AsString(fate);
159 
160  // try to generate kinematics - repeat till is done (should seldom need >2)
161  fNumIterations = 0;
163 }
enum genie::EINukeFateHA_t INukeFateHA_t
virtual GHepParticle * Particle(int position) const
Definition: GHepRecord.cxx:148
#define pERROR
Definition: Messenger.h:50
int Pdg(void) const
Definition: GHepParticle.h:64
int FirstMother(void) const
Definition: GHepParticle.h:67
string Name(void) const
Name that corresponds to the PDG code.
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:87
const int kPdgKM
Definition: PDGCodes.h:147
const int kPdgGamma
Definition: PDGCodes.h:163
const int kPdgKP
Definition: PDGCodes.h:146
const int kPdgPiP
Definition: PDGCodes.h:132
const int kPdgPi0
Definition: PDGCodes.h:134
INukeFateHA_t HadronFateHA(const GHepParticle *p) const
void SetStatus(GHepStatus_t s)
Definition: GHepParticle.h:125
static string AsString(INukeFateHN_t fate)
const int kPdgPiM
Definition: PDGCodes.h:133
virtual void AddParticle(const GHepParticle &p)
Definition: GHepRecord.cxx:526
const int kPdgProton
Definition: PDGCodes.h:62
#define pNOTICE
Definition: Messenger.h:52
const int kPdgNeutron
Definition: PDGCodes.h:64
void SimulateHadronicFinalStateKinematics(GHepRecord *ev, GHepParticle *p) const
unsigned int fNumIterations
void HAIntranuke2014::SimulateHadronicFinalStateKinematics ( GHepRecord ev,
GHepParticle p 
) const
private

Definition at line 165 of file HAIntranuke2014.cxx.

167 {
168  // get stored fate
169  INukeFateHA_t fate = (INukeFateHA_t)
170  ev->Particle(p->FirstMother())->RescatterCode();
171 
172  LOG("HAIntranuke2014", pINFO)
173  << "Generating kinematics for " << p->Name()
174  << " fate: "<< INukeHadroFates::AsString(fate);
175 
176  // try to generate kinematics for the selected fate
177 
178  try
179  {
180  fNumIterations++;
181  if (fate == kIHAFtElas)
182  {
183  this->ElasHA(ev,p,fate);
184  }
185  else
186  if (fate == kIHAFtInelas || fate == kIHAFtCEx)
187  {
188  this->InelasticHA(ev,p,fate);
189  }
190  else if (fate == kIHAFtAbs || fate == kIHAFtPiProd)
191  {
192  this->Inelastic(ev,p,fate);
193  }
194  }
196  {
197  LOG("HAIntranuke2014", pNOTICE)
198  << exception;
199  if(fNumIterations <= 100) {
200  LOG("HAIntranuke2014", pNOTICE)
201  << "Failed attempt to generate kinematics for "
202  << p->Name() << " fate: " << INukeHadroFates::AsString(fate)
203  << " - After " << fNumIterations << " tries, still retrying...";
205  } else {
206  LOG("HAIntranuke2014", pNOTICE)
207  << "Failed attempt to generate kinematics for "
208  << p->Name() << " fate: " << INukeHadroFates::AsString(fate)
209  << " after " << fNumIterations-1
210  << " attempts. Trying a new fate...";
211  this->SimulateHadronicFinalState(ev,p);
212  }
213  }
214 }
enum genie::EINukeFateHA_t INukeFateHA_t
An exception thrown by SimulateHadronState for kinematics problems. TwoBodyCollision/Kinematics used ...
virtual GHepParticle * Particle(int position) const
Definition: GHepRecord.cxx:148
void SimulateHadronicFinalState(GHepRecord *ev, GHepParticle *p) const
int FirstMother(void) const
Definition: GHepParticle.h:67
string Name(void) const
Name that corresponds to the PDG code.
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:87
void InelasticHA(GHepRecord *ev, GHepParticle *p, INukeFateHA_t fate) const
#define pINFO
Definition: Messenger.h:53
void ElasHA(GHepRecord *ev, GHepParticle *p, INukeFateHA_t fate) const
static string AsString(INukeFateHN_t fate)
#define pNOTICE
Definition: Messenger.h:52
void Inelastic(GHepRecord *ev, GHepParticle *p, INukeFateHA_t fate) const
void SimulateHadronicFinalStateKinematics(GHepRecord *ev, GHepParticle *p) const
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
unsigned int fNumIterations

Friends And Related Function Documentation

friend class IntranukeTester
friend

Definition at line 53 of file HAIntranuke2014.h.

Member Data Documentation

unsigned int genie::HAIntranuke2014::fNumIterations
mutableprivate

Definition at line 78 of file HAIntranuke2014.h.

int genie::HAIntranuke2014::nuclA
mutableprivate

value of A for the target nucleus in hA mode

Definition at line 77 of file HAIntranuke2014.h.


The documentation for this class was generated from the following files: