8 #ifndef TEST_UFO_PARALLELPOISSONDISKTHINNING_H_
9 #define TEST_UFO_PARALLELPOISSONDISKTHINNING_H_
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/AssociativeContainers.h"
28 #include "oops/util/Expect.h"
29 #include "test/TestEnvironment.h"
38 template <>
struct VectorPrintSelector<float> {
typedef VectorPrintSimple selector; };
45 bool expectValidationError =
false) {
46 util::DateTime bgn(conf.getString(
"window begin"));
47 util::DateTime end(conf.getString(
"window end"));
49 const eckit::LocalConfiguration obsSpaceConf(conf,
"obs space");
50 ioda::ObsTopLevelParameters obsParams;
51 obsParams.validateAndDeserialize(obsSpaceConf);
52 ioda::ObsSpace obsspace(obsParams, oops::mpi::world(), bgn, end, oops::mpi::myself());
55 obsspace, obsspace.obsvariables(),
"ObsError"));
57 obsspace, obsspace.obsvariables()));
59 eckit::LocalConfiguration filterConf(conf,
"Poisson Disk Thinning");
61 filterParameters.validateAndDeserialize(filterConf);
66 std::this_thread::sleep_for(obsspace.comm().rank() * std::chrono::milliseconds(1100));
70 std::vector<int> isObsRetained(qcflags->nlocs(), 0);
71 for (
size_t i = 0; i < qcflags->nlocs(); ++i)
74 if (obsSpaceConf.getString(
"distribution",
"RoundRobin") ==
"InefficientDistribution") {
76 const size_t rootRank = 0;
77 size_t isObsRetainedSizeOnRoot = isObsRetained.size();
78 obsspace.comm().broadcast(isObsRetainedSizeOnRoot, rootRank);
80 std::vector<int> isObsRetainedOnRoot(isObsRetainedSizeOnRoot);
81 if (obsspace.comm().rank() == rootRank) {
82 isObsRetainedOnRoot = isObsRetained;
84 obsspace.comm().broadcast(isObsRetainedOnRoot, rootRank);
86 EXPECT_EQUAL(isObsRetained, isObsRetainedOnRoot);
94 obsspace.distribution()->allGatherv(isObsRetained);
95 std::set<size_t> retainedGlobalObsIndices;
96 for (
size_t i = 0; i < isObsRetained.size(); ++i)
98 retainedGlobalObsIndices.insert(i);
101 std::vector<float> pressures(obsspace.nlocs());
102 obsspace.get_db(
"MetaData",
"air_pressure", pressures);
103 obsspace.distribution()->allGatherv(pressures);
106 std::vector<int> categories(obsspace.nlocs(), 0);
107 if (filterConf.has(
"category_variable"))
109 std::string name, group;
110 splitVarGroup(filterConf.getString(
"category_variable.name"), name, group);
111 obsspace.get_db(group, name, categories);
113 obsspace.distribution()->allGatherv(categories);
116 const float minAllowedDistance = filterConf.getFloat(
"min_vertical_spacing");
117 std::vector<float> minDistanceToRetainedObs(pressures.size(),
118 std::numeric_limits<float>::max());
119 for (
size_t i : retainedGlobalObsIndices) {
120 for (
size_t j = 0; j < pressures.size(); ++j) {
121 if (j == i || categories[i] != categories[j])
126 EXPECT(
distance >= minAllowedDistance);
128 minDistanceToRetainedObs[j] = std::min(minDistanceToRetainedObs[j],
distance);
133 for (
size_t j = 0; j < pressures.size(); ++j) {
136 EXPECT(minDistanceToRetainedObs[j] < minAllowedDistance);
143 std::string
testid()
const override {
return "ufo::test::ParallelPoissonDiskThinning";}
146 std::vector<eckit::testing::Test>& ts = eckit::testing::specification();
148 const eckit::LocalConfiguration conf(::test::TestEnvironment::config());
149 for (
const std::string & testCaseName : conf.keys())
151 const eckit::LocalConfiguration testCaseConf(::test::TestEnvironment::config(), testCaseName);
152 ts.emplace_back(
CASE(
"ufo/ParallelPoissonDiskThinning/" + testCaseName, testCaseConf)
void preProcess() override
Thins observations by iterating over them in random order and retaining each observation lying outsid...
Options controlling the operation of the PoissonDiskThinning filter.
void register_tests() const override
std::string testid() const override
void clear() const override
float distance(const Point &a, const Point &b)
Returns the distance between the two cartesian-mapped Point arguments
CASE("ufo/DataExtractor/bilinearinterp/float_linear")
void testPoissonDiskThinning(const eckit::LocalConfiguration &conf, bool expectValidationError=false)
bool contains(const std::set< T > &set, const T &element)
void splitVarGroup(const std::string &vargrp, std::string &var, std::string &grp)
util::Duration abs(const util::Duration &duration)