1 subroutine da_varbc_init (iv, be)
3 !---------------------------------------------------------------------------
4 ! PURPOSE: Initialize Variational bias correction from VARBC.in file
6 ! Called from da_radiance_init routine
8 ! HISTORY: 10/26/2007 - Creation Tom Auligne
9 !---------------------------------------------------------------------------
13 type (iv_type), intent(inout) :: iv ! O-B structure.
15 type (be_type), intent(inout) :: be ! background error.
20 integer :: n, i, ii, j, k, nchan, npred, npred_ws, ipred, ichan, np, nsensor
21 integer :: iunit, iost
22 integer :: size_jp, jp_start
23 integer :: platform_id, satellite_id, sensor_id, nchanl, npredmax, num_rad
24 integer, allocatable :: pred_use(:), ipred_ws(:)
25 real, allocatable :: pred_ws(:)
26 character(len=filename_len) :: filename
27 character(len=120) :: cline
28 logical :: lvarbc_read, limatch, lmatch
30 if (trace_use) call da_trace_entry("da_varbc_init")
32 !--------------------------------------------------------------
34 !--------------------------------------------------------------
35 size_jp = 0 !! Jp Control Variable size
36 jp_start = be % cv % size_jb + be % cv % size_je
38 do n = 1, iv % num_inst
39 nchan = iv%instid(n)%nchan
40 iv%instid(n)%varbc_info%npredmax = 0
41 allocate ( iv%instid(n)%varbc(nchan) )
43 iv%instid(n)%varbc(k)%npred = 0 ! by default, do not use VarBC
44 iv%instid(n)%varbc(k)%nobs = 0
48 !--------------------------------------------------------------
49 ! [2] Read VarBC.in file and match with obs data set
50 !--------------------------------------------------------------
52 inquire(file=trim(adjustl(filename)), exist=lvarbc_read)
55 write(unit=stdout,fmt='(A)') 'VARBC: Reading VARBC.in file'
56 call da_get_unit(iunit)
57 open(unit=iunit,file=filename, form='formatted', status='old')
60 read(iunit, *) nsensor
63 read(iunit, *) ; read(iunit, *) ;read(iunit, *)
64 read(iunit, *) platform_id, satellite_id, sensor_id, nchanl, npredmax
66 do n = 1, iv % num_inst
67 if ( (platform_id == iv%instid(n)%platform_id) .and. & !! found match !!
68 (satellite_id == iv%instid(n)%satellite_id) .and. & !! found match !!
69 (sensor_id == iv%instid(n)%sensor_id) ) then !! found match !!
70 limatch = .true. !! found match !!
72 ! write(unit=stdout,fmt='(A,A)') &
73 ! 'VARBC: Matching with obs for ', iv%instid(n)%rttovid_string
75 num_rad = iv%instid(n)%num_rad
76 allocate ( iv%instid(n)%varbc_info%pred(npredmax, num_rad) )
78 iv%instid(n)%varbc_info%platform_id = platform_id
79 iv%instid(n)%varbc_info%satellite_id = satellite_id
80 iv%instid(n)%varbc_info%sensor_id = sensor_id
81 iv%instid(n)%varbc_info%nchanl = nchanl
82 iv%instid(n)%varbc_info%npredmax = npredmax
83 iv%instid(n)%varbc_info%gammapred = 9 ! CRTM Gamma Correction
85 allocate ( iv%instid(n)%varbc_info%pred_mean(npredmax) )
86 allocate ( iv%instid(n)%varbc_info%pred_std (npredmax) )
87 allocate ( iv%instid(n)%varbc_info%nbgerr (npredmax) )
88 read(iunit, *) iv%instid(n)%varbc_info%pred_mean
89 read(iunit, *) iv%instid(n)%varbc_info%pred_std
90 read(iunit, *) iv%instid(n)%varbc_info%nbgerr
93 allocate ( pred_use(npredmax), ipred_ws(npredmax), pred_ws(npredmax) )
96 read(iunit, '(A)',iostat=iost) cline
97 read(cline, *) ii, ichan, pred_use
98 npred = COUNT (pred_use >= 0)
99 if (npred <= 0) cycle !! VarBC channels only
101 chan_loop: do k = 1, iv%instid(n)%nchan
102 if (iv%instid(n)%ichan(k) == ichan) then !! found match !!
103 lmatch = .true. !! found match !!
104 iv%instid(n)%varbc(k)%ichanl = ichan
105 iv%instid(n)%varbc(k)%npred = npred
106 allocate ( iv%instid(n)%varbc(k)%pred_use (npredmax) )
107 allocate ( iv%instid(n)%varbc(k)%ipred (npred) )
108 allocate ( iv%instid(n)%varbc(k)%index (npred) )
109 allocate ( iv%instid(n)%varbc(k)%param (npred) )
110 allocate ( iv%instid(n)%varbc(k)%bgerr (npred) )
111 allocate ( iv%instid(n)%varbc(k)%vtox (npred,npred) )
112 iv%instid(n)%varbc(k)%pred_use = pred_use
113 iv%instid(n)%varbc(k)%vtox(1:npred, 1:npred) = 0.0
115 iv%instid(n)%varbc(k)%vtox(ipred, ipred) = 1.0
117 iv%instid(n)%varbc(k)%param(1:npred) = 0.0
118 iv%instid(n)%varbc(k)%bgerr(1:npred) = 0.0
119 iv%instid(n)%varbc(k)%ipred(1:npred) = &
120 PACK((/ (ipred, ipred=1,npredmax) /), mask = (pred_use >= 0))
122 ! VarBC warm-start parameters
123 !-----------------------------
124 npred_ws = COUNT (pred_use > 0)
125 if (npred_ws > 0) then
126 read(cline, *) ii, ichan, pred_use, pred_ws(1:npred_ws)
127 ipred_ws(1:npred_ws) = PACK((/ (ipred, ipred=1,npred) /), &
128 mask = (pred_use(iv%instid(n)%varbc(k)%ipred) > 0))
129 iv%instid(n)%varbc(k)%param(ipred_ws(1:npred_ws))= pred_ws(1:npred_ws)
132 ! Jp Control Variable size
133 !--------------------------
135 size_jp = size_jp + 1
136 iv%instid(n)%varbc(k)%index(ipred) = jp_start + size_jp
143 if (.not. lmatch) write(unit=stdout,fmt='(A,I4)') &
144 'VARBC: no matching for channel:',ichan
146 deallocate(pred_use, ipred_ws, pred_ws)
149 if (.not. limatch) then
150 read(iunit, *) ; read(iunit, *) ; read(iunit, *) ; read(iunit, *) ; read(iunit, *)
154 write(unit=stdout,fmt='(A,3I4)') &
155 'VARBC: no matching for platform/satid/sensor',platform_id, satellite_id, sensor_id
159 call da_free_unit(iunit)
161 write(unit=stdout,fmt='(A)') 'VARBC: could not find VARBC.in file --> VARBC switched off'
163 freeze_varbc = .false.
166 !--------------------------------------------------------------
167 ! [3] Define VarBC control variable size:
168 !--------------------------------------------------------------
169 use_varbc = use_varbc.and.(.not.freeze_varbc)
171 be % cv % size_jp = size_jp
172 cv_size_domain_jp = size_jp
175 if (trace_use) call da_trace_exit("da_varbc_init")
177 end subroutine da_varbc_init