IODA
Has_Variables.cpp
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2021 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  */
8 
9 #include "ioda/Exception.h"
10 #include "ioda/Layout.h"
11 #include "ioda/Misc/MergeMethods.h"
12 #include "ioda/Misc/StringFuncs.h"
14 
15 #include <stdexcept>
16 
17 namespace ioda {
18 namespace detail {
19 
21 
22 Has_Variables_Base::Has_Variables_Base(std::shared_ptr<Has_Variables_Backend> b,
23  std::shared_ptr<const DataLayoutPolicy> layoutPolicy)
24  : backend_{b}, layout_{layoutPolicy}
25 {
26  try {
28  } catch (...) {
29  std::throw_with_nested(Exception(
30  "An exception occurred in ioda in Has_Variables_Base's constructor.", ioda_Here()));
31  }
32 }
33 
35 
37 
38 void Has_Variables_Base::setLayout(std::shared_ptr<const detail::DataLayoutPolicy> layout) {
39  layout_ = layout;
40 }
41 
43  try {
44  if (backend_ == nullptr)
45  throw Exception("Missing backend or unimplemented backend function.", ioda_Here());
46  return backend_->getFillValuePolicy();
47  } catch (...) {
48  std::throw_with_nested(Exception(
49  "An exception occurred in ioda while determining the fill value policy of a backend.",
50  ioda_Here()));
51  }
52 }
53 
56 }
57 
59  try {
60  if (backend_ == nullptr)
61  throw Exception("Missing backend or unimplemented backend function.", ioda_Here());
62  return backend_->getTypeProvider();
63  } catch (...) {
64  std::throw_with_nested(Exception(
65  "An exception occurred in ioda while getting a backend's type provider interface.",
66  ioda_Here()));
67  }
68 }
69 
70 bool Has_Variables_Base::exists(const std::string& name) const {
71  try {
72  if (backend_ == nullptr)
73  throw Exception("Missing backend or unimplemented backend function.", ioda_Here());
74  if (layout_ == nullptr)
75  throw Exception("Missing layout.", ioda_Here());
76  return backend_->exists(layout_->doMap(name));
77  } catch (...) {
78  std::throw_with_nested(Exception(
79  "An exception occurred inside ioda while checking variable existence.", ioda_Here())
80  .add("name", name));
81  }
82 }
83 
84 void Has_Variables_Base::remove(const std::string& name) {
85  try {
86  if (backend_ == nullptr)
87  throw Exception("Missing backend or unimplemented backend function.", ioda_Here());
88  if (layout_ == nullptr)
89  throw Exception("Missing layout.", ioda_Here());
90  backend_->remove(layout_->doMap(name));
91  } catch (...) {
92  std::throw_with_nested(Exception(
93  "An exception occurred inside ioda while removing a variable.", ioda_Here())
94  .add("name", name));
95  }
96 }
97 
98 Variable Has_Variables_Base::open(const std::string& name) const {
99  try {
100  if (backend_ == nullptr)
101  throw Exception("Missing backend or unimplemented backend function.", ioda_Here());
102  if (layout_ == nullptr)
103  throw Exception("Missing layout.", ioda_Here());
104  return backend_->open(layout_->doMap(name));
105  } catch (...) {
106  std::throw_with_nested(Exception(
107  "An exception occurred inside ioda while opening a variable.", ioda_Here())
108  .add("name", name));
109  }
110 }
111 
113  try {
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;
123 
124  bool outputVariableMetadataPreviouslyGenerated = true;
125  // point to the derived variable parameter group if it has already been created (if
126  // another component variable has already been accessed)
127  auto const it
128  = std::find_if(complementaryVariables_.begin(), complementaryVariables_.end(),
129  [&outputName](ComplementaryVariableCreationParameters compParam) {
130  return compParam.outputName == outputName;
131  });
132  if (it == complementaryVariables_.end()) {
133  outputVariableMetadataPreviouslyGenerated = false;
135  = createDerivedVariableParameters(name, outputName, position);
136  complementaryVariables_.push_back(derivedVariable);
137  }
138 
139  if (outputVariableMetadataPreviouslyGenerated || oneVariableStitch) {
140  ComplementaryVariableCreationParameters* derivedVariableParams;
141  if (oneVariableStitch) {
142  derivedVariableParams = &complementaryVariables_.back();
143  } else {
144  derivedVariableParams = &(*it);
145  derivedVariableParams->inputVariableNames.at(position) = name;
146  derivedVariableParams->inputVarsEnteredCount++;
147  if (derivedVariableParams->inputVarsEnteredCount
148  != derivedVariableParams->inputVarsNeededCount) {
149  continue;
150  }
151  }
152  std::vector<std::vector<std::string>> mergeMethodInput
153  = loadComponentVariableData(*derivedVariableParams);
154  Variable derivedVariable;
155  if (derivedVariableParams->mergeMethod
157  std::vector<std::string> derivedVector = concatenateStringVectors(mergeMethodInput);
158  derivedVariable
159  = this->create<std::string>(derivedVariableParams->outputName,
160  {gsl::narrow<ioda::Dimensions_t>(derivedVector.size())});
161  derivedVariable.write(derivedVector);
162  }
163  if (removeOriginals) {
164  for (auto const& inputVar : derivedVariableParams->inputVariableNames) {
165  this->remove(layout_->doMap(inputVar));
166  }
167  }
168  }
169  }
170  }
171  } catch (...) {
172  std::throw_with_nested(Exception(
173  "An exception occurred inside ioda.", ioda_Here()));
174  }
175 }
176 
178  try {
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;
184  // NOTE(Ryan): C++17 will supersede this with std::optional.
185  // Check for unit. If found, unit.first == true, and unit.second is the unit.
186  auto unit = layout_->getUnit(destinationName);
187  if (unit.first == true) {
188  Variable variableToConvert = this->open(destinationName);
189  try {
190  std::vector<double> outputData = variableToConvert.readAsVector<double>();
191  convertColumn(unit.second, outputData);
192  variableToConvert.write(outputData);
193  variableToConvert.atts.add<std::string>("units", getSIUnit(unit.second));
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);
200  }
201  }
202  }
203  } catch (...) {
204  std::throw_with_nested(Exception("An exception occurred inside ioda.", ioda_Here()));
205  }
206 }
207 
209  const std::string &inputName, const std::string &outputName, size_t position) {
210  try {
211  ComplementaryVariableCreationParameters newDerivedVariable(outputName);
212  const std::string destName = layout_->doMap(inputName);
213  newDerivedVariable.mergeMethod = layout_->getMergeMethod(destName);
214  newDerivedVariable.inputVarsNeededCount = layout_->getInputsNeeded(destName);
215  // Populates a vector with 1 empty entry for every vector that must be entered
216  std::vector<std::string> vec(newDerivedVariable.inputVarsNeededCount, "");
217  newDerivedVariable.inputVariableNames = std::move(vec);
218  newDerivedVariable.inputVariableNames.at(position) = inputName;
219  newDerivedVariable.inputVarsEnteredCount = 1;
220  return newDerivedVariable;
221  } catch (...) {
222  std::throw_with_nested(Exception(
223  "An exception occurred inside ioda.", ioda_Here())
224  .add("inputName", inputName).add("outputName", outputName).add("position", position));
225  }
226 }
227 
228 std::vector<std::vector<std::string> > Has_Variables_Base::loadComponentVariableData(
229  const ComplementaryVariableCreationParameters &derivedVariableParams)
230 {
231  try {
232  std::vector<std::vector<std::string>> mergeMethodInput;
233  for (size_t inputVariableIdx = 0;
234  inputVariableIdx != derivedVariableParams.inputVarsEnteredCount; inputVariableIdx++) {
235  Variable inputVariable
236  = this->open(derivedVariableParams.inputVariableNames[inputVariableIdx]);
237  mergeMethodInput.push_back(inputVariable.readAsVector<std::string>());
238  }
239  return mergeMethodInput;
240  } catch (...) {
241  std::throw_with_nested(Exception(
242  "An exception occurred inside ioda.", ioda_Here()));
243  }
244 }
245 
246 // This is a one-level search. For searching contents of an ObsGroup, you need to
247 // list the Variables in each child group.
248 std::vector<std::string> Has_Variables_Base::list() const {
249  try {
250  if (backend_ == nullptr)
251  throw Exception("Missing backend or unimplemented backend function.", ioda_Here());
252  return backend_->list();
253  } catch (...) {
254  std::throw_with_nested(Exception(
255  "An exception occurred inside ioda while listing one-level child variables of a group.",
256  ioda_Here()));
257  }
258 }
259 
260 /// @todo Extend collective variable creation interface to Python.
262  const std::vector<Dimensions_t>& cur_dimensions,
263  const std::vector<Dimensions_t>& max_dimensions,
264  const std::vector<Variable>& dimension_scales,
266  ) {
267  try {
268  Type typ = Type(dataType, getTypeProvider());
269  if (dimension_scales.size()) {
270  std::vector<Dimensions_t> c_d, m_d, chunking_hints;
271 
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"));
279  else
280  chunking_hints.push_back(-1);
281  }
282 
284  params2.chunk = true;
285  if (!params2.chunks.size()) params2.chunks = chunking_hints;
286  auto fvp = getFillValuePolicy();
287  _py_fvp_helper(dataType, fvp, params2);
288 
289  // TODO(ryan): Extend collective variable creation interface to Python.
290  auto var = create(name, typ, c_d, m_d, params2);
291  var.setDimScale(dimension_scales);
292  return var;
293  } else
294  return create(name, typ, cur_dimensions, max_dimensions, params);
295  } catch (...) {
296  std::throw_with_nested(Exception(
297  "An exception occurred inside ioda.", ioda_Here()));
298  }
299 }
300 
303  try {
304  using namespace FillValuePolicies;
305  const std::map<BasicTypes, std::function<void(FillValuePolicy, detail::FillValueData_t&)>>
306  fvp_map{{BasicTypes::bool_, applyFillValuePolicy<bool>},
307  {BasicTypes::char_, applyFillValuePolicy<char>},
308  {BasicTypes::double_, applyFillValuePolicy<double>},
309  {BasicTypes::float_, applyFillValuePolicy<float>},
310  {BasicTypes::int16_, applyFillValuePolicy<int16_t>},
311  {BasicTypes::int32_, applyFillValuePolicy<int32_t>},
312  {BasicTypes::int64_, applyFillValuePolicy<int64_t>},
313  {BasicTypes::int_, applyFillValuePolicy<int>},
314  {BasicTypes::ldouble_, applyFillValuePolicy<long double>},
315  {BasicTypes::lint_, applyFillValuePolicy<long int>},
316  {BasicTypes::llint_, applyFillValuePolicy<long long int>},
317  {BasicTypes::short_, applyFillValuePolicy<short int>},
318  {BasicTypes::str_, applyFillValuePolicy<std::string>},
319  {BasicTypes::uint16_, applyFillValuePolicy<uint16_t>},
320  {BasicTypes::uint32_, applyFillValuePolicy<uint32_t>},
321  {BasicTypes::uint64_, applyFillValuePolicy<uint64_t>},
322  {BasicTypes::uint_, applyFillValuePolicy<unsigned int>},
323  {BasicTypes::ulint_, applyFillValuePolicy<unsigned long int>},
324  {BasicTypes::ullint_, applyFillValuePolicy<unsigned long long int>},
325  {BasicTypes::ushort_, applyFillValuePolicy<unsigned short int>}};
326  if (fvp_map.count(dataType))
327  fvp_map.at(dataType)(fvp, params.fillValue_);
328  else
329  throw Exception("Unimplemented map entry.", ioda_Here());
330  } catch (...) {
331  std::throw_with_nested(Exception("An exception occurred inside ioda.", ioda_Here()));
332  }
333 }
334 
336  const std::vector<std::pair<Variable, std::vector<Variable>>>& mapping) {
337  try {
338  if (backend_ == nullptr)
339  throw Exception("Missing backend or unimplemented backend function.", ioda_Here());
340  backend_->attachDimensionScales(mapping);
341  } catch (...) {
342  std::throw_with_nested(Exception(
343  "An exception occurred inside ioda while attaching dimension scales.", ioda_Here()));
344  }
345 }
346 
348  const std::vector<std::pair<Variable, std::vector<Variable>>>& mapping) {
349  try {
350  for (auto& m : mapping) {
351  // The Variable{} is because the function params are a const vector<pair<...>>,
352  // which implies that m.first.var would also be const. It really isn't, but C++'s const
353  // implementation is a bit limited with respect to resource handles (in this case, Variables).
354  Variable(m.first).setDimScale(m.second);
355  }
356  } catch (...) {
357  std::throw_with_nested(Exception(
358  "An exception occurred inside ioda while attaching dimension scales.", ioda_Here()));
359  }
360 }
361 
362 Variable Has_Variables_Base::create(const std::string& name, const Type& in_memory_dataType,
363  const std::vector<Dimensions_t>& dimensions,
364  const std::vector<Dimensions_t>& max_dimensions,
366  try {
367  if (backend_ == nullptr)
368  throw Exception("Missing backend or unimplemented backend function.", ioda_Here());
369  if (layout_ == nullptr)
370  throw Exception("Missing layout.", ioda_Here());
371 
372  std::vector<Dimensions_t> fixed_max_dimensions
373  = (max_dimensions.size()) ? max_dimensions : dimensions;
374  auto newVar = backend_->create(layout_->doMap(name), in_memory_dataType, dimensions,
375  fixed_max_dimensions, params);
376  params.applyImmediatelyAfterVariableCreation(newVar);
377  return newVar;
378  } catch (...) {
379  std::throw_with_nested(Exception(
380  "An exception occurred inside ioda while creating a variable.", ioda_Here())
381  .add("name", name));
382  }
383 }
384 
386  try {
387  if (backend_ == nullptr)
388  throw Exception("Missing backend or unimplemented backend function.", ioda_Here());
389 
390  using std::pair;
391  using std::vector;
392  vector<pair<Variable, vector<Variable>>> scaleMappings;
393  scaleMappings.reserve(newvars.size());
394 
395  for (const auto& newvar : newvars) {
396  //Type in_memory_dataType = Types::GetType<DataType>(getTypeProvider());
397  Type t = (newvar->dataTypeKnown_.isValid())
398  ? newvar->dataTypeKnown_
399  : this->getTypeProvider()->makeFundamentalType(newvar->dataType_);
400  std::vector<Dimensions_t> dimensions, max_dimensions, chunking_hints;
401  for (size_t i = 0; i < newvar->scales_.size(); ++i) {
402  const auto& varDims = newvar->scales_[i];
403  const auto& d = varDims.getDimensions();
404  dimensions.push_back(d.dimsCur[0]);
405  max_dimensions.push_back(d.dimsMax[0]);
406  if (varDims.atts.exists("suggested_chunk_dim"))
407  chunking_hints.push_back(varDims.atts.read<Dimensions_t>("suggested_chunk_dim"));
408  else
409  chunking_hints.push_back(-1);
410  }
411 
412  // Make a copy and set chunk properties and fill value if not already set.
413  // The overall use of chunking is set in params, in the .chunk bool.
414  // TODO(Ryan): Differentiate the two with more distinct names.
415  VariableCreationParameters params2 = newvar->vcp_;
416 
417  //auto fvp = getFillValuePolicy();
418  //_py_fvp_helper(dataType, fvp, params2);
419  // TODO(Ryan): Fix the fill value issue.
420  //FillValuePolicies::applyFillValuePolicy<DataType>(getFillValuePolicy(), params2.fillValue_);
421 
422  params2.chunk = true;
423  if (!params2.chunks.size()) params2.chunks = chunking_hints;
424 
425  auto var = create(newvar->name_, t, dimensions, max_dimensions, params2);
426  using std::make_pair;
427  scaleMappings.push_back(make_pair(var, newvar->scales_));
428  }
429 
430  attachDimensionScales(scaleMappings);
431  } catch (...) {
432  std::throw_with_nested(Exception(
433  "An exception occurred inside ioda while creating variable(s).", ioda_Here()));
434  }
435 }
436 
437 } // namespace detail
438 
440 Has_Variables::Has_Variables() : Has_Variables_Base(nullptr) {}
441 Has_Variables::Has_Variables(std::shared_ptr<detail::Has_Variables_Backend> b,
442  std::shared_ptr<const detail::DataLayoutPolicy> pol)
443  : Has_Variables_Base(b, pol) {}
444 
447  : fillValue_{r.fillValue_},
448  chunk{r.chunk},
449  chunks{r.chunks},
450  gzip_{r.gzip_},
451  szip_{r.szip_},
452  gzip_level_{r.gzip_level_},
453  szip_PixelsPerBlock_{r.szip_PixelsPerBlock_},
454  szip_options_{r.szip_options_},
455  atts{r.atts},
456  _py_setFillValue{this} {}
457 
459  const VariableCreationParameters& r) {
460  if (this == &r) return *this;
462  chunk = r.chunk;
463  chunks = r.chunks;
464  gzip_ = r.gzip_;
465  szip_ = r.szip_;
469  atts = r.atts;
470  _py_setFillValue = decltype(_py_setFillValue){this};
471  return *this;
472 }
473 
474 
476  szip_ = false;
477  gzip_ = false;
478 }
480  szip_ = false;
481  gzip_ = true;
482  gzip_level_ = level;
483 }
484 void VariableCreationParameters::compressWithSZIP(unsigned PixelsPerBlock, unsigned options) {
485  gzip_ = false;
486  szip_ = true;
487  szip_PixelsPerBlock_ = PixelsPerBlock;
488  szip_options_ = options;
489 }
490 
492  try {
493  atts.apply(h.atts);
494 
495  return h;
496  } catch (...) {
497  std::throw_with_nested(Exception(
498  "An exception occurred inside ioda while adding attributes to an object.", ioda_Here()));
499  }
500 
501 }
502 } // namespace ioda
IODA's error system.
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.
Definition: Exception.h:54
virtual ~Has_Variables()
Represents the "type" (i.e. integer, string, float) of a piece of data.
Definition: Type.h:123
Variables store data!
Definition: Variable.h:680
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.
Definition: Layout.cpp:28
@ None
Do no manipulation of the Group / Variable layout.
@ Concat
Concatenate complementary variables entry-by-entry.
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 &params=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 &params=VariableCreationParameters::defaulted< DataType >())
Convenience function to create a Variable from certain dimension scales.
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 &params)
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 &params=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.
Definition: Type.h:81
Backends implement type providers in conjunction with Attributes, Has_Attributes, Variables and Has_V...
Definition: Type_Provider.h:36
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).
Definition: Variable.cpp:212
Has_Attributes atts
Attributes.
Definition: Variable.h:71
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 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.
Definition: Variable.cpp:317
FillValuePolicy
This option describes the default fill values that will be used if the user does not manually specify...
Definition: FillPolicy.h:28
@ 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)
BasicTypes
Definition: Type.h:37
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.
#define ioda_Here()
ioda::detail::DataLayoutPolicy::MergeMethod mergeMethod
Definition: MergeMethods.h:28
std::vector< std::string > inputVariableNames
Definition: MergeMethods.h:30
Used to specify Variable creation-time properties.
Definition: Has_Variables.h:57
Variable applyImmediatelyAfterVariableCreation(Variable h) const
Apply the properties to a Variable (second pass; after Variable is created).
detail::python_bindings::VariableCreationFillValues< VariableCreationParameters > _py_setFillValue
Attribute_Creator_Store atts
Set any initial attributes here.
detail::FillValueData_t fillValue_
Definition: Has_Variables.h:66
std::vector< Dimensions_t > chunks
Manually specify the chunks. Never directly use. Use getChunks(...) instead.
Definition: Has_Variables.h:87
VariableCreationParameters & operator=(const VariableCreationParameters &)
void compressWithSZIP(unsigned PixelsPerBlock=16, unsigned options=4)
bool chunk
Do we chunk this variable? Required for extendible / compressible Variables.
Definition: Has_Variables.h:84
Container used to store and manipulate fill values.
Definition: Fill.h:35