GENIEGenerator
Loading...
Searching...
No Matches
genie::utils Namespace Reference

Root of GENIE utility namespaces. More...

Namespaces

namespace  app_init
 Initialization code commonly occuring in GENIE apps, factored out from existing apps for convenience. Not generic GENIE initialization code.
namespace  bwfunc
 Breit Wigner functions.
namespace  config
 Simple functions for loading and reading nucleus dependent keys from config files.
namespace  frgmfunc
 Fragmentation functions.
namespace  geometry
 Geometry utilities.
namespace  ghep
 GHEP event record utilities.
namespace  gsl
 Simple utilities for integrating GSL in the GENIE framework.
namespace  gui
 Simple utilities for GENIE Graphical User Interface widgets.
namespace  hadxs
 Simple functions and data for computing hadron interaction xsecs.
namespace  hnl
 Useful kinematic functions.
namespace  intranuke
namespace  intranuke2018
namespace  intranuke2025
namespace  kinematics
 Kinematical utilities.
namespace  math
 Simple mathematical utilities not found in ROOT's TMath.
namespace  mec
 MEC utilities.
namespace  nnbar_osc
namespace  nuclear
 Simple nuclear physics empirical formulas (densities, radii, ...) and empirical nuclear corrections.
namespace  nucleon_decay
namespace  phys
 Various physics formulas & utilities.
namespace  prem
 Preliminary Earth Model.
namespace  print
 Simple printing utilities.
namespace  res
 Baryon Resonance utilities.
namespace  str
 Utilities for string manipulation.
namespace  style
 GENIE style!
namespace  system
 System utilities.
namespace  units
 Simple unit system utilities.
namespace  xml

Classes

 Utility class to store MC job meta-data. More...

Functions

ostream & operator<< (ostream &stream, const T2KEvGenMetaData &md)
double EnergyDeltaFunctionSolutionDMEL (const Interaction &inter)
DMELEvGen_BindingMode_t StringToDMELBindingMode (const std::string &mode_str)
double ComputeFullDMELPXSec (Interaction *interaction, const NuclearModelI *nucl_model, const XSecAlgorithmI *xsec_model, double cos_theta_0, double phi_0, double &Eb, DMELEvGen_BindingMode_t hitNucleonBindingMode, double min_angle_EM=0., bool bind_nucleon=true)
double CosTheta0Max (const genie::Interaction &interaction)
void BindHitNucleon (Interaction &interaction, const NuclearModelI &nucl_model, double &Eb, DMELEvGen_BindingMode_t hitNucleonBindingMode)
void SetPrimaryLeptonPolarization (GHepRecord *ev)
double EnergyDeltaFunctionSolutionQEL (const Interaction &inter)
QELEvGen_BindingMode_t StringToQELBindingMode (const std::string &mode_str)
double ComputeFullQELPXSec (Interaction *interaction, const NuclearModelI *nucl_model, const XSecAlgorithmI *xsec_model, double cos_theta_0, double phi_0, double &Eb, QELEvGen_BindingMode_t hitNucleonBindingMode, double min_angle_EM=0., bool bind_nucleon=true)
void BindHitNucleon (Interaction &interaction, const NuclearModelI &nucl_model, double &Eb, QELEvGen_BindingMode_t hitNucleonBindingMode)

Detailed Description

Root of GENIE utility namespaces.

Common functions used for handling generation of the primary lepton, regardless of whether the relevant class inherits from PrimaryLeptonGenerator or not.

Author
Steven Gardiner <gardiner \at fnal.gov> Fermi National Accelerator Laboratory
Created:\n May 01, 2020
License:\n Copyright (c) 2003-2025, The GENIE Collaboration
For the full text of the license visit http://copyright.genie-mc.org

Function Documentation

◆ BindHitNucleon() [1/2]

void genie::utils::BindHitNucleon ( genie::Interaction & interaction,
const NuclearModelI & nucl_model,
double & Eb,
genie::DMELEvGen_BindingMode_t hitNucleonBindingMode )

Definition at line 259 of file DMELUtils.cxx.

