FdSimEventChecker.cc
Go to the documentation of this file.
1 #include "FdSimEventChecker.h"
2 
3 #include <utl/ErrorLogger.h>
4 #include <utl/RandomEngine.h>
5 
6 #include <det/Detector.h>
7 
8 #include <fdet/Eye.h>
9 #include <fdet/FDetector.h>
10 #include <fdet/Telescope.h>
11 
12 #include <atm/InclinedAtmosphericProfile.h>
13 #include <atm/ProfileResult.h>
14 
15 #include <utl/TimeStamp.h>
16 #include <utl/Reader.h>
17 
18 #include <evt/Event.h>
19 #include <evt/ShowerSimData.h>
20 
21 #include <fevt/FEvent.h>
22 #include <fevt/Header.h>
23 #include <fevt/Eye.h>
24 #include <fevt/Telescope.h>
25 #include <fevt/EyeHeader.h>
26 
27 #include <fwk/CentralConfig.h>
28 #include <fwk/RunController.h>
29 #include <fwk/RandomEngineRegistry.h>
30 #include <fwk/LocalCoordinateSystem.h>
31 #include <fwk/CoordinateSystemRegistry.h>
32 
33 #include <utl/UTMPoint.h>
34 
35 #include <CLHEP/Random/Randomize.h>
36 
37 #include <iostream>
38 
39 #include <TH2.h>
40 #include <TFile.h>
41 
42 // #define DEBUGTHIS
43 
44 #ifdef DEBUGTHIS
45 # include <TH2D.h>
46 #endif
47 
48 using CLHEP::RandFlat;
49 
50 using namespace det;
51 using namespace evt;
52 using namespace fdet;
53 using namespace std;
54 using namespace utl;
55 using namespace fwk;
56 using namespace FdSimEventCheckerOG;
57 
58 
61 {
62  // get data cards
63 
64  CentralConfig* const cc = CentralConfig::GetInstance();
65  Branch topB = cc->GetTopBranch("FdSimEventChecker");
66 
67  if (!topB) {
68  ERROR("Could not find branch FdSimEventChecker");
69  return eFailure;
70  }
71 
72  fVerbosity = 0;
73  if (topB.GetChild("verbosity"))
74  topB.GetChild("verbosity").GetData(fVerbosity);
75 
76  // laser deselection flags
77  topB.GetChild("upTime").GetData(fUpTimeCheck);
78  topB.GetChild("geometry").GetData(fGeometryCheck);
79  topB.GetChild("geometryCherenkovHEAT").GetData(fGeometryCheckCherenkoHEAT);
80  topB.GetChild("geometryCherenkovHECO").GetData(fGeometryCheckCherenkoHECO);
81  topB.GetChild("fastSkip").GetData(fFastSkip);
82  topB.GetChild("fastRepeat").GetData(fFastRepeat);
83  topB.GetChild("useCDAS").GetData(fUseCDAS);
84 
85  hMaxVA = NULL;
86  if (fGeometryCheckCherenkoHECO && topB.GetChild("maxVAfileHECO")) {
87  string f;
88  topB.GetChild("maxVAfileHECO").GetData(f);
89  TFile* f_eff = new TFile(f.c_str());
90  hMaxVA = (TH2D*)f_eff->Get("hMaxVA");
91  hMaxVA->SetDirectory(0);
92  f_eff->Close();
93  }
94 
95  fMinViewingAngle = 1e10; // large number -> no cut
96  if (topB.GetChild("minViewingAngle"))
97  topB.GetChild("minViewingAngle").GetData(fMinViewingAngle);
98 
99  fRandomEngine = &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector);
100 
101 
102  // -------- do some output ------------
103  ostringstream info;
104  info << " Version: "
105  << GetVersionInfo(VModule::eRevisionNumber) << "\n"
106  " Parameters:\n";
107  info << " -- shower mode -- \n"
108  " up-time check: " << fUpTimeCheck << "\n"
109  " geometry check (std FD): " << fGeometryCheck << "\n"
110  "geometry check (PCGF, HEAT): " << fGeometryCheckCherenkoHEAT << "\n"
111  "geometry check (PCGF, HECO): " << fGeometryCheckCherenkoHECO << "\n"
112  " fastSkip: " << fFastSkip << " (to issue eBreakLoop) \n"
113  " fastRepeat: " << fFastRepeat << " (to issue eContinueLoop) \n"
114  " useCDAS: " << fUseCDAS << "\n";
115  if (fMinViewingAngle<180*degree) {
116  info << " viewing angle cut: " << fMinViewingAngle/degree << " deg\n";
117  }
118  INFO(info);
119 
120  if (fFastSkip && fFastRepeat) {
121  ERROR("It is not possible to isse at the same time eBreakLoop and eContinueLoop. Fix xml configuration.");
122  return eFailure;
123  }
124 
125 #ifdef DEBUGTHIS
126  int nE = 1000;
127  int nD = 1000;
128  TH2D* hDebug = new TH2D("debug", "threshold;lgE;dist/m", nE, 14.5, 17.5, nD, 0, 12000);
129  for (int i=0; i<nE; ++i) {
130  for (int j=0; j<nD; ++j) {
131  double lgE = 14.5 + (17.5-14.5) / (nE-1) * i;
132  double dist = 0. + 12000. / (nD-1) * j;
133  hDebug->Fill(lgE, dist, InterpolatePCGFAcceptanceMap(lgE, dist));
134  }
135  }
136  hDebug->SaveAs("debug.root");
137 #endif
138 
139 
140  return eSuccess;
141 }
142 
143 
145 FdSimEventChecker::Run(Event& event)
146 {
147  if (!event.HasFEvent())
148  return eContinueLoop;
149 
150  if (!event.HasSimShower()) {
151  ERROR ("Event has no simulated shower.");
152  return eFailure;
153  }
154 
155  evt::ShowerSimData& simShower = event.GetSimShower();
156  const CoordinateSystemPtr showerCS = simShower.GetShowerCoordinateSystem();
157  Point showerPos(0, 0, 0, showerCS);
158  Vector showerAxis(0, 0, -1, showerCS);
159 
160  bool simAny = false;
161  bool skipAny = false;
162  bool minViewingAngleRejected = false;
163 
164  // check if we run laser simulation
165  // -> no geometry cutting !!!
166  bool isLaser = simShower.HasLaserData();
167  if (isLaser) {
168  WARNING("Running in Laser simulation mode. Skipping geometry cuts.");
169  }
170 
171  Detector& detector = Detector::GetInstance();
172  const FDetector& detFD = detector.GetFDetector();
173 
174  if (fVerbosity >= 1) {
175  DumpDB();
176  }
177 
178  // --------------------------------------------------------------
179  // up time check
180  if (fUpTimeCheck && fUseCDAS) {
181 
182  double cdasUpTimeFraction = detFD.GetCDASUpTimeFraction();
183  int cdasDaqStatus = detFD.GetCDASDAQStatus();
184  double r = RandFlat::shoot(&fRandomEngine->GetEngine(), 0.0, 1.0);
185 
186  if (cdasDaqStatus == 0)
187  cdasUpTimeFraction = 0;
188 
189  if (r > cdasUpTimeFraction) {
190  ostringstream info;
191  info << "Skipping event beacuse of CDAS up time cdasTimeFraction=" << cdasUpTimeFraction;
192  INFO(info);
193  skipAny = true;
194  }
195  }
196 
197  if (!skipAny) { // check for CDAS veto
198 
199  for (FDetector::EyeIterator iEye = detFD.EyesBegin() ;
200  iEye != detFD.EyesEnd() ; ++iEye){
201 
202  const unsigned int eyeId = iEye->GetId();
203 
204  // --------------------------------------------------------------
205  // up time check
206  if (fUpTimeCheck) {
207  double eyeUpTimeFraction = iEye->GetUpTimeFraction();
208  int eyeDaqStatus = iEye->GetDAQStatus();
209  double fdasVetoFraction = iEye->GetFDASVetoFraction();
210  double cdasVetoFraction = fUseCDAS ? iEye->GetCDASVetoFraction() : 1.;
211  double r = RandFlat::shoot(&fRandomEngine->GetEngine(), 0.0, 1.0);
212 
213  if (eyeDaqStatus == 0)
214  eyeUpTimeFraction = 0;
215 
216  if (r > eyeUpTimeFraction*fdasVetoFraction*cdasVetoFraction) {
217  ostringstream info;
218  info << "Skipping eye=" << eyeId << " because of upTimeFraction *fdasVetoFraction * cdasVetoFraction =" << eyeUpTimeFraction*fdasVetoFraction*cdasVetoFraction;
219  INFO(info);
220  skipAny = true;
221  continue;
222  }
223  }
224 
225  if (!event.GetFEvent().HasEye(eyeId, fevt::ComponentSelector::eExists)) {
226  ERROR("EYE missing!");
227  }
228  fevt::Eye& eyeEvent = event.GetFEvent().GetEye(eyeId, fevt::ComponentSelector::eExists);
230 
231  // --------------------------------------------------------------
232  // geometry check
233  bool geometryRejected = false;
234  if (fGeometryCheck && !isLaser) {
235 
236  const Point eyePosition = iEye->GetPosition();
237  const double dist = (showerPos - eyePosition).GetMag();
238 
239  const double lgE = log10(simShower.GetEnergy()/eV);
240  const double Rcut = Rcutoff(lgE);
241 
242  if (dist > Rcut) {
243 
244  ostringstream info;
245  info << "Skipping eye=" << eyeId
246  << " because of geometry cut (distance=" << dist/km << "km > R_cut=" << Rcut/km << "km)";
247  INFO(info);
248 
249  geometryRejected = true;
250  skipAny = true;
252  }
253  }
254 
255  if (fGeometryCheckCherenkoHEAT && !isLaser) {
256 
257  const Point eyePosition = iEye->GetPosition();
258  const double dist = (showerPos - eyePosition).GetMag();
259 
260  const double lgE = log10(simShower.GetEnergy()/eV);
261  const double XmaxAngle = CalculateXmaxViewingAngle(*iEye, simShower);
262  const bool cut = PCGFTriggerProbabilityCut(lgE, dist, XmaxAngle);
263 
264  if (cut) {
265  ostringstream info;
266  info << "Skipping eye=" << eyeId
267  << " because of PCGF HEAT geometry cut (distance=" << dist/km << "km, lgE=" << lgE << ", angle=" << XmaxAngle/deg << "deg)";
268  INFO(info);
269 
270  geometryRejected = true;
271  skipAny = true;
273  }
274  }
275 
276  if (fGeometryCheckCherenkoHECO && !isLaser) {
277 
278  const Point HEPosition = detFD.GetEye(5).GetPosition();
279  const Point COPosition = detFD.GetEye(4).GetPosition();
280  const double distHE = (showerPos - HEPosition).GetMag();
281  const double distCO = (showerPos - COPosition).GetMag();
282 
283  const double lgE = log10(simShower.GetEnergy()/eV);
284  const double XmaxAngleHE = CalculateXmaxViewingAngle(detFD.GetEye(5), simShower);
285  const double XmaxAngleCO = CalculateXmaxViewingAngle(detFD.GetEye(4), simShower);
286  const bool cutHE = PCGFTriggerProbabilityCutHECO(lgE, distHE, XmaxAngleHE);
287  const bool cutCO = PCGFTriggerProbabilityCutHECO(lgE, distCO, XmaxAngleCO);
288  const bool cut = cutHE || cutCO;
289 
290  if (cut) {
291  ostringstream info;
292  info << "Skipping eye=" << eyeId
293  << " because of PCGF HECO geometry cut (distHE=" << distHE/km << "km, distCO=" << distCO/km << "km, lgE=" << lgE
294  << ", angleHE=" << XmaxAngleHE/deg << "deg, angleCO=" << XmaxAngleCO/deg << "deg)";
295  INFO(info);
296 
297  geometryRejected = true;
298  skipAny = true;
300  }
301  }
302 
303  // Only telescopes with status eInDAQ in the FEvent HERE will be considered by any Modules
304  // further donwstream in the sequence !
305  for (fdet::Eye::TelescopeIterator iTel = iEye->TelescopesBegin();
306  iTel != iEye->TelescopesEnd(); ++iTel) {
307 
308  const unsigned int telId = iTel->GetId();
309 
310  // --------------------------------------------------------------
311  // up time check
312  if (fUpTimeCheck) {
313 
314  double telUpTimeFraction = iTel->GetUpTimeFraction();
315  int telDaqStatus = iTel->GetDAQStatus();
316  double r = RandFlat::shoot(&fRandomEngine->GetEngine(), 0.0, 1.0);
317 
318  if (telDaqStatus == 0)
319  telUpTimeFraction = 0;
320 
321  if (r > telUpTimeFraction) {
322  ostringstream info;
323  info << "Skipping eye=" << eyeId << " tel=" << telId
324  << " because of upTimeFraction=" << telUpTimeFraction;
325  INFO(info);
326  skipAny = true;
327  continue;
328  }
329  }
330  // --------------------------------------------------------------
331  // Min Angle check
332  if (fMinViewingAngle < 180*deg) {
333  if (CalculateMinViewingAngle(*iTel, simShower)>fMinViewingAngle) {
334  minViewingAngleRejected = true;
335  skipAny = true;
336  continue;
337  }
338  }
339 
340  if (!eyeEvent.HasTelescope(telId, fevt::ComponentSelector::eExists)) {
341  ERROR("Telescope does not exists");
342  }
345 
346  ostringstream pointing;
347  pointing << "sim: " << iTel->GetTelescopePointingId();
348  tel.SetRawTelPointing(pointing.str());
349 
350  if (!geometryRejected) {
351  simAny = true;
352  }
353  } // loop tel
354  } // loop eyes
355  } // if not CDAS veto
356 
357  if (minViewingAngleRejected) {
358  ++RunController::GetInstance().GetRunData().GetNamedCounters()["FdSimEventChecker/rejectedDueToMinViewingAngle"];
359  INFO("At least one telescope was rejected because of minimum viewing angle cut.");
360  }
361 
362  if (!simAny) {
363  INFO("No telescopes/eyes left for simulation.");
364  }
365 
366  if (skipAny) {
367  ++RunController::GetInstance().GetRunData().GetNamedCounters()["FdSimEventChecker/eventsWithSkippedTelescopes"];
368  INFO("Some telescopes/eyes have been removed from DAQ.");
369  }
370 
371  if (!simAny) {
372  ++RunController::GetInstance().GetRunData().GetNamedCounters()["FdSimEventChecker/NoFdSim"];
373  if (fFastSkip)
374  return eBreakLoop; // Break the sim "loop=1". Don't waste time.
375  if (fFastRepeat)
376  return eContinueLoop; // sample next geometry in the sim loop
377  }
378 
379  /* if (fMinViewingAngle<180*deg) {
380  const CoordinateSystemPtr referenceCS = det::Detector::GetInstance().GetReferenceCoordinateSystem();
381  const CoordinateSystemPtr localCS = simShower.GetLocalCoordinateSystem();
382  utl::Point core = simShower.GetPosition();
383  const double E = simShower.GetEnergy()/giga;// convert to Gev
384  const double Zenith = (-simShower.GetDirection()).GetTheta(localCS)/degree; // converted to degree
385  const double Azimuth = (-simShower.GetDirection()).GetPhi(localCS)/degree; // degree
386  const double core_X= core.GetX(referenceCS)/centi ; // converted to cm
387  const double core_Y= core.GetY(referenceCS)/centi ; // cm
388 
389  ofstream outfile;
390  outfile.open ("FedToCORSIKA.txt", std::ios_base::app);
391  outfile << E << " " << Zenith <<" "<< Azimuth << " "<< core_X << " " << core_Y << " "<< endl;
392  INFO(" Sim E(GeV) , zenith(deg) ,azimuth(deg) and shower core(cm) wrote to text file to fed to CORSIKA ");
393  outfile.close();
394  }
395  */
396 
397  return eSuccess;
398 }
399 
400 
402 FdSimEventChecker::Finish()
403 {
404  return eSuccess;
405 }
406 
407 
408 void
409 FdSimEventChecker::DumpDB()
410  const
411 {
412  cout << " ************** dumpDB ************* " << endl;
413 
414  Detector& detector = Detector::GetInstance();
415  const FDetector& detFD = detector.GetFDetector();
416 
417  cout << " ******* time = " << detector.GetTime() << " ********* " << endl;
418  cout << " ******* GPS = " << detector.GetTime().GetGPSSecond() << " ********* " << endl;
419 
420  double cdasUpTimeFraction = detFD.GetCDASUpTimeFraction();
421  int cdasDaqStatus = detFD.GetCDASDAQStatus();
422 
423  cout << " CDAS uptime : " << cdasUpTimeFraction
424  << " status: " << cdasDaqStatus << endl;
425 
426  for (FDetector::EyeIterator iEye = detFD.EyesBegin() ;
427  iEye != detFD.EyesEnd() ; ++iEye){
428 
429  unsigned int eyeId = iEye->GetId();
430 
431  double eyeUpTimeFraction = iEye->GetUpTimeFraction();
432  int eyeDaqStatus = iEye->GetDAQStatus();
433 
434  cout << " eye id=" << eyeId
435  << " uptime: " << eyeUpTimeFraction
436  << " status: " << eyeDaqStatus << endl;
437 
438  for (fdet::Eye::TelescopeIterator iTel = iEye->TelescopesBegin();
439  iTel != iEye->TelescopesEnd(); ++iTel) {
440 
441  unsigned int telId = iTel->GetId();
442 
443  double telUpTimeFraction = iTel->GetUpTimeFraction();
444  int telDaqStatus = iTel->GetDAQStatus();
445 
446  cout << " tel id=" << telId
447  << " uptime: " << telUpTimeFraction
448  << " status: " << telDaqStatus << endl;
449 
450  } // loop tel
451 
452  } // loop eyes
453 
454 }
455 
456 
457 double
458 FdSimEventChecker::Rcutoff(const double lgE)
459  const
460 {
461  const double x = fmax(16.5, fmin(21., lgE));
462 
463  const double p1 = 4.86267e+05;
464  const double p2 = -6.72442e+04;
465  const double p3 = 2.31169e+03;
466 
467  return p1 + p2*x + p3*x*x;
468 }
469 
470 //similar to what is done for HEAT only PCGF - TH2D used explicitely, HE+CO was used in simulations to make this
471 //TLT trigger probability = 1e-4 defines the max allowed VA
472 bool
473 FdSimEventChecker::PCGFTriggerProbabilityCutHECO(const double lgE, const double dist, const double angle)
474  const
475 {
476  if (hMaxVA == NULL)
477  return angle > 20*degree;
478  int binLogE = 0;
479  int binDist = 0;
480  int dz = 0;
481  hMaxVA->GetBinXYZ(hMaxVA->FindBin(lgE, dist), binLogE, binDist, dz);
482  if (binLogE < 1 || binLogE > hMaxVA->GetNbinsX() || binDist < 1 || binDist > hMaxVA->GetNbinsY())
483  return false;
484  const double thresholdAngle = hMaxVA->GetBinContent(binLogE, binDist) * degree;
485  return angle > thresholdAngle; // true: cut, false : no cut
486 }
487 
488 
489 bool
490 FdSimEventChecker::PCGFTriggerProbabilityCut(const double lgE, const double dist, const double angle)
491  const
492 {
493  const double thresholdAngle = InterpolatePCGFAcceptanceMap(lgE, dist) * degree;
494  return angle > thresholdAngle; // true: cut, false : no cut
495 }
496 
497 /*
498  The acceptance map is a 2D histogram binned in lgE and distance/m
499  around HEAT, specifying the "Xmax viewing angle" (angle between line
500  of sight from HEAT to Xmax wrt. to shower axis) above which the
501  (Cherenkov) trigger threshold drops below 0.001.
502  */
503 double
504 FdSimEventChecker::InterpolatePCGFAcceptanceMap(const double lgE, const double dist)
505  const
506 {
507  // this cut is based on 6M CONEX simulations. Please excuse the ASCII dump of a TH2D...
508  // the cut is only effective inside the margins of the study: lgE=15...17 and dist=0...10km
509  const int nEbins = 5;
510  const double lgEmin = 15;
511  const double lgEmax = 17;
512  const int nDbins = 12;
513  const double dmin = 0;
514  const double dmax = 10000;
515 
516  // bin content in order: iebin + idbin * Nebins
517 
518  const double angleMax[60] = {
519  17.5674
520  ,63.6736
521  ,47.1347
522  ,100
523  ,100
524  ,21.0435
525  ,54.6757
526  ,84.3739
527  ,100
528  ,100
529  ,0
530  ,33.0216
531  ,66.2782
532  ,100
533  ,100
534  ,0
535  ,21.6176
536  ,42.0684
537  ,80.9825
538  ,43.8473
539  ,0
540  ,0
541  ,32.9672
542  ,61.9826
543  ,33.5471
544  ,0
545  ,0
546  ,0
547  ,40.9694
548  ,6.69125
549  ,0
550  ,0
551  ,0
552  ,0
553  ,5.98639
554  ,0
555  ,0
556  ,0
557  ,0
558  ,49.8777
559  ,0
560  ,0
561  ,0
562  ,0
563  ,0
564  ,0
565  ,0
566  ,0
567  ,0
568  ,0
569  ,0
570  ,0
571  ,0
572  ,0
573  ,0
574  ,0
575  ,0
576  ,0
577  ,0
578  ,0
579  };
580 
581  const double ebin = (lgE - lgEmin) / (lgEmax - lgEmin) * nEbins;
582  const double dbin = (dist/m - dmin) / (dmax - dmin) * nDbins;
583 
584  const int iebin = int(ebin); // x.0 ... x.999 -> x
585  const int idbin = int(dbin); // x.0 ... x.999 -> x
586 
587  if (iebin >= nEbins)
588  return 360; // no cut, high-e
589 
590  if (iebin < 0 || idbin < 0 || idbin >= nDbins)
591  return 0; // full cut: low-e, far away
592 
593  // linear interpolate in 2D, first in lgE, then in D
594 
595  const double dE = ebin - iebin; // 0...0.999
596  const double dD = dbin - idbin; // 0...0.999
597 
598  double vecTemp[nDbins]; // this is the vector in d-direction interpolated between two lgE bins
599  for (int idbin = 0; idbin < nDbins; ++idbin)
600  vecTemp[idbin] = angleMax[iebin + idbin * nEbins];
601 
602  if (dE < 0.5) { // dE = 0...0.5
603  if (iebin > 0) {
604  // towards lower lgE
605  for (int idbin = 0; idbin < nDbins; ++idbin)
606  vecTemp[idbin] += (dE-0.5) * (angleMax[iebin + idbin * nEbins] - angleMax[iebin-1 + idbin * nEbins]);
607  }
608  } else { // dE = 0.5..0.999
609  // towards higher lgE
610  if (iebin < nEbins-1) {
611  for (int idbin = 0; idbin < nDbins; ++idbin)
612  vecTemp[idbin] += (dE-0.5) * (angleMax[iebin+1 + idbin * nEbins] - angleMax[iebin + idbin * nEbins]);
613  }
614  }
615 
616  double result = vecTemp[idbin];
617 
618  if (dD < 0.5) { // dD = 0...0.5
619  if (idbin > 0) {
620  // towards lower D
621  result += (dD-0.5) * (vecTemp[idbin] - vecTemp[idbin-1]);
622  }
623  } else { // dD = 0.5...0.99
624  if (idbin < nDbins-1) {
625  // towards higher D
626  result += (dD-0.5) * (vecTemp[idbin+1] - vecTemp[idbin]);
627  }
628  }
629  return result;
630 }
631 
632 
633 double
634 FdSimEventChecker::CalculateMinViewingAngle(const fdet::Telescope& tel,
635  const evt::ShowerSimData& shower)
636  const
637 {
638  utl::Vector telescope_axis = tel.GetAxis();
639  utl::Vector shower_axis = shower.GetDirection();
640  utl::Point shower_core = shower.GetPosition();
641  utl::Point Eye_pos = tel.GetPosition();
642 
643  // CHECK LightAtDiaphragmSimulator FieldOfViewChecker to be smarter !!!
644 
645  double theMinAngle = 1e20;
646  const int nBins = 20000;
647  for (int i = 0; i < nBins; ++i) {
648 
649  double length = 20.0*meter * (i - nBins/2);
650 
651  utl::Point pSh = shower_core + length * shower_axis;
652 
653  utl::Vector view = pSh - Eye_pos;
654 
655  double theAngleFOV = acos(view*telescope_axis/view.GetMag());
656 
657  if (theAngleFOV>tel.GetCamera().GetFieldOfView()) // 23.07 degree by default
658  continue;
659 
660  theMinAngle = min(theMinAngle, (acos(shower_axis*view/view.GetMag())));
661  } // along shower axis
662 
663  return theMinAngle;
664 }
665 
666 
667 double
668 FdSimEventChecker::CalculateXmaxViewingAngle(const fdet::Eye& eye,
669  const evt::ShowerSimData& shower) const
670 {
671  utl::Point eyePos = eye.GetPosition();
673 
674  const Point& showerCore = shower.GetPosition();
675  // const TimeStamp& timeAtCore = shower.GetTimeStamp();
676  const Vector& showerAxisReal = shower.GetDirection(); // REAL SHOWER MOVEMENT
677  Vector showerAxis = showerAxisReal;
678  bool upward = true;
679  if (showerAxis.GetTheta(localCS)>90.*deg) {
680  showerAxis *= -1; // reco-def (ALWAYS POINTING UPWARDS)
681  upward = false;
682  }
683 
684  const Vector eyeToCore = showerCore-eyePos;
685  Vector sdp = cross(showerAxis, eyeToCore);
686  // const double rp = sdp.GetMag() * (upward ? -1 : 1);
687  sdp.Normalize();
688 
689  const Vector vertical(0, 0, 1, localCS);
690  utl::Vector horizontalInSDP = cross(sdp, vertical);
691  horizontalInSDP.Normalize();
692 
693  const double chi0 = Angle(horizontalInSDP, showerAxis) - (upward ? 180.*deg : 0.*deg);
694 
695  if (shower.HasGHParameters()) {
696 
697  const double XmaxSim = shower.GetGHParameters().GetXMax();
698 
699  double XmaxChi = 0;
700  //double
701  //otoa::fd::ConvertXToChi(const double x, const fdet::Telescope& detTel,
702  //const Point& core, const Vector& axis, const Vector& sdp)
703  {
705 
706  try {
707  const double deltaX = 10.*g/cm2;
708  atm::InclinedAtmosphericProfile incModel(showerCore, showerAxis, deltaX);
709 
710  // use the inclined atmosphere model
711  const atm::ProfileResult& distVsSlantDepth = incModel.EvaluateDistanceVsSlantDepth();
712  //const ProfileResult &heightVsSlantDepth = incModel.EvaluateHeightVsSlantDepth();
713 
714  double distance = 0;
715  if (distVsSlantDepth.MinX() < XmaxSim && XmaxSim < distVsSlantDepth.MaxX())
716  distance = -distVsSlantDepth.Y(XmaxSim); // DEF: p = core + distance * axis
717 
718  // const utl::Point& telPos = detTel.GetPosition();
719  const utl::Point& xPoint = showerCore + distance*showerAxis;
720 
721  //CoordinateSystemPtr localCS = fwk::LocalCoordinateSystem::Create(telPos);
722  // Note that the following is wrong for telescopes:
723  //const CoordinateSystemPtr localCS = detTel.GetTelescopeeCoordinateSystem();
724  const Vector vertical(0, 0, 1, localCS);
725  const Vector horizontal = cross(sdp, vertical);
726 
727  XmaxChi = Angle((xPoint-eyePos), horizontal);
728 
729  //return angle;
731  } catch (OutOfBoundException& e) {
732  }
733 
734  //return 0;
735  }
736 
737  return chi0 - XmaxChi;
738  }
739 
740  return -1;
741 }
AxialVector cross(const Vector &l, const Vector &r)
vector cross product
Definition: OperationsAV.h:32
Telescope & GetTelescope(const unsigned int telescopeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
Retrieve Telescope by Id, throw exception if not existent.
Definition: FEvent/Eye.cc:57
const double eV
Definition: GalacticUnits.h:35
void Normalize()
Definition: Vector.h:64
const double degree
Point object.
Definition: Point.h:32
bool HasLaserData() const
Check initialization of the LaserData.
double Angle(const double theta1, const double phi1, const double theta2, const double phi2)
double GetFieldOfView() const
Fluorescence Detector Eye Event.
Definition: FEvent/Eye.h:29
const evt::VGaisserHillasParameter & GetGHParameters() const
Get the Gaisser-Hillas parameters of the shower.
void SetStatus(const ComponentSelector::Status status)
bool HasFEvent() const
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
Definition: BasicVector.h:248
utl::TimeStamp GetTime() const
Get time pertaining to the detector description.
Definition: Detector.h:134
bool HasSimShower() const
utl::Vector GetAxis() const
const double meter
Definition: GalacticUnits.h:29
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void Init()
Initialise the registry.
const Eye & GetEye(const unsigned int eyeId) const
Find eye by numerical Id.
Definition: FDetector.cc:68
EyeIterator EyesBegin(const FDetComponentSelector::Type type=FDetComponentSelector::ePhysical) const
iterator pointing to first eye of given type (ePhysical, eVirtual, eAll)
Definition: FDetector.h:72
Detector description interface for Eye-related data.
Definition: FDetector/Eye.h:45
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
static const ReferenceEllipsoid & Get(const EllipsoidID theID)
Get known ellipsoid by registered ID.
double GetMag() const
Definition: Vector.h:58
void SetStatus(const ComponentSelector::Status status)
Definition: FEvent/Eye.h:119
const Camera & GetCamera() const
Get the Camera object that belongs to the telescope.
Detector description interface for FDetector-related data.
Definition: FDetector.h:44
double Y(const double x) const
Get the Y value (coordinate) for given X (ordinate)
Exception for reporting variable out of valid range.
constexpr double deg
Definition: AugerUnits.h:140
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Class representing a document branch.
Definition: Branch.h:107
Reference ellipsoids for UTM transformations.
boost::filter_iterator< FDetComponentSelector, AllEyeIterator > EyeIterator
Definition: FDetector.h:69
const utl::Vector & GetDirection() const
Get the direction of the shower axis. This is the true direction of shower movement.
Class describing the Atmospheric profile.
Definition: ProfileResult.h:25
const Data result[]
const utl::Point & GetPosition() const
Get the position of the shower core.
double GetCDASUpTimeFraction() const
Definition: FDetector.cc:235
Top of the hierarchy of the detector description interface.
Definition: Detector.h:81
const fdet::FDetector & GetFDetector() const
Definition: Detector.cc:131
const double km
constexpr double g
Definition: AugerUnits.h:200
void SetRawTelPointing(const std::string &pointing)
double GetEnergy() const
Get the energy of the shower primary particle.
Definition: ShowerSimData.h:89
#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
Provides translational services for inclined profile.
boost::filter_iterator< TelIsCommissioned, InternalConstTelescopeIterator > TelescopeIterator
An iterator over telescopes.
Definition: FDetector/Eye.h:76
fevt::FEvent & GetFEvent()
bool HasEye(const unsigned int eyeId, const ComponentSelector::Status status=ComponentSelector::eHasData) const
Definition: FEvent.cc:57
Detector description interface for Telescope-related data.
double MinX() const
Return the minimum value for X (ordinate) stored in the profile.
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
unsigned long GetGPSSecond() const
GPS second.
Definition: TimeStamp.h:124
bool HasGHParameters() const
Check initialization of the Gaisser-Hillas parameters.
bool HasTelescope(const unsigned int telescopeId, const ComponentSelector::Status status=ComponentSelector::eHasData) const
Check if the telescope is in the event.
Definition: FEvent/Eye.cc:117
utl::Point GetPosition() const
execption handling for calculation/access for inclined atmosphere model
Vector object.
Definition: Vector.h:30
Main configuration utility.
Definition: CentralConfig.h:51
Fluorescence Detector Telescope Event.
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
const atm::ProfileResult & EvaluateDistanceVsSlantDepth() const
Table of distance as a function of slant depth.
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
int GetCDASDAQStatus() const
Definition: FDetector.cc:253
utl::Point GetPosition() const
Eye position.
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
utl::CoordinateSystemPtr GetShowerCoordinateSystem() const
double MaxX() const
Return the maximum value for X (ordinate) stored in the profile.
constexpr double cm2
Definition: AugerUnits.h:118
EyeIterator EyesEnd(const FDetComponentSelector::Type type=FDetComponentSelector::ePhysical) const
iterator pointing to end of available eyes of given type (ePhysical, eVirtual, eAll) ...
Definition: FDetector.h:76

, generated on Tue Sep 26 2023.