/* VXRIT_SEVIRI.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 // getenv #include #include #include "debug.h" #include "VXRIT_SEVIRI.h" #include "normalize_cal_factors.h" #include "date.h" const double VXRIT_SEVIRI::wavelengths[] = { 0.6, 0.8, 1.6, 3.9, 6.2, 7.3, 8.703, 9.7, 10.745, 11.910, 13.4 }; void VXRIT_SEVIRI::allocate(size_t n) { PDEBUG; assert(lat_ == NULL); assert(lon_ == NULL); assert(time_ == NULL); assert(data_ == NULL); try { lat_ = new float[n]; lon_ = new float[n]; time_ = new time_type[n]; data_ = malloc(n*sizeof(uint16_t)); } catch (std::bad_alloc &e) { Debug(std::cerr << APPNAME << ": " << __PRETTY_FUNCTION__ << ": " << e.what() << endl;); destroy(); throw; } catch (...) { std::cerr << APPNAME << ": internal error: unexpected exception" << endl; destroy(); throw; } } void VXRIT_SEVIRI::destroy() { PDEBUG; if (lat_) { delete[] lat_; lat_ = NULL; } if (lon_) { delete[] lon_; lon_ = NULL; } if (time_) { delete[] time_; time_ = NULL; } if (data_) { free(data_); data_ = NULL; } } void VXRIT_SEVIRI::read_seviri_latlon(const char *filename, size_t nbuffer, float *buffer) { PDEBUG; FILE *stream; size_t nread; stream = fopen(filename, "r"); if (stream == NULL) { perror(filename); exit (EXIT_FAILURE); } nread = fread(buffer, nbuffer*sizeof(*buffer), 1, stream); if (nread != 1) { perror(filename); exit (EXIT_FAILURE); } if (fclose(stream)) { perror(filename); exit(EXIT_FAILURE); } } VXRIT_SEVIRI::VXRIT_SEVIRI(const char *filename, const char *dataset) : VFile(filename, dataset) { PDEBUG; int err = 0; const int nrows = SEVIRI_NROWS; const int ncols = SEVIRI_NCOLS; xrit_rows_infos_t xrit_rows_infos; uint16_t *uint16_data; assert(dimensions_.size() == 0); dimensions_.push_back(nrows); dimensions_.push_back(ncols); allocate(nrows*ncols); const char *env_rawpath = getenv("REMAP_RAWPATH"); if (env_rawpath == NULL) { env_rawpath = "."; } std::string rawpath(env_rawpath); std::string seviri_lat_file = rawpath + "/seviri_latitudes.raw"; std::string seviri_lon_file = rawpath + "/seviri_longitudes.raw"; assert(lat_); assert(lon_); assert(time_); assert(data_); xrit_orientation(XRIT_NORTH_AT_TOP); read_seviri_latlon(seviri_lat_file.c_str(), nrows*ncols, lat_); read_seviri_latlon(seviri_lon_file.c_str(), nrows*ncols, lon_); data_type_code_ = DFNT_UINT16; uint16_data = static_cast(data_); err = read_xrit(filename, uint16_data, NULL, NULL, &xrit_rows_infos, &prologue_, NULL); /* a quick'n'dirty hack to display system error messages if read_xrit failed. * TODO: find a better way to do this (the best way should be to add an error function in libxrit, * or to have errno returned by read_xrit) */ if (err < 0) { FILE *stream; stream = fopen(filename, "r"); if (stream == NULL) { ostringstream s; s << filename << ": " << strerror(errno); throw s.str(); } else { cerr << APPNAME ": " << __FILE__ << ": " << __LINE__ << ": unexpected error on read_xrit: read_xrit() returned " << err << endl; exit (EXIT_FAILURE); } } // converts zero counts from the XRIT file into g_data_fill_value (zero counts are not initialized in XRIT) for (int irow = 0 ; irow < nrows ; ++irow) { for (int icol = 0 ; icol < ncols ; ++icol) { const int ipixel = irow*ncols + icol; if (uint16_data[ipixel] == 0) uint16_data[ipixel] = g_data_fill_value; } } // converts from Unix time into TAI93 time // dataset 'time' will be considered 'suspicious' if no row contains a valid time info (different from 0 or -1) // time info appears to be broken in some old XRIT files Date date; bool suspicious_time = true; for (int irow = 0 ; irow < nrows ; ++irow) { time_t xrit_time = xrit_rows_infos.time[irow]; if (xrit_time != 0 && xrit_time != static_cast(-1)) { suspicious_time = false; } date.set_epoch_time(xrit_time); time_[irow*ncols + 0] = date.get_TAI93_time(); for (int icol = 1 ; icol < ncols ; ++icol) { time_[irow*ncols + icol] = time_[irow*ncols + 0]; } } if (suspicious_time == true) { std::cerr << APPNAME << ": " << filename << ": suspicious time field (seems to be empty)" << endl; } } void VXRIT_SEVIRI::get_calibration(double &slope, double &offset) const { PDEBUG; int met8_channel = xrit_met8_channel(filename().c_str()); assert(0 <= met8_channel && met8_channel <= 10); slope = ntoh_double(prologue_.radiometricProcessing.level1_5ImageCalibration[met8_channel].cal_Slope); offset = ntoh_double(prologue_.radiometricProcessing.level1_5ImageCalibration[met8_channel].cal_Offset); normalize_seviri_factors(met8_channel, slope, offset); } VXRIT_SEVIRI::~VXRIT_SEVIRI() { PDEBUG; destroy(); }