262{
263 genie::Target* tgt = interaction.InitState().TgtPtr();
264 TLorentzVector* p4Ni = tgt->HitNucP4Ptr();
265
266 // Initial nucleon 3-momentum (lab frame)
267 TVector3 p3Ni = nucl_model.Momentum3();
268
269 // Look up the (on-shell) mass of the initial nucleon
270 TDatabasePDG* tb = TDatabasePDG::Instance();
271 double mNi = tb->GetParticle( tgt->HitNucPdg() )->Mass();
272
273 // Set the (possibly off-shell) initial nucleon energy based on
274 // the selected binding energy mode. Always put the initial nucleon
275 // on shell if it is not part of a composite nucleus
276 double ENi = 0.;
277 if ( tgt->IsNucleus() && hitNucleonBindingMode != genie::kOnShell ) {
278
279 // For a nuclear target with a bound initial struck nucleon, take binding
280 // energy effects and Pauli blocking into account when computing QE
281 // differential cross sections
282 interaction.ResetBit( kIAssumeFreeNucleon );
283
284 // Initial nucleus mass
285 double Mi = tgt->Mass();
286
287 // Final nucleus mass
288 double Mf = 0.;
289
290 // If we use the removal energy reported by the nuclear
291 // model, then it implies a certain value for the final
292 // nucleus mass
293 if ( hitNucleonBindingMode == genie::kUseNuclearModel ) {
294 Eb = nucl_model.RemovalEnergy();
295 // This equation is the definition that we assume
296 // here for the "removal energy" (Eb) returned by the
297 // nuclear model. It matches GENIE's convention for
298 // the Bodek/Ritchie Fermi gas model.
299 Mf = Mi + Eb - mNi;
300 }
301 // We can also assume that the final nucleus is in its
302 // ground state. In this case, we can just look up its
303 // mass from the standard table. This implies a particular
304 // binding energy for the hit nucleon.
305 else if ( hitNucleonBindingMode == genie::kUseGroundStateRemnant ) {
306 // Determine the mass and proton numbers for the remnant nucleus
307 int Af = tgt->A() - 1;
308 int Zf = tgt->Z();
309 if ( genie::pdg::IsProton( tgt->HitNucPdg()) ) --Zf;
311
312 // Deduce the binding energy from the final nucleus mass
313 Eb = Mf - Mi + mNi;
314 }
315
316 // The (lab-frame) off-shell initial nucleon energy is the difference
317 // between the lab frame total energies of the initial and remnant nuclei
318 ENi = Mi - std::sqrt( Mf*Mf + p3Ni.Mag2() );
319 }
320 else {
321 // Keep the struck nucleon on shell either because
322 // hitNucleonBindingMode == kOnShell or because
323 // the target is a single nucleon
324 ENi = std::sqrt( p3Ni.Mag2() + std::pow(mNi, 2) );
325 Eb = 0.;
326
327 // If we're dealing with a nuclear target but using the on-shell
328 // binding mode, set the "assume free nucleon" flag. This turns off
329 // Pauli blocking and the requirement that q0 > 0 in the QE cross section
330 // models (an on-shell nucleon *is* a free nucleon)
331 if ( tgt->IsNucleus() ) interaction.SetBit( kIAssumeFreeNucleon );
332 }
333
334 // Update the initial nucleon lab-frame 4-momentum in the interaction with
335 // its current components
336 p4Ni->SetVect( p3Ni );
337 p4Ni->SetE( ENi );
338
339}
Target * TgtPtr(void) const
const InitialState & InitState(void) const
Definition Interaction.h:69
const TVector3 & Momentum3(void) const
double RemovalEnergy(void) const
static PDGLibrary * Instance(void)
TParticlePDG * Find(int pdgc, bool must_exist=true)
A Neutrino Interaction Target. Is a transparent encapsulation of quite different physical systems suc...
Definition Target.h:40
int HitNucPdg(void) const
Definition Target.cxx:304
int Z(void) const
Definition Target.h:68
TLorentzVector * HitNucP4Ptr(void) const
Definition Target.cxx:247
int A(void) const
Definition Target.h:70
double Mass(void) const
Definition Target.cxx:224
bool IsNucleus(void) const
Definition Target.cxx:272
int IonPdgCode(int A, int Z)
Definition PDGUtils.cxx:71
bool IsProton(int pdgc)
Definition PDGUtils.cxx:336
@ kUseNuclearModel
Definition DMELUtils.h:20
@ kOnShell
Definition DMELUtils.h:27
@ kUseGroundStateRemnant
Definition DMELUtils.h:24
const UInt_t kIAssumeFreeNucleon
Definition Interaction.h:49

References genie::Target::A(), genie::PDGLibrary::Find(), genie::Target::HitNucP4Ptr(), genie::Target::HitNucPdg(), genie::Interaction::InitState(), genie::PDGLibrary::Instance(), genie::pdg::IonPdgCode(), genie::Target::IsNucleus(), genie::pdg::IsProton(), genie::kIAssumeFreeNucleon, genie::kOnShell, genie::kUseGroundStateRemnant, genie::kUseNuclearModel, genie::Target::Mass(), genie::NuclearModelI::Momentum3(), genie::NuclearModelI::RemovalEnergy(), genie::InitialState::TgtPtr(), and genie::Target::Z().

Referenced by ComputeFullDMELPXSec(), ComputeFullQELPXSec(), genie::DMELEventGenerator::ComputeMaxXSec(), genie::QELEventGenerator::ComputeMaxXSec(), genie::DMELEventGenerator::ProcessEventRecord(), and genie::QELEventGenerator::ProcessEventRecord().

◆ BindHitNucleon() [2/2]

void genie::utils::BindHitNucleon ( genie::Interaction & interaction,
const NuclearModelI & nucl_model,
double & Eb,
genie::QELEvGen_BindingMode_t hitNucleonBindingMode )

Definition at line 261 of file QELUtils.cxx.

