25 #include <Math/Factory.h>
26 #include <Math/Minimizer.h>
29 #include "Framework/Conventions/GBuild.h"
54 using namespace genie;
55 using namespace genie::controls;
56 using namespace genie::utils;
57 using namespace genie::utils::gsl;
61 const double max_dbl = std::numeric_limits<double>::max();
62 const double min_dbl = std::numeric_limits<double>::min();
84 LOG(
"QELEvent",
pINFO) <<
"Generating QE event kinematics...";
88 <<
"Generating kinematics uniformly over the allowed phase space";
92 const InitialState & init_state = interaction -> InitState();
99 LOG(
"QELEvent",
pFATAL) <<
"No hit nucleon was set";
108 double hitNucPos = nucleon->
X4()->Vect().Mag();
120 bool isHeavyNucleus = tgt->
A()>3;
131 double dvmax= isHeavyNucleus ? this->
MaxXSec(evrec, 2) : 0.;
135 double Q2, v, kF, xsec;
136 unsigned int iter = 0;
141 LOG(
"QELEvent",
pINFO) <<
"Attempt #: " << iter;
145 <<
"Couldn't select a valid kinematics after " << iter <<
" iterations";
148 exception.
SetReason(
"Couldn't select kinematics");
154 double xsec_max = 0.;
155 double pth = rnd->
RndKine().Rndm();
159 xsec_max = xsec_max1;
164 xsec_max = xsec_max2;
172 dv = dvmax * rnd->
RndKine().Rndm();
197 double t = xsec_max * rnd->
RndKine().Rndm();
217 double qv = TMath::Sqrt(v*v+Q2);
218 TLorentzVector transferMom(0, 0, qv, v);
221 TLorentzVector * tempTLV = evrec->
Probe()->
GetP4();
222 TLorentzVector neutrinoMom = *tempTLV;
226 double theta = neutrinoMom.Vect().Theta();
227 double phi = neutrinoMom.Vect().Phi();
228 double theta_k =
sm_utils-> GetTheta_k(v, qv);
229 double costheta_k = TMath::Cos(theta_k);
230 double sintheta_k = TMath::Sin(theta_k);
232 double theta_p =
sm_utils-> GetTheta_p(kF, v, qv, E_p);
233 double costheta_p = TMath::Cos(theta_p);
234 double sintheta_p = TMath::Sin(theta_p);
235 double fi_p = 2 * TMath::Pi() * rnd->
RndGen().Rndm();
236 double cosfi_p = TMath::Cos(fi_p);
237 double sinfi_p = TMath::Sin(fi_p);
238 double psi = 2 * TMath::Pi() * rnd->
RndGen().Rndm();
241 TLorentzVector neutrinoMomZ(neutrinoMom.P()*sintheta_k, 0, neutrinoMom.P()*costheta_k, neutrinoMom.E());
244 TLorentzVector outLeptonMom = neutrinoMomZ-transferMom;
247 TLorentzVector inNucleonMom(kF*sintheta_p*cosfi_p, kF*sintheta_p*sinfi_p, kF*costheta_p, E_p);
250 TLorentzVector outNucleonMom = inNucleonMom+transferMom;
253 TVector3 yvec (0.0, 1.0, 0.0);
254 TVector3 zvec (0.0, 0.0, 1.0);
255 TVector3 unit_nudir = neutrinoMom.Vect().Unit();
257 outLeptonMom.Rotate(theta-theta_k, yvec);
258 outLeptonMom.Rotate(phi, zvec);
260 inNucleonMom.Rotate(theta-theta_k, yvec);
261 inNucleonMom.Rotate(phi, zvec);
263 outNucleonMom.Rotate(theta-theta_k, yvec);
264 outNucleonMom.Rotate(phi, zvec);
266 outLeptonMom.Rotate(psi, unit_nudir);
267 inNucleonMom.Rotate(psi, unit_nudir);
268 outNucleonMom.Rotate(psi, unit_nudir);
272 p4->SetPx( inNucleonMom.Px() );
273 p4->SetPy( inNucleonMom.Py() );
274 p4->SetPz( inNucleonMom.Pz() );
275 p4->SetE ( inNucleonMom.E() );
300 double totxsec = evrec->
XSec();
301 double wght = (vol/totxsec)*xsec;
302 LOG(
"QELEvent",
pNOTICE) <<
"Kinematics wght = "<< wght;
306 LOG(
"QELEvent",
pNOTICE) <<
"Current event wght = " << wght;
309 TLorentzVector x4l(*(evrec->
Probe())->X4());
327 LOG(
"QELEvent",
pNOTICE) <<
"pn: " << inNucleonMom.X() <<
", " <<inNucleonMom.Y() <<
", " <<inNucleonMom.Z() <<
", " <<inNucleonMom.E();
336 LOG(
"QELEvent",
pINFO) <<
"Done generating QE event kinematics!";
343 LOG(
"QELEvent",
pINFO) <<
"Adding final state nucleus";
351 int A = nucleus->
A();
352 int Z = nucleus->
Z();
357 for(
int id = fd;
id <= ld;
id++)
363 int pdgc = particle->
Pdg();
368 if (is_p || is_n) A--;
370 Px += particle->
Px();
371 Py += particle->
Py();
372 Pz += particle->
Pz();
377 TParticlePDG * remn = 0;
383 <<
"No particle with [A = " << A <<
", Z = " << Z
384 <<
", pdgc = " << ipdgc <<
"] in PDGLibrary!";
388 double Mi = nucleus->
Mass();
396 <<
"Adding nucleus [A = " << A <<
", Z = " << Z
397 <<
", pdgc = " << ipdgc <<
"]";
401 ipdgc,
kIStStableFinalState, imom,-1,-1,-1, Px,Py,Pz,E, 0,0,0,0);
417 Registry r(
"QELEventGeneratorSM_specific",
false ) ;
418 r.
Set(
"sm_utils_algo",
RgAlg(
"genie::SmithMonizUtils",
"Default") ) ;
458 double xsec_max = -1;
459 double tmp_xsec_max = -1;
462 const InitialState & init_state = interaction -> InitState();
464 bool isHeavyNucleus = tgt->
A()>3;
465 int N_v = isHeavyNucleus?32:0;
468 const double logQ2min = TMath::Log(TMath::Max(rQ2.
min, eps));
469 const double logQ2max = TMath::Log(TMath::Min(rQ2.
max,
fQ2Min));
473 for (
int Q2_n=0; Q2_n <= N_Q2; Q2_n++)
476 double Q2 = TMath::Exp(Q2_n*(logQ2max-logQ2min)/N_Q2 + logQ2min);
479 const double logvmin = TMath::Log(TMath::Max(rv.
min, eps));
480 const double logvmax = TMath::Log(TMath::Max(rv.
max, TMath::Max(rv.
min, eps)));
481 for (
int v_n=0; v_n <= N_v; v_n++)
484 double v = TMath::Exp(v_n*(logvmax-logvmin)/N_v + logvmin);
489 if (xs > tmp_xsec_max)
498 const double Q2min = rQ2.
min;
499 const double Q2max = TMath::Min(rQ2.
max,
fQ2Min);
503 ROOT::Math::Minimizer * min = ROOT::Math::Factory::CreateMinimizer(
"Minuit",
"Minimize");
504 ROOT::Math::IBaseFunctionMultiDim * f = isHeavyNucleus?
static_cast<ROOT::Math::IBaseFunctionMultiDim*
>(
new d3XSecSM_dQ2dvdkF_E(
fXSecModel, interaction, pFmax)):
506 min->SetFunction( *f );
507 min->SetMaxFunctionCalls(10000);
508 min->SetMaxIterations(10000);
509 min->SetTolerance(0.001);
510 min->SetPrintLevel(0);
512 min->SetVariable(0,
"Q2", Q20, step);
513 min->SetVariableLimits(0, Q2min, Q2max);
516 min->SetVariable(1,
"v", v0, step);
517 min->SetVariableLimits(1, vmin, vmax);
520 xsec_max = -min->MinValue();
521 if (tmp_xsec_max > xsec_max)
523 xsec_max = tmp_xsec_max;
543 double xsec_max = -1;
544 double tmp_xsec_max = -1;
547 const InitialState & init_state = interaction -> InitState();
549 bool isHeavyNucleus = tgt->
A()>3;
550 int N_v = isHeavyNucleus?32:0;
552 const double logQ2min = TMath::Log(
fQ2Min);
553 const double logQ2max = TMath::Log(rQ2.
max);
557 for (
int Q2_n=0; Q2_n <= N_Q2; Q2_n++)
560 double Q2 = TMath::Exp(Q2_n*(logQ2max-logQ2min)/N_Q2 + logQ2min);
563 const double logvmin = TMath::Log(TMath::Max(rv.
min, eps));
564 const double logvmax = TMath::Log(TMath::Max(rv.
max, TMath::Max(rv.
min, eps)));
565 for (
int v_n=0; v_n <= N_v; v_n++)
568 double v = TMath::Exp(v_n*(logvmax-logvmin)/N_v + logvmin);
573 if (xs > tmp_xsec_max)
582 const double Q2min =
fQ2Min;
583 const double Q2max = rQ2.
max;
586 ROOT::Math::Minimizer * min = ROOT::Math::Factory::CreateMinimizer(
"Minuit",
"Minimize");
587 ROOT::Math::IBaseFunctionMultiDim * f = isHeavyNucleus?
static_cast<ROOT::Math::IBaseFunctionMultiDim*
>(
new d3XSecSM_dQ2dvdkF_E(
fXSecModel, interaction, pFmax)):
589 min->SetFunction( *f );
590 min->SetMaxFunctionCalls(10000);
591 min->SetMaxIterations(10000);
592 min->SetTolerance(0.001);
593 min->SetPrintLevel(0);
595 min->SetVariable(0,
"Q2", Q20, step);
596 min->SetVariableLimits(0, Q2min, Q2max);
599 min->SetVariable(1,
"v", v0, step);
600 min->SetVariableLimits(1, vmin, vmax);
603 xsec_max = -min->MinValue();
604 if (tmp_xsec_max > xsec_max)
606 xsec_max = tmp_xsec_max;
612 double diffv_max = -1;
613 double tmp_diffv_max = -1;
614 const int N_Q2 = 100;
617 for (
int Q2_n = 0; Q2_n<=N_Q2; Q2_n++)
619 double Q2 = rQ2.
min + 1.*Q2_n * (rQ2.
max-rQ2.
min)/N_Q2;
621 if (rv.max-rv.min > tmp_diffv_max)
623 tmp_diffv_max = rv.
max-rv.min;
628 ROOT::Math::Minimizer * min = ROOT::Math::Factory::CreateMinimizer(
"Minuit",
"Minimize");
629 ROOT::Math::IBaseFunctionMultiDim * f =
new dv_dQ2_E(interaction);
630 min->SetFunction( *f );
631 min->SetMaxFunctionCalls(10000);
632 min->SetMaxIterations(10000);
633 min->SetTolerance(0.001);
634 min->SetPrintLevel(0);
636 min->SetVariable(0,
"Q2", Q20, step);
637 min->SetVariableLimits(0, rQ2.
min, rQ2.
max);
639 diffv_max = -min->MinValue();
641 if (tmp_diffv_max > diffv_max)
643 diffv_max = tmp_diffv_max;
654 d3XSecSM_dQ2dvdkF_E::d3XSecSM_dQ2dvdkF_E(
657 double pF) : ROOT::Math::IBaseFunctionMultiDim(),
681 ROOT::Math::IBaseFunctionMultiDim *
689 const Interaction * i) : ROOT::Math::IBaseFunctionMultiDim(),
710 ROOT::Math::IBaseFunctionMultiDim *
739 ROOT::Math::IBaseFunctionMultiDim *
void SetInteraction(const Interaction *i)
unsigned int NDim(void) const
Cross Section Calculation Interface.
Range1D_t Q2QES_SM_lim(void) const
double vQES_SM_max(double Q2min, double Q2max) const
SmithMonizUtils * sm_utils
unsigned int NDim(void) const
virtual GHepParticle * Particle(int position) const
virtual void SetWeight(double wght)
double fQ2Min
Q2-threshold for seeking the second maximum.
bool fGenerateUniformly
uniform over allowed phase space + event weight?
double E(void) const
Get energy.
double Q2(const Interaction *const i)
virtual Interaction * Summary(void) const
static RandomGen * Instance()
Access instance.
void SetQ2(double Q2, bool selected=false)
Kinematics * KinePtr(void) const
double DoEval(const double *) const
int FirstDaughter(void) const
int RecoilNucleonPdg(void) const
recoil nucleon pdg
A simple [min,max] interval for doubles.
virtual void AssertXSecLimits(const Interaction *in, double xsec, double xsec_max) const
bool IsNucleus(void) const
int GetParamVect(const std::string &comm_name, std::vector< T > &v, bool is_top_call=true) const
Handle to load vectors of parameters.
double fMaxXSecDiffTolerance
max{100*(xsec-maxxsec)/.5*(xsec+maxxsec)} if xsec>maxxsec
int fNumOfSafetyFactors
Number of given safety factors.
Defines the EventGeneratorI interface.
virtual double MaxXSec(GHepRecord *evrec, const int nkey=0) const
Generated/set kinematical variables for an event.
virtual int HitNucleonPosition(void) const
virtual double Weight(void) const
void SetHitNucPosition(double r)
double ComputeMaxXSec(const Interaction *in) const
dv_dQ2_E(const Interaction *)
void SetMomentum(const TLorentzVector &p4)
double Mass(void) const
Mass that corresponds to the PDG code.
Range1D_t vQES_SM_lim(double Q2) const
Abstract class. Provides a data caching mechanism for for concrete implementations of the EventRecord...
A singleton holding random number generator classes. All random number generation in GENIE should tak...
double Pz(void) const
Get Pz.
const XSecAlgorithmI * fXSecModel
int FSPrimLeptonPdg(void) const
final state primary lepton pdg
double GetBindingEnergy(void) const
double Px(void) const
Get Px.
virtual GHepParticle * Probe(void) const
double W(const Interaction *const i)
int fNumOfInterpolatorTypes
Number of given interpolators types.
d1XSecSM_dQ2_E(const XSecAlgorithmI *, const Interaction *)
std::vector< double > vSafetyFactors
MaxXSec -> MaxXSec * fSafetyFactors[nkey].
Summary information for an interaction.
const TLorentzVector & HitNucP4(void) const
Range1D_t kFQES_SM_lim(double nu, double Q2) const
int LastDaughter(void) const
An exception thrown by EventRecordVisitorI when the normal processing sequence has to be disrupted (f...
d3XSecSM_dQ2dvdkF_E(const XSecAlgorithmI *, const Interaction *, double pF)
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
ROOT::Math::IBaseFunctionMultiDim * Clone(void) const
double DoEval(const double *) const
ROOT::Math::IBaseFunctionMultiDim * Clone(void) const
ROOT::Math::IBaseFunctionMultiDim * Clone(void) const
const Interaction * fInteraction
static constexpr double A
void Configure(const Registry &config)
const Interaction * fInteraction
TLorentzVector * GetP4(void) const
void WQ2toXY(double Ev, double M, double W, double Q2, double &x, double &y)
A Neutrino Interaction Target. Is a transparent encapsulation of quite different physical systems suc...
virtual void Configure(const Registry &config)
const Algorithm * GetAlgorithm(const AlgId &algid)
void ProcessEventRecord(GHepRecord *event_rec) const
bool fGenerateNucleonInNucleus
generate struck nucleon in nucleus
SmithMonizUtils * sm_utils
virtual GHepParticle * TargetNucleus(void) const
TRandom3 & RndKine(void) const
rnd number generator used by kinematics generators
const UInt_t kISkipKinematicChk
if set, skip kinematic validity checks
double vQES_SM_min(double Q2min, double Q2max) const
virtual double XSec(const Interaction *i, KinePhaseSpace_t k=kPSfE) const =0
Compute the cross section for the input interaction.
void Setx(double x, bool selected=false)
void SetKV(KineVar_t kv, double value)
void SetRemovalEnergy(double Erm)
static RunningThreadInfo * Instance(void)
void SetW(double W, bool selected=false)
void SwitchOnFastForward(void)
TLorentzVector * HitNucP4Ptr(void) const
static PDGLibrary * Instance(void)
Contains auxiliary functions for Smith-Moniz model. .
void SetReason(string reason)
virtual TBits * EventFlags(void) const
static AlgFactory * Instance()
void AddTargetNucleusRemnant(GHepRecord *evrec) const
add a recoiled nucleus remnant
double PhaseSpaceVolume(KinePhaseSpace_t ps) const
const TLorentzVector * X4(void) const
A registry. Provides the container for algorithm configuration parameters.
void Sety(double y, bool selected=false)
virtual GHepParticle * HitNucleon(void) const
Target * TgtPtr(void) const
TRandom3 & RndGen(void) const
rnd number generator for generic usage
double fEMin
min E for which maxxsec is cached - forcing explicit calc.
int IonPdgCode(int A, int Z)
virtual const XSecAlgorithmI * CrossSectionAlg(void) const =0
const XSecAlgorithmI * fModel
const Interaction * fInteraction
virtual double XSec(void) const
const InitialState & InitState(void) const
virtual void AddParticle(const GHepParticle &p)
double DoEval(const double *) const
TParticlePDG * Find(int pdgc, bool must_exist=true)
void ClearRunningValues(void)
bool GetParamDef(const RgKey &name, T &p, const T &def) const
const Target & Tgt(void) const
The GENIE Algorithm Factory.
virtual int ProbePosition(void) const
static const unsigned int kRjMaxIterations
const XSecAlgorithmI * fModel
const EventGeneratorI * RunningThread(void)
void SetPrimaryLeptonPolarization(GHepRecord *ev)
void Set(RgIMapPair entry)
double ProbeE(RefFrame_t rf) const
GENIE's GHEP MC event record.
static constexpr double m
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
STDHEP-like event record entry that can fit a particle or a nucleus.
Keep info on the event generation thread currently on charge. This is used so that event generation m...
virtual int TargetNucleusPosition(void) const
const UInt_t kISkipProcessChk
if set, skip process validity checks
virtual void SetDiffXSec(double xsec, KinePhaseSpace_t ps)
enum genie::EGHepStatus GHepStatus_t
unsigned int NDim(void) const
double GetFermiMomentum(void) const
Initial State information.
std::vector< string > vInterpolatorTypes
Type of interpolator for each key in a branch.
double Py(void) const
Get Py.
const Algorithm * SubAlg(const RgKey ®istry_key) const