138#if defined(HAVE_FENV_H) && defined(HAVE_FEENABLEEXCEPT)
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__
190using std::ostringstream;
192using namespace genie;
202#ifdef __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__
203void GenerateEventsUsingFluxOrTgtMix();
205GFluxI * FluxDriver (
void);
206GFluxI * MonoEnergeticFluxDriver (
void);
207GFluxI * TH1FluxDriver (
void);
235int main(
int argc,
char ** argv)
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";
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;
362 mcjmonitor.
Update(ievent,event);
372#ifdef __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__
374void 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;
422 ntpw.AddEventRecord(ievent, event);
423 mcjmonitor.Update(ievent,event);
451 else flux_driver = TH1FluxDriver();
456GFluxI * MonoEnergeticFluxDriver(
void)
466GFluxI * 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);
547 bool force_binwidth =
false;
548#if ROOT_VERSION_CODE <= ROOT_VERSION(9,99,99)
553 TAxis* xaxis = spectrum->GetXaxis();
554 if (xaxis->IsVariableBinSize()) force_binwidth =
true;
556 if ( force_binwidth ) {
557 for(
int ibin = 1; ibin <= spectrum->GetNbinsX(); ++ibin) {
558 double data = spectrum->GetBinContent(ibin);
559 double width = spectrum->GetBinWidth(ibin);
560 spectrum->SetBinContent(ibin,data*width);
565 LOG(
"gevgen_dm",
pNOTICE) << spectrum->GetEntries();
570 LOG(
"gevgen_dm",
pNOTICE) << spectrum->GetEntries();
576 TF1 * input_func =
new TF1(
"input_func",
gOptFlux.c_str(), emin, emax);
577 spectrum =
new TH1D(
"spectrum",
"dark matter flux", 300, emin, emax);
578 spectrum->SetDirectory(0);
579 spectrum->FillRandom(
"input_func", flux_entries);
584 TFile f(
"./input-flux.root",
"recreate");
588 TVector3 bdir (0,0,1);
589 TVector3 bspot(0,0,0);
591 flux->SetNuDirection (bdir);
592 flux->SetBeamSpot (bspot);
593 flux->SetTransverseRadius (-1);
605 LOG(
"gevgen_dm",
pINFO) <<
"Parsing command line arguments";
623 LOG(
"gevgen_dm",
pFATAL) <<
"No Dark Matter tune selected, please select one ";
630 LOG(
"gevgen_dm",
pINFO) <<
"Reading number of events to generate";
634 <<
"Unspecified number of events to generate - Using default";
640 LOG(
"gevgen_dm",
pINFO) <<
"Reading MC run number";
643 LOG(
"gevgen_dm",
pINFO) <<
"Unspecified run number - Using default";
649 LOG(
"gevgen_dm",
pINFO) <<
"Reading output file name";
661 bool using_flux =
false;
663 LOG(
"gevgen_dm",
pINFO) <<
"Reading flux function";
670 <<
"-s option no longer available. Please read the revised code documentation";
681 LOG(
"gevgen_dm",
pINFO) <<
"Reading dark matter energy";
685 if(dme.find(
",") != string::npos) {
688 assert(nurange.size() == 2);
689 double emin = atof(nurange[0].c_str());
690 double emax = atof(nurange[1].c_str());
691 assert(emax>emin && emin>=0);
696 <<
"No flux was specified but an energy range was input!";
698 <<
"Events will be generated at fixed E = " <<
gOptDMEnergy <<
" GeV";
706 LOG(
"gevgen_dm",
pFATAL) <<
"Unspecified dark matter energy - Exiting";
713 LOG(
"gevgen_dm",
pINFO) <<
"Reading dark matter mass";
716 LOG(
"gevgen_dm",
pFATAL) <<
"Unspecified dark matter mass - Exiting";
723 LOG(
"gevgen_dm",
pINFO) <<
"Reading mediator coupling";
726 LOG(
"gevgen_dm",
pINFO) <<
"Unspecified mediator coupling - Using value from config file";
731 bool using_tgtmix =
false;
733 LOG(
"gevgen_dm",
pINFO) <<
"Reading target mix";
737 if(tgtmix.size()==1) {
738 int pdg = atoi(tgtmix[0].c_str());
743 vector<string>::const_iterator tgtmix_iter = tgtmix.begin();
744 for( ; tgtmix_iter != tgtmix.end(); ++tgtmix_iter) {
745 string tgt_with_wgt = *tgtmix_iter;
746 string::size_type open_bracket = tgt_with_wgt.find(
"[");
747 string::size_type close_bracket = tgt_with_wgt.find(
"]");
748 string::size_type ibeg = 0;
749 string::size_type iend = open_bracket;
750 string::size_type jbeg = open_bracket+1;
751 string::size_type jend = close_bracket-1;
752 int pdg = atoi(tgt_with_wgt.substr(ibeg,iend).c_str());
753 double wgt = atof(tgt_with_wgt.substr(jbeg,jend).c_str());
755 <<
"Adding to target mix: pdg = " <<
pdg <<
", wgt = " << wgt;
761 LOG(
"gevgen_dm",
pFATAL) <<
"Unspecified target PDG code - Exiting";
768 LOG(
"gevgen_dm",
pINFO) <<
"Reading mediator mass ratio";
771 LOG(
"gevgen_dm",
pINFO) <<
"Unspecified mediator mass ratio - Using default";
779 LOG(
"gevgen_dm",
pINFO) <<
"Reading random number seed";
782 LOG(
"gevgen_dm",
pINFO) <<
"Unspecified random number seed - Using default";
788 LOG(
"gevgen_dm",
pINFO) <<
"Reading cross-section file";
791 LOG(
"gevgen_dm",
pINFO) <<
"Unspecified cross-section file";
808 <<
"Random number seed was not set, using default";
817 <<
"No input cross-section spline file";
825 <<
"Dark matter energy: ["
834 <<
"Target code (PDG) & weight fraction (in case of multiple targets): ";
837 map<int,double>::const_iterator iter;
839 int tgtpdgc = iter->first;
840 double wgt = iter->second;
842 <<
" >> " << tgtpdgc <<
" (weight fraction = " << wgt <<
")";
853 <<
"\n\n" <<
"Syntax:" <<
"\n"
854 <<
"\n gevgen_dm [-h]"
857 <<
"\n -e energy (or energy range) "
859 <<
"\n -t target_pdg "
860 <<
"\n [-g zp_coupling]"
861 <<
"\n [-z med_ratio]"
862 <<
"\n [-f flux_description]"
863 <<
"\n [-o outfile_name]"
865 <<
"\n [--seed random_number_seed]"
866 <<
"\n [--cross-sections xml_file]"
867 <<
"\n [--event-generator-list list_name]"
868 <<
"\n [--message-thresholds xml_file]"
869 <<
"\n [--unphysical-event-mask mask]"
870 <<
"\n [--event-record-print-level level]"
871 <<
"\n [--mc-job-status-refresh-rate rate]"
872 <<
"\n [--cache-file root_file]"
883 r->
Get(
"ZpCoupling", gzp);
884 double gzp4 = TMath::Power(gzp,4);
886 double Mzp2 = Mzp*Mzp;
888 double xsec_est = gzp4 / (4. *
kPi * Mzp2);
895 double pcm2 = M2 * (Ed2 - ml2) / (ml2 + M2 + 2.*M*Ed);
896 double xsec_lim =
kPi / pcm2;
897 bool unitary = xsec_lim > xsec_est;
900 <<
"Estimated a cross-section " << xsec_est/
cm2 <<
" cm^2";
902 <<
"Unitarity limit set to " << xsec_lim/
cm2 <<
" cm^2";
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE,...
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils.
static AlgConfigPool * Instance()
Registry * CommonList(const string &file_id, const string &set_name) const
Command line argument parser.
string ArgAsString(char opt)
double ArgAsDouble(char opt)
bool OptionExists(char opt)
was option set?
A vector of EventGeneratorI objects.
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
GENIE Event Generation Driver. A minimalist user interface object for generating neutrino interaction...
void SetUnphysEventMask(const TBits &mask)
void Configure(int nu_pdgc, int Z, int A)
EventRecord * GenerateEvent(const TLorentzVector &nu4p)
void SetEventGeneratorList(string listname)
GENIE Interface for user-defined flux classes.
static void SetPrintLevel(int print_level)
A GENIE ‘MC Job Driver’. Can be used for setting up complicated event generation cases involving deta...
void ForceSingleProbScale(void)
void UseFluxDriver(GFluxI *flux)
void UseGeomAnalyzer(GeomAnalyzerI *geom)
void Configure(bool calc_prob_scales=true)
void UseSplines(bool useLogE=true)
void SetUnphysEventMask(const TBits &mask)
void SetEventGeneratorList(string listname)
EventRecord * GenerateEvent(void)
Simple class to create & update MC job status files and env. vars. This is used to be able to keep tr...
void CustomizeFilename(string filename)
void Update(int iev, const EventRecord *event)
void SetRefreshRate(int rate)
Defines the GENIE Geometry Analyzer Interface.
Initial State information.
A utility class to facilitate creating the GENIE MC Ntuple from the output GENIE GHEP event records.
void CustomizeFilename(string filename)
void Initialize(void)
add event
void Save(void)
get the even tree
void AddEventRecord(int ievent, const EventRecord *ev_rec)
save the event tree
void AddDarkMatter(double mass, double med_ratio)
static PDGLibrary * Instance(void)
A singleton holding random number generator classes. All random number generation in GENIE should tak...
static RandomGen * Instance()
Access instance.
TRandom3 & RndGen(void) const
rnd number generator for generic usage
A registry. Provides the container for algorithm configuration parameters.
void Lock(void)
locks the registry
void Set(RgIMapPair entry)
void Get(RgKey key, const RegistryItemI *&item) const
void UnLock(void)
unlocks the registry (doesn't unlock items)
void ReadFromCommandLine(int argc, char **argv)
void BuildTune()
build tune and inform XSecSplineList
void EnableBareXSecPreCalc(bool flag)
static RunOpt * Instance(void)
A numeric analysis tool class for interpolating 1-D functions.
double Evaluate(double x) const
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...
The PointGeomAnalyzer class is the simplest implementation of the GeomAnalyserI interface and defines...
NtpMCFormat_t kDefOptNtpFormat
map< int, double > gOptTgtMix
void GenerateEventsAtFixedInitState(void)
void GetCommandLineArgs(int argc, char **argv)
bool CheckUnitarityLimit(void)
bool gOptUsingFluxOrTgtMix
static const double kNucleonMass
Misc GENIE control constants.
static const unsigned int kRjMaxIterations
Utilities for improving the code readability when using PDG codes.
Physical System of Units.
static constexpr double cm2
void XSecTable(string inpfile, bool require_table)
void RandGen(long int seed)
void MesgThresholds(string inpfile)
void CacheFile(string inpfile)
string PrintFramedMesg(string mesg, unsigned int nl=1, const char f=' *')
vector< string > Split(string input, string delim)
THE MAIN GENIE PROJECT NAMESPACE
enum genie::ENtpMCFormat NtpMCFormat_t