10 use oops_variables_mod
22 type(oops_variables),
public :: obsvars
23 type(oops_variables),
public :: geovars
24 integer :: nlayers_kernel
25 real(kind_real),
allocatable,
dimension(:) :: ak_kernel, bk_kernel
26 character(kind=c_char,len=:),
allocatable :: obskernelvar, tracervars(:)
27 logical :: troposphere, totalcolumn
28 real(kind_real) :: convert_factor_model, convert_factor_hofx
39 use fckit_configuration_module,
only: fckit_configuration
43 type(fckit_configuration),
intent(in) :: f_conf
44 type(fckit_configuration) :: f_confOpts
46 integer :: ivar, nvars
47 character(len=max_string) :: err_msg
50 call f_conf%get_or_die(
"obs options",f_confopts)
52 call f_confopts%get_or_die(
"nlayers_kernel", self%nlayers_kernel)
53 nlevs_yaml = f_confopts%get_size(
"ak")
54 if (nlevs_yaml /= self%nlayers_kernel+1)
then
55 write(err_msg, *)
"ufo_avgkernel_setup error: YAML nlayers_kernel != size of ak array"
56 call abor1_ftn(err_msg)
58 nlevs_yaml = f_confopts%get_size(
"bk")
59 if (nlevs_yaml /= self%nlayers_kernel+1)
then
60 write(err_msg, *)
"ufo_avgkernel_setup error: YAML nlayers_kernel != size of bk array"
61 call abor1_ftn(err_msg)
65 allocate(self%ak_kernel(nlevs_yaml))
66 allocate(self%bk_kernel(nlevs_yaml))
67 call f_confopts%get_or_die(
"ak", self%ak_kernel)
68 call f_confopts%get_or_die(
"bk", self%bk_kernel)
71 if (.not. f_confopts%get(
"AvgKernelVar", self%obskernelvar))
then
72 self%obskernelvar =
"averaging_kernel"
76 nvars = self%obsvars%nvars()
77 call f_confopts%get_or_die(
"tracer variables", self%tracervars)
81 if (.not. f_confopts%get(
"tropospheric column", self%troposphere)) self%troposphere = .false.
82 if (.not. f_confopts%get(
"total column", self%totalcolumn)) self%totalcolumn = .false.
85 if (.not. f_confopts%get(
"model units coeff", self%convert_factor_model)) self%convert_factor_model =
one
86 if (.not. f_confopts%get(
"hofx units coeff", self%convert_factor_hofx)) self%convert_factor_hofx =
one
91 call self%geovars%push_back(self%tracervars(ivar))
94 call self%geovars%push_back(
var_ps)
96 call self%geovars%push_back(
var_prs)
97 call self%geovars%push_back(
var_prsi)
99 call self%geovars%push_back(
var_ts)
101 call self%geovars%push_back(
var_zi)
124 integer,
intent(in) :: nvars, nlocs
126 real(c_double),
intent(inout) :: hofx(nvars, nlocs)
127 type(c_ptr),
value,
intent(in) :: obss
130 type(
ufo_geoval),
pointer :: prsi, prsl, psfc, temp, phii, tracer
131 integer :: ivar, iobs, ilev
132 character(len=MAXVARLEN) :: geovar, varstring
133 character(len=4) :: levstr
134 real(kind_real),
allocatable,
dimension(:,:) :: avgkernel_obs, prsl_obs, prsi_obs
135 real(kind_real),
allocatable,
dimension(:) :: airmass_tot, airmass_trop
136 integer,
allocatable,
dimension(:) :: troplev_obs
137 real(kind_real) :: hofx_tmp
152 allocate(avgkernel_obs(self%nlayers_kernel, nlocs))
153 do ilev = 1, self%nlayers_kernel
154 write(levstr, fmt =
"(I3)") ilev
155 levstr = adjustl(levstr)
156 varstring = trim(self%obskernelvar)//
"_"//trim(levstr)
157 call obsspace_get_db(obss,
"MetaData", trim(varstring), avgkernel_obs(ilev, :))
161 allocate(prsl_obs(self%nlayers_kernel, nlocs))
162 allocate(prsi_obs(self%nlayers_kernel+1, nlocs))
164 do ilev = 1, self%nlayers_kernel+1
165 prsi_obs(ilev,:) = self%ak_kernel(ilev) + self%bk_kernel(ilev) * psfc%vals(1,:)
168 do ilev = 1, self%nlayers_kernel
169 prsl_obs(ilev,:) = (prsi_obs(ilev,:) + prsi_obs(ilev+1,:)) *
half
172 if (self%troposphere)
then
173 allocate(troplev_obs(nlocs))
174 allocate(airmass_trop(nlocs))
175 allocate(airmass_tot(nlocs))
176 call obsspace_get_db(obss,
"MetaData",
"troposphere_layer_index", troplev_obs)
177 call obsspace_get_db(obss,
"MetaData",
"air_mass_factor_troposphere", airmass_trop)
178 call obsspace_get_db(obss,
"MetaData",
"air_mass_factor_total", airmass_tot)
183 geovar = self%tracervars(ivar)
186 if (avgkernel_obs(1,iobs) > -1.0e9_kind_real)
then
187 if (self%troposphere)
then
189 prsl_obs(:,iobs), prsl%vals(:,iobs), temp%vals(:,iobs),&
190 phii%vals(:,iobs), tracer%vals(:,iobs)*self%convert_factor_model, &
191 hofx_tmp, troplev_obs(iobs), airmass_tot(iobs), airmass_trop(iobs))
192 hofx(ivar,iobs) = hofx_tmp * self%convert_factor_hofx
195 hofx(ivar,iobs) =
zero