2
/****************************************************************************
5
* AUTHOR(S): Yann Chemin - yann.chemin@gmail.com
6
* PURPOSE: Calculate TOA Reflectance for Aster from DN.
7
* Input 9 bands (VNIR and SWIR).
9
* COPYRIGHT: (C) 2002-2010 by the GRASS Development Team
11
* This program is free software under the GNU Lesser General Public
12
* License. Read the file COPYING that comes with GRASS for details.
14
*****************************************************************************/
19
#include <grass/gis.h>
20
#include <grass/raster.h>
21
#include <grass/glocale.h>
25
/* DN to radiance conversion factors */
26
double gain_aster(int band_number, int gain_code);
29
/*0 - High (Not Applicable for band 10-14: TIR) */
31
/*2 - Low 1(Not Applicable for band 10-14: TIR) */
32
/*3 - Low 2(Not Applicable for Band 1-3N/B & 10-14) */
34
/*sun exo-atmospheric irradiance */
47
double rad2ref_aster(double radiance, double doy, double sun_elevation,
50
int main(int argc, char *argv[])
52
struct Cell_head cellhd; /*region+header info */
53
char *mapset; /*mapset name */
56
struct GModule *module;
57
struct Option *input, *output;
58
struct Option *input1, *input2;
59
struct Flag *flag0, *flag1, *flag2;
60
struct Flag *flag3, *flag4, *flag5;
61
struct History history; /*metadata */
63
/************************************/
64
char *name; /*input raster name */
65
char *result; /*output raster name */
67
/*Prepare new names for output files */
68
char result0[GNAME_MAX], result1[GNAME_MAX];
69
char result2[GNAME_MAX], result3[GNAME_MAX];
70
char result4[GNAME_MAX], result5[GNAME_MAX];
71
char result6[GNAME_MAX], result7[GNAME_MAX];
72
char result8[GNAME_MAX], result9[GNAME_MAX];
73
char result10[GNAME_MAX], result11[GNAME_MAX];
74
char result12[GNAME_MAX], result13[GNAME_MAX];
75
char result14[GNAME_MAX];
81
/* For some strange reason infd[0] cannot be used later */
82
/* So nfiles is initialized with nfiles = 1 */
86
void *inrast[MAXFILES];
87
DCELL *outrast[MAXFILES];
88
RASTER_MAP_TYPE in_data_type[MAXFILES];
89
RASTER_MAP_TYPE out_data_type = DCELL_TYPE; /* 0=numbers 1=text */
90
double gain[MAXFILES], offset[MAXFILES];
91
double kexo[MAXFILES];
92
double doy, sun_elevation;
94
/************************************/
96
module = G_define_module();
97
G_add_keyword(_("imagery"));
98
G_add_keyword(_("radiometric conversion"));
99
G_add_keyword(_("Terra-ASTER"));
100
G_add_keyword(_("radiance"));
101
G_add_keyword(_("reflectance"));
102
G_add_keyword(_("brightness temperature"));
103
module->description =
104
_("Calculates Top of Atmosphere Radiance/Reflectance/Brightness Temperature from ASTER DN.\n");
106
/* Define the different options */
107
input = G_define_standard_option(G_OPT_R_INPUTS);
108
input->description = _("Names of ASTER DN layers (15 layers)");
110
input1 = G_define_option();
111
input1->key = "dayofyear";
112
input1->type = TYPE_DOUBLE;
113
input1->required = YES;
114
input1->gisprompt = "value";
115
input1->description = _("Day of Year of satellite overpass [0-366]");
117
input2 = G_define_option();
118
input2->key = "sun_elevation";
119
input2->type = TYPE_DOUBLE;
120
input2->required = YES;
121
input2->gisprompt = "value";
122
input2->description = _("Sun elevation angle (degrees, < 90.0)");
124
output = G_define_standard_option(G_OPT_R_OUTPUT);
125
output->description = _("Base name of the output layers (will add .x)");
127
/* Define the different flags */
128
flag0 = G_define_flag();
130
flag0->description = _("Output is radiance (W/m2)");
132
flag1 = G_define_flag();
134
flag1->description = _("VNIR is High Gain");
136
flag2 = G_define_flag();
138
flag2->description = _("SWIR is High Gain");
140
flag3 = G_define_flag();
142
flag3->description = _("VNIR is Low Gain 1");
144
flag4 = G_define_flag();
146
flag4->description = _("SWIR is Low Gain 1");
148
flag5 = G_define_flag();
150
flag5->description = _("SWIR is Low Gain 2");
152
/********************/
153
if (G_parser(argc, argv))
156
names = input->answers;
157
ptr = input->answers;
158
doy = atof(input1->answer);
159
sun_elevation = atof(input2->answer);
160
result = output->answer;
162
radiance = (flag0->answer);
164
/********************/
165
/*Prepare the output file names */
167
/********************/
168
sprintf(result0,"%s%s", result, ".1");
169
sprintf(result1,"%s%s", result, ".2");
170
sprintf(result2,"%s%s", result, ".3N");
171
sprintf(result3,"%s%s", result, ".3B");
172
sprintf(result4,"%s%s", result, ".4");
173
sprintf(result5,"%s%s", result, ".5");
174
sprintf(result6,"%s%s", result, ".6");
175
sprintf(result7,"%s%s", result, ".7");
176
sprintf(result8,"%s%s", result, ".8");
177
sprintf(result9,"%s%s", result, ".9");
178
sprintf(result10,"%s%s", result, ".10");
179
sprintf(result11,"%s%s", result, ".11");
180
sprintf(result12,"%s%s", result, ".12");
181
sprintf(result13,"%s%s", result, ".13");
182
sprintf(result14,"%s%s", result, ".14");
183
/********************/
184
/*Prepare radiance boundaries */
186
/********************/
189
for (i = 0; i < MAXFILES; i++) {
190
/*0 - High (Not Applicable for band 10-14: TIR) */
192
/*2 - Low 1(Not Applicable for band 10-14: TIR) */
193
/*3 - Low 2(Not Applicable for Band 1-3N/B & 10-14) */
194
if (flag1->answer && i <= 3)
196
if (flag2->answer && i >= 4 && i <= 9)
198
if (flag3->answer && i <= 3)
200
if (flag4->answer && i >= 4 && i <= 9)
202
if (flag5->answer && i >= 4 && i <= 9)
204
gain[i] = gain_aster(i, gain_code);
205
/* Reset to NORMAL GAIN */
209
/********************/
210
/*Prepare sun exo-atm irradiance */
212
/********************/
224
/********************/
226
/********************/
227
for (; *ptr != NULL; ptr++) {
228
if (nfiles > MAXFILES)
229
G_fatal_error(_("Too many input maps. Only %d allowed."),
232
/* Allocate input buffer */
233
in_data_type[nfiles-1] = Rast_map_type(name, "");
234
/* For some strange reason infd[0] cannot be used later */
235
/* So nfiles is initialized with nfiles = 1 */
236
infd[nfiles] = Rast_open_old(name, "");
238
Rast_get_cellhd(name, "", &cellhd);
239
inrast[nfiles-1] = Rast_allocate_buf(in_data_type[nfiles-1]);
243
if (nfiles < MAXFILES)
244
G_fatal_error(_("The input band number should be 15"));
246
/***************************************************/
247
/* Allocate output buffer, use input map data_type */
248
nrows = Rast_window_rows();
249
ncols = Rast_window_cols();
250
out_data_type = DCELL_TYPE;
251
for (i = 0; i < MAXFILES; i++)
252
outrast[i] = Rast_allocate_buf(out_data_type);
254
outfd[1] = Rast_open_new(result0, 1);
255
outfd[2] = Rast_open_new(result1, 1);
256
outfd[3] = Rast_open_new(result2, 1);
257
outfd[4] = Rast_open_new(result3, 1);
258
outfd[5] = Rast_open_new(result4, 1);
259
outfd[6] = Rast_open_new(result5, 1);
260
outfd[7] = Rast_open_new(result6, 1);
261
outfd[8] = Rast_open_new(result7, 1);
262
outfd[9] = Rast_open_new(result8, 1);
263
outfd[10] = Rast_open_new(result9, 1);
264
outfd[11] = Rast_open_new(result10, 1);
265
outfd[12] = Rast_open_new(result11, 1);
266
outfd[13] = Rast_open_new(result12, 1);
267
outfd[14] = Rast_open_new(result13, 1);
268
outfd[15] = Rast_open_new(result14, 1);
271
DCELL dout[MAXFILES];
274
for (row = 0; row < nrows; row++) {
275
G_percent(row, nrows, 2);
277
for (i = 1; i <= MAXFILES; i++)
278
Rast_get_row(infd[i], inrast[i-1], row, in_data_type[i-1]);
280
/*process the data */
281
for (col = 0; col < ncols; col++) {
282
for (i = 0; i < MAXFILES; i++) {
283
switch (in_data_type[i]) {
285
d[i] = (double)((CELL *) inrast[i])[col];
288
d[i] = (double)((FCELL *) inrast[i])[col];
291
d[i] = (double)((DCELL *) inrast[i])[col];
294
/* if radiance mode or Thermal band */
295
if (radiance || i >= 10) {
296
dout[i] = gain[i] * (d[i] - 1.0);
298
/* if reflectance default mode and Not Thermal Band */
300
dout[i] = gain[i] * (d[i] - 1.0);
302
rad2ref_aster(dout[i], doy, sun_elevation, kexo[i]);
304
outrast[i][col] = dout[i];
307
for (i = 1; i <= MAXFILES; i++)
308
Rast_put_row(outfd[i], outrast[i-1], out_data_type);
310
for (i = 1; i <= MAXFILES; i++) {
313
G_free(outrast[i-1]);
314
Rast_close(outfd[i]);