UFO
TrackCheckUtils.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2020 Met Office UK
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  */
7 
8 #include <algorithm>
9 #include <cmath>
10 #include <memory>
11 #include <string>
12 
13 #include "eckit/exception/Exceptions.h"
14 #include "eckit/geometry/Point2.h"
15 #include "eckit/geometry/Point3.h"
16 #include "eckit/geometry/Sphere.h"
17 #include "ioda/ObsSpace.h"
18 #include "oops/util/DateTime.h"
19 #include "oops/util/sqr.h"
21 #include "ufo/filters/QCflags.h"
23 #include "ufo/utils/Constants.h"
25 
26 namespace ufo {
27 
28 namespace {
29 /// \brief Returns the square of the distance between the two \p Point arguments.
31  float sum = 0;
32  for (size_t i = 0; i < a.size(); ++i)
33  sum += util::sqr(a[i] - b[i]);
34  return sum;
35 }
36 
37 TrackCheckUtils::Point pointFromLatLon(float latitude, float longitude) {
38  // This local copy is needed because convertSphericalToCartesian takes the first parameter by
39  // reference, but Constants::mean_earth_rad has no out-of-line definition.
40  const double meanEarthRadius = Constants::mean_earth_rad;
41  eckit::geometry::Point3 eckitPoint;
42  eckit::geometry::Sphere::convertSphericalToCartesian(
43  meanEarthRadius, eckit::geometry::Point2(longitude, latitude), eckitPoint);
45  std::copy(eckitPoint.begin(), eckitPoint.end(), Point.begin());
46  return Point;
47 }
48 } // namespace
49 
50 /// \p Returns the distance between the two cartesian-mapped \p Point arguments
51 float TrackCheckUtils::distance(const Point &a, const Point &b) {
52  return std::sqrt(distance2(a, b));
53 }
54 
55 ObsAccessor TrackCheckUtils::createObsAccessor(const boost::optional<Variable> &stationIdVariable,
56  const ioda::ObsSpace &obsdb) {
57  if (stationIdVariable != boost::none) {
59  obsdb, *stationIdVariable);
60  } else if (!obsdb.obs_group_vars().empty()) {
61  // Assume observations were grouped into records by station IDs
63  } else {
64  // Observations were not grouped into records and no station ID variable was provided.
65  // Assume all observations were taken by the same station.
66  return ObsAccessor::toAllObservations(obsdb);
67  }
68 }
69 
70 void TrackCheckUtils::sortTracksChronologically(const std::vector<size_t> &validObsIds,
71  const ObsAccessor &obsAccessor,
72  RecursiveSplitter &splitter) {
73  const std::vector<util::DateTime> times = obsAccessor.getDateTimeVariableFromObsSpace(
74  "MetaData", "datetime");
75  splitter.sortGroupsBy([&times, &validObsIds](size_t obsIndex)
76  { return times[validObsIds[obsIndex]]; });
77 }
78 
81  ObsGroupLocationTimes locationTimes;
82 
83  locationTimes.latitudes = obsAccessor.getFloatVariableFromObsSpace("MetaData", "latitude");
84  locationTimes.longitudes = obsAccessor.getFloatVariableFromObsSpace("MetaData", "longitude");
85  locationTimes.datetimes = obsAccessor.getDateTimeVariableFromObsSpace("MetaData", "datetime");
86 
87  return locationTimes;
88 }
89 
90 TrackCheckUtils::ObsLocationTime::ObsLocationTime(float latitude, float longitude,
91  const util::DateTime &time)
92  : location_(pointFromLatLon(latitude, longitude)), time_(time)
93 {}
94 
96  return numChecks_ != 0 ? static_cast<float>(numFailedChecks_) / numChecks_ : 0.0f;
97 }
98 
100  : numFailedChecks_(0), numChecks_(0)
101 {}
102 
104  if (result != CheckResult::SKIPPED)
105  ++numChecks_;
106  if (result == CheckResult::FAILED)
107  ++numFailedChecks_;
108  assert(numChecks_ >= 0);
109  assert(numFailedChecks_ >= 0);
110  assert(numFailedChecks_ <= numChecks_);
111 }
112 
114  if (result != CheckResult::SKIPPED)
115  --numChecks_;
116  if (result == CheckResult::FAILED)
117  --numFailedChecks_;
118  assert(numChecks_ >= 0);
119  assert(numFailedChecks_ >= 0);
120  assert(numFailedChecks_ <= numChecks_);
121 }
122 
123 } // namespace ufo
This class provides access to observations that may be held on multiple MPI ranks.
Definition: ObsAccessor.h:56
static ObsAccessor toObservationsSplitIntoIndependentGroupsByRecordId(const ioda::ObsSpace &obsdb)
Create an accessor to the collection of observations held in obsdb, assuming that each record can be ...
Definition: ObsAccessor.cc:89
static ObsAccessor toAllObservations(const ioda::ObsSpace &obsdb)
Create an accessor to observations from the observation space obsdb, assuming that the whole set of o...
Definition: ObsAccessor.cc:84
static ObsAccessor toObservationsSplitIntoIndependentGroupsByVariable(const ioda::ObsSpace &obsdb, const Variable &variable)
Create an accessor to the collection of observations held in obsdb, assuming that observations with d...
Definition: ObsAccessor.cc:94
std::vector< float > getFloatVariableFromObsSpace(const std::string &group, const std::string &variable) const
Definition: ObsAccessor.cc:144
std::vector< util::DateTime > getDateTimeVariableFromObsSpace(const std::string &group, const std::string &variable) const
Definition: ObsAccessor.cc:159
Partitions an array into groups of elements equivalent according to certain criteria.
void sortGroupsBy(const UnaryOperation &key)
Sort the elements in each equivalence class in ascending order.
void registerCheckResult(const CheckResult &result)
void unregisterCheckResult(const CheckResult &result)
Locations/times of all observations processed by the track checking filter.
std::vector< util::DateTime > datetimes
ObsLocationTime(float latitude, float longitude, const util::DateTime &time)
ObsGroupLocationTimes collectObservationsLocations(const ObsAccessor &obsAccessor)
ObsAccessor createObsAccessor(const boost::optional< Variable > &stationIdVariable, const ioda::ObsSpace &obsdb)
Create an ObsAccessor object providing access to observations that need to be checked by the current ...
void sortTracksChronologically(const std::vector< size_t > &validObsIds, const ObsAccessor &obsAccessor, RecursiveSplitter &splitter)
float distance(const Point &a, const Point &b)
Returns the distance between the two cartesian-mapped Point arguments
std::array< float, 3 > Point
float distance2(const TrackCheckUtils::Point &a, const TrackCheckUtils::Point &b)
Returns the square of the distance between the two Point arguments.
TrackCheckUtils::Point pointFromLatLon(float latitude, float longitude)
Definition: RunCRTM.h:27
static constexpr double mean_earth_rad
Definition: Constants.h:40