GOESDB.cc
Go to the documentation of this file.
1 #include <det/Detector.h>
2 
3 #include <utl/ErrorLogger.h>
4 #include <utl/Point.h>
5 #include <utl/ReferenceEllipsoid.h>
6 #include <utl/AugerException.h>
7 
8 #include <atm/Atmosphere.h>
9 #include <atm/GOESDB.h>
10 
11 using namespace det;
12 using namespace utl;
13 using namespace std;
14 
15 
16 namespace atm {
17 
18  // some hardcoded parameters related to the GOES pixelization of the Auger array
19 
20  namespace {
21  const int gNumEasting = 30; // # of pixels in easting
22  const int gNumNorthing = 12; // # of pixels in northing
23  const int gNumCloudProbabilityLevels = 5; // DB returns from [0, 4]
24  const double gStartEasting = (440000 + 553.2)*m; // start of easting coverage
25  const double gStartNorthing = (6060000 + 9736.34)*m; // start of northing coverage
26  const double gDeltaEasting = 2394.9*m; // size of pixel in easting
27  const double gDeltaNorthing = 5493.03*m; // size of pixel in northing
28  }
29 
30 
31  double
32  GOESDB::GetPixelWidthEasting()
33  const
34  {
35  return gDeltaEasting;
36  }
37 
38 
39  double
40  GOESDB::GetPixelWidthNorthing()
41  const
42  {
43  return gDeltaNorthing;
44  }
45 
46 
47  unsigned int
48  GOESDB::GetNumberOfPixels()
49  const
50  {
51  return gNumEasting * gNumNorthing;
52  }
53 
54 
55  int
56  GOESDB::GetPixelId(const double easting, const double northing)
57  const
58  {
59  const int northPixel = GetNorthPixel(northing);
60  const int eastPixel = GetEastPixel(easting, northPixel);
61  return gNumEasting * northPixel + eastPixel;
62  }
63 
64 
65  int
66  GOESDB::GetNorthPixel(const double northing)
67  const
68  {
69  const double deltaNorthing = GetPixelWidthNorthing();
70  return (northing - gStartNorthing) / deltaNorthing;
71  }
72 
73 
74  int
75  GOESDB::GetEastPixel(const double easting, const int northPixel)
76  const
77  {
78  const double deltaEasting = GetPixelWidthEasting();
79  return (easting - (gStartEasting - (northPixel%6) *
80  deltaEasting / 6)) / deltaEasting;
81  }
82 
83 
84  const utl::UTMPoint&
85  GOESDB::GetPixelCenter(const unsigned int pixelId)
86  const
87  {
88  if (pixelId >= GetNumberOfPixels()) {
89  ostringstream errMsg;
90  errMsg << " pixel id " << pixelId << " out of bound ";
91  throw OutOfBoundException(errMsg.str());
92  }
93 
94  if (fPixelCenters.empty()) {
95 
96  const double deltaEasting = GetPixelWidthEasting();
97  const double deltaNorthing = GetPixelWidthNorthing();
98  const ReferenceEllipsoid& wgs84 = ReferenceEllipsoid::Get(ReferenceEllipsoid::eWGS84);
99 
100  for (unsigned int i = 0; i < GetNumberOfPixels(); ++i) {
101  const unsigned int eastPixel = i % gNumEasting;
102  const unsigned int northPixel = i / gNumEasting;
103  const double easting = gStartEasting + eastPixel * deltaEasting
104  - (northPixel%6) * deltaEasting / 6 + deltaEasting / 2;
105  const double northing = gStartNorthing + northPixel * deltaNorthing
106  + deltaNorthing / 2;
107  const UTMPoint thisPoint(northing, easting, 1400*m, 19, 'H', wgs84);
108  fPixelCenters.push_back(thisPoint);
109  }
110 
111  }
112 
113  return fPixelCenters[pixelId];
114  }
115 
116 
117  double
118  GOESDB::GetCloudProbability(const unsigned int pId)
119  const
120  {
121  return IndexToProbability(GetCloudProbabilityIndex(pId));
122  }
123 
124 
125  double
126  GOESDB::IndexToProbability(const unsigned int cpIndex)
127  const
128  {
129  return cpIndex / double(gNumCloudProbabilityLevels);
130  }
131 
132 
133  int
134  GOESDB::GetCloudProbabilityIndex(const unsigned int pId)
135  const
136  {
137  if (!HasData(pId)) {
139  im["pixel_id"] = boost::lexical_cast<string>(pId);
140  throw DataNotFoundInDBException("cloud_probability", "cloud_pixel", im,
141  boost::lexical_cast<string>(Detector::GetInstance().GetTime()));
142  }
143  return fPixelMap[pId];
144  }
145 
146 
147  bool
148  GOESDB::HasData(const unsigned int pId)
149  const
150  {
151  if (fPixelMap.find(pId) != fPixelMap.end())
152  return true;
153 
154  const VManager& manager = Detector::GetInstance().GetAManagerRegister().GetManager("AGOESSQLManager");
155 
156  int cloudProb;
157  const VManager::IndexMap im({{"pixel_id", boost::lexical_cast<string>(pId)}});
158  if (manager.GetData(cloudProb, "cloud_pixel", "cloud_probability", im) != VManager::eFound)
159  return false;
160 
161  if (cloudProb < 0 || cloudProb > gNumCloudProbabilityLevels - 1) {
162  ostringstream errMsg;
163  errMsg << " cloud index from DB out of range! Index = " << cloudProb
164  << ", expected range is [" << 0 << ", "
165  << gNumCloudProbabilityLevels - 1 << "]"
166  << " (maybe gNumCloudProbabilityLevels needs to be changed?)";
167  throw OutOfBoundException(errMsg.str());
168  }
169  fPixelMap[pId] = cloudProb;
170  return true;
171  }
172 
173 
175  GOESDB::GetAllCloudProbabilities()
176  const
177  {
178  if (fPixelMap.size() < GetNumberOfPixels()) {
179 
180  const VManager& vmanager =
181  Detector::GetInstance().GetAManagerRegister().GetManager("AGOESSQLManager");
182  const AGOESSQLManager& manager = dynamic_cast<const AGOESSQLManager&>(vmanager);
183 
184  const VManager::IndexMap im;
185 
186  if (manager.GetData(fPixelMap, "cloud_pixel", "cloud_probability", im) == VManager::eFound) {
187 
188  auto maxCloudProb = max_element(fPixelMap.begin(), fPixelMap.end());
189  if (maxCloudProb->second < 0 || maxCloudProb->second > gNumCloudProbabilityLevels - 1) {
190  ostringstream errMsg;
191  errMsg << " cloud index from DB out of range! Index = " << maxCloudProb->first
192  << ", expected range is [" << 0 << ", "
193  << gNumCloudProbabilityLevels - 1 << "]"
194  << " (maybe gNumCloudProbabilityLevels needs to be changed?)";
195  throw OutOfBoundException(errMsg.str());
196  }
197  } else {
198  ostringstream msg;
199  msg << "request for data not found in the database for time "
200  << Detector::GetInstance().GetTime() << endl;
201  // ERROR(msg);
203  throw DataNotFoundInDBException("pixel_id,cloud_probability", "cloud_pixel", im,
204  boost::lexical_cast<string>(Detector::GetInstance().GetTime()));
205  }
206 
207  }
208 
209  ProbabilityMap retval;
210  for (const auto& p : fPixelMap)
211  retval[p.first] = IndexToProbability(p.second);
212 
213  return retval;
214  }
215 
216 
217  double
218  GOESDB::GetCloudProbability(const Point& p)
219  const
220  {
221  utl::UTMPoint utmPoint(p, ReferenceEllipsoid::GetWGS84());
222  return GetCloudProbability(utmPoint);
223  }
224 
225 
226  double
227  GOESDB::GetCloudProbability(const UTMPoint& p)
228  const
229  {
230  const double x = p.GetEasting();
231  const double y = p.GetNorthing();
232  return GetCloudProbability(x, y);
233  }
234 
235 
236  double
237  GOESDB::GetCloudProbability(const double easting, const double northing)
238  const
239  {
240  const int pId = GetPixelId(easting, northing);
241  if (pId < 0 || pId >= int(GetNumberOfPixels()))
242  throw NonExistentComponentException("Request Point is not within the range covered by GOES data");
243 
244  return GetCloudProbability(pId);
245  }
246 
247 
248  // utility function for intersection of two line segments
249  inline
250  bool
251  SegmentIntersection(double p0X, double p0Y, double p1X, double p1Y,
252  double p2X, double p2Y, double p3X, double p3Y)
253  {
254  const double s1X = p1X - p0X;
255  const double s1Y = p1Y - p0Y;
256  const double s2X = p3X - p2X;
257  const double s2Y = p3Y - p2Y;
258 
259  if (s1X * s2Y == s2X * s1Y)
260  return false;
261 
262  const double d = s1X * s2Y - s2X * s1Y;
263 
264  const double s = (-s1Y * (p0X - p2X) + s1X * (p0Y - p2Y)) / d;
265  const double t = ( s2X * (p0Y - p2Y) - s2Y * (p0X - p2X)) / d;
266 
267  return (s >= 0 && s <= 1 && t >= 0 && t <= 1);
268  }
269 
270 
271  double
272  GOESDB::GetMaximumCloudProbability(const utl::Point& pos1,
273  const utl::Point& pos2)
274  const
275  {
276  const double dX = GetPixelWidthEasting() / 2;
277  const double dY = GetPixelWidthNorthing() / 2;
278 
279  UTMPoint p1(pos1, ReferenceEllipsoid::Get(ReferenceEllipsoid::eWGS84));
280  UTMPoint p2(pos2, ReferenceEllipsoid::Get(ReferenceEllipsoid::eWGS84));
281  const double x1 = p1.GetEasting();
282  const double y1 = p1.GetNorthing();
283  const double x2 = p2.GetEasting();
284  const double y2 = p2.GetNorthing();
285 
286  // the pixels that contain point 1 and 2
287  const int pixelId1 = GetPixelId(x1, y1);
288  const int pixelId2 = GetPixelId(x2, y2);
289 
290  int maxCloudProbabilityIndex = -1;
291 
292  for (int i = 0; i < int(GetNumberOfPixels()); ++i) {
293  bool isCloudPixel = false;
294  if (i == pixelId1 || i == pixelId2)
295  isCloudPixel = true;
296  else {
297  const utl::UTMPoint& pixelCenter = GetPixelCenter(i);
298  const double x = pixelCenter.GetEasting();
299  const double y = pixelCenter.GetNorthing();
300  if (SegmentIntersection(x1, y1, x2, y2, x - dX, y - dY, x - dX, y + dY) ||
301  SegmentIntersection(x1, y1, x2, y2, x + dX, y - dY, x + dX, y + dY) ||
302  SegmentIntersection(x1, y1, x2, y2, x - dX, y - dY, x + dX, y - dY) ||
303  SegmentIntersection(x1, y1, x2, y2, x - dX, y + dY, x + dX, y + dY))
304  isCloudPixel = true;
305  }
306 
307  if (isCloudPixel) {
308  const int thisIndex = GetCloudProbabilityIndex(i);
309  if (thisIndex > maxCloudProbabilityIndex)
310  maxCloudProbabilityIndex = thisIndex;
311  }
312  }
313 
314  return IndexToProbability(maxCloudProbabilityIndex);
315  }
316 
317 }
Point object.
Definition: Point.h:32
bool SegmentIntersection(double p0X, double p0Y, double p1X, double p1Y, double p2X, double p2Y, double p3X, double p3Y)
Definition: GOESDB.cc:251
Class to hold and convert a point in geodetic coordinates.
Definition: UTMPoint.h:40
Base class for exceptions trying to access non-existing components.
Interface for detector managers.
Definition: VManager.h:115
double GetNorthing() const
Get the northing.
Definition: UTMPoint.h:206
Exception for reporting variable out of valid range.
virtual Status GetData(double &returnData, const std::string &componentProperty, const std::string &componentName, const IndexMap &componentIndex) const =0
Exception to use in case requested data not found in the database with detailed printout.
constexpr double s
Definition: AugerUnits.h:163
Reference ellipsoids for UTM transformations.
double GetEasting() const
Get the easting.
Definition: UTMPoint.h:209
std::map< unsigned int, double > ProbabilityMap
Definition: GOESDB.h:32
std::map< std::string, std::string > IndexMap
Definition: VManager.h:133
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
constexpr double m
Definition: AugerUnits.h:121

, generated on Tue Sep 26 2023.