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
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  if( ( c2_sensor_id == oci_id ) .OR. ( c2_sensor_id == ocis_id ) ) &
188  asl_37 = .false.
189 
190 
191  if ( rssice(1) < 0 ) then
192  if ( tab_ice_cloud_effective_radius(1) > 0.0 ) ice_re_16_retrieval_failed = .false.
193  end if
194 
195  if ( rssice(2) < 0 ) then
196  if ( tab_ice_cloud_effective_radius(2) > 0.0 ) ice_re_21_retrieval_failed = .false.
197  end if
198 
199  if ( rssice(3) < 0 ) then
200  if ( tab_ice_cloud_effective_radius(3) > 0.0 ) ice_re_37_retrieval_failed = .false.
201  end if
202 
203  if ( rssliq(1) < 0 ) then
204  if ( tab_water_cloud_effective_radius(1) > 0.0 ) liq_re_16_retrieval_failed = .false.
205  end if
206 
207  if ( rssliq(2) < 0 ) then
208  if ( tab_water_cloud_effective_radius(2) > 0.0 ) liq_re_21_retrieval_failed = .false.
209  end if
210 
211  if ( rssliq(3) < 0 ) then
212  if ( tab_water_cloud_effective_radius(3) > 0.0 ) liq_re_37_retrieval_failed = .false.
213  end if
214 
215 
216 !---------- Cloud_Phase_Infrared_1km (cloud phase test) ----------!
217 
218  if ( ir_phase%watercloud == 1 ) modis_c6_phase = modis_c6_phase + 1
219  if ( ir_phase%icecloud == 1) modis_c6_phase = modis_c6_phase - 1
220 
221 !---------- Re 1.6 (cloud phase test) ----------!
222 
223  if (procflag_band_used_ot == 3 .and. optical_thickness_liquid < 3.0d0 ) then
224 
225  if ( measurements(band_0163) > 0.0d0 .and. measurements(band_0124) > 0.0d0 ) then
226 
227  if ( measurements(band_0163)/measurements(band_0124) < 0.45 ) modis_c6_phase = modis_c6_phase - 1
228  if ( measurements(band_0163)/measurements(band_0124) > 0.70 ) modis_c6_phase = modis_c6_phase + 1
229 
230  end if
231 
232  else
233  if ( asl_16 ) then
234 
235  if ( tab_water_cloud_effective_radius(1) < min_liq_re + 0.01 ) modis_c6_phase = modis_c6_phase + 1
236  if ( tab_ice_cloud_effective_radius(1) > max_ice_re - 0.01 ) modis_c6_phase = modis_c6_phase - 1
237 
238  else
239 
240  if ( .not. ice_re_16_retrieval_failed .and. tab_ice_cloud_effective_radius(1) .gt. re_threshold_01(1) ) &
241  modis_c6_phase = modis_c6_phase - 1
242  if ( .not. ice_re_16_retrieval_failed .and. tab_ice_cloud_effective_radius(1) < re_threshold_02(1) ) &
243  modis_c6_phase = modis_c6_phase + 1
244  if ( ice_re_16_retrieval_failed .and. .not. liq_re_16_retrieval_failed ) modis_c6_phase = modis_c6_phase + 1
245 
246  end if
247  end if
248 
249 !---------- Re 2.1 (cloud phase test) ----------!
250 
251  if ( procflag_band_used_ot == 3 .and. optical_thickness_liquid < 3.0d0 ) then
252 
253  if( measurements(band_0213) > 0.0d0 .and. measurements(band_0124) > 0.0d0 )then
254 
255  if( measurements(band_0163) < 0.0d0 )then
256  if ( measurements(band_0213)/measurements(band_0124) < 0.20 ) modis_c6_phase = modis_c6_phase - 2
257  if ( measurements(band_0213)/measurements(band_0124) > 0.45 ) modis_c6_phase = modis_c6_phase + 2
258  else
259  if ( measurements(band_0213)/measurements(band_0124) < 0.20 ) modis_c6_phase = modis_c6_phase - 1
260  if ( measurements(band_0213)/measurements(band_0124) > 0.45 ) modis_c6_phase = modis_c6_phase + 1
261  end if
262 
263  end if
264 
265  else
266 
267  if ( asl_21 )then
268 
269  if ( band06_reflectance_measurement_failed ) then
270 
271  if ( tab_water_cloud_effective_radius(2) < min_liq_re + 0.01 ) modis_c6_phase = modis_c6_phase + 2
272  if ( tab_ice_cloud_effective_radius(2) > max_ice_re - 0.01 ) modis_c6_phase = modis_c6_phase - 2
273 
274  else
275 
276  if ( tab_water_cloud_effective_radius(2) < min_liq_re + 0.01 ) modis_c6_phase = modis_c6_phase + 1
277  if ( tab_ice_cloud_effective_radius(2) > max_ice_re - 0.01 ) modis_c6_phase = modis_c6_phase - 1
278 
279  end if
280 
281  else
282 
283  if ( .not. ice_re_21_retrieval_failed .and. tab_ice_cloud_effective_radius(2) > re_threshold_01(2) ) then
284  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
285  if ( .not. band06_reflectance_measurement_failed ) modis_c6_phase = modis_c6_phase - 1
286  end if
287 
288  if( .not. ice_re_21_retrieval_failed .and. tab_ice_cloud_effective_radius(2) < re_threshold_02(2) ) then
289  if ( band06_reflectance_measurement_failed ) modis_c6_phase = modis_c6_phase + 2
290  if ( .not. band06_reflectance_measurement_failed ) modis_c6_phase = modis_c6_phase + 1
291  end if
292 
293  if( ice_re_21_retrieval_failed .and. .not. liq_re_21_retrieval_failed ) then
294  if ( band06_reflectance_measurement_failed ) modis_c6_phase = modis_c6_phase + 2
295  if ( .not. band06_reflectance_measurement_failed ) modis_c6_phase = modis_c6_phase + 1
296  end if
297 
298  end if
299  end if
300 
301 !---------- Re 3.7 (cloud phase test) ----------!
302 
303  if (procflag_band_used_ot /= 3 .or. (procflag_band_used_ot == 3 .and. optical_thickness_liquid >= 3.0d0 )) then
304 
305  if ( asl_37 ) then
306 
307  if ( tab_water_cloud_effective_radius(3) < min_liq_re + 0.01 ) modis_c6_phase = modis_c6_phase + 1
308  if ( tab_ice_cloud_effective_radius(3) > max_ice_re - 0.01 ) modis_c6_phase = modis_c6_phase - 1
309  else
310 
311  if ( .not. ice_re_37_retrieval_failed .and. tab_ice_cloud_effective_radius(3) > re_threshold_01(3) ) &
312  modis_c6_phase = modis_c6_phase - 1
313  if ( .not. ice_re_37_retrieval_failed .and. tab_ice_cloud_effective_radius(3) < re_threshold_02(3) ) &
314  modis_c6_phase = modis_c6_phase + 1
315  if ( ice_re_37_retrieval_failed .and. .not. liq_re_37_retrieval_failed ) modis_c6_phase = modis_c6_phase + 1
316 
317  end if
318  end if
319 
320 !---------- CTT (cloud phase test) ----------!
321 
322  if ( cloud_top_temperature_1km < 240.0 ) then
323  if ( cloud_top_temperature_1km > 0.0 ) then
324  modis_c6_phase = modis_c6_phase - 1
325  end if
326  end if
327 
328  if ( optical_thickness_liquid > 2.0d0 ) then
329  if ( cloud_top_temperature_1km >= 270.0 ) then
330  modis_c6_phase = modis_c6_phase + 20
331  end if
332  if ( cloud_top_temperature_1km > 260.0 .and. cloud_top_temperature_1km < 270.0 ) then
333  modis_c6_phase = modis_c6_phase + 3
334  end if
335  else
336  if ( cloud_top_temperature_1km >= 270.0 ) then
337  modis_c6_phase = modis_c6_phase + 3
338  end if
339  if ( cloud_top_temperature_1km > 260.0 .and. cloud_top_temperature_1km < 270.0 ) then
340  modis_c6_phase = modis_c6_phase + 2
341  end if
342 
343  end if
344 
345 
346 !---------- 1.38 Test (cloud phase test) ----------!
347 
348  if ( .not. optical_thickness_ice_failed .and. optical_thickness_ice < 2.0 ) then
349  if ( cloudmask%test_high_138==1 .and. cloudmask%applied_highcloud138==1) modis_c6_phase = modis_c6_phase - 1
350  end if
351 
352 
353 ! Cold sanity check for undetermined and water cloud
354 
355  if (modis_c6_phase ==0 .or. modis_c6_phase == 1 .and. cloud_top_temperature_1km > 0.0) then
356 
357  if (optical_thickness_ice <= 40) then
358 
359  if (ir_phase%icecloud == 1 .and. cloud_top_temperature_1km < 240.0 .and. cloudheightmethod < 3) &
360  modis_c6_phase = modis_c6_phase - 20
361  else
362 
363  if (ir_phase%icecloud == 1 .or. (cloud_top_temperature_1km < 240.0 .and. cloudheightmethod < 3)) &
364  modis_c6_phase = modis_c6_phase - 20
365  endif
366 
367  endif
368 
369 !---------- MODIS C6 Cloud Phase Decision ----------!
370 
371  if ( modis_c6_phase > 0 ) cloudsummary%watercloud = .true.
372  if ( modis_c6_phase < 0 ) cloudsummary%icecloud = .true.
373  if ( modis_c6_phase == 0 ) cloudsummary%unknowncloud = .true.
374 
375 
376 
377 
378 
379 !---------- MODIS C6 Cloud Phase Decision Done ----------!
380 
381  end if
382 
383  decision_made = .true. ! appears to be vestigial variable.
384 
385  return
386 
387 
388 
389 
390 
391 end subroutine clouddecision
392 
393 
394 end module cloud_phase
Definition: ch_xfr.f90:1
integer, parameter band_0124
integer ocis_id
Definition: ch_xfr.f90:51
integer, parameter band_0370
integer, parameter band_0213
integer, parameter band_0163
integer c2_sensor_id
Definition: ch_xfr.f90:50
integer oci_id
Definition: ch_xfr.f90:52
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:43