|
@@ -3,7 +3,7 @@
|
|
|
*
|
|
|
* MODULE: i.landsat.toar
|
|
|
*
|
|
|
- * AUTHOR(S): E. Jorge Tizado - ej.tizado@unileon.es
|
|
|
+ * AUTHOR(S): E. Jorge Tizado - ej.tizado at unileon.es
|
|
|
* Hamish Bowman (small grassification cleanups)
|
|
|
* Yann Chemin (v7 + L5TM _MTL.txt support) [removed after update]
|
|
|
* Adopted for GRASS 7 by Martin Landa <landa.martin gmail.com>
|
|
@@ -27,6 +27,8 @@
|
|
|
|
|
|
#include "local_proto.h"
|
|
|
|
|
|
+#define QCALMAX 65536 /* L1-7=256 but L8=65536 */
|
|
|
+
|
|
|
int main(int argc, char *argv[])
|
|
|
{
|
|
|
struct History history;
|
|
@@ -49,14 +51,14 @@ int main(int argc, char *argv[])
|
|
|
|
|
|
lsat_data lsat;
|
|
|
char band_in[GNAME_MAX], band_out[GNAME_MAX];
|
|
|
- int i, j, q, method, pixel, dn_dark[MAX_BANDS], dn_mode[MAX_BANDS];
|
|
|
+ int i, j, q, method, pixel, dn_dark[MAX_BANDS], dn_mode[MAX_BANDS], dn_sat;
|
|
|
int overwrite;
|
|
|
double qcal, rad, ref, percent, ref_mode, rayleigh;
|
|
|
+ unsigned long hist[QCALMAX], h_max;
|
|
|
|
|
|
struct Colors colors;
|
|
|
struct FPRange range;
|
|
|
double min, max;
|
|
|
- unsigned long hist[256], h_max;
|
|
|
|
|
|
/* initialize GIS environment */
|
|
|
G_gisinit(argv[0]);
|
|
@@ -64,7 +66,7 @@ int main(int argc, char *argv[])
|
|
|
/* initialize module */
|
|
|
module = G_define_module();
|
|
|
module->description =
|
|
|
- _("Calculates top-of-atmosphere radiance or reflectance and temperature for Landsat MSS/TM/ETM+/OT.");
|
|
|
+ _("Calculates top-of-atmosphere radiance or reflectance and temperature for Landsat MSS/TM/ETM+/OLI");
|
|
|
G_add_keyword(_("imagery"));
|
|
|
G_add_keyword(_("radiometric conversion"));
|
|
|
G_add_keyword(_("radiance"));
|
|
@@ -100,29 +102,29 @@ int main(int argc, char *argv[])
|
|
|
sensor->key = "sensor";
|
|
|
sensor->type = TYPE_STRING;
|
|
|
sensor->label = _("Spacecraft sensor");
|
|
|
- sensor->description =
|
|
|
- _("Required only if 'metfile' not given (recommended for sanity)");
|
|
|
- sensor->options = "mss1,mss2,mss3,mss4,mss5,tm4,tm5,tm7,ot8";
|
|
|
+ sensor->description = _("Required only if 'metfile' not given (recommended for sanity)");
|
|
|
+ sensor->options = "mss1,mss2,mss3,mss4,mss5,tm4,tm5,tm7,oli8";
|
|
|
desc = NULL;
|
|
|
G_asprintf(&desc,
|
|
|
- "mss1;%s;mss2;%s;mss3;%s;mss4;%s;mss5;%s;tm4;%s;tm5;%s;tm7;%s;ot8;%s",
|
|
|
- _("Landsat-1 MSS"),
|
|
|
- _("Landsat-2 MSS"),
|
|
|
- _("Landsat-3 MSS"),
|
|
|
- _("Landsat-4 MSS"),
|
|
|
- _("Landsat-5 MSS"),
|
|
|
- _("Landsat-4 TM"),
|
|
|
- _("Landsat-5 TM"),
|
|
|
- _("Landsat-7 ETM+"), _("Landsat_8 OLI/TIRS"));
|
|
|
+ "mss1;%s;mss2;%s;mss3;%s;mss4;%s;mss5;%s;tm4;%s;tm5;%s;tm7;%s;oli8;%s",
|
|
|
+ _("Landsat-1 MSS"),
|
|
|
+ _("Landsat-2 MSS"),
|
|
|
+ _("Landsat-3 MSS"),
|
|
|
+ _("Landsat-4 MSS"),
|
|
|
+ _("Landsat-5 MSS"),
|
|
|
+ _("Landsat-4 TM"),
|
|
|
+ _("Landsat-5 TM"),
|
|
|
+ _("Landsat-7 ETM+"),
|
|
|
+ _("Landsat_8 OLI/TIRS"));
|
|
|
sensor->descriptions = desc;
|
|
|
- sensor->required = NO;
|
|
|
+ sensor->required = NO; /* perhaps YES for clarity */
|
|
|
sensor->guisection = _("Metadata");
|
|
|
|
|
|
metho = G_define_option();
|
|
|
metho->key = "method";
|
|
|
metho->type = TYPE_STRING;
|
|
|
metho->required = NO;
|
|
|
- metho->options = "uncorrected,corrected,dos1,dos2,dos2b,dos3,dos4";
|
|
|
+ metho->options = "uncorrected,dos1,dos2,dos2b,dos3,dos4";
|
|
|
metho->label = _("Atmospheric correction method");
|
|
|
metho->description = _("Atmospheric correction method");
|
|
|
metho->answer = "uncorrected";
|
|
@@ -232,10 +234,10 @@ int main(int argc, char *argv[])
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
|
|
|
|
- /*****************************************
|
|
|
- * ---------- START --------------------
|
|
|
- * Stores options and flag to variables
|
|
|
- *****************************************/
|
|
|
+ /*****************************************
|
|
|
+ * ---------- START --------------------
|
|
|
+ * Stores options and flags to variables
|
|
|
+ *****************************************/
|
|
|
met = metfn->answer;
|
|
|
inputname = input_prefix->answer;
|
|
|
outputname = output_prefix->answer;
|
|
@@ -267,9 +269,10 @@ int main(int argc, char *argv[])
|
|
|
pixel = atoi(dark->answer);
|
|
|
rayleigh = atof(atmo->answer);
|
|
|
|
|
|
- /* Data from metadata file */
|
|
|
- /* Unnecessary because G_zero filled, but for sanity */
|
|
|
- lsat.flag = NOMETADATAFILE;
|
|
|
+ /*
|
|
|
+ * Data from metadata file
|
|
|
+ */
|
|
|
+ lsat.flag = NOMETADATAFILE; /* Unnecessary because G_zero filled, but for sanity */
|
|
|
if (met != NULL) {
|
|
|
lsat.flag = METADATAFILE;
|
|
|
lsat_metadata(met, &lsat);
|
|
@@ -316,28 +319,29 @@ int main(int argc, char *argv[])
|
|
|
if (!lsat.sensor || lsat.number > 8 || lsat.number < 1)
|
|
|
G_fatal_error(_("Failed to identify satellite"));
|
|
|
|
|
|
- G_debug(1, "Landsat-%d %s with data set in met file [%s]",
|
|
|
+ G_debug(1, "Landsat-%d %s with data set in metadata file [%s]",
|
|
|
lsat.number, lsat.sensor, met);
|
|
|
|
|
|
- /* Overwrite solar elevation of metadata file */
|
|
|
- if (elev->answer != NULL)
|
|
|
+ if (elev->answer != NULL) {
|
|
|
lsat.sun_elev = atof(elev->answer);
|
|
|
+ G_warning("Overwriting solar elevation of metadata file");
|
|
|
+ }
|
|
|
}
|
|
|
- /* Data from date and solar elevation */
|
|
|
+ /*
|
|
|
+ * Data from command line
|
|
|
+ */
|
|
|
else if (adate->answer == NULL || elev->answer == NULL) {
|
|
|
- G_fatal_error(_("Missing '%s' and/or '%s' for this satellite"),
|
|
|
+ G_fatal_error(_("Lacking '%s' and/or '%s' for this satellite"),
|
|
|
adate->key, elev->key);
|
|
|
}
|
|
|
else {
|
|
|
- /* Need gain */
|
|
|
if (strcmp(sensorname, "tm7") == 0) {
|
|
|
if (bgain->answer == NULL || strlen(bgain->answer) != 9)
|
|
|
- G_fatal_error(_("Landsat-7 requires band gain with 9 (H/L) data"));
|
|
|
+ G_fatal_error(_("Landsat-7 requires band gain with 9 (H/L) characters"));
|
|
|
set_ETM(&lsat, bgain->answer);
|
|
|
}
|
|
|
- /* Not need gain */
|
|
|
- else if (strcmp(sensorname, "ot8") == 0)
|
|
|
- set_LDCM(&lsat);
|
|
|
+ else if (strcmp(sensorname, "oli8") == 0)
|
|
|
+ set_OLI(&lsat);
|
|
|
else if (strcmp(sensorname, "tm5") == 0)
|
|
|
set_TM5(&lsat);
|
|
|
else if (strcmp(sensorname, "tm4") == 0)
|
|
@@ -354,13 +358,13 @@ int main(int argc, char *argv[])
|
|
|
set_MSS1(&lsat);
|
|
|
else
|
|
|
G_fatal_error(_("Unknown satellite type (defined by '%s')"),
|
|
|
- sensor->key);
|
|
|
+ sensorname);
|
|
|
}
|
|
|
|
|
|
- /*****************************************
|
|
|
- * ------------ PREPARATION --------------
|
|
|
- *****************************************/
|
|
|
- if (strcasecmp(metho->answer, "corrected") == 0)
|
|
|
+ /*****************************************
|
|
|
+ * ------------ PREPARATION --------------
|
|
|
+ *****************************************/
|
|
|
+ if (strcasecmp(metho->answer, "corrected") == 0) /* deleted 2013 */
|
|
|
method = CORRECTED;
|
|
|
else if (strcasecmp(metho->answer, "dos1") == 0)
|
|
|
method = DOS1;
|
|
@@ -376,21 +380,21 @@ int main(int argc, char *argv[])
|
|
|
method = UNCORRECTED;
|
|
|
|
|
|
/*
|
|
|
- if (metho->answer[3] == 'r') method = CORRECTED;
|
|
|
- else if (metho->answer[3] == '1') method = DOS1;
|
|
|
- else if (metho->answer[3] == '2') method = (metho->answer[4] == '\0') ? DOS2 : DOS2b;
|
|
|
- else if (metho->answer[3] == '3') method = DOS3;
|
|
|
- else if (metho->answer[3] == '4') method = DOS4;
|
|
|
+ if (metho->answer[3] == '2') method = (metho->answer[4] == '\0') ? DOS2 : DOS2b;
|
|
|
+ else if (metho->answer[3] == '1') method = DOS1;
|
|
|
+ else if (metho->answer[3] == '3') method = DOS3;
|
|
|
+ else if (metho->answer[3] == '4') method = DOS4;
|
|
|
else method = UNCORRECTED;
|
|
|
*/
|
|
|
|
|
|
for (i = 0; i < lsat.bands; i++) {
|
|
|
dn_mode[i] = 0;
|
|
|
dn_dark[i] = (int)lsat.band[i].qcalmin;
|
|
|
- /* Calculate dark pixel */
|
|
|
+ dn_sat = (int)(0.90 * lsat.band[i].qcalmax);
|
|
|
+ /* Begin: calculate dark pixel */
|
|
|
if (method > DOS && !lsat.band[i].thermal) {
|
|
|
- for (j = 0; j < 256; j++)
|
|
|
- hist[j] = 0L;
|
|
|
+ for (q = 0; q <= lsat.band[i].qcalmax; q++)
|
|
|
+ hist[q] = 0L;
|
|
|
|
|
|
sprintf(band_in, "%s%d", inputname, lsat.band[i].code);
|
|
|
if ((infd = Rast_open_old(band_in, "")) < 0)
|
|
@@ -399,6 +403,8 @@ int main(int argc, char *argv[])
|
|
|
G_set_window(&cellhd);
|
|
|
|
|
|
in_data_type = Rast_get_map_type(infd);
|
|
|
+ if (in_data_type < 0)
|
|
|
+ G_fatal_error(_("Unable to read data type of raster map <%s>"), band_in);
|
|
|
inrast = Rast_allocate_buf(in_data_type);
|
|
|
|
|
|
nrows = Rast_window_rows();
|
|
@@ -421,56 +427,62 @@ int main(int argc, char *argv[])
|
|
|
ptr = (void *)((DCELL *) inrast + col);
|
|
|
q = (int)*((DCELL *) ptr);
|
|
|
break;
|
|
|
+ default:
|
|
|
+ ptr = NULL;
|
|
|
+ q = -1.;
|
|
|
+ break;
|
|
|
}
|
|
|
if (!Rast_is_null_value(ptr, in_data_type) &&
|
|
|
- q >= lsat.band[i].qcalmin && q < 256)
|
|
|
+ q >= lsat.band[i].qcalmin &&
|
|
|
+ q <= lsat.band[i].qcalmax)
|
|
|
hist[q]++;
|
|
|
}
|
|
|
}
|
|
|
/* DN of dark object */
|
|
|
- for (j = lsat.band[i].qcalmin; j < 256; j++) {
|
|
|
+ for (j = lsat.band[i].qcalmin; j <= lsat.band[i].qcalmax; j++) {
|
|
|
if (hist[j] >= (unsigned int)pixel) {
|
|
|
dn_dark[i] = j;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- /* Mode of DN */
|
|
|
+ /* Mode of DN (exclude potentially saturated) */
|
|
|
h_max = 0L;
|
|
|
- for (j = lsat.band[i].qcalmin; j < 241; j++) { /* Exclude potentially saturated < 240 */
|
|
|
+ for (j = lsat.band[i].qcalmin; j < dn_sat; j++) {
|
|
|
/* G_debug(5, "%d-%ld", j, hist[j]); */
|
|
|
if (hist[j] > h_max) {
|
|
|
h_max = hist[j];
|
|
|
dn_mode[i] = j;
|
|
|
}
|
|
|
}
|
|
|
- G_verbose_message("... DN = %.2d [%lu] : mode %.2d [%lu] %s",
|
|
|
- dn_dark[i], hist[dn_dark[i]],
|
|
|
- dn_mode[i], hist[dn_mode[i]],
|
|
|
- hist[255] >
|
|
|
- hist[dn_mode[i]] ? ", excluding DN > 241" : "");
|
|
|
+ G_verbose_message
|
|
|
+ ("... DN = %.2d [%lu] : mode %.2d [%lu], excluding DN > %d",
|
|
|
+ dn_dark[i], hist[dn_dark[i]], dn_mode[i], hist[dn_mode[i]],
|
|
|
+ dn_sat);
|
|
|
|
|
|
G_free(inrast);
|
|
|
Rast_close(infd);
|
|
|
}
|
|
|
+ /* End: calculate dark pixel */
|
|
|
+
|
|
|
/* Calculate transformation constants */
|
|
|
lsat_bandctes(&lsat, i, method, percent, dn_dark[i], rayleigh);
|
|
|
}
|
|
|
|
|
|
- /* unnecessary or necessary with more checking as acquisition date,...
|
|
|
- if (strlen(lsat.creation) == 0)
|
|
|
- G_fatal_error(_("Unknown production date (defined by '%s')"), pdate->key);
|
|
|
+ /*
|
|
|
+ * unnecessary or necessary with more checking as acquisition date,...
|
|
|
+ * if (strlen(lsat.creation) == 0)
|
|
|
+ * G_fatal_error(_("Unknown production date (defined by '%s')"), pdate->key);
|
|
|
*/
|
|
|
|
|
|
if (G_verbose() > G_verbose_std()) {
|
|
|
- fprintf(stderr, " LANDSAT: %d SENSOR: %s\n", lsat.number,
|
|
|
+ fprintf(stderr, "\n LANDSAT: %d SENSOR: %s\n", lsat.number,
|
|
|
lsat.sensor);
|
|
|
fprintf(stderr, " ACQUISITION DATE %s [production date %s]\n",
|
|
|
lsat.date, lsat.creation);
|
|
|
fprintf(stderr, " Earth-sun distance = %.8lf\n", lsat.dist_es);
|
|
|
fprintf(stderr, " Solar elevation angle = %.8lf\n", lsat.sun_elev);
|
|
|
- fprintf(stderr, " Atmospheric correction = %s\n",
|
|
|
- (method == CORRECTED ? "CORRECTED"
|
|
|
- : (method == UNCORRECTED ? "UNCORRECTED" : metho->answer)));
|
|
|
+ fprintf(stderr, " Atmospheric correction: %s\n",
|
|
|
+ (method == UNCORRECTED ? "UNCORRECTED" : metho->answer));
|
|
|
if (method > DOS) {
|
|
|
fprintf(stderr,
|
|
|
" Percent of solar irradiance in path radiance = %.4lf\n",
|
|
@@ -478,16 +490,15 @@ int main(int argc, char *argv[])
|
|
|
}
|
|
|
for (i = 0; i < lsat.bands; i++) {
|
|
|
fprintf(stderr, "-------------------\n");
|
|
|
- fprintf(stderr, " BAND %d %s (code %d)\n",
|
|
|
- lsat.band[i].number,
|
|
|
+ fprintf(stderr, " BAND %d %s(code %d)\n", lsat.band[i].number,
|
|
|
(lsat.band[i].thermal ? "thermal " : ""),
|
|
|
lsat.band[i].code);
|
|
|
fprintf(stderr,
|
|
|
" calibrated digital number (DN): %.1lf to %.1lf\n",
|
|
|
lsat.band[i].qcalmin, lsat.band[i].qcalmax);
|
|
|
- fprintf(stderr, " calibration constants (L): %.3lf to %.3lf\n",
|
|
|
+ fprintf(stderr, " calibration constants (L): %.5lf to %.5lf\n",
|
|
|
lsat.band[i].lmin, lsat.band[i].lmax);
|
|
|
- fprintf(stderr, " at-%s radiance = %.8lf * DN + %.3lf\n",
|
|
|
+ fprintf(stderr, " at-%s radiance = %.8lf * DN + %.5lf\n",
|
|
|
(method > DOS ? "surface" : "sensor"), lsat.band[i].gain,
|
|
|
lsat.band[i].bias);
|
|
|
if (lsat.band[i].thermal) {
|
|
@@ -497,7 +508,7 @@ int main(int argc, char *argv[])
|
|
|
}
|
|
|
else {
|
|
|
fprintf(stderr,
|
|
|
- " mean solar exoatmospheric irradiance (ESUN): %.3lf\n",
|
|
|
+ " mean solar exoatmospheric irradiance (ESUN): %.5lf\n",
|
|
|
lsat.band[i].esun);
|
|
|
fprintf(stderr, " at-%s reflectance = radiance / %.5lf\n",
|
|
|
(method > DOS ? "surface" : "sensor"),
|
|
@@ -515,8 +526,8 @@ int main(int argc, char *argv[])
|
|
|
}
|
|
|
|
|
|
/*****************************************
|
|
|
- * ------------ CALCULUS -----------------
|
|
|
- *****************************************/
|
|
|
+ * ------------ CALCULUS -----------------
|
|
|
+ *****************************************/
|
|
|
|
|
|
G_message(_("Calculating..."));
|
|
|
for (i = 0; i < lsat.bands; i++) {
|
|
@@ -539,6 +550,8 @@ int main(int argc, char *argv[])
|
|
|
}
|
|
|
|
|
|
in_data_type = Rast_get_map_type(infd);
|
|
|
+ if (in_data_type < 0)
|
|
|
+ G_fatal_error(_("Unable to read data type of raster map <%s>"), band_in);
|
|
|
Rast_get_cellhd(band_in, "", &cellhd);
|
|
|
|
|
|
/* set same size as original band raster */
|
|
@@ -551,17 +564,19 @@ int main(int argc, char *argv[])
|
|
|
if ((outfd = Rast_open_new(band_out, DCELL_TYPE)) < 0)
|
|
|
G_fatal_error(_("Unable to create raster map <%s>"), band_out);
|
|
|
|
|
|
- /* Allocate input and output buffer */
|
|
|
+ /* allocate input and output buffer */
|
|
|
inrast = Rast_allocate_buf(in_data_type);
|
|
|
outrast = Rast_allocate_buf(DCELL_TYPE);
|
|
|
|
|
|
nrows = Rast_window_rows();
|
|
|
ncols = Rast_window_cols();
|
|
|
- /* ================================================================= */
|
|
|
+
|
|
|
G_important_message(_("Writing %s of <%s> to <%s>..."),
|
|
|
- (frad->answer ? _("radiance")
|
|
|
- : (lsat.band[i].thermal) ? _("temperature")
|
|
|
- : _("reflectance")), band_in, band_out);
|
|
|
+ (frad->
|
|
|
+ answer ? _("radiance") : (lsat.band[i].
|
|
|
+ thermal) ?
|
|
|
+ _("temperature") : _("reflectance")), band_in,
|
|
|
+ band_out);
|
|
|
for (row = 0; row < nrows; row++) {
|
|
|
G_percent(row, nrows, 2);
|
|
|
|
|
@@ -580,6 +595,10 @@ int main(int argc, char *argv[])
|
|
|
ptr = (void *)((DCELL *) inrast + col);
|
|
|
qcal = (double)((DCELL *) inrast)[col];
|
|
|
break;
|
|
|
+ default:
|
|
|
+ ptr = NULL;
|
|
|
+ qcal = -1.;
|
|
|
+ break;
|
|
|
}
|
|
|
if (Rast_is_null_value(ptr, in_data_type) ||
|
|
|
qcal < lsat.band[i].qcalmin) {
|
|
@@ -613,17 +632,20 @@ int main(int argc, char *argv[])
|
|
|
ref_mode = lsat_rad2ref(ref_mode, &lsat.band[i]);
|
|
|
}
|
|
|
|
|
|
- /* ================================================================= */
|
|
|
|
|
|
G_free(inrast);
|
|
|
- Rast_close(infd);
|
|
|
G_free(outrast);
|
|
|
+ Rast_close(infd);
|
|
|
Rast_close(outfd);
|
|
|
|
|
|
- /* needed ?
|
|
|
- if (out_type != CELL_TYPE)
|
|
|
- G_quantize_fp_map_range(band_out, G_mapset(), 0., 360., 0, 360);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * needed?
|
|
|
+ * if (out_type != CELL_TYPE)
|
|
|
+ * G_quantize_fp_map_range(band_out, G_mapset(), 0., 360., 0,
|
|
|
+ * 360);
|
|
|
*/
|
|
|
+
|
|
|
/* set grey255 colortable */
|
|
|
Rast_init_colors(&colors);
|
|
|
Rast_read_fp_range(band_out, G_mapset(), &range);
|
|
@@ -631,32 +653,36 @@ int main(int argc, char *argv[])
|
|
|
Rast_make_grey_scale_fp_colors(&colors, min, max);
|
|
|
Rast_write_colors(band_out, G_mapset(), &colors);
|
|
|
|
|
|
- /* Initialize the 'hist' structure with basic info */
|
|
|
+ /* Initialize the 'history' structure with basic info */
|
|
|
Rast_short_history(band_out, "raster", &history);
|
|
|
- /* Append a string to the 'history' structure */
|
|
|
Rast_append_format_history(&history,
|
|
|
" %s of Landsat-%d %s (method %s)",
|
|
|
- (frad->answer ? "Radiance" :
|
|
|
- (lsat.band[i].thermal ? "Temperature" :
|
|
|
- "Reflectance")),
|
|
|
+ (frad->
|
|
|
+ answer ? "Radiance" : (lsat.band[i].
|
|
|
+ thermal ?
|
|
|
+ "Temperature" :
|
|
|
+ "Reflectance")),
|
|
|
lsat.number, lsat.sensor, metho->answer);
|
|
|
Rast_append_history(&history,
|
|
|
- "----------------------------------------------------------------");
|
|
|
+ "-----------------------------------------------------------------");
|
|
|
Rast_append_format_history(&history,
|
|
|
- " Acquisition date ...................... %s",
|
|
|
- lsat.date);
|
|
|
+ " Acquisition date (and time) ........... %s (%.4lf h)",
|
|
|
+ lsat.date, lsat.time);
|
|
|
Rast_append_format_history(&history,
|
|
|
" Production date ....................... %s\n",
|
|
|
lsat.creation);
|
|
|
Rast_append_format_history(&history,
|
|
|
- " Earth-sun distance (d) ................ %.8lf",
|
|
|
+ " Earth-sun distance (d) ................ %.7lf",
|
|
|
lsat.dist_es);
|
|
|
Rast_append_format_history(&history,
|
|
|
+ " Sun elevation (and azimuth) ........... %.5lf (%.5lf)",
|
|
|
+ lsat.sun_elev, lsat.sun_az);
|
|
|
+ Rast_append_format_history(&history,
|
|
|
" Digital number (DN) range ............. %.0lf to %.0lf",
|
|
|
lsat.band[i].qcalmin,
|
|
|
lsat.band[i].qcalmax);
|
|
|
Rast_append_format_history(&history,
|
|
|
- " Calibration constants (Lmin to Lmax) .. %+.3lf to %+.3lf",
|
|
|
+ " Calibration constants (Lmin to Lmax) .. %+.5lf to %+.5lf",
|
|
|
lsat.band[i].lmin, lsat.band[i].lmax);
|
|
|
Rast_append_format_history(&history,
|
|
|
" DN to Radiance (gain and bias) ........ %+.5lf and %+.5lf",
|
|
@@ -671,10 +697,10 @@ int main(int argc, char *argv[])
|
|
|
" Mean solar irradiance (ESUN) .......... %.3lf",
|
|
|
lsat.band[i].esun);
|
|
|
Rast_append_format_history(&history,
|
|
|
- " Reflectance = Radiance divided by ..... %.5lf",
|
|
|
+ " Radiance to Reflectance (divide by) ... %+.5lf",
|
|
|
lsat.band[i].K1);
|
|
|
if (method > DOS) {
|
|
|
- Rast_append_history(&history, " ");
|
|
|
+ Rast_append_format_history(&history, " ");
|
|
|
Rast_append_format_history(&history,
|
|
|
" Dark object (%4d pixels) DN = ........ %d",
|
|
|
pixel, dn_dark[i]);
|
|
@@ -684,7 +710,7 @@ int main(int argc, char *argv[])
|
|
|
}
|
|
|
}
|
|
|
Rast_append_history(&history,
|
|
|
- "-----------------------------------------------------------------");
|
|
|
+ "------------------------------------------------------------------");
|
|
|
|
|
|
Rast_command_history(&history);
|
|
|
Rast_write_history(band_out, &history);
|
|
@@ -692,7 +718,7 @@ int main(int argc, char *argv[])
|
|
|
if (lsat.band[i].thermal)
|
|
|
Rast_write_units(band_out, "Kelvin");
|
|
|
else if (frad->answer)
|
|
|
- Rast_write_units(band_out, "W/(m^2 sr µm)");
|
|
|
+ Rast_write_units(band_out, "W/(m^2 sr um)");
|
|
|
else
|
|
|
Rast_write_units(band_out, "unitless");
|
|
|
}
|