11 #include <type_traits>
13 #include "eckit/exception/Exceptions.h"
16 #include <boost/algorithm/string.hpp>
27 description_(description)
31 std::map<SubCategory, ioda::ObsGroup>
36 std::map<SubCategory, ioda::ObsGroup> obsGroups;
38 for (
const auto& categories : dataContainer->allSubCategories())
46 std::map<std::string, std::string> substitutions;
47 for (
const auto &catPair : dataContainer->getCategoryMap())
49 substitutions.insert({catPair.first, categories.at(catIdx)});
59 ioda::Engines::BackendFileActions::Create;
60 backendParams.flush =
true;
61 backendParams.allocBytes = dataContainer->size(categories);
66 bool foundInvalidDim =
false;
73 size = std::stoi(scale.size);
77 std::string
token = scale.size.substr(scale.size.find(
'.') + 1,
80 std::string varName = scale.size.substr(0,
81 scale.size.find(
'.'));
85 size = dataContainer->get(varName, categories)->ncols();
87 else if (
token ==
"nrows")
89 size = dataContainer->get(varName, categories)->nrows();
93 std::ostringstream errStr;
94 errStr <<
"Tried to get unknown parameter " <<
token;
95 errStr <<
" from " << varName;
96 throw eckit::BadParameter(errStr.str());
100 auto newDim = ioda::NewDimensionScale<int>(scale.name, size);
103 if (size <= 0) { foundInvalidDim =
true; }
115 auto scaleMap = std::map<std::string, ioda::Variable>();
118 scaleMap.insert({scale.name, obsGroup.vars[scale.name]});
124 global->addTo(rootGroup);
130 std::vector<ioda::Dimensions_t>
chunks;
131 auto dimensions = std::vector<ioda::Variable>();
132 for (
size_t dimIdx = 0; dimIdx < varDesc.dimensions.size(); dimIdx++)
134 auto dimVar = scaleMap.at(varDesc.dimensions[dimIdx]);
135 dimensions.push_back(dimVar);
137 if (dimIdx < varDesc.chunks.size())
139 chunks.push_back(std::min(dimVar.getChunkSizes()[0],
140 varDesc.chunks[dimIdx]));
144 chunks.push_back(dimVar.getChunkSizes()[0]);
148 auto data = dataContainer->get(varDesc.source, categories);
149 auto var = data->createVariable(obsGroup,
153 varDesc.compressionLevel);
157 var.atts.add<std::string>(
"long_name", { varDesc.longName }, {1});
158 var.atts.add<std::string>(
"units", { varDesc.units }, {1});
160 if (varDesc.coordinates)
162 var.atts.add<std::string>(
"coordinates", { *varDesc.coordinates }, {1});
168 {varDesc.range->start, varDesc.range->end},
173 obsGroups.insert({categories, obsGroup});
180 const std::map<std::string, std::string>& subMap)
182 auto resultStr = prototype;
185 std::reverse(subIdxs.begin(), subIdxs.end());
187 for (
const auto& subs : subIdxs)
189 if (subMap.find(subs.first) != subMap.end())
191 auto repIdxs = subs.second;
192 resultStr = resultStr.replace(repIdxs.first,
193 repIdxs.second - repIdxs.first + 1,
194 subMap.at(subs.first));
198 std::ostringstream errStr;
199 errStr <<
"Can't find " << subs.first <<
". No category with that name.";
200 throw eckit::BadParameter(errStr.str());
207 std::vector<std::pair<std::string, std::pair<int, int>>>
210 std::vector<std::pair<std::string, std::pair<int, int>>> result;
215 while (startPos <
str.size())
217 startPos =
str.find(
"{", startPos+1);
219 if (startPos <
str.size())
221 endPos =
str.find(
"}", startPos+1);
223 if (endPos <
str.size())
225 result.push_back({
str.substr(startPos + 1, endPos - startPos - 1),
226 {startPos, endPos}});
231 throw eckit::BadParameter(
"Unmatched { found in output filename.");
248 for (
auto it =
str.begin(); it !=
str.end(); it++)
250 if (!std::isdigit(*it))
Contains definitions for how data are arranged in ioda internally.
Describes how to write data to IODA.
ioda::Engines::BackendNames getBackend() const
VariableDescriptions getVariables() const
GlobalDescriptions getGlobals() const
std::string getFilepath() const
DimDescriptions getDims() const
IodaEncoder(const eckit::Configuration &conf)
std::map< SubCategory, ioda::ObsGroup > encode(const std::shared_ptr< DataContainer > &data, bool append=false)
Encode the data into an ioda::ObsGroup object.
std::string makeStrWithSubstitions(const std::string &prototype, const std::map< std::string, std::string > &subMap)
Create a string from a template string.
const IodaDescription description_
The description.
std::vector< std::pair< std::string, std::pair< int, int > > > findSubIdxs(const std::string &str)
Used to find indecies of { and } by the makeStrWithSubstitions method.
bool isInteger(const std::string &str) const
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.
static std::shared_ptr< const DataLayoutPolicy > generate(const std::string &polid="")
Factory generator.
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...
@ Open
Open an existing file.
@ Hdf5File
HDF5 file access.
@ Truncate_If_Exists
If the file already exists, overwrite it.
@ Read_Write
Open the file in read-write mode.
std::vector< std::shared_ptr< NewDimensionScale_Base > > NewDimensionScales_t
Used to specify backend creation-time properties.