16#include <Math/Factory.h>
17#include <Math/Minimizer.h>
23#include "Framework/Conventions/GBuild.h"
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();
187 double W = Wl.
min + (Wl.
max - Wl.
min)*xin[0];
189 double Q2 = Q2l.
min + (Q2l.
max - Q2l.
min)*xin[1];
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);
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();
471ROOT::Math::IBaseFunctionMultiDim(),
fModel(m),
fWcut(wcut)
483 const InitialState & init_state = interaction -> InitState();
487 if (Enu < kps->Threshold_SPP_iso())
493 Wl =
kps->WLim_SPP_iso();
514 double W =
Wl.min + (
Wl.max -
Wl.min)*xin[0];
518 double Q2 = Q2l.
min + (Q2l.
max - Q2l.
min)*xin[1];
529ROOT::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.
virtual void Configure(const Registry &config)
bool GetParamDef(const RgKey &name, T &p, const T &def) const
Defines the EventGeneratorI interface.
virtual const XSecAlgorithmI * CrossSectionAlg(void) const =0
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 Interaction * Summary(void) const
virtual TBits * EventFlags(void) const
virtual void AddParticle(const GHepParticle &p)
virtual void SetWeight(double wght)
virtual int HitNucleonPosition(void) const
virtual GHepParticle * HitNucleon(void) const
Initial State information.
TLorentzVector * GetProbeP4(RefFrame_t rf=kRfHitNucRest) const
double ProbeE(RefFrame_t rf) const
Summary information for an interaction.
const XclsTag & ExclTag(void) const
int FSPrimLeptonPdg(void) const
final state primary lepton pdg
KPhaseSpace * PhaseSpacePtr(void) const
TParticlePDG * FSPrimLepton(void) const
final state primary lepton
const KPhaseSpace & PhaseSpace(void) const
Kinematics * KinePtr(void) const
Range1D_t WLim_SPP_iso(void) const
W limits for resonance single pion production on isoscalar nucleon.
Range1D_t Q2Lim_W_SPP_iso(void) const
Q2 limits @ fixed W for resonance single pion production on isoscalar nucleon.
virtual void AssertXSecLimits(const Interaction *in, double xsec, double xsec_max) const
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.
double fSafetyFactor
ComputeMaxXSec -> ComputeMaxXSec * fSafetyFactor.
virtual double MaxXSec(GHepRecord *evrec, const int nkey=0) const
const XSecAlgorithmI * fXSecModel
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)
Singleton class to load & serve a TDatabasePDG.
static PDGLibrary * Instance(void)
TParticlePDG * Find(int pdgc, bool must_exist=true)
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
A simple [min,max] interval for doubles.
A registry. Provides the container for algorithm configuration parameters.
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)
void ProcessEventRecord(GHepRecord *event_rec) const
void Configure(const Registry &config)
int GetFinalPionPdgCode(Interaction *interaction) const
int GetRecoilNucleonPdgCode(Interaction *interaction) const
double ComputeMaxXSec(const Interaction *interaction) const
int fMaxDepth
Maximum depth of dividing parent cell.
A Neutrino Interaction Target. Is a transparent encapsulation of quite different physical systems suc...
void SetHitNucP4(const TLorentzVector &p4)
bool IsNucleus(void) const
Cross Section Calculation Interface.
Contains minimal information for tagging exclusive processes.
An exception thrown by EventRecordVisitorI when the normal processing sequence has to be disrupted (f...
void SwitchOnFastForward(void)
void SetReason(string reason)
double DoEval(const double *xin) const
Interaction * fInteraction
d4XSecMK_dWQ2CosThetaPhi_E(const XSecAlgorithmI *m, const Interaction *i, double wcut)
ROOT::Math::IBaseFunctionMultiDim * Clone(void) const
const XSecAlgorithmI * fModel
unsigned int NDim(void) const
~d4XSecMK_dWQ2CosThetaPhi_E()
Misc GENIE control constants.
static const unsigned int kRjMaxIterations
static constexpr double cm2
Simple functions for loading and reading nucleus dependent keys from config files.
void WQ2toXY(double Ev, double M, double W, double Q2, double &x, double &y)
Baryon Resonance utilities.
Resonance_t FromString(const char *res)
string -> resonance id
double Width(Resonance_t res)
resonance width (GeV)
double Mass(Resonance_t res)
resonance mass (GeV)
Root of GENIE utility namespaces.
THE MAIN GENIE PROJECT NAMESPACE
enum genie::EResonance Resonance_t
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