NASA Logo
Ocean Color Science Software

ocssw V2022
pfaast.f90
Go to the documentation of this file.
1 module pfaast
2 
4  use cld_tbl_names
5 
6  private
7 
8  public :: modis_fascode
9 
10  integer, parameter :: Fnr = 17, fnd = 10
11 
12  real :: coefd(Fncd,Fnm,0:Fnd,Fnr),&
13  coefo(Fnco,Fnm,0:Fnd,Fnr), &
14  coefl(Fncl,Fnm,0:Fnd,Fnr),&
15  coefs(Fncs,Fnm,0:Fnd,Fnr), &
16  coefc(Fncc,Fnm,0:Fnd,Fnr)
17 
18 contains
19 
20 
21  subroutine modis_fascode(coeff_dir_path, year, jday, temp, wvmr, ozmr, theta, ang_2way, platform, &
22  kban, jdet, taut, taut_2way, newang, newatm, new_2way, do_2way, iok, xxx, yyy )
23 
24 ! * MODIS band/detector 101-level fast transmittance routine
25 ! .... version of 06.08.03
26 
27 ! coeff_dir_path = directory that contains fast model coefficients
28 ! year = profile year
29 ! jday = profile day-of-year
30 ! temp = temperature (Kelvin) profile
31 ! wvmr = water-vapor mixing-ratio (g/kg) profile
32 ! ozmr = ozone mixing-ratio (ppmv) profile
33 ! theta = local zenith angle
34 ! craft = TERRA, AQUA (either upper or lower case)
35 ! kban = band number (20...36)
36 ! jdet = detector number (0...10) [ Product Order ]
37 ! detector 0 is based on band-average response functions
38 
39 ! taut = total transmittance (see note below)
40 ! iok = 0 if successful, 1 if I/O problem
41 
42 ! * NOTE: for kban = 26, return-arrays are filled with 1.0
43 
44 ! * PLOD/PFAAST regression model based on LBLRTM line-by-line transmittances.
45 ! * Input temperatures, and water-vapor and ozone mixing ratios, must
46 ! * be defined at the pressure levels in array 'pstd'
47 ! * (see block data 'reference_atmosphere').
48 ! * Units: temperature, deg-K; water vapor, g/kg; ozone, ppmv.
49 ! * Logical units 31-35 are used for coefficient files.
50 ! * Component taus are returned through common, product in 'taut'.
51  character(*), intent(in) :: coeff_dir_path
52  integer, intent(in) :: year, jday
53  real, intent(inout) :: temp(*),wvmr(*),ozmr(*),taut(*), taut_2way(*)
54  integer, intent(in) :: platform
55  real, intent(in) :: theta, ang_2way
56  integer, intent(in) :: kban, jdet, xxx, yyy
57  integer, intent(inout) :: iok
58  logical, intent(in) :: newang, newatm, new_2way, do_2way
59 
60  integer, parameter :: nd=10,nk=5,nl=101,nm=nl-1,koff=19,nr=17
61  integer, parameter :: nxc= 4,ncc=nxc+1,lencc=ncc*nm,lenccb=lencc*4
62  integer, parameter :: nxd= 8,ncd=nxd+1,lencd=ncd*nm,lencdb=lencd*4
63  integer, parameter :: nxo= 9,nco=nxo+1,lenco=nco*nm,lencob=lenco*4
64  integer, parameter :: nxl= 2,ncl=nxl+1,lencl=ncl*nm,lenclb=lencl*4
65  integer, parameter :: nxs=11,ncs=nxs+1,lencs=ncs*nm,lencsb=lencs*4
66  integer, parameter :: ndt=nd+1,nrps=nr*ndt,nxw=nxl+nxs
67  real, parameter :: slp=1.5/365.0
68  real, parameter :: smag=3.0
69  real, parameter :: pi=3.14159
70  real, parameter :: soff=0.41
71  real, parameter :: coff=337.5
72 
73 ! common/stdatm/pstd(nl),tstd(nl),wstd(nl),ostd(nl)
74 ! common/taudwo/taud(nl),tauw(nl),tauo(nl)
75  real :: taud(nl), tauw(nl), tauo(nl)
76  real :: taud_2way(nl), tauw_2way(nl), tauo_2way(nl)
77 
78  real :: bufs(lencs)
79 ! real :: pavg(nm),tref(nm),wref(nm),oref(nm)
80 ! real :: tavg(nm),wamt(nm),oamt(nm),secz(nm)
81  real :: tauc(nl),tauc_2way(nl), tlas(nl),wlas(nl),olas(nl)
82 
83  real*4 x,rco2,ratio,tau_test
84  character*28 xfile
85  character*256 path
86  character*256 cfile(nk),dfile
87  character*6 craft
88  character*6 cbt,cba
89  character*6 cst,csa
90  character*3 comp(nk)
91  character*3 cbe,cle
92  integer*4 lengcf(nk)
93  integer*4 lengcx(nk)
94  integer*4 iuc(nk)
95  integer*2 jj
96  logical big_endian
97 
98  real :: zlas, zlas2way
99 
100  integer :: stat
101  integer :: trans_id(5) = (/fast_trans_coeff_dry, fast_trans_coeff_ozo, &
103  integer :: ksat, iux, m, j, kk, ikrec, krec, krecx, k, lencx, l, i
104  integer :: lencf
105  integer*2 :: nsat
106  real :: dt, dw, fdo, datm, zsec, zsec_2way
107 
108  integer :: firsttime = 0 ! WDR To limit reads to first fill
109  integer :: do_init ! WDR reduce computations in calpir
110 
111  ! WDR for test-out of new netcdf file read
112  integer*4 :: start(5) = (/ 1, 1, 1, 1, 1/), edge(5), nc_stat
113  integer :: fid, sds_id, tbl_no
114  real :: coef_dry( fncd, fnm, 0:fnd, fnr )
115  real :: coef_oz( fnco, fnm, 0:fnd, fnr )
116  real :: coef_wtr1( fncs, fnm, 0:fnd, fnr )
117  real :: coef_wtr2( fncl, fnm, 0:fnd, fnr )
118  real :: coef_cont( fncc, fnm, 0:fnd, fnr )
119  character(100) :: tbl_nam
120  integer :: ids(5), lendim
121 
122 ! data cinit/'zzzzzz'/
123 
124  taud_2way = 0 ! WDR-UIV
125  ratio = 1 ! WDR-UIV
126 
127  tlas = nl*0.
128  wlas = nl*0.
129  olas = nl*0.
130  zlas = -999.
131  zlas2way = -999.
132  xfile = '/modisdet.com.101.xxx_end.v3'
133  cbe = 'big'
134  cle = 'lit'
135 
136  cbt = 'TERRA'
137  cba = 'AQUA'
138  cst = 'terra'
139  csa = 'aqua'
140 
141  comp = (/'dry','ozo','wts','wtl','wco'/)
142  lengcf = (/lencdb,lencob,lencsb,lenclb,lenccb/)
143  lengcx = (/lencd,lenco,lencs,lencl,lencc/)
144 
145  iok = 0
146 
147  if (platform == 0) then
148 ! Shifted bands 34-36, LBL 11.3
149  craft = 'TERRA'
150  path = coeff_dir_path
151  else if (platform == 1) then
152  craft = 'AQUA'
153  path = coeff_dir_path
154  else
155  write(*,'(''tran_modisd101- unknown spacecraft '',i2)') platform
156  iok = 1
157  return
158  endif
159 
160  if (craft /= cinit) then
161 
162  if (craft == "TERRA") then
163  ksat = 1
164  else if (craft == "AQUA") then
165  ksat = 2
166  else
167  write(*,'(''tran_modisd101- unknown spacecraft '',a6)') craft
168  iok = 1
169  return
170  endif
171 
172 ! select big- or little-endian libraries.
173 ! if (big_endian()) then
174  xfile(19:21) = cbe
175 ! else
176 ! xfile(19:21) = cle
177 ! endif
178 
179 ! WDR if first time through, do the reads, otherwise rely on pre-read data
180  if( firsttime == 0 ) then
181  firsttime = 1
182  !
183  ! WDR replace with get_cld_tbl()
184  ! we only have 1 set of tables and they are for modis aqua
185 
186  ! The following code is for the old binary yfast trans coeff files
187  ! keep it behind a do_old_files variable so a return is easy
188  do_old_files = 0
189  coefd = 0
190  coefo = 0
191  coefs = 0
192  coefl = 0
193  coefc = 0
194  if( do_old_files == 1 ) then
195  iux = 30
196  do m=1, nk
197  iux = iux + 1
198  call get_cld_tbl( 0, trans_id(m), dfile, stat )
199  if( stat /= 0 ) then
200  print *, __file__,__line__, &
201  'Unable to get the FAST_TRANS_COEFF file', m
202  stop 123
203  endif
204  lencf=lengcf(m)
205  open( iux, file=dfile, recl=lencf, access='direct', status='old', &
206  convert='big_endian')
207  iuc(m) = iux
208  cfile(m)=dfile
209  enddo
210 
211  ! first read each files fill-record for band 26/det 0
212  ! and verify satellite number stored in word 1
213  ! note: number of levels is in word 2, creation date
214  ! (yyyyddd) is in word 3
215  ikrec=nrps*(ksat-1)
216  krecx=ikrec+7
217  do k=1,nk
218  lencx=lengcx(k)
219  read(iuc(k),rec=krecx) (bufs(j),j=1,lencx)
220  nsat=bufs(1)
221  if(nsat /= ksat) then
222  dfile=cfile(k)
223  write(*,'(''In tran_modisd101 ... requested data for '', &
224  & ''satellite '',i1/'' but read data for '', ''satellite '',i1,'' from file '',a80)') ksat,nsat,dfile
225  iok = 1
226  return
227  endif
228  enddo
229 
230  ! * now read in the coefficients
231  krec=ikrec
232  do l=0,nd
233  do k=1,nr
234  krec=krec+1
235  read(iuc(1),rec=krec) ((coefd(i,j,l,k),i=1,ncd),j=1,nm)
236  read(iuc(2),rec=krec) ((coefo(i,j,l,k),i=1,nco),j=1,nm)
237  read(iuc(3),rec=krec) ((coefs(i,j,l,k),i=1,ncs),j=1,nm)
238  read(iuc(4),rec=krec) ((coefl(i,j,l,k),i=1,ncl),j=1,nm)
239  read(iuc(5),rec=krec) ((coefc(i,j,l,k),i=1,ncc),j=1,nm)
240  enddo
241  enddo
242  do k=1,nk
243  close(iuc(k))
244  enddo
245  endif
246  ! WDR I believe this is the end of first time read
247  ! WDR now, read the new trans coeff arrays from the new file and compare
248  call get_cld_tbl( 0, trans_id(1), dfile, stat )
249  nc_stat = nf_open( dfile, nf_nowrite, fid )
250  call cld_fchk( nc_stat, __file__, __line__ )
251  start(5) = ksat
252  edge(5) = 1
253  edge(4) = fnr
254  edge(3) = fnd + 1
255  edge(2) = fnm
256 
257  do tbl_no = 1,5
258  select case (tbl_no)
259  case (1)
260  edge(1) = fncd
261  tbl_nam = "Dry_air_component"
262  case (2)
263  edge(1) = fnco
264  tbl_nam = "Ozone_component"
265  case (3)
266  edge(1) = fncs
267  tbl_nam = "Water_component_1"
268  case (4)
269  edge(1) = fncl
270  tbl_nam = "Water_component_2"
271  case (5)
272  edge(1) = fncc
273  tbl_nam = "Continuum_component"
274  end select
275  nc_stat = nf_inq_varid( fid, tbl_nam, sds_id )
276  call cld_fchk( nc_stat, __file__, __line__ )
277  ! find the dimids and their size
278  nc_stat = nf_inq_vardimid(fid, sds_id, ids )
279  !do l=1,5
280  ! nc_stat = nf_inq_dimlen(fid, ids(l), lendim)
281  ! print*,'dim len: ', lendim
282  !enddo
283  select case (tbl_no)
284  case (1)
285  nc_stat = nf_get_vara_real( fid, sds_id, start, edge, coef_dry )
286  call cld_fchk( nc_stat, __file__, __line__ )
287  !print*, 'in pfasst, dif min, max for: ', tbl_nam, &
288  ! minval(coef_dry-coefd), maxval(coef_dry-coefd)
289  case (2)
290  nc_stat = nf_get_vara_real( fid, sds_id, start, edge, coef_oz )
291  call cld_fchk( nc_stat, __file__, __line__ )
292  !print*, 'in pfasst, dif min, max for: ', tbl_nam, &
293  ! minval(coef_oz-coefo), maxval(coef_oz-coefo)
294  case (3)
295  nc_stat = nf_get_vara_real( fid, sds_id, start, edge, coef_wtr1 )
296  call cld_fchk( nc_stat, __file__, __line__ )
297  ! print*, 'in pfasst, dif min, max for: ', tbl_nam, &
298  ! minval(coef_wtr1-coefs), maxval(coef_wtr1-coefs)
299  case (4)
300  nc_stat = nf_get_vara_real( fid, sds_id, start, edge, coef_wtr2 )
301  call cld_fchk( nc_stat, __file__, __line__ )
302  !print*, 'in pfasst, dif min, max for: ', tbl_nam, &
303  ! minval(coef_wtr2-coefl), maxval(coef_wtr2-coefl)
304  case (5)
305  nc_stat = nf_get_vara_real( fid, sds_id, start, edge, coef_cont )
306  call cld_fchk( nc_stat, __file__, __line__ )
307  !print*, 'in pfasst, dif min, max for: ', tbl_nam, &
308  ! minval(coef_cont-coefc), maxval(coef_cont-coefc)
309  end select
310  enddo
311  !
312  ! WDR - this will use the new nc file coefficient arrays
313  coefd = coef_dry
314  coefo = coef_oz
315  coefs = coef_wtr1
316  coefl = coef_wtr2
317  coefc = coef_cont
318  !
319  ! close the file and be off
320  nc_stat = nf_close( fid )
321  call cld_fchk( nc_stat, __file__, __line__ )
322 
323  end if
324 
325  call conpir(pstd,tstd,wstd,ostd,nl,1,pavg,tref,wref,oref)
326 
327  cinit=craft
328  iok=0
329 
330 ! End "first-time-through-only" block.
331  endif
332 
333 
334  if(newatm) then
335  call conpir(pstd,temp,wvmr,ozmr,nl,1,pavg,tavg,wamt,oamt)
336  endif
337 
338 ! we have to enable doing two-way angles on an as-needed basis
339 
340  if(newang) then
341  zsec = secant(theta)
342  secz = zsec
343  endif
344 
345  if (do_2way .and. new_2way) then
346  zsec_2way = secant(ang_2way)
347  secz_2way = zsec_2way
348  endif
349 ! WDR try to avoid all init computations for same profile
350  do_init = 1
351  if(newang .or. newatm ) then
353  nm,nxd,nxw,nxo,nxc,xdry,xwet,xozo,xcon,do_init)
354  endif
355 
356  if (do_2way .and. (new_2way .or. newatm)) then
358  nm,nxd,nxw,nxo,nxc,xdry_2way,xwet_2way,xozo_2way,xcon_2way,do_init)
359  endif
360 
361 
362  if(kban == 26) then
363  do j=1,nl
364  taud(j)=1.0
365  tauo(j)=1.0
366  tauw(j)=1.0
367  taut(j)=1.0
368  enddo
369  return
370  endif
371 
372  j=jdet
373  k=kban-koff
374 ! * dry
375  call taudoc(ncd,nxd,nm,coefd(:,:,j,k),xdry,taud)
376 
377 ! do j=1, nl
378 ! print*, j, taud(j)
379 ! end do
380 
381 ! Adjust dry tau for changes in CO2 concentration from model (R. Frey)
382 
383 #ifdef CT_CODE
384  x = (year - 1980) * 365.25 + jday
385  rco2 = (slp*x - smag*sin(2*pi*(x/365.25 + soff))) + coff
386  ratio=rco2/380.0
387  do jj=1,nl
388  tau_test = taud(jj)
389  if(taud(jj) > 0.0 .and. taud(jj) < 1.0) then
390  taud(jj)=taud(jj)**ratio
391  endif
392  enddo
393 
394 ! * ozo
395  call taudoc(nco,nxo,nm,coefo(:,:,j,k),xozo,tauo)
396 #else
397 ! we set the ozone to 0. if we're not doing CT, so transmittance due to ozone is 1.0
398  tauo = 1.0
399 #endif
400 
401 ! * wet
402  call tauwtr(ncs,ncl,nxs,nxl,nxw,nm,coefs(:,:,j,k),coefl(:,:,j,k),xwet,tauw)
403 
404  call taudoc(ncc,nxc,nm,coefc(:,:,j,k),xcon,tauc)
405 
406  do jj=1,nl
407  tauw(jj)=tauw(jj)*tauc(jj)
408  enddo
409 ! * total
410  do jj=1,nl
411  taut(jj)=taud(jj)*tauo(jj)*tauw(jj)
412  enddo
413 
414  if (do_2way) then
415 
416  j=jdet
417 
418  call taudoc(ncd,nxd,nm,coefd(:,:,j,k),xdry_2way,taud_2way)
419  do jj=1,nl
420  tau_test = taud_2way(jj)
421  if(taud_2way(jj) > 0.0 .and. taud_2way(jj) < 1.0) then
422  taud_2way(jj)=taud_2way(jj)**ratio
423 
424  endif
425  enddo
426 #ifdef CT_CODE
427  call taudoc(nco,nxo,nm,coefo(:,:,j,k),xozo_2way,tauo_2way)
428 #else
429  tauo_2way = 1.0
430 #endif
431  call tauwtr(ncs,ncl,nxs,nxl,nxw,nm,coefs(:,:,j,k),coefl(:,:,j,k),xwet_2way,tauw_2way)
432  call taudoc(ncc,nxc,nm,coefc(:,:,j,k),xcon_2way,tauc_2way)
433 
434 
435  do jj=1,nl
436  tauw_2way(jj)=tauw_2way(jj)*tauc_2way(jj)
437  enddo
438 ! * total
439  do jj=1,nl
440  taut_2way(jj)=taud_2way(jj)*tauo_2way(jj)*tauw_2way(jj)
441  enddo
442 
443 
444  endif
445 
446 
447 
448  end subroutine modis_fascode
449 
450 
451 
452 
453 
454 end module pfaast
Definition: pfaast.f90:1
real, dimension(fnm) oamt
real, dimension(fnxw, fnm) xwet_2way
real, dimension(nl), parameter wstd
real, dimension(fnm) tref
real, dimension(nl), parameter ostd
real, dimension(fnxd, fnm) xdry
real, dimension(fnm) wamt
real, dimension(nl), parameter pstd
subroutine tauwtr(ncs, ncl, nxs, nxl, nxw, ny, ccs, ccl, xx, tau)
subroutine conpir(p, t, w, o, n_levels, i_dir, p_avg, t_avg, w_amt, o_amt)
subroutine taudoc(nc, nx, ny, cc, xx, tau)
int32_t jday(int16_t i, int16_t j, int16_t k)
Converts a calendar date to the corresponding Julian day starting at noon on the calendar date....
Definition: jday.c:14
#define real
Definition: DbAlgOcean.cpp:26
integer, parameter fast_trans_coeff_wtl
real, dimension(fnxc, fnm) xcon
integer, parameter fast_trans_coeff_wts
subroutine cld_fchk(status, file, line)
Definition: cld_fchk.f90:2
integer, parameter fast_trans_coeff_wco
real, dimension(fnm) secz_2way
real, dimension(fnm) pavg
real, dimension(fnm) wref
real, dimension(fnxo, fnm) xozo_2way
void print(std::ostream &stream, const char *format)
Definition: PrintDebug.hpp:38
real, dimension(fnxw, fnm) xwet
integer, parameter fast_trans_coeff_ozo
subroutine calpir(t_avg_ref, amt_wet_ref, amt_ozo_ref, t_avg, amt_wet, amt_ozo, p_avg, sec_theta, n_layers, n_dry_pred, n_wet_pred, n_ozo_pred, n_con_pred, pred_dry, pred_wet, pred_ozo, pred_con, do_init)
#define pi
Definition: vincenty.c:23
integer, parameter fast_trans_coeff_dry
real, dimension(fnm) secz
real, dimension(fnxc, fnm) xcon_2way
real, dimension(fnm) tavg
real, dimension(nl), parameter tstd
real function secant(z)
real, dimension(fnxd, fnm) xdry_2way
real, dimension(fnm) oref
subroutine, public modis_fascode(coeff_dir_path, year, jday, temp, wvmr, ozmr, theta, ang_2way, platform, kban, jdet, taut, taut_2way, newang, newatm, new_2way, do_2way, iok, xxx, yyy)
Definition: pfaast.f90:23
real, dimension(fnxo, fnm) xozo