GENIEGenerator
Loading...
Searching...
No Matches
QELEventGeneratorSM.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 Igor Kakorin <kakorin@jinr.ru>
7 Joint Institute for Nuclear Research
8
9 adapted from fortran code provided by:
10
11 Konstantin Kuzmin <kkuzmin@theor.jinr.ru>,
12 Joint Institute for Nuclear Research,
13 Institute for Theoretical and Experimental Physics
14
15 Vadim Naumov <vnaumov@theor.jinr.ru>,
16 Joint Institute for Nuclear Research
17
18 based on code of:
19 Costas Andreopoulos <c.andreopoulos \at cern.ch>
20 University of Liverpool
21*/
22//____________________________________________________________________________
23
24#include <TMath.h>
25#include <Math/Factory.h>
26#include <Math/Minimizer.h>
27
29#include "Framework/Conventions/GBuild.h"
45
46
53
54using namespace genie;
55using namespace genie::controls;
56using namespace genie::utils;
57using namespace genie::utils::gsl;
58
59namespace { // anonymous namespace (file only visibility)
60 const double eps = std::numeric_limits<double>::epsilon();
61 const double max_dbl = std::numeric_limits<double>::max();
62 const double min_dbl = std::numeric_limits<double>::min();
63}
64//___________________________________________________________________________
66KineGeneratorWithCache("genie::QELEventGeneratorSM")
67{
68
69}
70//___________________________________________________________________________
72KineGeneratorWithCache("genie::QELEventGeneratorSM", config)
73{
74
75}
76//___________________________________________________________________________
81//___________________________________________________________________________
83{
84 LOG("QELEvent", pINFO) << "Generating QE event kinematics...";
85
87 LOG("QELEvent", pNOTICE)
88 << "Generating kinematics uniformly over the allowed phase space";
89 }
90 // Get the interaction and set the 'trust' bits
91 Interaction * interaction = evrec->Summary();
92 const InitialState & init_state = interaction -> InitState();
93 interaction->SetBit(kISkipProcessChk);
94 interaction->SetBit(kISkipKinematicChk);
95
96 // Skip if no hit nucleon is set
97 if(! evrec->HitNucleon())
98 {
99 LOG("QELEvent", pFATAL) << "No hit nucleon was set";
100 gAbortingInErr = true;
101 exit(1);
102 }
103
104 // Access the target from the interaction summary
105 Target * tgt = init_state.TgtPtr();
106 GHepParticle * nucleon = evrec->HitNucleon();
107 // Store position of nucleon
108 double hitNucPos = nucleon->X4()->Vect().Mag();
109 tgt->SetHitNucPosition( hitNucPos );
110
111 // Get the random number generators
113
114 // Access cross section algorithm for running thread
116 const EventGeneratorI * evg = rtinfo->RunningThread();
118
119 // heavy nucleus is nucleus that heavier than tritium or 3He.
120 bool isHeavyNucleus = tgt->A()>3;
121
122 sm_utils->SetInteraction(interaction);
123 // phase space for heavy nucleus is different from light one
124 fkps = isHeavyNucleus?kPSQ2vpfE:kPSQ2fE;
125 Range1D_t rQ2 = sm_utils->Q2QES_SM_lim();
126 // Try to calculate the maximum cross-section in kinematical limits
127 // if not pre-computed already
128 double xsec_max1 = fGenerateUniformly ? -1 : this->MaxXSec(evrec);
129 // this make correct calculation of probability
130 double xsec_max2 = fGenerateUniformly ? -1 : (rQ2.max<fQ2Min)? 0:this->MaxXSec(evrec, 1);
131 double dvmax= isHeavyNucleus ? this->MaxXSec(evrec, 2) : 0.;
132
133
134 // generate Q2, v, pF
135 double Q2, v, kF, xsec;
136 unsigned int iter = 0;
137 bool accept = false;
138 TLorentzVector q;
139 while(1)
140 {
141 LOG("QELEvent", pINFO) << "Attempt #: " << iter;
142 if(iter > 100*kRjMaxIterations)
143 {
144 LOG("QELEvent", pWARN)
145 << "Couldn't select a valid kinematics after " << iter << " iterations";
146 evrec->EventFlags()->SetBitNumber(kKineGenErr, true);
148 exception.SetReason("Couldn't select kinematics");
149 exception.SwitchOnFastForward();
150 throw exception;
151 }
152
153 // Pick Q2, v and pF
154 double xsec_max = 0.;
155 double pth = rnd->RndKine().Rndm();
156 //pth < prob1/(prob1+prob2), where prob1,prob2 - probabilities to generate event in area1 (Q2<fQ2Min) and area2 (Q2>fQ2Min) which are not normalized
157 if (pth <= xsec_max1*(TMath::Min(rQ2.max, fQ2Min)-rQ2.min)/(xsec_max1*(TMath::Min(rQ2.max, fQ2Min)-rQ2.min)+xsec_max2*(rQ2.max-fQ2Min)))
158 {
159 xsec_max = xsec_max1;
160 Q2 = (rnd->RndKine().Rndm() * (TMath::Min(rQ2.max, fQ2Min)-rQ2.min)) + rQ2.min;
161 }
162 else
163 {
164 xsec_max = xsec_max2;
165 Q2 = (rnd->RndKine().Rndm() * (rQ2.max-fQ2Min)) + fQ2Min;
166 }
167 Range1D_t rv = sm_utils->vQES_SM_lim(Q2);
168 // for nuclei heavier than deuterium generate energy transfer in defined energy interval
169 double dv = 0.;
170 if (isHeavyNucleus)
171 {
172 dv = dvmax * rnd->RndKine().Rndm();
173 if (dv > (rv.max-rv.min))
174 {
175 continue;
176 }
177 }
178 v = rv.min + dv;
179
180 Range1D_t rkF = sm_utils->kFQES_SM_lim(Q2, v);
181 // rkF.max = Fermi momentum
182 kF = rnd->RndKine().Rndm()*sm_utils->GetFermiMomentum();
183 if (kF < rkF.min)
184 {
185 continue;
186 }
187
188 Kinematics * kinematics = interaction->KinePtr();
189 kinematics->SetKV(kKVQ2, Q2);
190 kinematics->SetKV(kKVv, v);
191 kinematics->SetKV(kKVPn, kF);
192 xsec = fXSecModel->XSec(interaction, fkps);
193 //-- Decide whether to accept the current kinematics
195 {
196 this->AssertXSecLimits(interaction, xsec, xsec_max);
197 double t = xsec_max * rnd->RndKine().Rndm();
198
199 accept = (t < xsec);
200 }
201 else
202 {
203 accept = (xsec>0);
204 }
205
206 // If the generated kinematics are accepted, finish-up module's job
207 if(accept)
208 {
209 interaction->ResetBit(kISkipProcessChk);
210 interaction->ResetBit(kISkipKinematicChk);
211 break;
212 }
213 iter++;
214 }
215
216 // Z-frame is frame where momentum transfer is (v,0,0,qv)
217 double qv = TMath::Sqrt(v*v+Q2);
218 TLorentzVector transferMom(0, 0, qv, v);
219
220 // Momentum of initial neutrino in LAB frame
221 TLorentzVector * tempTLV = evrec->Probe()->GetP4();
222 TLorentzVector neutrinoMom = *tempTLV;
223 delete tempTLV;
224
225 // define all angles in Z frame
226 double theta = neutrinoMom.Vect().Theta();
227 double phi = neutrinoMom.Vect().Phi();
228 double theta_k = sm_utils-> GetTheta_k(v, qv);
229 double costheta_k = TMath::Cos(theta_k);
230 double sintheta_k = TMath::Sin(theta_k);
231 double E_p; //energy of initial nucleon
232 double theta_p = sm_utils-> GetTheta_p(kF, v, qv, E_p);
233 double costheta_p = TMath::Cos(theta_p);
234 double sintheta_p = TMath::Sin(theta_p);
235 double fi_p = 2 * TMath::Pi() * rnd->RndGen().Rndm();
236 double cosfi_p = TMath::Cos(fi_p);
237 double sinfi_p = TMath::Sin(fi_p);
238 double psi = 2 * TMath::Pi() * rnd->RndGen().Rndm();
239
240 // 4-momentum of initial neutrino in Z-frame
241 TLorentzVector neutrinoMomZ(neutrinoMom.P()*sintheta_k, 0, neutrinoMom.P()*costheta_k, neutrinoMom.E());
242
243 // 4-momentum of final lepton in Z-frame
244 TLorentzVector outLeptonMom = neutrinoMomZ-transferMom;
245
246 // 4-momentum of initial nucleon in Z-frame
247 TLorentzVector inNucleonMom(kF*sintheta_p*cosfi_p, kF*sintheta_p*sinfi_p, kF*costheta_p, E_p);
248
249 // 4-momentum of final nucleon in Z-frame
250 TLorentzVector outNucleonMom = inNucleonMom+transferMom;
251
252 // Rotate all vectors from Z frame to LAB frame
253 TVector3 yvec (0.0, 1.0, 0.0);
254 TVector3 zvec (0.0, 0.0, 1.0);
255 TVector3 unit_nudir = neutrinoMom.Vect().Unit();
256
257 outLeptonMom.Rotate(theta-theta_k, yvec);
258 outLeptonMom.Rotate(phi, zvec);
259
260 inNucleonMom.Rotate(theta-theta_k, yvec);
261 inNucleonMom.Rotate(phi, zvec);
262
263 outNucleonMom.Rotate(theta-theta_k, yvec);
264 outNucleonMom.Rotate(phi, zvec);
265
266 outLeptonMom.Rotate(psi, unit_nudir);
267 inNucleonMom.Rotate(psi, unit_nudir);
268 outNucleonMom.Rotate(psi, unit_nudir);
269
270 // set 4-momentum of struck nucleon
271 TLorentzVector * p4 = tgt->HitNucP4Ptr();
272 p4->SetPx( inNucleonMom.Px() );
273 p4->SetPy( inNucleonMom.Py() );
274 p4->SetPz( inNucleonMom.Pz() );
275 p4->SetE ( inNucleonMom.E() );
276
277 int rpdgc = interaction->RecoilNucleonPdg();
278 assert(rpdgc);
279 double W = PDGLibrary::Instance()->Find(rpdgc)->Mass();
280 LOG("QELEvent", pNOTICE) << "Selected: W = "<< W;
281 double M = init_state.Tgt().HitNucP4().M();
282 double E = init_state.ProbeE(kRfHitNucRest);
283
284 // (W,Q2) -> (x,y)
285 double x=0, y=0;
286 kinematics::WQ2toXY(E,M,W,Q2,x,y);
287
288 // lock selected kinematics & clear running values
289 interaction->KinePtr()->SetQ2(Q2, true);
290 interaction->KinePtr()->SetW (W, true);
291 interaction->KinePtr()->Setx (x, true);
292 interaction->KinePtr()->Sety (y, true);
293 interaction->KinePtr()->ClearRunningValues();
294
295 // set the cross section for the selected kinematics
296 evrec->SetDiffXSec(xsec,fkps);
298 {
299 double vol = sm_utils->PhaseSpaceVolume(fkps);
300 double totxsec = evrec->XSec();
301 double wght = (vol/totxsec)*xsec;
302 LOG("QELEvent", pNOTICE) << "Kinematics wght = "<< wght;
303
304 // apply computed weight to the current event weight
305 wght *= evrec->Weight();
306 LOG("QELEvent", pNOTICE) << "Current event wght = " << wght;
307 evrec->SetWeight(wght);
308 }
309 TLorentzVector x4l(*(evrec->Probe())->X4());
310
311 // Add the final-state lepton to the event record
312 evrec->AddParticle(interaction->FSPrimLeptonPdg(), kIStStableFinalState, evrec->ProbePosition(),-1,-1,-1, outLeptonMom, x4l);
313
314 // Set its polarization
316
317 GHepStatus_t ist;
320 else
321 ist = (tgt->IsNucleus() && isHeavyNucleus) ? kIStHadronInTheNucleus : kIStStableFinalState;
322
323 GHepParticle outNucleon(interaction->RecoilNucleonPdg(), ist, evrec->HitNucleonPosition(),-1,-1,-1, outNucleonMom , x4l);
324 evrec->AddParticle(outNucleon);
325
326 // Store struck nucleon momentum
327 LOG("QELEvent",pNOTICE) << "pn: " << inNucleonMom.X() << ", " <<inNucleonMom.Y() << ", " <<inNucleonMom.Z() << ", " <<inNucleonMom.E();
328 nucleon->SetMomentum(inNucleonMom);
329 nucleon->SetRemovalEnergy(sm_utils->GetBindingEnergy());
330
331 // skip if not a nuclear target
332 if(evrec->Summary()->InitState().Tgt().IsNucleus())
333 // add a recoiled nucleus remnant
334 this->AddTargetNucleusRemnant(evrec);
335
336 LOG("QELEvent", pINFO) << "Done generating QE event kinematics!";
337}
338//___________________________________________________________________________
340{
341// add the remnant nuclear target at the GHEP record
342
343 LOG("QELEvent", pINFO) << "Adding final state nucleus";
344
345 double Px = 0;
346 double Py = 0;
347 double Pz = 0;
348 double E = 0;
349
350 GHepParticle * nucleus = evrec->TargetNucleus();
351 int A = nucleus->A();
352 int Z = nucleus->Z();
353
354 int fd = nucleus->FirstDaughter();
355 int ld = nucleus->LastDaughter();
356
357 for(int id = fd; id <= ld; id++)
358 {
359
360 // compute A,Z for final state nucleus & get its PDG code and its mass
361 GHepParticle * particle = evrec->Particle(id);
362 assert(particle);
363 int pdgc = particle->Pdg();
364 bool is_p = pdg::IsProton (pdgc);
365 bool is_n = pdg::IsNeutron(pdgc);
366
367 if (is_p) Z--;
368 if (is_p || is_n) A--;
369
370 Px += particle->Px();
371 Py += particle->Py();
372 Pz += particle->Pz();
373 E += particle->E();
374
375 }//daughters
376
377 TParticlePDG * remn = 0;
378 int ipdgc = pdg::IonPdgCode(A, Z);
379 remn = PDGLibrary::Instance()->Find(ipdgc);
380 if(!remn)
381 {
382 LOG("HadronicVtx", pFATAL)
383 << "No particle with [A = " << A << ", Z = " << Z
384 << ", pdgc = " << ipdgc << "] in PDGLibrary!";
385 assert(remn);
386 }
387
388 double Mi = nucleus->Mass();
389 Px *= -1;
390 Py *= -1;
391 Pz *= -1;
392 E = Mi-E;
393
394 // Add the nucleus to the event record
395 LOG("QELEvent", pINFO)
396 << "Adding nucleus [A = " << A << ", Z = " << Z
397 << ", pdgc = " << ipdgc << "]";
398
399 int imom = evrec->TargetNucleusPosition();
400 evrec->AddParticle(
401 ipdgc,kIStStableFinalState, imom,-1,-1,-1, Px,Py,Pz,E, 0,0,0,0);
402
403 LOG("QELEvent", pINFO) << "Done";
404 LOG("QELEvent", pINFO) << *evrec;
405}
406//___________________________________________________________________________
412//____________________________________________________________________________
414{
416
417 Registry r( "QELEventGeneratorSM_specific", false ) ;
418 r.Set( "sm_utils_algo", RgAlg("genie::SmithMonizUtils","Default") ) ;
419
421
422 this->LoadConfig();
423}
424//____________________________________________________________________________
426{
427
428 // Safety factors for the maximum differential cross section
429 fNumOfSafetyFactors = GetParamVect("Safety-Factors", vSafetyFactors, false);
430
431 // Interpolator types for the maximum differential cross section
432 fNumOfInterpolatorTypes = GetParamVect("Interpolator-Types", vInterpolatorTypes, false);
433
434
435 // Minimum energy for which max xsec would be cached, forcing explicit
436 // calculation for lower eneries
437 GetParamDef( "Cache-MinEnergy", fEMin, 1.00) ;
438 GetParamDef( "Threshold-Q2", fQ2Min, 2.00);
439
440 // Maximum allowed fractional cross section deviation from maxim cross
441 // section used in rejection method
442 GetParamDef( "MaxXSec-DiffTolerance", fMaxXSecDiffTolerance, 999999.);
443 assert(fMaxXSecDiffTolerance>=0);
444
445 //-- Generate kinematics uniformly over allowed phase space and compute
446 // an event weight?
447 GetParamDef( "UniformOverPhaseSpace", fGenerateUniformly, false);
448
449 // Generate nucleon in nucleus?
450 GetParamDef( "IsNucleonInNucleus", fGenerateNucleonInNucleus, true);
451
452
453 sm_utils = const_cast<genie::SmithMonizUtils *>(dynamic_cast<const genie::SmithMonizUtils *>( this -> SubAlg("sm_utils_algo") ) ) ;
454}
455//____________________________________________________________________________
456double QELEventGeneratorSM::ComputeMaxXSec(const Interaction * interaction) const
457{
458 double xsec_max = -1;
459 double tmp_xsec_max = -1;
460 double Q20, v0;
461 const int N_Q2 = 32;
462 const InitialState & init_state = interaction -> InitState();
463 Target * tgt = init_state.TgtPtr();
464 bool isHeavyNucleus = tgt->A()>3;
465 int N_v = isHeavyNucleus?32:0;
466
467 Range1D_t rQ2 = sm_utils->Q2QES_SM_lim();
468 const double logQ2min = TMath::Log(TMath::Max(rQ2.min, eps));
469 const double logQ2max = TMath::Log(TMath::Min(rQ2.max, fQ2Min));
470 Kinematics * kinematics = interaction->KinePtr();
471 const double pFmax = sm_utils->GetFermiMomentum();
472 // Now scan through kinematical variables Q2,v,kF
473 for (int Q2_n=0; Q2_n <= N_Q2; Q2_n++)
474 {
475 // Scan around Q2
476 double Q2 = TMath::Exp(Q2_n*(logQ2max-logQ2min)/N_Q2 + logQ2min);
477 kinematics->SetKV(kKVQ2, Q2);
478 Range1D_t rv = sm_utils->vQES_SM_lim(Q2);
479 const double logvmin = TMath::Log(TMath::Max(rv.min, eps));
480 const double logvmax = TMath::Log(TMath::Max(rv.max, TMath::Max(rv.min, eps)));
481 for (int v_n=0; v_n <= N_v; v_n++)
482 {
483 // Scan around v
484 double v = TMath::Exp(v_n*(logvmax-logvmin)/N_v + logvmin);
485 kinematics->SetKV(kKVv, v);
486 kinematics->SetKV(kKVPn, pFmax);
487 // Compute the QE cross section for the current kinematics
488 double xs = fXSecModel->XSec(interaction, fkps);
489 if (xs > tmp_xsec_max)
490 {
491 tmp_xsec_max = xs;
492 Q20 = Q2;
493 v0 = v;
494 }
495 } // Done with v scan
496 }// Done with Q2 scan
497
498 const double Q2min = rQ2.min;
499 const double Q2max = TMath::Min(rQ2.max, fQ2Min);
500 const double vmin = sm_utils->vQES_SM_min(Q2min, Q2max);
501 const double vmax = sm_utils->vQES_SM_max(Q2min, Q2max);
502
503 ROOT::Math::Minimizer * min = ROOT::Math::Factory::CreateMinimizer("Minuit", "Minimize");
504 ROOT::Math::IBaseFunctionMultiDim * f = isHeavyNucleus?static_cast<ROOT::Math::IBaseFunctionMultiDim*>(new d3XSecSM_dQ2dvdkF_E(fXSecModel, interaction, pFmax)):
505 static_cast<ROOT::Math::IBaseFunctionMultiDim*>(new d1XSecSM_dQ2_E(fXSecModel, interaction));
506 min->SetFunction( *f );
507 min->SetMaxFunctionCalls(10000); // for Minuit/Minuit2
508 min->SetMaxIterations(10000); // for GSL
509 min->SetTolerance(0.001);
510 min->SetPrintLevel(0);
511 double step = 1e-7;
512 min->SetVariable(0, "Q2", Q20, step);
513 min->SetVariableLimits(0, Q2min, Q2max);
514 if (isHeavyNucleus)
515 {
516 min->SetVariable(1, "v", v0, step);
517 min->SetVariableLimits(1, vmin, vmax);
518 }
519 min->Minimize();
520 xsec_max = -min->MinValue();
521 if (tmp_xsec_max > xsec_max)
522 {
523 xsec_max = tmp_xsec_max;
524 }
525
526 return xsec_max;
527
528}
529//___________________________________________________________________________
530double QELEventGeneratorSM::ComputeMaxXSec(const Interaction * interaction, const int nkey) const
531{
532 switch (nkey){
533 case 0:
534 return this->ComputeMaxXSec(interaction);
535
536 case 1:
537 {
538 Range1D_t rQ2 = sm_utils->Q2QES_SM_lim();
539 if (rQ2.max<fQ2Min)
540 {
541 return -1.;
542 }
543 double xsec_max = -1;
544 double tmp_xsec_max = -1;
545 double Q20, v0;
546 const int N_Q2 = 32;
547 const InitialState & init_state = interaction -> InitState();
548 Target * tgt = init_state.TgtPtr();
549 bool isHeavyNucleus = tgt->A()>3;
550 int N_v = isHeavyNucleus?32:0;
551
552 const double logQ2min = TMath::Log(fQ2Min);
553 const double logQ2max = TMath::Log(rQ2.max);
554 Kinematics * kinematics = interaction->KinePtr();
555 const double pFmax = sm_utils->GetFermiMomentum();
556 // Now scan through kinematical variables Q2,v,kF
557 for (int Q2_n=0; Q2_n <= N_Q2; Q2_n++)
558 {
559 // Scan around Q2
560 double Q2 = TMath::Exp(Q2_n*(logQ2max-logQ2min)/N_Q2 + logQ2min);
561 kinematics->SetKV(kKVQ2, Q2);
562 Range1D_t rv = sm_utils->vQES_SM_lim(Q2);
563 const double logvmin = TMath::Log(TMath::Max(rv.min, eps));
564 const double logvmax = TMath::Log(TMath::Max(rv.max, TMath::Max(rv.min, eps)));
565 for (int v_n=0; v_n <= N_v; v_n++)
566 {
567 // Scan around v
568 double v = TMath::Exp(v_n*(logvmax-logvmin)/N_v + logvmin);
569 kinematics->SetKV(kKVv, v);
570 kinematics->SetKV(kKVPn, pFmax);
571 // Compute the QE cross section for the current kinematics
572 double xs = fXSecModel->XSec(interaction, fkps);
573 if (xs > tmp_xsec_max)
574 {
575 tmp_xsec_max = xs;
576 Q20 = Q2;
577 v0 = v;
578 }
579 } // Done with v scan
580 }// Done with Q2 scan
581
582 const double Q2min = fQ2Min;
583 const double Q2max = rQ2.max;
584 const double vmin = sm_utils->vQES_SM_min(Q2min, Q2max);
585 const double vmax = sm_utils->vQES_SM_max(Q2min, Q2max);
586 ROOT::Math::Minimizer * min = ROOT::Math::Factory::CreateMinimizer("Minuit", "Minimize");
587 ROOT::Math::IBaseFunctionMultiDim * f = isHeavyNucleus?static_cast<ROOT::Math::IBaseFunctionMultiDim*>(new d3XSecSM_dQ2dvdkF_E(fXSecModel, interaction, pFmax)):
588 static_cast<ROOT::Math::IBaseFunctionMultiDim*>(new d1XSecSM_dQ2_E(fXSecModel, interaction));
589 min->SetFunction( *f );
590 min->SetMaxFunctionCalls(10000); // for Minuit/Minuit2
591 min->SetMaxIterations(10000); // for GSL
592 min->SetTolerance(0.001);
593 min->SetPrintLevel(0);
594 double step = 1e-7;
595 min->SetVariable(0, "Q2", Q20, step);
596 min->SetVariableLimits(0, Q2min, Q2max);
597 if (isHeavyNucleus)
598 {
599 min->SetVariable(1, "v", v0, step);
600 min->SetVariableLimits(1, vmin, vmax);
601 }
602 min->Minimize();
603 xsec_max = -min->MinValue();
604 if (tmp_xsec_max > xsec_max)
605 {
606 xsec_max = tmp_xsec_max;
607 }
608 return xsec_max;
609 }
610 case 2:
611 {
612 double diffv_max = -1;
613 double tmp_diffv_max = -1;
614 const int N_Q2 = 100;
615 double Q20;
616 Range1D_t rQ2 = sm_utils->Q2QES_SM_lim();
617 for (int Q2_n = 0; Q2_n<=N_Q2; Q2_n++) // Scan around Q2
618 {
619 double Q2 = rQ2.min + 1.*Q2_n * (rQ2.max-rQ2.min)/N_Q2;
620 Range1D_t rv = sm_utils->vQES_SM_lim(Q2);
621 if (rv.max-rv.min > tmp_diffv_max)
622 {
623 tmp_diffv_max = rv.max-rv.min;
624 Q20 = Q2;
625 }
626 } // Done with Q2 scan
627
628 ROOT::Math::Minimizer * min = ROOT::Math::Factory::CreateMinimizer("Minuit", "Minimize");
629 ROOT::Math::IBaseFunctionMultiDim * f = new dv_dQ2_E(interaction);
630 min->SetFunction( *f );
631 min->SetMaxFunctionCalls(10000); // for Minuit/Minuit2
632 min->SetMaxIterations(10000); // for GSL
633 min->SetTolerance(0.001);
634 min->SetPrintLevel(0);
635 double step = 1e-7;
636 min->SetVariable(0, "Q2", Q20, step);
637 min->SetVariableLimits(0, rQ2.min, rQ2.max);
638 min->Minimize();
639 diffv_max = -min->MinValue();
640
641 if (tmp_diffv_max > diffv_max)
642 {
643 diffv_max = tmp_diffv_max;
644 }
645 return diffv_max;
646 }
647 default:
648 return -1.;
649 }
650}
651//___________________________________________________________________________
652// GSL wrappers
653//____________________________________________________________________________
655 const XSecAlgorithmI * m,
656 const Interaction * i,
657 double pF) : ROOT::Math::IBaseFunctionMultiDim(),
658 fModel(m),
659 fInteraction(i),
660 fpF(pF)
661{
662}
666unsigned int d3XSecSM_dQ2dvdkF_E::NDim(void) const
667{
668 return 2;
669}
670double d3XSecSM_dQ2dvdkF_E::DoEval(const double * xin) const
671{
672// outputs:
673// differential cross section
674//
675 fInteraction->KinePtr()->SetKV(kKVQ2, xin[0]);
676 fInteraction->KinePtr()->SetKV(kKVv, xin[1]);
677 fInteraction->KinePtr()->SetKV(kKVPn, fpF);
678 double xsec = -fModel->XSec(fInteraction, kPSQ2vpfE);
679 return xsec;
680}
681ROOT::Math::IBaseFunctionMultiDim *
686//____________________________________________________________________________
688 const XSecAlgorithmI * m,
689 const Interaction * i) : ROOT::Math::IBaseFunctionMultiDim(),
690 fModel(m),
691 fInteraction(i)
692{
693}
697unsigned int d1XSecSM_dQ2_E::NDim(void) const
698{
699 return 1;
700}
701double d1XSecSM_dQ2_E::DoEval(const double * xin) const
702{
703// outputs:
704// differential cross section
705//
706 fInteraction->KinePtr()->SetKV(kKVQ2, xin[0]);
707 double xsec = -fModel->XSec(fInteraction, kPSQ2fE);
708 return xsec;
709}
710ROOT::Math::IBaseFunctionMultiDim *
712{
714}
715//____________________________________________________________________________
716dv_dQ2_E::dv_dQ2_E(const Interaction * i) : ROOT::Math::IBaseFunctionMultiDim(),
717 fInteraction(i)
718{
720 sm_utils = const_cast<SmithMonizUtils *>(dynamic_cast<const SmithMonizUtils *>(algf->GetAlgorithm("genie::SmithMonizUtils","Default")));
721 sm_utils->SetInteraction(fInteraction);
722}
726unsigned int dv_dQ2_E::NDim(void) const
727{
728 return 1;
729}
730double dv_dQ2_E::DoEval(const double * xin) const
731{
732// outputs:
733// differential cross section
734//
735 double Q2 = xin[0];
736 Range1D_t rv = sm_utils->vQES_SM_lim(Q2);
737 return rv.min-rv.max;
738}
739ROOT::Math::IBaseFunctionMultiDim *
741{
742 return new dv_dQ2_E(fInteraction);
743}
744//____________________________________________________________________________
#define pNOTICE
Definition Messenger.h:61
#define pINFO
Definition Messenger.h:62
#define pFATAL
Definition Messenger.h:56
#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
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils.
The GENIE Algorithm Factory.
Definition AlgFactory.h:39
const Algorithm * GetAlgorithm(const AlgId &algid)
static AlgFactory * Instance()
int GetParamVect(const std::string &comm_name, std::vector< T > &v, bool is_top_call=true) const
Handle to load vectors of parameters.
virtual void Configure(const Registry &config)
Definition Algorithm.cxx:62
bool GetParamDef(const RgKey &name, T &p, const T &def) const
const Algorithm * SubAlg(const RgKey &registry_key) const
Defines the EventGeneratorI interface.
virtual const XSecAlgorithmI * CrossSectionAlg(void) const =0
STDHEP-like event record entry that can fit a particle or a nucleus.
void SetMomentum(const TLorentzVector &p4)
TLorentzVector * GetP4(void) const
int Pdg(void) const
void SetRemovalEnergy(double Erm)
double Mass(void) const
Mass that corresponds to the PDG code.
const TLorentzVector * X4(void) const
int LastDaughter(void) const
double Px(void) const
Get Px.
int Z(void) const
double E(void) const
Get energy.
double Pz(void) const
Get Pz.
double Py(void) const
Get Py.
int A(void) const
int FirstDaughter(void) const
GENIE's GHEP MC event record.
Definition GHepRecord.h:45
virtual double Weight(void) const
Definition GHepRecord.h:124
virtual int ProbePosition(void) const
virtual GHepParticle * Probe(void) const
virtual void SetDiffXSec(double xsec, KinePhaseSpace_t ps)
Definition GHepRecord.h:133
virtual double XSec(void) const
Definition GHepRecord.h:126
virtual GHepParticle * TargetNucleus(void) const
virtual Interaction * Summary(void) const
virtual TBits * EventFlags(void) const
Definition GHepRecord.h:117
virtual void AddParticle(const GHepParticle &p)
virtual int TargetNucleusPosition(void) const
virtual void SetWeight(double wght)
Definition GHepRecord.h:130
virtual GHepParticle * Particle(int position) const
virtual int HitNucleonPosition(void) const
virtual GHepParticle * HitNucleon(void) const
Initial State information.
const Target & Tgt(void) const
double ProbeE(RefFrame_t rf) const
Target * TgtPtr(void) const
Summary information for an interaction.
Definition Interaction.h:56
int RecoilNucleonPdg(void) const
recoil nucleon pdg
int FSPrimLeptonPdg(void) const
final state primary lepton pdg
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
std::vector< string > vInterpolatorTypes
Type of interpolator for each key in a branch.
std::vector< double > vSafetyFactors
MaxXSec -> MaxXSec * fSafetyFactors[nkey].
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.
int fNumOfInterpolatorTypes
Number of given interpolators types.
int fNumOfSafetyFactors
Number of given safety factors.
virtual double MaxXSec(GHepRecord *evrec, const int nkey=0) const
Generated/set kinematical variables for an event.
Definition Kinematics.h:39
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)
static PDGLibrary * Instance(void)
TParticlePDG * Find(int pdgc, bool must_exist=true)
void Configure(const Registry &config)
double fQ2Min
Q2-threshold for seeking the second maximum.
void ProcessEventRecord(GHepRecord *event_rec) const
void AddTargetNucleusRemnant(GHepRecord *evrec) const
add a recoiled nucleus remnant
double ComputeMaxXSec(const Interaction *in) const
bool fGenerateNucleonInNucleus
generate struck nucleon in nucleus
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
TRandom3 & RndGen(void) const
rnd number generator for generic usage
Definition RandomGen.h:80
A simple [min,max] interval for doubles.
Definition Range1.h:43
A registry. Provides the container for algorithm configuration parameters.
Definition Registry.h:65
void Set(RgIMapPair entry)
Definition Registry.cxx:267
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)
Contains auxiliary functions for Smith-Moniz model. .
A Neutrino Interaction Target. Is a transparent encapsulation of quite different physical systems suc...
Definition Target.h:40
void SetHitNucPosition(double r)
Definition Target.cxx:210
const TLorentzVector & HitNucP4(void) const
Definition Target.h:91
TLorentzVector * HitNucP4Ptr(void) const
Definition Target.cxx:247
int A(void) const
Definition Target.h:70
bool IsNucleus(void) const
Definition Target.cxx:272
Cross Section Calculation Interface.
An exception thrown by EventRecordVisitorI when the normal processing sequence has to be disrupted (f...
ROOT::Math::IBaseFunctionMultiDim * Clone(void) const
d1XSecSM_dQ2_E(const XSecAlgorithmI *, const Interaction *)
double DoEval(const double *) const
ROOT::Math::IBaseFunctionMultiDim * Clone(void) const
d3XSecSM_dQ2dvdkF_E(const XSecAlgorithmI *, const Interaction *, double pF)
unsigned int NDim(void) const
ROOT::Math::IBaseFunctionMultiDim * Clone(void) const
double DoEval(const double *) const
const double e
Misc GENIE control constants.
static const unsigned int kRjMaxIterations
Definition Controls.h:26
int IonPdgCode(int A, int Z)
Definition PDGUtils.cxx:71
bool IsProton(int pdgc)
Definition PDGUtils.cxx:336
bool IsNeutron(int pdgc)
Definition PDGUtils.cxx:341
Simple functions for loading and reading nucleus dependent keys from config files.
Simple utilities for integrating GSL in the GENIE framework.
Kinematical utilities.
void WQ2toXY(double Ev, double M, double W, double Q2, double &x, double &y)
Root of GENIE utility namespaces.
void SetPrimaryLeptonPolarization(GHepRecord *ev)
THE MAIN GENIE PROJECT NAMESPACE
Definition AlgCmp.h:25
@ kIStHadronInTheNucleus
Definition GHepStatus.h:37
@ kIStStableFinalState
Definition GHepStatus.h:30
bool gAbortingInErr
Definition Messenger.cxx:34
enum genie::EGHepStatus GHepStatus_t
@ kKVQ2
Definition KineVar.h:33
@ kKVv
Definition KineVar.h:53
@ kKVPn
Definition KineVar.h:52
const UInt_t kISkipKinematicChk
if set, skip kinematic validity checks
Definition Interaction.h:48
@ kRfHitNucRest
Definition RefFrame.h:30
const UInt_t kISkipProcessChk
if set, skip process validity checks
Definition Interaction.h:47
@ kKineGenErr
Definition GHepFlags.h:31