main.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /****************************************************************************
  2. *
  3. * MODULE: i.aster.toar
  4. * AUTHOR(S): Yann Chemin - yann.chemin@gmail.com
  5. * PURPOSE: Calculate TOA Reflectance for Aster from DN.
  6. * Input 9 bands (VNIR and SWIR).
  7. *
  8. * COPYRIGHT: (C) 2002-2010 by the GRASS Development Team
  9. *
  10. * This program is free software under the GNU Lesser General Public
  11. * License. Read the file COPYING that comes with GRASS for details.
  12. *
  13. *****************************************************************************/
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <grass/gis.h>
  18. #include <grass/raster.h>
  19. #include <grass/glocale.h>
  20. #define MAXFILES 15
  21. /* DN to radiance conversion factors */
  22. double gain_aster(int band_number, int gain_code);
  23. /*Gain Code */
  24. /*0 - High (Not Applicable for band 10-14: TIR) */
  25. /*1 - Normal */
  26. /*2 - Low 1(Not Applicable for band 10-14: TIR) */
  27. /*3 - Low 2(Not Applicable for Band 1-3N/B & 10-14) */
  28. /*sun exo-atmospheric irradiance */
  29. #define KEXO1 1828.0
  30. #define KEXO2 1559.0
  31. #define KEXO3 1045.0
  32. #define KEXO4 226.73
  33. #define KEXO5 86.50
  34. #define KEXO6 81.99
  35. #define KEXO7 74.72
  36. #define KEXO8 66.41
  37. #define KEXO9 59.83
  38. #define PI M_PI
  39. double rad2ref_aster(double radiance, double doy, double sun_elevation,
  40. double k_exo);
  41. int main(int argc, char *argv[])
  42. {
  43. struct Cell_head cellhd; /*region+header info */
  44. int nrows, ncols;
  45. int row, col;
  46. struct GModule *module;
  47. struct Option *input, *output;
  48. struct Option *input1, *input2;
  49. struct Flag *flag0, *flag1, *flag2;
  50. struct Flag *flag3, *flag4, *flag5;
  51. /************************************/
  52. char *name; /*input raster name */
  53. char *result; /*output raster name */
  54. /*Prepare new names for output files */
  55. char result0[GNAME_MAX], result1[GNAME_MAX];
  56. char result2[GNAME_MAX], result3[GNAME_MAX];
  57. char result4[GNAME_MAX], result5[GNAME_MAX];
  58. char result6[GNAME_MAX], result7[GNAME_MAX];
  59. char result8[GNAME_MAX], result9[GNAME_MAX];
  60. char result10[GNAME_MAX], result11[GNAME_MAX];
  61. char result12[GNAME_MAX], result13[GNAME_MAX];
  62. char result14[GNAME_MAX];
  63. /*File Descriptors */
  64. int infd[MAXFILES];
  65. int outfd[MAXFILES];
  66. char **names, **ptr;
  67. /* For some strange reason infd[0] cannot be used later */
  68. /* So nfiles is initialized with nfiles = 1 */
  69. int nfiles = 0;
  70. int i = 0;
  71. int radiance = 0;
  72. void *inrast[MAXFILES];
  73. DCELL *outrast[MAXFILES];
  74. RASTER_MAP_TYPE in_data_type[MAXFILES];
  75. RASTER_MAP_TYPE out_data_type = DCELL_TYPE; /* 0=numbers 1=text */
  76. double gain[MAXFILES]; /* , offset[MAXFILES]; */
  77. double kexo[MAXFILES];
  78. double doy, sun_elevation;
  79. /************************************/
  80. G_gisinit(argv[0]);
  81. module = G_define_module();
  82. G_add_keyword(_("imagery"));
  83. G_add_keyword(_("radiometric conversion"));
  84. G_add_keyword(_("radiance"));
  85. G_add_keyword(_("reflectance"));
  86. G_add_keyword(_("brightness temperature"));
  87. G_add_keyword(_("satellite"));
  88. G_add_keyword(_("ASTER"));
  89. module->description =
  90. _("Calculates Top of Atmosphere Radiance/Reflectance/Brightness Temperature from ASTER DN.");
  91. /* Define the different options */
  92. input = G_define_standard_option(G_OPT_R_INPUTS);
  93. input->description = _("Names of ASTER DN layers (15 layers)");
  94. input1 = G_define_option();
  95. input1->key = "dayofyear";
  96. input1->type = TYPE_DOUBLE;
  97. input1->required = YES;
  98. input1->gisprompt = "value";
  99. input1->description = _("Day of Year of satellite overpass [0-366]");
  100. input2 = G_define_option();
  101. input2->key = "sun_elevation";
  102. input2->type = TYPE_DOUBLE;
  103. input2->required = YES;
  104. input2->gisprompt = "value";
  105. input2->description = _("Sun elevation angle (degrees, < 90.0)");
  106. output = G_define_standard_option(G_OPT_R_OUTPUT);
  107. output->description = _("Base name of the output layers (will add .x)");
  108. /* Define the different flags */
  109. flag0 = G_define_flag();
  110. flag0->key = 'r';
  111. flag0->description = _("Output is radiance (W/m2)");
  112. flag1 = G_define_flag();
  113. flag1->key = 'a';
  114. flag1->description = _("VNIR is High Gain");
  115. flag2 = G_define_flag();
  116. flag2->key = 'b';
  117. flag2->description = _("SWIR is High Gain");
  118. flag3 = G_define_flag();
  119. flag3->key = 'c';
  120. flag3->description = _("VNIR is Low Gain 1");
  121. flag4 = G_define_flag();
  122. flag4->key = 'd';
  123. flag4->description = _("SWIR is Low Gain 1");
  124. flag5 = G_define_flag();
  125. flag5->key = 'e';
  126. flag5->description = _("SWIR is Low Gain 2");
  127. /********************/
  128. if (G_parser(argc, argv))
  129. exit(EXIT_FAILURE);
  130. names = input->answers;
  131. ptr = input->answers;
  132. doy = atof(input1->answer);
  133. sun_elevation = atof(input2->answer);
  134. result = output->answer;
  135. radiance = (flag0->answer);
  136. /********************/
  137. /*Prepare the output file names */
  138. /********************/
  139. sprintf(result0, "%s%s", result, ".1");
  140. sprintf(result1, "%s%s", result, ".2");
  141. sprintf(result2, "%s%s", result, ".3N");
  142. sprintf(result3, "%s%s", result, ".3B");
  143. sprintf(result4, "%s%s", result, ".4");
  144. sprintf(result5, "%s%s", result, ".5");
  145. sprintf(result6, "%s%s", result, ".6");
  146. sprintf(result7, "%s%s", result, ".7");
  147. sprintf(result8, "%s%s", result, ".8");
  148. sprintf(result9, "%s%s", result, ".9");
  149. sprintf(result10, "%s%s", result, ".10");
  150. sprintf(result11, "%s%s", result, ".11");
  151. sprintf(result12, "%s%s", result, ".12");
  152. sprintf(result13, "%s%s", result, ".13");
  153. sprintf(result14, "%s%s", result, ".14");
  154. /********************/
  155. /*Prepare radiance boundaries */
  156. /********************/
  157. int gain_code = 1;
  158. for (i = 0; i < MAXFILES; i++) {
  159. /*0 - High (Not Applicable for band 10-14: TIR) */
  160. /*1 - Normal */
  161. /*2 - Low 1(Not Applicable for band 10-14: TIR) */
  162. /*3 - Low 2(Not Applicable for Band 1-3N/B & 10-14) */
  163. if (flag1->answer && i <= 3)
  164. gain_code = 0;
  165. if (flag2->answer && i >= 4 && i <= 9)
  166. gain_code = 0;
  167. if (flag3->answer && i <= 3)
  168. gain_code = 2;
  169. if (flag4->answer && i >= 4 && i <= 9)
  170. gain_code = 2;
  171. if (flag5->answer && i >= 4 && i <= 9)
  172. gain_code = 3;
  173. gain[i] = gain_aster(i, gain_code);
  174. /* Reset to NORMAL GAIN */
  175. gain_code = 1;
  176. }
  177. /********************/
  178. /*Prepare sun exo-atm irradiance */
  179. /********************/
  180. kexo[0] = KEXO1;
  181. kexo[1] = KEXO2;
  182. kexo[2] = KEXO3;
  183. kexo[3] = KEXO3;
  184. kexo[4] = KEXO4;
  185. kexo[5] = KEXO5;
  186. kexo[6] = KEXO6;
  187. kexo[7] = KEXO7;
  188. kexo[8] = KEXO8;
  189. kexo[9] = KEXO9;
  190. /********************/
  191. /********************/
  192. for (; *ptr != NULL; ptr++) {
  193. if (nfiles == MAXFILES)
  194. G_fatal_error(_("Too many input maps. Only %d allowed."),
  195. MAXFILES);
  196. name = *ptr;
  197. /* Allocate input buffer */
  198. in_data_type[nfiles] = Rast_map_type(name, "");
  199. infd[nfiles] = Rast_open_old(name, "");
  200. Rast_get_cellhd(name, "", &cellhd);
  201. inrast[nfiles] = Rast_allocate_buf(in_data_type[nfiles]);
  202. nfiles++;
  203. }
  204. if (nfiles < MAXFILES)
  205. G_fatal_error(_("The input band number should be %d"), MAXFILES);
  206. /***************************************************/
  207. /* Allocate output buffer, use input map data_type */
  208. nrows = Rast_window_rows();
  209. ncols = Rast_window_cols();
  210. out_data_type = DCELL_TYPE;
  211. for (i = 0; i < MAXFILES; i++)
  212. outrast[i] = Rast_allocate_buf(out_data_type);
  213. outfd[0] = Rast_open_new(result0, 1);
  214. outfd[1] = Rast_open_new(result1, 1);
  215. outfd[2] = Rast_open_new(result2, 1);
  216. outfd[3] = Rast_open_new(result3, 1);
  217. outfd[4] = Rast_open_new(result4, 1);
  218. outfd[5] = Rast_open_new(result5, 1);
  219. outfd[6] = Rast_open_new(result6, 1);
  220. outfd[7] = Rast_open_new(result7, 1);
  221. outfd[8] = Rast_open_new(result8, 1);
  222. outfd[9] = Rast_open_new(result9, 1);
  223. outfd[10] = Rast_open_new(result10, 1);
  224. outfd[11] = Rast_open_new(result11, 1);
  225. outfd[12] = Rast_open_new(result12, 1);
  226. outfd[13] = Rast_open_new(result13, 1);
  227. outfd[14] = Rast_open_new(result14, 1);
  228. /* Process pixels */
  229. DCELL dout[MAXFILES];
  230. DCELL d[MAXFILES];
  231. for (row = 0; row < nrows; row++) {
  232. G_percent(row, nrows, 2);
  233. /* read input map */
  234. for (i = 0; i < MAXFILES; i++)
  235. Rast_get_row(infd[i], inrast[i], row, in_data_type[i]);
  236. /*process the data */
  237. for (col = 0; col < ncols; col++) {
  238. for (i = 0; i < MAXFILES; i++) {
  239. switch (in_data_type[i]) {
  240. case CELL_TYPE:
  241. d[i] = (double)((CELL *) inrast[i])[col];
  242. break;
  243. case FCELL_TYPE:
  244. d[i] = (double)((FCELL *) inrast[i])[col];
  245. break;
  246. case DCELL_TYPE:
  247. d[i] = (double)((DCELL *) inrast[i])[col];
  248. break;
  249. }
  250. /* if radiance mode or Thermal band */
  251. if (radiance || i >= 10) {
  252. dout[i] = gain[i] * (d[i] - 1.0);
  253. }
  254. /* if reflectance default mode and Not Thermal Band */
  255. else {
  256. dout[i] = gain[i] * (d[i] - 1.0);
  257. dout[i] =
  258. rad2ref_aster(dout[i], doy, sun_elevation, kexo[i]);
  259. }
  260. outrast[i][col] = dout[i];
  261. }
  262. }
  263. for (i = 0; i < MAXFILES; i++)
  264. Rast_put_row(outfd[i], outrast[i], out_data_type);
  265. }
  266. for (i = 0; i < MAXFILES; i++) {
  267. G_free(inrast[i]);
  268. Rast_close(infd[i]);
  269. G_free(outrast[i]);
  270. Rast_close(outfd[i]);
  271. }
  272. exit(EXIT_SUCCESS);
  273. }