From 9d2f411e047b7cd33abac46f2b892b5400e7e689 Mon Sep 17 00:00:00 2001 From: Michael Uleysky Date: Mon, 15 Jan 2024 16:17:38 +1000 Subject: [PATCH] Added interface for partially writing a variable to a netcdf file --- include/ncfilew.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/include/ncfilew.h b/include/ncfilew.h index d49198a..bcd5d59 100644 --- a/include/ncfilew.h +++ b/include/ncfilew.h @@ -23,26 +23,31 @@ class NCFileWBase { static constexpr nc_type nc = NC_UBYTE; static int put_var(int nc, int vid, const michlib::uint1* data) { return nc_put_var_ubyte(nc, vid, data); } + static int put_vara(int nc, int vid, const size_t* startp, const size_t* countp, const michlib::uint1* data) { return nc_put_vara_ubyte(nc, vid, startp, countp, data); } }; template struct NCTypeD { static constexpr nc_type nc = NC_SHORT; static int put_var(int nc, int vid, const michlib::int2* data) { return nc_put_var_short(nc, vid, data); } + static int put_vara(int nc, int vid, const size_t* startp, const size_t* countp, const michlib::int2* data) { return nc_put_vara_short(nc, vid, startp, countp, data); } }; template struct NCTypeD { static constexpr nc_type nc = NC_USHORT; static int put_var(int nc, int vid, const michlib::uint2* data) { return nc_put_var_ushort(nc, vid, data); } + static int put_vara(int nc, int vid, const size_t* startp, const size_t* countp, const michlib::uint2* data) { return nc_put_vara_ushort(nc, vid, startp, countp, data); } }; template struct NCTypeD { static constexpr nc_type nc = NC_INT; static int put_var(int nc, int vid, const michlib::int4* data) { return nc_put_var_int(nc, vid, data); } + static int put_vara(int nc, int vid, const size_t* startp, const size_t* countp, const michlib::int4* data) { return nc_put_vara_int(nc, vid, startp, countp, data); } }; template struct NCTypeD { static constexpr nc_type nc = NC_UINT; static int put_var(int nc, int vid, const michlib::uint4* data) { return nc_put_var_uint(nc, vid, data); } + static int put_vara(int nc, int vid, const size_t* startp, const size_t* countp, const michlib::uint4* data) { return nc_put_vara_uint(nc, vid, startp, countp, data); } }; template struct NCTypeD { @@ -56,11 +61,13 @@ class NCFileWBase { static constexpr nc_type nc = NC_FLOAT; static int put_var(int nc, int vid, const float* data) { return nc_put_var_float(nc, vid, data); } + static int put_vara(int nc, int vid, const size_t* startp, const size_t* countp, const float* data) { return nc_put_vara_float(nc, vid, startp, countp, data); } }; template struct NCTypeD { static constexpr nc_type nc = NC_DOUBLE; static int put_var(int nc, int vid, const double* data) { return nc_put_var_double(nc, vid, data); } + static int put_vara(int nc, int vid, const size_t* startp, const size_t* countp, const double* data) { return nc_put_vara_double(nc, vid, startp, countp, data); } }; template struct NCTypeD { @@ -287,6 +294,40 @@ class NCFileWBase err.Reset(NCTypeD::put_var(ncid, varid, data)); } + template + requires requires(int nc, int vid, const size_t* start, const size_t* count, const T* d) { + { + NCTypeD::put_vara(nc, vid, start, count, d) + } -> std::same_as; + } + void WriteVar(const MString& vname, size_t ind, const T* data) + { + if(err.IsErr()) return; + + int varid; + err.Reset(nc_inq_varid(ncid, vname.Buf(), &varid)); + if(err.IsErr()) return; + + int ndim; + err.Reset(nc_inq_var(ncid, varid, nullptr, nullptr, &ndim, nullptr, nullptr)); + if(err.IsErr()) return; + std::vector dimids(ndim); + err.Reset(nc_inq_var(ncid, varid, nullptr, nullptr, nullptr, dimids.data(), nullptr)); + if(err.IsErr()) return; + + std::vector start(ndim), count(ndim); + start[0] = ind; + count[0] = 1; + for(size_t i = 1; i < dimids.size(); i++) + { + start[i] = 0; + err.Reset(nc_inq_dim(ncid, dimids[i], nullptr, &count[i])); + if(err.IsErr()) return; + } + + err.Reset(NCTypeD::put_vara(ncid, varid, start.data(), count.data(), data)); + } + private: // Members int ncid;