12#include "../dg/blas.h"
13#include "../dg/backend/memory.h"
164 open( filename, mode);
193 std::cerr << e.
what() << std::endl;
205 void open(
const std::filesystem::path& filename,
216 err = nc_open( filename.string().c_str(), NC_NETCDF4 |
217 NC_NOWRITE, &m_ncid);
220 err = nc_open( filename.string().c_str(), NC_NETCDF4 |
224 err = nc_create( filename.string().c_str(), NC_NETCDF4 |
225 NC_NOCLOBBER, &m_ncid);
228 err = nc_create( filename.string().c_str(), NC_NETCDF4 |
229 NC_CLOBBER, &m_ncid);
258 err = nc_close(m_ncid);
270 err = nc_sync( m_ncid);
291 err = nc_inq_format(m_ncid, &formatp);
309 err = nc_def_grp( m_grp, name.c_str(), &new_grp_id);
326 if( not path.has_root_path())
329 path = (current / path);
331 int groupid = m_ncid;
332 auto rel_path = path.relative_path();
334 for(
auto it = rel_path.begin(); it != rel_path.end(); it++)
338 std::wstring string_to_convert = *it;
340 using convert_type = std::codecvt_utf8<wchar_t>;
341 std::wstring_convert<convert_type, wchar_t> converter;
344 std::string grp = converter.to_bytes(string_to_convert);
347 std::string grp = *it;
350 int retval = nc_inq_ncid( groupid, grp.c_str(), &new_grpid);
351 if( retval != NC_NOERR)
352 err = nc_def_grp( groupid, grp.c_str(), &groupid);
364 std::string name = path.generic_string();
365 if( not path.has_root_path())
368 name = (current / path ).generic_string();
371 int retval = nc_inq_grp_full_ncid( m_ncid, name.c_str(), &grpid);
372 return retval == NC_NOERR;
386 void set_grp( std::filesystem::path path =
"")
390 std::string name = path.generic_string();
393 if ( name ==
"" or name ==
"/")
397 else if ( name ==
"..")
401 err = nc_inq_grp_parent( m_grp, &m_grp);
405 if( not path.has_root_path())
408 name = (current / path ).generic_string();
410 err = nc_inq_grp_full_ncid( m_ncid, name.c_str(), &m_grp);
420 err = nc_inq_grp_ncid( m_grp, old_name.c_str(), &old_grp);
421 err = nc_rename_grp( old_grp, new_name.c_str());
431 return get_grp_path( m_grp);
439 auto grps = get_grps_abs(m_grp);
440 std::list<std::filesystem::path> grps_v;
441 for(
auto grp : grps)
442 grps_v.push_back( grp.second);
458 auto grps = get_grps_abs_r(m_grp);
459 std::list<std::filesystem::path> grps_v;
460 for(
auto grp : grps)
461 grps_v.push_back( grp.second);
484 err = nc_def_dim( m_grp, name.c_str(), size, &dim_id);
492 err = nc_inq_dimid( m_grp, old_name.c_str(), &dimid);
493 err = nc_rename_dim( m_grp, dimid, new_name.c_str());
507 err = nc_inq_dimid( m_grp, name.c_str(), &dimid);
509 err = nc_inq_dimlen( m_grp, dimid, &len);
517 std::vector<size_t> shape( dims.size());
518 for(
unsigned u=0; u<dims.size(); u++)
532 std::vector<std::string>
get_dims(
bool include_parents =
true)
const
539 err = nc_inq_dimids( m_grp, &ndims, NULL, include_parents);
542 std::vector<int> dimids(ndims);
543 err = nc_inq_dimids( m_grp, &ndims, &dimids[0], include_parents);
546 std::vector<std::string> dims;
547 for (
int i = 0; i < ndims; i++)
549 char dimname [ NC_MAX_NAME+1];
550 err = nc_inq_dimname( m_grp, dimids[i], dimname);
551 if( std::find(dims.begin(), dims.end(), std::string(dimname) ) ==
553 dims.push_back(dimname);
569 err = nc_inq_unlimdims( m_grp, &ndims, NULL);
572 std::vector<int> dimids(ndims);
575 err = nc_inq_unlimdims( m_grp, &ndims, &dimids[0]);
576 std::vector<std::string> dims;
577 for(
int i=0; i<ndims; i++)
579 char dimname [ NC_MAX_NAME+1];
580 err = nc_inq_dimname( m_grp, dimids[i], dimname);
581 if( std::find(dims.begin(), dims.end(), std::string(dimname) ) ==
583 dims.push_back(dimname);
593 int retval = nc_inq_dimid( m_grp, name.c_str(), &dimid);
594 return retval == NC_NOERR;
604 void put_att(
const std::pair<std::string, nc_att_t>& att, std::string
id =
"")
606 int varid = name2varid(
id);
607 dg::file::detail::put_att( m_grp, varid, att);
619 template<
class S,
class T>
620 void put_att(
const std::tuple<S,nc_type, T>& att, std::string
id =
"")
622 int varid = name2varid(
id);
623 dg::file::detail::put_att( m_grp, varid, att);
639 template<
class Attributes = std::map<std::
string, nc_att_t> >
640 void put_atts(
const Attributes& atts, std::string
id =
"")
642 int varid = name2varid(
id);
643 dg::file::detail::put_atts( m_grp, varid, atts);
660 T
get_att_as(std::string att_name, std::string
id =
"")
const
662 int varid = name2varid(
id);
663 return dg::file::detail::get_att_as<T>( m_grp, varid, att_name);
687 int varid = name2varid(
id);
688 return dg::file::detail::get_atts_as<T>( m_grp, varid);
693 std::map<std::string, nc_att_t>
get_atts( std::string
id =
"")
const
708 void del_att(std::string att_name, std::string
id =
"")
710 int varid = name2varid(
id);
711 auto name = att_name.c_str();
713 err = nc_del_att( m_grp, varid, name);
719 int varid = name2varid(
id);
721 int retval = nc_inq_attid( m_grp, varid, att_name.c_str(), &attid);
722 return retval == NC_NOERR;
734 new_att_name, std::string
id =
"")
736 int varid = name2varid(
id);
737 auto old_name = old_att_name.c_str();
738 auto new_name = new_att_name.c_str();
740 err = nc_rename_att( m_grp, varid, old_name, new_name);
756 template<
class T,
class Attributes = std::map<std::
string, nc_att_t>>
758 const std::vector<std::string>& dim_names,
759 const Attributes& atts = {})
761 def_var( name, detail::getNCDataType<T>(), dim_names, atts);
775 template<
class Attributes = std::map<std::
string, nc_att_t>>
776 void def_var( std::string name, nc_type xtype,
777 const std::vector<std::string>& dim_names,
778 const Attributes& atts = {})
781 std::vector<int> dimids( dim_names.size());
782 for(
unsigned u=0; u<dim_names.size(); u++)
783 err = nc_inq_dimid( m_grp, dim_names[u].c_str(), &dimids[u]);
785 err = nc_def_var( m_grp, name.c_str(), xtype, dim_names.size(),
801 template<
class ContainerType, std::enable_if_t< dg::is_vector_v<
802 ContainerType, SharedVectorTag>,
bool > =
true>
804 const ContainerType& data)
806 int varid = name2varid( name);
809 err = nc_inq_varndims( m_grp, varid, &ndims);
810 assert( (
unsigned)ndims == slab.
ndim());
811 if constexpr ( dg::has_policy_v<ContainerType, dg::CudaTag>)
813 using value_type = dg::get_value_type<ContainerType>;
814 m_buffer.template set<value_type>( data.size());
815 auto& buffer = m_buffer.template get<value_type>( );
816 dg::assign ( data, buffer);
817 err = detail::put_vara_T( m_grp, varid, slab.
startp(), slab.
countp(),
821 err = detail::put_vara_T( m_grp, varid, slab.
startp(), slab.
countp(),
822 thrust::raw_pointer_cast(data.data()));
836 template<
class ContainerType,
class Attributes = std::map<std::
string, nc_att_t>,
837 std::enable_if_t< dg::is_vector_v<ContainerType, SharedVectorTag>,
bool > = true>
838 void defput_var( std::string name,
const std::vector<std::string>& dim_names,
840 const ContainerType& data)
857 template<
class T, std::enable_if_t< dg::is_scalar_v<T>,
bool> = true>
858 void put_var( std::string name,
const std::vector<size_t>& start, T data)
860 int varid = name2varid( name);
862 std::vector<size_t> count( start.size(), 1);
863 err = detail::put_vara_T( m_grp, varid, &start[0], &count[0], &data);
884 template<
class T,
class Attributes = std::map<std::
string, nc_att_t>>
907 template<
class ContainerType,
class Attributes = std::map<std::
string, nc_att_t>>
909 const Attributes& atts,
910 const ContainerType& abscissas)
913 abscissas.size(), atts);
914 put_var( name, {abscissas}, abscissas);
926 template<
class ContainerType, std::enable_if_t< dg::is_vector_v<
927 ContainerType, SharedVectorTag>,
bool > =
true>
929 ContainerType& data)
const
931 int varid = name2varid( name);
934 err = nc_inq_varndims( m_grp, varid, &ndims);
935 assert( (
unsigned)ndims == slab.
ndim());
937 for(
unsigned u=0; u<slab.
ndim(); u++)
938 size *= slab.
count()[u];
939 if constexpr ( dg::has_policy_v<ContainerType, dg::CudaTag>)
941 using value_type = dg::get_value_type<ContainerType>;
942 m_buffer.template set<value_type>( size);
943 auto& buffer = m_buffer.template get<value_type>( );
944 err = detail::get_vara_T( m_grp, varid, slab.
startp(), slab.
countp(),
946 dg::assign ( buffer, data);
951 err = detail::get_vara_T( m_grp, varid, slab.
startp(), slab.
countp(),
952 thrust::raw_pointer_cast(data.data()));
964 template<
class T, std::enable_if_t< dg::is_scalar_v<T>,
bool> = true>
965 void get_var( std::string name,
const std::vector<size_t>& start, T& data)
const
967 int varid = name2varid( name);
970 err = nc_inq_varndims( m_grp, varid, &ndims);
971 assert( (
unsigned)ndims == start.size());
973 err = detail::get_vara_T( m_grp, varid, NULL, NULL, &data);
976 std::vector<size_t> count( start.size(), 1);
977 err = detail::get_vara_T( m_grp, varid, &start[0], &count[0], &data);
990 template<
class ContainerType, std::enable_if_t< dg::is_vector_v<
991 ContainerType, SharedVectorTag>,
bool > =
true>
1004 template<
class ContainerType, std::enable_if_t< dg::is_vector_v<
1005 ContainerType, SharedVectorTag>,
bool > =
true>
1021 template<
class T, std::enable_if_t< dg::is_scalar_v<T>,
bool> = true>
1022 T
get_var_as( std::string name,
const std::vector<size_t>& start = {})
const
1035 int retval = nc_inq_varid( m_grp, name.c_str(), &varid);
1036 return retval == NC_NOERR;
1043 int varid = name2varid( name);
1046 err = nc_inq_vartype( m_grp, varid, &xtype);
1058 int varid = name2varid( name);
1062 err = nc_inq_varndims( m_grp, varid, &ndims);
1065 std::vector<int> dimids(ndims);
1066 err = nc_inq_vardimid( m_grp, varid, &dimids[0]);
1068 std::vector<std::string> dims(ndims);
1069 for(
int i=0; i<ndims; i++)
1071 char dimname [ NC_MAX_NAME+1];
1072 err = nc_inq_dimname( m_grp, dimids[i], dimname);
1090 return get_var_names_private( m_grp);
1094 int name2varid( std::string
id)
const
1106 err = nc_inq_varid( m_grp,
id.c_str(), &varid);
1112 std::filesystem::path get_grp_path(
int ncid )
const
1115 NC_Error_Handle err;
1116 err = nc_inq_grpname_full( ncid, &len, NULL);
1117 std::string current( len,
'x');
1118 err = nc_inq_grpname_full( ncid, &len, ¤t[0]);
1122 std::map<int, std::filesystem::path> get_grps_abs(
int ncid )
const
1124 NC_Error_Handle err;
1126 err = nc_inq_grps( ncid, &num_grps, NULL);
1129 std::vector<int> group_ids( num_grps);
1130 err = nc_inq_grps( ncid, &num_grps, &group_ids[0]);
1131 std::map<int, std::filesystem::path> groups;
1132 for(
int i=0; i<num_grps; i++)
1135 err = nc_inq_grpname_full( group_ids[i], &len, NULL);
1136 std::string name( len,
'z');
1137 err = nc_inq_grpname_full( group_ids[i], &len, &name[0]);
1138 groups[group_ids[i]] = name;
1142 std::map<int, std::filesystem::path> get_grps_abs_r(
int ncid)
const
1144 auto grps = get_grps_abs(ncid);
1145 for(
auto grp : grps)
1147 auto subgrps = get_grps_abs_r( grp.first);
1148 grps.merge( subgrps);
1153 std::list<std::string> get_var_names_private(
int grpid)
const
1155 std::list<std::string> vars;
1156 int num_vars = 0, num_dims;
1157 file::NC_Error_Handle err;
1158 err = nc_inq(grpid, &num_dims, &num_vars, NULL, NULL);
1160 for(
int i=0; i<num_vars; i++)
1162 char name[NC_MAX_NAME+1];
1163 err = nc_inq_varname( grpid, i, name);
1164 vars.push_back( name);
1170 void check_open()
const
1173 throw NC_Error( 1000);
1176 bool m_open =
false;
1184 mutable dg::detail::AnyVector<thrust::host_vector> m_buffer;
1197using NcFile = SerialNcFile;
MPINcFile NcFile
Definition nc_mpi_file.h:722
NcFileMode
Convenience NetCDF file opening/create flags.
Definition nc_file.h:121
@ nc_clobber
Call nc_create( path, NC_CLOBBER | NC_NETCDF4, ...);Create a new netCDF-4 file for read and write acc...
Definition nc_file.h:124
@ nc_nowrite
Call nc_open(path, NC_NOWRITE, ...);. Open an existing file for read-only access, fail if it does not...
Definition nc_file.h:122
@ nc_write
Call nc_open(path, NC_WRITE, ...)Open an existing (netCDF-4 file for read and write access,...
Definition nc_file.h:123
@ nc_noclobber
Call nc_create( path, NC_NOCLOBBER | NC_NETCDF4, ...); Create new netCDF-4 file for read and write ac...
Definition nc_file.h:125
Definition easy_atts.h:15
DEPRECATED Empty utitlity class that handles return values of netcdf functions and throws NC_Error(st...
Definition nc_error.h:70
Class thrown by the NC_Error_Handle.
Definition nc_error.h:20
char const * what() const noexcept
What string.
Definition nc_error.h:35
A NetCDF Hyperslab for SerialNcFile.
Definition nc_hyperslab.h:27
const size_t * countp() const
Definition nc_hyperslab.h:135
const std::vector< size_t > & count() const
Definition nc_hyperslab.h:127
const size_t * startp() const
Definition nc_hyperslab.h:133
unsigned ndim() const
Definition nc_hyperslab.h:122
Serial NetCDF-4 file.
Definition nc_file.h:151
T get_att_as(std::string att_name, std::string id="") const
Get an attribute named att_name of the group or variable id.
Definition nc_file.h:660
void sync()
Call nc_sync.
Definition nc_file.h:266
void get_var(std::string name, const std::vector< size_t > &start, T &data) const
Read scalar from position start from variable named name.
Definition nc_file.h:965
std::vector< std::string > get_var_dims(std::string name) const
Get the dimension names associated to variable name.
Definition nc_file.h:1056
ContainerType get_var_as(std::string name, const NcHyperslab &slab) const
Convenience shortcut (vector version)
Definition nc_file.h:992
void def_grp(std::string name)
Define a group named name in the current group.
Definition nc_file.h:304
void defput_var(std::string name, const std::vector< std::string > &dim_names, const Attributes &atts, const NcHyperslab &slab, const ContainerType &data)
Define and put a variable in one go.
Definition nc_file.h:838
void put_att(const std::tuple< S, nc_type, T > &att, std::string id="")
Put an individual attribute of preset type to variable id.
Definition nc_file.h:620
void put_att(const std::pair< std::string, nc_att_t > &att, std::string id="")
Put an individual attribute.
Definition nc_file.h:604
void del_att(std::string att_name, std::string id="")
Remove an attribute named att_name from variable id.
Definition nc_file.h:708
ContainerType get_var_as(std::string name) const
Convenience shortcut for get_var_as<ContainerType>( name, {*this, name});
Definition nc_file.h:1006
SerialNcFile(SerialNcFile &&rhs)=default
Swap resources between two file handles.
std::vector< size_t > get_dims_shape(const std::vector< std::string > &dims) const
Get the size of each dimension in dims.
Definition nc_file.h:515
void rename_dim(std::string old_name, std::string new_name)
Rename a dimension from old_name to new_name.
Definition nc_file.h:487
void rename_att(std::string old_att_name, std::string new_att_name, std::string id="")
Rename an attribute of the variable id.
Definition nc_file.h:733
std::list< std::filesystem::path > get_grps_r() const
Get all subgroups recursively in the current group as absolute paths.
Definition nc_file.h:456
SerialNcFile(const SerialNcFile &rhs)=delete
There can only be exactly one file handle per physical file.
bool var_is_defined(std::string name) const
Definition nc_file.h:1031
std::list< std::string > get_var_names() const
Get a list of variable names in the current group.
Definition nc_file.h:1087
void put_atts(const Attributes &atts, std::string id="")
Write a collection of attributes to a NetCDF variable or file.
Definition nc_file.h:640
nc_type get_var_type(std::string name) const
Definition nc_file.h:1041
std::map< std::string, nc_att_t > get_atts(std::string id="") const
Definition nc_file.h:693
bool is_open() const noexcept
Definition nc_file.h:237
void def_var(std::string name, nc_type xtype, const std::vector< std::string > &dim_names, const Attributes &atts={})
Define a variable with given type, dimensions and (optionally) attributes.
Definition nc_file.h:776
void def_grp_p(std::filesystem::path path)
Define a group named path and all required intermediary groups.
Definition nc_file.h:323
void defput_dim(std::string name, const Attributes &atts, const ContainerType &abscissas)
Define a dimension and define and write to a dimension variable in one go.
Definition nc_file.h:908
void set_grp(std::filesystem::path path="")
Change group to path.
Definition nc_file.h:386
std::filesystem::path get_current_path() const
Get the absolute path of the current group.
Definition nc_file.h:428
bool dim_is_defined(std::string name) const
Definition nc_file.h:590
void def_dim(std::string name, size_t size)
Define a dimension named name of size size.
Definition nc_file.h:479
void get_var(std::string name, const NcHyperslab &slab, ContainerType &data) const
Read hyperslab slab from variable named name into container data.
Definition nc_file.h:928
~SerialNcFile()
Close open nc file and release all resources.
Definition nc_file.h:185
std::vector< T > get_att_vec_as(std::string att_name, std::string id="") const
Short for get_att_as<std::vector<T>>( id, att_name);
Definition nc_file.h:668
int get_grpid() const noexcept
Get the NetCDF-C ID of the current group.
Definition nc_file.h:425
int get_format() const
Check the binary file format of the netCDF file.
Definition nc_file.h:287
SerialNcFile(const std::filesystem::path &filename, enum NcFileMode mode=nc_nowrite)
Open/Create a netCDF file.
Definition nc_file.h:161
void put_var(std::string name, const std::vector< size_t > &start, T data)
Write a single data point.
Definition nc_file.h:858
void close()
Explicitly close a file.
Definition nc_file.h:252
SerialNcFile & operator=(const SerialNcFile &rhs)=delete
There can only be exactly one file handle per physical file.
bool grp_is_defined(std::filesystem::path path) const
Check for existence of the group given by path.
Definition nc_file.h:361
bool att_is_defined(std::string att_name, std::string id="") const
Definition nc_file.h:717
T get_var_as(std::string name, const std::vector< size_t > &start={}) const
Convenience shortcut (scalar version)
Definition nc_file.h:1022
std::vector< std::string > get_unlim_dims() const
Get all visible unlimited dimension names in the current group.
Definition nc_file.h:564
void put_var(std::string name, const NcHyperslab &slab, const ContainerType &data)
Write data to a variable.
Definition nc_file.h:803
std::vector< std::string > get_dims(bool include_parents=true) const
Get all visible dimension names in the current group.
Definition nc_file.h:532
void def_dimvar_as(std::string name, size_t size, const Attributes &atts)
Define a dimension and dimension variable in one go.
Definition nc_file.h:885
int get_ncid() const noexcept
Get the ncid of the underlying NetCDF C-API.
Definition nc_file.h:278
size_t get_dim_size(std::string name) const
Get the size of the dimension named name.
Definition nc_file.h:502
void def_var_as(std::string name, const std::vector< std::string > &dim_names, const Attributes &atts={})
Define a variable with given type, dimensions and (optionally) attributes.
Definition nc_file.h:757
std::map< std::string, T > get_atts_as(std::string id="") const
Read all NetCDF attributes of a certain type.
Definition nc_file.h:685
std::list< std::filesystem::path > get_grps() const
Get all subgroups in the current group as absolute paths.
Definition nc_file.h:436
void rename_grp(std::string old_name, std::string new_name)
rename a subgroup in the current group from old_name to new_name
Definition nc_file.h:415
void open(const std::filesystem::path &filename, enum NcFileMode mode=nc_nowrite)
Open/Create a netCDF file.
Definition nc_file.h:205