Jpp  18.3.0-209-g56ce19a
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Functions
JShowerPostfit.cc File Reference

Example program to histogram shower fit results: it handles both neutrino and muon productions. More...

#include <string>
#include <iostream>
#include <iomanip>
#include <vector>
#include <set>
#include "TROOT.h"
#include "TFile.h"
#include "TH1D.h"
#include "TH2D.h"
#include "TProfile.h"
#include "TMath.h"
#include "km3net-dataformat/offline/Head.hh"
#include "km3net-dataformat/offline/Evt.hh"
#include "km3net-dataformat/online/JDAQModuleIdentifier.hh"
#include "km3net-dataformat/definitions/reconstruction.hh"
#include "km3net-dataformat/definitions/fitparameters.hh"
#include "km3net-dataformat/tools/time_converter.hh"
#include "JAAnet/JHead.hh"
#include "JAAnet/JHeadToolkit.hh"
#include "JAAnet/JAAnetToolkit.hh"
#include "JAAnet/JVolume.hh"
#include "JDAQ/JDAQEventIO.hh"
#include "JPhysics/JConstants.hh"
#include "JTools/JQuantile.hh"
#include "JSupport/JTriggeredFileScanner.hh"
#include "JSupport/JMonteCarloFileSupportkit.hh"
#include "JSupport/JSupport.hh"
#include "JReconstruction/JEvt.hh"
#include "JReconstruction/JEvtToolkit.hh"
#include "JLang/JPredicate.hh"
#include "JPhysics/JGeanz.hh"
#include "JGeometry3D/JShower3E.hh"
#include "JGeometry3D/JCylinder3D.hh"
#include "Jeep/JParser.hh"
#include "Jeep/JMessage.hh"

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Detailed Description

Example program to histogram shower fit results: it handles both neutrino and muon productions.

Author
mdejong, adomi

Definition in file JShowerPostfit.cc.

Function Documentation

int main ( int  argc,
char **  argv 
)

Definition at line 79 of file JShowerPostfit.cc.

