guessnc.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #ifdef HAVE_NETCDF
  2. #include "guessnc.h"
  3. #include <netcdf.h>
  4. namespace GuessNC {
  5. void handle_error(int status, const std::string& message) {
  6. // todo: simplify formatting message for more helpful messages?
  7. if (status != NC_NOERR) {
  8. std::string error_message =
  9. std::string("NetCDF error: ") + nc_strerror(status) + ": " + message;
  10. throw GuessNCError(error_message);
  11. }
  12. }
  13. int open_ncdf(const char* fname) {
  14. int netcdf_id;
  15. int status = nc_open(fname, NC_NOWRITE, &netcdf_id);
  16. handle_error(status, (std::string("Cannot open NetCDF file: ") + fname).c_str());
  17. return netcdf_id;
  18. }
  19. void close_ncdf(int ncid) {
  20. int status = nc_close(ncid);
  21. handle_error(status, "Failed to close NetCDF file");
  22. }
  23. bool get_attribute(int ncid_file, int ncid_var,
  24. const std::string& attr_name, std::string& value) {
  25. nc_type type;
  26. size_t len;
  27. int status = nc_inq_att(ncid_file, ncid_var, attr_name.c_str(), &type, &len);
  28. if (status == NC_ENOTATT) {
  29. return false;
  30. }
  31. handle_error(status, std::string("Failed to get attribute: ") + attr_name);
  32. if (type != NC_CHAR) {
  33. return false;
  34. }
  35. std::vector<char> buff(len+1, 0);
  36. status = nc_get_att_text(ncid_file, ncid_var, attr_name.c_str(), &buff.front());
  37. handle_error(status, "Failed to get attribute: " + attr_name);
  38. value = &buff.front();
  39. return true;
  40. }
  41. bool get_attribute(int ncid_file, int ncid_var,
  42. const std::string& attr_name, double& value) {
  43. nc_type type;
  44. size_t len;
  45. int status = nc_inq_att(ncid_file, ncid_var, attr_name.c_str(), &type, &len);
  46. if (status == NC_ENOTATT) {
  47. return false;
  48. }
  49. handle_error(status, std::string("Failed to get attribute: ") + attr_name);
  50. status = nc_get_att_double(ncid_file, ncid_var, attr_name.c_str(), &value);
  51. handle_error(status, "Failed to get attribute: " + attr_name);
  52. return true;
  53. }
  54. void get_dimensions(int ncid_file, int ncid_var,
  55. std::vector<int>& dimensions) {
  56. int ndims;
  57. int status = nc_inq_varndims(ncid_file, ncid_var, &ndims);
  58. handle_error(status, "Failed to get number of dimensions of variable" +
  59. get_variable_name(ncid_file, ncid_var));
  60. dimensions.resize(ndims);
  61. status = nc_inq_vardimid(ncid_file, ncid_var, &dimensions.front());
  62. handle_error(status, "Failed to get dimensions for variable" +
  63. get_variable_name(ncid_file, ncid_var));
  64. }
  65. bool get_coordinate_variable(int ncid_file, int ncid_dim, int& ncid_coord_var) {
  66. // Get the name of the dimension
  67. char name[NC_MAX_NAME+1];
  68. int status = nc_inq_dimname(ncid_file, ncid_dim, name);
  69. handle_error(status, "Failed to get name of a dimension");
  70. status = nc_inq_varid(ncid_file, name, &ncid_coord_var);
  71. if (status == NC_ENOTVAR) {
  72. return false;
  73. }
  74. handle_error(status,
  75. std::string("Failed to get coordinate variable " \
  76. "corresponding to dimension: ") + name);
  77. return true;
  78. }
  79. std::string get_variable_name(int ncid_file, int ncid_var) {
  80. char name[NC_MAX_NAME+1];
  81. int status = nc_inq_varname(ncid_file, ncid_var, name);
  82. handle_error(status, "Failed to get name of a variable");
  83. return name;
  84. }
  85. } // namespace GuessNC
  86. #endif // HAVE_NETCDF