OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
retrieval_prep_logic.f90
Go to the documentation of this file.
2 
4 
5  implicit none
6 
7 
8  integer, private :: TOTAL_POINTS, total_taus, max_allowable_tau
9  real, dimension(:), allocatable, private :: taux, rfx
10 
11  logical :: go_print
12 
13 contains
14 
15 subroutine init_retrieval(library_taus)
16 
17  real, dimension(:), intent(in) :: library_taus
18  integer :: i
19 
20  total_taus = size(library_taus)
21  total_points = total_taus+1
22  max_allowable_tau = library_taus(total_taus)
23 
24  allocate(taux(total_points))
25  allocate(rfx(total_points))
26 
27  taux(1) = 0
28  do i = 1, total_taus
29  taux(i+1) = library_taus(i)
30  enddo
31 
32 end subroutine init_retrieval
33 
34 subroutine cleanup_retrieval
35 
36  deallocate(taux)
37  deallocate(rfx)
38 
39 end subroutine cleanup_retrieval
40 
41 subroutine compute_water_path(tau, re, density, library_re, &
42  extinction_efficiency, water_path)
43  ! added by G. Wind 11.07.05 to compute the water path properly
44 
46  use generalauxtype
47  implicit none
48 
49  real, intent(in) :: tau, re, density
50  real, dimension(:), intent(in) :: extinction_efficiency, library_re
51  real, intent(out) :: water_path
52 
53  integer :: ilo, ihi
54  real :: x(2), y(2), Qe
55 
56  ilo = 0
57  ihi = 0
58 
59  ! determine the bounds for interpolation
60  call bisectionsearch(library_re, re, ilo, ihi)
61  x(1) = library_re(ilo)
62  x(2) = library_re(ihi)
63  y(1) = extinction_efficiency(ilo)
64  y(2) = extinction_efficiency(ihi)
65 
66  qe = linearinterpolation(x,y,re)
67 
68  water_path = ( 4. * tau * re * density ) / (3. * qe)
69 
70 end subroutine compute_water_path
71 
72 subroutine vis_nonabsorbing_science(reflectance_nonabsorbing, &
73  nonabsorbing_index, nonabsorbing_albedo, library_taus, &
74  library_radii, sfr,fti1,fti0, rfi, theta, theta0, phi, &
75  cloudtop_pressure, process, optical_thickness_vector)
76  !
77  ! WDR some info
78  ! I believe that for each radius in the table, this finds the optical
79  ! thickness values that give the closest reflectance to the non-absorbing
80  ! band's reflectance. Before doing that, it corrects the table refl for
81  ! the sfc albedo. It also (over land) makes a (iterative for 0.66
82  ! non-abs band for land) correction to the input point reflectance for
83  ! rayleigh effects from the atmosphere, cloud and both.
84  !
85  ! reflectance_nonabsorbing IN the reflectance to get COT vector for
86  ! nonabsorbing_index IN index of non abs band (to get right table look at)
87  ! nonabsorbing_albedo IN the sfc albedo in non abs band
88  ! library_taus IN tau axis values in refl table
89  ! library_radii IN re axis values (ice or water or...)
90  ! sfr IN (re x Lam x tau) spherical albedo (ice or water or...)
91  ! fti1 IN ( x x ) fluxdownwater_sensor?
92  ! fti0 IN ( x x ) fluxdownwater_solar?
93  ! rfi IN ( tau,lambda, re) reflectance table for pixel view geometry
94  ! theta IN sen zen
95  ! theta0 IN sol zen
96  ! phi IN rel azimuth
97  ! cloudtop_pressure IN cloud top pressure
98  ! process IN structure with phase info
99  ! optical_thickness_vector OUT output set of COT candidates for the radii
100  ! in the table
101 
102  ! sep modification w/Rayleigh scattering, 24 May 2005, etc.
103 
104  use generalauxtype
109 
110  implicit none
111 
112  type(cloudphase), intent(in) :: process
113  integer, intent(in) :: nonabsorbing_index
114 
115  real, intent(in) :: reflectance_nonabsorbing, nonabsorbing_albedo, &
116  theta, theta0, phi, cloudtop_pressure
117  real(single), dimension (:), intent(in) :: library_taus, library_radii
118  real(single), dimension (:,:,:), intent(in) :: sfr, fti1, fti0, rfi
119 
120  real, intent(out) :: optical_thickness_vector(:)
121 
122 
123 
124  !local variables
125  integer :: radii, i, ii
126  integer :: correction_iteration, maximum_correction_iterations
127  real :: reflectance_corrected, local_reflectance_nonabsorbing, &
128  optical_thickness
129  ! real :: max_allowable_tau
130  ! integer :: TOTAL_POINTS
131  ! real, dimension(:), allocatable :: taux, rfx
132  real, dimension(:), allocatable :: rfi1
133 
134  ! parameter (max_allowable_tau = 200.)
135 
136  ! TOTAL_POINTS = size(library_taus)+1
137 
138  radii = size(library_radii)
139 
140  allocate( rfi1(radii) )
141  ! allocate( taux(TOTAL_POINTS) )
142  ! allocate( rfx(TOTAL_POINTS))
143 
144 
145  ! add the tau=0 to the working list of taus
146  ! taux(1) = 0
147  ! do i = 1, total_taus
148  ! taux(i+1) = library_taus(i)
149  ! enddo
150 
151  ! calculated refl value for tauc=inf at non absorbing wavelength
152  ! for all radii
153  ! now this is simply the maximum library reflectance.
154  if (.not. cox_munk) then
155  rfi1(1:radii) = rfi(total_taus,nonabsorbing_index,1:radii)
156  else
157  rfi1(1:radii) = rfi(total_points,nonabsorbing_index,1:radii)
158  endif
159 
160  DO i = 1, radii
161 
162  ! sep, 25 May: this has to be inside the re loop, otherwise
163  ! local_reflectance_nonabsorbing decreases
164  ! with each subsequent re, in addition to each subsequent iterations
165  local_reflectance_nonabsorbing = reflectance_nonabsorbing
166 
167  ! Perform Rayleigh correction iteration loop only for 0.65 um band
168 #if ASTER_INST
169  if (nonabsorbing_index==1 .or. nonabsorbing_index == 2) then!{
170 #else
171  if (nonabsorbing_index==1) then!{
172 #endif
173  maximum_correction_iterations = 3
174  else!}{
175  maximum_correction_iterations = 1
176  end if
177 
178  ! rfx index=1 is set to the surface albedo
179  if (.not. cox_munk) then
180  rfx(1) = nonabsorbing_albedo
181 
182  ! Modify the reflectances by non-absorbing sfc albedo
183  rfx(2:total_points) = rfi(1:total_taus, nonabsorbing_index, i) + &
184  (nonabsorbing_albedo * fti1(1:total_taus, nonabsorbing_index, i) * &
185  fti0(1:total_taus, nonabsorbing_index, i)) / &
186  ( 1.0 - nonabsorbing_albedo * sfr(1:total_taus, nonabsorbing_index, i))
187  else
188  rfx(1:total_points) = rfi(1:total_points, nonabsorbing_index, i)
189  endif
190 
191  ! save the nonabsorbing library off to the side so we can use it
192  ! if necessary during the alternate retrieval
193  refliba(1:total_points, i) = rfx(:)
194 
195  do correction_iteration=1, maximum_correction_iterations
196 
197  ! wind fix 6.24.05 correct for divide-by-zero and also indexing
198  ! changed to (i) from (1:radii)
199  if ( (rfi1(i) - local_reflectance_nonabsorbing) < 0.0001) then!{
200  optical_thickness_vector(i) = max_allowable_tau
201  exit
202  endif!}
203 
204  call interpolate_refl_cot (local_reflectance_nonabsorbing, rfx, taux, &
205  optical_thickness)
206 
207  optical_thickness_vector(i) = optical_thickness
208 
209 #if ASTER_INST
210  if ( (nonabsorbing_index == 1 .or. nonabsorbing_index == 2) .and. &
211  optical_thickness > 0. .and. maximum_correction_iterations /= 1 ) then!{
212 #else
213  if (nonabsorbing_index == 1 .and. optical_thickness > 0. .and. &
214  maximum_correction_iterations /= 1 ) then!{
215 #endif
216  call rayleighcorrection (reflectance_nonabsorbing, cloudtop_pressure, &
217  process, optical_thickness, nonabsorbing_albedo, &
218  fti1(:,nonabsorbing_index,i),fti0(:,nonabsorbing_index,i), &
219  sfr(:,nonabsorbing_index,i), nonabsorbing_index,i,theta0,theta,phi, &
220  reflectance_corrected)
221 
222  local_reflectance_nonabsorbing = reflectance_corrected
223 
224  ! collect the rayleigh-corrected reflectance for later storage to disk
225  if (process%icecloud == 1) then
226  rayleigh_ice(i) = local_reflectance_nonabsorbing
227  else if (process%watercloud == 1) then
228  rayleigh_liq(i) = local_reflectance_nonabsorbing
229  endif
230 
231  if (local_reflectance_nonabsorbing > rfi1(i)) then!{
232  optical_thickness_vector(i) = max_allowable_tau
233  exit
234  endif!}
235 
236  else!}{
237  exit
238  endif!}
239 
240  end do ! Rayleigh correction loop
241 
242  if ( (rfi1(i) - local_reflectance_nonabsorbing) < 0.0001) &
243  optical_thickness_vector(i) = max_allowable_tau
244 
245  call interpolate_refl_cot (local_reflectance_nonabsorbing, rfx, taux, &
246  optical_thickness)
247  optical_thickness_vector(i) = optical_thickness
248 
249  END DO ! radii loop for nonabsorbing band optical thickness
250 
251  do i = 1, radii
252  ! if (optical_thickness_vector(i) > 100.) optical_thickness_vector(i) = 100.
253  if(rfi1(i) < reflectance_nonabsorbing ) &
254  optical_thickness_vector(i) = max_allowable_tau
255  end do
256 
257  deallocate (rfi1)
258  ! deallocate(taux, rfx)
259 
260 end subroutine vis_nonabsorbing_science
261 !
262 
263 subroutine vis_absorbing_science(optical_thickness_vector, &
264  reflectance_absorbing, absorbing_index, absorbing_albedo, &
265  library_taus, library_radii, sfr,fti1,fti0, rfi, &
266  residual, maxradii, debug )
267  !
268  ! Use the tau(Re) found for the non-absorb refl and look in the
269  ! abs table at the same locations and get the fraction diff (relative
270  ! to the pixel reflectance) between
271  ! the table refl and the pixel refl, output as residual. Again, the table
272  ! refl are corrected for the sfc albedo before doing this
273  !
274  ! optical_thickness_vector IN the best COT found for each table radius
275  ! reflectance_absorbing IN the target abs refl to match
276  ! absorbing_index IN which abs band being used
277  ! absorbing_albedo IN sfc albedo
278  ! library_taus IN tau axis in table
279  ! library_radii IN reff axis in table
280  ! sfr IN spherical_albedo_water
281  ! fti1 IN fluxdownwater_sensor
282  ! fti0 IN fluxdownwater_solar
283  ! rfi IN reflectance table
284  ! residual OUT residual for each radii again, this is the
285  ! abs refl(point) - refl(radius). so this goes to solveretrieval
286  ! to declare the winner.
287  ! maxradii OUT
288  ! debug IN debug switch
289  !
290  ! sep, 4 May: example call
291  ! WDR nore args, so ??
292  !
293  ! call vis_absorbing_science(optical_thickness_vector, &
294  ! band_measurements(xpoint, absorbingband_index, ypoint), &
295  ! absorbingband_index, &
296  ! surface_albedo(xpoint, ypoint,absorbingband_index), &
297  ! library_wavelengths, &
298  ! library_taus, &
299  ! ice_radii, &
300  ! asymmetry_ice, &
301  ! singlescattering_ice, &
302  ! extinction_ice, &
303  ! ak_ice, &
304  ! el_ice, &
305  ! em_ice, &
306  ! en_ice, &
307  ! spherical_albedo_ice, &
308  ! int_escapefuncice_solar, &
309  ! int_fluxdownice_sensor, &
310  ! int_fluxdownice_solar, &
311  ! int_escapefuncice_sensor, &
312  ! int_reflectance_ice, &
313  ! residual,maxradii,debug)
314 
315  ! with
316  ! 1) a known vector of optical thicknesses
317  ! 2) absorbing band reflectance for the scene of interest
318  ! 3) library values for the scene of interest
319  !
320  ! cloud top effective particle radius is calculated
321 
322  use generalauxtype
325  use libraryarrays, only: reflibb
326 
327  implicit none
328 
329  real, intent(in) :: optical_thickness_vector(:), reflectance_absorbing, &
330  absorbing_albedo
331 
332  integer, intent(in) :: absorbing_index
333 
334  real(single), intent(in) :: library_taus(:), library_radii(:), &
335  sfr(:,:,:), fti1(:,:,:), fti0(:,:,:), rfi(:,:,:)
336 
337  real, intent(out) :: residual(:)
338  logical, intent(in) :: debug
339  integer, intent(out) :: maxradii
340 
341  ! local variables
342  real :: rf1
343 
344  real, allocatable :: rfi1(:)
345  real, allocatable :: localoptical_thickness_vector(:)
346  ! real, allocatable :: taux(:)
347 
348  integer :: radii, i, ii
349 
350  ! real, dimension(:), allocatable :: rfx
351  ! integer :: TOTAL_POINTS
352  integer :: lowbound, highbound, taubounds(2)
353  real :: iftau(2), refvals(2)
354  real :: interp_tau
355 
356  lowbound = 0 ! WDR-UIV
357  highbound = 0 ! WDR-UIV
358 
359  ! TOTAL_POINTS = size(library_taus)+1
360 
361  ! total_taus = size(library_taus)
362  radii = size(library_radii)
363 
364  ! allocate(rfx(TOTAL_POINTS))
365 
366  allocate(rfi1(radii))
367  ! allocate(taux(TOTAL_POINTS))
368  allocate(localoptical_thickness_vector(radii))
369 
370  ! science fixer, for when the semi-infinite layer library reflectance
371  ! goes wiggly
372  ! apparently, a (-) tau can occur?
373  do i = radii, 2, -1
374  maxradii = i
375  if (optical_thickness_vector(i) > 0. ) exit
376  enddo
377 
378  ! insert the zero tau into the tau vector
379  ! taux(1) = 0.
380  ! do i = 1, total_taus
381  ! taux(i+1) = library_taus(i)
382  ! enddo
383 
384  ! get reflectance residual (library - measurement) for the absorbing band
385 
386  localoptical_thickness_vector = optical_thickness_vector
387 
388  ! calculated refl value for tauc=inf at absorbing wavelength for all radii
389 
390  if (.not. cox_munk) then
391  rfi1(1:radii) = rfi(total_taus,absorbing_index,1:radii)
392  else
393  rfi1(1:radii) = rfi(total_points,absorbing_index,1:radii)
394  endif
395 
396  ! reflection functions for channel 2 and 3 with fixed tc
397  ! all variables must be redefined because this part is used
398  ! after line-scanning for ch-1.
399 
400  ! optical thickness for the appropriate wavelength =
401  ! qext(wavelength)/qext(0.65 um) * tauc(0.65 um)
402  ! determine the reflectance at calculated optical thickness
403 
404  do i = 1,maxradii
405 
406  if (.not. cox_munk) then
407  rfx(1) = absorbing_albedo
408 
409  rfx(2:total_points) = rfi(1:(total_points-1),absorbing_index,i) + &
410  fti1(1:(total_points-1),absorbing_index,i) * &
411  fti0(1:(total_points-1),absorbing_index,i) * &
412  absorbing_albedo / &
413  ( 1.-absorbing_albedo*sfr(1:(total_points-1),absorbing_index,i))
414  else
415  rfx(1:total_points) = rfi(1:total_points,absorbing_index,i)
416  endif
417 
418  ! save the absorbing library off to the side so we can use it if necessary
419  ! during the alternate retrieval
420  reflibb(1:total_points, i) = rfx(:)
421 
422  call bisectionsearch(taux, localoptical_thickness_vector(i), &
423  lowbound, highbound)
424  taubounds(1) = lowbound
425  taubounds(2) = highbound
426  iftau(1) = taux(taubounds(1))
427  iftau(2) = taux(taubounds(2))
428 
429  refvals(1) = rfx(lowbound)
430  refvals(2) = rfx(highbound)
431 
432  rf1 = linearinterpolation(iftau,refvals,localoptical_thickness_vector(i))
433 
434  residual(i) = rf1/reflectance_absorbing- 1.0
435 
436  enddo
437 
438 
439  deallocate(rfi1, localoptical_thickness_vector)
440  ! deallocate(taux, rfx)
441 
442 end subroutine vis_absorbing_science
443 
444 subroutine interpolate_refl_cot(reflectance, reflectance_vector, &
445  optical_thickness_vector, optical_thickness)
446  !
447  ! reflectance
448  ! reflectance_vector
449  ! optical_thickness_vector
450  ! optical_thickness
451  !
452  ! We need to interpolate the reflectance vector to get the optical
453  ! thickness that corresponds to the reflectance given. We cannot
454  ! assume however that the reflectance
455  ! is uniformly increasing as a function of the optical thickness.
456  ! There are cases
457  ! where there maybe multiple solutions of the optical thickness
458  ! for a given reflectance
459  ! In this case we take the larger solution and move on.
460 
461  use generalauxtype
463 
464  implicit none
465 
466  real, intent(in) :: reflectance, reflectance_vector(:), &
467  optical_thickness_vector(:)
468  real, intent(out):: optical_thickness
469 
470  integer :: refl_size, tau_size
471  integer :: lowbound, highbound, refbounds(2)
472  real :: ifref(2), tauvals(2)
473  real :: interp_tau
474 
475  lowbound = 0 ! WDR-UIV
476  highbound = 0 ! WDR-UIV
477 
478  refl_size = size(reflectance_vector)
479 
480  if (reflectance < reflectance_vector(1) ) then!{
481  ! reflectance is out of range. no interpolation is possible
482  optical_thickness = - 1.
483  return
484  endif!}
485 
486  ! reflectance is super-bright, thick cloud, so just set to max
487  ! tau and be done with it,
488  ! no interpolation possible, so be it.
489  if ( reflectance > reflectance_vector(refl_size) ) then
490  tau_size = size(optical_thickness_vector)
491  optical_thickness = optical_thickness_vector(tau_size)
492  return
493  endif
494 
495  ! doesn't matter nothing. We will use the standard linear
496  ! interpolation with the library that big.
497  ! we can probably get away with it.
498 
499  call bisectionsearch(reflectance_vector, reflectance, lowbound, highbound)
500  refbounds(1) = lowbound
501  refbounds(2) = highbound
502  ifref(1) = reflectance_vector(refbounds(1))
503  ifref(2) = reflectance_vector(refbounds(2))
504 
505  tauvals(1) = optical_thickness_vector(lowbound)
506  tauvals(2) = optical_thickness_vector(highbound)
507  optical_thickness = linearinterpolation(ifref,tauvals,reflectance)
508 
509 end subroutine interpolate_refl_cot
510 
511 subroutine rayleighcorrection (reflectance, cloudtoppressure, process, &
512  optical_thickness, nonabsorbing_galbedo, fti1, fti0, sfr, iw, ir, &
513  solarzenith, sensorzenith, azimuth, reflectance_corrected)
514  !
515  ! reflectance IN non-absorbing reflectance, I believe only the 0.66
516  ! um band value is used
517  ! cloudtoppressure IN pressure of cloud top
518  ! process IN processing info, has cloud phase
519  ! optical_thickness IN optical thickness at current point
520  ! nonabsorbing_galbedo IN surface albedo
521  ! fti1 IN fluxdownwater_sensor at the current table location
522  ! fti0 IN fluxdownwater_solar at the current table location
523  ! sfr IN spherical albedo (ice or water or...)
524  ! iw IN non absorbing index, probably 1 for .66 um
525  ! ir IN table radii index
526  ! solarzenith, sensorzenith, azimuth point 's view geometry
527  ! reflectance_corrected OUT final reflectance, rayleigh corrected
528  !
529  ! Versioning history:
530  !
531  ! Initial, but incomplete, portions written by M. Gray
532  ! Modified by B. Wind, G. Wind to add cloud albedo
533  ! 5-16-05, etc.: Modified by S. Platnick to include non-zero
534  ! surface albedo and reflectances in the asymptotic regime,
535  ! as well as changes to loop logic/structure in vis_nonabsorbing_science
536  ! This algorithm is based on the Rayleigh correction algorithm
537  ! described in Wang and King (1997). The
538  ! Rayleigh correction algorithm described in the paper is derived
539  ! for a black surface and describes
540  ! results for water clouds only. Here the algorithm has been
541  ! extended to a non-zero surface albedo
542  ! and uses forward library water and ice cloud fluxes based on
543  ! the decision tree cloud phase.
544 
545  ! VARIABLE TRANSLATION
546  !
547  ! nonabsorbing_galbedo = sfc albedo in nonabsorbing band; scalar
548  ! fti0, fti1 = transmitted fluxes interpolated to mu0, mu;
549  ! indexing: (tau index)
550  ! sfr = spherical albedo; indexing: (tau index)
551  ! iw, ir = band and effective radius indices, respectively
552 
553  use generalauxtype
554  use libraryarrays
556 
557  implicit none
558 
559  !intent in/out variables
560  type(cloudphase), intent(in) :: process
561  integer, intent(in) :: iw, ir
562  real, intent(in) :: reflectance, cloudtoppressure, &
563  optical_thickness, nonabsorbing_galbedo, &
564  solarzenith, sensorzenith, azimuth
565  real, intent(in) :: sfr(:), fti0(:), fti1(:)
566 
567  real, intent(out) :: reflectance_corrected
568 
569  !local variables
570  real :: taur, rd, cloud_albedo
571  real :: mu0, mu, flux0, flux1, pray, x, refl_s
572  real :: local_int_fluxup_solar,local_int_fluxup_sensor
573 
574  real, parameter :: surfacepressure = 1013. ! Fixed sfc P!
575  real, parameter :: Cm = 0.84
576  real, parameter :: taur0(2) = (/0.044, 0.025/)
577  ! the second position of taur0 is for ASTER only, none of
578  ! the other instruments would use it,
579  ! because none of the other instruments do rayleigh correction
580  ! for non-0.65um band
581 
582  local_int_fluxup_solar=0.; local_int_fluxup_sensor=0.
583  reflectance_corrected=0.
584 
585  ! Rayleigh optical depth from TOA to cloud-top
586  ! WDR TOA-TOC thickness, Wang&King Eq 12
587  taur = taur0(iw)*cloudtoppressure/surfacepressure
588 
589  mu0 = cos(d2r*solarzenith)
590  mu = cos(d2r*sensorzenith)
591 
592  if(process%icecloud == 1) then!{
593  call interp_lib_reflflux_cloudalbedo( mu0, mu, optical_thickness, &
594  nonabsorbing_galbedo, sfr, fti1, fti0, iw, ir, &
596  flux_up_ice_sensor, local_int_fluxup_solar, local_int_fluxup_sensor)
597  else!}{
598  call interp_lib_reflflux_cloudalbedo(mu0, mu, optical_thickness, &
599  nonabsorbing_galbedo, sfr, fti1, fti0, iw, ir, &
601  flux_up_water_solar, flux_up_water_sensor, local_int_fluxup_solar, &
602  local_int_fluxup_sensor)
603  endif!}
604 
605 
606  ! Rayleigh scattering phase function, where x=scattering angle
607  ! (Eq. 3, Wang and King)
608  ! sep, 13 May: confirmed that pi is not needed in pray formula
609  ! since it is for reflectance, not intensity.
610  ! sep, 16 May: w/KIng, confirmed that this formula is correct
611  ! for the usual definition of relative azimuth
612  ! and mu, mo0 defined to be always positive.
613 
614  x = -mu0*mu + sqrt((1.-mu0**2)*(1.-mu**2))*cos(d2r*azimuth)
615  pray = 3.*(1.+x**2)/4.0
616 
617  ! compute single scattering reflectance from molecules
618  ! bounded by cloud layer (portion of Eq. 11, Wang and King)
619 
620  refl_s = taur*pray/(4.*mu0*mu) + &
621  0.5*taur* local_int_fluxup_sensor * exp(-taur/mu )/mu0 + &
622  0.5*taur* local_int_fluxup_solar * exp(-taur/mu0)/mu
623 
624  ! remove rayleigh scattering effects (Eq. 11, Wang and King)
625 
626  reflectance_corrected = (reflectance - refl_s)*exp(cm*taur*(1./mu0 + 1./mu))
627 
628 end subroutine rayleighcorrection
629 
630 subroutine interp_lib_reflflux_cloudalbedo(miu0, miu, &
631  optical_thickness, nonabsorbing_galbedo, sfr, fti1, fti0, iw, ir, &
632  fluxsolarzenithangles, fluxsensorzenithangles, &
633  fluxup_solar, fluxup_sensor, interp_fluxup_solar, interp_fluxup_sensor)
634  !
635  ! miu0 IN cos( solz )
636  ! miu IN cos( senz )
637  ! optical_thickness IN optical thickness at current point
638  ! nonabsorbing_galbedo IN surface albedo
639  ! sfr IN spherical albedo (ice or water or...)
640  ! fti1 IN fluxdownwater_sensor at the current table location
641  ! fti0 IN fluxdownwater_solar at the current table location
642  ! iw IN non absorbing index, probably 1 for .66 um
643  ! ir IN table radii index
644  ! fluxsolarzenithangles IN list of the solz angles in the table
645  ! fluxsensorzenithangles IN list of the senz angles in the table
646  ! fluxup_solar IN array of table up sol flux (n_solz, n_tau, n_wav,
647  ! n_ice_rad )
648  ! fluxup_sensor IN array of table up sen flux (n_solz, n_tau, n_wav,
649  ! n_ice_rad )
650  ! interp_fluxup_solar OUT sol flux at the solz, tau, wave, and radius
651  ! interp_fluxup_sensor OUT sen flux at the solz, tau, wave, and radius
652 
653  use generalauxtype
655  use libraryarrays
656  implicit none
657 
658  !intent in/out variables
659  integer, intent(in) :: iw, ir
660  real, intent(in) :: miu0, miu, optical_thickness, nonabsorbing_galbedo
661  real, intent(in) :: sfr(:), fti0(:), fti1(:)
662  real, dimension(:), intent(in) :: fluxsolarzenithangles, &
663  fluxsensorzenithangles
664  real, dimension(:,:,:,:), intent(in) :: fluxup_solar, fluxup_sensor
665 
666  real, intent(out) :: interp_fluxup_solar, interp_fluxup_sensor
667 
668  !local variables
669  integer :: lowbound, highbound, its, nts, taubounds(2)
670  real :: scaledTau, iftaus(2), angles(2), functionvalues(2)
671  real :: q1, interp_fti0, interp_fti1, interp_sfr
672  real, dimension(:), allocatable :: fluxup_solar_tau,fluxup_sensor_tau
673 
674  ! ---------------------------------------------------------------
675  ! Subroutine to interpolate .65 micron band cloud albedo library
676  ! in angle and tau space
677  ! --------------------------------------------------------------
678 
679  ! sep NOTES:
680  !
681  ! 'bisectionsearch' subroutine (looks like numerical recipe code)
682  ! and function 'linearinterpolation'
683  ! both exist in modis_numerical_module.f90
684  !
685  ! Get the cloud-top albedo, including the effect of a non-zero surface albedo
686  !
687  ! For non-asymptotic regime:
688  !
689  ! With a non-zero surface albedo, the cloud-top albedo is:
690  !
691  ! A(tau, mu, galb) = A(tau, mu, galb=0) +
692  ! T(tau, mu, galb=0)*galb*Tsph(tau)/(1 - Rsph(tau)*galb)
693  !
694  ! where,
695  !
696  ! A(tau, mu0, galb=0) = local_int_fluxup_solar
697  ! A(tau, mu, galb=0) = local_int_fluxup_sensor
698  ! T(tau, mu, galb=0) = transmitted flux = fti1/0
699  ! = interp_fluxdown_sensor/solar
700  ! Rsph(tau) = "spherical" albedo for galb=0
701  ! Tsph(tau) = "spherical" transmittance for galb=0 = 1
702  ! - Rsph for conservative scattering
703  !
704  ! For asymptotic regime, the cloud-surface albedo for conservative
705  ! scattering can be simply written as (from M. King notes):
706  !
707  ! A(tau, mu, galb) =
708  ! 1 - 4*(1-galb)*K(mu0)/[3*(1-galb)*(1-g)*(tau+2q0) + 4*galb]
709 
710  ! NOTE: from modis_frontend_module.f90:1522:
711  ! allocate(flux_up_ice_solar (number_fluxsolarzenith, number_taus,
712  ! number_wavelengths, number_iceradii))
713 
714 
715  interp_fluxup_solar=0.; interp_fluxup_sensor=0.
716 
717  ! allocations and initializations
718  nts = total_taus !size(library_taus)
719  allocate(fluxup_solar_tau(nts),fluxup_sensor_tau(nts))
720  interp_fluxup_solar = 0.; interp_fluxup_sensor = 0.
721  taubounds = 0; lowbound=0; highbound=0; iftaus=0.
722 
723  ! -------------------------------------------------------
724  ! NON-ASYMPTOTIC REGIME: CLOUD-TOP ALBEDO w/BLACK SURFACE
725  ! -------------------------------------------------------
726 
727  ! sep, 24May: scaledTau<0.5 was not being explicitly counted
728  ! for in non-asymptotic calculations.
729  ! Fortunately (or by design) the values returned for
730  ! library_taus(0) and fluxup_solar_tau(0) = 0,
731  ! despite the arrays not being declared for a zero index.
732  ! Following modified to treat scaledTau<0.5 explicitly.
733 
734  !
735  ! Tau index bounds for the scaled optical thickness
736  !
737  if (optical_thickness < library_taus(1)) then!{
738  taubounds(1) = 1
739  iftaus(1) = 0.
740  iftaus(2) = library_taus(taubounds(1))
741  else!}{
742  call bisectionsearch(library_taus, optical_thickness, lowbound, highbound)
743  taubounds(1) = lowbound
744  taubounds(2) = highbound
745  iftaus(1) = library_taus(taubounds(1))
746  iftaus(2) = library_taus(taubounds(2))
747  end if
748 
749  !
750  ! Interpolation of fti0, fti1, and srf to the scaled optical
751  ! thickness (for incorporating surface reflectance)
752  !
753  if (nonabsorbing_galbedo > 0.) then
754 
755  if (optical_thickness < library_taus(1)) then!{
756  functionvalues(1) = 1.
757  functionvalues(2) = fti0(1)
758  interp_fti0 = linearinterpolation(iftaus,functionvalues,optical_thickness)
759  functionvalues(1) = 1.
760  functionvalues(2) = fti1(1)
761  interp_fti1 = linearinterpolation(iftaus,functionvalues,optical_thickness)
762  functionvalues(1) = 0.
763  functionvalues(2) = sfr(1)
764  interp_sfr = linearinterpolation(iftaus,functionvalues,optical_thickness)
765  else!}{
766  functionvalues(1) = fti0(lowbound)
767  functionvalues(2) = fti0(highbound)
768  interp_fti0 = linearinterpolation(iftaus,functionvalues,optical_thickness)
769  functionvalues(1) = fti1(lowbound)
770  functionvalues(2) = fti1(highbound)
771  interp_fti1 = linearinterpolation(iftaus,functionvalues,optical_thickness)
772  functionvalues(1) = sfr(lowbound)
773  functionvalues(2) = sfr(highbound)
774  interp_sfr = linearinterpolation(iftaus,functionvalues,optical_thickness)
775  end if
776 
777  else
778 
779  endif
780 
781  !
782  ! Interpolation for solar zenith angles and scaled optical thickness
783  !
784  call bisectionsearch(library_fluxsolarzenith, miu0, lowbound, highbound)
785  angles(1) = fluxsolarzenithangles(lowbound)
786  angles(2) = fluxsolarzenithangles(highbound)
787 
788  do its = 1,nts
789  functionvalues(1) = fluxup_solar(lowbound,its, iw,ir)
790  functionvalues(2) = fluxup_solar(highbound,its,iw,ir)
791  fluxup_solar_tau(its) = linearinterpolation(angles,functionvalues,miu0)
792  enddo
793 
794  if (optical_thickness < library_taus(1)) then!{
795  functionvalues(1) = 0.
796  functionvalues(2) = fluxup_solar_tau(taubounds(1))
797  else!}{
798  functionvalues(1) = fluxup_solar_tau(taubounds(1))
799  functionvalues(2) = fluxup_solar_tau(taubounds(2))
800  end if
801  interp_fluxup_solar = linearinterpolation(iftaus,functionvalues, &
802  optical_thickness)
803 
804  !
805  ! Interpolation for sensor zenith angles and scaled optical thickness
806  !
807  call bisectionsearch(library_fluxsensorzenith, miu, lowbound, highbound)
808  angles(1) = fluxsensorzenithangles(lowbound)
809  angles(2) = fluxsensorzenithangles(highbound)
810 
811  do its = 1,nts
812  functionvalues(1) = fluxup_sensor(lowbound, its,iw,ir)
813  functionvalues(2) = fluxup_sensor(highbound,its,iw,ir)
814  fluxup_sensor_tau(its) = linearinterpolation(angles,functionvalues,miu)
815  enddo
816 
817  if (optical_thickness < library_taus(1)) then!{
818  functionvalues(1) = 0.
819  functionvalues(2) = fluxup_sensor_tau(taubounds(1))
820  else!}{
821  functionvalues(1) = fluxup_sensor_tau(taubounds(1))
822  functionvalues(2) = fluxup_sensor_tau(taubounds(2))
823  end if
824  interp_fluxup_sensor = linearinterpolation(iftaus,functionvalues, &
825  optical_thickness)
826 
827 
828  ! --------------------------------
829  ! NON-ASYMPTOTIC REGIME: w/SURFACE
830  ! --------------------------------
831 
832  ! A(tau, mu, galb) = A(tau, mu, galb=0) +
833  ! T(tau, mu, galb=0)*galb*Tsph(tau)/(1 - Rsph(tau)*galb)
834  if (nonabsorbing_galbedo > 0.) then
835 
836  interp_fluxup_solar = interp_fluxup_solar + &
837  interp_fti0*nonabsorbing_galbedo*(1-interp_sfr)/ &
838  (1 - interp_sfr*nonabsorbing_galbedo)
839  interp_fluxup_sensor = interp_fluxup_sensor + &
840  interp_fti1*nonabsorbing_galbedo*(1-interp_sfr)/ &
841  (1 - interp_sfr*nonabsorbing_galbedo)
842  else
843  ! cox-munk
844  ! we do nothing, the surface assumed not to contribute
845  ! anything in this case. This would be the case
846  ! when 0.86um band saturated.
847  endif
848 
849  deallocate(fluxup_solar_tau,fluxup_sensor_tau)
850 
851 end subroutine interp_lib_reflflux_cloudalbedo
852 
853 subroutine nir_absorbing_science(platform_name, optical_thickness_vector, &
854  reflectance_absorbing, absorbing_index, absorbing_albedo, &
855  xpoint, ypoint, CTT, thermal_trans_1way, thermal_trans_2way, &
856  library_taus, library_radii, sfr,fti1,fti0,fri1, rfi, cl_emis, sf_emis, &
857  residual, maxradii, channel_number_37, emission_uncertainty_pw, &
858  emission_uncertainty_Tc, sigma_R37_PW, debug)
859 
860  ! sep, 4 May: example call
861  !
862  ! call nir_absorbing_science(platform_name, &
863  ! optical_thickness_vector, &
864  ! band_measurements(xpoint, absorbingband_index, ypoint), &
865  ! absorbingband_index - 1, &
866  ! surface_albedo(xpoint, ypoint,absorbingband_index), &
867  ! cloud_top_temperature(xpoint, ypoint), &
868  ! surface_temperature(xpoint, ypoint), &
869  ! thermal_trans_1way, &
870  ! thermal_trans_2way, &
871  ! solar_zenith_angle(xpoint,ypoint), &
872  ! library_taus, &
873  ! ice_radii, &
874  ! spherical_albedo_ice, sfr &
875  ! int_fluxdownice_sensor, fti1 &
876  ! int_fluxdownice_solar, fti0 &
877  ! int_fluxupice_sensor, fr1 &
878  ! int_reflectance_ice, rfi &
879  ! int_cloud_emissivity_water, &
880  ! int_surface_emissivity_water, &
881  ! residual, maxradii, channel_37, debug)
882 
883 
884  use generalauxtype
887  use libraryarrays, only : reflibb
888  use planck_functions
895 
896  implicit none
897 
898  character*(*),intent(in):: platform_name
899 
900  real, intent(in) :: optical_thickness_vector(:), reflectance_absorbing, &
901  absorbing_albedo
902 
903  integer, intent(in) :: absorbing_index, channel_number_37, xpoint, ypoint
904 
905  real, intent(in) :: thermal_trans_2way,thermal_trans_1way, CTT
906 
907  real(single), intent(in) :: library_taus(:), library_radii(:), &
908  sfr(:,:,:), fti1(:,:,:), fti0(:,:,:), fri1(:,:,:), &
909  rfi(:,:,:), cl_emis(:,:,:), sf_emis(:,:,:)
910 
911  real, intent(inout) :: emission_uncertainty_pw(:), &
912  emission_uncertainty_Tc(:), sigma_R37_PW(:)
913  logical, intent(in) :: debug
914  real, intent(out) :: residual(:)
915  integer, intent(out) :: maxradii
916 
917  integer :: radii, wavelengths,i
918  real :: ReflectanceSolarMeasured,rf1, rtherm37
919  real :: tc, local_trans_1way, local_trans_2way
920  real, allocatable :: localoptical_thickness_vector(:), rfi1(:)
921  ! real, allocatable :: taux(:)
922 
923  real :: rtherm37_high, rtherm37_low, rsm_low, rsm_high
924  real :: emission_low, emission_high, emission_reg
925  real :: solar_zenith
926 
927  real :: Es, Ec, Es_gnd, B_Tc, sigmaZ1, sigmaZ2
928  real :: B_Tg, B_Tc_low, B_Tc_high, Z2_term, Trans_ratio, sigmaPW_squared
929 
930  ! integer :: TOTAL_POINTS
931  ! TOTAL_POINTS = size(library_taus) + 1
932 
933  solar_zenith = solar_zenith_angle(xpoint, ypoint)
934 
935  ! total_taus = size(library_taus)
936  radii = size(library_radii)
937 
938  ! Early exit criteria. If we have no thermal information a retrieval is
939  ! impossible
940 
941  if (ctt < 0. ) then!{
942  residual =-999.
943  return
944  endif!}
945 
946  allocate(localoptical_thickness_vector(radii))
947  allocate(rfi1(radii))
948  ! allocate(taux(TOTAL_POINTS))
949 
950  ! taux(1) = 0.
951  ! do i = 1, total_taus
952  ! taux(i+1) = library_taus(i)
953  ! enddo
954 
955 
956  ! science fixer, for when the semi-infinite layer library
957  ! reflectance goes wiggly
958  do i = radii, 2, -1
959  maxradii = i
960  if (optical_thickness_vector(i) > 0. ) exit
961  enddo
962 
963  if (.not. cox_munk) then
964  rfi1(1:radii) = rfi(total_taus,absorbing_index,1:radii)
965  else
966  rfi1(1:radii) = rfi(total_points,absorbing_index,1:radii)
967  endif
968 
969  localoptical_thickness_vector = optical_thickness_vector
970 
971  if (thermal_trans_1way < 0. .or. thermal_trans_1way > 1.) then!{
972  local_trans_1way = 1.
973  else!}{
974  local_trans_1way = thermal_trans_1way
975  endif!}
976 
977  if (thermal_trans_2way < 0. .or. thermal_trans_2way > 1.) then!{
978  local_trans_2way = 1.
979  else!}{
980  local_trans_2way = thermal_trans_2way
981  endif!}
982 
983  ! why call modis_planck ten billion times for each Re when this
984  ! number never changes
985  ! as long as we're processing a single pixel.
986 
987  b_tc = modis_planck(platform_name, ctt, channel_number_37, 1)
988  b_tg = modis_planck(platform_name, surface_temperature(xpoint, ypoint), &
989  channel_number_37, 1)
990  b_tc_low = modis_planck(platform_name, tc_low_for_delta, &
991  channel_number_37, 1)
992  b_tc_high = modis_planck(platform_name, tc_high_for_delta, &
993  channel_number_37, 1)
994  sigmaz1 = const_c * (reflectance_absorbing / (local_trans_2way**2)) &
995  * transprime_2way * &
996  ((2.*watervapor_error)*abovecloud_watervapor(xpoint, ypoint))
997 
998  do i = 1, maxradii
999 
1000  if (.not. cox_munk) then
1001  call toa_radiance37 (platform_name, taux, &
1002  localoptical_thickness_vector(i), sfr(:,absorbing_index,i), &
1003  rfi1(i), fti0(:,absorbing_index,i), fti1(:,absorbing_index,i), &
1004  fri1(:,absorbing_index,i), rfi(:,absorbing_index,i), &
1005  absorbing_albedo, b_tg, b_tc, rf1, &
1006  rtherm37, channel_number_37, reflibb(:,i), es, ec)
1007 
1008  es_gnd = 1. - absorbing_albedo
1009  else
1010  call toa_radiance37_cox_munk(platform_name, taux, &
1011  localoptical_thickness_vector(i), b_tg, b_tc, &
1012  rfi(:, absorbing_index, i), cl_emis(:,1,i), sf_emis(:,1,i), rf1, &
1013  rtherm37, channel_number_37, es, ec)
1014 
1015  es_gnd = es
1016  reflibb(:,i) = rfi(:, absorbing_index, i)
1017  endif
1018  ! thermal component of the top of the atmosphere measurement
1019  ! in radiance units
1020 
1021  emission_reg = rtherm37
1022  rtherm37 = rtherm37 * local_trans_1way
1023 
1024  trans_ratio = transprime_1way / local_trans_1way - transprime_2way / &
1025  local_trans_2way
1026  sigmapw_squared = ((2.*watervapor_error)* &
1027  abovecloud_watervapor(xpoint, ypoint))**2
1028  z2_term = (es * bprime_ts)**2 * (2*delta_ts)**2 + &
1029  ( ec*bprime_tc + ( es_gnd + ec*b_tc) * trans_ratio )**2 * &
1030  sigmapw_squared
1031 
1032  sigmaz2 = const_c * (local_trans_1way / local_trans_2way) * sqrt(z2_term)
1033 
1034 
1035  ! keeping it squared as we always need it squared later.
1036  sigma_r37_pw(i) = sigmaz1**2 + sigmaz2**2 - 2*abs(sigmaz1*sigmaz2)
1037 
1038 
1039  ! solar component of the top of the atmosphere measurement in
1040  ! reflectance units
1041 
1042  ! Fri Sep 27, 2002: 3.7 um solar iradiance changed to 11.297 from 10.715 (sep)
1043  ! Th, June 2, 2005: 3.7 um solar iradiance changed from 11.297 to
1044  ! 11.739 W/m2-um based on Juan Fontenla (LASP, CU) solar model
1045 
1046  ! above cloud atmosphere corrected solar component
1047  ! of the top of the atmosphere measurement in reflectance units
1048 #ifdef SIM_NORAD
1049  reflectancesolarmeasured = const_c * reflectance_absorbing !11.739)
1050 #else
1051  reflectancesolarmeasured = const_c * (reflectance_absorbing-rtherm37) !11.739)
1052 #endif
1053  reflectancesolarmeasured = reflectancesolarmeasured / local_trans_2way
1054 
1055 
1056  ! Compare this with the library value rf1
1057  residual(i) = ( rf1 / reflectancesolarmeasured ) - 1.
1058 
1059  ! rtherm37 > reflectance_absorbing is not physical. Strictly speaking
1060  ! the answer here would be infinity.
1061 
1062 #ifndef SIM_NORAD
1063  if (rtherm37 .gt. reflectance_absorbing) then!{
1064  residual(i) = 10000.
1065  endif!}
1066 #endif
1067 
1068  enddo
1069 
1070  deallocate( rfi1, localoptical_thickness_vector)
1071 ! deallocate(taux)
1072 
1073 end subroutine nir_absorbing_science
1074 
1075 subroutine toa_radiance37(platform_name, taux, tc, sfr, rfi1, &
1076  fti0, fti1, fri1, rfi, galbedo, B_Tg, B_Tc, rf1, &
1077  rtherm37, channel_number_37, reflib, Es, Ec )
1078  !
1079  ! platform_name
1080  ! taux
1081  ! tc
1082  ! sfr
1083  ! rfi1
1084  ! fti0
1085  ! fti1
1086  ! fri1
1087  ! rfi
1088  ! galbedo
1089  ! B_Tg
1090  ! B_Tc
1091  ! rf1
1092  ! rtherm37
1093  ! channel_number_37
1094  ! reflib
1095  ! Es
1096  ! Ec
1097  !call toa_radiance37 (platform_name, &
1098  ! taux, &
1099  ! local_optical_thickness_vector(i), &
1100  ! sfr(:,absorbing_index,i), &
1101  ! rfi1(i), &
1102  ! fti0(:,absorbing_index,i), &
1103  ! fti1(:,absorbing_index,i), &
1104  ! fri1(:,absorbing_index,i), &
1105  ! rfi(:,absorbing_index,i), &
1106  ! absorbing_albedo, &
1107  ! surface_temperature,&
1108  ! cloud_top_temperature, &
1109  ! rf1, &
1110  ! rtherm37)
1111 
1112  use generalauxtype
1114  use mod06_run_settings
1115  implicit none
1116 
1117  character*(*),intent(in) :: platform_name
1118 
1119  real, intent(in) :: taux(:)
1120 
1121  real(single), intent(in) :: sfr(:), &
1122  fti1(:), fri1(:), fti0(:),rfi(:)
1123  real, dimension(:), intent(inout) :: reflib(:)
1124  real, intent(in) :: tc, galbedo, rfi1, B_Tg, B_Tc
1125  integer, intent(in) :: channel_number_37
1126 
1127  real, intent(out) :: rtherm37, rf1, Es, Ec
1128 
1129  integer :: i, nts
1130  real :: sfr1,rthermc, rthermg, frefl1, trans
1131 
1132  real, dimension(:), allocatable :: tranx, frefl, local_sfr
1133  ! real, dimension(:), allocatable :: rfx
1134 
1135  integer :: lowbound, highbound, taubounds(2)
1136  real :: iftaus(2), functionvalues(2)
1137 
1138  real intensity, intensity_g
1139  ! integer :: TOTAL_POINTS
1140 
1141  lowbound = 0 ! WDR-UIV
1142  highbound = 0 ! WDR-UIV
1143 
1144 
1145  ! TOTAL_POINTS = size(taux)
1146  nts = total_points - 1
1147 
1148  allocate(tranx(total_points), frefl(total_points), local_sfr(total_points))
1149  ! allocate(rfx(TOTAL_POINTS))
1150 
1151  !note: previous developer suggests finding a
1152  !better way to pass these variables. no reason was given
1153 
1154  !compute reflectance, transmittance, cloud albedo,
1155  !and spherical albedo of cloud layer bounded by
1156  !lambertian sea surface at the top for band 3.7 micron.
1157  local_sfr(1) = 0.
1158  local_sfr(2:total_points) = sfr(1:nts)
1159 
1160  ! set reflectance, transmissivity and upward flux for optical thickness == 0.
1161  ! sep, 3 May: this rfx zero tau value is for a black surface,
1162  ! but rfx(2),... include the surface albedo as they should
1163  ! rfx(1) = 0.
1164  rfx(1) = galbedo
1165 
1166  tranx(1) = 1.0
1167  frefl(1) = 0.
1168 
1169  do i = 1, nts
1170 
1171  rfx(i+1) = rfi(i)+fti1(i)*fti0(i)*galbedo/ (1.-galbedo*sfr(i))
1172 
1173  ! downward flux
1174  tranx(i+1) = fti1(i)
1175 
1176  ! upward flux
1177  frefl(i+1) = fri1(i)
1178 
1179  enddo
1180 
1181  reflib = rfx
1182 
1183  !
1184  ! Tau index bounds for the scaled optical thickness
1185  !
1186  call bisectionsearch(taux, tc, lowbound, highbound)
1187  taubounds(1) = lowbound
1188  taubounds(2) = highbound
1189  iftaus(1) = taux(taubounds(1))
1190  iftaus(2) = taux(taubounds(2))
1191  !
1192  ! Interpolation of fti0, fti1, and srf to the scaled optical
1193  ! thickness (for incorporating surface reflectance)
1194  !
1195 
1196  functionvalues(1) = rfx(lowbound)
1197  functionvalues(2) = rfx(highbound)
1198  rf1 = linearinterpolation(iftaus,functionvalues,tc)
1199  functionvalues(1) = frefl(lowbound)
1200  functionvalues(2) = frefl(highbound)
1201  frefl1 = linearinterpolation(iftaus,functionvalues,tc)
1202  functionvalues(1) = tranx(lowbound)
1203  functionvalues(2) = tranx(highbound)
1204  trans = linearinterpolation(iftaus,functionvalues,tc)
1205  functionvalues(1) = local_sfr(lowbound)
1206  functionvalues(2) = local_sfr(highbound)
1207  sfr1 = linearinterpolation(iftaus,functionvalues,tc)
1208 
1209 
1210  ! emission from the cloud (radiance units) at 3.7um
1211  intensity = b_tc
1212  rthermc = (1.- trans - frefl1) * intensity
1213 
1214  ec = (1.- trans - frefl1)
1215 
1216  ! surface emission from the ground (radiance units) at 3.7um
1217  ! intensity = modis_planck(platform_name, ttop, 20, 1)
1218  ! *** sep, 2 May: should use gtemp for sfc instead of ttop. Fixed on 3 May.
1219  intensity_g = b_tg
1220  rthermg = trans*(1.-galbedo) * intensity_g / (1.-sfr1*galbedo)
1221 
1222  es = trans*(1.-galbedo) / (1.-sfr1*galbedo)
1223 
1224  ! total thermal radiance contribution at band 3.7 micron
1225  rtherm37 = rthermc + rthermg
1226 
1227 
1228  deallocate(tranx, frefl, local_sfr)
1229  ! deallocate(rfx)
1230 
1231 end subroutine toa_radiance37
1232 
1233 subroutine toa_radiance37_cox_munk(platform_name, taux, tc, B_Tg, &
1234  B_Tc, rfi, cl_emis, sf_emis, rf1, rtherm37, channel_number_37, Es, Ec)
1235  !
1236  ! platform_name
1237  ! taux
1238  ! tc
1239  ! B_Tg
1240  ! B_Tc
1241  ! rfi
1242  ! cl_emis
1243  ! sf_emis\
1244  ! rf1
1245  ! rtherm37
1246  ! channel_number_37
1247  ! Es
1248  ! Ec
1249  !
1250  use generalauxtype
1252  use mod06_run_settings
1253  implicit none
1254 
1255  character*(*),intent(in) :: platform_name
1256  real, intent(in) :: taux(:)
1257  real(single), intent(in) :: cl_emis(:), sf_emis(:), rfi(:)
1258  real, intent(in) :: tc, B_Tg, B_Tc
1259  integer, intent(in) :: channel_number_37
1260  real, intent(out) :: rtherm37, rf1, Es, Ec
1261 
1262  integer :: i, nts
1263  real :: surface_emissivity, cloud_emissivity, rthermc, rthermg
1264 
1265  integer :: lowbound, highbound, taubounds(2)
1266  real :: iftaus(2), functionvalues(2)
1267 
1268  real intensity, intensity_g
1269  ! integer :: TOTAL_POINTS
1270 
1271  lowbound = 0 ! WDR-UIV
1272  highbound = 0 ! WDR-UIV
1273 
1274  ! TOTAL_POINTS = size(taux)
1275  nts = total_points
1276  !
1277  ! Tau index bounds for the scaled optical thickness
1278  !
1279  call bisectionsearch(taux, tc, lowbound, highbound)
1280  taubounds(1) = lowbound
1281  taubounds(2) = highbound
1282  iftaus(1) = taux(taubounds(1))
1283  iftaus(2) = taux(taubounds(2))
1284  !
1285  ! Interpolation of fti0, fti1, and srf to the scaled optical
1286  ! thickness (for incorporating surface reflectance)
1287  !
1288  functionvalues(1) = rfi(lowbound)
1289  functionvalues(2) = rfi(highbound)
1290  rf1 = linearinterpolation(iftaus,functionvalues,tc)
1291  functionvalues(1) = cl_emis(lowbound)
1292  functionvalues(2) = cl_emis(highbound)
1293  cloud_emissivity = linearinterpolation(iftaus,functionvalues,tc)
1294  functionvalues(1) = sf_emis(lowbound)
1295  functionvalues(2) = sf_emis(highbound)
1296  surface_emissivity = linearinterpolation(iftaus,functionvalues,tc)
1297 
1298  ! emission from the cloud (radiance units) at 3.7um
1299  intensity = b_tc
1300  rthermc = cloud_emissivity * intensity
1301 
1302  ec = cloud_emissivity
1303 
1304  ! surface emission from the ground (radiance units) at 3.7um
1305  ! intensity = modis_planck(platform_name, ttop, 20, 1)
1306  ! *** sep, 2 May: should use gtemp for sfc instead of ttop. Fixed on 3 May.
1307  intensity_g = b_tg
1308  rthermg = surface_emissivity * intensity_g
1309 
1310  es = surface_emissivity
1311 
1312  ! total thermal radiance contribution at band 3.7 micron
1313  rtherm37 = rthermc + rthermg
1314 
1315 
1316 end subroutine toa_radiance37_cox_munk
1317 
1318 subroutine calculate_new_tc(platform_name, Tc, Tg, galbedo, wlen, tau, re, &
1319  lib_taus, lib_res, sph_albedo, down_flux_sensor, up_flux_sensor, &
1320  cloud_emiss, surface_emiss, newTc, PRN)
1321  !
1322  ! platform_name
1323  ! Tc
1324  ! Tg
1325  ! galbedo
1326  ! wlen
1327  ! tau
1328  ! re
1329  ! lib_taus
1330  ! lib_res
1331  ! sph_albedo
1332  ! down_flux_sensor
1333  ! up_flux_sensor
1334  ! cloud_emiss
1335  ! surface_emiss\
1336  ! newTc
1337  ! PRN
1338  !
1340  use mod06_run_settings
1342  use planck_functions
1344  implicit none
1345 
1346  character(*), intent(in) :: platform_name
1347  real, intent(in) :: Tc, Tg, tau, re, galbedo
1348  integer, intent(in) :: wlen
1349  real, dimension(:), intent(in) :: lib_taus, lib_res
1350  real, dimension(:,:,:), intent(in) :: sph_albedo, down_flux_sensor, &
1351  up_flux_sensor, cloud_emiss, surface_emiss
1352  real, intent(inout) :: newTc
1353  logical, intent(in) :: PRN
1354 
1355  integer :: lowbound_tau, highbound_tau
1356  real :: taubounds(2), rebounds(2)
1357  integer :: lowbound_re, highbound_re
1358  real :: iftaus(2), forint(2,2)
1359 
1360  ! integer :: TOTAL_POINTS, total_taus
1361  ! real, dimension(:), allocatable :: taux
1362 
1363  real :: ec, eg
1364  real :: BTg, BTc, BTcr, temp_T_low, temp_T_high
1365  integer :: i
1366  real :: frefl1, trans, sfr1
1367 
1368  lowbound_tau = 0 ! WDR-UIV
1369  highbound_tau = 0 ! WDR-UIV
1370  lowbound_re = 0 ! WDR-UIV
1371  highbound_re = 0 ! WDR-UIV
1372 
1373  ! total_taus = size(lib_taus)
1374  ! TOTAL_POINTS = total_taus + 1
1375 
1376  ! allocate(taux(TOTAL_POINTS))
1377 
1378  ! taux(1) = 0.
1379  ! do i = 1, total_taus
1380  ! taux(i+1) = lib_taus(i)
1381  ! enddo
1382 
1383  call bisectionsearch(taux, tau, lowbound_tau, highbound_tau)
1384  call bisectionsearch(lib_res, re, lowbound_re, highbound_re)
1385 
1386  taubounds(1) = taux(lowbound_tau)
1387  taubounds(2) = taux(highbound_tau)
1388  rebounds(1) = lib_res(lowbound_re)
1389  rebounds(2) = lib_res(highbound_re)
1390 
1391 
1392  if (cox_munk) then
1393 
1394  forint(1,1) = cloud_emiss(lowbound_tau, 2, lowbound_re)
1395  forint(1,2) = cloud_emiss(highbound_tau, 2, lowbound_re)
1396  forint(2,1) = cloud_emiss(lowbound_tau, 2, highbound_re)
1397  forint(2,2) = cloud_emiss(highbound_tau, 2, highbound_re)
1398 
1399 
1400  ec = bilinear_interpolation( taubounds, rebounds, tau, re, forint, 0)
1401 
1402  forint(1,1) = surface_emiss(lowbound_tau, 2, lowbound_re)
1403  forint(1,2) = surface_emiss(highbound_tau, 2, lowbound_re)
1404  forint(2,1) = surface_emiss(lowbound_tau, 2, highbound_re)
1405  forint(2,2) = surface_emiss(highbound_tau, 2, highbound_re)
1406 
1407  eg = bilinear_interpolation( taubounds, rebounds, tau, re, forint, 0)
1408 
1409  else
1410  ! in Lambertian libraries we are missing
1411  lowbound_tau = lowbound_tau - 1
1412  highbound_tau = highbound_tau - 1
1413 
1414  if(highbound_re < 1) highbound_re = 1
1415  if(lowbound_re < 1) lowbound_re = 1
1416  if (highbound_tau < 1) highbound_tau = 1
1417  if (lowbound_tau < 1) lowbound_tau = 1
1418 
1419  if (lowbound_tau == 0) then
1420  forint(1,1) = 0.
1421  forint(2,1) = 0.
1422  else
1423  forint(1,1) = sph_albedo(lowbound_tau, wlen, lowbound_re)
1424  forint(2,1) = sph_albedo(lowbound_tau, wlen, highbound_re)
1425  endif
1426 
1427  forint(2,2) = sph_albedo(highbound_tau, wlen, highbound_re)
1428  forint(1,2) = sph_albedo(highbound_tau, wlen, lowbound_re)
1429 
1430 
1431  sfr1 = bilinear_interpolation( taubounds, rebounds, tau, re, forint, 0)
1432 
1433  if (lowbound_tau == 0) then
1434  forint(1,1) = 1.
1435  forint(2,1) = 1.
1436  else
1437  forint(1,1) = down_flux_sensor(lowbound_tau, wlen, lowbound_re)
1438  forint(2,1) = down_flux_sensor(lowbound_tau, wlen, highbound_re)
1439  endif
1440 
1441  forint(2,2) = down_flux_sensor(highbound_tau, wlen, highbound_re)
1442  forint(1,2) = down_flux_sensor(highbound_tau, wlen, lowbound_re)
1443 
1444 
1445  trans = bilinear_interpolation( taubounds, rebounds, tau, re, forint, 0)
1446 
1447  if (lowbound_tau == 0) then
1448  forint(1,1) = 0.
1449  forint(2,1) = 0.
1450  else
1451  forint(1,1) = up_flux_sensor(lowbound_tau, wlen, lowbound_re)
1452  forint(2,1) = up_flux_sensor(lowbound_tau, wlen, highbound_re)
1453  endif
1454 
1455  forint(2,2) = up_flux_sensor(highbound_tau, wlen, highbound_re)
1456  forint(1,2) = up_flux_sensor(highbound_tau, wlen, lowbound_re)
1457 
1458  frefl1 = bilinear_interpolation( taubounds, rebounds, tau, re, forint, 0)
1459 
1460  ec = 1.- trans - frefl1
1461  eg = trans*(1.-galbedo) / (1.-sfr1*galbedo)
1462 
1463  endif
1464 
1465  btcr = modis_planck(platform_name, tc, channel_11um, 1)
1466  btg = modis_planck(platform_name, tg, channel_11um, 1)
1467 
1468  btc = (btcr - eg*btg) / ec
1469  if (btc < 0.) then
1470  newtc = fillvalue_real
1471  return
1472  endif
1473 
1474  newtc = modis_bright(platform_name, btc, channel_11um, 1)
1475 
1476  ! recalculate Tc_low and Tc_high
1477  btcr = modis_planck(platform_name, tc_low_for_delta, channel_11um, 1)
1478  btc = (btcr - eg*btg) / ec
1479  if (btc < 0.) then
1480  newtc = fillvalue_real
1481  return
1482  endif
1483  temp_t_low = modis_bright(platform_name, btc, channel_11um, 1)
1484 
1485  btcr = modis_planck(platform_name, tc_high_for_delta, channel_11um, 1)
1486  btc = (btcr - eg*btg) / ec
1487  if (btc < 0.) then
1488  newtc = fillvalue_real
1489  return
1490  endif
1491  temp_t_high = modis_bright(platform_name, btc, channel_11um, 1)
1492 
1493  if (temp_t_high < newtc .or. temp_t_low > newtc) then
1494  newtc = fillvalue_real
1495  return
1496  endif
1497  ! overwrite these variables only when nothing broke down
1498  tc_low_for_delta = temp_t_low
1499  tc_high_for_delta = temp_t_high
1500 
1501 end subroutine calculate_new_tc
1502 
1503 
1504 
1505 end module retrieval_prep_logic
subroutine compute_water_path(tau, re, density, library_re, extinction_efficiency, water_path)
subroutine vis_nonabsorbing_science(reflectance_nonabsorbing, nonabsorbing_index, nonabsorbing_albedo, library_taus, library_radii, sfr, fti1, fti0, rfi, theta, theta0, phi, cloudtop_pressure, process, optical_thickness_vector)
real, dimension(2) thermal_correction_oneway_high
real, dimension(2) thermal_correction_twoway_high
real, parameter watervapor_error
subroutine nir_absorbing_science(platform_name, optical_thickness_vector, reflectance_absorbing, absorbing_index, absorbing_albedo, xpoint, ypoint, CTT, thermal_trans_1way, thermal_trans_2way, library_taus, library_radii, sfr, fti1, fti0, fri1, rfi, cl_emis, sf_emis, residual, maxradii, channel_number_37, emission_uncertainty_pw, emission_uncertainty_Tc, sigma_R37_PW, debug)
real(single), dimension(:,:,:,:), allocatable flux_up_water_solar
real function, public linearinterpolation(X, Y, XX)
real, parameter delta_ts
real(single), dimension(:), allocatable library_fluxsolarzenith
subroutine toa_radiance37_cox_munk(platform_name, taux, tc, B_Tg, B_Tc, rfi, cl_emis, sf_emis, rf1, rtherm37, channel_number_37, Es, Ec)
real(single), dimension(:), allocatable library_taus
real, dimension(:,:), allocatable refliba
subroutine vis_absorbing_science(optical_thickness_vector, reflectance_absorbing, absorbing_index, absorbing_albedo, library_taus, library_radii, sfr, fti1, fti0, rfi, residual, maxradii, debug)
real tc_low_for_delta
subroutine toa_radiance37(platform_name, taux, tc, sfr, rfi1, fti0, fti1, fri1, rfi, galbedo, B_Tg, B_Tc, rf1, rtherm37, channel_number_37, reflib, Es, Ec)
real, dimension(:,:), allocatable solar_zenith_angle
Definition: core_arrays.f90:6
real function, public modis_bright(platform_name, RAD, BAND, UNITS, cwn_array, tcs_array, tci_array)
subroutine rayleighcorrection(reflectance, cloudtoppressure, process, optical_thickness, nonabsorbing_galbedo, fti1, fti0, sfr, iw, ir, solarzenith, sensorzenith, azimuth, reflectance_corrected)
endif() set(LIBS $
Definition: CMakeLists.txt:6
real function, public modis_planck(platform_name, TEMP, BAND, UNITS)
real, dimension(:), allocatable rayleigh_liq
real(single), dimension(:,:,:,:), allocatable flux_up_water_sensor
real, dimension(:,:), allocatable reflibb
subroutine init_retrieval(library_taus)
real function, public bilinear_interpolation(X, Y, XX, YY, source, method)
real(single), dimension(:,:), allocatable surface_temperature
subroutine calculate_new_tc(platform_name, Tc, Tg, galbedo, wlen, tau, re, lib_taus, lib_res, sph_albedo, down_flux_sensor, up_flux_sensor, cloud_emiss, surface_emiss, newTc, PRN)
subroutine interpolate_refl_cot(reflectance, reflectance_vector, optical_thickness_vector, optical_thickness)
subroutine interp_lib_reflflux_cloudalbedo(miu0, miu, optical_thickness, nonabsorbing_galbedo, sfr, fti1, fti0, iw, ir, fluxsolarzenithangles, fluxsensorzenithangles, fluxup_solar, fluxup_sensor, interp_fluxup_solar, interp_fluxup_sensor)
real(single), dimension(:,:,:,:), allocatable flux_up_ice_solar
real tc_high_for_delta
integer, parameter channel_11um
real(single), dimension(:,:), allocatable abovecloud_watervapor
real, dimension(:), allocatable rayleigh_ice
subroutine, public bisectionsearch(xx, x, jlo, jhi)
real, dimension(2) thermal_correction_oneway_low
real, dimension(2) thermal_correction_twoway_low
real transprime_1way
real(single), dimension(:,:,:,:), allocatable flux_up_ice_sensor
#define abs(a)
Definition: misc.h:90
real(single), dimension(:), allocatable library_fluxsensorzenith
real transprime_2way