29 using namespace genie;
30 using namespace genie::flux;
31 using namespace genie::constants;
34 GAtmoFlux::GAtmoFlux()
39 GAtmoFlux::~GAtmoFlux()
44 double GAtmoFlux::MaxEnergy(
void)
46 return TMath::Min(fMaxEv, fMaxEvCut);
49 bool GAtmoFlux::GenerateNext(
void)
53 bool nextok = this->GenerateNext_1try();
59 const TLorentzVector & p4 = this->Momentum();
60 double E = p4.Energy();
61 double Emin = this->MinEnergy();
62 double Emax = this->MaxEnergy();
63 double wght = this->Weight();
65 bool accept = (E<=Emax && E>=Emin && wght>0);
66 if(accept)
return true;
71 bool GAtmoFlux::GenerateNext_1try(
void)
77 this->ResetSelection();
98 double alpha = fSpectralIndex;
100 double emin = TMath::Power(fEnergyBins[0],1.0-alpha);
101 double emax = TMath::Power(fEnergyBins[fNumEnergyBins],1.0-alpha);
102 Ev = TMath::Power(emin+(emax-emin)*rnd->
RndFlux().Rndm(),1.0/(1.0-alpha));
103 costheta = -1+2*rnd->
RndFlux().Rndm();
106 unsigned int nnu = fPdgCList->size();
107 unsigned int inu = rnd->
RndFlux().Integer(nnu);
108 nu_pdg = (*fPdgCList)[inu];
110 if(Ev < fEnergyBins[0]) {
114 double flux = this->
GetFlux(nu_pdg, Ev, costheta, phi);
119 weight = flux*TMath::Power(Ev,alpha);
127 Axis_t ax = 0, ay = 0, az = 0;
128 fTotalFluxHisto->GetRandom3(ax, ay, az);
130 costheta = (double)ay;
132 nu_pdg = this->SelectNeutrino(Ev, costheta, phi);
137 double sintheta = TMath::Sqrt(1-costheta*costheta);
138 double cosphi = TMath::Cos(phi);
139 double sinphi = TMath::Sin(phi);
149 double pz = -1.* Ev * costheta;
150 double py = -1.* Ev * sintheta * sinphi;
151 double px = -1.* Ev * sintheta * cosphi;
163 y += fRl * sintheta * sinphi;
164 x += fRl * sintheta * cosphi;
169 if( !fRotTHz2User.IsIdentity() )
171 TVector3 tx3(x, y, z );
172 TVector3 tp3(px,py,pz);
174 tx3 = fRotTHz2User * tx3;
175 tp3 = fRotTHz2User * tp3;
191 TVector3 dvec1 = vec.Orthogonal();
192 TVector3 dvec2 = dvec1;
193 dvec2.Rotate(-
kPi/2.0,vec);
196 double random = rnd->
RndFlux().Rndm();
197 dvec1.SetMag(TMath::Sqrt(random)*fRt*TMath::Cos(psi));
198 dvec2.SetMag(TMath::Sqrt(random)*fRt*TMath::Sin(psi));
199 x += dvec1.X() + dvec2.X();
200 y += dvec1.Y() + dvec2.Y();
201 z += dvec1.Z() + dvec2.Z();
206 fgP4.SetPxPyPzE(px, py, pz, Ev);
207 fgX4.SetXYZT (x, y, z, 0.);
214 <<
"Generated neutrino: "
215 <<
"\n pdg-code: " << fgPdgC
222 long int GAtmoFlux::NFluxNeutrinos(
void)
const
227 void GAtmoFlux::ForceMinEnergy(
double emin)
229 emin = TMath::Max(0., emin);
233 void GAtmoFlux::ForceMaxEnergy(
double emax)
235 emax = TMath::Max(0., emax);
239 void GAtmoFlux::Clear(Option_t * opt)
243 LOG(
"Flux",
pERROR) <<
"No clear method implemented for option:"<< opt;
246 void GAtmoFlux::GenerateWeighted(
bool gen_weighted)
248 fGenWeighted = gen_weighted;
251 void GAtmoFlux:: SetSpectralIndex(
double index)
254 fSpectralIndex = index;
257 LOG(
"Flux",
pWARN) <<
"Warning: cannot use a spectral index of unity";
260 LOG(
"Flux",
pNOTICE) <<
"Using Spectral Index = " << index;
263 void GAtmoFlux::SetUserCoordSystem(TRotation & rotation)
265 fRotTHz2User = rotation;
270 LOG(
"Flux",
pNOTICE) <<
"Initializing atmospheric flux driver";
275 fNumCosThetaBins = 0;
282 fTotalFluxHistoIntg = 0;
284 bool allow_dup =
false;
289 fFluxHistoMap.clear();
291 fTotalFluxHistoIntg = 0;
300 fSpectralIndex = 2.0;
303 this->GenerateWeighted(
false);
306 this->ForceMinEnergy(0.);
307 this->ForceMaxEnergy(9999999999.);
314 fRotTHz2User.SetToIdentity();
317 this->ResetSelection();
326 void GAtmoFlux::ResetSelection(
void)
331 fgP4.SetPxPyPzE (0.,0.,0.,0.);
332 fgX4.SetXYZT (0.,0.,0.,0.);
336 void GAtmoFlux::CleanUp(
void)
340 map<int,TH3D*>::iterator rawiter = fRawFluxHistoMap.begin();
341 for( ; rawiter != fRawFluxHistoMap.end(); ++rawiter) {
342 TH3D * flux_histogram = rawiter->second;
344 delete flux_histogram;
348 fRawFluxHistoMap.clear();
350 map<int,TH3D*>::iterator iter = fFluxHistoMap.begin();
351 for( ; iter != fFluxHistoMap.end(); ++iter) {
352 TH3D * flux_histogram = iter->second;
354 delete flux_histogram;
358 fFluxHistoMap.clear();
360 if (fTotalFluxHisto)
delete fTotalFluxHisto;
361 if (fPdgCList)
delete fPdgCList;
363 if (fPhiBins ) {
delete[] fPhiBins ; fPhiBins =NULL; }
364 if (fCosThetaBins) {
delete[] fCosThetaBins; fCosThetaBins=NULL; }
365 if (fEnergyBins ) {
delete[] fEnergyBins ; fEnergyBins =NULL; }
369 void GAtmoFlux::SetRadii(
double Rlongitudinal,
double Rtransverse)
371 LOG (
"Flux",
pNOTICE) <<
"Setting R[longitudinal] = " << Rlongitudinal;
372 LOG (
"Flux",
pNOTICE) <<
"Setting R[transverse] = " << Rtransverse;
378 double GAtmoFlux::GetFluxSurfaceArea(
void)
380 return kPi*pow(fRt,2);
383 double GAtmoFlux::GetLongitudinalRadius(
void)
388 double GAtmoFlux::GetTransverseRadius(
void)
394 void GAtmoFlux::AddFluxFile(
int nu_pdg,
string filename)
397 std::ifstream f(filename.c_str());
399 LOG(
"Flux",
pFATAL) <<
"Flux file does not exist "<<filename;
403 fFluxFlavour.push_back(nu_pdg);
404 fFluxFile.push_back(filename);
407 <<
"Input particle code: " << nu_pdg <<
" not a neutrino!";
411 void GAtmoFlux::AddFluxFile(
string filename)
420 std::ifstream f(filename.c_str());
422 LOG(
"Flux",
pFATAL) <<
"Flux file does not exist "<<filename;
426 fFluxFlavour.push_back(
kPdgNuE); fFluxFile.push_back(filename);
427 fFluxFlavour.push_back(
kPdgAntiNuE); fFluxFile.push_back(filename);
428 fFluxFlavour.push_back(
kPdgNuMu); fFluxFile.push_back(filename);
429 fFluxFlavour.push_back(
kPdgAntiNuMu); fFluxFile.push_back(filename);
438 bool GAtmoFlux::LoadFluxData(
void)
441 <<
"Loading atmospheric neutrino flux simulation data";
443 fFluxHistoMap.clear();
446 bool loading_status =
true;
448 for(
unsigned int n=0; n<fFluxFlavour.size(); n++ ){
449 int nu_pdg = fFluxFlavour.at(n);
450 string filename = fFluxFile.at(n);
453 LOG(
"Flux",
pNOTICE) <<
"Loading data for: " << pname;
457 std::map<int,TH3D*>::iterator myMapEntry = fRawFluxHistoMap.find(nu_pdg);
458 if( myMapEntry == fRawFluxHistoMap.end() ){
459 hist = this->CreateFluxHisto(pname.c_str(), pname.c_str());
460 fRawFluxHistoMap.insert( map<int,TH3D*>::value_type(nu_pdg,hist) );
464 bool loaded = this->FillFluxHisto(nu_pdg, filename);
466 loading_status = loading_status && loaded;
470 <<
"Error loading atmospheric neutrino flux simulation data from " << filename;
476 map<int,TH3D*>::iterator hist_iter = fRawFluxHistoMap.begin();
477 for ( ; hist_iter != fRawFluxHistoMap.end(); ++hist_iter) {
478 int nu_pdg = hist_iter->first;
479 TH3D* hist = hist_iter->second;
481 TH3D* hnorm = this->CreateNormalisedFluxHisto( hist );
482 fFluxHistoMap.insert( map<int,TH3D*>::value_type(nu_pdg,hnorm) );
483 fPdgCList->push_back(nu_pdg);
487 <<
"Atmospheric neutrino flux simulation data loaded!";
488 this->AddAllFluxes();
493 <<
"Error loading atmospheric neutrino flux simulation data";
497 TH3D* GAtmoFlux::CreateNormalisedFluxHisto(TH3D* hist)
505 TString histname = hist->GetName();
506 histname.Append(
"_IntegratedFlux");
509 TH3D* hist_intg = (TH3D*)(hist->Clone(histname.Data()));
513 Double_t dN_dEdS = 0.0;
518 for(Int_t e_bin = 1; e_bin <= hist->GetXaxis()->GetNbins(); e_bin++)
520 for(Int_t c_bin = 1; c_bin <= hist->GetYaxis()->GetNbins(); c_bin++)
522 for(Int_t p_bin = 1; p_bin <= hist->GetZaxis()->GetNbins(); p_bin++)
524 dN_dEdS = hist->GetBinContent(e_bin,c_bin,p_bin);
526 dE = hist->GetXaxis()->GetBinUpEdge(e_bin)
527 - hist->GetXaxis()->GetBinLowEdge(e_bin);
529 dS = ( hist->GetZaxis()->GetBinUpEdge(p_bin)
530 - hist->GetZaxis()->GetBinLowEdge(p_bin) )
531 * ( hist->GetYaxis()->GetBinUpEdge(c_bin)
532 - hist->GetYaxis()->GetBinLowEdge(c_bin) );
536 hist_intg->SetBinContent(e_bin,c_bin,p_bin,dN);
544 void GAtmoFlux::ZeroFluxHisto(TH3D * histo)
546 LOG(
"Flux",
pDEBUG) <<
"Forcing flux histogram contents to 0";
551 void GAtmoFlux::AddAllFluxes(
void)
554 <<
"Computing combined flux & flux normalization factor";
556 if(fTotalFluxHisto)
delete fTotalFluxHisto;
558 fTotalFluxHisto = this->CreateFluxHisto(
"sum",
"combined flux" );
560 map<int,TH3D*>::iterator it = fFluxHistoMap.begin();
561 for( ; it != fFluxHistoMap.end(); ++it) {
562 TH3D * flux_histogram = it->second;
563 fTotalFluxHisto->Add(flux_histogram);
566 fTotalFluxHistoIntg = fTotalFluxHisto->Integral();
569 TH3D * GAtmoFlux::CreateFluxHisto(
string name,
string title)
571 LOG(
"Flux",
pNOTICE) <<
"Instantiating histogram: [" << name <<
"]";
572 TH3D * hist =
new TH3D(
573 name.c_str(), title.c_str(),
574 fNumEnergyBins, fEnergyBins,
575 fNumCosThetaBins, fCosThetaBins,
576 fNumPhiBins, fPhiBins);
580 int GAtmoFlux::SelectNeutrino(
double Ev,
double costheta,
double phi)
586 unsigned int n = fPdgCList->size();
587 double * flux =
new double[n];
590 map<int,TH3D*>::iterator it = fFluxHistoMap.begin();
591 for( ; it != fFluxHistoMap.end(); ++it) {
592 TH3D * flux_histogram = it->second;
593 int ibin = flux_histogram->FindBin(Ev,costheta,phi);
594 flux[i] = flux_histogram->GetBinContent(ibin);
602 <<
"Sum{Flux(0->" << i <<
")} = " << flux[i];
606 double R = flux_sum * rnd->
RndFlux().Rndm();
613 int selected_pdg = (*fPdgCList)[i];
615 <<
"Selected neutrino PDG code = " << selected_pdg;
621 LOG(
"Flux",
pERROR) <<
"Could not select a neutrino species!";
628 TH3D* GAtmoFlux::GetFluxHistogram(
int flavour)
631 std::map<int,TH3D*>::iterator it = fRawFluxHistoMap.find(flavour);
632 if(it != fRawFluxHistoMap.end())
634 histogram = it->second;
640 double GAtmoFlux::GetTotalFlux(
void)
643 map<int,TH3D*>::iterator rawiter;
645 rawiter = fRawFluxHistoMap.begin();
646 for (; rawiter != fRawFluxHistoMap.end(); ++rawiter) {
647 TH3D *h = rawiter->second;
649 flux += h->Integral(
"width");
650 LOG(
"Flux",
pDEBUG) <<
"Total flux for " << rawiter->first <<
" equals " << h->Integral(
"width") <<
".";
659 double GAtmoFlux::GetTotalFluxInEnergyRange(
void)
662 map<int,TH3D*>::iterator rawiter;
663 int e_min_bin, e_max_bin;
666 Emin = this->MinEnergy();
667 Emax = this->MaxEnergy();
670 LOG(
"Flux",
pFATAL) <<
"Emax = " << Emax <<
" is less than Emin = " << Emin;
674 rawiter = fRawFluxHistoMap.begin();
675 for (; rawiter != fRawFluxHistoMap.end(); ++rawiter) {
676 TH3D *h = rawiter->second;
681 e_min_bin = h->GetXaxis()->FindBin(Emin);
682 e_max_bin = h->GetXaxis()->FindBin(Emax);
684 if (e_min_bin > h->GetXaxis()->GetNbins()) {
687 }
else if (e_min_bin == e_max_bin) {
691 flux += h->Integral(e_min_bin,e_min_bin,1,h->GetYaxis()->GetNbins(),1,h->GetZaxis()->GetNbins(),
"width")*(Emax - Emin)/(h->GetXaxis()->GetBinUpEdge(e_min_bin)-h->GetXaxis()->GetBinLowEdge(e_min_bin));
696 flux += h->Integral(e_min_bin,e_min_bin,1,h->GetYaxis()->GetNbins(),1,h->GetZaxis()->GetNbins(),
"width")*(h->GetXaxis()->GetBinUpEdge(e_min_bin) - Emin)/(h->GetXaxis()->GetBinUpEdge(e_min_bin)-h->GetXaxis()->GetBinLowEdge(e_min_bin));
699 if (e_min_bin < h->GetXaxis()->GetNbins())
700 flux += h->Integral(e_min_bin+1,e_max_bin-1,1,h->GetYaxis()->GetNbins(),1,h->GetZaxis()->GetNbins(),
"width");
702 if (e_max_bin <= h->GetXaxis()->GetNbins())
703 flux += h->Integral(e_max_bin,e_max_bin,1,h->GetYaxis()->GetNbins(),1,h->GetZaxis()->GetNbins(),
"width")*(Emax - h->GetXaxis()->GetBinLowEdge(e_max_bin))/(h->GetXaxis()->GetBinUpEdge(e_max_bin)-h->GetXaxis()->GetBinLowEdge(e_max_bin));
713 TH3D* flux_hist = this->GetFluxHistogram(flavour);
714 if(!flux_hist)
return 0.0;
717 Double_t dN_dEdS = 0.0;
721 for(Int_t e_bin = 1; e_bin <= flux_hist->GetXaxis()->GetNbins(); e_bin++)
723 for(Int_t c_bin = 1; c_bin <= flux_hist->GetYaxis()->GetNbins(); c_bin++)
725 for( Int_t p_bin = 1; p_bin <= flux_hist->GetZaxis()->GetNbins(); p_bin++)
727 dN_dEdS = flux_hist->GetBinContent(e_bin,c_bin,p_bin);
729 dE = flux_hist->GetXaxis()->GetBinUpEdge(e_bin)
730 - flux_hist->GetXaxis()->GetBinLowEdge(e_bin);
732 dS = ( flux_hist->GetZaxis()->GetBinUpEdge(p_bin)
733 - flux_hist->GetZaxis()->GetBinLowEdge(p_bin) )
734 * ( flux_hist->GetYaxis()->GetBinUpEdge(c_bin)
735 - flux_hist->GetYaxis()->GetBinLowEdge(c_bin) );
737 flux += dN_dEdS*dE*dS;
747 TH3D* flux_hist = this->GetFluxHistogram(flavour);
748 if(!flux_hist)
return 0.0;
751 Double_t dN_dEdS = 0.0;
754 Int_t e_bin = flux_hist->GetXaxis()->FindBin(energy);
756 for(Int_t c_bin = 1; c_bin <= flux_hist->GetYaxis()->GetNbins(); c_bin++)
758 for( Int_t p_bin = 1; p_bin <= flux_hist->GetZaxis()->GetNbins(); p_bin++)
760 dN_dEdS = flux_hist->GetBinContent(e_bin,c_bin,p_bin);
762 dS = ( flux_hist->GetZaxis()->GetBinUpEdge(p_bin)
763 - flux_hist->GetZaxis()->GetBinLowEdge(p_bin) )
764 * ( flux_hist->GetYaxis()->GetBinUpEdge(c_bin)
765 - flux_hist->GetYaxis()->GetBinLowEdge(c_bin) );
776 TH3D* flux_hist = this->GetFluxHistogram(flavour);
777 if(!flux_hist)
return 0.0;
780 Double_t dN_dEdS = 0.0;
783 Int_t e_bin = flux_hist->GetXaxis()->FindBin(energy);
784 Int_t c_bin = flux_hist->GetYaxis()->FindBin(costh);
786 for( Int_t p_bin = 1; p_bin <= flux_hist->GetZaxis()->GetNbins(); p_bin++)
788 dN_dEdS = flux_hist->GetBinContent(e_bin,c_bin,p_bin);
790 dS = ( flux_hist->GetZaxis()->GetBinUpEdge(p_bin)
791 - flux_hist->GetZaxis()->GetBinLowEdge(p_bin) );
801 TH3D* flux_hist = this->GetFluxHistogram(flavour);
802 if(!flux_hist)
return 0.0;
804 Int_t e_bin = flux_hist->GetXaxis()->FindBin(energy);
805 Int_t c_bin = flux_hist->GetYaxis()->FindBin(costh);
806 Int_t p_bin = flux_hist->GetZaxis()->FindBin(phi);
808 Double_t flux = flux_hist->GetBinContent(e_bin,c_bin,p_bin);
string P4AsShortString(const TLorentzVector *p)
bool IsNeutrino(int pdgc)
static RandomGen * Instance()
Access instance.
A singleton holding random number generator classes. All random number generation in GENIE should tak...
GAtmoFlux * GetFlux(void)
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
bool IsAntiNeutrino(int pdgc)
static PDGLibrary * Instance(void)
TParticlePDG * Find(int pdgc, bool must_exist=true)
TRandom3 & RndFlux(void) const
rnd number generator used by flux drivers
string X4AsString(const TLorentzVector *x)
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...