/* This program reads Remote Sensing Systems Scatterometer Level-4 gridded bytemap files, Version-4, GMF: Ku-2011 The data are returned in 1 x 5 x 720 x 1440 arrays. the second index of the array is the data type (wind speed,wind direction and rain bitflag) the third index of the array is the latitude in 1/4 degrees and the fourth is the longitude in 1/4 degrees The center of the first cell of the 1440 column and 720 row map is at 0.125 E longitude and -89.875 latitude. The center of the second cell is 0.375 E longitude, -89.875 latitude. XLAT=0.25*ILAT-90.125 XLON=0.25*ILON-0.125 You must UNZIP FILES before reading them CHANGE filename format of file names are: 3-day qscat_yyyymmddv4_d3d weekly qscat_yyyymmddv4 monthly qscat_yyyymmv4 where ss = satellite number yyyy = year mm = month dd = day of month This main program can be adapted to your needs. It also calls a subroutine that extracts the rain data. Data Types: 1 Wind Speed : windspd = 10m surface wind speed in m/s 2 Wind Direction : winddir = direction wind is flowing to, North is 0 deg 3 Combination Rain Data : use bit extraction to access all data bit pos 0 SCATTEROMETER rainflag (0=no rain, 1=rain) bit pos 1 collocated SSMI, TMI or AMSR observation within 60 min=1, else=0 bit pos 2-7 0-63: radiometer rain where: 0= absolutely no rain 1= rain in one of the adjacent cells 2= Radiometer columnar RR = 0.5 km*mm/hr 3= Radiometer columnar RR = 1.0 4: Radiometer columnar RR = 1.5 etc. The rain subroutine will extract these bit flags and add the following 2 arrays 4 scatflag (0=no rain, 1 = rain) and 5 radrain: 251-255 = no rad data -1.0 = adjacent rain exists 0.0-31.0 = radiometer columnar rain rate in km*mm/hr Data from the daily files are scalar (wind speed) and vector (wind direction) averaged to produce the values in the time-averaged files. A data value for a given cell is only provided in a time-averaged file if a minimum number of pass data exist within the time period being produced (3-day maps, 2 obs; week maps, 5 obs; month maps, 20 obs) 3-day = (average of 3 days ending on file date) weekly= (average of 7 days ending on Saturday of file date) monthly=(average of all days in month) Please make sure your system/compiler reads the data as an array of 8-bit unsigned integer values (0-255) Please read the data description on www.remss.com To contact RSS support: http://www.remss.com/support 8/2014 n.picard */ #include #include #include #include #include #include #include #include "dataset.h" #include "quikscat_averaged.h" using namespace std; QuikScataveraged::QuikScataveraged(char * _filename, int _missing) { filename = _filename; missing = _missing; } QuikScataveraged::QuikScataveraged(char * filename) { QuikScataveraged(filename, 0); } QuikScataveraged::QuikScataveraged() { QuikScataveraged(""); } void QuikScataveraged::show_rain(int ilat, int ilon, int iasc) { int r = data.at(iasc).at(get_index("rain")).at(ilon).at(ilat); cout << r << " " << r % 2 << " " << (r % 4)/2 << " " << (r/4)*.5; cout << "\n"; } void QuikScataveraged::unpack_rain() { for(int _asc = 0; _asc < get_dimensions().at(0); _asc++) { vector > scatflag; vector > radrain; int lon_m = get_dimensions().at(2); int lat_m = get_dimensions().at(3); for(int _lon = 0; _lon < lon_m; _lon++) { vector scat_v1; vector rad_v1; for(int _lat = 0; _lat < lat_m; _lat++) { float cell = data.at(_asc).at(get_index("rain")).at(_lon).at(_lat); if (cell > 250) { scat_v1.push_back(cell); rad_v1.push_back(cell); } else { scat_v1.push_back((int)cell % 2); if (((int)cell % 4)/2 == 0) { rad_v1.push_back(255); } else if (((int)cell/4) == 0) { rad_v1.push_back(0); } else if (((int)cell/4) == 1) { rad_v1.push_back(-1); } else { rad_v1.push_back((((int)cell/4)-1)*0.5); } } } scatflag.push_back(scat_v1); radrain.push_back(rad_v1); } data.at(_asc).push_back(scatflag); data.at(_asc).push_back(radrain); } } std::vector QuikScataveraged::get_attributes() { std::vector m; m.push_back("coordinates"); m.push_back("long_name"); m.push_back("units"); m.push_back("valid_min"); m.push_back("valid_max"); return m; } vector QuikScataveraged::get_dimensions() { vector temp; temp.push_back(1); temp.push_back(3); temp.push_back(720); temp.push_back(1440); return temp; } std::vector QuikScataveraged::get_coordinates() { std::vector m; m.push_back("orbit_segment"); m.push_back("variable"); m.push_back("latitude"); m.push_back("longitude"); return m; } std::vector QuikScataveraged::get_variables() { std::vector m; m.push_back("windspd"); m.push_back("winddir"); m.push_back("rain"); m.push_back("scatflag"); m.push_back("radrain"); m.push_back("longitude"); m.push_back("latitude"); m.push_back("land"); m.push_back("ice"); m.push_back("nodata"); return m; } int QuikScataveraged::get_index(std::string var) { if (var == "windspd") return 0; if (var == "winddir") return 1; if (var == "rain") return 2; if (var == "scatflag") return 3; if (var == "radrain") return 4; } float QuikScataveraged::get_scale(std::string var) { if (var == "windspd") return 0.2f; if (var == "winddir") return 1.5f; if (var == "rain") return 1; if (var == "scatflag") return 1; if (var == "radrain") return 1; } float QuikScataveraged::get_offset(std::string var) { return 0; } std::string QuikScataveraged::get_long_name(std::string var) { if (var == "windspd") return "10m Surface Wind Speed"; if (var == "winddir") return "10m Surface Wind Direction"; if (var == "rain") return "Rain Flag"; if (var == "scatflag") return "Scatterometer Rain Flag"; if (var == "radrain") return "Radiometer Rain Flag"; if (var == "longitude") return "Grid Cell Center Longitude"; if (var == "latitude") return "Grid Cell Center Latitude"; if (var == "land") return "Is this land?"; if (var == "ice") return "Is this ice?"; if (var == "nodata") return "Is there no data?"; } std::string QuikScataveraged::get_units(std::string var) { if (var == "windspd") return "m/s"; if (var == "winddir") return "deg oceanographic"; if (var == "rain") return "km*mm/hr"; if (var == "scatflag") return "0=no-rain, 1=rain"; if (var == "radrain") return "0=no-rain, -1=adjacent-rain, >0=rain(km*mm/hr)"; if (var == "longitude") return "degrees east"; if (var == "latitude") return "degrees north"; if (var == "land") return "True or False"; if (var == "ice") return "True or False"; if (var == "nodata") return "True or False"; } float QuikScataveraged::get_valid_min(std::string var) { if (var == "windspd") return 0.0; if (var == "winddir") return 0.0; if (var == "rain") return 0; if (var == "scatflag") return 0; if (var == "radrain") return -1; if (var == "longitude") return 0.0; if (var == "latitude") return -90.0; if (var == "land") return 0.0; if (var == "ice") return 0.0; if (var == "nodata") return 0.0; } float QuikScataveraged::get_valid_max(std::string var) { if (var == "windspd") return 50.0; if (var == "winddir") return 360.0; if (var == "rain") return 1; if (var == "scatflag") return 1; if (var == "radrain") return 31; if (var == "longitude") return 360.0; if (var == "latitude") return 90.0; if (var == "land") return 1.0; if (var == "ice") return 1.0; if (var == "nodata") return 1.0; } AveragedVerify::AveragedVerify() {} void AveragedVerify::checkVerify_scat(Dataset &dataset) { dataset.show_somedata_scat(iasc, variables, ilat1, ilat2, ilon1, ilon2); } AveragedVerify::AveragedVerify(Dataset &dataset) { ilon1 = 169; ilon2 = 174; ilat1 = 273; ilat2 = 277; iasc = 0; variables.push_back("windspd"); variables.push_back("winddir"); variables.push_back("scatflag"); variables.push_back("radrain"); checkVerify_scat(dataset); }