264{
265 genie::Target* tgt = interaction.InitState().TgtPtr();
266 TLorentzVector* p4Ni = tgt->HitNucP4Ptr();
267
268 // Initial nucleon 3-momentum (lab frame)
269 TVector3 p3Ni = nucl_model.Momentum3();
270
271 // Look up the (on-shell) mass of the initial nucleon
272 TDatabasePDG* tb = TDatabasePDG::Instance();
273 double mNi = tb->GetParticle( tgt->HitNucPdg() )->Mass();
274
275 // Set the (possibly off-shell) initial nucleon energy based on
276 // the selected binding energy mode. Always put the initial nucleon
277 // on shell if it is not part of a composite nucleus
278 double ENi = 0.;
279 if ( tgt->IsNucleus() && hitNucleonBindingMode != genie::kOnShell ) {
280
281 // For a nuclear target with a bound initial struck nucleon, take binding
282 // energy effects and Pauli blocking into account when computing QE
283 // differential cross sections
284 interaction.ResetBit( kIAssumeFreeNucleon );
285
286 // Initial nucleus mass
287 double Mi = tgt->Mass();
288
289 // Final nucleus mass
290 double Mf = 0.;
291
292 // If we use the removal energy reported by the nuclear
293 // model, then it implies a certain value for the final
294 // nucleus mass
295 if ( hitNucleonBindingMode == genie::kUseNuclearModel ) {
296 Eb = nucl_model.RemovalEnergy();
297 // This equation is the definition that we assume
298 // here for the "removal energy" (Eb) returned by the
299 // nuclear model. It matches GENIE's convention for
300 // the Bodek/Ritchie Fermi gas model.
301 Mf = Mi + Eb - mNi;
302 }
303 // We can also assume that the final nucleus is in its
304 // ground state. In this case, we can just look up its
305 // mass from the standard table. This implies a particular
306 // binding energy for the hit nucleon.
307 else if ( hitNucleonBindingMode == genie::kUseGroundStateRemnant ) {
308 // Determine the mass and proton numbers for the remnant nucleus
309 int Af = tgt->A() - 1;
310 int Zf = tgt->Z();
311 if ( genie::pdg::IsProton( tgt->HitNucPdg()) ) --Zf;
313
314 // Deduce the binding energy from the final nucleus mass
315 Eb = Mf - Mi + mNi;
316 }
317 // A third option is to assign the binding energy and final nuclear
318 // mass in a way that is equivalent to the original Valencia model
319 // treatment
320 else if ( hitNucleonBindingMode == genie::kValenciaStyleQValue ) {
321 // Compute the Q-value needed for the ground-state-to-ground-state
322 // transition without nucleon removal (see Sec. III B of
323 // https://arxiv.org/abs/nucl-th/0408005). Note that this will be
324 // zero for NC and EM scattering since the proton and nucleon numbers
325 // are unchanged. Also get Q_LFG, the difference in Fermi energies
326 // between the final and initial struck nucleon species. This will
327 // likewise be zero for NC and EM interactions.
328 const genie::ProcessInfo& info = interaction.ProcInfo();
329 double Qvalue = 0.;
330 double Q_LFG = 0.;
331 if ( info.IsWeakCC() ) {
332 // Without nucleon removal, the final nucleon number remains the same
333 int Af = tgt->A();
334 // For CC interactions, the proton number will change by one. Choose
335 // the right change by checking whether we're working with a neutrino
336 // or an antineutrino.
337 int Zf = tgt->Z();
338 int probe_pdg = interaction.InitState().ProbePdg();
339 if ( genie::pdg::IsAntiNeutrino(probe_pdg) ) {
340 --Zf;
341 }
342 else if ( genie::pdg::IsNeutrino(probe_pdg) ) {
343 ++Zf;
344 }
345 else {
346 LOG( "QELEvent", pFATAL ) << "Unhandled probe PDG code " << probe_pdg
347 << " encountered for a CC interaction in"
348 << " genie::utils::BindHitNucleon()";
349 gAbortingInErr = true;
350 std::exit( 1 );
351 }
352
353 // We have what we need to get the Q-value. Get the final nuclear
354 // mass (without nucleon removal)
355 double mf_keep_nucleon = genie::PDGLibrary::Instance()
356 ->Find( genie::pdg::IonPdgCode(Af, Zf) )->Mass();
357
358 Qvalue = mf_keep_nucleon - Mi;
359
360 // Get the Fermi energies for the initial and final nucleons. Include
361 // the radial dependence if using the LFG.
362 double hit_nucleon_radius = tgt->HitNucPosition();
363
364 // Average of the proton and neutron masses. It may actually be better
365 // to use the exact on-shell masses here. However, the original paper
366 // uses the same value for protons and neutrons when computing the
367 // difference in Fermi energies. For consistency with the Valencia
368 // model publication, I'll do the same.
369 const double mN = genie::constants::kNucleonMass;
370
371 double kF_Ni = nucl_model.LocalFermiMomentum( *tgt,
372 tgt->HitNucPdg(), hit_nucleon_radius );
373 double EFermi_Ni = std::sqrt( std::max(0., mN*mN + kF_Ni*kF_Ni) );
374
375 double kF_Nf = nucl_model.LocalFermiMomentum( *tgt,
376 interaction.RecoilNucleonPdg(), hit_nucleon_radius );
377 // (On-shell) final nucleon mass
378 //double mNf = interaction.RecoilNucleon()->Mass();
379 double EFermi_Nf = std::sqrt( std::max(0., mN*mN + kF_Nf*kF_Nf) );
380
381 // The difference in Fermi energies is Q_LFG
382 Q_LFG = EFermi_Nf - EFermi_Ni;
383 }
384 // Fail here for interactions that aren't one of EM/NC/CC. This is
385 // intended to help avoid silently doing the wrong thing in the future.
386 else if ( !info.IsEM() && !info.IsWeakNC() ) {
387 LOG( "QELEvent", pFATAL ) << "Unhandled process type \"" << info
388 << "\" encountered in genie::utils::BindHitNucleon()";
389 gAbortingInErr = true;
390 std::exit( 1 );
391 }
392
393 // On-shell total energy of the initial struck nucleon
394 double ENi_OnShell = std::sqrt( std::max(0., mNi*mNi + p3Ni.Mag2()) );
395
396 // Total energy of the remnant nucleus (with the hit nucleon removed)
397 double Ef = Mi - ENi_OnShell + Qvalue - Q_LFG;
398
399 // Mass and kinetic energy of the remnant nucleus (with the hit nucleon
400 // removed)
401 Mf = std::sqrt( std::max(0., Ef*Ef - p3Ni.Mag2()) );
402
403 // Deduce the binding energy from the final nucleus mass
404 Eb = Mf - Mi + mNi;
405
406 LOG( "QELEvent", pDEBUG ) << "Qvalue = " << Qvalue
407 << ", Q_LFG = " << Q_LFG << " at radius = " << tgt->HitNucPosition();
408 }
409
410 // The (lab-frame) off-shell initial nucleon energy is the difference
411 // between the lab frame total energies of the initial and remnant nuclei
412 ENi = Mi - std::sqrt( Mf*Mf + p3Ni.Mag2() );
413 }
414 else {
415 // Keep the struck nucleon on shell either because
416 // hitNucleonBindingMode == kOnShell or because
417 // the target is a single nucleon
418 ENi = std::sqrt( p3Ni.Mag2() + std::pow(mNi, 2) );
419 Eb = 0.;
420
421 // If we're dealing with a nuclear target but using the on-shell
422 // binding mode, set the "assume free nucleon" flag. This turns off
423 // Pauli blocking and the requirement that q0 > 0 in the QE cross section
424 // models (an on-shell nucleon *is* a free nucleon)
425 if ( tgt->IsNucleus() ) interaction.SetBit( kIAssumeFreeNucleon );
426 }
427
428 LOG( "QELEvent", pDEBUG ) << "Eb = " << Eb << ", pNi = " << p3Ni.Mag()
429 << ", ENi = " << ENi;
430
431 // Update the initial nucleon lab-frame 4-momentum in the interaction with
432 // its current components
433 p4Ni->SetVect( p3Ni );
434 p4Ni->SetE( ENi );
435
436}
#define pFATAL
Definition Messenger.h:56
#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
int ProbePdg(void) const
int RecoilNucleonPdg(void) const
recoil nucleon pdg
const ProcessInfo & ProcInfo(void) const
Definition Interaction.h:70
virtual double LocalFermiMomentum(const Target &, int nucleon_pdg, double radius) const
A class encapsulating an enumeration of interaction types (EM, Weak-CC, Weak-NC) and scattering types...
Definition ProcessInfo.h:46
bool IsWeakNC(void) const
bool IsWeakCC(void) const
bool IsEM(void) const
double HitNucPosition(void) const
Definition Target.h:89
bool IsNeutrino(int pdgc)
Definition PDGUtils.cxx:110
bool IsAntiNeutrino(int pdgc)
Definition PDGUtils.cxx:118
double Qvalue(int targetpdg, int nupdg)
Definition MECUtils.cxx:164
@ kValenciaStyleQValue
Definition QELUtils.h:49
bool gAbortingInErr
Definition Messenger.cxx:34

