123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- /****************************************************************************
- *
- * MODULE: i.aster.toar
- * AUTHOR(S): Yann Chemin - yann.chemin@gmail.com
- * PURPOSE: Calculate TOA Reflectance for Aster from DN.
- * Input 9 bands (VNIR and SWIR).
- *
- * COPYRIGHT: (C) 2002-2010 by the GRASS Development Team
- *
- * This program is free software under the GNU Lesser General Public
- * License. Read the file COPYING that comes with GRASS for details.
- *
- *****************************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <grass/gis.h>
- #include <grass/raster.h>
- #include <grass/glocale.h>
- #define MAXFILES 15
- /* DN to radiance conversion factors */
- double gain_aster(int band_number, int gain_code);
- /*Gain Code */
- /*0 - High (Not Applicable for band 10-14: TIR) */
- /*1 - Normal */
- /*2 - Low 1(Not Applicable for band 10-14: TIR) */
- /*3 - Low 2(Not Applicable for Band 1-3N/B & 10-14) */
- /*sun exo-atmospheric irradiance */
- #define KEXO1 1828.0
- #define KEXO2 1559.0
- #define KEXO3 1045.0
- #define KEXO4 226.73
- #define KEXO5 86.50
- #define KEXO6 81.99
- #define KEXO7 74.72
- #define KEXO8 66.41
- #define KEXO9 59.83
- #define PI 3.1415926
- double rad2ref_aster(double radiance, double doy, double sun_elevation,
- double k_exo);
- int main(int argc, char *argv[])
- {
- struct Cell_head cellhd; /*region+header info */
- char *mapset; /*mapset name */
- int nrows, ncols;
- int row, col;
- struct GModule *module;
- struct Option *input, *output;
- struct Option *input1, *input2;
- struct Flag *flag0, *flag1, *flag2;
- struct Flag *flag3, *flag4, *flag5;
- struct History history; /*metadata */
- /************************************/
- char *name; /*input raster name */
- char *result; /*output raster name */
- /*Prepare new names for output files */
- char result0[GNAME_MAX], result1[GNAME_MAX];
- char result2[GNAME_MAX], result3[GNAME_MAX];
- char result4[GNAME_MAX], result5[GNAME_MAX];
- char result6[GNAME_MAX], result7[GNAME_MAX];
- char result8[GNAME_MAX], result9[GNAME_MAX];
- char result10[GNAME_MAX], result11[GNAME_MAX];
- char result12[GNAME_MAX], result13[GNAME_MAX];
- char result14[GNAME_MAX];
- /*File Descriptors */
- int infd[MAXFILES];
- int outfd[MAXFILES];
- char **names, **ptr;
- /* For some strange reason infd[0] cannot be used later */
- /* So nfiles is initialized with nfiles = 1 */
- int nfiles = 1;
- int i = 0, j = 0;
- int radiance = 0;
- void *inrast[MAXFILES];
- DCELL *outrast[MAXFILES];
- RASTER_MAP_TYPE in_data_type[MAXFILES];
- RASTER_MAP_TYPE out_data_type = DCELL_TYPE; /* 0=numbers 1=text */
- double gain[MAXFILES], offset[MAXFILES];
- double kexo[MAXFILES];
- double doy, sun_elevation;
- /************************************/
- G_gisinit(argv[0]);
- module = G_define_module();
- G_add_keyword(_("imagery"));
- G_add_keyword(_("radiometric conversion"));
- G_add_keyword(_("Terra-ASTER"));
- G_add_keyword(_("radiance"));
- G_add_keyword(_("reflectance"));
- G_add_keyword(_("brightness temperature"));
- module->description =
- _("Calculates Top of Atmosphere Radiance/Reflectance/Brightness Temperature from ASTER DN.\n");
- /* Define the different options */
- input = G_define_standard_option(G_OPT_R_INPUTS);
- input->description = _("Names of ASTER DN layers (15 layers)");
- input1 = G_define_option();
- input1->key = "dayofyear";
- input1->type = TYPE_DOUBLE;
- input1->required = YES;
- input1->gisprompt = "value";
- input1->description = _("Day of Year of satellite overpass [0-366]");
- input2 = G_define_option();
- input2->key = "sun_elevation";
- input2->type = TYPE_DOUBLE;
- input2->required = YES;
- input2->gisprompt = "value";
- input2->description = _("Sun elevation angle (degrees, < 90.0)");
- output = G_define_standard_option(G_OPT_R_OUTPUT);
- output->description = _("Base name of the output layers (will add .x)");
- /* Define the different flags */
- flag0 = G_define_flag();
- flag0->key = 'r';
- flag0->description = _("Output is radiance (W/m2)");
- flag1 = G_define_flag();
- flag1->key = 'a';
- flag1->description = _("VNIR is High Gain");
- flag2 = G_define_flag();
- flag2->key = 'b';
- flag2->description = _("SWIR is High Gain");
- flag3 = G_define_flag();
- flag3->key = 'c';
- flag3->description = _("VNIR is Low Gain 1");
- flag4 = G_define_flag();
- flag4->key = 'd';
- flag4->description = _("SWIR is Low Gain 1");
- flag5 = G_define_flag();
- flag5->key = 'e';
- flag5->description = _("SWIR is Low Gain 2");
- /********************/
- if (G_parser(argc, argv))
- exit(EXIT_FAILURE);
- names = input->answers;
- ptr = input->answers;
- doy = atof(input1->answer);
- sun_elevation = atof(input2->answer);
- result = output->answer;
- radiance = (flag0->answer);
- /********************/
- /*Prepare the output file names */
- /********************/
- sprintf(result0,"%s%s", result, ".1");
- sprintf(result1,"%s%s", result, ".2");
- sprintf(result2,"%s%s", result, ".3N");
- sprintf(result3,"%s%s", result, ".3B");
- sprintf(result4,"%s%s", result, ".4");
- sprintf(result5,"%s%s", result, ".5");
- sprintf(result6,"%s%s", result, ".6");
- sprintf(result7,"%s%s", result, ".7");
- sprintf(result8,"%s%s", result, ".8");
- sprintf(result9,"%s%s", result, ".9");
- sprintf(result10,"%s%s", result, ".10");
- sprintf(result11,"%s%s", result, ".11");
- sprintf(result12,"%s%s", result, ".12");
- sprintf(result13,"%s%s", result, ".13");
- sprintf(result14,"%s%s", result, ".14");
- /********************/
- /*Prepare radiance boundaries */
- /********************/
- int gain_code = 1;
- for (i = 0; i < MAXFILES; i++) {
- /*0 - High (Not Applicable for band 10-14: TIR) */
- /*1 - Normal */
- /*2 - Low 1(Not Applicable for band 10-14: TIR) */
- /*3 - Low 2(Not Applicable for Band 1-3N/B & 10-14) */
- if (flag1->answer && i <= 3)
- gain_code = 0;
- if (flag2->answer && i >= 4 && i <= 9)
- gain_code = 0;
- if (flag3->answer && i <= 3)
- gain_code = 2;
- if (flag4->answer && i >= 4 && i <= 9)
- gain_code = 2;
- if (flag5->answer && i >= 4 && i <= 9)
- gain_code = 3;
- gain[i] = gain_aster(i, gain_code);
- /* Reset to NORMAL GAIN */
- gain_code = 1;
- }
- /********************/
- /*Prepare sun exo-atm irradiance */
- /********************/
- kexo[0] = KEXO1;
- kexo[1] = KEXO2;
- kexo[2] = KEXO3;
- kexo[3] = KEXO3;
- kexo[4] = KEXO4;
- kexo[5] = KEXO5;
- kexo[6] = KEXO6;
- kexo[7] = KEXO7;
- kexo[8] = KEXO8;
- kexo[9] = KEXO9;
- /********************/
- /********************/
- for (; *ptr != NULL; ptr++) {
- if (nfiles > MAXFILES)
- G_fatal_error(_("Too many input maps. Only %d allowed."),
- MAXFILES);
- name = *ptr;
- /* Allocate input buffer */
- in_data_type[nfiles-1] = Rast_map_type(name, "");
- /* For some strange reason infd[0] cannot be used later */
- /* So nfiles is initialized with nfiles = 1 */
- infd[nfiles] = Rast_open_old(name, "");
- Rast_get_cellhd(name, "", &cellhd);
- inrast[nfiles-1] = Rast_allocate_buf(in_data_type[nfiles-1]);
- nfiles++;
- }
- nfiles--;
- if (nfiles < MAXFILES)
- G_fatal_error(_("The input band number should be 15"));
- /***************************************************/
- /* Allocate output buffer, use input map data_type */
- nrows = Rast_window_rows();
- ncols = Rast_window_cols();
- out_data_type = DCELL_TYPE;
- for (i = 0; i < MAXFILES; i++)
- outrast[i] = Rast_allocate_buf(out_data_type);
- outfd[1] = Rast_open_new(result0, 1);
- outfd[2] = Rast_open_new(result1, 1);
- outfd[3] = Rast_open_new(result2, 1);
- outfd[4] = Rast_open_new(result3, 1);
- outfd[5] = Rast_open_new(result4, 1);
- outfd[6] = Rast_open_new(result5, 1);
- outfd[7] = Rast_open_new(result6, 1);
- outfd[8] = Rast_open_new(result7, 1);
- outfd[9] = Rast_open_new(result8, 1);
- outfd[10] = Rast_open_new(result9, 1);
- outfd[11] = Rast_open_new(result10, 1);
- outfd[12] = Rast_open_new(result11, 1);
- outfd[13] = Rast_open_new(result12, 1);
- outfd[14] = Rast_open_new(result13, 1);
- outfd[15] = Rast_open_new(result14, 1);
- /* Process pixels */
- DCELL dout[MAXFILES];
- DCELL d[MAXFILES];
- for (row = 0; row < nrows; row++) {
- G_percent(row, nrows, 2);
- /* read input map */
- for (i = 1; i <= MAXFILES; i++)
- Rast_get_row(infd[i], inrast[i-1], row, in_data_type[i-1]);
- /*process the data */
- for (col = 0; col < ncols; col++) {
- for (i = 0; i < MAXFILES; i++) {
- switch (in_data_type[i]) {
- case CELL_TYPE:
- d[i] = (double)((CELL *) inrast[i])[col];
- break;
- case FCELL_TYPE:
- d[i] = (double)((FCELL *) inrast[i])[col];
- break;
- case DCELL_TYPE:
- d[i] = (double)((DCELL *) inrast[i])[col];
- break;
- }
- /* if radiance mode or Thermal band */
- if (radiance || i >= 10) {
- dout[i] = gain[i] * (d[i] - 1.0);
- }
- /* if reflectance default mode and Not Thermal Band */
- else {
- dout[i] = gain[i] * (d[i] - 1.0);
- dout[i] =
- rad2ref_aster(dout[i], doy, sun_elevation, kexo[i]);
- }
- outrast[i][col] = dout[i];
- }
- }
- for (i = 1; i <= MAXFILES; i++)
- Rast_put_row(outfd[i], outrast[i-1], out_data_type);
- }
- for (i = 1; i <= MAXFILES; i++) {
- G_free(inrast[i-1]);
- Rast_close(infd[i]);
- G_free(outrast[i-1]);
- Rast_close(outfd[i]);
- }
- exit(EXIT_SUCCESS);
- }
|