GENIEGenerator
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SPPXSecWithCache.cxx
Go to the documentation of this file.
1 //____________________________________________________________________________
2 /*
3  Copyright (c) 2003-2024, The GENIE Collaboration
4  For the full text of the license visit http://copyright.genie-mc.org
5  or see $GENIE/LICENSE
6 
7  Authors: Igor Kakorin <kakorin@jinr.ru>, Joint Institute for Nuclear Research
8  Vadim Naumov <vnaumov@theor.jinr.ru >, Joint Institute for Nuclear Research \n
9  based on code of Costas Andreopoulos <c.andreopoulos \at cern.ch>
10  University of Liverpool
11 
12  For the class documentation see the corresponding header file.
13 
14 */
15 //____________________________________________________________________________
16 
17 #include <sstream>
18 #include <algorithm>
19 #include <cassert>
20 
21 #include <TMath.h>
22 #include <Math/IFunction.h>
23 #include <Math/IntegratorMultiDim.h>
24 #include <Math/AdaptiveIntegratorMultiDim.h>
25 
28 #include "Framework/Conventions/GBuild.h"
43 #include "Framework/Utils/Cache.h"
46 #include "Framework/Utils/Range1.h"
48 
49 using std::ostringstream;
50 
51 using namespace genie;
52 using namespace genie::controls;
53 using namespace genie::constants;
54 
55 //____________________________________________________________________________
58 {
59 
60 }
61 //____________________________________________________________________________
63  XSecIntegratorI(nm)
64 {
65 
66 }
67 //____________________________________________________________________________
68 SPPXSecWithCache::SPPXSecWithCache(string nm,string conf):
69  XSecIntegratorI(nm,conf)
70 {
71 
72 }
73 //____________________________________________________________________________
75 {
76 
77 }
78 //____________________________________________________________________________
80 {
81  // Cache resonance neutrino production data from free nucleons
82 
83  Cache * cache = Cache::Instance();
84 
86 
87  SppChannel_t spp_channel = SppChannel::FromInteraction(in);
88 
89  // Splines parameters are taken from Splines configuration
91 
92  // Compute the number of spline knots - use at least 10 knots per decade
93  // && at least 40 knots in the full energy range
94  const double Emin = xsl -> Emin() ;
95  const double Emax = std::min( fEMax, xsl -> Emax() ) ; // here we ignore the run configuration
96  // since we know that the splines have a plateau
97  const int nknots = xsl -> NKnots() ;
98 
99  vector<double> E( nknots, 0. ) ;
100 
101  int nu_code = in->InitState().ProbePdg();
102  int nuc_code = in->InitState().Tgt().HitNucPdg();
103  int tgt_code = (nuc_code==kPdgProton) ? kPdgTgtFreeP : kPdgTgtFreeN;
104 
105  Interaction local_interaction(*in);
106  local_interaction.InitStatePtr()->SetPdgs(tgt_code, nu_code);
107  local_interaction.InitStatePtr()->TgtPtr()->SetHitNucPdg(nuc_code);
108 
109  InteractionType_t wkcur = local_interaction.ProcInfo().InteractionTypeId();
110 
111  // Get a unique cache branch name
112  string key = this->CacheBranchName(spp_channel, wkcur, nu_code);
113 
114  // Make sure the cache branch does not already exists
115  CacheBranchFx * cache_branch =
116  dynamic_cast<CacheBranchFx *> (cache->FindCacheBranch(key));
117  assert(!cache_branch);
118 
119  // Create the new cache branch
120  LOG("SPPCache", pNOTICE)
121  << "\n ** Creating cache branch - key = " << key;
122  cache_branch = new CacheBranchFx("ResSPP XSec");
123  cache->AddCacheBranch(key, cache_branch);
124  assert(cache_branch);
125 
126  const KPhaseSpace& kps = in->PhaseSpace();
127 
128  double Ethr = kps.Threshold_SPP_iso();
129  LOG("SPPCache", pNOTICE) << "E threshold = " << Ethr;
130 
131  // Distribute the knots in the energy range as is being done in the
132  // XSecSplineList so that the energy threshold is treated correctly
133  // in the spline - see comments there in.
134  int nkb = (Ethr>Emin) ? 5 : 0; // number of knots < threshold
135  int nka = nknots-nkb; // number of knots >= threshold
136  // knots < energy threshold
137  double dEb = (Ethr>Emin) ? (Ethr - Emin) / nkb : 0;
138  for(int i=0; i<nkb; i++) {
139  E[i] = Emin + i*dEb;
140  }
141  // knots >= energy threshold
142  double E0 = TMath::Max(Ethr,Emin);
143  double dEa = (TMath::Log10(Emax) - TMath::Log10(E0)) /(nka-1);
144  for(int i=0; i<nka; i++) {
145  E[i+nkb] = TMath::Power(10., TMath::Log10(E0) + i*dEa);
146  }
147 
148  // Compute cross sections at the given set of energies
149  for(int ie=0; ie<nknots; ie++) {
150  double xsec = 0.;
151  double Ev = E[ie];
152 
153  TLorentzVector p4(0., 0., Ev, Ev);
154  local_interaction.InitStatePtr()->SetProbeP4(p4);
155 
156  if(Ev>Ethr+kASmallNum) {
157 
158  LOG("SPPCache", pINFO)
159  << "*** Integrating d^3 XSec/dWdQ^2dCosTheta for Ch: "
160  << SppChannel::AsString(spp_channel) << " at Ev = " << Ev;
161 
163  ROOT::Math::IntegrationMultiDim::Type ig_type = utils::gsl::IntegrationNDimTypeFromString(fGSLIntgType);
164  ROOT::Math::IntegratorMultiDim ig(ig_type,0,fGSLRelTol,fGSLMaxEval);
165  if (ig_type == ROOT::Math::IntegrationMultiDim::kADAPTIVE)
166  {
167  ROOT::Math::AdaptiveIntegratorMultiDim * cast = dynamic_cast<ROOT::Math::AdaptiveIntegratorMultiDim*>( ig.GetIntegrator() );
168  assert(cast);
169  cast->SetMinPts(fGSLMinEval);
170  }
171  ig.SetFunction(func);
172  double kine_min[3] = { 0., 0., 0.};
173  double kine_max[3] = { 1., 1., 1.};
174  xsec = ig.Integral(kine_min, kine_max)*(1E-38 * units::cm2);;
175  }
176  else
177  LOG("SPPCache", pINFO) << "** Below threshold E = " << Ev << " <= " << Ethr;
178 
179  cache_branch->AddValues(Ev,xsec);
180 
181 
182  string nc_nuc = ((pdg::IsNeutrino(nu_code)) ? ";v:" : ";vb:");
183 
184 
185  SLOG("SPPCache", pNOTICE)
186  << "SPP XSec (Ch:" << SppChannel::AsString(spp_channel) << nc_nuc << nu_code
187  << ", E="<< Ev << ") = "<< xsec << " x 1E-38 cm^2";
188  }//spline knots
189 
190  // Build the spline
191  cache_branch->CreateSpline();
192 
193 }
194 //____________________________________________________________________________
196  SppChannel_t spp_channel, InteractionType_t it, int nupdgc) const
197 {
198  // Build a unique name for the cache branch
199 
200  Cache * cache = Cache::Instance();
201  string spp_channel_name = SppChannel::AsString(spp_channel);
202  string it_name = InteractionType::AsString(it);
203  string nc_nuc = ((pdg::IsNeutrino(nupdgc)) ? ";v:" : ";vb:");
204 
205  ostringstream intk;
206  intk << "ResSPPXSec/Ch:" << spp_channel_name << nc_nuc << nupdgc
207  << ";int:" << it_name;
208 
209  string algkey = fSinglePionProductionXSecModel->Id().Key();
210  string ikey = intk.str();
211  string key = cache->CacheBranchKey(algkey, ikey);
212 
213  return key;
214 }
215 //____________________________________________________________________________
216 // GSL wrappers
217 //____________________________________________________________________________
219  const XSecAlgorithmI * m, const Interaction * interaction, double wcut) :
220  ROOT::Math::IBaseFunctionMultiDim(),
221  fModel(m),
222  fWcut(wcut)
223 {
224 
225  isZero = false;
226  fInteraction = const_cast<Interaction*>(interaction);
229 
231 
232  // Get kinematical parameters
233  const InitialState & init_state = interaction -> InitState();
234  double Enu = init_state.ProbeE(kRfHitNucRest);
235 
236 
237  if (Enu < kps->Threshold_SPP_iso())
238  {
239  isZero = true;
240  return;
241  }
242 
243  Wl = kps->WLim_SPP_iso();
244  if (fWcut >= Wl.min)
245  Wl.max = TMath::Min(fWcut,Wl.max);
246 
247 
248 }
250 {
251 
252 }
254 {
255  return 3;
256 }
258 {
259  // outputs:
260  // differential cross section [1/GeV^3] for Resonance single pion production production
261  //
262 
263  if (isZero) return 0.;
264 
265  double W2 = Wl.min*Wl.min + (Wl.max*Wl.max - Wl.min*Wl.min)*xin[0];
266  fInteraction->KinePtr()->SetW(TMath::Sqrt(W2));
267 
268  Range1D_t Q2l = kps->Q2Lim_W_SPP_iso();
269 
270  double sqrt_Q2 = TMath::Sqrt(Q2l.min) + ( TMath::Sqrt(Q2l.max) - TMath::Sqrt(Q2l.min) )*xin[1];
271  fInteraction->KinePtr()->SetQ2(sqrt_Q2*sqrt_Q2);
272 
273  fInteraction->KinePtr()->SetKV(kKVctp, -1. + 2.*xin[2]); //CosTheta
274 
275  double xsec = fModel->XSec(fInteraction, kPSWQ2ctpfE)*sqrt_Q2*(Wl.max*Wl.max - Wl.min*Wl.min)*(TMath::Sqrt(Q2l.max) - TMath::Sqrt(Q2l.min))*2/TMath::Sqrt(W2);
276  return xsec/(1E-38 * units::cm2);
277 }
278 ROOT::Math::IBaseFunctionMultiDim *
280 {
281  return
282  new genie::utils::gsl::d3XSecMK_dWQ2CosTheta_E(fModel,fInteraction,fWcut);
283 }
double DoEval(const double *xin) const
Cross Section Calculation Interface.
static SppChannel_t FromInteraction(const Interaction *interaction)
Definition: SppChannel.h:402
const KPhaseSpace & PhaseSpace(void) const
Definition: Interaction.h:73
InteractionType_t InteractionTypeId(void) const
string fGSLIntgType
name of GSL numerical integrator
bool IsNeutrino(int pdgc)
Definition: PDGUtils.cxx:110
void SetProbeP4(const TLorentzVector &P4)
Cross Section Integrator Interface.
ROOT::Math::IntegrationMultiDim::Type IntegrationNDimTypeFromString(string type)
Definition: GSLUtils.cxx:59
int HitNucPdg(void) const
Definition: Target.cxx:304
A simple [min,max] interval for doubles.
Definition: Range1.h:42
void CreateSpline(string type="TSpline3")
double Threshold_SPP_iso(void) const
Energy limit for resonance single pion production on isoscalar nucleon.
static XSecSplineList * Instance()
void AddCacheBranch(string key, CacheBranchI *branch)
Definition: Cache.cxx:88
enum genie::ESppChannel SppChannel_t
KPhaseSpace * PhaseSpacePtr(void) const
Definition: Interaction.h:78
static string AsString(SppChannel_t channel)
Definition: SppChannel.h:76
Summary information for an interaction.
Definition: Interaction.h:56
void AddValues(double x, double y)
string CacheBranchName(SppChannel_t spp_channel, InteractionType_t it, int nu) const
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:96
static constexpr double cm2
Definition: Units.h:69
ROOT::Math::IBaseFunctionMultiDim * Clone(void) const
string CacheBranchKey(string k0, string k1="", string k2="") const
Definition: Cache.cxx:93
int ProbePdg(void) const
Definition: InitialState.h:64
Kinematical phase space.
Definition: KPhaseSpace.h:33
const int kPdgTgtFreeN
Definition: PDGCodes.h:200
const int kPdgTgtFreeP
Definition: PDGCodes.h:199
const XSecAlgorithmI * fSinglePionProductionXSecModel
double func(double x, double y)
void SetPdgs(int tgt_pdgc, int probe_pdgc)
static const double kASmallNum
Definition: Controls.h:40
#define pINFO
Definition: Messenger.h:62
const UInt_t kISkipKinematicChk
if set, skip kinematic validity checks
Definition: Interaction.h:48
CacheBranchI * FindCacheBranch(string key)
finding/adding cache branches
Definition: Cache.cxx:80
d3XSecMK_dWQ2CosTheta_E(const XSecAlgorithmI *m, const Interaction *i, double wcut)
static string AsString(InteractionType_t type)
GENIE Cache Memory.
Definition: Cache.h:38
virtual const AlgId & Id(void) const
Get algorithm ID.
Definition: Algorithm.h:98
double max
Definition: Range1.h:53
int fGSLMaxEval
GSL max evaluations.
void CacheResExcitationXSec(const Interaction *interaction) const
void SetHitNucPdg(int pdgc)
Definition: Target.cxx:171
Target * TgtPtr(void) const
Definition: InitialState.h:67
Range1D_t WLim_SPP_iso(void) const
W limits for resonance single pion production on isoscalar nucleon.
InitialState * InitStatePtr(void) const
Definition: Interaction.h:74
const InitialState & InitState(void) const
Definition: Interaction.h:69
const ProcessInfo & ProcInfo(void) const
Definition: Interaction.h:70
double min
Definition: Range1.h:52
const int kPdgProton
Definition: PDGCodes.h:81
#define pNOTICE
Definition: Messenger.h:61
const Target & Tgt(void) const
Definition: InitialState.h:66
static Cache * Instance(void)
Definition: Cache.cxx:67
A simple cache branch storing the cached data in a TNtuple.
Definition: CacheBranchFx.h:49
#define SLOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a short string (using the FUNCTION and...
Definition: Messenger.h:84
List of cross section vs energy splines.
double ProbeE(RefFrame_t rf) const
static constexpr double m
Definition: Units.h:71
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
enum genie::EInteractionType InteractionType_t
int fGSLMinEval
GSL min evaluations. Ignored by some integrators.
string Key(void) const
Definition: AlgId.h:46
const UInt_t kISkipProcessChk
if set, skip process validity checks
Definition: Interaction.h:47
Initial State information.
Definition: InitialState.h:48
double fGSLRelTol
required relative tolerance (error)