References genie::Target::A(), genie::PDGLibrary::Find(), genie::gAbortingInErr, genie::Target::HitNucP4Ptr(), genie::Target::HitNucPdg(), genie::Target::HitNucPosition(), genie::Interaction::InitState(), genie::PDGLibrary::Instance(), genie::pdg::IonPdgCode(), genie::pdg::IsAntiNeutrino(), genie::ProcessInfo::IsEM(), genie::pdg::IsNeutrino(), genie::Target::IsNucleus(), genie::pdg::IsProton(), genie::ProcessInfo::IsWeakCC(), genie::ProcessInfo::IsWeakNC(), genie::kIAssumeFreeNucleon, genie::constants::kNucleonMass, genie::kOnShell, genie::kUseGroundStateRemnant, genie::kUseNuclearModel, genie::kValenciaStyleQValue, genie::NuclearModelI::LocalFermiMomentum(), LOG, genie::Target::Mass(), genie::NuclearModelI::Momentum3(), pDEBUG, pFATAL, genie::InitialState::ProbePdg(), genie::Interaction::ProcInfo(), genie::Interaction::RecoilNucleonPdg(), genie::NuclearModelI::RemovalEnergy(), genie::InitialState::TgtPtr(), and genie::Target::Z().

◆ ComputeFullDMELPXSec()

double genie::utils::ComputeFullDMELPXSec ( genie::Interaction * interaction,
const NuclearModelI * nucl_model,
const XSecAlgorithmI * xsec_model,
double cos_theta_0,
double phi_0,
double & Eb,
genie::DMELEvGen_BindingMode_t hitNucleonBindingMode,
double min_angle_EM = 0.,
bool bind_nucleon = true )

Definition at line 94 of file DMELUtils.cxx.

99{
100 // If requested, set the initial hit nucleon 4-momentum to be off-shell
101 // according to the binding mode specified in the function call
102 if ( bind_nucleon ) {
103 genie::utils::BindHitNucleon(*interaction, *nucl_model, Eb,
104 hitNucleonBindingMode);
105 }
106
107 // Mass of the outgoing lepton
108 double lepMass = interaction->FSPrimLepton()->Mass();
109
110 // Look up the (on-shell) mass of the final nucleon
111 TDatabasePDG *tb = TDatabasePDG::Instance();
112 double mNf = tb->GetParticle( interaction->RecoilNucleonPdg() )->Mass();
113
114 // Mandelstam s for the probe/hit nucleon system
115 double s = std::pow( interaction->InitState().CMEnergy(), 2 );
116
117 // Return a differential cross section of zero if we're below threshold (and
118 // therefore need to sample a new event)
119 if ( std::sqrt(s) < lepMass + mNf ) return 0.;
120
121 double outLeptonEnergy = ( s - mNf*mNf + lepMass*lepMass ) / (2 * std::sqrt(s));
122
123 if (outLeptonEnergy*outLeptonEnergy - lepMass*lepMass < 0.) return 0.;
124 double outMomentum = TMath::Sqrt(outLeptonEnergy*outLeptonEnergy - lepMass*lepMass);
125
126 // Compute the boost vector for moving from the COM frame to the
127 // lab frame, i.e., the velocity of the COM frame as measured
128 // in the lab frame.
129 TVector3 beta = COMframe2Lab( interaction->InitState() );
130
131 // FullDifferentialXSec depends on theta_0 and phi_0, the lepton COM
132 // frame angles with respect to the direction of the COM frame velocity
133 // as measured in the lab frame. To generate the correct dependence
134 // here, first set the lepton COM frame angles with respect to +z
135 // (via TVector3::SetTheta() and TVector3::SetPhi()).
136 TVector3 lepton3Mom(0., 0., outMomentum);
137 lepton3Mom.SetTheta( TMath::ACos(cos_theta_0) );
138 lepton3Mom.SetPhi( phi_0 );
139
140 // Then rotate the lepton 3-momentum so that the old +z direction now
141 // points along the COM frame velocity (beta)
142 TVector3 zvec(0., 0., 1.);
143 TVector3 rot = ( zvec.Cross(beta) ).Unit();
144 double angle = beta.Angle( zvec );
145
146 // Handle the edge case where beta is along -z, so the
147 // cross product above vanishes
148 if ( beta.Perp() == 0. && beta.Z() < 0. ) {
149 rot = TVector3(0., 1., 0.);
150 angle = genie::constants::kPi;
151 }
152
153 // Rotate if the rotation vector is not 0
154 if ( rot.Mag() >= genie::controls::kASmallNum ) {
155 lepton3Mom.Rotate(angle, rot);
156 }
157
158 // Construct the lepton 4-momentum in the COM frame
159 TLorentzVector lepton(lepton3Mom, outLeptonEnergy);
160
161 // The final state nucleon will have an equal and opposite 3-momentum
162 // in the COM frame and will be on the mass shell
163 TLorentzVector outNucleon(-1*lepton.Px(),-1*lepton.Py(),-1*lepton.Pz(),
164 TMath::Sqrt(outMomentum*outMomentum + mNf*mNf));
165
166 // Boost the 4-momenta for both particles into the lab frame
167 lepton.Boost(beta);
168 outNucleon.Boost(beta);
169
170 // Check if event is at a low angle - if so return 0 and stop wasting time
171 if (180 * lepton.Theta() / genie::constants::kPi < min_angle_EM && interaction->ProcInfo().IsEM()) {
172 return 0;
173 }
174
175 TLorentzVector * nuP4 = interaction->InitState().GetProbeP4( genie::kRfLab );
176 TLorentzVector qP4 = *nuP4 - lepton;
177 delete nuP4;
178 double Q2 = -1 * qP4.Mag2();
179
180 interaction->KinePtr()->SetFSLeptonP4( lepton );
181 interaction->KinePtr()->SetHadSystP4( outNucleon );
182 interaction->KinePtr()->SetQ2( Q2 );
183
184 // Check the Q2 range. If we're outside of it, don't bother
185 // with the rest of the calculation.
186 Range1D_t Q2lim = interaction->PhaseSpace().Q2Lim();
187 if (Q2 < Q2lim.min || Q2 > Q2lim.max) return 0.;
188
189 // Compute the QE cross section for the current kinematics
190 double xsec = xsec_model->XSec(interaction, genie::kPSDMELEvGen);
191
192 return xsec;
193}
TLorentzVector * GetProbeP4(RefFrame_t rf=kRfHitNucRest) const
double CMEnergy() const
centre-of-mass energy (sqrt s)
TParticlePDG * FSPrimLepton(void) const
final state primary lepton
const KPhaseSpace & PhaseSpace(void) const
Definition Interaction.h:73
Kinematics * KinePtr(void) const
Definition Interaction.h:76
Range1D_t Q2Lim(void) const
Q2 limits.
void SetHadSystP4(const TLorentzVector &p4)
void SetQ2(double Q2, bool selected=false)
void SetFSLeptonP4(const TLorentzVector &p4)
virtual double XSec(const Interaction *i, KinePhaseSpace_t k=kPSfE) const =0
Compute the cross section for the input interaction.
static const double kASmallNum
Definition Controls.h:40
double Q2(const Interaction *const i)
void BindHitNucleon(Interaction &interaction, const NuclearModelI &nucl_model, double &Eb, DMELEvGen_BindingMode_t hitNucleonBindingMode)
@ kRfLab
Definition RefFrame.h:26

