UFO
ufo_radiancerttov_tlad_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 for radiancerttov tl/ad observation operator
7 
9 
10  use fckit_configuration_module, only: fckit_configuration
11  use fckit_log_module, only : fckit_log
12  use iso_c_binding
13  use kinds
14  use missing_values_mod
15 
16  use obsspace_mod
17 
19  use ufo_vars_mod
21 
22  use rttov_types
23  use rttov_const, only : errorstatus_success
24  use rttov_unix_env
25 
26  implicit none
27  private
28 
29  !> Fortran derived type for radiancerttov trajectory
30  type, public :: ufo_radiancerttov_tlad
31  private
32  character(len=MAXVARLEN), public, allocatable :: varin(:) ! variables requested from the model
33  integer, allocatable :: channels(:)
34  type(rttov_conf) :: conf
35  type(rttov_conf) :: conf_traj
36  type(ufo_rttov_io) :: rtprof_k
37 
38  integer :: nprofiles
39  integer :: nchan_total
40  integer :: nlevels
41 
42  logical :: ltraj
43  logical, allocatable :: skip_profiles(:)
44 
45  contains
46  procedure :: setup => ufo_radiancerttov_tlad_setup
47  procedure :: delete => ufo_radiancerttov_tlad_delete
48  procedure :: settraj => ufo_radiancerttov_tlad_settraj
49  procedure :: simobs_tl => ufo_radiancerttov_simobs_tl
50  procedure :: simobs_ad => ufo_radiancerttov_simobs_ad
51  end type ufo_radiancerttov_tlad
52 
53  character(len=maxvarlen), dimension(1), parameter :: varin_default_tlad = &
54  (/var_ts/)
55 
56 contains
57 
58  ! ------------------------------------------------------------------------------
59  subroutine ufo_radiancerttov_tlad_setup(self, f_confOper, channels)
60  implicit none
61 
62  class(ufo_radiancerttov_tlad), intent(inout) :: self
63  type(fckit_configuration), intent(in) :: f_confOper
64  integer(c_int), intent(in) :: channels(:) !List of channels to use
65 
66  type(fckit_configuration) :: f_confOpts ! RTcontrol
67  type(fckit_configuration) :: f_confLinOper
68  integer :: nvars_in
69  integer :: ind, jspec
70 
71  call f_confoper % get_or_die("obs options",f_confopts)
72 
73  call rttov_conf_setup(self % conf_traj, f_confopts,f_confoper)
74 
75  if ( f_confoper%has("linear obs operator") ) then
76  call f_confoper%get_or_die("linear obs operator",f_conflinoper)
77  call rttov_conf_setup(self%conf, f_confopts, f_conflinoper)
78  else
79  call rttov_conf_setup(self%conf, f_confopts, f_confoper)
80  end if
81 
82  !DAR what is the RTTOV equivalant of making sure that humidity and ozone data are present
83  if ( ufo_vars_getindex(self%conf%Absorbers, var_mixr) < 1 .and. &
84  ufo_vars_getindex(self%conf%Absorbers, var_q) < 1 ) then
85  write(message,*) 'ufo_radiancerttov_setup error: H2O must be included in RTTOV Absorbers'
86  call abor1_ftn(message)
87  end if
88 
89  nvars_in = size(varin_default_tlad) + self%conf%ngas + 5 ! 5 near-surface parameters
90 
91  allocate(self%varin(nvars_in))
92  self%varin(1:size(varin_default_tlad)) = varin_default_tlad
93  ind = size(varin_default_tlad) + 1
94 
95  do jspec = 1, self%conf%ngas
96  self%varin(ind) = self%conf%Absorbers(jspec)
97  ind = ind + 1
98  end do
99 
100  self%varin(ind) = var_sfc_t2m
101  ind = ind + 1
102  self%varin(ind) = var_sfc_q2m
103  ind = ind + 1
104  self%varin(ind) = var_sfc_tskin
105  ind = ind + 1
106  self%varin(ind) = var_u
107  ind = ind + 1
108  self%varin(ind) = var_v
109 
110  ! save channels
111  allocate(self%channels(size(channels)))
112  self%channels(:) = channels(:)
113 
114  end subroutine ufo_radiancerttov_tlad_setup
115 
116  ! ------------------------------------------------------------------------------
118  implicit none
119 
120  class(ufo_radiancerttov_tlad), intent(inout) :: self
121  integer(kind=jpim) :: errorstatus
122 
123  self % ltraj = .false.
124 
125  call rttov_conf_delete(self % conf)
126  call rttov_conf_delete(self % conf_traj)
127 
128  if (allocated(self%Skip_Profiles)) deallocate(self%Skip_Profiles)
129 
130  end subroutine ufo_radiancerttov_tlad_delete
131 
132  ! ------------------------------------------------------------------------------
133  subroutine ufo_radiancerttov_tlad_settraj(self, geovals, obss, hofxdiags)
134 
135  use fckit_mpi_module, only: fckit_mpi_comm
136 
137  implicit none
138 
139  class(ufo_radiancerttov_tlad), intent(inout) :: self
140  type(ufo_geovals), intent(in) :: geovals
141  type(c_ptr), value, intent(in) :: obss
142  type(ufo_geovals), intent(inout) :: hofxdiags !non-h(x) diagnostics
143 
144  type(fckit_mpi_comm) :: f_comm
145 
146  ! Local Variables
147  character(*), parameter :: ROUTINE_NAME = 'ufo_radiancerttov_tlad_settraj'
148  type(ufo_geoval), pointer :: temp
149 
150  integer(kind=jpim) :: errorstatus ! Return error status of RTTOV subroutine calls
151 
152  integer :: nchan_max_sim, nchan_count, nchan_total
153  integer :: nprof_sim, nprof_max_sim
154 
155  integer :: iprof, ichan, i_inst
156  integer :: prof_start, prof_end
157 
158  logical :: layer_quantities
159  logical :: jacobian_needed
160 
161  include 'rttov_k.interface'
162  include 'rttov_print_profile.interface'
163  include 'rttov_user_profile_checkinput.interface'
164 
165  !DAR: What is this?
166  call obsspace_get_comm(obss, f_comm)
167 
168  ! Get number of profile and layers from geovals
169  ! ---------------------------------------------
170  self % nprofiles = geovals % nlocs
171  if (ufo_vars_getindex(geovals%variables, var_ts) > 0) then
172  call ufo_geovals_get_var(geovals, var_ts, temp)
173  self % nlevels = temp % nval ! lfric passing nlevels
174  layer_quantities = .false.
175  endif
176 
177  nullify(temp)
178 
179  errorstatus = 0_jpim
180  nchan_count = 0
181  nchan_total = 0
182 
183  nchan_inst = size(self % channels)
184 
185  nchan_max_sim = self % nprofiles * nchan_inst ! Maximum number of channels to pass to RTTOV to simulate
186 
187  !! Parse hofxdiags%variables into independent/dependent variables and channel
188  !! assumed formats:
189  !! jacobian var --> <ystr>_jacobian_<xstr>_<chstr>
190  !! non-jacobian var --> <ystr>_<chstr>
191  call parse_hofxdiags(hofxdiags, jacobian_needed)
192 
193  sensor_loop:do i_inst = 1, self % conf % nSensors
194 
195  ! Ensure the options and coefficients are consistent
196  call rttov_user_options_checkinput(errorstatus, self % conf % rttov_opts, &
197  self % conf % rttov_coef_array(i_inst))
198 
199  if (errorstatus /= errorstatus_success) then
200  write(message,'(A, A,I6)') trim(routine_name), 'after rttov_user_options_checkinput: error = ',&
201  errorstatus
202  call fckit_log%info(message)
203  end if
204 
205  ! keep journal of which profiles have no obs data these will be skipped
206  allocate(self % Skip_Profiles(self % nprofiles))
207  call ufo_rttov_skip_profiles(self%nProfiles,nchan_inst,self%channels,obss,self%Skip_Profiles)
208 
209  ! Determine the total number of radiances to simulate (nchanprof).
210  ! In this example we simulate all specified channels for each profile, but
211  ! in general one can simulate a different number of channels for each profile.
212 
213  nprof_max_sim = nchan_max_sim / nchan_inst
214  nprof_sim = min(nprof_max_sim, self % nprofiles)
215 
216  prof_start = 1
217  prof_end = self % nprofiles
218 
219  !DARFIX should actually be packed count of skip_profiles * SIZE(channels)
220  nprof_sim = min(nprof_sim, prof_end - prof_start + 1)
221  nchan_sim = nprof_sim * size(self%channels)
222 
223  ! --------------------------------------------------------------------------
224  ! Allocate RTTOV input and output structures
225  ! --------------------------------------------------------------------------
226 
227  call self % RTprof_K % alloc(errorstatus, self % conf, nprof_sim, nchan_sim, self % nlevels, init=.true., asw=2)
228 
229  do while ( prof_start <= prof_end)
230 
231  ! --------------------------------------------------------------------------
232  ! Build the list of profile/channel indices in chanprof
233  ! --------------------------------------------------------------------------
234 
235  nchan_sim = 0_jpim
236  nprof_sim = min(nprof_sim, prof_end - prof_start + 1)
237 
238  do iprof = 1, min(nprof_sim, prof_end - prof_start + 1)
239  if(.not. self % Skip_Profiles(prof_start + iprof - 1)) then
240  do ichan = 1, nchan_inst
241  nchan_sim = nchan_sim + 1_jpim
242 
243  self % RTProf_K % chanprof(nchan_total + nchan_sim) % prof = iprof
244  self % RTprof_K % chanprof(nchan_total + nchan_sim) % chan = self % channels(ichan)
245  end do
246  endif
247  end do
248 
249  !Assign the data from the GeoVaLs
250  !--------------------------------
251 
252  call load_atm_data_rttov(geovals,obss,self % RTprof_K % profiles,prof_start,self % conf,layer_quantities)
253  call load_geom_data_rttov(obss,self % RTprof_K % profiles,prof_start)
254 
255  ! --------------------------------------------------------------------------
256  ! Set surface emissivity
257  ! --------------------------------------------------------------------------
258  call self % RTProf_K % init_emissivity(self % conf)
259 
260  ! Inintialize the K-matrix INPUT so that the results are dTb/dx
261  ! -------------------------------------------------------------
262 
263  self % RTprof_K % emissivity_k(:) % emis_out = 0
264  self % RTprof_K % emissivity_k(:) % emis_in = 0
265  self % RTprof_K % emissivity(:) % emis_out = 0
266  self % RTprof_K % radiance_k % bt(:) = 1
267  self % RTprof_K % radiance_k % total(:) = 1
268 
269  if(self % conf % RTTOV_profile_checkinput) then
270  if (self % conf % inspect > 0) then
271  ! no error checking, could check multiple profiles in loop but what would be the point
272  call rttov_print_profile(self % RTprof_K % profiles(self % conf % inspect))
273 
274  call rttov_user_profile_checkinput(rttov_errorstatus, &
275  self % conf % rttov_opts, &
276  self % conf % rttov_coef_array(i_inst), &
277  self % RTprof_K % profiles(self % conf % inspect))
278  endif
279  endif
280 
281  ! --------------------------------------------------------------------------
282  ! Call RTTOV K model
283  ! --------------------------------------------------------------------------
284 
285  call rttov_k( &
286  errorstatus, &! out error flag
287  self % RTprof_K % chanprof(nchan_total + 1:nchan_total + nchan_sim), &! in channel and profile index structure
288  self % conf % rttov_opts, &! in options structure
289  self % RTprof_K % profiles, &! in profile array
290  self % RTprof_K % profiles_k(nchan_total + 1 : nchan_total + nchan_sim), &! in profile array
291  self % conf % rttov_coef_array(i_inst), &! in coefficients structure
292  self % RTprof_K % transmission, &! inout computed transmittances
293  self % RTprof_K % transmission_k, &! inout computed transmittances
294  self % RTprof_K % radiance, &! inout computed radiances
295  self % RTprof_K % radiance_k, &! inout computed radiances
296  calcemis = self % RTprof_K % calcemis, &! in flag for internal emissivity calcs
297  emissivity = self % RTprof_K % emissivity, &!, &! inout input/output emissivities per channel
298  emissivity_k = self % RTprof_K % emissivity_k)!, &! inout input/output emissivities per channel
299 
300  if (self % conf % inspect > 0) then
301  ! no error checking, could check multiple channels here using inspect_k array (NOT IMPLEMENTED)
302  call rttov_print_profile(self % RTprof_K % profiles_k(self % conf % inspect))
303  endif
304 
305  if ( errorstatus /= errorstatus_success ) then
306  write(message,'(A, A, 2I6)') trim(routine_name), 'after rttov_k: error ', errorstatus, i_inst
307  call abor1_ftn(message)
308  end if
309 
310  write(*,'(A1, i0, A, i0)',advance="NO") achar(13), prof_start+nprof_sim-1, ' locations processed out of ', geovals%nlocs
311 
312  ! Put simulated diagnostics into hofxdiags
313  ! ----------------------------------------------
314  if(hofxdiags%nvar > 0) call populate_hofxdiags(self % RTprof_K, self % RTprof_K % chanprof, hofxdiags)
315 
316  prof_start = prof_start + nprof_sim
317  nchan_total = nchan_total + nchan_sim
318 
319  self % nchan_total = nchan_total
320  end do
321  ! Deallocate structures for rttov_direct
322  end do sensor_loop
323 
324  write(*,*)
325 
326  ! Set flag that the tracectory was set
327  ! ------------------------------------
328  self % ltraj = .true.
329 
330  end subroutine ufo_radiancerttov_tlad_settraj
331 
332  ! ------------------------------------------------------------------------------
333  subroutine ufo_radiancerttov_simobs_tl(self, geovals, obss, nvars, nlocs, hofx)
334 
335  use ufo_constants_mod, only : zero, g_to_kg
336 
337  implicit none
338 
339  class(ufo_radiancerttov_tlad), intent(in) :: self
340  type(ufo_geovals), intent(in) :: geovals
341  type(c_ptr), value, intent(in) :: obss
342  integer, intent(in) :: nvars, nlocs
343  real(c_double), intent(inout) :: hofx(nvars, nlocs)
344 
345  character(len=*), parameter :: myname_="ufo_radiancerttov_simobs_tl"
346  integer :: ichan, jchan, prof, jspec
347 
348  type(ufo_geoval), pointer :: geoval_d, geoval_d2
349 
350  ! Initial checks
351  ! --------------
352 
353  ! Check if trajectory was set
354  if (.not. self % ltraj) then
355  write(message,*) myname_, ' trajectory wasnt set!'
356  call abor1_ftn(message)
357  end if
358 
359  ! Check if nlocs is consistent in geovals & hofx
360  if (geovals % nlocs /= self % nprofiles) then
361  write(message,*) myname_, ' error: nlocs inconsistent!'
362  call abor1_ftn(message)
363  end if
364 
365  ! Initialize hofx
366  ! ---------------
367  hofx(:,:) = zero
368 
369  ! Temperature
370  ! -----------
371  call ufo_geovals_get_var(geovals, var_ts, geoval_d) ! var_ts = air_temperature
372 
373  ! Check model levels is consistent in geovals
374  if (geoval_d % nval /= self % nlevels) then
375  write(message,*) myname_, ' error: layers inconsistent!'
376  call abor1_ftn(message)
377 
378  end if
379 
380  do ichan = 1, self % nchan_total, size(self%channels)
381  prof = self % RTprof_K % chanprof(ichan) % prof
382  if (.not. self % Skip_Profiles(prof)) then
383  do jchan = 1, size(self%channels)
384  hofx(jchan,prof) = hofx(jchan,prof) + &
385  sum(self % RTprof_K % profiles_k(ichan+jchan-1) % t(self % nlevels:1:-1) * geoval_d % vals(1:geoval_d % nval,prof))
386  enddo
387  endif
388  end do
389 
390  do jspec = 1, self%conf%ngas
391  call ufo_geovals_get_var(geovals, self%conf%Absorbers(jspec), geoval_d)
392 
393  ! Check model levels is consistent in geovals
394  if (geoval_d % nval /= self % nlevels) then
395  write(message,*) myname_, ' error: layers inconsistent!'
396  call abor1_ftn(message)
397  end if
398 
399  ! Absorbers
400  ! ---------
401  ! This is where CO2 and friends will live as well as CLW
402  do ichan = 1, self % nchan_total, size(self%channels)
403  prof = self % RTprof_K % chanprof(ichan) % prof
404  if (.not. self % Skip_Profiles(prof)) then
405  do jchan = 1, size(self%channels)
406  if(self%conf%Absorbers(jspec) == var_q) then
407  hofx(jchan,prof) = hofx(jchan,prof) + &
408  sum(self % RTprof_K % profiles_k(ichan+jchan-1) % q(self % nlevels:1:-1) * geoval_d % vals(1:geoval_d % nval,prof))
409  elseif(self%conf%Absorbers(jspec) == var_mixr) then
410  hofx(jchan,prof) = hofx(jchan,prof) + &
411  sum(self % RTprof_K % profiles_k(ichan+jchan-1) % q(self % nlevels:1:-1) * geoval_d % vals(1:geoval_d % nval,prof)) / &
412  g_to_kg
413  elseif(self%conf%Absorbers(jspec) == var_clw) then
414  hofx(jchan,prof) = hofx(jchan,prof) + &
415  sum(self % RTprof_K % profiles_k(ichan+jchan-1) % clw(self % nlevels:1:-1) * geoval_d % vals(1:geoval_d % nval,prof))
416  endif
417  enddo
418  endif
419  end do
420  enddo
421 
422  ! Cloud
423  ! --------------------------
424  !IR
425 
426 
427  ! Surface + Single-valued Variables
428  ! --------------------------
429  !CTP/cloudfrac
430  !O3total
431  !LWP
432 
433  !T2m
434  call ufo_geovals_get_var(geovals, var_sfc_t2m, geoval_d)
435 
436  do ichan = 1, self % nchan_total, size(self%channels)
437  prof = self % RTprof_K % chanprof(ichan) % prof
438  if (.not. self % Skip_Profiles(prof)) then
439  do jchan = 1, size(self%channels)
440  hofx(jchan,prof) = hofx(jchan,prof) + &
441  self % RTprof_K % profiles_k(ichan+jchan-1) % s2m % t * geoval_d % vals(1,prof)
442  enddo
443  endif
444  end do
445 
446  !q2m
447  call ufo_geovals_get_var(geovals, var_sfc_q2m, geoval_d)
448 
449  do ichan = 1, self % nchan_total, size(self%channels)
450  prof = self % RTprof_K % chanprof(ichan) % prof
451  if (.not. self % Skip_Profiles(prof)) then
452  do jchan = 1, size(self%channels)
453  hofx(jchan,prof) = hofx(jchan,prof) + &
454  self % RTprof_K % profiles_k(ichan+jchan-1) % s2m % q * geoval_d % vals(1,prof)
455  enddo
456  endif
457  end do
458 
459  !windspeed
460  call ufo_geovals_get_var(geovals, var_u, geoval_d)
461  call ufo_geovals_get_var(geovals, var_v, geoval_d2)
462 
463  do ichan = 1, self % nchan_total, size(self%channels)
464  prof = self % RTprof_K % chanprof(ichan) % prof
465  if (.not. self % Skip_Profiles(prof)) then
466  do jchan = 1, size(self%channels)
467  hofx(jchan,prof) = hofx(jchan,prof) + &
468  self % RTprof_K % profiles_k(ichan+jchan-1) % s2m % u * geoval_d % vals(1,prof) + &
469  self % RTprof_K % profiles_k(ichan+jchan-1) % s2m % v * geoval_d2 % vals(1,prof)
470  enddo
471  endif
472  end do
473 
474  !Tskin
475  call ufo_geovals_get_var(geovals, var_sfc_tskin, geoval_d)
476 
477  do ichan = 1, self % nchan_total, size(self%channels)
478  prof = self % RTprof_K % chanprof(ichan) % prof
479  if (.not. self % Skip_Profiles(prof)) then
480  do jchan = 1, size(self%channels)
481  hofx(jchan,prof) = hofx(jchan,prof) + &
482  self % RTprof_K % profiles_k(ichan+jchan-1) % skin % t * geoval_d % vals(1,prof)
483  enddo
484  endif
485  end do
486 
487  end subroutine ufo_radiancerttov_simobs_tl
488 
489  ! ------------------------------------------------------------------------------
490  subroutine ufo_radiancerttov_simobs_ad(self, geovals, obss, nvars, nlocs, hofx)
491 
492  use ufo_constants_mod, only : zero, g_to_kg
493 
494  implicit none
495 
496  class(ufo_radiancerttov_tlad), intent(in) :: self
497  type(ufo_geovals), intent(inout) :: geovals
498  type(c_ptr), value, intent(in) :: obss
499  integer, intent(in) :: nvars, nlocs
500  real(c_double), intent(in) :: hofx(nvars, nlocs)
501 
502  type(ufo_geoval), pointer :: geoval_d, geoval_d2
503 
504  real(c_double) :: missing
505  integer :: ichan, jchan, prof, jspec
506 
507  character(len=*), parameter :: myname_ = "ufo_radiancerttov_simobs_ad"
508 
509  ! Set missing value
510  missing = missing_value(missing)
511 
512  ! Initial checks
513  ! --------------
514 
515  ! Check if trajectory was set
516  if (.not. self % ltraj) then
517  write(message,*) myname_, ' trajectory wasnt set!'
518  call abor1_ftn(message)
519  end if
520 
521  ! Check if nlocs is consistent in geovals & hofx
522  if (geovals % nlocs /= self % nprofiles) then
523  write(message,*) myname_, ' error: nlocs inconsistent!'
524  call abor1_ftn(message)
525  end if
526 
527  ! Temperature
528  ! -----------
529  call ufo_geovals_get_var(geovals, var_ts, geoval_d) ! var_ts = air_temperature
530 
531  ! allocate if not yet allocated
532  if (.not. allocated(geoval_d % vals)) then
533  geoval_d % nlocs = self % nprofiles
534  geoval_d % nval = self % nlevels
535  allocate(geoval_d % vals(geoval_d % nval,geoval_d % nlocs))
536  geoval_d % vals = zero
537  end if
538 
539  do ichan = 1, self % nchan_total, size(self%channels)
540  prof = self % RTprof_K % chanprof(ichan) % prof
541  if (.not. self % Skip_Profiles(prof)) then
542  do jchan = 1, size(self%channels)
543  if (hofx(jchan, prof) /= missing) then
544  geoval_d % vals(:,prof) = geoval_d % vals(:,prof) + &
545  self % RTprof_K % profiles_k(ichan+jchan-1) % t(self % nlevels:1:-1) * hofx(jchan,prof)
546  endif
547  enddo
548  endif
549  end do
550 
551  ! Absorbers
552  ! ---------
553  ! This is where CO2 and friends will live as well as CLW
554 
555  do jspec = 1, self%conf%ngas
556  call ufo_geovals_get_var(geovals, self%conf%Absorbers(jspec), geoval_d)
557 
558  ! allocate if not yet allocated
559  if (.not. allocated(geoval_d % vals)) then
560  geoval_d % nlocs = self % nprofiles
561  geoval_d % nval = self % nlevels
562  allocate(geoval_d % vals(geoval_d % nval,geoval_d % nlocs))
563  geoval_d % vals = zero
564  end if
565 
566  do ichan = 1, self % nchan_total, size(self%channels)
567  prof = self % RTprof_K % chanprof(ichan) % prof
568  if (.not. self % Skip_Profiles(prof)) then
569  do jchan = 1, size(self%channels)
570  if (hofx(jchan, prof) /= missing) then
571 
572  if(self%conf%Absorbers(jspec) == var_q) then
573  geoval_d % vals(:,prof) = geoval_d % vals(:,prof) + &
574  self % RTprof_K % profiles_k(ichan+jchan-1) % q(self % nlevels:1:-1) * hofx(jchan,prof)
575  elseif(self%conf%Absorbers(jspec) == var_mixr) then
576  geoval_d % vals(:,prof) = geoval_d % vals(:,prof) + &
577  (self % RTprof_K % profiles_k(ichan+jchan-1) % q(self % nlevels:1:-1) / g_to_kg) * hofx(jchan,prof)
578  elseif(self%conf%Absorbers(jspec) == var_clw) then
579  geoval_d % vals(:,prof) = geoval_d % vals(:,prof) + &
580  self % RTprof_K % profiles_k(ichan+jchan-1) % clw(self % nlevels:1:-1) * hofx(jchan,prof)
581  endif
582  endif
583  enddo
584  endif
585  enddo
586  enddo
587 
588  ! Cloud
589  ! --------------------------
590  !IR
591 
592  ! Surface + Single-valued Variables
593  ! --------------------------
594  !CTP/cloudfrac
595  !O3total
596  !LWP
597  !T2m
598 
599  call ufo_geovals_get_var(geovals, var_sfc_t2m, geoval_d)
600 
601  ! allocate if not yet allocated
602  if (.not. allocated(geoval_d % vals)) then
603  geoval_d % nlocs = self % nprofiles
604  geoval_d % nval = self % nlevels
605  allocate(geoval_d % vals(geoval_d % nval,geoval_d % nlocs)) ! DARFIX try setting to 1?
606  geoval_d % vals = zero
607  end if
608 
609  do ichan = 1, self % nchan_total, size(self%channels)
610  prof = self % RTprof_K % chanprof(ichan) % prof
611  if (.not. self % Skip_Profiles(prof)) then
612  do jchan = 1, size(self%channels)
613  if (hofx(jchan, prof) /= missing) then
614  geoval_d % vals(1,prof) = geoval_d % vals(1,prof) + &
615  self % RTprof_K % profiles_k(ichan+jchan-1) % s2m % t * hofx(jchan,prof)
616  endif
617  enddo
618  endif
619  end do
620 
621  !q2m
622  call ufo_geovals_get_var(geovals, var_sfc_q2m, geoval_d)
623  ! allocate if not yet allocated
624  if (.not. allocated(geoval_d % vals)) then
625  geoval_d % nlocs = self % nprofiles
626  geoval_d % nval = self % nlevels
627  allocate(geoval_d % vals(geoval_d % nval,geoval_d % nlocs)) ! DARFIX try setting to 1?
628  geoval_d % vals = zero
629  end if
630 
631  do ichan = 1, self % nchan_total, size(self%channels)
632  prof = self % RTprof_K % chanprof(ichan) % prof
633  if (.not. self % Skip_Profiles(prof)) then
634  do jchan = 1, size(self%channels)
635  if (hofx(jchan, prof) /= missing) then
636  geoval_d % vals(1,prof) = geoval_d % vals(1,prof) + &
637  self % RTprof_K % profiles_k(ichan+jchan-1) % s2m % q * hofx(jchan,prof)
638  endif
639  enddo
640  endif
641  end do
642 
643  !windspeed
644  call ufo_geovals_get_var(geovals, var_u, geoval_d)
645  call ufo_geovals_get_var(geovals, var_v, geoval_d2)
646 
647  ! allocate if not yet allocated
648  if (.not. allocated(geoval_d % vals)) then
649  geoval_d % nlocs = self % nprofiles
650  geoval_d % nval = self % nlevels
651  geoval_d2 % nlocs = self % nprofiles
652  geoval_d2 % nval = self % nlevels
653  allocate(geoval_d % vals(geoval_d % nval,geoval_d % nlocs), &
654  geoval_d2 % vals(geoval_d % nval,geoval_d % nlocs)) ! DARFIX try setting to 1?
655  geoval_d % vals = zero
656  geoval_d2 % vals = zero
657  end if
658 
659  do ichan = 1, self % nchan_total, size(self%channels)
660  prof = self % RTprof_K % chanprof(ichan) % prof
661  if (.not. self % Skip_Profiles(prof)) then
662  do jchan = 1, size(self%channels)
663  if (hofx(jchan, prof) /= missing) then
664  geoval_d % vals(1,prof) = geoval_d % vals(1,prof) + &
665  self % RTprof_K % profiles_k(ichan+jchan-1) % s2m % u * hofx(jchan,prof)
666 
667  geoval_d2 % vals(1,prof) = geoval_d2 % vals(1,prof) + &
668  self % RTprof_K % profiles_k(ichan+jchan-1) % s2m % v * hofx(jchan,prof)
669  endif
670  enddo
671  endif
672  end do
673 
674  !Tskin
675  call ufo_geovals_get_var(geovals, var_sfc_tskin, geoval_d)
676 
677  ! allocate if not yet allocated
678  if (.not. allocated(geoval_d % vals)) then
679  geoval_d % nlocs = self % nprofiles
680  geoval_d % nval = self % nlevels
681  allocate(geoval_d % vals(geoval_d % nval,geoval_d % nlocs)) ! DARFIX try setting to 1?
682  geoval_d % vals = zero
683  end if
684 
685  do ichan = 1, self % nchan_total, size(self%channels)
686  prof = self % RTprof_K % chanprof(ichan) % prof
687  if (.not. self % Skip_Profiles(prof)) then
688  do jchan = 1, size(self%channels)
689  if (hofx(jchan, prof) /= missing) then
690  geoval_d % vals(1,prof) = geoval_d % vals(1,prof) + &
691  self % RTprof_K % profiles_k(ichan+jchan-1) % skin % t * hofx(jchan,prof)
692  endif
693  enddo
694  endif
695  end do
696 
697  ! Once all geovals set replace flag
698  ! ---------------------------------
699  if (.not. geovals % linit ) geovals % linit=.true.
700 
701  end subroutine ufo_radiancerttov_simobs_ad
702 
703  ! ------------------------------------------------------------------------------
704 
ufo_vars_mod::var_v
character(len=maxvarlen), parameter, public var_v
Definition: ufo_variables_mod.F90:24
ufo_radiancerttov_utils_mod::nchan_sim
integer, public nchan_sim
Definition: ufo_radiancerttov_utils_mod.F90:98
ufo_radiancerttov_tlad_mod::ufo_radiancerttov_tlad
Fortran derived type for radiancerttov trajectory.
Definition: ufo_radiancerttov_tlad_mod.F90:30
ufo_radiancerttov_utils_mod::load_atm_data_rttov
subroutine, public load_atm_data_rttov(geovals, obss, profiles, prof_start, conf, layer_quantities, obs_info)
Definition: ufo_radiancerttov_utils_mod.F90:318
ufo_radiancerttov_utils_mod::rttov_conf
Definition: ufo_radiancerttov_utils_mod.F90:126
ufo_radiancerttov_tlad_mod::ufo_radiancerttov_tlad_settraj
subroutine ufo_radiancerttov_tlad_settraj(self, geovals, obss, hofxdiags)
Definition: ufo_radiancerttov_tlad_mod.F90:134
ufo_radiancerttov_utils_mod::message
character(len=max_string), public message
Definition: ufo_radiancerttov_utils_mod.F90:45
ufo_constants_mod::g_to_kg
real(kind_real), parameter, public g_to_kg
Definition: ufo_constants_mod.F90:64
ufo_radiancerttov_utils_mod::load_geom_data_rttov
subroutine, public load_geom_data_rttov(obss, profiles, prof_start1, obs_info)
Definition: ufo_radiancerttov_utils_mod.F90:779
ufo_radiancerttov_tlad_mod::varin_default_tlad
character(len=maxvarlen), dimension(1), parameter varin_default_tlad
Definition: ufo_radiancerttov_tlad_mod.F90:53
ufo_radiancerttov_utils_mod::ufo_rttov_skip_profiles
subroutine, public ufo_rttov_skip_profiles(nprofiles, nchannels, channels, obss, Skip_Profiles)
Definition: ufo_radiancerttov_utils_mod.F90:1272
ufo_radiancerttov_tlad_mod::ufo_radiancerttov_simobs_ad
subroutine ufo_radiancerttov_simobs_ad(self, geovals, obss, nvars, nlocs, hofx)
Definition: ufo_radiancerttov_tlad_mod.F90:491
ufo_radiancerttov_tlad_mod::ufo_radiancerttov_tlad_setup
subroutine ufo_radiancerttov_tlad_setup(self, f_confOper, channels)
Definition: ufo_radiancerttov_tlad_mod.F90:60
ufo_radiancerttov_utils_mod::rttov_errorstatus
integer, public rttov_errorstatus
Definition: ufo_radiancerttov_utils_mod.F90:48
ufo_radiancerttov_utils_mod::rttov_conf_setup
subroutine, public rttov_conf_setup(conf, f_confOpts, f_confOper)
Definition: ufo_radiancerttov_utils_mod.F90:161
ufo_vars_mod::ufo_vars_getindex
integer function, public ufo_vars_getindex(vars, varname)
Definition: ufo_variables_mod.F90:204
ufo_vars_mod::var_mixr
character(len=maxvarlen), parameter, public var_mixr
Definition: ufo_variables_mod.F90:21
ufo_geovals_mod
Definition: ufo_geovals_mod.F90:7
ufo_radiancerttov_utils_mod
Fortran module to provide code shared between nonlinear and tlm/adm radiance calculations.
Definition: ufo_radiancerttov_utils_mod.F90:8
ufo_radiancerttov_utils_mod::ufo_rttov_io
Definition: ufo_radiancerttov_utils_mod.F90:104
ufo_radiancerttov_utils_mod::nchan_inst
integer, public nchan_inst
Definition: ufo_radiancerttov_utils_mod.F90:97
ufo_constants_mod
Definition: ufo_constants_mod.F90:2
ufo_vars_mod::var_u
character(len=maxvarlen), parameter, public var_u
Definition: ufo_variables_mod.F90:23
ufo_radiancerttov_tlad_mod
Fortran module for radiancerttov tl/ad observation operator.
Definition: ufo_radiancerttov_tlad_mod.F90:8
ufo_vars_mod::var_sfc_q2m
character(len=maxvarlen), parameter, public var_sfc_q2m
Definition: ufo_variables_mod.F90:48
ufo_radiancerttov_tlad_mod::ufo_radiancerttov_tlad_delete
subroutine ufo_radiancerttov_tlad_delete(self)
Definition: ufo_radiancerttov_tlad_mod.F90:118
ufo_vars_mod
Definition: ufo_variables_mod.F90:8
ufo_geovals_mod::ufo_geovals_get_var
subroutine, public ufo_geovals_get_var(self, varname, geoval)
Definition: ufo_geovals_mod.F90:128
ufo_vars_mod::var_q
character(len=maxvarlen), parameter, public var_q
Definition: ufo_variables_mod.F90:22
ufo_vars_mod::var_clw
character(len=maxvarlen), parameter, public var_clw
Definition: ufo_variables_mod.F90:34
ufo_vars_mod::var_sfc_t2m
character(len=maxvarlen), parameter, public var_sfc_t2m
Definition: ufo_variables_mod.F90:49
ufo_vars_mod::var_ts
character(len=maxvarlen), parameter, public var_ts
Definition: ufo_variables_mod.F90:19
ufo_radiancerttov_utils_mod::populate_hofxdiags
subroutine, public populate_hofxdiags(RTProf, chanprof, hofxdiags)
Definition: ufo_radiancerttov_utils_mod.F90:1547
ufo_vars_mod::var_sfc_tskin
character(len=maxvarlen), parameter, public var_sfc_tskin
Definition: ufo_variables_mod.F90:50
ufo_geovals_mod::ufo_geovals
type to hold interpolated fields required by the obs operators
Definition: ufo_geovals_mod.F90:47
ufo_radiancerttov_utils_mod::rttov_conf_delete
subroutine, public rttov_conf_delete(conf)
Definition: ufo_radiancerttov_utils_mod.F90:305
ufo_constants_mod::zero
real(kind_real), parameter, public zero
Definition: ufo_constants_mod.F90:24
ufo_geovals_mod::ufo_geoval
type to hold interpolated field for one variable, one observation
Definition: ufo_geovals_mod.F90:40
conf
Definition: conf.py:1
ufo_radiancerttov_utils_mod::parse_hofxdiags
subroutine, public parse_hofxdiags(hofxdiags, jacobian_needed)
Definition: ufo_radiancerttov_utils_mod.F90:1726
ufo_radiancerttov_tlad_mod::ufo_radiancerttov_simobs_tl
subroutine ufo_radiancerttov_simobs_tl(self, geovals, obss, nvars, nlocs, hofx)
Definition: ufo_radiancerttov_tlad_mod.F90:334