FieldOfViewCalculator.cc
Go to the documentation of this file.
1 #include <iomanip>
2 #include <algorithm>
3 #include <vector>
4 
5 #include <utl/Reader.h>
6 #include <utl/ErrorLogger.h>
7 #include <utl/AugerUnits.h>
8 #include <utl/AugerException.h>
9 #include <utl/MathConstants.h>
10 #include <utl/PhysicalConstants.h>
11 #include <utl/PhysicalFunctions.h>
12 #include <utl/Point.h>
13 #include <utl/Vector.h>
14 #include <utl/AxialVector.h>
15 #include <utl/TabulatedFunction.h>
16 #include <utl/TabulatedFunctionErrors.h>
17 #include <utl/UTMPoint.h>
18 #include <utl/ReferenceEllipsoid.h>
19 #include <utl/TransformationMatrix.h>
20 #include <utl/TimeStamp.h>
21 #include <utl/AugerCoordinateSystem.h>
22 
23 #include <utl/Particle.h>
24 
25 #include <evt/Event.h>
26 #include <evt/ShowerSimData.h>
27 #include <evt/LaserData.h>
28 
29 #include <fevt/FEvent.h>
30 #include <fevt/Eye.h>
31 #include <fevt/TelescopeSimData.h>
32 #include <fevt/Telescope.h>
33 
34 #include <fwk/CentralConfig.h>
35 #include <fwk/LocalCoordinateSystem.h>
36 
37 #include <det/Detector.h>
38 #include <fdet/FDetector.h>
39 #include <fdet/Eye.h>
40 #include <fdet/Telescope.h>
41 #include <fdet/Camera.h>
42 
43 #include <atm/AttenuationResult.h>
44 #include <atm/ScatteringResult.h>
45 #include <atm/Atmosphere.h>
46 #include <atm/ProfileResult.h>
47 
48 #include "FieldOfViewCalculator.h"
49 
50 #include <TH2D.h> // for debug
51 #include <TH1D.h> // for debug
52 #include <TCanvas.h>// for debug
53 #include <TGraph.h>// for debug
54 #include <TFile.h>// for debug
55 
56 using namespace std;
57 using namespace FieldOfViewCalculatorKG;
58 using namespace utl;
59 using namespace evt;
60 using namespace fwk;
61 using namespace det;
62 using namespace fdet;
63 using namespace atm;
64 
65 
68 {
69  Branch topB =
70  CentralConfig::GetInstance()->GetTopBranch("FieldOfViewCalculator");
71 
72  topB.GetChild("binning").GetData(fBinning);
73  topB.GetChild("maxAngleBinWidth").GetData(fMaxAngleBinWidth);
74 
75  // -------- do some output ------------
76  // info output
77  ostringstream info;
78  info << " Version: "
79  << GetVersionInfo(VModule::eRevisionNumber) << "\n"
80  " Parameters:\n"
81  " time binning: " << fBinning << " (relative to FADC sampling)" << "\n"
82  " min. angular step: "<< fMaxAngleBinWidth/deg << " deg \n ";
83  INFO(info);
84 
85  return eSuccess;
86 }
87 
88 
89 /*
90  find out the tMin and tMax for all telescopes (time from showerInitialPos to telescope)
91  (-> the position along the shower track, where it enters the FOV of a tel)
92  AND
93  initialize the photon - distance - traces
94 
95  INFO:
96 
97  The geometry is defined relative to the "core" location:
98  p = core + distance * axis"
99 
100  and not any more (as previously, before Di 7. Mär 10:14:57 CET 2017) as
101  p = showerInitialPos + distance * axis
102 */
103 
104 
106 FieldOfViewCalculator::Run(evt::Event& event)
107 {
108  if (!event.HasFEvent()) {
109  ERROR("Missing FEvent. Check your module configurations and ModuleSequence.");
110  return eFailure;
111  }
112  fevt::FEvent& FDevent = event.GetFEvent();
113 
114  if (!event.HasSimShower()) {
115  ERROR("Event has no simulated shower.");
116  return eFailure;
117  }
118  evt::ShowerSimData& simShower = event.GetSimShower();
119 
120  // Shower initial and final positions
121  const CoordinateSystemPtr showerCS = simShower.GetShowerCoordinateSystem();
122  const Point core(0, 0, 0, showerCS);
123  const Vector showerAxis(0, 0, -1, showerCS);
124 
125  //const ReferenceEllipsoid& wgs84 = ReferenceEllipsoid::GetWGS84();
126  //const double coreZ = wgs84.PointToLatitudeLongitudeHeight(core).get<2>();
127 
128  Detector& detector = Detector::GetInstance();
129  const Atmosphere& atmo = detector.GetAtmosphere();
130 
131  // --------------------------------------------------------------------------
132  // find the part of the shower, that was emitting light
133 
134  detector.GetAtmosphere().InitSlantProfileModel(core, -showerAxis, 10.*g/cm2);
135 
136  const ProfileResult& distanceVsSlantDepth = atmo.EvaluateDistanceVsSlantDepth();
137  double atmDepthMin = distanceVsSlantDepth.MinX();
138  double atmDepthMax = distanceVsSlantDepth.MaxX();
139  double distStart = distanceVsSlantDepth.Y(atmDepthMin);
140  double distStop = distanceVsSlantDepth.Y(atmDepthMax);
141 
142  // before injection there is no dE/dX profile
143  double profStartX = simShower.GetXInject();
144  double profStartDist = distanceVsSlantDepth.Y(profStartX);
145  if (profStartDist > distStart)
146  distStart = profStartDist;
147 
148 #if 1
149  {
150  // debug
151  const double distInitFinal = distStop - distStart;
152  ostringstream info;
153  info << "Shower geometry parameters: distance_start=" << distStart/km << " km, "
154  << " distance_stop=" << distStop/km << " km, "
155  << " length=" << distInitFinal/km << " km";
156  INFO(info);
157  }
158 #endif
159 
160  TimeStamp timeAtCore = simShower.GetTimeStamp();
161  const FDetector& detFD = detector.GetFDetector();
162  unsigned int sumAllBins = 0;
163 
164  for (FDetector::EyeIterator iEye = detFD.EyesBegin();
165  iEye != detFD.EyesEnd(); ++iEye) {
166 
167  const unsigned int eyeId = iEye->GetId();
168 
169  if (FDevent.HasEye(eyeId, fevt::ComponentSelector::eExists)) {
170  ERROR("EYE already there!!!!");
171  }
173  fevt::Eye& eyeEvent = FDevent.GetEye(eyeId, fevt::ComponentSelector::eExists);
174 
175  for (fdet::Eye::TelescopeIterator iTel = iEye->TelescopesBegin();
176  iTel != iEye->TelescopesEnd(); ++iTel) {
177 
178  const unsigned int telId = iTel->GetId();
179 
180  if (eyeEvent.HasTelescope(telId, fevt::ComponentSelector::eExists)) {
181  ERROR("TELESCOPE already there!!!!");
182  }
185 
186  /*
187  for (fevt::FEvent::EyeIterator iEye = fevent.EyesBegin(fevt::ComponentSelector::eInDAQ);
188  iEye != fevent.EyesEnd(fevt::ComponentSelector::eInDAQ) ; ++iEye) {
189 
190  if (iEye->GetStatus() == fevt::ComponentSelector::eDeSelected)
191  continue;
192 
193  for (fevt::Eye::TelescopeIterator iTel = eyeEvent.TelescopesBegin(fevt::ComponentSelector::eInDAQ);
194  iTel != eyeEvent.TelescopesEnd(fevt::ComponentSelector::eInDAQ); ++iTel) {
195 
196  fevt::Telescope& telEvent = *iTel;
197  unsigned int telId = telEvent.GetId();
198 
199  const fdet::Telescope& detTel = detFD.GetTelescope(telEvent);
200  */
201 
202  const fdet::Telescope& detTel = *iTel;
203  const Point telPosition = detTel.GetPosition();
204  const Vector d_initial = core - telPosition;
205 
206  ostringstream info;
207  info << "Eye=" << eyeId << " Tel=" << telId;
208 
209  if (!telEvent.HasSimData())
210  telEvent.MakeSimData();
211  fevt::TelescopeSimData& telSim = telEvent.GetSimData();
212 
213  const Vector axis = detTel.GetAxis();
214 
215  /*
216  Calculate tmin/tmax of shower in FOV of telescope
217  */
218 
219  const double b1 = std::pow(d_initial * axis, 2);
220  const double b2 = 2 * (d_initial * axis) * (axis * showerAxis);
221  const double b3 = std::pow(axis * showerAxis, 2);
222  const double a1 = d_initial * d_initial;
223  const double a2 = 2 * (d_initial * showerAxis);
224  const double a3 = 1; // == showerAxis * showerAxis;
225 
226  const double cosFOV = cos(detTel.GetCamera().GetFieldOfView());
227  const double cosFOV2 = cosFOV * cosFOV;
228 
229  const double A = cosFOV2 * a3 - b3;
230  const double B = cosFOV2 * a2 - b2;
231  const double C = cosFOV2 * a1 - b1;
232 
233  // quadratic equation gets complex ?
234  if (B*B - 4*A*C < 0) {
235  //info << " - not in field of view";
236  //INFO(info);
237  continue;
238  } // if quadratic equation is not solvable
239 
240  double distMin = (-B - sqrt(B*B - 4*A*C)) / (2*A);
241  double distMax = (-B + sqrt(B*B - 4*A*C)) / (2*A);
242 
243  /* **
244  cerr << "1: distMin " << setw (10) << distMin
245  << " distMax " << distMax
246  << " distGnd: " << distGround
247  << endl;
248  *** */
249 
250  // check order in time / distance
251  if (distMin > distMax)
252  swap(distMin, distMax);
253 
254  /* **
255  cerr << "2: distMin " << setw (10) << distMin
256  << " distMax " << distMax
257  << " distGnd: " << distGround
258  << endl;
259  *** */
260 
261  //const Point p1 = showerInitialPos + distMin*showerAxis;
262  //const Point p2 = showerInitialPos + distMax*showerAxis;
263  const Point pMin = core + distMin*showerAxis;
264  const Point pMax = core + distMax*showerAxis;
265 
266  // check for non-FOV shower parts
267  const bool invalidPointMin = ((pMin - telPosition)*axis < 0);
268  const bool invalidPointMax = ((pMax - telPosition)*axis < 0);
269 
270  if (invalidPointMin && invalidPointMax) { // --> (case 1)
271 
272  //info << " - not in field of view" ;
273  //INFO(info);
274  continue;
275 
276  } else if (invalidPointMax) { // --> (case 2)
277 
278  if (distMin > distStart) { // --> (case 2a)
279 
280  distMax = distMin;
281  distMin = distStart;
282 
283  } else { // --> (case 2b)
284 
285  //info << " - not in field of view";
286  //INFO(info);
287  continue;
288 
289  }
290 
291  } else if (invalidPointMin) { // --> (case 3)
292 
293  if (distMax<distStop) { // --> (case 3a)
294 
295  distMin = distMax;
296  distMax = distStop;
297 
298  } else { // --> (case 3b)
299 
300  //info << " - not in field of view";
301  //INFO(info);
302  continue;
303 
304  }
305  }
306 
307  /* **
308  cerr << "3: distMin " << setw (10) << distMin
309  << " distMax " << distMax
310  << " distGnd: " << distGround
311  << endl;
312  *** */
313 
314  // check for points before profile start or below ground level
315  distMin = max(distMin, distStart);
316  distMax = min(distMax, distStop);
317 
318  /* **
319  cerr << "4: distMin " << setw (10) << distMin
320  << " distMax " << distMax
321  << " distGnd: " << distGround
322  << endl;
323  *** */
324 
325  if (distMin >= distMax) {
326  //info << " - not in field of view ";
327  //INFO(info);
328  continue;
329  }
330 
331  // here we finally found a part of the shower inside FOV !!!!!
332 
333  //const Point pointMin = showerInitialPos + distMin*showerAxis;
334  //const Point pointMax = showerInitialPos + distMax*showerAxis;
335  const Point pointMin = core + distMin*showerAxis;
336  const Point pointMax = core + distMax*showerAxis;
337 
338  //tMinAtDia = ((showerInitialPos - pointMin).GetMag() +
339  double tMinAtDia = (distMin + (pointMin - telPosition).GetMag()) / kSpeedOfLight;
340 
341  /* **
342  cerr << "tMinAtDia " << tMinAtDia
343  << " dt " << (tMinAtDia - tMinAtDia_) / ns
344  << " ds " << (tMinAtDia - tMinAtDia_) * kSpeedOfLight / m
345  << " distMin " << distMin
346  << endl;
347  *** */
348 
349  //tMaxAtDia = ((showerInitialPos - pointMax).GetMag() +
350  double tMaxAtDia = (distMax + (pointMax - telPosition).GetMag()) / kSpeedOfLight;
351 
352  /* **
353  cerr << "tMaxAtDia " << tMaxAtDia
354  << " dt " << (tMaxAtDia - tMaxAtDia_) / ns
355  << " ds " << (tMaxAtDia - tMaxAtDia_) * kSpeedOfLight / m
356  << " distMax " << distMax
357  << endl;
358  *** */
359 
360  // time must move FORWARD
361  if (tMinAtDia > tMaxAtDia)
362  swap(tMinAtDia, tMaxAtDia);
363 
364  /*
365  Found tMinAtDia/tMaxAtDia -> initialize simteldata
366  */
367 
368  const double deltaT = tMaxAtDia - tMinAtDia;
369  unsigned int numbins = deltaT / (detTel.GetCamera().GetFADCBinSize() / fBinning);
370 
371  if (numbins < 2) {
372  info << " - track too short: deltaT/ns=" << deltaT/ns;
373  INFO(info);
374  continue;
375  }
376 
377  const double minimalDist = min((telPosition - pointMin).GetMag(),
378  (telPosition - pointMax).GetMag());
379  double deltaD = fabs(distMax - distMin) / numbins;
380  double deltaPhi = atan(deltaD / minimalDist);
381 
382  // RU Mi 8. Mär 11:56:23 CET 2017 It is actually only the
383  // angular bin-width that matters for FD telescopes. The
384  // previous logic was producing either to fine (bad
385  // performance), or to sparse binning (bad physics).
386 
387  if (deltaPhi>fMaxAngleBinWidth) { // FOR VERY CLOSE SHOWERS
388  deltaPhi = fMaxAngleBinWidth;
389  deltaD = tan(deltaPhi) * minimalDist;
390  numbins = fabs(distMax-distMin) / deltaD;
391  }
392 
393  const double tracebin = deltaT / numbins;
394 
395  info << resetiosflags(std::ios::scientific) << setiosflags(std::ios::fixed);
396  info //<< " : tMinAtDia=" << tMinAtDia << " tMaxAtDia=" << tMaxAtDia << ", "
397  << ", nBins=" << setw(4) << numbins << ", dT=" << setw(5) << setprecision(1) << tracebin/ns << " ns, "
398  //<< " dMin=" << distMin/m << " dMax=" << distMax/m << ", "
399  << "dDist=" << setw(7) << setprecision(2) << deltaD/m << " m, "
400  << "dAngle=" << setw(5) << setprecision(3) << deltaPhi/deg << " deg";
401  //info << "; dmin=" << distMin << " dmax=" << distMax << " tmin=" << tMinAtDia << " tmax=" << tMaxAtDia << " mdist=" << minimalDist << " tMinAtDia=" << tMinAtDia;
402  INFO(info);
403 
404  //TimeStamp traceAtDiaTime = timeAtStart + TimeInterval(tMinAtDia);
405  TimeStamp traceAtDiaTime = timeAtCore + TimeInterval(tMinAtDia);
406  telSim.SetPhotonsStartTime(traceAtDiaTime);
407 
408  // create event-structure
409  // TRACE POSITION --------------------------------------------
410  if (!telSim.HasDistanceTrace())
411  telSim.MakeDistanceTrace(numbins, tracebin);
412 
413  sumAllBins += numbins;
414 
415  } // tel loop
416 
417  } // eye loop
418 
419  ostringstream info;
420  info << "Looping over " << sumAllBins << " bins in all telescopes combined";
421  INFO(info);
422 
423  return eSuccess;
424 }
425 
426 
428 FieldOfViewCalculator::Finish()
429 {
430  return eSuccess;
431 }
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
Branch GetTopBranch() const
Definition: Branch.cc:63
unsigned int GetId() const
Definition: FEvent/Eye.h:54
Top of the interface to Atmosphere information.
double GetFADCBinSize() const
void swap(utl::Trace< T > &t1, utl::Trace< T > &t2)
Definition: Trace.h:363
Point object.
Definition: Point.h:32
const utl::TimeStamp & GetTimeStamp() const
Get the TimeStamp of the absolute shower core-time.
void InitSlantProfileModel(const utl::Point &core, const utl::Vector &dir, const double deltaX) const
double GetFieldOfView() const
Fluorescence Detector Eye Event.
Definition: FEvent/Eye.h:29
bool HasFEvent() const
bool HasSimShower() const
const atm::ProfileResult & EvaluateDistanceVsSlantDepth() const
Table of distance as a function of slant depth.
utl::Vector GetAxis() const
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void MakeEye(const unsigned int eyeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
Definition: FEvent.cc:115
void Init()
Initialise the registry.
EyeIterator EyesBegin(const FDetComponentSelector::Type type=FDetComponentSelector::ePhysical) const
iterator pointing to first eye of given type (ePhysical, eVirtual, eAll)
Definition: FDetector.h:72
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
double pow(const double x, const unsigned int i)
void MakeTelescope(const unsigned int telescopeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
Make Telescope telescopeId.
Definition: FEvent/Eye.cc:102
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)
void MakeDistanceTrace(const unsigned int size=0, const double binSize=0)
Make the trace of distance along the shower axis of light at the diaphragm.
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
constexpr double deg
Definition: AugerUnits.h:140
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
void SetPhotonsStartTime(const utl::TimeStamp &ts)
const atm::Atmosphere & GetAtmosphere() const
Definition: Detector.h:113
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
fevt::TelescopeSimData & GetSimData()
Description of simulated data for one Telescope.
#define max(a, b)
Class representing a document branch.
Definition: Branch.h:107
boost::filter_iterator< FDetComponentSelector, AllEyeIterator > EyeIterator
Definition: FDetector.h:69
const double ns
Class describing the Atmospheric profile.
Definition: ProfileResult.h:25
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 GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
Top of Fluorescence Detector event hierarchy.
Definition: FEvent.h:33
Eye & GetEye(const unsigned int eyeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
return Eye by id
Definition: FEvent.cc:70
bool HasDistanceTrace() const
Check that trace for the distance along the shower axis is present.
boost::filter_iterator< TelIsCommissioned, InternalConstTelescopeIterator > TelescopeIterator
An iterator over telescopes.
Definition: FDetector/Eye.h:76
bool HasEye(const unsigned int eyeId, const ComponentSelector::Status status=ComponentSelector::eHasData) const
Definition: FEvent.cc:57
constexpr double kSpeedOfLight
Detector description interface for Telescope-related data.
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
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
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
Vector object.
Definition: Vector.h:30
Fluorescence Detector Telescope Event.
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
bool HasSimData() const
utl::CoordinateSystemPtr GetShowerCoordinateSystem() const
double MaxX() const
Return the maximum value for X (ordinate) stored in the profile.
double GetXInject() const
Get depth particle injection.
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.