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...