19 #include "pism/util/io/NC4File.hh"
24 #define MPI_INCLUDED 1
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,
161 const std::vector<unsigned int> &imap,
double *op)
const {
163 start,
count, imap, op,
169 const std::vector<unsigned int> &start,
170 const std::vector<unsigned int> &
count,
172 std::vector<unsigned int> dummy;
174 start,
count, dummy, op,
180 const std::vector<unsigned int> &start,
181 const std::vector<unsigned int> &
count,
182 const double *op)
const {
183 std::vector<unsigned int> dummy;
185 start,
count, dummy,
const_cast<double*
>(op),
196 int ndims = 0, varid = -1;
197 std::vector<int> dimids;
208 result.resize(ndims);
209 dimids.resize(ndims);
213 for (
int k = 0;
k < ndims; ++
k) {
214 std::vector<char> name(NC_MAX_NAME + 1, 0);
218 result[
k] = name.data();
223 if (variable_name ==
"PISM_GLOBAL") {
228 int stat = nc_inq_varid(
m_file_id, variable_name.c_str(), &result);
242 int stat = nc_inq_varid(
m_file_id, variable_name.c_str(), &varid);
244 exists = (stat == NC_NOERR);
248 std::vector<char> varname(NC_MAX_NAME + 1, 0);
250 int stat = nc_inq_varname(
m_file_id, j, varname.data());
253 result = varname.data();
259 const std::string &att_name,
260 std::vector<double> &result)
const {
265 int stat = nc_inq_attlen(
m_file_id, varid, att_name.c_str(), &attlen);
268 if (stat == NC_NOERR) {
269 len =
static_cast<int>(attlen);
270 }
else if (stat == NC_ENOTATT) {
285 stat = nc_get_att_double(
m_file_id, varid, att_name.c_str(), result.data());
290 static void get_att_text(
int ncid,
int varid,
const std::string &att_name,
291 std::string &result) {
293 int stat = nc_inq_attlen(ncid, varid, att_name.c_str(), &attlen);
294 if (stat != NC_NOERR) {
299 std::vector<char> buffer(attlen + 1, 0);
300 stat = nc_get_att_text(ncid, varid, att_name.c_str(), buffer.data());
302 result = (stat == NC_NOERR) ? buffer.data() :
"";
308 std::string &result) {
310 int stat = nc_inq_attlen(ncid, varid, att_name.c_str(), &attlen);
311 if (stat != NC_NOERR) {
316 std::vector<char*> buffer(attlen + 1, 0);
317 stat = nc_get_att_string(ncid, varid, att_name.c_str(), buffer.data());
318 if (stat == NC_NOERR) {
319 std::vector<std::string> strings(attlen);
320 for (
size_t k = 0;
k < attlen; ++
k) {
321 strings[
k] = buffer[
k];
323 result =
join(strings,
",");
327 stat = nc_free_string(attlen, buffer.data());
332 const std::string &att_name, std::string &result)
const {
336 int stat = nc_inq_atttype(
m_file_id, varid, att_name.c_str(), &nctype);
338 if (stat == NC_NOERR) {
339 if (nctype == NC_CHAR) {
341 }
else if (nctype == NC_STRING) {
346 }
else if (stat == NC_ENOTATT) {
359 const std::string &att_name,
361 const std::vector<double> &data)
const {
363 xtype, data.size(), data.data());
368 const std::string &att_name,
369 const std::string &value)
const {
371 value.size(), value.c_str());
377 std::string &result)
const {
378 std::vector<char> name(NC_MAX_NAME + 1, 0);
382 result = name.data();
386 const std::string &att_name,
388 nc_type tmp = NC_NAT;
389 int stat = nc_inq_atttype(
m_file_id,
get_varid(variable_name), att_name.c_str(), &tmp);
391 if (stat == NC_ENOTATT) {
411 const std::vector<unsigned int> &start,
412 const std::vector<unsigned int> &
count,
413 const std::vector<unsigned int> &imap_input,
416 bool transposed)
const {
417 int stat, varid, ndims =
static_cast<int>(start.size());
418 std::vector<unsigned int> imap = imap_input;
420 if (not transposed) {
424 std::vector<size_t> nc_start(ndims), nc_count(ndims);
425 std::vector<ptrdiff_t> nc_imap(ndims), nc_stride(ndims);
429 for (
int j = 0; j < ndims; ++j) {
430 nc_start[j] = start[j];
431 nc_count[j] =
count[j];
432 nc_imap[j] = imap[j];
441 stat = nc_get_varm_double(
m_file_id, varid,
442 nc_start.data(), nc_count.data(), nc_stride.data(), nc_imap.data(),
445 stat = nc_put_varm_double(
m_file_id, varid,
446 nc_start.data(), nc_count.data(), nc_stride.data(), nc_imap.data(),
454 stat = nc_get_vara_double(
m_file_id, varid,
455 nc_start.data(), nc_count.data(),
458 stat = nc_put_vara_double(
m_file_id, varid,
459 nc_start.data(), nc_count.data(),
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 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 set_access_mode(int varid, bool mapped) 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 get_put_var_double(const std::string &variable_name, const std::vector< unsigned int > &start, const std::vector< unsigned int > &count, const std::vector< unsigned int > &imap, double *ip, bool get, bool mapped) 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 get_varm_double_impl(const std::string &variable_name, const std::vector< unsigned int > &start, const std::vector< unsigned int > &count, const std::vector< unsigned int > &imap, double *ip) 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)