GENIEGenerator
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gtestGAtmoFlux.cxx
Go to the documentation of this file.
1 //____________________________________________________________________________
2 /*!
3 
4 \program gtestGAtmoFlux
5 
6 \brief Program used for testing the GAtmoFlux class
7 
8 \author Anthony LaTorre <tlatorre at uchicago dot edu>
9 
10 \created March 31, 2020
11 
12 \cpright Copyright (c) 2003-2024, The GENIE Collaboration
13  For the full text of the license visit http://copyright.genie-mc.org
14 
15 */
16 //____________________________________________________________________________
17 //
18 
19 #include <cstdio>
21 #include "Tools/Flux/GAtmoFlux.h"
23 #include <stdlib.h> /* For getenv(). */
24 #include "TH3D.h"
26 
27 #define UNUSED(V) ((void) V)
28 
29 /* Macro to compute the size of a static C array.
30  *
31  * See https://stackoverflow.com/questions/1598773. */
32 #define LEN(x) ((sizeof(x)/sizeof(0[x]))/((size_t)(!(sizeof(x) % sizeof(0[x])))))
33 
34 typedef int testFunction(char *err);
35 
36 int isclose(double a, double b, double rel_tol, double abs_tol)
37 {
38  /* Returns 1 if a and b are "close". This algorithm is taken from Python's
39  * math.isclose() function.
40  *
41  * See https://www.python.org/dev/peps/pep-0485/. */
42  return fabs(a-b) <= fmax(rel_tol*fmax(fabs(a),fabs(b)),abs_tol);
43 }
44 
45 using namespace genie;
46 using namespace genie::flux;
47 
48 /* Tests the GetTotalFlux() function. */
49 int testGetTotalFlux(char *err)
50 {
51  GAtmoFlux *atmo_flux_driver;
52  double emin, emax, value, expected;
53  char filename[256];
54 
55  sprintf(filename, "%s/src/contrib/test/fmax20_i0403z.sno_nue", getenv("GENIE"));
56 
57  GBGLRSAtmoFlux *bartol_flux = new GBGLRSAtmoFlux;
58  atmo_flux_driver = dynamic_cast<GAtmoFlux *>(bartol_flux);
59 
60  emin = -1;
61  emax = 1e9;
62 
63  // Configure GAtmoFlux options (common to all concrete atmospheric flux drivers)
64  // set min/max energy:
65  atmo_flux_driver->ForceMinEnergy(emin * units::GeV);
66  atmo_flux_driver->ForceMaxEnergy(emax * units::GeV);
67  // set flux files:
68  atmo_flux_driver->AddFluxFile(12, filename);
69  atmo_flux_driver->LoadFluxData();
70 
71  value = atmo_flux_driver->GetTotalFlux();
72  expected = atmo_flux_driver->GetFlux(12);
73 
74  /* Test that GetTotalFlux() is the same as GetFlux(12) since we are only
75  * including a single neutrino flavour. */
76  if (value != expected) {
77  sprintf(err, "GetTotalFlux() = %f which is not equal to GetFlux(12) = %f", value, expected);
78  goto err;
79  }
80 
81  delete atmo_flux_driver;
82 
83  return 0;
84 
85 err:
86  delete atmo_flux_driver;
87 
88  return 1;
89 }
90 
91 /* Tests the GetTotalFluxInEnergyRange() function. */
93 {
94  GAtmoFlux *atmo_flux_driver;
95  double emin, emax, value, expected;
96  char filename[256];
97 
98  sprintf(filename, "%s/src/contrib/test/fmax20_i0403z.sno_nue", getenv("GENIE"));
99 
100  GBGLRSAtmoFlux *bartol_flux = new GBGLRSAtmoFlux;
101  atmo_flux_driver = dynamic_cast<GAtmoFlux *>(bartol_flux);
102 
103  // set flux files:
104  atmo_flux_driver->AddFluxFile(12, filename);
105  atmo_flux_driver->LoadFluxData();
106 
107  emin = 0;
108  emax = 1e4;
109 
110  // Configure GAtmoFlux options (common to all concrete atmospheric flux drivers)
111  // set min/max energy:
112  atmo_flux_driver->ForceMinEnergy(emin * units::GeV);
113  atmo_flux_driver->ForceMaxEnergy(emax * units::GeV);
114 
115  value = atmo_flux_driver->GetTotalFlux();
116  expected = atmo_flux_driver->GetTotalFluxInEnergyRange();
117 
118  if (value != expected) {
119  sprintf(err, "GetTotalFlux(%.2f,%.2f) = %f which is not equal to the expected total flux = %f", emin, emax, value, expected);
120  goto err;
121  }
122 
123  /* Now set emin and emax both to 10 GeV and make sure we get 0. */
124  emin = 1e4;
125  emax = 1e4;
126 
127  atmo_flux_driver->ForceMinEnergy(emin * units::GeV);
128  atmo_flux_driver->ForceMaxEnergy(emax * units::GeV);
129 
130  value = atmo_flux_driver->GetTotalFluxInEnergyRange();
131  expected = 0;
132 
133  if (value != expected) {
134  sprintf(err, "GetTotalFlux(%.1e,%.1e) = %f, but expected %f!", emin, emax, value, expected);
135  goto err;
136  }
137 
138  /* Now set emin and emax both below the bounds and make sure we get 0. */
139  emin = 0;
140  emax = 0.01;
141 
142  atmo_flux_driver->ForceMinEnergy(emin * units::GeV);
143  atmo_flux_driver->ForceMaxEnergy(emax * units::GeV);
144 
145  value = atmo_flux_driver->GetTotalFluxInEnergyRange();
146  expected = 0;
147 
148  if (value != expected) {
149  sprintf(err, "GetTotalFlux(%.1e,%.1e) = %f, but expected %f!", emin, emax, value, expected);
150  return 1;
151  }
152 
153  /* Now we test when both emin and emax are in the same bin. */
154  emin = 0.106;
155  emax = 0.11;
156 
157  atmo_flux_driver->ForceMinEnergy(emin * units::GeV);
158  atmo_flux_driver->ForceMaxEnergy(emax * units::GeV);
159 
160  value = atmo_flux_driver->GetTotalFluxInEnergyRange();
161  expected = atmo_flux_driver->GetFlux(12,emin)*(emax-emin);
162 
163  if (!isclose(value,expected,1e-5,0)) {
164  sprintf(err, "GetTotalFlux(%.3f,%.3f) = %f, but expected %f!", emin, emax, value, expected);
165  goto err;
166  }
167 
168  /* Now we test when emin and emax are just past the low and high bin edges. */
169  emin = 0.10 + 1e-10;
170  emax = 10.0 - 1e-10;
171 
172  atmo_flux_driver->ForceMinEnergy(emin * units::GeV);
173  atmo_flux_driver->ForceMaxEnergy(emax * units::GeV);
174 
175  value = atmo_flux_driver->GetTotalFluxInEnergyRange();
176  expected = atmo_flux_driver->GetTotalFlux();
177 
178  if (!isclose(value,expected,1e-5,0)) {
179  sprintf(err, "GetTotalFlux(%.3f,%.3f) = %f, but expected %f!", emin, emax, value, expected);
180  goto err;
181  }
182 
183  delete atmo_flux_driver;
184 
185  return 0;
186 
187 err:
188  delete atmo_flux_driver;
189 
190  return 1;
191 }
192 
193 struct tests {
195  const char *name;
196 } tests[] = {
197  {testGetTotalFlux, "testGetTotalFlux"},
198  {testGetTotalFluxInEnergyRange, "testGetTotalFluxInEnergyRange"},
199 };
200 
201 int main(int argc, char **argv)
202 {
203  unsigned int i;
204  char err[256];
205  int retval = 0;
206  struct tests test;
207 
208  UNUSED(argc);
209  UNUSED(argv);
210 
211  /* Don't print low level messages so we get a nice output. */
212  Messenger * msg = Messenger::Instance();
213  msg->SetPriorityLevel("Flux", pFATAL);
214 
215  for (i = 0; i < LEN(tests); i++) {
216  test = tests[i];
217 
218  if (!test.test(err)) {
219  printf("[\033[92mok\033[0m] %s\n", test.name);
220  } else {
221  printf("[\033[91mfail\033[0m] %s: %s\n", test.name, err);
222  retval = 1;
223  }
224  }
225 
226  return retval;
227 }
#define UNUSED(V)
Program used for testing the GAtmoFlux class.
#define pFATAL
Definition: Messenger.h:56
double GetTotalFluxInEnergyRange(void)
Definition: GAtmoFlux.cxx:659
double GetFlux(int flavour)
Definition: GAtmoFlux.cxx:711
int main(int argc, char **argv)
Definition: gAtmoEvGen.cxx:327
static constexpr double b
Definition: Units.h:78
const double e
void ForceMaxEnergy(double emax)
Definition: GAtmoFlux.cxx:233
static constexpr double GeV
Definition: Units.h:28
const double a
static Messenger * Instance(void)
Definition: Messenger.cxx:49
testFunction * test
int testGetTotalFluxInEnergyRange(char *err)
int testGetTotalFlux(char *err)
int isclose(double a, double b, double rel_tol, double abs_tol)
int testFunction(char *err)
double GetTotalFlux(void)
Definition: GAtmoFlux.cxx:640
A more convenient interface to the log4cpp Message Service.
Definition: Messenger.h:258
const char * name
void SetPriorityLevel(const char *stream, log4cpp::Priority::Value p)
Definition: Messenger.cxx:88
void AddFluxFile(int neutrino_pdg, string filename)
Definition: GAtmoFlux.cxx:394
A base class for the FLUKA, BGLRS and ATMNC atmo. nu. flux drivers. The driver depends on data files ...
Definition: GAtmoFlux.h:60
void ForceMinEnergy(double emin)
Definition: GAtmoFlux.cxx:227
#define LEN(x)
A flux driver for the Bartol Atmospheric Neutrino Flux.