30 #include "Framework/Conventions/GBuild.h" 55 using namespace genie;
60 const double eps = std::numeric_limits<double>::epsilon();
82 LOG(
"QELEvent",
pINFO) <<
"Generating QE event kinematics...";
86 <<
"Generating kinematics uniformly over the allowed phase space";
91 const InitialState & init_state = interaction -> InitState();
98 LOG(
"QELEvent",
pFATAL) <<
"No hit nucleon was set";
107 double hitNucPos = nucleon->
X4()->Vect().Mag();
119 bool isHeavyNucleus = tgt->
A()>=3;
129 double vmax= isHeavyNucleus?this->
MaxDiffv(evrec) : 0.;
134 unsigned int iter = 0;
139 LOG(
"QELEvent",
pINFO) <<
"Attempt #: " << iter;
143 <<
"Couldn't select a valid kinematics after " << iter <<
" iterations";
146 exception.
SetReason(
"Couldn't select kinematics");
152 double xsec_max = 0.;
153 double pth = rnd->
RndKine().Rndm();
157 xsec_max = xsec_max1;
162 xsec_max = xsec_max2;
170 v = vmax * rnd->
RndKine().Rndm();
187 double t = xsec_max * rnd->
RndKine().Rndm();
189 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ 190 LOG(
"QELEvent",
pDEBUG)<<
"xsec= " << xsec <<
", J= " <<
J <<
", Rnd= " <<
t;
210 double qv = TMath::Sqrt(v*v+gQ2);
211 TLorentzVector transferMom(0, 0, qv, v);
217 TLorentzVector * tempTLV = evrec->
Probe()->
GetP4();
218 TLorentzVector neutrinoMom = *tempTLV;
222 double theta = neutrinoMom.Vect().Theta();
223 double phi = neutrinoMom.Vect().Phi();
224 double theta_k =
sm_utils-> GetTheta_k(v, qv);
225 double costheta_k = TMath::Cos(theta_k);
226 double sintheta_k = TMath::Sin(theta_k);
228 double theta_p =
sm_utils-> GetTheta_p(kF, v, qv, E_p);
229 double costheta_p = TMath::Cos(theta_p);
230 double sintheta_p = TMath::Sin(theta_p);
231 double fi_p = 2 * TMath::Pi() * rnd->
RndGen().Rndm();
232 double cosfi_p = TMath::Cos(fi_p);
233 double sinfi_p = TMath::Sin(fi_p);
234 double psi = 2 * TMath::Pi() * rnd->
RndGen().Rndm();
237 TLorentzVector neutrinoMomZ(neutrinoMom.P()*sintheta_k, 0, neutrinoMom.P()*costheta_k, neutrinoMom.E());
240 TLorentzVector outLeptonMom = neutrinoMomZ-transferMom;
243 TLorentzVector inNucleonMom(kF*sintheta_p*cosfi_p, kF*sintheta_p*sinfi_p, kF*costheta_p, E_p);
246 TLorentzVector outNucleonMom = inNucleonMom+transferMom;
250 TVector3 yvec (0.0, 1.0, 0.0);
251 TVector3 zvec (0.0, 0.0, 1.0);
252 TVector3 unit_nudir = neutrinoMom.Vect().Unit();
254 outLeptonMom.Rotate(theta-theta_k, yvec);
255 outLeptonMom.Rotate(phi, zvec);
257 inNucleonMom.Rotate(theta-theta_k, yvec);
258 inNucleonMom.Rotate(phi, zvec);
260 outNucleonMom.Rotate(theta-theta_k, yvec);
261 outNucleonMom.Rotate(phi, zvec);
263 outLeptonMom.Rotate(psi, unit_nudir);
264 inNucleonMom.Rotate(psi, unit_nudir);
265 outNucleonMom.Rotate(psi, unit_nudir);
269 p4->SetPx( inNucleonMom.Px() );
270 p4->SetPy( inNucleonMom.Py() );
271 p4->SetPz( inNucleonMom.Pz() );
272 p4->SetE ( inNucleonMom.E() );
277 LOG(
"QELEvent",
pNOTICE) <<
"Selected: W = "<< gW;
297 double totxsec = evrec->
XSec();
298 double wght = (vol/totxsec)*xsec;
299 LOG(
"QELEvent",
pNOTICE) <<
"Kinematics wght = "<< wght;
303 LOG(
"QELEvent",
pNOTICE) <<
"Current event wght = " << wght;
306 TLorentzVector x4l(*(evrec->
Probe())->X4());
324 LOG(
"QELEvent",
pNOTICE) <<
"pn: " << inNucleonMom.X() <<
", " <<inNucleonMom.Y() <<
", " <<inNucleonMom.Z() <<
", " <<inNucleonMom.E();
334 LOG(
"QELEvent",
pINFO) <<
"Done generating QE event kinematics!";
341 LOG(
"QELEvent",
pINFO) <<
"Adding final state nucleus";
349 int A = nucleus->
A();
350 int Z = nucleus->
Z();
355 for(
int id = fd;
id <= ld;
id++)
361 int pdgc = particle->
Pdg();
366 if (is_p || is_n) A--;
368 Px += particle->
Px();
369 Py += particle->
Py();
370 Pz += particle->
Pz();
375 TParticlePDG * remn = 0;
381 <<
"No particle with [A = " << A <<
", Z = " << Z
382 <<
", pdgc = " << ipdgc <<
"] in PDGLibrary!";
386 double Mi = nucleus->
Mass();
394 <<
"Adding nucleus [A = " << A <<
", Z = " << Z
395 <<
", pdgc = " << ipdgc <<
"]";
399 ipdgc,
kIStStableFinalState, imom,-1,-1,-1, Px,Py,Pz,E, 0,0,0,0);
415 Registry r(
"QELEventGeneratorSM_specific",
false ) ;
416 r.
Set(
"sm_utils_algo",
RgAlg(
"genie::SmithMonizUtils",
"Default") ) ;
453 double xsec_max = -1;
458 const double logQ2min = TMath::Log(TMath::Max(rQ2.
min, eps));
459 const double logQ2max = TMath::Log(TMath::Min(rQ2.
max,
fQ2Min));
461 double tmp_xsec_max = -1;
463 for (
int Q2_n=0; Q2_n < N_Q2; Q2_n++)
466 double Q2 = TMath::Exp(Q2_n * (logQ2max-logQ2min)/N_Q2 + logQ2min);
468 const double logvmin = TMath::Log(TMath::Max(rv.
min, eps));
469 const double logvmax = TMath::Log(TMath::Max(rv.
max, TMath::Max(rv.
min, eps)));
470 for (
int v_n=0; v_n < N_v; v_n++)
473 double v = TMath::Exp(v_n * (logvmax-logvmin)/N_v + logvmin);
479 if (xs > tmp_xsec_max)
484 xsec_max = tmp_xsec_max;
494 double xsec_max = -1;
500 const double logQ2min = TMath::Log(
fQ2Min);
501 const double logQ2max = TMath::Log(rQ2.
max);
503 double tmp_xsec_max = -1;
505 for (
int Q2_n=0; Q2_n < N_Q2; Q2_n++)
508 double Q2 = TMath::Exp(Q2_n * (logQ2max-logQ2min)/N_Q2 + logQ2min);
510 const double logvmin = TMath::Log(TMath::Max(rv.
min, eps));
511 const double logvmax = TMath::Log(TMath::Max(rv.
max, TMath::Max(rv.
min, eps)));
512 for (
int v_n=0; v_n < N_v; v_n++)
515 double v = TMath::Exp(v_n * (logvmax-logvmin)/N_v + logvmin);
521 if (xs > tmp_xsec_max)
526 xsec_max = tmp_xsec_max;
537 <<
"Getting max. differential xsec for the rejection method";
539 double xsec_max = -1;
543 <<
"Attempting to find a cached max{dxsec/dK} value";
545 if(xsec_max>0)
return xsec_max;
548 <<
"Attempting to compute the max{dxsec/dK} value";
551 LOG(
"Kinematics",
pINFO) <<
"max{dxsec/dK} = " << xsec_max;
557 <<
"Can not generate event kinematics {K} (max_xsec({K};E)<=0)";
567 exception.
SetReason(
"kinematics generation: max_xsec({K};E)<=0");
581 double E = this->
Energy(interaction);
586 <<
"Below minimum energy - Forcing explicit calculation";
599 <<
"\nInterpolated: max xsec (E=" << E <<
") = " << spl_max_xsec;
603 <<
"Outside spline boundaries - Forcing explicit calculation";
609 double dE = TMath::Min(0.25, 0.05*E);
610 const map<double,double> & fmap = cb->
Map();
612 if(iter != fmap.end()) {
613 if(TMath::Abs(E - iter->first) < dE)
return iter->second;
624 <<
"Adding the computed max{dxsec/dK} value to cache";
627 double E = this->
Energy(interaction);
628 if(max_xsec>0) cb->
AddValues(E,max_xsec);
650 string algkey = this->
Id().
Key();
651 string intkey = interaction->
AsString();
658 LOG(
"Kinematics",
pINFO) <<
"No Max d^nXSec/d{K}^n cache branch found";
659 LOG(
"Kinematics",
pINFO) <<
"Creating cache branch - key = " <<
key;
661 cache_branch =
new CacheBranchFx(
"max[d^nXSec/d^n{K}] over phase space");
664 assert(cache_branch);
671 double max_diffv = -1;
675 for (
int Q2_n = 0; Q2_n<N_Q2; Q2_n++)
677 double Q2 = rQ2.
min + 1.*Q2_n * (rQ2.
max-rQ2.
min)/N_Q2;
679 if (rv.max-rv.min > max_diffv)
680 max_diffv = rv.
max-rv.min;
690 <<
"Getting max. vmax(Q2)-vmin(Q2) for the rejection method";
692 double max_diffv = -1;
696 <<
"Attempting to find a cached max{vmax(Q2)-vmin(Q2)} value";
698 if(max_diffv>0)
return max_diffv;
701 <<
"Attempting to compute the max{vmax(Q2)-vmin(Q2)} value";
704 LOG(
"Kinematics",
pINFO) <<
"max{vmax(Q2)-vmin(Q2)} = " << max_diffv;
710 <<
"Can not generate event kinematics (max{vmax(Q2)-vmin(Q2);E}<=0)";
720 exception.
SetReason(
"kinematics generation: max{vmax(Q2)-vmin(Q2);E}<=0");
733 double E = this->
Energy(interaction);
738 <<
"Below minimum energy - Forcing explicit calculation";
752 <<
"\nInterpolated: max vmax(Q2)-vmin(Q2) (E=" << E <<
") = " << spl_maxdiffv;
756 <<
"Outside spline boundaries - Forcing explicit calculation";
762 double dE = TMath::Min(0.25, 0.05*E);
763 const map<double,double> & fmap = cb->
Map();
765 if(iter != fmap.end())
767 if(TMath::Abs(E - iter->first) < dE)
return iter->second;
777 <<
"Adding the computed max{vmax(Q2)-vmin(Q2)} value to cache";
780 double E = this->
Energy(interaction);
781 if(max_diffv>0) cb->
AddValues(E,max_diffv);
805 string algkey = this->
Id().
Key();
806 string intkey = interaction->
AsString();
814 LOG(
"Kinematics",
pINFO) <<
"No Max vmax(Q2)-vmin(Q2) cache branch found";
815 LOG(
"Kinematics",
pINFO) <<
"Creating cache branch - key = " <<
key;
817 cache_branch =
new CacheBranchFx(
"max[vmax(Q2)-vmin(Q2)] over phase space");
820 assert(cache_branch);
void SetInteraction(const Interaction *i)
Range1D_t Q2QES_SM_lim(void) const
virtual double MaxXSec(GHepRecord *evrec) const
SmithMonizUtils * sm_utils
virtual GHepParticle * Particle(int position) const
virtual void SetWeight(double wght)
double ComputeMaxDiffv(const Interaction *in) const
double fQ2Min
Q2-threshold for seeking the second maximum.
bool fGenerateUniformly
uniform over allowed phase space + event weight?
double J(double q0, double q3, double Enu, double ml)
THE MAIN GENIE PROJECT NAMESPACE
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 fSafetyFactor
maxxsec -> maxxsec * safety_factor
int FirstDaughter(void) const
virtual double XSec(const Interaction *i, KinePhaseSpace_t k=kPSfE) const =0
Compute the cross section for the input interaction.
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
double fMaxXSecDiffTolerance
max{100*(xsec-maxxsec)/.5*(xsec+maxxsec)} if xsec>maxxsec
double MaxDiffv(GHepRecord *evrec) const
Defines the EventGeneratorI interface.
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
void SetMomentum(const TLorentzVector &p4)
double Mass(void) const
Mass that corresponds to the PDG code.
double Evaluate(double x) const
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.
string AsString(void) const
const XSecAlgorithmI * fXSecModel
int FSPrimLeptonPdg(void) const
final state primary lepton pdg
double GetBindingEnergy(void) const
double Px(void) const
Get Px.
void AddCacheBranch(string key, CacheBranchI *branch)
virtual GHepParticle * Probe(void) const
CacheBranchFx * AccessCacheBranchDiffv(const Interaction *in) const
Summary information for an interaction.
void CacheMaxXSec2(const Interaction *in, double xsec) const
void AddValues(double x, double y)
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...
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
double ComputeMaxXSec2(const Interaction *in) const
void Configure(const Registry &config)
string CacheBranchKey(string k0, string k1="", string k2="") const
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)
void ProcessEventRecord(GHepRecord *event_rec) const
bool fGenerateNucleonInNucleus
generate struck nucleon in nucleus
double MaxXSec2(GHepRecord *evrec) const
virtual GHepParticle * TargetNucleus(void) const
void CacheMaxDiffv(const Interaction *in, double xsec) const
TRandom3 & RndKine(void) const
rnd number generator used by kinematics generators
Misc GENIE control constants.
const UInt_t kISkipKinematicChk
if set, skip kinematic validity checks
virtual const XSecAlgorithmI * CrossSectionAlg(void) const =0
CacheBranchI * FindCacheBranch(string key)
finding/adding cache branches
void Setx(double x, bool selected=false)
void SetKV(KineVar_t kv, double value)
void SetRemovalEnergy(double Erm)
static RunningThreadInfo * Instance(void)
virtual const AlgId & Id(void) const
Get algorithm ID.
void SetW(double W, bool selected=false)
void SwitchOnFastForward(void)
TLorentzVector * HitNucP4Ptr(void) const
static PDGLibrary * Instance(void)
const map< double, double > & Map(void) const
Contains auxiliary functions for Smith-Moniz model. .
void SetReason(string reason)
virtual TBits * EventFlags(void) const
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 FindMaxXSec2(const Interaction *in) const
double fEMin
min E for which maxxsec is cached - forcing explicit calc.
virtual double Energy(const Interaction *in) const
int IonPdgCode(int A, int Z)
double FindMaxDiffv(const Interaction *in) const
virtual double XSec(void) const
const InitialState & InitState(void) const
virtual void AddParticle(const GHepParticle &p)
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
virtual int ProbePosition(void) const
static const unsigned int kRjMaxIterations
static Cache * Instance(void)
A simple cache branch storing the cached data in a TNtuple.
const EventGeneratorI * RunningThread(void)
void SetPrimaryLeptonPolarization(GHepRecord *ev)
void Set(RgIMapPair entry)
double ProbeE(RefFrame_t rf) const
GENIE's GHEP MC event record.
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
Root of GENIE utility namespaces.
cet::coded_exception< error, detail::translate > exception
CacheBranchFx * AccessCacheBranch2(const Interaction *in) const
const UInt_t kISkipProcessChk
if set, skip process validity checks
virtual void SetDiffXSec(double xsec, KinePhaseSpace_t ps)
enum genie::EGHepStatus GHepStatus_t
Initial State information.
double Py(void) const
Get Py.
const Algorithm * SubAlg(const RgKey ®istry_key) const