template<class T> static bool load_nc_array(const NcFile& ncf, const string& name, vector<T>& dest, bool required = true, int offset = 0, int count = -1) { NcVar *v = load_nc_variable(ncf, name.c_str(), required); if (v) { vector<long> offsets = list_of(offset).repeat(v->num_dims()-1, 0); v->set_cur(&offsets.front()); vector<long> counts (v->num_dims()); long* shape = v->edges(); transform(shape, shape + v->num_dims(), offsets.begin(), counts.begin(), minus<long>()); delete shape; if (count > 0) { counts[0] = count; } dest.resize(product(counts)); bool success = v->get(&dest.front(), &counts.front()); if (!success) { dest.resize(0); check(!required, string("NetcdfDataset::load_nc_array<") + typeid(T).name() + "> " + name + '\n' + "failed with offset " + str(offsets) + ", counts " + str(counts)); } return success; } return false; }
bool ReadAstro::open(const char *path) { assert(!m_ncfile); m_ncfile = new NcFile(path, NcFile::ReadOnly); if (!m_ncfile->is_valid()) { close(); sendError("failed to open NetCDF file %s", path); return false; } if (m_ncfile->get_format() == NcFile::BadFormat) { close(); sendError("bad NetCDF file"); return false; } fprintf(stderr, "dims=%d, vars=%d, attrs=%d\n", m_ncfile->num_dims(), m_ncfile->num_vars(), m_ncfile->num_atts()); for (int i = 0; i < m_ncfile->num_dims(); ++i) { fprintf(stderr, "%s: %ld\n", m_ncfile->get_dim(i)->name(), m_ncfile->get_dim(i)->size()); } for (int i = 0; i < m_ncfile->num_vars(); ++i) { fprintf(stderr, "%s: dims=%d atts=%d vals=%ld type=%d\n", m_ncfile->get_var(i)->name(), m_ncfile->get_var(i)->num_dims(), m_ncfile->get_var(i)->num_atts(), m_ncfile->get_var(i)->num_vals(), m_ncfile->get_var(i)->type()); //int dims = m_ncfile->get_var(i)->num_dims(); NcVar *var = m_ncfile->get_var(i); for (int j = 0; j < var->num_dims(); ++j) { fprintf(stderr, " %s: %ld edge=%ld\n", var->get_dim(j)->name(), var->get_dim(j)->size(), var->edges()[j]); } } for (int i = 0; i < m_ncfile->num_atts(); ++i) { fprintf(stderr, "%s\n", m_ncfile->get_att(i)->name()); } return true; }
static string get_nc_string(const NcFile& ncf, const string& name, int offset = 0, bool required = true) { static array<long, 2> offsets = {{0, 0}}; static array<long, 2> counts = {{1, 0}}; NcVar *v = load_nc_variable(ncf, name.c_str(), required); if (v) { long* shape = v->edges(); offsets.front() = offset; counts.back() = shape[1]; v->set_cur(&offsets.front()); char* temp = new char [shape[1]]; delete shape; bool success = v->get(temp, &counts.front()); if(!success) { check(!required, " index " + str(offset) + " out of bounds for " + name + " in netcdf file"); } string s(temp); delete [] temp; return s; } return ""; }
RadarData_t ReadRadarFile(const string &filename, const float latmin, const float latmax, const float lonmin, const float lonmax) { RadarData_t inputData; // Sets the internal netcdf error handling to nonfatal for this scope NcError error_handler(NcError::verbose_nonfatal); NcFile radarFile(filename.c_str()); if (!radarFile.is_valid()) { cerr << "ERROR: Could not open radar file: " << filename << " for reading.\n"; // Error is indicated by the lack of initialization of // the filename member of the struct. return(inputData); } NcVar* latVar = radarFile.get_var("lat"); if (NULL == latVar) { cerr << "ERROR: invalid data file. No variable called 'lat'!\n"; radarFile.close(); return(inputData); } long latCnt = latVar->num_vals(); double* latVals = new double[latCnt]; latVar->get(latVals, latCnt); inputData.latUnits = GrabAttribute(latVar, 0); inputData.latSpacing = strtod(GrabAttribute(latVar, 1).c_str(), NULL); const long minLatIndex = lower_bound(latVals, latmin, latCnt); const long maxLatIndex = upper_bound(latVals, latmax, latCnt); delete latVals; latCnt = (maxLatIndex - minLatIndex) + 1; latVar->set_cur(minLatIndex); inputData.latVals = new double[latCnt]; latVar->get(inputData.latVals, latCnt); NcVar* lonVar = radarFile.get_var("lon"); if (NULL == lonVar) { cerr << "ERROR: invalid data file. No variable called 'lon'!\n"; radarFile.close(); return(inputData); } long lonCnt = lonVar->num_vals(); double* lonVals = new double[lonCnt]; lonVar->get(lonVals, lonCnt); inputData.lonUnits = GrabAttribute(lonVar, 0); inputData.lonSpacing = strtod(GrabAttribute(lonVar, 1).c_str(), NULL); const long minLonIndex = lower_bound(lonVals, lonmin, lonCnt); const long maxLonIndex = upper_bound(lonVals, lonmax, lonCnt); delete lonVals; lonCnt = (maxLonIndex - minLonIndex) + 1; lonVar->set_cur(minLonIndex); inputData.lonVals = new double[lonCnt]; lonVar->get(inputData.lonVals, lonCnt); NcVar* reflectVar = NULL; reflectVar = radarFile.get_var("value"); if ( reflectVar == NULL ) { // Try this variable name reflectVar = radarFile.get_var("Reflectivity"); } if (reflectVar == NULL) { cerr << "ERROR: invalid data file. No variable called 'value'!\n"; radarFile.close(); return(inputData); } inputData.dataEdges = reflectVar->edges(); // [0] - time, [1] - lat, [2] - lon inputData.dataEdges[1] = latCnt; inputData.dataEdges[2] = lonCnt; inputData.dataVals = new double[inputData.dataEdges[0] * inputData.dataEdges[1] * inputData.dataEdges[2]]; reflectVar->set_cur(0, minLatIndex, minLonIndex); reflectVar->get(inputData.dataVals, inputData.dataEdges); inputData.var_LongName = GrabAttribute(reflectVar, 0); inputData.var_Units = "dBZ";//GrabAttribute(reflectVar, 1); NcVar* timeVar = radarFile.get_var("time"); if (NULL == timeVar) { cerr << "ERROR: invalid data file. No variable called 'time'!\n"; radarFile.close(); return(inputData); } inputData.scanTime = timeVar->as_long(0); inputData.timeUnits = GrabAttribute(timeVar, 0); NcAtt* titleAttrib = radarFile.get_att("title"); inputData.fileTitle = (NULL == titleAttrib ? "" : titleAttrib->as_string(0)); delete titleAttrib; radarFile.close(); // Success! inputData.inputFilename = filename; return(inputData); }