11 #ifndef TEST_IODA_OBSVECTOR_H_ 
   12 #define TEST_IODA_OBSVECTOR_H_ 
   18 #include <boost/shared_ptr.hpp> 
   20 #define ECKIT_TESTING_SELF_REGISTER_CASES 0 
   22 #include "eckit/config/LocalConfiguration.h" 
   23 #include "eckit/testing/Test.h" 
   25 #include "oops/mpi/mpi.h" 
   26 #include "oops/runs/Test.h" 
   27 #include "oops/test/TestEnvironment.h" 
   28 #include "oops/util/dot_product.h" 
   29 #include "oops/util/Logger.h" 
   31 #include "ioda/IodaTrait.h" 
   48     for (
auto &space : spaces) {
 
   57     return theObsVecTestFixture;
 
   61     util::DateTime bgn((::test::TestEnvironment::config().getString(
"window begin")));
 
   62     util::DateTime end((::test::TestEnvironment::config().getString(
"window end")));
 
   64     std::vector<eckit::LocalConfiguration> conf;
 
   65     ::test::TestEnvironment::config().get(
"observations", conf);
 
   67     for (std::size_t jj = 0; jj < conf.size(); ++jj) {
 
   68       eckit::LocalConfiguration obsconf(conf[jj], 
"obs space");
 
   70       obsparams.validateAndDeserialize(obsconf);
 
   71       boost::shared_ptr<ObsSpace_> tmp(
new ObsSpace_(obsparams, oops::mpi::world(),
 
   72                                                      bgn, end, oops::mpi::myself()));
 
   79   std::vector<boost::shared_ptr<ObsSpace_> > 
ospaces_;
 
   88   for (std::size_t jj = 0; jj < Test_::obspace().size(); ++jj) {
 
   89     std::unique_ptr<ObsVector_> ov(
new ObsVector_(*Test_::obspace()[jj]));
 
  103   for (std::size_t jj = 0; jj < Test_::obspace().size(); ++jj) {
 
  104     std::unique_ptr<ObsVector_> ov(
new ObsVector_(*Test_::obspace()[jj]));
 
  106     std::unique_ptr<ObsVector_> other(
new ObsVector_(*ov));
 
  110     EXPECT(!other.get());
 
  121   const double zero = 0.0;
 
  123   for (std::size_t jj = 0; jj < Test_::obspace().size(); ++jj) {
 
  124     ObsVector_ ov(*Test_::obspace()[jj]);
 
  128     const double ovov2 = dot_product(ov, ov);
 
  129     EXPECT(ovov2 > zero);
 
  133     const double zz = dot_product(ov, ov);
 
  141   typedef ObsVecTestFixture Test_;
 
  144   std::vector<eckit::LocalConfiguration> conf;
 
  145   ::test::TestEnvironment::config().get(
"observations", conf);
 
  147   for (std::size_t jj = 0; jj < Test_::obspace().size(); ++jj) {
 
  152     eckit::LocalConfiguration testConfig;
 
  153     conf[jj].get(
"test data", testConfig);
 
  154     double ExpectedRms = testConfig.getDouble(
"rms ref");
 
  155     double Tol = testConfig.getDouble(
"tolerance");
 
  158     std::unique_ptr<ObsVector_> ov(
new ObsVector_(*Odb, 
"ObsValue"));
 
  159     double Rms = ov->rms();
 
  161     EXPECT(oops::is_close(Rms, ExpectedRms, Tol));
 
  175   std::vector<eckit::LocalConfiguration> conf;
 
  176   ::test::TestEnvironment::config().get(
"observations", conf);
 
  178   for (std::size_t jj = 0; jj < Test_::obspace().size(); ++jj) {
 
  179     Odb = Test_::obspace()[jj].get();
 
  180     bool read_obs_from_separate_file =
 
  181       conf[jj].getBool(
"obs space.read obs from separate file", 
false);
 
  186     std::unique_ptr<ObsVector_> ov_orig(
new ObsVector_(*Odb, 
"ObsValue"));
 
  187     ExpectedRms = ov_orig->rms();
 
  189     if (!read_obs_from_separate_file)
 
  190       ov_orig->save(
"ObsTest");
 
  192     std::unique_ptr<ObsVector_> ov_test(
new ObsVector_(*Odb, 
"ObsTest"));
 
  193     Rms = ov_test->rms();
 
  195     EXPECT(oops::is_close(Rms, ExpectedRms, 1.0e-12));
 
  211   for (std::size_t jj = 0; jj < Test_::obspace().size(); ++jj) {
 
  213     ObsVector_ vec1(obspace);
 
  217     ObsVector_ vec2(vec1);
 
  218     vec2.axpy(2.0, vec1);
 
  219     ObsVector_ vec3(vec1);
 
  220     std::vector<double> beta(obspace.obsvariables().size(), 2.0);
 
  221     vec3.axpy(beta, vec1);
 
  222     oops::Log::test() << 
"Testing ObsVector::axpy" << std::endl;
 
  223     oops::Log::test() << 
"x = " << vec1 << std::endl;
 
  224     oops::Log::test() << 
"x.axpy(2, x) = " << vec2 << std::endl;
 
  225     oops::Log::test() << 
"x.axpy(vector of 2, x) = " << vec3 << std::endl;
 
  226     EXPECT(oops::is_close(vec2.rms(), vec3.rms(), 1.0e-8));
 
  229     std::vector<double> beta1(obspace.obsvariables().size());
 
  230     std::vector<double> beta2(obspace.obsvariables().size());
 
  231     for (
size_t jj = 0; jj < beta1.size(); ++jj) {
 
  232       beta1[jj] = 
static_cast<double>(jj)/beta1.size();
 
  233       beta2[jj] = 2.0 - beta1[jj];
 
  235     oops::Log::test() << 
"beta1 = " << beta1 << 
", beta2 = " << beta2 << std::endl;
 
  236     ObsVector_ vec4(vec1);
 
  237     vec4.axpy(beta1, vec1);
 
  238     oops::Log::test() << 
"x.axpy(beta1, x) = " << vec4 << std::endl;
 
  239     vec4.axpy(beta2, vec1);
 
  240     oops::Log::test() << 
"x.axpy(beta2, x) = " << vec4 << std::endl;
 
  241     EXPECT(oops::is_close(vec4.rms(), vec3.rms(), 1.0e-8));
 
  253   for (std::size_t jj = 0; jj < Test_::obspace().size(); ++jj) {
 
  255     ObsVector_ vec1(obspace);
 
  257     ObsVector_ vec2(obspace);
 
  260     double dp1 = vec1.dot_product_with(vec2);
 
  261     std::vector<double> dp2 = vec1.multivar_dot_product_with(vec2);
 
  262     oops::Log::test() << 
"Testing ObsVector::dot_product" << std::endl;
 
  263     oops::Log::test() << 
"x1 = " << vec1 << std::endl;
 
  264     oops::Log::test() << 
"x2 = " << vec2 << std::endl;
 
  265     oops::Log::test() << 
"x1.dot_product_with(x2) = " << dp1 << std::endl;
 
  266     oops::Log::test() << 
"x1.multivar_dot_product_with(x2) = " << dp2 << std::endl;
 
  269     EXPECT_EQUAL(dp2.size(), vec1.nvars());
 
  272     EXPECT(oops::is_close(dp1, std::accumulate(dp2.begin(), dp2.end(), 0.0), 1.0e-12));
 
  281   typedef std::vector< std::shared_ptr< ObsVector_> > ObsVectors_;
 
  288   std::vector<std::string> dist_names =
 
  289     ::test::TestEnvironment::config().getStringVector(
"distributions");
 
  290   for (std::size_t ii = 0; ii < dist_names.size(); ++ii) {
 
  291     oops::Log::debug() << 
"using distribution: " << dist_names[ii] << std::endl;
 
  295   util::DateTime bgn((::test::TestEnvironment::config().getString(
"window begin")));
 
  296   util::DateTime end((::test::TestEnvironment::config().getString(
"window end")));
 
  297   std::vector<eckit::LocalConfiguration> conf;
 
  298   ::test::TestEnvironment::config().get(
"observations", conf);
 
  301   std::vector< ObsVectors_ > dist_obsvecs;
 
  302   std::vector< std::shared_ptr<ObsSpace_> > dist_obsdbs;
 
  303   for (std::size_t dd = 0; dd < dist_names.size(); ++dd) {
 
  305     for (std::size_t jj = 0; jj < conf.size(); ++jj) {
 
  324        eckit::LocalConfiguration obsconf(conf[jj], 
"obs space");
 
  325        obsconf.set(
"distribution", dist_names[dd]);
 
  326        if (obsconf.has(
"obsdataout.obsfile")) {
 
  327            std::string fileName = obsconf.getString(
"obsdataout.obsfile");
 
  328            std::string fileTag = std::string(
"_Dist_") + dist_names[dd];
 
  329            std::size_t pos = fileName.find_last_of(
".");
 
  330            if (pos != std::string::npos) {
 
  332                fileName.insert(pos, fileTag);
 
  337            obsconf.set(
"obsdataout.obsfile", fileName);
 
  341        obsparams.validateAndDeserialize(obsconf);
 
  344        std::shared_ptr<ObsSpace_> obsdb(
new ObsSpace(obsparams, oops::mpi::world(),
 
  345                                                      bgn, end, oops::mpi::myself()));
 
  346        std::shared_ptr<ObsVector_> obsvec(
new ObsVector_(*obsdb, 
"ObsValue"));
 
  347        oops::Log::debug() << dist_names[dd] << 
": " << *obsvec << std::endl;
 
  348        dist_obsdbs.push_back(obsdb);
 
  349        obsvecs.push_back(obsvec);
 
  351     dist_obsvecs.push_back(obsvecs);
 
  356   for (std::size_t ii = 0; ii < conf.size(); ++ii) {
 
  358     int nobs = dist_obsvecs[0][ii]->nobs();
 
  359     double rms = dist_obsvecs[0][ii]->rms();
 
  360     double dot = dist_obsvecs[0][ii]->dot_product_with(*dist_obsvecs[0][ii]);
 
  363     for (std::size_t jj = 1; jj < dist_obsvecs.size(); ++jj) {
 
  364       int nobs2 = dist_obsvecs[jj][ii]->nobs();
 
  365       double rms2 = dist_obsvecs[jj][ii]->rms();
 
  366       double dot2 = dist_obsvecs[jj][ii]->dot_product_with(*dist_obsvecs[jj][ii]);
 
  368       EXPECT(nobs == nobs2);
 
  369       EXPECT(oops::is_close(rms, rms2, 1.0e-12));
 
  370       EXPECT(oops::is_close(dot, dot2, 1.0e-12));
 
  380   typedef ObsVecTestFixture Test_;
 
  393   std::string 
testid()
 const override {
return "test::ObsVector<ioda::IodaTrait>";}
 
  396     std::vector<eckit::testing::Test>& ts = eckit::testing::specification();
 
  398      ts.emplace_back(
CASE(
"ioda/ObsVector/testConstructor")
 
  400      ts.emplace_back(
CASE(
"ioda/ObsVector/testCopyConstructor")
 
  402      ts.emplace_back(
CASE(
"ioda/ObsVector/testNotZero")
 
  404      ts.emplace_back(
CASE(
"ioda/ObsVector/testRead")
 
  406      ts.emplace_back(
CASE(
"ioda/ObsVector/testSave")
 
  408      ts.emplace_back(
CASE(
"ioda/ObsVector/testAxpy")
 
  410      ts.emplace_back(
CASE(
"ioda/ObsVector/testDotProduct")
 
  412      ts.emplace_back(
CASE(
"ioda/ObsVector/testDistributedMath")
 
  414      ts.emplace_back(
CASE(
"ioda/ObsVector/testCleanup")
 
ObsVector class to handle vectors in observation space for IODA.
 
static ObsVecTestFixture & getInstance()
 
std::vector< boost::shared_ptr< ObsSpace_ > > ospaces_
 
static std::vector< boost::shared_ptr< ObsSpace_ > > & obspace()
 
std::string testid() const override
 
void clear() const override
 
void register_tests() const override
 
CASE("Derived variable, unit conversion, and exception checking methods")
 
void testAxpy()
tests ObsVector::axpy methods
 
void testCopyConstructor()
 
void testDotProduct()
tests ObsVector::dot_product methods
 
void testDistributedMath()