23 std::shared_ptr<const DataLayoutPolicy> layoutPolicy)
24 : backend_{b}, layout_{layoutPolicy}
30 "An exception occurred in ioda in Has_Variables_Base's constructor.",
ioda_Here()));
46 return backend_->getFillValuePolicy();
49 "An exception occurred in ioda while determining the fill value policy of a backend.",
65 "An exception occurred in ioda while getting a backend's type provider interface.",
79 "An exception occurred inside ioda while checking variable existence.",
ioda_Here())
93 "An exception occurred inside ioda while removing a variable.",
ioda_Here())
107 "An exception occurred inside ioda while opening a variable.",
ioda_Here())
114 if (
layout_->name() != std::string(
"ObsGroup ODB v1"))
return;
115 std::vector<std::string> variableList =
list();
116 for (
auto const&
name : variableList) {
117 const std::string destinationName =
layout_->doMap(
name);
118 if (
layout_->isComplementary(destinationName)) {
119 size_t position =
layout_->getComplementaryPosition(destinationName);
120 std::string outputName =
layout_->getOutputNameFromComponent(destinationName);
121 bool oneVariableStitch =
false;
122 if (
layout_->getInputsNeeded(destinationName) == 1) oneVariableStitch =
true;
124 bool outputVariableMetadataPreviouslyGenerated =
true;
130 return compParam.outputName == outputName;
133 outputVariableMetadataPreviouslyGenerated =
false;
139 if (outputVariableMetadataPreviouslyGenerated || oneVariableStitch) {
141 if (oneVariableStitch) {
144 derivedVariableParams = &(*it);
152 std::vector<std::vector<std::string>> mergeMethodInput
159 = this->create<std::string>(derivedVariableParams->
outputName,
160 {gsl::narrow<ioda::Dimensions_t>(derivedVector.size())});
161 derivedVariable.
write(derivedVector);
163 if (removeOriginals) {
173 "An exception occurred inside ioda.",
ioda_Here()));
179 if (
layout_->name() != std::string(
"ObsGroup ODB v1"))
return;
180 std::vector<std::string> variableList =
list();
181 for (
auto const&
name : variableList) {
182 const std::string destinationName =
layout_->doMap(
name);
183 if (!
layout_->isMapped(destinationName))
continue;
186 auto unit =
layout_->getUnit(destinationName);
187 if (unit.first ==
true) {
188 Variable variableToConvert = this->
open(destinationName);
190 std::vector<double> outputData = variableToConvert.
readAsVector<
double>();
192 variableToConvert.
write(outputData);
194 }
catch (std::invalid_argument) {
195 out <<
"The unit specified in ODB mapping file '" << unit.second
196 <<
"' does not have a unit conversion defined in"
197 <<
" UnitConversions.h, and the variable will be stored in"
198 <<
" its original form.\n";
199 variableToConvert.
atts.
add<std::string>(
"units", unit.second);
209 const std::string &inputName,
const std::string &outputName,
size_t position) {
212 const std::string destName =
layout_->doMap(inputName);
220 return newDerivedVariable;
223 "An exception occurred inside ioda.",
ioda_Here())
224 .add(
"inputName", inputName).add(
"outputName", outputName).add(
"position", position));
232 std::vector<std::vector<std::string>> mergeMethodInput;
233 for (
size_t inputVariableIdx = 0;
237 mergeMethodInput.push_back(inputVariable.
readAsVector<std::string>());
239 return mergeMethodInput;
242 "An exception occurred inside ioda.",
ioda_Here()));
255 "An exception occurred inside ioda while listing one-level child variables of a group.",
262 const std::vector<Dimensions_t>& cur_dimensions,
263 const std::vector<Dimensions_t>& max_dimensions,
264 const std::vector<Variable>& dimension_scales,
269 if (dimension_scales.size()) {
270 std::vector<Dimensions_t> c_d, m_d, chunking_hints;
272 for (
size_t i = 0; i < dimension_scales.size(); ++i) {
273 const auto& varDims = dimension_scales[i];
274 const auto& d = varDims.getDimensions();
275 c_d.push_back(d.dimsCur[0]);
276 m_d.push_back(d.dimsMax[0]);
277 if (varDims.atts.exists(
"suggested_chunk_dim"))
278 chunking_hints.push_back(varDims.atts.read<Dimensions_t>(
"suggested_chunk_dim"));
280 chunking_hints.push_back(-1);
284 params2.
chunk =
true;
285 if (!params2.
chunks.size()) params2.
chunks = chunking_hints;
290 auto var =
create(
name, typ, c_d, m_d, params2);
291 var.setDimScale(dimension_scales);
297 "An exception occurred inside ioda.",
ioda_Here()));
304 using namespace FillValuePolicies;
326 if (fvp_map.count(dataType))
327 fvp_map.at(dataType)(fvp,
params.fillValue_);
336 const std::vector<std::pair<
Variable, std::vector<Variable>>>& mapping) {
340 backend_->attachDimensionScales(mapping);
343 "An exception occurred inside ioda while attaching dimension scales.",
ioda_Here()));
348 const std::vector<std::pair<
Variable, std::vector<Variable>>>& mapping) {
350 for (
auto& m : mapping) {
358 "An exception occurred inside ioda while attaching dimension scales.",
ioda_Here()));
363 const std::vector<Dimensions_t>& dimensions,
364 const std::vector<Dimensions_t>& max_dimensions,
372 std::vector<Dimensions_t> fixed_max_dimensions
373 = (max_dimensions.size()) ? max_dimensions : dimensions;
375 fixed_max_dimensions,
params);
376 params.applyImmediatelyAfterVariableCreation(newVar);
380 std::string eMessage =
"The following variable was not remapped in the YAML file: '" +
name +
381 "'. Ensure that the fundamental dimensions are declared in 'generate'.";
387 "An exception occurred inside ioda while creating a variable.",
ioda_Here())
399 vector<pair<Variable, vector<Variable>>> scaleMappings;
400 scaleMappings.reserve(newvars.size());
402 for (
const auto& newvar : newvars) {
404 Type t = (newvar->dataTypeKnown_.isValid())
405 ? newvar->dataTypeKnown_
407 std::vector<Dimensions_t> dimensions, max_dimensions, chunking_hints;
408 for (
size_t i = 0; i < newvar->scales_.size(); ++i) {
409 const auto& varDims = newvar->scales_[i];
410 const auto& d = varDims.getDimensions();
411 dimensions.push_back(d.dimsCur[0]);
412 max_dimensions.push_back(d.dimsMax[0]);
413 if (varDims.atts.exists(
"suggested_chunk_dim"))
414 chunking_hints.push_back(varDims.atts.read<Dimensions_t>(
"suggested_chunk_dim"));
416 chunking_hints.push_back(-1);
429 params2.
chunk =
true;
430 if (!params2.
chunks.size()) params2.
chunks = chunking_hints;
432 auto var =
create(newvar->name_, t, dimensions, max_dimensions, params2);
433 using std::make_pair;
434 scaleMappings.push_back(make_pair(var, newvar->scales_));
440 "An exception occurred inside ioda while creating variable(s).",
ioda_Here()));
449 std::shared_ptr<const detail::DataLayoutPolicy> pol)
450 : Has_Variables_Base(b, pol) {}
454 : fillValue_{r.fillValue_},
459 gzip_level_{r.gzip_level_},
460 szip_PixelsPerBlock_{r.szip_PixelsPerBlock_},
461 szip_options_{r.szip_options_},
463 _py_setFillValue{this} {}
467 if (
this == &r)
return *
this;
505 "An exception occurred inside ioda while adding attributes to an object.",
ioda_Here()));
Interfaces for ioda::Has_Variables and related classes.
Contains definitions for how data are arranged in ioda internally.
Utility functions and structs for combining multiple variables into one.
Basic arithmetic unit conversions to SI.
void apply(Has_Attributes &obj) const
The ioda exception class.
Represents the "type" (i.e. integer, string, float) of a piece of data.
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.
@ None
Do no manipulation of the Group / Variable layout.
@ Concat
Concatenate complementary variables entry-by-entry.
virtual ~Has_Variables_Backend()
void attachDimensionScales(const std::vector< std::pair< Variable, std::vector< Variable >>> &mapping) override
Attach dimension scales to many Dimension Numbers in a set of Variables.
FillValuePolicy getFillValuePolicy() const override
Get the fill value policy used for Variables within this Group.
virtual Variable create(const std::string &name, const Type &in_memory_dataType, const std::vector< Dimensions_t > &dimensions={1}, const std::vector< Dimensions_t > &max_dimensions={}, const VariableCreationParameters ¶ms=VariableCreationParameters())
Create a Variable without setting its data.
std::shared_ptr< const detail::DataLayoutPolicy > layout_
Set by ObsGroup.
Has_Variables_Base(std::shared_ptr< Has_Variables_Backend >, std::shared_ptr< const DataLayoutPolicy >=nullptr)
virtual void setLayout(std::shared_ptr< const detail::DataLayoutPolicy >)
void convertVariableUnits(std::ostream &out=std::cerr)
Converts unit to SI for all eligible variables. If conversion function not defined,...
Variable createWithScales(const std::string &name, const std::vector< Variable > &dimension_scales, const VariableCreationParameters ¶ms=VariableCreationParameters::defaulted< DataType >())
Convenience function to create a Variable from certain dimension scales.
virtual ~Has_Variables_Base()
virtual FillValuePolicy getFillValuePolicy() const
Get the fill value policy used for Variables within this Group.
virtual Variable open(const std::string &name) const
Open a Variable by name.
virtual std::vector< std::string > list() const
virtual Type_Provider * getTypeProvider() const
Query the backend and get the type provider.
std::vector< ComplementaryVariableCreationParameters > complementaryVariables_
virtual void attachDimensionScales(const std::vector< std::pair< Variable, std::vector< Variable >>> &mapping)
Attach dimension scales to many Dimension Numbers in a set of Variables.
std::shared_ptr< Has_Variables_Backend > backend_
Using an opaque object to implement the backend.
virtual bool exists(const std::string &name) const
Does a Variable with the specified name exist?
std::vector< std::vector< std::string > > loadComponentVariableData(const ComplementaryVariableCreationParameters &derivedVariableParams)
virtual void remove(const std::string &name)
Delete an Attribute with the specified name.
static void _py_fvp_helper(BasicTypes dataType, FillValuePolicy &fvp, VariableCreationParameters ¶ms)
FillValuePolicy helper.
Variable _create_py(const std::string &name, BasicTypes dataType, const std::vector< Dimensions_t > &cur_dimensions={1}, const std::vector< Dimensions_t > &max_dimensions={}, const std::vector< Variable > &dimension_scales={}, const VariableCreationParameters ¶ms=VariableCreationParameters())
ComplementaryVariableCreationParameters createDerivedVariableParameters(const std::string &inputName, const std::string &outputName, size_t position)
void stitchComplementaryVariables(bool removeOriginals=true)
Combines all complementary variables as specified in the mapping file, opens them,...
detail::Type_Provider * getTypeProvider() const
Get the type provider.
Backends implement type providers in conjunction with Attributes, Has_Attributes, Variables and Has_V...
virtual Type makeFundamentalType(std::type_index type) const
Make a basic object type, like a double, a float, or a char.
Variable setDimScale(const std::vector< Variable > &dims)
Set dimensions (convenience function to several invocations of attachDimensionScale).
Has_Attributes atts
Attributes.
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.
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.
FillValuePolicy
This option describes the default fill values that will be used if the user does not manually specify...
@ NETCDF4
Use NetCDF4 default fill values. This is the default option for ioda files.
std::vector< std::shared_ptr< NewVariable_Base > > NewVariables_t
IODA_DL std::string getSIUnit(const std::string &unit)
IODA_DL void convertColumn(const std::string &unit, std::vector< double > &dataToConvert)
IODA_DL std::vector< std::string > concatenateStringVectors(const std::vector< std::vector< std::string >> &stringVectors)
Concatenate equal-length vectors of strings element-by-element. Removes trailing spaces.
size_t inputVarsNeededCount
size_t inputVarsEnteredCount
ioda::detail::DataLayoutPolicy::MergeMethod mergeMethod
std::vector< std::string > inputVariableNames
Used to specify Variable creation-time properties.
Variable applyImmediatelyAfterVariableCreation(Variable h) const
Apply the properties to a Variable (second pass; after Variable is created).
detail::python_bindings::VariableCreationFillValues< VariableCreationParameters > _py_setFillValue
void compressWithGZIP(int level=6)
unsigned int szip_PixelsPerBlock_
Attribute_Creator_Store atts
Set any initial attributes here.
detail::FillValueData_t fillValue_
std::vector< Dimensions_t > chunks
Manually specify the chunks. Never directly use. Use getChunks(...) instead.
VariableCreationParameters()
VariableCreationParameters & operator=(const VariableCreationParameters &)
unsigned int szip_options_
void compressWithSZIP(unsigned PixelsPerBlock=16, unsigned options=4)
bool chunk
Do we chunk this variable? Required for extendible / compressible Variables.
Container used to store and manipulate fill values.