8 #ifndef TEST_UFO_PREDICTOR_H_
9 #define TEST_UFO_PREDICTOR_H_
17 #define ECKIT_TESTING_SELF_REGISTER_CASES 0
20 #include "eckit/config/LocalConfiguration.h"
21 #include "eckit/mpi/Comm.h"
22 #include "eckit/testing/Test.h"
23 #include "ioda/ObsSpace.h"
24 #include "ioda/ObsVector.h"
25 #include "oops/interface/ObsDataVector.h"
26 #include "oops/interface/ObsOperator.h"
27 #include "oops/mpi/mpi.h"
28 #include "oops/runs/Test.h"
29 #include "oops/util/Expect.h"
30 #include "oops/util/IntSetParser.h"
31 #include "test/interface/ObsTestsFixture.h"
40 typedef ::test::ObsTestsFixture<ObsTraits> Test_;
41 typedef oops::ObsDiagnostics<ufo::ObsTraits> ObsDiags_;
43 std::vector<eckit::LocalConfiguration> typeconfs;
44 ::test::TestEnvironment::config().get(
"observations", typeconfs);
46 for (std::size_t jj = 0; jj < Test_::obspace().size(); ++jj) {
47 ioda::ObsSpace &ospace = Test_::obspace()[jj].obsspace();
48 const eckit::Configuration &conf = typeconfs[jj];
51 eckit::LocalConfiguration bconf(conf,
"obs bias");
53 bparams.validateAndDeserialize(bconf);
54 const ObsBias ybias(ospace, bparams);
56 std::vector<std::string> predictor_names = ybias.requiredPredictors();
59 oops::Variables gvars;
60 gvars += ybias.requiredVars();
61 std::unique_ptr<const GeoVaLs> gval;
62 if (gvars.size() > 0) {
64 eckit::LocalConfiguration gconf(conf,
"geovals");
65 gval.reset(
new GeoVaLs(gconf, ospace, gvars));
68 gval.reset(
new GeoVaLs(ospace.distribution(), gvars));
72 oops::Variables diagvars;
73 diagvars += ybias.requiredHdiagnostics();
74 std::vector<float> lons(ospace.nlocs());
75 std::vector<float> lats(ospace.nlocs());
76 std::vector<util::DateTime> times(ospace.nlocs());
77 ospace.get_db(
"MetaData",
"latitude", lats);
78 ospace.get_db(
"MetaData",
"longitude", lons);
79 ospace.get_db(
"MetaData",
"datetime", times);
80 Locations locs(lons, lats, times, ospace.distribution());
83 bool expect_error_message =
false;
86 const std::size_t npreds = predictor_names.size();
88 std::vector<ioda::ObsVector> predData(npreds, ioda::ObsVector(ospace));
90 const Predictors & predictors = ybias.predictors();
91 for (std::size_t p = 0; p < npreds; ++p) {
92 if (conf.has(
"expectExceptionWithMessage")) {
93 const std::string msg = conf.getString(
"expectExceptionWithMessage");
94 EXPECT_THROWS_MSG(predictors[p]->compute(ospace, *gval, ydiags, predData[p]), msg.c_str());
95 expect_error_message =
true;
98 predictors[p]->compute(ospace, *gval, ydiags, predData[p]);
99 predData[p].save(predictors[p]->name() +
"Predictor");
102 if (expect_error_message) {
107 const double tol = conf.getDouble(
"tolerance");
112 std::vector<std::string> vars;
113 for (std::size_t jp = 0; jp < npreds; ++jp) {
114 vars.push_back(
"predictor_" + predictor_names[jp]);
116 const oops::Variables testvars = ospace.obsvariables();
117 const std::size_t nvars = testvars.size();
118 if (!testvars.channels().empty()) {
121 ASSERT(nvars == testvars.channels().size());
125 std::vector<double> testData(ospace.nlocs());
126 for (std::size_t jp = 0; jp < npreds; ++jp) {
127 const std::size_t
nlocs = predData[jp].nlocs();
128 for (std::size_t jv = 0; jv < nvars; ++jv) {
129 std::string refVarName =
"predictor_" + predictor_names[jp] +
'_';
130 if (testvars.channels().empty())
131 refVarName += testvars[jv];
133 refVarName += std::to_string(testvars.channels()[jv]);
135 ospace.get_db(
"TestReference", refVarName, testData);
139 for (
size_t jl = 0; jl <
nlocs; jl++) {
140 testData[jl] -= predData[jp][jl*nvars + jv];
141 rms += testData[jl] * testData[jl];
143 rms = std::sqrt(rms /
nlocs);
145 oops::Log::debug() <<
"Vector difference between reference and computed for "
146 << refVarName <<
": " << testData << std::endl;
158 std::string
testid()
const override {
return "ufo::test::Predictor";}
161 std::vector<eckit::testing::Test>& ts = eckit::testing::specification();
163 ts.emplace_back(
CASE(
"ufo/Predictor/testPredictor")
Parameters influencing the bias correction process.
void register_tests() const override
void clear() const override
std::string testid() const override
CASE("ufo/DataExtractor/bilinearinterp/float_linear")
integer function nlocs(this)
Return the number of observational locations in this Locations object.
std::vector< std::shared_ptr< PredictorBase > > Predictors