SdRecPlotter.cc
Go to the documentation of this file.
1 
9 #include <vector>
10 #include <sstream>
11 #include <iomanip>
12 
13 #include <boost/tokenizer.hpp>
14 
15 #include <TROOT.h>
16 #include <TStyle.h>
17 #include <TFile.h>
18 #include <TCanvas.h>
19 #include <TH2F.h>
20 #include <TEllipse.h>
21 #include <TLatex.h>
22 #include <TLine.h>
23 #include <TGraph.h>
24 #include <TGraphErrors.h>
25 #include <TGraphBentErrors.h>
26 #include <TMultiGraph.h>
27 #include <TPaveText.h>
28 #include <TPolyLine.h>
29 
30 #include <fwk/CentralConfig.h>
31 
32 #include <det/Detector.h>
33 
34 #include <sdet/SDetector.h>
35 #include <sdet/STimeVariance.h>
36 
37 #include <evt/ShowerSimData.h>
38 #include <evt/Event.h>
39 #include <evt/ShowerRecData.h>
40 #include <evt/ShowerSRecData.h>
41 
42 #include <sevt/SEvent.h>
43 #include <sevt/Header.h>
44 #include <sevt/Station.h>
45 #include <sevt/StationRecData.h>
46 #include <sevt/StationTriggerData.h>
47 
48 #include <utl/PhysicalConstants.h>
49 #include <utl/TimeStamp.h>
50 #include <utl/UTCDateTime.h>
51 #include <utl/TraceAlgorithm.h>
52 #include <utl/AxialVector.h>
53 #include <utl/UTMPoint.h>
54 #include <utl/TabulatedFunctionErrors.h>
55 #include <utl/ErrorLogger.h>
56 #include <utl/Reader.h>
57 #include <utl/SaveCurrentTDirectory.h>
58 
59 #include "SdRecPlotter.h"
60 
61 using namespace SdRecPlotterOG;
62 using namespace sdet;
63 using namespace fwk;
64 using namespace evt;
65 using namespace sevt;
66 using namespace utl;
67 using namespace std;
68 
69 
70 namespace SdRecPlotterOG {
71 
72  // perpendicular distance from the axis
73  inline
74  double
75  RPerp(const Vector& axis, const Vector& station)
76  {
77  const double scal = axis*station;
78  return sqrt(station*station - scal*scal);
79  }
80 
81 
82  inline
83  string
84  GetT4TriggerName(const int t4)
85  {
86  ostringstream trig;
87  if (t4) {
88  if (t4 & ShowerSRecData::eT4_FD)
89  trig << "FD";
90  if (t4 & ShowerSRecData::eT4_3TOT)
91  trig << (trig.str().length() ? "+" : "") << "3TOT";
92  if (t4 & ShowerSRecData::eT4_4C1)
93  trig << (trig.str().length() ? "+" : "") << "4C1";
94  } else
95  trig << "None";
96  return trig.str();
97  }
98 
99 
100  inline
101  string
102  GetT5TriggerName(const int t5)
103  {
104  ostringstream trig;
105  if (t5) {
106  if (t5 & ShowerSRecData::eT5_Prior)
107  trig << "Prior";
108  if (t5 & ShowerSRecData::eT5_Posterior)
109  trig << (trig.str().length() ? "+" : "") << "Posterior";
110  } else
111  trig << "None";
112  return trig.str();
113  }
114 
115  void
116  AddText(TPaveText& pt, const string& str)
117  {
118  typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
119  boost::char_separator<char> separator("\n");
120  tokenizer tokens(str, separator);
121  for (tokenizer::iterator it = tokens.begin();
122  it != tokens.end(); ++it)
123  pt.AddText(it->c_str());
124  }
125 
126 }
127 
128 
131 {
132  CentralConfig* cc = CentralConfig::GetInstance();
133  Branch topBranch = cc->GetTopBranch("SdRecPlotter");
134 
135  topBranch.GetChild("FileNamePrefix").GetData(fFileNamePrefix);
136 
137  fGenerateROOTFile = bool(topBranch.GetChild("GenerateROOTFile"));
138 
139  fGeneratePDFFile = bool(topBranch.GetChild("GeneratePDFFile"));
140 
141  fAppendOutput = bool(topBranch.GetChild("AppendOutput"));
142 
143  if (!fGenerateROOTFile && !fGeneratePDFFile)
144  WARNING("Both ROOT and PS options switched off, no output will be generated.");
145 
146  if (fGenerateROOTFile) {
147  const string fileName = fFileNamePrefix + ".root";
148  fROOTFile = new TFile(fileName.c_str(), "recreate", "SdRecPlotter", 9);
149  INFO(fileName + " file created.");
150  }
151 
152  gROOT->SetStyle("Plain");
153  gStyle->SetPalette(1, 0);
154 
155  if (fGeneratePDFFile) {
156  gStyle->SetPaperSize(TStyle::kA4);
157  gStyle->SetTitlePS(fFileNamePrefix.c_str());
158  if (fAppendOutput)
159  fPDFFileName = fFileNamePrefix + ".pdf";
160  }
161 
162  return eSuccess;
163 }
164 
165 
168 {
169  if (!fGenerateROOTFile && !fGeneratePDFFile)
170  return eSuccess;
171  if (!event.HasRecShower()) {
172  WARNING("No reconstructed shower data found.");
173  return eSuccess;
174  }
175  if (!event.GetRecShower().HasSRecShower()) {
176  WARNING("No SD reconstructed shower data found.");
177  return eSuccess;
178  }
179 
180  if (fGeneratePDFFile && !fAppendOutput) {
181  ostringstream os;
182  os << fFileNamePrefix << '_' << event.GetSEvent().GetHeader().GetId() << ".pdf";
183  fPDFFileName = os.str();
184  }
185 
186  DrawEvent(event);
187 
188  return eSuccess;
189 }
190 
191 
194 {
195  if (fROOTFile) {
196  fROOTFile->Close();
197  delete fROOTFile;
198  }
199  if (fGeneratePDFFile && fAppendOutput) {
200  TCanvas c;
201  c.Print((fPDFFileName + ")").c_str(), "pdf");
202  }
203  return eSuccess;
204 }
205 
206 
207 //=================================================================================================
208 
209 namespace SdRecPlotterOG {
210 
212  public:
214  ~CandidateInfo();
215  void PushStation(const int id, const double x, const double y,
216  const double r, const double sig, const double tCurv,
217  const double t0, const double sigma_t,
218  const double t10, const double t50, const double t90,
219  const int groupSize, const int saturation, const bool tot);
220  void SetSeed();
221  void CalculateLimits(const double zoom = 1);
222  double GetMinX() const { return fMinX; }
223  double GetMaxX() const { return fMaxX; }
224  double GetMinY() const { return fMinY; }
225  double GetMaxY() const { return fMaxY; }
226  double GetMinR() const { return fMinR; }
227  double GetMaxR() const { return fMaxR; }
228  double GetMaxSignal() const { return fMaxSignal; }
229  double GetMinTime() const { return fMinTime; }
230  double GetMaxTime() const { return fMaxTime; }
231  void DrawArray();
232  TGraph* GetLDFGraph();
233  TGraphBentErrors* GetSaturatedLDFGraph();
234  TGraph* GetStartTimeGraph();
235  TGraphBentErrors* GetRiseFallTimeGraph();
236  TGraph* GetCurvatureFitGraph();
237 
238  static const double kAspect;
239  static const double kLDFMinR;
240  static const double kStationMinRadius;
241  static const double kStationMaxRadius;
242  static const double kMinDX;
243  static const double kTwinSplit;
244  static const double kTwinIdSplit;
245  static const double kLowGainSatFactor;
246 
247  private:
248  vector<int> fId;
249  vector<double> fPositionX;
250  vector<double> fPositionY;
251  double fMinX = 0;
252  double fMaxX = 0;
253  double fMinY = 0;
254  double fMaxY = 0;
255  vector<double> fR;
256  double fMinR = 1;
257  double fMaxR = 1;
258  vector<double> fSignal;
259  double fMaxSignal = 0;
260  vector<double> fPlotRadius;
261  vector<double> fCurvTime;
262  vector<double> fStartTime;
263  vector<double> fStartTimeErr;
264  double fMinStartTime = 0;
265  double fMaxStartTime = 0;
266  vector<double> fTime10;
267  vector<double> fTime50;
268  vector<double> fTime90;
269  double fMinTime = 0;
270  double fMaxTime = 0;
271  vector<int> fTwin;
272  vector<int> fSaturation;
273  vector<bool> fTOT;
274  // deletables
275  vector<TEllipse*> fCircles;
276  TGraph* fLDFGraph = nullptr;
277  TGraphBentErrors* fSaturatedLDFGraph = nullptr;
278  TGraphErrors* fLDFNonsaturatedGraph = nullptr;
279  TGraph* fStartTimeGraph = nullptr;
280  TGraphBentErrors* fRiseFallTimeGraph = nullptr;
281  TGraph* fCurvatureFitGraph = nullptr;
282  };
283 
284 
285  const double CandidateInfo::kAspect = sqrt(2.);
286  const double CandidateInfo::kLDFMinR = 0.2; //km
287  const double CandidateInfo::kStationMinRadius = 0.07; //km
288  const double CandidateInfo::kStationMaxRadius = 0.7; //km
289  const double CandidateInfo::kMinDX = 7; //km
290  const double CandidateInfo::kTwinSplit = 0.07; //km
291  const double CandidateInfo::kTwinIdSplit = 0.3; //km
292  const double CandidateInfo::kLowGainSatFactor = 0.8;
293 
294 }
295 
296 
298 {
299  for (const auto c : fCircles)
300  delete c;
301  delete fLDFGraph;
302  delete fSaturatedLDFGraph;
303  delete fLDFNonsaturatedGraph;
304  delete fStartTimeGraph;
305  delete fRiseFallTimeGraph;
306  delete fCurvatureFitGraph;
307 }
308 
309 
310 void
311 CandidateInfo::PushStation(const int id, const double x, const double y,
312  const double r, const double sig, const double tCurv,
313  const double t0, const double sigma_t,
314  const double t10, const double t50, const double t90,
315  const int groupSize, const int sat, const bool tot)
316 {
317  fId.push_back(id);
318  fPositionX.push_back(x);
319  fPositionY.push_back(y);
320  fR.push_back(r);
321  if (r < fMinR)
322  fMinR = r;
323  if (r > fMaxR)
324  fMaxR = r;
325  fSignal.push_back(sig);
326  if (sig > fMaxSignal)
327  fMaxSignal = sig;
328  fCurvTime.push_back(tCurv);
329  fStartTime.push_back(t0);
330  fStartTimeErr.push_back(sigma_t);
331  fTime10.push_back(t10);
332  fTime50.push_back(t50);
333  fTime90.push_back(t90);
334  fTwin.push_back(groupSize);
335  fSaturation.push_back(sat);
336  fTOT.push_back(tot);
337 }
338 
339 
340 void
342 {
343  // limits
344  const unsigned int nStations = fPositionX.size();
345  if (!nStations)
346  return;
347  fMinX = fMaxX = fPositionX[0];
348  fMinY = fMaxY = fPositionY[0];
349  fMinTime = 0; // should always see zero
350  fMinStartTime = fMaxStartTime = fMaxTime = fStartTime[0];
351  const double sqrtMaxSignal = sqrt(fMaxSignal);
352  for (unsigned int i = 0; i < nStations; ++i) {
353  const double sqrtS = sqrt(fSignal[i]);
354  const double r = kStationMinRadius +
355  (kStationMaxRadius - kStationMinRadius)*sqrtS/sqrtMaxSignal;
356  fPlotRadius.push_back(r);
357  const double x = fPositionX[i];
358  const double xdown = x - r;
359  if (fMinX > xdown)
360  fMinX = xdown;
361  const double xup = x + r;
362  if (fMaxX < xup)
363  fMaxX = xup;
364  const double y = fPositionY[i];
365  const double ydown = y - r;
366  if (fMinY > ydown)
367  fMinY = ydown;
368  const double yup = y + r;
369  if (fMaxY < yup)
370  fMaxY = yup;
371  const double tCurv = fCurvTime[i];
372  if (fMinTime > tCurv)
373  fMinTime = tCurv;
374  if (fMaxTime < tCurv)
375  fMaxTime = tCurv;
376  const double t0 = fStartTime[i];
377  if (fMinStartTime > t0)
378  fMinStartTime = t0;
379  if (fMaxStartTime < t0)
380  fMaxStartTime = t0;
381  if (fMinTime > t0)
382  fMinTime = t0;
383  if (fMaxTime < t0)
384  fMaxTime = t0;
385  const double t10 = fTime10[i];
386  if (fMinTime > t10)
387  fMinTime = t10;
388  if (fMaxTime < t10)
389  fMaxTime = t10;
390  const double t50 = fTime50[i];
391  if (fMinTime > t50)
392  fMinTime = t50;
393  if (fMaxTime < t50)
394  fMaxTime = t50;
395  /*const double t90 = fTime90[i];
396  if (fMinTime > t90)
397  fMinTime = t90;
398  if (fMaxTime < t90)
399  fMaxTime = t90;*/
400  }
401  // R
402  if (fMinR < kLDFMinR)
403  fMinR = kLDFMinR;
404  if (fMaxR < fMinR)
405  fMaxR = 1;
406  fMinR /= 2;
407  fMaxR *= zoom;
408  // ascpect issue
409  double dx = zoom * (fMaxX - fMinX);
410  if (dx < kMinDX)
411  dx = kMinDX;
412  double dy = zoom * (fMaxY - fMinY);
413  if (dx/kAspect > dy) {
414  dy = dx/kAspect;
415  } else {
416  dx = kAspect*dy;
417  }
418  dx /= 2;
419  dy /= 2;
420  const double meanX = (fMinX + fMaxX)/2;
421  const double meanY = (fMinY + fMaxY)/2;
422  fMinX = meanX - dx;
423  fMaxX = meanX + dx;
424  fMinY = meanY - dy;
425  fMaxY = meanY + dy;
426  // time
427  double dt = zoom * (fMaxTime - fMinTime) / 2;
428  if (!dt)
429  dt = 1;
430  const double meanTime = (fMinTime + fMaxTime) / 2;
431  fMinTime = meanTime - dt;
432  fMaxTime = meanTime + dt;
433  if (fMinStartTime == fMaxStartTime)
434  ++fMaxStartTime;
435 }
436 
437 
438 void
440 {
441  const unsigned int nStations = fPositionX.size();
442  for (unsigned int i = 0; i < nStations; ++i) {
443  const double r = fPlotRadius[i];
444  const int sat = fSaturation[i];
445  TEllipse* s = nullptr;
446  TEllipse* s2 = nullptr;
447  TEllipse* thresh = nullptr;
448  switch (fTwin[i]) {
449  case 0: // normal
450  s = new TEllipse(fPositionX[i], fPositionY[i], (sat == 2 ? kLowGainSatFactor : 1)*r);
451  if (sat)
452  s2 = new TEllipse(fPositionX[i], fPositionY[i], r);
453  if (!fTOT[i])
454  thresh = new TEllipse(fPositionX[i], fPositionY[i], r/4);
455  break;
456  case 1: // lower twin
457  s = new TEllipse(fPositionX[i], fPositionY[i] - kTwinSplit,
458  (sat == 2 ? kLowGainSatFactor : 1)*r);
459  if (sat)
460  s2 = new TEllipse(fPositionX[i], fPositionY[i] - kTwinSplit, r);
461  if (!fTOT[i])
462  thresh = new TEllipse(fPositionX[i], fPositionY[i] - kTwinSplit, r/4,
463  0, 180, 360, 0);
464  break;
465  default: // upper twin
466  s = new TEllipse(fPositionX[i], fPositionY[i] + kTwinSplit,
467  (sat == 2 ? kLowGainSatFactor : 1)*r);
468  if (sat)
469  s2 = new TEllipse(fPositionX[i], fPositionY[i] + kTwinSplit, r);
470  if (!fTOT[i])
471  thresh = new TEllipse(fPositionX[i], fPositionY[i] + kTwinSplit,
472  r/4, 0, 0, 180, 0);
473  break;
474  }
475  const int color =
476  int(51 + (fStartTime[i] - fMinStartTime)/(fMaxStartTime - fMinStartTime)*49.);
477  switch (sat) {
478  case 0: // no saturation (no border)
479  s->SetLineColor(color);
480  if (thresh)
481  thresh->SetLineColor(10);
482  break;
483  case 1: // high
484  case 2: // low gain saturation (black border)
485  s->SetLineWidth(2);
486  s->SetLineColor(color);
487  s2->SetLineWidth(2);
488  s2->SetLineColor(kBlack);
489  if (thresh)
490  thresh->SetLineColor(kBlack);
491  break;
492  }
493  s->SetFillColor(color);
494  s->SetFillStyle(1001);
495  s->Draw();
496  fCircles.push_back(s);
497  if (s2) {
498  s2->Draw();
499  fCircles.push_back(s2);
500  }
501  if (thresh) {
502  thresh->SetFillColor(10);
503  thresh->SetFillStyle(1001);
504  thresh->Draw();
505  fCircles.push_back(thresh);
506  }
507  }
508  TLatex label;
509  label.SetTextSize(0.03);
510  for (unsigned int i = 0; i < nStations; ++i) {
511  ostringstream id;
512  id << fId[i];
513  //twin text split
514  const double textSplit = kTwinIdSplit * (fTwin[i] ? (fTwin[i] >= 1 ? -1 : 1) : 0);
515  label.DrawLatex(fPositionX[i], fPositionY[i] + textSplit, id.str().c_str());
516  }
517 }
518 
519 
520 TGraph*
522 {
523  delete fLDFGraph;
524  fLDFGraph = nullptr;
525  vector<double> r;
526  vector<double> signal;
527  vector<double> signalErr;
528  const unsigned int nR = fR.size();
529 
530  for (unsigned int i = 0; i < nR; ++i)
531  if (fSaturation[i] != 2) {
532  r.push_back(fR[i]);
533  signal.push_back(fSignal[i]);
534  signalErr.push_back(sqrt(fSignal[i]));
535  }
536  if (r.size()) {
537  fLDFGraph = new TGraphErrors(r.size(), &r[0], &signal[0], 0, &signalErr[0]);
538  fLDFGraph->SetMarkerSize(0.5);
539  fLDFGraph->SetMarkerStyle(8);
540  }
541  return fLDFGraph;
542 }
543 
544 
545 TGraphBentErrors*
547 {
548  delete fSaturatedLDFGraph;
549  fSaturatedLDFGraph = nullptr;
550  vector<double> r;
551  vector<double> signal;
552  vector<double> signalErr;
553  const unsigned int nR = fR.size();
554  for (unsigned int i = 0; i < nR; ++i)
555  if (fSaturation[i] == 2) {
556  r.push_back(fR[i]);
557  signal.push_back(fSignal[i]);
558  signalErr.push_back(sqrt(fSignal[i]));
559  }
560  if (r.size()) {
561  fSaturatedLDFGraph = new TGraphBentErrors(r.size(), &r[0], &signal[0], 0, 0, &signalErr[0]);
562  fSaturatedLDFGraph->SetMarkerSize(0.5);
563  fSaturatedLDFGraph->SetMarkerStyle(22);
564  fSaturatedLDFGraph->SetMarkerColor(kBlue);
565  }
566  return fSaturatedLDFGraph;
567 }
568 
569 
570 TGraph*
572 {
573  delete fStartTimeGraph;
574  fStartTimeGraph = new TGraphErrors(fR.size(), &fR[0], &fStartTime[0], 0, &fStartTimeErr[0]);
575  fStartTimeGraph->SetMarkerStyle(22);
576  fStartTimeGraph->SetMarkerSize(0.5);
577  return fStartTimeGraph;
578 }
579 
580 
581 TGraphBentErrors*
583 {
584  vector<double> low;
585  vector<double> high;
586  const unsigned int nR = fR.size();
587  for (unsigned int i = 0; i < nR; ++i) {
588  const double t50 = fTime50[i];
589  low.push_back(t50 - fTime10[i]);
590  high.push_back(fTime90[i] - t50);
591  }
592  delete fRiseFallTimeGraph;
593  fRiseFallTimeGraph = new TGraphBentErrors(fR.size(), &fR[0], &fTime50[0], 0, 0, &low[0], &high[0]);
594  fRiseFallTimeGraph->SetMarkerStyle(21);
595  fRiseFallTimeGraph->SetMarkerSize(0.3);
596  fRiseFallTimeGraph->SetMarkerColor(38);
597  fRiseFallTimeGraph->SetLineColor(38);
598  return fRiseFallTimeGraph;
599 }
600 
601 
602 TGraph*
604 {
605  delete fCurvatureFitGraph;
606  fCurvatureFitGraph = new TGraph(fR.size(), &fR[0], &fCurvTime[0]);
607  fCurvatureFitGraph->SetMarkerStyle(4);
608  fCurvatureFitGraph->SetMarkerSize(0.9);
609  fCurvatureFitGraph->SetMarkerColor(kGreen);
610  return fCurvatureFitGraph;
611 }
612 
613 
614 //=================================================================================================
615 
616 namespace SdRecPlotterOG {
617 
619  public:
621  ~AccidentalInfo();
622  void SetLimits(const double minX, const double maxX,
623  const double minY, const double maxY,
624  const double maxR, const double maxSignal);
625  void PushStation(const int id, const double x, const double y, const double r,
626  const double sig, const double t, const int groupSize);
627  void DrawArray();
628  TGraphErrors* GetSignalGraph();
629  TGraph* GetTimeGraph();
630 
631  private:
632  vector<int> fId;
633  vector<double> fPositionX;
634  vector<double> fPositionY;
635  double fMinX = 0;
636  double fMaxX = 0;
637  double fMinY = 0;
638  double fMaxY = 0;
639  vector<double> fR;
640  double fMaxR = 0;
641  vector<double> fSignal;
642  double fMaxSignal = 0;
643  vector<double> fTime;
644  vector<int> fTwin;
645  // deletables
646  vector<TLine*> fLines;
647  vector<TEllipse*> fCircles;
648  TGraphErrors* fSignalGraph = nullptr;
649  TGraph* fTimeGraph = nullptr;
650  };
651 
652 }
653 
654 
656 {
657  for (const auto line : fLines)
658  delete line;
659  for (const auto circ : fCircles)
660  delete circ;
661  delete fSignalGraph;
662  delete fTimeGraph;
663 }
664 
665 
666 void
667 AccidentalInfo::SetLimits(const double minX, const double maxX,
668  const double minY, const double maxY,
669  const double maxR, const double maxSignal)
670 {
671  const double d = 0.1;
672  fMinX = minX + d;
673  fMaxX = maxX - d;
674  fMinY = minY + d;
675  fMaxY = maxY - d;
676  fMaxR = maxR;
677  fMaxSignal = maxSignal;
678 }
679 
680 
681 void
682 AccidentalInfo::PushStation(const int id, const double x, const double y,
683  const double r, const double sig, const double t,
684  const int groupSize)
685 {
686  fId.push_back(id);
687  fPositionX.push_back(x);
688  fPositionY.push_back(y);
689  fR.push_back(r);
690  fSignal.push_back(sig);
691  fTime.push_back(t);
692  fTwin.push_back(groupSize);
693 }
694 
695 
696 void
698 {
699  const double sqrtMaxSignal = sqrt(fMaxSignal);
700  const unsigned int nStations = fId.size();
701  vector<bool> isDrawn(nStations, false);
702  for (unsigned int i = 0; i < nStations; ++i) {
703  const double x = fPositionX[i];
704  const double y = fPositionY[i];
705  const double sqrtS = sqrt(fSignal[i]);
706  const double r = CandidateInfo::kStationMinRadius +
708  const double size = r/sqrt(2.);
709  if (fMinX + size < x && x < fMaxX - size &&
710  fMinY + size < y && y < fMaxY - size) {
711  TLine* line1 = nullptr;
712  TLine* line2 = nullptr;
713  TEllipse* c = nullptr;
714  switch (fTwin[i]) {
715  case 0: // normal
716  line1 = new TLine(x - size, y - size, x + size, y + size);
717  line2 = new TLine(x - size, y + size, x + size, y - size);
718  c = new TEllipse(x, y, r);
719  break;
720  case 1: // lower twin
721  {
722  const double yy = y - CandidateInfo::kTwinSplit;
723  line1 = new TLine(x - size, yy - size, x, yy);
724  line2 = new TLine(x, yy, x + size, yy - size);
725  c = new TEllipse(x, yy, r, 0, 180, 360, 0);
726  break;
727  }
728  default: // upper twin
729  {
730  const double yy = y + CandidateInfo::kTwinSplit;
731  line1 = new TLine(x - size, yy + size, x, yy);
732  line2 = new TLine(x, yy, x + size, yy + size);
733  c = new TEllipse(x, yy, r, 0, 0, 180, 0);
734  break;
735  }
736  }
737  line1->SetLineColor(kRed);
738  line2->SetLineColor(kRed);
739  c->SetLineColor(kRed);
740  line1->Draw();
741  line2->Draw();
742  c->Draw();
743  fLines.push_back(line1);
744  fLines.push_back(line2);
745  fCircles.push_back(c);
746  isDrawn[i] = true;
747  }
748  }
749  TLatex label;
750  label.SetTextSize(0.03);
751  for (unsigned int i = 0; i < nStations; ++i)
752  if (isDrawn[i]) {
753  ostringstream id;
754  id << fId[i];
755  // twin text split
756  const double textSplit =
757  CandidateInfo::kTwinIdSplit * (fTwin[i] ? (fTwin[i] >= 1 ? -1 : 1) : 0);
758  label.DrawLatex(fPositionX[i], fPositionY[i] + textSplit, id.str().c_str());
759  }
760 }
761 
762 
763 TGraphErrors*
765 {
766  delete fSignalGraph;
767  fSignalGraph = nullptr;
768  vector<double> r;
769  vector<double> signal;
770  vector<double> signalErr;
771  const unsigned int nR = fR.size();
772  for (unsigned int i = 0; i < nR; ++i)
773  if (fR[i] < fMaxR) {
774  r.push_back(fR[i]);
775  signal.push_back(fSignal[i]);
776  signalErr.push_back(sqrt(fSignal[i]));
777  }
778  if (r.size()) {
779  fSignalGraph = new TGraphErrors(r.size(), &r[0], &signal[0], 0, &signalErr[0]);
780  fSignalGraph->SetLineColor(kRed);
781  fSignalGraph->SetMarkerColor(kRed);
782  fSignalGraph->SetMarkerStyle(8);
783  fSignalGraph->SetMarkerSize(0.5);
784  }
785  return fSignalGraph;
786 }
787 
788 
789 TGraph*
791 {
792  delete fTimeGraph;
793  fTimeGraph = nullptr;
794  const unsigned int nR = fR.size();
795  if (nR) {
796  fTimeGraph = new TGraph(nR, &fR[0], &fTime[0]);
797  fTimeGraph->SetMarkerStyle(22);
798  fTimeGraph->SetMarkerSize(0.5);
799  fTimeGraph->SetMarkerColor(kRed);
800  }
801  return fTimeGraph;
802 }
803 
804 
805 //=================================================================================================
806 
807 namespace SdRecPlotterOG {
808 
809  class SilentInfo {
810  public:
812  ~SilentInfo();
813  void SetLimits(const double minX, const double maxX,
814  const double minY, const double maxY,
815  const double maxR);
816  void PushStation(const double x, const double y,
817  const double r, const int groupSize);
818  void DrawArray();
819  TGraph* GetLimitsGraph();
820 
821  static double kSilentThreshold;
822 
823  private:
824  vector<double> fPositionX;
825  vector<double> fPositionY;
826  double fMinX = 0;
827  double fMaxX = 0;
828  double fMinY = 0;
829  double fMaxY = 0;
830  vector<double> fR;
831  double fMaxR = 0;
832  vector<int> fTwin;
833  // deletables
834  vector<TEllipse*> fCircles;
835  TGraph* fLimitsGraph = nullptr;
836  };
837 
838 
839  double SilentInfo::kSilentThreshold = 2.8;
840 
841 }
842 
843 
845 {
846  for (const auto circ : fCircles)
847  delete circ;
848  delete fLimitsGraph;
849 }
850 
851 
852 void
853 SilentInfo::SetLimits(const double minX, const double maxX,
854  const double minY, const double maxY,
855  const double maxR)
856 {
857  const double d = 0.1;
858  fMinX = minX + d;
859  fMaxX = maxX - d;
860  fMinY = minY + d;
861  fMaxY = maxY - d;
862  fMaxR = maxR;
863 }
864 
865 
866 void
867 SilentInfo::PushStation(const double x, const double y, const double r, const int groupSize)
868 {
869  fPositionX.push_back(x);
870  fPositionY.push_back(y);
871  fR.push_back(r);
872  fTwin.push_back(groupSize);
873 }
874 
875 
876 void
878 {
879  const double size = 0.05; //km
880  const double twinSplit = 0.03; //km
881  const unsigned int nStations = fPositionX.size();
882  for (unsigned int i = 0; i < nStations; ++i) {
883  const double x = fPositionX[i];
884  const double y = fPositionY[i];
885  if (fMinX < x && x < fMaxX && fMinY < y && y < fMaxY) {
886  TEllipse* c = nullptr;
887  switch (fTwin[i]) {
888  case 0: //normal
889  c = new TEllipse(x, y, size);
890  break;
891  case 1: //lower twin
892  c = new TEllipse(x, y - twinSplit, size, 0, 180, 360, 0);
893  break;
894  default: //upper twin
895  c = new TEllipse(x, y + twinSplit, size, 0, 0, 180, 0);
896  break;
897  }
898  c->Draw();
899  fCircles.push_back(c);
900  }
901  }
902 }
903 
904 
905 TGraph*
907 {
908  delete fLimitsGraph;
909  fLimitsGraph = nullptr;
910  vector<double> r;
911  const unsigned int nR = fR.size();
912  for (unsigned int i = 0; i < nR; ++i)
913  if (fR[i] < fMaxR)
914  r.push_back(fR[i]);
915  const unsigned nLimits = r.size();
916  if (nLimits) {
917  vector<double> trigger(nLimits, kSilentThreshold);
918  fLimitsGraph = new TGraph(nLimits, &r[0], &trigger[0]);
919  fLimitsGraph->SetMarkerStyle(23);
920  fLimitsGraph->SetMarkerColor(kBlue);
921  fLimitsGraph->SetMarkerSize(0.5);
922  }
923  return fLimitsGraph;
924 }
925 
926 
927 //=================================================================================================
928 
929 void
931 {
932  const SEvent& sEvent = event.GetSEvent();
933  const sevt::Header& sHeader = sEvent.GetHeader();
934  //const int eventId = sHeader.GetId();
935  const string globalId = event.GetHeader().GetId();
936  const det::Detector& detector = det::Detector::GetInstance();
937  const SDetector& sDetector = detector.GetSDetector();
938  const STimeVariance& timeVariance = STimeVariance::GetInstance();
939  const CoordinateSystemPtr siteCS = detector.GetSiteCoordinateSystem();
940  const ShowerSRecData& shRec = event.GetRecShower().GetSRecShower();
941  const Point& core = shRec.GetCorePosition();
942  const TimeStamp& coreTime = shRec.GetCoreTime();
943  const Vector& axis = shRec.GetAxis();
944  const double curvature = shRec.GetCurvature();
945  const double curvR = curvature ? 1/curvature : 1000*kilometer;
946  const Vector showerCenter(curvR*axis);
947  const TimeStamp curvT0(coreTime - TimeInterval(curvR/kSpeedOfLight));
948 
949  CandidateInfo candidates;
950  AccidentalInfo accidentals;
951  SilentInfo silents;
952 
953  // curvature data
954  double minHeight = 0;
955  double maxHeight = 0;
956 
957  for (SEvent::ConstStationIterator sIt = sEvent.StationsBegin();
958  sIt != sEvent.StationsEnd(); ++sIt) {
959 
960  const int sId = sIt->GetId();
961  const sdet::Station& dStation = sDetector.GetStation(sId);
962  const Point& sPosition = dStation.GetPosition();
963  const double x = sPosition.GetX(siteCS)/kilometer;
964  const double y = sPosition.GetY(siteCS)/kilometer;
965  const Vector sRelPos(sPosition - core);
966  const double r = RPerp(axis, sRelPos)/kilometer;
967  const int groupSize = dStation.GetNumberOfPartners();
968 
969  if (sIt->IsCandidate()) {
970 
971  const double radius = (showerCenter - sRelPos).GetMag();
972  const double height = axis*sRelPos;
973  if (minHeight > height)
974  minHeight = height;
975  if (maxHeight < height)
976  maxHeight = height;
977  const StationRecData& sRec = sIt->GetRecData();
978  const double signal = sRec.GetTotalSignal();
979  const TimeStamp planeFrontTime(coreTime -
980  TimeInterval(height/kSpeedOfLight));
981  const double tCurv = (curvT0 + TimeInterval(radius/kSpeedOfLight) - planeFrontTime).GetInterval();
982  const double t0 = (sRec.GetSignalStartTime() - planeFrontTime).GetInterval();
983  const double traceTime = (sIt->GetTraceStartTime() - planeFrontTime).GetInterval();
984  const int start = sRec.GetSignalStartSlot();
985  const int end = sRec.GetSignalEndSlot();
986  const TraceD& trace = sIt->GetVEMTrace();
987  const double t10 = traceTime + TraceAlgorithm::TimeAtRelativeSignalX(trace, start, end, 10);
988  const double t50 = traceTime + TraceAlgorithm::TimeAtRelativeSignalX(trace, start, end, 50);
989  const double t90 = traceTime + TraceAlgorithm::TimeAtRelativeSignalX(trace, start, end, 90);
990  const double sigma_t = sqrt(timeVariance.GetTimeSigma2(signal, t50 - t0, axis.GetCosTheta(siteCS), r));
991  const int sat = sIt->IsLowGainSaturation() ? 2 : sIt->IsHighGainSaturation();
992  const bool tot = sIt->GetTriggerData().GetAlgorithm() == StationTriggerData::eTimeOverThreshold;
993  candidates.PushStation(sId, x, y, r, signal, curvature ? tCurv/nanosecond : 0,
994  t0/nanosecond, sigma_t/nanosecond, t10/nanosecond, t50/nanosecond, t90/nanosecond,
995  groupSize, sat, tot);
996 
997  } else if (sIt->IsRejected() && sIt->HasRecData()) {
998 
999  const StationRecData& sRec = sIt->GetRecData();
1000  const TimeStamp planeFrontTime(coreTime -
1001  TimeInterval((sPosition - core)*axis/kSpeedOfLight));
1002  const double t0 = (sRec.GetSignalStartTime() - planeFrontTime).GetInterval();
1003  accidentals.PushStation(sId, x, y, r, sIt->GetRecData().GetTotalSignal(), t0/nanosecond, groupSize);
1004 
1005  } else // Silent
1006 
1007  silents.PushStation(x, y, r, groupSize);
1008 
1009  }
1010 
1011  candidates.CalculateLimits(1.2);
1012  const double minX = candidates.GetMinX();
1013  const double maxX = candidates.GetMaxX();
1014  const double minY = candidates.GetMinY();
1015  const double maxY = candidates.GetMaxY();
1016  const double minR = candidates.GetMinR();
1017  const double maxR = candidates.GetMaxR();
1018 
1019  ostringstream cName;
1020  // cName << "Event_" << eventId;
1021  cName << "Event_" << globalId;
1022  TCanvas canvas(cName.str().c_str(), cName.str().c_str(), 1);
1023  canvas.Divide(2, 2);
1024 
1025  // array view
1026  canvas.cd(1);
1027  TH2F array("array", "Array layout", 10, minX, maxX, 10, minY, maxY);
1028  array.GetXaxis()->SetTitle("x [km]");
1029  array.GetYaxis()->SetTitle("y [km]");
1030  array.SetStats(kFALSE);
1031  array.Draw();
1032  // accidentals
1033  accidentals.SetLimits(minX, maxX, minY, maxY, maxR, candidates.GetMaxSignal());
1034  accidentals.DrawArray();
1035  // silent
1036  silents.SetLimits(minX, maxX, minY, maxY, maxR);
1037  silents.DrawArray();
1038  // candidates
1039  candidates.DrawArray();
1040  // seed
1041  const vector<int>& seedStation = shRec.GetReconstructionSeed();
1042  if (seedStation.size()) {
1043  vector<double> sx;
1044  vector<double> sy;
1045  for (unsigned int i = 0; i < seedStation.size(); ++i) {
1046  const Point& sPos = sDetector.GetStation(seedStation[i]).GetPosition();
1047  sx.push_back(sPos.GetX(siteCS)/kilometer);
1048  sy.push_back(sPos.GetY(siteCS)/kilometer);
1049  }
1050  const Point& sPos = sDetector.GetStation(seedStation[0]).GetPosition();
1051  sx.push_back(sPos.GetX(siteCS)/kilometer);
1052  sy.push_back(sPos.GetY(siteCS)/kilometer);
1053  TPolyLine* const grSeed = new TPolyLine(sx.size(), &sx[0], &sy[0]);
1054  grSeed->SetBit(kCanDelete);
1055  grSeed->SetLineColor(kGreen);
1056  grSeed->Draw();
1057  }
1058  // coreMC
1059  const bool hasSimShower = event.HasSimShower();
1060  if (hasSimShower) {
1061  const ShowerSimData& simShower = event.GetSimShower();
1062  const Point& coreMC = simShower.GetPosition();
1063  const Vector& axisMC = -simShower.GetDirection();
1064  const double phiMC = axisMC.GetPhi(siteCS);
1065  const double coreMCX = coreMC.GetX(siteCS)/kilometer;
1066  const double coreMCY = coreMC.GetY(siteCS)/kilometer;
1067  TEllipse* const coreMCMark = new TEllipse(coreMCX, coreMCY, 0.25, 0, 31, 329, phiMC/degree);
1068  coreMCMark->SetBit(kCanDelete);
1069  coreMCMark->SetLineColor(kBlue);
1070  coreMCMark->SetLineWidth(2);
1071  coreMCMark->SetFillStyle(1001);
1072  coreMCMark->SetFillColor(10);
1073  coreMCMark->Draw();
1074  const double coreLength = 2;
1075  TLine* const coreMCLine =
1076  new TLine(coreMCX, coreMCY, coreMCX + coreLength*cos(phiMC), coreMCY + coreLength*sin(phiMC));
1077  coreMCLine->SetBit(kCanDelete);
1078  coreMCLine->SetLineColor(kBlue);
1079  coreMCLine->SetLineWidth(2);
1080  coreMCLine->Draw();
1081  }
1082  // core
1083  const double phi = axis.GetPhi(siteCS);
1084  const double coreX = core.GetX(siteCS)/kilometer;
1085  const double coreY = core.GetY(siteCS)/kilometer;
1086  TEllipse coreMark(coreX, coreY, 0.25, 0, 31, 329, phi/degree);
1087  coreMark.SetLineColor(kRed);
1088  coreMark.SetLineWidth(2);
1089  coreMark.SetFillStyle(1001);
1090  coreMark.SetFillColor(10);
1091  coreMark.Draw();
1092  const double coreLength = 2;
1093  TLine coreLine(coreX, coreY, coreX + coreLength*cos(phi), coreY + coreLength*sin(phi));
1094  coreLine.SetLineColor(kRed);
1095  coreLine.SetLineWidth(2);
1096  coreLine.Draw();
1097 
1098  // timing
1099  canvas.cd(2);
1100  double timeZeroX[] = { 0, maxR };
1101  double timeZeroY[] = { 0, 0 };
1102  TGraph* const grTimeZero = new TGraph(2, timeZeroX, timeZeroY);
1103  grTimeZero->SetBit(kCanDelete);
1104  grTimeZero->SetLineStyle(3);
1105  grTimeZero->SetTitle("Timing");
1106  grTimeZero->GetXaxis()->SetTitle("r [km]");
1107  grTimeZero->GetYaxis()->SetTitle("time to plane front [ns]");
1108  grTimeZero->GetXaxis()->SetLimits(0, maxR);
1109  grTimeZero->SetMinimum(candidates.GetMinTime());
1110  grTimeZero->SetMaximum(candidates.GetMaxTime());
1111  grTimeZero->Draw("al");
1112  TGraph* grStartTime = candidates.GetStartTimeGraph();
1113  if (curvature) {
1114  vector<double> timingR;
1115  vector<double> timingCurve;
1116  const double rc = 1/curvature;
1117  const int nPoints = 100;
1118  const double dr = maxR*kilometer/(nPoints - 1);
1119  const double rc1 = rc - maxHeight;
1120  for (int i = nPoints - 1; i >= 0; --i) {
1121  const double r = i*dr;
1122  timingR.push_back(r/kilometer);
1123  timingCurve.push_back((sqrt(r*r+rc1*rc1) - rc1)/kSpeedOfLight);
1124  }
1125  const double rc2 = rc - minHeight;
1126  for (int i = 0; i < nPoints; ++i) {
1127  const double r = i*dr;
1128  timingR.push_back(r/kilometer);
1129  timingCurve.push_back((sqrt(r*r+rc2*rc2) - rc2)/kSpeedOfLight);
1130  }
1131  TGraph* const grCurvature = new TGraph(timingR.size(), &timingR[0], &timingCurve[0]);
1132  grCurvature->SetBit(kCanDelete);
1133  grCurvature->SetLineColor(7);
1134  grCurvature->SetLineStyle(2);
1135  grCurvature->Draw("samel");
1136  TGraph* const grCurvatureFit = candidates.GetCurvatureFitGraph();
1137  grCurvatureFit->Draw("samep");
1138  }
1139  candidates.GetRiseFallTimeGraph()->Draw("samep");
1140  grStartTime->Draw("samep");
1141  TGraph* grAccidentalTime = accidentals.GetTimeGraph();
1142  if (grAccidentalTime)
1143  grAccidentalTime->Draw("samep");
1144 
1145  // LDF
1146  canvas.cd(3);
1147  gPad->SetLogy();
1148  // LDF signal
1149  TGraph* grSignal = candidates.GetLDFGraph();
1150  TGraphBentErrors* grSatSignal = candidates.GetSaturatedLDFGraph();
1151 
1152  if (shRec.HasLDF()) {
1153  const TabulatedFunctionErrors& ldf = shRec.GetLDF();
1154  // LDF error
1155  vector<double> signalR;
1156  vector<double> signal;
1157  vector<double> signalErr;
1158  const unsigned int nLDFPoints = ldf.GetNPoints();
1159  for (unsigned int i = 0; i < nLDFPoints; ++i) {
1160  signalR.push_back(ldf.GetX(i)/kilometer);
1161  const double sig = ldf.GetY(i);
1162  signal.push_back(sig);
1163  signalErr.push_back(sig + ldf.GetYErr(i));
1164  }
1165  for (int i = nLDFPoints - 1; i >= 0; --i) {
1166  signalR.push_back(ldf.GetX(i)/kilometer);
1167  const double low = ldf.GetY(i) - ldf.GetYErr(i);
1168  signalErr.push_back(low > 0.01 ? low : 0.01);
1169  }
1170 
1171  TGraph* const grLDFError = new TGraph(signalR.size(), &signalR[0], &signalErr[0]);
1172  grLDFError->SetBit(kCanDelete);
1173  grLDFError->SetTitle("LDF fit");
1174  grLDFError->GetYaxis()->SetTitle("Signal [VEM]");
1175  grLDFError->GetXaxis()->SetTitle("r [km]");
1176  grLDFError->SetFillStyle(1001);
1177  grLDFError->SetFillColor(18);
1178  grLDFError->GetXaxis()->SetLimits(minR, maxR);
1179  grLDFError->SetMinimum(min(SilentInfo::kSilentThreshold/2,
1180  grSatSignal ? min(grSignal->GetYaxis()->GetXmin(), grSatSignal->GetYaxis()->GetXmin()) :
1181  grSignal->GetYaxis()->GetXmin()));
1182  grLDFError->SetMaximum(1.2 * (grSatSignal ? max(grSignal->GetYaxis()->GetXmax(), grSatSignal->GetYaxis()->GetXmax()) :
1183  grSignal->GetYaxis()->GetXmax()));
1184  grLDFError->Draw("af");
1185  // LDF fit
1186  TGraph* grLDFFit = new TGraph(signal.size(), &signalR[0], &signal[0]);
1187  grLDFFit->SetBit(kCanDelete);
1188  grLDFFit->SetLineColor(kGreen);
1189  grLDFFit->SetLineWidth(2);
1190  grLDFFit->Draw("samel");
1191  double rOpt = shRec.GetLDFOptimumDistance();
1192  if (rOpt && ldf.GetX(0) <= rOpt && rOpt <= ldf.GetX(ldf.GetNPoints()-1)) {
1193  const double sROpt = ldf.Y(rOpt);
1194  rOpt /= kilometer;
1195  TGraph* const grLDFROpt = new TGraph(1, &rOpt, &sROpt);
1196  grLDFROpt->SetBit(kCanDelete);
1197  grLDFROpt->SetMarkerColor(kGreen);
1198  grLDFROpt->SetMarkerStyle(kStar);
1199  grLDFROpt->SetMarkerSize(1.3);
1200  grLDFROpt->Draw("samep");
1201  }
1202  } else {
1203  WARNING("No LDF tabulated function object found.");
1204  grSignal->SetTitle("LDF fit");
1205  grSignal->GetYaxis()->SetTitle("Signal [VEM]");
1206  grSignal->GetXaxis()->SetTitle("r [km]");
1207  grSignal->GetXaxis()->SetLimits(minR, maxR);
1208  grSignal->SetMinimum(min(SilentInfo::kSilentThreshold/2,
1209  grSatSignal ? min(grSignal->GetYaxis()->GetXmin(), grSatSignal->GetYaxis()->GetXmin()) :
1210  grSignal->GetYaxis()->GetXmin()));
1211  grSignal->SetMaximum(1.2 * (grSatSignal ? max(grSignal->GetYaxis()->GetXmax(), grSatSignal->GetYaxis()->GetXmax()) :
1212  grSignal->GetYaxis()->GetXmax()));
1213  grSignal->Draw("ap");
1214  }
1215  // silent limits
1216  TGraph* grSilentLimits = silents.GetLimitsGraph();
1217  if (grSilentLimits)
1218  grSilentLimits->Draw("samep");
1219  // LDF accidental
1220  TGraphErrors* grAccidentalSignal = accidentals.GetSignalGraph();
1221  if (grAccidentalSignal)
1222  grAccidentalSignal->Draw("samep");
1223  // LDF candiates
1224  if (shRec.HasLDF())
1225  grSignal->Draw("samep");
1226  if (grSatSignal)
1227  grSatSignal->Draw("samep");
1228  gPad->RedrawAxis();
1229 
1230  // Data
1231  canvas.cd(4);
1232  gPad->Range(0,0,1,1);
1233  TPaveText pt(0.1,0.1,0.9,0.9, "br");
1234  pt.SetFillColor(kWhite);
1235  pt.SetTextAlign(11);
1236  ostringstream info;
1237  //info << "Event: " << eventId;
1238  info << " \n"
1239  "Event: " << globalId << '\n';
1240  Point coreMC;
1241  double eastingMC = 0;
1242  double northingMC = 0;
1243  double thetaMC = 0;
1244  double phiMC = 0;
1245  double energyMC = 0;
1246  if (hasSimShower) {
1247  const ShowerSimData& simShower = event.GetSimShower();
1248  coreMC = simShower.GetPosition();
1249  const Vector axisMC = -simShower.GetDirection();
1250  const UTMPoint utmMCCore(coreMC, ReferenceEllipsoid::GetWGS84());
1251  phiMC = axisMC.GetPhi(siteCS);
1252  thetaMC = axisMC.GetTheta(siteCS);
1253  eastingMC = utmMCCore.GetEasting();
1254  northingMC = utmMCCore.GetNorthing();
1255  energyMC = simShower.GetEnergy();
1256  }
1257 
1258  const TimeStamp& eventTime = sHeader.GetTime();
1259  info << "Time: " << UTCDateTime(eventTime) << "\n"
1260  "GPS Time: " << eventTime.GetGPSSecond() << " s, "
1261  << eventTime.GetGPSNanoSecond() << " ns\n"
1262  "T4: " << GetT4TriggerName(shRec.GetT4Trigger())
1263  << " T5: " << GetT5TriggerName(shRec.GetT5Trigger());
1264  const int badId = shRec.GetBadPeriodId();
1265  if (badId)
1266  info << " BadPeriod: " << badId;
1267  info << "\nReconstruction stage: " << shRec.GetLDFRecStage() << '\n';
1268  const UTMPoint utmCore(core, ReferenceEllipsoid::GetWGS84());
1269  const Vector& coreError = shRec.GetCoreError();
1270  info << "Easting: " << setprecision(8) << utmCore.GetEasting()/meter << " #pm "
1271  << setprecision(3) << coreError.GetX(siteCS)/meter;
1272  if (hasSimShower)
1273  info << " (MC: " << setprecision(8) << eastingMC/meter << ')';
1274  info << " [m]\n"
1275  "Northing: " << setprecision(9) << utmCore.GetNorthing()/meter << " #pm "
1276  << setprecision(3) << coreError.GetY(siteCS)/meter;
1277  if (hasSimShower)
1278  info << " (MC: " << setprecision(8) << northingMC/meter << ')';
1279  info << " [m]\n";
1280  if (hasSimShower) {
1281  info << "Distance to MC core: " << setprecision(5) << (core - coreMC).GetMag()/meter
1282  << " [m]\n";
1283  }
1284  info << "#theta: " << setprecision(4) << axis.GetTheta(siteCS)/degree << " #pm "
1285  << setprecision(2) << shRec.GetThetaError()/degree;
1286  if (hasSimShower)
1287  info << " (MC: " << setprecision(4) << thetaMC/degree << ')';
1288  info << " [#circ] "
1289  "#phi: " << setprecision(5) << axis.GetPhi(siteCS)/degree << " #pm "
1290  << setprecision(2) << shRec.GetPhiError()/degree;
1291  if (hasSimShower)
1292  info << " (MC: " << setprecision(5) << phiMC/degree << ')';
1293  info << " [#circ]\n";
1294  if (curvature) {
1295  const double rc = 1/curvature;
1296  info << "R_{c}: " << setprecision(4) << rc/kilometer << " #pm "
1297  << setprecision(2) << shRec.GetCurvatureError()*rc*rc/kilometer << " [km]\n";
1298  }
1299  info << shRec.GetShowerSizeLabel() << ": " << setprecision(4) << shRec.GetShowerSize()
1300  << " #pm " << setprecision(2) << shRec.GetShowerSizeError()
1301  << " (#pm" << shRec.GetShowerSizeSystematics() << " sys)";
1302  const double rOpt = shRec.GetLDFOptimumDistance();
1303  if (rOpt)
1304  info << " r_{opt}: " << setprecision(5) << rOpt << " [m]";
1305  info << "\n#beta: " << setprecision(4) << shRec.GetBeta()
1306  << " #pm " << setprecision(2) << shRec.GetBetaError()
1307  << " (#pm" << shRec.GetBetaSystematics() << " sys)\n";
1308  info << "Energy: " << setprecision(4) << shRec.GetEnergy()/EeV << " #pm "
1309  << setprecision(2) << shRec.GetEnergyError()/EeV;
1310  if (hasSimShower)
1311  info << " (MC: " << setprecision(4) << energyMC/EeV << ')';
1312  info << " [EeV]\n ";
1313  AddText(pt, info.str());
1314  pt.Draw();
1315 
1316  canvas.Update();
1317  if (fGeneratePDFFile) {
1318  static string multipage = "(";
1319  canvas.Print((fPDFFileName + multipage).c_str(), "pdf");
1320  multipage = "";
1321  }
1322  if (fROOTFile) {
1323  SaveCurrentTDirectory save;
1324  fROOTFile->cd();
1325  canvas.Write();
1326  }
1327 }
struct Station * array
static const double kAspect
Class to access station level reconstructed data.
fwk::VModule::ResultFlag Finish() override
Finish: invoked at end of the run (NOT end of the event)
int GetT4Trigger() const
unsigned int GetNPoints() const
double GetCurvatureError() const
StationIterator StationsEnd()
End of all stations.
Definition: SEvent.h:59
const double degree
static const double kTwinIdSplit
Point object.
Definition: Point.h:32
double GetPhi(const CoordinateSystemPtr &coordinateSystem) const
azimuth (phi) angle in spherical and cylindrical coordinates
Definition: BasicVector.h:254
double GetCurvature() const
gaussian curvature = 1 / Rc
Detector description interface for Station-related data.
void CalculateLimits(const double zoom=1)
vector< TEllipse * > fCircles
Interface class to access to the SD Reconstruction of a Shower.
void PushStation(const double x, const double y, const double r, const int groupSize)
bool HasRecShower() const
const utl::TabulatedFunctionErrors & GetLDF() const
fwk::VModule::ResultFlag Run(evt::Event &event) override
Run: invoked once per event.
Interface class to access to the SD part of an event.
Definition: SEvent.h:39
double GetBetaError() const
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
Definition: BasicVector.h:248
Class to hold and convert a point in geodetic coordinates.
Definition: UTMPoint.h:40
ShowerRecData & GetRecShower()
void SetLimits(const double minX, const double maxX, const double minY, const double maxY, const double maxR)
const double meter
Definition: GalacticUnits.h:29
const utl::Vector & GetCoreError() const
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
int GetId() const
Definition: SEvent/Header.h:20
double GetShowerSize() const
Header file holding the SD Event Trigger class definition.
Definition: SEvent/Header.h:16
static const double kStationMinRadius
TGraphBentErrors * GetSaturatedLDFGraph()
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
utl::CoordinateSystemPtr GetSiteCoordinateSystem() const
Get the coordinate system for the site.
Definition: Detector.h:137
const double EeV
Definition: GalacticUnits.h:34
double GetNorthing() const
Get the northing.
Definition: UTMPoint.h:206
void PushStation(const int id, const double x, const double y, const double r, const double sig, const double t, const int groupSize)
double GetEnergyError() const
const std::vector< int > & GetReconstructionSeed() const
const double high[npar]
Definition: UnivRec.h:78
double GetBetaSystematics() const
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
string GetT5TriggerName(const int t5)
static const double kTwinSplit
utl::Point GetPosition() const
Tank position.
const utl::TimeStamp & GetTime() const
Definition: SEvent/Header.h:19
void DrawEvent(const evt::Event &event)
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
vector< double > fPositionY
double GetBeta() const
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
static const double kMinDX
#define max(a, b)
Class representing a document branch.
Definition: Branch.h:107
const double & GetYErr(const unsigned int idx) const
void AddText(TPaveText &pt, const string &str)
constexpr double s
Definition: AugerUnits.h:163
const utl::Vector & GetDirection() const
Get the direction of the shower axis. This is the true direction of shower movement.
utl::TimeStamp GetSignalStartTime() const
Start time of the signal.
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
constexpr double nanosecond
Definition: AugerUnits.h:143
const utl::TimeStamp & GetCoreTime() const
time when shower front passes through the core point
double GetTotalSignal() const
Total integrated signal in VEM unit, averaged over pmts.
void PushStation(const int id, const double x, const double y, const double r, const double sig, const double tCurv, const double t0, const double sigma_t, const double t10, const double t50, const double t90, const int groupSize, const int saturation, const bool tot)
const utl::Point & GetPosition() const
Get the position of the shower core.
Top of the hierarchy of the detector description interface.
Definition: Detector.h:81
const sdet::SDetector & GetSDetector() const
Definition: Detector.cc:119
unsigned int GetSignalStartSlot() const
Start time of the signal in time slots from beginning of trace.
double GetEasting() const
Get the easting.
Definition: UTMPoint.h:209
double GetLDFRecStage() const
static const double kLDFMinR
double GetThetaError() const
double GetEnergy() const
Get the energy of the shower primary particle.
Definition: ShowerSimData.h:89
const utl::Vector & GetAxis() const
double GetPhiError() const
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
unsigned int GetSignalEndSlot() const
End time of the signal in time slots from beginning of trace.
void SetLimits(const double minX, const double maxX, const double minY, const double maxY, const double maxR, const double maxSignal)
vector< TEllipse * > fCircles
vector< TEllipse * > fCircles
const double & GetY(const unsigned int idx) const
double GetEnergy() const
static const double kLowGainSatFactor
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:209
constexpr double kSpeedOfLight
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
const double low[npar]
Definition: UnivRec.h:77
double GetLDFOptimumDistance() const
unsigned long GetGPSSecond() const
GPS second.
Definition: TimeStamp.h:124
const char * GetShowerSizeLabel() const
int GetT5Trigger() const
double GetGPSNanoSecond() const
GPS nanosecond.
Definition: TimeStamp.h:127
StationIterator StationsBegin()
Beginning of all stations.
Definition: SEvent.h:57
constexpr double kilometer
Definition: AugerUnits.h:93
Vector object.
Definition: Vector.h:30
const double & GetX(const unsigned int idx) const
Detector description interface for SDetector-related data.
Definition: SDetector.h:42
double GetShowerSizeError() const
const utl::Point & GetCorePosition() const
sevt::Header & GetHeader()
Definition: SEvent.h:155
Main configuration utility.
Definition: CentralConfig.h:51
bool HasLDF() const
vector< double > fPositionX
string GetT4TriggerName(const int t4)
Definition: SdRecPlotter.cc:84
double RPerp(const Vector &axis, const Vector &station)
Definition: SdRecPlotter.cc:75
TGraphBentErrors * GetRiseFallTimeGraph()
const Station & GetStation(const int stationId) const
Get station by Station Id.
Definition: SDetector.cc:192
double Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
boost::indirect_iterator< InternalConstStationIterator, const Station & > ConstStationIterator
Definition: SEvent.h:54
int GetNumberOfPartners() const
Number of partners the station has.
bool HasSRecShower() const
double GetShowerSizeSystematics() const
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
static const double kStationMaxRadius
vector< double > fStartTimeErr
fwk::VModule::ResultFlag Init() override
Initialize: invoked at beginning of run (NOT beginning of event)
static double kSilentThreshold
int GetBadPeriodId() const
double GetTimeSigma2(const double signal, const double t50, const double cosTheta, const double distance=0) const

, generated on Tue Sep 26 2023.