19#include "pism/util/io/NC4File.hh"
30#include "pism/util/io/pism_type_conversion.hh"
31#include "pism/util/pism_utilities.hh"
32#include "pism/util/error_handling.hh"
39 if (return_code != NC_NOERR) {
45 :
NCFile(c), m_compression_level(compression_level) {
75 int stat = nc_def_dim(
m_file_id, name.c_str(), length, &dimid);
82 int stat = nc_inq_dimid(
m_file_id, dimension_name.c_str(), &tmp);
84 if (stat == NC_NOERR) {
95 int stat = nc_inq_dimid(
m_file_id, dimension_name.c_str(), &dimid);
100 result =
static_cast<unsigned int>(len);
105 std::vector<char> dimname(NC_MAX_NAME + 1, 0);
114 result = dimname.data();
121 const std::vector<std::string> &dims)
const {
122 std::vector<int> dimids;
123 int stat = 0, varid = -1;
125 for (
auto d : dims) {
128 dimids.push_back(dimid);
132 static_cast<int>(dims.size()), dimids.data(), &varid);
141 if (stat == NC_EINVAL) {
150 std::vector<size_t> &dimensions)
const {
151 int stat = 0, varid = 0;
153 stat = nc_inq_varid(
m_file_id, name.c_str(), &varid);
156 stat = nc_def_var_chunking(
m_file_id, varid, NC_CHUNKED, dimensions.data());
161 const std::vector<unsigned int> &start,
162 const std::vector<unsigned int> &
count,
170 const std::vector<unsigned int> &start,
171 const std::vector<unsigned int> &
count,
172 const double *op)
const {
174 start,
count,
const_cast<double*
>(op),
179 const std::vector<unsigned int> &start,
180 const std::vector<unsigned int> &
count,
const char *data)
const {
181 std::vector<size_t> nc_start{};
182 nc_start.reserve(start.size());
183 for (
const auto &s : start) {
184 nc_start.push_back(s);
187 std::vector<size_t> nc_count{};
188 nc_count.reserve(
count.size());
189 for (
const auto &c :
count) {
190 nc_count.push_back(c);
194 nc_put_vara_text(
m_file_id,
get_varid(variable_name), nc_start.data(), nc_count.data(), data);
203 int ndims = 0, varid = -1;
204 std::vector<int> dimids;
215 result.resize(ndims);
216 dimids.resize(ndims);
220 for (
int k = 0;
k < ndims; ++
k) {
221 std::vector<char> name(NC_MAX_NAME + 1, 0);
225 result[
k] = name.data();
230 if (variable_name ==
"PISM_GLOBAL") {
235 int stat = nc_inq_varid(
m_file_id, variable_name.c_str(), &result);
249 int stat = nc_inq_varid(
m_file_id, variable_name.c_str(), &varid);
251 exists = (stat == NC_NOERR);
255 std::vector<char> varname(NC_MAX_NAME + 1, 0);
257 int stat = nc_inq_varname(
m_file_id, j, varname.data());
260 result = varname.data();
266 const std::string &att_name,
267 std::vector<double> &result)
const {
272 int stat = nc_inq_attlen(
m_file_id, varid, att_name.c_str(), &attlen);
275 if (stat == NC_NOERR) {
276 len =
static_cast<int>(attlen);
277 }
else if (stat == NC_ENOTATT) {
292 stat = nc_get_att_double(
m_file_id, varid, att_name.c_str(), result.data());
297static void get_att_text(
int ncid,
int varid,
const std::string &att_name,
298 std::string &result) {
300 int stat = nc_inq_attlen(ncid, varid, att_name.c_str(), &attlen);
301 if (stat != NC_NOERR) {
306 std::vector<char> buffer(attlen + 1, 0);
307 stat = nc_get_att_text(ncid, varid, att_name.c_str(), buffer.data());
309 result = (stat == NC_NOERR) ? buffer.data() :
"";
315 std::string &result) {
317 int stat = nc_inq_attlen(ncid, varid, att_name.c_str(), &attlen);
318 if (stat != NC_NOERR) {
323 std::vector<char*> buffer(attlen + 1, 0);
324 stat = nc_get_att_string(ncid, varid, att_name.c_str(), buffer.data());
325 if (stat == NC_NOERR) {
326 std::vector<std::string> strings(attlen);
327 for (
size_t k = 0;
k < attlen; ++
k) {
328 strings[
k] = buffer[
k];
330 result =
join(strings,
",");
334 stat = nc_free_string(attlen, buffer.data());
339 const std::string &att_name, std::string &result)
const {
343 int stat = nc_inq_atttype(
m_file_id, varid, att_name.c_str(), &nctype);
345 if (stat == NC_NOERR) {
346 if (nctype == NC_CHAR) {
348 }
else if (nctype == NC_STRING) {
353 }
else if (stat == NC_ENOTATT) {
366 const std::string &att_name,
368 const std::vector<double> &data)
const {
370 xtype, data.size(), data.data());
375 const std::string &att_name,
376 const std::string &value)
const {
378 value.size(), value.c_str());
384 std::string &result)
const {
385 std::vector<char> name(NC_MAX_NAME + 1, 0);
389 result = name.data();
393 const std::string &att_name,
395 nc_type tmp = NC_NAT;
396 int stat = nc_inq_atttype(
m_file_id,
get_varid(variable_name), att_name.c_str(), &tmp);
398 if (stat == NC_ENOTATT) {
418 const std::vector<unsigned int> &start,
419 const std::vector<unsigned int> &
count,
422 int stat, varid, ndims =
static_cast<int>(start.size());
424 std::vector<size_t> nc_start(ndims), nc_count(ndims);
428 for (
int j = 0; j < ndims; ++j) {
429 nc_start[j] = start[j];
430 nc_count[j] =
count[j];
437 stat = nc_get_vara_double(
m_file_id, varid, nc_start.data(), nc_count.data(), op);
440 stat = nc_put_vara_double(
m_file_id, varid, nc_start.data(), nc_count.data(), op);
virtual void get_att_double_impl(const std::string &variable_name, const std::string &att_name, std::vector< double > &result) const
virtual void inq_attname_impl(const std::string &variable_name, unsigned int n, std::string &result) const
virtual void inq_nvars_impl(int &result) const
virtual void get_put_var_double(const std::string &variable_name, const std::vector< unsigned int > &start, const std::vector< unsigned int > &count, double *ip, bool get) const
virtual void put_att_double_impl(const std::string &variable_name, const std::string &att_name, io::Type xtype, const std::vector< double > &data) const
virtual void get_att_text_impl(const std::string &variable_name, const std::string &att_name, std::string &result) const
virtual void close_impl()
virtual void inq_varid_impl(const std::string &variable_name, bool &exists) const
virtual void sync_impl() const
virtual void inq_dimid_impl(const std::string &dimension_name, bool &exists) const
virtual void enddef_impl() const
virtual void inq_unlimdim_impl(std::string &result) const
unsigned int m_compression_level
virtual void def_var_chunking_impl(const std::string &name, std::vector< size_t > &dimensions) const
virtual void redef_impl() const
virtual void inq_dimlen_impl(const std::string &dimension_name, unsigned int &result) const
virtual void put_vara_text_impl(const std::string &variable_name, const std::vector< unsigned int > &start, const std::vector< unsigned int > &count, const char *data) const
virtual void del_att_impl(const std::string &variable_name, const std::string &att_name) const
virtual void set_access_mode(int varid) const
virtual void put_att_text_impl(const std::string &variable_name, const std::string &att_name, const std::string &value) const
NC4File(MPI_Comm com, unsigned int compression_level)
virtual void def_dim_impl(const std::string &name, size_t length) const
virtual void inq_vardimid_impl(const std::string &variable_name, std::vector< std::string > &result) const
virtual void set_fill_impl(int fillmode, int &old_modep) const
virtual void def_var_impl(const std::string &name, io::Type nctype, const std::vector< std::string > &dims) const
virtual void put_vara_double_impl(const std::string &variable_name, const std::vector< unsigned int > &start, const std::vector< unsigned int > &count, const double *op) const
int get_varid(const std::string &variable_name) const
virtual void inq_varname_impl(unsigned int j, std::string &result) const
virtual void get_vara_double_impl(const std::string &variable_name, const std::vector< unsigned int > &start, const std::vector< unsigned int > &count, double *ip) const
virtual void inq_atttype_impl(const std::string &variable_name, const std::string &att_name, io::Type &result) const
virtual void inq_varnatts_impl(const std::string &variable_name, int &result) const
The PISM wrapper for a subset of the NetCDF C API.
#define PISM_ERROR_LOCATION
static void check(const ErrorLocation &where, int return_code)
Prints an error message; for debugging.
static void get_att_string(int ncid, int varid, const std::string &att_name, std::string &result)
static void get_att_text(int ncid, int varid, const std::string &att_name, std::string &result)
std::string join(const std::vector< std::string > &strings, const std::string &separator)
Concatenate strings, inserting separator between elements.
static pism::io::Type nc_type_to_pism_type(int input)
static nc_type pism_type_to_nc_type(pism::io::Type input)