bes  Updated for version 3.20.10
GeoFile.cc
Go to the documentation of this file.
1 
8 #include <netcdf.h>
9 
10 #include <BESDebug.h>
11 
12 #include "GeoFile.h"
13 
14 #define MODULE "geofile"
15 
21 string
22 GeoFile::sanitize_pathname(string path) const
23 {
24  string::size_type last_slash = path.find_last_of('/');
25  ++last_slash; // don't include the slash in the returned string
26  return (last_slash == string::npos) ? path: path.substr(last_slash);
27 }
28 
29 string
30 GeoFile::sidecar_filename(const string &file_name) const
31 {
32  // Is there a file extension?
33  size_t f = file_name.rfind(".");
34  if (f != string::npos)
35  return file_name.substr(0, f) + "_stare.nc";
36  else {
37  string sidecarFileName = file_name;
38  return sidecarFileName.append("_stare.nc");
39  }
40 }
41 
55 int
56 GeoFile::read_sidecar_file(const string &fileName) {
57  BESDEBUG(MODULE, "Reading sidecar file " << fileName << endl);
58 
59  // Open the sidecar file.
60  int ret;
61  if ((ret = nc_open(fileName.c_str(), NC_NOWRITE, &d_ncid)))
62  return ret;
63 
64  // Check the title attribute to make sure this is a sidecar file.
65  char title_in[NC_MAX_NAME + 1];
66  if ((ret = nc_get_att_text(d_ncid, NC_GLOBAL, SSC_TITLE_NAME, title_in)))
67  return ret;
68  if (strncmp(title_in, SSC_TITLE, NC_MAX_NAME))
69  return SSC_NOT_SIDECAR;
70 
71  // How many vars and dims in the index file?
72  int ndims, nvars;
73  if ((ret = nc_inq(d_ncid, &ndims, &nvars, NULL, NULL)))
74  return ret;
75 
76  // Find all variables that are STARE indexes.
77  d_num_index = 0;
78  for (int v = 0; v < nvars; v++) {
79  // Learn about this var.
80  char var_name[NC_MAX_NAME + 1];
81  nc_type xtype;
82  int ndims, dimids[NDIM2], natts;
83  if ((ret = nc_inq_var(d_ncid, v, var_name, &xtype, &ndims, dimids, &natts)))
84  return ret;
85 
86  BESDEBUG(MODULE, "var " << var_name << " type " << xtype << " ndims " << ndims << endl);
87 
88  // Get the long_name attribute value.
89  char long_name_in[NC_MAX_NAME + 1];
90  if ((ret = nc_get_att_text(d_ncid, v, SSC_LONG_NAME, long_name_in)))
91  continue;
92 
93  // If this is a STARE index, learn about it.
94  if (!strncmp(long_name_in, SSC_INDEX_LONG_NAME, NC_MAX_NAME)) {
95  // Save the varid.
96  d_stare_varid.push_back(v);
97 
98  // Find the length of the dimensions.
99  size_t dimlen[NDIM2];
100  if ((ret = nc_inq_dimlen(d_ncid, dimids[0], &dimlen[0])))
101  return ret;
102  if ((ret = nc_inq_dimlen(d_ncid, dimids[1], &dimlen[1])))
103  return ret;
104 
105  // What variables does this STARE index apply to?
106  char variables_in[NC_MAX_NAME + 1];
107  if ((ret = nc_get_att_text(d_ncid, v, SSC_INDEX_VAR_ATT_NAME, variables_in)))
108  return ret;
109 
110  d_variables.emplace_back(string(variables_in));
111 
112  // Save the name of this STARE index variable.
113  d_stare_index_name.emplace_back(var_name);
114 
115  // Save the dimensions of the STARE index var.
116  d_size_i.push_back(dimlen[0]);
117  d_size_j.push_back(dimlen[1]);
118 
119  // Keep count of how many STARE indexes we find in the file.
120  d_num_index++;
121  BESDEBUG(MODULE, "variable_in " << variables_in << endl);
122  }
123  }
124 
125  return 0;
126 }
127 
136 void
137 GeoFile::get_stare_indices(const std::string &variable_name, vector<unsigned long long> &values) {
138 
139  BESDEBUG(MODULE, "get_stare_indices called for '" << variable_name << "'" << endl);
140 
141  // Check all of the sets of STARE indices. 'variables[v]' lists all of the variables
142  // that are indexed by stare_varid[v].
143  for (unsigned long v = 0; v < d_variables.size(); ++v) {
144  BESDEBUG(MODULE, "Looking st: '" << d_variables[v] << "'" << endl);
145 
146  // Is the desired variable listed in the variables[v] string?
147  if (d_variables[v].find(variable_name) != string::npos) {
148  BESDEBUG(MODULE, "found" << endl);
149 
150  values.resize(d_size_i[v] * d_size_j[v]);
151  int status = nc_get_var(d_ncid, d_stare_varid[v], &values[0]);
152  if (status != NC_NOERR)
153  throw BESInternalError("Could not get STARE indices from the sidecar file "
154  + sanitize_pathname(sidecar_filename(d_data_file_name))
155  + " for " + variable_name + " - " + nc_strerror(status), __FILE__, __LINE__);
156  }
157  }
158 }
159 
160 size_t GeoFile::get_variable_rows(string variable_name) const {
161  for (unsigned long v = 0; v < d_variables.size(); ++v) {
162  if (d_variables[v].find(variable_name) != string::npos) {
163  return d_size_i[v];
164  }
165  }
166 
167  throw BESInternalError("Could not get row size from the sidecar file "
168  + sanitize_pathname(sidecar_filename(d_data_file_name))
169  + " for " + variable_name, __FILE__, __LINE__);
170 }
171 
172 size_t GeoFile::get_variable_cols(string variable_name) const {
173  for (unsigned long v = 0; v < d_variables.size(); ++v) {
174  if (d_variables[v].find(variable_name) != string::npos) {
175  return d_size_j[v];
176  }
177  }
178 
179  throw BESInternalError("Could not get column size from the sidecar file "
180  + sanitize_pathname(sidecar_filename(d_data_file_name))
181  + " for " + variable_name, __FILE__, __LINE__);
182 }
183 
190 void
192 {
193  BESDEBUG(MODULE, "Closing sidecar file with ncid " << d_ncid << endl);
194 
195  if (d_ncid != -1) {
196  (void) nc_close(d_ncid);
197  d_ncid = -1;
198  }
199 }
200 
201 
exception thrown if internal error encountered
int read_sidecar_file(const std::string &file_name)
Read a sidecar file.
Definition: GeoFile.cc:56
std::string sidecar_filename(const std::string &file_name) const
Definition: GeoFile.cc:30
std::string sanitize_pathname(string path) const
Strip away path info. Use in error messages.
Definition: GeoFile.cc:22
void close_sidecar_file()
Definition: GeoFile.cc:191
void get_stare_indices(const std::string &var_name, std::vector< STARE_ArrayIndexSpatialValue > &values)
Definition: GeoFile.cc:137