5 #include <TLorentzVector.h> 8 #include "GENIE/Framework/Numerical/RandomGen.h" 9 #include "GENIE/Framework/Conventions/Constants.h" 10 #include "GENIE/Framework/Utils/PrintUtils.h" 11 #include "GENIE/Tools/Flux/GFluxDriverFactory.h" 12 #include "GENIE/Framework/Messenger/Messenger.h" 13 #include "Framework/ParticleData/PDGCodeList.h" 14 #include "Framework/ParticleData/PDGCodes.h" 15 #include "Framework/ParticleData/PDGUtils.h" 16 #include "Framework/ParticleData/PDGLibrary.h" 23 using namespace
genie;
24 using namespace genie::flux;
25 using namespace genie::constants;
30 <<
"Instantiating the GENIE Power Spectrum atmospheric neutrino flux driver";
36 GPowerSpectrumAtmoFlux::~GPowerSpectrumAtmoFlux()
71 RandomGen * rnd = RandomGen::Instance();
85 double emin = TMath::Power(this->
MinEnergy(),1.0-alpha);
86 double emax = TMath::Power(this->
MaxEnergy(),1.0-alpha);
87 Ev = TMath::Power(emin+(emax-emin)*rnd->RndFlux().Rndm(),1.0/(1.0-alpha));
88 costheta = -1+2*rnd->RndFlux().Rndm();
89 phi = 2.*kPi* rnd->RndFlux().Rndm();
92 unsigned int inu = rnd->RndFlux().Integer(nnu);
93 nu_pdg = (*fPdgCList)[inu];
97 double sintheta = TMath::Sqrt(1-costheta*costheta);
98 double cosphi = TMath::Cos(phi);
99 double sinphi = TMath::Sin(phi);
109 double pz = -1.* Ev * costheta;
110 double py = -1.* Ev * sintheta * sinphi;
111 double px = -1.* Ev * sintheta * cosphi;
123 y +=
fRl * sintheta * sinphi;
124 x +=
fRl * sintheta * cosphi;
131 TVector3 tx3(x, y, z );
132 TVector3 tp3(px,py,pz);
151 TVector3 dvec1 = vec.Orthogonal();
152 TVector3 dvec2 = dvec1;
153 dvec2.Rotate(-kPi/2.0,vec);
155 double psi = 2.*kPi* rnd->RndFlux().Rndm();
156 double random = rnd->RndFlux().Rndm();
157 dvec1.SetMag(TMath::Sqrt(random)*
fRt*TMath::Cos(psi));
158 dvec2.SetMag(TMath::Sqrt(random)*
fRt*TMath::Sin(psi));
159 x += dvec1.X() + dvec2.X();
160 y += dvec1.Y() + dvec2.Y();
161 z += dvec1.Z() + dvec2.Z();
166 fgP4.SetPxPyPzE(px, py, pz, Ev);
167 fgX4.SetXYZT (x, y, z, 0.);
174 <<
"Generated neutrino: " 175 <<
"\n pdg-code: " <<
fgPdgC 176 <<
"\n p4: " << utils::print::P4AsShortString(&
fgP4)
177 <<
"\n x4: " << utils::print::X4AsString(&
fgX4);
189 fgP4.SetPxPyPzE (0.,0.,0.,0.);
190 fgX4.SetXYZT (0.,0.,0.,0.);
247 LOG(
"Flux", pWARN) <<
"GPowerSpectrumAtmoFlux::Clear(" << opt <<
") called";
257 LOG(
"Flux", pERROR) <<
258 "The neutrinos are always generated weighted with this implementation!! GenerateWeighted method not implemented.";
270 LOG(
"Flux", pWARN) <<
"Warning: cannot use a spectral index of unity";
272 LOG(
"Flux", pNOTICE) <<
"Using Spectral Index = " << index;
286 LOG(
"Flux", pNOTICE) <<
"Initializing power spectrum atmospheric flux driver";
288 bool allow_dup =
false;
318 LOG (
"Flux", pNOTICE) <<
"Setting R[longitudinal] = " << Rlongitudinal;
319 LOG (
"Flux", pNOTICE) <<
"Setting R[transverse] = " << Rtransverse;
332 for(
int flavor : flavors){
341 LOG(
"Flux", pNOTICE) <<
"Cleaning up...";
374 <<
"Loading fine grained flux for neutrino: " << nu_pdg
375 <<
" from file: " << filename;
377 TH3D* histo =
nullptr;
379 TFile *
f =
new TFile(filename.c_str(),
"READ");
380 f->GetObject(
"flux", histo);
383 LOG(
"Flux", pERROR) <<
"Null flux histogram!";
388 TH3D* h =
static_cast<TH3D*
>(histo->Clone());
393 TH2D*
h2 =
static_cast<TH2D*
>(h->Project3D(
"yx"));
405 std::ifstream
f(filename.c_str());
407 LOG(
"Flux", pFATAL) <<
"Flux file does not exist "<<filename;
410 if ( pdg::IsNeutrino(nu_pdg) || pdg::IsAntiNeutrino(nu_pdg) ) {
415 <<
"Input particle code: " << nu_pdg <<
" not a neutrino!";
424 <<
"Loading atmospheric neutrino flux simulation data";
428 bool loading_status =
true;
433 string pname = PDGLibrary::Instance()->Find(nu_pdg)->GetName();
435 LOG(
"Flux", pNOTICE) <<
"Loading data for: " << pname;
439 loading_status = loading_status && loaded;
443 <<
"Error loading atmospheric neutrino flux simulation data from " << filename;
451 int nu_pdg = hist_iter->first;
456 <<
"Atmospheric neutrino flux simulation data loaded!";
461 <<
"Error loading atmospheric neutrino flux simulation data";
470 TH3D* flux_hist =
nullptr;
474 flux_hist = it->second;
477 LOG(
"Flux", pERROR) <<
"flux_hist: " << flux_hist;
479 if(!flux_hist)
return 0.0;
481 if(flux_hist->GetZaxis()->GetNbins() == 1){
483 return h2->Interpolate(energy, costh);
486 return flux_hist->Interpolate(energy, costh, phi);
494 double flux = this->
GetFlux(flavour, energy, costh, phi);
509 double ITheta = 4*kPi;
long int fNNeutrinos
number of flux neutrinos thrown so far
long int Index(void) override
returns corresponding index for current flux neutrino (e.g. for a flux ntuple returns the current ent...
double fAgen
current generation area
GENIE neutrino interaction simulation objects.
map< int, TH3D * > fRawFluxHistoMap
flux = f(Ev,cos8,phi) for each neutrino species
void SetUserCoordSystem(TRotation &rotation)
TLorentzVector fgP4
current generated nu 4-momentum
const TLorentzVector & Position(void) override
returns the flux neutrino 4-position (note: expect SI rather than physical units) ...
const PDGCodeList & FluxParticles(void) override
declare list of flux neutrinos that can be generated (for init. purposes)
void GenerateWeighted(bool gen_weighted) override
set whether to generate weighted or unweighted neutrinos
A driver for a power spectrum atmospheric neutrino flux. Elements extensively reused from GAtmoFlux...
void ResetNFluxNeutrinos(void)
int PdgCode(void) override
returns the flux neutrino pdg code
double fSpectralIndex
power law function
bool GenerateNext(void) override
generate the next flux neutrino (return false in err)
double fRl
defining flux neutrino generation surface: longitudinal radius
void SetSpectralIndex(double index)
double fRt
defining flux neutrino generation surface: transverse radius
bool FillFluxHisto(int nu_pdg, string filename)
void SetFlavors(std::vector< int > flavors)
void SetMaxEnergy(double Emax)
void AddFluxFile(int neutrino_pdg, string filename)
long int NFluxNeutrinos(void) const
TRotation fRotTHz2User
coord. system rotation: THZ -> Topocentric user-defined
double ComputeWeight(int flavour, double energy, double costh, double phi)
double fGlobalGenWeight
global generation weight to apply to all events
void Clear(Option_t *opt) override
reset state variables based on opt
double fMinEvCut
user-defined cut: minimum energy
void SetMinEnergy(double Emin)
double Weight(void) override
returns the flux neutrino weight (if any)
vector< int > fFluxFlavour
input flux file for each neutrino species
int fgPdgC
current generated nu pdg-code
bool End(void) override
true if no more flux nu's can be thrown (eg reaching end of beam sim ntuples)
double fWeight
current generated nu weight
map< int, TH2D * > fRawFluxHistoMap2D
flux = f(Ev,cos8) for each neutrino species
TLorentzVector fgX4
current generated nu 4-position
double MaxEnergy(void) override
declare the max flux neutrino energy that can be generated (for init. purposes)
PDGCodeList * fPdgCList
input list of neutrino pdg-codes
void SetRadii(double Rlongitudinal, double Rtransverse)
double fMaxEvCut
user-defined cut: maximum energy
vector< string > fFluxFile
input flux file for each neutrino species
void ResetSelection(void)
const TLorentzVector & Momentum(void) override
returns the flux neutrino 4-momentum
double GetFlux(int flavour, double energy, double costh, double phi)