GENIEGenerator
Loading...
Searching...
No Matches
HELeptonKinematicsGenerator.cxx
Go to the documentation of this file.
1//____________________________________________________________________________
2/*
3 Copyright (c) 2003-2025, The GENIE Collaboration
4 For the full text of the license visit http://copyright.genie-mc.org
5
6 Alfonso Garcia <aagarciasoto \at km3net.de>
7 IFIC & Harvard University
8*/
9//____________________________________________________________________________
10
25
26#include "Math/Minimizer.h"
27#include "Math/Factory.h"
28
29using namespace genie;
30using namespace genie::controls;
31using namespace genie::utils;
32
33//___________________________________________________________________________
35KineGeneratorWithCache("genie::HELeptonKinematicsGenerator")
36{
37
38}
39//___________________________________________________________________________
41KineGeneratorWithCache("genie::HELeptonKinematicsGenerator", config)
42{
43
44}
45//___________________________________________________________________________
50//___________________________________________________________________________
52{
54 LOG("HELeptonKinematics", pNOTICE)
55 << "Generating kinematics uniformly over the allowed phase space";
56 }
57
58 //-- Get the random number generators
60
61 //-- Access cross section algorithm for running thread
63 const EventGeneratorI * evg = rtinfo->RunningThread();
65
66 Interaction * interaction = evrec->Summary();
67
68 //-- For the subsequent kinematic selection with the rejection method:
69 // Calculate the max differential cross section or retrieve it from the
70 // cache. Throw an exception and quit the evg thread if a non-positive
71 // value is found.
72 // If the kinematics are generated uniformly over the allowed phase
73 // space the max xsec is irrelevant
74 double xsec_max = this->MaxXSec(evrec);
75
76 const ProcessInfo & proc_info = interaction->ProcInfo();
77 if(proc_info.IsPhotonCoherent()) {
78
79 double nupdg = interaction->InitState().ProbePdg();
80
81 double n2min = 0.;
82 double n2max = 1.;
83 double n3min = 0.;
84 double n3max = 1.;
85 double dn2 = n2max-n2min;
86 double dn3 = n3max-n3min;
87
88 double n1max = 0.;
89 double n1min = 0.;
90 if (pdg::IsNuE (TMath::Abs(nupdg))) { n1min = 1.-fDeltaN1NuE; n1max = 1.+fDeltaN1NuE; }
91 else if (pdg::IsNuMu (TMath::Abs(nupdg))) { n1min = 1.-fDeltaN1NuMu; n1max = 1.+fDeltaN1NuMu; }
92 else if (pdg::IsNuTau(TMath::Abs(nupdg))) { n1min = 1.-fDeltaN1NuTau; n1max = 1.+fDeltaN1NuTau; }
93 double dn1 = n1max-n1min;
94
95
96 //-- Try to select a valid inelastisity y
97 double xsec = -1;
98 unsigned int iter = 0;
99 bool accept = false;
100
101 while(1) {
102 iter++;
103 if(iter > 1000000) {
104 LOG("HELeptonKinematics", pWARN)
105 << "*** Could not select a valid y after "
106 << iter << " iterations";
107 evrec->EventFlags()->SetBitNumber(kKineGenErr, true);
109 exception.SetReason("Couldn't select kinematics");
110 exception.SwitchOnFastForward();
111 throw exception;
112 }
113
114 double n2 = n2min + dn2 * rnd->RndKine().Rndm();
115 double n3 = n3min + dn3 * rnd->RndKine().Rndm();
116 double n1 = n1min + dn1 * rnd->RndKine().Rndm();
117 n1 = (n1>1.) ? n1-2. : n1;
118
119 interaction->KinePtr()->SetKV(kKVn1,n1);
120 interaction->KinePtr()->SetKV(kKVn2,n2);
121 interaction->KinePtr()->SetKV(kKVn3,n3);
122
123 LOG("HELeptonKinematics", pDEBUG) << "Trying: n1 = " << n1 << ", n2 = " << n2 << ", n3 = " << n3;
124
125 //-- computing cross section for the current kinematics
126 xsec = fXSecModel->XSec(interaction, kPSn1n2n3fE);
127
128 this->AssertXSecLimits(interaction, xsec, xsec_max);
129
130 double t = xsec_max * rnd->RndKine().Rndm();
131 LOG("HELeptonKinematics", pDEBUG) << "xsec= "<< xsec<< ", J= 1, Rnd= "<< t;
132
133 accept = (t<xsec);
134
135 //-- If the generated kinematics are accepted, finish-up module's job
136 if(accept) {
137 LOG("HELeptonKinematics", pINFO) << "Selected: n1 = " << n1 << ", n2 = " << n2 << ", n3 = " << n3;
138
139 // set the cross section for the selected kinematics
140 evrec->SetDiffXSec(xsec,kPSn1n2n3fE);
141
142 // lock selected kinematics & clear running values
143 interaction->KinePtr()->ClearRunningValues();
144
145 return;
146 }
147 }// iterations
148
149 }
150 else {
151 double n1min = -1.;
152 double n1max = 1.;
153 double n2min = 0.;
154 double n2max = 1.;
155 double dn1 = n1max-n1min;
156 double dn2 = n2max-n2min;
157
158 //-- Try to select a valid inelastisity y
159 double xsec = -1;
160 unsigned int iter = 0;
161 bool accept = false;
162
163 while(1) {
164 iter++;
165 if(iter > 1000000) {
166 LOG("HELeptonKinematics", pWARN)
167 << "*** Could not select a valid y after "
168 << iter << " iterations";
169 evrec->EventFlags()->SetBitNumber(kKineGenErr, true);
171 exception.SetReason("Couldn't select kinematics");
172 exception.SwitchOnFastForward();
173 throw exception;
174 }
175
176 double n1 = n1min + dn1 * rnd->RndKine().Rndm();
177 double n2 = n2min + dn2 * rnd->RndKine().Rndm();
178 interaction->KinePtr()->SetKV(kKVn1,n1);
179 interaction->KinePtr()->SetKV(kKVn2,n2);
180
181 LOG("HELeptonKinematics", pDEBUG) << "Trying: n1 = " << n1 << ", n2 = " << n2;
182
183 //-- computing cross section for the current kinematics
184 xsec = fXSecModel->XSec(interaction, kPSn1n2fE);
185
186 this->AssertXSecLimits(interaction, xsec, xsec_max);
187
188 double t = xsec_max * rnd->RndKine().Rndm();
189 LOG("HELeptonKinematics", pDEBUG) << "xsec= "<< xsec<< ", J= 1, Rnd= "<< t;
190
191 accept = (t<xsec);
192
193 //-- If the generated kinematics are accepted, finish-up module's job
194 if(accept) {
195 LOG("HELeptonKinematics", pINFO) << "Selected: n1 = " << n1 << ", n2 = " << n2;
196
197 // set the cross section for the selected kinematics
198 evrec->SetDiffXSec(xsec,kPSn1n2fE);
199
200 // lock selected kinematics & clear running values
201 interaction->KinePtr()->ClearRunningValues();
202
203 return;
204 }
205 }// iterations
206
207 }
208}
209//___________________________________________________________________________
211 const Interaction * interaction) const
212{
213// Computes the maximum differential cross section in the requested phase
214// space. This method overloads KineGeneratorWithCache::ComputeMaxXSec
215// method and the value is cached at a circular cache branch for retrieval
216// during subsequent event generation.
217// The computed max differential cross section does not need to be the exact
218// maximum. The number used in the rejection method will be scaled up by a
219// safety factor. But it needs to be fast - do not use a very small y step.
220
221 double max_xsec = -1.0;
222
223 ROOT::Math::Minimizer * min = ROOT::Math::Factory::CreateMinimizer("Minuit");
224
225 const ProcessInfo & proc_info = interaction->ProcInfo();
226 if(proc_info.IsPhotonCoherent()) {
227
229 min->SetFunction( f );
230 min->SetMaxFunctionCalls(10000);
231 min->SetTolerance(0.05);
232
233 min->SetFixedVariable ( 0, "n1", 1.);
234 min->SetLimitedVariable ( 1, "n2", 0., 0.01, 0., 1.);
235 min->SetLimitedVariable ( 2, "n3", 0., 0.01, 0., 1.);
236 min->Minimize();
237 min->SetFixedVariable ( 0, "n1", 1.);
238 min->SetLimitedVariable ( 1, "n2", min->X()[1], 0.01, TMath::Max(0.,min->X()[1]-0.1), TMath::Min(1.,min->X()[1]+0.1));
239 min->SetLimitedVariable ( 2, "n3", min->X()[2], 0.01, TMath::Max(0.,min->X()[2]-0.1), TMath::Min(1.,min->X()[2]+0.1));
240 min->Minimize();
241 interaction->KinePtr()->SetKV(kKVn1,min->X()[0]);
242 interaction->KinePtr()->SetKV(kKVn2,min->X()[1]);
243 interaction->KinePtr()->SetKV(kKVn3,min->X()[2]);
244 SLOG("HELeptonKinematics", pDEBUG) << "Minimum found -> n1: 1, n2: " << min->X()[1] << ", n3: " << min->X()[2] << ", xsec: " << fXSecModel->XSec(interaction, kPSn1n2n3fE);
245 max_xsec = TMath::Max(fXSecModel->XSec(interaction, kPSn1n2n3fE),max_xsec);
246
247 min->SetFixedVariable ( 0, "n1", -1.);
248 min->SetLimitedVariable ( 1, "n2", 0., 0.01, 0., 1.);
249 min->SetLimitedVariable ( 2, "n3", 0., 0.01, 0., 1.);
250 min->Minimize();
251 min->SetFixedVariable ( 0, "n1", -1.);
252 min->SetLimitedVariable ( 1, "n2", min->X()[1], 0.01, TMath::Max(0.,min->X()[1]-0.1), TMath::Min(1.,min->X()[1]+0.1));
253 min->SetLimitedVariable ( 2, "n3", min->X()[2], 0.01, TMath::Max(0.,min->X()[2]-0.1), TMath::Min(1.,min->X()[2]+0.1));
254 interaction->KinePtr()->SetKV(kKVn1,min->X()[0]);
255 interaction->KinePtr()->SetKV(kKVn2,min->X()[1]);
256 interaction->KinePtr()->SetKV(kKVn3,min->X()[2]);
257 SLOG("HELeptonKinematics", pDEBUG) << "Minimum found -> n1: -1, n2: " << min->X()[1] << ", n3: " << min->X()[2] << ", xsec: " << fXSecModel->XSec(interaction, kPSn1n2n3fE);
258 max_xsec = TMath::Max(fXSecModel->XSec(interaction, kPSn1n2n3fE),max_xsec);
259
260 }
261 else {
262
263 const int Nscan = 100;
264 const int n1min = -1.;
265 const int n1max = 1.;
266 const int n2min = 0.;
267 const int n2max = 1.;
268 const double dn1 = (n1max-n1min)/(double)Nscan;
269 const double dn2 = (n2max-n2min)/(double)
270 Nscan;
271
272 double scan_n1 = 0.;
273 double scan_n2 = 0.;
274 for (int i=0; i<Nscan; i++) {
275 double n1 = n1min + dn1*i;
276 for (int j=0; j<Nscan; j++) {
277 double n2 = n2min + dn2*j;
278 interaction->KinePtr()->SetKV(kKVn1,n1);
279 interaction->KinePtr()->SetKV(kKVn2,n2);
280 double dxsec = fXSecModel->XSec(interaction, kPSn1n2fE);
281 if ( dxsec > max_xsec ) {
282 scan_n1 = n1;
283 scan_n2 = n2;
284 max_xsec = dxsec;
285 }
286 }
287 }
288
289 utils::gsl::d2Xsec_dn1dn2_E f(fXSecModel,interaction,-1);
290 min->SetFunction( f );
291 min->SetMaxFunctionCalls(10000);
292 min->SetTolerance(0.05);
293 min->SetLimitedVariable ( 0, "n1", scan_n1, 0.001, TMath::Max(-1.,scan_n1-0.1), TMath::Min(1.,scan_n1+0.1));
294 min->SetLimitedVariable ( 1, "n2", scan_n2, 0.1, TMath::Max(-0.,scan_n2-0.1), TMath::Min(1.,scan_n2+0.1));
295 min->Minimize();
296 interaction->KinePtr()->SetKV(kKVn1,min->X()[0]);
297 interaction->KinePtr()->SetKV(kKVn2,min->X()[1]);
298 max_xsec = fXSecModel->XSec(interaction, kPSn1n2fE);
299 SLOG("HELeptonKinematics", pDEBUG) << "Minimum found -> n1: " << min->X()[0] << ", n2: " << min->X()[1];
300
301 }
302
303 // Apply safety factor, since value retrieved from the cache might
304 // correspond to a slightly different energy.
305 max_xsec *= fSafetyFactor;
306
307 SLOG("HELeptonKinematics", pDEBUG) << interaction->AsString();
308 SLOG("HELeptonKinematics", pDEBUG) << "Max xsec in phase space = " << max_xsec;
309 SLOG("HELeptonKinematics", pDEBUG) << "Computed using alg = " << *fXSecModel;
310
311 return max_xsec;
312}
313//___________________________________________________________________________
314double HELeptonKinematicsGenerator::Energy(const Interaction * interaction) const
315{
316// Override the base class Energy() method to cache the max xsec for the
317// neutrino energy in the LAB rather than in the hit nucleon rest frame.
318
319 const InitialState & init_state = interaction->InitState();
320 double E = init_state.ProbeE(kRfLab);
321 return E;
322}
323//___________________________________________________________________________
329//____________________________________________________________________________
335//____________________________________________________________________________
337{
338// Reads its configuration data from its configuration Registry and loads them
339// in private data members to avoid looking up at the Registry all the time.
340
341 //-- Safety factor for the maximum differential cross section
342 GetParamDef( "MaxXSec-SafetyFactor", fSafetyFactor, 2. ) ;
343
344 //-- Maximum allowed fractional cross section deviation from maxim cross
345 // section used in rejection method
346 GetParamDef( "MaxXSec-DiffTolerance", fMaxXSecDiffTolerance, 999999. ) ;
347 assert(fMaxXSecDiffTolerance>=0);
348
349 //-- Sampling range for n1 variable
350 GetParamDef( "Delta-N1-NuE", fDeltaN1NuE, 0. ) ;
351 GetParamDef( "Delta-N1-NuMu", fDeltaN1NuMu, 0. ) ;
352 GetParamDef( "Delta-N1-NuTau", fDeltaN1NuTau, 0. ) ;
353
354
355}
356//____________________________________________________________________________
#define pNOTICE
Definition Messenger.h:61
#define pINFO
Definition Messenger.h:62
#define pDEBUG
Definition Messenger.h:63
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE,...
Definition Messenger.h:96
#define pWARN
Definition Messenger.h:60
#define SLOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a short string (using the FUNCTION and...
Definition Messenger.h:84
virtual void Configure(const Registry &config)
Definition Algorithm.cxx:62
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.
Definition GHepRecord.h:45
virtual void SetDiffXSec(double xsec, KinePhaseSpace_t ps)
Definition GHepRecord.h:133
virtual Interaction * Summary(void) const
virtual TBits * EventFlags(void) const
Definition GHepRecord.h:117
double Energy(const Interaction *in) const
void ProcessEventRecord(GHepRecord *event_rec) const
double ComputeMaxXSec(const Interaction *in) const
Initial State information.
int ProbePdg(void) const
double ProbeE(RefFrame_t rf) const
Summary information for an interaction.
Definition Interaction.h:56
string AsString(void) const
const ProcessInfo & ProcInfo(void) const
Definition Interaction.h:70
const InitialState & InitState(void) const
Definition Interaction.h:69
Kinematics * KinePtr(void) const
Definition Interaction.h:76
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 fSafetyFactor
ComputeMaxXSec -> ComputeMaxXSec * fSafetyFactor.
virtual double MaxXSec(GHepRecord *evrec, const int nkey=0) const
void ClearRunningValues(void)
void SetKV(KineVar_t kv, double value)
A class encapsulating an enumeration of interaction types (EM, Weak-CC, Weak-NC) and scattering types...
Definition ProcessInfo.h:46
bool IsPhotonCoherent(void) const
A singleton holding random number generator classes. All random number generation in GENIE should tak...
Definition RandomGen.h:29
static RandomGen * Instance()
Access instance.
Definition RandomGen.cxx:74
TRandom3 & RndKine(void) const
rnd number generator used by kinematics generators
Definition RandomGen.h:50
A registry. Provides the container for algorithm configuration parameters.
Definition Registry.h:65
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)
An exception thrown by EventRecordVisitorI when the normal processing sequence has to be disrupted (f...
Misc GENIE control constants.
bool IsNuE(int pdgc)
Definition PDGUtils.cxx:158
bool IsNuMu(int pdgc)
Definition PDGUtils.cxx:163
bool IsNuTau(int pdgc)
Definition PDGUtils.cxx:168
Simple functions for loading and reading nucleus dependent keys from config files.
Root of GENIE utility namespaces.
THE MAIN GENIE PROJECT NAMESPACE
Definition AlgCmp.h:25
@ kKVn2
Definition KineVar.h:62
@ kKVn1
Definition KineVar.h:61
@ kKVn3
Definition KineVar.h:63
@ kRfLab
Definition RefFrame.h:26
@ kKineGenErr
Definition GHepFlags.h:31