19#include "pism/util/io/NC4File.hh"
28#include "pism/util/io/pism_type_conversion.hh"
29#include "pism/util/pism_utilities.hh"
30#include "pism/util/error_handling.hh"
37 if (return_code != NC_NOERR) {
43 :
NCFile(c), m_compression_level(compression_level) {
73 int stat = nc_def_dim(
m_file_id, name.c_str(), length, &dimid);
80 int stat = nc_inq_dimid(
m_file_id, dimension_name.c_str(), &tmp);
82 if (stat == NC_NOERR) {
93 int stat = nc_inq_dimid(
m_file_id, dimension_name.c_str(), &dimid);
98 result =
static_cast<unsigned int>(len);
103 std::vector<char> dimname(NC_MAX_NAME + 1, 0);
112 result = dimname.data();
119 const std::vector<std::string> &dims)
const {
120 std::vector<int> dimids;
121 int stat = 0, varid = -1;
123 for (
auto d : dims) {
126 dimids.push_back(dimid);
130 static_cast<int>(dims.size()), dimids.data(), &varid);
139 if (stat == NC_EINVAL) {
148 std::vector<size_t> &dimensions)
const {
149 int stat = 0, varid = 0;
151 stat = nc_inq_varid(
m_file_id, name.c_str(), &varid);
154 stat = nc_def_var_chunking(
m_file_id, varid, NC_CHUNKED, dimensions.data());
159 const std::vector<unsigned int> &start,
160 const std::vector<unsigned int> &
count,
168 const std::vector<unsigned int> &start,
169 const std::vector<unsigned int> &
count,
170 const double *op)
const {
172 start,
count,
const_cast<double*
>(op),
182 int ndims = 0, varid = -1;
183 std::vector<int> dimids;
194 result.resize(ndims);
195 dimids.resize(ndims);
199 for (
int k = 0;
k < ndims; ++
k) {
200 std::vector<char> name(NC_MAX_NAME + 1, 0);
204 result[
k] = name.data();
209 if (variable_name ==
"PISM_GLOBAL") {
214 int stat = nc_inq_varid(
m_file_id, variable_name.c_str(), &result);
228 int stat = nc_inq_varid(
m_file_id, variable_name.c_str(), &varid);
230 exists = (stat == NC_NOERR);
234 std::vector<char> varname(NC_MAX_NAME + 1, 0);
236 int stat = nc_inq_varname(
m_file_id, j, varname.data());
239 result = varname.data();
245 const std::string &att_name,
246 std::vector<double> &result)
const {
251 int stat = nc_inq_attlen(
m_file_id, varid, att_name.c_str(), &attlen);
254 if (stat == NC_NOERR) {
255 len =
static_cast<int>(attlen);
256 }
else if (stat == NC_ENOTATT) {
271 stat = nc_get_att_double(
m_file_id, varid, att_name.c_str(), result.data());
276static void get_att_text(
int ncid,
int varid,
const std::string &att_name,
277 std::string &result) {
279 int stat = nc_inq_attlen(ncid, varid, att_name.c_str(), &attlen);
280 if (stat != NC_NOERR) {
285 std::vector<char> buffer(attlen + 1, 0);
286 stat = nc_get_att_text(ncid, varid, att_name.c_str(), buffer.data());
288 result = (stat == NC_NOERR) ? buffer.data() :
"";
276static void get_att_text(
int ncid,
int varid,
const std::string &att_name, {
…}
294 std::string &result) {
296 int stat = nc_inq_attlen(ncid, varid, att_name.c_str(), &attlen);
297 if (stat != NC_NOERR) {
302 std::vector<char*> buffer(attlen + 1, 0);
303 stat = nc_get_att_string(ncid, varid, att_name.c_str(), buffer.data());
304 if (stat == NC_NOERR) {
305 std::vector<std::string> strings(attlen);
306 for (
size_t k = 0;
k < attlen; ++
k) {
307 strings[
k] = buffer[
k];
309 result =
join(strings,
",");
313 stat = nc_free_string(attlen, buffer.data());
318 const std::string &att_name, std::string &result)
const {
322 int stat = nc_inq_atttype(
m_file_id, varid, att_name.c_str(), &nctype);
324 if (stat == NC_NOERR) {
325 if (nctype == NC_CHAR) {
327 }
else if (nctype == NC_STRING) {
332 }
else if (stat == NC_ENOTATT) {
345 const std::string &att_name,
347 const std::vector<double> &data)
const {
349 xtype, data.size(), data.data());
354 const std::string &att_name,
355 const std::string &value)
const {
357 value.size(), value.c_str());
363 std::string &result)
const {
364 std::vector<char> name(NC_MAX_NAME + 1, 0);
368 result = name.data();
372 const std::string &att_name,
374 nc_type tmp = NC_NAT;
375 int stat = nc_inq_atttype(
m_file_id,
get_varid(variable_name), att_name.c_str(), &tmp);
377 if (stat == NC_ENOTATT) {
397 const std::vector<unsigned int> &start,
398 const std::vector<unsigned int> &
count,
401 int stat, varid, ndims =
static_cast<int>(start.size());
403 std::vector<size_t> nc_start(ndims), nc_count(ndims);
407 for (
int j = 0; j < ndims; ++j) {
408 nc_start[j] = start[j];
409 nc_count[j] =
count[j];
416 stat = nc_get_vara_double(
m_file_id, varid, nc_start.data(), nc_count.data(), op);
419 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 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)