References BindHitNucleon(), genie::InitialState::CMEnergy(), anonymous_namespace{DMELUtils.cxx}::COMframe2Lab(), genie::Interaction::FSPrimLepton(), genie::InitialState::GetProbeP4(), genie::Interaction::InitState(), genie::controls::kASmallNum, genie::Interaction::KinePtr(), genie::constants::kPi, genie::kPSDMELEvGen, genie::kRfLab, genie::Range1D_t::max, genie::Interaction::PhaseSpace(), genie::KPhaseSpace::Q2Lim(), genie::Interaction::RecoilNucleonPdg(), genie::Kinematics::SetFSLeptonP4(), genie::Kinematics::SetHadSystP4(), genie::Kinematics::SetQ2(), and genie::XSecAlgorithmI::XSec().

Referenced by genie::DMELEventGenerator::ComputeMaxXSec(), and genie::DMELEventGenerator::ProcessEventRecord().

◆ ComputeFullQELPXSec()

double genie::utils::ComputeFullQELPXSec ( genie::Interaction * interaction,
const NuclearModelI * nucl_model,
const XSecAlgorithmI * xsec_model,
double cos_theta_0,
double phi_0,
double & Eb,
genie::QELEvGen_BindingMode_t hitNucleonBindingMode,
double min_angle_EM = 0.,
bool bind_nucleon = true )

Definition at line 93 of file QELUtils.cxx.

98{
99 // If requested, set the initial hit nucleon 4-momentum to be off-shell
100 // according to the binding mode specified in the function call
101 if ( bind_nucleon ) {
102 genie::utils::BindHitNucleon(*interaction, *nucl_model, Eb,
103 hitNucleonBindingMode);
104 }
105
106 // Mass of the outgoing lepton
107 double lepMass = interaction->FSPrimLepton()->Mass();
108
109 // Look up the (on-shell) mass of the final nucleon
110 TDatabasePDG *tb = TDatabasePDG::Instance();
111 double mNf = tb->GetParticle( interaction->RecoilNucleonPdg() )->Mass();
112
113 // Mandelstam s for the probe/hit nucleon system
114 double s = std::pow( interaction->InitState().CMEnergy(), 2 );
115
116 // Return a differential cross section of zero if we're below threshold (and
117 // therefore need to sample a new event)
118 if ( std::sqrt(s) < lepMass + mNf ) return 0.;
119
120 double outLeptonEnergy = ( s - mNf*mNf + lepMass*lepMass ) / (2 * std::sqrt(s));
121
122 if (outLeptonEnergy*outLeptonEnergy - lepMass*lepMass < 0.) return 0.;
123 double outMomentum = TMath::Sqrt(outLeptonEnergy*outLeptonEnergy - lepMass*lepMass);
124
125 // Compute the boost vector for moving from the COM frame to the
126 // lab frame, i.e., the velocity of the COM frame as measured
127 // in the lab frame.
128 TVector3 beta = COMframe2Lab( interaction->InitState() );
129
130 // FullDifferentialXSec depends on theta_0 and phi_0, the lepton COM
131 // frame angles with respect to the direction of the COM frame velocity
132 // as measured in the lab frame. To generate the correct dependence
133 // here, first set the lepton COM frame angles with respect to +z
134 // (via TVector3::SetTheta() and TVector3::SetPhi()).
135 TVector3 lepton3Mom(0., 0., outMomentum);
136 lepton3Mom.SetTheta( TMath::ACos(cos_theta_0) );
137 lepton3Mom.SetPhi( phi_0 );
138
139 // Then rotate the lepton 3-momentum so that the old +z direction now
140 // points along the COM frame velocity (beta)
141 TVector3 zvec(0., 0., 1.);
142 TVector3 rot = ( zvec.Cross(beta) ).Unit();
143 double angle = beta.Angle( zvec );
144
145 // Handle the edge case where beta is along -z, so the
146 // cross product above vanishes
147 if ( beta.Perp() == 0. && beta.Z() < 0. ) {
148 rot = TVector3(0., 1., 0.);
149 angle = genie::constants::kPi;
150 }
151
152 // Rotate if the rotation vector is not 0
153 if ( rot.Mag() >= genie::controls::kASmallNum ) {
154 lepton3Mom.Rotate(angle, rot);
155 }
156
157 // Construct the lepton 4-momentum in the COM frame
158 TLorentzVector lepton(lepton3Mom, outLeptonEnergy);
159
160 // The final state nucleon will have an equal and opposite 3-momentum
161 // in the COM frame and will be on the mass shell
162 TLorentzVector outNucleon(-1*lepton.Px(),-1*lepton.Py(),-1*lepton.Pz(),
163 TMath::Sqrt(outMomentum*outMomentum + mNf*mNf));
164
165 // Boost the 4-momenta for both particles into the lab frame
166 lepton.Boost(beta);
167 outNucleon.Boost(beta);
168
169 // Check if event is at a low angle - if so return 0 and stop wasting time
170 if (180 * lepton.Theta() / genie::constants::kPi < min_angle_EM && interaction->ProcInfo().IsEM()) {
171 return 0;
172 }
173
174 TLorentzVector * nuP4 = interaction->InitState().GetProbeP4( genie::kRfLab );
175 TLorentzVector qP4 = *nuP4 - lepton;
176 delete nuP4;
177 double Q2 = -1 * qP4.Mag2();
178
179 interaction->KinePtr()->SetFSLeptonP4( lepton );
180 interaction->KinePtr()->SetHadSystP4( outNucleon );
181 interaction->KinePtr()->SetQ2( Q2 );
182
183 // Check the Q2 range. If we're outside of it, don't bother
184 // with the rest of the calculation.
185 Range1D_t Q2lim = interaction->PhaseSpace().Q2Lim();
186 if (Q2 < Q2lim.min || Q2 > Q2lim.max) return 0.;
187
188 // Compute the QE cross section for the current kinematics
189 double xsec = xsec_model->XSec(interaction, genie::kPSQELEvGen);
190
191 return xsec;
192}

