UFO
TrackCheckShipMainLoop.h
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 #ifndef TEST_UFO_TRACKCHECKSHIPMAINLOOP_H_
9 #define TEST_UFO_TRACKCHECKSHIPMAINLOOP_H_
10 
11 #include <iomanip>
12 #include <memory>
13 #include <string>
14 #include <vector>
15 
16 #define ECKIT_TESTING_SELF_REGISTER_CASES 0
17 
18 #include "eckit/config/LocalConfiguration.h"
19 #include "eckit/testing/Test.h"
20 #include "ioda/ObsSpace.h"
21 #include "ioda/ObsVector.h"
22 #include "oops/mpi/mpi.h"
23 #include "oops/runs/Test.h"
24 #include "oops/util/Expect.h"
25 #include "test/TestEnvironment.h"
28 #include "ufo/filters/Variables.h"
29 
30 namespace ufo {
31 namespace test {
32 
33 void testFirstRejectionSimultaneousIncluded(const eckit::LocalConfiguration &conf) {
34  util::DateTime bgn(conf.getString("window begin"));
35  util::DateTime end(conf.getString("window end"));
36 
37  const eckit::LocalConfiguration obsSpaceConf(conf, "obs space");
38  ioda::ObsTopLevelParameters obsParams;
39  obsParams.validateAndDeserialize(obsSpaceConf);
40  ioda::ObsSpace obsspace(obsParams, oops::mpi::world(), bgn, end, oops::mpi::myself());
41 
42  if (conf.has("station_ids")) {
43  const std::vector<int> stationIds = conf.getIntVector("station_ids");
44  obsspace.put_db("MetaData", "station_id", stationIds);
45  }
46 
47  std::shared_ptr<ioda::ObsDataVector<float>> obserr(new ioda::ObsDataVector<float>(
48  obsspace, obsspace.obsvariables(), "ObsError"));
49  std::shared_ptr<ioda::ObsDataVector<int>> qcflags(new ioda::ObsDataVector<int>(
50  obsspace, obsspace.obsvariables()));
51 
52  eckit::LocalConfiguration filterConf(conf, "Ship Track Check");
53  ufo::TrackCheckShipParameters filterParameters;
54  filterParameters.validateAndDeserialize(filterConf);
55  ufo::TrackCheckShip filter(obsspace, filterParameters, qcflags, obserr);
56  filter.preProcess();
57  const ufo::TrackCheckShipDiagnostics diagnostics = *filter.diagnostics();
58 
59  const std::vector<size_t> expectedFirstRejectionIndices =
60  conf.getUnsignedVector("expected first rejection index");
61  const std::vector<int> expectedCategories = conf.getIntVector("expected error category");
62  std::vector<size_t> testedFirstRejectionIndices;
63  std::vector<int> testedErrorCategories;
64  for (auto const& trackFirstRemovalsInfo : diagnostics.getFirstIterativeRemovalInfo()) {
65  for (auto const& indexRejected : trackFirstRemovalsInfo.first)
66  testedFirstRejectionIndices.push_back(indexRejected);
67  testedErrorCategories.push_back(trackFirstRemovalsInfo.second);
68  }
69  EXPECT_EQUAL(testedFirstRejectionIndices, expectedFirstRejectionIndices);
70  EXPECT_EQUAL(testedErrorCategories, expectedCategories);
71  auto const expectedDistanceSum = conf.getDoubleVector("expected distance sum", {-1});
72  if (*expectedDistanceSum.begin() != -1) {
73  auto calculatedDistanceSum = diagnostics.getDistanceSum();
74  EXPECT(oops::are_all_close_relative(calculatedDistanceSum, expectedDistanceSum, .05));
75  }
76  auto const expectedDistancePreviousObservationOmitted =
77  conf.getDoubleVector("expected distance previous observation omitted", {-1});
78  if (*expectedDistancePreviousObservationOmitted.begin() != -1) {
79  auto calculatedDistancePreviousObservationOmitted = diagnostics.getDistancePrevObsOmitted();
80  EXPECT(oops::are_all_close_relative(calculatedDistancePreviousObservationOmitted,
81  expectedDistancePreviousObservationOmitted, .05));
82  }
83  auto const expectedDistanceCurrentObservationOmitted =
84  conf.getDoubleVector("expected distance current observation omitted", {-1});
85  if (*expectedDistanceCurrentObservationOmitted.begin() != -1) {
86  auto calculatedDistanceCurrentObservationOmitted = diagnostics.getDistanceCurrentObsOmitted();
87  EXPECT(oops::are_all_close_relative(calculatedDistanceCurrentObservationOmitted,
88  expectedDistanceCurrentObservationOmitted, .05));
89  }
90  auto const expectedTimeSum = conf.getDoubleVector("expected time sum", {-1});
91  if (*expectedTimeSum.begin() != -1) {
92  auto calculatedTimeSum = diagnostics.getTimeSum();
93  EXPECT(oops::are_all_close_relative(calculatedTimeSum, expectedTimeSum, .05));
94  }
95  auto const expectedPreviousSegmentDistanceProportion = conf.getDoubleVector(
96  "expected previous segment distance proportion", {-1});
97  if (*expectedPreviousSegmentDistanceProportion.begin() != -1) {
98  auto calculatedPreviousSegmentDistanceProportion =
100  EXPECT(oops::are_all_close_relative(calculatedPreviousSegmentDistanceProportion,
101  expectedPreviousSegmentDistanceProportion, .05));
102  }
103  auto const expectedPreviousObservationDistanceAveragedProportion = conf.getDoubleVector(
104  "expected previous observation distance averaged proportion", {-1});
105  if (*expectedPreviousObservationDistanceAveragedProportion.begin() != -1) {
106  auto calculatedPreviousObservationDistanceAveragedProportion =
108  EXPECT(oops::are_all_close_relative(
109  calculatedPreviousObservationDistanceAveragedProportion,
110  expectedPreviousObservationDistanceAveragedProportion, .05));
111  }
112  auto const expectedPreviousSegmentTimeProportion = conf.getDoubleVector(
113  "expected previous segment time proportion", {-1});
114  if (*expectedPreviousSegmentTimeProportion.begin() != -1) {
115  auto calculatedPreviousSegmentTimeProportion =
116  diagnostics.getPreviousSegmentTimeProportion();
117  EXPECT(oops::are_all_close_relative(calculatedPreviousSegmentTimeProportion,
118  expectedPreviousSegmentTimeProportion, .05));
119  }
120  auto const expectedPreviousAndFastestSegmentTimeProportion = conf.getDoubleVector(
121  "expected previous and fastest segment time proportion", {-1});
122  if (*expectedPreviousAndFastestSegmentTimeProportion.begin() != -1) {
123  auto calculatedPreviousAndFastestSegmentTimeProportion =
125  EXPECT(oops::are_all_close_relative(calculatedPreviousAndFastestSegmentTimeProportion,
126  expectedPreviousAndFastestSegmentTimeProportion, .05));
127  }
128 
129  for (auto const& i : expectedFirstRejectionIndices) {
130  EXPECT_EQUAL((*qcflags)[0][i], ufo::QCflags::track);
131  // tests that the rejected observations are changing the qc flags correctly
132  }
133 }
134 
135 
136 class TrackCheckShipMainLoop : public oops::Test {
137  private:
138  std::string testid() const override {return "ufo::test::TrackCheckShipMainLoop";}
139 
140  void register_tests() const override {
141  std::vector<eckit::testing::Test>& ts = eckit::testing::specification();
142 
143  const eckit::LocalConfiguration conf(::test::TestEnvironment::config());
144  for (const std::string & testCaseName : conf.keys())
145  {
146  const eckit::LocalConfiguration testCaseConf(::test::TestEnvironment::config(), testCaseName);
147  ts.emplace_back(CASE("ufo/TrackCheckShipMainLoop/" + testCaseName, testCaseConf)
148  {
150  });
151  }
152  }
153 
154  void clear() const override {}
155 };
156 
157 } // namespace test
158 } // namespace ufo
159 
160 #endif // TEST_UFO_TRACKCHECKSHIPMAINLOOP_H_
void preProcess() override
std::vector< double > getDistanceSum() const
std::vector< double > getPreviousSegmentDistanceProportion() const
std::vector< double > getTimeSum() const
std::vector< double > getDistanceCurrentObsOmitted() const
std::vector< double > getPreviousSegmentTimeProportion() const
std::vector< double > getPreviousObservationDistanceAveragedProportion() const
const std::vector< FirstIterativeRemovalInfo > & getFirstIterativeRemovalInfo() const
std::vector< double > getPreviousAndFastestSegmentTimeProportion() const
std::vector< double > getDistancePrevObsOmitted() const
Checks tracks of ships and buoys, rejecting observations whose locations and timestamps make them inc...
const TrackCheckShipDiagnostics * diagnostics() const
Options controlling the operation of the ship track check filter.
std::string testid() const override
constexpr int track
Definition: QCflags.h:31
CASE("ufo/DataExtractor/bilinearinterp/float_linear")
void testFirstRejectionSimultaneousIncluded(const eckit::LocalConfiguration &conf)
Definition: RunCRTM.h:27