27 using namespace genie;
28 using namespace genie::flux;
29 using namespace genie::constants;
32 GAstroFlux::GAstroFlux()
37 GAstroFlux::~GAstroFlux()
42 double GAstroFlux::MaxEnergy(
void)
47 bool GAstroFlux::GenerateNext(
void)
50 this->ResetSelection();
52 if(!fEnergySpectrum) {
55 if(!fSolidAngleAcceptance) {
58 if(fRelNuPopulations.size() == 0) {
67 double log10Emin = TMath::Log10(TMath::Max(
kAstroDefMinEv,fMinEvCut));
68 double log10Emax = TMath::Log10(TMath::Min(
kAstroDefMaxEv,fMaxEvCut));
70 double wght_species = 1.;
71 double wght_energy = 1.;
72 double wght_origin = 1.;
75 double log10E = -99999;
77 double costheta = -999999;
81 status = fNuGen->SelectNuPdg(
82 fGenWeighted, fRelNuPopulations, nupdg, wght_species);
87 status = fNuGen->SelectEnergy(
88 fGenWeighted, *fEnergySpectrum, log10Emin, log10Emax, log10E, wght_energy);
92 double Ev = TMath::Power(10.,log10E);
94 status = fNuGen->SelectOrigin(
95 fGenWeighted, *fSolidAngleAcceptance, phi, costheta, wght_origin);
105 status = fNuPropg->Go(phi, costheta, fDetCenter, fDetSize, nupdg, Ev);
110 int pnupdg = fNuPropg->NuPdgAtDetVolBoundary();
111 TVector3 & px3 = fNuPropg->X3AtDetVolBoundary();
112 TVector3 & pp3 = fNuPropg->P3AtDetVolBoundary();
118 px3 = fRotGEF2THz * px3;
119 pp3 = fRotGEF2THz * pp3;
122 px3 = fRotTHz2User * px3;
123 pp3 = fRotTHz2User * pp3;
128 fgWeight = wght_species * wght_energy * wght_origin;
133 fgP4.SetE(pp3.Mag());
138 void GAstroFlux::ForceMinEnergy(
double emin)
144 void GAstroFlux::ForceMaxEnergy(
double emax)
150 void GAstroFlux::Clear(Option_t * opt)
154 LOG(
"Flux",
pERROR) <<
"No clear method implemented for option:"<< opt;
157 void GAstroFlux::GenerateWeighted(
bool gen_weighted)
159 fGenWeighted = gen_weighted;
162 void GAstroFlux::SetDetectorPosition(
163 double latitude,
double longitude,
double depth,
double size)
168 assert(latitude >= -
kPi/2. && latitude <=
kPi/2.);
169 assert(longitude >= 0. && longitude < 2.*
kPi );
172 fDetGeoLatitude = latitude;
173 fDetGeoLongitude = longitude;
174 fDetGeoDepth = depth;
183 double radius = REarth - fDetGeoDepth;
185 double theta =
kPi/2. - fDetGeoLatitude;
186 double phi = fDetGeoLongitude;
188 double sintheta = TMath::Sin(theta);
189 double costheta = TMath::Cos(theta);
190 double sinphi = TMath::Sin(phi);
191 double cosphi = TMath::Cos(phi);
193 double xdc = radius * sintheta * cosphi;
194 double ydc = radius * sintheta * sinphi;
195 double zdc = radius * costheta;
197 fDetCenter.SetXYZ(xdc,ydc,zdc);
208 void GAstroFlux::SetRelNuPopulations(
209 double nnue,
double nnumu,
double nnutau,
210 double nnuebar,
double nnumubar,
double nnutaubar)
212 fRelNuPopulations.clear();
216 fRelNuPopulations.insert(
217 map<int,double>::value_type(
kPdgNuE, nnue));
221 fRelNuPopulations.insert(
222 map<int,double>::value_type(
kPdgNuMu, nnumu));
226 fRelNuPopulations.insert(
227 map<int,double>::value_type(
kPdgNuTau, nnutau));
231 fRelNuPopulations.insert(
232 map<int,double>::value_type(
kPdgAntiNuE, nnuebar));
236 fRelNuPopulations.insert(
241 fRelNuPopulations.insert(
246 double tot = nnue + nnumu + nnutau + nnuebar + nnumubar + nnutaubar;
250 map<int,double>::iterator iter = fRelNuPopulations.begin();
251 for ( ; iter != fRelNuPopulations.end(); ++iter) {
252 double fraction = iter->second;
253 double norm_fraction = fraction/tot;
254 fRelNuPopulations[iter->first] = norm_fraction;
258 void GAstroFlux::SetEnergyPowLawIdx(
double n)
260 if(fEnergySpectrum)
delete fEnergySpectrum;
267 fEnergySpectrum->SetDirectory(0);
270 double log10E = fEnergySpectrum->GetBinCenter(i);
271 double Ev = TMath::Power(10., log10E);
272 double flux = TMath::Power(Ev, -1*n);
273 fEnergySpectrum->SetBinContent(i,flux);
277 double max = fEnergySpectrum->GetMaximum();
278 fEnergySpectrum->Scale(1./max);
281 void GAstroFlux::SetUserCoordSystem(TRotation & rotation)
283 fRotTHz2User = rotation;
288 LOG(
"Flux",
pNOTICE) <<
"Initializing flux driver";
290 bool allow_dup =
false;
301 fDetGeoLatitude = -1.;
302 fDetGeoLongitude = -1.;
305 fDetCenter.SetXYZ(0,0,0);
309 fSolidAngleAcceptance = 0;
319 fRelNuPopulations.clear();
322 fRotGEF2THz.SetToIdentity();
323 fRotTHz2User.SetToIdentity();
330 this->ResetSelection();
333 void GAstroFlux::ResetSelection(
void)
338 fgP4.SetPxPyPzE (0.,0.,0.,0.);
339 fgX4.SetXYZT (0.,0.,0.,0.);
342 void GAstroFlux::CleanUp(
void)
346 fRelNuPopulations.clear();
350 if(fEnergySpectrum)
delete fEnergySpectrum;
351 if(fSolidAngleAcceptance)
delete fSolidAngleAcceptance;
363 bool GAstroFlux::NuGenerator::SelectNuPdg (
364 bool weighted,
const map<int,double> & nupdgpdf,
365 int & nupdg,
double & wght)
372 if(nupdgpdf.size() == 0) {
381 unsigned int nnu = nupdgpdf.size();
382 unsigned int inu = rnd->
RndFlux().Integer(nnu);
383 map<int,double>::const_iterator iter = nupdgpdf.begin();
392 double xrnd = rnd->
RndFlux().Uniform();
393 map<int,double>::const_iterator iter = nupdgpdf.begin();
394 for( ; iter != nupdgpdf.end(); ++iter) {
395 xsum += iter->second;
411 bool GAstroFlux::NuGenerator::SelectEnergy(
412 bool weighted, TH1D & log10Epdf,
double log10Emin,
double log10Emax,
413 double & log10E,
double & wght)
421 if(log10Emax <= log10Emin) {
429 log10E = log10Emin + (log10Emax-log10Emin) * rnd->
RndFlux().Rndm();
430 wght = log10Epdf.GetBinContent(log10Epdf.FindBin(log10E));
437 log10E = log10Epdf.GetRandom();
439 while(log10E < log10Emin || log10E > log10Emax);
446 bool GAstroFlux::NuGenerator::SelectOrigin(
447 bool weighted, TH2D & opdf,
448 double & phi,
double & costheta,
double & wght)
459 costheta = -1. + 2.*rnd->
RndFlux().Rndm();
460 wght = opdf.GetBinContent(opdf.FindBin(phi,costheta));
466 opdf.GetRandom2(phi,costheta);
473 bool GAstroFlux::NuPropagator::Go(
474 double phi,
double costheta,
const TVector3 & detector_centre,
475 double detector_sz,
int nu_pdg,
double Ev)
483 double sintheta = TMath::Sqrt(1-costheta*costheta);
484 double cosphi = TMath::Cos(phi);
485 double sinphi = TMath::Sin(phi);
487 double zs = REarth * costheta;
488 double ys = REarth * sintheta * cosphi;
489 double xs = REarth * sintheta * sinphi;
491 TVector3 start_position(xs,ys,zs);
492 fX3 = start_position - detector_centre;
497 TVector3 direction_unit_vec = -1. * fX3.Unit();
498 fP3 = Ev * direction_unit_vec;
504 LOG(
"Flux",
pWARN) <<
"|dist| = " << fX3.Mag();
505 LOG(
"Flux",
pWARN) <<
"|detsize| = " << detector_sz;
508 double currdist = fX3.Mag();
509 if(currdist <= detector_sz - 0.1)
break;
511 double stepsz = (currdist-detector_sz > fStepSize) ?
512 fStepSize : currdist-detector_sz;
513 if(stepsz <= 0.)
break;
524 fX3 += (stepsz * direction_unit_vec);
536 GDiffuseAstroFlux::GDiffuseAstroFlux() :
575 string name,
double ra,
double dec,
double rel_intensity)
578 (ra >= 0. && ra < 2.*
kPi) &&
579 (dec >= -
kPi/2. && dec <=
kPi/2.) &&
580 (rel_intensity > 0) &&
586 fPntSrcName.insert( map<int, string>::value_type(
id, name ) );
587 fPntSrcRA. insert( map<int, double>::value_type(
id, ra ) );
588 fPntSrcDec. insert( map<int, double>::value_type(
id, dec ) );
589 fPntSrcRelI.insert( map<int, double>::value_type(
id, rel_intensity) );
605 unsigned int srcid = 0;
613 srcid = rnd->
RndFlux().Integer(nsrc);
622 map<int,double>::const_iterator piter =
fPntSrcRelI.begin();
624 xsum += piter->second;
626 srcid = piter->first;
bool fGenWeighted
(config) generate a weighted or unweighted flux?
static RandomGen * Instance()
Access instance.
const double kAstroDefMaxEv
static constexpr double km
map< int, double > fPntSrcRelI
relative intensity
A singleton holding random number generator classes. All random number generation in GENIE should tak...
map< int, string > fPntSrcName
point source name
double fPntSrcTotI
sum of all relative intensities
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
static constexpr double GeV
void AddPointSource(string name, double ra, double dec, double rel_intensity)
unsigned int fSelSourceId
static const double kREarth
map< int, double > fPntSrcDec
declination
map< int, double > fPntSrcRA
right ascension
static constexpr double zs
const int kAstroNlog10EvBins
vector< vector< double > > clear
TRandom3 & RndFlux(void) const
rnd number generator used by flux drivers
A base class for the concrete astrophysical neutrino flux drivers.
bool GenerateNext(void)
generate the next flux neutrino (return false in err)
static constexpr double ys
const double kAstroDefMinEv
static constexpr double m
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
double fgWeight
(current) generated nu weight