138 #if defined(HAVE_FENV_H) && defined(HAVE_FEENABLEEXCEPT) 145 #include <TVector3.h> 152 #include "Framework/Conventions/GBuild.h" 178 #ifdef __GENIE_FLUX_DRIVERS_ENABLED__ 179 #ifdef __GENIE_GEOM_DRIVERS_ENABLED__ 180 #define __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__ 190 using std::ostringstream;
192 using namespace genie;
202 #ifdef __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__ 203 void GenerateEventsUsingFluxOrTgtMix();
205 GFluxI * FluxDriver (
void);
206 GFluxI * MonoEnergeticFluxDriver (
void);
207 GFluxI * TH1FluxDriver (
void);
249 #if defined(HAVE_FENV_H) && defined(HAVE_FEENABLEEXCEPT) 250 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
257 #ifdef __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__ 258 GenerateEventsUsingFluxOrTgtMix();
261 <<
"\n To be able to generate dark matter events from a flux and/or a target mix" 262 <<
"\n you need to add the following config options at your GENIE installation:" 263 <<
"\n --enable-flux-drivers --enable-geom-drivers \n" ;
275 LOG(
"gmkspl",
pFATAL) <<
" No TuneId in RunOption";
294 int target = gOptTgtMix.begin()->first;
297 double pd = TMath::Sqrt(Ed*Ed - Md*Md);
299 TLorentzVector dm_p4(0.,0.,pd,Ed);
307 <<
"Cross-section risks exceeding unitarity limit - Exiting";
339 <<
"\n ** Will generate " <<
gOptNevents <<
" events for \n" 340 << init_state <<
" at Ev = " << Ed <<
" GeV";
346 <<
" *** Generating event............ " << ievent;
353 <<
"Last attempt failed. Re-trying....";
358 <<
"Generated Event GHEP Record: " << *
event;
372 #ifdef __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__ 374 void GenerateEventsUsingFluxOrTgtMix(
void)
377 GFluxI * flux_driver = FluxDriver();
414 LOG(
"gevgen_dm",
pNOTICE) <<
" *** Generating event............ " << ievent;
419 LOG(
"gevgen_dm",
pNOTICE) <<
"Generated Event GHEP Record: " << *
event;
451 else flux_driver = TH1FluxDriver();
456 GFluxI * MonoEnergeticFluxDriver(
void)
466 GFluxI * TH1FluxDriver(
void)
473 int flux_entries = 100000;
481 bool input_is_text_file = ! gSystem->AccessPathName(
gOptFlux.c_str());
482 bool input_is_root_file =
gOptFlux.find(
".root") != string::npos &&
484 if(input_is_text_file) {
490 double estep = (emax-emin)/(n-1);
491 double ymax = -1, ry = -1, gy = -1,
e = -1;
492 for(
int i=0; i<
n; i++) {
494 ymax = TMath::Max(ymax, input_flux->
Evaluate(
e));
499 spectrum =
new TH1D(
"spectrum",
"dark matter flux", 300, emin, emax);
500 spectrum->SetDirectory(0);
502 for(
int ientry=0; ientry<flux_entries; ientry++) {
508 LOG(
"gevgen_dm",
pFATAL) <<
"Couldn't generate a flux histogram";
511 e = emin + de * r->
RndGen().Rndm();
512 gy = ymax * r->
RndGen().Rndm();
515 if(accept) spectrum->Fill(
e);
520 else if(input_is_root_file) {
525 assert(fv.size()==2);
526 assert( !gSystem->AccessPathName(fv[0].c_str()) );
528 LOG(
"gevgen_dm",
pNOTICE) <<
"Getting input flux from root file: " << fv[0];
529 TFile * flux_file =
new TFile(fv[0].c_str(),
"read");
531 LOG(
"gevgen_dm",
pNOTICE) <<
"Flux name: " << fv[1];
532 TH1D * hst = (TH1D *)flux_file->Get(fv[1].c_str());
535 LOG(
"gevgen_dm",
pNOTICE) << hst->GetEntries();
538 spectrum = (TH1D*)hst->Clone();
539 spectrum->SetNameTitle(
"spectrum",
"dark_matter_flux");
540 spectrum->SetDirectory(0);
541 for(
int ibin = 1; ibin <= hst->GetNbinsX(); ibin++) {
542 if(hst->GetBinLowEdge(ibin) + hst->GetBinWidth(ibin) > emax ||
543 hst->GetBinLowEdge(ibin) < emin) {
544 spectrum->SetBinContent(ibin, 0);
548 LOG(
"gevgen_dm",
pNOTICE) << spectrum->GetEntries();
553 LOG(
"gevgen_dm",
pNOTICE) << spectrum->GetEntries();
559 TF1 * input_func =
new TF1(
"input_func",
gOptFlux.c_str(), emin, emax);
560 spectrum =
new TH1D(
"spectrum",
"dark matter flux", 300, emin, emax);
561 spectrum->SetDirectory(0);
562 spectrum->FillRandom(
"input_func", flux_entries);
567 TFile
f(
"./input-flux.root",
"recreate");
571 TVector3 bdir (0,0,1);
572 TVector3 bspot(0,0,0);
588 LOG(
"gevgen_dm",
pINFO) <<
"Parsing command line arguments";
606 LOG(
"gevgen_dm",
pFATAL) <<
"No Dark Matter tune selected, please select one ";
613 LOG(
"gevgen_dm",
pINFO) <<
"Reading number of events to generate";
617 <<
"Unspecified number of events to generate - Using default";
623 LOG(
"gevgen_dm",
pINFO) <<
"Reading MC run number";
626 LOG(
"gevgen_dm",
pINFO) <<
"Unspecified run number - Using default";
632 LOG(
"gevgen_dm",
pINFO) <<
"Reading output file name";
644 bool using_flux =
false;
646 LOG(
"gevgen_dm",
pINFO) <<
"Reading flux function";
653 <<
"-s option no longer available. Please read the revised code documentation";
664 LOG(
"gevgen_dm",
pINFO) <<
"Reading dark matter energy";
668 if(dme.find(
",") != string::npos) {
671 assert(nurange.size() == 2);
672 double emin = atof(nurange[0].c_str());
673 double emax = atof(nurange[1].c_str());
674 assert(emax>emin && emin>=0);
679 <<
"No flux was specified but an energy range was input!";
681 <<
"Events will be generated at fixed E = " <<
gOptDMEnergy <<
" GeV";
689 LOG(
"gevgen_dm",
pFATAL) <<
"Unspecified dark matter energy - Exiting";
696 LOG(
"gevgen_dm",
pINFO) <<
"Reading dark matter mass";
699 LOG(
"gevgen_dm",
pFATAL) <<
"Unspecified dark matter mass - Exiting";
706 LOG(
"gevgen_dm",
pINFO) <<
"Reading mediator coupling";
709 LOG(
"gevgen_dm",
pINFO) <<
"Unspecified mediator coupling - Using value from config file";
714 bool using_tgtmix =
false;
716 LOG(
"gevgen_dm",
pINFO) <<
"Reading target mix";
720 if(tgtmix.size()==1) {
721 int pdg = atoi(tgtmix[0].c_str());
723 gOptTgtMix.insert(map<int, double>::value_type(pdg, wgt));
727 for( ; tgtmix_iter != tgtmix.end(); ++tgtmix_iter) {
728 string tgt_with_wgt = *tgtmix_iter;
729 string::size_type open_bracket = tgt_with_wgt.find(
"[");
730 string::size_type close_bracket = tgt_with_wgt.find(
"]");
731 string::size_type ibeg = 0;
732 string::size_type iend = open_bracket;
733 string::size_type jbeg = open_bracket+1;
734 string::size_type jend = close_bracket-1;
735 int pdg = atoi(tgt_with_wgt.substr(ibeg,iend).c_str());
736 double wgt = atof(tgt_with_wgt.substr(jbeg,jend).c_str());
738 <<
"Adding to target mix: pdg = " << pdg <<
", wgt = " << wgt;
739 gOptTgtMix.insert(map<int, double>::value_type(pdg, wgt));
744 LOG(
"gevgen_dm",
pFATAL) <<
"Unspecified target PDG code - Exiting";
751 LOG(
"gevgen_dm",
pINFO) <<
"Reading mediator mass ratio";
754 LOG(
"gevgen_dm",
pINFO) <<
"Unspecified mediator mass ratio - Using default";
762 LOG(
"gevgen_dm",
pINFO) <<
"Reading random number seed";
765 LOG(
"gevgen_dm",
pINFO) <<
"Unspecified random number seed - Using default";
771 LOG(
"gevgen_dm",
pINFO) <<
"Reading cross-section file";
774 LOG(
"gevgen_dm",
pINFO) <<
"Unspecified cross-section file";
791 <<
"Random number seed was not set, using default";
800 <<
"No input cross-section spline file";
808 <<
"Dark matter energy: [" 817 <<
"Target code (PDG) & weight fraction (in case of multiple targets): ";
821 for(iter = gOptTgtMix.begin(); iter != gOptTgtMix.end(); ++iter) {
822 int tgtpdgc = iter->first;
823 double wgt = iter->second;
825 <<
" >> " << tgtpdgc <<
" (weight fraction = " << wgt <<
")";
836 <<
"\n\n" <<
"Syntax:" <<
"\n" 837 <<
"\n gevgen_dm [-h]" 840 <<
"\n -e energy (or energy range) " 842 <<
"\n -t target_pdg " 843 <<
"\n [-g zp_coupling]" 844 <<
"\n [-z med_ratio]" 845 <<
"\n [-f flux_description]" 846 <<
"\n [-o outfile_name]" 848 <<
"\n [--seed random_number_seed]" 849 <<
"\n [--cross-sections xml_file]" 850 <<
"\n [--event-generator-list list_name]" 851 <<
"\n [--message-thresholds xml_file]" 852 <<
"\n [--unphysical-event-mask mask]" 853 <<
"\n [--event-record-print-level level]" 854 <<
"\n [--mc-job-status-refresh-rate rate]" 855 <<
"\n [--cache-file root_file]" 866 r->
Get(
"ZpCoupling", gzp);
867 double gzp4 = TMath::Power(gzp,4);
869 double Mzp2 = Mzp*Mzp;
871 double xsec_est = gzp4 / (4. *
kPi * Mzp2);
878 double pcm2 = M2 * (Ed2 - ml2) / (ml2 + M2 + 2.*M*Ed);
879 double xsec_lim =
kPi / pcm2;
880 bool unitary = xsec_lim > xsec_est;
883 <<
"Estimated a cross-section " << xsec_est/
cm2 <<
" cm^2";
885 <<
"Unitarity limit set to " << xsec_lim/
cm2 <<
" cm^2";
void RandGen(long int seed)
static void SetPrintLevel(int print_level)
void XSecTable(string inpfile, bool require_table)
void GenerateEventsAtFixedInitState(void)
void SetUnphysEventMask(const TBits &mask)
double ArgAsDouble(char opt)
Physical System of Units.
string ArgAsString(char opt)
THE MAIN GENIE PROJECT NAMESPACE
bool CheckUnitarityLimit(void)
void AddDarkMatter(double mass, double med_ratio)
static const double kNucleonMass
static RandomGen * Instance()
Access instance.
void SetEventGeneratorList(string listname)
void CustomizeFilename(string filename)
void ReadFromCommandLine(int argc, char **argv)
A numeric analysis tool class for interpolating 1-D functions.
int main(int argc, char **argv)
void Update(int iev, const EventRecord *event)
void CustomizeFilename(string filename)
double Evaluate(double x) const
A singleton holding random number generator classes. All random number generation in GENIE should tak...
Registry * CommonList(const string &file_id, const string &set_name) const
void SetRefreshRate(int rate)
void UseFluxDriver(GFluxI *flux)
Simple class to create & update MC job status files and env. vars. This is used to be able to keep tr...
A GENIE `MC Job Driver'. Can be used for setting up complicated event generation cases involving deta...
void Get(RgKey key, const RegistryItemI *&item) const
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
void SetEventGeneratorList(string listname)
static constexpr double cm2
void ForceSingleProbScale(void)
A generic GENIE flux driver. Generates a 'cylindrical' neutrino beam along the input direction...
A simple GENIE flux driver for monoenergetic neutrinos along the z direction. Can handle a mix of neu...
NtpMCFormat_t kDefOptNtpFormat
void GetCommandLineArgs(int argc, char **argv)
void Configure(bool calc_prob_scales=true)
void Save(void)
get the even tree
GENIE Event Generation Driver. A minimalist user interface object for generating neutrino interaction...
void Lock(void)
locks the registry
void AddEventRecord(int ievent, const EventRecord *ev_rec)
save the event tree
void SetTransverseRadius(double Rt)
Misc GENIE control constants.
void SetNuDirection(const TVector3 &direction)
map< int, double > gOptTgtMix
void BuildTune()
build tune and inform XSecSplineList
EventRecord * GenerateEvent(void)
void UnLock(void)
unlocks the registry (doesn't unlock items)
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
void Initialize(void)
add event
static PDGLibrary * Instance(void)
static RunOpt * Instance(void)
vector< string > Split(string input, string delim)
A utility class to facilitate creating the GENIE MC Ntuple from the output GENIE GHEP event records...
A registry. Provides the container for algorithm configuration parameters.
TRandom3 & RndGen(void) const
rnd number generator for generic usage
void Configure(int nu_pdgc, int Z, int A)
bool gOptUsingFluxOrTgtMix
string PrintFramedMesg(string mesg, unsigned int nl=1, const char f='*')
A vector of EventGeneratorI objects.
void SetBeamSpot(const TVector3 &spot)
void MesgThresholds(string inpfile)
void AddEnergySpectrum(int nu_pdgc, TH1D *spectrum)
Command line argument parser.
enum genie::ENtpMCFormat NtpMCFormat_t
Defines the GENIE Geometry Analyzer Interface.
static const unsigned int kRjMaxIterations
void SetUnphysEventMask(const TBits &mask)
void Set(RgIMapPair entry)
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
void UseGeomAnalyzer(GeomAnalyzerI *geom)
void UseSplines(bool useLogE=true)
The PointGeomAnalyzer class is the simplest implementation of the GeomAnalyserI interface and defines...
bool OptionExists(char opt)
was option set?
void CacheFile(string inpfile)
void EnableBareXSecPreCalc(bool flag)
Event finding and building.
static AlgConfigPool * Instance()
Initial State information.
GENIE Interface for user-defined flux classes.
EventRecord * GenerateEvent(const TLorentzVector &nu4p)