Namespaces | Classes | Functions
genie::utils Namespace Reference

Root of GENIE utility namespaces. More...

Namespaces

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

Classes

class  neutron_osc
 Utilities for simulating neutron oscillation. More...
 
class  nhl
 Utilities for simulating the decay of Neutral Heavy Leptons. More...
 
class  nucleon_decay
 Utilities for simulating nucleon decay. More...
 
class  T2KEvGenMetaData
 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 fnal.gov> Fermi National Accelerator Laboratory

May 01, 2020

Copyright (c) 2003-2020, The GENIE Collaboration For the full text of the license visit http://copyright.genie-mc.org

Function Documentation

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;
310  Mf = genie::PDGLibrary::Instance()->Find( genie::pdg::IonPdgCode(Af, Zf) )->Mass();
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 }
int HitNucPdg(void) const
Definition: Target.cxx:304
int A(void) const
Definition: Target.h:70
bool IsNucleus(void) const
Definition: Target.cxx:272
constexpr T pow(T x)
Definition: pow.h:72
double Mass(Resonance_t res)
resonance mass (GeV)
double Mass(void) const
Definition: Target.cxx:224
bool IsProton(int pdgc)
Definition: PDGUtils.cxx:333
A Neutrino Interaction Target. Is a transparent encapsulation of quite different physical systems suc...
Definition: Target.h:40
int Z(void) const
Definition: Target.h:68
TLorentzVector * HitNucP4Ptr(void) const
Definition: Target.cxx:247
static PDGLibrary * Instance(void)
Definition: PDGLibrary.cxx:57
const UInt_t kIAssumeFreeNucleon
Definition: Interaction.h:49
Target * TgtPtr(void) const
Definition: InitialState.h:67
int IonPdgCode(int A, int Z)
Definition: PDGUtils.cxx:68
const InitialState & InitState(void) const
Definition: Interaction.h:69
TParticlePDG * Find(int pdgc, bool must_exist=true)
Definition: PDGLibrary.cxx:75
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;
312  Mf = genie::PDGLibrary::Instance()->Find( genie::pdg::IonPdgCode(Af, Zf) )->Mass();
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 }
bool IsWeakCC(void) const
bool IsNeutrino(int pdgc)
Definition: PDGUtils.cxx:107
static const double kNucleonMass
Definition: Constants.h:77
int HitNucPdg(void) const
Definition: Target.cxx:304
int RecoilNucleonPdg(void) const
recoil nucleon pdg
int A(void) const
Definition: Target.h:70
#define pFATAL
Definition: Messenger.h:56
bool IsNucleus(void) const
Definition: Target.cxx:272
constexpr T pow(T x)
Definition: pow.h:72
double Mass(Resonance_t res)
resonance mass (GeV)
double Mass(void) const
Definition: Target.cxx:224
double Qvalue(int targetpdg, int nupdg)
Definition: MECUtils.cxx:164
bool IsProton(int pdgc)
Definition: PDGUtils.cxx:333
bool IsWeakNC(void) const
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:96
A class encapsulating an enumeration of interaction types (EM, Weak-CC, Weak-NC) and scattering types...
Definition: ProcessInfo.h:46
bool IsAntiNeutrino(int pdgc)
Definition: PDGUtils.cxx:115
A Neutrino Interaction Target. Is a transparent encapsulation of quite different physical systems suc...
Definition: Target.h:40
int ProbePdg(void) const
Definition: InitialState.h:64
int Z(void) const
Definition: Target.h:68
static int max(int a, int b)
bool IsEM(void) const
TLorentzVector * HitNucP4Ptr(void) const
Definition: Target.cxx:247
static PDGLibrary * Instance(void)
Definition: PDGLibrary.cxx:57
const UInt_t kIAssumeFreeNucleon
Definition: Interaction.h:49
double HitNucPosition(void) const
Definition: Target.h:89
Target * TgtPtr(void) const
Definition: InitialState.h:67
int IonPdgCode(int A, int Z)
Definition: PDGUtils.cxx:68
const InitialState & InitState(void) const
Definition: Interaction.h:69
const ProcessInfo & ProcInfo(void) const
Definition: Interaction.h:70
TParticlePDG * Find(int pdgc, bool must_exist=true)
Definition: PDGLibrary.cxx:75
bool gAbortingInErr
Definition: Messenger.cxx:34
#define pDEBUG
Definition: Messenger.h:63
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 }
const KPhaseSpace & PhaseSpace(void) const
Definition: Interaction.h:73
double beta(double KE, const simb::MCParticle *part)
double Q2(const Interaction *const i)
Definition: KineUtils.cxx:1064
void SetQ2(double Q2, bool selected=false)
Definition: Kinematics.cxx:255
Kinematics * KinePtr(void) const
Definition: Interaction.h:76
int RecoilNucleonPdg(void) const
recoil nucleon pdg
constexpr T pow(T x)
Definition: pow.h:72
double Mass(Resonance_t res)
resonance mass (GeV)
void BindHitNucleon(Interaction &interaction, const NuclearModelI &nucl_model, double &Eb, DMELEvGen_BindingMode_t hitNucleonBindingMode)
Definition: DMELUtils.cxx:259
Range1D_t Q2Lim(void) const
Q2 limits.
void SetFSLeptonP4(const TLorentzVector &p4)
Definition: Kinematics.cxx:297
static const double kASmallNum
Definition: Controls.h:40
TParticlePDG * FSPrimLepton(void) const
final state primary lepton
bool IsEM(void) const
double CMEnergy() const
centre-of-mass energy (sqrt s)
void SetHadSystP4(const TLorentzVector &p4)
Definition: Kinematics.cxx:307
const InitialState & InitState(void) const
Definition: Interaction.h:69
const ProcessInfo & ProcInfo(void) const
Definition: Interaction.h:70
static const double kPi
Definition: Constants.h:37
static QCString * s
Definition: config.cpp:1042
TLorentzVector * GetProbeP4(RefFrame_t rf=kRfHitNucRest) const
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 }
const KPhaseSpace & PhaseSpace(void) const
Definition: Interaction.h:73
double beta(double KE, const simb::MCParticle *part)
double Q2(const Interaction *const i)
Definition: KineUtils.cxx:1064
void SetQ2(double Q2, bool selected=false)
Definition: Kinematics.cxx:255
Kinematics * KinePtr(void) const
Definition: Interaction.h:76
int RecoilNucleonPdg(void) const
recoil nucleon pdg
constexpr T pow(T x)
Definition: pow.h:72
double Mass(Resonance_t res)
resonance mass (GeV)
void BindHitNucleon(Interaction &interaction, const NuclearModelI &nucl_model, double &Eb, DMELEvGen_BindingMode_t hitNucleonBindingMode)
Definition: DMELUtils.cxx:259
Range1D_t Q2Lim(void) const
Q2 limits.
void SetFSLeptonP4(const TLorentzVector &p4)
Definition: Kinematics.cxx:297
static const double kASmallNum
Definition: Controls.h:40
TParticlePDG * FSPrimLepton(void) const
final state primary lepton
bool IsEM(void) const
double CMEnergy() const
centre-of-mass energy (sqrt s)
void SetHadSystP4(const TLorentzVector &p4)
Definition: Kinematics.cxx:307
const InitialState & InitState(void) const
Definition: Interaction.h:69
const ProcessInfo & ProcInfo(void) const
Definition: Interaction.h:70
static const double kPi
Definition: Constants.h:37
static QCString * s
Definition: config.cpp:1042
TLorentzVector * GetProbeP4(RefFrame_t rf=kRfHitNucRest) const
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 }
double beta(double KE, const simb::MCParticle *part)
TParticlePDG * RecoilNucleon(void) const
recoil nucleon
double HitNucMass(void) const
Definition: Target.cxx:233
bool IsNucleus(void) const
Definition: Target.cxx:272
const TLorentzVector & HitNucP4(void) const
Definition: Target.h:91
static int max(int a, int b)
double gamma(double KE, const simb::MCParticle *part)
TParticlePDG * FSPrimLepton(void) const
final state primary lepton
const UInt_t kIAssumeFreeNucleon
Definition: Interaction.h:49
double CMEnergy() const
centre-of-mass energy (sqrt s)
const InitialState & InitState(void) const
Definition: Interaction.h:69
const Target & Tgt(void) const
Definition: InitialState.h:66
double ProbeE(RefFrame_t rf) const
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 }
constexpr T pow(T x)
Definition: pow.h:72
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 }
constexpr T pow(T x)
Definition: pow.h:72
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 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 }
bool IsNeutrino(int pdgc)
Definition: PDGUtils.cxx:107
#define pERROR
Definition: Messenger.h:59
double PolzPolarAngle(void) const
Definition: GHepParticle.h:119
void SetPolarization(double theta, double phi)
double Pz(void) const
Get Pz.
Definition: GHepParticle.h:90
double Px(void) const
Get Px.
Definition: GHepParticle.h:88
int Pdg(void) const
Definition: GHepParticle.h:63
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:96
virtual GHepParticle * FinalStatePrimaryLepton(void) const
Definition: GHepRecord.cxx:326
bool IsTau(int pdgc)
Definition: PDGUtils.cxx:205
#define pINFO
Definition: Messenger.h:62
bool IsMuon(int pdgc)
Definition: PDGUtils.cxx:195
bool PolzIsSet(void) const
double PolzAzimuthAngle(void) const
Definition: GHepParticle.h:120
STDHEP-like event record entry that can fit a particle or a nucleus.
Definition: GHepParticle.h:39
bool IsElectron(int pdgc)
Definition: PDGUtils.cxx:185
double Py(void) const
Get Py.
Definition: GHepParticle.h:89
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" ) {
201  return kUseGroundStateRemnant;
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 }
#define pFATAL
Definition: Messenger.h:56
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:96
bool gAbortingInErr
Definition: Messenger.cxx:34
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" ) {
200  return kUseGroundStateRemnant;
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" ) {
209  return kValenciaStyleQValue;
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 }
#define pFATAL
Definition: Messenger.h:56
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:96
bool gAbortingInErr
Definition: Messenger.cxx:34