Jpp  debug
the software that should make you happy
Functions
JMuonPostfit.cc File Reference

Example program to histogram fit results for the muon reconstruction chain. 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 "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 79 of file JMuonPostfit.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  string primary;
99  int debug;
100 
101  try {
102 
103  JParser<> zap("Example program to histogram fit results.");
104 
105  zap['f'] = make_field(inputFile);
106  zap['o'] = make_field(outputFile) = "postfit.root";
107  zap['n'] = make_field(numberOfEvents) = JLimit::max();
108  zap['N'] = make_field(numberOfPrefits) = 1;
110  zap['E'] = make_field(Emin_GeV) = 0.0;
111  zap['M'] = make_field(NPE) = 0.0;
113  zap['a'] = make_field(atmosphere) = JAtmosphericMuon(90.0, 90.0);
114  zap['O'] = make_field(option) = "E", "N", "LINE", "LOGE";
115  zap['p'] = make_field(primary) = muon_t, neutrino_t;
116  zap['d'] = make_field(debug) = 2;
117 
118  zap(argc, argv);
119  }
120  catch(const exception& error) {
121  FATAL(error.what() << endl);
122  }
123 
124  JHead head;
125 
126  try {
127  head = getCommonHeader(inputFile);
128  }
129  catch(const exception& error) {
130  FATAL(error.what() << endl);
131  }
132 
133  JVolume volume(head, option != "LINE");
134  JPosition3D offset = getPosition(getOffset(head));
136  JCylinder3D cylinder = getCylinder(head);
137 
138  cylinder.add(offset);
139 
140  NOTICE("Offset: " << offset << endl);
141  NOTICE("Cylinder: " << cylinder << endl);
142 
143  TFile out(outputFile.c_str(), "recreate");
144 
145  TH1D job("job", NULL, 100, 0.5, 100.5);
146 
147  TH1D hn("hn", NULL, 250, -0.5, 249.5); // NDF
148  TH1D hq("hq", NULL, 300, 0.0, 600.0); // quality parameter
149  TH1D hi("hi", NULL, 101, -0.5, 100.5); // index of the best event in order of descending angular resolution
150  TH1D hv("hv", NULL, 200, -6.0, 0.0); // log of Poisson distribution of (#hits,number photo-electrons)
151  TH1D h1("h1", NULL, 200, -2.0, +2.0); // number of photo-electrons along the whole track
152  TH1D hc("hc", NULL, 200, -1.0, +1.0); // dz (z-slope)
153  TH1D hu("hu", NULL, 400, -1.0e3, 1.0e3); // quality difference between best up-going and down-going track (check of atmospheric muon)
154 
155  TH1D hx("hx", NULL, 70, -3.0, +2.3); // angular deviation [log(deg)]
156  TH1D hd("hd", NULL, 100, 0.0, 10.0); // distance between true and best event at intersection point [m]
157  TH1D ht("ht", NULL, 100, -100.0, 100.0); // time between true and best track [ns]
158 
159  TH1D hz0("hz0[start]", NULL, 400, -200.0, 200.0); // start point [m]
160  TH1D hz1("hz1[end]", NULL, 400, -200.0, 200.0); // end point [m]
161 
162  TH1D E_0("E_0", NULL, 100, volume.getXmin(), volume.getXmax()); // true muon energy
163  TH1D E_1("E_1", NULL, 100, volume.getXmin(), volume.getXmax()); // uncorrected energy of best track
164  TH1D E_2("E_2", NULL, 100, volume.getXmin(), volume.getXmax()); // corrected energy of best track
165  TH1D E_E("E_E", NULL, 100, -5.0, +5.0); // ratio of reconstructed energy and true energy [log(E/E)]
166  TH2D ExE("ExE", NULL,
167  40, volume.getXmin(), volume.getXmax(),
168  40, volume.getXmin(), volume.getXmax()); // (Etrue,Ereco)
169 
170  const Int_t ny = 28800;
171  const Double_t ymin = 0.0; // [deg]
172  const Double_t ymax = 180.0; // [deg]
173 
174  vector<double> X;
175 
176  if (option.find('E') != string::npos) {
177 
178  for (double x = volume.getXmin(), dx = (volume.getXmax() - volume.getXmin()) / 20.0; x < volume.getXmax() + 0.5*dx; x += dx) {
179  X.push_back(x);
180  }
181 
182  } else {
183 
184  const double xmin = log((double) 1);
185  const double xmax = log((double) 300);
186 
187  for (double x = xmin, dx = (xmax - xmin) / 25; x <= xmax; x += dx) {
188  X.push_back((int) exp(x));
189  }
190  }
191 
192  TH2D h2("h2", NULL, X.size() - 1, X.data(), ny, ymin, ymax);
193 
194  TH2D Va("Va", NULL,
195  100, 0.0, cylinder.getRadius()*cylinder.getRadius(),
196  100, cylinder.getZmin() - 50.0, cylinder.getZmax() + 50.0);
197  TH2D Vb("Vb", NULL,
198  100, 0.0, cylinder.getRadius()*cylinder.getRadius(),
199  100, cylinder.getZmin() - 50.0, cylinder.getZmax() + 50.0);
200 
201  JQuantile Q("Angle", true);
202  JQuantile O("Omega", true);
203 
204 
205  while (inputFile.hasNext()) {
206 
207  STATUS("event: " << setw(10) << inputFile.getCounter() << '\r'); DEBUG(endl);
208 
209  multi_pointer_type ps = inputFile.next();
210 
211  JDAQEvent* tev = ps;
212  JEvt* evt = ps;
213  Evt* event = ps;
214 
215  const time_converter converter(*event, *tev);
216 
217  job.Fill(1.0);
218 
219 
220  double Enu = 0.0;
221  double Emu = 0.0;
222  double Emax = 0.0;
223 
224  if (has_neutrino(*event)) {
225  Enu = get_neutrino(*event).E;
226  }
227 
228  vector<Trk>::const_iterator muon = event->mc_trks.end();
229 
230  for (vector<Trk>::const_iterator track = event->mc_trks.begin(); track != event->mc_trks.end(); ++track) {
231 
232  if (is_muon(*track)) {
233 
234  Emu += track->E;
235 
236  if (track->E > Emax) {
237  muon = track;
238  Emax = track->E;
239  }
240  }
241  }
242 
243  if (muon == event->mc_trks.end()) {
244  continue;
245  }
246 
247  job.Fill(3.0);
248 
249 
250  // abscissa
251 
252  Double_t x = 0.0;
253 
254  if (option.find('E') != string::npos)
255  x = volume.getX(event->mc_trks[0].E);
256  else
257  x = getCount(tev->begin<JDAQTriggeredHit>(), tev->end<JDAQTriggeredHit>());
258 
259  if (!evt->empty()) {
260 
261  JEvt::iterator __end = partition(evt->begin(), evt->end(), JHistory::is_event(application));
262 
263  if (evt->begin() == __end) {
264  continue;
265  }
266 
267  job.Fill(4.0);
268 
269  if (numberOfPrefits > 0) {
270 
271  JEvt::iterator __q = __end;
272 
273  advance(__end = evt->begin(), min(numberOfPrefits, (size_t) distance(evt->begin(), __q)));
274 
275  partial_sort(evt->begin(), __end, __q, quality_sorter);
276 
277  } else {
278 
279  sort(evt->begin(), __end, quality_sorter);
280  }
281 
282  double E = 0.0;
283  JPointing pointing;
284 
285  if (primary == muon_t) {
286  E = Emu;
287  pointing = JPointing(getDirection(*muon));
288  } else if (primary == neutrino_t) {
289  E = Enu;
290  pointing = JPointing(getDirection(get_neutrino(*event)));
291  }
292 
293  JEvt::iterator best = pointing(evt->begin(), __end);
294  const Double_t beta = pointing.getAngle(*best);
295  const double Efit = best->getE();
296  const double Eraw = best->getW(JENERGY_ENERGY, numeric_limits<double>::min());
297  const double mip = best->getW(JSTART_NPE_MIP, numeric_limits<double>::max());
298 
299  // selection of fit result
300 
301  bool ok = (Efit >= Emin_GeV && mip >= NPE);
302 
303  if (ok) {
304 
305  job.Fill(5.0);
306 
307  hn.Fill((Double_t) best->getNDF());
308  hq.Fill(best->getQ());
309  hi.Fill((Double_t) distance(evt->begin(), best));
310  hc.Fill(best->getDZ());
311 
312  // atmospheric muon hypothesis test.
313 
314  if (( has_neutrino(*event) && get_neutrino(*event).dir.z >= atmosphere.dot2) || // difference in quality between best upwards and best downgoing track.
315  (!has_neutrino(*event) && best->getDZ() >= atmosphere.dot2)) { // negative (positive) values imply a down(up) going track.
316  hu.Fill(atmosphere(evt->begin(), __end));
317  }
318 
319  hx.Fill(max(log10(beta), hx.GetXaxis()->GetXmin()));
320 
321  Q.put(beta);
322 
323  JTrack3E ta = getTrack(*muon);
324  JTrack3E tb = getTrack(*best);
325 
326  ta.add(offset);
327  tb.sub(converter.putTime());
328 
329  static_cast<JTrack3D&>(ta).move(ta.getIntersection(tb), getSpeedOfLight()); // move to intersection point of both tracks
330  static_cast<JTrack3D&>(tb).move(tb.getIntersection(ta), getSpeedOfLight());
331 
332  hd.Fill((tb.getPosition() - ta.getPosition()).getLength());
333 
334  if (has_neutrino(*event)) {
335 
336  job.Fill(6.0);
337 
338  const Trk neutrino = get_neutrino(*event);
339 
340  JPosition3D vertex = getPosition(neutrino);
341 
342  vertex.add(offset);
343 
344  if (cylinder.is_inside(vertex)) {
345 
346  job.Fill(7.0);
347 
348  Va.Fill(JVector2D(best->getX() - origin.getX(), best->getY() - origin.getY()).getLengthSquared(), best->getZ()); //R^{2} [m^2], z [m]
349 
350  JTrack3E tc = getTrack(*best);
351 
352  hz0.Fill(tc.getIntersection(vertex));
353  hz1.Fill(best->getW(JSTART_LENGTH_METRES, 0.0) - gWater(muon->E));
354  }
355  }
356 
357  Vb.Fill(JVector2D(best->getX() - origin.getX(), best->getY() - origin.getY()).getLengthSquared(), best->getZ()); //R^{2} [m^2], z [m]
358  ht.Fill(tb.getT() - ta.getT());
359 
360  E_0.Fill(volume.getX(E, true));
361  E_1.Fill(volume.getX(Eraw, true));
362  E_2.Fill(volume.getX(Efit, true));
363  E_E.Fill(volume.getX(Efit) - volume.getX(E));
364  ExE.Fill(volume.getX(E), volume.getX(Efit));
365 
366  h2.Fill(x, beta);
367 
368  if (best->hasW(JSTART_NPE_MIP)) {
369  h1.Fill(log10(best->getW(JSTART_NPE_MIP)));
370  }
371 
372  if (best->hasW(JVETO_NPE) && best->hasW(JVETO_NUMBER_OF_HITS)) {
373 
374  const double npe = best->getW(JVETO_NPE); // number of photo-electrons
375  const int count = best->getW(JVETO_NUMBER_OF_HITS); // number of hits
376  const double pv = TMath::PoissonI(count, npe); // Poisson distribution function for (#hits,npe)
377 
378  hv.Fill(max(log10(pv), hv.GetXaxis()->GetXmin()));
379  }
380  }
381  }
382  }
383  STATUS(endl);
384 
385  NOTICE("Number of events input " << setw(8) << right << job.GetBinContent(1) << endl);
386  NOTICE("Number of events with muon " << setw(8) << right << job.GetBinContent(3) << endl);
387  NOTICE("Number of events with fit " << setw(8) << right << job.GetBinContent(4) << endl);
388  NOTICE("Number of events selected " << setw(8) << right << job.GetBinContent(5) << endl);
389  NOTICE("Number of events with neutrino " << setw(8) << right << job.GetBinContent(6) << endl);
390  NOTICE("Number of events contained " << setw(8) << right << job.GetBinContent(7) << endl);
391 
392  if (Q.getCount() != 0) {
393  NOTICE("Median space angle [deg] " << FIXED (6,3) << Q.getQuantile(0.5) << endl);
394  }
395 
396  out.Write();
397  out.Close();
398 }
string outputFile
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62
#define STATUS(A)
Definition: JMessage.hh:63
#define NOTICE(A)
Definition: JMessage.hh:64
#define FATAL(A)
Definition: JMessage.hh:67
int debug
debug level
Definition: JSirene.cc:69
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:2158
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
Monte Carlo run header.
Definition: JHead.hh:1236
double getRadius() const
Get radius.
Definition: JCircle2D.hh:144
Data structure for vector in two dimensions.
Definition: JVector2D.hh:34
double getLengthSquared() const
Get length squared.
Definition: JVector2D.hh:188
double getIntersection(const JVector3D &pos) const
Get longitudinal position along axis of position of closest approach with given position.
Definition: JAxis3D.hh:146
Cylinder object.
Definition: JCylinder3D.hh:41
double getZmin() const
Get minimal z position.
Definition: JCylinder3D.hh:111
bool is_inside(const JVector3D &pos) const
Check whether given point is inside cylinder.
Definition: JCylinder3D.hh:208
JCylinder3D & add(const JVector3D &pos)
Add position.
Definition: JCylinder3D.hh:156
double getZmax() const
Get maximal z position.
Definition: JCylinder3D.hh:122
Data structure for position in three dimensions.
Definition: JPosition3D.hh:38
const JPosition3D & getPosition() const
Get position.
Definition: JPosition3D.hh:130
JTime & add(const JTime &value)
Addition operator.
double getT(const JVector3D &pos) const
Get arrival time of Cherenkov light at given position.
Definition: JTrack3D.hh:126
JTime & sub(const JTime &value)
Subtraction operator.
3D track with energy.
Definition: JTrack3E.hh:32
JVector3D & add(const JVector3D &vector)
Add vector.
Definition: JVector3D.hh:142
Utility class to parse command line options.
Definition: JParser.hh:1714
Auxiliary class to evaluate atmospheric muon hypothesis.
Auxiliary class to compare fit results with respect to a reference direction (e.g....
double getAngle(const JFit &fit) const
Get angle between reference direction and fit result.
const_iterator< T > end() const
Get end of data.
const_iterator< T > begin() const
Get begin of data.
Auxiliary class to convert DAQ hit time to/from Monte Carlo hit time.
static const int JMUONGANDALF
static const int JMUONPREFIT
static const int JMUONENERGY
static const int JMUONSIMPLEX
static const int JMUONPATH
static const int JMUONSTART
static const int JENERGY_ENERGY
uncorrected energy [GeV] from JEnergy.cc
static const int JVETO_NPE
number of photo-electrons from JVeto.cc
static const int JSTART_LENGTH_METRES
distance between first and last hits in metres from JStart.cc
static const int JVETO_NUMBER_OF_HITS
number of hits from JVeto.cc
static const int JSTART_NPE_MIP
number of photo-electrons up to the barycentre from JStart.cc
const double xmax
Definition: JQuadrature.cc:24
const double xmin
Definition: JQuadrature.cc:23
const Trk & get_neutrino(const Evt &evt)
Get incoming neutrino.
Vec getOrigin(const JHead &header)
Get origin.
JDirection3D getDirection(const Vec &dir)
Get direction.
JTrack3E getTrack(const Trk &track)
Get track.
JCylinder3D getCylinder(const JHead &header)
Get cylinder corresponding to the positions of generated tracks (i.e.
bool has_neutrino(const Evt &evt)
Test whether given event has an incoming neutrino.
JPosition3D getPosition(const Vec &pos)
Get position.
bool is_muon(const Trk &track)
Test whether given track is a (anti-)muon.
Vec getOffset(const JHead &header)
Get offset.
size_t getCount(const array_type< T > &buffer, const JCompare_t &compare)
Count number of unique values.
Definition: JVectorize.hh:261
static const JGeaneWater gWater
Function object for energy loss of muon in sea water.
Definition: JGeane.hh:381
const double getSpeedOfLight()
Get speed of light.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
counter_type advance(counter_type &counter, const counter_type value, const counter_type limit=std::numeric_limits< counter_type >::max())
Advance counter.
Head getCommonHeader(const JMultipleFileScanner_t &file_list)
Get common Monte Carlo header.
KM3NeT DAQ data structures and auxiliaries.
Definition: DataQueue.cc:39
const char *const neutrino_t
Definition: io_ascii.hh:29
Definition: JSTDTypes.hh:14
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.
Definition: Evt.hh:21
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:448
Auxiliary class for histogramming of effective volume.
Definition: JVolume.hh:29
Primary particle.
Definition: JHead.hh:1174
Acoustic event fit.
Auxiliary class to test history.
Definition: JHistory.hh:105
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:84
General purpose sorter of fit results.
Auxiliary class for defining the range of iterations of objects.
Definition: JLimit.hh:45
const JLimit & getLimit() const
Get limit.
Definition: JLimit.hh:84
Auxiliary class to synchronously read DAQ events and Monte Carlo events (and optionally other events)...
Auxiliary data structure for running average, standard deviation and quantiles.
Definition: JQuantile.hh:46
The Trk class represents a Monte Carlo (MC) particle as well as a reconstructed track/shower.
Definition: Trk.hh:15
Vec dir
track direction
Definition: Trk.hh:18
double E
Energy [GeV] (either MC truth or reconstructed)
Definition: Trk.hh:20
double z
Definition: Vec.hh:14
Reconstruction type dependent comparison of track quality.