FOVCalculator.cc
Go to the documentation of this file.
1 #include <utl/config.h>
2 #include <adst/RecEvent.h>
3 
4 #include "FOVCalculator.h"
5 
6 #include <fwk/CentralConfig.h>
7 #include <fwk/CoordinateSystemRegistry.h>
8 
9 #include <utl/Reader.h>
10 #include <utl/TimeStamp.h>
11 #include <utl/ErrorLogger.h>
12 #include <utl/MathConstants.h>
13 #include <utl/PhysicalConstants.h>
14 #include <utl/Transformation.h>
15 #include <utl/CoordinateSystemPtr.h>
16 #include <utl/Point.h>
17 #include <utl/Vector.h>
18 #include <utl/AxialVector.h>
19 #include <utl/UTMPoint.h>
20 #include <utl/ReferenceEllipsoid.h>
21 #include <utl/TabulatedFunction.h>
22 
23 #include <det/Detector.h>
24 #include <fdet/FDetector.h>
25 #include <fdet/Pixel.h>
26 #include <fdet/Camera.h>
27 #include <fdet/Eye.h>
28 #include <fdet/Telescope.h>
29 
30 #include <fevt/FEvent.h>
31 #include <fevt/Eye.h>
32 #include <fevt/Telescope.h>
33 
34 #include <atm/ProfileResult.h>
35 #include <atm/InclinedAtmosphericProfile.h>
36 #include <atm/AttenuationResult.h>
37 
38 #include <iostream>
39 #include <string>
40 #include <map>
41 #include <vector>
42 
43 using namespace fwk;
44 using namespace utl;
45 using namespace fdet;
46 using namespace atm;
47 using namespace std;
48 using namespace otoa;
49 
50 
51 void
52 FOVCalculator::FillFOVVariables(const fevt::FEvent& fdEvent, RecEvent& theRecEvent)
53 {
54  CoordinateSystemPtr referenceCS = det::Detector::GetInstance().GetReferenceCoordinateSystem();
55  const Atmosphere& atm = det::Detector::GetInstance().GetAtmosphere();
56  const fdet::FDetector& fdDet = det::Detector::GetInstance().GetFDetector();
57 
58  std::vector<FDEvent>& theFDEvents = theRecEvent.GetFDEvents();
59  for (unsigned int i = 0; i < theFDEvents.size(); ++i) {
60 
61  const unsigned int eyeID = theFDEvents[i].GetEyeId();
62  const fdet::Eye& detEye = fdDet.GetEye(eyeID);
63  const fevt::Eye& evtEye = fdEvent.GetEye(eyeID, fevt::ComponentSelector::eInDAQ);
64 
65  set<unsigned int> telescopesWithData;
66  set<unsigned int> telescopesInDAQ;
67  for (auto telIter = evtEye.TelescopesBegin(fevt::ComponentSelector::eInDAQ);
68  telIter != evtEye.TelescopesEnd(fevt::ComponentSelector::eInDAQ); ++telIter)
69  telescopesInDAQ.insert(telIter->GetId());
70 
71  for (auto telIter = evtEye.TelescopesBegin(fevt::ComponentSelector::eHasData);
72  telIter != evtEye.TelescopesEnd(fevt::ComponentSelector::eHasData); ++telIter)
73  telescopesWithData.insert(telIter->GetId());
74 
75  if (theFDEvents[i].GetRecLevel() >= eHasGHParameters) {
76 
77  FdRecShower& theShower = theFDEvents[i].GetFdRecShower();
78  const double zeta = theFDEvents[i].GetFdRecApertureLight().GetZeta();
79  const TVector3& adstCore = theShower.GetCoreSiteCS();
80  const TVector3& adstAxis = theShower.GetAxisSiteCS();
81 
82  const Vector axis(adstAxis.X(), adstAxis.Y(), adstAxis.Z(), referenceCS);
83  const Point core(adstCore.X(), adstCore.Y(), adstCore.Z(), referenceCS);
84 
85  try {
86 
87  atm.InitSlantProfileModel(core, axis, 50*g/cm2);
88 
89  double xLow = -1;
90  double xUp = -1;
91 
92  CalculateFOVBoundaries(core, axis, detEye,
93  telescopesInDAQ,
94  telescopesWithData,
95  zeta, xLow, xUp);
96 
97  theShower.SetXFOVMin(xLow);
98  theShower.SetXFOVMax(xUp);
99 
101  ERROR(e.GetMessage());
102  }
103  }
104  }
105 
106  CalculateXmaxErrors(theRecEvent);
107 }
108 
109 
110 void
111 FOVCalculator::CalculateXmaxErrors(RecEvent& theRecEvent)
112 {
113  fXmaxScanner.EstimateXmaxErrors(theRecEvent);
114  std::vector<FDEvent>& theFDEvents = theRecEvent.GetFDEvents();
115  const std::vector<LongitudinalScan> longScan =
116  fXmaxScanner.GetLongitudinalScan();
117  const std::vector<double> errAtXmaxVec =
118  fXmaxScanner.GetErrorAtXmax();
119  if (theFDEvents.size() != longScan.size() ||
120  theFDEvents.size() != errAtXmaxVec.size()) {
121  ERROR("size mismatch FDEvent vs. XmaxErrors!!");
122  cout << theFDEvents.size() << ' '
123  << longScan.size() << ' '
124  << errAtXmaxVec.size() << endl;
125  throw AugerException();
126  }
127 
128  for (unsigned int i = 0; i < theFDEvents.size(); ++i) {
129  FdRecShower& recShower = theFDEvents[i].GetFdRecShower();
130  vector<double>& zVec = recShower.GetZVector();
131  zVec.clear();
132  vector<double>& mvaVec = recShower.GetMinViewingAngles();
133  mvaVec.clear();
134  const vector<double>& xmaxErrors = longScan[i].GetXiXmaxVector();
135  const vector<double>& mvaValues = longScan[i].GetMinViewingAngleVector();
136  for (unsigned int j = 0; j < xmaxErrors.size(); ++j) {
137  zVec.push_back(xmaxErrors[j]/g*cm2);
138  mvaVec.push_back(mvaValues[j]);
139  }
140  recShower.SetZXmax(errAtXmaxVec[i]/g*cm2);
141  }
142 }
143 
144 
145 bool
146 FOVCalculator::CalculateFOVBoundaries(const Point& core, const Vector& axis,
147  const fdet::Eye& detEye,
148  const set<unsigned int>& telsInDAQ,
149  const set<unsigned int>& telsWithData,
150  const double zeta,
151  double& xLow, double& xUp)
152 {
153  const Atmosphere& atm = det::Detector::GetInstance().GetAtmosphere();
154  ReferenceEllipsoid wgs84(ReferenceEllipsoid::Get(ReferenceEllipsoid::eWGS84));
155 
156  const Point& eyePos = detEye.GetPosition();
158 
159  double xUpGeom = -1;
160  double xLowGeom = -1;
161  double xUpDAQ = -1;
162  double xLowDAQ = -1;
163 
164  try {
165 
166  const atm::ProfileResult& depthProfile = atm.EvaluateSlantDepthVsDistance();
167  const double maxDistance = depthProfile.MaxX();
168  const double minDistance = depthProfile.MinX();
169  const CoordinateSystemPtr& CS = detEye.GetLocalCoordinateSystem();
170  const utl::Vector vertical(0, 0, 1, CS, Vector::kCartesian);
171 
172  const double cosZeta = cos(zeta);
173 
174  const utl::Vector eyeToShower = core - eyePos;
175 
176  utl::Vector sdp = Cross(axis, eyeToShower);
177  const double Rp = sdp.GetMag();
178  sdp.Normalize();
179  sdp.TransformTo(eyeCS);
180 
181  const AxialVector horizontal = Normalized(Cross(sdp, vertical));
182 
183  const double chi0 = Angle(horizontal, axis);
184  const Vector eyeCoreVec = Rp / sin(kPi - chi0) * horizontal;
185  const double eyeCoreDistance = eyeCoreVec.GetMag();
186 
187  for (auto telIter = detEye.TelescopesBegin(); telIter != detEye.TelescopesEnd(); ++telIter) {
188 
189  const unsigned int telID = telIter->GetId();
190 
191  const bool telHasData = (telsWithData.find(telID) != telsWithData.end());
192  const bool telInDAQ = (telsInDAQ.find(telID)!= telsInDAQ.end());
193 
194  bool goodTelescope = false;
195 
196  try {
197  const bool telInAquisition = telInDAQ;
198  const double telUpTime = telIter->GetUpTimeFraction();
199  if (fVerbosity > -1)
200  cout << " telId=" << telID << " upTime = " << telUpTime
201  << " isInAqu=" << telInAquisition
202  << " " << (telHasData ? "[data]" : " ")
203  << '\n';
204  goodTelescope = (telUpTime > 0 && telInDAQ);
205  } catch (NonExistentComponentException& c) {
206  // use telescopes in event for non-existing uptime
207  cerr << " no FdUptime available!!\n"
208  << c.GetExceptionName() << "\n " << c.GetMessage() << '\n';
209  if (telHasData)
210  goodTelescope = true;
211  }
212 
213  if (!goodTelescope && telHasData) {
214  cerr << " FOVCalculator::CalculateFOVBoundaries() -"
215  << " telescope out of DAQ with data!! eye="
216  << detEye.GetId() << " tel=" << telIter->GetId() << '\n';
217  goodTelescope = true;
218  }
219 
220  if (!goodTelescope)
221  continue;
222 
223  vector<unsigned int> candidatePixelIds;
224 
225  for (unsigned int iP = telIter->GetFirstPixelId(); iP <= telIter->GetLastPixelId(); ++iP) {
226 
227  const Vector& pixelDir = telIter->GetPixel(iP).GetDirection();
228 
229  const double angle = fabs(0.5*kPi - Angle(sdp, pixelDir));
230  if (angle <= 0.75*degree) {
231  candidatePixelIds.push_back(iP);
232  }
233  }
234 
235  const unsigned int minSLTPixels = 4;
236 
237  if (candidatePixelIds.size() >= minSLTPixels) {
238 
239  for (unsigned int iPix = 0; iPix < candidatePixelIds.size(); ++iPix) {
240 
241  const unsigned int iP = candidatePixelIds[iPix];
242  const Vector& pixelDir = telIter->GetPixel(iP).GetDirection();
243 
244  const Vector chi_i_vector = pixelDir - (sdp * pixelDir) * sdp;
245 
246  const double nominalAngle = Angle(chi_i_vector, horizontal);
247  if (nominalAngle < 0 || nominalAngle>chi0)
248  continue;
249 
250  for (double dChi = -0.85*degree; dChi <= 0.85*degree; dChi += 0.1*degree) {
251 
252  const double chi_i = nominalAngle + dChi;
253 
254  double l = eyeCoreDistance * sin(chi_i) / sin(chi0 - chi_i);
255  if (l < 0)
256  l *= -1;
257  double distance = -l; // by convention
258  if (distance < minDistance)
259  distance = minDistance;
260  else if (distance > maxDistance)
261  distance = maxDistance;
262 
263  const Vector closestApproach = eyeCoreVec + l * axis;
264  closestApproach.TransformTo(eyeCS);
265 
266  // check if close to border (FdApertureLightFinder::IsNearBorder())
267  bool isNearBorder = false;
268 
269  for (auto oobPixIter = telIter->OutOfBorderPixelsBegin(); oobPixIter!= telIter->OutOfBorderPixelsEnd(); ++oobPixIter) {
270  if (CosAngle(closestApproach, *oobPixIter) > cosZeta) {
271  isNearBorder = true;
272  break;
273  }
274  }
275 
276  if (!isNearBorder) {
277 
278  const Point pclosestApproach(closestApproach.GetX(eyeCS),
279  closestApproach.GetY(eyeCS),
280  closestApproach.GetZ(eyeCS),
281  eyeCS);
282  const double thePhi = pclosestApproach.GetPhi(eyeCS)/degree;
283  if (thePhi > -1 && thePhi < 181) {
284 
285  const double depth = depthProfile.Y(distance);
286 
287  if (xUpGeom < 0 || depth > xUpGeom)
288  xUpGeom = depth;
289  if (xLowGeom < 0 || depth < xLowGeom)
290  xLowGeom = depth;
291 
292  if (xUpDAQ < 0 || depth > xUpDAQ)
293  xUpDAQ = depth;
294  if (xLowDAQ < 0 || depth < xLowDAQ)
295  xLowDAQ = depth;
296 
297  }
298  }
299  }
300  }
301  } else {
302  if (fVerbosity > 10)
303  cout << " skipping mirror with less than "
304  << minSLTPixels
305  << " pixels " << candidatePixelIds.size() << endl;
306  }
307  }
308  } catch (OutOfBoundException& e) {
309  // ignore
310  }
311 
312  if (xUpGeom > 0 && xLowGeom > 0) {
313  xUpGeom /= (g/cm2);
314  xLowGeom /= (g/cm2);
315  }
316 
317  if (xUpDAQ > 0 && xLowDAQ > 0) {
318  xUpDAQ /= (g/cm2);
319  xLowDAQ /= (g/cm2);
320  }
321 
322  if (fVerbosity > -1) {
323  cout << "geom FOV boundaries: " << detEye.GetId() << " "
324  << xUpGeom << " " << xLowGeom << "\n"
325  "DAQ FOV boundaries: " << detEye.GetId() << " "
326  << xUpDAQ << " " << xLowDAQ << endl;
327  if (xUpGeom != xUpDAQ || xLowGeom != xLowDAQ)
328  cout << " ######### GEOM-FOV update! ##########" << endl;
329  if (fabs(xUp - xUpDAQ) > 10*g/cm2 || fabs(xLow - xLowDAQ) > 10*g/cm2)
330  cout << " ######### FOV update! ##########" << endl;
331  }
332 
333  xLow = xLowDAQ;
334  xUp = xUpDAQ;
335 
336  return true;
337 }
338 
339 
340 bool
341 FOVCalculator::FdUpAndRunning()
342  const
343 {
344  bool oneIsUp = false;
345  const fdet::FDetector& fdDet = det::Detector::GetInstance().GetFDetector();
346  try {
347  for (auto eyeIter = fdDet.EyesBegin(fdet::FDetComponentSelector::eAll);
348  eyeIter != fdDet.EyesEnd(fdet::FDetComponentSelector::eAll); ++eyeIter) {
349  for (auto telIter = eyeIter->TelescopesBegin();
350  telIter != eyeIter->TelescopesEnd(); ++telIter) {
351  if (telIter->GetDAQStatus()) {
352  oneIsUp = true;
353  break;
354  }
355  }
356  if (oneIsUp)
357  break;
358  }
359  } catch (NonExistentComponentException& c) {
360  cerr << " no FdUptime available!!\n"
361  << c.GetExceptionName() << "\n " << c.GetMessage() << endl;
362  }
363 
364  return oneIsUp;
365 }
utl::CoordinateSystemPtr GetLocalCoordinateSystem() const
The Auger coordinate system (x to east, z local verical) for this eye.
AxialVector Cross(const Vector &l, const Vector &r)
Definition: OperationsAV.h:25
Top of the interface to Atmosphere information.
void Normalize()
Definition: Vector.h:64
const double degree
Point object.
Definition: Point.h:32
double Angle(const double theta1, const double phi1, const double theta2, const double phi2)
double GetPhi(const CoordinateSystemPtr &coordinateSystem) const
azimuth (phi) angle in spherical and cylindrical coordinates
Definition: BasicVector.h:254
void InitSlantProfileModel(const utl::Point &core, const utl::Vector &dir, const double deltaX) const
Base class for all exceptions used in the auger offline code.
Fluorescence Detector Eye Event.
Definition: FEvent/Eye.h:29
Base class for exceptions trying to access non-existing components.
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
double GetMag() const
Definition: Vector.h:58
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.
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Reference ellipsoids for UTM transformations.
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
utl::CoordinateSystemPtr GetEyeCoordinateSystem() const
Returns the Eye Coordinate system.
Class describing the Atmospheric profile.
Definition: ProfileResult.h:25
TelescopeIterator TelescopesEnd()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:230
constexpr double kPi
Definition: MathConstants.h:24
TelescopeIterator TelescopesBegin() const
Beginning of the collection of telescopes.
Definition: FDetector/Eye.h:79
unsigned int GetId() const
Eye numerical Id.
constexpr double g
Definition: AugerUnits.h:200
Top of Fluorescence Detector event hierarchy.
Definition: FEvent.h:33
AxialVector Normalized(const AxialVector &v)
Definition: AxialVector.h:81
Eye & GetEye(const unsigned int eyeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
return Eye by id
Definition: FEvent.cc:70
TelescopeIterator TelescopesBegin()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:207
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:209
double MinX() const
Return the minimum value for X (ordinate) stored in the profile.
execption handling for calculation/access for inclined atmosphere model
Vector object.
Definition: Vector.h:30
double CosAngle(const Vector &l, const Vector &r)
Definition: OperationsVV.h:71
TelescopeIterator TelescopesEnd() const
End of the collection of telescopes.
Definition: FDetector/Eye.h:83
AxialVector object.
Definition: AxialVector.h:30
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:212
const atm::ProfileResult & EvaluateSlantDepthVsDistance() const
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
const std::string & GetMessage() const
Retrieve the message from the exception.
utl::Point GetPosition() const
Eye position.
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.