110{
114
116 typedef JParallelFileScanner_t::multi_pointer_type multi_pointer_type;
118
119 JParallelFileScanner_t inputFile;
121 string detectorFile;
122 JCalibration_t calibrationFile;
123 double Tmax_s;
124 string pdfFile;
127 int application;
130 bool batch;
132 double arrowSize = 0.003;
133 string arrowType = "|->";
134 double arrowScale = 250.0;
135 Width_t lineWidth = 2;
136 Style_t lineStyle = 1;
137 int nbinsX = 50;
138 int nbinsY = 250;
139 double T_ns = 0.0;
140 bool equalize = false;
141 } graphics;
143 string option;
145
146
147 try {
148
150
158
160
161 JParser<> zap(
"Program to display hit probabilities.");
162
163 zap[
'w'] =
make_field(canvas,
"size of canvas <nx>x<ny> [pixels]") =
JCanvas(1200, 600);
164 zap[
'f'] =
make_field(inputFile,
"input file (output of JXXXMuonReconstruction.sh)");
176 zap[
'O'] =
make_field(option,
"draw option") = arrow_t, histogram_t;
177 zap[
'B'] =
make_field(batch,
"batch processing");
179
180 zap(argc, argv);
181 }
182 catch(const exception& error) {
183 FATAL(error.what() << endl);
184 }
185
187 FATAL(
"Missing output file name " <<
outputFile <<
" in batch mode." << endl);
188 }
189
192 }
193
196 }
197
198
200
201 try {
203 }
206 }
207 unique_ptr<JDynamics> dynamics;
208
209 try {
210
212
213 dynamics->load(calibrationFile);
214 }
215 catch(const exception& error) {
216 if (!calibrationFile.empty()) {
218 }
219 }
220
221 const double Zbed = 0.0;
222
224
226
227 if (cylinder.getZmin() < Zbed) {
228 cylinder.setZmin(Zbed);
229 }
230
232
234
236
238
241
243
244
245 Vec offset(0.0, 0.0, 0.0);
246
247 try {
249 } catch(const exception& error) {}
250
251 NOTICE(
"Offset applied to true tracks is: " << offset << endl);
252
253
254
255
256 gROOT->SetBatch(batch);
257
258 TApplication* tp = new TApplication("user", NULL, NULL);
259 TCanvas* cv =
new TCanvas(
"display",
"", canvas.
x, canvas.
y);
260
261 if (!batch) {
262 ((TRootCanvas *) cv->GetCanvasImp())->Connect("CloseWindow()", "TApplication", tp, "Terminate()");
263 }
264
265 unique_ptr<TStyle> gStyle(
new JStyle(
"gplot", cv->GetWw(), cv->GetWh(), graphics));
266
267 gROOT->SetStyle("gplot");
268 gROOT->ForceStyle();
269
270 const size_t NUMBER_OF_PADS = 3;
271
272 cv->SetFillStyle(4000);
273 cv->SetFillColor(kWhite);
274
275 TPad*
p1 =
new TPad(
"p1", NULL, 0.0, 0.00, 1.0, 0.95);
276 TPad* p2 = new TPad("p2", NULL, 0.0, 0.95, 1.0, 1.00);
277
278 p1->Divide(NUMBER_OF_PADS, 1);
279
281 p2->Draw();
282
284 const double Rmin = 0.0;
285 const double Rmax = min(parameters.
roadWidth_m, 0.4 * Dmax);
286 const double Tmin = min(parameters.
TMin_ns, -10.0);
287 const double Tmax = max(parameters.
TMax_ns, +100.0);
288 const double Amin = 0.002 * (Tmax - Tmin);
289 const double Amax = 0.8 * (Tmax - Tmin);
290 const double ymin = Tmin - (option == arrow_t ? 0.2 * Amax : 0.0);
291 const double ymax = Tmax + (option == arrow_t ? 0.5 * Amax : 0.0);
292
293 const string Xlabel[NUMBER_OF_PADS] = { "R [m]", "#phi [rad]", "z [m]" };
294 const double Xmin [NUMBER_OF_PADS] = { Rmin, -
PI, -0.4 * Dmax };
295 const double Xmax [NUMBER_OF_PADS] = { Rmax, +
PI, +0.4 * Dmax };
296
297 double Xs[NUMBER_OF_PADS];
298
299 for (size_t i = 0; i != NUMBER_OF_PADS; ++i) {
300 Xs[i] = 0.003 * (Xmax[i] - Xmin[i]) * (0.5 * NUMBER_OF_PMTS);
301 }
302
303 TH2D H2[NUMBER_OF_PADS];
304 TGraph G2[NUMBER_OF_PADS];
305
306 for (size_t i = 0; i != NUMBER_OF_PADS; ++i) {
307
308 H2[i] = TH2D(
MAKE_CSTRING(
"h" << i), NULL, graphics.nbinsX, Xmin[i] - Xs[i], Xmax[i] + Xs[i], graphics.nbinsY, ymin, ymax);
309
310 H2[i].GetXaxis()->SetTitle(Xlabel[i].c_str());
311 H2[i].GetYaxis()->SetTitle("#Deltat [ns]");
312
313 H2[i].GetXaxis()->CenterTitle(true);
314 H2[i].GetYaxis()->CenterTitle(true);
315
316 H2[i].SetStats(kFALSE);
317
318 G2[i].Set(2);
319
320 G2[i].SetPoint(0, H2[i].GetXaxis()->GetXmin(), 0.0);
321 G2[i].SetPoint(1, H2[i].GetXaxis()->GetXmax(), 0.0);
322
324
325 H2[i].Draw("AXIS");
326 G2[i].Draw("SAME");
327 }
328
329
331
332 cout << "event: " << setw(8) << inputFile.getCounter() << '\r';
333
334 multi_pointer_type ps = inputFile.next();
335
339
340 if (dynamics) {
341 dynamics->update(*tev);
342 }
343
344 if (mc.getEntries() != 0) {
346 }
347
349
350 if (!in->empty()) {
351
353
354 if (!event_selector(*tev, *in, event)) {
355 continue;
356 }
357
358
359 JDataL0_t dataL0;
360
361 buildL0(*tev, router, true, back_inserter(dataL0));
362
363 summary.update(*tev);
364
366
367 if (event != NULL) {
368
370
371 for (const auto& t1 : event->mc_trks) {
373 if (t1.E > muon.
getE()) {
374
376
379
380 muon =
getFit(0, ta, 0.0, 0, t1.E, 1);
381
383 }
384 }
385 }
386 }
387
388 bool monte_carlo = false;
389 size_t index = 0;
390
391 for (bool next = false; !next; ) {
392
393 for (size_t i = 0; i != NUMBER_OF_PADS; ++i) {
394 H2[i].Reset();
395 }
396
398
399 if (!monte_carlo)
400 fit = (*in)[index];
401 else
402 fit = muon;
403
407
408
409
410
411
412
414
415
416
418
419 for (JDataL0_t::const_iterator i = dataL0.begin(); i != dataL0.end(); ++i) {
420
421 const int type = 0;
422 const double QE = 1.0;
423 const double R_Hz = summary.getRate(i->getPMTIdentifier(), parameters.
R_Hz);
424
425 JHitW0 hit(*i, type, QE, R_Hz);
426
427 hit.rotate(R);
428
429 if (match(hit)) {
431 }
432 }
433
434
435
436 sort(
data.begin(),
data.end(), JHitW0::compare);
437
438 JDataW0_t::iterator __end = unique(
data.begin(),
data.end(), equal_to<JDAQPMTIdentifier>());
439
440 double E_GeV = parameters.
E_GeV;
441
442
443
444
445
446
447
448
450
451 for (JDataW0_t::iterator hit =
data.begin(); hit != __end; ++hit) {
452
453 const double x = hit->getX() - tz.getX();
454 const double y = hit->getY() - tz.getY();
455 const double z = hit->getZ();
456 const double R = sqrt(x*x + y*y);
457
459 }
460
461 const double z0 = tz.getZ();
463
465
466
467
468 ostringstream os;
471
473
474 marker[2].push_back(TMarker(z0 - tz.getZ(), 0.0, kFullCircle));
476
477 static_cast<TAttMarker&>(marker[2][0]) = TAttMarker(kRed, kFullCircle, 0.7);
478 static_cast<TAttMarker&>(marker[2][1]) = TAttMarker(kRed, kFullCircle, 0.7);
479 }
480
482 <<
FIXED(7,2) << tz.getX() <<
' '
483 <<
FIXED(7,2) << tz.getY() <<
' '
484 <<
FIXED(7,2) << tz.getZ() <<
' '
485 <<
FIXED(12,2) << tz.getT() << endl);
486
487 double chi2 = 0;
488
489 for (JDataW0_t::const_iterator hit =
data.begin(); hit != __end; ++hit) {
490
491 const double x = hit->getX() - tz.getX();
492 const double y = hit->getY() - tz.getY();
493 const double z = hit->getZ() - tz.getZ();
494 const double R = sqrt(x*x + y*y);
495
497
498 JDirection3D dir(hit->getDX(), hit->getDY(), hit->getDZ());
499
501
502 const double theta = dir.getTheta();
503 const double phi = fabs(dir.getPhi());
504
505
506 const double E = E_GeV;
507 const double dt = T_ns.constrain(hit->getT() - t1);
508
511
514 }
515
516 H1 += H0;
517
518 chi2 += H1.getChi2() - H0.getChi2();
519
521 << setw(8) << hit->getModuleID() <<
'.' <<
FILL(2,
'0') << (
int) hit->getPMTAddress() <<
FILL() <<
' '
523 <<
FIXED(7,2) << R <<
' '
524 <<
FIXED(7,4) << theta <<
' '
525 <<
FIXED(7,4) << phi <<
' '
526 <<
FIXED(7,3) << dt <<
' '
527 <<
FIXED(7,3) << H1.getChi2() <<
' '
528 <<
FIXED(7,3) << H0.getChi2() << endl);
529
530 const double derivative = H1.getDerivativeOfChi2() - H0.getDerivativeOfChi2();
531
532 double size = derivative * graphics.arrowScale;
533
534 if (fabs(size) < Amin) {
535 size = (size > 0.0 ? +Amin : -Amin);
536 } else if (fabs(size) > Amax) {
537 size = (size > 0.0 ? +Amax : -Amax);
538 }
539
540 const double X[NUMBER_OF_PADS] = { R, atan2(y,x), z - R/
getTanThetaC() };
541
542 const double xs = (double) (NUMBER_OF_PMTS - 2 * hit->getPMTAddress()) / (double) NUMBER_OF_PMTS;
543
544 for (size_t i = 0; i != NUMBER_OF_PADS; ++i) {
545
546 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());
547
548 a1.SetLineWidth(graphics.lineWidth);
549 a1.SetLineStyle(graphics.lineStyle);
550
551 arrow[i].push_back(a1);
552
553 H2[i].Fill(
X[i], dt + graphics.T_ns);
554 }
555 }
556
557 if (graphics.equalize) {
558
559 double zmax = 0.0;
560
561 for (size_t i = 0; i != NUMBER_OF_PADS; ++i) {
562 if (H2[i].GetMaximum() > zmax) {
563 zmax = H2[i].GetMaximum();
564 }
565 }
566
567 zmax *= 1.2;
568
569 for (size_t i = 0; i != NUMBER_OF_PADS; ++i) {
570 H2[i].SetMaximum(zmax);
571 }
572 }
573
575 os <<
" Q = " <<
FIXED(4,0) << fit.
getQ()
576 <<
'/' <<
FIXED(4,0) << -chi2;
578 os <<
" cos(#theta) = " <<
FIXED(6,3) << fit.
getDZ();
580
581 for (const auto& key : keys) {
583 }
584
585 if (monte_carlo)
586 os << " Monte Carlo";
589
590
591
592
593 TLatex title(0.05, 0.5, os.str().c_str());
594
595 title.SetTextAlign(12);
596 title.SetTextFont(42);
597 title.SetTextSize(0.6);
598
599 p2->cd();
600
601 title.Draw();
602
603 for (int i = 0; i != NUMBER_OF_PADS; ++i) {
604
606
607 if (option == arrow_t) {
608
609 for (auto& a1 : arrow[i]) {
610 a1.Draw();
611 }
612
613 for (auto& m1 : marker[i]) {
614 m1.Draw();
615 }
616 }
617
618 if (option == histogram_t) {
619 H2[i].Draw("SAME");
620 }
621 }
622
623 cv->Update();
624
625
626
627
628 if (batch) {
629
631
632 next = true;
633
634 } else {
635
636 static int count = 0;
637
638 if (count++ == 0) {
639 cout << endl << "Type '?' for possible options." << endl;
640 }
641
642 for (bool user = true; user; ) {
643
645
647
648 ts.move(intersection.first);
649
650 cout << "\n> " << flush;
651
653
654 case '?':
655 cout << endl;
656 cout << "possible options: " << endl;
657 cout << 'p' << " -> " << "print information" << endl;
658 cout << 'q' << " -> " << "exit application" << endl;
659 cout << 'u' << " -> " << "update canvas" << endl;
660 cout << 's' << " -> " << "save graphics to file" << endl;
661 cout << '+' << " -> " << "next fit" << endl;
662 cout << '-' << " -> " << "previous fit" << endl;
663 cout << 'M' << " -> " << "Monte Carlo true muon information" << endl;
664 cout << 'F' << " -> " << "fit information" << endl;
666 cout << 'L' << " -> " << "reload event selector" << endl;
667 }
668 cout << 'r' << " -> " << "rewind input file" << endl;
669 cout << 'R' << " -> " << "switch to ROOT mode (quit ROOT to continue)" << endl;
670 cout << ' ' << " -> " << "next event (as well as any other key)" << endl;
671 break;
672
673 case 'p':
674
675 cout << endl;
676 cout <<
"intersection: " <<
FIXED(6,1) << intersection.first <<
' '<<
FIXED(6,1) << intersection.second << endl;
677 cout << "entry point: "
678 <<
FIXED(6,1) << ts.getX() - cylinder.getX() <<
' '
679 <<
FIXED(6,1) << ts.getY() - cylinder.getY() <<
' '
680 <<
FIXED(6,1) << ts.getZ() << endl;
683 }
684 break;
685
686 case 'q':
687 cout << endl;
688 return 0;
689
690 case 'u':
691 cv->Update();
692 break;
693
694 case 's':
696 break;
697
698 case '+':
699 monte_carlo = false;
700 index = (index != in->size() - 1 ? index + 1 : 0);
701 user = false;
702 break;
703
704 case '-':
705 monte_carlo = false;
706 index = (index != 0 ? index - 1 : in->size() - 1);
707 user = false;
708 break;
709
710 case 'M':
712 monte_carlo = true;
713 else
714 ERROR(endl <<
"No Monte Carlo muon available." << endl);
715 user = false;
716 break;
717
718 case 'F':
719 monte_carlo = false;
720 user = false;
721 break;
722
723 case 'L':
725 execute(
MAKE_STRING(
"make -f " <<
getPath(argv[0]) <<
"/JMakeEventSelector libs"), 3);
727 }
728 break;
729
730 case 'R':
731 tp->Run(kTRUE);
732 break;
733
734 case 'r':
735 inputFile.rewind();
736
737 default:
738 next = true;
739 user = false;
740 break;
741 }
742 }
743 }
744 }
745 }
746 }
747 cout << endl;
748}
#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.
array_type< JKey_t > get_keys(const std::map< JKey_t, JValue_t, JComparator_t, JAllocator_t > &data)
Method to create array of keys of map.
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.