WSL/SLF GitLab Repository

Commit b30d9ebf authored by Thomas Egger's avatar Thomas Egger
Browse files

NetCDFIO: Cleanup and code reduction

parent aa89ed27
......@@ -204,7 +204,8 @@ void NetCDFIO::read2DGrid_internal(Grid2DObject& grid_out, const std::string& fi
delete[] lat; delete[] lon; delete[] grid;
}
void NetCDFIO::copy_grid(const size_t& latlen, const size_t& lonlen, double*& lat, double*& lon, double*& grid, Grid2DObject& grid_out)
void NetCDFIO::copy_grid(const size_t& latlen, const size_t& lonlen, const double * const lat, const double * const lon,
const double * const grid, Grid2DObject& grid_out)
{
Coords location(coordin, coordinparam);
location.setLatLon(lat[0], lon[0], grid[0]);
......@@ -234,8 +235,8 @@ void NetCDFIO::copy_grid(const size_t& latlen, const size_t& lonlen, double*& la
* determine a factor that will be used for resampling the grid to likewise consist of
* quadratic cells.
*/
double NetCDFIO::calculate_cellsize(const size_t& latlen, const size_t& lonlen,
double const* lat, double const* lon, double& factor_x, double& factor_y)
double NetCDFIO::calculate_cellsize(const size_t& latlen, const size_t& lonlen, const double * const lat, const double * const lon,
double& factor_x, double& factor_y)
{
Coords llcorner(coordin, coordinparam);
llcorner.setLatLon(lat[0], lon[0], IOUtils::nodata);
......@@ -658,7 +659,7 @@ void NetCDFIO::writeMeteoData(const std::vector< std::vector<MeteoData> >& vecMe
copy_data(number_of_stations, number_of_records, vecMeteo, map_param_name, map_data);
write_record(ncid, NetCDFIO::cf_time, vid_time, number_of_records, dates);
write_record(ncid, NetCDFIO::cf_time, vid_time, 0, number_of_records, dates);
for (map<string, double*>::const_iterator it = map_data.begin(); it != map_data.end(); it++) {
const string& varname = it->first;
write_data(ncid, varname, varid[varname], map_data[varname]);
......@@ -928,7 +929,7 @@ void NetCDFIO::write2DGrid_internal(const Grid2DObject& grid_in, const std::stri
}
if (is_record) {
size_t pos_start = append_record(ncid, NetCDFIO::cf_time, vid_time, date.getModifiedJulianDate());
size_t pos_start = add_record(ncid, NetCDFIO::cf_time, vid_time, date.getModifiedJulianDate());
write_data(ncid, varname, vid_var, grid_in, pos_start, data);
} else {
write_data(ncid, varname, vid_var, data);
......@@ -1242,7 +1243,12 @@ void NetCDFIO::read_data_2D(const int& ncid, const std::string& varname, const i
void NetCDFIO::read_value(const int& ncid, const std::string& varname, const int& varid, double& data)
{
size_t index[] = {0};
read_value(ncid, varname, varid, 0, data);
}
void NetCDFIO::read_value(const int& ncid, const std::string& varname, const int& varid, const size_t& pos, double& data)
{
size_t index[] = {pos};
int status = nc_get_var1_double(ncid, varid, index, &data);
if (status != NC_NOERR)
......@@ -1268,14 +1274,15 @@ void NetCDFIO::read_data(const int& ncid, const std::string& varname, const int&
throw IOException("Could not retrieve data for variable '" + varname + "': " + nc_strerror(status), AT);
}
void NetCDFIO::write_data(const int& ncid, const std::string& varname, const int& varid, double*& data)
void NetCDFIO::write_data(const int& ncid, const std::string& varname, const int& varid, const double * const data)
{
int status = nc_put_var_double(ncid, varid, data);
if (status != NC_NOERR)
throw IOException("Could not write data for variable '" + varname + "': " + nc_strerror(status), AT);
}
void NetCDFIO::write_data(const int& ncid, const std::string& varname, const int& varid, const Grid2DObject& grid, const size_t& pos_start, double*& data)
void NetCDFIO::write_data(const int& ncid, const std::string& varname, const int& varid, const Grid2DObject& grid,
const size_t& pos_start, const double * const data)
{
size_t start[] = {pos_start, 0, 0};
size_t count[] = {1, grid.nrows, grid.ncols};
......@@ -1286,7 +1293,10 @@ void NetCDFIO::write_data(const int& ncid, const std::string& varname, const int
}
}
size_t NetCDFIO::find_record(const int& ncid, const std::string& varname, const int& varid, const double& data)
// Adding a record value (e.g. timestamp), in case it doesn't already exist and
// that the value is greater than the last record variable value. For example,
// timestamps have to be strictly monotonically increasing or already existent.
size_t NetCDFIO::add_record(const int& ncid, const std::string& varname, const int& varid, const double& data)
{
int dimid;
size_t dimlen;
......@@ -1295,59 +1305,65 @@ size_t NetCDFIO::find_record(const int& ncid, const std::string& varname, const
//check if record already exists
if (dimlen > 0) {
double *timesteps = new double[dimlen];
read_data(ncid, varname, varid, timesteps);
double last_value = IOUtils::nodata;
read_value(ncid, varname, varid, dimlen-1, last_value);
for (size_t ii=0; ii<dimlen; ii++) {
if (timesteps[ii] == data) {
delete[] timesteps;
return ii;
if (last_value == data) return (dimlen - 1); //The timestamp already exists
if (last_value > data) {
size_t pos = find_record(ncid, varname, dimid, data); // Search for a possible match
if (pos != IOUtils::npos) {
return pos;
} else {
throw IOException("The variable '" + varname + "' has to be linearly increasing", AT);
}
}
delete[] timesteps;
}
return IOUtils::npos; // data not found
}
void NetCDFIO::write_record(const int& ncid, const std::string& varname, const int& varid, const size_t& length, double*& data)
{
size_t start[] = {0};
size_t count[] = {length};
int status = nc_put_vara_double(ncid, varid, start, count, data);
if (status != NC_NOERR)
throw IOException("Could not write data for variable '" + varname + "': " + nc_strerror(status), AT);
write_record(ncid, varname, varid, dimlen, 1, &data);
return dimlen;
}
size_t NetCDFIO::append_record(const int& ncid, const std::string& varname, const int& varid, const double& data)
// Finding a certain record variable value (e.g. timestamp) by retrieving all
// record values and then performing a linear search
size_t NetCDFIO::find_record(const int& ncid, const std::string& varname, const int& varid, const double& data)
{
int dimid, status;
int dimid;
size_t dimlen;
get_dimension(ncid, varname, dimid, dimlen);
//check if record already exists
if (dimlen > 0) {
double last_value = IOUtils::nodata;
const size_t index_read[] = {dimlen-1};
double *record_value = new double[dimlen];
read_data(ncid, varname, varid, record_value);
status = nc_get_var1_double(ncid, varid, index_read, &last_value);
if (status != NC_NOERR)
throw IOException("Could not retrieve last value for record '" + varname + "': " + nc_strerror(status), AT);
cout << "Last time value: " << last_value << endl;
for (size_t ii=0; ii<dimlen; ii++) {
if (record_value[ii] == data) {
delete[] record_value;
return ii;
}
}
if (last_value == data) return (dimlen - 1); //The timestamp already exists
delete[] record_value;
}
const size_t index[] = {dimlen}; //append at the end
return IOUtils::npos; // data not found
}
status = nc_put_var1_double(ncid, varid, index, &data);
if (status != NC_NOERR)
throw IOException("Could not write data for record '" + varname + "': " + nc_strerror(status), AT);
// In case the dimension length of the record variable is less than start_pos
// values will be added (containing the _FillValue) until a length of start_pos-1
// has been reached. Finally the length amount elements from start_pos and on
// will be added.
void NetCDFIO::write_record(const int& ncid, const std::string& varname, const int& varid, const size_t& start_pos, const size_t& length, const double * const data)
{
size_t start[] = {start_pos};
size_t count[] = {length};
return dimlen;
int status = nc_put_vara_double(ncid, varid, start, count, data);
if (status != NC_NOERR)
throw IOException("Could not write data for record variable '" + varname + "': " + nc_strerror(status), AT);
}
void NetCDFIO::add_dimension(const int& ncid, const std::string& dimname, const size_t& length, int& dimid)
......
......@@ -82,7 +82,6 @@ class NetCDFIO : public IOInterface {
void readData(const int& ncid, const size_t& index_start, const std::vector<Date>& vec_date, const std::map<std::string, size_t>& map_parameters,
const MeteoData& meteo_data, std::vector< std::vector<MeteoData> >& vecMeteo);
void readMetaData(const int& ncid, std::vector<StationData>& vecStation);
void copy_grid(const size_t& latlen, const size_t& lonlen, double*& lat, double*& lon, double*& grid, Grid2DObject& grid_out);
std::string get_varname(const MeteoGrids::Parameters& parameter);
void get_indices(const int& ncid, const Date& dateStart, const Date& dateEnd, size_t& indexStart, size_t& indexEnd, std::vector<Date>& vecDate);
void calculate_offset(const std::string& units, NetCDFIO::TimeUnit& time_unit, Date& offset);
......@@ -91,8 +90,10 @@ class NetCDFIO : public IOInterface {
void read2DGrid_internal(Grid2DObject& grid_out, const std::string& full_name, const std::string& varname, const Date& date=Date());
void write2DGrid_internal(const Grid2DObject& grid_in, const std::string& filename, const std::string& varname, const Date& date=Date());
void fill_data(const Grid2DObject& grid, double*& data);
double calculate_cellsize(const size_t& latlen, const size_t& lonlen,
double const * lat, double const* lon, double& factor_x, double& factor_y);
void copy_grid(const size_t& latlen, const size_t& lonlen, const double * const lat, const double * const lon,
const double * const grid, Grid2DObject& grid_out);
double calculate_cellsize(const size_t& latlen, const size_t& lonlen, const double * const lat, const double * const lon,
double& factor_x, double& factor_y);
void calculate_dimensions(const Grid2DObject& grid, double*& lat_array, double*& lon_array);
void add_attributes_for_variable(const int& ncid, const int& varid, const std::string& varname);
void create_latlon_dimensions(const int& ncid, const Grid2DObject& grid, int& did_lat, int& did_lon, int& vid_lat, int& vid_lon);
......@@ -130,16 +131,19 @@ class NetCDFIO : public IOInterface {
void read_data_2D(const int& ncid, const std::string& varname, const int& varid,
const size_t& record, const size_t& count, const size_t& length, double*& data);
void read_value(const int& ncid, const std::string& varname, const int& varid, double& data);
void read_value(const int& ncid, const std::string& varname, const int& varid, const size_t& pos, double& data);
void read_data(const int& ncid, const std::string& varname, const int& varid, double*& data);
//Writing data to NetCDF file
void write_data(const int& ncid, const std::string& varname, const int& varid, double*& data);
void write_data(const int& ncid, const std::string& varname, const int& varid, const Grid2DObject& grid, const size_t& pos_start, double*& data);
void write_data(const int& ncid, const std::string& varname, const int& varid, const double * const data);
void write_data(const int& ncid, const std::string& varname, const int& varid, const Grid2DObject& grid,
const size_t& pos_start, const double * const data);
//Dealing with variables that have dimension NC_UNLIMITED
size_t find_record(const int& ncid, const std::string& varname, const int& varid, const double& data);
size_t append_record(const int& ncid, const std::string& varname, const int& varid, const double& data);
void write_record(const int& ncid, const std::string& varname, const int& varid, const size_t& length, double*& data);
size_t add_record(const int& ncid, const std::string& varname, const int& varid, const double& data);
void write_record(const int& ncid, const std::string& varname, const int& varid, const size_t& pos,
const size_t& length, const double * const data);
//Dealing with variables and dimensions
bool check_dim_var(const int& ncid, const std::string& dimname);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment