25#include <Math/Factory.h>
26#include <Math/Minimizer.h>
29#include "Framework/Conventions/GBuild.h"
60 const double eps = std::numeric_limits<double>::epsilon();
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;
122 sm_utils->SetInteraction(interaction);
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() );
280 LOG(
"QELEvent",
pNOTICE) <<
"Selected: W = "<< W;
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));
471 const double pFmax =
sm_utils->GetFermiMomentum();
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);
500 const double vmin =
sm_utils->vQES_SM_min(Q2min, Q2max);
501 const double vmax =
sm_utils->vQES_SM_max(Q2min, Q2max);
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);
555 const double pFmax =
sm_utils->GetFermiMomentum();
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;
584 const double vmin =
sm_utils->vQES_SM_min(Q2min, Q2max);
585 const double vmax =
sm_utils->vQES_SM_max(Q2min, Q2max);
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;
657 double pF) : ROOT::Math::IBaseFunctionMultiDim(),
681ROOT::Math::IBaseFunctionMultiDim *
689 const Interaction * i) : ROOT::Math::IBaseFunctionMultiDim(),
710ROOT::Math::IBaseFunctionMultiDim *
739ROOT::Math::IBaseFunctionMultiDim *
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE,...
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils.
The GENIE Algorithm Factory.
const Algorithm * GetAlgorithm(const AlgId &algid)
static AlgFactory * Instance()
int GetParamVect(const std::string &comm_name, std::vector< T > &v, bool is_top_call=true) const
Handle to load vectors of parameters.
virtual void Configure(const Registry &config)
bool GetParamDef(const RgKey &name, T &p, const T &def) const
const Algorithm * SubAlg(const RgKey ®istry_key) const
Defines the EventGeneratorI interface.
virtual const XSecAlgorithmI * CrossSectionAlg(void) const =0
STDHEP-like event record entry that can fit a particle or a nucleus.
void SetMomentum(const TLorentzVector &p4)
TLorentzVector * GetP4(void) const
void SetRemovalEnergy(double Erm)
double Mass(void) const
Mass that corresponds to the PDG code.
const TLorentzVector * X4(void) const
int LastDaughter(void) const
double Px(void) const
Get Px.
double E(void) const
Get energy.
double Pz(void) const
Get Pz.
double Py(void) const
Get Py.
int FirstDaughter(void) const
GENIE's GHEP MC event record.
virtual double Weight(void) const
virtual int ProbePosition(void) const
virtual GHepParticle * Probe(void) const
virtual void SetDiffXSec(double xsec, KinePhaseSpace_t ps)
virtual double XSec(void) const
virtual GHepParticle * TargetNucleus(void) const
virtual Interaction * Summary(void) const
virtual TBits * EventFlags(void) const
virtual void AddParticle(const GHepParticle &p)
virtual int TargetNucleusPosition(void) const
virtual void SetWeight(double wght)
virtual GHepParticle * Particle(int position) const
virtual int HitNucleonPosition(void) const
virtual GHepParticle * HitNucleon(void) const
Initial State information.
const Target & Tgt(void) const
double ProbeE(RefFrame_t rf) const
Target * TgtPtr(void) const
Summary information for an interaction.
int RecoilNucleonPdg(void) const
recoil nucleon pdg
int FSPrimLeptonPdg(void) const
final state primary lepton pdg
const InitialState & InitState(void) const
Kinematics * KinePtr(void) const
virtual void AssertXSecLimits(const Interaction *in, double xsec, double xsec_max) const
std::vector< string > vInterpolatorTypes
Type of interpolator for each key in a branch.
std::vector< double > vSafetyFactors
MaxXSec -> MaxXSec * fSafetyFactors[nkey].
bool fGenerateUniformly
uniform over allowed phase space + event weight?
double fMaxXSecDiffTolerance
max{100*(xsec-maxxsec)/.5*(xsec+maxxsec)} if xsec>maxxsec
double fEMin
min E for which maxxsec is cached - forcing explicit calc.
int fNumOfInterpolatorTypes
Number of given interpolators types.
int fNumOfSafetyFactors
Number of given safety factors.
virtual double MaxXSec(GHepRecord *evrec, const int nkey=0) const
const XSecAlgorithmI * fXSecModel
Generated/set kinematical variables for an event.
void Setx(double x, bool selected=false)
void SetQ2(double Q2, bool selected=false)
void ClearRunningValues(void)
void Sety(double y, bool selected=false)
void SetW(double W, bool selected=false)
static PDGLibrary * Instance(void)
TParticlePDG * Find(int pdgc, bool must_exist=true)
void Configure(const Registry &config)
double fQ2Min
Q2-threshold for seeking the second maximum.
void ProcessEventRecord(GHepRecord *event_rec) const
void AddTargetNucleusRemnant(GHepRecord *evrec) const
add a recoiled nucleus remnant
SmithMonizUtils * sm_utils
double ComputeMaxXSec(const Interaction *in) const
bool fGenerateNucleonInNucleus
generate struck nucleon in nucleus
A singleton holding random number generator classes. All random number generation in GENIE should tak...
static RandomGen * Instance()
Access instance.
TRandom3 & RndKine(void) const
rnd number generator used by kinematics generators
TRandom3 & RndGen(void) const
rnd number generator for generic usage
A simple [min,max] interval for doubles.
A registry. Provides the container for algorithm configuration parameters.
void Set(RgIMapPair entry)
Keep info on the event generation thread currently on charge. This is used so that event generation m...
static RunningThreadInfo * Instance(void)
const EventGeneratorI * RunningThread(void)
Contains auxiliary functions for Smith-Moniz model. .
A Neutrino Interaction Target. Is a transparent encapsulation of quite different physical systems suc...
void SetHitNucPosition(double r)
const TLorentzVector & HitNucP4(void) const
TLorentzVector * HitNucP4Ptr(void) const
bool IsNucleus(void) const
Cross Section Calculation Interface.
An exception thrown by EventRecordVisitorI when the normal processing sequence has to be disrupted (f...
void SwitchOnFastForward(void)
void SetReason(string reason)
ROOT::Math::IBaseFunctionMultiDim * Clone(void) const
const XSecAlgorithmI * fModel
d1XSecSM_dQ2_E(const XSecAlgorithmI *, const Interaction *)
double DoEval(const double *) const
unsigned int NDim(void) const
const Interaction * fInteraction
ROOT::Math::IBaseFunctionMultiDim * Clone(void) const
const XSecAlgorithmI * fModel
double DoEval(const double *) const
d3XSecSM_dQ2dvdkF_E(const XSecAlgorithmI *, const Interaction *, double pF)
unsigned int NDim(void) const
const Interaction * fInteraction
dv_dQ2_E(const Interaction *)
unsigned int NDim(void) const
ROOT::Math::IBaseFunctionMultiDim * Clone(void) const
SmithMonizUtils * sm_utils
double DoEval(const double *) const
const Interaction * fInteraction
Misc GENIE control constants.
static const unsigned int kRjMaxIterations
int IonPdgCode(int A, int Z)
Simple functions for loading and reading nucleus dependent keys from config files.
Simple utilities for integrating GSL in the GENIE framework.
void WQ2toXY(double Ev, double M, double W, double Q2, double &x, double &y)
Root of GENIE utility namespaces.
void SetPrimaryLeptonPolarization(GHepRecord *ev)
THE MAIN GENIE PROJECT NAMESPACE
enum genie::EGHepStatus GHepStatus_t
const UInt_t kISkipKinematicChk
if set, skip kinematic validity checks
const UInt_t kISkipProcessChk
if set, skip process validity checks