OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
cloud_phase.f90
Go to the documentation of this file.
1 module cloud_phase
2 
3  implicit none
4 
5 contains
6 
7 subroutine clouddecision(platform_name, &
8  cloudmask, &
9  measurements, &
10  RSSLiq, &
11  RSSIce, &
12  optical_thickness_liquid, &
13  optical_thickness_ice, &
14  effective_radius_16_liquid, &
15  effective_radius_21_liquid, &
16  effective_radius_37_liquid, &
17  effective_radius_16_ice, &
18  effective_radius_21_ice, &
19  effective_radius_37_ice, &
20  cloud_top_temperature_1km, &
21  cloud_mask_SPI, &
22  cloudHeightMethod, &
23  ir_phase, &
24  procflag_band_used_ot, &
25  cloudsummary, &
26  debug,status, i, j)
27 
28 
29  ! clouddecision will use cloud information values and the results
30  ! from the CER/COT derivation for both ice and water phase clouds to
31  ! decide the phase of the cloud at this pixel. Essentially, a score is
32  ! constructed from all the information: if > 0 the phase is water,
33  ! < 0 ice phase and = 0 unknown phase
34  !
35  ! WDR added the use of c2_cmp_there to avoid certain tests (ie, if 3.7 um
36  ! data is not in the measurement suite)
37  !
38  ! input argument is the full cloudmask and level 1B reflectances
39  ! output argument is the cloudsummary. This reports on the underlying
40  ! ecosystem and the cloud phase type
41 
44  use generalauxtype
45  use ch_xfr, only: c2_cmp_there
46 
47  implicit none
48 
49  character*(*), intent(in) :: platform_name
50  logical, intent(in) :: debug
51  type(cloudmask_type),intent(in) :: cloudmask
52  type(processflag) , intent(inout) :: cloudsummary
53  type(cloudphase), intent(in) :: ir_phase
54  real, intent(in) :: measurements(:), cloud_top_temperature_1km, cloud_mask_SPI
55  real, intent(in) :: RSSLiq(4), RSSIce(4)
56  integer, intent(out) :: status
57  integer, intent(in) :: i, j
58  integer*1, intent(in) :: procflag_band_used_ot,cloudHeightMethod
59 
60  real :: band_8_11_difference, xdimension, &
61  threshold_1, threshold_2, threshold_3, &
62  threshold_4, bright_temp_11, bright_temp_85, &
63  water_particle_threshold, ice_particle_threshold
64  logical :: decision_made
65 
66  integer :: modis_c6_phase
67  real :: Re_threshold_01(3), Re_threshold_02(3)
68  real :: Tab_Water_Cloud_Effective_Radius(3), Tab_Ice_Cloud_Effective_Radius(3)
69 
70  real :: optical_thickness_liquid, optical_thickness_ice
71  real :: effective_radius_16_liquid, effective_radius_21_liquid
72  real :: effective_radius_37_liquid, effective_radius_16_ice
73  real :: effective_radius_21_ice, effective_radius_37_ice
74 
75  logical :: ice_re_16_retrieval_failed, ice_re_21_retrieval_failed, ice_re_37_retrieval_failed
76  logical :: liq_re_16_retrieval_failed, liq_re_21_retrieval_failed, liq_re_37_retrieval_failed
77  logical :: Optical_Thickness_Ice_failed
78  logical :: band06_reflectance_measurement_failed
79 
80  logical :: ASL_16, ASL_21, ASL_37
81  real :: min_liq_re, max_ice_re
82 
83 
84  decision_made = .false.
85  status = 0
86 
87 
88  !initialize outputs, just to be sure
89  cloudsummary%cloudmask_determined = .true.
90  cloudsummary%cloudobserved = .false.
91  cloudsummary%watercloud = .false.
92  cloudsummary%icecloud = .false.
93  cloudsummary%unknowncloud = .false.
94 
95  !check if we have a cloud
96 
97 
98  if (.not. cloudmask%cloudmask_determined) then
99  cloudsummary%cloudmask_determined = .false.
100  decision_made = .true.
101  return
102  endif
103 
104  if (cloudmask%night == 1) then
105  decision_made = .true.
106  return
107  endif
108 
109 
110 
111 !---------- MODIS C6 cloud phase Decision ----------!
112 
113 
114  if (cloudmask%confident_cloudy .or. cloudmask%probablyclear_66 ) then
115 
116  cloudsummary%cloudobserved = .true.
117 
118  modis_c6_phase = 0
119 
120 !---------- Re thresholds (MODIS C6 cloud phase) ----------!
121 
122 
123  if ( cloud_mask_spi < 30.0 ) then
124 
125  re_threshold_01(1) = 30.0
126  re_threshold_02(1) = 20.0
127 
128  re_threshold_01(2) = 30.0
129  re_threshold_02(2) = 20.0
130 
131  re_threshold_01(3) = 25.0
132  re_threshold_02(3) = 15.0
133 
134  else
135 
136 
137  re_threshold_01(1) = 90.0
138  re_threshold_02(1) = 20.0
139 
140  re_threshold_01(2) = 90.0
141  re_threshold_02(2) = 20.0
142 
143  re_threshold_01(3) = 90.0
144  re_threshold_02(3) = 15.0
145  endif
146 
147 
148  min_liq_re = 4.0
149  max_ice_re = 60.0
150 
151 !--------------------------------------------------!
152 
153  tab_water_cloud_effective_radius(1) = effective_radius_16_liquid
154  tab_water_cloud_effective_radius(2) = effective_radius_21_liquid
155  tab_water_cloud_effective_radius(3) = effective_radius_37_liquid
156 
157  tab_ice_cloud_effective_radius(1) = effective_radius_16_ice
158  tab_ice_cloud_effective_radius(2) = effective_radius_21_ice
159  tab_ice_cloud_effective_radius(3) = effective_radius_37_ice
160 
161 !---------- Initialisation ----------!
162 
163  ice_re_16_retrieval_failed = .true.
164  ice_re_21_retrieval_failed = .true.
165  ice_re_37_retrieval_failed = .true.
166 
167  liq_re_16_retrieval_failed = .true.
168  liq_re_21_retrieval_failed = .true.
169  liq_re_37_retrieval_failed = .true.
170 
171  asl_16 = .false.
172  asl_21 = .false.
173  asl_37 = .false.
174 
175  optical_thickness_ice_failed = .true.
176 
177  band06_reflectance_measurement_failed = .true.
178 
179  if ( optical_thickness_ice > 0.0 ) optical_thickness_ice_failed = .false.
180 
181  if ( measurements(4) > 0.0 ) band06_reflectance_measurement_failed = .false.
182 
183  if ( rssliq(1) > 0.0 .and. rssice(1) > 0.0 ) asl_16 = .true.
184  if ( rssliq(2) > 0.0 .and. rssice(2) > 0.0 ) asl_21 = .true.
185  if ( ( c2_cmp_there(band_0370) == 1 ) .and. rssliq(3) > 0.0 .and. &
186  rssice(3) > 0.0 ) asl_37 = .true.
187 
188 
189  if ( rssice(1) < 0 ) then
190  if ( tab_ice_cloud_effective_radius(1) > 0.0 ) ice_re_16_retrieval_failed = .false.
191  end if
192 
193  if ( rssice(2) < 0 ) then
194  if ( tab_ice_cloud_effective_radius(2) > 0.0 ) ice_re_21_retrieval_failed = .false.
195  end if
196 
197  if ( rssice(3) < 0 ) then
198  if ( tab_ice_cloud_effective_radius(3) > 0.0 ) ice_re_37_retrieval_failed = .false.
199  end if
200 
201  if ( rssliq(1) < 0 ) then
202  if ( tab_water_cloud_effective_radius(1) > 0.0 ) liq_re_16_retrieval_failed = .false.
203  end if
204 
205  if ( rssliq(2) < 0 ) then
206  if ( tab_water_cloud_effective_radius(2) > 0.0 ) liq_re_21_retrieval_failed = .false.
207  end if
208 
209  if ( rssliq(3) < 0 ) then
210  if ( tab_water_cloud_effective_radius(3) > 0.0 ) liq_re_37_retrieval_failed = .false.
211  end if
212 
213 
214 !---------- Cloud_Phase_Infrared_1km (cloud phase test) ----------!
215 
216  if ( ir_phase%watercloud == 1 ) modis_c6_phase = modis_c6_phase + 1
217  if ( ir_phase%icecloud == 1) modis_c6_phase = modis_c6_phase - 1
218 
219 !---------- Re 1.6 (cloud phase test) ----------!
220 
221  if (procflag_band_used_ot == 3 .and. optical_thickness_liquid < 3.0d0 ) then
222 
223  if ( measurements(band_0163) > 0.0d0 .and. measurements(band_0124) > 0.0d0 ) then
224 
225  if ( measurements(band_0163)/measurements(band_0124) < 0.45 ) modis_c6_phase = modis_c6_phase - 1
226  if ( measurements(band_0163)/measurements(band_0124) > 0.70 ) modis_c6_phase = modis_c6_phase + 1
227 
228  end if
229 
230  else
231  if ( asl_16 ) then
232 
233  if ( tab_water_cloud_effective_radius(1) < min_liq_re + 0.01 ) modis_c6_phase = modis_c6_phase + 1
234  if ( tab_ice_cloud_effective_radius(1) > max_ice_re - 0.01 ) modis_c6_phase = modis_c6_phase - 1
235 
236  else
237 
238  if ( .not. ice_re_16_retrieval_failed .and. tab_ice_cloud_effective_radius(1) .gt. re_threshold_01(1) ) &
239  modis_c6_phase = modis_c6_phase - 1
240  if ( .not. ice_re_16_retrieval_failed .and. tab_ice_cloud_effective_radius(1) < re_threshold_02(1) ) &
241  modis_c6_phase = modis_c6_phase + 1
242  if ( ice_re_16_retrieval_failed .and. .not. liq_re_16_retrieval_failed ) modis_c6_phase = modis_c6_phase + 1
243 
244  end if
245  end if
246 
247 !---------- Re 2.1 (cloud phase test) ----------!
248 
249  if ( procflag_band_used_ot == 3 .and. optical_thickness_liquid < 3.0d0 ) then
250 
251  if( measurements(band_0213) > 0.0d0 .and. measurements(band_0124) > 0.0d0 )then
252 
253  if( measurements(band_0163) < 0.0d0 )then
254  if ( measurements(band_0213)/measurements(band_0124) < 0.20 ) modis_c6_phase = modis_c6_phase - 2
255  if ( measurements(band_0213)/measurements(band_0124) > 0.45 ) modis_c6_phase = modis_c6_phase + 2
256  else
257  if ( measurements(band_0213)/measurements(band_0124) < 0.20 ) modis_c6_phase = modis_c6_phase - 1
258  if ( measurements(band_0213)/measurements(band_0124) > 0.45 ) modis_c6_phase = modis_c6_phase + 1
259  end if
260 
261  end if
262 
263  else
264 
265  if ( asl_21 )then
266 
267  if ( band06_reflectance_measurement_failed ) then
268 
269  if ( tab_water_cloud_effective_radius(2) < min_liq_re + 0.01 ) modis_c6_phase = modis_c6_phase + 2
270  if ( tab_ice_cloud_effective_radius(2) > max_ice_re - 0.01 ) modis_c6_phase = modis_c6_phase - 2
271 
272  else
273 
274  if ( tab_water_cloud_effective_radius(2) < min_liq_re + 0.01 ) modis_c6_phase = modis_c6_phase + 1
275  if ( tab_ice_cloud_effective_radius(2) > max_ice_re - 0.01 ) modis_c6_phase = modis_c6_phase - 1
276 
277  end if
278 
279  else
280 
281  if ( .not. ice_re_21_retrieval_failed .and. tab_ice_cloud_effective_radius(2) > re_threshold_01(2) ) then
282  if ( band06_reflectance_measurement_failed ) modis_c6_phase = modis_c6_phase - 2 ! If no info from 1.6 increase the weight of 2.1 test
283  if ( .not. band06_reflectance_measurement_failed ) modis_c6_phase = modis_c6_phase - 1
284  end if
285 
286  if( .not. ice_re_21_retrieval_failed .and. tab_ice_cloud_effective_radius(2) < re_threshold_02(2) ) then
287  if ( band06_reflectance_measurement_failed ) modis_c6_phase = modis_c6_phase + 2
288  if ( .not. band06_reflectance_measurement_failed ) modis_c6_phase = modis_c6_phase + 1
289  end if
290 
291  if( ice_re_21_retrieval_failed .and. .not. liq_re_21_retrieval_failed ) then
292  if ( band06_reflectance_measurement_failed ) modis_c6_phase = modis_c6_phase + 2
293  if ( .not. band06_reflectance_measurement_failed ) modis_c6_phase = modis_c6_phase + 1
294  end if
295 
296  end if
297  end if
298 
299 !---------- Re 3.7 (cloud phase test) ----------!
300 
301  if (procflag_band_used_ot /= 3 .or. (procflag_band_used_ot == 3 .and. optical_thickness_liquid >= 3.0d0 )) then
302 
303  if ( asl_37 ) then
304 
305  if ( tab_water_cloud_effective_radius(3) < min_liq_re + 0.01 ) modis_c6_phase = modis_c6_phase + 1
306  if ( tab_ice_cloud_effective_radius(3) > max_ice_re - 0.01 ) modis_c6_phase = modis_c6_phase - 1
307  else
308 
309  if ( .not. ice_re_37_retrieval_failed .and. tab_ice_cloud_effective_radius(3) > re_threshold_01(3) ) &
310  modis_c6_phase = modis_c6_phase - 1
311  if ( .not. ice_re_37_retrieval_failed .and. tab_ice_cloud_effective_radius(3) < re_threshold_02(3) ) &
312  modis_c6_phase = modis_c6_phase + 1
313  if ( ice_re_37_retrieval_failed .and. .not. liq_re_37_retrieval_failed ) modis_c6_phase = modis_c6_phase + 1
314 
315  end if
316  end if
317 
318 !---------- CTT (cloud phase test) ----------!
319 
320  if ( cloud_top_temperature_1km < 240.0 ) then
321  if ( cloud_top_temperature_1km > 0.0 ) then
322  modis_c6_phase = modis_c6_phase - 1
323  end if
324  end if
325 
326  if ( optical_thickness_liquid > 2.0d0 ) then
327  if ( cloud_top_temperature_1km >= 270.0 ) then
328  modis_c6_phase = modis_c6_phase + 20
329  end if
330  if ( cloud_top_temperature_1km > 260.0 .and. cloud_top_temperature_1km < 270.0 ) then
331  modis_c6_phase = modis_c6_phase + 3
332  end if
333  else
334  if ( cloud_top_temperature_1km >= 270.0 ) then
335  modis_c6_phase = modis_c6_phase + 3
336  end if
337  if ( cloud_top_temperature_1km > 260.0 .and. cloud_top_temperature_1km < 270.0 ) then
338  modis_c6_phase = modis_c6_phase + 2
339  end if
340 
341  end if
342 
343 
344 !---------- 1.38 Test (cloud phase test) ----------!
345 
346  if ( .not. optical_thickness_ice_failed .and. optical_thickness_ice < 2.0 ) then
347  if ( cloudmask%test_high_138==1 .and. cloudmask%applied_highcloud138==1) modis_c6_phase = modis_c6_phase - 1
348  end if
349 
350 
351 ! Cold sanity check for undetermined and water cloud
352 
353  if (modis_c6_phase ==0 .or. modis_c6_phase == 1 .and. cloud_top_temperature_1km > 0.0) then
354 
355  if (optical_thickness_ice <= 40) then
356 
357  if (ir_phase%icecloud == 1 .and. cloud_top_temperature_1km < 240.0 .and. cloudheightmethod < 3) &
358  modis_c6_phase = modis_c6_phase - 20
359  else
360 
361  if (ir_phase%icecloud == 1 .or. (cloud_top_temperature_1km < 240.0 .and. cloudheightmethod < 3)) &
362  modis_c6_phase = modis_c6_phase - 20
363  endif
364 
365  endif
366 
367 !---------- MODIS C6 Cloud Phase Decision ----------!
368 
369  if ( modis_c6_phase > 0 ) cloudsummary%watercloud = .true.
370  if ( modis_c6_phase < 0 ) cloudsummary%icecloud = .true.
371  if ( modis_c6_phase == 0 ) cloudsummary%unknowncloud = .true.
372 
373 
374 
375 
376 
377 !---------- MODIS C6 Cloud Phase Decision Done ----------!
378 
379  end if
380 
381  decision_made = .true. ! appears to be vestigial variable.
382 
383  return
384 
385 
386 
387 
388 
389 end subroutine clouddecision
390 
391 
392 end module cloud_phase
Definition: ch_xfr.f90:1
integer, parameter band_0124
integer, parameter band_0370
integer, parameter band_0213
integer, parameter band_0163
subroutine clouddecision(platform_name, cloudmask, measurements, RSSLiq, RSSIce, optical_thickness_liquid, optical_thickness_ice, effective_radius_16_liquid, effective_radius_21_liquid, effective_radius_37_liquid, effective_radius_16_ice, effective_radius_21_ice, effective_radius_37_ice, cloud_top_temperature_1km, cloud_mask_SPI, cloudHeightMethod, ir_phase, procflag_band_used_ot, cloudsummary, debug, status, i, j)
Definition: cloud_phase.f90:27
integer *1, dimension(:), allocatable c2_cmp_there
Definition: ch_xfr.f90:41