FV3 Bundle
gsidiag_bin2txt.f90
Go to the documentation of this file.
2 
6  use ncd_kinds,only: r_quad, r_single
7 
8  implicit none
9 
10  integer nargs, iargc, n
11  character*256, allocatable :: arg(:)
12 
13  type(diag_header_fix_list ) :: headfix
14  type(diag_header_chan_list),allocatable :: headchan(:)
15  type(diag_data_name_list) :: headname
16 
17  type(diag_data_fix_list) :: datafix
18  type(diag_data_chan_list) ,allocatable :: datachan(:)
19  type(diag_data_extra_list) ,allocatable :: dataextra(:,:)
20 
21  real(r_quad) :: ret_var
22  real(r_quad) :: ret_stddev
23 
24 ! optional namelist inputs - can be overriden in a radmon_diag_bin2txt.nl
25  logical :: debug = .false.
26  integer :: npred_read = 7
27  logical :: sst_ret = .false.
28  integer :: iversion = -9999
29  logical :: append_txt_suffix = .false.
30 
31  logical :: netcdf = .false.
32  character*256 infn, outfn
33 
34 ! integer,parameter :: inlun = 51
35  integer :: inlun
36  integer,parameter :: outlun= 52
37  integer,parameter :: nllun = 53
38 
39  integer strlen, iflag
40  integer iuse, ich, nch, ipr, counter
41 
42  logical,dimension(:),allocatable :: luse
43  logical lqcpass
44 
45  real(r_single),parameter :: missing = -9999.999
46  integer,parameter :: imissing = -9999
47  integer,parameter :: nvar = 4 ! number of positions in array needed for inline variance calc
48 ! variables for output, all to be allocated as nchan. Variances will be calculated using inline algorithm
49 ! accredited to Welford, according
50  real(r_quad),dimension(:),allocatable :: nobstotal, nobsassim, tbtotal, tbassim, omf_nbc , omf_bc , sigo, jo
51  real(r_quad),dimension(:,:),allocatable :: vomf_nbc, vomf_bc
52 ! total bias and fixed bias terms. When Yanqui's variational angle correction is brought in, this may need to be updated.
53  real(r_quad),dimension(:),allocatable :: totbias , fixbias
54  real(r_quad),dimension(:,:),allocatable :: vtotbias, vfixbias
55 ! variational bias correction variables, which will be allocated as nchan and npred_read
56  real(r_quad),dimension(:,:),allocatable :: biasterms
57  real(r_quad),dimension(:,:,:),allocatable :: vbiasterms
58 ! Definitions for above variables -
59 ! nobstotal - number of observations considered - total
60 ! nobsassim - number of observations that are assimilated
61 ! tbtotal - mean brightness temperature of all observations
62 ! tbassim - mean brightness temperature of assimilated observations
63 ! omf_nbc/vomf_nbc - mean/variance of O-F without bias correction applied
64 ! omf_bc/vomf_bc - mean/variance of O-F with bias correction applied
65 ! sigo - mean observation error of assimilated observations
66 ! jo - mean cost (Jo) of assimilated observations
67 ! totbias/vtotbias - mean/variance of bias correction applied to assimilated observations
68 ! fixbias/vfixbias - mean/variance of fixed scan angle position bias correction (sac.x-derived)
69 ! biasterms
70 ! /vbiasterms - means/variances of the variational terms as defined by npred_read.
71 
72 ! single variables used later for printing purposes
73  integer :: inobstotal, inobsassim
74  real(r_single) :: rvomf_nbc, rvomf_bc, rvtotbias, rvfixbias
75  real(r_single),dimension(:),allocatable :: rvbiasterms
76  character(len=13),dimension(:),allocatable :: chfrwn
77 
78  integer,parameter :: max_npred = 9
79 
80  character(len=10),dimension(max_npred) :: biasnames
81  data biasnames / 'bc_const ', &
82  'bc_satang ', &
83  'bc_tlap ', &
84  'bc_tlap2 ', &
85  'bc_clw ', &
86  'bc_coslat ', &
87  'bc_sinlat ', &
88  'bc_emis ', &
89  'bc_sst ' /
90 
91  real(r_quad) :: cvar, rch
92 
93  logical linfile
94  character*80 :: nlfn = './gsidiag_bin2txt.nl'
95 
96 
97  nargs = iargc()
98  if( nargs.eq.0 ) then
99  call usage
100  else
101  netcdf = .false.
102  debug = .false.
103  npred_read = 7
104  sst_ret = .false.
105  iversion = -9999
106  append_txt_suffix = .false.
107 
108  allocate(arg(nargs))
109  do n=1,nargs
110  call getarg(n,arg(n))
111  enddo
112  do n=1,nargs
113  if (trim(arg(n)).eq.'-nc4' ) netcdf=.true.
114  if (trim(arg(n)).eq.'-debug' ) debug=.true.
115  if (trim(arg(n)).eq.'-sst_ret' ) sst_ret=.true.
116  if (trim(arg(n)).eq.'-append_txt') append_txt_suffix=.true.
117  if (trim(arg(n)).eq.'-npred' ) read ( arg(n+1),* ) npred_read
118  if (trim(arg(n)).eq.'-iversion' ) read ( arg(n+1),* ) iversion
119  enddo
120  endif
121 
122  if (debug) write(*,*)'Debugging on - Verbose Printing'
123 
124  ! get infn from command line
125  infn = arg(nargs)
126 
127  strlen = len(trim(infn))
128 
129  write(*,*)'Input diag file: ',trim(infn)
130  inquire(file=trim(infn), exist=linfile)
131  if (.not. linfile) then
132  write(*,*)trim(infn) // ' does not exist - exiting'
133  call abort
134  endif
135 
136  if (.not. append_txt_suffix) then
137  outfn = infn(1:strlen-3) // 'txt' ! assumes GMAO diag filename format ending with .bin, and replaces it
138  else
139  outfn = infn(1:strlen) // '.txt' ! if not GMAO format, use append_txt_suffix = .true. in namelist
140  ! to simply append infile with .txt suffix
141  endif
142 
143  write(*,*)'Output text summary: ',trim(outfn)
144 
145  iflag = 0
146 
147  if (netcdf) then
148  call set_netcdf_read(.true.)
149  call nc_diag_read_init(infn, inlun)
150  else
151  open(inlun,file=infn,form='unformatted',convert='big_endian')
152  endif
153 
154  write(*,*)'File opened on lun=',inlun
155 ! open(inlun,file=infn,form='unformatted',convert='big_endian')
156 
157  call read_radiag_header( inlun, npred_read, sst_ret, headfix, headchan, headname, iflag, debug )
158 
159  nch = headfix%nchan
160  allocate(luse(nch))
161 
162  if (debug) then
163  write(*,*)'Number of Channels: ',nch
164  write(*,*)'Number of variationalbc predictors: ',npred_read
165  write(*,*)' predictors: ',biasnames(1:npred_read)
166  write(*,*)' iversion=',headfix%iversion
167  endif
168 
169  if (iversion .gt. 0) then
170  write(*,*)'BE AWARE THAT iversion IS BEING OVERRIDEN!'
171  write(*,*)' iversion diag, override=',headfix%iversion,iversion
172  write(*,*)' (this was made necessary w/ emis bc...hopefully only temporary)'
173  headfix%iversion = iversion
174  endif
175 
176  allocate(nobstotal(nch), &
177  nobsassim(nch), &
178  tbtotal(nch), &
179  tbassim(nch), &
180  omf_nbc(nch), &
181  omf_bc(nch), &
182  sigo(nch), &
183  jo(nch), &
184  totbias(nch), &
185  fixbias(nch) )
186  allocate(vomf_nbc(nvar,nch), &
187  vomf_bc(nvar,nch), &
188  vtotbias(nvar,nch), &
189  vfixbias(nvar,nch) )
190  allocate(biasterms(nch,max_npred) )
191  allocate(vbiasterms(nvar,nch,max_npred) )
192  allocate(rvbiasterms(max_npred) )
193  allocate(chfrwn(nch) )
194 
195  nobstotal = 0.0
196  nobsassim = 0.0
197  tbtotal = 0.0
198  tbassim = 0.0
199  omf_nbc = 0.0
200  omf_bc = 0.0
201  sigo = 0.0
202  jo = 0.0
203  totbias = 0.0
204  fixbias = 0.0
205  vomf_nbc = 0.0
206  vomf_bc = 0.0
207  vtotbias = 0.0
208  vfixbias = 0.0
209  biasterms = 0.0
210  vbiasterms = 0.0
211  rvbiasterms = 0.0
212 
213  do ich=1,nch
214  luse(ich) = (headchan(ich)%iuse .gt. 0)
215  if (headchan(ich)%wave .gt. 100.0) then
216  write(chfrwn(ich),fmt='(F9.3,A4)')headchan(ich)%wave,'cm-1'
217  else
218  write(chfrwn(ich),fmt='(F9.3,A4)')headchan(ich)%freq,'GHz '
219  endif
220  if (debug) write(*,*)'ich,chfreq or wn=',ich,chfrwn(ich)
221  enddo
222  counter = 0
223 
224  do while (iflag .ge. 0) ! iflag == 0 means the end of the file
225  call read_radiag_data ( inlun, headfix, .false., datafix, datachan, &
226  dataextra, iflag )
227 
228  if (iflag .lt. 0) cycle
229  counter = counter + 1
230 ! print *,counter,datafix%lon,datafix%lat
231 
232  do ich=1,nch
233  lqcpass = luse(ich) .and. datachan(ich)%qcmark .eq. 0
234 
235  ! check to make sure ob is realistic - SSMI seems to have the occasional bad ob sneak in
236  if (datachan(ich)%tbobs .gt. 0.0 .and. datachan(ich)%tbobs .lt. 450) then
237 
238  ! first, operations for all observations regardless of luse
239  nobstotal(ich) = nobstotal(ich) + 1
240  if (debug .and. nobstotal(ich) .lt. 15) print *,nobstotal(ich),ich,datachan(ich)%tbobs
241 
242  tbtotal(ich) = tbtotal(ich) + datachan(ich)%tbobs
243  if (luse(ich)) then
244  if (lqcpass) then
245  nobsassim(ich) = nobsassim(ich) + 1
246  tbassim(ich) = tbassim(ich) + datachan(ich)%tbobs
247  omf_nbc(ich) = omf_nbc(ich) + datachan(ich)%omgnbc
248  call inc_var(datachan(ich)%omgnbc, vomf_nbc(:,ich))
249  omf_bc(ich) = omf_bc(ich) + datachan(ich)%omgbc
250  call inc_var(datachan(ich)%omgbc, vomf_bc(:,ich))
251  sigo(ich) = sigo(ich) + 1.0 / datachan(ich)%errinv
252  jo(ich) = jo(ich) + (datachan(ich)%omgbc * datachan(ich)%errinv)**2
253  totbias(ich) = totbias(ich) + ( datachan(ich)%omgnbc - datachan(ich)%omgbc )
254  call inc_var(datachan(ich)%omgnbc - datachan(ich)%omgbc, vtotbias(:,ich))
255  fixbias(ich) = fixbias(ich) + datachan(ich)%bifix(1)
256  call inc_var(datachan(ich)%bifix(1), vfixbias(:,ich))
257  biasterms(ich,1) = biasterms(ich,1) + datachan(ich)%bicons
258  call inc_var(datachan(ich)%bicons, vbiasterms(:,ich,1))
259  biasterms(ich,2) = biasterms(ich,2) + datachan(ich)%biang
260  call inc_var(datachan(ich)%biang, vbiasterms(:,ich,2))
261  biasterms(ich,3) = biasterms(ich,3) + datachan(ich)%bilap
262  call inc_var(datachan(ich)%bilap, vbiasterms(:,ich,3))
263  biasterms(ich,4) = biasterms(ich,4) + datachan(ich)%bilap2
264  call inc_var(datachan(ich)%bilap2, vbiasterms(:,ich,4))
265  biasterms(ich,5) = biasterms(ich,5) + datachan(ich)%biclw
266  call inc_var(datachan(ich)%biclw, vbiasterms(:,ich,5))
267  biasterms(ich,6) = biasterms(ich,6) + datachan(ich)%bicos
268  call inc_var(datachan(ich)%bicos, vbiasterms(:,ich,6))
269  biasterms(ich,7) = biasterms(ich,7) + datachan(ich)%bisin
270  call inc_var(datachan(ich)%bisin, vbiasterms(:,ich,7))
271  biasterms(ich,8) = biasterms(ich,8) + datachan(ich)%biemis
272  call inc_var(datachan(ich)%biemis, vbiasterms(:,ich,8))
273  biasterms(ich,9) = biasterms(ich,9) + datachan(ich)%bisst
274  call inc_var(datachan(ich)%bisst, vbiasterms(:,ich,9))
275  endif
276  else
277  omf_nbc(ich) = omf_nbc(ich) + datachan(ich)%omgnbc
278  call inc_var(datachan(ich)%omgnbc, vomf_nbc(:,ich))
279  endif
280 
281  endif
282  enddo
283 
284  enddo
285 
286  open(unit=outlun,file=outfn)
287 
288 
289  do ich=1,nch
290  inobstotal = nobstotal(ich)
291  if (nobstotal(ich) .gt. 1) then
292  tbtotal(ich) = tbtotal(ich) / nobstotal(ich)
293 
294  if (luse(ich)) then
295  inobsassim = nobsassim(ich)
296  if (nobsassim(ich) .gt. 0) then
297  tbassim(ich) = tbassim(ich) / nobsassim(ich)
298  omf_nbc(ich) = omf_nbc(ich) / nobsassim(ich)
299  rvomf_nbc = ret_stddev(vomf_nbc(:,ich))
300  omf_bc(ich) = omf_bc(ich) / nobsassim(ich)
301  rvomf_bc = ret_stddev(vomf_bc(:,ich))
302  sigo(ich) = sigo(ich) / nobsassim(ich)
303  jo(ich) = jo(ich) / nobsassim(ich)
304  totbias(ich) = totbias(ich) / nobsassim(ich)
305  rvtotbias = ret_stddev(vtotbias(:,ich))
306  fixbias(ich) = fixbias(ich) / nobsassim(ich)
307  rvfixbias = ret_stddev(vfixbias(:,ich))
308  do ipr=1,max_npred
309  biasterms(ich,ipr) = biasterms(ich,ipr) / nobsassim(ich)
310  rvbiasterms(ipr) = ret_stddev(vbiasterms(:,ich,ipr))
311  enddo
312  else ! if zero obs assimilated, pass missings
313  tbassim(ich) = missing
314  omf_nbc(ich) = missing
315  rvomf_nbc = missing
316  omf_bc(ich) = missing
317  rvomf_bc = missing
318  sigo(ich) = missing
319  jo(ich) = missing
320  totbias(ich) = missing
321  rvtotbias = missing
322  fixbias(ich) = missing
323  rvfixbias = missing
324  do ipr=1,max_npred
325  biasterms(ich,ipr) = missing
326  rvbiasterms(ipr) = missing
327  enddo
328  endif
329  else
330  inobsassim = imissing
331  tbassim(ich) = missing
332  omf_nbc(ich) = omf_nbc(ich) / nobstotal(ich)
333  rvomf_nbc = ret_stddev(vomf_nbc(:,ich))
334  omf_bc(ich) = missing
335  rvomf_bc = missing
336  sigo(ich) = missing
337  jo(ich) = missing
338  totbias(ich) = missing
339  rvtotbias = missing
340  fixbias(ich) = missing
341  rvfixbias = missing
342  do ipr=1,max_npred
343  biasterms(ich,ipr) = missing
344  rvbiasterms(ipr) = missing
345  enddo
346  endif
347  else
348  tbtotal(ich) = missing
349  inobsassim = imissing
350  tbassim(ich) = missing
351  omf_nbc(ich) = missing
352  rvomf_nbc = missing
353  omf_bc(ich) = missing
354  rvomf_bc = missing
355  sigo(ich) = missing
356  jo(ich) = missing
357  totbias(ich) = missing
358  rvtotbias = missing
359  fixbias(ich) = missing
360  rvfixbias = missing
361  do ipr=1,max_npred
362  biasterms(ich,ipr) = missing
363  rvbiasterms(ipr) = missing
364  enddo
365  endif
366  if (npred_read .lt. max_npred) then
367  biasterms(ich,npred_read+1:max_npred) = missing
368  rvbiasterms(npred_read+1:max_npred) = missing
369  endif
370  if (ich .eq. 1) then
371  ! write header
372  write(unit=outlun,fmt='(A1,A19,3x,A10,3x,A5)')'!','Satellite/Sensor','YYYYMMDDHH','#chan'
373  write(unit=outlun,fmt='(A20,3x,I10,3x,I5)')trim(headfix%isis), headfix%idate, headfix%nchan
374 
375 !_RT write(unit=outlun,fmt='(A6,A1,A13,A1,A4,A1,A12,A1,A12,30(A1,A9))')'!ichan','|','freq/wavenum','|','iuse','|','#total obs','|', &
376 !_RT '#assim obs','|','Tb-Total','|','Tb-Assim','|','O-F noBC','|','','|','O-F BC','|','','|','Obs Error','|','Cost (Jo)','|','bc_total','|','','|', &
377 !_RT 'bc_fixang','|','',('|',biasnames(ipr),'|','',ipr=1,max_npred)
378 !_RT write(unit=outlun,fmt='(A6,A1,A13,A1,A4,A1,A12,A1,A12,30(A1,A9))')'! ','|','' ,'|','' ,'|','' ,'|', &
379 !_RT '' ,'|','mean','|','mean','|','mean','|','stddev','|','mean','|','stddev','|','mean','|','mean','|','mean','|','stddev','|','mean','|','stddev',('|','mean','|','stddev',ipr=1,max_npred)
380  endif
381 !_RTwrite(unit=outlun,fmt='(I6,1x,A13,1x,I4,1x,I12,1x,I12,1x,30(f9.3,1x))')headchan(ich)%nuchan,chfrwn(ich),headchan(ich)%iuse,inobstotal, &
382 !_RT inobsassim,tbtotal(ich),tbassim(ich),omf_nbc(ich),rvomf_nbc,omf_bc(ich),rvomf_bc,sigo(ich),jo(ich), &
383 !_RT totbias(ich),rvtotbias,fixbias(ich),rvfixbias,(biasterms(ich,ipr),rvbiasterms(ipr),ipr=1,max_npred)
384  enddo
385 end program gsidiag_bin2txt
386 
387 subroutine inc_var(x,arr)
389 
390  real(r_single) ,intent(in) :: x
391  real(r_quad),dimension(4),intent(inout) :: arr
392 
393  arr(1) = arr(1) + 1
394  arr(2) = x - arr(3)
395  arr(3) = arr(3) + arr(2)/arr(1)
396  arr(4) = arr(4) + arr(2)*(x-arr(3))
397 
398 end subroutine inc_var
399 
400 real(r_quad) function ret_var(arr)
401  use ncd_kinds,only: r_quad
402 
403  real(r_quad),dimension(4),intent(in) :: arr
404 
405  ret_var = arr(4) / (arr(1)- 1)
406  return
407 end function ret_var
408 
409 real(r_quad) function ret_stddev(arr)
410  use ncd_kinds,only: r_quad
411 
412  real(r_quad),dimension(4),intent(in) :: arr
413 
414  ret_stddev = (arr(4) / (arr(1)- 1))**(0.5)
415  return
416 end function ret_stddev
417 
418 subroutine usage
419  write(6,100)
420 100 format( "Usage: ",/,/ &
421  " gsidiag_bin2txt.x <options> <filename>",/,/ &
422  "where options:",/ &
423  " -nc4 : Read NC4 Diag (instead of binary)",/ &
424  " -debug : Set debug verbosity",/ &
425  " -sst_ret : SST BC term is included (default: not included)",/ &
426  " -npred INT : Number of preductors (default: 7)",/ &
427  " -iversion INT : Override iversion with INT (default: use internal iversion)",/ &
428  " -append_txt : Append .txt suffix, instead of replace last three",/ &
429  " characters (default: replaced)",/ &
430  " Note: The GMAO diag files end with .bin or .nc4,",/ &
431  " which is where fixed 3-char truncation originates",/,/,/ &
432  " Example:",/ &
433  " gsidiag_bin2txt.x nc_4emily_nc4.diag_airs_aqua_ges.20161202_06z.nc4",/ &
434  " Output file:",/ &
435  " nc_4emily_nc4.diag_airs_aqua_ges.20161202_06z.txt",/ &
436  )
437  stop
438 end subroutine usage
subroutine, public read_radiag_header(ftin, npred_radiag, retrieval, header_fix, header_chan, data_name, iflag, lverbose)
Definition: read_diag.f90:321
integer, parameter, public strlen
real(r_quad) function ret_var(arr)
subroutine, public set_netcdf_read(use_netcdf)
Definition: read_diag.f90:224
subroutine, public read_radiag_data(ftin, header_fix, retrieval, data_fix, data_chan, data_extra, iflag)
Definition: read_diag.f90:729
real(r_quad) function ret_stddev(arr)
subroutine usage
program gsidiag_bin2txt
integer, parameter, public r_quad
Definition: ncd_kinds.F90:82
subroutine inc_var(x, arr)
integer, parameter, public r_single
Definition: ncd_kinds.F90:79
subroutine nc_diag_read_init(filename, file_ncdr_id, from_push)