Jpp - the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JVolume1D.cc
Go to the documentation of this file.
1 #include <string>
2 #include <iostream>
3 
4 #include "TROOT.h"
5 #include "TFile.h"
6 #include "TH1D.h"
7 
11 #include "JDAQ/JDAQEventIO.hh"
12 #include "JAAnet/JAAnetToolkit.hh"
13 #include "JAAnet/JVolume.hh"
16 
19 #include "JSupport/JSupport.hh"
20 
21 #include "JDetector/JDetector.hh"
23 
24 #include "Jeep/JParser.hh"
25 #include "Jeep/JMessage.hh"
26 
27 
28 int debug;
29 
30 namespace {
31 
32  using namespace JPP;
33 
34  /**
35  * Test event from genie/gSeaGen simulation.
36  *
37  * The function checks that the vertex of the neutrino event is inside the can volume.
38  *
39  * \param cylinder cylinder
40  * \param event event
41  * \return true if accepted; else false
42  */
43  inline bool test_event(const JCylinder3D& cylinder, const Evt& event)
44  {
45  using namespace std;
46  using namespace JPP;
47 
48  Bool_t accepted = true;
49 
50  if ( has_neutrino(event) ) {
51  accepted = accepted && cylinder.is_inside( getPosition( get_neutrino(event) ) );
52  }
53  else {
54 
55  // future/further logic for atm_muon events here, if any
56 
57  accepted = false;
58  }
59 
60  return accepted;
61  }
62 
63  /**
64  * Function to infer the coordinate origin from the header.
65  *
66  * This bulky logic exists because historically gSeaGen and Jpp have used different coordinate systems. For gSeaGen files the coordinate origin can be syncronised to Jpp, which is performed here.
67  *
68  * \param header Monte Carlo simulation file header
69  * \return Coordinate origin in the simulation
70  */
71  inline Vec get_coord_origin(const JHead &header)
72  {
73  using namespace std;
74 
75  Vec coord_origin(0, 0, 0);
76 
77  if (header.is_valid(&JHead::coord_origin)) {
78 
79  coord_origin = header.coord_origin;
80 
81  NOTICE("JVolume1D::get_coord_origin() Coordinate origin (x, y, z) " << coord_origin << " read from header" << endl);
82 
83  } else if (header.is_valid(&JHead::can) ) {
84 
85  if (header.can.zmin < 0) coord_origin.z = -header.can.zmin;
86 
87  NOTICE("JVolume1D::get_coord_origin() Coordinate origin (x, y, z) " << coord_origin << " calculated from can dimensions (zmin, zmax, r) " << header.can.zmin << " " << header.can.zmax << " " << header.can.r << endl);
88 
89  } else {
90 
91  FATAL("JVolume1D::get_coord_origin() Error in determining the coordinate origin.");
92  }
93 
94  return coord_origin;
95  }
96 }
97 
98 /**
99  * \file
100  *
101  * Example program to histogram neutrino effective volume for triggered events. For genie/gSeaGen events a histogram depicting the fraction of events that triggered the detector inside the instrumented volume is also shown.
102  * The unit of the contents of the histogram is \f$km^{3}\f$.
103  * \author mdejong, bstrandberg
104  */
105 int main(int argc, char **argv)
106 {
107  using namespace std;
108  using namespace JPP;
109  using namespace KM3NETDAQ;
110 
111  //------------------------------------------------------------------------------
112  // parse command line arguments, check that header can be found in the input file
113  //------------------------------------------------------------------------------
114 
115  JTriggeredFileScanner<> inputFile;
116  string outputFile;
117  JLimit& numberOfEvents = inputFile.getLimit();
118  double wall;
119  bool logx;
120  int numberOfBins;
121  string detectorFile;
122 
123 
124  try {
125 
126  JParser<> zap("Example program to histogram neutrino effective volume for triggered events. For genie/gSeaGen events a histogram depicting the fraction of events that triggered the detector inside the instrumented volume is also shown.");
127 
128  zap['f'] = make_field(inputFile);
129  zap['o'] = make_field(outputFile) = "volume.root";
130  zap['n'] = make_field(numberOfEvents) = JLimit::max();
131  zap['R'] = make_field(wall, "Addition margin around the volume in which the considered events must reside") = 0.0;
132  zap['X'] = make_field(logx, "Use logarithm of energy");
133  zap['N'] = make_field(numberOfBins, "Number of bins in the energy range of the MC simulation") = 10;
134  zap['d'] = make_field(debug) = 1;
135  zap['a'] = make_field(detectorFile, "Detector file: if not provided, trigger fraction is not calculated") = "";
136 
137  zap(argc, argv);
138  }
139  catch(const exception &error) {
140  FATAL(error.what() << endl);
141  }
142 
143  //-------------------------------------------------------------------------
144  // deal with the header and init the detector
145  //-------------------------------------------------------------------------
146 
147  Head head;
148 
149  try {
150  head = getHeader(inputFile);
151  }
152  catch(const JException& error) {
153  FATAL(error);
154  }
155 
157 
158  if (detectorFile != "") {
159 
160  try {
161  load(detectorFile, detector);
162  }
163  catch(const JException& error) {
164  FATAL(error);
165  }
166  }
167 
168  //------------------------------------------------------------------------------
169  // create the can volume from the dimensions stored in the header and instrumented volume from detector file
170  //------------------------------------------------------------------------------
171 
172  const JHead buffer(head);
173 
174  const bool genie = is_gseagen(buffer);
175 
176  // the can volume comes from the generator header and the coordinate system is consistent by construction
177  const JVolume volume(head, logx);
178  JCylinder3D canvol = get<JCylinder3D>(buffer);
179  canvol.addMargin(wall);
180 
181  // as the detector is constructed from Jpp detector file, the coordinate system needs to be synced
182  // to the one used in the event generator
183  detector -= JAANET::getPosition( get_coord_origin(buffer) );
184  JCylinder3D instvol( detector.begin(), detector.end() );
185  instvol.addMargin(wall);
186 
187  NOTICE("JVolume1D: Instrumented volume dimensions (zmin, zmax, r): " << instvol.getZmin() << " " << instvol.getZmax() << " " << instvol.getRadius() << endl );
188 
189  //------------------------------------------------------------------------------
190  // initialise output
191  //------------------------------------------------------------------------------
192 
193  TFile out(outputFile.c_str(), "recreate");
194 
195  TH1D hV("hV", "effective volume in km^3" , numberOfBins, volume.getXmin(), volume.getXmax());
196  TH1D hF("hF", "n_trig/n_gen in instrumented volume", numberOfBins, volume.getXmin(), volume.getXmax());
197  hV.Sumw2();
198  hF.Sumw2();
199 
200  //------------------------------------------------------------------------------
201  // loop over triggered events in the input file
202  //------------------------------------------------------------------------------
203 
204  NOTICE("JVolume1D: Scanning triggered events." << endl);
205  while (inputFile.hasNext()) {
206 
207  STATUS("event: " << setw(10) << inputFile.getCounter() << '\r'); DEBUG(endl);
208 
209  JTriggeredFileScanner<>::multi_pointer_type ps = inputFile.next();
210 
211  const Evt* event = ps;
212 
213  if (has_neutrino(*event)) {
214 
215  const Trk& neutrino = get_neutrino(*event);
216  const double E = neutrino.E;
217 
218  // genie/gSeaGen events filled with weight 1, histograms normalised after the second loop below
219  if ( genie ) {
220 
221  // events are filled to hV if they are inside the can
222  hV.Fill(volume.getX(E), test_event(canvol, *event) ? 1.0 : 0.0);
223 
224  // events are filled to hF if they are inside the instrumented volume
225  hF.Fill(volume.getX(E), test_event(instvol, *event) ? 1.0 : 0.0);
226 
227  }
228  // for other simulated events effective volume calculated from event weights, normalisation not required
229  else {
230  hV.Fill(volume.getX(E), volume.getW(hV.GetXaxis(), E));
231  }
232 
233  }
234  else {
235  WARNING("JVolume1D: cannot find neutrino in triggered event " << inputFile.getCounter() );
236  }
237 
238  } // end loop over triggered events
239  STATUS(endl);
240 
241  //------------------------------------------------------------------------------
242  // loop over generated events in the input file; FATAL if generator events have not been stored
243  //------------------------------------------------------------------------------
244 
245  if ( genie ) {
246 
247  // this histogram counts the generated events inside the can volume
248  TH1D* hNV = (TH1D*) hV.Clone("hNV");
249  hNV->Reset();
250 
251  // this histogram counts the generated events inside the instrumented volume
252  TH1D* hNF = (TH1D*) hF.Clone("hNF");
253  hNF->Reset();
254 
255  NOTICE("JVolume1D: Scanning generated events." << endl);
256 
257  JMultipleFileScanner<Evt> in(inputFile);
258 
259  while ( in.hasNext() ) {
260 
261  STATUS("event: " << setw(10) << in.getCounter() << '\r'); DEBUG(endl);
262 
263  const Evt* event = in.next();
264 
265  if (has_neutrino(*event)) {
266 
267  const Trk& neutrino = get_neutrino(*event);
268  const double E = neutrino.E;
269 
270  hNV->Fill(volume.getX(E), test_event(canvol, *event) ? 1.0 : 0.0);
271  hNF->Fill(volume.getX(E), test_event(instvol, *event) ? 1.0 : 0.0);
272 
273  }
274  else {
275  WARNING("JVolume1D: cannot find neutrino in generated event " << inputFile.getCounter() );
276  }
277 
278  }
279  STATUS(endl);
280 
281  if ( in.getCounter() == 0 ) {
282  FATAL("JVolume1D: generated events not stored in the input file, JTriggerEfficiency should be run without option -O");
283  }
284 
285  //------------------------------------------------------------------------------
286  // convert 'generated' and 'triggered' histograms to effective volume and trigger fraction
287  //------------------------------------------------------------------------------
288 
289  hV.Divide(hNV);
290  hV.Scale(canvol.getVolume()*1e-9); // km^3
291  hF.Divide(hNF);
292 
293  delete hNV;
294  delete hNF;
295 
296  }
297 
298  out.Write();
299  out.Close();
300 
301 }
double zmin
Bottom [m].
Definition: JHead.hh:532
Utility class to parse command line options.
Definition: JParser.hh:1500
General exception.
Definition: JException.hh:23
#define WARNING(A)
Definition: JMessage.hh:65
Double_t getXmin() const
Get minimal abscissa value.
Definition: JVolume.hh:89
int main(int argc, char *argv[])
Definition: Main.cc:15
ROOT TTree parameter settings of various packages.
double z
Definition: Vec.hh:14
bool is_gseagen(const JHead &header)
Check for generator.
Definition: JHeadToolkit.hh:60
Synchronously read DAQ events and Monte Carlo events (and optionally other events).
#define STATUS(A)
Definition: JMessage.hh:63
bool has_neutrino(const Evt &evt)
Test whether given event has an incoming neutrino.
Detector data structure.
Definition: JDetector.hh:80
Auxiliary class to synchronously read DAQ events and Monte Carlo events (and optionally other events)...
Double_t getXmax() const
Get maximal abscissa value.
Definition: JVolume.hh:100
Double_t getX(const Double_t E, double constrain=false) const
Get abscissa value.
Definition: JVolume.hh:113
static counter_type max()
Get maximum counter value.
Definition: JLimit.hh:117
string outputFile
double E
Energy [GeV] (either MC truth or reconstructed)
Definition: Trk.hh:19
Data structure for detector geometry and calibration.
Coordinate origin.
Definition: JHead.hh:663
Head getHeader(const JMultipleFileScanner_t &file_list)
Get Monte Carlo header.
Auxiliary class for histogramming of effective volume.
Definition: JVolume.hh:26
Auxiliary class for defining the range of iterations of objects.
Definition: JLimit.hh:41
JAANET::can can
Definition: JHead.hh:1406
The Vec class is a straightforward 3-d vector, which also works in pyroot.
Definition: Vec.hh:12
Cylinder object.
Definition: JCylinder3D.hh:39
Detector file.
Definition: JHead.hh:196
virtual bool hasNext() override
Check availability of next element.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1961
Double_t getW(TAxis *axis, const Double_t E) const
Get bin width corrected energy spectrum dependent weight.
Definition: JVolume.hh:159
JPosition3D getPosition(const Vec &pos)
Get position.
Definition of hit and track types and auxiliary methods for handling Monte Carlo data.
#define NOTICE(A)
Definition: JMessage.hh:64
void addMargin(const double D)
Add (safety) margin.
Definition: JCylinder3D.hh:173
int debug
debug level
Definition: JSirene.cc:63
General purpose messaging.
Monte Carlo run header.
Definition: JHead.hh:1113
The Head class reflects the header of Monte-Carlo event files, which consists of keys (also referred ...
Definition: Head.hh:67
#define FATAL(A)
Definition: JMessage.hh:67
double r
Radius [m].
Definition: JHead.hh:534
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
General purpose class for object reading from a list of file names.
Utility class to parse command line options.
then usage $script< input_file >< detector_file > fi set_variable OUTPUT_DIR set_variable SELECTOR JDAQTimesliceL1 set_variable DEBUG case set_variable DEBUG
virtual const pointer_type & next() override
Get next element.
bool is_inside(const JVector3D &pos) const
Check whether given point is inside cylinder.
Definition: JCylinder3D.hh:209
counter_type getCounter() const
Get counter.
const JLimit & getLimit() const
Get limit.
Definition: JLimit.hh:73
const Trk & get_neutrino(const Evt &evt)
Get incoming neutrino.
do set_variable DETECTOR_TXT $WORKDIR detector
JAANET::coord_origin coord_origin
Definition: JHead.hh:1409
General purpose class for multiple pointers.
bool is_valid(T JHead::*pd) const
Check validity of given data member in JHead.
Definition: JHead.hh:1183
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY source JAcoustics sh $DETECTOR_ID CHECK_EXIT_CODE typeset A TRIPODS get_tripods $WORKDIR tripod txt TRIPODS for EMITTER in
Definition: JCanberra.sh:38
The Trk class represents a Monte Carlo (MC) particle as well as a reconstructed track/shower.
Definition: Trk.hh:13
Vec coord_origin() const
Get coordinate origin.
Definition: Head.hh:393
int numberOfBins
number of bins for average CDF integral of optical module
Definition: JSirene.cc:64
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.
Definition: Evt.hh:19
then usage $script[input file[working directory[option]]] nWhere option can be E
Definition: JMuonPostfit.sh:35
double zmax
Top [m].
Definition: JHead.hh:533