main.c 9.4 KB

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