OB.DAAC Logo
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 ! data cinit/'zzzzzz'/
112 
113  taud_2way = 0 ! WDR-UIV
114  ratio = 1 ! WDR-UIV
115 
116  tlas = nl*0.
117  wlas = nl*0.
118  olas = nl*0.
119  zlas = -999.
120  zlas2way = -999.
121  xfile = '/modisdet.com.101.xxx_end.v3'
122  cbe = 'big'
123  cle = 'lit'
124 
125  cbt = 'TERRA'
126  cba = 'AQUA'
127  cst = 'terra'
128  csa = 'aqua'
129 
130  comp = (/'dry','ozo','wts','wtl','wco'/)
131  lengcf = (/lencdb,lencob,lencsb,lenclb,lenccb/)
132  lengcx = (/lencd,lenco,lencs,lencl,lencc/)
133 
134  iok = 0
135 
136  if (platform == 0) then
137 ! Shifted bands 34-36, LBL 11.3
138  craft = 'TERRA'
139  path = coeff_dir_path
140  else if (platform == 1) then
141  craft = 'AQUA'
142  path = coeff_dir_path
143  else
144  write(*,'(''tran_modisd101- unknown spacecraft '',i2)') platform
145  iok = 1
146  return
147  endif
148 
149  if (craft /= cinit) then
150 
151  if (craft == "TERRA") then
152  ksat = 1
153  else if (craft == "AQUA") then
154  ksat = 2
155  else
156  write(*,'(''tran_modisd101- unknown spacecraft '',a6)') craft
157  iok = 1
158  return
159  endif
160 
161 ! select big- or little-endian libraries.
162 ! if (big_endian()) then
163  xfile(19:21) = cbe
164 ! else
165 ! xfile(19:21) = cle
166 ! endif
167 
168 ! WDR if first time through, do the reads, otherwise rely on pre-read data
169  if( firsttime == 0 ) then
170  firsttime = 1
171 ! * define and open the files
172 ! iux = 30
173 ! do m=1, nk
174 !
175 ! iux = iux + 1
176 ! xfile(11:13) = comp(m)
177 !! RAF This code block modified to enable file name manipulation
178 !! when passed in from a C routine.
179 !
180 ! dfile = path
181 ! j = len(dfile)
182 ! kk = len(xfile)
183 ! i = 1
184 ! do while( (i <= j) .and. (ichar(dfile(i:i)) .ne. 0) )
185 ! i = i + 1
186 ! enddo
187 !
188 ! dfile(i:i+kk-1) = xfile(1:kk)
189 ! jj = i + kk
190 ! do while( jj <= j)
191 ! dfile(jj:jj) = ' '
192 ! jj = jj + 1
193 ! enddo
194 !
195 ! lencf=lengcf(m)
196 !! PRINT*, __FILE__,__LINE__, '**** WDR opening file: ', dfile
197 ! open(iux,file=dfile,recl=lencf,access='direct', status='old', convert='big_endian')
198 ! iuc(m)=iux
199 ! cfile(m)=dfile
200 !
201 ! enddo
202  !
203  ! WDR replace with get_cld_tbl()
204  ! we only have 1 set of tables and they aare for modis aqua, but i
205  ! get_cld_tbl won't use the sensor id
206  iux = 30
207  do m=1, nk
208  iux = iux + 1
209  call get_cld_tbl( 0, trans_id(m), dfile, stat )
210  if( stat /= 0 ) then
211  print *, __file__,__line__, &
212  'Unable to get the FAST_TRANS_COEFF file', m
213  stop 123
214  endif
215  lencf=lengcf(m)
216  open( iux, file=dfile, recl=lencf, access='direct', status='old', &
217  convert='big_endian')
218  iuc(m) = iux
219  cfile(m)=dfile
220  enddo
221 
222 ! * first read each files fill-record for band 26/det 0
223 ! and verify satellite number stored in word 1
224 ! * note: number of levels is in word 2, creation date (yyyyddd) is in word 3
225  ikrec=nrps*(ksat-1)
226  krecx=ikrec+7
227  do k=1,nk
228  lencx=lengcx(k)
229  read(iuc(k),rec=krecx) (bufs(j),j=1,lencx)
230  nsat=bufs(1)
231  if(nsat /= ksat) then
232  dfile=cfile(k)
233  write(*,'(''In tran_modisd101 ... requested data for '', &
234 & ''satellite '',i1/'' but read data for '', ''satellite '',i1,'' from file '',a80)') ksat,nsat,dfile
235  iok = 1
236  return
237  endif
238  enddo
239 
240 ! * now read in the coefficients
241  krec=ikrec
242  do l=0,nd
243  do k=1,nr
244  krec=krec+1
245  read(iuc(1),rec=krec) ((coefd(i,j,l,k),i=1,ncd),j=1,nm)
246  read(iuc(2),rec=krec) ((coefo(i,j,l,k),i=1,nco),j=1,nm)
247  read(iuc(3),rec=krec) ((coefs(i,j,l,k),i=1,ncs),j=1,nm)
248  read(iuc(4),rec=krec) ((coefl(i,j,l,k),i=1,ncl),j=1,nm)
249  read(iuc(5),rec=krec) ((coefc(i,j,l,k),i=1,ncc),j=1,nm)
250  enddo
251  enddo
252  do k=1,nk
253  close(iuc(k))
254  enddo
255  ! WDR I believe this is the end of first time read
256  end if
257 
258  call conpir(pstd,tstd,wstd,ostd,nl,1,pavg,tref,wref,oref)
259 
260  cinit=craft
261  iok=0
262 
263 ! End "first-time-through-only" block.
264  endif
265 
266 
267  if(newatm) then
268  call conpir(pstd,temp,wvmr,ozmr,nl,1,pavg,tavg,wamt,oamt)
269  endif
270 
271 ! we have to enable doing two-way angles on an as-needed basis
272 
273  if(newang) then
274  zsec = secant(theta)
275  secz = zsec
276  endif
277 
278  if (do_2way .and. new_2way) then
279  zsec_2way = secant(ang_2way)
280  secz_2way = zsec_2way
281  endif
282 ! WDR try to avoid all init computations for same profile
283  do_init = 1
284  if(newang .or. newatm ) then
286  nm,nxd,nxw,nxo,nxc,xdry,xwet,xozo,xcon,do_init)
287  endif
288 
289  if (do_2way .and. (new_2way .or. newatm)) then
291  nm,nxd,nxw,nxo,nxc,xdry_2way,xwet_2way,xozo_2way,xcon_2way,do_init)
292  endif
293 
294 
295  if(kban == 26) then
296  do j=1,nl
297  taud(j)=1.0
298  tauo(j)=1.0
299  tauw(j)=1.0
300  taut(j)=1.0
301  enddo
302  return
303  endif
304 
305  j=jdet
306  k=kban-koff
307 ! * dry
308  call taudoc(ncd,nxd,nm,coefd(:,:,j,k),xdry,taud)
309 
310 ! do j=1, nl
311 ! print*, j, taud(j)
312 ! end do
313 
314 ! Adjust dry tau for changes in CO2 concentration from model (R. Frey)
315 
316 #ifdef CT_CODE
317  x = (year - 1980) * 365.25 + jday
318  rco2 = (slp*x - smag*sin(2*pi*(x/365.25 + soff))) + coff
319  ratio=rco2/380.0
320  do jj=1,nl
321  tau_test = taud(jj)
322  if(taud(jj) > 0.0 .and. taud(jj) < 1.0) then
323  taud(jj)=taud(jj)**ratio
324  endif
325  enddo
326 
327 ! * ozo
328  call taudoc(nco,nxo,nm,coefo(:,:,j,k),xozo,tauo)
329 #else
330 ! we set the ozone to 0. if we're not doing CT, so transmittance due to ozone is 1.0
331  tauo = 1.0
332 #endif
333 
334 ! * wet
335  call tauwtr(ncs,ncl,nxs,nxl,nxw,nm,coefs(:,:,j,k),coefl(:,:,j,k),xwet,tauw)
336 
337  call taudoc(ncc,nxc,nm,coefc(:,:,j,k),xcon,tauc)
338 
339  do jj=1,nl
340  tauw(jj)=tauw(jj)*tauc(jj)
341  enddo
342 ! * total
343  do jj=1,nl
344  taut(jj)=taud(jj)*tauo(jj)*tauw(jj)
345  enddo
346 
347  if (do_2way) then
348 
349  j=jdet
350 
351  call taudoc(ncd,nxd,nm,coefd(:,:,j,k),xdry_2way,taud_2way)
352  do jj=1,nl
353  tau_test = taud_2way(jj)
354  if(taud_2way(jj) > 0.0 .and. taud_2way(jj) < 1.0) then
355  taud_2way(jj)=taud_2way(jj)**ratio
356 
357  endif
358  enddo
359 #ifdef CT_CODE
360  call taudoc(nco,nxo,nm,coefo(:,:,j,k),xozo_2way,tauo_2way)
361 #else
362  tauo_2way = 1.0
363 #endif
364  call tauwtr(ncs,ncl,nxs,nxl,nxw,nm,coefs(:,:,j,k),coefl(:,:,j,k),xwet_2way,tauw_2way)
365  call taudoc(ncc,nxc,nm,coefc(:,:,j,k),xcon_2way,tauc_2way)
366 
367 
368  do jj=1,nl
369  tauw_2way(jj)=tauw_2way(jj)*tauc_2way(jj)
370  enddo
371 ! * total
372  do jj=1,nl
373  taut_2way(jj)=taud_2way(jj)*tauo_2way(jj)*tauw_2way(jj)
374  enddo
375 
376 
377  endif
378 
379 
380 
381  end subroutine modis_fascode
382 
383 
384 
385 
386 
387 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)
Definition: jday.c:4
#define real
Definition: DbAlgOcean.cpp:26
integer, parameter fast_trans_coeff_wtl
real, dimension(fnxc, fnm) xcon
integer, parameter fast_trans_coeff_wts
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
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