80 {
81  using namespace std;
82  using namespace JPP;
83  using namespace KM3NETDAQ;
84 
85  typedef JTriggeredFileScanner<JEvt> JTriggeredFileScanner_t;
86  typedef JTriggeredFileScanner_t::multi_pointer_type multi_pointer_type;
87 
88  JTriggeredFileScanner_t inputFile;
89  JLimit_t& numberOfEvents = inputFile.getLimit();
90  string outputFile;
91  size_t numberOfPrefits;
93  JAtmosphericMuon atmosphere;
94  double Emin_GeV;
95  double NPE;
96  int application;
97  string option;
98  bool isMuon;
99  bool wrtNeutrino;
100  double radius;
101  JRange<double> height;
102  int debug;
103 
104  try {
105 
106  JParser<> zap("Example program to histogram fit results.");
107 
108  zap['f'] = make_field(inputFile);
109  zap['o'] = make_field(outputFile) = "postfit.root";
110  zap['n'] = make_field(numberOfEvents) = JLimit::max();
111  zap['N'] = make_field(numberOfPrefits) = 1;
113  zap['E'] = make_field(Emin_GeV) = 0.0;
114  zap['M'] = make_field(NPE) = 0.0;
116  zap['a'] = make_field(atmosphere) = JAtmosphericMuon(90.0, 90.0);
117  zap['O'] = make_field(option) = "E", "N", "LINE", "LOGE";
118  zap['I'] = make_field(isMuon);
119  zap['w'] = make_field(wrtNeutrino);
120  zap['r'] = make_field(radius) = numeric_limits<double>::max(); // no containment
121  zap['z'] = make_field(height) = JRange<double>(); // no containment
122  zap['d'] = make_field(debug) = 2;
123 
124  zap(argc, argv);
125  }
126  catch(const exception& error) {
127  FATAL(error.what() << endl);
128  }
129 
130  cout << "APPLICATION " << application << endl;
131 
132  JHead head;
133 
134  try {
135  head = getHeader(inputFile);
136  }
137  catch(const JException& error) {
138  FATAL(error);
139  }
140 
141  JVolume volume(head, option != "LINE");
142  JPosition3D offset = getPosition(getOffset(head));
144  JCylinder3D cylinder = getCylinder(head);
145 
146  cylinder.add(offset);
147 
148  JCylinder3D containment(JCircle2D(JPosition2D(), radius), height.getLowerLimit(), height.getUpperLimit());
149 
150  containment.add(origin);
151 
152  NOTICE("Offset: " << offset << endl);
153  NOTICE("Origin: " << origin << endl);
154  NOTICE("Cylinder: " << cylinder << endl);
155  NOTICE("Containment: " << containment << endl);
156 
157  const double EMIN_GEV = 10e3; // MUPAGE
158 
159  TFile out(outputFile.c_str(), "recreate");
160 
161  TH1D job("job", NULL, 100, 0.5, 100.5);
162 
163  TH1D hn("hn", "NDF (Number of Degrees of Freedom)", 250, -0.5, 249.5);
164  TH1D hq("hq", "Fit Quality", 300, 0.0, 600.0);
165  TH1D hi("hi", "Fit Index vs Best Resolution", 101, -0.5, 100.5); // to see if the fit with the best quality has also the best resolution
166  TH1D hd("hd", "Square Distance between Reco and True position", 2000, 0.0, 400.0); // [m]
167  TH1D hz("hz", "Longitudinal Distance between Reco and MC lepton position", 100, -200.0, 200.0); // [m]
168  TH1D ht("ht", "Time difference between Reco and MC lepton", 100, -100.0, 100.0); // [ns]
169 
170  TH1D ha("ha", "Angle between reco direction and true direction", 1000, 0.0, 180.0); // [ns]
171 
172  TH1D e0("e0", "True lepton energy", 100, volume.getXmin(), volume.getXmax()); // [log(E)]
173  TH1D e2("e2", "Reconstructed energy", 100, volume.getXmin(), volume.getXmax()); // [log(E)]
174  TH1D er("er", "Ratio of reconstructed energy and true energy", 100, -5.0, +5.0); // [log(E/E)]
175  TH1D ea("ea", "Distribution of Energy error for all the events; E_{reco}-E_{true}", 100, -30, +30);
176  TH1D ed3_5GeV("ed3_5GeV", "Distribution of Energy error for events with MC energy #in [3,5] GeV; E_{reco}-E_{true}", 100, -30, +30);
177  TH1D ed8_11GeV("ed8_11GeV", "Distribution of Energy error for events with MC energy #in [8,11] GeV; E_{reco}-E_{true}", 100, -30, +30);
178  TH1D ed15_21GeV("ed15_21GeV", "Distribution of Energy error for events with MC energy #in [15,21] GeV; E_{reco}-E_{true}", 100, -30, +30);
179  TH2D ee("ee", "; E_{true} [GeV]; E_{reco} [GeV]",
180  40, volume.getXmin(), volume.getXmax(),
181  40, volume.getXmin(), volume.getXmax());
182 
183  const Int_t ny = 28800;
184  const Double_t ymin = 0.0; // [deg]
185  const Double_t ymax = 180.0; // [deg]
186 
188 
189  if (option.find('E') != string::npos) {
190 
191  for (double x = volume.getXmin(); x <= volume.getXmax(); x += (volume.getXmax() - volume.getXmin()) / 20) {
192  X.push_back(x);
193  }
194 
195  } else {
196 
197  double x = -0.5;
198 
199  for ( ; x <= 15.5; x += 1.0) { X.push_back(x); }
200  for ( ; x <= 25.5; x += 2.0) { X.push_back(x); }
201  for ( ; x <= 50.5; x += 5.0) { X.push_back(x); }
202  for ( ; x <= 100.5; x += 10.0) { X.push_back(x); }
203  for ( ; x <= 250.5; x += 20.0) { X.push_back(x); }
204  }
205 
206  TH2D h2("h2", NULL, X.size() - 1, X.data(), ny, ymin, ymax);
207 
208  TProfile herrorE("herrorE", "Energy Error", X.size() - 1, X.data());
209  TProfile hfracE( "hfracE", "Fractional Energy Error", X.size() - 1, X.data());
210  TProfile he("he","Reconstruction Efficiency", X.size() - 1, X.data());
211  TProfile htheta_nu_lep("htheta_nu_lep", "Angle between neutrino and primary lepton", X.size() - 1, X.data());
212 
213  TH2D hb("hb", NULL, 100, 0.0, 0.5e6, 100, -100.0, +900.0);
214  TH2S hmca("hmca", NULL, X.size() - 1, X.data(), 1000, 0, 180);
215 
216  TH2D hzenith("hzenith", "Reco Zenith vs MC Energy", 100, 0, 100, ny, ymin, ymax);
217  TH2D hY("hY", "Reco Bjorken Y vs MC Bjorken Y", 40, 0, 1, 40, 0, 1);
218  TH2D hby3_5GeV("hby3_5GeV", "Reco Bjorken Y vs MC Bjorken Y for events with Reco E #in [3, 5] GeV", 40, 0, 1, 40, 0, 1);
219  TH2D hby8_10GeV("hby8_10GeV", "Reco Bjorken Y vs MC Bjorken Y for events with Reco E #in [8, 10] GeV", 40, 0, 1, 40, 0, 1);
220 
221  JQuantile Q("Angle", true);
222  JQuantile O("Omega", true);
223 
224 
225  while (inputFile.hasNext()) {
226 
227  STATUS("event: " << setw(10) << inputFile.getCounter() << '\r'); DEBUG(endl);
228 
229  multi_pointer_type ps = inputFile.next();
230 
231  JDAQEvent* tev = ps;
232  JEvt* evt = ps; // Reco event
233  Evt* event = ps; // MC event
234 
235  const time_converter converter(*event, *tev);
236 
237  job.Fill(1.0);
238 
239  double Enu = 0.0;
240  double Elep = 0.0;
241  double Emax = 0.0;
242 
243  Trk neutrino;
244 
245  if(has_neutrino(*event)){
246 
247  neutrino = get_neutrino(*event);
248  Enu = neutrino.E;
249 
250  }
251 
252  vector<Trk>::const_iterator lepton = event->mc_trks.end(); // can be electron or muon
253 
254  for (vector<Trk>::const_iterator mc_evt = event->mc_trks.begin(); mc_evt != event->mc_trks.end(); ++mc_evt) {
255 
256  if (!isMuon && is_electron(*mc_evt)) {
257 
258  Elep += mc_evt->E;
259 
260  if (mc_evt->E > Emax) {
261  lepton = mc_evt;
262  Emax = mc_evt->E;
263  }
264 
265 
266  } else if(isMuon && is_muon(*mc_evt)){
267 
268  Elep += mc_evt->E;
269  if (mc_evt->E > Emax) {
270  lepton = mc_evt;
271  Emax = mc_evt->E;
272  }
273  }
274  }
275 
276  if (lepton == event->mc_trks.end()) {
277  continue;
278  }
279 
280  job.Fill(3.0);
281 
282  double true_BjY = (Enu - Elep) / Enu;
283 
284  // abscissa
285 
286  Double_t x = 0.0;
287 
288  if (option.find('E') != string::npos){
289 
290  if(wrtNeutrino == true && !isMuon) x = volume.getX(neutrino.E);
291  else if(!wrtNeutrino && !isMuon) x = volume.getX(lepton->E);
292 
293  } else{
294  x = getCount(tev->begin<JDAQTriggeredHit>(), tev->end<JDAQTriggeredHit>());
295  }
296 
297  // weight for efficiency determination
298  Double_t W = 0.0;
299 
300  if (!evt->empty()) {
301 
302  JEvt::iterator __end = partition(evt->begin(), evt->end(), JHistory::is_event(application));
303 
304  if (evt->begin() == __end) {
305  continue;
306  }
307 
308  job.Fill(4.0);
309 
310  //if (numberOfPrefits > 0 && numberOfPrefits < (size_t) distance(evt->begin(), evt->end())) {
311  if (numberOfPrefits > 0 ) {
312 
313  JEvt::iterator __q = __end;
314 
315  advance(__end = evt->begin(), min(numberOfPrefits, (size_t) distance(evt->begin(), __q)));
316 
317  partial_sort(evt->begin(), __end, __q, quality_sorter);
318 
319  } else {
320 
321  sort(evt->begin(), __end, quality_sorter);
322  }
323 
324  JEvt::iterator best = evt->begin(); // the best shower is the one with the best quality
325 
326  JPosition position(getPosition(lepton->pos)); // by default the lepton pos is the interaction vertex
327  JPointing pointing(getDirection(*lepton));
328  JShowerEnergy energy(lepton->E);
329 
330  JVector3D showerBrightPoint(getPosition(lepton->pos) + offset + getPosition(lepton->dir) * geanz.getMaximum(lepton->E));
331 
332  if(!wrtNeutrino && !isMuon){
333  position = JPosition(showerBrightPoint); // wrt the em shower brightest point
334  } else if(wrtNeutrino == true && !isMuon){
335  position = JPosition(getPosition(neutrino));
336  pointing = JPointing(getDirection(neutrino));
337  energy = JShowerEnergy(Enu);
338  }
339 
340  JEvt::iterator fit_with_smallest_error = best;
341 
342  if(application == JSHOWERPREFIT || application == JSHOWERPOINTSIMPLEX || application == JSHOWERPOSITIONFIT){
343  fit_with_smallest_error = position(evt->begin(), __end);
344  } else if (application == JSHOWERENERGYPREFIT){
345  fit_with_smallest_error = energy(evt->begin(), __end);
346  } else {
347  fit_with_smallest_error = pointing(evt->begin(), __end);
348  }
349 
350  const Double_t beta = pointing.getAngle(*best);
351  const double Efit = best->getE();
352 
353  if (containment.is_inside(getPosition(*best))){
354 
355  // selection of fit result
356  bool ok = (Efit >= Emin_GeV);
357 
358  if (ok) {
359 
360  W = 1.0;
361 
362  job.Fill(5.0);
363 
364  hn.Fill((Double_t) best->getNDF());
365  hq.Fill(best->getQ());
366  hi.Fill((Double_t) distance(evt->begin(), fit_with_smallest_error));
367 
368  Q.put(beta);
369 
370  JShower3E ta;
371 
372  if(wrtNeutrino){
373  ta = getTrack(neutrino);
374  } else {
375  ta = getTrack(*lepton); // MC event
376  }
377 
378  JShower3E tb = getTrack(*best); // Reco event
379 
380  double zenith = tb.getDirection().getTheta() * 180 / PI;
381 
382  // take into account the difefrent MC/Reco geometry and time
383  ta.add(offset);
384  tb.sub(converter.putTime());
385 
386  if(!isMuon && !wrtNeutrino){
387 
388  double distance_m = (tb.getPosition() - JPosition3D(showerBrightPoint)).getLength();
389 
390  hd.Fill(distance_m * distance_m);
391 
392  } else {
393 
394  double distance_m = (tb.getPosition() - ta.getPosition()).getLength();
395 
396  hd.Fill(distance_m * distance_m);
397 
398  }
399 
400  if (has_neutrino(*event)) {
401 
402  job.Fill(6.0);
403 
404  JPosition3D mc_vx = getPosition(neutrino); // mc vertex
405 
406  mc_vx.add(offset);
407 
408  if (cylinder.is_inside(mc_vx)) {
409 
410  job.Fill(7.0);
411 
412  hz.Fill(tb.getIntersection(mc_vx));
413  }
414  }
415 
416  if (best->getE() >= EMIN_GEV) {
417  hb.Fill(JVector2D(best->getX() - origin.getX(), best->getY() - origin.getY()).getLengthSquared(), best->getZ());
418  }
419 
420  ht.Fill(tb.getT() - ta.getT());
421 
422  ha.Fill(getAngle(ta.getDirection(), tb.getDirection()));
423 
424  htheta_nu_lep.Fill(x, getAngle(getDirection(neutrino), getDirection(*lepton)));
425  hmca.Fill(x, getAngle(ta.getDirection(), tb.getDirection()));
426 
427  if(application == JSHOWER_BJORKEN_Y) {
428 
429  hY.Fill(true_BjY, best->getW(5));
430 
431  if(Efit > 2.5 && Efit < 6) hby3_5GeV.Fill(true_BjY, best->getW(5));
432  else if(Efit > 7.5 && Efit < 11) hby8_10GeV.Fill(true_BjY, best->getW(5));
433 
434  }
435  if(wrtNeutrino){
436 
437  e0.Fill(volume.getX(Enu, true));
438  er.Fill(volume.getX(Efit) - volume.getX(Enu));
439  ee.Fill(volume.getX(Enu), volume.getX(Efit));
440  ea.Fill(Efit - Enu);
441  hzenith.Fill(Enu, zenith);
442 
443  herrorE.Fill(x, volume.getX(Efit) - volume.getX(Enu));
444  hfracE.Fill(x, fabs(volume.getX(Efit) - volume.getX(Enu))/volume.getX(Enu));
445 
446  if(Enu >= 3 && Enu <= 5) ed3_5GeV.Fill(Efit - Enu);
447  else if(Enu >= 8 && Enu <= 11) ed8_11GeV.Fill(Efit - Enu);
448  else if(Enu >= 15 && Enu <= 21) ed15_21GeV.Fill(Efit - Enu);
449 
450  } else {
451 
452  e0.Fill(volume.getX(Elep, true));
453  er.Fill(volume.getX(Efit) - volume.getX(Elep));
454  ee.Fill(volume.getX(Elep), volume.getX(Efit));
455  ea.Fill(Efit - Elep);
456  hzenith.Fill(Elep, zenith);
457 
458  herrorE.Fill(x, volume.getX(Efit) - volume.getX(Elep));
459  hfracE.Fill(x, fabs(volume.getX(Efit) - volume.getX(Elep))/volume.getX(Elep));
460 
461  if(Elep >= 3 && Elep <= 5) ed3_5GeV.Fill(Efit - Elep);
462  else if(Elep >= 8 && Elep <= 11) ed8_11GeV.Fill(Efit - Elep);
463  else if(Elep >= 15 && Elep <= 21) ed15_21GeV.Fill(Efit - Elep);
464 
465  }
466 
467  e2.Fill(volume.getX(Efit, true));
468 
469  h2.Fill(x, beta);
470  }
471  }
472  }
473 
474  he.Fill(x, W);}
475 
476  STATUS(endl);
477 
478  NOTICE("Number of events input " << setw(8) << right << job.GetBinContent(1) << endl);
479  if(!isMuon){
480  NOTICE("Number of events with electron " << setw(8) << right << job.GetBinContent(3) << endl);
481  } else{
482  NOTICE("Number of events with muon " << setw(8) << right << job.GetBinContent(3) << endl);
483  }
484  NOTICE("Number of events with fit " << setw(8) << right << job.GetBinContent(4) << endl);
485  NOTICE("Number of events selected " << setw(8) << right << job.GetBinContent(5) << endl);
486  NOTICE("Number of events with neutrino " << setw(8) << right << job.GetBinContent(6) << endl);
487  NOTICE("Number of events contained " << setw(8) << right << job.GetBinContent(7) << endl);
488 
489  if (Q.getCount() != 0) {
490  NOTICE("Median space angle [deg] " << FIXED (6,3) << Q.getQuantile(0.5) << endl);
491  }
492 
493  out.Write();
494  out.Close();
495 }
Data structure for vector in two dimensions.
Definition: JVector2D.hh:32
bool is_electron(const Trk &track)
Test whether given track is a (anti-)electron.
Utility class to parse command line options.
Definition: JParser.hh:1711
double getAngle(const JQuaternion3D &first, const JQuaternion3D &second)
Get space angle between quanternions.
General exception.
Definition: JException.hh:24
Q(UTCMax_s-UTCMin_s)-livetime_s
Auxiliary class to compare fit results with respect to a reference position (e.g. true muon)...
Auxiliary class to compare fit results with respect to a reference direction (e.g. true muon).
Vec getOffset(const JHead &header)
Get offset.
JCylinder3D getCylinder(const JHead &header)
Get cylinder corresponding to the positions of generated tracks (i.e.
JTrack3E getTrack(const Trk &track)
Get track.
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
Data structure for circle in two dimensions.
Definition: JCircle2D.hh:33
JTime & sub(const JTime &value)
Subtraction operator.
#define STATUS(A)
Definition: JMessage.hh:63
bool has_neutrino(const Evt &evt)
Test whether given event has an incoming neutrino.
double getIntersection(const JVector3D &pos) const
Get longitudinal position along axis of position of closest approach with given position.
Definition: JAxis3D.hh:146
bool is_muon(const Trk &track)
Test whether given track is a (anti-)muon.
static const int JSHOWERPOINTSIMPLEX
General purpose sorter of fit results.
Auxiliary class to synchronously read DAQ events and Monte Carlo events (and optionally other events)...
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:84
Auxiliary class to convert DAQ hit time to/from Monte Carlo hit time.
JCylinder3D & add(const JVector3D &pos)
Add position.
Definition: JCylinder3D.hh:156
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:446
string outputFile
double E
Energy [GeV] (either MC truth or reconstructed)
Definition: Trk.hh:20
static const int JSHOWERENERGYPREFIT
3D track with energy.
Definition: JTrack3E.hh:30
JVersor3D getDirection(const JVector3D &pos) const
Get photon direction of Cherenkov light on PMT.
Definition: JTrack3D.hh:147
JTime & add(const JTime &value)
Addition operator.
static const int JSHOWERPOSITIONFIT
Head getHeader(const JMultipleFileScanner_t &file_list)
Get Monte Carlo header.
Auxiliary class for histogramming of effective volume.
Definition: JVolume.hh:29
Auxiliary class for defining the range of iterations of objects.
Definition: JLimit.hh:41
const_iterator< T > end() const
Get end of data.
static const int JSHOWERPREFIT
Cylinder object.
Definition: JCylinder3D.hh:39
JDirection3D getDirection(const Vec &dir)
Get direction.
Data structure for vector in three dimensions.
Definition: JVector3D.hh:34
Acoustic event fit.
Monte Carlo run header.
Definition: JHead.hh:1234
const_iterator< T > begin() const
Get begin of data.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:2158
static const JGeanz geanz(1.85, 0.62, 0.54)
Function object for longitudinal EM-shower profile.
Auxiliary class to test history.
Definition: JHistory.hh:105
static const int JSHOWERDIRECTIONPREFIT
double getTheta() const
Get theta angle.
Definition: JVersor3D.hh:128
JPosition3D getPosition(const Vec &pos)
Get position.
#define NOTICE(A)
Definition: JMessage.hh:64
static const double PI
Mathematical constants.
static const int JSHOWER_BJORKEN_Y
const JPosition3D & getPosition() const
Get position.
Definition: JPosition3D.hh:130
Reconstruction type dependent comparison of track quality.
Auxiliary class to evaluate atmospheric muon hypothesis.
double getT(const JVector3D &pos) const
Get arrival time of Cherenkov light at given position.
Definition: JTrack3D.hh:126
counter_type advance(counter_type &counter, const counter_type value, const counter_type limit=std::numeric_limits< counter_type >::max())
Advance counter.
static const int JSHOWERCOMPLETEFIT
#define FATAL(A)
Definition: JMessage.hh:67
Vec getOrigin(const JHead &header)
Get origin.
then for APP in event gandalf start energy
Definition: JMuonMCEvt.sh:44
Data structure for position in two dimensions.
Definition: JPosition2D.hh:31
Auxiliary data structure for average.
Definition: JKatoomba_t.hh:76
double getMaximum(const double E) const
Get depth of shower maximum.
Definition: JGeanz.hh:162
int getCount(const T &hit)
Get hit count.
no fit printf nominal n $STRING awk v X
Data structure for position in three dimensions.
Definition: JPosition3D.hh:36
const JLimit & getLimit() const
Get limit.
Definition: JLimit.hh:84
const Trk & get_neutrino(const Evt &evt)
Get incoming neutrino.
The Trk class represents a Monte Carlo (MC) particle as well as a reconstructed track/shower.
Definition: Trk.hh:14
JVector3D & add(const JVector3D &vector)
Add vector.
Definition: JVector3D.hh:142
int debug
debug level
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.
Definition: Evt.hh:20
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62