31 type(crtm_atmosphere_type),
allocatable :: atm_k(:,:)
32 type(crtm_surface_type),
allocatable :: sfc_k(:,:)
48 class(ufo_radiance_tlad),
intent(inout) :: self
49 type(c_ptr),
intent(in) :: c_conf
60 class(ufo_radiance_tlad),
intent(inout) :: self
65 if (
allocated(self%atm_k))
then 66 call crtm_atmosphere_destroy(self%atm_K)
67 deallocate(self%atm_k)
70 if (
allocated(self%sfc_k))
then 71 call crtm_surface_destroy(self%sfc_K)
72 deallocate(self%sfc_k)
83 class(ufo_radiance_tlad),
intent(inout) :: self
84 type(ufo_geovals),
intent(in) :: geovals
85 type(c_ptr),
value,
intent(in) :: obss
88 character(*),
parameter :: PROGRAM_NAME =
'ufo_radiance_mod.F90' 89 character(255) :: message, version
90 integer :: err_stat, alloc_stat
91 integer :: n, k1, ierr
92 type(ufo_geoval),
pointer :: temp
95 type(CRTM_ChannelInfo_type) :: chinfo(self%rc%n_Sensors)
96 type(CRTM_Geometry_type),
allocatable :: geo(:)
99 type(CRTM_Atmosphere_type),
allocatable :: atm(:)
100 type(CRTM_Surface_type),
allocatable :: sfc(:)
101 type(CRTM_RTSolution_type),
allocatable :: rts(:,:)
104 type(CRTM_RTSolution_type),
allocatable :: rts_K(:,:)
109 self%n_Profiles = geovals%nobs
111 self%n_Layers = temp%nval
117 call program_message( program_name, &
118 'Check/example program for the CRTM Forward and K-Matrix (setTraj) functions using '//&
119 trim(self%rc%ENDIAN_type)//
' coefficient datafiles', &
120 'CRTM Version: '//trim(version) )
128 write( *,
'(/5x,"Initializing the CRTM (setTraj) ...")' )
129 err_stat = crtm_init( self%rc%SENSOR_ID, &
131 file_path=trim(self%rc%COEFFICIENT_PATH), &
133 if ( err_stat /= success )
THEN 134 message =
'Error initializing CRTM (setTraj)' 135 call display_message( program_name, message, failure )
141 sensor_loop:
do n = 1, self%rc%n_Sensors
146 self%N_Channels = crtm_channelinfo_n_channels(chinfo(n))
151 allocate( geo( self%n_Profiles ) , &
152 atm( self%n_Profiles ) , &
153 sfc( self%n_Profiles ) , &
154 rts( self%N_Channels, self%n_Profiles ) , &
155 self%atm_K( self%N_Channels, self%n_Profiles ) , &
156 self%sfc_K( self%N_Channels, self%n_Profiles ) , &
157 rts_k( self%N_Channels, self%n_Profiles ) , &
159 if ( alloc_stat /= 0 )
THEN 160 message =
'Error allocating structure arrays (setTraj)' 161 call display_message( program_name, message, failure )
168 call crtm_atmosphere_create( atm, self%n_Layers, self%rc%n_Absorbers, self%rc%n_Clouds, self%rc%n_Aerosols )
169 if ( any(.NOT. crtm_atmosphere_associated(atm)) )
THEN 170 message =
'Error allocating CRTM Forward Atmosphere structure (setTraj)' 171 CALL display_message( program_name, message, failure )
178 call crtm_surface_create(sfc, self%N_Channels)
179 IF ( any(.NOT. crtm_surface_associated(sfc)) )
THEN 180 message =
'Error allocating CRTM Surface structure (setTraj)' 181 CALL display_message( program_name, message, failure )
188 call crtm_atmosphere_create( self%atm_K, self%n_Layers, self%rc%n_Absorbers, self%rc%n_Clouds, self%rc%n_Aerosols )
189 if ( any(.NOT. crtm_atmosphere_associated(self%atm_K)) )
THEN 190 message =
'Error allocating CRTM K-matrix Atmosphere structure (setTraj)' 191 CALL display_message( program_name, message, failure )
198 call crtm_surface_create(self%sfc_K, self%N_Channels)
199 IF ( any(.NOT. crtm_surface_associated(self%sfc_K)) )
THEN 200 message =
'Error allocating CRTM K-matrix Surface structure (setTraj)' 201 CALL display_message( program_name, message, failure )
208 call load_atm_data(self%N_PROFILES,self%N_LAYERS,geovals,atm)
209 call load_sfc_data(self%N_PROFILES,self%N_LAYERS,self%N_Channels,geovals,sfc,chinfo,obss)
215 call crtm_atmosphere_zero( self%atm_K )
216 call crtm_surface_zero( self%sfc_K )
221 rts_k%Radiance =
zero 222 rts_k%Brightness_Temperature =
one 227 err_stat = crtm_k_matrix( atm , &
235 if ( err_stat /= success )
THEN 236 message =
'Error calling CRTM (setTraj) K-Matrix Model for '//trim(self%rc%SENSOR_ID(n))
237 call display_message( program_name, message, failure )
244 call crtm_geometry_destroy(geo)
245 call crtm_atmosphere_destroy(atm)
246 call crtm_rtsolution_destroy(rts_k)
247 call crtm_rtsolution_destroy(rts)
248 call crtm_surface_destroy(sfc)
253 deallocate(geo, atm, sfc, rts, rts_k, stat = alloc_stat)
254 if ( alloc_stat /= 0 )
THEN 255 message =
'Error deallocating structure arrays (setTraj)' 256 call display_message( program_name, message, failure )
265 write( *,
'( /5x, "Destroying the CRTM (setTraj)..." )' )
266 err_stat = crtm_destroy( chinfo )
267 if ( err_stat /= success )
THEN 268 message =
'Error destroying CRTM (setTraj)' 269 call display_message( program_name, message, failure )
285 class(ufo_radiance_tlad),
intent(in) :: self
286 type(ufo_geovals),
intent(in) :: geovals
287 real(c_double),
intent(inout) :: hofx(:)
288 type(c_ptr),
value,
intent(in) :: obss
290 character(len=*),
parameter :: myname_=
"ufo_radiance_simobs_tl" 291 character(max_string) :: err_msg
292 integer :: job, jprofile, jchannel, jlevel, ierr
293 type(ufo_geoval),
pointer :: tv_d
300 if (.not. self%ltraj)
then 301 write(err_msg,*) myname_,
' trajectory wasnt set!' 302 call abor1_ftn(err_msg)
306 if (geovals%nobs /= self%n_Profiles)
then 307 write(err_msg,*) myname_,
' error: nobs inconsistent!' 308 call abor1_ftn(err_msg)
313 hofx(:) = 0.0_kind_real
322 write(err_msg,*) myname_, trim(
var_tv),
' doesnt exist' 323 call abor1_ftn(err_msg)
327 if (tv_d%nval /= self%n_Layers)
then 328 write(err_msg,*) myname_,
' error: layers inconsistent!' 329 call abor1_ftn(err_msg)
334 do jprofile = 1, self%n_Profiles
335 do jchannel = 1, self%n_Channels
337 do jlevel = 1, tv_d%nval
338 hofx(job) = hofx(job) + &
339 self%atm_K(jchannel,jprofile)%Temperature(jlevel) * tv_d%vals(jlevel,jprofile)
352 class(ufo_radiance_tlad),
intent(in) :: self
353 type(ufo_geovals),
intent(inout) :: geovals
354 real(c_double),
intent(in) :: hofx(:)
355 type(c_ptr),
value,
intent(in) :: obss
357 character(len=*),
parameter :: myname_=
"ufo_radiance_simobs_ad" 358 character(max_string) :: err_msg
359 integer :: job, jprofile, jchannel, jlevel, ierr
360 type(ufo_geoval),
pointer :: tv_d
367 if (.not. self%ltraj)
then 368 write(err_msg,*) myname_,
' trajectory wasnt set!' 369 call abor1_ftn(err_msg)
373 if (geovals%nobs /= self%n_Profiles)
then 374 write(err_msg,*) myname_,
' error: nobs inconsistent!' 375 call abor1_ftn(err_msg)
385 write(err_msg,*) myname_, trim(
var_tv),
' doesnt exist' 386 call abor1_ftn(err_msg)
390 if (.not.
allocated(tv_d%vals))
then 391 tv_d%nobs = self%n_Profiles
392 tv_d%nval = self%n_Layers
393 allocate(tv_d%vals(tv_d%nval,tv_d%nobs))
394 tv_d%vals = 0.0_kind_real
400 do jprofile = 1, self%n_Profiles
401 do jchannel = 1, self%n_Channels
403 do jlevel = 1, tv_d%nval
404 tv_d%vals(jlevel,jprofile) = tv_d%vals(jlevel,jprofile) + &
405 self%atm_K(jchannel,jprofile)%Temperature(jlevel) * hofx(job)
413 if (.not. geovals%linit ) geovals%linit=.true.
subroutine, public ufo_geovals_get_var(self, varname, geoval, status)
real(fp), parameter, public zero
subroutine ufo_radiance_simobs_ad(self, geovals, hofx, obss)
Fortran module to provide code shared between nonlinear and tlm/adm radiance calculations.
subroutine ufo_radiance_tlad_setup(self, c_conf)
subroutine, public load_atm_data(N_PROFILES, N_LAYERS, geovals, atm)
subroutine, public load_sfc_data(n_Profiles, n_Layers, N_Channels, geovals, sfc, chinfo, obss)
Fortran module to handle tl/ad for radiance observations.
subroutine, public load_geom_data(obss, geo)
subroutine ufo_radiance_tlad_delete(self)
subroutine, public rad_conf_setup(rc, c_conf)
subroutine, public rad_conf_delete(rc)
real(fp), parameter, public one
Fortran derived type for radiance trajectory.
subroutine crtm_version(version)
type to hold interpolated fields required by the obs operators
subroutine ufo_radiance_simobs_tl(self, geovals, hofx, obss)
Fortran interface to ObsSpace.
character(len=maxvarlen), public var_tv
subroutine ufo_radiance_tlad_settraj(self, geovals, obss)
type to hold interpolated field for one variable, one observation
subroutine, public delete(self)