10 use fckit_configuration_module,
only: fckit_configuration
13 use missing_values_mod
27 character(len=MAXVARLEN),
public,
allocatable :: varin(:)
28 integer,
allocatable :: channels(:)
33 type(crtm_atmosphere_type),
allocatable :: atm_k(:,:)
34 type(crtm_surface_type),
allocatable :: sfc_k(:,:)
35 REAL(kind_real),
allocatable :: scaling_factor(:,:)
53 type(fckit_configuration),
intent(in) :: f_confOper
54 integer(c_int),
intent(in) :: channels(:)
56 type(fckit_configuration) :: f_confOpts
59 CHARACTER(len=MAXVARLEN),
ALLOCATABLE :: var_aerosols(:)
61 call f_confoper%get_or_die(
"obs options",f_confopts)
67 nvars_in =
size(var_aerosols)
68 allocate(self%varin(nvars_in))
69 self%varin(1:nvars_in) = var_aerosols
72 allocate(self%channels(
size(channels)))
73 self%channels(:) = channels(:)
87 if (
allocated(self%atm_k))
then
88 call crtm_atmosphere_destroy(self%atm_K)
89 deallocate(self%atm_k)
92 if (
allocated(self%sfc_k))
then
93 call crtm_surface_destroy(self%sfc_K)
94 deallocate(self%sfc_k)
97 IF (
ALLOCATED(self%scaling_factor))
THEN
98 deallocate(self%scaling_factor)
112 type(c_ptr),
value,
intent(in) :: obss
115 character(*),
parameter :: PROGRAM_NAME =
'ufo_aodcrtm_tlad_mod.F90'
116 character(255) :: message, version
117 integer :: err_stat, alloc_stat
122 type(crtm_channelinfo_type) :: chinfo(self%conf%n_Sensors)
123 type(crtm_geometry_type),
allocatable :: geo(:)
126 type(crtm_atmosphere_type),
allocatable :: atm(:)
127 type(crtm_surface_type),
allocatable :: sfc(:)
128 type(crtm_rtsolution_type),
allocatable :: rts(:,:)
131 type(crtm_rtsolution_type),
allocatable :: rts_K(:,:)
136 self%n_Profiles = geovals%nlocs
138 self%n_Layers = temp%nval
156 err_stat = crtm_init( self%conf%SENSOR_ID, &
158 file_path=trim(self%conf%COEFFICIENT_PATH), &
160 if ( err_stat /= success )
THEN
161 message =
'Error initializing CRTM (setTraj)'
162 call display_message( program_name, message, failure )
168 sensor_loop:
do n = 1, self%conf%n_Sensors
173 self%N_Channels = crtm_channelinfo_n_channels(chinfo(n))
178 allocate( geo( self%n_Profiles ) , &
179 atm( self%n_Profiles ) , &
180 sfc( self%n_Profiles ) , &
181 rts( self%N_Channels, self%n_Profiles ) , &
182 self%atm_K( self%N_Channels, self%n_Profiles ) , &
183 self%sfc_K( self%N_Channels, self%n_Profiles ) , &
184 self%scaling_factor(self%n_Layers,self%n_Profiles ) , &
185 rts_k( self%N_Channels, self%n_Profiles ) , &
187 if ( alloc_stat /= 0 )
THEN
188 message =
'Error allocating structure arrays (setTraj)'
189 call display_message( program_name, message, failure )
196 call crtm_atmosphere_create( atm, self%n_Layers, self%conf%n_Absorbers, self%conf%n_Clouds, self%conf%n_Aerosols )
197 if ( any(.NOT. crtm_atmosphere_associated(atm)) )
THEN
198 message =
'Error allocating CRTM Forward Atmosphere structure (setTraj)'
199 CALL display_message( program_name, message, failure )
205 call crtm_atmosphere_create( self%atm_K, self%n_Layers, self%conf%n_Absorbers, self%conf%n_Clouds, self%conf%n_Aerosols )
206 if ( any(.NOT. crtm_atmosphere_associated(self%atm_K)) )
THEN
207 message =
'Error allocating CRTM K-matrix Atmosphere structure (setTraj)'
208 CALL display_message( program_name, message, failure )
214 CALL load_atm_data(self%N_PROFILES,self%N_LAYERS,geovals,atm,self%conf)
216 IF (trim(self%conf%aerosol_option) /=
"") &
218 &self%conf%aerosol_option,atm)
220 CALL crtm_rtsolution_create(rts, self%n_layers )
221 CALL crtm_rtsolution_create(rts_k, self%n_layers )
225 call crtm_atmosphere_zero( self%atm_K )
232 FORALL (l=1:self%n_channels,m=1:self%n_profiles) rts_k(l,m)%layer_optical_depth = one
236 err_stat = crtm_aod_k( atm , &
241 if ( err_stat /= success )
THEN
242 message =
'Error calling CRTM (setTraj) K-Matrix Model for '//trim(self%conf%SENSOR_ID(n))
243 call display_message( program_name, message, failure )
249 call crtm_atmosphere_destroy(atm)
250 call crtm_rtsolution_destroy(rts_k)
251 call crtm_rtsolution_destroy(rts)
257 deallocate(geo, atm, sfc, rts, rts_k, stat = alloc_stat)
258 if ( alloc_stat /= 0 )
THEN
259 message =
'Error deallocating structure arrays (setTraj)'
260 call display_message( program_name, message, failure )
270 err_stat = crtm_destroy( chinfo )
271 if ( err_stat /= success )
THEN
272 message =
'Error destroying CRTM (setTraj)'
273 call display_message( program_name, message, failure )
291 type(c_ptr),
value,
intent(in) :: obss
292 integer,
intent(in) :: nvars, nlocs
293 real(c_double),
intent(inout) :: hofx(nvars, nlocs)
295 character(len=*),
parameter :: myname_=
"ufo_aodcrtm_simobs_tl"
296 character(max_string) :: err_msg
297 integer :: jprofile, jchannel, jlevel, jaero
300 CHARACTER(len=MAXVARLEN),
ALLOCATABLE :: var_aerosols(:)
307 if (.not. self%ltraj)
then
308 write(err_msg,*) myname_,
' trajectory wasnt set!'
309 call abor1_ftn(err_msg)
313 if (geovals%nlocs /= self%n_Profiles)
then
314 write(err_msg,*) myname_,
' error: nlocs inconsistent!'
315 call abor1_ftn(err_msg)
320 IF (
SIZE(var_aerosols) /= self%conf%n_aerosols)
THEN
321 WRITE(err_msg,*) myname_,
' error: n_aerosols inconsistent!'
322 call abor1_ftn(err_msg)
329 if (var_p%nval /= self%n_Layers)
then
330 write(err_msg,*) myname_,
' error: layers inconsistent!'
331 call abor1_ftn(err_msg)
337 hofx(:,:) = 0.0_kind_real
340 do jprofile = 1, self%n_profiles
342 do jchannel = 1,
size(self%channels)
343 DO jaero = 1, self%conf%n_aerosols
345 DO jlevel = 1, var_p%nval
346 hofx(jchannel, jprofile) = hofx(jchannel, jprofile) + &
347 self%atm_k(self%channels(jchannel),jprofile)%aerosol(jaero)%concentration(jlevel) * &
348 var_p%vals(jlevel,jprofile) * self%scaling_factor(jlevel,jprofile)
363 type(c_ptr),
value,
intent(in) :: obss
364 integer,
intent(in) :: nvars, nlocs
365 real(c_double),
intent(in) :: hofx(nvars, nlocs)
367 character(len=*),
parameter :: myname_=
"ufo_aodcrtm_simobs_ad"
368 character(max_string) :: err_msg
369 integer :: jprofile, jchannel, jlevel
371 real(c_double) :: missing
373 CHARACTER(len=MAXVARLEN),
ALLOCATABLE :: var_aerosols(:)
381 if (.not. self%ltraj)
then
382 write(err_msg,*) myname_,
' trajectory wasnt set!'
383 call abor1_ftn(err_msg)
387 if (geovals%nlocs /= self%n_Profiles)
then
388 write(err_msg,*) myname_,
' error: nlocs inconsistent!'
389 call abor1_ftn(err_msg)
393 missing = missing_value(missing)
397 DO jaero=1,self%conf%n_aerosols
402 DO jprofile = 1, self%n_Profiles
403 DO jchannel = 1,
size(self%channels)
404 DO jlevel = 1, var_p%nval
405 var_p%vals(jlevel,jprofile) = var_p%vals(jlevel,jprofile) + &
406 self%atm_k(self%channels(jchannel),jprofile)%aerosol(jaero)%concentration(jlevel) * hofx(jchannel, jprofile)
411 FORALL (jlevel=1:var_p%nval,jprofile=1:self%n_profiles) &
412 var_p%vals(jlevel,jprofile)=var_p%vals(jlevel,jprofile)*self%scaling_factor(jlevel,jprofile)
418 if (.not. geovals%linit ) geovals%linit=.true.
Fortran module to handle tl/ad for aod observations.
subroutine ufo_aodcrtm_tlad_settraj(self, geovals, obss)
subroutine ufo_aodcrtm_tlad_delete(self)
subroutine ufo_aodcrtm_simobs_ad(self, geovals, obss, nvars, nlocs, hofx)
subroutine ufo_aodcrtm_tlad_setup(self, f_confOper, channels)
subroutine ufo_aodcrtm_simobs_tl(self, geovals, obss, nvars, nlocs, hofx)
Fortran module to provide code shared between nonlinear and tlm/adm radiance calculations.
subroutine, public crtm_conf_setup(conf, f_confOpts, f_confOper)
subroutine, public load_aerosol_data(n_profiles, n_layers, geovals, aerosol_option, atm)
subroutine, public assign_aerosol_names(aerosol_option, var_aerosols)
subroutine, public crtm_conf_delete(conf)
subroutine, public load_atm_data(n_Profiles, n_Layers, geovals, atm, conf)
subroutine, public ufo_geovals_get_var(self, varname, geoval)
character(len=maxvarlen), parameter, public var_ts
Fortran derived type for aod trajectory.
type to hold interpolated field for one variable, one observation
type to hold interpolated fields required by the obs operators