80{
84
86 typedef JTriggeredFileScanner_t::multi_pointer_type multi_pointer_type;
87
88 JTriggeredFileScanner_t inputFile;
91 size_t numberOfPrefits;
94 double Emin_GeV;
95 double NPE;
96 int application;
97 string option;
98 bool isMuon;
99 bool wrtNeutrino;
100 double radius;
103
104 try {
105
106 JParser<> zap(
"Example program to histogram fit results.");
107
117 zap[
'O'] =
make_field(option) =
"E",
"N",
"LINE",
"LOGE";
120 zap[
'r'] =
make_field(radius) = numeric_limits<double>::max();
123
124 zap(argc, argv);
125 }
126 catch(const exception& error) {
127 FATAL(error.what() << endl);
128 }
129
130 cout << "APPLICATION " << application << endl;
131
133
134 try {
136 }
137 catch(const exception& error) {
138 FATAL(error.what() << endl);
139 }
140
141 JVolume volume(head, option !=
"LINE");
145
146 cylinder.
add(offset);
147
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;
158
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);
166 TH1D hd("hd", "Distance between Reco and True position", 2000, 0.0, 100.0);
167 TH1D hz("hz", "Longitudinal Distance between Reco and MC lepton position", 100, -200.0, 200.0);
168 TH1D ht("ht", "Time difference between Reco and MC lepton", 100, 0, 100.0);
169 TH1D h4D("h4D", "4D-distance between reco and true vertex", 2000, 0.0, 100.0);
170
171 TH1D ha("ha", "Angle between reco direction and true direction", 1000, 0.0, 180.0);
172
173 TH1D e0("e0", "True lepton energy", 100, volume.getXmin(), volume.getXmax());
174 TH1D e2("e2", "Reconstructed energy", 100, volume.getXmin(), volume.getXmax());
175 TH1D er("er", "Ratio of reconstructed energy and true energy", 100, -5.0, +5.0);
176 TH1D ea("ea", "Distribution of Energy error for all the events; E_{reco}-E_{true}", 100, -30, +30);
177 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);
178 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);
179 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);
180 TH2D ee("ee", "; E_{true} [GeV]; E_{reco} [GeV]",
181 40, 0, 4,
182 40, 0, 4);
183 TH1D eeres("eeres","Median reco energy as a function of true energy",40,0,4);
184 TH1D eeres16("eeres16","16%Quantile reco energy as a function of true energy",40,0,4);
185 TH1D eeres84("eeres84","84%Quantile reco energy as a function of true energy",40,0,4);
186 const Int_t ny = 28800;
187 const Double_t ymin = 0.0;
188 const Double_t ymax = 180.0;
189
191
192 if (option.find('E') != string::npos) {
193
194 for (double x = volume.getXmin(); x <= volume.getXmax(); x += (volume.getXmax() - volume.getXmin()) / 20) {
195 X.push_back(x);
196 }
197
198 } else {
199
201
202 for ( ;
x <= 15.5;
x += 1.0) { X.push_back(x); }
203 for ( ;
x <= 25.5;
x += 2.0) { X.push_back(x); }
204 for ( ;
x <= 50.5;
x += 5.0) { X.push_back(x); }
205 for ( ;
x <= 100.5;
x += 10.0) { X.push_back(x); }
206 for ( ;
x <= 250.5;
x += 20.0) { X.push_back(x); }
207 }
208
209 TH2D h2("h2", NULL, X.size() - 1, X.data(), ny, ymin, ymax);
210
211 TProfile herrorE("herrorE", "Energy Error", X.size() - 1, X.data());
212 TProfile hfracE( "hfracE", "Fractional Energy Error", X.size() - 1, X.data());
213 TProfile he("he","Reconstruction Efficiency", X.size() - 1, X.data());
214 TProfile htheta_nu_lep("htheta_nu_lep", "Angle between neutrino and primary lepton", X.size() - 1, X.data());
215 TH2D hgetln("hgetln","Kinematic angle", 40,0,4,1000,0,180);
216 TH1D hln1d("hln1d","Angle between neutrino and lepton",40,0,4);
217 TH2D hb("hb", NULL, 100, 0.0, 0.5e6, 100, -100.0, +900.0);
218 TH2S hmca("hmca", NULL, X.size() - 1, X.data(), 1000, 0, 180);
219 TH2D hae("hae",NULL,40,0,4,1000,0,180);
220 TH1D hmae("hmae","Mean angle deviation as function of log MC energy",40,0,4);
221 TH2D hzenith("hzenith", "Reco Zenith vs MC Energy", 100, 0, 100, ny, ymin, ymax);
222 TH2D hY("hY", "Reco Bjorken Y vs MC Bjorken Y", 40, 0, 1, 40, 0, 1);
223 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);
224 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);
225
232 while (inputFile.hasNext()) {
233
234 STATUS(
"event: " << setw(10) << inputFile.getCounter() <<
'\r');
DEBUG(endl);
235
236 multi_pointer_type ps = inputFile.next();
237
241
243
244 job.Fill(1.0);
245
246 double Enu = 0.0;
247 double Elep = 0.0;
248 double Emax = 0.0;
249
251
253
256
257 }
258
259 vector<Trk>::const_iterator lepton = event->mc_trks.end();
260
261 for (vector<Trk>::const_iterator mc_evt = event->mc_trks.begin(); mc_evt != event->mc_trks.end(); ++mc_evt) {
262
264
265 Elep += mc_evt->E;
266
267 if (mc_evt->E > Emax) {
268 lepton = mc_evt;
269 Emax = mc_evt->E;
270 }
271
272
273 }
else if(isMuon &&
is_muon(*mc_evt)){
274
275 Elep += mc_evt->E;
276 if (mc_evt->E > Emax) {
277 lepton = mc_evt;
278 Emax = mc_evt->E;
279 }
280 }
281 }
282
283 if (lepton == event->mc_trks.end()) {
284 continue;
285 }
286
287 job.Fill(3.0);
288
289 double true_BjY = (Enu - Elep) / Enu;
290
291
292
294
295 if (option.find('E') != string::npos){
296
297 if(wrtNeutrino ==
true && !isMuon)
x = volume.getX(neutrino.
E);
298 else if(!wrtNeutrino && !isMuon)
x = volume.getX(lepton->E);
299
300 } else{
302 }
303
304
305 Double_t W = 0.0;
306
307 if (!evt->empty()) {
308
309 JEvt::iterator __end = partition(evt->begin(), evt->end(),
JHistory::is_event(application));
310
311 if (evt->begin() == __end) {
312 continue;
313 }
314
315 job.Fill(4.0);
316
317
318 if (numberOfPrefits > 0 ) {
319
320 JEvt::iterator __q = __end;
321
322 advance(__end = evt->begin(), min(numberOfPrefits, (
size_t)
distance(evt->begin(), __q)));
323
325
326 } else {
327
329 }
330
331 JEvt::iterator best = evt->begin();
332
336
338
339 if(!wrtNeutrino && !isMuon){
341 } else if(wrtNeutrino == true && !isMuon){
345 }
346
347 JEvt::iterator fit_with_smallest_error = best;
348
350 fit_with_smallest_error = position(evt->begin(), __end);
352 fit_with_smallest_error = energy(evt->begin(), __end);
353 } else {
354 fit_with_smallest_error = pointing(evt->begin(), __end);
355 }
356 best = fit_with_smallest_error;
357
358 const Double_t beta = pointing.getAngle(*best);
359 const double Efit = best->getE();
360
362
363
364 bool ok = (Efit >= Emin_GeV);
365
366 if (ok) {
367
368 W = 1.0;
369
370 job.Fill(5.0);
371
372 hn.Fill((Double_t) best->getNDF());
373 hq.Fill(best->getQ());
374 hi.Fill((Double_t)
distance(evt->begin(), fit_with_smallest_error));
375 Q.put(beta);
376
378
379 if(wrtNeutrino){
381 } else {
383 }
384
386
388
389
391 tb.
sub(converter.putTime());
392 double time_true = ta.
getT();
393 double time_reco=tb.
getT();
394 double distance_m;
395
396 if(!isMuon && !wrtNeutrino){
400 hd.Fill(fabs(distance_m));
401 ht.Fill(fabs(time_reco - time_true));
402 Qp.put(fabs(distance_m));
403 Qt.put(fabs(time_reco-time_true));
405 h4D.Fill(distance4d);
406 Q4d.put(distance4d);
407 } else {
410 hd.Fill(fabs(distance_m));
411 ht.Fill(fabs(time_reco - time_true));
412 Qp.put(fabs(distance_m));
413 Qt.put(fabs(time_reco-time_true));
415 h4D.Fill(distance4d);
416 Q4d.put(distance4d);
417 }
418
420
421 job.Fill(6.0);
422
424
426
428
429 job.Fill(7.0);
430
432 }
433 }
434
435 if (best->getE() >= EMIN_GEV) {
437 }
438
440
443 for (int i = 1; i <= hgetln.GetNbinsX(); ++i) {
445 for (
int j = 1;
j <= hgetln.GetNbinsY(); ++
j) {
446 double binContent = hgetln.GetBinContent(i,
j);
447
448 for (int k = 0; k < binContent; ++k) {
449 double deltaTheta = hgetln.GetYaxis()->GetBinCenter(
j);
450 deltaThetaValues.push_back(deltaTheta);
451 }
452 }
453
454
455 double medianDeltaTheta = TMath::Median(deltaThetaValues.size(), &deltaThetaValues[0]);
456
457
458 hln1d.SetBinContent(i, medianDeltaTheta);
459 }
462 for (int i = 1; i <= hae.GetNbinsX(); ++i) {
464 for (
int j = 1;
j <= hae.GetNbinsY(); ++
j) {
465 double binContent = hae.GetBinContent(i,
j);
466
467 for (int k = 0; k < binContent; ++k) {
468 double deltaTheta = hae.GetYaxis()->GetBinCenter(
j);
469 deltaThetaValues.push_back(deltaTheta);
470 }
471 }
472
473
474 double medianDeltaTheta = TMath::Median(deltaThetaValues.size(), &deltaThetaValues[0]);
475
476
477 hmae.SetBinContent(i, medianDeltaTheta);
478 }
480
481 hY.Fill(true_BjY, best->getW(5));
482
483 if(Efit > 2.5 && Efit < 6) hby3_5GeV.Fill(true_BjY, best->getW(5));
484 else if(Efit > 7.5 && Efit < 11) hby8_10GeV.Fill(true_BjY, best->getW(5));
485
486 }
487 if(wrtNeutrino){
488
489 e0.Fill(volume.getX(Enu, true));
490 er.Fill(volume.getX(Efit) - volume.getX(Enu));
491 ee.Fill(volume.getX(Enu), volume.getX(Efit));
492 ea.Fill(Efit - Enu);
493 hzenith.Fill(Enu, zenith);
494 QE.put(log10(Efit/Enu));
495 herrorE.Fill(x, volume.getX(Efit) - volume.getX(Enu));
496 hfracE.Fill(x, fabs(volume.getX(Efit) - volume.getX(Enu))/volume.getX(Enu));
497
498 if(Enu >= 3 && Enu <= 5) ed3_5GeV.Fill(Efit - Enu);
499 else if(Enu >= 8 && Enu <= 11) ed8_11GeV.Fill(Efit - Enu);
500 else if(Enu >= 15 && Enu <= 21) ed15_21GeV.Fill(Efit - Enu);
501
502 } else {
503
504 e0.Fill(volume.getX(Elep, true));
505 er.Fill(volume.getX(Efit) - volume.getX(Elep));
506 ee.Fill(volume.getX(Elep), volume.getX(Efit));
507 ea.Fill(Efit - Elep);
508 hzenith.Fill(Elep, zenith);
509 QE.put(log10(Efit/Elep));
510 herrorE.Fill(x, volume.getX(Efit) - volume.getX(Elep));
511 hfracE.Fill(x, fabs(volume.getX(Efit) - volume.getX(Elep))/volume.getX(Elep));
512
513 if(Elep >= 3 && Elep <= 5) ed3_5GeV.Fill(Efit - Elep);
514 else if(Elep >= 8 && Elep <= 11) ed8_11GeV.Fill(Efit - Elep);
515 else if(Elep >= 15 && Elep <= 21) ed15_21GeV.Fill(Efit - Elep);
516
517 }
518 for (int i = 1; i <= ee.GetNbinsX(); ++i) {
520 for (
int j = 1;
j <= ee.GetNbinsY(); ++
j) {
521 double binContent = ee.GetBinContent(i,
j);
522
523 for (int k = 0; k < binContent; ++k) {
524 double Erecobin = ee.GetYaxis()->GetBinCenter(
j);
525 Erecovalues.push_back(Erecobin);
526 }
527 }
528 if(Erecovalues.empty()) continue;
529 eeres.SetBinContent(i, Erecovalues[int(Erecovalues.size()*0.5)]);
530 eeres16.SetBinContent(i, Erecovalues[int(Erecovalues.size()*0.16)]);
531 eeres84.SetBinContent(i, Erecovalues[int(Erecovalues.size()*0.84)]);}
532 e2.Fill(volume.getX(Efit, true));
533
534 h2.Fill(x, beta);
535 }
536 }
537 }
538
539 he.Fill(x, W);}
540
542
543 NOTICE(
"Number of events input " << setw(8) << right << job.GetBinContent(1) << endl);
544 if(!isMuon){
545 NOTICE(
"Number of events with electron " << setw(8) << right << job.GetBinContent(3) << endl);
546 } else{
547 NOTICE(
"Number of events with muon " << setw(8) << right << job.GetBinContent(3) << endl);
548 }
549 NOTICE(
"Number of events with fit " << setw(8) << right << job.GetBinContent(4) << endl);
550 NOTICE(
"Number of events selected " << setw(8) << right << job.GetBinContent(5) << endl);
551 NOTICE(
"Number of events with neutrino " << setw(8) << right << job.GetBinContent(6) << endl);
552 NOTICE(
"Number of events contained " << setw(8) << right << job.GetBinContent(7) << endl);
553
554 if (Q.getCount() != 0) {
555 NOTICE(
"Median, 70, 80 and 90% quantiles of space angle [deg] " <<
FIXED (6,3) << Q.getQuantile(0.5) <<
" "<< Q.getQuantile(0.7) <<
" "<< Q.getQuantile(0.8)<<
" "<< Q.getQuantile(0.9)<< endl);
556 }
557 if (QE.getCount() != 0) {
558 NOTICE(
"Median, 70%, 80% and 90% quantiles of energy ratio log(Ereco/Etrue) " <<
FIXED (6,3) << QE.getQuantile(0.5) <<
" "<< QE.getQuantile(0.7) <<
" "<< QE.getQuantile(0.8)<<
" "<< QE.getQuantile(0.9) << endl);
559 }
560 if(Qp.getCount() != 0){
561 NOTICE(
"Median distance to vertex: " << setw(8) << Qp.getQuantile(0.5) <<
" "<< Qp.getQuantile(0.7)<<
" "<< Qp.getQuantile(0.8)<<
" "<<Qp.getQuantile(0.9)<<endl);
562 NOTICE(
"Median time to vertex: " << setw(8) << Qt.getQuantile(0.5) <<
" "<< Qt.getQuantile(0.7)<<
" "<< Qt.getQuantile(0.8)<<
" "<<Qt.getQuantile(0.9)<<endl);
563 NOTICE(
"Median 4D-distance to vertex: " << setw(8) << Q4d.getQuantile(0.5) <<
" "<< Q4d.getQuantile(0.7)<<
" "<< Q4d.getQuantile(0.8)<<
" "<<Q4d.getQuantile(0.9)<<endl);
564 }
565 out.Write();
566 out.Close();
567}
#define DEBUG(A)
Message macros.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
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.
Data structure for position in two dimensions.
Data structure for vector in two dimensions.
double getLengthSquared() const
Get length squared.
double getIntersection(const JVector3D &pos) const
Get longitudinal position along axis of position of closest approach with given position.
bool is_inside(const JVector3D &pos) const
Check whether given point is inside cylinder.
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.
JTime & add(const JTime &value)
Addition operator.
JVersor3D getDirection(const JVector3D &pos) const
Get photon direction of Cherenkov light on PMT.
JTime & sub(const JTime &value)
Subtraction operator.
Data structure for vector in three dimensions.
JVector3D & add(const JVector3D &vector)
Add vector.
double getLength() const
Get length.
double getLengthSquared() const
Get length squared.
double getTheta() const
Get theta angle.
Utility class to parse command line options.
double getMaximum(const double E) const
Get depth of shower maximum.
Auxiliary class to evaluate atmospheric muon hypothesis.
Auxiliary class to compare fit results with respect to a reference direction (e.g....
Auxiliary class to compare fit results with respect to a reference position (e.g. true muon).
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 JSHOWERPOSITIONFIT
static const int JSHOWERDIRECTIONPREFIT
static const int JSHOWERPOINTSIMPLEX
static const int JSHOWERCOMPLETEFIT
static const int JSHOWER_BJORKEN_Y
static const int JSHOWERPREFIT
static const int JSHOWERENERGYPREFIT
Vec getOrigin(const JHead &header)
Get origin.
JDirection3D getDirection(const Vec &dir)
Get direction.
JTrack3E getTrack(const Trk &track)
Get track.
bool is_electron(const Trk &track)
Test whether given track is a (anti-)electron.
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.
double getAngle(const JQuaternion3D &first, const JQuaternion3D &second)
Get space angle between quanternions.
size_t getCount(const array_type< T > &buffer, const JCompare_t &compare)
Count number of unique values.
T pow(const T &x, const double y)
Power .
static const double PI
Mathematical constants.
static const JGeanz geanz(1.85, 0.62, 0.54)
Function object for longitudinal EM-shower profile.
double getIndexOfRefraction()
Get average index of refraction of water corresponding to group velocity.
const double getInverseSpeedOfLight()
Get inverse speed of light.
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.
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.
Auxiliary data structure for floating point format specification.
Auxiliary class for histogramming of effective volume.
Auxiliary class to test history.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
General purpose sorter of fit results.
Auxiliary class for defining the range of iterations of objects.
const JLimit & getLimit() const
Get limit.
static counter_type max()
Get maximum counter value.
Auxiliary class to synchronously read DAQ events and Monte Carlo events (and optionally other events)...
The Trk class represents a Monte Carlo (MC) particle as well as a reconstructed track/shower.
double E
Energy [GeV] (either MC truth or reconstructed)
Reconstruction type dependent comparison of track quality.