16 #include <Math/Factory.h>
17 #include <Math/Minimizer.h>
23 #include "Framework/Conventions/GBuild.h"
41 using namespace genie;
42 using namespace genie::controls;
43 using namespace genie::utils;
44 using namespace genie::constants;
68 LOG(
"SPPEventGen",
pINFO) <<
"Generating resonance single pion production event kinematics...";
72 <<
"Generating kinematics uniformly over the allowed phase space";
77 const InitialState & init_state = interaction -> InitState();
82 Target * tgt = interaction -> InitStatePtr()->TgtPtr();
88 double mpi2 = mpi*mpi;
98 TLorentzVector p1(*(evrec->
HitNucleon())->P4());
99 TLorentzVector p1_copy(p1);
101 p1.SetE(TMath::Sqrt(p1.P()*p1.P() + M*M));
105 TLorentzVector k1_HNRF = k1;
106 k1_HNRF.Boost(-p1.BoostVector());
108 double Ev = k1_HNRF.E();
110 TLorentzVector p1_HNRF(0,0,0,M);
134 unsigned int iter = 0;
141 <<
"*** Could not select a valid kinematics variable after "
142 << iter <<
" iterations";
145 exception.
SetReason(
"Couldn't select kinematics");
150 xin[0] = rnd->
RndKine().Rndm();
151 xin[1] = rnd->
RndKine().Rndm();
152 xin[2] = rnd->
RndKine().Rndm();
153 xin[3] = rnd->
RndKine().Rndm();
163 double t = xsec_max * rnd->
RndKine().Rndm();
190 double CosTheta_isb = -1. + 2.*xin[2];
191 double SinTheta_isb = (1 - CosTheta_isb*CosTheta_isb)<0?0:TMath::Sqrt(1 - CosTheta_isb*CosTheta_isb);
192 double Phi_isb = 2*
kPi*xin[3];
202 double totxsec = evrec->
XSec();
203 double wght = (vol/totxsec)*xsec;
222 double Enu_isb = (Ev*M - (ml2 +
Q2)/2)/
W;
223 double El_isb = (Ev*M - (ml2 + W2 - M2)/2)/
W;
224 double v_isb = (W2 - M2 -
Q2)/2/W;
225 double q_isb = TMath::Sqrt(v_isb*v_isb + Q2);
226 double kz1_isb = 0.5*(q_isb+(Enu_isb*Enu_isb - El_isb*El_isb + ml2)/q_isb);
227 double kz2_isb = kz1_isb - q_isb;
228 double kx1_isb = (Enu_isb*Enu_isb - kz1_isb*kz1_isb)<0?0:TMath::Sqrt(Enu_isb*Enu_isb - kz1_isb*kz1_isb);
229 double Epi_isb = (W2 + mpi2 - M2)/W/2;
230 double ppi_isb = (Epi_isb - mpi)<0?0:TMath::Sqrt(Epi_isb*Epi_isb - mpi2);
231 double E1_isb = (W2 + Q2 + M2)/2/W;
232 double E2_isb = W - Epi_isb;
235 TLorentzVector k1_isb(kx1_isb, 0, kz1_isb, Enu_isb);
236 TLorentzVector k2_isb(kx1_isb, 0, kz2_isb, El_isb);
237 TLorentzVector p1_isb(0, 0, -q_isb, E1_isb);
238 TLorentzVector p2_isb(-ppi_isb*SinTheta_isb*TMath::Cos(Phi_isb), -ppi_isb*SinTheta_isb*TMath::Sin(Phi_isb), -ppi_isb*CosTheta_isb, E2_isb);
239 TLorentzVector pi_isb( ppi_isb*SinTheta_isb*TMath::Cos(Phi_isb), ppi_isb*SinTheta_isb*TMath::Sin(Phi_isb), ppi_isb*CosTheta_isb, Epi_isb);
243 TVector3 boost = -p1_isb.BoostVector();
251 TVector3 rot_vect = k1_isb.Vect().Cross(k1_HNRF.Vect());
252 double rot_angle = k1_isb.Vect().Angle(k1_HNRF.Vect());
253 k2_isb.Rotate(rot_angle, rot_vect);
254 p2_isb.Rotate(rot_angle, rot_vect);
255 pi_isb.Rotate(rot_angle, rot_vect);
258 boost = p1.BoostVector();
266 TLorentzVector x4l(*(evrec->
Probe())->X4());
346 ROOT::Math::Minimizer * min = ROOT::Math::Factory::CreateMinimizer(
"Minuit",
"Minimize");
348 min->SetFunction( *f );
349 min->SetMaxFunctionCalls(10000);
350 min->SetMaxIterations(10000);
351 min->SetTolerance(1
e-3);
352 min->SetPrintLevel(0);
353 double min_xsec = 0.;
357 int total_cells = (TMath::Power(16,
fMaxDepth) - 1)/15;
358 vector<Cell> cells(total_cells);
360 for (
int dep = 0; dep <
fMaxDepth; dep++)
362 int aux = TMath::Power(16, dep) - 1;
363 for (
int cell = aux/15; cell <= 16*aux/15 ; cell++)
367 cells[cell].Vertex1 =
Vertex(0., 0., 0., 0.);
368 cells[cell].Vertex2 =
Vertex(1., 1., 1., 1.);
370 double x1m = (cells[cell].Vertex1.x1 + cells[cell].Vertex2.x1)/2;
371 double x2m = (cells[cell].Vertex1.x2 + cells[cell].Vertex2.x2)/2;
372 double x3m = (cells[cell].Vertex1.x3 + cells[cell].Vertex2.x3)/2;
373 double x4m = (cells[cell].Vertex1.x4 + cells[cell].Vertex2.x4)/2;
374 min->SetVariable(0,
"x1", x1m, step);
375 min->SetVariable(1,
"x2", x2m, step);
376 min->SetVariable(2,
"x3", x3m, step);
377 min->SetVariable(3,
"x4", x4m, step);
378 min->SetVariableLimits(0, cells[cell].Vertex1.x1, cells[cell].Vertex2.x1);
379 min->SetVariableLimits(1, cells[cell].Vertex1.x2, cells[cell].Vertex2.x2);
380 min->SetVariableLimits(2, cells[cell].Vertex1.x3, cells[cell].Vertex2.x3);
381 min->SetVariableLimits(3, cells[cell].Vertex1.x4, cells[cell].Vertex2.x4);
383 xsec = min->MinValue();
386 const double *xs = min->X();
387 Vertex minv(xs[0], xs[1], xs[2], xs[3]);
388 if (minv == cells[cell].Vertex1 || minv == cells[cell].Vertex2)
389 minv =
Vertex (x1m, x2m, x3m, x4m);
390 if (dep < fMaxDepth - 1)
391 for (
int i = 0; i < 16; i++)
393 int child = 16*cell + i + 1;
394 cells[child].Vertex1 = minv;
395 cells[child].Vertex2 =
Vertex ((i>>0)%2?cells[cell].Vertex1.x1:cells[cell].Vertex2.x1,
396 (i>>1)%2?cells[cell].Vertex1.x2:cells[cell].Vertex2.x2,
397 (i>>2)%2?cells[cell].Vertex1.x3:cells[cell].Vertex2.x3,
398 (i>>3)%2?cells[cell].Vertex1.x4:cells[cell].Vertex2.x4);
403 const InitialState & init_state = interaction -> InitState();
413 double dW = Wl.
max - Wl.
min;
416 double x1 = (MR - Wl.
min)/dW;
417 double x1min = (MR - WR - Wl.
min)/dW;
423 x1min = x1min<0?0:x1min;
424 double x1max = (MR + WR - Wl.
min)/dW;
430 x1max = x1max>1?1:x1max;
431 if (x1 < x1min || x1 > x1max) x1=0.5*(x1min + x1max);
432 for (
int i3 = 0; i3 < N3; i3++)
435 double x3min = .5*i3;
436 double x3max = .5*(i3 + 1);
437 for (
int i4 = 0; i4 <= N4; i4++)
439 double x4 = 1.*i4/N4;
440 double x4min = 1.*i4/N4;
441 double x4max = 1.*(i4 + 1)/N4;
447 min->SetVariable(0,
"x1", x1, step);
448 min->SetVariable(1,
"x2", 1./6, step);
449 min->SetVariable(2,
"x3", x3, step);
450 min->SetVariable(3,
"x4", x4, step);
451 min->SetVariableLimits(0, x1min, x1max);
452 min->SetVariableLimits(1, 0, x2max);
453 min->SetVariableLimits(2, x3min, x3max);
454 min->SetVariableLimits(3, x4min, x4max);
456 xsec = min->MinValue();
471 ROOT::Math::IBaseFunctionMultiDim(), fModel(m), fWcut(wcut)
483 const InitialState & init_state = interaction -> InitState();
487 if (Enu < kps->Threshold_SPP_iso())
512 if (isZero)
return 0.;
514 double W = Wl.min + (Wl.max - Wl.min)*xin[0];
515 fInteraction->KinePtr()->SetW(W);
519 fInteraction->KinePtr()->SetQ2(Q2);
521 fInteraction->KinePtr()->SetKV(
kKVctp, -1. + 2.*xin[2]);
523 fInteraction->KinePtr()->SetKV(
kKVphip , 2.*
kPi*xin[3]);
526 xsec *= 4*
kPi*(Wl.max - Wl.min)*(Q2l.
max - Q2l.
min);
529 ROOT::Math::IBaseFunctionMultiDim *
Cross Section Calculation Interface.
Interaction * fInteraction
Resonance_t FromString(const char *res)
string -> resonance id
const KPhaseSpace & PhaseSpace(void) const
virtual void SetWeight(double wght)
bool fGenerateUniformly
uniform over allowed phase space + event weight?
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
int GetRecoilNucleonPdgCode(Interaction *interaction) const
double fSafetyFactor
ComputeMaxXSec -> ComputeMaxXSec * fSafetyFactor.
A simple [min,max] interval for doubles.
virtual void AssertXSecLimits(const Interaction *in, double xsec, double xsec_max) const
bool IsNucleus(void) const
~d4XSecMK_dWQ2CosThetaPhi_E()
double fMaxXSecDiffTolerance
max{100*(xsec-maxxsec)/.5*(xsec+maxxsec)} if xsec>maxxsec
Defines the EventGeneratorI interface.
virtual double MaxXSec(GHepRecord *evrec, const int nkey=0) const
void SetHitNucP4(const TLorentzVector &p4)
virtual int HitNucleonPosition(void) const
virtual double Weight(void) const
double Mass(Resonance_t res)
resonance mass (GeV)
double Width(Resonance_t res)
resonance width (GeV)
Abstract class. Provides a data caching mechanism for for concrete implementations of the EventRecord...
enum genie::EResonance Resonance_t
A singleton holding random number generator classes. All random number generation in GENIE should tak...
const XSecAlgorithmI * fXSecModel
void ProcessEventRecord(GHepRecord *event_rec) const
Contains minimal information for tagging exclusive processes.
int FSPrimLeptonPdg(void) const
final state primary lepton pdg
KPhaseSpace * PhaseSpacePtr(void) const
virtual GHepParticle * Probe(void) const
double W(const Interaction *const i)
ROOT::Math::IBaseFunctionMultiDim * Clone(void) const
Summary information for an interaction.
Range1D_t Q2Lim_W_SPP_iso(void) const
Q2 limits @ fixed W for resonance single pion production on isoscalar nucleon.
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...
static constexpr double cm2
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)
unsigned int NDim(void) const
TRandom3 & RndKine(void) const
rnd number generator used by kinematics generators
const UInt_t kISkipKinematicChk
if set, skip kinematic validity checks
TParticlePDG * FSPrimLepton(void) const
final state primary lepton
void Setx(double x, bool selected=false)
static RunningThreadInfo * Instance(void)
void SetW(double W, bool selected=false)
void SwitchOnFastForward(void)
static PDGLibrary * Instance(void)
double DoEval(const double *xin) const
void SetReason(string reason)
virtual TBits * EventFlags(void) const
Singleton class to load & serve a TDatabasePDG.
void Configure(const Registry &config)
A registry. Provides the container for algorithm configuration parameters.
void Sety(double y, bool selected=false)
const XclsTag & ExclTag(void) const
virtual GHepParticle * HitNucleon(void) const
double fEMin
min E for which maxxsec is cached - forcing explicit calc.
virtual const XSecAlgorithmI * CrossSectionAlg(void) const =0
Range1D_t WLim_SPP_iso(void) const
W limits for resonance single pion production on isoscalar nucleon.
virtual double XSec(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
virtual int ProbePosition(void) const
d4XSecMK_dWQ2CosThetaPhi_E(const XSecAlgorithmI *m, const Interaction *i, double wcut)
static const unsigned int kRjMaxIterations
int fMaxDepth
Maximum depth of dividing parent cell.
const EventGeneratorI * RunningThread(void)
int GetFinalPionPdgCode(Interaction *interaction) const
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...
Keep info on the event generation thread currently on charge. This is used so that event generation m...
TLorentzVector * GetProbeP4(RefFrame_t rf=kRfHitNucRest) const
const UInt_t kISkipProcessChk
if set, skip process validity checks
double ComputeMaxXSec(const Interaction *interaction) const
virtual void SetDiffXSec(double xsec, KinePhaseSpace_t ps)
enum genie::EGHepStatus GHepStatus_t
Initial State information.