10 use fckit_configuration_module,
only: fckit_configuration
11 use fckit_log_module,
only : fckit_log
14 use missing_values_mod
23 use rttov_const,
only : errorstatus_success
32 character(len=MAXVARLEN),
public,
allocatable :: varin(:)
33 integer,
allocatable :: channels(:)
39 integer :: nchan_total
43 logical,
allocatable :: skip_profiles(:)
63 type(fckit_configuration),
intent(in) :: f_confOper
64 integer(c_int),
intent(in) :: channels(:)
66 type(fckit_configuration) :: f_confOpts
67 type(fckit_configuration) :: f_confLinOper
71 call f_confoper % get_or_die(
"obs options",f_confopts)
75 if ( f_confoper%has(
"linear obs operator") )
then
76 call f_confoper%get_or_die(
"linear obs operator",f_conflinoper)
85 write(
message,*)
'ufo_radiancerttov_setup error: H2O must be included in RTTOV Absorbers'
91 allocate(self%varin(nvars_in))
95 do jspec = 1, self%conf%ngas
96 self%varin(ind) = self%conf%Absorbers(jspec)
106 self%varin(ind) =
var_u
108 self%varin(ind) =
var_v
111 allocate(self%channels(
size(channels)))
112 self%channels(:) = channels(:)
121 integer(kind=jpim) :: errorstatus
123 self % ltraj = .false.
128 if (
allocated(self%Skip_Profiles))
deallocate(self%Skip_Profiles)
135 use fckit_mpi_module,
only: fckit_mpi_comm
141 type(c_ptr),
value,
intent(in) :: obss
144 type(fckit_mpi_comm) :: f_comm
147 character(*),
parameter :: ROUTINE_NAME =
'ufo_radiancerttov_tlad_settraj'
150 integer(kind=jpim) :: errorstatus
152 integer :: nchan_max_sim, nchan_count, nchan_total
153 integer :: nprof_sim, nprof_max_sim
155 integer :: iprof, ichan, i_inst
156 integer :: prof_start, prof_end
158 logical :: layer_quantities
159 logical :: jacobian_needed
161 include
'rttov_k.interface'
162 include
'rttov_print_profile.interface'
163 include
'rttov_user_profile_checkinput.interface'
166 call obsspace_get_comm(obss, f_comm)
170 self % nprofiles = geovals % nlocs
173 self % nlevels = temp % nval
174 layer_quantities = .false.
193 sensor_loop:
do i_inst = 1, self % conf % nSensors
196 call rttov_user_options_checkinput(errorstatus, self % conf % rttov_opts, &
197 self % conf % rttov_coef_array(i_inst))
199 if (errorstatus /= errorstatus_success)
then
200 write(
message,
'(A, A,I6)') trim(routine_name),
'after rttov_user_options_checkinput: error = ',&
206 allocate(self % Skip_Profiles(self % nprofiles))
214 nprof_sim = min(nprof_max_sim, self % nprofiles)
217 prof_end = self % nprofiles
220 nprof_sim = min(nprof_sim, prof_end - prof_start + 1)
221 nchan_sim = nprof_sim *
size(self%channels)
227 call self % RTprof_K % alloc(errorstatus, self % conf, nprof_sim,
nchan_sim, self % nlevels, init=.true., asw=2)
229 do while ( prof_start <= prof_end)
236 nprof_sim = min(nprof_sim, prof_end - prof_start + 1)
238 do iprof = 1, min(nprof_sim, prof_end - prof_start + 1)
239 if(.not. self % Skip_Profiles(prof_start + iprof - 1))
then
243 self % RTProf_K % chanprof(nchan_total +
nchan_sim) % prof = iprof
244 self % RTprof_K % chanprof(nchan_total +
nchan_sim) % chan = self % channels(ichan)
252 call load_atm_data_rttov(geovals,obss,self % RTprof_K % profiles,prof_start,self % conf,layer_quantities)
258 call self % RTProf_K % init_emissivity(self % conf)
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
269 if(self % conf % RTTOV_profile_checkinput)
then
270 if (self % conf % inspect > 0)
then
272 call rttov_print_profile(self % RTprof_K % profiles(self % conf % inspect))
275 self % conf % rttov_opts, &
276 self % conf % rttov_coef_array(i_inst), &
277 self % RTprof_K % profiles(self % conf % inspect))
287 self % RTprof_K % chanprof(nchan_total + 1:nchan_total +
nchan_sim), &
288 self % conf % rttov_opts, &
289 self % RTprof_K % profiles, &
290 self % RTprof_K % profiles_k(nchan_total + 1 : nchan_total +
nchan_sim), &
291 self % conf % rttov_coef_array(i_inst), &
292 self % RTprof_K % transmission, &
293 self % RTprof_K % transmission_k, &
294 self % RTprof_K % radiance, &
295 self % RTprof_K % radiance_k, &
296 calcemis = self % RTprof_K % calcemis, &
297 emissivity = self % RTprof_K % emissivity, &
298 emissivity_k = self % RTprof_K % emissivity_k)
300 if (self % conf % inspect > 0)
then
302 call rttov_print_profile(self % RTprof_K % profiles_k(self % conf % inspect))
305 if ( errorstatus /= errorstatus_success )
then
306 write(
message,
'(A, A, 2I6)') trim(routine_name),
'after rttov_k: error ', errorstatus, i_inst
310 write(*,
'(A1, i0, A, i0)',advance=
"NO") achar(13), prof_start+nprof_sim-1,
' locations processed out of ', geovals%nlocs
314 if(hofxdiags%nvar > 0)
call populate_hofxdiags(self % RTprof_K, self % RTprof_K % chanprof, hofxdiags)
316 prof_start = prof_start + nprof_sim
319 self % nchan_total = nchan_total
328 self % ltraj = .true.
341 type(c_ptr),
value,
intent(in) :: obss
342 integer,
intent(in) :: nvars, nlocs
343 real(c_double),
intent(inout) :: hofx(nvars, nlocs)
345 character(len=*),
parameter :: myname_=
"ufo_radiancerttov_simobs_tl"
346 integer :: ichan, jchan, prof, jspec
348 type(
ufo_geoval),
pointer :: geoval_d, geoval_d2
354 if (.not. self % ltraj)
then
355 write(
message,*) myname_,
' trajectory wasnt set!'
360 if (geovals % nlocs /= self % nprofiles)
then
361 write(
message,*) myname_,
' error: nlocs inconsistent!'
374 if (geoval_d % nval /= self % nlevels)
then
375 write(
message,*) myname_,
' error: layers inconsistent!'
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))
390 do jspec = 1, self%conf%ngas
394 if (geoval_d % nval /= self % nlevels)
then
395 write(
message,*) myname_,
' error: layers inconsistent!'
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)) / &
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))
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)
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)
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)
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)
498 type(c_ptr),
value,
intent(in) :: obss
499 integer,
intent(in) :: nvars, nlocs
500 real(c_double),
intent(in) :: hofx(nvars, nlocs)
502 type(
ufo_geoval),
pointer :: geoval_d, geoval_d2
504 real(c_double) :: missing
505 integer :: ichan, jchan, prof, jspec
507 character(len=*),
parameter :: myname_ =
"ufo_radiancerttov_simobs_ad"
510 missing = missing_value(missing)
516 if (.not. self % ltraj)
then
517 write(
message,*) myname_,
' trajectory wasnt set!'
522 if (geovals % nlocs /= self % nprofiles)
then
523 write(
message,*) myname_,
' error: nlocs inconsistent!'
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
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)
555 do jspec = 1, self%conf%ngas
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
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
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)
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))
606 geoval_d % vals =
zero
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)
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))
628 geoval_d % vals =
zero
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)
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))
655 geoval_d % vals =
zero
656 geoval_d2 % vals =
zero
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)
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)
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))
682 geoval_d % vals =
zero
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)
699 if (.not. geovals % linit ) geovals % linit=.true.