NASA Logo
Ocean Color Science Software

ocssw V2022
retrieval_solution_logic.f90
Go to the documentation of this file.
2 
3  implicit none
4 
5  integer, parameter :: top_nk_asl_contour_ice = 1, &
7 
8 contains
9 
10  ! ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
11 subroutine find_zero_crossings (residual, crossing_vector, crossing_num)
12  ! ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
13 
14  ! *** S. Platnick, 17-Oct-2005
15  ! *** G. Wind 20-Oct-2005 -- removed the dynamic memory
16  ! allocation to speed things up a bit
17  !
18  ! residual
19  ! crossing_vector
20  ! crossing_num
21  !
22  implicit none
23 
24  REAL, intent(in) :: residual(:)
25  INTEGER, intent(out) :: crossing_num, crossing_vector(:)
26 
27  ! local variables
28  ! INTEGER, allocatable, dimension(:) :: k
29  integer :: k(18)
30 
31  INTEGER :: i,length
32 
33  length = size(residual)
34  ! allocate (k(length))
35 
36  ! G.Wind 12.19.05: Replaced the where statement below with a do loop. This
37  ! eliminates ambiguities arising from the use of nonconformable arrays.
38  k = 1
39  ! where(residual<0) k=-1
40 
41  do i=1, length
42  if ( residual(i) < 0 ) k(i) = -1
43  end do
44  ! crossing index in vector is defined for the smaller index
45  ! between which the zero lies
46  crossing_num=0; crossing_vector=0.
47  Do i=1,length-1
48  if( abs(k(i+1)-k(i)) > 1) then!{
49  crossing_num = crossing_num + 1
50  crossing_vector(crossing_num) = i
51  end if
52  End do
53 
54  ! deallocate (k)
55 
56 end subroutine find_zero_crossings
57 
58 
59  ! ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
60 subroutine find_local_minima (residual, local_min_vector, local_min_num)
61  ! ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
62 
63  ! *** S. Platnick, 17-Oct-2005
64  ! This give the local minima for the absolute residual, not the residual**2.
65  ! 10-18-05: modify so that minima at end points are not
66  ! considered local minima
67  ! to the extent that they do not indicate a change in curvature.
68  ! residual
69  ! local_min_vector
70  ! local_min_num
71 
72  implicit none
73 
74  REAL, intent(in) :: residual(:)
75  INTEGER, intent(out) :: local_min_num, local_min_vector(:)
76 
77  ! local variables
78  INTEGER i,length
79 
80  length = size(residual)
81 
82  local_min_num=0; local_min_vector=0.
83 
84  if (length > 2) then!{
85  Do i=2,length-1
86  if( residual(i) < residual(i-1) .AND. residual(i) < residual(i+1) ) then!{
87  local_min_num = local_min_num + 1
88  local_min_vector(local_min_num) = i
89  end if
90  End do
91  end if
92 
93 end subroutine find_local_minima
94 
95  ! ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
96 subroutine find_local_maxima (residual, local_max_vector, local_max_num)
97  ! ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
98 
99  ! *** S. Platnick, 17-Oct-2005
100  ! This give the local maxima for the absolute residual, not the residual**2.
101  ! 10-18-05: modify so that minima at end points are not
102  ! considered local maxima
103  ! to the extent that they do not indicate a change in curvature.
104  !
105  ! residual
106  ! local_max_vector
107  ! local_max_num
108  !
109  implicit none
110 
111  REAL, intent(in) :: residual(:)
112  INTEGER, intent(out) :: local_max_num, local_max_vector(:)
113 
114  ! local variables
115  INTEGER i,length
116 
117  length = size(residual)
118 
119  local_max_num=0; local_max_vector=0.
120 
121  if (length > 2) then!{
122  Do i=2,length-1
123  if( residual(i) > residual(i-1) .AND. residual(i) > residual(i+1) ) then!{
124  local_max_num = local_max_num + 1
125  local_max_vector(local_max_num) = i
126  end if
127  End do
128  end if
129 
130 end subroutine find_local_maxima
131 
132  ! sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
133 subroutine solution_re (re, residual, crossing_vector, crossing_num, &
134  local_min_vector, local_min_num, local_max_vector, local_max_num, &
135  retrieval, quality )
136  ! sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
137 
138  use science_parameters
139 
140  ! *** S. Platnick, 17-Oct-2005
141  ! Using input from sep routines 'find_zero_crossings',
142  ! 'find_local_minima', and 'find_local_maxima'
143  !
144  ! *** S. Platnick, 7-March-2006
145  !
146  ! Modification of collection 5 solution logic:
147  ! 1. process_zero_crossing_residual = .FALSE., i.e., re for
148  ! pixels with no zero crossings are set to fill
149  ! 2. solve_for_zero_crossing modified to use spline interpolation
150  ! and iterative root finder
151  ! 3. No longer need 'find_local_minima' and 'find_local_maxima'
152  ! routines, though left intact for now since
153  ! they provide useful information that might still be needed sometime.
154  ! 4. No retrieval when crossing_num > 2
155 
156  implicit none
157 
158  integer, intent(in) :: crossing_vector(:), crossing_num, &
159  local_min_vector(:), local_min_num, local_max_vector(:), local_max_num
160  real, intent(in) :: residual(:), re(:)
161 
162  real, intent(out) :: retrieval
163  integer*1, intent(out) :: quality
164 
165  integer :: residual_crossing_index, index1(1)
166  real :: fillval_r4, resid_lo, resid_hi, slope_1, slope_2
167  logical :: process_zero_crossing_residual
168 
169 
170  fillval_r4 = invalid_attempted_but_failed_re; residual_crossing_index = 0
171 
172  ! ===================================
173  ! SOLUTION LOGIC QUALITY ASSIGNMENTS:
174  ! ===================================
175  ! Can be used for diagnostic purposes and setting retrieval
176  ! confidence QA in core science (not presently being
177  ! done as of this writing)
178  !
179  ! quality = -6 => spline interpolation, iteration /< iternum-5
180  ! quality = -5 => crossing_num < 0 (should never occur, but
181  ! included for completeness)
182  ! quality = -4 => crossing_num = 0 and process_zero_crossing_residual
183  ! =.FALSE.
184  ! quality = -3 => crossing_num = 0 and process_zero_crossing_residual
185  ! =.TRUE.
186  ! quality = -2 => crossing_num > 2
187  ! quality = -1 => DEFAULT: this quality index should never occur,
188  ! and if it does something went awry
189  ! quality = 0 => occur for truncated residual vector having fill value(s)
190  ! quality = 1 => linear interpolation w/maxval(abs(residual)) >
191  ! resid_max_for_spline
192  ! quality = 2 => linear interpolation when the root lies in the
193  ! last interval of the residual vector
194  ! quality = 3 => spline interpolation (or no interpolation),
195  ! and iteration < iternum-5
196  !
197  ! If ever used in MOD06 for assigning confidence QA then possible
198  ! negative assignments are:
199  ! -6->3 or 2; -5->0; -4->0; -3->1 or 0;
200  ! -2->1 or 0 depending on solution logic
201 
202  ! --------------------------------------------------------------
203  ! .TRUE. corresponds to the logic that had apparently been in
204  ! place since the beginning of the c5 deliveries
205  ! 2 March 06: Changed to .FALSE., i.e., for a non-zero crossing
206  ! residual, return a fill value. Do not return with
207  ! the library radius corresponding to smallest residual as the solution.
208  ! -------------------------------------------------------------
209 
210  process_zero_crossing_residual = .false.
211 
212  ! -------------------------
213  ! Default retrieval output:
214  ! -------------------------
215  retrieval = fillval_r4; quality = -1
216 
217  ! ------------------------------------------
218  ! Check for a proper value for crossing_num:
219  ! ------------------------------------------
220 
221  if (crossing_num < 0) then
222  quality = -5
223  return
224  end if
225  ! ---------------------------------------------------------------------------
226  ! If there are more than 2 roots for the residual vector return a fill value:
227  ! ---------------------------------------------------------------------------
228 
229  if (crossing_num > 2) then
230  quality = -2
231  return
232  end if
233 
234  ! -----------------------------------------------------------------
235  ! The calling routine in C5 truncates the residual array to get
236  ! rid of contiguous fill values starting with the largest radii, and
237  ! then passes the useful max radii to the re solution routines.
238  ! However, the calling routine does not look for remaining fill values
239  ! that are elsewhere in the residual vector but with non-fill
240  ! neighbors. If such a residual vector remains, then return with a
241  ! fill value for effective radius.
242  !
243  ! However, I can't determine if resdiual vector is initialized
244  ! to fillvalue_real !?
245  !
246  ! ----------------------------------------------------------------
247 
248  ! if (min(residual) == fillvalue_real) then
249  ! quality = 0
250  ! return
251  ! end if
252 
253  ! ------------------------------------------------------------------------
254  ! If there are NO roots for the residual vector (i.e., no zero crossings):
255  ! ------------------------------------------------------------------------
256  IF (crossing_num == 0) THEN
257  if (process_zero_crossing_residual) then
258 
259  index1 = minloc(abs(residual))
260  retrieval = re(index1(1))
261  quality = -3
262  else
263  quality = -4
264  end if
265  return
266  END IF
267 
268  ! --------------------------------------------------
269  ! If there are 1 or 2 roots for the residual vector:
270  ! --------------------------------------------------
271 
272  IF (crossing_num == 1 .OR. crossing_num == 2) THEN
273 
274  ! If there are 2 zero crossings for the residual vector
275  ! then choose the crossing having the negative slope
276  ! regardless of the cloud phase. A derivative of residual
277  ! w.r.t. re < 0 corresponds to the physical situation
278  ! where single scattering albedo decreases with re (and no
279  ! significant change in effective radius or extinction).
280 
281  If (crossing_num == 1) Then
282  residual_crossing_index = crossing_vector(crossing_num)
283 
284  Else
285  slope_1 = residual(crossing_vector(1)+1) - residual(crossing_vector(1))
286  slope_2 = residual(crossing_vector(2)+1) - residual(crossing_vector(2))
287  ! resid_lo = 0.5 * ( residual(crossing_vector(1)) + &
288  ! residual(crossing_vector(1) + 1) )
289  ! resid_hi = 0.5 * ( residual(crossing_vector(2)) + &
290  ! residual(crossing_vector(2) + 1) )
291 
292  ! For crossing_num =2, both slopes can't be of the same sign.
293  ! If they are something's not correct, but choose larger residual.
294  if ( slope_1 <= 0. ) then
295  residual_crossing_index = crossing_vector(1)
296  end if
297  if ( slope_2 <= 0. ) then
298  residual_crossing_index = crossing_vector(2)
299  end if
300 
301 
302  End If
303 
304  ! it could potentially happen that slopes are > 0, then this
305  ! would be a segfault because residual_crossing_index
306  ! defaults to 0. --- G.Wind 12.15.11
307  if (residual_crossing_index > 0) &
308  call solve_for_zero_crossing (re, residual, residual_crossing_index, &
309  fillval_r4, local_min_vector, local_min_num, local_max_vector, &
310  local_max_num, retrieval, quality)
311  END IF
312 
313 end subroutine solution_re
314 
315  ! sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
316 subroutine solve_for_zero_crossing (re, residual, &
317  residual_crossing_index, fillval_r4, &
318  local_min_vector, local_min_num, local_max_vector, local_max_num, &
319  retrieval, quality)
320  ! ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
321 
322  use generalauxtype
323  use spline_module
324 
325  ! *** S. Platnick, 7-March-2006
326  !
327  ! Modification of collection 5 solution logic:
328  !
329  ! 1. Use natural spline interpolation instead of quadratic(s) fits.
330  ! The piece-wise quadratic approach was producing discontinuities
331  ! in the re histograms. Epecially for ice clouds where
332  ! the residual vector often has changes in curvature which exacerbates
333  ! the piece-wise approach. The advantage of the
334  ! quadratic fits is that they are analytic and computationally
335  ! fast; the spline fit must use an iterative procedure for
336  ! for finding the root of the residual vector.
337  !
338  ! 2. Also, see comments in solution_re routine.
339 
340  implicit none
341 
342  real, intent (in) :: re(:), residual(:), fillval_r4
343  integer, intent (in) :: residual_crossing_index, &
344  local_min_vector(:), local_min_num, local_max_vector(:), local_max_num
345 
346  real, intent(inout) :: retrieval
347  integer*1, intent(inout) :: quality
348 
349  integer i, icount, iternum
350  real y2(size(re)), z, delta_resid, delta_resid_fraction, &
351  resid_min_allowable, resid_max_for_spline
352  real yl(2), xl(2), re_lower, re_upper, re_iter
353 
354  character*15 numerical_type
355 
356  retrieval=fillval_r4
357 
358  ! -------------------------------------------------------------
359  ! If the root is close enough to a library re, don't bother
360  ! interpolating for the solution
361  ! (also, spline bisection search was found to fail for a residual
362  ! index of zero which did occur for test granules)
363  ! --------------------------------------------------------------
364 
365  resid_min_allowable = 0.0001
366  if (abs(residual(residual_crossing_index)) < resid_min_allowable) then
367  retrieval = re(residual_crossing_index)
368  quality = 3
369  return
370  end if
371  if (abs(residual(residual_crossing_index+1)) < resid_min_allowable) then
372  retrieval = re(residual_crossing_index+1)
373  quality = 3
374  return
375  end if
376 
377  ! -----------------------------------------------------------------
378  ! If bounding library points are so near to one another as to be
379  ! representationally equal, no need to interpolate
380  ! ----------------------------------------------------------------
381 
382  if (real_s_equal(residual(residual_crossing_index), &
383  residual(residual_crossing_index+1))) then
384  retrieval = re(residual_crossing_index)
385  quality = 3
386  return
387  end if
388 
389  ! -----------------------------------------------------------------
390  ! Use either a linear or spline interpolation to determine the
391  ! residual vector root:
392  ! ------------------------------------------------------------------
393  numerical_type = 'spline'
394 
395  ! The following 2 Do Loops set linear interpolation for residual
396  ! roots near a local minimum or maximum. Commented out
397  ! to use spline interpolation in these instances. Use of linear
398  ! interpoltion gave some re histogram discontinuities in
399  ! test granules, at least for ice clouds where local min and max
400  ! seemed to occur more often.
401 
402  ! Do i=1,local_max_num
403  ! if (residual_crossing_index == local_max_vector(i) .OR. &
404  ! residual_crossing_index+1 == local_max_vector(i)) then
405  ! numerical_type = 'linear'
406  ! exit
407  ! end if
408  ! End do
409  ! IF (numerical_type /= 'linear') THEN
410  ! Do i=1,local_min_num
411  ! if (residual_crossing_index == local_min_vector(i) .OR. &
412  ! residual_crossing_index+1 == local_min_vector(i)) then
413  ! numerical_type = 'linear'
414  ! exit
415  ! end if
416  ! End do
417  ! End If
418 
419 
420  ! Use linear interpolation if the root is before end of re vector.
421  ! Especially for ice clouds, the spline appears to give undue
422  ! curvature to fit the large distance from 60 to 90 microns. For
423  ! water clouds, the accuracy in establishing the root between
424  ! 28 and 30 microns isn't relevant. Use of this logic did not
425  ! appear to cause any undue features in the re histogram.
426 
427  ! The following innocuous check on 'linear' remains for historical
428  ! reasons in case the block immediately above ever gains favor
429  IF (numerical_type /= 'linear') THEN
430  if (residual_crossing_index == size(re)-1) then
431  numerical_type = 'linear'
432  quality = 2
433  end if
434  End If
435 
436  ! Use linear interpolation if there are large discontinuities in
437  ! the residual which would give rise to spline oscillations
438  !
439  ! Example print output for 3.7 um residual, MYD Katrina granule:
440  ! iterational doesn't converge because the spline does not provide
441  ! a root between 30 and 35 um points due to large oscillation set
442  ! up by large residual at larger radii.
443  !
444  ! *** number of spline iterations: icount = 30 residual_crossing_index= 6
445  ! re: 5.0 10.0 15.0 20.0 25.0 30.0 35.0
446  ! 40.0 45.0 50.0 55.0 60.0 90.0
447  ! residual: 3.9147 2.1260 0.6555 0.0979 -0.0182 -0.0686 0.0729
448  ! 0.4781 2.1382 10000.0 383.20 10000.0 10000.0
449 
450  resid_max_for_spline = 100.
451  IF (numerical_type /= 'linear') THEN
452  if ( maxval(abs(residual)) > resid_max_for_spline) then
453  numerical_type = 'linear'
454  quality = 1
455  end if
456  End If
457 
458  ! ------------------------------------------------------------------
459  ! Implement interpolation scheme and solve for residual vector root:
460  ! ------------------------------------------------------------------
461 
462  IF (numerical_type == 'linear') THEN
463  yl(1) = residual(residual_crossing_index); yl(2) = &
464  residual(residual_crossing_index+1)
465  if (sign(1.,yl(1))*sign(1.,yl(2)) <= 0.) then
466  call linear_interpolate_for_root (yl, &
467  re(residual_crossing_index:residual_crossing_index+1), retrieval)
468  end if
469  END IF
470 
471  IF (numerical_type == 'spline') THEN
472  call spline (size(re), re, residual, y2)
473 
474  iternum = 30; icount = 1; delta_resid_fraction=0.001
475 
476  delta_resid = abs( delta_resid_fraction * &
477  max(residual(residual_crossing_index), &
478  residual(residual_crossing_index+1)) )
479  if(delta_resid < resid_min_allowable) delta_resid = resid_min_allowable
480  re_lower = re(residual_crossing_index)
481  re_upper = re(residual_crossing_index+1)
482  re_iter = 0.5*(re_lower + re_upper)
483 
484  ! The interpolation finds the y (residual) for the input x (re), so
485  ! they iterate till the y they find is close to 0. Now, if the
486  ! relation is reversed, and y is re and x is residual, you could do
487  ! the spline 1 time for x = 0. All the min, max points could be used to
488  ! isolate the correct segment so a function wuld be analyzed.`
489  DO WHILE (icount < iternum)
490  z= splint(size(re), re_iter, re, residual, y2)
491 
492  if(abs(z) < delta_resid) then
493  retrieval = re_iter
494  exit
495  end if
496 
497  if(sign(1.,z)*sign(1.,residual(residual_crossing_index)) > 0.) then
498  re_lower = re_iter
499  else
500  re_upper = re_iter
501  end if
502  re_iter = 0.5*(re_lower + re_upper)
503  icount = icount + 1
504  END DO
505 
506  ! If consistently near the max iteration number, it is possible a
507  ! higher max iteration number might be more suitable.
508  if(icount < iternum-5) then
509  quality = 3
510  else
511  quality = -6
512  end if
513 
514  END IF
515 
516 end subroutine solve_for_zero_crossing
517 
518 
519  logical function is_water_phase(library_radii)
520 
521  use libraryarrays
522 
523  real(single), intent(in) :: library_radii(:)
524 
525  ! if it's not ice phase, it's water
526  is_water_phase = (size(library_radii) .ne. size(ice_radii))
527 
528  ! NOTE: if at some point ice & water libs have equal sizes,
529  ! this needs reconsideration
530 
531  end function is_water_phase
532 
533 subroutine ray_corr_nearest(refl_source, As, iw, tau, re, Pc, &
534  sfr, fti1, fti0, fluxup_solar, fluxup_sensor, &
535  theta, theta0, phi, location, crefl)
536  ! don't know what this does specifically
537  ! refl_source
538  ! As
539  ! iw
540  ! tau
541  ! re
542  ! Pc
543  ! sfr
544  ! fti1
545  ! fti0
546  ! fluxup_solar
547  ! fluxup_sensor
548  ! theta
549  ! theta0
550  ! phi
551  ! location I radius location
552  ! crefl O returned reflectance?
553 
555  use libraryarrays
558 
559  real, intent(in) :: tau, re, Pc, sfr, fti1, fti0, theta, theta0, phi, &
560  As, refl_source
561  integer, dimension(2), intent(in) :: location
562  integer, intent(in) :: iw
563  real, dimension(:,:,:,:), intent(in) :: fluxup_solar, fluxup_sensor
564  real, intent(inout) :: crefl
565 
566  real, parameter :: Ps = 1013.
567  real, parameter :: Cm = 0.84
568  real, parameter :: taur0(2) = (/0.044, 0.025/)
569 
570  real :: taur, mu0, mu, x, pray, refl_s
571  real :: fti1_as, fti0_as
572  real :: angles(2), functionvalues(2)
573  real :: fluxup_solar_tau, fluxup_sensor_tau
574  integer :: lowbound, highbound
575 
576  lowbound = 0 ! WDR-UIV
577  highbound = 0 ! WDR-UIV
578 
579  taur = taur0(iw) * pc / ps
580  mu0 = cos(d2r*theta0)
581  mu = cos(d2r*theta)
582 
583  x = -mu0*mu + sqrt((1.-mu0**2)*(1.-mu**2))*cos(d2r*phi)
584  pray = 3.*(1.+x**2)/4.0
585 
586  !
587  ! Interpolation for solar zenith angles and scaled optical thickness
588  !
589  call bisectionsearch(library_fluxsolarzenith, mu0, lowbound, highbound)
590  angles(1) = library_fluxsolarzenith(lowbound)
591  angles(2) = library_fluxsolarzenith(highbound)
592 
593  if (location(1) == 1) then
594  functionvalues = 0.
595  else
596  functionvalues(1) = fluxup_solar(lowbound,location(1)-1,1,location(2))
597  functionvalues(2) = fluxup_solar(highbound,location(1)-1,1,location(2))
598  endif
599 
600  fluxup_solar_tau = linearinterpolation(angles,functionvalues,mu0)
601 
602  !
603  ! Interpolation for sensor zenith angles and scaled optical thickness
604  !
605  call bisectionsearch(library_fluxsensorzenith, mu, lowbound, highbound)
606  angles(1) = library_fluxsensorzenith(lowbound)
607  angles(2) = library_fluxsensorzenith(highbound)
608 
609  if (location(1) == 1) then
610  functionvalues = 0.
611  else
612  functionvalues(1) = fluxup_sensor(lowbound,location(1)-1,1,location(2))
613  functionvalues(2) = fluxup_sensor(lowbound,location(1)-1,1,location(2))
614  endif
615  fluxup_sensor_tau = linearinterpolation(angles,functionvalues,mu)
616 
617  fti1_as = fluxup_sensor_tau
618  fti0_as = fluxup_solar_tau
619 
620  if (as > 0.) then
621  fti0_as = fti0_as + fti0*as*(1-sfr)/(1 - sfr*as)
622  fti1_as = fti1_as + fti1*as*(1-sfr)/(1 - sfr*as)
623  endif
624 
625  refl_s = taur*pray/(4.*mu0*mu) + 0.5*taur* fti1_as * exp(-taur/mu )/mu0 + &
626  0.5*taur* fti0_as * exp(-taur/mu0)/mu
627  crefl = (refl_source - refl_s)*exp(cm*taur*(1./mu0 + 1./mu))
628 
629 end subroutine ray_corr_nearest
630 
631 subroutine solveretrieval_nearest(xx_pt,yy_pt,Ram, Rbm, twobands, &
632  radii, tau, re, lib_dist, phase_liquid, Ram_corr,quality_in,CH37_IDX, &
633  CTopT,CH37_NUM, platFormName)
634  ! xx_pt, IN x, loc of point in the chunk
635  ! yy_pt IN y loc of point in the chunk
636  ! Ram IN non-abs reflectance
637  ! Rbm IN absorbing band reflectance
638  ! twobands IN size 2 indicies of non-abs and absorbing indiciew
639  ! radii IN array of table re values
640  ! tau OUT retrieved optical thickness
641  ! re OUT retrieved final radius
642  ! lib_dist OUT I believe a uncertainty measure (root sum square) for the
643  ! derived re / tau?
644  ! phase_liquid IN switch for liquid phase if true
645  ! Ram_corr
646  ! quality_in
647  ! --- extra args? ---
648  ! CH37_IDX
649  ! CTopT,CH37_NUM
650  ! platFormName
651  !
652  ! alternate solution exterior, just the boundary (for water, re=4,
653  ! re=30 and tau = 158.8)
654  ! for ice re=5,re=60 and tau = 158.8 (top, bottom and rightmost
655 
656  use generalauxtype
657  use core_arrays
661  use libraryarrays
662  use planck_functions
663 
664  integer, intent(in) ::xx_pt,yy_pt
665  real, intent(in) :: Ram, Rbm
666  real, dimension(:), intent(in) :: radii
667  integer, dimension(:), intent(in) :: twobands
668  real, intent(inout) :: tau, re, lib_dist, Ram_corr
669  logical, intent(in) :: phase_liquid
670  integer, intent(in) :: quality_in
671  CHARACTER(len=*),INTENT(IN),OPTIONAL::platFormName
672  INTEGER,INTENT(IN),OPTIONAL::CH37_NUM,CH37_IDX
673  REAL, INTENT(IN), OPTIONAL::CTopT
674 
675  REAL :: Pc, theta, theta0, phi
676  real::CTopT_lcl, intCTop,intSurf
677  integer :: size_tau, size_re
678 
679  size_tau = number_taus + 1
680  size_re = size(refliba, 2)
681 
682  pc = cloud_top_pressure(xx_pt,yy_pt)
683  theta = sensor_zenith_angle(xx_pt,yy_pt)
684  theta0= solar_zenith_angle(xx_pt,yy_pt)
685  phi=relative_azimuth_angle(xx_pt,yy_pt)
686  !
687  ! WDR have the CTopT go to a local variable and handle presence then
688  IF(PRESENT(ctopt)) THEN
689  ctopt_lcl = ctopt
690  else
691  ctopt_lcl = 0.
692  endif
693  ! 3.7 not in PACE, so return later
694  IF(PRESENT(ch37_idx) .AND. PRESENT(ctopt) .and. PRESENT(platformname) &
695  .and. PRESENT(ch37_num) .and. ctopt_lcl > 0.0)THEN
696  intctop= modis_planck(platformname, ctopt_lcl, ch37_num, 1)
697  intsurf = modis_planck(platformname, surface_temperature(xx_pt,yy_pt), &
698  ch37_num, 1)
699 
700  if( (.NOT. cox_munk))THEN
701  if(phase_liquid)then
702  call calc37radianceliblamb(intctop,intsurf, &
704  thermal_correction_twoway(1), theta0, &
705  spherical_albedo_water(:,ch37_idx,:), &
706  int_fluxdownwater_sensor(:,ch37_idx,:), &
707  int_fluxdownwater_solar(:,ch37_idx,:), &
708  int_fluxupwater_sensor(:,ch37_idx,:))
709  else
710  call calc37radianceliblamb(intctop,intsurf, &
712  spherical_albedo_ice(:,ch37_idx,:), &
713  int_fluxdownice_sensor(:,ch37_idx,:), &
714  int_fluxdownice_solar(:,ch37_idx,:), &
715  int_fluxupice_sensor(:,ch37_idx,:))
716  endif
717 
718  elseif(cox_munk)THEN
719  if(phase_liquid)then
720  call calc37radiancelibcm(intctop,intsurf, &
722  thermal_correction_twoway(1), theta0, &
725  else
726  call calc37radiancelibcm(intctop,intsurf, &
728  theta0, int_cloud_emissivity_ice(:,1,:), &
730  endif
731  endif
732  ENDIF ! End 3.7 related logic
733 
734  if(quality_in == -4 .OR. quality_in == -3)then
735  CALL asl_boundary(ram, rbm, twobands, radii, tau, re, lib_dist, pc, &
736  theta, theta0, phi, phase_liquid, ram_corr)
737  else
738  CALL asl_interior(ram, rbm, twobands, radii, tau, re, lib_dist, pc, &
739  theta, theta0, phi, phase_liquid, ram_corr)
740  endif
741 
742  return
743 
744 end subroutine solveretrieval_nearest
745 
746 subroutine calc37radianceliblamb(intensity,intensity_g, &
747  thermal_trans_1way, thermal_trans_2way, solar_zenith, &
748  sfr,fti1,fti0,fri1)
749 
750  use generalauxtype
752  use libraryarrays, only : reflibb,rad37lib
753 
754  implicit none
755 
756  real, intent(in) :: intensity,intensity_g,solar_zenith
757 
758  real, intent(in) :: thermal_trans_2way,thermal_trans_1way
759  real(single), intent(in) :: sfr(:,:), fti1(:,:), fti0(:,:), fri1(:,:)
760 ! rfi(:,:)
761 
762  integer :: total_taus, radii, wavelengths,i,j
763  real :: absorbing_albedo
764  real :: tc, local_trans_1way, local_trans_2way
765 
766  if (thermal_trans_1way < 0. .or. thermal_trans_1way > 1.) then!{
767  local_trans_1way = 1.
768  else!}{
769  local_trans_1way = thermal_trans_1way
770  endif!}
771 
772  if (thermal_trans_2way < 0. .or. thermal_trans_2way > 1.) then!{
773  local_trans_2way = 1.
774  else!}{
775  local_trans_2way = thermal_trans_2way
776  endif!}
777 
778 
779  !populate rad37lib here, in reflectance units
780  absorbing_albedo = reflibb(1,1)
781 
782  rad37lib(1,:) = (1.0 - absorbing_albedo) * intensity_g
783  rad37lib(2:,:) = (1.0- fti1(:,:) - fri1(:,:)) * intensity + &
784  fti1(:,:) * (1.0 - absorbing_albedo) * intensity_g / &
785  (1.0 - absorbing_albedo * sfr(:,:))
786  rad37lib(:,:) = rad37lib(:,:) * local_trans_1way * pi/ &
787  ( cos(solar_zenith*d2r)*solar_constant_37)
788  rad37lib(:,:) = rad37lib(:,:) + local_trans_2way * reflibb(:,:)
789 
790 end subroutine calc37radianceliblamb
791 
792 subroutine calc37radiancelibcm(intensity,intensity_g, &
793  thermal_trans_1way, thermal_trans_2way, solar_zenith, &
794  cl_emis,sf_emis)
795 
796  use generalauxtype
798  use libraryarrays, only : reflibb,rad37lib
799 
800  implicit none
801 
802  real, intent(in) :: intensity,intensity_g,solar_zenith
803  real, intent(in) :: thermal_trans_2way,thermal_trans_1way
804  real(single), intent(in) :: cl_emis(:,:), sf_emis(:,:)
805 
806  ! real,intent(out)::rad037lib(:,:),rtherm037lib(:,:)
807 
808 
809  integer :: total_taus, radii, wavelengths,i,j
810  real :: absorbing_albedo
811  real :: tc, local_trans_1way, local_trans_2way
812 
813  if (thermal_trans_1way < 0. .or. thermal_trans_1way > 1.) then!{
814  local_trans_1way = 1.
815  else!}{
816  local_trans_1way = thermal_trans_1way
817  endif!}
818 
819  if (thermal_trans_2way < 0. .or. thermal_trans_2way > 1.) then!{
820  local_trans_2way = 1.
821  else!}{
822  local_trans_2way = thermal_trans_2way
823  endif!}
824 
825  !populate rad37lib here, in reflectance units
826 
827  rad37lib(:,:) = cl_emis(:,:) * intensity + sf_emis(:,:) * intensity_g
828  rad37lib(:,:) = rad37lib(:,:) * local_trans_1way * pi/ &
829  ( cos(solar_zenith*d2r)*solar_constant_37)
830  rad37lib(:,:) = rad37lib(:,:) + local_trans_2way * reflibb(:,:)
831 
832 end subroutine calc37radiancelibcm
833 
834 subroutine asl_interior(Ram, Rbm_in, bands, radii, tau, re, lib_dist, Pc, &
835  theta, theta0, phi, phase_liquid, Ram_corr)
836  !
837  ! For solutions inside the LUT with multiple solutions - derive one and
838  ! essentialy an uncertainty in the form of a distance - This is for
839  !alternate solution interior
840  !
841  ! Ram
842  ! Rbm_in
843  ! bands
844  ! radii
845  ! tau
846  ! re
847  ! lib_dist
848  ! Pc
849  ! theta
850  ! theta0
851  ! phi
852  ! phase_liquid
853  ! Ram_corr
854  !
855  use generalauxtype
856  use libraryarrays
861 
862  real, intent(in) :: Ram, Rbm_in, Pc, theta, theta0, phi
863  real, dimension(:), intent(in) :: radii
864  integer, dimension(:), intent(in) :: bands
865  real, intent(inout) :: tau, re, lib_dist, Ram_corr
866  logical, intent(in) :: phase_liquid
867 
868 
869  real, dimension(:,:), allocatable :: rel_residual,reflibBL
870  integer :: size_tau, size_re, loc(2), rel_loc(2)
871  logical :: re_altered
872 
873  real :: Ramc, crefl,Rbm
874  integer :: iter, max_iter
875 
876  real :: albedoA, albedoB,normConst
877  real :: sfr, fti1, fti0
878 
879  size_tau = number_taus + 1
880  size_re = size(refliba, 2)
881  allocate(rel_residual(size_tau, size_re),reflibbl(size_tau, size_re))
882 
883  reflibbl(:,:) = reflibb(:,:)
884  rbm = rbm_in
885 
886  if( bands(2) == band_0370)then
887  normconst = pi/(cos(theta0*d2r)*solar_constant_37)
888  rbm = rbm_in * normconst
889  reflibbl(:,:) = rad37lib(:,:)
890  endif
891 
892  albedoa = refliba(1,1)
893  albedob = reflibbl(1,1)
894 
895 
896 #if ASTER_INST
897  if (bands(1) == band_0065 .or. bands(1) == band_0086) then
898 #else
899  if (bands(1) == band_0065) then
900 #endif
901  max_iter = 3
902  else
903  max_iter = 1
904  endif
905 
906  ramc = ram
907  iter = 1
908 
909  do while (iter <= max_iter)
910 
911  ! the point has no chance, it is darker than the surface albedo
912  if (ramc < albedoa) then
913  tau = fillvalue_real
914  re = fillvalue_real
915  lib_dist = max_cost_function
916  ram_corr = ramc
917  deallocate (rel_residual, reflibbl ) ! WDR add the reflibBL deallocate
918  return
919  endif
920  ! collect the value of cost function
921  rel_residual = sqrt( (refliba - ramc)**2 + (reflibbl-rbm)**2 ) / &
922  sqrt(ramc**2 + rbm**2)
923  loc = minloc(rel_residual)
924  lib_dist = rel_residual(loc(1), loc(2))
925  re = radii(loc(2))
926 
927  ! don't want any 2's and such
928  if (re < 4. ) re = 4.
929  ! the library taus don't have 0., so we need to explicitly count for
930  ! it. But we can't put in a 0. straight because
931  ! L3 code can't handle an explicit 0. value.
932  if (loc(1) == 1) then
933  tau = 0.01
934  else
935  tau = library_taus(loc(1)-1)
936  endif
937 
938  ! call rayleigh here
939 #if ASTER_INST
940  if (bands(1) == band_0065 .or. bands(1) == band_0086) then
941 #else
942  if (bands(1) == band_0065) then
943 #endif
944  if (phase_liquid) then
945  if (loc(1) == 1) then
946  sfr = 0.
947  fti1 = 1.
948  fti0 = 1.
949  else
950  sfr = spherical_albedo_water(loc(1)-1,bands(1),loc(2))
951  fti1 = int_fluxdownwater_sensor(loc(1)-1,bands(1),loc(2))
952  fti0 = int_fluxdownwater_solar(loc(1)-1,bands(1),loc(2))
953  endif
954 
955  call ray_corr_nearest (ram, albedoa, bands(1), tau, re, pc, &
956  sfr, fti1, fti0, flux_up_water_solar, flux_up_water_sensor, &
957  theta, theta0, phi, loc, crefl)
958  else
959  if (loc(1) == 1) then
960  sfr = 0.
961  fti1 = 1.
962  fti0 = 1.
963  else
964  sfr = spherical_albedo_ice(loc(1)-1,bands(1),loc(2))
965  fti1 = int_fluxdownice_sensor(loc(1)-1,bands(1),loc(2))
966  fti0 = int_fluxdownice_solar(loc(1)-1,bands(1),loc(2))
967  endif
968 
969  call ray_corr_nearest (ram, albedoa, bands(1), tau, re, pc, &
970  sfr, fti1, fti0, flux_up_ice_solar, flux_up_ice_sensor, &
971  theta, theta0, phi, loc, crefl)
972  endif
973  ramc = crefl
974 
975  endif
976 
977  iter = iter + 1
978 
979  end do
980 
981  ram_corr = ramc
982 
983  if (ramc < albedoa) then
984  tau = fillvalue_real
985  re = fillvalue_real
986  lib_dist = max_cost_function
987  deallocate (rel_residual, reflibbl ) ! WDR add this to complete deallocs
988  return
989  endif
990  ! collect the value of cost function
991  rel_residual = sqrt( (refliba - ramc)**2 + (reflibbl-rbm)**2 ) / &
992  sqrt(ramc**2 + rbm**2)
993  loc = minloc(rel_residual)
994  lib_dist = rel_residual(loc(1), loc(2))
995 
996  ! do the alternate retrieval
997  re = radii(loc(2))
998  ! don't want any 2's and such
999  if (re < 4. ) re = 4.
1000  ! the library taus don't have 0., so we need to explicitly count
1001  ! for it. But we can't put in a 0. straight because
1002  ! L3 code can't handle an explicit 0. value.
1003  if (loc(1) == 1) then
1004  tau = 0.01
1005  else
1006  tau = library_taus(loc(1)-1)
1007  endif
1008 
1009  deallocate (rel_residual,reflibbl)
1010 
1011 end subroutine asl_interior
1012 
1013 
1014 subroutine asl_boundary(Ram, Rbm_in, bands, radii, tau, re, lib_dist, Pc, &
1015  theta, theta0, phi, phase_liquid, Ram_corr)
1017  ! For solutions outside the LUT - derive one and
1018  ! essentialy an uncertainty in the form of a distance - This is for
1019  !alternate solution exterior, just the boundary (for water, re=4,
1020  ! re=30 and tau = 158.8)
1021  ! for ice re=5,re=60 and tau = 158.8 (top, bottom and rightmost)
1022  !
1023  ! Ram IN non-abs reflectance
1024  ! Rbm_in IN absorbing band reflectance
1025  ! bands IN size 2 indicies of non-abs and absorbing indicies
1026  ! radii IN array of table re values
1027  ! tau IN/OUT retrieved optical thickness
1028  ! re IN/OUT retrieved radius
1029  ! lib_dist a distance outside the LUT, a measure of amount off
1030  ! Pc IN cloud top pressure
1031  ! theta IN I believe the sat zen angle
1032  ! theta0 IN I believe the sol zen angle
1033  ! phi IN I believe the delta azimuth angle
1034  ! phase_liquid IN switch for liquid phase if true
1035  ! Ram_corr OUT may be abs band refl
1036 
1037  use generalauxtype
1038  use libraryarrays
1041  use mod06_run_settings
1042  use science_parameters
1043 
1044  real, intent(in) :: Ram, Rbm_in, Pc, theta, theta0, phi
1045  real, dimension(:), intent(in) :: radii
1046  integer, dimension(:), intent(in) :: bands
1047  real, intent(inout) :: tau, re, lib_dist, Ram_corr
1048  logical, intent(in) :: phase_liquid
1049 
1050  real, dimension(:,:), allocatable :: temp_refl,reflibBL
1051  real,dimension(:),allocatable::rel_residual
1052  integer :: size_tau, size_re, loc, rel_loc(1),ire_ct_1, &
1053  temp_array_size,s_rt,iL,iR
1054  logical :: re_altered
1055 
1056  real :: Ramc, crefl, Rbm
1057  integer :: iter, max_iter,iiiloc
1058 
1059  real :: albedoA, albedoB,normConst
1060  real :: sfr, fti1, fti0
1061 
1062  size_tau = number_taus + 1
1063  size_re = size(refliba, 2)
1064 
1065  ramc = ram
1066  rbm = rbm_in
1067 
1068  allocate(reflibbl(size_tau, size_re))
1069 
1070  reflibbl(:,:) = reflibb(:,:)
1071 
1072  if( bands(2) == band_0370)then
1073  normconst = pi/(cos(theta0*d2r)*solar_constant_37)
1074  rbm = rbm_in * normconst
1075  reflibbl(:,:) = rad37lib(:,:)
1076  endif
1077 
1078  ! set the top contour (CT 1) for ice =1 (re =5) for water = 2(re = 4)
1079  ! can do it in mod06_run_settings
1080 
1081  ire_ct_1 = top_nk_asl_contour_ice
1082  if(phase_liquid)ire_ct_1 = top_nk_asl_contour_water
1083 
1084  ! reflibA is the modified copied non-abs reflectance table made back in
1085  ! vis non absorbing work and reflibBL is the abs table
1086  albedoa = refliba(1,ire_ct_1)
1087  albedob = reflibbl(1,ire_ct_1)
1088 
1089  s_rt = size_tau+size_re
1090  temp_array_size = size_tau + s_rt - (ire_ct_1 + 1)
1091 
1092  allocate(rel_residual(temp_array_size))
1093  allocate(temp_refl(2,temp_array_size))
1094  ! EXPLAIN YOUR WORK!
1095  temp_refl(1,1:size_tau) = refliba(1:size_tau,ire_ct_1)
1096 
1097  temp_refl(1, size_tau+1 : s_rt-ire_ct_1) = &
1098  refliba(size_tau,ire_ct_1+1:size_re) !
1099 
1100  temp_refl(1, s_rt-ire_ct_1+1 : temp_array_size) = &
1101  refliba(1:size_tau-1,size_re)
1102 
1103  ! assign the radiance+emission of the 3.7 LUT
1104  temp_refl(2, 1 : size_tau) = reflibbl(1:size_tau,ire_ct_1)
1105  temp_refl(2, size_tau+1 : s_rt-ire_ct_1) = &
1106  reflibbl(size_tau,ire_ct_1+1:size_re) !
1107  temp_refl(2, s_rt-ire_ct_1+1 : temp_array_size) = &
1108  reflibbl(1:size_tau-1,size_re)
1109 
1110  ! abs refl is below sfc albedo: region I
1111  ! the point has no chance, it is darker than the surface albedo
1112  if (ramc < albedoa .OR. &
1113  ( rbm < minval(reflibbl(size_tau,ire_ct_1:size_re)) .and. &
1114  ramc > minval(refliba(size_tau,ire_ct_1:size_re)) ) .OR. &
1115  ( rbm > maxval(reflibbl(size_tau,ire_ct_1:size_re)) .and. &
1116  ramc > maxval(refliba(size_tau,ire_ct_1:size_re)) )) then
1117 
1118  tau = fillvalue_real
1119  re = fillvalue_real
1120  lib_dist = max_cost_function
1121  ram_corr = ramc
1122  deallocate (rel_residual, temp_refl, reflibbl)
1123  return
1124 
1125  endif
1126  ! collect the value of cost function
1127  rel_residual = sqrt( (temp_refl(1,:) - ramc)**2 + &
1128  (temp_refl(2,:) -rbm)**2 ) / sqrt(ramc**2 + rbm**2)
1129  rel_loc = minloc(rel_residual)
1130  lib_dist = rel_residual(rel_loc(1))
1131 
1132  ! reclaculate lib_dist with both x and y in terms of reflectances,
1133  ! if band(2)=3.7
1134 
1135  ! do the alternate retrieval
1136  if(rel_loc(1) <= size_tau)then
1137  ! contour 1
1138  re = radii(ire_ct_1)
1139  loc = rel_loc(1)
1140 
1141  if(bands(1) == band_0065)then
1142  if(phase_liquid) then
1143  ramc = rayleigh_liq(ire_ct_1)
1144  else
1145  ramc = rayleigh_ice(ire_ct_1)
1146  endif
1147 
1148  CALL calcdistanceandminloc(ramc,rbm,temp_refl(1,1:size_tau), &
1149  temp_refl(2,1:size_tau),lib_dist,loc)
1150  ram_corr = ramc
1151  endif
1152 
1153  if (loc == 1) then
1154  tau = 0.01
1155  else
1156  tau = library_taus(loc-1)
1157  endif
1158 
1159  if(ramc > maxval(refliba(size_tau,ire_ct_1:size_re)))then
1160  if(bands(1) == band_0163 .AND. bands(2) == band_0213 )then
1161  tau = fillvalue_real
1162  else
1163  if((rbm - reflibbl(size_tau,ire_ct_1)) < 0.0)then
1164  do iiiloc = ire_ct_1+1,size_re
1165  il = iiiloc-1
1166  ir = iiiloc
1167  if((rbm - reflibbl(size_tau,iiiloc)) >=0.0)exit
1168  enddo
1169  tau = max_tau_rtrieved
1170  re=radii(il)
1171 
1172  if(abs(reflibbl(size_tau,ir)-reflibbl(size_tau,il)) > 0.000001)then
1173  re = (rbm-reflibbl(size_tau,il))*(radii(ir) - &
1174  radii(il))/(reflibbl(size_tau,ir)-reflibbl(size_tau,il)) + &
1175  radii(il)
1176  if(re > radii(ir) .OR. re < radii(il))re = radii(il)
1177  endif
1178  endif
1179  endif
1180  endif
1181 
1182  elseif(rel_loc(1) > size_tau .and. rel_loc(1) <= s_rt - ire_ct_1)then
1183  !contour 4
1184  loc = rel_loc(1) - size_tau + 1
1185  re = radii(loc)
1186 
1187  if(loc==1 .OR. &
1188  ((rbm - reflibbl(size_tau,loc)) < 0.0 .AND. loc <= size_re))then
1189  do iiiloc = loc , size_re
1190  if((rbm - reflibbl(size_tau,iiiloc)) >=0.0)exit
1191  loc = iiiloc
1192  enddo
1193 
1194  il = loc
1195  ir = loc+1
1196  elseif((rbm - reflibbl(size_tau,loc)) >= 0.0 .AND. loc <= size_re)then
1197  do iiiloc = loc-1 , 1,-1
1198  if((rbm - reflibbl(size_tau,iiiloc)) <= 0.0)exit
1199  loc = iiiloc
1200  enddo
1201  il = loc-1
1202  ir = loc
1203  endif
1204 
1205  if(ir <= size_re .and. il >= 1)then
1206  re = radii(loc)
1207  if(abs(reflibbl(size_tau,ir)-reflibbl(size_tau,il)) > 0.000001 &
1208  .and. abs(rbm - reflibbl(size_tau,loc)) > 0.0)then
1209  re = radii(loc) + (rbm-reflibbl(size_tau,loc))*(radii(ir) - &
1210  radii(il))/(reflibbl(size_tau,ir)-reflibbl(size_tau,il))
1211  if(re > radii(ir) .OR. re < radii(il))re = radii(loc)
1212  endif
1213  endif
1214 
1215  if(bands(1) == band_0065)then
1216  if(phase_liquid)then
1217  ramc = rayleigh_liq(loc)
1218  else
1219  ramc = rayleigh_ice(loc)
1220  endif
1221  ram_corr = ramc
1222  endif
1223 
1224  tau = fillvalue_real
1225  if(bands(1) == band_0163 .AND. bands(2) == band_0213 )then
1226  tau = fillvalue_real
1227  else
1228  tau = max_tau_rtrieved
1229  endif
1230 
1231  if(ramc > 0 .and. ramc < maxval(refliba(1:size_tau,size_re)) .and. &
1232  ir > size_re)THEN
1233  tau = fillvalue_real
1234  re = fillvalue_real
1235  lib_dist = max_cost_function
1236  endif
1237  else
1238  !contour 2
1239  re = radii(size_re)
1240  loc = rel_loc(1) - (s_rt-ire_ct_1) + 1
1241 
1242  if(bands(1) == band_0065)then
1243  if(phase_liquid)then
1244  ramc = rayleigh_liq(size_re)
1245  else
1246  ramc = rayleigh_ice(size_re)
1247  endif
1248 
1249  CALL calcdistanceandminloc(ramc,rbm, &
1250  temp_refl(1,s_rt-ire_ct_1+1: temp_array_size), &
1251  temp_refl(2,s_rt-ire_ct_1+1: temp_array_size),lib_dist,loc)
1252  ram_corr = ramc
1253  endif
1254 
1255  if ( loc == 1 ) then
1256  tau = 0.01
1257  else
1258  tau = library_taus(loc-1 )
1259  endif
1260 
1261  if(ramc > maxval(refliba(1:size_tau,size_re)))then
1262  tau = fillvalue_real
1263  re = fillvalue_real
1264  lib_dist = max_cost_function
1265 
1266  endif
1267 
1268  endif
1269 
1270  if(tau > library_taus(size_tau-1)-1.0 )then
1271  tau = fillvalue_real
1272  re = fillvalue_real
1273  lib_dist = max_cost_function
1274  endif
1275 
1276  ! don't want any 2's and such
1277  ! if (re < 4. ) re = 4.
1278  ! the library taus don't have 0., so we need to explicitly count
1279  ! for it. But we can't put in a 0. straight because
1280  ! L3 code can't handle an explicit 0. value.
1281 
1282  deallocate (rel_residual,temp_refl,reflibbl)
1283 
1284 end subroutine asl_boundary
1285 
1286 subroutine calcdistanceandminloc(R1,R2,R1vec, R2vec,mindist,loc_index)
1287  !
1288  ! R1
1289  ! R2
1290  ! R1vec
1291  ! R2vec
1292  ! mindist
1293  ! loc_index
1294 
1295  REAL,INTENT(IN)::R1,R2
1296  REAL,DIMENSION(:),INTENT(IN)::R1vec,R2vec
1297  REAL,INTENT(OUT)::mindist
1298  INTEGER,INTENT(OUT)::loc_index
1299 
1300  real,dimension(:),allocatable::rel_residual
1301  INTEGER::rel_loc(1)
1302 
1303  allocate(rel_residual(size(r1vec)))
1304 
1305  rel_residual = sqrt( (r1vec - r1)**2 + (r2vec -r2)**2 ) / &
1306  sqrt(r1**2 + r2**2)
1307  rel_loc = minloc(rel_residual)
1308  mindist = rel_residual(rel_loc(1))
1309  loc_index = rel_loc(1)
1310 
1311  deallocate(rel_residual)
1312 
1313  return
1314 end subroutine calcdistanceandminloc
1315 
1316 subroutine solve_retrieval_noswir(optical_thickness_vector, &
1317  library_radii, effective_radius, optical_thickness)
1318  !
1319  ! optical_thickness_vector
1320  ! library_radii
1321  ! effective_radius
1322  ! optical_thickness
1323 
1325  use science_parameters
1326  use libraryarrays, only:library_taus
1327 
1328  real, intent(in) :: optical_thickness_vector(:)
1329  real, intent(in) :: library_radii(:)
1330  real, intent(in) :: effective_radius
1331  real, intent(out) :: optical_thickness
1332 
1333 
1334  integer :: ilo, ihi
1335 
1336  ! we have no SWIR (or knocked it out on purpose)
1337  ! we are fixing the value of effective radius on some value that
1338  ! is generally agreed on
1339  ! as being reasonable. We will return an optical thickness retrieval
1340  ! that's all nice
1341  ! and interpolated, but the re is going to be a constant
1342  ! There will be no ASL retrieval because we are just staying on the
1343  ! re=const curve in the library
1344 
1345  call findinterpolationrange(3, effective_radius, size(library_radii), &
1346  real(library_radii), ilo, ihi)
1347 
1348  optical_thickness = lagrangeinterp(effective_radius, &
1349  real(library_radii(ilo:ilo+2)), optical_thickness_vector(ilo:ilo+2) )
1350 
1351  if (optical_thickness > 150.) optical_thickness = 150.
1352  if (optical_thickness < 0.) then
1353  optical_thickness = fillvalue_real
1354  endif
1355 
1356 end subroutine solve_retrieval_noswir
1357 
1358 subroutine solveretrieval( residual, optical_thickness_vector, &
1359  library_radii, effective_radius, optical_thickness, debug, &
1360  use_nearest, quality_out)
1361  !
1362  ! residual IN vector of fractional diff of rho(abs) measured -
1363  ! rho(abs) of the rho library for the set of solved tau (by the
1364  ! non-abs algorithm) at each re (make sense?)
1365  ! optical_thickness_vector IN tau solved for at each re
1366  ! library_radii IN the re axis values
1367  ! effective_radius OUT solved re
1368  ! optical_thickness OUT solved tau
1369  ! debug IN switch for debugging
1370  ! use_nearest OUT apparently, this failed and solveretrieval_nearest needs
1371  ! to be called
1372  ! quality_out OUT many states of the re retrieval
1373 
1374  use generalauxtype
1376  use science_parameters
1377  use libraryarrays, only:library_taus
1378 
1379  real, intent(in) :: residual(:), optical_thickness_vector(:)
1380  real(single), intent(in) :: library_radii(:)
1381  logical, intent(in) :: debug
1382  logical, intent(inout) :: use_nearest
1383  real, intent(out) :: effective_radius, optical_thickness
1384  integer,intent(out)::quality_out
1385 
1386  real :: max_allowable_tau,local_max_allowable !!added
1387  integer:: total_taus !!added
1388 
1389  integer :: number_local_minima, ilo, ihi, zero_count
1390  integer :: local_minima(8)
1391 
1392  INTEGER, parameter :: nre=18
1393  INTEGER :: crossing_num, crossing_vector(nre), local_max_num, &
1394  local_max_vector(nre), local_min_num, local_min_vector(nre), k
1395  integer(integer_onebyte) :: quality
1396 
1397  integer:: res_size
1398 
1399  real re_water_outofbounds_high, re_water_outofbounds_low
1400  logical :: re_altered, correction_made
1401 
1402  local_minima(:) = 0
1403  re_water_outofbounds_high = 30.; re_water_outofbounds_low = 4.
1404 
1405  correction_made = .false.
1406 
1407  ! get effective radius solution !added/changed
1408  ! changed for water residual going in from re = 4
1409  ! This decides if we are doing ice or water retr by checking the
1410  ! library array size The find_zero_crossings, find_local_minima,
1411  ! find_local_maxima gets the indicies of the tops, bottoms and
1412  ! (value before) the zero crossing of the residual and the # of these
1413  ! Then, solution_re
1414  if(is_water_phase(library_radii))then
1415  call find_zero_crossings (residual(top_nk_asl_contour_water:), &
1416  crossing_vector, crossing_num)
1417  call find_local_minima (residual(top_nk_asl_contour_water:), &
1418  local_min_vector, local_min_num)
1419  call find_local_maxima (residual(top_nk_asl_contour_water:), &
1420  local_max_vector, local_max_num)
1421 
1422  call solution_re (library_radii(top_nk_asl_contour_water:), &
1423  residual(top_nk_asl_contour_water:) , crossing_vector, crossing_num, &
1424  local_min_vector, local_min_num, local_max_vector, local_max_num, &
1425  effective_radius, quality )
1426  else
1427  call find_zero_crossings (residual, crossing_vector, crossing_num)
1428  call find_local_minima (residual, local_min_vector, local_min_num)
1429  call find_local_maxima (residual, local_max_vector, local_max_num)
1430 
1431  call solution_re (library_radii, residual, crossing_vector, crossing_num, &
1432  local_min_vector, local_min_num, local_max_vector, local_max_num, &
1433  effective_radius, quality )
1434  endif
1435 
1436  quality_out = quality !added/changed
1437 
1438  use_nearest = .false.
1439  if ( quality == -2 .or. quality == -3 .or. quality == -4 &
1440  .OR. quality == -6) then !added/changed
1441 
1442  use_nearest = .true.
1443  RETURN
1444 
1445  endif
1446  ! get optical thickness solution
1447 
1448  ! PARTIAL RETRIEVAL LOGIC ADDENDUM FOR RETENTION OF TAU SOLUTION
1449  ! FOR FAILED RE
1450  ! order is important here--the following block needs to be done
1451  ! here before the call to findinterpolationrange
1452  ! for performing a partial tau retrieval after having retrieved the
1453  ! maximum or minimum desireable, or failed to retrieve liquid library re
1454 
1455  ! sep: 3=8-06
1456  ! For water clouds there are 4 possibilities at this point: re>=30,
1457  ! re<=4, re=INVALID, or re valid
1458  ! For ice clouds there are 2 possibilities at this point: re=INVALID
1459  ! or re valid
1460  ! It was decided to perform "partial" optical thickness retrievals
1461  ! for any non-valid case by temporarily assigning re a
1462  ! value of 10 or 30 microns for ice and water, respectively.
1463  ! The logic to account for this is simpler than the previous version.
1464 
1465  re_altered = .false.
1466  if (is_water_phase(library_radii) .and. & ! changed/added <= to <
1467  ( (effective_radius < re_water_outofbounds_low) .or. &
1468  (effective_radius == invalid_attempted_but_failed_re) ) ) then!{
1469  effective_radius = 10.
1470  re_altered = .true.
1471  else!}{
1472  ! for performing a partial tau retrieval after having failed to
1473  ! retrieve ice library re
1474  if (effective_radius == invalid_attempted_but_failed_re) then!{
1475  effective_radius = 30.
1476  re_altered = .true.
1477  endif!}
1478  endif!}
1479  ! END PARTIAL RETRIEVAL LOGIC ADDENDUM FOR RETENTION OF TAU
1480  ! SOLUTION FOR FAILED RE
1481 
1482  call findinterpolationrange(3, effective_radius, size(library_radii), &
1483  real(library_radii), ilo, ihi)
1484 
1485  !!! added !!! Cloud folks emphasis
1486  !!! correction starts here !!!!!!!!
1487  total_taus = size(library_taus)
1488  max_allowable_tau = library_taus(total_taus)
1489  local_max_allowable = max_allowable_tau - 1.0
1490 
1491  ! we go in if tau_vector(ilo:ilo+2) has a 158.78
1492  ! or -1 (i.e, lagrange interpolation points)
1493  if(.not.(use_nearest) .and. &
1494  (maxval(optical_thickness_vector(ilo:ilo+2)) > local_max_allowable &
1495  .OR. minval(optical_thickness_vector(ilo:ilo+2)) < 0))then
1496 
1497  correction_made = .true.
1498  if(ilo <= 2)then
1499  if(maxval(optical_thickness_vector(1:2)) > local_max_allowable &
1500  .OR. minval(optical_thickness_vector(1:2)) < 0)then
1501  optical_thickness = fillvalue_real
1502  use_nearest = .true.
1503  quality_out = -4
1504  else
1505  ilo =1
1506  optical_thickness = optical_thickness_vector(ilo) + &
1507  ( ( effective_radius - real(library_radii(ilo))) / &
1508  (real(library_radii(ilo+1)-library_radii(ilo))) ) * &
1509  (optical_thickness_vector(ilo+1) - optical_thickness_vector(ilo) )
1510  endif
1511 
1512  elseif(maxval(optical_thickness_vector(ilo-1:ilo)) > local_max_allowable &
1513  .OR. minval(optical_thickness_vector(ilo-1:ilo)) < 0)then
1514  optical_thickness = fillvalue_real
1515  use_nearest = .true.
1516  quality_out = -4
1517 
1518  elseif(maxval(optical_thickness_vector(ilo-1:ilo)) < local_max_allowable &
1519  .AND. minval(optical_thickness_vector(ilo-1:ilo)) > 0)then
1520  ilo = ilo-2
1521  if(optical_thickness_vector(ilo+3) < local_max_allowable &
1522  .AND. optical_thickness_vector(ilo+3) > 0)ilo = ilo+1
1523 
1524  optical_thickness = optical_thickness_vector(ilo+1) + &
1525  ( ( effective_radius - real(library_radii(ilo+1))) / &
1526  (real(library_radii(ilo+2)-library_radii(ilo+1))) ) * &
1527  (optical_thickness_vector(ilo+2) - optical_thickness_vector(ilo+1) )
1528  else
1529  ! this else can be removed. If all above fails it should come here.
1530  ! Tested 5 granuels and didn't come here
1531  ! but to be safe make it filled
1532  ! optical_thickness = fillvalue_real
1533  use_nearest = .true.
1534  quality_out = -4
1535  endif
1536  endif
1537 
1538  !!! correction done !!!! The end of their correction
1539 
1540  if(.NOT.(correction_made))then
1541  optical_thickness = lagrangeinterp(effective_radius, &
1542  real(library_radii(ilo:ilo+2)), &
1543  optical_thickness_vector(ilo:ilo+2) )
1544  endif
1545 
1546  if( optical_thickness < optical_thickness_vector(ilo) .AND. &
1547  (.NOT.(correction_made))) then!{ !!!!!!added /changed
1548 
1549  call findinterpolationrange(2, effective_radius, size(library_radii), &
1550  real(library_radii), ilo, ihi)
1551  optical_thickness = optical_thickness_vector(ilo) + &
1552  ( ( effective_radius - real(library_radii(ilo))) / &
1553  (real(library_radii(ilo+1)-library_radii(ilo))) ) * &
1554  (optical_thickness_vector(ilo+1) - optical_thickness_vector(ilo) )
1555  endif!}
1556 
1557  ! KILL RE FOR PARTIAL RETRIEVAL
1558  ! Now that the optical thickness has been determined, set the
1559  ! effective radius to fill if re_altered = .TRUE.
1560  if (re_altered) effective_radius = fillvalue_real
1561 
1562  ! RANGE CHECKING of optical thickness and effective radius
1563 
1564  ! OPTICAL THICKNESS
1565 
1566  ! tau low boundary of range
1567  if (optical_thickness /= fillvalue_real .and. optical_thickness < 0.) then
1568  optical_thickness = fillvalue_real
1569  effective_radius = fillvalue_real
1570  use_nearest = .true.
1571  quality_out = -4
1572  endif
1573 
1574  if (optical_thickness /= fillvalue_real .and. &
1575  optical_thickness < 0.01 .and. optical_thickness > 0.) then!{
1576  optical_thickness = 0.01
1577  endif!}
1578  ! end tau low boundary of range
1579 
1580  ! tau high boundary of range
1581  ! QA for large optical thickness
1582  ! if (optical_thickness > 150.) then!{
1583  ! optical_thickness_outofbounds = 2
1584  ! elseif (optical_thickness > 100. .and. optical_thickness <= 150.) then!}{
1585  ! optical_thickness_outofbounds = 1
1586  ! else!}{
1587  ! optical_thickness_outofbounds = 0
1588  ! endif!}
1589 
1590  ! if ( optical_thickness > 100.) then!{
1591  ! optical_thickness = 100.
1592  ! endif!}
1593  ! end tau high boundary of range
1594 
1595  ! EFFECTIVE RADIUS
1596 
1597  ! NOTE: Ideally, it would be more satisfying to assign re retrievals
1598  ! outside of the library space to fill value,
1599  ! even here after other checks have done the same however, retrievals
1600  ! can be within epsilon of boundary
1601  ! (e.g., Liam's pixel with ice re = 90.00000763). That is the intent
1602  ! of this strict range enforcement here.
1603 
1604  ! re low boundary of range
1605  if (effective_radius /= fillvalue_real .and. &
1606  effective_radius < library_radii(1)) then!{
1607  effective_radius = library_radii(1)
1608  endif!}
1609  ! end re low boundary of range
1610 
1611  ! re high boundary of range
1612  if (effective_radius > library_radii(size(library_radii))) then!{
1613  effective_radius = library_radii(size(library_radii))
1614  endif!}
1615  ! end re high boundary of range
1616 
1617 end subroutine solveretrieval
1618 
1619 subroutine linear_interpolate_for_root(residual, rad, re)
1620  !
1621  ! residual
1622  ! rad
1623  ! re
1624  !
1625  implicit none
1626 
1627  real, intent(in) :: residual(2), rad(2)
1628  real, intent(out) :: re
1629 
1630  re = -1.0*( rad(1)*residual(2)/(residual(1)-residual(2)) + &
1631  rad(2)*residual(1)/(residual(2)-residual(1)) )
1632 
1633 end subroutine linear_interpolate_for_root
1634 
1635 subroutine findinterpolationrange( n1, xx, n,x, k1, k2)
1636  !
1637  ! n1
1638  ! xx
1639  ! n
1640  ! x
1641  ! k1
1642  ! k2
1643  !
1644  implicit none
1645 
1646  integer, intent(in) :: n1, n
1647  real, intent(in) :: xx, x(n)
1648 
1649  integer,intent(out) :: k1, k2
1650 
1651  integer :: i, n2
1652 
1653  if (n > n1) then!{
1654  n2 = 0.5*n1
1655  i = 1
1656  do while (xx > x(i) .and. i < n)
1657  i = i + 1
1658  enddo
1659  k1 = max(1,i-n2)
1660  k2 = k1 + n1 - 1
1661  if (k2 > n) then!{
1662  k2 = n
1663  k1 = k2 - n1 + 1
1664  end if
1665  else!}{
1666  ! if # of exist data set n <= n1, i
1667  ! use n1 = n for interp_mas_geoolation.
1668  k1 = 1
1669  k2 = n
1670  end if
1671 
1672 end subroutine findinterpolationrange
1673 
1674 real function lagrangeinterp( xx, x, y)
1675  ! in the previous interation of the COT retrieval code this was
1676  ! known as 'BINTPB'
1677  !
1678  ! xx
1679  ! x
1680  ! y
1681  !
1682  implicit none
1683  real, intent(in) :: x(3), y(3), xx
1684  lagrangeinterp = (xx-x(2))* (xx-x(3))/ (x(1)-x(2))/ (x(1)-x(3))*y(1) + &
1685  (xx-x(3))* (xx-x(1))/ (x(2)-x(3))/ (x(2)-x(1))*y(2) + &
1686  (xx-x(1))* (xx-x(2))/ (x(3)-x(1))/ (x(3)-x(2))*y(3)
1687 end function lagrangeinterp
1688 
1689  ! sssssssssssssssssssssssssssssssssssssssssssssss
1690 subroutine check_for_signchange (x, signchange)
1691  ! sssssssssssssssssssssssssssssssssssssssssssssss
1692  !
1693  ! x
1694  ! signchange
1695  !
1696  ! *** Copied from collect 5 core_science code
1697 
1698  ! this routine reports on sign change for a set of 3 values
1699  ! signchnage == 0 -> no sign change
1700  ! signchange == 1 -> sign changes between x1 and x2
1701  ! signchange == 2 -> sign changes bweteen x2 and x3
1702 
1703  implicit none
1704 
1705  real, intent(in) :: x(3)
1706  integer, intent(out) :: signchange
1707 
1708  if ( (x(1)==0 .and. x(2)==0) .or. (x(1)==0 .and. x(3)==0) .or. &
1709  (x(2)==0 .and. x(3)==0) ) Then
1710  signchange = 0
1711  else!}{
1712  if ( sign(1.,x(1))*sign(1.,x(2))*sign(1.,x(3)) /= -1.) Then
1713  signchange =1
1714  if ( x(1) > 0 .AND. x(2) > 0 .AND. x(3) > 0) then!{
1715  signchange =0
1716  end if
1717 
1718  if ( x(1) < 0 .AND. x(2) < 0 .AND. x(3) < 0) then!{
1719  signchange =0
1720  end if
1721 
1722  else!}{
1723  signchange =1
1724  endif!}
1725  endif!}
1726 
1727  if (signchange == 1) then!{
1728  if ( sign(1.,x(1))*sign(1.,x(2)) == -1. ) signchange = 1
1729  if ( sign(1.,x(2))*sign(1.,x(3)) == -1. ) signchange = 2
1730  endif!}
1731 
1732 end subroutine check_for_signchange
1733 
1734 subroutine quad_interpolate_for_root ( radii, residual, radius_solution, &
1735  status)
1736  !
1737  ! radii
1738  ! residual
1739  ! radius_solution
1740  ! status
1741  !
1742  use generalauxtype
1743  implicit none
1744 
1745  real(single), intent(in) :: radii(:), residual(:)
1746 
1747  real(single), intent(out) :: radius_solution
1748  integer, intent(out) :: status
1749 
1750  real(double) :: d1, d2, d3, a0, a1, a2, root1, root2, z
1751 
1752  d1 = residual(1) / ((radii(1)-radii(2))*(radii(1)-radii(3)))
1753  d2 = residual(2) / ((radii(2)-radii(1))*(radii(2)-radii(3)))
1754  d3 = residual(3) / ((radii(3)-radii(1))*(radii(3)-radii(2)))
1755 
1756  a0 = d1*radii(2)*radii(3) + d2*radii(1)*radii(3) + d3*radii(1)*radii(2)
1757  a1 = -d1*(radii(2)+radii(3)) - d2*(radii(1)+radii(3)) - d3*(radii(1)+radii(2))
1758  a2 = d1 + d2 + d3
1759 
1760 
1761  z = a1**2 - 4*a0*a2
1762 
1763  if(z >= 0. .and. a2 /= 0.) then!{
1764  root1 = (-a1 + sqrt(z))/(2*a2)
1765  root2 = (-a1 - sqrt(z))/(2*a2)
1766  else!}{
1767  root1 = -999; root2 = -999
1768  status = 1
1769  return
1770  end if
1771  if (root1 < radii(1) .and. root2 < radii(1)) then!{
1772  radius_solution =-999.
1773  status = 2
1774  elseif (root1 > radii(3) .and. root2 > radii(3)) then!}{
1775  radius_solution =-999.
1776  status = 3
1777  elseif (root1 >= radii(1) .and. root1 <= radii(3)) then!}{
1778  radius_solution = root1
1779  status = 4
1780  elseif(root2 >= radii(1) .and. root2 <= radii(3)) then!}{
1781  radius_solution = root2
1782  status = 5
1783  else!}{
1784  radius_solution = -999.
1785  status = 1
1786  endif!}
1787 
1788 end subroutine quad_interpolate_for_root
1789 
1790 end module retrieval_solution_logic
subroutine findinterpolationrange(n1, xx, n, x, k1, k2)
real, dimension(set_number_of_bands) thermal_correction_oneway
real, dimension(:,:), allocatable rad37lib
subroutine solveretrieval(residual, optical_thickness_vector, library_radii, effective_radius, optical_thickness, debug, use_nearest, quality_out)
real(single), dimension(:,:), allocatable cloud_top_pressure
real(single), dimension(:,:,:,:), allocatable flux_up_water_solar
real function, public linearinterpolation(X, Y, XX)
subroutine solve_retrieval_noswir(optical_thickness_vector, library_radii, effective_radius, optical_thickness)
subroutine spline(s, x, y, n, in, t, il, iu, vl, vu, e, u)
Definition: phs.f:1348
subroutine check_for_signchange(x, signchange)
subroutine find_local_maxima(residual, local_max_vector, local_max_num)
real(single), dimension(:,:,:), allocatable int_fluxdownwater_solar
#define sign(x)
Definition: misc.h:95
integer, parameter band_0370
#define real
Definition: DbAlgOcean.cpp:26
real, dimension(set_number_of_bands) thermal_correction_twoway
subroutine find_local_minima(residual, local_min_vector, local_min_num)
integer, parameter band_0086
real(single), dimension(:,:,:), allocatable int_cloud_emissivity_ice
integer, parameter band_0213
subroutine calcdistanceandminloc(R1, R2, R1vec, R2vec, mindist, loc_index)
real(single), dimension(:,:,:), allocatable int_cloud_emissivity_water
real(single), dimension(:), allocatable library_fluxsolarzenith
real(single), dimension(:), allocatable library_taus
real, dimension(:,:), allocatable refliba
subroutine find_zero_crossings(residual, crossing_vector, crossing_num)
real(single), dimension(:,:,:), allocatable spherical_albedo_water
real, dimension(:,:), allocatable solar_zenith_angle
Definition: core_arrays.f90:6
real(single), dimension(:,:,:), allocatable int_surface_emissivity_ice
subroutine solve_for_zero_crossing(re, residual, residual_crossing_index, fillval_r4, local_min_vector, local_min_num, local_max_vector, local_max_num, retrieval, quality)
real(single), dimension(:,:,:), allocatable int_fluxdownice_solar
real(single), dimension(:,:,:), allocatable int_surface_emissivity_water
#define max(A, B)
Definition: main_biosmap.c:61
logical function is_water_phase(library_radii)
real(single), dimension(:,:,:), allocatable spherical_albedo_ice
endif() set(LIBS $
Definition: CMakeLists.txt:6
subroutine solution_re(re, residual, crossing_vector, crossing_num, local_min_vector, local_min_num, local_max_vector, local_max_num, retrieval, quality)
real function, public modis_planck(platform_name, TEMP, BAND, UNITS)
real, dimension(:), allocatable rayleigh_liq
real(single), dimension(:), allocatable ice_radii
integer, parameter top_nk_asl_contour_ice
real(single), dimension(:,:,:,:), allocatable flux_up_water_sensor
real, dimension(:,:), allocatable reflibb
logical function real_s_equal(x, y)
subroutine ray_corr_nearest(refl_source, As, iw, tau, re, Pc, sfr, fti1, fti0, fluxup_solar, fluxup_sensor, theta, theta0, phi, location, crefl)
integer, parameter band_0163
subroutine calc37radiancelibcm(intensity, intensity_g, thermal_trans_1way, thermal_trans_2way, solar_zenith, cl_emis, sf_emis)
subroutine calc37radianceliblamb(intensity, intensity_g, thermal_trans_1way, thermal_trans_2way, solar_zenith, sfr, fti1, fti0, fri1)
subroutine asl_boundary(Ram, Rbm_in, bands, radii, tau, re, lib_dist, Pc, theta, theta0, phi, phase_liquid, Ram_corr)
#define pi
Definition: vincenty.c:23
real, dimension(:,:), allocatable sensor_zenith_angle
real(single), dimension(:,:), allocatable relative_azimuth_angle
real(single), dimension(:,:,:), allocatable int_fluxupice_sensor
real(single), dimension(:,:), allocatable surface_temperature
subroutine single
Definition: single.f:2
integer, parameter band_0065
real(single), dimension(:,:,:,:), allocatable flux_up_ice_solar
subroutine solveretrieval_nearest(xx_pt, yy_pt, Ram, Rbm, twobands, radii, tau, re, lib_dist, phase_liquid, Ram_corr, quality_in, CH37_IDX, CTopT, CH37_NUM, platFormName)
subroutine linear_interpolate_for_root(residual, rad, re)
real(single), dimension(:,:,:), allocatable int_fluxdownwater_sensor
subroutine quad_interpolate_for_root(radii, residual, radius_solution, status)
subroutine asl_interior(Ram, Rbm_in, bands, radii, tau, re, lib_dist, Pc, theta, theta0, phi, phase_liquid, Ram_corr)
subroutine splint(xa, ya, y2a, n, x, y)
real, dimension(:), allocatable rayleigh_ice
subroutine, public bisectionsearch(xx, x, jlo, jhi)
real(single), dimension(:,:,:), allocatable int_fluxdownice_sensor
real(single), dimension(:,:,:,:), allocatable flux_up_ice_sensor
#define abs(a)
Definition: misc.h:90
real(single), dimension(:), allocatable library_fluxsensorzenith
real, parameter invalid_attempted_but_failed_re
integer, parameter top_nk_asl_contour_water
real function lagrangeinterp(xx, x, y)
real(single), dimension(:,:,:), allocatable int_fluxupwater_sensor
integer number_taus