Transform.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #include <math.h>
  2. #include "Transform.h"
  3. void EtmDN(int iwave, float asol, bool before, float &lmin, float &lmax)
  4. {
  5. if (before) /* ETM+ digital numbers taken before July 1, 2000 */
  6. {
  7. switch(iwave)
  8. {
  9. case 61:
  10. {
  11. lmin = -6.2f;
  12. lmax = 194.3f;
  13. break;
  14. }
  15. case 62:
  16. {
  17. lmin = -6.0f;
  18. lmax = 202.4f;
  19. break;
  20. }
  21. case 63:
  22. {
  23. lmin = -4.5f;
  24. lmax = 158.6f;
  25. break;
  26. }
  27. case 64:
  28. {
  29. if (asol < 45.)
  30. {
  31. lmin = -4.5f;
  32. lmax = 235.0f;
  33. }
  34. else
  35. {
  36. lmin = -4.5f;
  37. lmax = 157.5f;
  38. }
  39. break;
  40. }
  41. case 65:
  42. {
  43. lmin = -1.0f;
  44. lmax = 31.76f;
  45. break;
  46. }
  47. case 66:
  48. {
  49. lmin = -0.35f;
  50. lmax = 10.932f;
  51. break;
  52. }
  53. case 67:
  54. {
  55. lmin = -5.0f;
  56. lmax = 244.00f;
  57. break;
  58. }
  59. }
  60. }
  61. else /* ETM+ digital numbers taken after July 1, 2000 */
  62. {
  63. switch(iwave)
  64. {
  65. case 61:
  66. {
  67. lmin = -6.2f;
  68. lmax = 191.6f;
  69. break;
  70. }
  71. case 62:
  72. {
  73. lmin = -6.4f;
  74. lmax = 196.5f;
  75. break;
  76. }
  77. case 63:
  78. {
  79. lmin = -5.0f;
  80. lmax = 152.9f;
  81. break;
  82. }
  83. case 64:
  84. {
  85. if (asol < 45.)
  86. {
  87. lmin = -5.1f;
  88. lmax = 241.1f;
  89. }
  90. else
  91. {
  92. lmin = -5.1f;
  93. lmax = 157.4f;
  94. }
  95. break;
  96. }
  97. case 65:
  98. {
  99. lmin = -1.0f;
  100. lmax = 31.06f;
  101. break;
  102. }
  103. case 66:
  104. {
  105. lmin = -0.35f;
  106. lmax = 10.80f;
  107. break;
  108. }
  109. case 67:
  110. {
  111. lmin = -4.7f;
  112. lmax = 243.1f;
  113. break;
  114. }
  115. }
  116. }
  117. }
  118. /* Assuming input value between 0 and 1
  119. if rad is true, idn should first be converted to a reflectance value
  120. returns adjusted value also between 0 and 1 */
  121. float transform(const TransformInput ti, InputMask imask, float idn)
  122. {
  123. /* convert from radiance to reflectance */
  124. if((imask & ETM_BEFORE) || (imask & ETM_AFTER))
  125. {
  126. /* http://ltpwww.gsfc.nas */
  127. float lmin, lmax;
  128. EtmDN(ti.iwave, ti.asol, imask & ETM_BEFORE, lmin, lmax);
  129. /* multiply idn by 255.f to correct precondition that idn lies in [0, 255] */
  130. idn = (lmax - lmin) / 254.f * (idn * 255.f - 1.f) + lmin;
  131. if (idn < 0.f) idn = 0.f;
  132. idn /= 255.f;
  133. }
  134. if(imask & RADIANCE) idn += (float)M_PI * idn * 255.f * ti.sb / ti.xmus / ti.seb;
  135. float rapp = idn;
  136. float ainrpix = ti.ainr[0][0];
  137. float xa = 0.0f;
  138. float xb = 0.0f;
  139. float xc = 0.0f;
  140. float rog = rapp / ti.tgasm;
  141. /* The if below was added to avoid ground reflectances lower than
  142. zero when ainr(1,1) greater than rapp/tgasm
  143. In such case either the choice of atmospheric model was not
  144. adequate for that image or the calculated apparent reflectance
  145. was too low. Run the model again for other conditions.
  146. The lines below just decrease ainr(1,1)/tgasm to avoid too
  147. bright pixels in the image. Check the output file to see if that
  148. has happened. */
  149. float decrfact = 1.0f;
  150. if (rog < (ainrpix / ti.tgasm))
  151. {
  152. do
  153. {
  154. decrfact = decrfact - 0.1f;
  155. ainrpix = decrfact * ainrpix;
  156. }
  157. while(rog < (ainrpix / ti.tgasm));
  158. }
  159. rog = (rog - ainrpix / ti.tgasm) / ti.sutott / ti.sdtott;
  160. rog = rog / (1.f + rog * ti.sast);
  161. xa = (float)M_PI * ti.sb / ti.xmus / ti.seb / ti.tgasm / ti.sutott / ti.sdtott;
  162. xb = ti.srotot / ti.sutott / ti.sdtott / ti.tgasm;
  163. xc = ti.sast;
  164. if (rog > 1) rog = 1;
  165. if (rog < 0) rog = 0;
  166. return rog;
  167. }