Jpp 21.0.0-rc.1
the software that should make you happy
Loading...
Searching...
No Matches
JMuonPostfit.cc
Go to the documentation of this file.
1#include <string>
2#include <iostream>
3#include <iomanip>
4#include <vector>
5#include <set>
6
7#include "TROOT.h"
8#include "TFile.h"
9#include "TH1D.h"
10#include "TH2D.h"
11#include "TProfile.h"
12#include "TMath.h"
13
20#include "JAAnet/JHead.hh"
23#include "JAAnet/JVolume.hh"
24#include "JDAQ/JDAQEventIO.hh"
26#include "JTools/JQuantile.hh"
29#include "JSupport/JSupport.hh"
32#include "JLang/JPredicate.hh"
33
34#include "Jeep/JParser.hh"
35#include "Jeep/JMessage.hh"
36
37
38namespace {
39
41
42
43 /**
44 * Count number of unique identifiers in event.
45 *
46 * \param __begin begin of data
47 * \param __end end of data
48 * \return number of unique identifiers
49 */
50 template<class JHit_t>
53 {
54 using namespace std;
55 using namespace KM3NETDAQ;
56
57 typedef JDAQModuleIdentifier JType_t;
58
59 set<JType_t> buffer;
60
61 for (JDAQEvent::const_iterator<JHit_t> i = __begin; i != __end; ++i) {
62 buffer.insert(JType_t(*i));
63 }
64
65 return buffer.size();
66 }
67
68
69 const char* const LINN_t = "LINN";
70 const char* const LOGN_t = "LOGN";
71 const char* const LINE_t = "LINE";
72 const char* const LOGE_t = "LOGE";
73
74 const char* const muon_t = "muon";
75 const char* const neutrino_t = "neutrino";
76}
77
78/**
79 * \file
80 *
81 * Example program to histogram fit results for the muon reconstruction chain.
82 * \author mdejong, bofearraigh.
83 */
84int main(int argc, char **argv)
85{
86 using namespace std;
87 using namespace JPP;
88 using namespace KM3NETDAQ;
89
90 typedef JTriggeredFileScanner<JEvt> JTriggeredFileScanner_t;
91 typedef JTriggeredFileScanner_t::multi_pointer_type multi_pointer_type;
92
93 JTriggeredFileScanner_t inputFile;
94 JLimit_t& numberOfEvents = inputFile.getLimit();
95 string outputFile;
96 size_t numberOfPrefits;
98 JAtmosphericMuon atmosphere;
99 double Emin_GeV;
100 int application;
101 string option;
102 string primary;
103 int debug;
104
105 try {
106
107 JParser<> zap("Example program to histogram fit results.");
108
109 zap['f'] = make_field(inputFile);
110 zap['o'] = make_field(outputFile) = "postfit.root";
111 zap['n'] = make_field(numberOfEvents) = JLimit::max();
112 zap['N'] = make_field(numberOfPrefits) = 1;
114 zap['E'] = make_field(Emin_GeV) = 0.0;
116 zap['a'] = make_field(atmosphere) = JAtmosphericMuon(90.0, 90.0);
117 zap['O'] = make_field(option) = LINE_t, LOGE_t, LINN_t, LOGN_t;
118 zap['p'] = make_field(primary) = muon_t, neutrino_t;
119 zap['d'] = make_field(debug) = 2;
120
121 zap(argc, argv);
122 }
123 catch(const exception& error) {
124 FATAL(error.what() << endl);
125 }
126
127 JHead head;
128
129 try {
130 head = getCommonHeader(inputFile);
131 }
132 catch(const exception& error) {
133 FATAL(error.what() << endl);
134 }
135
136 JVolume volume(head, option != LINE_t);
137 JPosition3D offset = getPosition(getOffset(head));
138 JPosition3D origin = getPosition(getOrigin(head));
139 JCylinder3D cylinder = getCylinder(head);
140
141 cylinder.add(offset);
142
143 NOTICE("Offset: " << offset << endl);
144 NOTICE("Cylinder: " << cylinder << endl);
145
146 TFile out(outputFile.c_str(), "recreate");
147
148 TH1D job("job", NULL, 100, 0.5, 100.5);
149
150 TH1D hn("hn", NULL, 250, -0.5, 249.5); // NDF
151 TH1D hq("hq", NULL, 300, 0.0, 600.0); // quality parameter
152 TH1D hi("hi", NULL, 101, -0.5, 100.5); // index of the best event in order of descending angular resolution
153 TH1D hc("hc", NULL, 200, -1.0, +1.0); // dz (z-slope)
154 TH1D hu("hu", NULL, 400, -1.0e3, 1.0e3); // quality difference between best up-going and down-going track (check of atmospheric muon)
155
156 TH1D hx("hx", NULL, 70, -3.0, +2.3); // angular deviation [log(deg)]
157 TH1D hd("hd", NULL, 100, 0.0, 10.0); // distance between true and best event at intersection point [m]
158 TH1D ht("ht", NULL, 100, -100.0, 100.0); // time between true and best track [ns]
159
160 TH1D hz0("hz0[start]", NULL, 400, -200.0, 200.0); // start point [m]
161 TH1D hz1("hz1[end]", NULL, 400, -200.0, 200.0); // end point [m]
162
163 TH1D E_0("E_0", NULL, 100, volume.getXmin(), volume.getXmax()); // true muon energy
164 TH1D E_1("E_1", NULL, 100, volume.getXmin(), volume.getXmax()); // uncorrected energy of best track
165 TH1D E_2("E_2", NULL, 100, volume.getXmin(), volume.getXmax()); // corrected energy of best track
166 TH1D E_E("E_E", NULL, 100, -5.0, +5.0); // ratio of reconstructed energy and true energy [log(E/E)]
167 TH2D ExE("ExE", NULL,
168 40, volume.getXmin(), volume.getXmax(),
169 40, volume.getXmin(), volume.getXmax()); // (Etrue,Ereco)
170
171 const Int_t ny = 28800;
172 const Double_t ymin = 0.0; // [deg]
173 const Double_t ymax = 180.0; // [deg]
174
176
177 if (option == LINN_t) {
178
179 const double xmin = log((double) 3);
180 const double xmax = log((double) 300);
181
182 for (double x = xmin, dx = (xmax - xmin) / 20; x <= xmax; x += dx) {
183 X.push_back((int) exp(x));
184 }
185
186 } else if (option == LOGN_t) {
187
188 const double xmin = log10((double) 3);
189 const double xmax = log10((double) 400);
190
191 for (double x = xmin, dx = (xmax - xmin) / 20; x <= xmax; x += dx) {
192 X.push_back(x);
193 }
194
195 } else {
196
197 for (double x = volume.getXmin(), dx = (volume.getXmax() - volume.getXmin()) / 20.0; x < volume.getXmax() + 0.5*dx; x += dx) {
198 X.push_back(x);
199 }
200 }
201
202 TH2D h2("h2", NULL, X.size() - 1, X.data(), ny, ymin, ymax);
203
204 TH2D Va("Va", NULL,
205 100, 0.0, cylinder.getRadius()*cylinder.getRadius(),
206 100, cylinder.getZmin() - 50.0, cylinder.getZmax() + 50.0);
207 TH2D Vb("Vb", NULL,
208 100, 0.0, cylinder.getRadius()*cylinder.getRadius(),
209 100, cylinder.getZmin() - 50.0, cylinder.getZmax() + 50.0);
210
211 JQuantile Q("Angle");
212 JQuantile O("Omega");
213
214
215 while (inputFile.hasNext()) {
216
217 STATUS("event: " << setw(10) << inputFile.getCounter() << '\r'); DEBUG(endl);
218
219 multi_pointer_type ps = inputFile.next();
220
221 JDAQEvent* tev = ps;
222 JEvt* evt = ps;
223 Evt* event = ps;
224
225 const time_converter converter(*event, *tev);
226
227 job.Fill(1.0);
228
229
230 double Enu = 0.0;
231 double Emu = 0.0;
232 double Emax = 0.0;
233
234 if (has_neutrino(*event)) {
235 Enu = get_neutrino(*event).E;
236 }
237
238 vector<Trk>::const_iterator muon = event->mc_trks.end();
239
240 for (vector<Trk>::const_iterator track = event->mc_trks.begin(); track != event->mc_trks.end(); ++track) {
241
242 if (is_muon(*track)) {
243
244 Emu += track->E;
245
246 if (track->E > Emax) {
247 muon = track;
248 Emax = track->E;
249 }
250 }
251 }
252
253 if (muon == event->mc_trks.end()) {
254 continue;
255 }
256
257 job.Fill(3.0);
258
259
260 // abscissa
261
262 Double_t x = 0.0;
263
264 {
265 const double E = event->mc_trks[0].E;
266 const int N = getCount(tev->begin<JDAQTriggeredHit>(), tev->end<JDAQTriggeredHit>());
267
268 if (option == LINN_t)
269 x = N;
270 else if (option == LOGN_t)
271 x = log10(N);
272 else
273 x = volume.getX(E);
274 }
275
276
277 if (!evt->empty()) {
278
279 JEvt::iterator __end = partition(evt->begin(), evt->end(), JHistory::is_application(application));
280
281 if (evt->begin() == __end) {
282 continue;
283 }
284
285 job.Fill(4.0);
286
287 if (numberOfPrefits > 0) {
288
289 JEvt::iterator __q = __end;
290
291 advance(__end = evt->begin(), min(numberOfPrefits, (size_t) distance(evt->begin(), __q)));
292
293 partial_sort(evt->begin(), __end, __q, quality_sorter);
294
295 } else {
296
297 sort(evt->begin(), __end, quality_sorter);
298 }
299
300 double E = 0.0;
301 JPointing pointing;
302
303 if (primary == muon_t) {
304 E = Emu;
305 pointing = JPointing(getDirection(*muon));
306 } else if (primary == neutrino_t) {
307 E = Enu;
308 pointing = JPointing(getDirection(get_neutrino(*event)));
309 }
310
311 JEvt::iterator best = pointing(evt->begin(), __end);
312 const Double_t beta = pointing.getAngle(*best);
313 const double Efit = best->getE();
314 const double Eraw = best->getW(JENERGY_ENERGY, numeric_limits<double>::min());
315
316 // selection of fit result
317
318 bool ok = (Efit >= Emin_GeV);
319
320 if (ok) {
321
322 job.Fill(5.0);
323
324 hn.Fill((Double_t) best->getNDF());
325 hq.Fill(best->getQ());
326 hi.Fill((Double_t) distance(evt->begin(), best));
327 hc.Fill(best->getDZ());
328
329 // atmospheric muon hypothesis test.
330
331 if (( has_neutrino(*event) && get_neutrino(*event).dir.z >= atmosphere.dot2) || // difference in quality between best upwards and best downgoing track.
332 (!has_neutrino(*event) && best->getDZ() >= atmosphere.dot2)) { // negative (positive) values imply a down(up) going track.
333 hu.Fill(atmosphere(evt->begin(), __end));
334 }
335
336 hx.Fill(max(log10(beta), hx.GetXaxis()->GetXmin()));
337
338 Q.put(beta);
339
340 JTrack3E ta = getTrack(*muon);
341 JTrack3E tb = getTrack(*best);
342
343 ta.add(offset);
344 tb.sub(converter.putTime());
345
346 static_cast<JTrack3D&>(ta).move(ta.getIntersection(tb), getSpeedOfLight()); // move to intersection point of both tracks
347 static_cast<JTrack3D&>(tb).move(tb.getIntersection(ta), getSpeedOfLight());
348
349 hd.Fill((tb.getPosition() - ta.getPosition()).getLength());
350
351 if (has_neutrino(*event)) {
352
353 job.Fill(6.0);
354
355 const Trk neutrino = get_neutrino(*event);
356
357 JPosition3D vertex = getPosition(neutrino);
358
359 vertex.add(offset);
360
361 if (cylinder.is_inside(vertex)) {
362
363 job.Fill(7.0);
364
365 Va.Fill(JVector2D(best->getX() - origin.getX(), best->getY() - origin.getY()).getLengthSquared(), best->getZ()); //R^{2} [m^2], z [m]
366
367 JTrack3E tc = getTrack(*best);
368
369 hz0.Fill(tc.getIntersection(vertex));
370 hz1.Fill(best->getW(JSTART_LENGTH_METRES, 0.0) - gWater(muon->E));
371 }
372 }
373
374 Vb.Fill(JVector2D(best->getX() - origin.getX(), best->getY() - origin.getY()).getLengthSquared(), best->getZ()); //R^{2} [m^2], z [m]
375 ht.Fill(tb.getT() - ta.getT());
376
377 E_0.Fill(volume.getX(E, true));
378 E_1.Fill(volume.getX(Eraw, true));
379 E_2.Fill(volume.getX(Efit, true));
380 E_E.Fill(volume.getX(Efit) - volume.getX(E));
381 ExE.Fill(volume.getX(E), volume.getX(Efit));
382
383 h2.Fill(x, beta);
384 }
385 }
386 }
387 STATUS(endl);
388
389 NOTICE("Number of events input " << setw(8) << right << job.GetBinContent(1) << endl);
390 NOTICE("Number of events with muon " << setw(8) << right << job.GetBinContent(3) << endl);
391 NOTICE("Number of events with fit " << setw(8) << right << job.GetBinContent(4) << endl);
392 NOTICE("Number of events selected " << setw(8) << right << job.GetBinContent(5) << endl);
393 NOTICE("Number of events with neutrino " << setw(8) << right << job.GetBinContent(6) << endl);
394 NOTICE("Number of events contained " << setw(8) << right << job.GetBinContent(7) << endl);
395
396 if (Q.getCount() != 0) {
397
398 NOTICE("Median space angle [deg] " << FIXED (6,3) << Q.getQuantile(0.5) << endl);
399
400 for (double q : {0.50, 0.90, 0.99}) {
401 NOTICE("Space angle " << FIXED(5,1) << (100.0 * q) << "% quantile [deg] " << FIXED(6,3) << Q.getQuantile(q) << endl);
402 }
403 }
404
405 out.Write();
406 out.Close();
407}
Definition of hit and track types and auxiliary methods for handling Monte Carlo data.
string outputFile
General purpose messaging.
#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:74
int main(int argc, char **argv)
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition JParser.hh:2140
Physics constants.
ROOT TTree parameter settings of various packages.
Synchronously read DAQ events and Monte Carlo events (and optionally other events).
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
double getZmin() const
Get minimal z position.
bool is_inside(const JVector3D &pos) const
Check whether given point is inside cylinder.
double getZmax() const
Get maximal z position.
JCylinder3D & add(const JVector3D &pos)
Add position.
Data structure for position in three dimensions.
const JPosition3D & getPosition() const
Get position.
double getT(const JVector3D &pos) const
Get arrival time of Cherenkov light at given position.
Definition JTrack3D.hh:87
JTime & add(const JTime &value)
Addition operator.
JTime & sub(const JTime &value)
Subtraction operator.
3D track with energy.
Definition JTrack3E.hh:34
JVector3D & add(const JVector3D &vector)
Add vector.
Definition JVector3D.hh:142
Utility class to parse command line options.
Definition JParser.hh:1697
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.
Template const_iterator.
Definition JDAQEvent.hh:68
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.
double putTime() const
Get Monte Carlo time minus DAQ/trigger time.
static const int JENERGY_ENERGY
uncorrected energy [GeV] see JRECONSTRUCTION::JMuonEnergy
static const int JSTART_LENGTH_METRES
distance between projected positions on the track of optical modules for which the response does not ...
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.
const Trk & get_neutrino(const Evt &evt)
Get incoming neutrino.
size_t getCount(const array_type< T > &buffer, const JCompare_t &compare)
Count number of unique values.
static const JX X
Definition JMathlib.hh:1551
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
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
Double_t getX(const Double_t E, double constrain=false) const
Get abscissa value.
Definition JVolume.hh:115
Double_t getXmax() const
Get maximal abscissa value.
Definition JVolume.hh:102
Double_t getXmin() const
Get minimal abscissa value.
Definition JVolume.hh:91
Primary particle.
Definition JHead.hh:1174
Acoustic event fit.
Auxiliary class to test history.
Definition JHistory.hh:188
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition JParser.hh:67
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
static counter_type max()
Get maximum counter value.
Definition JLimit.hh:128
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:41
double getQuantile(const double Q, const Quantile_t option=forward_t) const
Get quantile.
Definition JQuantile.hh:147
void put(const double x, const double w=1.0)
Put value.
Definition JQuantile.hh:106
long long int getCount() const
Get total count.
Definition JStats.hh:168
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.
Auxiliary include file for time conversion between DAQ/trigger hit and Monte Carlo hit.