/* VHdf.cpp */ /* remap Copyright (C) 2006 Fabrice Ducos, fabrice.ducos@icare.univ-lille1.fr This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include "debug.h" #include "common.h" #include "VHdf.h" #include "hdffiledata.h" VHdf::VHdf(const char *filename, const char *dataset, int ichannel, const char *sds_time, const char *sds_latitude, const char *sds_longitude) : VFile(filename, dataset, ichannel, sds_time, sds_latitude, sds_longitude) { PDEBUG; lat_ = NULL; lon_ = NULL; time_ = NULL; data_ = NULL; if (sds_time && sds_latitude && sds_longitude) { strcpy(sds_lat_, sds_latitude); strcpy(sds_lon_, sds_longitude); strcpy(sds_time_, sds_time); read_lat_lon_time(); } assert(ichannel_ >= 0); if (ichannel_ == 0) { read_data_2D(sds_data_); } else { read_data_3D(sds_data_, ichannel_); } } void VHdf::get_calibration(double &slope, double &offset) const { PDEBUG; try { float64 cal; float64 cal_err; float64 cal_offset; float64 offset_err; int32 sds_type; // unused HDFFileData f_data(data_filename_, "r"); Hdf_file *hdf_file = f_data.get_hdf_file(); hdf_file->get_calibration(sds_data_, cal, cal_err, cal_offset, offset_err, sds_type); slope = cal; offset = cal_offset; } catch (bad_file &e) { Debug(cerr << APPNAME << ": " << __PRETTY_FUNCTION__ << ": " << e.what() << endl;); throw; } catch (bad_sds_name &e) { Debug(cerr << APPNAME << ": " << __PRETTY_FUNCTION__ << ": " << e.what() << endl;); throw; } catch (sd_get_calibration_error &e) { Debug(cerr << APPNAME << ": " << __PRETTY_FUNCTION__ << ": " << e.what() << endl;); throw; } catch (...) { cerr << APPNAME << ": " __FILE__ << ": " << __LINE__ << ": unexpected exception" << endl; throw; } } void VHdf::read_data_2D(const char *dataset) { using namespace std; try { HDFFileData f_data(data_filename_, "r"); vector data_dimensions = f_data.get_sds_dimension(dataset); if (data_dimensions.size() != 2) { ostringstream s; s << APPNAME ": " << data_filename_ << "::" << dataset << ": this is not a 2-dimensions array"; //throw VError(s.str().c_str()); // currently buggy, do not use it until VError is fixed throw s.str().c_str(); } assert(data_dimensions.size() == 2); const int nrows = data_dimensions[0]; const int ncols = data_dimensions[1]; dimensions_.push_back(nrows); dimensions_.push_back(ncols); data_type_code_ = f_data.get_hdf_file()->get_sds_data_type(dataset); data_ = f_data.read_data(data_, dataset); } catch (bad_file &e) { Debug(cerr << APPNAME << ": " << __PRETTY_FUNCTION__ << ": " << e.what() << endl;); throw; } catch (bad_sds_name &e) { Debug(cerr << APPNAME << ": " << __PRETTY_FUNCTION__ << ": " << e.what() << endl;); throw; } catch (VError &e) { Debug(cerr << APPNAME << ": " << __PRETTY_FUNCTION__ << ": " << e.what() << endl;); throw; } catch (...) { cerr << APPNAME << ": " __FILE__ << ": " << __LINE__ << ": unexpected exception" << endl; throw; } } void VHdf::read_data_3D(const char *dataset, int ichannel) { using namespace std; const int32 rank = 3; int32 start[3]; int32 *stride = NULL; int32 edges[3]; assert(ichannel > 0); try { HDFFileData f_data(data_filename_, "r"); HDFFileData f_latlon(latlon_filename_, "r"); vector data_dimensions = f_data.get_sds_dimension(dataset); if (data_dimensions.size() != 3) { ostringstream s; s << APPNAME ": " << data_filename_ << "::" << dataset << ": this is not a 3-dimensions array"; //throw VError(s.str().c_str()); // currently buggy, do not use it until VError is fixed throw s.str().c_str(); } assert(data_dimensions.size() == 3); const int nchannels = data_dimensions[0]; const int nrows = data_dimensions[1]; const int ncols = data_dimensions[2]; if ((1 <= ichannel && ichannel <= nchannels) == false) { ostringstream s; s << APPNAME ": " << data_filename_ << "::" << dataset << ": the channel no. " << ichannel << " is out of bounds: [1," << nchannels << "]"; //throw VError(s.str().c_str()); // currently buggy, do not use it until VError is fixed throw s.str().c_str(); } assert(1 <= ichannel && ichannel <= nchannels); dimensions_.push_back(nrows); dimensions_.push_back(ncols); start[0] = ichannel - 1; start[1] = 0; start[2] = 0; edges[0] = 1; edges[1] = nrows; edges[2] = ncols; data_type_code_ = f_data.get_hdf_file()->get_sds_data_type(dataset); data_ = f_data.read_data(data_, dataset, (long int *) start, (long int *) stride, (long int *) edges, (long int) rank); } catch (bad_file &e) { Debug(cerr << APPNAME << ": " << __PRETTY_FUNCTION__ << ": " << e.what() << endl;); throw; } catch (bad_sds_name &e) { Debug(cerr << APPNAME << ": " << __PRETTY_FUNCTION__ << ": " << e.what() << endl;); throw; } catch (VError &e) { Debug(cerr << APPNAME << ": " << __PRETTY_FUNCTION__ << ": " << e.what() << endl;); throw; } catch (const char *err_msg) { Debug(cerr << APPNAME << ": " << __PRETTY_FUNCTION__ << ": " << err_msg << endl;); throw; } catch (...) { cerr << APPNAME << ": " __FILE__ << ": " << __LINE__ << ": unexpected exception" << endl; throw; } } void VHdf::read_lat_lon_time() { PDEBUG; assert(sds_time_ && *sds_time_); assert(sds_lat_ && *sds_lat_); assert(sds_lon_ && *sds_lon_); assert(lat_ == NULL); assert(lon_ == NULL); assert(time_ == NULL); try { HDFFileData f_latlon(latlon_filename_, "r"); HDFFileData f_time(time_filename_, "r"); vector time_dimensions = f_time.get_sds_dimension(sds_time_); vector latlon_dimensions = f_latlon.get_sds_dimension(sds_lat_); const size_t nrows = latlon_dimensions[0]; const size_t ncols = latlon_dimensions[1]; { assert(time_dimensions.size() == 2); assert(time_dimensions[0] == latlon_dimensions[0]); assert(time_dimensions[1] == latlon_dimensions[1]); } lat_ = static_cast(f_latlon.read_data(lat_, sds_lat_)); lon_ = static_cast(f_latlon.read_data(lon_, sds_lon_)); time_ = static_cast(f_time.read_data(time_, sds_time_)); } catch (bad_file &e) { Debug(cerr << APPNAME << ": " << __PRETTY_FUNCTION__ << ": " << e.what() << endl;); throw; } catch (bad_sds_name &e) { Debug(cerr << APPNAME << ": " << __PRETTY_FUNCTION__ << ": " << e.what() << endl;); throw; } catch (...) { cerr << APPNAME << ": " __FILE__ << ": " << __LINE__ << ": unexpected exception" << endl; throw; } } void VHdf::destroy() { PDEBUG; delete[] lat_; lat_ = NULL; delete[] lon_; lon_ = NULL; delete[] time_; time_ = NULL; if (data_) { free(data_); // data_ (allocated with read_data(void *)) is to be free'd with free() and not delete[] data_ = NULL; } } VHdf::~VHdf() { PDEBUG; destroy(); }