References BindHitNucleon(), genie::InitialState::CMEnergy(), anonymous_namespace{QELUtils.cxx}::COMframe2Lab(), genie::Interaction::FSPrimLepton(), genie::InitialState::GetProbeP4(), genie::Interaction::InitState(), genie::controls::kASmallNum, genie::Interaction::KinePtr(), genie::constants::kPi, genie::kPSQELEvGen, genie::kRfLab, genie::Range1D_t::max, genie::Interaction::PhaseSpace(), genie::KPhaseSpace::Q2Lim(), genie::Interaction::RecoilNucleonPdg(), genie::Kinematics::SetFSLeptonP4(), genie::Kinematics::SetHadSystP4(), genie::Kinematics::SetQ2(), and genie::XSecAlgorithmI::XSec().

Referenced by genie::QELEventGenerator::ComputeMaxXSec(), genie::utils::gsl::FullQELdXSec::DoEval(), and genie::QELEventGenerator::ProcessEventRecord().

◆ CosTheta0Max()

double genie::utils::CosTheta0Max ( const genie::Interaction & interaction)

Definition at line 217 of file DMELUtils.cxx.

217 {
218
219 // q0 > 0 only needs to be enforced (indirectly via a calculation of
220 // CosTheta0Max) for bound nucleons. The Q2 limits should take care of valid
221 // kinematics for free nucleons.
222 if ( !interaction.InitState().Tgt().IsNucleus()
223 || interaction.TestBit(kIAssumeFreeNucleon) ) return 1.;
224
225 double probe_E_lab = interaction.InitState().ProbeE( genie::kRfLab );
226
227 TVector3 beta = COMframe2Lab( interaction.InitState() );
228 double gamma = 1. / std::sqrt(1. - beta.Mag2());
229
230 double sqrt_s = interaction.InitState().CMEnergy();
231 double mNf = interaction.RecoilNucleon()->Mass();
232 double ml = interaction.FSPrimLepton()->Mass();
233 double lepton_E_COM = (sqrt_s*sqrt_s + ml*ml - mNf*mNf) / (2.*sqrt_s);
234
235 // If there isn't enough available energy to create an on-shell
236 // final lepton, then don't bother with the rest of the calculation
237 // NOTE: C++11 would allow use to use lowest() here instead
238 if ( lepton_E_COM <= ml ) return -std::numeric_limits<double>::max();
239
240 double lepton_p_COM = std::sqrt( std::max(lepton_E_COM*lepton_E_COM
241 - ml*ml, 0.) );
242
243 // Possibly off-shell initial struck nucleon total energy
244 // (BindHitNucleon() should have been called previously if needed)
245 const TLorentzVector& p4Ni = interaction.InitState().Tgt().HitNucP4();
246 double ENi = p4Ni.E();
247 // On-shell mass of initial struck nucleon
248 double mNi = interaction.InitState().Tgt().HitNucMass();
249 // On-shell initial struck nucleon energy
250 double ENi_on_shell = std::sqrt( mNi*mNi + p4Ni.Vect().Mag2() );
251 // Energy needed to put initial nucleon on the mass shell
252 double epsilon_B = ENi_on_shell - ENi;
253
254 double cos_theta0_max = ( probe_E_lab - gamma*lepton_E_COM - epsilon_B )
255 / ( gamma * lepton_p_COM * beta.Mag() );
256 return cos_theta0_max;
257}
const Target & Tgt(void) const
double ProbeE(RefFrame_t rf) const
TParticlePDG * RecoilNucleon(void) const
recoil nucleon
const TLorentzVector & HitNucP4(void) const
Definition Target.h:91
double HitNucMass(void) const
Definition Target.cxx:233

References genie::InitialState::CMEnergy(), anonymous_namespace{DMELUtils.cxx}::COMframe2Lab(), genie::Interaction::FSPrimLepton(), genie::Target::HitNucMass(), genie::Target::HitNucP4(), genie::Interaction::InitState(), genie::Target::IsNucleus(), genie::kIAssumeFreeNucleon, genie::kRfLab, genie::InitialState::ProbeE(), genie::Interaction::RecoilNucleon(), and genie::InitialState::Tgt().

Referenced by genie::DMELEventGenerator::ComputeMaxXSec(), genie::QELEventGenerator::ComputeMaxXSec(), genie::DMELEventGenerator::ProcessEventRecord(), and genie::QELEventGenerator::ProcessEventRecord().

◆ EnergyDeltaFunctionSolutionDMEL()

double genie::utils::EnergyDeltaFunctionSolutionDMEL ( const Interaction & inter)

Definition at line 51 of file DMELUtils.cxx.

53{
54 // Get the final-state lepton and struck nucleon 4-momenta in the lab frame
55 const TLorentzVector& lepton = inter.Kine().FSLeptonP4();
56 const TLorentzVector& outNucleon = inter.Kine().HadSystP4();
57
58 // Get beta for a Lorentz boost from the lab frame to the COM frame and
59 // vice-versa
60 TLorentzVector* probe = inter.InitStatePtr()->GetProbeP4( kRfLab );
61 const TLorentzVector& hit_nucleon = inter.InitStatePtr()->TgtPtr()
62 ->HitNucP4();
63 TLorentzVector total_p4 = (*probe) + hit_nucleon;
64 TVector3 beta_COM_to_lab = total_p4.BoostVector();
65 TVector3 beta_lab_to_COM = -beta_COM_to_lab;
66
67 // Square of the Lorentz gamma factor for the boosts
68 double gamma2 = std::pow(total_p4.Gamma(), 2);
69
70 // Get the final-state lepton 4-momentum in the COM frame
71 TLorentzVector leptonCOM = TLorentzVector( lepton );
72 leptonCOM.Boost( beta_lab_to_COM );
73
74 // Angle between COM outgoing lepton and lab-frame velocity of COM frame
75 double theta0 = leptonCOM.Angle( beta_COM_to_lab );
76 double cos_theta0_squared = std::pow(std::cos( theta0 ), 2);
77 //double sin_theta0_squared = 1. - cos_theta0_squared; // sin^2(x) + cos^2(x) = 1
78
79 // Difference in lab frame velocities between lepton and outgoing nucleon
80 TVector3 lepton_vel = ( lepton.Vect() * (1. / lepton.E()) );
81 TVector3 outNucleon_vel = ( outNucleon.Vect() * (1. / outNucleon.E()) );
82 double vel_diff = ( lepton_vel - outNucleon_vel ).Mag();
83
84 // Compute the factor in the kPSDMELEvGen phase space that arises from
85 // eliminating the energy-conserving delta function
86 double factor = std::sqrt( 1. + (1. - cos_theta0_squared)*(gamma2 - 1.) )
87 * std::pow(leptonCOM.P(), 2) / vel_diff;
88
89 delete probe;
90
91 return factor;
92}
InitialState * InitStatePtr(void) const
Definition Interaction.h:74
const Kinematics & Kine(void) const
Definition Interaction.h:71
const TLorentzVector & HadSystP4(void) const
Definition Kinematics.h:66
const TLorentzVector & FSLeptonP4(void) const
Definition Kinematics.h:65

References genie::Kinematics::FSLeptonP4(), genie::InitialState::GetProbeP4(), genie::Kinematics::HadSystP4(), genie::Target::HitNucP4(), genie::Interaction::InitStatePtr(), genie::Interaction::Kine(), genie::kRfLab, and genie::InitialState::TgtPtr().

◆ EnergyDeltaFunctionSolutionQEL()

double genie::utils::EnergyDeltaFunctionSolutionQEL ( const Interaction & inter)

Definition at line 50 of file QELUtils.cxx.

52{
53 // Get the final-state lepton and struck nucleon 4-momenta in the lab frame
54 const TLorentzVector& lepton = inter.Kine().FSLeptonP4();
55 const TLorentzVector& outNucleon = inter.Kine().HadSystP4();
56
57 // Get beta for a Lorentz boost from the lab frame to the COM frame and
58 // vice-versa
59 TLorentzVector* probe = inter.InitStatePtr()->GetProbeP4( kRfLab );
60 const TLorentzVector& hit_nucleon = inter.InitStatePtr()->TgtPtr()
61 ->HitNucP4();
62 TLorentzVector total_p4 = (*probe) + hit_nucleon;
63 TVector3 beta_COM_to_lab = total_p4.BoostVector();
64 TVector3 beta_lab_to_COM = -beta_COM_to_lab;
65
66 // Square of the Lorentz gamma factor for the boosts
67 double gamma2 = std::pow(total_p4.Gamma(), 2);
68
69 // Get the final-state lepton 4-momentum in the COM frame
70 TLorentzVector leptonCOM = TLorentzVector( lepton );
71 leptonCOM.Boost( beta_lab_to_COM );
72
73 // Angle between COM outgoing lepton and lab-frame velocity of COM frame
74 double theta0 = leptonCOM.Angle( beta_COM_to_lab );
75 double cos_theta0_squared = std::pow(std::cos( theta0 ), 2);
76 //double sin_theta0_squared = 1. - cos_theta0_squared; // sin^2(x) + cos^2(x) = 1
77
78 // Difference in lab frame velocities between lepton and outgoing nucleon
79 TVector3 lepton_vel = ( lepton.Vect() * (1. / lepton.E()) );
80 TVector3 outNucleon_vel = ( outNucleon.Vect() * (1. / outNucleon.E()) );
81 double vel_diff = ( lepton_vel - outNucleon_vel ).Mag();
82
83 // Compute the factor in the kPSQELEvGen phase space that arises from
84 // eliminating the energy-conserving delta function
85 double factor = std::sqrt( 1. + (1. - cos_theta0_squared)*(gamma2 - 1.) )
86 * std::pow(leptonCOM.P(), 2) / vel_diff;
87
88 delete probe;
89
90 return factor;
91}

References genie::Kinematics::FSLeptonP4(), genie::InitialState::GetProbeP4(), genie::Kinematics::HadSystP4(), genie::Target::HitNucP4(), genie::Interaction::InitStatePtr(), genie::Interaction::Kine(), genie::kRfLab, and genie::InitialState::TgtPtr().

Referenced by genie::LwlynSmithQELCCPXSec::FullDifferentialXSec(), and genie::NievesQELCCPXSec::XSec().

◆ operator<<()

ostream & genie::utils::operator<< ( ostream & stream,
const T2KEvGenMetaData & md )

Definition at line 22 of file T2KEvGenMetaData.cxx.

