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