Commit 45ffe13e authored by R.K.Garcia's avatar R.K.Garcia
Browse files

handle HSD format 1.3 including radiance calculation and calibration API

presence of HIMAWARI_FORCE_FORMAT_V1P2 environment variable turns this off and uses old rad_m and rad_b
a warning will be presented if this override is used
old values will be transposed into bt_c2 and rad_c0 in the calibration query API if new values are used
parent 7b7e779d
......@@ -115,6 +115,7 @@ struct HimawariMetadata {
char satellite_name[17];
char processing_center_name[17];
char observation_area[5];
char format_version[33];
};
......
......@@ -107,6 +107,7 @@ struct HimawariMetadata {
char satellite_name[17];
char processing_center_name[17];
char observation_area[5];
char format_version[33];
};
......
......@@ -26,6 +26,7 @@
# include <utility> // std::pair
typedef std::pair<int, int> intpair;
typedef std::pair<double, double> doublepair;
class aHimawariFile {
......@@ -36,6 +37,10 @@ public:
// filename not including directory path
virtual std::string filename() const = 0;
virtual std::string formatVersion() const {
return std::string("");
}
// return the one-based inclusive range of scene lines represented by the file, e.g. (5501,6000)
virtual intpair lineRange() const = 0;
......
......@@ -9,7 +9,7 @@
#include <algorithm> // pair
#include <vector> // vector
#include <cmath> // isnan
#include <cstdio> // tmpfile
#include <cstdio> // tmpfile, sscanf
#include <sys/wait.h> // waitpid
#include <sstream> // ostringstream
#include <strings.h> // memcmp
......@@ -48,6 +48,8 @@ const int LOCAL_ENDIAN=1;
const unsigned MAX_IMAGE_LINES = 30000;
const unsigned MAX_IMAGE_COLUMNS = 30000;
const bool HIMAWARI_FORCE_FORMAT_V1P2 = (0 != getenv("HIMAWARI_FORCE_FORMAT_V1P2"));
// generated code defines the data structures
#include "himawari_file_struct.gxx"
......@@ -1074,6 +1076,9 @@ public:
return res;
}
virtual std::string formatVersion() const {
return trimmed_string(hsd->basic->file_format_version, sizeof(hsd->basic->file_format_version));
}
virtual std::string satelliteName() const {
return trimmed_string(hsd->basic->satellite_name, sizeof(hsd->basic->satellite_name));
......@@ -1106,13 +1111,58 @@ public:
return 0;
}
inline bool is_v1p3_or_newer() const {
const string fv = formatVersion();
int major = 0, minor = 0;
if (2==sscanf(fv.c_str(), "%d.%d", &major, &minor)) {
return ((major > 1) || (major==1 && minor>=3));
}
LOG << "WARNING: Unable to parse format version '" << fv << "'\n";
return false;
}
inline bool is_v1p3_albedo() const {
return (is_v1p3_or_newer() && (bandType()==AHI_BAND_ALBEDO));
}
// Format version 1.3 stores a preferred slope and intercept in a different part of the cal block
inline doublepair preferred_rad_m_b() const {
if (is_v1p3_albedo() && !HIMAWARI_FORCE_FORMAT_V1P2) {
// LOG << "INFO: using HSD format version 1.3 radiance slope and intercept values\n";
return doublepair(hsd->cal->bt_c2, hsd->cal->rad_c0); // FUTURE: apply a proper union
} else { // BT bands use same m & b as prior format revisions
static bool not_yet_explained = true;
if (HIMAWARI_FORCE_FORMAT_V1P2 && not_yet_explained) {
LOG << "WARNING: HIMAWARI_FORCE_FORMAT_V1P2 set: will use v1.0~v1.2 radiance slope/intercept for albedo channels\n";
not_yet_explained = false;
}
return doublepair(hsd->cal->rad_m, hsd->cal->rad_b);
}
}
inline HimawariRadianceCalc preferredRadianceCalc() const {
const doublepair mandb = preferred_rad_m_b();
HimawariRadianceCalc
calc_rad(mandb.first, mandb.second);
return calc_rad;
}
virtual int calibration(HimawariCalibration &zult) const {
zult.rad_m = hsd->cal->rad_m;
zult.rad_b = hsd->cal->rad_b;
// transpose the preferred m and b into the rad_m and rad_b spaces, albedo v1.3 format files
// swap the original values into the new values' location
doublepair mandb(preferred_rad_m_b());
const bool transpose_mandb = is_v1p3_albedo();
// always present the preferred m and b as the primary
zult.rad_m = mandb.first;
zult.rad_b = mandb.second;
zult.bt_c0_or_albedo_cprime = hsd->cal->bt_c0_or_albedo_cprime;
zult.bt_c1 = hsd->cal->bt_c1;
zult.bt_c2 = hsd->cal->bt_c2;
zult.rad_c0 = hsd->cal->rad_c0;
zult.bt_c2 = transpose_mandb? hsd->cal->rad_m : hsd->cal->bt_c2;
zult.rad_c0 = transpose_mandb? hsd->cal->rad_b : hsd->cal->rad_c0;
zult.rad_c1 = hsd->cal->rad_c1;
zult.rad_c2 = hsd->cal->rad_c2;
zult.c = hsd->cal->c;
......@@ -1153,8 +1203,9 @@ public:
float *output, int32_t line_increment, int32_t column_increment /* output data, and how many cells to add per line/column addressed */
/* default of 0 implies line_increment = columns, column_increment = 1 */
) const {
HimawariRadianceCalc
calc_rad(hsd->cal->rad_m, hsd->cal->rad_b);
calc_rad(preferredRadianceCalc());
return copyHimawari(hsd,
line_offset, column_offset,
......@@ -1178,7 +1229,7 @@ public:
) const {
HimawariRadianceCalc
calc_rad(hsd->cal->rad_m, hsd->cal->rad_b);
calc_rad(preferredRadianceCalc());
HimawariBrightnessTempCalc
calc_bt(hsd->cal->h, hsd->cal->c, hsd->cal->k,
hsd->cal->central_wavelength,
......@@ -1207,7 +1258,7 @@ public:
) const {
HimawariRadianceCalc
calc_rad(hsd->cal->rad_m, hsd->cal->rad_b);
calc_rad(preferredRadianceCalc());
HimawariAlbedoCalc
calc_alb(hsd->cal->bt_c0_or_albedo_cprime);
......
......@@ -1018,6 +1018,7 @@ int queryHimawariSceneMetadata(const struct HimawariScene *it, struct HimawariMe
out->wmo_sat_id = wmo_sat_id_for_name(strip(&out->satellite_name[0], &out->satellite_name[16]));
strncpy(out->processing_center_name, firstFile->processingCenterName().c_str(), 17);
strncpy(out->observation_area, firstFile->observationArea().c_str(), 5);
strncpy(out->format_version, firstFile->formatVersion().c_str(), 33);
return 0;
}
......
......@@ -79,6 +79,7 @@ module hsd_structs
character(c_char) :: satellite_name(17)
character(c_char) :: processing_center_name(17)
character(c_char) :: observation_area(5)
character(c_char) :: format_version(33)
end type hsd_metadata
type, bind(c) :: hsd_source
......
......@@ -30,6 +30,9 @@ static int dump_bt(const HimawariScene *it, const char *pathname)
namestream << "BT_" << stem << ".real4." << columns << '.' << lines;
string filename(namestream.str());
std::string format = std::string(meta.format_version, sizeof(meta.format_version));
std::cout << "Format: '" << format << "'\n";
// allocate output data buffer
float *buffer = (float *)malloc(sizeof(float) * columns * lines);
assert(buffer!=0);
......
Markdown is supported
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