11 use fckit_configuration_module,
only: fckit_configuration
21 use missing_values_mod
24 use fckit_log_module,
only : fckit_log
31 integer :: nval, nlocs
32 real(kind_real),
allocatable :: prs(:,:), t(:,:), q(:,:), gph(:,:), gph_sfc(:,:)
35 real(kind_real),
allocatable :: obslon2d(:), obslat2d(:)
50 type(fckit_configuration),
intent(in) :: f_conf
62 type(c_ptr),
value,
intent(in) :: obss
63 character(len=*),
parameter :: myname_=
"ufo_gnssro_bndropp2d_tlad_settraj"
64 character(max_string) :: err_msg
65 type(
ufo_geoval),
pointer :: t, q, prs, gph, gph_sfc
67 real(kind_real),
allocatable :: obsAzim(:)
68 real(kind_real),
allocatable :: obsLat(:), obsLon(:)
69 real(kind_real),
allocatable :: obsLonnh(:),obsLatnh(:)
71 real(kind_real) :: dtheta
73 write(err_msg,*)
"TRACE: ufo_gnssro_bndropp2d_tlad_settraj: begin"
74 call fckit_log%info(err_msg)
85 self%nlocs = obsspace_get_nlocs(obss)
88 n_horiz = self%roconf%n_horiz
89 dtheta = self%roconf%dtheta
91 if (prs%vals(1,1) .lt. prs%vals(prs%nval,1) )
then
93 write(err_msg,
'(a)')
' ufo_gnssro_bndropp2d_tlad_settraj:'//new_line(
'a')// &
94 ' Model vertical height profile is in descending order,'//new_line(
'a')// &
95 ' but ROPP requires it to be ascending order, need flip'
96 call fckit_log%info(err_msg)
99 allocate(self%obsLat2d(self%nlocs*n_horiz))
100 allocate(self%obsLon2d(self%nlocs*n_horiz))
102 allocate(obslon(self%nlocs))
103 allocate(obslat(self%nlocs))
104 allocate(obsazim(self%nlocs))
106 call obsspace_get_db(obss,
"MetaData",
"longitude", obslon)
107 call obsspace_get_db(obss,
"MetaData",
"latitude", obslat)
108 call obsspace_get_db(obss,
"MetaData",
"sensor_azimuth_angle", obsazim)
110 allocate(obslatnh(n_horiz))
111 allocate(obslonnh(n_horiz))
114 call ropp_fm_2d_plane(obslat(i),obslon(i),obsazim(i),dtheta,n_horiz,obslatnh,obslonnh,kerror)
115 self%obsLon2d((i-1)*n_horiz+1:i*n_horiz) = obslonnh
116 self%obsLat2d((i-1)*n_horiz+1:i*n_horiz) = obslatnh
125 allocate(self%t(self%nval,self%nlocs*n_horiz))
126 allocate(self%q(self%nval,self%nlocs*n_horiz))
127 allocate(self%prs(self%nval,self%nlocs*n_horiz))
128 allocate(self%gph(self%nval,self%nlocs*n_horiz))
129 allocate(self%gph_sfc(1,self%nlocs*n_horiz))
136 self%gph_sfc = gph_sfc%vals
146 use ropp_fm_types,
only: state2dfm, state1dfm
147 use ropp_fm_types,
only: obs1dbangle
148 use datetimetypes,
only: dp
152 real(kind_real),
intent(inout) :: hofx(:)
153 type(c_ptr),
value,
intent(in) :: obss
154 real(c_double) :: missing
156 type(state2dfm) :: x,x_tl
157 type(state1dfm) :: x1d,x1d_tl
158 type(obs1dbangle) :: y,y_tl
160 integer :: iobs,nlev, nlocs,nvprof
162 character(len=*),
parameter :: myname_=
"ufo_gnssro_bndropp2d_simobs_tl"
163 character(max_string) :: err_msg
167 real(kind_real),
allocatable :: gph_d_zero(:,:)
168 real(kind_real) :: gph_sfc_d_zero
170 real(kind_real),
allocatable :: obsImpP(:),obsLocR(:),obsGeoid(:),obsAzim(:)
171 real(kind_real),
allocatable :: obsLat(:),obsLon(:)
173 real(kind_real) :: dtheta
174 real(kind_real) :: ob_time
176 missing = missing_value(missing)
178 n_horiz = self%roconf%n_horiz
179 dtheta = self%roconf%dtheta
181 write(err_msg,*)
"TRACE: ufo_gnssro_bndropp2d_simobs_tl: begin"
182 call fckit_log%info(err_msg)
185 if (.not. self%ltraj)
then
186 write(err_msg,*) myname_,
' trajectory wasnt set!'
187 call abor1_ftn(err_msg)
191 if (geovals%nlocs /=
size(hofx)*n_horiz )
then
192 write(err_msg,*) myname_,
' error: 2d nlocs inconsistent! geovals%nlocs, size(hofx), &
193 and n_horiz are', geovals%nlocs,
size(hofx), n_horiz
194 call abor1_ftn(err_msg)
205 allocate(gph_d_zero(nlev,nlocs*n_horiz))
210 allocate(obslon(nlocs))
211 allocate(obslat(nlocs))
212 allocate(obsimpp(nlocs))
213 allocate(obslocr(nlocs))
214 allocate(obsgeoid(nlocs))
215 allocate(obsazim(nlocs))
216 call obsspace_get_db(obss,
"MetaData",
"longitude", obslon)
217 call obsspace_get_db(obss,
"MetaData",
"latitude", obslat)
218 call obsspace_get_db(obss,
"MetaData",
"impact_parameter", obsimpp)
219 call obsspace_get_db(obss,
"MetaData",
"earth_radius_of_curvature", obslocr)
220 call obsspace_get_db(obss,
"MetaData",
"geoid_height_above_reference_ellipsoid", obsgeoid)
221 call obsspace_get_db(obss,
"MetaData",
"sensor_azimuth_angle", obsazim)
227 obs_loop:
do iobs = 1, nlocs
229 if ( ( obsimpp(iobs)-obslocr(iobs)-obsgeoid(iobs) ) <= self%roconf%top_2d .and. &
230 obsazim(iobs) /= missing )
then
234 self%obsLat2d( (iobs-1)*n_horiz+1:iobs*n_horiz ), &
235 self%t(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
236 self%q(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
237 self%prs(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
238 self%gph(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
239 nlev, x, n_horiz, dtheta, self%iflip)
243 where(x%shum .le. 1e-8) x%shum = 1e-8
247 self%obsLat2d( (iobs-1)*n_horiz+1:iobs*n_horiz ), &
248 t_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
249 q_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
250 prs_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
251 gph_d_zero(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
252 nlev, x_tl, n_horiz, dtheta, self%iflip)
264 call ropp_fm_bangle_2d_tl(x,x_tl,y, y_tl)
265 hofx(iobs) = y_tl%bangle(nvprof)
276 self%t(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
277 self%q(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
278 self%prs(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
279 self%gph(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
281 self%gph_sfc(1,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
284 where(x1d%shum .le. 1e-8) x1d%shum = 1e-8
289 t_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
290 q_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
291 prs_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
292 gph_d_zero(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
307 call ropp_fm_bangle_1d_tl(x1d,x1d_tl,y,y_tl%bangle(nvprof))
308 hofx(iobs) = y_tl%bangle(nvprof)
322 deallocate(gph_d_zero)
324 write(err_msg,*)
"TRACE: ufo_gnssro_bndropp2d_simobs_tl: complete"
325 call fckit_log%info(err_msg)
335 use ropp_fm_types,
only: state2dfm, state1dfm
336 use ropp_fm_types,
only: obs1dbangle
337 use typesizes,
only: wp => eightbytereal
338 use datetimetypes,
only: dp
343 real(kind_real),
intent(in) :: hofx(:)
344 type(c_ptr),
value,
intent(in) :: obss
345 real(c_double) :: missing
350 real(kind_real),
allocatable :: gph_d_zero(:,:)
351 real(kind_real) :: gph_sfc_d_zero
353 real(kind_real),
allocatable :: obsLat(:), obsLon(:), obsImpP(:), obsLocR(:), obsGeoid(:)
354 real(kind_real),
allocatable :: obsAzim(:)
355 type(state2dfm) :: x,x_ad
356 type(state1dfm) :: x1d,x1d_ad
357 type(obs1dbangle) :: y,y_ad
358 integer :: iobs,nlev,nlocs,nvprof
359 character(len=*),
parameter :: myname_=
"ufo_gnssro_bndropp2d_simobs_ad"
360 character(max_string) :: err_msg
362 real(kind_real) :: dtheta
363 real(kind_real) :: ob_time
365 n_horiz = self%roconf%n_horiz
366 dtheta = self%roconf%dtheta
368 write(err_msg,*)
"TRACE: ufo_gnssro_bndropp2d_simobs_ad: begin"
369 call fckit_log%info(err_msg)
372 if (.not. self%ltraj)
then
373 write(err_msg,*) myname_,
' trajectory wasnt set!'
374 call abor1_ftn(err_msg)
377 if (geovals%nlocs /=
size(hofx)*n_horiz)
then
378 write(err_msg,*) myname_,
' error: 2d nlocs inconsistent!'
379 call abor1_ftn(err_msg)
388 if (.not.
allocated(t_d%vals))
then
389 t_d%nlocs = self%nlocs*n_horiz
391 allocate(t_d%vals(t_d%nval,t_d%nlocs))
392 t_d%vals = 0.0_kind_real
395 if (.not.
allocated(prs_d%vals))
then
396 prs_d%nlocs = self%nlocs*n_horiz
397 prs_d%nval = self%nval
398 allocate(prs_d%vals(prs_d%nval,prs_d%nlocs))
399 prs_d%vals = 0.0_kind_real
402 if (.not.
allocated(q_d%vals))
then
403 q_d%nlocs = self%nlocs*n_horiz
405 allocate(q_d%vals(q_d%nval,q_d%nlocs))
406 q_d%vals = 0.0_kind_real
409 if (.not. geovals%linit ) geovals%linit=.true.
414 allocate(gph_d_zero(nlev,nlocs*n_horiz))
419 allocate(obslon(nlocs))
420 allocate(obslat(nlocs))
421 allocate(obsimpp(nlocs))
422 allocate(obslocr(nlocs))
423 allocate(obsgeoid(nlocs))
424 allocate(obsazim(nlocs))
426 call obsspace_get_db(obss,
"MetaData",
"longitude", obslon)
427 call obsspace_get_db(obss,
"MetaData",
"latitude", obslat)
428 call obsspace_get_db(obss,
"MetaData",
"impact_parameter", obsimpp)
429 call obsspace_get_db(obss,
"MetaData",
"earth_radius_of_curvature", obslocr)
430 call obsspace_get_db(obss,
"MetaData",
"geoid_height_above_reference_ellipsoid", obsgeoid)
431 call obsspace_get_db(obss,
"MetaData",
"sensor_azimuth_angle", obsazim)
433 missing = missing_value(missing)
439 obs_loop:
do iobs = 1, nlocs
441 if (hofx(iobs) .gt. missing)
then
442 if ( ( obsimpp(iobs)-obslocr(iobs)-obsgeoid(iobs) ) <= self%roconf%top_2d .and. &
443 obsazim(iobs) /= missing )
then
447 self%obsLat2d((iobs-1)*n_horiz+1:iobs*n_horiz), &
448 self%t(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
449 self%q(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
450 self%prs(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
451 self%gph(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
452 nlev, x, n_horiz, dtheta, self%iflip)
455 self%obsLat2d( (iobs-1)*n_horiz+1:iobs*n_horiz ), &
456 t_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
457 q_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
458 prs_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
459 gph_d_zero(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
460 nlev, x_ad, n_horiz, dtheta, self%iflip)
463 x_ad%temp(:,:) = 0.0_wp
464 x_ad%pres(:,:) = 0.0_wp
465 x_ad%shum(:,:) = 0.0_wp
466 x_ad%geop(:,:) = 0.0_wp
479 y_ad%bangle(:) = 0.0_wp
482 y_ad%bangle(nvprof) = y_ad%bangle(nvprof) + hofx(iobs)
483 call ropp_fm_bangle_2d_ad(x,x_ad,y,y_ad)
486 t_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
487 q_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
488 prs_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
489 gph_d_zero(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
491 nlev, x_ad, n_horiz,self%iflip)
502 self%t(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
503 self%q(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
504 self%prs(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
505 self%gph(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
507 self%gph_sfc(1,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
513 t_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
514 q_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
515 prs_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
516 gph_d_zero(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
523 x1d_ad%temp(:) = 0.0_wp
524 x1d_ad%pres(:) = 0.0_wp
525 x1d_ad%shum(:) = 0.0_wp
526 x1d_ad%geop(:) = 0.0_wp
539 y_ad%bangle(:) = 0.0_wp
542 y_ad%bangle(nvprof) = y_ad%bangle(nvprof) + hofx(iobs)
543 call ropp_fm_bangle_1d_ad(x1d,x1d_ad,y,y_ad)
545 t_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
546 q_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
547 prs_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
548 gph_d_zero(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
549 nlev, x1d_ad, self%iflip)
567 deallocate(gph_d_zero)
569 write(err_msg,*)
"TRACE: ufo_gnssro_bndropp2d_simobs_ad: complete"
570 call fckit_log%info(err_msg)
582 character(len=*),
parameter :: myname_=
"ufo_gnssro_bndropp_tlad_delete"
585 if (
allocated(self%prs))
deallocate(self%prs)
586 if (
allocated(self%t))
deallocate(self%t)
587 if (
allocated(self%q))
deallocate(self%q)
588 if (
allocated(self%gph))
deallocate(self%gph)
589 if (
allocated(self%gph_sfc))
deallocate(self%gph_sfc)
590 if (
allocated(self%obsLat2d))
deallocate(self%obsLat2d)
591 if (
allocated(self%obsLon2d))
deallocate(self%obsLon2d)