Jpp
Functions
JMuonPostfit.cc File Reference
#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 "JAAnet/JHead.hh"
#include "JAAnet/JHeadToolkit.hh"
#include "JDAQ/JDAQEventIO.hh"
#include "JTools/JConstants.hh"
#include "JTools/JQuantile.hh"
#include "JTrigger/JTimeConverter.hh"
#include "JSupport/JTriggeredFileScanner.hh"
#include "JSupport/JMonteCarloFileSupportkit.hh"
#include "JSupport/JSupport.hh"
#include "JFit/JEvt.hh"
#include "JFit/JEvtToolkit.hh"
#include "JFit/JFitParameters.hh"
#include "JGizmo/JVolume.hh"
#include "JLang/JPredicate.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 fit results for the muon reconstruction chain.

Author
mdejong, bofearraigh.

Definition in file JMuonPostfit.cc.

Function Documentation

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 73 of file JMuonPostfit.cc.

74 {
75  using namespace std;
76  using namespace JPP;
77  using namespace KM3NETDAQ;
78 
79  typedef JTriggeredFileScanner<JEvt> JTriggeredFileScanner_t;
80  typedef JTriggeredFileScanner_t::multi_pointer_type multi_pointer_type;
81 
82  JTriggeredFileScanner_t inputFile;
83  JLimit_t& numberOfEvents = inputFile.getLimit();
84  string outputFile;
85  size_t numberOfPrefits;
87  JAtmosphericMuon atmosphere;
88  double Emin_GeV;
89  double NPE;
90  int application;
91  string option;
92  int debug;
93 
94  try {
95 
96  JParser<> zap("Example program to histogram fit results.");
97 
98  zap['f'] = make_field(inputFile);
99  zap['o'] = make_field(outputFile) = "postfit.root";
100  zap['n'] = make_field(numberOfEvents) = JLimit::max();
101  zap['N'] = make_field(numberOfPrefits) = 1;
103  zap['E'] = make_field(Emin_GeV) = 0.0;
104  zap['M'] = make_field(NPE) = 0.0;
106  zap['a'] = make_field(atmosphere) = JAtmosphericMuon(90.0, 90.0);
107  zap['O'] = make_field(option) = "E", "N", "LINE", "LOGE";
108  zap['d'] = make_field(debug) = 2;
109 
110  zap(argc, argv);
111  }
112  catch(const exception& error) {
113  FATAL(error.what() << endl);
114  }
115 
116  JHead head;
117 
118  try {
119  head = getHeader(inputFile);
120  }
121  catch(const JException& error) {
122  FATAL(error);
123  }
124 
125  const JVolume volume(head, option != "LINE");
126  const JPosition3D center = get<JPosition3D>(head);
127  JCylinder3D cylinder = get<JCylinder3D>(head);
128 
129  cylinder.add(center);
130 
131  NOTICE("Reposition can [m]: " << cylinder << endl);
132 
133  const double EMIN_GEV = 10; // set to low value for ORCA..
134  const double E_nu_min = head.cut_nu.Emin; //neutrino minimum energy
135  const double E_nu_max = head.cut_nu.Emax; //neutrino maximum energy
136 
137  TFile out(outputFile.c_str(), "recreate");
138 
139  TH1D job("job", NULL, 100, 0.5, 100.5);
140 
141  TH1D hn("hn", NULL, 250, -0.5, 249.5); //NDF
142  TH1D hq("hq", NULL, 300, 0.0, 600.0); //quality parameter
143  TH1D hi("hi", NULL, 101, -0.5, 100.5); //index of the best event in order of descending angular resolution
144  TH1D hv("hv", NULL, 200, -6.0, 0.0); //log of Poisson distribution of (#hits,number photo-electrons)
145  TH1D h1("h1", NULL, 200, -2.0, +2.0); //number of photo-electrons along the whole track
146  TH1D hc("hc", NULL, 200, -1.0, +1.0); //dz (z-slope)
147  TH1D hu("hu", NULL, 400, -1.0e3, 1.0e3); //quality difference between best up-going and down-going track (check of atmospheric muon)
148 
149  TH1D hx("hx", NULL, 70, -3.0, +2.3); // angular deviation [log(deg)]
150  TH1D hd("hd", NULL, 100, 0.0, 10.0); // distance between true and best event at intersection point [m]
151  TH1D hz("hz", NULL, 100, -200.0, 200.0); // intersection of track with neutrino vertex [m]
152  TH1D ht("ht", NULL, 100, -100.0, 100.0); // time between true and best track [ns]
153 
154  TH1D e0("e0", NULL, 100, volume.getXmin(), volume.getXmax()); // true track energy [log(E)]
155  TH1D e1("e1", NULL, 100, volume.getXmin(), volume.getXmax()); // uncorrected energy [log(E)]
156  TH1D e2("e2", NULL, 100, volume.getXmin(), volume.getXmax()); // energy of best track[log(E)]
157  TH1D er("er", NULL, 100, -5.0, +5.0); // ratio of reconstructed energy and true energy [log(E/E)]
158  TH2D ee("ee", NULL,
159  40, volume.getXmin(), volume.getXmax(),
160  40, volume.getXmin(), volume.getXmax()); //(Etrue,Ereco)
161 
162  TH2D muon_angle_Emu("muon_angle_Emu", NULL, 30, E_nu_min, E_nu_max, 100, 0,90); // energy vs angular deviation between true muon and reco muon direction
163  TH2D muon_angle_Enu("muon_angle_Enu", NULL, 30, E_nu_min, E_nu_max, 100, 0,90); // energy vs angular deviation between true muon and reco muon direction
164  TH2D neutrino_angle_Enu("neutrino_angle_Enu", NULL, 30, E_nu_min, E_nu_max, 100, 0,90); // energy vs angular deviation between neutrino and reco muon direction
165  TH2D MC_angle_Enu("MC_angle_Enu", NULL, 30, E_nu_min, E_nu_max, 100, 0,90); // energy vs angular deviation between neutrino and true muon direction
166 
167  const Int_t ny = 28800;
168  const Double_t ymin = 0.0; // [deg]
169  const Double_t ymax = 180.0; // [deg]
170 
171  vector<double> X;
172 
173  if (option.find('E') != string::npos) {
174 
175  for (double x = volume.getXmin(); x <= volume.getXmax(); x += (volume.getXmax() - volume.getXmin()) / 20) {
176  X.push_back(x);
177  }
178 
179  } else {
180 
181  double x = -0.5;
182 
183  for ( ; x <= 15.5; x += 1.0) { X.push_back(x); }
184  for ( ; x <= 25.5; x += 2.0) { X.push_back(x); }
185  for ( ; x <= 50.5; x += 5.0) { X.push_back(x); }
186  for ( ; x <= 100.5; x += 10.0) { X.push_back(x); }
187  for ( ; x <= 250.5; x += 20.0) { X.push_back(x); }
188  }
189 
190  TH2D h2("h2", NULL, X.size() - 1, X.data(), ny, ymin, ymax);
191  TProfile he("he", NULL, X.size() - 1, X.data());
192 
193  TH2D ha("ha", NULL, 100, 0.0, 0.5e6, 100, -100.0, +900.0);
194  TH2D hb("hb", NULL, 100, 0.0, 0.5e6, 100, -100.0, +900.0);
195 
196  JQuantile Q("Angle", true);
197  JQuantile O("Omega", true);
198 
199 
200  while (inputFile.hasNext()) {
201 
202  STATUS("event: " << setw(10) << inputFile.getCounter() << '\r'); DEBUG(endl);
203 
204  multi_pointer_type ps = inputFile.next();
205 
206  JDAQEvent* tev = ps;
207  JEvt* evt = ps;
208  Evt* event = ps;
209 
210  const JTimeConverter converter(*event, *tev);
211 
212  job.Fill(1.0);
213 
214 
215  double Emu = 0.0;
216  double Emax = 0.0;
217 
218  vector<Trk>::const_iterator muon = event->mc_trks.end();
219 
220  for (vector<Trk>::const_iterator track = event->mc_trks.begin(); track != event->mc_trks.end(); ++track) {
221 
222  if (is_muon(*track)) {
223 
224  Emu += track->E;
225 
226  if (track->E > Emax) {
227  muon = track;
228  Emax = track->E;
229  }
230  }
231  }
232 
233  if (muon == event->mc_trks.end()) {
234  continue;
235  }
236 
237  job.Fill(3.0);
238 
239 
240  // abscissa
241 
242  Double_t x = 0.0;
243 
244  if (option.find('E') != string::npos)
245  x = volume.getX(event->mc_trks[0].E);
246  else
247  x = getCount(tev->begin<JDAQTriggeredHit>(), tev->end<JDAQTriggeredHit>());
248 
249 
250  // weight for efficiency determination
251 
252  Double_t W = 0.0;
253 
254  if (!evt->empty()) {
255 
256  JEvt::iterator __end = partition(evt->begin(), evt->end(), JHistory::is_event(application));
257 
258  if (evt->begin() == __end) {
259  continue;
260  }
261 
262  job.Fill(4.0);
263 
264  if (numberOfPrefits > 0) {
265 
266  JEvt::iterator __q = __end;
267 
268  advance(__end = evt->begin(), min(numberOfPrefits, (size_t) distance(evt->begin(), __q)));
269 
270  partial_sort(evt->begin(), __end, __q, quality_sorter);
271 
272  } else {
273 
274  sort(evt->begin(), __end, quality_sorter);
275  }
276 
277  const JPointing pointing(getDirection(*muon));
278 
279  JEvt::iterator best = pointing(evt->begin(), __end);
280  const Double_t beta = pointing.getAngle(*best);
281  const double Efit = best->getE();
282  const double Eraw = best->getW(JENERGY_ENERGY, numeric_limits<double>::min());
283  const double mip = best->getW(JSTART_NPE_MIP, numeric_limits<double>::max());
284 
285  // selection of fit result
286 
287  bool ok = (Efit >= Emin_GeV &&
288  mip >= NPE);
289 
290  if (ok) {
291 
292  W = 1.0;
293 
294  job.Fill(5.0);
295 
296  hn.Fill((Double_t) best->getNDF());
297  hq.Fill(best->getQ());
298  hi.Fill((Double_t) distance(evt->begin(), best));
299  hc.Fill(best->getDZ());
300 
301  if (( has_neutrino(*event) && get_neutrino(*event).dir.z >= atmosphere.dot2) || //Atmospheric muon hypothesis test. Difference in quality between best upwards and best downgoing track.
302  (!has_neutrino(*event) && best->getDZ() >= atmosphere.dot2)) { //negative values imply a down going track, positive an up-going track.
303  hu.Fill(atmosphere(evt->begin(), __end));
304  }
305 
306  hx.Fill(max(log10(beta), hx.GetXaxis()->GetXmin()));
307 
308  Q.put(beta);
309 
310  const Trk neutrino = get_neutrino(*event);
311  JTrack3E ta = getTrack(*muon);
312  JTrack3E tb = getTrack(*best);
313 
314  ta.add(center);
315  tb.sub(converter.putTime());
316 
317  static_cast<JTrack3D&>(ta).move(ta.getIntersection(tb), getSpeedOfLight()); //move to intersection point of both tracks
318  static_cast<JTrack3D&>(tb).move(tb.getIntersection(ta), getSpeedOfLight());
319 
320  hd.Fill((tb.getPosition() - ta.getPosition()).getLength());
321 
322  if (has_neutrino(*event)) {
323 
324  job.Fill(6.0);
325 
326  JPosition3D vertex = getPosition(neutrino);
327 
328  vertex.add(center);
329 
330  if (cylinder.is_inside(vertex)) {
331 
332  job.Fill(7.0);
333 
334  JTrack3E tc = getTrack(*best);
335 
336  ha.Fill(best->getX()*best->getX() + best->getY()*best->getY(), best->getZ()); //R^{2} [m^2],
337  hz.Fill(tc.getIntersection(vertex));
338  }
339  }
340 
341  if (best->getE() >= EMIN_GEV) {
342  hb.Fill(best->getX()*best->getX() + best->getY()*best->getY(), best->getZ()); //R^{2} [m^2], z [m]
343  }
344  ht.Fill(tb.getT() - ta.getT());
345 
346  e0.Fill(volume.getX(Emu, true));
347  e1.Fill(volume.getX(Eraw, true));
348  e2.Fill(volume.getX(Efit, true));
349  er.Fill(volume.getX(Efit) - volume.getX(Emu));
350  ee.Fill(volume.getX(Emu), volume.getX(Efit));
351  h2.Fill(x, beta);
352 
353  const double Enu = neutrino.E; //true neutrino E
354 
355  neutrino_angle_Enu.Fill(Enu, (180/M_PI)* acos(getDirection(*best).getDot(getDirection(neutrino))));
356  muon_angle_Enu.Fill(Enu,(180/M_PI)* acos(getDirection(*best).getDot(getDirection(*muon))));
357  muon_angle_Emu.Fill(Emu,(180/M_PI)* acos(getDirection(*best).getDot(getDirection(*muon))));
358  MC_angle_Enu.Fill(Enu, (180/M_PI)* acos(getDirection(*muon).getDot(getDirection(neutrino))));
359 
360 
361  if (best->hasW(JSTART_NPE_MIP)) {
362  h1.Fill(log10(best->getW(JSTART_NPE_MIP)));
363  }
364 
365  if (best->hasW(JVETO_NPE) && best->hasW(JVETO_NUMBER_OF_HITS)) {
366 
367  const double npe = best->getW(JVETO_NPE); //number of photoelectrons
368  const int count = best->getW(JVETO_NUMBER_OF_HITS); //number of hits
369  const double pv = TMath::PoissonI(count, npe); //Poisson distribution function for (#hits,npe)
370 
371  hv.Fill(max(log10(pv), hv.GetXaxis()->GetXmin()));
372  }
373  }
374  }
375 
376  he.Fill(x, W); //efficiency
377  }
378  STATUS(endl);
379 
380  NOTICE("Number of events input " << setw(8) << right << job.GetBinContent(1) << endl);
381  NOTICE("Number of events with muon " << setw(8) << right << job.GetBinContent(3) << endl);
382  NOTICE("Number of events with fit " << setw(8) << right << job.GetBinContent(4) << endl);
383  NOTICE("Number of events selected " << setw(8) << right << job.GetBinContent(5) << endl);
384  NOTICE("Number of events with neutrino " << setw(8) << right << job.GetBinContent(6) << endl);
385  NOTICE("Number of events contained " << setw(8) << right << job.GetBinContent(7) << endl);
386 
387  if (Q.getCount() != 0) {
388  NOTICE("Median space angle [deg] " << FIXED (6,3) << Q.getQuantile(0.5) << endl);
389  }
390 
391  out.Write();
392  out.Close();
393 }
JMUONENERGY
static const int JMUONENERGY
Definition: reconstruction.hh:17
JGEOMETRY3D::JTrack3D::sub
JTime & sub(const JTime &value)
Subtraction operator.
Definition: JGeometry3D/JTime.hh:80
JMUONSTART
static const int JMUONSTART
Definition: reconstruction.hh:18
KM3NETDAQ::JDAQEvent
DAQ Event.
Definition: JDAQEvent.hh:30
Vec::z
double z
Definition: Vec.hh:14
JMUONPREFIT
static const int JMUONPREFIT
Definition: reconstruction.hh:14
JSUPPORT::JLimit
Auxiliary class for defining the range of iterations of objects.
Definition: JLimit.hh:41
FIXED
Auxiliary data structure for floating point format specification.
Definition: JPrint.hh:481
JTOOLS::getSpeedOfLight
const double getSpeedOfLight()
Number of bytes in a gigabyte.
Definition: JConstants.hh:89
KM3NETDAQ::JDAQEvent::begin
const_iterator< T > begin() const
Get begin of data.
JROOT::advance
counter_type advance(counter_type &counter, const counter_type value, const counter_type limit=std::numeric_limits< counter_type >::max())
Advance counter.
Definition: JCounter.hh:35
JFIT::JAtmosphericMuon::dot2
double dot2
Definition: JEvtToolkit.hh:718
JPARSER::initialised
Empty structure for specification of parser element that is initialised (i.e.
Definition: JParser.hh:63
JAANET::JHead::cut_nu
JAANET::cut_nu cut_nu
Definition: JHead.hh:1081
JGEOMETRY3D::JCylinder3D::is_inside
bool is_inside(const JVector3D &pos) const
Check whether given point is inside cylinder.
Definition: JCylinder3D.hh:199
JGEOMETRY3D::JDirection3D::getDot
double getDot(const JAngle3D &angle) const
Get dot product.
Definition: JDirection3D.hh:333
Trk::E
double E
Energy (either MC truth or reconstructed)
Definition: Trk.hh:18
std::vector< double >
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
JGEOMETRY3D::JCylinder3D::add
JCylinder3D & add(const JVector3D &pos)
Add position.
Definition: JCylinder3D.hh:146
JTRIGGER::JTimeConverter
Auxiliary class to convert DAQ/trigger hit time to/from Monte Carlo hit time.
Definition: JTimeConverter.hh:36
JAANET::getTrack
JTrack3E getTrack(const Trk &track)
Get track.
Definition: JAAnetToolkit.hh:256
JPARSER::JParser
Utility class to parse command line options.
Definition: JParser.hh:1493
distance
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
Definition: PhysicsEvent.hh:434
NOTICE
#define NOTICE(A)
Definition: JMessage.hh:64
JFIT::JEvt
Data structure for set of track fit results.
Definition: JEvt.hh:293
JGEOMETRY3D::JTrack3D::getT
double getT(const JVector3D &pos) const
Get arrival time of Cherenkov light at given position.
Definition: JTrack3D.hh:126
JAANET::is_muon
bool is_muon(const Trk &track)
Test whether given track is a (anti-)muon.
Definition: JAAnetToolkit.hh:367
JAANET::JHead
Monte Carlo run header.
Definition: JHead.hh:839
Trk::dir
Vec dir
track direction
Definition: Trk.hh:16
KM3NETDAQ::JDAQEvent::end
const_iterator< T > end() const
Get end of data.
JPP
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Definition: JAAnetToolkit.hh:37
KM3NETDAQ::JDAQTriggeredHit
DAQ triggered hit.
Definition: JDAQTriggeredHit.hh:20
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
JSTART_NPE_MIP
static const int JSTART_NPE_MIP
number of photo-electrons up to the barycentre from JStart.cc
Definition: fitparameters.hh:20
JFIT::JQualitySorter
General purpose sorter of fit results.
Definition: JEvtToolkit.hh:239
JGEOMETRY3D::JTrack3D::add
JTime & add(const JTime &value)
Addition operator.
Definition: JGeometry3D/JTime.hh:66
debug
int debug
debug level
Definition: JSirene.cc:59
JGEOMETRY3D::JPosition3D
Data structure for position in three dimensions.
Definition: JPosition3D.hh:35
JAANET::get_neutrino
const Trk & get_neutrino(const Evt &evt)
Get incoming neutrino.
Definition: JAAnetToolkit.hh:438
JSUPPORT::JLimit::getLimit
const JLimit & getLimit() const
Get limit.
Definition: JLimit.hh:73
JMUONSIMPLEX
static const int JMUONSIMPLEX
Definition: reconstruction.hh:15
JAANET::has_neutrino
bool has_neutrino(const Evt &evt)
Test whether given event has an incoming neutrino.
Definition: JAAnetToolkit.hh:427
JMUONGANDALF
static const int JMUONGANDALF
Definition: reconstruction.hh:16
JGEOMETRY3D::JTrack3E
3D track with energy.
Definition: JTrack3E.hh:29
JGIZMO::JVolume
Auxiliary class for histogramming of effective volume.
Definition: JVolume.hh:26
JFIT::JHistory::is_event
Auxiliary class to test history.
Definition: JHistory.hh:101
JMUONPATH
static const int JMUONPATH
Definition: reconstruction.hh:40
STATUS
#define STATUS(A)
Definition: JMessage.hh:63
JTOOLS::JQuantile
Quantile calculator.
Definition: JQuantile.hh:34
JAANET::getDirection
JDirection3D getDirection(const Vec &v)
Get direction.
Definition: JAAnetToolkit.hh:221
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
JGEOMETRY3D::JPosition3D::getPosition
const JPosition3D & getPosition() const
Get position.
Definition: JPosition3D.hh:129
JAANET::getPosition
JPosition3D getPosition(const Vec &v)
Get position.
Definition: JAAnetToolkit.hh:197
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
JAANET::cut::Emax
double Emax
Maximal energy [GeV].
Definition: JHead.hh:211
JAANET::cut::Emin
double Emin
Minimal energy [GeV].
Definition: JHead.hh:210
JGEOMETRY3D::JAxis3D::getIntersection
double getIntersection(const JVector3D &pos) const
Get longitudinal position along axis of position of closest approach with given position.
Definition: JAxis3D.hh:157
JVETO_NPE
static const int JVETO_NPE
number of photo-electrons from JVeto.cc
Definition: fitparameters.hh:23
JFIT::JPointing
Auxiliary class to compare fit results with respect to a reference direction (e.g.
Definition: JEvtToolkit.hh:533
JGEOMETRY3D::JVector3D::add
JVector3D & add(const JVector3D &vector)
Add vector.
Definition: JVector3D.hh:141
JENERGY_ENERGY
static const int JENERGY_ENERGY
uncorrected energy [GeV] from JEnergy.cc
Definition: fitparameters.hh:16
FATAL
#define FATAL(A)
Definition: JMessage.hh:67
outputFile
string outputFile
Definition: JDAQTimesliceSelector.cc:37
JVETO_NUMBER_OF_HITS
static const int JVETO_NUMBER_OF_HITS
number of hits from JVeto.cc
Definition: fitparameters.hh:24
JFIT::JAtmosphericMuon
Auxiliary class to evaluate atmospheric muon hypothesis.
Definition: JEvtToolkit.hh:624
JLANG::JException
General exception.
Definition: JException.hh:23
JFIT::getCount
int getCount(const JHitL0 &hit)
Get hit count.
Definition: JEvtToolkit.hh:728
JAANET::quality_sorter
Reconstruction type dependent comparison of track quality.
Definition: JAAnetToolkit.hh:670