20 use missing_values_mod
23 use fckit_log_module,
only : fckit_log
31 logical :: vert_interp_ops
33 real(kind_real) :: min_temp_grad
50 logical(c_bool),
intent(in) :: vert_interp_ops
51 logical(c_bool),
intent(in) :: pseudo_ops
52 real(c_float),
intent(in) :: min_temp_grad
54 self % vert_interp_ops = vert_interp_ops
55 self % pseudo_ops = pseudo_ops
56 self % min_temp_grad = min_temp_grad
70 real(kind_real),
intent(inout) :: hofx(:)
71 type(c_ptr),
value,
intent(in) :: obss
74 character(len=*),
parameter :: myname_ =
"ufo_gnssro_bendmetoffice_simobs"
75 integer,
parameter :: max_string = 800
77 character(max_string) :: err_msg
78 character(max_string) :: message
86 real(kind_real),
allocatable :: obsLat(:)
87 real(kind_real),
allocatable :: obsLon(:)
88 real(kind_real),
allocatable :: impact_param(:)
89 real(kind_real),
allocatable :: radius_curv(:)
90 real(kind_real),
allocatable :: undulation(:)
94 real(kind_real),
allocatable :: refractivity(:)
95 real(kind_real),
allocatable :: model_heights(:)
97 write(err_msg,*)
"TRACE: ufo_gnssro_bendmetoffice_simobs: begin"
98 call fckit_log%info(err_msg)
103 DO ivar = 1, obs_diags % nvar
104 IF (obs_diags % variables(ivar) ==
"refractivity" .OR. &
105 obs_diags % variables(ivar) ==
"model_heights")
THEN
106 write(err_msg,*)
"TRACE: ufo_gnssro_bendmetoffice_simobs: initialising obs_diags for " // &
107 obs_diags % variables(ivar)
108 call fckit_log%info(err_msg)
109 obs_diags % geovals(ivar) % nval = 0
114 if (geovals%nlocs /=
size(hofx))
then
115 write(err_msg,*) myname_,
' error: nlocs inconsistent!'
116 call abor1_ftn(err_msg)
119 write(message, *) myname_,
' Running Met Office GNSS-RO forward operator with'
120 call fckit_log%info(message)
121 write(message, *)
'vert_interp_ops =', self % vert_interp_ops, &
122 'pseudo_ops =', self % pseudo_ops
123 call fckit_log%info(message)
131 write(message,
'(A,10I6)')
'Q: ', q%nval, q%nlocs, shape(q%vals)
132 call fckit_log%info(message)
133 write(message,
'(A,10I6)')
'Pressure: ', prs%nval, prs%nlocs, shape(prs%vals)
134 call fckit_log%info(message)
136 nobs = obsspace_get_nlocs(obss)
139 if (prs%vals(1,1) .lt. prs%vals(prs%nval,1) )
then
140 write(err_msg,
'(a)')
' ufo_gnssro_bendmetoffice_simobs:'//new_line(
'a')// &
141 ' Model vertical height profile is in descending order,'//new_line(
'a')// &
142 ' The data will be flipped for processing'
143 call fckit_log%info(err_msg)
148 allocate(obslon(nobs))
149 allocate(obslat(nobs))
150 allocate(impact_param(nobs))
151 allocate(radius_curv(nobs))
152 allocate(undulation(nobs))
154 call obsspace_get_db(obss,
"MetaData",
"longitude", obslon)
155 call obsspace_get_db(obss,
"MetaData",
"latitude", obslat)
156 call obsspace_get_db(obss,
"MetaData",
"impact_parameter", impact_param)
157 call obsspace_get_db(obss,
"MetaData",
"earth_radius_of_curvature", radius_curv)
158 call obsspace_get_db(obss,
"MetaData",
"geoid_height_above_reference_ellipsoid", undulation)
160 obs_loop:
do iobs = 1, nobs
165 rho_heights % vals(rho_heights%nval:1:-1, iobs), &
166 theta_heights % vals(theta_heights%nval:1:-1, iobs), &
167 prs % vals(prs%nval:1:-1, iobs), &
168 q % vals(q%nval:1:-1, iobs), &
170 self % vert_interp_ops, &
171 self % min_temp_grad, &
173 impact_param(iobs:iobs), &
184 rho_heights % vals(:,iobs), &
185 theta_heights % vals(:,iobs), &
186 prs % vals(:,iobs), &
189 self % vert_interp_ops, &
190 self % min_temp_grad, &
192 impact_param(iobs:iobs), &
203 write(err_msg,*)
"Error with observation processing ", iobs
204 call fckit_log % info(err_msg)
208 DO ivar = 1, obs_diags % nvar
209 IF (obs_diags % variables(ivar) ==
"refractivity")
THEN
211 obs_diags % geovals(ivar) % nval =
SIZE(refractivity)
212 ALLOCATE(obs_diags % geovals(ivar) % vals(
SIZE(refractivity), obs_diags % nlocs))
216 obs_diags % geovals(ivar) % vals(:,iobs) = missing_value(obs_diags % geovals(ivar) % vals(1,1))
218 obs_diags % geovals(ivar) % vals(:,iobs) = refractivity(:)
222 IF (obs_diags % variables(ivar) ==
"model_heights")
THEN
224 obs_diags % geovals(ivar) % nval =
SIZE(model_heights)
225 ALLOCATE(obs_diags % geovals(ivar) % vals(
SIZE(model_heights), obs_diags % nlocs))
229 obs_diags % geovals(ivar) % vals(:,iobs) = missing_value(obs_diags % geovals(ivar) % vals(1,1))
231 obs_diags % geovals(ivar) % vals(:,iobs) = model_heights(:)
239 deallocate(impact_param)
240 deallocate(radius_curv)
241 deallocate(undulation)
243 write(err_msg,*)
"TRACE: ufo_gnssro_bendmetoffice_simobs: completed"
244 call fckit_log%info(err_msg)
257 GPSRO_vert_interp_ops, &
258 GPSRO_min_temp_grad, &
269 INTEGER,
INTENT(IN) :: nlevp
270 INTEGER,
INTENT(IN) :: nlevq
271 REAL(kind_real),
INTENT(IN) :: za(1:nlevp)
272 REAL(kind_real),
INTENT(IN) :: zb(1:nlevq)
273 REAL(kind_real),
INTENT(IN) :: pressure(1:nlevp)
274 REAL(kind_real),
INTENT(IN) :: humidity(1:nlevq)
275 LOGICAL,
INTENT(IN) :: GPSRO_pseudo_ops
276 LOGICAL,
INTENT(IN) :: GPSRO_vert_interp_ops
277 REAL(kind_real),
INTENT(IN) :: GPSRO_min_temp_grad
278 INTEGER,
INTENT(IN) :: nobs
279 REAL(kind_real),
INTENT(IN) :: zobs(1:nobs)
280 REAL(kind_real),
INTENT(IN) :: RO_Rad_Curv
281 REAL(kind_real),
INTENT(IN) :: Latitude
282 REAL(kind_real),
INTENT(IN) :: RO_geoid_und
283 REAL(kind_real),
INTENT(INOUT) :: ycalc(1:nobs)
284 LOGICAL,
INTENT(OUT) :: BAErr
285 REAL(kind_real),
INTENT(INOUT),
ALLOCATABLE :: refractivity(:)
286 REAL(kind_real),
INTENT(INOUT),
ALLOCATABLE :: model_heights(:)
290 INTEGER :: nRefLevels
291 REAL(kind_real),
ALLOCATABLE :: nr(:)
295 integer,
parameter :: max_string = 800
296 character(len=*),
parameter :: myname_ =
"Ops_GPSRO_ForwardModel"
300 INTEGER :: num_pseudo
301 REAL(kind_real) :: x(1:nlevp+nlevq)
302 character(max_string) :: err_msg
305 IF (nlevp /= nlevq + 1)
THEN
306 write(err_msg,*) myname_ //
':' //
' Data must be on a staggered grid nlevp, nlevq = ', nlevp, nlevq
307 call fckit_log % warning(err_msg)
308 write(err_msg,*) myname_ //
':' //
' error: number of levels inconsistent!'
309 call abor1_ftn(err_msg)
321 gpsro_vert_interp_ops, &
322 gpsro_min_temp_grad, &
328 ALLOCATE(nr(1:nreflevels))
331 IF (.NOT. baerr)
THEN
Fortran module to prepare for Lagrange polynomial interpolation. based on GSI: lagmod....
subroutine, public lag_interp_const(q, x, n)
subroutine, public lag_interp_smthweights(x, xt, aq, bq, w, dw, n)
type(registry_t), public ufo_geovals_registry
Linked list interface - defines registry_t type.
subroutine, public ufo_geovals_get_var(self, varname, geoval)
Fortran module for gnssro bending angle Met Office forward operator.
subroutine ops_gpsro_forwardmodel(nlevp, nlevq, za, zb, pressure, humidity, GPSRO_pseudo_ops, GPSRO_vert_interp_ops, GPSRO_min_temp_grad, nobs, zobs, RO_Rad_Curv, Latitude, RO_geoid_und, ycalc, BAErr, refractivity, model_heights)
subroutine ufo_gnssro_bendmetoffice_simobs(self, geovals, obss, hofx, obs_diags)
subroutine ufo_gnssro_bendmetoffice_setup(self, vert_interp_ops, pseudo_ops, min_temp_grad)
subroutine, public ops_gpsrocalc_nr(nb, zb, refrac, Rad, lat, und, nr)
subroutine, public ops_gpsrocalc_alpha(nobs, nlev, a, refrac, nr, alpha)
Module for containing a general refractivity forward operator and its K-matrix.
subroutine, public ufo_calculate_refractivity(nlevP, nlevq, za, zb, P, q, vert_interp_ops, pseudo_ops, min_temp_grad, refracerr, nRefLevels, refractivity, model_heights, temperature, interp_pressure)
Calculation of the refractivity from the pressure and specific humidity.
character(len=maxvarlen), parameter, public var_prsi
character(len=maxvarlen), parameter, public var_q
character(len=maxvarlen), parameter, public var_zi
character(len=maxvarlen), parameter, public var_z
Fortran module to perform linear interpolation.
type to hold interpolated field for one variable, one observation
type to hold interpolated fields required by the obs operators
Fortran derived type for gnssro trajectory.