IODA
ObsIoRead.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2018 UCAR
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_IO_OBSIOREAD_H_
9 #define TEST_IO_OBSIOREAD_H_
10 
11 #include <algorithm>
12 #include <functional>
13 #include <map>
14 #include <memory>
15 #include <numeric>
16 #include <string>
17 #include <utility>
18 #include <vector>
19 
20 #define ECKIT_TESTING_SELF_REGISTER_CASES 0
21 
22 #include "eckit/config/LocalConfiguration.h"
23 #include "eckit/testing/Test.h"
24 
25 #include "oops/mpi/mpi.h"
26 #include "oops/runs/Test.h"
27 #include "oops/test/TestEnvironment.h"
28 #include "oops/util/DateTime.h"
29 #include "oops/util/FloatCompare.h"
30 #include "oops/util/Logger.h"
31 
32 #include "ioda/core/IodaUtils.h"
33 #include "ioda/distribution/DistributionFactory.h"
34 #include "ioda/io/ObsIo.h"
35 #include "ioda/io/ObsIoFactory.h"
36 #include "ioda/ObsGroup.h"
37 #include "ioda/ObsSpaceParameters.h"
39 
40 namespace ioda {
41 namespace test {
42 
43 // -----------------------------------------------------------------------------
44 // Helper Functions
45 // -----------------------------------------------------------------------------
46 
47 // -----------------------------------------------------------------------------
48 // Test Functions
49 // -----------------------------------------------------------------------------
50 
51 // -----------------------------------------------------------------------------
52 void testRead() {
53  const eckit::LocalConfiguration conf(::test::TestEnvironment::config());
54  std::vector<eckit::LocalConfiguration> confOspaces = conf.getSubConfigurations("observations");
55  util::DateTime bgn(::test::TestEnvironment::config().getString("window begin"));
56  util::DateTime end(::test::TestEnvironment::config().getString("window end"));
57 
58  for (std::size_t i = 0; i < confOspaces.size(); ++i) {
59  eckit::LocalConfiguration obsConfig;
60  eckit::LocalConfiguration testConfig;
61  confOspaces[i].get("obs space", obsConfig);
62  confOspaces[i].get("test data", testConfig);
63  oops::Log::trace() << "ObsIo testRead obs space config: " << i << ": "
64  << obsConfig << std::endl;
65  oops::Log::trace() << "ObsIo testRead test data config: " << i << ": "
66  << testConfig << std::endl;
67 
69  topParams.validateAndDeserialize(obsConfig);
70  ioda::ObsSpaceParameters obsParams(topParams, bgn, end,
71  oops::mpi::world(), oops::mpi::myself());
72 
73  // Input constructor
74  std::shared_ptr<ObsIo> obsIo;
75  obsIo = ObsIoFactory::create(ObsIoModes::READ, obsParams);
76 
77  // Try reading a couple variables
78  float floatTol = testConfig.getFloat("tolerance", 1.0e-5);
79  std::vector<eckit::LocalConfiguration> readVarConfigs =
80  testConfig.getSubConfigurations("read variables");
81 
82  for (std::size_t ivar = 0; ivar < readVarConfigs.size(); ++ivar) {
83  std::string varName = readVarConfigs[ivar].getString("name");
84  std::string expectedVarType = readVarConfigs[ivar].getString("type");
85  ioda::Variable var = obsIo->vars().open(varName);
86 
87  if (expectedVarType == "int") {
88  EXPECT(var.isA<int>());
89  std::vector<int> expectedVarValues =
90  readVarConfigs[ivar].getIntVector("values");
91  std::vector<int> varValues;
92  var.read<int>(varValues);
93  for (std::size_t ival = 0; ival < expectedVarValues.size(); ++ival) {
94  EXPECT_EQUAL(varValues[ival], expectedVarValues[ival]);
95  }
96  } else if (expectedVarType == "float") {
97  EXPECT(var.isA<float>());
98  std::vector<float> expectedVarValues =
99  readVarConfigs[ivar].getFloatVector("values");
100  std::vector<float> varValues;
101  var.read<float>(varValues);
102  for (std::size_t ival = 0; ival < expectedVarValues.size(); ++ival) {
103  EXPECT(oops::is_close_relative(varValues[ival],
104  expectedVarValues[ival], floatTol));
105  }
106  } else if (expectedVarType == "string") {
107  EXPECT(var.isA<std::string>());
108  std::vector<std::string> expectedVarValues =
109  readVarConfigs[ivar].getStringVector("values");
110  std::vector<std::string> varValues;
111  Dimensions varDims = var.getDimensions();
112  if (varDims.dimensionality > 1) {
113  std::vector<Dimensions_t> varShape = var.getDimensions().dimsCur;
114  std::vector<std::string> stringArray = var.readAsVector<std::string>();
115  varValues = StringArrayToStringVector(stringArray, varShape);
116  } else {
117  var.read<std::string>(varValues);
118  }
119  for (std::size_t ival = 0; ival < expectedVarValues.size(); ++ival) {
120  EXPECT_EQUAL(varValues[ival], expectedVarValues[ival]);
121  }
122  }
123  }
124  }
125 }
126 
127 // -----------------------------------------------------------------------------
128 
129 class ObsIoRead : public oops::Test {
130  public:
132  virtual ~ObsIoRead() {}
133  private:
134  std::string testid() const override {return "test::ObsIoRead";}
135 
136  void register_tests() const override {
137  std::vector<eckit::testing::Test>& ts = eckit::testing::specification();
138 
139  ts.emplace_back(CASE("ioda/ObsIoRead/testRead")
140  { testRead(); });
141  }
142 
143  void clear() const override {}
144 };
145 
146 // -----------------------------------------------------------------------------
147 
148 } // namespace test
149 } // namespace ioda
150 
151 #endif // TEST_IO_OBSIOREAD_H_
Interfaces for ioda::ObsGroup and related classes.
Interfaces for ioda::Variable and related classes.
static std::shared_ptr< ObsIo > create(ObsIoModes mode, const ObsSpaceParameters &parameters)
Create and return a new instance of an ObsIo subclass.
Definition: ObsIoFactory.cc:24
Variables store data!
Definition: Variable.h:680
bool isA() const
Convenience function to check a Variable's storage type.
Definition: Variable.h:99
virtual Dimensions getDimensions() const
Definition: Variable.cpp:160
std::vector< DataType > readAsVector(const Selection &mem_selection=Selection::all, const Selection &file_selection=Selection::all) const
Read the variable into a new vector. Python convenience function.
Definition: Variable.h:502
virtual Variable read(gsl::span< char > data, const Type &in_memory_dataType, const Selection &mem_selection=Selection::all, const Selection &file_selection=Selection::all) const
Read the Variable - as char array. Ordering is row-major.
Definition: Variable.cpp:330
void clear() const override
Definition: ObsIoRead.h:143
virtual ~ObsIoRead()
Definition: ObsIoRead.h:132
void register_tests() const override
Definition: ObsIoRead.h:136
std::string testid() const override
Definition: ObsIoRead.h:134
CASE("Derived variable, unit conversion, and exception checking methods")
std::vector< std::string > StringArrayToStringVector(const std::vector< std::string > &arrayData, const std::vector< Dimensions_t > &arrayShape)
convert 2D string array to a vector of strings
Definition: IodaUtils.cc:274
std::vector< Dimensions_t > dimsCur
The dimensions of the data.
Definition: Dimensions.h:23