1 subroutine da_scan_obs_rain (iv, filename, ifgat)
3 !---------------------------------------------------------------------------
4 ! Purpose: Scan the rain observation file
5 !---------------------------------------------------------------------------
9 type (iv_type), intent(inout) :: iv
10 character(len=*), intent(in) :: filename
11 integer, intent(in) :: ifgat
12 integer :: i, j, n, iost, nlevels, fm
16 type (rain_single_level_type) :: platform
18 character (len = 120) :: char_file_rain
19 character (len = 120) :: fmt_name
20 character (len = 160) :: info_string
21 logical :: outside, outside_all
22 integer :: n_dup, ndup
25 integer :: iyear, imonth, iday, ihour, imin
28 real :: dlat_earth,dlon_earth,crit
29 integer :: itt,itx,iout
32 real, allocatable :: in(:), out(:)
34 integer :: num_outside_all, num_outside_time, num_thinned, num_report
36 if (trace_use) call da_trace_entry("da_scan_obs_rain")
42 tp = iv%info(rain)%plocal(ifgat-1)
47 call da_get_unit(iunit)
49 FILE = trim(filename), &
51 ACCESS = 'SEQUENTIAL', &
56 write(unit=message(1),fmt='(A,I5,A)') &
57 "Error",iost," opening rainfall obs file "//trim(filename)
58 call da_warning(__FILE__,__LINE__,message(1:1))
59 call da_free_unit(iunit)
60 if (trace_use) call da_trace_exit("da_scan_obs_rain")
64 ! 2. read rainfall data
70 read (unit=iunit, fmt = '(A)', iostat = iost) char_file_rain
75 ! Does matter if present and unreadable
76 call da_error(__FILE__,__LINE__, &
77 (/"Cannot read rainfall file"/))
84 read (unit=iunit, fmt = '(A)', iostat = iost) info_string
87 write(unit=message(1),fmt='(A,I3,A,I3)') &
88 "Error",iost,"reading rainfall obs header on unit",iunit
89 call da_warning(__FILE__,__LINE__,message(1:1))
90 if (trace_use) call da_trace_exit("da_scan_obs_rain")
94 if (info_string(1:6) == 'EACH ') exit
98 ! 2.3 total rainfall data info
100 read (unit=char_file_rain (8:14),fmt='(I7)', iostat = iost) file_rain
104 read (unit=iunit, fmt = '(A)', iostat = iost)
108 reports: do n = 1, file_rain
110 ! 3.1 read station general info
112 read (unit = iunit, iostat = iost, &
113 fmt = '(A12,1X,A19,1X,I6,2(F12.3,2X),F8.1,1X,A5)') &
114 platform % info % platform, &
115 platform % info % date_char, &
116 platform % info % levels, &
117 platform % info % lat, &
118 platform % info % lon, &
119 platform % info % elv, &
122 if (print_detail_rain) then
123 write(unit=stdout, fmt = '(A12,1X,A19,1X,I6,2(F12.3,2X),F8.1,1X,A5)') &
124 platform % info % platform, &
125 platform % info % date_char, &
126 platform % info % levels, &
127 platform % info % lat, &
128 platform % info % lon, &
129 platform % info % elv, &
133 read(unit=platform % info % platform (4:6), fmt='(I3)') fm
135 num_report = num_report+1
137 ! 3.2 read rainfall data
139 platform%each (1) = rain_each_type(missing_r, missing, -1.0,&
140 field_type(missing_r, missing, missing_r, missing, missing_r))
142 read (unit = iunit, fmt = '(F12.3,F12.3,I4,F12.3)') &
143 platform % each (1) % height, &
144 platform % each (1) % rain % inv, &
145 platform % each (1) % rain % qc, &
146 platform % each (1) % rain % error
148 ! 3.3 Check if outside of the time range:
150 read (platform%info%date_char,'(i4,4(1x,i2))') &
151 iyear, imonth, iday, ihour, imin
152 call da_get_julian_time (iyear,imonth,iday,ihour,imin,obs_time)
153 if ( obs_time < time_slots(0) .or. &
154 obs_time >= time_slots(num_fgat_time) ) then
155 num_outside_time = num_outside_time + 1
159 call da_llxy (platform%info, platform%loc, outside, outside_all)
161 nlevels = platform%info%levels
163 if (outside_all) then
164 num_outside_all = num_outside_all + 1
168 dlat_earth = platform%info%lat
169 dlon_earth = platform%info%lon
170 if (dlon_earth < 0.0) dlon_earth = dlon_earth + 360.0
171 if (dlon_earth >= 360.0) dlon_earth = dlon_earth - 360.0
172 dlat_earth = dlat_earth * deg2rad
173 dlon_earth = dlon_earth * deg2rad
175 ! 3.4 Loop over duplicating obs for global
178 (platform%loc%i == ids .or. platform%loc%i == ide)) n_dup= 2
180 if (test_transforms) ndup = 1
186 if (iv%info(rain)%nlocal > max_rain_input) then
187 write(unit=message(1),fmt='(A,I6,A,I6)') &
188 ' rain #= ',iv%info(rain)%nlocal, ' > max_rain_input = ', max_rain_input
189 call da_error(__FILE__,__LINE__,message(1:1))
191 iv%info(rain)%ntotal = iv%info(rain)%ntotal + 1
192 if (outside) cycle reports
193 if ( thin_rainobs ) then
195 call map2grids(rain,ifgat,dlat_earth,dlon_earth,crit,iv%info(rain)%nlocal,itx,1,itt,iout,iuse)
196 if ( .not. iuse ) then
197 num_thinned = num_thinned + 1
201 iv%info(rain)%nlocal = iv%info(rain)%nlocal + 1
205 write(unit=message(1), fmt='(a)') 'unsaved obs found:'
206 write(unit=message(2), fmt='(2a)') &
207 'platform%info%platform=', platform%info%platform
208 write(unit=message(3), fmt='(a, i3)') &
209 'platform%info%levels=', platform%info%levels
210 call da_warning(__FILE__,__LINE__,message(1:3))
214 iv%info(rain)%max_lev = 1
216 end do ! loop over duplicate
220 if ( thin_rainobs ) then
221 if ( iv%info(rain)%ntotal > 0 ) then
224 ! Get minimum crit and associated processor index.
225 allocate ( in (thinning_grid(rain,ifgat)%itxmax) )
226 allocate ( out (thinning_grid(rain,ifgat)%itxmax) )
227 do i = 1, thinning_grid(rain,ifgat)%itxmax
228 in(i) = thinning_grid(rain,ifgat)%score_crit(i)
231 call mpi_reduce(in, out, thinning_grid(rain,ifgat)%itxmax, true_mpi_real, mpi_min, root, comm, ierr)
232 call wrf_dm_bcast_real (out, thinning_grid(rain,ifgat)%itxmax)
234 do i = 1, thinning_grid(rain,ifgat)%itxmax
235 if ( abs(out(i)-thinning_grid(rain,ifgat)%score_crit(i)) > 1.0E-10 ) then
236 thinning_grid(rain,ifgat)%ibest_obs(i) = 0
240 thinning_grid(rain,ifgat)%score_crit(:) = out(:)
246 do j = (1+tp), iv%info(rain)%nlocal
247 do i = 1, thinning_grid(rain,ifgat)%itxmax
248 if ( thinning_grid(rain,ifgat)%ibest_obs(i) == j .and. &
249 thinning_grid(rain,ifgat)%score_crit(i) < 9.99e6 ) then
256 num_thinned = num_thinned + iv%info(rain)%nlocal - nlocal
257 iv%info(rain)%nlocal = tp + nlocal
259 end if ! thin_rainobs
261 write(unit=message(1),fmt='(A,4(1x,i7))') &
262 'da_scan_obs_rain: num_report, num_outside_all, num_outside_time, num_thinned: ', &
263 num_report, num_outside_all, num_outside_time, num_thinned
264 call da_message(message(1:1))
267 call da_free_unit(iunit)
269 if (trace_use) call da_trace_exit("da_scan_obs_rain")
272 end subroutine da_scan_obs_rain