23 {
24 md.Print(stream);
25 return stream;
26 }
void Print(ostream &stream) const

◆ SetPrimaryLeptonPolarization()

void genie::utils::SetPrimaryLeptonPolarization ( GHepRecord * ev)

Definition at line 23 of file PrimaryLeptonUtils.cxx.

24{
25// Moved out of the PrimaryLeptonGenerator class to make the same treatment
26// accessible for generators that use a more unified approach (e.g.,
27// QELEventGenerator and MECGenerator). -- S. Gardiner
28
29// Set the final state lepton polarization. A mass-less lepton would be fully
30// polarized. This would be exact for neutrinos and a very good approximation
31// for electrons for the energies this generator is going to be used. This is
32// not the case for muons and, mainly, for taus. I need to refine this later.
33// How? See Kuzmin, Lyubushkin and Naumov, hep-ph/0312107
34
35 // get the final state primary lepton
37 if ( !fsl ) {
38 LOG("LeptonicVertex", pERROR)
39 << "Final state lepton not set yet! \n" << *ev;
40 return;
41 }
42
43 // Get (px,py,pz) @ LAB
44 TVector3 plab( fsl->Px(), fsl->Py(), fsl->Pz() );
45
46 // In the limit m/E->0: leptons are left-handed and their anti-particles
47 // are right-handed
48 int pdgc = fsl->Pdg();
49 if ( pdg::IsNeutrino(pdgc) || pdg::IsElectron(pdgc) ||
50 pdg::IsMuon(pdgc) || pdg::IsTau(pdgc) )
51 {
52 plab *= -1; // left-handed
53 }
54
55 LOG("LeptonicVertex", pINFO)
56 << "Setting polarization angles for particle: " << fsl->Name();
57
58 fsl->SetPolarization( plab );
59
60 if ( fsl->PolzIsSet() ) {
61 LOG("LeptonicVertex", pINFO)
62 << "Polarization (rad): Polar = " << fsl->PolzPolarAngle()
63 << ", Azimuthal = " << fsl->PolzAzimuthAngle();
64 }
65}
#define pINFO
Definition Messenger.h:62
#define pERROR
Definition Messenger.h:59
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 Pdg(void) const
double PolzAzimuthAngle(void) const
double PolzPolarAngle(void) const
double Px(void) const
Get Px.
double Pz(void) const
Get Pz.
double Py(void) const
Get Py.
void SetPolarization(double theta, double phi)
bool PolzIsSet(void) const
virtual GHepParticle * FinalStatePrimaryLepton(void) const
bool IsTau(int pdgc)
Definition PDGUtils.cxx:208
bool IsElectron(int pdgc)
Definition PDGUtils.cxx:188
bool IsMuon(int pdgc)
Definition PDGUtils.cxx:198

References genie::GHepRecord::FinalStatePrimaryLepton(), genie::pdg::IsElectron(), genie::pdg::IsMuon(), genie::pdg::IsNeutrino(), genie::pdg::IsTau(), LOG, genie::GHepParticle::Name(), genie::GHepParticle::Pdg(), pERROR, pINFO, genie::GHepParticle::PolzAzimuthAngle(), genie::GHepParticle::PolzIsSet(), genie::GHepParticle::PolzPolarAngle(), genie::GHepParticle::Px(), genie::GHepParticle::Py(), genie::GHepParticle::Pz(), and genie::GHepParticle::SetPolarization().

Referenced by genie::MECGenerator::AddFinalStateLepton(), genie::QELEventGenerator::ProcessEventRecord(), genie::QELEventGeneratorSM::ProcessEventRecord(), genie::MECGenerator::SelectNSVLeptonKinematics(), and genie::PrimaryLeptonGenerator::SetPolarization().

◆ StringToDMELBindingMode()

genie::DMELEvGen_BindingMode_t genie::utils::StringToDMELBindingMode ( const std::string & mode_str)

Definition at line 195 of file DMELUtils.cxx.

197{
198 // Translate the string setting the binding mode to the appropriate
199 // enum value, or complain if one couldn't be found
200 if ( binding_mode == "UseGroundStateRemnant" ) {
202 }
203 else if ( binding_mode == "UseNuclearModel" ) {
204 return kUseNuclearModel;
205 }
206 else if ( binding_mode == "OnShell" ) {
207 return kOnShell;
208 }
209 else {
210 LOG("DMELEvent", pFATAL) << "Unrecognized setting \"" << binding_mode
211 << "\" requested in genie::utils::StringToDMELBindingMode()";
212 gAbortingInErr = true;
213 std::exit(1);
214 }
215}

References genie::gAbortingInErr, genie::kOnShell, genie::kUseGroundStateRemnant, genie::kUseNuclearModel, LOG, and pFATAL.

Referenced by genie::DMELEventGenerator::LoadConfig().

◆ StringToQELBindingMode()

genie::QELEvGen_BindingMode_t genie::utils::StringToQELBindingMode ( const std::string & mode_str)

Definition at line 194 of file QELUtils.cxx.

196{
197 // Translate the string setting the binding mode to the appropriate
198 // enum value, or complain if one couldn't be found
199 if ( binding_mode == "UseGroundStateRemnant" ) {
201 }
202 else if ( binding_mode == "UseNuclearModel" ) {
203 return kUseNuclearModel;
204 }
205 else if ( binding_mode == "OnShell" ) {
206 return kOnShell;
207 }
208 else if ( binding_mode == "ValenciaStyleQValue" ) {
210 }
211 else {
212 LOG("QELEvent", pFATAL) << "Unrecognized setting \"" << binding_mode
213 << "\" requested in genie::utils::StringToQELBindingMode()";
214 gAbortingInErr = true;
215 std::exit(1);
216 }
217}

References genie::gAbortingInErr, genie::kOnShell, genie::kUseGroundStateRemnant, genie::kUseNuclearModel, genie::kValenciaStyleQValue, LOG, and pFATAL.

Referenced by genie::NewQELXSec::Integrate(), genie::LwlynSmithQELCCPXSec::LoadConfig(), genie::NievesQELCCPXSec::LoadConfig(), and genie::QELEventGenerator::LoadConfig().