Jpp
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 "JGizmo/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 namespace {
29 
30  using namespace JPP;
31 
32  /**
33  * Test event from genie/gSeaGen simulation.
34  *
35  * The function checks that the vertex of the neutrino event is inside the can volume.
36  *
37  * \param cylinder cylinder
38  * \param event event
39  * \return true if accepted; else false
40  */
41  inline bool test_event(const JCylinder3D& cylinder, const Evt& event)
42  {
43  using namespace std;
44  using namespace JPP;
45 
46  Bool_t accepted = true;
47 
48  if ( has_neutrino(event) ) {
49  accepted = accepted && cylinder.is_inside( getPosition( get_neutrino(event) ) );
50  }
51  else {
52 
53  // future/further logic for atm_muon events here, if any
54 
55  accepted = false;
56  }
57 
58  return accepted;
59  }
60 
61  /** Function to infer the coordinate origin from the header.
62 
63  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.
64 
65  \param header - MC simulation file header
66  \return Coordinate origin in the simulation
67  */
68  inline Vec get_coord_origin(const JHead &header)
69  {
70  using namespace std;
71 
72  Vec coord_origin(0, 0, 0);
73 
74  if ( is_valid(header.coord_origin) ) {
75 
76  coord_origin = header.coord_origin;
77 
78  // using NOTICE here gives a linker error...
79  cout << "JVolume1D::get_coord_origin() Coordinate origin (x, y, z) " << coord_origin << " read from header" << endl;
80 
81  }
82 
83  else if ( is_valid(header.can) ) {
84 
85  if (header.can.zmin < 0) coord_origin.z = -header.can.zmin;
86 
87  cout << "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  }
90 
91  else {
92  FATAL("JVolume1D::get_coord_origin() Error in determining the coordinate origin.");
93  }
94 
95  return coord_origin;
96 
97  }
98 
99 }
100 
101 /**
102  * \file
103  *
104  * 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.
105  * The unit of the contents of the histogram is \f$km^{3}\f$.
106  * \author mdejong, bstrandberg
107  */
108 int main(int argc, char **argv)
109 {
110  using namespace std;
111  using namespace JPP;
112  using namespace KM3NETDAQ;
113 
114  //------------------------------------------------------------------------------
115  // parse command line arguments, check that header can be found in the input file
116  //------------------------------------------------------------------------------
117 
118  JTriggeredFileScanner<> inputFile;
119  string outputFile;
120  JLimit& numberOfEvents = inputFile.getLimit();
121  double wall;
122  bool logx;
123  int numberOfBins;
124  int debug;
125  string detectorFile;
126 
127 
128  try {
129 
130  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.");
131 
132  zap['f'] = make_field(inputFile);
133  zap['o'] = make_field(outputFile) = "volume.root";
134  zap['n'] = make_field(numberOfEvents) = JLimit::max();
135  zap['R'] = make_field(wall, "Addition margin around the volume in which the considered events must reside") = 0.0;
136  zap['X'] = make_field(logx, "Use logarithm of energy");
137  zap['N'] = make_field(numberOfBins, "Number of bins in the energy range of the MC simulation") = 10;
138  zap['d'] = make_field(debug) = 1;
139  zap['a'] = make_field(detectorFile, "Detector file: if not provided, trigger fraction is not calculated") = "";
140 
141  zap(argc, argv);
142  }
143  catch(const exception &error) {
144  FATAL(error.what() << endl);
145  }
146 
147  //-------------------------------------------------------------------------
148  // deal with the header and init the detector
149  //-------------------------------------------------------------------------
150 
151  Head head;
152 
153  try {
154  head = getHeader(inputFile);
155  }
156  catch(const JException& error) {
157  FATAL(error);
158  }
159 
161 
162  if (detectorFile != "") {
163 
164  try {
165  load(detectorFile, detector);
166  }
167  catch(const JException& error) {
168  FATAL(error);
169  }
170  }
171 
172  //------------------------------------------------------------------------------
173  // create the can volume from the dimensions stored in the header and instrumented volume from detector file
174  //------------------------------------------------------------------------------
175 
176  const JHead buffer(head);
177 
178  const bool genie = is_genie(buffer);
179 
180  // the can volume comes from the generator header and the coordinate system is consistent by construction
181  const JVolume volume(head, logx);
182  JCylinder3D canvol = get<JCylinder3D>(buffer);
183  canvol.addMargin(wall);
184 
185  // as the detector is constructed from Jpp detector file, the coordinate system needs to be synced
186  // to the one used in the event generator
187  detector -= JAANET::getPosition( get_coord_origin(buffer) );
188  JCylinder3D instvol( detector.begin(), detector.end() );
189  instvol.addMargin(wall);
190 
191  NOTICE("JVolume1D: Instrumented volume dimensions (zmin, zmax, r): " << instvol.getZmin() << " " << instvol.getZmax() << " " << instvol.getRadius() << endl );
192 
193  //------------------------------------------------------------------------------
194  // initialise output
195  //------------------------------------------------------------------------------
196 
197  TFile out(outputFile.c_str(), "recreate");
198 
199  TH1D hV("hV", "effective volume in km^3" , numberOfBins, volume.getXmin(), volume.getXmax());
200  TH1D hF("hF", "n_trig/n_gen in instrumented volume", numberOfBins, volume.getXmin(), volume.getXmax());
201  hV.Sumw2();
202  hF.Sumw2();
203 
204  //------------------------------------------------------------------------------
205  // loop over triggered events in the input file
206  //------------------------------------------------------------------------------
207 
208  NOTICE("JVolume1D: Scanning triggered events." << endl);
209  while (inputFile.hasNext()) {
210 
211  STATUS("event: " << setw(10) << inputFile.getCounter() << '\r'); DEBUG(endl);
212 
214 
215  const Evt* event = ps;
216 
217  if (has_neutrino(*event)) {
218 
219  const Trk& neutrino = get_neutrino(*event);
220  const double E = neutrino.E;
221 
222  // genie/gSeaGen events filled with weight 1, histograms normalised after the second loop below
223  if ( genie ) {
224 
225  // events are filled to hV if they are inside the can
226  hV.Fill(volume.getX(E), test_event(canvol, *event) ? 1.0 : 0.0);
227 
228  // events are filled to hF if they are inside the instrumented volume
229  hF.Fill(volume.getX(E), test_event(instvol, *event) ? 1.0 : 0.0);
230 
231  }
232  // for other simulated events effective volume calculated from event weights, normalisation not required
233  else {
234  hV.Fill(volume.getX(E), volume.getW(hV.GetXaxis(), E));
235  }
236 
237  }
238  else {
239  WARNING("JVolume1D: cannot find neutrino in triggered event " << inputFile.getCounter() );
240  }
241 
242  } // end loop over triggered events
243  STATUS(endl);
244 
245  //------------------------------------------------------------------------------
246  // loop over generated events in the input file; FATAL if generator events have not been stored
247  //------------------------------------------------------------------------------
248 
249  if ( genie ) {
250 
251  // this histogram counts the generated events inside the can volume
252  TH1D* hNV = (TH1D*) hV.Clone("hNV");
253  hNV->Reset();
254 
255  // this histogram counts the generated events inside the instrumented volume
256  TH1D* hNF = (TH1D*) hF.Clone("hNF");
257  hNF->Reset();
258 
259  NOTICE("JVolume1D: Scanning generated events." << endl);
260 
261  JMultipleFileScanner<Evt> in(inputFile);
262 
263  while ( in.hasNext() ) {
264 
265  STATUS("event: " << setw(10) << in.getCounter() << '\r'); DEBUG(endl);
266 
267  const Evt* event = in.next();
268 
269  if (has_neutrino(*event)) {
270 
271  const Trk& neutrino = get_neutrino(*event);
272  const double E = neutrino.E;
273 
274  hNV->Fill(volume.getX(E), test_event(canvol, *event) ? 1.0 : 0.0);
275  hNF->Fill(volume.getX(E), test_event(instvol, *event) ? 1.0 : 0.0);
276 
277  }
278  else {
279  WARNING("JVolume1D: cannot find neutrino in generated event " << inputFile.getCounter() );
280  }
281 
282  }
283  STATUS(endl);
284 
285  if ( in.getCounter() == 0 ) {
286  FATAL("JVolume1D: generated events not stored in the input file, JTriggerEfficiency should be run without option -O");
287  }
288 
289  //------------------------------------------------------------------------------
290  // convert 'generated' and 'triggered' histograms to effective volume and trigger fraction
291  //------------------------------------------------------------------------------
292 
293  hV.Divide(hNV);
294  hV.Scale(canvol.getVolume()*1e-9); // km^3
295  hF.Divide(hNF);
296 
297  delete hNV;
298  delete hNF;
299 
300  }
301 
302  out.Write();
303  out.Close();
304 
305 }
Head.hh
main
int main(int argc, char **argv)
Definition: JVolume1D.cc:108
Vec::z
double z
Definition: Vec.hh:14
JAANET::can::r
double r
Radius [m].
Definition: JHead.hh:371
JSUPPORT::JLimit
Auxiliary class for defining the range of iterations of objects.
Definition: JLimit.hh:41
JMessage.hh
JPosition3D.hh
JAANET::JHead::coord_origin
JAANET::coord_origin coord_origin
Definition: JHead.hh:1086
JAANET::is_valid
bool is_valid(const T &value)
Check validity of given value.
Definition: JHead.hh:823
JGEOMETRY3D::JCylinder3D::getVolume
double getVolume() const
Get volume.
Definition: JCylinder3D.hh:176
JDETECTOR::load
void load(const JString &file_name, JDetector &detector)
Load detector from input file.
Definition: JDetectorToolkit.hh:476
JLANG::JMultiPointer
General purpose class for multiple pointers.
Definition: JMultiPointer.hh:22
JGEOMETRY3D::JCylinder3D::is_inside
bool is_inside(const JVector3D &pos) const
Check whether given point is inside cylinder.
Definition: JCylinder3D.hh:199
Trk::E
double E
Energy (either MC truth or reconstructed)
Definition: Trk.hh:18
Trk
The Trk class represents a Monte Carlo (MC) particle as well as a reconstructed track/shower.
Definition: Trk.hh:12
Evt
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.
Definition: Evt.hh:19
Evt.hh
JPARSER::JParser
Utility class to parse command line options.
Definition: JParser.hh:1493
JGIZMO::JVolume::getXmax
Double_t getXmax() const
Get maximal abscissa value.
Definition: JVolume.hh:102
JTriggeredFileScanner.hh
NOTICE
#define NOTICE(A)
Definition: JMessage.hh:64
JAANET::coord_origin
Coordinate origin.
Definition: JHead.hh:489
Vec.hh
JGEOMETRY3D::JCylinder3D::addMargin
void addMargin(const double D)
Add (safety) margin.
Definition: JCylinder3D.hh:163
JAANET::JHead
Monte Carlo run header.
Definition: JHead.hh:839
JAANET::can::zmin
double zmin
Bottom [m].
Definition: JHead.hh:369
JSUPPORT::JTriggeredFileScanner::hasNext
virtual bool hasNext()
Check availability of next element.
Definition: JTriggeredFileScanner.hh:72
JSupport.hh
JPP
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Definition: JAAnetToolkit.hh:37
JGEOMETRY3D::JCylinder3D
Cylinder object.
Definition: JCylinder3D.hh:37
JSUPPORT::getHeader
Head getHeader(const JMultipleFileScanner_t &file_list)
Get Monte Carlo header.
Definition: JMonteCarloFileSupportkit.hh:458
JSUPPORT::JMultipleFileScanner< JTypeList< JDAQEvent, JTypelist_t > >::getCounter
counter_type getCounter() const
Get counter.
Definition: JMultipleFileScanner.hh:323
JDAQEventIO.hh
JGIZMO::JVolume::getXmin
Double_t getXmin() const
Get minimal abscissa value.
Definition: JVolume.hh:91
JGIZMO::JVolume::getW
Double_t getW(TAxis *axis, const Double_t E) const
Get bin width corrected energy spectrum dependent weight.
Definition: JVolume.hh:161
WARNING
#define WARNING(A)
Definition: JMessage.hh:65
debug
int debug
debug level
Definition: JSirene.cc:59
JSUPPORT::JMultipleFileScanner::next
virtual const pointer_type & next()
Get next element.
Definition: JMultipleFileScanner.hh:398
JSUPPORT::JTriggeredFileScanner::next
virtual const multi_pointer_type & next()
Get next element.
Definition: JTriggeredFileScanner.hh:92
Head
The Head class reflects the header of Monte-Carlo event files, which consists of keys (also referred ...
Definition: Head.hh:39
JAANET::get_neutrino
const Trk & get_neutrino(const Evt &evt)
Get incoming neutrino.
Definition: JAAnetToolkit.hh:438
JAAnetToolkit.hh
JAANET::has_neutrino
bool has_neutrino(const Evt &evt)
Test whether given event has an incoming neutrino.
Definition: JAAnetToolkit.hh:427
JGIZMO::JVolume
Auxiliary class for histogramming of effective volume.
Definition: JVolume.hh:26
JGIZMO::JVolume::getX
Double_t getX(const Double_t E, double constrain=false) const
Get abscissa value.
Definition: JVolume.hh:115
STATUS
#define STATUS(A)
Definition: JMessage.hh:63
JSUPPORT::JMultipleFileScanner::hasNext
virtual bool hasNext()
Check availability of next element.
Definition: JMultipleFileScanner.hh:350
JAANET::can::zmax
double zmax
Top [m].
Definition: JHead.hh:370
JParser.hh
JDetectorToolkit.hh
JAANET::JHead::can
JAANET::can can
Definition: JHead.hh:1083
JSUPPORT::JTriggeredFileScanner
Auxiliary class to synchronously read DAQ events and Monte Carlo events (and optionally other events)...
Definition: JTriggeredFileScanner.hh:39
make_field
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1954
JSUPPORT::JMultipleFileScanner
General purpose class for object reading from a list of file names.
Definition: JMultipleFileScanner.hh:167
JDETECTOR::JDetector
Detector data structure.
Definition: JDetector.hh:80
JAANET::getPosition
JPosition3D getPosition(const Vec &v)
Get position.
Definition: JAAnetToolkit.hh:197
JAANET::detector
Detector file.
Definition: JHead.hh:130
DEBUG
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62
std
Definition: jaanetDictionary.h:36
KM3NETDAQ
KM3NeT DAQ data structures and auxiliaries.
Definition: DataQueue.cc:39
JCylinder3D.hh
JVolume.hh
Vec
The Vec class is a straightforward 3-d vector, which also works in pyroot.
Definition: Vec.hh:12
JAANET::is_genie
bool is_genie(const JHead &header)
Check for generator.
Definition: JHeadToolkit.hh:223
JMonteCarloFileSupportkit.hh
JDetector.hh
FATAL
#define FATAL(A)
Definition: JMessage.hh:67
outputFile
string outputFile
Definition: JDAQTimesliceSelector.cc:37
JLANG::JException
General exception.
Definition: JException.hh:23
JSUPPORT::JLimit::max
static counter_type max()
Get maximum counter value.
Definition: JLimit.hh:117