FV3 Bundle
ufo_radiance_mod.F90
Go to the documentation of this file.
1 ! (C) Copyright 2017-2018 UCAR
2 !
3 ! This software is licensed under the terms of the Apache Licence Version 2.0
4 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5 
6 !> Fortran module to handle radiance observations
7 
9 
10  use iso_c_binding
11  use config_mod
12  use kinds
13 
15  use ufo_basis_mod, only: ufo_basis
16  use ufo_vars_mod
18  use crtm_module
19  use obsspace_mod
20 
21  implicit none
22  private
23 
24  !> Fortran derived type for radiance trajectory
25  type, extends(ufo_basis), public :: ufo_radiance
26  private
27  type(rad_conf) :: rc
28  contains
29  procedure :: setup => ufo_radiance_setup
30  procedure :: delete => ufo_radiance_delete
31  procedure :: simobs => ufo_radiance_simobs
32  end type ufo_radiance
33 
34 contains
35 
36 ! ------------------------------------------------------------------------------
37 
38 subroutine ufo_radiance_setup(self, c_conf)
39 
40 implicit none
41 class(ufo_radiance), intent(inout) :: self
42 type(c_ptr), intent(in) :: c_conf
43 
44  call rad_conf_setup(self%rc,c_conf)
45 
46 end subroutine ufo_radiance_setup
47 
48 ! ------------------------------------------------------------------------------
49 
50 subroutine ufo_radiance_delete(self)
51 
52 implicit none
53 class(ufo_radiance), intent(inout) :: self
54 
55  call rad_conf_delete(self%rc)
56 
57 end subroutine ufo_radiance_delete
58 
59 ! ------------------------------------------------------------------------------
60 
61 subroutine ufo_radiance_simobs(self, geovals, hofx, obss)
62 
63 implicit none
64 class(ufo_radiance), intent(in) :: self
65 type(ufo_geovals), intent(in) :: geovals
66 real(c_double), intent(inout) :: hofx(:)
67 type(c_ptr), value, intent(in) :: obss
68 
69 ! Local Variables
70 character(*), parameter :: PROGRAM_NAME = 'ufo_radiance_mod.F90'
71 character(255) :: message, version
72 integer :: err_stat, alloc_stat
73 integer :: l, m, n, i, s, ierr
74 type(ufo_geoval), pointer :: temp
75 
76 integer :: n_Profiles
77 integer :: n_Layers
78 integer :: n_Channels
79 
80 ! Define the "non-demoninational" arguments
81 type(CRTM_ChannelInfo_type) :: chinfo(self%rc%n_Sensors)
82 type(CRTM_Geometry_type), allocatable :: geo(:)
83 
84 ! Define the FORWARD variables
85 type(CRTM_Atmosphere_type), allocatable :: atm(:)
86 type(CRTM_Surface_type), allocatable :: sfc(:)
87 type(CRTM_RTSolution_type), allocatable :: rts(:,:)
88 
89 
90  ! Get number of profile and layers from geovals
91  ! ---------------------------------------------
92  n_profiles = geovals%nobs
93  call ufo_geovals_get_var(geovals, var_tv, temp, status=ierr)
94  n_layers = temp%nval
95  nullify(temp)
96 
97 
98  ! Program header
99  ! --------------
100  call crtm_version( version )
101  call program_message( program_name, &
102  'Check/example program for the CRTM Forward and K-Matrix functions using '//&
103  trim(self%rc%ENDIAN_type)//' coefficient datafiles', &
104  'CRTM Version: '//trim(version) )
105 
106 
107  ! Initialise all the sensors at once
108  ! ----------------------------------
109  !** NOTE: CRTM_Init points to the various binary files needed for CRTM. See the
110  !** CRTM_Lifecycle.f90 for more details.
111 
112  write( *,'(/5x,"Initializing the CRTM...")' )
113  err_stat = crtm_init( self%rc%SENSOR_ID, &
114  chinfo, &
115  file_path=trim(self%rc%COEFFICIENT_PATH), &
116  quiet=.true.)
117  if ( err_stat /= success ) THEN
118  message = 'Error initializing CRTM'
119  call display_message( program_name, message, failure )
120  stop
121  end if
122 
123 
124  ! Loop over all sensors. Not necessary if we're calling CRTM for each sensor
125  ! ----------------------------------------------------------------------------
126  sensor_loop:do n = 1, self%rc%n_Sensors
127 
128 
129  ! Determine the number of channels for the current sensor
130  ! -------------------------------------------------------
131  n_channels = crtm_channelinfo_n_channels(chinfo(n))
132 
133 
134  ! Allocate the ARRAYS
135  ! -------------------
136  allocate( geo( n_profiles ), &
137  atm( n_profiles ), &
138  sfc( n_profiles ), &
139  rts( n_channels, n_profiles ), &
140  stat = alloc_stat )
141  if ( alloc_stat /= 0 ) THEN
142  message = 'Error allocating structure arrays'
143  call display_message( program_name, message, failure )
144  stop
145  end if
146 
147 
148  ! Create the input FORWARD structure (atm)
149  ! ----------------------------------------
150  call crtm_atmosphere_create( atm, n_layers, self%rc%n_Absorbers, self%rc%n_Clouds, self%rc%n_Aerosols )
151  if ( any(.NOT. crtm_atmosphere_associated(atm)) ) THEN
152  message = 'Error allocating CRTM Forward Atmosphere structure'
153  CALL display_message( program_name, message, failure )
154  stop
155  END IF
156 
157 
158  ! Create the input FORWARD structure (sfc)
159  ! ----------------------------------------
160  call crtm_surface_create(sfc, n_channels)
161  IF ( any(.NOT. crtm_surface_associated(sfc)) ) THEN
162  message = 'Error allocating CRTM Surface structure'
163  CALL display_message( program_name, message, failure )
164  stop
165  END IF
166 
167 
168  !Assign the data from the GeoVaLs
169  !--------------------------------
170  call load_atm_data(n_profiles,n_layers,geovals,atm)
171  call load_sfc_data(n_profiles,n_layers,n_channels,geovals,sfc,chinfo,obss)
172  call load_geom_data(obss,geo)
173 
174 
175  ! Call THE CRTM inspection
176  ! ------------------------
177  call crtm_atmosphere_inspect(atm(12))
178  call crtm_surface_inspect(sfc(12))
179  call crtm_geometry_inspect(geo(12))
180  call crtm_channelinfo_inspect(chinfo(1))
181 
182 
183  ! Call the forward model call for each sensor
184  ! -------------------------------------------
185  err_stat = crtm_forward( atm , & ! Input
186  sfc , & ! Input
187  geo , & ! Input
188  chinfo(n:n), & ! Input
189  rts ) ! Output
190  if ( err_stat /= success ) THEN
191  message = 'Error calling CRTM Forward Model for '//trim(self%rc%SENSOR_ID(n))
192  call display_message( program_name, message, failure )
193  stop
194  end if
195 
196 
197  ! Put simulated brightness temperature into hofx
198  ! ----------------------------------------------
199 
200  !Set to zero and initializ counter
201  hofx(:) = 0.0_kind_real
202  i = 1
203 
204  do m = 1, n_profiles
205  do l = 1, n_channels
206 
207  hofx(i) = rts(l,m)%Brightness_Temperature
208  i = i + 1
209 
210  end do
211  end do
212 
213 
214  ! Deallocate the structures
215  ! -------------------------
216  call crtm_geometry_destroy(geo)
217  call crtm_atmosphere_destroy(atm)
218  call crtm_rtsolution_destroy(rts)
219  call crtm_surface_destroy(sfc)
220 
221 
222  ! Deallocate all arrays
223  ! ---------------------
224  deallocate(geo, atm, sfc, rts, stat = alloc_stat)
225  if ( alloc_stat /= 0 ) THEN
226  message = 'Error deallocating structure arrays'
227  call display_message( program_name, message, failure )
228  stop
229  end if
230 
231  end do sensor_loop
232 
233 
234  ! Destroy CRTM instance
235  ! ---------------------
236  write( *, '( /5x, "Destroying the CRTM..." )' )
237  err_stat = crtm_destroy( chinfo )
238  if ( err_stat /= success ) THEN
239  message = 'Error destroying CRTM'
240  call display_message( program_name, message, failure )
241  stop
242  end if
243 
244 end subroutine ufo_radiance_simobs
245 
246 ! ------------------------------------------------------------------------------
247 
248 end module ufo_radiance_mod
subroutine, public ufo_geovals_get_var(self, varname, geoval, status)
Fortran derived type for radiance trajectory.
Fortran module to handle radiance observations.
Fortran module to provide code shared between nonlinear and tlm/adm radiance calculations.
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)
subroutine, public load_geom_data(obss, geo)
subroutine ufo_radiance_delete(self)
subroutine, public rad_conf_setup(rc, c_conf)
subroutine, public rad_conf_delete(rc)
subroutine crtm_version(version)
Definition: CRTM_Module.F90:79
type to hold interpolated fields required by the obs operators
subroutine ufo_radiance_simobs(self, geovals, hofx, obss)
Fortran interface to ObsSpace.
Definition: obsspace_mod.F90:9
character(len=maxvarlen), public var_tv
type to hold interpolated field for one variable, one observation
subroutine, public delete(self)
Definition: qg_fields.F90:136
subroutine ufo_radiance_setup(self, c_conf)