8 #ifndef TEST_UFO_TRACKCHECKSHIP_H_
9 #define TEST_UFO_TRACKCHECKSHIP_H_
16 #include <boost/none.hpp>
17 #include <boost/optional.hpp>
19 #define ECKIT_TESTING_SELF_REGISTER_CASES 0
21 #include "eckit/config/LocalConfiguration.h"
22 #include "eckit/testing/Test.h"
23 #include "ioda/ObsSpace.h"
24 #include "ioda/ObsVector.h"
25 #include "oops/mpi/mpi.h"
26 #include "oops/runs/Test.h"
27 #include "oops/util/Expect.h"
28 #include "oops/util/FloatCompare.h"
29 #include "test/TestEnvironment.h"
38 const eckit::LocalConfiguration &conf, std::vector<size_t> *rejectedObsIndices =
nullptr) {
39 util::DateTime bgn(conf.getString(
"window begin"));
40 util::DateTime end(conf.getString(
"window end"));
42 const eckit::LocalConfiguration obsSpaceConf(conf,
"obs space");
43 ioda::ObsTopLevelParameters obsParams;
44 obsParams.validateAndDeserialize(obsSpaceConf);
45 ioda::ObsSpace obsspace(obsParams, oops::mpi::world(), bgn, end, oops::mpi::myself());
47 if (conf.has(
"station_ids")) {
48 const std::vector<int> stationIds = conf.getIntVector(
"station_ids");
49 obsspace.put_db(
"MetaData",
"station_id", stationIds);
53 obsspace, obsspace.obsvariables(),
"ObsError"));
55 obsspace, obsspace.obsvariables()));
57 eckit::LocalConfiguration filterConf(conf,
"Ship Track Check");
59 filterParameters.validateAndDeserialize(filterConf);
62 if (filterConf.getBool(
"comparison test",
false) && rejectedObsIndices) {
63 for (
size_t i = 0; i < qcflags->nlocs(); ++i)
65 rejectedObsIndices->push_back(i);
67 }
else if (filterConf.getBool(
"unit testing mode",
false)) {
77 const std::vector<double> expectedDistances = conf.getDoubleVector(
"expected distance");
78 const std::vector<double> expectedSpeeds = conf.getDoubleVector(
"expected speed");
79 const std::vector<double> expectedDistancesAveraged =
80 conf.getDoubleVector(
"expected distance averaged");
81 const std::vector<double> expectedSpeedsAveraged =
82 conf.getDoubleVector(
"expected speed averaged");
83 const std::vector<float> expectedAngles = conf.getFloatVector(
"expected angle");
84 const std::vector<int> expectedShort = conf.getIntVector(
"expected short");
85 const std::vector<int> expectedFast = conf.getIntVector(
"expected fast");
86 const std::vector<int> expectedBends = conf.getIntVector(
"expected bends");
87 const std::vector<double> expectedSumSpeeds = conf.getDoubleVector(
"expected sum speed");
88 const std::vector<double> expectedMeanSpeeds = conf.getDoubleVector(
"expected mean speed");
89 std::vector<double> calculatedDistances, calculatedSpeeds, calculatedDistancesAveraged,
90 calculatedSpeedsAveraged, calculatedSumSpeeds, calculatedMeanSpeeds;
91 std::vector<float> calculatedAngles;
92 std::vector<int> calculatedShort, calculatedFast, calculatedBends;
93 for (
auto const& tracks : diagnostics->getInitialCalculationResults()) {
94 for (
auto const& obsStats : tracks.first) {
95 calculatedDistances.push_back(obsStats.distance);
96 calculatedSpeeds.push_back(obsStats.speed);
97 calculatedDistancesAveraged.push_back(obsStats.distanceAveraged);
98 calculatedSpeedsAveraged.push_back(obsStats.speedAveraged);
99 calculatedAngles.push_back(obsStats.angle);
101 calculatedShort.push_back(tracks.second.numShort_);
102 calculatedFast.push_back(tracks.second.numFast_);
103 calculatedBends.push_back(tracks.second.numBends_);
104 calculatedSumSpeeds.push_back(tracks.second.sumSpeed_);
105 calculatedMeanSpeeds.push_back(tracks.second.meanSpeed_);
107 EXPECT(oops::are_all_close_relative(calculatedDistances, expectedDistances,
109 EXPECT(oops::are_all_close_relative(calculatedSpeeds, expectedSpeeds,
111 EXPECT(oops::are_all_close_relative(
112 calculatedDistancesAveraged, expectedDistancesAveraged,
114 EXPECT(oops::are_all_close_relative(
115 calculatedSpeedsAveraged, expectedSpeedsAveraged,
117 EXPECT(oops::are_all_close_absolute(
118 calculatedAngles, expectedAngles,
120 EXPECT_EQUAL(calculatedShort, expectedShort);
121 EXPECT_EQUAL(calculatedFast, expectedFast);
122 EXPECT_EQUAL(calculatedBends, expectedBends);
123 EXPECT(oops::are_all_close_relative(
124 calculatedSumSpeeds, expectedSumSpeeds,
126 EXPECT(oops::are_all_close_relative
127 (calculatedMeanSpeeds, expectedMeanSpeeds,
132 const eckit::LocalConfiguration filterConf(conf,
"Ship Track Check");
133 if (!filterConf.getBool(
"early break check",
true)) {
141 std::vector<int> expectedEarlyBreaks(conf.getIntVector(
"expected early breaks"));
142 std::vector<int> calculatedEarlyBreaks;
144 for (
auto const& earlyBreakResults : diagnostics->getEarlyBreaks()) {
145 calculatedEarlyBreaks.push_back(earlyBreakResults);
147 EXPECT_EQUAL(expectedEarlyBreaks, calculatedEarlyBreaks);
151 std::vector<size_t> rejectedObsIndices;
155 const std::vector<size_t> expectedRejectedObsIndices =
156 conf.getUnsignedVector(
"expected rejected obs indices");
157 EXPECT_EQUAL(rejectedObsIndices, expectedRejectedObsIndices);
162 std::string
testid()
const override {
return "ufo::test::TrackCheckShip";}
165 std::vector<eckit::testing::Test>& ts = eckit::testing::specification();
167 const eckit::LocalConfiguration conf(::test::TestEnvironment::config());
168 for (
const std::string & testCaseName : conf.keys())
170 const eckit::LocalConfiguration testCaseConf(::test::TestEnvironment::config(), testCaseName);
171 ts.emplace_back(
CASE(
"ufo/TrackCheckShip/" + testCaseName, testCaseConf)
void preProcess() override
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.
void clear() const override
std::string testid() const override
void register_tests() const override
const boost::optional< ufo::TrackCheckShipDiagnostics > setupRunFilter(const eckit::LocalConfiguration &conf, std::vector< size_t > *rejectedObsIndices=nullptr)
void testEarlyBreakCondition(const eckit::LocalConfiguration &conf)
void testRejectedObservations(const eckit::LocalConfiguration &conf)
CASE("ufo/DataExtractor/bilinearinterp/float_linear")
void testTrackCheckShipInitialCalculations(const eckit::LocalConfiguration &conf)