OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
multi_layer_clouds.f90
Go to the documentation of this file.
1 #if SEV_PR06OD || VIIRS_OD
2 
3 #else
4 
6 !-------------------------------------------------------------------------------
7 ! DESCRIPTION:
8 ! this module contains the subroutines needed for computation of
9 ! the 0.94-based ancillary and the multi-layer map.
10 !
11 !
12 ! PROGRAMMER:
13 ! Gala Wind (L3 Comm GSI)
14 ! Climate and Radiation Branch
15 ! Code 913, NASA Goddard Space Flight Center
16 ! Greenbelt, Maryland 20771, U.S.A.
17 !
18 ! Mark A Gray (L3 Comm GSI)
19 ! Climate and Radiation Branch
20 ! Code 913, NASA Goddard Space Flight Center
21 ! Greenbelt, Maryland 20771, U.S.A.
22 !------------------------------------------------------------------------------
23 ! REVISION:
24 ! -------------------------------------------------------------------------------------------
25 ! 6.7.04 Initial revision
26 ! 7.04 corrected variable names for MODIS
27 ! implented logical cloud decision types
28 !
29 !------------------------------------------------------------------------------
30  use generalauxtype
34  use core_arrays
36  use specific_other
38 
39  implicit none
40  private
41 
42  ! there is only one public routine here
44 
45 
46  ! All these variables are private to this module.
47  INTEGER, PARAMETER :: NumberOfPressureHeights = 10
48  REAL, DIMENSION(NumberOfPressureHeights), PARAMETER :: &
49  heightScale = (/ 100., 200., 300., 400., 500., 600., 700., 800., 900., 1000. /)
50 
51  INTEGER, PARAMETER :: NumberOfPrecipitableWater = 53
52  REAL, DIMENSION(NumberOfPrecipitableWater), PARAMETER :: &
53  pwScale = (/ 0.0, 0.02, 0.04, 0.06, 0.08, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, &
54  0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6,1.8, &
55  2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, &
56  4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2, &
57  6.4, 6.6, 6.8, 7.0, 7.2, 7.4, 7.6, 7.8, 8.0, 8.2, 8.4, &
58  8.6 /)
59 
60  INTEGER, PARAMETER :: NumberOfMiu = 20
61  REAL, DIMENSION(NumberOfMiu), PARAMETER :: &
62  miuscale = (/ 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, &
63  0.50, 0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, &
64  0.95, 1.00 /)
65 
66 
67  integer, parameter :: nvza = 7
68  integer, parameter :: nsza = 8
69  integer, parameter :: nsct = 18
70 
71 
72 ! AVHRR cloud overlap function coefficients
73  real*8, dimension(7,8) :: a_win_over, b_win_over, c_win_over, d_win_over, e_win_over
74 
75  ! minimum 11-12um BTD for overlap detection
76  real, dimension (7,8) :: MIN_win_over
77 
78 
79  ! VIIRS cloud overlap coefficients for water surface
80  real*8, dimension(18) :: a_nir_over_water, b_nir_over_water, c_nir_over_water, d_nir_over_water, e_nir_over_water
81 
82  ! VIIRS cloud overlap coefficients for grass surface
83  real*8, dimension(18) :: a_nir_over_land, b_nir_over_land, c_nir_over_land, d_nir_over_land, e_nir_over_land
84 
85 
86 
87  contains
88 
89 
90 
91 !=====================================
92 subroutine compute_multilayer_map(platform_name, &
93  BigTransTable, &
94  measurements, &
95  cloud_phase, &
96  Baum_phase, &
97  p_ncep, &
98  mixR_ncep, &
99  t_ncep, &
100  surface, &
101  MOD06_Pc, &
102  MOD06_PW, &
103  sat_zen, &
104  sol_zen, &
105  rel_az, &
106  tau, tau1621, xpoint, ypoint, &
107  mlayer, mlayer_test)
108 !=====================================
109 
110 !-----------------------------------------------------------------------
111 ! !f90
112 !
113 ! !Description:
114 ! This subroutine computes the multi-layer cloud value for one pixel
115 !
116 ! !Input Parameters:
117 ! platform_name -- character(*) -- Terra or Aqua
118 ! BigTransTable -- real, dimension(:,:,:,:) -- entire transmittance table
119 ! measurements -- real, dimension(:) -- MODIS radiances/reflectances
120 ! cloud_phase -- logical structure
121 ! Baum_phase -- logical structure
122 ! p_ncep -- real, dimension(:) -- NCEP pressure profile
123 ! mixR_ncep -- real, dimension(:) -- NCEP mixing ratio profile
124 ! t_ncep -- real, dimension(:) -- NCEP temperature profile
125 ! MOD06_Pc -- real -- Cloud top pressure from MOD06CT
126 ! MOD06_PW -- real -- above cloud precip. water derived from MOD06_Pc and NCEP by MOD06OD ancillary
127 ! sat_zen -- real -- viewing angle
128 ! sol_zen -- real -- solar zenith angle
129 ! rel_az -- real -- relative azlimuth angle
130 ! tau -- real(:,:) -- retrieved cloud optical depth 3x3 points
131 ! tau1621 -- real(:,:) -- retrieved cloud optical depth 1.6-2.1um 3x3 points
132 ! xpoint -- integer -- x coordinate of pixel
133 ! ypoint -- integer -- y coordinate of pixel
134 !
135 ! !Output Parameters:
136 ! mlayer -- integer*1 -- multi-layer cloud map for one pixel
137 ! mlayer_test -- integer*1 -- multilayer qa
138 !
139 ! !Revision History:
140 ! 2004/06/02 wind: Gala Wind
141 ! Revision 1.0 Initial Revision
142 ! 2009/03/25 wind: Gala Wind
143 ! Revision 2.0 added Pavolonis-Heidinger and the delta-tau algorithms
144 ! 2009/05/19 wind: Gala Wind
145 ! Revision 2.1 added the multilayer qa
146 !
147 !
148 ! !Team-Unique Header:
149 ! Developed by the Cloud Retrieval Group, NASA GSFC, Greenbelt, Maryland, USA.
150 !
151 ! !References and Credits:
152 ! Written by:
153 ! Gala Wind
154 ! L3 GSI
155 ! Code 913, NASA/GSFC
156 ! Greenbelt, MD 20771
157 ! wind@climate.gsfc.nasa.gov
158 !
159 ! !Design Notes:
160 ! NONE
161 !
162 ! !END
163 !
164 !-----------------------------------------------------------------------
165  use ch_xfr, only : c2_cmp_there
166 
167 ! first of all we need to compute the quantities that usually come from the research retrieval
168 ! code. That would be the total column water and 0.94 pw
169  character*(*),intent(in) :: platform_name
170  real(single), dimension(:,:,:,:), intent(in) :: bigtranstable
171  real, dimension(:), intent(in) :: measurements
172  real, intent(in) :: mod06_pc, mod06_pw, sat_zen, sol_zen, rel_az
173  real, intent(in) :: tau, tau1621
174  type(processflag), intent(in) :: cloud_phase
175  integer*1, intent(in) :: surface
176  integer, intent(in) :: xpoint, ypoint
177  type(cloudphase),intent(in) :: baum_phase
178  real(single), dimension(:), intent(in) :: p_ncep, t_ncep, mixr_ncep
179 
180  integer(integer_onebyte), intent(out) :: mlayer, mlayer_test
181  real(single) :: refl_86, refl_94, iir_data, refl_65, refl_12
182 
183 
184  real :: t, p, pw, totalprecipwater, newt, temp, pw_at_900, miu, miu0
185  logical :: first
186  real :: plant_ratio, pw_fraction, pw_fraction_900, ice_ratio
187  integer(integer_onebyte) :: pw_test, pw_900_test, tau_test, cloud_phase_test
188  integer :: ph_test, delta_tau
189  integer :: db_co2
190  real :: db_th
191  integer :: mlayer_add
192  logical :: ice_ratio_var
193 
194 
195  integer :: i, n, j
196 
197 
198  miu = cos(sat_zen * d2r)
199  miu0 = cos(sol_zen * d2r)
200 
201  refl_65 = measurements(band_0065)
202  refl_86 = measurements(band_0086)
203  refl_94 = measurements(band_0935)
204  refl_12 = measurements(band_0124)
205  iir_data = measurements(band_1100)
206 
207  ! Get the initial guess for brightness temperature
208  t = modis_bright(platform_name,iir_data,channel_11um,1)
209 
210  ! compute the initial pressure
211 
212  call given_t_get_p(p, t, surface, p_ncep, t_ncep)
213 
214  ! find the initial amount of precipitable water based on the initial guess
215  ! for the cloud top pressure computed above
216 
217  call find_tpw(refl_86, refl_94, p, pw, bigtranstable, miu, miu0, xpoint, ypoint)
218 
219  first = .true.
220  call find_brightness_t(platform_name,pw, p, newt, totalprecipwater, p_ncep, t_ncep, mixr_ncep, surface, &
221  iir_data, bigtranstable, miu, first)
222 
223 
224  call given_t_get_p(p, newt, surface, p_ncep, t_ncep)
225  ! do another iteration
226  call find_tpw(refl_86, refl_94, p, pw, bigtranstable, miu, miu0, xpoint, ypoint)
227  call find_brightness_t(platform_name,pw, p, newt, temp, p_ncep, t_ncep, mixr_ncep, surface, &
228  iir_data, bigtranstable, miu, first)
229 
230  t = newt
231 
232  if (tau >= 4.) precip_water_094(xpoint, ypoint) = pw
233 
234 
235  ! now we're going to compute PW as if all the clouds were at 900 mb
236 
237 
238  if (p_ncep(surface) >= 900.) then
239  call find_tpw(refl_86, refl_94, 900., pw_at_900, bigtranstable, miu, miu0, xpoint, ypoint)
240  else
241  call find_tpw(refl_86, refl_94, p_ncep(surface) - 100., pw_at_900, bigtranstable, miu, miu0, xpoint, ypoint)
242  endif
243 
244 
245 
246  ! -----------------------------------------------------------------------
247  ! NOW ANCILLARY PORTION IS FINISHED. STARTING LAYER DETECTION
248  ! -----------------------------------------------------------------------
249 
250  if (pw > totalprecipwater) pw = totalprecipwater
251  if (pw_at_900 > totalprecipwater) pw_at_900 = totalprecipwater
252 
253  plant_ratio = refl_86 / refl_65 ! vegetation ratio: 0.86/0.65 um
254  pw_fraction = abs(mod06_pw - pw) / totalprecipwater ! precipitable water
255  pw_fraction_900 = abs(mod06_pw - pw_at_900) / totalprecipwater ! additional precip water ratio
256  ice_ratio = refl_86 / refl_12 ! ice ratio 0.86/1.2 um
257 
258  ice_ratio_var = set_ice_ratio(ice_ratio)
259 
260  ! there has to be enough precipitable water in the column for us to bother with retrieval.
261 
262  if (pw_fraction > 0.08 .and. mod06_pc < 550.0 .and. plant_ratio < 1.25 .and. ice_ratio_var ) then
263  pw_test = 1
264  else
265  pw_test = 0
266  endif
267 
268  if (pw_fraction_900 > 0.08 .and. mod06_pc < 550.0 .and. plant_ratio < 1.25 .and. ice_ratio_var ) then
269  pw_900_test = 1
270  else
271  pw_900_test = 0
272  endif
273 
274 
275 ! use the midpoint as that's what the original point would've been
276  if (tau < 4. .and. tau >= 0.) then
277  tau_test = 1
278  else
279  tau_test = 0
280  endif
281 
282  ! cloud phase test: 0 if phases agree, 1 if SWIR-water and IR-ice or IR-mixed,
283  ! 2 if SWIR-ice and IR-water
284  cloud_phase_test = 0
285  if (cloud_phase%watercloud .and. baum_phase%watercloud == 1 ) cloud_phase_test = 0
286  if (cloud_phase%icecloud .and. baum_phase%icecloud == 1) cloud_phase_test = 0
287 
288  if (cloud_phase%watercloud .and. baum_phase%icecloud == 1) cloud_phase_test = 1
289  if (cloud_phase%icecloud .and. baum_phase%watercloud == 1) cloud_phase_test = 2
290 
291 
292  if (tau_test == 1) then
293  cloud_phase_test = 0
294  pw_900_test = 0
295  pw_test = 0
296  endif
297 
298 
299 ! the don't bother CO2 test for ice cloud layer too thick
300  if ( abs(latitude(xpoint, ypoint)) < 30.) then
301  db_th = 1.7
302  else
303  db_th = 2.43
304  endif
305 
306  if ( ( c2_cmp_there(band_1350) == 1 ) .and. &
307  ( c2_cmp_there(band_1200) == 1 ) ) then
308  if (measurements(band_1350) < db_th) then
309  db_co2 = 1 ! don't bother
310  else
311  db_co2 = 0 ! bother
312  endif
313  else
314  db_co2 = 1 ! don't bother
315  endif
316 
317  delta_tau = 0
318  ph_test = 0
319 
320  if (db_co2 == 0 .and. tau_test == 0) then ! not too thick, not too thin, just right
321 
322 ! this is the Pavolonis-Heidinger algorithm
323  ph_test = ph_multilayer(sol_zen, sat_zen, rel_az, measurements, cloud_phase, platform_name, latitude(xpoint, ypoint))
324 
325 ! this is the delta-tau method
326  if (cloud_phase%icecloud) then
327  if (tau < 30. .and. tau1621 > 80.) then
328  delta_tau = 1
329  else
330  delta_tau = 0
331  endif
332  endif
333  else
334  delta_tau = 0
335  ph_test = 0
336  endif
337 
338 ! calculate the confidence level of the multilayer answer.
339 ! confidence levels like this: phase MLC5 test 1 point, the other MLC5 tests 2 points, two MLC5 tests: 3 points, three MLC5 tests 4 points, delta-tau 1 point,
340 ! ph_test 3 points
341 
342 
343  mlayer = 1 !to 1
344  mlayer_test = 0 ! no tests done
345 
346  if (cloud_phase_test == 1) mlayer = mlayer + 1
347  if (delta_tau == 1) mlayer = mlayer + 1
348  if (pw_test == 1) mlayer = mlayer + 2
349  if (pw_900_test == 1) mlayer = mlayer + 2
350  if (ph_test == 1) mlayer = mlayer + 3
351 
352  if (cloud_phase_test == 1) mlayer_test = ibset(mlayer_test, 0)
353  if (pw_test == 1) mlayer_test = ibset(mlayer_test, 1)
354  if (pw_900_test == 1) mlayer_test = ibset(mlayer_test, 2)
355  if (delta_tau == 1) mlayer_test = ibset(mlayer_test, 3)
356  if (ph_test == 1) mlayer_test = ibset(mlayer_test, 4)
357 
358  end subroutine compute_multilayer_map
359 
360 
361  !=====================================
362  subroutine find_tpw(refl_86, refl_94, P, PW, BigTransTable, miu1, miu0, xpoint, ypoint)
363 !=====================================
364 !-----------------------------------------------------------------------
365 ! !f90
366 !
367 ! !Description:
368 ! This subroutine computes 0.94um-based precipitable water above cloud for a given pixel
369 !
370 ! !Input Parameters:
371 ! refl_86 -- real*4 -- 0.86um reflectance (band 2 in MODIS)
372 ! refl_94 -- real*4 -- 0.94um reflectance (band 9 in MODIS)
373 ! P -- real*4 -- cloud top pressure in mb
374 ! BigTransTable -- real*4, dimension(:,:,:,:) -- transmittance table
375 ! miu1 -- real*4 -- cos of viewing angle
376 ! miu0 -- real*4 -- cos of solar zenith angle
377 !
378 ! !Output Parameters:
379 ! PW -- real*4 -- precipitable water amount in cm
380 !
381 ! !Revision History:
382 ! 2004/06/02 wind: Gala Wind
383 ! Revision 1.0 Initial Revision
384 !
385 ! !Team-Unique Header:
386 ! Developed by the Cloud Retrieval Group, NASA GSFC, Greenbelt, Maryland, USA.
387 !
388 ! !References and Credits:
389 ! Written by:
390 ! Gala Wind
391 ! L3 GSI
392 ! Code 913, NASA/GSFC
393 ! Greenbelt, MD 20771
394 ! wind@climate.gsfc.nasa.gov
395 !
396 ! !Design Notes:
397 ! NONE
398 !
399 ! !END
400 !
401 !-----------------------------------------------------------------------
402 
403  use generalauxtype
404 
405  implicit none
406 
407  real, intent(in) :: p, miu1, miu0, refl_86, refl_94
408  real, intent(inout) :: pw
409  real(single), dimension(:,:,:,:), intent(in) :: bigtranstable
410  integer, intent(in) :: xpoint, ypoint
411 
412  integer :: k
413 
414  real :: tpw
415  real, dimension(:), allocatable :: trans2way
416 
417 
418  integer, dimension(4) :: mindex
419 
420  integer :: miu_index, pindex, pwindex, miu2index, first_pindex, second_pindex
421  integer :: bandindexmapsw1(2)
422 
423  REAL :: miu, transvalue
424 
425 
426 
427  real, dimension(53) :: pix086, pix094, ans_diff, ans_diff_abs
428  real :: answer, trans_mid1, trans_mid2
429  integer :: first_miuindex, second_miuindex
430  real :: trans_p_1, trans_p_2 ! these are for the second pIndex
431  real :: trans1, trans2
432 
433  real :: point1, point2, x1, x2
434  integer :: idx1, idx2
435 
436  bandindexmapsw1(1) = 2
437  bandindexmapsw1(2) = 3
438 
439 
440  pindex = nint( (p - heightscale(1)) / 100.0 ) + 1
441  if(pindex < 1) then
442  pindex = 1
443  first_pindex = 1
444  second_pindex = 1
445  elseif(pindex > numberofpressureheights) then
446  pindex = numberofpressureheights
447  first_pindex = pindex
448  second_pindex = pindex
449  endif
450 
451  if (heightscale(pindex) >= p) then
452  first_pindex = pindex-1
453  second_pindex = pindex
454  else
455  first_pindex = pindex
456  second_pindex = pindex+1
457  endif
458 
459  if (first_pindex == 0 ) then
460  first_pindex = 1
461  second_pindex = 2
462  endif
463 
464  if (second_pindex > numberofpressureheights) &
465  second_pindex = numberofpressureheights
466 
467  ! key: compute effective miu for a two way path:
468 
469  miu = (miu0*miu1)/(miu0+miu1)
470 
471 !
472 !... find array indicies along p, pw and miu dimension:
473 !
474 
475  miu2index = nint( (miu - miuscale(1)) / 0.05 ) + 1
476  if (miu2index < 1) then
477  miu2index = 1
478  elseif(miu2index > numberofmiu) then
479  miu2index = numberofmiu
480  endif
481 
482 
483 !
484 !... 2-way case (for shortwave channels upto 3.7 micron band):
485 !
486 
487  mindex(1) = pindex
488  mindex(2) = 1
489  mindex(3) = miu2index
490  mindex(4) = bandindexmapsw1(1)
491 
492  if (miuscale(miu2index) >= miu ) then
493  first_miuindex = miu2index -1
494  second_miuindex = miu2index
495  else
496  first_miuindex = miu2index
497  second_miuindex = miu2index + 1
498  endif
499 
500  do k=1, numberofprecipitablewater
501 ! for the first pressure
502 ! call interpolate(miuscale(first_miuindex), &
503 ! bigtransTable(first_pIndex, k, first_miuindex, bandindexmapsw1(1)), &
504 ! miuscale(second_miuindex), &
505 ! bigtransTable(first_pIndex, k, second_miuindex, bandindexmapsw1(1)), &
506 ! miu, trans_mid1)
507  trans_mid1 = linearinterpolation( (/miuscale(first_miuindex), miuscale(second_miuindex)/), &
508  (/bigtranstable(first_pindex, k, first_miuindex, bandindexmapsw1(1)), &
509  bigtranstable(first_pindex, k, second_miuindex, bandindexmapsw1(1))/), &
510  miu)
511 
512 ! call interpolate(miuscale(first_miuindex), &
513 ! bigtransTable(first_pIndex, k, first_miuindex, bandindexmapsw1(2)), &
514 ! miuscale(second_miuindex), &
515 ! bigtransTable(first_pIndex, k, second_miuindex, bandindexmapsw1(2)), &
516 ! miu, trans_mid2)
517 
518  trans_mid2 = linearinterpolation( (/miuscale(first_miuindex), miuscale(second_miuindex)/), &
519  (/bigtranstable(first_pindex, k, first_miuindex, bandindexmapsw1(2)), &
520  bigtranstable(first_pindex, k, second_miuindex, bandindexmapsw1(2))/), &
521  miu)
522 ! for the second pressure
523 ! call interpolate(miuscale(first_miuindex), &
524 ! bigtransTable(second_pIndex, k, first_miuindex, bandindexmapsw1(1)), &
525 ! miuscale(second_miuindex), &
526 ! bigtransTable(second_pIndex, k, second_miuindex, bandindexmapsw1(1)), &
527 ! miu, trans_p_1)
528 
529  trans_p_1 = linearinterpolation( (/miuscale(first_miuindex), miuscale(second_miuindex)/), &
530  (/ bigtranstable(second_pindex, k, first_miuindex, bandindexmapsw1(1)), &
531  bigtranstable(second_pindex, k, second_miuindex, bandindexmapsw1(1)) /), &
532  miu)
533 ! call interpolate(miuscale(first_miuindex), &
534 ! bigtransTable(second_pIndex, k, first_miuindex, bandindexmapsw1(2)), &
535 ! miuscale(second_miuindex), &
536 ! bigtransTable(second_pIndex, k, second_miuindex, bandindexmapsw1(2)), &
537 ! miu, trans_p_2)
538  trans_p_2 = linearinterpolation( (/ miuscale(first_miuindex), miuscale(second_miuindex) /), &
539  (/ bigtranstable(second_pindex, k, first_miuindex, bandindexmapsw1(2)), &
540  bigtranstable(second_pindex, k, second_miuindex, bandindexmapsw1(2)) /), &
541  miu)
542 
543 ! final interpolation now along the pressure axis
544  trans1 = linearinterpolation((/heightscale(first_pindex), heightscale(second_pindex)/), &
545  (/trans_mid1, trans_p_1/), &
546  p)
547  trans2 = linearinterpolation((/heightscale(first_pindex), heightscale(second_pindex)/), &
548  (/trans_mid2, trans_p_2/), &
549  p)
550  if (trans_mid1 < 0. .or. trans_p_1 < 0.) trans1 = -1.0
551  if (trans_mid2 < 0. .or. trans_p_2 < 0.) trans2 = -1.0
552 
553  pix086(k) = refl_86 / trans1
554  pix094(k) = refl_94 / trans2
555 
556  if (trans1 < 0.0) pix086(k) = 20
557  if (trans2 < 0.0) pix094(k) = 300
558 
559  end do
560 
561  do k=1, numberofprecipitablewater
562  ans_diff(k) = pix086(k)-pix094(k)
563  ans_diff_abs(k) = ans_diff(k)
564  if (ans_diff(k) < 0) ans_diff_abs(k) = -ans_diff(k)
565  end do
566 
567 
568 
569  answer = minval(ans_diff_abs)
570  do k=1, numberofprecipitablewater
571  if (real_s_equal(ans_diff_abs(k), answer)) then
572  answer = pwscale(k)
573  exit
574  endif
575  end do
576 
577  if (ans_diff(k) < 0.) then
578 
579  idx1 = k-1
580  if (idx1 < 1) idx1 = 1
581  idx2 = k
582 
583  if (idx1 == idx2) then
584  pw = pwscale(k)
585  return
586  endif
587 
588  point1 = ans_diff(idx1)
589  point2 = ans_diff(idx2)
590 
591  x1 = pwscale(idx1)
592  x2 = pwscale(idx2)
593 
594  if (point1 == -280.) then
595  pw = pwscale(idx2)
596  else
597  pw = linearinterpolation( (/ point1, point2 /), (/ x1, x2 /), 0.0)
598  endif
599 
600  else
601  idx1 = k
602  idx2 = k+1
603  if (idx2 > numberofprecipitablewater) idx2 = numberofprecipitablewater
604 
605  if (idx1 == idx2) then
606  pw = pwscale(k)
607  return
608  endif
609 
610  point1 = ans_diff(idx1)
611  point2 = ans_diff(idx2)
612 
613  x1 = pwscale(idx1)
614  x2 = pwscale(idx2)
615 
616  if (point2 == -280.) then
617  pw = pwscale(idx1)
618  else
619  pw = linearinterpolation( (/ point1, point2 /), (/ x1, x2 /), 0.0)
620  endif
621 
622  endif
623 
624  end subroutine find_tpw
625 
626 
627 !=====================================
628  subroutine given_t_get_p(P,T, surface, p_ncep, t_ncep)
629 !=====================================
630 
631 !-----------------------------------------------------------------------
632 ! !f90
633 !
634 ! !Description:
635 ! This subroutine gets NCEP cloud top pressure for a given
636 ! cloud top temperature
637 !
638 ! !Input Parameters:
639 ! T -- real*4 -- cloud top temperature in K
640 ! p_ncep -- real*4, dimension(:) -- NCEP pressure profile
641 ! t_ncep -- real*4, dimension(:) -- NCEP temperature profile
642 !
643 ! !Output Parameters:
644 ! P -- real*4 -- cloud top pressure in mb
645 !
646 ! !Revision History:
647 ! 2004/06/02 wind: Gala Wind
648 ! Revision 1.0 Initial Revision
649 !
650 ! !Team-Unique Header:
651 ! Developed by the Cloud Retrieval Group, NASA GSFC, Greenbelt, Maryland, USA.
652 !
653 ! !References and Credits:
654 ! Written by:
655 ! Gala Wind
656 ! L3 GSI
657 ! Code 913, NASA/GSFC
658 ! Greenbelt, MD 20771
659 ! wind@climate.gsfc.nasa.gov
660 !
661 ! !Design Notes:
662 ! NONE
663 !
664 ! !END
665 !
666 !-----------------------------------------------------------------------
667  real, intent(in) :: t
668  real, intent(inout) :: p
669  integer*1, intent(in) :: surface
670  real, dimension(:), intent(in) :: p_ncep, t_ncep
671 
672  integer :: k
673  real :: factor
674 
675 ! do k=1, model_levels
676  do k=surface, 1, -1
677  if ( t > t_ncep(k)) &
678  exit
679  end do
680 
681  if (k <= 1) then
682  p = p_ncep(1)
683  elseif (k == surface) then
684  p = p_ncep(surface)
685  else
686 
687  p = linearinterpolation( (/ t_ncep(k), t_ncep(k+1) /), (/ p_ncep(k), p_ncep(k+1) /), t)
688 
689 ! factor = (T - t_ncep(k)) / (t_ncep(k-1) - t_ncep(k))
690 ! P = p_ncep(k) + factor* (p_ncep(k-1) - p_ncep(k))
691 
692  endif
693 
694  if (p < 100.) p = 100.
695 
696 
697  end subroutine given_t_get_p
698 
699 
700 
701 !=====================================
702  subroutine find_brightness_t(platform_name,PW, P, newT, TotalPrecipWater, p_ncep, t_ncep, mixR_ncep, surface, &
703  IIR_data, BigTransTable, miu, FIRST)
704 !=====================================
705 
706 !-----------------------------------------------------------------------
707 ! !f90
708 !
709 ! !Description:
710 ! This subroutine computes the cloud top temperature for a given pixel
711 !
712 ! !Input Parameters:
713 ! P -- real*4 -- cloud top pressure in mb
714 ! PW -- real*4 -- precipitable water amount in cm
715 ! p_ncep -- real*4, dimension(:) -- NCEP pressure profile
716 ! t_ncep -- real*4, dimension(:) -- NCEP temperature profile
717 ! mixR_ncep -- real*4, dimension(:) -- NCEP mixing ratio profile
718 ! IIR_data -- real*4 -- 11um radiance
719 ! BigTransTable -- real*4, dimension(:,:,:,:) -- transmittance table
720 ! miu -- real*4 -- cosine of viewing angle
721 ! FIRST -- logical -- flag for integration of TPW
722 !
723 ! !Output Parameters:
724 ! newT -- real*4 -- cloud top temperature in K
725 ! TotalPrecipWater -- real*4 -- integrated NCEP water vapor column amount
726 !
727 ! !Revision History:
728 ! 2004/06/02 wind: Gala Wind
729 ! Revision 1.0 Initial Revision
730 !
731 ! !Team-Unique Header:
732 ! Developed by the Cloud Retrieval Group, NASA GSFC, Greenbelt, Maryland, USA.
733 !
734 ! !References and Credits:
735 ! Written by:
736 ! Gala Wind
737 ! L3 GSI
738 ! Code 913, NASA/GSFC
739 ! Greenbelt, MD 20771
740 ! wind@climate.gsfc.nasa.gov
741 !
742 ! !Design Notes:
743 ! NONE
744 !
745 ! !END
746 !
747 !-----------------------------------------------------------------------
748 
749  implicit NONE
750  character*(*),intent(in) :: platform_name
751  real, intent(in) :: pw, p, iir_data, miu
752  logical, intent(inout) :: first
753  integer*1, intent(in) :: surface
754  real, intent(inout) :: newt, totalprecipwater
755  real(single), dimension(:), intent(in) :: p_ncep, t_ncep, mixr_ncep
756  real(single), dimension(:,:,:,:), intent(in) :: bigtranstable
757 
758 
759  integer :: pindex, miu2index, pwindex, first_miuindex, second_miuindex, k
760  real :: tpw, trans_mid1
761  integer :: mindex(4), first_pindex, second_pindex
762  real :: trans_p_1 ! these are for the second pIndex
763  real :: trans1
764  real :: total_pw, pw_layer, sum_t, slope, mixr_lower, mixr_upper, t_lower, t_upper, t_layer
765  real :: tmeanabovecloud, tpwabovecloud
766  real :: b_11_crude
767  real :: temp
768  integer :: bandindexmaplw1(1)
769 
770  bandindexmaplw1(1) = 8
771 
772  pindex = nint( (p - heightscale(1)) / 100.0 ) + 1
773  if(pindex < 1) then
774  pindex = 1
775  first_pindex = 1
776  second_pindex = 1
777  elseif(pindex > numberofpressureheights) then
778  pindex = numberofpressureheights
779  first_pindex = pindex
780  second_pindex = pindex
781  endif
782 
783  if (heightscale(pindex) >= p) then
784  first_pindex = pindex-1
785  second_pindex = pindex
786  else
787  first_pindex = pindex
788  second_pindex = pindex+1
789  endif
790 
791  if (first_pindex == 0) then
792  first_pindex = 1
793  second_pindex = 2
794  endif
795 
796  if (second_pindex > numberofpressureheights) &
797  second_pindex = numberofpressureheights
798 
799 !
800 !... find array indicies along p, pw and miu dimension:
801 !
802  miu2index = nint( (miu - miuscale(1)) / 0.05 ) + 1
803  if (miu2index < 1) then
804  miu2index = 1
805  elseif(miu2index > numberofmiu) then
806  miu2index = numberofmiu
807  endif
808 
809 
810  if(pw < 0.0) then
811  pwindex = 1
812  elseif(pw < 0.2) then
813  pwindex = nint( (pw- pwscale(1)) / 0.02 ) + 1
814  else
815  pwindex = nint( (pw - pwscale(11)) / 0.20 ) + 11
816  if(pwindex > numberofprecipitablewater) then
817  pwindex = numberofprecipitablewater
818  endif
819  endif
820 
821 
822  mindex(1) = pindex
823  mindex(2) = pwindex
824  mindex(3) = miu2index
825  mindex(4) = bandindexmaplw1(1)
826 
827  if (miuscale(miu2index) >= miu ) then
828  first_miuindex = miu2index -1
829  second_miuindex = miu2index
830  else
831  first_miuindex = miu2index
832  second_miuindex = miu2index + 1
833  endif
834 ! call interpolate(miuscale(first_miuindex), bigtransTable(first_pIndex, pwindex, first_miuindex, bandindexmaplw1(1)), &
835 ! miuscale(second_miuindex), bigtransTable(first_pIndex, pwindex, second_miuindex, bandindexmaplw1(1)), &
836 ! miu, trans_mid1)
837 
838  trans_mid1 = linearinterpolation( (/miuscale(first_miuindex), miuscale(second_miuindex)/), &
839  (/bigtranstable(first_pindex, pwindex, first_miuindex, bandindexmaplw1(1)), &
840  bigtranstable(first_pindex, pwindex, second_miuindex, bandindexmaplw1(1))/), &
841  miu)
842 
843 
844 ! call interpolate(miuscale(first_miuindex), bigtransTable(second_pindex, pwindex, first_miuindex, bandindexmaplw1(1)), &
845 ! miuscale(second_miuindex), bigtransTable(second_pindex, pwindex, second_miuindex, bandindexmaplw1(1)), &
846 ! miu, trans_p_1)
847  trans_p_1= linearinterpolation( (/miuscale(first_miuindex), miuscale(second_miuindex)/), &
848  (/bigtranstable(second_pindex, pwindex, first_miuindex, bandindexmaplw1(1)), &
849  bigtranstable(second_pindex, pwindex, second_miuindex, bandindexmaplw1(1))/), &
850  miu)
851 
852 
853 ! call interpolate(heightscale(first_pindex), trans_mid1, heightscale(second_pindex), trans_p_1, P, trans1)
854 
855  trans1 = linearinterpolation( (/heightscale(first_pindex), heightscale(second_pindex)/), &
856  (/trans_mid1, trans_p_1/), &
857  p)
858 
859  if (trans_mid1 >= 0. .and. trans_p_1 < 0.) trans1 = trans_p_1
860  if (trans_mid1 < 0. .and. trans_p_1 >= 0.) trans1 = trans_mid1
861 
862 
863 
864 ! at this point we have the 1-way transmittance for the atmosphere at 11 microns and the 11 micron radiance
865 ! stored in IIR_data that came from the read_mas_module.f90
866 
867 ! we can go ahead and find the amount of atmospheric correction for the 11 micron channel.
868 
869 
870  total_pw = 0.0
871  sum_t = 0.0
872 
873 
874 ! sep: start loop at NCEP's TOA level - 1
875 
876 
877 ! add up the water profile in order to get the column amount later used for multi-layer cloud detection.
878  if (first) then
879 
880 ! do k=1, model_levels-1
881  do k=surface, 2, -1
882  pw_layer = (p_ncep(k)-p_ncep(k-1)) * (mixr_ncep(k-1) + mixr_ncep(k))*0.5/ 980.616
883  total_pw = total_pw+pw_layer
884  end do
885  totalprecipwater = total_pw
886  endif
887 
888 
889  pw_layer = 0.0
890  total_pw = 0.0
891 
892 ! k = model_levels - 1
893  k = 2
894 ! DO WHILE(p_ncep(k) < P .AND. k > 1)
895  DO WHILE(p_ncep(k) < p .AND. k < surface)
896 
897  ! total precipitable water above cloud in g/cm2
898  ! sep: dPW = rho*w*dz, dp=abs(rho*g*dz) or dz=dp/rho*g => dPW=w*dp/g
899  ! {where w=layer mixing ratio, rho=density}
900  ! mixing ratio must be in g/kg, P in mb 1.22.04
901 
902  pw_layer = (p_ncep(k)-p_ncep(k-1)) * (mixr_ncep(k-1) + mixr_ncep(k))*0.5/ 980.616
903 
904  t_layer = (t_ncep(k)+t_ncep(k-1))*0.5
905  total_pw = total_pw + pw_layer
906  sum_t = sum_t + pw_layer*t_layer
907 
908 ! k = k - 1
909  k = k + 1
910  END DO
911 
912 ! if (P > p_ncep(model_levels)) then
913 ! tpwAboveCloud = total_PW
914 ! tmeanAbovecloud = sum_T
915 
916 ! else
917 
918 
919 ! all the (k+1) have now become (k-1)'s
920  slope = (mixr_ncep(k) - mixr_ncep(k-1)) / (p_ncep(k) - p_ncep(k-1))
921  mixr_upper = mixr_ncep(k-1)
922  mixr_lower = slope * (p - p_ncep(k-1)) + mixr_upper
923  pw_layer = (p - p_ncep(k-1))*(mixr_upper + mixr_lower)*0.5/980.616
924  tpwabovecloud = total_pw + pw_layer
925 
926  slope = (t_ncep(k) - t_ncep(k-1)) / (p_ncep(k) - p_ncep(k-1))
927  t_upper = t_ncep(k-1)
928  t_lower = slope * (p - p_ncep(k-1)) + t_upper
929  t_layer = (t_upper + t_lower)*0.5
930  tmeanabovecloud = (sum_t + pw_layer*t_layer)/tpwabovecloud
931 
932 ! endif
933 
934 ! now we have the mean temperature weighted by the the precip. water
935 ! now we apply the approximation
936 
937  b_11_crude = modis_planck(platform_name, tmeanabovecloud, channel_11um, 1)
938  if (trans1 < -0.0001) trans1 = 1.0
939  b_11_crude = b_11_crude * (1. - trans1) ! scale by 1. - 1waytransmittance
940 
941 ! got the amount of atmospheric correction
942 
943 
944 ! now let's go ahead and subtract the correction from the measured radiance
945  temp = iir_data - b_11_crude
946 ! now we need to divide this mess by the transmittance that we computed earlier
947  temp = temp / trans1
948 
949 ! now all this neat mess needs to be fed into the Planck function inversion
951 
952  end subroutine find_brightness_t
953 
954 !=====================================
955 !=====================================
956 
957 ! THESE ROUTINES BELONG TO THE PAVOLONIS-HEIDINGER ALGORITHM
958 
959 !=====================================
960 !=====================================
961 
962 
963 !=====================================
964  subroutine init_coeffs
965 !=====================================
966 
967 !-----------------------------------------------------------------------
968 ! !f90
969 !
970 ! !Description:
971 ! This subroutine initializes the coefficient arrays for the Pavolonis-Heidinger algorithm
972 !
973 ! !Input Parameters:
974 ! NONE
975 ! !Output Parameters:
976 ! NONE
977 !
978 ! !Revision History:
979 ! 2009/03/20 wind: Gala Wind
980 ! Revision 1.0 Initial Revision
981 !
982 ! !Team-Unique Header:
983 ! Developed by the Cloud Retrieval Group, NASA GSFC, Greenbelt, Maryland, USA.
984 !
985 ! !References and Credits:
986 ! Written by:
987 ! Gala Wind
988 ! SSAI
989 ! Code 613.2, NASA/GSFC
990 ! Greenbelt, MD 20771
991 ! Gala.Wind@nasa.gov
992 !
993 ! !Design Notes:
994 ! NONE
995 !
996 ! !END
997 !
998 !-----------------------------------------------------------------------
999  real*8, dimension(56) :: temp
1000 
1001 
1002  temp = (/0.70,0.70,0.70,0.70,0.75,0.80,0.80, &
1003  0.70,0.70,0.70,0.70,0.75,0.80,0.80,&
1004  0.70,0.70,0.70,0.70,0.75,0.80,0.80,&
1005  0.70,0.70,0.70,0.70,0.75,0.80,0.80,&
1006  0.70,0.70,0.70,0.70,0.75,0.80,0.80,&
1007  0.70,0.70,0.70,0.70,0.75,0.90,0.90,&
1008  0.75,0.75,0.75,0.80,0.80,0.90,0.90,&
1009  0.75,0.75,0.75,0.80,0.80,0.90,0.90 /)
1010 
1011  min_win_over = reshape(temp, (/ 7,8 /))
1012 
1013 
1014  temp = (/-5.09e+01,-3.83e+01,-4.20e+01,-5.52e+01,-4.80e+01,-3.16e+01,-3.16e+01 , &
1015  -5.09e+01,-3.83e+01,-4.20e+01,-5.52e+01,-4.80e+01,-3.16e+01,-3.16e+01 , &
1016  -6.02e+01,-4.36e+01,-4.01e+01,-4.14e+01,-4.67e+01,-6.36e+01,-6.36e+01 , &
1017  -4.67e+01,-5.81e+01,-4.20e+01,-3.79e+01,-3.25e+01,-4.11e+01,-4.11e+01 , &
1018  -6.25e+01,-5.49e+01,-5.42e+01,-4.99e+01,-5.63e+01,-7.13e+01,-7.13e+01 , &
1019  -7.72e+01,-6.02e+01,-6.28e+01,-5.13e+01,-4.70e+01,-3.22e+01,-3.22e+01 , &
1020  -1.00e+02,-1.12e+02,-8.96e+01,-7.65e+01,-7.04e+01,-8.40e+01,-8.40e+01 , &
1021  -2.85e+02,-2.52e+02,-1.49e+02,-1.82e+02,-1.28e+02,-5.21e+01,-5.21e+01 /)
1022 
1023  a_win_over = reshape(temp, (/ 7,8 /))
1024 
1025  temp = (/ 8.58e+01, 6.05e+01, 6.69e+01, 9.35e+01, 7.91e+01, 4.24e+01, 4.24e+01 , &
1026  8.58e+01, 6.05e+01, 6.69e+01, 9.35e+01, 7.91e+01, 4.24e+01, 4.24e+01 , &
1027  1.05e+02, 7.15e+01, 6.50e+01, 6.78e+01, 7.92e+01, 1.07e+02, 1.07e+02 , &
1028  7.88e+01, 1.03e+02, 7.16e+01, 6.47e+01, 5.46e+01, 6.82e+01, 6.82e+01 , &
1029  1.11e+02, 9.79e+01, 1.01e+02, 9.37e+01, 1.08e+02, 1.33e+02, 1.33e+02 , &
1030  1.41e+02, 1.08e+02, 1.20e+02, 1.03e+02, 9.63e+01, 7.01e+01, 7.01e+01 , &
1031  1.78e+02, 2.08e+02, 1.70e+02, 1.53e+02, 1.43e+02, 1.87e+02, 1.87e+02 , &
1032  5.08e+02, 4.55e+02, 2.75e+02, 3.69e+02, 2.66e+02, 1.40e+02, 1.40e+02 /)
1033 
1034 
1035  b_win_over = reshape(temp, (/ 7,8 /))
1036 
1037  temp = (/-4.12e+01,-2.41e+01,-2.77e+01,-4.57e+01,-3.60e+01,-8.56e+00,-8.56e+00 , &
1038  -4.12e+01,-2.41e+01,-2.77e+01,-4.57e+01,-3.60e+01,-8.56e+00,-8.56e+00 , &
1039  -5.47e+01,-3.20e+01,-2.77e+01,-2.96e+01,-3.80e+01,-5.29e+01,-5.29e+01 , &
1040  -3.76e+01,-5.51e+01,-3.41e+01,-3.01e+01,-2.40e+01,-3.02e+01,-3.02e+01 , &
1041  -6.08e+01,-5.30e+01,-5.77e+01,-5.38e+01,-6.41e+01,-7.67e+01,-7.67e+01 , &
1042  -8.14e+01,-5.96e+01,-7.29e+01,-6.59e+01,-6.21e+01,-4.88e+01,-4.88e+01 , &
1043  -1.02e+02,-1.27e+02,-1.06e+02,-1.00e+02,-9.37e+01,-1.38e+02,-1.38e+02 , &
1044  -3.09e+02,-2.80e+02,-1.69e+02,-2.56e+02,-1.86e+02,-1.23e+02,-1.23e+02 /)
1045 
1046  c_win_over = reshape(temp, (/ 7,8 /))
1047 
1048 
1049  temp = (/ 9.36e-01,-3.25e+00,-2.60e+00, 1.71e+00,-7.43e-01,-8.27e+00,-8.27e+00 , &
1050  9.36e-01,-3.25e+00,-2.60e+00, 1.71e+00,-7.43e-01,-8.27e+00,-8.27e+00 , &
1051  4.48e+00,-1.20e+00,-2.31e+00,-1.98e+00, 1.48e-01, 2.65e+00, 2.65e+00 , &
1052  3.65e-01, 4.94e+00,-2.40e-01,-1.20e+00,-2.60e+00,-2.09e+00,-2.09e+00 , &
1053  6.62e+00, 4.96e+00, 6.72e+00, 5.76e+00, 8.27e+00, 9.71e+00, 9.71e+00 , &
1054  1.21e+01, 6.67e+00, 1.12e+01, 1.05e+01, 9.62e+00, 7.24e+00, 7.24e+00 , &
1055  1.67e+01, 2.45e+01, 1.99e+01, 1.99e+01, 1.81e+01, 3.37e+01, 3.37e+01 , &
1056  6.92e+01, 6.26e+01, 3.53e+01, 6.57e+01, 4.58e+01, 3.56e+01, 3.56e+01 /)
1057 
1058  d_win_over = reshape(temp, (/ 7,8 /))
1059 
1060  temp = (/ 2.94e+00, 3.14e+00, 3.15e+00, 3.03e+00, 3.27e+00, 3.77e+00, 3.77e+00 , &
1061  2.94e+00, 3.14e+00, 3.15e+00, 3.03e+00, 3.27e+00, 3.77e+00, 3.77e+00 , &
1062  2.76e+00, 3.04e+00, 3.14e+00, 3.20e+00, 3.23e+00, 3.25e+00, 3.25e+00 , &
1063  2.95e+00, 2.75e+00, 3.03e+00, 3.15e+00, 3.34e+00, 3.48e+00, 3.48e+00 , &
1064  2.62e+00, 2.71e+00, 2.65e+00, 2.80e+00, 2.80e+00, 2.97e+00, 2.97e+00 , &
1065  2.26e+00, 2.59e+00, 2.33e+00, 2.43e+00, 2.62e+00, 3.01e+00, 3.01e+00 , &
1066  1.94e+00, 1.29e+00, 1.65e+00, 1.65e+00, 1.88e+00, 6.49e-01, 6.49e-01 , &
1067  -2.33e+00,-1.83e+00, 4.17e-01,-2.67e+00,-7.20e-01, 2.34e-01, 2.34e-01 /)
1068 
1069  e_win_over = reshape(temp, (/ 7,8 /))
1070 
1071 
1072 
1073 
1074 
1075  a_nir_over_water = (/ 1.98e+01,-3.83e+00,-1.41e+01,-1.49e+01,-3.62e+00, &
1076  -1.52e+01, 1.24e+01, 3.23e+00,-5.14e+00,-2.54e-01,&
1077  -1.42e+00,-4.17e+00, 4.11e+00, 9.23e+00, 6.03e+00, &
1078  3.11e+00, 3.11e+00, 3.11e+00 /)
1079 
1080  b_nir_over_water = (/-1.44e+01, 3.48e+00, 1.27e+01, 1.37e+01, 4.81e+00,&
1081  1.30e+01,-1.22e+01,-2.07e+00, 2.57e+00, 2.52e+00,&
1082  4.71e+00, 4.44e-01,-3.24e+00,-1.10e+01,-6.34e+00,&
1083  -3.65e+00,-3.65e+00,-3.65e+00 /)
1084 
1085  c_nir_over_water = (/ 2.64e+00,-1.87e+00,-4.24e+00,-4.98e+00,-3.13e+00,&
1086  -4.11e+00, 2.64e+00,-1.19e+00,-6.22e-01,-3.04e+00,&
1087  -4.57e+00, 1.19e+00,-6.76e-01, 3.30e+00, 7.73e-01,&
1088  9.53e-01, 9.53e-01, 9.53e-01 /)
1089 
1090  d_nir_over_water = (/ 8.73e-01, 1.18e+00, 1.45e+00, 1.43e+00, 1.36e+00,&
1091  1.18e+00, 6.15e-01, 1.09e+00, 6.95e-01, 1.26e+00,&
1092  1.74e+00,-1.17e-01, 9.93e-01, 2.53e-01, 9.02e-01,&
1093  2.00e-01, 2.00e-01, 2.00e-01 /)
1094 
1095  e_nir_over_water = (/ 5.34e-02, 4.15e-02, 3.46e-02, 2.77e-02, 3.93e-02,&
1096  6.08e-02, 7.28e-02, 5.06e-02, 7.56e-02, 3.34e-02,&
1097  1.97e-02, 1.92e-01, 5.29e-02, 1.07e-01, 7.66e-02,&
1098  3.03e-01, 3.03e-01, 3.03e-01 /)
1099 
1100 
1101 
1102  a_nir_over_land = (/ -1.94e+00, 9.09e-01, 2.51e+00,-1.01e+01, 1.01e+01, &
1103  -7.71e-01, 1.31e+00, 5.42e+00,-2.80e-01, 7.54e-01,&
1104  1.85e+00,-1.02e+01, 2.79e+00, 2.83e+00, 9.51e-01,&
1105  -3.39e+00,-3.39e+00,-3.39e+00 /)
1106 
1107  b_nir_over_land = (/ 2.55e+00,-9.93e-01,-2.95e+00, 7.17e+00,-9.65e+00, &
1108  -2.59e+00,-2.52e+00,-7.57e+00,-1.93e+00,-1.93e+00,&
1109  -2.33e+00, 7.87e+00,-3.29e+00,-3.75e+00,-5.92e-01,&
1110  4.13e+00, 4.13e+00, 4.13e+00 /)
1111 
1112  c_nir_over_land = (/ -1.24e+00, 1.82e-01, 1.15e+00,-5.48e-01, 3.33e+00, &
1113  3.19e+00, 1.93e+00, 3.63e+00, 2.45e+00, 1.87e+00, &
1114  1.33e+00,-6.52e-01, 1.53e+00, 1.79e+00,-3.28e-02, &
1115  -1.26e+00,-1.26e+00,-1.26e+00 /)
1116 
1117  d_nir_over_land = (/ 2.33e-01,-4.16e-03,-1.74e-01,-5.56e-01,-5.56e-01, &
1118  -1.13e+00,-7.03e-01,-7.78e-01,-1.01e+00,-7.98e-01, &
1119  -5.12e-01,-7.32e-01,-4.81e-01,-4.57e-01,-1.50e-02, &
1120  -1.05e-01,-1.05e-01,-1.05e-01 /)
1121 
1122  e_nir_over_land = (/ 3.16e-01, 3.17e-01, 3.34e-01, 3.27e-01, 3.29e-01, &
1123  3.43e-01, 3.12e-01, 3.19e-01, 3.46e-01, 3.25e-01, &
1124  3.14e-01, 3.98e-01, 3.17e-01, 3.22e-01, 3.08e-01, &
1125  4.77e-01, 4.77e-01, 4.77e-01 /)
1126 
1127 
1128  end subroutine init_coeffs
1129 
1130 !=====================================
1131  function poly4(a, b, c, d, e, x)
1132 !=====================================
1133 
1134 !-----------------------------------------------------------------------
1135 ! !f90
1136 !
1137 ! !Description:
1138 ! This function evaluates a 4th degree polynomial
1139 !
1140 ! !Input Parameters:
1141 ! real*8 -- a, b, c, d, e -- coefficients of the poly
1142 ! real -- x -- the abscissa to evaluate the poly at
1143 ! !Output Parameters:
1144 ! y = ax^4 + bx^3 + cx^2 + dx + e
1145 !
1146 ! !Revision History:
1147 ! 2009/03/20 wind: Gala Wind
1148 ! Revision 1.0 Initial Revision
1149 !
1150 ! !Team-Unique Header:
1151 ! Developed by the Cloud Retrieval Group, NASA GSFC, Greenbelt, Maryland, USA.
1152 !
1153 ! !References and Credits:
1154 ! Written by:
1155 ! Gala Wind
1156 ! SSAI
1157 ! Code 613.2, NASA/GSFC
1158 ! Greenbelt, MD 20771
1159 ! Gala.Wind@nasa.gov
1160 !
1161 ! !Design Notes:
1162 ! NONE
1163 !
1164 ! !END
1165 !
1166 !-----------------------------------------------------------------------
1167 
1168  real*8, intent(in) :: a, b, c, d, e
1169  real, intent(in) ::x
1170  real :: poly4
1171 
1172  poly4 = a*x**4 + b*x**3 + c*x**2 + d*x + e
1173 
1174  end function poly4
1175 
1176 
1177 !=====================================
1178 
1179  function ph_multilayer (sza, vza, rel_az, measurements, cloud_info, instrument, lat)
1180 
1181 !=====================================
1182 
1183 !-----------------------------------------------------------------------
1184 ! !f90
1185 !
1186 ! !Description:
1187 ! This function evaluates a 4th degree polynomial
1188 !
1189 ! !Input Parameters:
1190 ! real*4 -- sza -- solar zenith angle
1191 ! real*4 -- vza -- sensor zenith angle
1192 ! real*4 -- rel_az -- relative azimuth
1193 ! real*4, dimension(:) -- measurements -- array of reflectances and radiances for one pixel
1194 ! processflag -- cloud_info -- info about a pixel
1195 ! character(*) -- instrument -- name of the platform (Terra or Aqua)
1196 ! real*4 -- lat -- pixel latitude
1197 ! !Output Parameters:
1198 ! multilayer cloud result
1199 !
1200 ! !Revision History:
1201 ! 2009/03/20 wind: Gala Wind
1202 ! Revision 1.0 Initial Revision
1203 !
1204 ! !Team-Unique Header:
1205 ! Developed by the Cloud Retrieval Group, NASA GSFC, Greenbelt, Maryland, USA.
1206 !
1207 ! !References and Credits:
1208 ! Written by:
1209 ! Gala Wind
1210 ! SSAI
1211 ! Code 613.2, NASA/GSFC
1212 ! Greenbelt, MD 20771
1213 ! Gala.Wind@nasa.gov
1214 !
1215 ! !Design Notes:
1216 !
1217 ! Pavolonis, M.J. Heidinger A.K. "Daytime Cloud Overlap Detection from AVHRR and VIIRS"
1218 ! Journal of Applied Meteorology, 2004, Vol.43, pp. 762-778
1219 !
1220 ! the algorithm has been modified from the one described in this paper to include the
1221 ! improvements made to it since publication.
1222 !
1223 ! !END
1224 !
1225 !-----------------------------------------------------------------------
1226  use mod06_run_settings
1227  use specific_other
1228 
1229 
1230  real, intent(in) :: lat, sza, vza, rel_az
1231  real, dimension(:), intent(in) :: measurements
1232  type(processflag), intent(in) :: cloud_info
1233  character(len=*) :: instrument
1234 
1235  integer*1 :: ph_multilayer
1236 
1237 
1238  real :: r065, r040, r138, r163, i11, i12
1239  real :: dtor
1240  real :: bt11, bt12, btdiff, miu0, scata
1241  integer :: index1, index2, index3
1242  real :: win_over_thres, nir_overlap_thres, min_ref26_over
1243  real, parameter :: bad = 9999.
1244  logical :: over_avhrr, over_viirs
1245  real :: min_ref26_ocean_low, min_ref26_ocean_high, min_ref26_land_low, min_ref26_land_high
1246  real :: ref26_win_check_thres, snow_ref6_thres
1247  real :: ref26_win_check_thres_water, ref26_win_check_thres_land
1248 
1249  integer :: store1, store2, store3
1250 
1251  dtor = acos(-1.0)
1252  miu0 = cos(sza / 180. * dtor)
1253 
1254  scata = acos( miu0 * cos(vza / 180. *dtor) + &
1255  sin( sza / 180. *dtor) * sin(vza / 180. * dtor) * sin(rel_az / 180. *dtor)) * 180. / dtor
1256 
1257 
1258  r065 = measurements(band_0065)
1259  r040 = measurements(band_0410)
1260  r138 = measurements(band_0138)
1261  r163 = measurements(band_0163)
1262  i11 = measurements(band_1100)
1263  i12 = measurements(band_1200)
1264 
1265  bt11 = modis_bright(instrument, i11, channel_11um, 1)
1266  bt12 = modis_bright(instrument, i12, channel_12um, 1)
1267 
1268  call init_coeffs
1269 
1270  min_ref26_ocean_high = 0.1
1271  min_ref26_ocean_low = 0.025
1272  min_ref26_land_low = 0.027
1273  min_ref26_land_high = 0.1
1274 
1275  ref26_win_check_thres_water = 0.08
1276  ref26_win_check_thres_land = 0.12
1277 
1278  store1 = vza / 10
1279  store2 = sza / 10
1280  store3 = scata / 10
1281 
1282  index1 = min(nvza-1, max(0, store1 )) + 1
1283  index2 = min(nsza-1, max(0, store2 ) ) + 1
1284  index3 = min(nsct-1, max(0, store3 ) ) + 1
1285 
1286  ! This is how the BT11-BT12 threshold is defined. Don't ask me why.
1287  if (r065 >= 0.3 .and. r065 <= 0.6) then
1288  win_over_thres = max( poly4(a_win_over(index1, index2), b_win_over(index1, index2), &
1289  c_win_over(index1, index2), d_win_over(index1, index2), e_win_over(index1, index2), &
1290  r065), min_win_over(index1, index2)) - 0.25
1291  else if (r065 > 0.6 .and. r065 <= 1.0) then
1292  win_over_thres = min_win_over(index1, index2) - 0.25
1293  else
1294  win_over_thres = bad
1295  endif
1296 
1297 
1298  ! WARNING WARNING Pavolonis and Heidinger use the deep-blue band channel 8 to do additional testing
1299  ! over desert. That is not mentioned anywhere in their paper.
1300 
1301  call set_ph_desert(cloud_info%desert_surface, r040, win_over_thres)
1302 
1303 
1304  ! This is the 1.63um threshold definition
1305 
1306  if (r138 >= 0.4 .or. cloud_info%desert_surface) then
1307  nir_overlap_thres = bad
1308  ref26_win_check_thres = ref26_win_check_thres_land
1309  else
1310 
1311  if (cloud_info%ocean_surface) then
1312 
1313  nir_overlap_thres = poly4(a_nir_over_water(index3), b_nir_over_water(index3), &
1314  c_nir_over_water(index3), d_nir_over_water(index3), e_nir_over_water(index3), &
1315  r138) + 0.03
1316 
1317  ! Aqua correction also is not mentioned in the paper
1318  if (instrument == "Aqua") nir_overlap_thres = nir_overlap_thres - 0.09
1319 
1320  ref26_win_check_thres = ref26_win_check_thres_water
1321 
1322  else
1323 
1324  nir_overlap_thres = max(poly4(a_nir_over_land(index3), b_nir_over_land(index3), &
1325  c_nir_over_land(index3), d_nir_over_land(index3), e_nir_over_land(index3), r138), 0.25 ) + 0.05
1326 
1327  if (instrument == "Aqua") nir_overlap_thres = nir_overlap_thres - 0.09
1328 
1329  ref26_win_check_thres = ref26_win_check_thres_land
1330  endif
1331 
1332  endif
1333 
1334 
1335 
1336  ! THIS LOGIC IS NOT IN THE PAPER
1337 
1338  if (cloud_info%ocean_surface) then
1339  if (lat >= 50. .or. lat <= -50.) then
1340  min_ref26_over = min_ref26_ocean_high
1341  else
1342  min_ref26_over = min_ref26_ocean_low
1343  endif
1344  else if (cloud_info%desert_surface) then
1345  if (lat >= 50. .or. lat <= -50.) then
1346  min_ref26_over = min_ref26_land_high
1347  else
1348  min_ref26_over = min_ref26_land_low
1349  endif
1350  else
1351  if (lat >= 40. .or. lat <= -40.) then
1352  min_ref26_over = min_ref26_land_high
1353  else
1354  min_ref26_over = min_ref26_land_low
1355  endif
1356  endif
1357 
1358  if (lat >= 60. .or. lat <= -60) then
1359  snow_ref6_thres = 0.3
1360  else
1361  snow_ref6_thres = 0.1
1362  endif
1363 
1364  btdiff = bt11 - bt12
1365 
1366 
1367  ph_multilayer = 0
1368 
1369  if (r065 > 0.3 .and. r065 < 1.0 .and. btdiff > win_over_thres .and. bt11 < 270.) ph_multilayer = 1
1370 
1371  ! this is the NIR reflectance method
1372  if (r138 < ref26_win_check_thres) then
1373 
1374  if ( r138 > min_ref26_over .and. r163 > nir_overlap_thres .and. r163/r065 < 1.0 .and. &
1375  bt11 < 280.0 .and. btdiff > win_over_thres .and. bt11 > 220.) ph_multilayer = 1
1376 
1377  else
1378 
1379  if ( r138 > min_ref26_over .and. r163 > nir_overlap_thres .and. r163/r065 < 1.0 .and. &
1380  bt11 < 280.0 .and. bt11 > 220.) ph_multilayer = 1
1381 
1382  endif
1383 
1384  ! this is the IR split window technique
1385 
1386  if (btdiff > win_over_thres .and. bt11 < 270. .and. r163 > snow_ref6_thres .and. bt11 > 220.) &
1387  ph_multilayer = 1
1388 
1389 
1390 
1391 
1392  end function ph_multilayer
1393 
1394 
1395 
1396 
1397  end module multi_layer_clouds
1398 
1399 #endif
Definition: ch_xfr.f90:1
integer, parameter band_0124
integer, parameter band_0138
integer, parameter band_1200
real function, public linearinterpolation(X, Y, XX)
real(single), dimension(:,:), allocatable latitude
subroutine, public find_brightness_t(platform_name, PW, P, newT, TotalPrecipWater, p_ncep, t_ncep, mixR_ncep, surface, IIR_data, BigTransTable, miu, FIRST)
character *15 platform_name
#define real
Definition: DbAlgOcean.cpp:26
integer, parameter band_1100
integer, parameter band_0086
integer, parameter band_1350
integer, parameter single
real function, public modis_bright(platform_name, RAD, BAND, UNITS, cwn_array, tcs_array, tci_array)
#define max(A, B)
Definition: main_biosmap.c:61
subroutine set_ph_desert(surface, R040, thres)
real function, public modis_planck(platform_name, TEMP, BAND, UNITS)
logical function real_s_equal(x, y)
integer, parameter band_0163
real, dimension(:,:), allocatable precip_water_094
#define min(A, B)
Definition: main_biosmap.c:62
subroutine, public find_tpw(refl_86, refl_94, P, PW, BigTransTable, miu1, miu0, xpoint, ypoint)
integer, parameter band_0065
integer, parameter channel_11um
integer, parameter channel_12um
integer, parameter band_0935
void newt(float x[], int n, int *check, void(*vecfunc)(int, float[], float[]))
integer, parameter band_0410
logical function set_ice_ratio(ice_ratio)
subroutine, public compute_multilayer_map(platform_name, BigTransTable, measurements, cloud_phase, Baum_phase, p_ncep, mixR_ncep, t_ncep, surface, MOD06_Pc, MOD06_PW, sat_zen, sol_zen, rel_az, tau, tau1621, xpoint, ypoint, mlayer, mlayer_test)
#define abs(a)
Definition: misc.h:90
subroutine, public given_t_get_p(P, T, surface, p_ncep, t_ncep)
integer *1, dimension(:), allocatable c2_cmp_there
Definition: ch_xfr.f90:41