10 use fckit_configuration_module,
only: fckit_configuration
11 use fckit_log_module,
only : fckit_log
14 use missing_values_mod
16 use oops_variables_mod
51 onedvarflag, passflag)
55 type(c_ptr),
value,
intent(in) :: obsspace
56 type(fckit_configuration),
intent(in) :: f_conf
57 integer(c_int),
intent(in) :: channels(:)
58 integer(c_int),
intent(in) :: onedvarflag
59 integer(c_int),
intent(in) :: passflag
61 self % obsdb = obsspace
62 self % onedvarflag = onedvarflag
63 self % passflag = passflag
81 if (
allocated(self % retrieval_variables))
deallocate(self % retrieval_variables)
82 if (
allocated(self % channels))
deallocate(self % channels)
103 type(fckit_configuration),
intent(in) :: f_conf
104 type(oops_variables),
intent(in) :: vars
105 type(oops_variables),
intent(in) :: hofxdiags_vars
107 logical,
intent(in) :: apply(:)
119 character(len=max_string) :: sensor_id
120 character(len=max_string) :: var
121 character(len=max_string) :: varname
122 character(len=max_string) ::
message
123 integer :: jvar, ivar, jobs, band, ii
124 integer :: nchans_used
125 integer :: jchans_used
127 integer :: apply_count
128 integer :: nprofelements
129 integer,
allocatable :: fields_in(:)
130 real(kind_real) :: missing
131 real(kind_real) :: t1, t2
132 real(kind_real),
allocatable :: b_matrix(:,:)
133 real(kind_real),
allocatable :: b_inverse(:,:)
134 real(kind_real),
allocatable :: b_sigma(:)
135 real(kind_real),
allocatable :: max_error(:)
136 logical :: file_exists
137 logical :: onedvar_success
138 logical :: cloud_retrieval = .false.
140 integer(c_size_t),
allocatable :: ret_nlevs(:)
145 missing = missing_value(missing)
148 call rttov_simobs % setup(f_conf, self % channels)
151 if (self % pcemiss)
then
152 if (len(self % EmisAtlas) > 4)
then
153 call ir_pcemis % setup(self % EmisEigVecPath, self % EmisAtlas)
155 call ir_pcemis % setup(self % EmisEigVecPath)
160 call full_bmatrix % setup(self % retrieval_variables, self % b_matrix_path, &
164 call full_rmatrix % setup(self % r_matrix_path)
167 do ii = 1,
size(self % retrieval_variables)
168 if (
cmp_strings(self % retrieval_variables(ii),
"cloud_top_pressure"))
then
169 write(*,*)
"Simple cloud is part of the state vector"
170 cloud_retrieval = .true.
175 call prof_index % setup(full_bmatrix, self%nlevels)
178 call obs % setup(self, prof_index % nprofelements, geovals, vars, ir_pcemis)
181 allocate(b_matrix(prof_index % nprofelements,prof_index % nprofelements))
182 allocate(b_inverse(prof_index % nprofelements,prof_index % nprofelements))
183 allocate(b_sigma(prof_index % nprofelements))
184 allocate(ret_nlevs(hofxdiags_vars % nvars()))
187 if (self % StartOb == 0) self % StartOb = 1
188 if (self % FinishOb == 0) self % FinishOb = obs % iloc
189 if (self % StartOb > self % FinishOb)
then
190 write(
message,*)
"start loop ",self % StartOb,
" is greater than finish loop ",self % FinishOb
200 write(*,*)
"Beginning loop over observations: ",trim(self%qcname)
202 obs_loop:
do jobs = self % StartOb, self % FinishOb
203 if (apply(jobs))
then
205 apply_count = apply_count + 1
206 write(
message, *)
"starting obs number ",jobs
207 call fckit_log % debug(
message)
214 prof_index, obs % surface_type(jobs))
217 call full_bmatrix % reset( obs % lat(jobs), &
218 b_matrix, b_inverse, b_sigma )
225 do jvar = 1, self%nchans
226 if( obs % QCflags(jvar,jobs) == self % passflag )
then
227 nchans_used = nchans_used + 1
230 if (nchans_used == 0)
then
231 write(
message, *)
"No channels selected for observation number ", &
233 call fckit_log % debug(
message)
238 call ob % setup(nchans_used, self % nlevels, prof_index % nprofelements, self % nchans)
239 ob % forward_mod_name = self % forward_mod_name
240 ob % latitude = obs % lat(jobs)
241 ob % longitude = obs % lon(jobs)
242 ob % elevation = obs % elevation(jobs)
243 ob % sensor_zenith_angle = obs % sat_zen(jobs)
244 ob % sensor_azimuth_angle = obs % sat_azi(jobs)
245 ob % solar_zenith_angle = obs % sol_zen(jobs)
246 ob % solar_azimuth_angle = obs % sol_azi(jobs)
247 ob % channels_all = self % channels
248 ob % surface_type = obs % surface_type(jobs)
249 ob % retrievecloud = cloud_retrieval
250 ob % pcemis => ir_pcemis
251 ob % calc_emiss = obs % calc_emiss(jobs)
252 if(self % RTTOV_mwscattSwitch) ob % mwscatt = .true.
253 if(self % RTTOV_usetotalice) ob % mwscatt_totalice = .true.
257 ob % background_T(:) = geoval%vals(:, 1)
261 do jvar = 1, self%nchans
262 if( obs % QCflags(jvar,jobs) == self % passflag )
then
263 jchans_used = jchans_used + 1
264 ob % yobs(jchans_used) = obs % yobs(jvar, jobs)
265 ob % channels_used(jchans_used) = self % channels(jvar)
266 ob % emiss(jchans_used) = obs % emiss(jvar, jobs)
269 call r_submatrix % setup(nchans_used, ob % channels_used, full_rmatrix=full_rmatrix)
272 call ufo_geovals_setup(hofxdiags, hofxdiags_vars, 1, hofxdiags_vars % nvars(), ret_nlevs)
274 if (self % FullDiagnostics)
then
276 call r_submatrix % info()
277 write(*, *)
"Observations used = ",ob % yobs(:)
278 write(*,*)
"ob % emiss = ",ob % emiss
279 write(*,*)
"ob % calc_emiss = ",ob % calc_emiss
280 write(*,*)
"Channel selection = "
281 write(*,
'(15I5)') ob % channels_used
282 write(*,*)
"All Channels = "
283 write(*,
'(15I5)') ob % channels_all
289 if (self % UseMLMinimization)
then
291 r_submatrix, b_matrix, b_inverse, b_sigma, &
292 local_geovals, hofxdiags, rttov_simobs, &
293 prof_index, onedvar_success)
296 r_submatrix, b_matrix, b_inverse, b_sigma, &
297 local_geovals, hofxdiags, rttov_simobs, &
298 prof_index, onedvar_success)
301 obs % output_BT(:, jobs) = ob % output_BT(:)
302 obs % background_BT(:, jobs) = ob % background_BT(:)
303 obs % output_profile(:,jobs) = ob % output_profile(:)
304 obs % final_cost(jobs) = ob % final_cost
305 obs % LWP(jobs) = ob % LWP
306 obs % niter(jobs) = ob % niter
309 if (.NOT. onedvar_success)
then
310 do jvar = 1, self%nchans
311 if( obs % QCflags(jvar,jobs) == 0 )
then
312 obs % QCflags(jvar,jobs) = self % onedvarflag
318 if (self % RetrievedErrorFactor > 0.0 .and. any(obs % QCflags(:,jobs) == 0))
then
319 allocate(max_error(
size(ob % channels_used)))
320 call r_submatrix % multiply_factor_by_stdev(self % RetrievedErrorFactor, max_error)
321 if (any(abs(ob % final_bt_diff(:)) > max_error(:)))
then
322 do jvar = 1, self % nchans
323 if( obs % QCflags(jvar,jobs) == 0 )
then
324 obs % QCflags(jvar,jobs) = self % onedvarflag
328 deallocate(max_error)
335 call r_submatrix % delete()
338 call fckit_log % info(
"Final 1Dvar cost, apply = F")
347 write(
message, *)
"Total number of observations = ", obs % iloc
349 write(
message, *)
"Number tested by 1dvar = ", apply_count
353 call obs % output(self % obsdb, prof_index, vars, self % nchans)
356 call full_bmatrix % delete()
357 call full_rmatrix % delete()
359 if (self % pcemiss)
call ir_pcemis % delete()
360 if (
allocated(b_matrix))
deallocate(b_matrix)
361 if (
allocated(b_inverse))
deallocate(b_inverse)
362 if (
allocated(b_sigma))
deallocate(b_sigma)
363 if (
allocated(ret_nlevs))
deallocate(ret_nlevs)
364 call rttov_simobs % delete()
subroutine, public ufo_geovals_setup(self, vars, nlocs, nvars, nvals)
Initializes and allocates self GeoVaLs with nlocs number of locations for vars variables....
subroutine, public ufo_geovals_delete(self)
subroutine, public ufo_geovals_copy_one(self, other, loc_index)
Copy one location from GeoVaLs into a new object.
subroutine, public ufo_geovals_get_var(self, varname, geoval)
Fortran module containing the full b-matrix data type and methods for the 1D-Var.
Fortran derived type to hold data for the observation covariance.
Fortran module for radiancerttov observation operator.
Fortran module constants used throughout the rttovonedvarcheck filter.
Fortran module containing the routines to perform a Marquardt-Levenberg minimization.
subroutine, public ufo_rttovonedvarcheck_minimize_ml(self, ob, r_matrix, b_matrix, b_inv, b_sigma, local_geovals, hofxdiags, rttov_simobs, profile_index, onedvar_success)
Perform a minimization using the Marquardt-Levenberg method.
Fortran module to perform newton steepest descent minimization.
subroutine, public ufo_rttovonedvarcheck_minimize_newton(self, ob, r_matrix, b_matrix, b_inv, b_sigma, local_geovals, hofxdiags, rttov_simobs, profile_index, onedvar_success)
Get the jacobian used in the 1D-Var.
Fortran module containing subroutines used by both minimizers.
subroutine, public ufo_rttovonedvarcheck_check_geovals(self, geovals, profindex, surface_type)
Check the geovals are ready for the first iteration.
character(len=max_string) message
subroutine, public ufo_rttovonedvarcheck_hofxdiags_levels(retrieval_vars, nlevels, ret_nlevs)
The main Fortran module for implementing the rttov onedvar check.
subroutine, public ufo_rttovonedvarcheck_delete(self)
Delete the main rttov onedvar object in Fortran.
subroutine, public ufo_rttovonedvarcheck_apply(self, f_conf, vars, hofxdiags_vars, geovals, apply)
The main routine that applys the rttov onedvar filter.
subroutine, public ufo_rttovonedvarcheck_create(self, obsspace, f_conf, channels, onedvarflag, passflag)
Setup the main rttov onedvar object in Fortran.
Fortran module which contains the observation metadata for a single observation.
Fortran module which contains the observation data for a all the obs space.
Fortran module which contains the methods for Infrared Principal Component Emissivity The science can...
Fortran module containing profile index.
Fortran derived type to hold data for the observation covariance.
Fortran module containing main type, setup and utilities for the main rttovonedvarcheck object.
subroutine, public ufo_rttovonedvarcheck_setup(self, f_conf, channels)
Setup the defaults for the main rttovonedvarcheck object and read in the contents of the yaml file.
Fortran module with various useful routines.
logical function, public cmp_strings(str1, str2)
character(len=maxvarlen), parameter, public var_ts
type to hold interpolated field for one variable, one observation
type to hold interpolated fields required by the obs operators
Fortran derived type for the observation type.