diff --git a/CHANGELOG.md b/CHANGELOG.md index 55fce114..5ab148b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Updated read_obs_sm_ASCAT_EUMET to work with both original and revised file name templates. + ### Fixed ### Removed diff --git a/GEOSlandassim_GridComp/clsm_ensupd_read_obs.F90 b/GEOSlandassim_GridComp/clsm_ensupd_read_obs.F90 index e87b3df4..05eeaf66 100644 --- a/GEOSlandassim_GridComp/clsm_ensupd_read_obs.F90 +++ b/GEOSlandassim_GridComp/clsm_ensupd_read_obs.F90 @@ -1667,7 +1667,7 @@ subroutine read_obs_sm_ASCAT_EUMET( & ! -------------------- - character(100), dimension(2*N_fnames_max) :: fname_list ! max 2 days of files + character(200), dimension(2*N_fnames_max) :: fname_list ! max 2 days of files real, dimension(:), allocatable :: tmp1_obs, tmp1_lat, tmp1_lon real*8, dimension(:), allocatable :: tmp1_jtime @@ -1741,24 +1741,59 @@ subroutine read_obs_sm_ASCAT_EUMET( & N_tmp = 0 do kk = 1,N_fnames - + tmpfname = fname_list(kk) - + ! Are we in the required assimilation window? ! + ! NOTE: EUMETSAT changed the file name template sometime in 2023 or 2024. + ! There was no change to the file contents. + ! Files from the original download (through data day ~1 Jun 2023) have + ! the original file name template ("M0[X]-ASCA..."), more recently downloaded + ! files have the revised template ("W_XX-EUMETSAT..."). + ! This reader accommodates both templates: + ! ! e.g. Y2019/M07/M01-ASCA-ASCSMO02-NA-5.0-20190702075700.000000000Z-20190702084627-1350204.bfr + ! Y2024/M02/W_XX-EUMETSAT-Darmstadt,SOUNDING+SATELLITE,METOPC+ASCAT_C_EUMR_20240229095700_27567_eps_o_250_ssm_l2.bin ! - ! 12345678901234567890123456789012345678901234567890123456789012345678901234567890 - ! 1 2 3 4 5 6 7 - - str_date_time = tmpfname(36:49) - + ! 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + ! 1 2 3 4 5 6 7 8 9 10 11 12 + + ! check if tmpfname contains "ASCA-ASCSMO02" or "W_XX-EUMETSAT", error if neither + + if (index(tmpfname, "ASCA-ASCSMO02") /= 0) then + str_date_time = tmpfname(36:49) + else if (index(tmpfname, "W_XX-EUMETSAT") /= 0) then + str_date_time = tmpfname(74:87) + else + err_msg = 'Unknown ASCAT observation file name format' + call ldas_abort(LDAS_GENERIC_ERROR, Iam, err_msg) + end if + + ! check if str_date_time only contains numeric characters + + do ii = 1, len(trim(str_date_time)) + if (ichar(str_date_time(ii:ii)) < ichar('0') .or. ichar(str_date_time(ii:ii)) > ichar('9')) then + err_msg = 'Date-time string parsed from ASCAT sm obs file name contains non-numeric characters' + call ldas_abort(LDAS_GENERIC_ERROR, Iam, err_msg) + end if + end do + read(str_date_time( 1: 4), *) date_time_tmp%year read(str_date_time( 5: 6), *) date_time_tmp%month read(str_date_time( 7: 8), *) date_time_tmp%day read(str_date_time( 9:10), *) date_time_tmp%hour read(str_date_time(11:12), *) date_time_tmp%min read(str_date_time(13:14), *) date_time_tmp%sec + + ! check if year, month, and day are valid + + if ( date_time_tmp%year < 2007 .or. date_time_tmp%year > 2100 .or. & + date_time_tmp%month < 1 .or. date_time_tmp%month > 12 .or. & + date_time_tmp%day < 1 .or. date_time_tmp%day > 31 ) then + err_msg = 'Could not parse valid date-time string from ASCAT obs file name' + call ldas_abort(LDAS_GENERIC_ERROR, Iam, err_msg) + end if if ( datetime_lt_refdatetime( date_time_low_fname, date_time_tmp ) .and. & datetime_le_refdatetime( date_time_tmp, date_time_up ) ) then @@ -6132,7 +6167,7 @@ subroutine read_obs_SMAP_FT( date_time, N_catd, this_obs_param, & character(100) :: dset_name_lon, dset_name_lat character(100) :: dset_name_time, dset_name_ft, dset_name_ft_qual_flag - character(100), dimension(2*N_halforbits_max) :: fname_list ! max 2 days of files + character(200), dimension(2*N_halforbits_max) :: fname_list ! max 2 days of files integer, dimension(7) :: dset_size integer, dimension(N_fnames_max) :: N_obs_kept @@ -6839,7 +6874,7 @@ subroutine read_obs_SMAP_halforbit_Tb( date_time, N_catd, this_obs_param, & character(100) :: dset_name_time_1, dset_name_tb_1, dset_name_tb_qual_flag_1 character(100) :: dset_name_time_2, dset_name_tb_2, dset_name_tb_qual_flag_2 - character(100), dimension(2*N_halforbits_max) :: fname_list ! max 2 days of files + character(200), dimension(2*N_halforbits_max) :: fname_list ! max 2 days of files integer, dimension(7) :: dset_size integer, dimension(N_fnames_max) :: N_obs_kept @@ -8167,7 +8202,7 @@ subroutine read_obs_fnames( date_time, this_obs_param, & integer, intent(out) :: N_fnames - character(100), dimension(N_max), intent(out) :: fname_list + character(200), dimension(N_max), intent(out) :: fname_list integer, optional, intent(in) :: obs_dir_hier @@ -8176,7 +8211,7 @@ subroutine read_obs_fnames( date_time, this_obs_param, & character(300) :: fname character(200) :: fpath_tmp character( 80) :: fname_tmp - character( 80) :: tmpstr80 + character(200) :: tmpstr200 character( 14) :: YYYYMMDDdir character( 10) :: YYYYMMdir @@ -8225,7 +8260,7 @@ subroutine read_obs_fnames( date_time, this_obs_param, & do while (istat==0) - read(10,*,iostat=istat) tmpstr80 + read(10, '(A)',iostat=istat) tmpstr200 if (istat==0) then @@ -8238,7 +8273,7 @@ subroutine read_obs_fnames( date_time, this_obs_param, & ! preface file names with "Yyyyy/Mmm/Ddd" (default) - fname_list(ii) = YYYYMMDDdir // trim(tmpstr80) + fname_list(ii) = YYYYMMDDdir // trim(tmpstr200) if (present(obs_dir_hier)) then @@ -8246,7 +8281,7 @@ subroutine read_obs_fnames( date_time, this_obs_param, & ! preface file names with "Yyyyy/Mmm" - fname_list(ii) = YYYYMMdir // trim(tmpstr80) + fname_list(ii) = YYYYMMdir // trim(tmpstr200) else diff --git a/GEOSldas_App/LDASsa_DEFAULT_inputs_ensupd.nml b/GEOSldas_App/LDASsa_DEFAULT_inputs_ensupd.nml index 6f4951a0..50850985 100644 --- a/GEOSldas_App/LDASsa_DEFAULT_inputs_ensupd.nml +++ b/GEOSldas_App/LDASsa_DEFAULT_inputs_ensupd.nml @@ -2158,7 +2158,13 @@ obs_param_nml(48)%xcorr = 0.1875 obs_param_nml(48)%ycorr = 0.1875 obs_param_nml(48)%adapt = 0 -! -------------------------------------------------------------------- +! -------------------------------------------------------------------------------------------------------------- +! +! ASCAT_MET[X]_SM soil moisture observations from EUMETSAT +! +! Leave %name blank. Provide text files that contain file names via %flistpath and %flistname. +! +! ------------------- ! ! 49 = ASCAT_META_SM (ASCAT soil moisture ascending and descending orbits) ! @@ -2182,7 +2188,7 @@ obs_param_nml(49)%nodata = -9999. obs_param_nml(49)%varname = 'sfds' obs_param_nml(49)%units = '%' obs_param_nml(49)%path = '/discover/nobackup/projects/gmao/smap/SMAP_Nature/ASCAT_EUMETSAT/Metop_A/' -obs_param_nml(49)%name = 'M02-ASCA-ASCSMO02' +obs_param_nml(49)%name = '' obs_param_nml(49)%maskpath = '' obs_param_nml(49)%maskname = '' obs_param_nml(49)%scalepath = '' @@ -2221,7 +2227,7 @@ obs_param_nml(50)%nodata = -9999. obs_param_nml(50)%varname = 'sfds' obs_param_nml(50)%units = '%' obs_param_nml(50)%path = '/discover/nobackup/projects/gmao/smap/SMAP_Nature/ASCAT_EUMETSAT/Metop_B/' -obs_param_nml(50)%name = 'M01-ASCA-ASCSMO02' +obs_param_nml(50)%name = '' obs_param_nml(50)%maskpath = '' obs_param_nml(50)%maskname = '' obs_param_nml(50)%scalepath = '' @@ -2260,7 +2266,7 @@ obs_param_nml(51)%nodata = -9999. obs_param_nml(51)%varname = 'sfds' obs_param_nml(51)%units = '%' obs_param_nml(51)%path = '/discover/nobackup/projects/gmao/smap/SMAP_Nature/ASCAT_EUMETSAT/Metop_C/' -obs_param_nml(51)%name = 'M03-ASCA-ASCSMO02' +obs_param_nml(51)%name = '' obs_param_nml(51)%maskpath = '' obs_param_nml(51)%maskname = '' obs_param_nml(51)%scalepath = ''