10 use fckit_configuration_module,
only: fckit_configuration
11 use fckit_log_module,
only : fckit_log
14 use missing_values_mod
15 use,
intrinsic :: iso_fortran_env, only : stderr=>error_unit, &
18 use rttov_types,
only : rttov_options, rttov_profile, rttov_coefs, &
19 rttov_radiance, rttov_transmission, rttov_emissivity, &
46 character(len=max_string),
public ::
message
79 character(len=*),
parameter :: &
81 [gas_name(1:ngases_max),
'CLW', &
84 integer,
parameter :: &
96 real(kind_real),
parameter :: &
109 character(len=MAXVARLEN),
parameter ::
null_str =
''
112 character(len=MAXVARLEN),
parameter :: &
115 'mole_fraction_of_carbon_monoxide_in_air',
'mole_fraction_of_methane_in_air', &
127 logical,
pointer :: calcemis(:)
128 type(rttov_emissivity),
pointer :: emissivity(:)
129 type(rttov_profile),
allocatable :: profiles(:)
130 type(rttov_profile),
allocatable :: profiles_k(:)
131 type(rttov_chanprof),
pointer :: chanprof(:)
132 type(rttov_transmission) :: transmission
133 type(rttov_radiance) :: radiance
135 type(rttov_emissivity),
pointer :: emissivity_k(:)
136 type(rttov_transmission) :: transmission_k
137 type(rttov_radiance) :: radiance_k
158 character(len=MAXVARLEN),
allocatable :: absorbers(:)
159 integer,
allocatable :: absorber_id(:)
160 real(kind_real) :: scale_fac(0:ngases_max)
161 logical :: rttov_gasunitconv
163 character(len=255),
allocatable :: sensor_id(:)
164 character(len=255) :: coefficient_path
166 type(rttov_coefs),
allocatable :: rttov_coef_array(:)
167 character(len=10) :: rttov_default_opts =
'RTTOV'
168 type(rttov_options) :: rttov_opts
169 logical :: rttov_is_setup = .false.
171 logical :: satrad_compatibility = .true.
172 logical :: userhwaterforqc = .true.
173 logical :: usecoldsurfacecheck = .false.
174 logical :: splitqtotal = .false.
175 logical :: useqtsplitrain = .false.
176 logical :: rttov_profile_checkinput = .false.
178 logical :: prof_by_prof = .true.
180 integer,
allocatable :: inspect(:)
181 integer :: nchan_max_sim
199 type(fckit_configuration),
intent(in) :: f_confopts
200 type(fckit_configuration),
intent(in) :: f_confoper
202 character(*),
parameter :: routine_name =
'rttov_conf_setup'
203 integer :: ivar, jspec
204 character(len=:),
allocatable :: str
205 character(len=:),
allocatable :: str_array(:)
206 logical :: varin_satrad = .false.
208 integer :: i,k,n, i_inst
210 include
'rttov_user_options_checkinput.interface'
216 if (f_confoper%has(
"Debug"))
then
217 call f_confoper % get_or_die(
"Debug",
debug)
222 if (f_confoper%has(
"GeoVal_type"))
then
223 call f_confoper%get_or_die(
"GeoVal_type",str)
226 varin_satrad = .true.
229 varin_satrad = .false.
231 write(
message,*) trim(routine_name),
' error: ',trim(str),
' is not a supported GeoVal type'
241 if (f_confoper%has(
"Absorbers")) &
242 conf%ngas = conf%ngas + f_confoper%get_size(
"Absorbers")
244 allocate(conf%Absorbers( conf%ngas ), &
245 conf%Absorber_Id( conf%ngas ))
247 if (conf%ngas > 0)
then
248 call f_confoper%get_or_die(
"Absorbers",str_array)
249 conf%Absorbers(1:conf%ngas) = str_array
254 do jspec = 2, conf%ngas
255 if ( any(conf%Absorbers(jspec-1) == conf%Absorbers(jspec:conf%ngas)) )
then
256 write(
message,*) trim(routine_name),
' error: ',trim(conf%Absorbers(jspec)),
' is duplicated in Absorbers'
262 do jspec = 1, conf%ngas
266 write(
message,*) trim(routine_name),
' error: ',trim(conf%Absorbers(jspec)),
' not supported by UFO_Absorbers'
274 if(conf%Absorbers(jspec) ==
var_mixr .and. varin_satrad)
then
275 conf%Absorbers(jspec) =
var_q
280 if(f_confopts % has(
"RTTOV_GasUnitConv"))
then
281 call f_confopts % get_or_die(
"RTTOV_GasUnitConv",conf % RTTOV_GasUnitConv)
283 conf % RTTOV_GasUnitConv = .false.
287 if(conf%RTTOV_GasUnitConv)
then
294 allocate(conf % SENSOR_ID(conf % nSensors))
297 call f_confopts % get_or_die(
"Sensor_ID",str)
298 conf % SENSOR_ID(conf%nSensors) = str
301 call f_confopts % get_or_die(
"CoefficientPath",str)
302 conf % COEFFICIENT_PATH = str
304 if(f_confopts % has(
"RTTOV_default_opts"))
then
305 call f_confopts % get_or_die(
"RTTOV_default_opts",str)
306 conf % RTTOV_default_opts = str
309 if(f_confopts % has(
"SatRad_compatibility"))
then
310 call f_confopts % get_or_die(
"SatRad_compatibility",conf % SatRad_compatibility)
313 if(f_confopts % has(
"UseRHwaterForQC"))
then
314 call f_confopts % get_or_die(
"UseRHwaterForQC",conf % UseRHwaterForQC)
317 if(f_confopts % has(
"UseColdSurfaceCheck"))
then
318 call f_confopts % get_or_die(
"UseColdSurfaceCheck",conf % UseColdSurfaceCheck)
321 if(f_confopts % has(
"prof_by_prof"))
then
322 call f_confopts % get_or_die(
"prof_by_prof",conf % prof_by_prof)
324 conf % prof_by_prof = .false.
327 if(f_confopts % has(
"max_channels_per_batch"))
then
328 call f_confopts % get_or_die(
"max_channels_per_batch",conf % nchan_max_sim)
330 conf % nchan_max_sim = 10000
333 if( .not. conf % rttov_is_setup)
then
334 call conf % setup(f_confopts)
338 if (conf % rttov_coef_array(1) % coef % id_sensor == sensor_id_mw)
then
339 if(conf % rttov_opts % rt_mw % clw_data .and. &
340 conf % SatRad_compatibility)
then
341 conf % SplitQtotal = .true.
342 conf % UseQtsplitRain = .true.
345 conf % rttov_opts % rt_ir % ozone_data = .false.
346 conf % rttov_opts % rt_ir % co2_data = .false.
347 conf % rttov_opts % rt_ir % n2o_data = .false.
348 conf % rttov_opts % rt_ir % ch4_data = .false.
349 conf % rttov_opts % rt_ir % so2_data = .false.
353 do i_inst = 1,
SIZE(conf % rttov_coef_array(:))
354 call rttov_user_options_checkinput(
rttov_errorstatus, conf % rttov_opts, conf % rttov_coef_array(i_inst))
357 write(
message,
'(A, A, I6, I6)') trim(routine_name),
': Error in rttov_user_options_checkinput: ',
rttov_errorstatus, i_inst
363 if(f_confopts % has(
"QtSplitRain"))
then
364 call f_confopts % get_or_die(
"QtSplitRain", conf % UseQtsplitRain)
367 if(f_confopts % has(
"RTTOV_profile_checkinput"))
then
368 call f_confopts % get_or_die(
"RTTOV_profile_checkinput",conf % RTTOV_profile_checkinput)
371 if (f_confopts%has(
"InspectProfileNumber"))
then
372 call f_confopts % get_or_die(
"InspectProfileNumber",str)
376 i = index(str(k:),
',')
382 allocate(conf % inspect(n+1))
383 read(str, *) conf % inspect
385 allocate(conf % inspect(0))
399 include
'rttov_dealloc_coefs.interface'
401 do i = 1,
size(conf % rttov_coef_array)
404 deallocate(conf % rttov_coef_array)
405 conf%rttov_is_setup =.false.
407 deallocate(conf%SENSOR_ID)
408 deallocate(conf%Absorbers)
409 deallocate(conf%Absorber_Id)
427 type(fckit_configuration),
intent(in) :: f_confOpts
429 include
'rttov_print_opts.interface'
431 call self % set_defaults(self%RTTOV_default_opts)
434 if (f_confopts % has(
"RTTOV_addrefrac"))
then
435 call f_confopts % get_or_die(
"RTTOV_addrefrac", self % rttov_opts % rt_all % addrefrac)
439 if (f_confopts % has(
"RTTOV_switchrad"))
then
440 call f_confopts % get_or_die(
"RTTOV_switchrad", self % rttov_opts % rt_all % switchrad)
444 if (f_confopts % has(
"RTTOV_use_q2m"))
then
445 call f_confopts % get_or_die(
"RTTOV_use_q2m", self % rttov_opts % rt_all % use_q2m)
449 if (f_confopts % has(
"RTTOV_do_lambertian"))
then
450 call f_confopts % get_or_die(
"RTTOV_do_lambertian", self % rttov_opts % rt_all % do_lambertian)
454 if (f_confopts % has(
"RTTOV_lambertian_fixed_angle"))
then
455 call f_confopts % get_or_die(
"RTTOV_lambertian_fixed_angle", self % rttov_opts % rt_all % lambertian_fixed_angle)
459 if (f_confopts % has(
"RTTOV_plane_parallel"))
then
460 call f_confopts % get_or_die(
"RTTOV_plane_parallel", self % rttov_opts % rt_all % plane_parallel)
464 if (f_confopts % has(
"RTTOV_rad_down_lin_tau"))
then
465 call f_confopts % get_or_die(
"RTTOV_rad_down_lin_tau", self % rttov_opts % rt_all % rad_down_lin_tau)
469 if (f_confopts % has(
"RTTOV_dtau_test"))
then
470 call f_confopts % get_or_die(
"RTTOV_dtau_test", self % rttov_opts % rt_all % dtau_test)
474 if (f_confopts % has(
"RTTOV_fastem_version"))
then
475 call f_confopts % get_or_die(
"RTTOV_fastem_version", self % rttov_opts % rt_mw % fastem_version)
479 if (f_confopts % has(
"RTTOV_supply_foam_fraction"))
then
480 call f_confopts % get_or_die(
"RTTOV_supply_foam_fraction", self % rttov_opts % rt_mw % supply_foam_fraction)
484 if (f_confopts % has(
"RTTOV_clw_data"))
then
485 call f_confopts % get_or_die(
"RTTOV_clw_data", self % rttov_opts % rt_mw % clw_data)
489 if (f_confopts % has(
"RTTOV_clw_scheme"))
then
490 call f_confopts % get_or_die(
"RTTOV_clw_scheme", self % rttov_opts % rt_mw % clw_scheme)
494 if (f_confopts % has(
"RTTOV_clw_calc_on_coef_lev"))
then
495 call f_confopts % get_or_die(
"RTTOV_clw_calc_on_coef_lev", self % rttov_opts % rt_mw % clw_calc_on_coef_lev)
499 if (f_confopts % has(
"RTTOV_clw_cloud_top"))
then
500 call f_confopts % get_or_die(
"RTTOV_clw_cloud_top", self % rttov_opts % rt_mw % clw_cloud_top)
504 if (f_confopts % has(
"RTTOV_apply_band_correction"))
then
505 call f_confopts % get_or_die(
"RTTOV_apply_band_correction", self % rttov_opts % rt_mw % apply_band_correction)
509 if (f_confopts % has(
"RTTOV_addinterp"))
then
510 call f_confopts % get_or_die(
"RTTOV_addinterp", self % rttov_opts % interpolation % addinterp)
514 if (f_confopts % has(
"RTTOV_interp_mode"))
then
515 call f_confopts % get_or_die(
"RTTOV_interp_mode", self % rttov_opts % interpolation % interp_mode)
519 if (f_confopts % has(
"RTTOV_lgradp"))
then
520 call f_confopts % get_or_die(
"RTTOV_lgradp", self % rttov_opts % interpolation % lgradp)
524 if (f_confopts % has(
"RTTOV_spacetop"))
then
525 call f_confopts % get_or_die(
"RTTOV_spacetop", self % rttov_opts % interpolation % spacetop)
529 if (f_confopts % has(
"RTTOV_reg_limit_extrap"))
then
530 call f_confopts % get_or_die(
"RTTOV_reg_limit_extrap", self % rttov_opts % interpolation % reg_limit_extrap)
533 if (f_confopts % has(
"RTTOV_fix_hgpl"))
then
534 call f_confopts % get_or_die(
"RTTOV_fix_hgpl", self % rttov_opts % config % fix_hgpl)
537 if (f_confopts % has(
"RTTOV_verbose"))
then
538 call f_confopts % get_or_die(
"RTTOV_verbose", self % rttov_opts % config % verbose)
541 if (f_confopts % has(
"RTTOV_do_checkinput"))
then
542 call f_confopts % get_or_die(
"RTTOV_do_checkinput", self % rttov_opts % config % do_checkinput)
545 if (f_confopts % has(
"RTTOV_apply_reg_limits"))
then
546 call f_confopts % get_or_die(
"RTTOV_apply_reg_limits", self % rttov_opts % config % apply_reg_limits)
550 if (f_confopts % has(
"RTTOV_solar_sea_brdf_model"))
then
551 call f_confopts % get_or_die(
"RTTOV_solar_sea_brdf_model", self % rttov_opts % rt_ir % solar_sea_brdf_model)
555 if (f_confopts % has(
"RTTOV_ir_sea_emis_model"))
then
556 call f_confopts % get_or_die(
"RTTOV_ir_sea_emis_model", self % rttov_opts % rt_ir % ir_sea_emis_model)
560 if (f_confopts % has(
"RTTOV_addsolar"))
then
561 call f_confopts % get_or_die(
"RTTOV_addsolar", self % rttov_opts % rt_ir % addsolar)
565 if (f_confopts % has(
"RTTOV_rayleigh_single_scatt"))
then
566 call f_confopts % get_or_die(
"RTTOV_rayleigh_single_scatt", self % rttov_opts % rt_ir % rayleigh_single_scatt)
570 if (f_confopts % has(
"RTTOV_do_nlte_correction"))
then
571 call f_confopts % get_or_die(
"RTTOV_do_nlte_correction", self % rttov_opts % rt_ir % do_nlte_correction)
575 if (f_confopts % has(
"RTTOV_addaerosl"))
then
576 call f_confopts % get_or_die(
"RTTOV_addaerosl", self % rttov_opts % rt_ir % addaerosl)
580 if (f_confopts % has(
"RTTOV_user_aer_opt_param"))
then
581 call f_confopts % get_or_die(
"RTTOV_user_aer_opt_param", self % rttov_opts % rt_ir % user_aer_opt_param)
585 if (f_confopts % has(
"RTTOV_addclouds"))
then
586 call f_confopts % get_or_die(
"RTTOV_addclouds", self % rttov_opts % rt_ir % addclouds)
590 if (f_confopts % has(
"RTTOV_user_cld_opt_param"))
then
591 call f_confopts % get_or_die(
"RTTOV_user_cld_opt_param", self % rttov_opts % rt_ir % user_cld_opt_param)
595 if (f_confopts % has(
"RTTOV_grid_box_avg_cloud"))
then
596 call f_confopts % get_or_die(
"RTTOV_grid_box_avg_cloud", self % rttov_opts % rt_ir % grid_box_avg_cloud)
601 if (f_confopts % has(
"RTTOV_cldstr_threshold"))
then
602 call f_confopts % get_or_die(
"RTTOV_cldstr_threshold", self % rttov_opts % rt_ir % cldstr_threshold)
606 if (f_confopts % has(
"RTTOV_cldstr_simple"))
then
607 call f_confopts % get_or_die(
"RTTOV_cldstr_simple", self % rttov_opts % rt_ir % cldstr_simple)
611 if (f_confopts % has(
"RTTOV_cldstr_low_cloud_top"))
then
612 call f_confopts % get_or_die(
"RTTOV_cldstr_low_cloud_top", self % rttov_opts % rt_ir % cldstr_low_cloud_top)
616 if (f_confopts % has(
"RTTOV_ir_scatt_model"))
then
617 call f_confopts % get_or_die(
"RTTOV_ir_scatt_model", self % rttov_opts % rt_ir % ir_scatt_model)
621 if (f_confopts % has(
"RTTOV_vis_scatt_model"))
then
622 call f_confopts % get_or_die(
"RTTOV_vis_scatt_model", self % rttov_opts % rt_ir % vis_scatt_model)
626 if (f_confopts % has(
"RTTOV_dom_nstreams"))
then
627 call f_confopts % get_or_die(
"RTTOV_dom_nstreams", self % rttov_opts % rt_ir % dom_nstreams)
631 if (f_confopts % has(
"RTTOV_dom_accuracy"))
then
632 call f_confopts % get_or_die(
"RTTOV_dom_accuracy", self % rttov_opts % rt_ir % dom_accuracy)
636 if (f_confopts % has(
"RTTOV_dom_opdep_threshold"))
then
637 call f_confopts % get_or_die(
"RTTOV_dom_opdep_threshold", self % rttov_opts % rt_ir % dom_opdep_threshold)
641 if (f_confopts % has(
"RTTOV_ozone_data"))
then
642 call f_confopts % get_or_die(
"RTTOV_ozone_data", self % rttov_opts % rt_ir % ozone_data)
645 if (f_confopts % has(
"RTTOV_co2_data"))
then
646 call f_confopts % get_or_die(
"RTTOV_co2_data", self % rttov_opts % rt_ir % co2_data)
650 if (f_confopts % has(
"RTTOV_n2o_data"))
then
651 call f_confopts % get_or_die(
"RTTOV_n2o_data", self % rttov_opts % rt_ir % n2o_data)
655 if (f_confopts % has(
"RTTOV_co_data"))
then
656 call f_confopts % get_or_die(
"RTTOV_co_data", self % rttov_opts % rt_ir % co_data)
660 if (f_confopts % has(
"RTTOV_ch4_data"))
then
661 call f_confopts % get_or_die(
"RTTOV_ch4_data", self % rttov_opts % rt_ir % ch4_data)
665 if (f_confopts % has(
"RTTOV_so2_data"))
then
666 call f_confopts % get_or_die(
"RTTOV_so2_data", self % rttov_opts % rt_ir % so2_data)
669 call rttov_print_opts(self % rttov_opts,lu = stderr)
676 type(fckit_configuration),
intent(in) :: f_confOpts
678 character(len=255) :: coef_filename
679 character(len=4) :: coef_ext
682 include
'rttov_read_coefs.interface'
685 if (.not. self%rttov_is_setup )
then
690 call self % set_options(f_confopts)
695 allocate(self % rttov_coef_array(self % nSensors))
697 do i_inst = 1, self%nSensors
699 trim(self % COEFFICIENT_PATH) //
'rtcoef_' // trim(self%SENSOR_ID(i_inst)) // trim(coef_ext)
702 self % rttov_coef_array(i_inst), &
704 file_coef = coef_filename)
707 write(
message,*)
'fatal error reading coefficients'
710 write(
message,*)
'successfully read' // coef_filename
716 self % rttov_is_setup =.true.
724 integer,
intent(in) :: n
725 character(len=*),
intent(out) :: varname
727 character(len=6) :: chan
729 write(chan,
'(I0)') n
730 varname =
'brightness_temperature_' // trim(chan)
745 type(c_ptr),
value,
intent(in) :: obss
750 type(rttov_profile),
pointer :: profiles(:)
757 character(MAXVARLEN) :: varname
759 real(kind_real) :: ifrac, sfrac, lfrac, wfrac
760 real(kind_real) :: itmp, stmp, ltmp
761 real(kind_real) :: s2m_t(1), s2m_p(1)
763 real(kind_real),
allocatable :: TmpVar(:), windsp(:), p(:)
764 logical :: variable_present
766 integer :: top_level, bottom_level, stride
767 real(kind_real) :: NewT
768 integer :: level_1000hPa, level_950hpa
770 real(kind_real),
allocatable :: q_temp(:), clw_temp(:), ciw_temp(:), Qtotal(:), qsaturated(:)
772 real(kind_real) :: scale_fac
774 profiles => self % profiles
778 if(
present(ob_info))
then
784 nprofiles = min(
size(profiles), geovals%nlocs)
786 nlevels =
size(profiles(1)%p)
790 bottom_level = nlevels
797 do iprof = 1, nprofiles
798 p = geoval%vals(geoval%nval-nlevels+1:geoval%nval,
iprof) *
pa_to_hpa
800 if (p(1) > p(2))
then
806 profiles(
iprof)%p(top_level:bottom_level:stride) = p(:)
848 do iprof = 1, nprofiles
849 profiles(
iprof)%t(top_level:bottom_level:stride) = geoval%vals(:,
iprof)
853 if (conf % RTTOV_GasUnitConv)
then
856 profiles(1:nprofiles)%gas_units = gas_unit_ppmvdry
859 profiles(1:nprofiles)%gas_units = gas_unit_specconc
862 do jspec = 1, conf%ngas
864 scale_fac = conf%scale_fac(conf%absorber_id(jspec))
868 select case (conf%Absorbers(jspec))
870 do iprof = 1, nprofiles
871 profiles(
iprof)%q(top_level:bottom_level:stride) = geoval%vals(:,
iprof) * scale_fac *
g_to_kg
874 do iprof = 1, nprofiles
875 profiles(
iprof)%q(top_level:bottom_level:stride) = geoval%vals(:,
iprof) * scale_fac
878 if (
associated(profiles(1)%o3))
then
879 do iprof = 1, nprofiles
880 profiles(
iprof)%o3(top_level:bottom_level:stride) = geoval%vals(:,
iprof) * scale_fac
884 if (
associated(profiles(1)%co2))
then
885 do iprof = 1, nprofiles
886 profiles(
iprof)%co2(top_level:bottom_level:stride) = geoval%vals(:,
iprof) * scale_fac
890 if (
associated(profiles(1)%clw))
then
891 do iprof = 1, nprofiles
892 profiles(
iprof)%clw(top_level:bottom_level:stride) = geoval%vals(:,
iprof)
907 profiles(1:nprofiles)%s2m%p = geoval%vals(1,:) *
pa_to_hpa
909 write(
message,
'(A)')
'No near-surface pressure. Using bottom pressure level'
912 do iprof = 1, nprofiles
913 profiles(
iprof)%s2m%p = profiles(
iprof)%p(nlevels)
920 profiles(1:nprofiles)%s2m%t = geoval%vals(1,1:nprofiles)
922 write(
message,
'(A)')
'No near-surface temperature. Using bottom temperature level'
924 do iprof = 1, nprofiles
925 profiles(
iprof)%s2m%t = profiles(
iprof)%t(nlevels)
933 profiles(1:nprofiles)%s2m%q = geoval%vals(1,1:nprofiles) * conf%scale_fac(gas_id_watervapour)
935 write(
message,
'(A)')
'No near-surface specific humidity. Using bottom q level'
938 do iprof = 1, nprofiles
939 profiles(
iprof)%s2m%q = profiles(
iprof)%q(nlevels)
947 profiles(1:nprofiles)%s2m%u = geoval%vals(1,1:nprofiles)
953 profiles(1:nprofiles)%s2m%v = geoval%vals(1,1:nprofiles)
955 allocate(windsp(nprofiles))
958 windsp(1:nprofiles) = geoval%vals(1,1:nprofiles)
962 do iprof = 1, nprofiles
972 profiles(1:nprofiles) % skin % watertype = watertype_ocean_water
977 profiles(1:nprofiles)%skin%t = geoval%vals(1,1:nprofiles)
980 profiles(1:nprofiles) % s2m % wfetc = 100000.0_kind_real
984 profiles(1:nprofiles)%skin%salinity = 35.0_kind_real
987 do iprof = 1,nprofiles
989 profiles(
iprof)%skin%fastem = [0,0,0,0,0]
996 if(conf % SatRad_compatibility)
then
997 do iprof = 1, nprofiles
1003 if(profiles(
iprof)%skin%surftype /= surftype_sea .and. &
1004 conf % UseColdSurfaceCheck)
then
1005 if(profiles(
iprof)%skin%t < 271.4_kind_real .and. &
1006 profiles(
iprof)%s2m%p > 950.0_kind_real)
then
1008 level_1000hpa = minloc(abs(profiles(
iprof)%p - 1000.0_kind_real),dim=1)
1009 level_950hpa = minloc(abs(profiles(
iprof)%p - 950.0_kind_real),dim=1)
1011 newt = profiles(
iprof)%t(level_950hpa)
1012 if(profiles(
iprof)%s2m%p > 1000.0_kind_real) &
1013 newt = max(newt,profiles(
iprof)%t(level_1000hpa))
1014 newt = min(newt, 271.4_kind_real)
1016 profiles(
iprof)%t(level_1000hpa) = max(profiles(
iprof)%t(level_1000hpa), newt)
1017 profiles(
iprof)%s2m%t = max(profiles(
iprof)%s2m%t, newt)
1018 profiles(
iprof)%skin%t = max(profiles(
iprof)%skin%t, newt)
1025 allocate(qsaturated(nlevels))
1026 if (conf % UseRHwaterForQC)
then
1028 profiles(
iprof) % t(:), &
1033 profiles(
iprof) % t(:), &
1038 qsaturated = qsaturated * conf%scale_fac(gas_id_watervapour)
1041 where (profiles(
iprof)%q > qsaturated)
1042 profiles(
iprof)%q = qsaturated
1044 deallocate(qsaturated)
1049 allocate(qsaturated(1))
1050 s2m_t(1) = profiles(
iprof)%s2m%t
1052 if (conf % UseRHwaterForQC)
then
1064 qsaturated(1) = qsaturated(1) * conf%scale_fac(gas_id_watervapour)
1066 if (profiles(
iprof)%s2m%q > qsaturated(1)) profiles(
iprof)%s2m%q = qsaturated(1)
1067 deallocate(qsaturated)
1070 where(profiles(
iprof)%q <
min_q * conf%scale_fac(gas_id_watervapour) ) profiles(
iprof)%q =
min_q * conf%scale_fac(gas_id_watervapour)
1071 if(profiles(
iprof)%s2m%q <
min_q * conf%scale_fac(gas_id_watervapour)) profiles(
iprof)%s2m%q =
min_q * conf%scale_fac(gas_id_watervapour)
1077 if(conf % SplitQtotal)
then
1078 allocate(qtotal(nlevels), q_temp(nlevels), clw_temp(nlevels), ciw_temp(nlevels))
1079 do iprof = 1, nprofiles
1083 qtotal(:) = profiles(
iprof) % q(:) / conf%scale_fac(gas_id_watervapour)
1084 qtotal(:) = max(qtotal(:),
min_q)
1085 qtotal(:) = qtotal(:) + profiles(
iprof) % clw(:)
1090 profiles(
iprof) % t(:), &
1095 useqtsplitrain = conf % UseQtSplitRain)
1098 profiles(
iprof) % clw(:) = clw_temp(:)
1099 profiles(
iprof) % q(:) = q_temp(:) * conf%scale_fac(gas_id_watervapour)
1109 deallocate(qtotal, q_temp, clw_temp, ciw_temp)
1115 if(
present(ob_info))
then
1117 profiles(1) % elevation = ob_info % elevation / 1000.0
1118 profiles(1) % latitude = ob_info % latitude
1119 profiles(1) % longitude = ob_info % longitude
1120 if (ob_info % retrievecloud)
then
1121 profiles(1) % ctp = ob_info % cloudtopp
1122 profiles(1) % cfraction = ob_info % cloudfrac
1126 nlevels =
size(profiles(1) % p)
1128 profiles(1) % zenangle = ob_info % sensor_zenith_angle
1129 profiles(1) % azangle = ob_info % sensor_azimuth_angle
1130 profiles(1) % sunzenangle = ob_info % solar_zenith_angle
1131 profiles(1) % sunazangle = ob_info % solar_azimuth_angle
1133 profiles(1)%skin%surftype = ob_info % surface_type
1138 if (obsspace_has(obss,
"MetaData",
"elevation"))
then
1139 call obsspace_get_db(obss,
"MetaData",
"elevation", tmpvar)
1140 profiles(1:nprofiles)%elevation = tmpvar(1:nprofiles) *
m_to_km
1141 else if (obsspace_has(obss,
"MetaData",
"surface_height"))
then
1142 call obsspace_get_db(obss,
"MetaData",
"surface_height", tmpvar)
1143 profiles(1:nprofiles)%elevation = tmpvar(1:nprofiles) *
m_to_km
1144 else if (obsspace_has(obss,
"MetaData",
"model_orography"))
then
1145 call obsspace_get_db(obss,
"MetaData",
"model_orography", tmpvar)
1146 profiles(1:nprofiles)%elevation = tmpvar(1:nprofiles) *
m_to_km
1149 profiles(1:nprofiles)%elevation = geoval%vals(1, 1:nprofiles) *
m_to_km
1151 write(
message,
'(A)')
'MetaData elevation not in database: check implicit filtering'
1156 variable_present = obsspace_has(obss,
"MetaData",
"latitude")
1157 if (variable_present)
then
1158 call obsspace_get_db(obss,
"MetaData",
"latitude", tmpvar )
1159 profiles(1:nprofiles)%latitude = tmpvar(1:nprofiles)
1162 'MetaData latitude not in database: check implicit filtering'
1166 variable_present = obsspace_has(obss,
"MetaData",
"longitude")
1167 if (variable_present)
then
1168 call obsspace_get_db(obss,
"MetaData",
"longitude", tmpvar )
1169 profiles(1:nprofiles)%longitude = tmpvar(1:nprofiles)
1172 'MetaData longitude not in database: check implicit filtering'
1180 call obsspace_get_db(obss,
"MetaData",
"sensor_zenith_angle", tmpvar)
1181 profiles(1:nprofiles)%zenangle = abs(tmpvar(1:nprofiles))
1184 variable_present = obsspace_has(obss,
"MetaData",
"sensor_azimuth_angle")
1185 if (variable_present)
then
1186 call obsspace_get_db(obss,
"MetaData",
"sensor_azimuth_angle", tmpvar)
1187 profiles(1:nprofiles)%azangle = tmpvar(1:nprofiles)
1189 write(
message,
'(A)')
'MetaData azimuth angle not in database: setting to zero'
1191 profiles(1:nprofiles)%azangle = zero
1195 variable_present = obsspace_has(obss,
"MetaData",
"solar_zenith_angle")
1196 if (variable_present)
then
1197 call obsspace_get_db(obss,
"MetaData",
"solar_zenith_angle", tmpvar)
1198 profiles(1:nprofiles)%sunzenangle = tmpvar(1:nprofiles)
1200 write(
message,
'(A)')
'MetaData solar zenith angle not in database: setting to zero'
1202 profiles(1:nprofiles)%sunzenangle = zero
1206 variable_present = obsspace_has(obss,
"MetaData",
"solar_azimuth_angle")
1207 if (variable_present)
then
1208 call obsspace_get_db(obss,
"MetaData",
"solar_azimuth_angle", tmpvar)
1209 profiles(1:nprofiles)%sunazangle = tmpvar(1:nprofiles)
1211 write(
message,
'(A)')
'MetaData solar azimuth angle not in database: setting to zero'
1213 profiles(1:nprofiles)%sunazangle = zero
1218 if (variable_present)
then
1222 profiles(1:nprofiles)%elevation = geoval%vals(1, 1:nprofiles) *
m_to_km
1241 integer,
intent(in) :: iprof
1242 integer,
intent(in) :: i_inst
1243 integer,
intent(out) :: errorstatus
1245 character(10) :: prof_str
1247 include
'rttov_print_profile.interface'
1248 include
'rttov_user_profile_checkinput.interface'
1250 call rttov_user_profile_checkinput(errorstatus, &
1251 conf % rttov_opts, &
1252 conf % rttov_coef_array(i_inst), &
1253 self % profiles(iprof))
1256 if(errorstatus /= errorstatus_success .and.
debug)
then
1257 write(prof_str,
'(i0)') iprof
1258 self % profiles(iprof) % id = prof_str
1259 call rttov_print_profile(self % profiles(iprof), lu = stderr)
1269 integer,
intent(in) :: iprof
1270 integer,
intent(in) :: i_inst
1272 character(10) :: prof_str
1274 include
'rttov_print_profile.interface'
1275 write(*,*)
'profile ', iprof
1276 write(prof_str,
'(i0)') iprof
1277 self % profiles(iprof) % id = prof_str
1278 call rttov_print_profile(self % profiles(iprof), lu = stdout)
1289 integer,
intent(out) :: errorstatus
1290 integer,
intent(in) :: asw
1291 logical,
optional,
intent(in) :: init
1292 integer ,
intent(in) :: nchannels
1293 integer ,
intent(in) :: nprofiles
1294 integer ,
intent(in) :: nlevels
1298 include
'rttov_alloc_direct.interface'
1300 if (
present(init))
then
1308 call rttov_alloc_direct( &
1314 opts = conf % rttov_opts, &
1315 coefs = conf % rttov_coef_array(1), &
1316 transmission = self % transmission, &
1317 radiance = self % radiance, &
1318 calcemis = self % calcemis, &
1319 emissivity = self % emissivity, &
1322 if (errorstatus /= errorstatus_success)
then
1323 write(
message,
'(A, I6)')
'after rttov_alloc_direct error = ', errorstatus
1329 self % calcemis = .false.
1330 self % emissivity % emis_in = -1.0_kind_real
1331 self % emissivity % emis_out = -1.0_kind_real
1343 integer,
intent(out) :: errorstatus
1344 integer,
intent(in) :: asw
1345 logical,
optional,
intent(in) :: init
1346 integer ,
intent(in) :: nchannels
1347 integer ,
intent(in) :: nprofiles
1348 integer ,
intent(in) :: nlevels
1352 include
'rttov_alloc_k.interface'
1354 if (
present(init))
then
1360 call rttov_alloc_k( &
1366 opts = conf % rttov_opts, &
1367 coefs = conf % rttov_coef_array(1), &
1368 transmission_k = self % transmission_k, &
1369 radiance_k = self % radiance_k, &
1370 emissivity_k = self % emissivity_k, &
1373 if (errorstatus /= errorstatus_success)
then
1374 write(
message,
'(A, I6)')
'after rttov_alloc_k error = ', errorstatus
1383 self % emissivity_k(:) % emis_out = 0
1384 self % emissivity_k(:) % emis_in = 0
1385 self % emissivity(:) % emis_out = 0
1386 self % radiance_k % bt(:) = 1
1387 self % radiance_k % total(:) = 1
1391 if (errorstatus /= errorstatus_success)
then
1392 write(
message,
'(A, I6)')
'after rttov_alloc_k error = ', errorstatus
1405 integer,
intent(out) :: errorstatus
1406 integer,
intent(in) :: asw
1407 logical,
optional,
intent(in) :: init
1408 integer ,
intent(in) :: nprofiles
1409 integer ,
intent(in) :: nlevels
1413 include
'rttov_alloc_prof.interface'
1415 if (
present(init))
then
1421 if (asw == 1)
allocate (self % profiles(nprofiles))
1424 call rttov_alloc_prof( &
1429 conf % rttov_opts, &
1431 coefs = conf % rttov_coef_array(1), &
1434 if (errorstatus /= errorstatus_success)
then
1435 write(
message,
'(A, I6)')
'after rttov_alloc_profiles error = ', errorstatus
1440 deallocate (self % profiles)
1442 self % profiles(:) % skin % surftype = -1_jpim
1454 integer,
intent(out) :: errorstatus
1455 integer,
intent(in) :: asw
1456 logical,
optional,
intent(in) :: init
1457 integer ,
intent(in) :: nprofiles
1458 integer ,
intent(in) :: nlevels
1462 include
'rttov_alloc_prof.interface'
1464 if (
present(init))
then
1471 allocate (self % profiles_k(nprofiles))
1474 call rttov_alloc_prof( &
1477 self % profiles_k, &
1479 conf % rttov_opts, &
1481 coefs = conf % rttov_coef_array(1), &
1484 if (errorstatus /= errorstatus_success)
then
1485 write(
message,
'(A, I6)')
'after rttov_alloc_profiles error = ', errorstatus
1498 include
'rttov_init_prof.interface'
1500 call rttov_init_prof(self % profiles_k)
1501 self % emissivity_k(:) % emis_in = 0.0
1502 self % emissivity_k(:) % emis_out = 0.0
1503 self % emissivity(:) % emis_out = 0.0
1504 self % radiance_k % bt(:) = 1.0
1505 self % radiance_k % total(:) = 1.0
1513 integer,
intent(in) :: prof_start
1515 integer :: prof, ichan
1520 if ( conf % rttov_coef_array(1) % coef % id_sensor == sensor_id_mw)
then
1522 prof = prof_start + self % chanprof(ichan)%prof - 1
1523 self % calcemis(ichan:ichan +
nchan_inst - 1) = .false.
1525 if (self % profiles(prof) % skin % surftype == surftype_sea)
then
1526 self % emissivity(ichan:ichan +
nchan_inst - 1) % emis_in = 0.0_kind_real
1527 self % calcemis(ichan:ichan +
nchan_inst - 1) = .true.
1532 if (self % profiles(prof) % skin % surftype == surftype_land)
then
1535 self % emissivity(ichan:ichan +
nchan_inst - 1) % emis_in = 0.95_kind_real
1536 elseif (self % profiles(prof) % skin % surftype == surftype_seaice)
then
1539 self % emissivity(ichan:ichan +
nchan_inst - 1) % emis_in = 0.92_kind_real
1544 elseif ( conf % rttov_coef_array(1) % coef % id_sensor == sensor_id_ir .or. &
1545 conf % rttov_coef_array(1) % coef % id_sensor == sensor_id_hi)
then
1547 do ichan = 1,
size (self % chanprof(:)),
nchan_inst
1548 prof = self % chanprof(ichan)%prof
1549 if (self % profiles(prof) % skin % surftype == surftype_sea)
then
1551 self % emissivity(ichan:ichan +
nchan_inst - 1) % emis_in = 0.0_kind_real
1552 self % calcemis(ichan:ichan +
nchan_inst - 1) = .true.
1556 if (self % profiles(prof) % skin % surftype == surftype_land)
then
1557 self % emissivity(ichan:ichan +
nchan_inst - 1) % emis_in = 0.95_kind_real
1558 elseif (self % profiles(prof) % skin % surftype == surftype_seaice)
then
1560 self % emissivity(ichan:ichan +
nchan_inst - 1) % emis_in = 0.92_kind_real
1572 character(10),
intent(in) :: default_opts_set
1574 integer :: PS_Number
1575 logical :: PS_configuration
1577 write(
message,
'(A, A)')
'Setting RTTOV default options to ', default_opts_set
1581 if(default_opts_set(1:4) ==
'UKMO')
then
1582 ps_configuration = .true.
1583 read(default_opts_set(8:9),*) ps_number
1585 write(
message,
'(A, i3)')
'Setting RTTOV default options for PS', ps_number
1588 ps_configuration = .false.
1593 self % rttov_opts % config % apply_reg_limits = .false.
1594 self % rttov_opts % config % verbose = .true.
1595 self % rttov_opts % config % do_checkinput = .true.
1596 self % rttov_opts % config % fix_hgpl = .false.
1598 self % rttov_opts % rt_all % addrefrac = .false.
1599 self % rttov_opts % rt_all % switchrad = .false.
1600 self % rttov_opts % rt_all % use_q2m = .true.
1601 self % rttov_opts % rt_all % do_lambertian = .false.
1602 self % rttov_opts % rt_all % lambertian_fixed_angle = .true.
1603 self % rttov_opts % rt_all % plane_parallel = .false.
1604 self % rttov_opts % rt_all % rad_down_lin_tau = .true.
1605 self % rttov_opts % rt_all % dtau_test = .true.
1607 self % rttov_opts % rt_ir % solar_sea_brdf_model = 1
1608 self % rttov_opts % rt_ir % ir_sea_emis_model = 2
1609 self % rttov_opts % rt_ir % addsolar = .false.
1610 self % rttov_opts % rt_ir % rayleigh_single_scatt = .true.
1611 self % rttov_opts % rt_ir % do_nlte_correction = .false.
1612 self % rttov_opts % rt_ir % addaerosl = .false.
1613 self % rttov_opts % rt_ir % user_aer_opt_param = .false.
1614 self % rttov_opts % rt_ir % addclouds = .false.
1615 self % rttov_opts % rt_ir % user_cld_opt_param = .false.
1616 self % rttov_opts % rt_ir % grid_box_avg_cloud = .false.
1618 self % rttov_opts % rt_ir % cldstr_threshold = -1.0_kind_real
1619 self % rttov_opts % rt_ir % cldstr_simple = .false.
1620 self % rttov_opts % rt_ir % cldstr_low_cloud_top = 750._kind_real
1621 self % rttov_opts % rt_ir % ir_scatt_model = ir_scatt_chou
1622 self % rttov_opts % rt_ir % vis_scatt_model = vis_scatt_dom
1623 self % rttov_opts % rt_ir % dom_nstreams = 8
1624 self % rttov_opts % rt_ir % dom_accuracy = 0._kind_real
1625 self % rttov_opts % rt_ir % dom_opdep_threshold = 0._kind_real
1627 self % rttov_opts % rt_ir % ozone_data = .false.
1628 self % rttov_opts % rt_ir % co2_data = .false.
1629 self % rttov_opts % rt_ir % n2o_data = .false.
1630 self % rttov_opts % rt_ir % co_data = .false.
1631 self % rttov_opts % rt_ir % ch4_data = .false.
1632 self % rttov_opts % rt_ir % so2_data = .false.
1634 self % rttov_opts % rt_ir % pc % addpc = .false.
1635 self % rttov_opts % rt_ir % pc % ipcbnd = -1
1636 self % rttov_opts % rt_ir % pc % ipcreg = -1
1637 self % rttov_opts % rt_ir % pc % npcscores = -1
1638 self % rttov_opts % rt_ir % pc % addradrec = .false.
1641 self % rttov_opts % rt_mw % fastem_version = 6
1642 self % rttov_opts % rt_mw % supply_foam_fraction = .false.
1643 self % rttov_opts % rt_mw % clw_data = .false.
1644 self % rttov_opts % rt_mw % clw_scheme = mw_clw_scheme_liebe
1645 self % rttov_opts % rt_mw % clw_calc_on_coef_lev = .true.
1646 self % rttov_opts % rt_mw % clw_cloud_top = 322
1647 self % rttov_opts % rt_mw % apply_band_correction = .true.
1649 self % rttov_opts % interpolation % addinterp = .false.
1650 self % rttov_opts % interpolation % interp_mode = interp_rochon
1651 self % rttov_opts % interpolation % lgradp = .false.
1652 self % rttov_opts % interpolation % spacetop = .true.
1653 self % rttov_opts % interpolation % reg_limit_extrap = .false.
1656 self % rttov_opts % htfrtc_opts % htfrtc = .false.
1657 self % rttov_opts % htfrtc_opts % n_pc_in = -1
1658 self % rttov_opts % htfrtc_opts % reconstruct = .false.
1659 self % rttov_opts % htfrtc_opts % simple_cloud = .false.
1660 self % rttov_opts % htfrtc_opts % overcast = .false.
1662 if (ps_configuration)
then
1665 if (
cmp_strings(default_opts_set(1:4),
'UKMO'))
then
1666 self % rttov_opts % config % verbose = .false.
1667 self % rttov_opts % config % do_checkinput = .false.
1669 self % rttov_opts % rt_all % switchrad = .true.
1670 self % rttov_opts % rt_all % use_q2m = .false.
1672 self % rttov_opts % rt_ir % grid_box_avg_cloud = .true.
1673 self % rttov_opts % rt_ir % ozone_data = .true.
1675 self % rttov_opts % rt_mw % clw_data = .true.
1677 self % rttov_opts % interpolation % addinterp = .true.
1678 self % rttov_opts % interpolation % interp_mode = interp_rochon_wfn
1682 if (ps_number <= 44)
then
1683 self % rttov_opts % rt_ir % ir_sea_emis_model = 1
1685 self % rttov_opts % rt_mw % fastem_version = 2
1687 self % rttov_opts % interpolation % spacetop = .false.
1691 if (ps_number >= 44)
then
1692 self % rttov_opts % config % apply_reg_limits = .true.
1693 self % rttov_opts % config % fix_hgpl = .true.
1695 self % rttov_opts % rt_all % dtau_test = .false.
1696 self % rttov_opts % rt_all % rad_down_lin_tau = .false.
1698 self % rttov_opts % rt_mw % clw_calc_on_coef_lev = .false.
1702 if (ps_number == 45)
then
1703 self % rttov_opts % rt_all % addrefrac = .true.
1705 self % rttov_opts % rt_mw % clw_scheme = mw_clw_scheme_rosenkranz
1707 self % rttov_opts % interpolation % reg_limit_extrap = .true.
1717 type(rttov_chanprof),
intent(in) :: chanprof(:)
1719 integer,
intent(in) :: prof_start
1722 integer :: jvar, chan, prof, ichan, rttov_prof
1723 integer :: nchanprof, nlevels, nprofiles
1724 real(kind_real),
allocatable :: od_level(:), wfunc(:)
1725 logical,
save :: firsttime = .true.
1727 include
'rttov_calc_weighting_fn.interface'
1729 allocate(od_level(
size(rtprof % transmission%tau_levels(:,1))))
1730 allocate(wfunc(
size(rtprof % transmission%tau_levels(:,1))))
1734 nchanprof =
size(chanprof)
1735 nlevels =
size(rtprof % profiles(1) % p)
1738 do jvar = 1, hofxdiags%nvar
1739 if (len(trim(hofxdiags%variables(jvar))) < 1) cycle
1754 hofxdiags%geovals(jvar)%nval = nlevels
1755 if(.not.
allocated(hofxdiags%geovals(jvar)%vals))
then
1756 allocate(hofxdiags%geovals(jvar)%vals(hofxdiags%geovals(jvar)%nval,nprofiles))
1757 hofxdiags%geovals(jvar)%vals =
missing
1761 do ichan = 1, nchanprof
1762 chan = chanprof(ichan)%chan
1763 rttov_prof = chanprof(ichan)%prof
1764 prof = prof_start + chanprof(ichan)%prof - 1
1769 od_level(:) = log(rtprof % transmission%tau_levels(:,chan))
1770 hofxdiags%geovals(jvar)%vals(:,prof) = od_level(1:nlevels-1) - od_level(2:nlevels)
1772 hofxdiags%geovals(jvar)%vals(:,prof) = rtprof % transmission % tau_levels(1:nlevels-1,chan) - &
1773 rtprof % transmission%tau_levels(2:,chan)
1775 od_level(:) = log(rtprof % transmission%tau_levels(:,chan))
1776 call rttov_calc_weighting_fn(
rttov_errorstatus, rtprof % profiles(rttov_prof)%p, od_level(:), &
1777 hofxdiags%geovals(jvar)%vals(:,prof))
1790 hofxdiags%geovals(jvar)%nval = 1
1791 if(.not.
allocated(hofxdiags%geovals(jvar)%vals))
then
1792 allocate(hofxdiags%geovals(jvar)%vals(hofxdiags%geovals(jvar)%nval,nprofiles))
1793 hofxdiags%geovals(jvar)%vals =
missing
1796 do ichan = 1, nchanprof
1797 chan = chanprof(ichan)%chan
1798 rttov_prof = chanprof(ichan)%prof
1799 prof = prof_start + chanprof(ichan)%prof - 1
1803 hofxdiags%geovals(jvar)%vals(1,prof) = rtprof % radiance % total(ichan)
1805 hofxdiags%geovals(jvar)%vals(1,prof) = rtprof % radiance % bt_clear(ichan)
1807 hofxdiags%geovals(jvar)%vals(1,prof) = rtprof % radiance % bt(ichan)
1809 call rttov_calc_weighting_fn(
rttov_errorstatus, rtprof % profiles(rttov_prof)%p, od_level(:), &
1811 hofxdiags%geovals(jvar)%vals(1,prof) = maxloc(wfunc(:), dim=1)
1813 hofxdiags%geovals(jvar)%vals(1,prof) = rtprof % transmission % tau_total(ichan)
1815 hofxdiags%geovals(jvar)%vals(1,prof) = rtprof % emissivity(ichan) % emis_out
1822 hofxdiags%geovals(jvar)%nval = 1
1823 if(.not.
allocated(hofxdiags%geovals(jvar)%vals))
then
1824 allocate(hofxdiags%geovals(jvar)%vals(hofxdiags%geovals(jvar)%nval,nprofiles))
1825 hofxdiags%geovals(jvar)%vals =
missing
1829 write(
message,*)
'ufo_radiancerttov_simobs: //&
1830 & ObsDiagnostic is unsupported but allocating anyway, ', &
1831 & hofxdiags%variables(jvar), shape(hofxdiags%geovals(jvar)%vals)
1843 hofxdiags%geovals(jvar)%nval = nlevels
1844 if(.not.
allocated(hofxdiags%geovals(jvar)%vals))
then
1845 allocate(hofxdiags%geovals(jvar)%vals(hofxdiags%geovals(jvar)%nval,nprofiles))
1846 hofxdiags%geovals(jvar)%vals =
missing
1849 do ichan = 1, nchanprof
1850 chan = chanprof(ichan)%chan
1851 rttov_prof = chanprof(ichan)%prof
1852 prof = prof_start + chanprof(ichan)%prof - 1
1856 hofxdiags%geovals(jvar)%vals(:,prof) = &
1857 rtprof % profiles_k(ichan) % t(:)
1859 hofxdiags%geovals(jvar)%vals(:,prof) = &
1860 rtprof % profiles_k(ichan) % q(:) * conf%scale_fac(gas_id_watervapour) /
g_to_kg
1862 hofxdiags%geovals(jvar)%vals(:,prof) = &
1863 rtprof % profiles_k(ichan) % q(:) * conf%scale_fac(gas_id_watervapour)
1865 hofxdiags%geovals(jvar)%vals(:,prof) = &
1866 rtprof % profiles_k(ichan) % clw(:)
1874 hofxdiags%geovals(jvar)%nval = 1
1875 if(.not.
allocated(hofxdiags%geovals(jvar)%vals))
then
1876 allocate(hofxdiags%geovals(jvar)%vals(hofxdiags%geovals(jvar)%nval,nprofiles))
1877 hofxdiags%geovals(jvar)%vals =
missing
1880 do ichan = 1, nchanprof
1881 chan = chanprof(ichan)%chan
1882 rttov_prof = chanprof(ichan)%prof
1883 prof = prof_start + chanprof(ichan)%prof - 1
1887 hofxdiags%geovals(jvar)%vals(1,prof) = &
1888 rtprof % profiles_k(ichan) % skin % t
1890 hofxdiags%geovals(jvar)%vals(1,prof) = &
1891 rtprof % profiles_k(ichan) % s2m % t
1893 hofxdiags%geovals(jvar)%vals(1,prof) = &
1894 rtprof % profiles_k(ichan) % s2m % p
1896 hofxdiags%geovals(jvar)%vals(1,prof) = &
1897 rtprof % profiles_k(ichan) % s2m % q * conf%scale_fac(gas_id_watervapour)
1899 hofxdiags%geovals(jvar)%vals(1,prof) = &
1900 rtprof % profiles_k(ichan) % s2m % u
1902 hofxdiags%geovals(jvar)%vals(1,prof) = &
1903 rtprof % profiles_k(ichan) % s2m % v
1905 hofxdiags%geovals(jvar)%vals(1,prof) = &
1906 rtprof % emissivity_k(ichan) % emis_in
1913 write(
message,*)
'ufo_radiancerttov_simobs: //&
1914 & Jacobian ObsDiagnostic is unsupported, ', &
1915 & hofxdiags%variables(jvar)
1921 write(
message,*)
'ufo_radiancerttov_simobs: //&
1922 & ObsDiagnostic is not recognised, ', &
1923 & hofxdiags%variables(jvar)
1930 deallocate(od_level,wfunc)
1938 logical,
intent(out) :: jacobian_needed
1939 character(10),
parameter :: jacobianstr =
"_jacobian_"
1941 integer :: str_pos(4)
1942 character(len=maxvarlen) :: varstr
1944 character(len=max_string) :: err_msg
1946 jacobian_needed = .false.
1952 if(hofxdiags%nvar > 0)
then
1959 do jvar = 1, hofxdiags%nvar
1960 varstr = hofxdiags%variables(jvar)
1962 str_pos(4) = len_trim(varstr)
1963 if (str_pos(4) < 1) cycle
1964 str_pos(3) = index(varstr,
"_",back=.true.)
1965 read(varstr(str_pos(3)+1:str_pos(4)),*, err=999)
ch_diags(jvar)
1966 999 str_pos(1) = index(varstr,jacobianstr) - 1
1967 if (str_pos(1) == 0)
then
1968 write(err_msg,*)
'parse_hofxdiags: _jacobian_ must be // &
1969 & preceded by dependent variable in config: ', &
1970 & hofxdiags%variables(jvar)
1971 call abor1_ftn(err_msg)
1972 else if (str_pos(1) > 0)
then
1975 str_pos(2) = str_pos(1) + len(jacobianstr) + 1
1976 jacobian_needed = .true.
1977 str_pos(4) = str_pos(3) - str_pos(2)
1978 xstr_diags(jvar)(1:str_pos(4)) = varstr(str_pos(2):str_pos(3)-1)
1984 ystr_diags(jvar)(1:str_pos(3)-1) = varstr(1:str_pos(3)-1)
real(kind_real), parameter, public g_to_kg
real(kind_real), parameter, public min_q
real(kind_real), parameter, public deg2rad
real(kind_real), parameter, public so2_mixratio_to_ppmv
real(kind_real), parameter, public co2_mixratio_to_ppmv
real(kind_real), parameter, public m_to_km
real(kind_real), parameter, public ch4_mixratio_to_ppmv
real(kind_real), parameter, public o3_mixratio_to_ppmv
real(kind_real), parameter, public q_mixratio_to_ppmv
real(kind_real), parameter, public n2o_mixratio_to_ppmv
real(kind_real), parameter, public co_mixratio_to_ppmv
real(kind_real), parameter, public half
real(kind_real), parameter, public pa_to_hpa
subroutine, public ufo_geovals_get_var(self, varname, geoval)
Fortran module to provide code shared between nonlinear and tlm/adm radiance calculations.
subroutine, public parse_hofxdiags(hofxdiags, jacobian_needed)
integer, dimension(:), allocatable ch_diags
subroutine set_defaults_rttov(self, default_opts_set)
integer, dimension(ngases_max+2), parameter rttov_absorber_id
subroutine ufo_rttov_zero_k(self)
subroutine ufo_rttov_alloc_profiles_k(self, errorstatus, conf, nprofiles, nlevels, init, asw)
integer, parameter, public maxvarin
integer, public nchan_inst
character(len=maxvarlen), dimension(maxvarin), public varin_temp
subroutine set_options_rttov(self, f_confOpts)
subroutine, public rttov_conf_setup(conf, f_confOpts, f_confOper)
integer, parameter, public max_string
character(len=maxvarlen), parameter null_str
subroutine ufo_rttov_alloc_profiles(self, errorstatus, conf, nprofiles, nlevels, init, asw)
subroutine ufo_rttov_check_rtprof(self, conf, iprof, i_inst, errorstatus)
character(len=max_string), public message
subroutine, public rttov_conf_delete(conf)
character(len=maxvarlen), dimension(21), target varin_default_crtm
character(len=maxvarlen), dimension(:), pointer, public varin_default
subroutine, public populate_hofxdiags(RTProf, chanprof, conf, prof_start, hofxdiags)
subroutine setup_rttov(self, f_confOpts)
character(len= *), dimension(ngases_max+2), parameter rttov_absorbers
subroutine ufo_rttov_alloc_direct(self, errorstatus, conf, nprofiles, nchannels, nlevels, init, asw)
subroutine ufo_rttov_setup_rtprof(self, geovals, obss, conf, ob_info)
integer, public nchan_sim
integer, public rttov_errorstatus
subroutine ufo_rttov_print_rtprof(self, conf, iprof, i_inst)
subroutine ufo_rttov_init_emissivity(self, conf, prof_start)
subroutine ufo_rttov_alloc_k(self, errorstatus, conf, nprofiles, nchannels, nlevels, init, asw)
character(len=maxvarlen), dimension(ngases_max+2), parameter ufo_absorbers
subroutine get_var_name(n, varname)
real(kind_real), dimension(0:ngases_max), parameter gas_unit_conv
character(len=maxvarlen), dimension(9), target varin_default_satrad
integer, public nlocs_total
character(len=maxvarlen), dimension(:), allocatable ystr_diags
character(len=maxvarlen), dimension(:), allocatable xstr_diags
Fortran module which contains the observation metadata for a single observation.
Fortran module with various useful routines.
subroutine, public ops_satrad_qsplit(output_type, p, t, qtotal, q, ql, qi, UseQtSplitRain)
Split the humidity into water vapour, liquid water and ice.
subroutine, public ops_qsat(QS, T, P, npnts)
Calculate the Saturation Specific Humidity Scheme (Qsat): Vapour to Liquid/Ice.
subroutine, public ops_qsatwat(QS, T, P, npnts)
Saturation Specific Humidity Scheme: Vapour to Liquid.
logical function, public cmp_strings(str1, str2)
character(len=maxvarlen), parameter, public var_radiance
character(len=maxvarlen), parameter, public var_co2
character(len=maxvarlen), parameter, public var_prsi
character(len=maxvarlen), parameter, public var_sfc_emiss
character(len=maxvarlen), parameter, public var_sfc_ifrac
character(len=maxvarlen), parameter, public var_surf_type_rttov
integer function, public ufo_vars_getindex(vars, varname)
character(len=maxvarlen), parameter, public var_oz
character(len=maxvarlen), parameter, public var_clw
character(len=maxvarlen), parameter, public var_sfc_lfrac
character(len=maxvarlen), parameter, public var_sfc_v10
character(len=maxvarlen), parameter, public var_sfc_wtmp
character(len=maxvarlen), parameter, public var_prs
character(len=maxvarlen), parameter, public var_q
character(len=maxvarlen), parameter, public var_sfc_u10
character(len=maxvarlen), parameter, public var_sfc_wfrac
character(len=maxvarlen), parameter, public var_tb_clr
character(len=maxvarlen), parameter, public var_sfc_sfrac
character(len=maxvarlen), parameter, public var_sfc_itmp
character(len=maxvarlen), parameter, public var_sfc_wdir
character(len=maxvarlen), parameter, public var_sfc_soilm
character(len=maxvarlen), parameter, public var_sfc_sdepth
character(len=maxvarlen), parameter, public var_sfc_landtyp
character(len=maxvarlen), parameter, public var_sfc_q2m
character(len=maxvarlen), parameter, public var_mixr
character(len=maxvarlen), parameter, public var_sfc_tskin
character(len=maxvarlen), parameter, public var_sfc_p2m
character(len=maxvarlen), parameter, public var_lvl_transmit
character(len=maxvarlen), parameter, public var_tb
character(len=maxvarlen), parameter, public var_sfc_stmp
character(len=maxvarlen), parameter, public var_lvl_weightfunc
character(len=maxvarlen), parameter, public var_ts
character(len=maxvarlen), parameter, public var_sfc_lai
character(len=maxvarlen), parameter, public var_pmaxlev_weightfunc
character(len=maxvarlen), parameter, public var_sfc_vegtyp
character(len=maxvarlen), parameter, public var_sfc_soiltyp
character(len=maxvarlen), parameter, public var_cli
character(len=maxvarlen), parameter, public var_sfc_vegfrac
character(len=maxvarlen), parameter, public var_sfc_ltmp
character(len=maxvarlen), parameter, public var_opt_depth
character(len=maxvarlen), parameter, public var_sfc_soilt
character(len=maxvarlen), parameter, public var_sfc_wspeed
character(len=maxvarlen), parameter, public var_total_transmit
character(len=maxvarlen), parameter, public var_sfc_t2m
type to hold interpolated field for one variable, one observation
type to hold interpolated fields required by the obs operators