16 #include "Eigen/Dense" 
   17 #include "eckit/testing/Test.h" 
   23 #include "ioda/testconfig.h" 
   26                                 const std::string mappingFile = 
"") {
 
   40   std::vector<int> nLocs(locationsX2);
 
   41   std::iota(nLocs.begin(), nLocs.end(), 0);
 
   44   std::iota(nChans.begin(), nChans.end(), 1);
 
   46   Eigen::ArrayXXf myDataExpected(locationsX2, 
channels);
 
   47   std::vector<float> myLonExpected(locationsX2);
 
   48   std::vector<float> myLatExpected(locationsX2);
 
   49   auto mid_loc = 
static_cast<float>(
locations);
 
   50   auto mid_chan = 
static_cast<float>(
channels) / 2.0f;
 
   51   for (std::size_t i = 0; i < locationsX2; ++i) {
 
   52     myLonExpected[i] = 
static_cast<float>(i % 8) * 3.0f;
 
   53     myLatExpected[i] = 
static_cast<float>(i / 8) * 3.0f;  
 
   54     for (std::size_t j = 0; j < 
channels; ++j) {
 
   55       float del_i = 
static_cast<float>(i) - mid_loc;
 
   56       float del_j = 
static_cast<float>(j) - mid_chan;
 
   57       myDataExpected(i, j) = sqrt(del_i * del_i + del_j * del_j);
 
   67   std::vector<float> myLatExpected1(myLatExpected.begin(), myLatExpected.begin() + 
locations);
 
   68   std::vector<float> myLatExpected2(myLatExpected.begin() + 
locations, myLatExpected.end());
 
   69   std::vector<float> myLonExpected1(myLonExpected.begin(), myLonExpected.begin() + 
locations);
 
   70   std::vector<float> myLonExpected2(myLonExpected.begin() + 
locations, myLonExpected.end());
 
   71   std::vector<int> nLocs1(nLocs.begin(), nLocs.begin() + 
locations);
 
   72   std::vector<int> nLocs2(nLocs.begin() + 
locations, nLocs.end());
 
   77   if (backendType == 
"file" || backendType == 
"fileRemapped") {
 
   83   } 
else if (backendType == 
"memory") {
 
   87             .
add(
"backendType", backendType);
 
   93   if (backendType != 
"fileRemapped") {
 
  103             NewDimensionScale<int>(
 
  105             NewDimensionScale<int>(
 
  108                                              mappingFile, {
"nlocs", 
"nchans"}));
 
  111   nlocs_var.
write(nLocs1);
 
  114   nchans_var.
write(nChans);
 
  118   float_params.
chunk = 
true;
 
  125   if (backendType == 
"fileRemapped") {
 
  126     obs_var = 
og.vars.createWithScales<
float>(
"ObsValue_renamed/myObs_renamed", {nlocs_var, nchans_var}, float_params);
 
  128     og.vars.createWithScales<
float>(
"MetaData_renamed/latitude_renamed", {nlocs_var}, float_params);
 
  129     lat_var = 
og.vars.open(
"MetaData/latitude");
 
  131     og.vars.createWithScales<
float>(
"MetaData_renamed/longitude_renamed", {nlocs_var}, float_params);
 
  132     lon_var = 
og.vars[
"MetaData/longitude"];
 
  135     bool unspecifiedVariableThrows = 
false;
 
  137       og.vars.createWithScales<
float>(
"Foo/bar", {nlocs_var}, float_params);
 
  139       unspecifiedVariableThrows = 
true;
 
  141     if (!unspecifiedVariableThrows) {
 
  142       throw Exception(
"Foo/bar did not throw an exception");
 
  145     obs_var = 
og.vars.createWithScales<
float>(
"ObsValue/myObs", {nlocs_var, nchans_var}, float_params);
 
  147     og.vars.createWithScales<
float>(
"MetaData/latitude", {nlocs_var}, float_params);
 
  148     lat_var = 
og.vars.open(
"MetaData/latitude");
 
  150     og.vars.createWithScales<
float>(
"MetaData/longitude", {nlocs_var}, float_params);
 
  151     lon_var = 
og.vars[
"MetaData/longitude"];
 
  155   obs_var.atts.add<std::string>(
"coordinates", {
"longitude latitude nchans"}, {1})
 
  156     .add<std::string>(
"long_name", {
"obs I made up"}, {1})
 
  157     .add<std::string>(
"units", {
"K"}, {1})
 
  158     .add<float>(
"valid_range", {0.0, 50.0}, {2});
 
  159   lat_var.
atts.
add<std::string>(
"long_name", {
"latitude"}, {1})
 
  160     .add<std::string>(
"units", {
"degrees_north"}, {1})
 
  161     .add<float>(
"valid_range", {-90.0, 90.0}, {2});
 
  162   lon_var.
atts.
add<std::string>(
"long_name", {
"longitude"}, {1})
 
  163     .add<std::string>(
"units", {
"degrees_east"}, {1})
 
  164     .add<float>(
"valid_range", {-360.0, 360.0}, {2});
 
  167   obs_var.writeWithEigenRegular(myDataExpected1);
 
  168   lat_var.
write(myLatExpected1);
 
  169   lon_var.
write(myLonExpected1);
 
  173   og.resize({std::pair<ioda::Variable, ioda::Dimensions_t>(nlocs_var, locationsX2)});
 
  176   std::vector<ioda::Dimensions_t> memStarts(1, 0);
 
  177   std::vector<ioda::Dimensions_t> memCounts(1, 
locations);
 
  178   std::vector<ioda::Dimensions_t> fileStarts(1, 
locations);
 
  179   std::vector<ioda::Dimensions_t> fileCounts(1, 
locations);
 
  187   memStarts.push_back(0);  
 
  189   fileStarts.push_back(0);
 
  198   nlocs_var.
write(nLocs2, memSelect1D, fileSelect1D);
 
  200   lat_var.
write(myLatExpected2, memSelect1D, fileSelect1D);
 
  201   lon_var.
write(myLonExpected2, memSelect1D, fileSelect1D);
 
  204   Eigen::ArrayXXf myData(locationsX2, 
channels);
 
  205   obs_var.readWithEigenRegular(myData);
 
  206   if (!myData.isApprox(myDataExpected)) {
 
  210   std::vector<float> myLats(locationsX2, 0.0);
 
  211   lat_var.
read(myLats);
 
  212   for (std::size_t i = 0; i < locationsX2; ++i) {
 
  213     double check = fabs((myLats[i] / myLatExpected[i]) - 1.0);
 
  214     if (check > 1.0e-3) {
 
  217               .
add(
"  myLatExpected[i]", myLatExpected[i])
 
  218               .
add(
"  myLats[i]", myLats[i]);
 
  222   std::vector<float> myLons(locationsX2, 0.0);
 
  223   lon_var.
read(myLons);
 
  224   for (std::size_t i = 0; i < locationsX2; ++i) {
 
  225     double check = fabs((myLons[i] / myLonExpected[i]) - 1.0);
 
  226     if (check > 1.0e-3) {
 
  229               .
add(
"  myLonExpected[i]", myLonExpected[i])
 
  230               .
add(
"  myLons[i]", myLons[i]);
 
  235   Expects(
og.open(
"ObsValue").vars[
"myObs"].isDimensionScaleAttached(1, 
og.vars[
"nchans"]));
 
  238 int main(
int argc, 
char** argv) {
 
  240     std::cerr << 
"Need to specify backend type (file, memory)" << std::endl;
 
  243   std::string backendType(argv[1]);
 
  245     if (backendType == 
"file") {
 
  246       std::cout << 
"Testing file backend" << std::endl;
 
  248     } 
else if (backendType == 
"memory") {
 
  249       std::cout << 
"Testing memory backend" << std::endl;
 
  251     } 
else if (backendType == 
"fileRemapped") {
 
  252       std::cout << 
"Testing ODB Data Layout Policy with explicit mapping file" << std::endl;
 
  253       std::string mappingFile = std::string(IODA_ENGINES_TEST_SOURCE_DIR)
 
  254         + 
"/obsgroup/odb_default_name_map.yaml";
 
  256       std::cout << 
"Testing ODB Data Layout Policy with explicit mapping file" << std::endl;
 
  257       mappingFile = std::string(IODA_ENGINES_TEST_SOURCE_DIR)
 
  258         + 
"/obsgroup/odb_incomplete_name_map.yaml";
 
  259       bool failedWhenNotAllVarsRemapped = 
false;
 
  262       } 
catch (
const std::exception &e) {
 
  263         failedWhenNotAllVarsRemapped = 
true;
 
  265       bool odbGroupFailedWithoutMapping = 
false;
 
  269       } 
catch (
const std::exception& e) {
 
  270         odbGroupFailedWithoutMapping = 
true;
 
  272       assert(odbGroupFailedWithoutMapping && failedWhenNotAllVarsRemapped);
 
  275               .
add(
"Backend type", backendType);
 
  277   } 
catch (
const std::exception& e) {
 
Definitions for setting up backends with file and memory I/O.
Contains definitions for how data are arranged in ioda internally.
Interfaces for ioda::ObsGroup and related classes.
The ioda exception class.
Exception & add(const std::string &key, const T value)
Add a key-value pair to the error message.
Groups are a new implementation of ObsSpaces.
An ObsGroup is a specialization of a ioda::Group. It provides convenience functions and guarantees th...
static ObsGroup generate(Group &emptyGroup, const NewDimensionScales_t &fundamentalDims, std::shared_ptr< const detail::DataLayoutPolicy > layout=nullptr)
Create an empty ObsGroup and populate it with the fundamental dimensions.
A Selection represents the bounds of the data, in ioda or in userspace, that you are reading or writi...
DerivedHasAtts add(const std::string &attrname, ::gsl::span< const DataType > data, const ::std::vector< Dimensions_t > &dimensions)
Create and write an Attribute, for arbitrary dimensions.
static std::shared_ptr< const DataLayoutPolicy > generate(const std::string &polid="")
Factory generator.
Variable_Implementation writeWithEigenRegular(const EigenClass &d, const Selection &mem_selection=Selection::all, const Selection &file_selection=Selection::all)
Write an Eigen object (a Matrix, an Array, a Block, a Map).
Has_Attributes atts
Attributes.
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.
virtual Variable write(gsl::span< char > data, const Type &in_memory_dataType, const Selection &mem_selection=Selection::all, const Selection &file_selection=Selection::all)
The fundamental write function. Backends overload this function to implement all write operations.
BackendNames
Backend names.
IODA_DL Group constructBackend(BackendNames name, BackendCreationParameters ¶ms)
This is a simple factory style function that will instantiate a different backend based on a given na...
@ Create
Create a new file.
@ Hdf5File
HDF5 file access.
@ ObsStore
ObsStore in-memory.
@ Truncate_If_Exists
If the file already exists, overwrite it.
Selection & extent(const VecDimensions_t &sz)
Provide the dimensions of the object that you are selecting from.
Selection & select(const SingleSelection &s)
Append a new selection.
constexpr int Unlimited
Specifies that a dimension is resizable to infinity.
IODA_DL void unwind_exception_stack(const std::exception &e, std::ostream &out=std::cerr, int level=0)
Convenience function for unwinding an exception stack.
Used to specify backend creation-time properties.
BackendFileActions action
BackendCreateModes createMode
Used to specify Variable creation-time properties.
void compressWithGZIP(int level=6)
VariableCreationParameters & setFillValue(DataType fill)
bool chunk
Do we chunk this variable? Required for extendible / compressible Variables.
int main(int argc, char **argv)
void test_obsgroup_helper_funcs(std::string backendType, std::string fileName, const std::string mappingFile="")