109{
113
115 typedef JParallelFileScanner_t::multi_pointer_type multi_pointer_type;
117
118 JParallelFileScanner_t inputFile;
120 string detectorFile;
121 JCalibration_t calibrationFile;
122 double Tmax_s;
123 string pdfFile;
126 int application;
129 bool batch;
131 double arrowSize = 0.003;
132 string arrowType = "|->";
133 double arrowScale = 250.0;
134 Width_t lineWidth = 2;
135 Style_t lineStyle = 1;
136 int nbinsX = 50;
137 int nbinsY = 250;
138 double T_ns = 0.0;
139 bool equalize = false;
140 } graphics;
141 string option;
143
144
145 try {
146
148
156
158
159 JParser<> zap(
"Program to display hit probabilities.");
160
161 zap[
'w'] =
make_field(canvas,
"size of canvas <nx>x<ny> [pixels]") =
JCanvas(1200, 600);
162 zap[
'f'] =
make_field(inputFile,
"input file (output of JXXXMuonReconstruction.sh)");
173 zap[
'O'] =
make_field(option,
"draw option") = arrow_t, histogram_t;
174 zap[
'B'] =
make_field(batch,
"batch processing");
176
177 zap(argc, argv);
178 }
179 catch(const exception& error) {
180 FATAL(error.what() << endl);
181 }
182
184 FATAL(
"Missing output file name " <<
outputFile <<
" in batch mode." << endl);
185 }
186
189 }
190
193 }
194
195
197
198 try {
200 }
203 }
204 unique_ptr<JDynamics> dynamics;
205
206 try {
207
209
210 dynamics->load(calibrationFile);
211 }
212 catch(const exception& error) {
213 if (!calibrationFile.empty()) {
215 }
216 }
217
218 const double Zbed = 0.0;
219
221
223
224 if (cylinder.getZmin() < Zbed) {
225 cylinder.setZmin(Zbed);
226 }
227
229
231
233
235
238
240
241
242 Vec offset(0.0, 0.0, 0.0);
243
244 try {
246 } catch(const exception& error) {}
247
248 NOTICE(
"Offset applied to true tracks is: " << offset << endl);
249
250
251
252
253 gROOT->SetBatch(batch);
254
255 TApplication* tp = new TApplication("user", NULL, NULL);
256 TCanvas* cv =
new TCanvas(
"display",
"", canvas.
x, canvas.
y);
257
258 if (!batch) {
259 ((TRootCanvas *) cv->GetCanvasImp())->Connect("CloseWindow()", "TApplication", tp, "Terminate()");
260 }
261
262 unique_ptr<TStyle> gStyle(
new JStyle(
"gplot", cv->GetWw(), cv->GetWh(), graphics));
263
264 gROOT->SetStyle("gplot");
265 gROOT->ForceStyle();
266
267 const size_t NUMBER_OF_PADS = 3;
268
269 cv->SetFillStyle(4000);
270 cv->SetFillColor(kWhite);
271
272 TPad*
p1 =
new TPad(
"p1", NULL, 0.0, 0.00, 1.0, 0.95);
273 TPad* p2 = new TPad("p2", NULL, 0.0, 0.95, 1.0, 1.00);
274
275 p1->Divide(NUMBER_OF_PADS, 1);
276
278 p2->Draw();
279
281 const double Rmin = 0.0;
282 const double Rmax = min(parameters.
roadWidth_m, 0.4 * Dmax);
283 const double Tmin = min(parameters.
TMin_ns, -10.0);
284 const double Tmax = max(parameters.
TMax_ns, +100.0);
285 const double Amin = 0.002 * (Tmax - Tmin);
286 const double Amax = 0.8 * (Tmax - Tmin);
287 const double ymin = Tmin - (option == arrow_t ? 0.2 * Amax : 0.0);
288 const double ymax = Tmax + (option == arrow_t ? 0.5 * Amax : 0.0);
289
290 const string Xlabel[NUMBER_OF_PADS] = { "R [m]", "#phi [rad]", "z [m]" };
291 const double Xmin [NUMBER_OF_PADS] = { Rmin, -
PI, -0.4 * Dmax };
292 const double Xmax [NUMBER_OF_PADS] = { Rmax, +
PI, +0.4 * Dmax };
293
294 double Xs[NUMBER_OF_PADS];
295
296 for (size_t i = 0; i != NUMBER_OF_PADS; ++i) {
297 Xs[i] = 0.003 * (Xmax[i] - Xmin[i]) * (0.5 * NUMBER_OF_PMTS);
298 }
299
300 TH2D H2[NUMBER_OF_PADS];
301 TGraph G2[NUMBER_OF_PADS];
302
303 for (size_t i = 0; i != NUMBER_OF_PADS; ++i) {
304
305 H2[i] = TH2D(
MAKE_CSTRING(
"h" << i), NULL, graphics.nbinsX, Xmin[i] - Xs[i], Xmax[i] + Xs[i], graphics.nbinsY, ymin, ymax);
306
307 H2[i].GetXaxis()->SetTitle(Xlabel[i].c_str());
308 H2[i].GetYaxis()->SetTitle("#Deltat [ns]");
309
310 H2[i].GetXaxis()->CenterTitle(true);
311 H2[i].GetYaxis()->CenterTitle(true);
312
313 H2[i].SetStats(kFALSE);
314
315 G2[i].Set(2);
316
317 G2[i].SetPoint(0, H2[i].GetXaxis()->GetXmin(), 0.0);
318 G2[i].SetPoint(1, H2[i].GetXaxis()->GetXmax(), 0.0);
319
321
322 H2[i].Draw("AXIS");
323 G2[i].Draw("SAME");
324 }
325
326
328
329 cout << "event: " << setw(8) << inputFile.getCounter() << endl;
330
331 multi_pointer_type ps = inputFile.next();
332
336
337 if (dynamics) {
338 dynamics->update(*tev);
339 }
340
341 if (mc.getEntries() != 0) {
343 }
344
346
347 if (!in->empty()) {
348
350
351 if (!event_selector(*tev, *in, event)) {
352 continue;
353 }
354
355
356 JDataL0_t dataL0;
357
358 buildL0(*tev, router, true, back_inserter(dataL0));
359
360 summary.update(*tev);
361
363
364 if (event != NULL) {
365
367
368 for (const auto& t1 : event->mc_trks) {
370 if (t1.E > muon.
getE()) {
371
373
376
377 muon =
getFit(0, ta, 0.0, 0, t1.E, 1);
378
380 }
381 }
382 }
383 }
384
385 bool monte_carlo = false;
386 size_t index = 0;
387
388 for (bool next = false; !next; ) {
389
390 for (size_t i = 0; i != NUMBER_OF_PADS; ++i) {
391 H2[i].Reset();
392 }
393
395
396 if (!monte_carlo)
397 fit = (*in)[index];
398 else
399 fit = muon;
400
404
405
406
407
408
410
411
412
414
415 for (JDataL0_t::const_iterator i = dataL0.begin(); i != dataL0.end(); ++i) {
416
417 const int type = 0;
418 const double QE = 1.0;
419 const double R_Hz = summary.getRate(i->getPMTIdentifier(), parameters.
R_Hz);
420
421 JHitW0 hit(*i, type, QE, R_Hz);
422
423 hit.rotate(R);
424
425 if (match(hit)) {
427 }
428 }
429
430
431
432 sort(
data.begin(),
data.end(), JHitW0::compare);
433
434 JDataW0_t::iterator __end = unique(
data.begin(),
data.end(), equal_to<JDAQPMTIdentifier>());
435
436 double E_GeV = parameters.
E_GeV;
437
438
439
440
441
442
443
444
446
447 for (JDataW0_t::iterator hit =
data.begin(); hit != __end; ++hit) {
448
449 const double x = hit->getX() - tz.getX();
450 const double y = hit->getY() - tz.getY();
451 const double z = hit->getZ();
452 const double R = sqrt(x*x + y*y);
453
455 }
456
457 const double z0 = tz.getZ();
459
461
462
463
464 ostringstream os;
467
469
470 marker[2].push_back(TMarker(z0 - tz.getZ(), 0.0, kFullCircle));
472
473 static_cast<TAttMarker&>(marker[2][0]) = TAttMarker(kRed, kFullCircle, 0.7);
474 static_cast<TAttMarker&>(marker[2][1]) = TAttMarker(kRed, kFullCircle, 0.7);
475 }
476
478 <<
FIXED(7,2) << tz.getX() <<
' '
479 <<
FIXED(7,2) << tz.getY() <<
' '
480 <<
FIXED(7,2) << tz.getZ() <<
' '
481 <<
FIXED(12,2) << tz.getT() << endl);
482
483 double chi2 = 0;
484
485 for (JDataW0_t::const_iterator hit =
data.begin(); hit != __end; ++hit) {
486
487 const double x = hit->getX() - tz.getX();
488 const double y = hit->getY() - tz.getY();
489 const double z = hit->getZ() - tz.getZ();
490 const double R = sqrt(x*x + y*y);
491
493
494 JDirection3D dir(hit->getDX(), hit->getDY(), hit->getDZ());
495
497
498 const double theta = dir.getTheta();
499 const double phi = fabs(dir.getPhi());
500
501
502 const double E = E_GeV;
503 const double dt = T_ns.constrain(hit->getT() - t1);
504
507
510 }
511
512 H1 += H0;
513
514 chi2 += H1.getChi2() - H0.getChi2();
515
517 << setw(8) << hit->getModuleID() <<
'.' <<
FILL(2,
'0') << (
int) hit->getPMTAddress() <<
FILL() <<
' '
519 <<
FIXED(7,2) << R <<
' '
520 <<
FIXED(7,4) << theta <<
' '
521 <<
FIXED(7,4) << phi <<
' '
522 <<
FIXED(7,3) << dt <<
' '
523 <<
FIXED(7,3) << H1.getChi2() <<
' '
524 <<
FIXED(7,3) << H0.getChi2() << endl);
525
526 const double derivative = H1.getDerivativeOfChi2() - H0.getDerivativeOfChi2();
527
528 double size = derivative * graphics.arrowScale;
529
530 if (fabs(size) < Amin) {
531 size = (size > 0.0 ? +Amin : -Amin);
532 } else if (fabs(size) > Amax) {
533 size = (size > 0.0 ? +Amax : -Amax);
534 }
535
536 const double X[NUMBER_OF_PADS] = { R, atan2(y,x), z - R/
getTanThetaC() };
537
538 const double xs = (double) (NUMBER_OF_PMTS - 2 * hit->getPMTAddress()) / (double) NUMBER_OF_PMTS;
539
540 for (size_t i = 0; i != NUMBER_OF_PADS; ++i) {
541
542 TArrow a1(X[i] + xs*Xs[i], dt + graphics.T_ns, X[i] + xs*Xs[i], dt + graphics.T_ns + size, graphics.arrowSize, graphics.arrowType.c_str());
543
544 a1.SetLineWidth(graphics.lineWidth);
545 a1.SetLineStyle(graphics.lineStyle);
546
547 arrow[i].push_back(a1);
548
549 H2[i].Fill(X[i], dt + graphics.T_ns);
550 }
551 }
552
553 if (graphics.equalize) {
554
555 double zmax = 0.0;
556
557 for (size_t i = 0; i != NUMBER_OF_PADS; ++i) {
558 if (H2[i].GetMaximum() > zmax) {
559 zmax = H2[i].GetMaximum();
560 }
561 }
562
563 zmax *= 1.2;
564
565 for (size_t i = 0; i != NUMBER_OF_PADS; ++i) {
566 H2[i].SetMaximum(zmax);
567 }
568 }
569
571 os <<
" Q = " <<
FIXED(4,0) << fit.
getQ()
572 <<
'/' <<
FIXED(4,0) << -chi2;
574 os <<
" cos(#theta) = " <<
FIXED(6,3) << fit.
getDZ();
576
577 if (monte_carlo)
578 os << " Monte Carlo";
581
582
583
584
585 TLatex title(0.05, 0.5, os.str().c_str());
586
587 title.SetTextAlign(12);
588 title.SetTextFont(42);
589 title.SetTextSize(0.6);
590
591 p2->cd();
592
593 title.Draw();
594
595 for (int i = 0; i != NUMBER_OF_PADS; ++i) {
596
598
599 if (option == arrow_t) {
600
601 for (auto& a1 : arrow[i]) {
602 a1.Draw();
603 }
604
605 for (auto& m1 : marker[i]) {
606 m1.Draw();
607 }
608 }
609
610 if (option == histogram_t) {
611 H2[i].Draw("SAME");
612 }
613 }
614
615 cv->Update();
616
617
618
619
620 if (batch) {
621
623
624 next = true;
625
626 } else {
627
628 static int count = 0;
629
630 if (count++ == 0) {
631 cout << endl << "Type '?' for possible options." << endl;
632 }
633
634 for (bool user = true; user; ) {
635
637
639
640 ts.move(intersection.first);
641
642 cout << "\n> " << flush;
643
645
646 case '?':
647 cout << endl;
648 cout << "possible options: " << endl;
649 cout << 'p' << " -> " << "print information" << endl;
650 cout << 'q' << " -> " << "exit application" << endl;
651 cout << 'u' << " -> " << "update canvas" << endl;
652 cout << 's' << " -> " << "save graphics to file" << endl;
653 cout << '+' << " -> " << "next fit" << endl;
654 cout << '-' << " -> " << "previous fit" << endl;
655 cout << 'M' << " -> " << "Monte Carlo true muon information" << endl;
656 cout << 'F' << " -> " << "fit information" << endl;
658 cout << 'L' << " -> " << "reload event selector" << endl;
659 }
660 cout << 'r' << " -> " << "rewind input file" << endl;
661 cout << 'R' << " -> " << "switch to ROOT mode (quit ROOT to continue)" << endl;
662 cout << ' ' << " -> " << "next event (as well as any other key)" << endl;
663 break;
664
665 case 'p':
666
667 cout << endl;
668 cout <<
"intersection: " <<
FIXED(6,1) << intersection.first <<
' '<<
FIXED(6,1) << intersection.second << endl;
669 cout << "entry point: "
670 <<
FIXED(6,1) << ts.getX() - cylinder.getX() <<
' '
671 <<
FIXED(6,1) << ts.getY() - cylinder.getY() <<
' '
672 <<
FIXED(6,1) << ts.getZ() << endl;
675 }
676 break;
677
678 case 'q':
679 cout << endl;
680 return 0;
681
682 case 'u':
683 cv->Update();
684 break;
685
686 case 's':
688 break;
689
690 case '+':
691 monte_carlo = false;
692 index = (index != in->size() - 1 ? index + 1 : 0);
693 user = false;
694 break;
695
696 case '-':
697 monte_carlo = false;
698 index = (index != 0 ? index - 1 : in->size() - 1);
699 user = false;
700 break;
701
702 case 'M':
704 monte_carlo = true;
705 else
706 ERROR(endl <<
"No Monte Carlo muon available." << endl);
707 user = false;
708 break;
709
710 case 'F':
711 monte_carlo = false;
712 user = false;
713 break;
714
715 case 'L':
717 execute(
MAKE_STRING(
"make -f " <<
getPath(argv[0]) <<
"/JMakeEventSelector libs"), 3);
719 }
720 break;
721
722 case 'R':
723 tp->Run(kTRUE);
724 break;
725
726 case 'r':
727 inputFile.rewind();
728
729 default:
730 next = true;
731 user = false;
732 break;
733 }
734 }
735 }
736 }
737 }
738 }
739 cout << endl;
740}
#define DEBUG(A)
Message macros.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
#define MAKE_CSTRING(A)
Make C-string.
#define MAKE_STRING(A)
Make string.
#define gmake_property(A)
macros to convert (template) parameter to JPropertiesElement object
Router for direct addressing of module data in detector data structure.
Utility class to parse parameter values.
Data structure for set of track fit results.
void select(const JSelector_t &selector)
Select fits.
Data structure for track fit results with history and optional associated values.
void setW(const std::vector< double > &W)
Set associated values.
double getDZ() const
Get Z-slope.
double getE() const
Get energy.
int getStatus() const
Get status of the fit; negative values should refer to a bad fit.
double getQ() const
Get quality.
const std::vector< double > & getW() const
Get associated values.
double getT() const
Get time.
bool hasW(const int i) const
Check availability of value.
Data structure for fit of straight line paralel to z-axis.
Data structure for direction in three dimensions.
JTime & add(const JTime &value)
Addition operator.
Utility class to parse command line options.
Auxiliary class for a hit with background rate value.
Data structure for size of TCanvas.
int y
number of pixels in Y
int x
number of pixels in X
Wrapper class around ROOT TStyle.
General purpose class for object reading from a list of file names.
General purpose class for parallel reading of objects from a single file or multiple files.
Object reading from a list of files.
File router for fast addressing of summary data.
Template definition for direct access of elements in ROOT TChain.
Enable unbuffered terminal input.
int getRunNumber() const
Get run number.
int getFrameIndex() const
Get frame index.
JTriggerCounter_t getCounter() const
Get trigger counter.
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 JSTART_LENGTH_METRES
distance between projected positions on the track of optical modules for which the response does not ...
JAxis3D getAxis(const Trk &track)
Get axis.
JDirection3D getDirection(const Vec &dir)
Get direction.
JTrack3E getTrack(const Trk &track)
Get track.
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.
JFit getFit(const int id, const JMODEL::JString &string)
Get fit parameters of string.
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
double getMaximalDistance(const JDetector &detector, const bool option=false)
Get maximal distance between modules in detector.
std::string getPath(const std::string &file_name)
Get path, i.e. part before last JEEP::PATHNAME_SEPARATOR if any.
double getAngle(const JQuaternion3D &first, const JQuaternion3D &second)
Get space angle between quanternions.
std::string replace(const std::string &input, const std::string &target, const std::string &replacement)
Replace tokens in string.
static const double PI
Mathematical constants.
const double getInverseSpeedOfLight()
Get inverse speed of light.
double getTanThetaC()
Get average tangent of Cherenkov angle of water corresponding to group velocity.
const double getSpeedOfLight()
Get speed of light.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
bool qualitySorter(const JFit &first, const JFit &second)
Comparison of fit results.
JRECONSTRUCTION::JWeight getWeight
Head getHeader(const JMultipleFileScanner_t &file_list)
Get Monte Carlo header.
KM3NeT DAQ data structures and auxiliaries.
static const char WILDCARD
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.
Auxiliary data structure for sequence of same character.
Auxiliary data structure for floating point format specification.
Dynamic detector calibration.
bool is_valid() const
Check validity of function.
void reload()
Reload function from shared library.
Auxiliary class to test history.
Auxiliary class to match data points with given model.
Auxiliary data structure for muon PDF.
JFunction1D_t::result_type result_type
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Data structure for fit parameters.
double TTS_ns
transition-time spread [ns]
double TMin_ns
minimal time w.r.t. Cherenkov hypothesis [ns]
double roadWidth_m
road width [m]
double TMax_ns
maximal time w.r.t. Cherenkov hypothesis [ns]
double VMax_npe
maximum number of of photo-electrons
double R_Hz
default rate [Hz]
size_t numberOfPrefits
number of prefits
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 data structure for floating point format specification.
The Vec class is a straightforward 3-d vector, which also works in pyroot.