12 use oops_variables_mod
13 use fckit_log_module,
only : fckit_log
15 use missing_values_mod
24 type(oops_variables),
public :: obsvars
25 type(oops_variables),
public :: geovars
26 real(kind_real),
public,
allocatable :: wavelength(:)
27 integer,
public :: nprofiles
41 integer function b_channel( bracket, nprofiles, bkg_wavelengths, obs_wavelength )
43 integer,
intent(in) :: bracket
44 integer,
intent(in) :: nprofiles
45 real(kind_real),
dimension(nprofiles) :: bkg_wavelengths
46 real(kind_real) :: obs_wavelength
48 character(len=maxvarlen) :: err_msg
51 do while(j < nprofiles)
52 if(obs_wavelength >= bkg_wavelengths(j) .and.&
53 obs_wavelength < bkg_wavelengths(j+1))
then
54 if (bracket == 1)
then
56 else if (bracket == 2)
then
59 write(err_msg,*)
"ufo_aodext_mod: function b_channel: bracket index should be 1 (lower) or 2 (upper)"
60 call abor1_ftn(err_msg)
63 else if(obs_wavelength > bkg_wavelengths(j) .and.&
64 obs_wavelength <= bkg_wavelengths(j+1))
then
65 if (bracket == 1)
then
67 else if (bracket == 2)
then
70 write(err_msg,*)
"ufo_aodext_mod: function b_channel: bracket index should be 1 (lower) or 2 (upper)"
71 call abor1_ftn(err_msg)
82 use fckit_configuration_module,
only: fckit_configuration
85 type(fckit_configuration),
intent(in) :: f_conf
89 character(len=maxvarlen) :: err_msg
94 call f_conf%get_or_die(
"nprofiles", self%nprofiles)
96 if (self%nprofiles < 2 .or. self%nprofiles > 3)
then
97 write(err_msg,*)
'ufo_aodext_setup: number of extinction profiles must be 2 or 3'
98 call abor1_ftn(err_msg)
101 do n = 1, self%nprofiles
107 allocate(self%wavelength(self%nprofiles))
108 call f_conf%get_or_die(
"bkg_wavelengths", self%wavelength)
111 do while (n < self%nprofiles)
112 if(self%wavelength(n) > self%wavelength(n+1))
then
113 write(err_msg,*)
' ufo_aodext_setup: bkg wavelengths should be in an ascending order'
114 call abor1_ftn(err_msg)
126 if (
allocated(self%wavelength))
deallocate(self%wavelength)
139 integer,
intent(in) :: nvars, nlocs
141 real(c_double),
intent(inout) :: hofx(nvars, nlocs)
142 type(c_ptr),
value,
intent(in) :: obss
149 real(kind_real),
dimension(:,:,:),
allocatable :: ext
150 real(kind_real),
dimension(:,:),
allocatable :: airdens
151 real(kind_real),
dimension(:,:),
allocatable :: delp
152 real(kind_real),
dimension(:,:),
allocatable :: aod_bkg
153 real(kind_real),
dimension(:),
allocatable :: obss_wavelength
155 real(kind_real) :: angstrom
156 real(kind_real) :: logm
158 character(len=MAXVARLEN) :: geovar
159 real(c_double) :: missing
161 character(len=MAXVARLEN) :: message
163 integer :: km, nobs, nch, ic, i, j, k
167 geovar = self%geovars%variable(1)
170 nlayers = delp_profile%nval
172 allocate(delp(nlayers,nlocs))
173 delp = delp_profile%vals
176 allocate(airdens(nlayers,nlocs))
177 airdens = airdens_profile%vals
181 allocate(ext(nlayers, nlocs, self%nprofiles))
182 do nch = 1, self%nprofiles
183 geovar = self%geovars%variable(nch)
185 ext(:,:,nch) = ext_profile%vals
190 allocate(obss_wavelength(nvars))
191 call obsspace_get_db(obss,
"VarMetaData",
"obs_wavelength", obss_wavelength)
196 if(obss_wavelength(ic) < self%wavelength(1) .or. obss_wavelength(ic) > self%wavelength(self%nprofiles))
then
197 write(message,*)
'ufo_aodext_simobs: observed wavelength outside of bkg wavelengths range', obss_wavelength(ic)
198 call fckit_log%info(message)
206 allocate(aod_bkg(nlocs, self%nprofiles))
208 do nch = 1, self%nprofiles
211 aod_bkg(nobs,nch) = aod_bkg(nobs, nch) + (ext(k,nobs,nch) * delp(k,nobs)/(airdens(k,nobs))/(
grav*1000.0_kind_real))
218 missing =missing_value(missing)
222 if(obss_wavelength(ic) < self%wavelength(1) .or. obss_wavelength(ic) > self%wavelength(self%nprofiles))
then
223 hofx(ic,nobs) = missing
225 i =
b_channel(1, self%nprofiles, self%wavelength, obss_wavelength(ic))
226 j =
b_channel(2, self%nprofiles, self%wavelength, obss_wavelength(ic))
227 logm = log(self%wavelength(i)/self%wavelength(j))
228 angstrom = log(aod_bkg(nobs,i)/aod_bkg(nobs,j))/logm
229 hofx(ic,nobs) = aod_bkg(nobs,i) * (obss_wavelength(ic)/self%wavelength(i))**angstrom
233 deallocate(ext, airdens, delp, aod_bkg, obss_wavelength)
Fortran module for aodext observation operator.
integer function b_channel(bracket, nprofiles, bkg_wavelengths, obs_wavelength)
character(len=maxvarlen), dimension(2), parameter varindefault
Default variables required from model.
subroutine ufo_aodext_setup(self, f_conf)
subroutine ufo_aodext_simobs(self, geovals, obss, nvars, nlocs, hofx)
subroutine destructor(self)
character(len=maxvarlen), dimension(3), parameter extdefault
real(kind_real), parameter, public grav
real(kind_real), parameter, public zero
subroutine, public ufo_geovals_get_var(self, varname, geoval)
character(len=maxvarlen), parameter, public var_ext2
character(len=maxvarlen), parameter, public var_airdens
character(len=maxvarlen), parameter, public var_ext3
character(len=maxvarlen), parameter, public var_delp
character(len=maxvarlen), parameter, public var_ext1
Fortran derived type for the observation type.
type to hold interpolated field for one variable, one observation
type to hold interpolated fields required by the obs operators