OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
retrieval_irw.f90
Go to the documentation of this file.
2 
3  use names, only : mymonth
5 #if MODIS_OD || MAS_OD || SEV_PR06OD || VIIRS_OD || AHI_PR06OD
6  use core_arrays
7 #else
9 #endif
12  use rtm_support
15 
16  implicit none
17 
18  private
19 
21 
22  real, parameter :: ma(60) = (/ &
23  2.9769800876, -0.0515871084, 0.0027409105, 0.0001135740, 0.00000113040 , &
24  3.3483238557, 0.1372575458, 0.0133258850, 0.0003043608, 0.00000218650 ,&
25  2.4060295675, 0.0372001609, 0.0096472724, 0.0002334206, 0.00000165450 ,&
26  2.6522386726, 0.0325728824, 0.0100892620, 0.0002601226, 0.00000198560 ,&
27  1.9578262599, -0.2112028966, -0.0057943564, -0.0001050464, -0.00000074313 ,&
28  2.7659753980, -0.1186500984, 0.0011626989, 0.0000936998, 0.00000101060 ,&
29  2.1106811602, -0.3073665907, -0.0090862456, -0.0000889596, 0.00000003552 ,&
30  3.0982173723, -0.1629588435, -0.0020384299, 0.0000286274, 0.00000060283 ,&
31  3.0760551826, -0.2043463270, -0.0053969994, -0.0000541329, -0.00000001768 ,&
32  3.6377215316, -0.0857783614, 0.0024313179, 0.0001495010, 0.00000170850 ,&
33  3.3206165420, -0.1411094234, -0.0026068389, 0.0000057937, 0.00000042113 , &
34  3.0526632533, -0.1121521836, -0.0009912556, 0.0000179690, 0.00000027070 /)
35 
36  real, parameter:: mb(60) = (/&
37  2.9426577089, -0.0510674066, 0.0052420293, 0.0001097927, -0.00000372380 ,&
38  2.6499605646, -0.0105152229, 0.0042895903, 0.0000719741, -0.00000066735 ,&
39  2.3652046763, 0.0141129341, 0.0059242144, -0.0000158816, -0.00000265790 ,&
40  2.5433158163, -0.0046876415, 0.0059325140, 0.0000143938, -0.00000346360 ,&
41  2.4994027830, -0.0364706332, 0.0082001522, 0.0000843577, -0.00000768780 ,&
42  2.7641495752, -0.0728625243, 0.0088877822, 0.0001767765, -0.00001168390 ,&
43  3.1202042743, -0.1002374752, 0.0064054059, 0.0002620230, -0.00001078950 ,&
44  3.4331195144, -0.1021765880, 0.0010498850, 0.0001614861, 0.00000510150 ,&
45  3.4539389485, -0.1158261776, 0.0015449592, 0.0001711651, 0.00000248080 ,&
46  3.6013336912, -0.0775800028, 0.0041940388, 0.0000941307, -0.00000408720 ,&
47  3.1947419143, -0.1045316345, 0.0049986486, 0.0001910731, -0.00000505500 ,&
48  3.1276377012, -0.0707628268, 0.0055532926, 0.0001549833, -0.00000570980 /)
49 
50  real, parameter :: mc(60) = (/ &
51  1.9009562748, 0.0236905223, 0.0086504022, -0.0002167013, 0.00000151230 ,&
52  2.4878735828, -0.0076514110, 0.0079443995, -0.0001773726, 0.00000114730 ,&
53  3.1251275103, -0.1214572133, 0.0146488407, -0.0003187508, 0.00000210290 ,&
54  13.3931706579, -1.2206947755, 0.0560380539, -0.0009873591, 0.00000598210 ,&
55  1.6432070460, 0.1151206937, 0.0033130967, -0.0001458434, 0.00000128610 ,&
56  -5.2366360253, 1.0105574562, -0.0355440449, 0.0005187964, -0.00000262410 ,&
57  -4.7396480830, 0.9625734101, -0.0355846807, 0.0005522497, -0.00000299860 ,&
58  -1.4424842734, 0.4769307320, -0.0139027010, 0.0001758823, -0.00000079846 ,&
59  -3.7140186247, 0.6720953861, -0.0210548327, 0.0002974491, -0.00000149380 ,&
60  8.2237401369, -0.5127532741, 0.0205285436, -0.0003015662, 0.00000157680 ,&
61  -0.4502046794, 0.2629679617, -0.0018419395, -0.0000368887, 0.00000048223 ,&
62  9.3930897423, -0.8836682302, 0.0460453172, -0.0008450362, 0.00000517810 /)
63 
64  real, parameter :: bs(24) = (/ &
65  - 3.8, 22.1 ,&
66  -21.5, 12.8 ,&
67  - 2.8, 10.7 ,&
68  -23.4, 29.4 ,&
69  -12.3, 14.9 ,&
70  - 7.0, 16.8 ,&
71  -10.5, 15.0 ,&
72  - 7.8, 19.5 ,&
73  - 8.6, 17.4 ,&
74  - 7.0, 27.0 ,&
75  - 9.2, 22.0 ,&
76  - 3.7, 19.0 /)
77 
78  real, parameter :: PBOT = 700.
79  real, parameter :: PTOP = 100.
80 
81 
82 
83 
84  real :: month_coeffsa(5, 12), month_coeffsb(5, 12), month_coeffsc(5, 12), breakpts(2, 12)
85 
86 
87 contains
88 
89 subroutine init_irw
90 
91  month_coeffsa = reshape(ma, (/5, 12/))
92  month_coeffsb = reshape(mb, (/5, 12/))
93  month_coeffsc = reshape(mc, (/5, 12/))
94  breakpts = reshape(bs, (/2, 12 /))
95 
96 end subroutine init_irw
97 
98 subroutine retrieve_irw_temp_for_uncert(x, y, I11_meas, idx_i, idx_j, irw_temp_low, irw_temp_high )
99 #ifndef CT_CODE
102 
103 
106 #endif
107 
108  integer, intent(in) :: x, y
109  real, intent(inout) :: irw_temp_low, irw_temp_high
110  integer, intent(in) :: idx_i, idx_j
111  real, intent(in) :: i11_meas
112 
113 #ifndef CT_CODE
114  real :: sfc_tmp
115  integer :: idx_hi, idx_lo, idx_hi_mean, idx_lo_mean
116  logical :: ocean_flag
117 
118  real :: esfc(2), clear_sky_radiance_low(2), clear_sky_bt_low(2), &
119  clear_sky_radiance_high(2), clear_sky_bt_high(2)
120 
121  integer :: trop_lev
122  integer :: sfc_lev
123  real, dimension(model_levels) :: iwin_low, iwin_mean, iwin_high
124  integer :: i, icnt, num_work_lev
125  real :: rad0, meas_temp
126  real, dimension(:), allocatable :: pp, tt, zz, ww
127 
128  real :: cpl, tpl, ppl, cph, tph, pph
129  integer :: m, zph, zpl
130  real :: dplat, c0, c1, c2, c3, c4, lapse_rate, dt, ctz
131  real :: adjustment1, irw_height_mean
132  real :: irw_p_low, irw_p_high
133 
134  integer :: irw_channel
135 
136  call set_irw_channel(irw_channel)
137 
138 ! get the temporally and spatially interpolated surface temperature
139  sfc_tmp = surface_temperature(x,y)
140 
141 ! get the calculated 11um clear sky radiance and brightness temperature
142  call set_esfc(cloudmask(x,y)%water_surface, x, y, esfc, ocean_flag)
143 
144  sfc_lev = c2_model_info%surface_level
145 
146 
147  call get_clear_toa_rad(platform_name, sfc_tmp, esfc, &
148  sfc_lev, clear_sky_radiance_low, clear_sky_bt_low, rtm_rad_atm_clr_low, rtm_trans_atm_clr_low, .false.)
149  call get_clear_toa_rad(platform_name, sfc_tmp, esfc, &
150  sfc_lev, clear_sky_radiance_high, clear_sky_bt_high, rtm_rad_atm_clr_high, rtm_trans_atm_clr_high, .false.)
151 
152 ! print*, sfc_lev, clear_sky_radiance(band_1100), clear_sky_bt(band_1100)
153 
154 ! get the tropopause level
155 
156  trop_lev = c2_model_info%trop_level
157 
158  iwin_high = 0.
159  iwin_low = 0.
160  icnt = 1
161 
162  do i=trop_lev, sfc_lev
163  iwin_low(icnt) = rtm_cloud_prof_low(irw_channel, i)
164  iwin_high(icnt) = rtm_cloud_prof_high(irw_channel, i)
165  icnt = icnt + 1
166  end do
167  num_work_lev = icnt-1
168 
169  rad0 = i11_meas
170 
171 
172 ! get the profile piece that we will do work on
173  allocate( tt(num_work_lev))
174 
175  icnt = 1
176  do i=trop_lev, sfc_lev
177  tt(icnt) = c2_model_info%temp_profile(i)
178  icnt = icnt + 1
179  end do
180 
181 
182 ! if the observed BT is colder than minimum trop temperature, then put cloud at trop
183  if (meas_temp < tt(1)) then
184  irw_temp_low = tt(1)
185  irw_temp_high = tt(1)
186 ! if the observed BT warmer than TSFC, put the cloud at surface
187  else if (meas_temp > sfc_tmp) then
188  irw_temp_low = sfc_tmp
189  irw_temp_high = sfc_tmp
190  else
191 ! interpolate the temperature and pressure. This is a little more advanced than what UWisc is doing. They take closest level.
192  call locate_point_top_down(rad0, iwin_low, num_work_lev, idx_lo, idx_hi)
193  irw_temp_low = linearinterpolation( (/ iwin_low(idx_lo), iwin_low(idx_hi) /), (/ tt(idx_lo), tt(idx_hi) /), rad0)
194 
195  call locate_point_top_down(rad0, iwin_high, num_work_lev, idx_lo, idx_hi)
196  irw_temp_high = linearinterpolation( (/ iwin_high(idx_lo), iwin_high(idx_hi) /), (/ tt(idx_lo), tt(idx_hi) /), rad0)
197 
198  endif
199 
200  deallocate(tt)
201 #endif
202 end subroutine retrieve_irw_temp_for_uncert
203 
204 
205 subroutine retrieve_irw_temp(x, y, I11_meas, idx_i, idx_j, clear_rad_table, clear_trans_table, cloud_prof, irw_temp, irw_pressure, &
206  irw_height)
207  ! WDR modified to replace model_info()%... with c2_model_info%...
208 
211 
212  integer, intent(in) :: x, y
213  real, intent(inout) :: irw_temp, irw_pressure, irw_height
214  integer, intent(in) :: idx_i, idx_j
215  real, intent(in) :: i11_meas, clear_rad_table(:,:), clear_trans_table(:,:), cloud_prof(:,:)
216 
217  real :: sfc_tmp
218  integer :: idx_hi, idx_lo, idx_hi_mean, idx_lo_mean
219  logical :: ocean_flag
220 #ifndef CT_CODE
221  real :: esfc(2), clear_sky_radiance(2), clear_sky_bt(2)
222 #else
223  real :: esfc(set_number_of_bands), &
224  clear_sky_radiance(set_number_of_bands), clear_sky_bt(set_number_of_bands)
225 #endif
226  integer :: trop_lev
227  integer :: sfc_lev
228  real, dimension(model_levels) :: iwin, iwin_mean
229  integer :: i, icnt, num_work_lev
230  real :: rad0, meas_temp
231  real, dimension(:), allocatable :: pp, tt, zz, ww
232 
233  real :: cpl, tpl, ppl, cph, tph, pph
234  integer :: m, zph, zpl, ii
235  real :: dplat, c0, c1, c2, c3, c4, lapse_rate, dt, ctz
236  real :: adjustment1, irw_height_mean
237 
238  integer :: irw_channel
239 
240  call set_irw_channel(irw_channel)
241 
242 ! get the temporally and spatially interpolated surface temperature
243  sfc_tmp = surface_temperature(x,y)
244 
245 ! get the info about NWP data
246 
247 
248 ! get the calculated 11um clear sky radiance and brightness temperature
249  call set_esfc(cloudmask(x,y)%water_surface, x, y, esfc, ocean_flag)
250 
251  sfc_lev = c2_model_info%surface_level
252 
253  call get_clear_toa_rad(platform_name, sfc_tmp, esfc, &
254  sfc_lev, clear_sky_radiance, clear_sky_bt, clear_rad_table, clear_trans_table, .false.)
255 
256 ! get the tropopause level
257 
258  trop_lev = c2_model_info%trop_level
259 
260  iwin = 0.
261  icnt = 1
262 
263  do i=trop_lev, sfc_lev
264  iwin(icnt) = cloud_prof(irw_channel, i)
265  icnt = icnt + 1
266  end do
267  num_work_lev = icnt-1
268 
269  rad0 = i11_meas
270  meas_temp = modis_bright(platform_name, rad0, channel_11um, 1)
271 
272 ! get the profile piece that we will do work on
273  allocate(pp(num_work_lev), zz(num_work_lev), tt(num_work_lev))
274 
275  icnt = 1
276  do i=trop_lev, sfc_lev
277  pp(icnt) = c2_model_info%pressure_profile(i)
278  tt(icnt) = c2_model_info%temp_profile(i)
279  zz(icnt) = c2_model_info%height_profile(i)
280  icnt = icnt + 1
281  end do
282 
283 ! if the observed BT is colder than minimum trop temperature, then put cloud at trop
284  if (meas_temp < tt(1)) then
285  irw_temp = tt(1)
286  irw_pressure = pp(1)
287  irw_height = zz(1)
288 
289 ! if the observed BT warmer than TSFC, put the cloud at surface
290  else if (meas_temp > sfc_tmp) then
291  irw_temp = sfc_tmp
292  irw_pressure = c2_model_info%Ps
293  irw_height = 0.
294  else
295 ! interpolate the temperature and pressure. This is a little more advanced than what UWisc is doing. They take closest level.
296  call locate_point_top_down(rad0, iwin, num_work_lev, idx_lo, idx_hi)
297  irw_temp = linearinterpolation( (/ iwin(idx_lo), iwin(idx_hi) /), (/ tt(idx_lo), tt(idx_hi) /), rad0)
298  irw_pressure = linearinterpolation( (/ iwin(idx_lo), iwin(idx_hi) /), (/ pp(idx_lo), pp(idx_hi) /), rad0)
299  irw_height = linearinterpolation( (/ iwin(idx_lo), iwin(idx_hi) /), (/ zz(idx_lo), zz(idx_hi) /), rad0)
300 
301  endif
302 
303 
304  if (irw_height < 0.) then
305  irw_height = 0.
306  irw_pressure = c2_model_info%Ps
307  irw_temp = sfc_tmp
308  endif
309 
310 
311 ! now we do the alternate IRW retrieval for extra-low clouds over ocean only.
312 
313  if (irw_pressure > 600. .and. ocean_flag) then
314 
315  m = mymonth
316 
317  dplat = latitude(x,y)
318 
319  if (dplat < breakpts(1, m)) then
320  c0 = month_coeffsa(1, m)
321  c1 = month_coeffsa(2, m)
322  c2 = month_coeffsa(3, m)
323  c3 = month_coeffsa(4, m)
324  c4 = month_coeffsa(5, m)
325  else if (dplat >= breakpts(1, m) .and. dplat <= breakpts(2, m)) then
326  c0 = month_coeffsb(1, m)
327  c1 = month_coeffsb(2, m)
328  c2 = month_coeffsb(3, m)
329  c3 = month_coeffsb(4, m)
330  c4 = month_coeffsb(5, m)
331  else
332  c0 = month_coeffsc(1, m)
333  c1 = month_coeffsc(2, m)
334  c2 = month_coeffsc(3, m)
335  c3 = month_coeffsc(4, m)
336  c4 = month_coeffsc(5, m)
337  endif
338 
339  lapse_rate = c0 + c1*dplat + c2*dplat**2 + c3*dplat**3 + c4*dplat**4
340  if (lapse_rate < 2.) lapse_rate = 2.
341  if (lapse_rate > 10.) lapse_rate = 10.
342 
343  dt = clear_sky_bt(irw_channel) - meas_temp
344  if (dt > 0.) then
345  ctz = (dt / lapse_rate) * 1000.
346  else
347  ctz = 0.
348  endif
349 
350  if (ctz == 0.) then
351  irw_temp = sfc_tmp
352  irw_pressure = c2_model_info%Ps
353  else
354 
355  do i = sfc_lev, trop_lev, -1
356 
357  if (c2_model_info%height_profile(i) > ctz) then
358  zpl = i + 1
359  if (zpl > sfc_lev) then
360  cpl = 0.
361  zpl = i
362  tpl = sfc_tmp
363  ppl = c2_model_info%Ps
364  else
365  cpl = c2_model_info%height_profile(zpl)
366  tpl = c2_model_info%temp_profile(zpl)
367  ppl = c2_model_info%pressure_profile(zpl)
368  endif
369 
370  zph = i
371  cph = c2_model_info%height_profile(zph)
372  tph = c2_model_info%temp_profile(zph)
373  pph = c2_model_info%pressure_profile(zph)
374  exit
375  endif
376 
377  end do
378 
379  if (abs(ctz - cph) <= abs(ctz - cpl)) then
380  irw_height = cph
381  irw_pressure = pph
382  else
383  irw_height = cpl
384  irw_pressure = ppl
385  endif
386 
387 
388 
389  if (irw_height < 0.) then
390  irw_height = 0.
391  irw_pressure = c2_model_info%Ps
392  irw_temp = sfc_tmp
393  endif
394 
395 
396  endif
397 
398  endif
399 
400 #if CT_CODE && (MAS_INST || EMAS_INST)
401  cloud_top_height(x,y) = irw_height
402 #endif
403 
404  deallocate(pp, zz, tt)
405 
406 end subroutine retrieve_irw_temp
407 
408 
409 
410  SUBROUTINE locate_point_top_down(theta,thetaArray,ntheta,iAngLow, iAngHi)
411 
412  INTEGER,INTENT(IN)::ntheta
413  REAL,INTENT(IN)::theta,thetaArray(1:ntheta)
414  INTEGER,INTENT(OUT)::iAngLow, iAngHi
415 
416  INTEGER:: iAng
417  integer :: i
418 
419  ianglow = 1
420  ianghi = ntheta
421 
422  do i=1, ntheta
423  if (theta < thetaarray(i)) then
424  ianglow = i-1
425  ianghi = i
426  exit
427  endif
428 
429  end do
430 
431  if (ianglow < 1) ianglow = 1
432  if (ianghi < 1) ianghi = 1
433  if (ianghi > ntheta) ianghi = ntheta
434  if (ianglow > ntheta) ianglow = ntheta
435 
436  END SUBROUTINE locate_point_top_down
437 
438 
439 end module retrieval_irw
real, dimension(nchan, model_levels), public rtm_rad_atm_clr_low
Definition: rtm_support.f90:59
real, dimension(nchan, model_levels), public rtm_trans_atm_clr_low
Definition: rtm_support.f90:58
type(cloudmask_type), dimension(:,:), allocatable cloudmask
real function, public linearinterpolation(X, Y, XX)
real(single), dimension(:,:), allocatable latitude
real, dimension(nchan, model_levels), public rtm_cloud_prof_high
Definition: rtm_support.f90:65
character *15 platform_name
subroutine set_esfc(os_flag_in, x, y, esfc, os_flag)
subroutine locate_point_top_down(theta, thetaArray, ntheta, iAngLow, iAngHi)
real(single), dimension(:,:), allocatable cloud_top_height
real, dimension(nchan, model_levels), public rtm_trans_atm_clr_high
Definition: rtm_support.f90:63
subroutine, public init_irw
real function, public modis_bright(platform_name, RAD, BAND, UNITS, cwn_array, tcs_array, tci_array)
real, dimension(nchan, model_levels), public rtm_cloud_prof_low
Definition: rtm_support.f90:60
subroutine, public retrieve_irw_temp_for_uncert(x, y, I11_meas, idx_i, idx_j, irw_temp_low, irw_temp_high)
subroutine tt(NMAX, NCHECK)
Definition: ampld.lp.f:1852
subroutine, public get_clear_toa_rad(platform, Tsfc, esfc, sfc_level, rad_clr, bt_clr, clear_rad_table, clear_trans_table, PRN)
type(ancillary_type) c2_model_info
integer mymonth
Definition: names.f90:9
real(single), dimension(:,:), allocatable surface_temperature
Definition: names.f90:1
integer, parameter channel_11um
subroutine, public retrieve_irw_temp(x, y, I11_meas, idx_i, idx_j, clear_rad_table, clear_trans_table, cloud_prof, irw_temp, irw_pressure, irw_height)
integer, parameter set_number_of_bands
subroutine set_irw_channel(IRW_channel)
subroutine cloud_prof(pcldtop, pcldbtm, ppodd, htdd, znpdd)
Definition: afrt_rt1.f:1411
real, dimension(nchan, model_levels), public rtm_rad_atm_clr_high
Definition: rtm_support.f90:64
#define abs(a)
Definition: misc.h:90