1 subroutine da_check_buddy_synop(iv, ob, dx, it)
3 !-----------------------------------------------------------------------
4 ! Purpose: Buddy check for SYNOP observations.
6 ! For SYNOP, there may not need the binning procedure before going
7 ! into the da_buddy_qc. So bottom_pressure = 30000.0 nad num_bins_p = 1.
8 ! If you want to do binning, minor modifications needed.
10 ! Yong-Run Guo, 10/10/2008
11 !-----------------------------------------------------------------------
15 type(iv_type), intent(inout) :: iv
16 type(y_type), intent(in) :: ob ! Observation structure
17 integer, intent(in) :: it ! Outer iteration
18 real, intent(in) :: dx
20 integer :: k, n, bin, i, j, m_max, kk, nn, numobs
21 real :: dx_km, Press_mb
23 ! All data in one bin:
24 integer, parameter :: num_bins_p = 1
25 real, parameter :: bottom_pressure = 30000.0
27 ! Total of 13 bins used:
28 ! integer, parameter :: num_bins_p = 13
29 ! real, parameter :: bottom_pressure = 100000.0
31 real, parameter :: bin_width_p = 10000.0
32 real , dimension(0:num_bins_p) :: bin_start_p, pressure, bin_width
33 integer, dimension(0:num_bins_p) :: num
35 integer, allocatable, dimension(:,:) :: n_iv
37 integer, allocatable, dimension(:) :: qc_flag_small
38 real, allocatable, dimension(:) :: xob, yob, obs
39 character(len=5), allocatable, dimension(:) :: station_id
40 !-----------------------------------------------------------------------------
42 ! if (trace_use_dull) call da_trace_entry("da_check_buddy_synop")
44 !---------------------------------------------------------------------------
45 ! [1.0] Open diagnostic file:
46 !---------------------------------------------------------------------------
48 if (rootproc .and. check_buddy_print) then
49 write (check_buddy_unit,'(/A)') &
50 '================================================================'
51 write (unit = check_buddy_unit, fmt = '(A,i4,A,i4/)') &
52 'SYNOP BUDDY TEST QC: no_buddies_qc=',no_buddies,&
53 ' fails_buddy_check_qc=',fails_buddy_check
56 !---------------------------------------------------------------------------
57 ! [2.0] Bin the data vertically based on the obs p::
58 !---------------------------------------------------------------------------
60 ! print*,'==> Synop Buddy check: num_bins_p = ',num_bins_p
63 bin_start_p(0) = bottom_pressure
64 pressure (0) = bin_start_p(0)
67 bin_start_p(n) = bin_start_p(n-1) - bin_width(n-1)
68 if (bin_start_p(n) > 30000.0) then
69 bin_width(n) = bin_width_p
71 bin_width(n) = bin_width_p / 2.0
73 pressure(n) = bin_start_p(n) - bin_width(n)/2.0
75 bin_start_p(0) = bottom_pressure + 10.0
77 ! Only 1 bin=0 used, if you want to do the normal binning, comment out
79 pressure (0) = 100000.0
81 ! print '(I3,2x,"start_p=",f10.1," mid-pressure=",f10.1," width=",f10.1)', &
82 ! (n, bin_start_p(n), pressure(n), bin_width(n), n=0, num_bins_p)
84 ! 2.1 Get the maximum dimension for all the bins:
87 do n = iv%info(synop)%n1,iv%info(synop)%n2
88 if (ob%synop(n)%p > missing_r) then
89 do i = 0, num_bins_p - 1
90 if (iv%synop(n)%p%qc >=0 .and. &
91 (ob%synop(n)%p <= bin_start_p(i) .and. &
92 ob%synop(n)%p > bin_start_p(i+1)) ) then
97 ! bin = int( (bottom_pressure - ob%synop(n)%p)/bin_width(n) ) + 1
98 if (ob%synop(n)%p > bottom_pressure) bin = 0
99 if (ob%synop(n)%p <= bin_start_p(num_bins_p)) bin = num_bins_p
100 num(bin) = num(bin) + 1
104 ! print *,(i,num(i),i=0,num_bins_p)
105 ! print *,"m_max=", m_max
107 ! 2.2 Save the location indices (n,k) for each of bins:
109 ! print '("Synop n1=",i5," n2=",i5)',iv%info(synop)%n1,iv%info(synop)%n2
110 allocate ( n_iv( 0: num_bins_p,1:m_max+10 ) )
113 do n = iv%info(synop)%n1,iv%info(synop)%n2
114 if (ob%synop(n)%p > missing_r) then
115 do i = 0, num_bins_p - 1
116 if (iv%synop(n)%p%qc >=0 .and. &
117 (ob%synop(n)%p <= bin_start_p(i) .and. &
118 ob%synop(n)%p > bin_start_p(i+1)) ) then
123 ! bin = int( (bottom_pressure - ob%synop(n)%p)/bin_width(n) ) + 1
124 if (ob%synop(n)%p > bottom_pressure) bin = 0
125 if (ob%synop(n)%p <= bin_start_p(num_bins_p)) bin = num_bins_p
127 num(bin) = num(bin) + 1
128 n_iv(bin,num(bin)) = n
133 ! 2.3 Print out the binned results:
135 ! do i = 0, num_bins_p
136 ! print '("bin:",I2," start_p=",f8.1," num=",i5)', &
137 ! i, bin_start_p(i), num(i)
140 ! print '("j, n:",2i5,2x,"p=",f10.1)', &
141 ! j, n, ob%synop(n)%p
144 !---------------------------------------------------------------------------
145 ! [3.0] Buddy check for each of the pressure-bins::
146 !---------------------------------------------------------------------------
150 if (num(i) <= 1) cycle
152 ! 3.1 Get the Station locations:
155 Press_mb = pressure(i) / 100.0
158 allocate(xob(1:numobs))
159 allocate(yob(1:numobs))
160 allocate(obs(1:numobs))
161 allocate(qc_flag_small(1:numobs))
162 allocate(station_id (1:numobs))
164 if (rootproc .and. check_buddy_print) then
165 write (check_buddy_unit,'(5X,A)') &
166 '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
167 write (unit = check_buddy_unit, fmt = '(5X,A,I3,2X,A,I6)') &
168 'BIN =', i, 'NUMOBS =', numobs
170 ! print *,'SYNOP: BIN=', i, ' numobs=',num(i)
177 station_id(n) = iv%info(synop)%id(nn)
178 xob(n) = iv%info(synop)%x(1,nn)
179 yob(n) = iv%info(synop)%y(1,nn)
182 ! 3.2 U-component buddy check:
184 if (rootproc .and. check_buddy_print) &
185 write (check_buddy_unit,'(8X,A,A,f10.1,3(A,f6.1))') &
186 'UU ', ' Pressure(mb)=',Press_mb, ' ds(km)=',dx_km,&
187 ' buddy_weight=', buddy_weight , &
188 ' max_buddy_uv=', max_buddy_uv
191 qc_flag_small(n) = missing
194 obs(n) = iv%synop(nn)%u%inv
195 qc_flag_small(n) = iv%synop(nn)%u%qc
198 call da_buddy_qc (numobs, m_max, station_id, xob, yob, obs, qc_flag_small,&
199 'UU ', Press_mb, dx_km, buddy_weight , &
200 max_buddy_uv , check_buddy_unit, check_buddy_print )
202 ! Put the qc_flag back into the permanent space.
206 iv%synop(nn)%u%qc = qc_flag_small(n)
209 ! 3.2 V-component buddy check:
211 if (rootproc .and. check_buddy_print) &
212 write (check_buddy_unit,'(8X,A,A,f10.1,3(A,f6.1))') &
213 'VV ', ' Pressure(mb)=',Press_mb, ' ds(km)=',dx_km,&
214 ' buddy_weight=', buddy_weight , &
215 ' max_buddy_uv=', max_buddy_uv
219 qc_flag_small(n) = missing
222 obs(n) = iv%synop(nn)%v%inv
223 qc_flag_small(n) = iv%synop(nn)%v%qc
226 call da_buddy_qc (numobs, m_max, station_id, xob, yob, obs, qc_flag_small,&
227 'VV ', Press_mb, dx_km, buddy_weight , &
228 max_buddy_uv , check_buddy_unit, check_buddy_print )
230 ! Put the qc_flag back into the permanent space.
234 iv%synop(nn)%v%qc = qc_flag_small(n)
237 ! 3.3 Temperature buddy check:
239 if (rootproc .and. check_buddy_print) &
240 write (check_buddy_unit,'(8X,A,A,f10.1,3(A,f6.1))') &
241 'TT ', ' Pressure(mb)=',Press_mb, ' ds(km)=',dx_km,&
242 ' buddy_weight=', buddy_weight , &
243 ' max_buddy_t=', max_buddy_t
246 qc_flag_small(n) = missing
249 obs(n) = iv%synop(nn)%t%inv
250 qc_flag_small(n) = iv%synop(nn)%t%qc
253 call da_buddy_qc (numobs, m_max, station_id, xob, yob, obs, qc_flag_small,&
254 'TT ', Press_mb, dx_km, buddy_weight , &
255 max_buddy_t , check_buddy_unit, check_buddy_print )
257 ! Put the qc_flag back into the permanent space.
261 iv%synop(nn)%t%qc = qc_flag_small(n)
264 ! 3.3 Specific humidity buddy check:
266 if (rootproc .and. check_buddy_print) &
267 write (check_buddy_unit,'(8X,A,A,f10.1,3(A,f6.1))') &
268 'QQ ', ' Pressure(mb)=',Press_mb, ' ds(km)=',dx_km,&
269 ' buddy_weight=', buddy_weight , &
270 ' max_buddy_rh=', max_buddy_rh
273 qc_flag_small(n) = missing
276 obs(n) = iv%synop(nn)%q%inv
277 qc_flag_small(n) = iv%synop(nn)%q%qc
280 call da_buddy_qc (numobs, m_max, station_id, xob, yob, obs, qc_flag_small,&
281 'QQ ', Press_mb, dx_km, buddy_weight , &
282 max_buddy_rh , check_buddy_unit, check_buddy_print )
284 ! Put the qc_flag back into the permanent space.
288 iv%synop(nn)%q%qc = qc_flag_small(n)
291 ! 3.4 Pressure buddy check:
293 if (rootproc .and. check_buddy_print) &
294 write (check_buddy_unit,'(8X,A,A,f10.1,3(A,f6.1))') &
295 'PMSL ', ' Pressure(mb)=',Press_mb, ' ds(km)=',dx_km,&
296 ' buddy_weight=', buddy_weight , &
297 ' max_buddy_p=', max_buddy_p
300 qc_flag_small(n) = missing
303 obs(n) = iv%synop(nn)%p%inv
304 qc_flag_small(n) = iv%synop(nn)%p%qc
307 call da_buddy_qc (numobs, m_max, station_id, xob, yob, obs, qc_flag_small,&
308 'PMSL ', Press_mb, dx_km, buddy_weight , &
309 max_buddy_p , check_buddy_unit, check_buddy_print )
311 ! Put the qc_flag back into the permanent space.
315 iv%synop(nn)%p%qc = qc_flag_small(n)
318 ! 3.5 Deallocate arrays
325 deallocate(qc_flag_small)
326 deallocate(station_id )
332 if (trace_use_dull) call da_trace_exit("da_check_buddy_synop")
334 end subroutine da_check_buddy_synop