GENIEGenerator
Loading...
Searching...
No Matches
Intranuke2025.cxx
Go to the documentation of this file.
1//____________________________________________________________________________
2/*
3 Copyright (c) 2003-2025, The GENIE Collaboration
4 For the full text of the license visit http://copyright.genie-mc.org
5
6
7 Author: Steve Dytman <dytman+@pitt.edu>, Pittsburgh Univ.
8 Aaron Meyer <asm58@pitt.edu>, Pittsburgh Univ.
9 Alex Bell, Pittsburgh Univ.
10 Hugh Gallagher <gallag@minos.phy.tufts.edu>, Tufts Univ.
11 Costas Andreopoulos <c.andreopoulos \at cern.ch>, Rutherford Lab.
12 September 20, 2005
13
14 For the class documentation see the corresponding header file.
15
16 Important revisions after version 2.0.0 :
17 @ Oct, 2025 - SD, MI establish hA2025 and hN2025, start with identical code of 2018 versions.
18
19*/
20//____________________________________________________________________________
21
22#include <cstdlib>
23#include <sstream>
24
25#include <TMath.h>
26
29#include "Framework/Conventions/GBuild.h"
50
51using std::ostringstream;
52
53using namespace genie;
54using namespace genie::utils;
55using namespace genie::constants;
56using namespace genie::controls;
57
58//___________________________________________________________________________
64//___________________________________________________________________________
67{
68
69}
70//___________________________________________________________________________
73{
74
75}
76//___________________________________________________________________________
81//___________________________________________________________________________
83{
84 // Do not continue if there is no nuclear target
85 GHepParticle * nucltgt = evrec->TargetNucleus();
86 if (!nucltgt) {
87 LOG("Intranuke2025", pINFO) << "No nuclear target found - INTRANUKE exits";
88 return;
89 }
90
91 // Decide tracking radius for the current nucleus (few * R0 * A^1/3)
92 this->SetTrackingRadius(nucltgt);
93
94 // Understand what the event generation mode is (hadron/photon-nucleus,
95 // lepton-nucleus, nucleon decay) from the input event.
96 // The determined mode has an effect on INTRANUKE behaviour (how to lookup
97 // the residual nucleus, whether to set an intranuclear vtx etc) but it
98 // does not affect the INTRANUKE physics.
99 fGMode = evrec->EventGenerationMode();
100
101 // For lepton-nucleus scattering and for nucleon decay intranuclear vtx
102 // position (in the target nucleus coord system) is set elsewhere.
103 // This method only takes effect in hadron/photon-nucleus interactions.
104 // In this special mode, an interaction vertex is set at the periphery
105 // of the target nucleus.
106// This is the only exception to the general case of setting vertex according to nuclear density presently anticipated.
109 {
110 this->GenerateVertex(evrec);
111 }
112
113 // Now transport all hadrons outside the tracking radius.
114 // Stepping part is common for both HA and HN.
115 // Once it has been estabished that an interaction takes place then
116 // HA and HN specific code takes over in order to simulate the final state.
117 this->TransportHadrons(evrec);
118}
119//___________________________________________________________________________
121{
122// Sets a vertex in the nucleus periphery
123// Called onlt in hadron/photon-nucleus interactions.
124
125 GHepParticle * nucltgt = evrec->TargetNucleus();
126 assert(nucltgt);
127
129 TVector3 vtx(999999.,999999.,999999.);
130
131 // *** For h+A events (test mode):
132 // Assume a hadron beam with uniform intensity across an area,
133 // so we need to choose events uniformly within that area.
134 double x=999999., y=999999., epsilon = 0.001;
135 double R2 = TMath::Power(fTrackingRadius,2.);
136 double rp2 = TMath::Power(x,2.) + TMath::Power(y,2.);
137 while(rp2 > R2-epsilon) {
138 x = (fTrackingRadius-epsilon) * rnd->RndFsi().Rndm();
139 y = -fTrackingRadius + 2*fTrackingRadius * rnd->RndFsi().Rndm();
140 y -= ((y>0) ? epsilon : -epsilon);
141 rp2 = TMath::Power(x,2.) + TMath::Power(y,2.);
142 }
143 vtx.SetXYZ(x,y, -1.*TMath::Sqrt(TMath::Max(0.,R2-rp2)) + epsilon);
144
145 // get the actual unit vector along the incoming hadron direction
146 TVector3 direction = evrec->Probe()->P4()->Vect().Unit();
147
148 // rotate the vtx position
149 vtx.RotateUz(direction);
150
151 LOG("Intranuke2025", pNOTICE)
152 << "Generated vtx @ R = " << vtx.Mag() << " fm / "
153 << print::Vec3AsString(&vtx);
154
155 TObjArrayIter piter(evrec);
156 GHepParticle * p = 0;
157 while( (p = (GHepParticle *) piter.Next()) )
158 {
159 if(pdg::IsPseudoParticle(p->Pdg())) continue;
160 if(pdg::IsIon (p->Pdg())) continue;
161
162 p->SetPosition(vtx.x(), vtx.y(), vtx.z(), 0.);
163 }
164}
165//___________________________________________________________________________
167{
168 assert(p && pdg::IsIon(p->Pdg()));
169 double A = p->A();
170 fTrackingRadius = fR0 * TMath::Power(A, 1./3.);
171
172 // multiply that by some input factor so that hadrons are tracked
173 // beyond the nuclear 'boundary' since the nuclear density distribution
174 // is not zero there
176
177 LOG("Intranuke2025", pNOTICE)
178 << "Setting tracking radius to R = " << fTrackingRadius;
179}
180//___________________________________________________________________________
182{
183// checks whether the particle should be rescattered
184
185 assert(p);
186
189 // hadron/photon-nucleus scattering propagate the incoming particle
190 return (
192 && !pdg::IsIon(p->Pdg()));
193 }
194 else {
195 // attempt to rescatter anything marked as 'hadron in the nucleus'
196 return (p->Status() == kIStHadronInTheNucleus);
197 }
198}
199//___________________________________________________________________________
201{
202// checks whether a particle that needs to be rescattered, can in fact be
203// rescattered by this cascade MC
204
205 assert(p);
206 return ( p->Pdg() == kPdgPiP ||
207 p->Pdg() == kPdgPiM ||
208 p->Pdg() == kPdgPi0 ||
209 p->Pdg() == kPdgProton ||
210 p->Pdg() == kPdgNeutron ||
211 // p->Pdg() == kPdgGamma ||
212 p->Pdg() == kPdgKP //||
213 // p->Pdg() == kPdgKM
214 );
215}
216//___________________________________________________________________________
218{
219// check whether the input particle is still within the nucleus
220//
221 return (p->X4()->Vect().Mag() < fTrackingRadius + fHadStep);
222}
223//___________________________________________________________________________
225{
226// transport all hadrons outside the nucleus
227
228 int inucl = -1;
229 fRemnA = -1;
230 fRemnZ = -1;
231
232 // Get 'nuclear environment' at the beginning of hadron transport
233 // and keep track of the remnant nucleus A,Z
234
237 {
238 inucl = evrec->TargetNucleusPosition();
239 }
240 else if(fGMode == kGMdLeptonNucleus ||
243 inucl = evrec->RemnantNucleusPosition();
244 }
245
246 LOG("Intranuke2025", pNOTICE)
247 << "Propagating hadrons within nucleus found in position = " << inucl;
248 GHepParticle * nucl = evrec->Particle(inucl);
249 if(!nucl) {
250 LOG("Intranuke2025", pERROR)
251 << "No nucleus found in position = " << inucl;
252 LOG("Intranuke2025", pERROR)
253 << *evrec;
254 return;
255 }
256
257 fRemnA = nucl->A();
258 fRemnZ = nucl->Z();
259
260 LOG("Intranuke2025", pNOTICE)
261 << "Nucleus (A,Z) = (" << fRemnA << ", " << fRemnZ << ")";
262
263 const TLorentzVector & p4nucl = *(nucl->P4());
264 fRemnP4 = p4nucl;
265
266 // Loop over GHEP and run intranuclear rescattering on handled particles
267 TObjArrayIter piter(evrec);
268 GHepParticle * p = 0;
269 int icurr = -1;
270
271 while( (p = (GHepParticle *) piter.Next()) )
272 {
273 icurr++;
274
275 // Check whether the particle needs rescattering, otherwise skip it
276 if( ! this->NeedsRescattering(p) ) continue;
277
278 LOG("Intranuke2025", pNOTICE)
279 << " >> Stepping a " << p->Name()
280 << " with kinetic E = " << p->KinE() << " GeV";
281
282 // Rescatter a clone, not the original particle
283 GHepParticle * sp = new GHepParticle(*p);
284
285 // Set clone's mom to be the hadron that was cloned
286 sp->SetFirstMother(icurr);
287
288 // Check whether the particle can be rescattered
289 if(!this->CanRescatter(sp)) {
290
291 // if I can't rescatter it, I will just take it out of the nucleus
292 LOG("Intranuke2025", pNOTICE)
293 << "... Current version can't rescatter a " << sp->Name();
294 sp->SetFirstMother(icurr);
296 evrec->AddParticle(*sp);
297 delete sp;
298 continue; // <-- skip to next GHEP entry
299 }
300
301 // Start stepping particle out of the nucleus
302 bool has_interacted = false;
303 while ( this-> IsInNucleus(sp) )
304 {
305 // advance the hadron by a step
307
308 // check whether it interacts
309 double d = this->GenerateStep(evrec,sp);
310 has_interacted = (d<fHadStep);
311 if(has_interacted) break;
312 }//stepping
313
314 if(has_interacted && fRemnA>0) {
315 // the particle interacts - simulate the hadronic interaction
316 LOG("Intranuke2025", pNOTICE)
317 << "Particle has interacted at location: "
318 << sp->X4()->Vect().Mag() << " / nucl rad= " << fTrackingRadius;
319 this->SimulateHadronicFinalState(evrec,sp);
320 } else if(has_interacted && fRemnA<=0) {
321 // nothing left to interact with!
322 LOG("Intranuke2025", pNOTICE)
323 << "*** Nothing left to interact with, escaping.";
325 evrec->AddParticle(*sp);
326 evrec->Particle(sp->FirstMother())->SetRescatterCode(1);
327 } else {
328 // the exits the nucleus without interacting - Done with it!
329 LOG("Intranuke2025", pNOTICE)
330 << "*** Hadron escaped the nucleus! Done with it.";
332 evrec->AddParticle(*sp);
333 evrec->Particle(sp->FirstMother())->SetRescatterCode(1);
334 }
335 delete sp;
336
337 // Current snapshot
338 //LOG("Intranuke2025", pINFO) << "Current event record snapshot: " << *evrec;
339
340 }// GHEP entries
341
342 // Add remnant nucleus - that 'hadronic blob' has all the remaining hadronic
343 // 4p not put explicitly into the simulated particles
344 TLorentzVector v4(0.,0.,0.,0.);
345 GHepParticle remnant_nucleus(
347 evrec->AddParticle(remnant_nucleus);
348 // Mark the initial remnant nucleus as an intermediate state
349 // Don't do that in the hadron/photon-nucleus scatterig mode since the initial
350 // remnant nucleus and the target nucleus coincide.
354 }
355}
356//___________________________________________________________________________
357double Intranuke2025::GenerateStep(GHepRecord* /*evrec*/, GHepParticle* p) const //Added ev to get tgt argument//
358{
359// Generate a step (in fermis) for particle p in the input event.
360// Computes the mean free path L and generate an 'interaction' distance d
361// from an exp(-d/L) distribution
362
363 int pdgc = p->Pdg();
364
365 double scale = 1.;
366 if (pdgc==kPdgPiP || pdgc==kPdgPiM) {
367 scale = fChPionMFPScale;
368 }
369 if (pdgc==kPdgPi0) {
370 scale = fNeutralPionMFPScale;
371 }
372 else if (pdgc==kPdgProton || pdgc==kPdgNeutron) {
373 scale = fNucleonMFPScale;
374 }
375
377
378 string fINukeMode = this->GetINukeMode();
379 string fINukeModeGen = this->GetGenINukeMode();
380
381 double L = utils::intranuke2025::MeanFreePath(p->Pdg(), *p->X4(), *p->P4(), fRemnA,
383
384 LOG("Intranuke2025", pDEBUG) << "mode= " << fINukeModeGen;
385 L *= scale;
386
387 double d = -1.*L * TMath::Log(rnd->RndFsi().Rndm());
388
389 /* LOG("Intranuke2025", pDEBUG)
390 << "mode= " << fINukeMode << "; Mean free path = " << L << " fm / "
391 << "Generated path length = " << d << " fm";
392 */
393 return d;
394}
395//___________________________________________________________________________
401//___________________________________________________________________________
402void Intranuke2025::Configure(string param_set)
403{
404 Algorithm::Configure(param_set);
405 this->LoadConfig();
406}
407//___________________________________________________________________________
#define pNOTICE
Definition Messenger.h:61
#define pINFO
Definition Messenger.h:62
#define pERROR
Definition Messenger.h:59
#define pDEBUG
Definition Messenger.h:63
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE,...
Definition Messenger.h:96
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils.
virtual void Configure(const Registry &config)
Definition Algorithm.cxx:62
STDHEP-like event record entry that can fit a particle or a nucleus.
string Name(void) const
Name that corresponds to the PDG code.
int FirstMother(void) const
void SetPosition(const TLorentzVector &v4)
void SetRescatterCode(int code)
int Pdg(void) const
void SetFirstMother(int m)
const TLorentzVector * P4(void) const
const TLorentzVector * X4(void) const
void SetStatus(GHepStatus_t s)
int Z(void) const
int A(void) const
double KinE(bool mass_from_pdg=false) const
Get kinetic energy.
GHepStatus_t Status(void) const
GENIE's GHEP MC event record.
Definition GHepRecord.h:45
virtual GHepParticle * Probe(void) const
virtual GHepParticle * TargetNucleus(void) const
GEvGenMode_t EventGenerationMode(void) const
virtual void AddParticle(const GHepParticle &p)
virtual int TargetNucleusPosition(void) const
virtual int RemnantNucleusPosition(void) const
virtual GHepParticle * Particle(int position) const
virtual void Configure(const Registry &config)
double fChPionMFPScale
tweaking factors for tuning
double fDelRPion
factor by which Pion Compton wavelength gets multiplied to become nuclear size enhancement
bool NeedsRescattering(const GHepParticle *p) const
virtual string GetINukeMode() const
double GenerateStep(GHepRecord *ev, GHepParticle *p) const
int fRemnA
remnant nucleus A
virtual string GetGenINukeMode() const
int fRemnZ
remnant nucleus Z
double fHadStep
step size for intranuclear hadron transport
double fNR
param multiplying the nuclear radius, determining how far to track hadrons beyond the "nuclear bounda...
GEvGenMode_t fGMode
event generation mode (lepton+A, hadron+A, ...)
virtual void SimulateHadronicFinalState(GHepRecord *ev, GHepParticle *p) const =0
bool fUseOset
Oset model for low energy pion in hN.
bool CanRescatter(const GHepParticle *p) const
bool fAltOset
NuWro's table-based implementation (not recommended)
double fTrackingRadius
tracking radius for the nucleus in the current event
TLorentzVector fRemnP4
P4 of remnant system.
void GenerateVertex(GHepRecord *ev) const
bool fXsecNNCorr
use nuclear medium correction for NN cross section
bool IsInNucleus(const GHepParticle *p) const
void TransportHadrons(GHepRecord *ev) const
double fDelRNucleon
factor by which Nucleon Compton wavelength gets multiplied to become nuclear size enhancement
virtual void ProcessEventRecord(GHepRecord *event_rec) const
void SetTrackingRadius(const GHepParticle *p) const
double fR0
effective nuclear size param
virtual void LoadConfig(void)=0
A singleton holding random number generator classes. All random number generation in GENIE should tak...
Definition RandomGen.h:29
static RandomGen * Instance()
Access instance.
Definition RandomGen.cxx:74
TRandom3 & RndFsi(void) const
rnd number generator used by intranuclear cascade monte carlos
Definition RandomGen.h:59
A registry. Provides the container for algorithm configuration parameters.
Definition Registry.h:65
const double epsilon
Basic constants.
Misc GENIE control constants.
bool IsIon(int pdgc)
Definition PDGUtils.cxx:42
bool IsPseudoParticle(int pdgc)
Definition PDGUtils.cxx:27
Simple functions for loading and reading nucleus dependent keys from config files.
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="XX2025")
Mean free path (pions, nucleons)
void StepParticle(GHepParticle *p, double step, double nuclear_radius=-1.)
Step particle.
string Vec3AsString(const TVector3 *vec)
Root of GENIE utility namespaces.
THE MAIN GENIE PROJECT NAMESPACE
Definition AlgCmp.h:25
const int kPdgPiM
Definition PDGCodes.h:159
@ kIStIntermediateState
Definition GHepStatus.h:31
@ kIStHadronInTheNucleus
Definition GHepStatus.h:37
@ kIStFinalStateNuclearRemnant
Definition GHepStatus.h:38
@ kIStStableFinalState
Definition GHepStatus.h:30
@ kIStInitialState
Definition GHepStatus.h:29
const int kPdgProton
Definition PDGCodes.h:81
const int kPdgPi0
Definition PDGCodes.h:160
const int kPdgKP
Definition PDGCodes.h:172
const int kPdgNeutron
Definition PDGCodes.h:83
@ kGMdNucleonDecay
Definition GMode.h:30
@ kGMdDarkMatterNucleus
Definition GMode.h:29
@ kGMdLeptonNucleus
Definition GMode.h:26
@ kGMdHadronNucleus
Definition GMode.h:27
@ kGMdPhotonNucleus
Definition GMode.h:28
const int kPdgHadronicBlob
Definition PDGCodes.h:211
const int kPdgPiP
Definition PDGCodes.h:158