From 82dc428416a963e39376e90876de36e24826a9ed Mon Sep 17 00:00:00 2001 From: amfox37 Date: Mon, 2 Dec 2024 14:46:39 -0700 Subject: [PATCH 1/4] updates to ASCAT obs reader --- .../clsm_ensupd_read_obs.F90 | 52 ++++++++++++++----- GEOSldas_App/LDASsa_DEFAULT_inputs_ensupd.nml | 6 +-- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/GEOSlandassim_GridComp/clsm_ensupd_read_obs.F90 b/GEOSlandassim_GridComp/clsm_ensupd_read_obs.F90 index e87b3df..2c30f96 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 @@ -1747,19 +1747,47 @@ subroutine read_obs_sm_ASCAT_EUMET( & ! Are we in the required assimilation window? ! ! 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 + ! 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + ! 1 2 3 4 5 6 7 8 9 10 11 12 - str_date_time = tmpfname(36:49) - + ! 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 filename format' + call ldas_abort(LDAS_GENERIC_ERROR, Iam, err_msg) + end if + + ! Check that str_date_time only contains numeric characters + + do ii = 1, len(str_date_time) + if (ichar(str_date_time(ii:ii)) < ichar('0') .or. ichar(str_date_time(ii:ii)) > ichar('9')) then + err_msg = 'The date-time string parsed from the ASCAT observation filename 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 date_time_tmp%year and date_time_tmp%month and date_time_tmp%day are valid + if (date_time_tmp%year < 1900 .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 = 'A valid date-time string has not been successfully parsed from the ASCAT observation filename' + 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 +6160,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 +6867,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 +8195,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 +8204,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 +8253,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 +8266,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 +8274,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 ece206c..b93496e 100644 --- a/GEOSldas_App/LDASsa_DEFAULT_inputs_ensupd.nml +++ b/GEOSldas_App/LDASsa_DEFAULT_inputs_ensupd.nml @@ -2178,7 +2178,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 = '' @@ -2217,7 +2217,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 = '' @@ -2256,7 +2256,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 = '' From 2ba02ca132767514ddb983a1dcbb40b2776bc289 Mon Sep 17 00:00:00 2001 From: amfox37 Date: Mon, 2 Dec 2024 16:09:04 -0700 Subject: [PATCH 2/4] len(trim(str_date_time)) --- GEOSlandassim_GridComp/clsm_ensupd_read_obs.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/GEOSlandassim_GridComp/clsm_ensupd_read_obs.F90 b/GEOSlandassim_GridComp/clsm_ensupd_read_obs.F90 index 2c30f96..3dc348f 100644 --- a/GEOSlandassim_GridComp/clsm_ensupd_read_obs.F90 +++ b/GEOSlandassim_GridComp/clsm_ensupd_read_obs.F90 @@ -1765,12 +1765,12 @@ subroutine read_obs_sm_ASCAT_EUMET( & ! Check that str_date_time only contains numeric characters - do ii = 1, len(str_date_time) - if (ichar(str_date_time(ii:ii)) < ichar('0') .or. ichar(str_date_time(ii:ii)) > ichar('9')) then - err_msg = 'The date-time string parsed from the ASCAT observation filename contains non-numeric characters' - call ldas_abort(LDAS_GENERIC_ERROR, Iam, err_msg) - end if - end do + 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 = 'The date-time string parsed from the ASCAT observation filename 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 From b0555b3fb1358596fb65117e137cc14211f1a113 Mon Sep 17 00:00:00 2001 From: amfox37 Date: Mon, 2 Dec 2024 18:55:52 -0700 Subject: [PATCH 3/4] changemod edit --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d07a99f..0df1162 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,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 new and old filename formats. + ### Fixed ### Removed From 01c541ddaea508c707b8bbc243c22e2a3c51ffb1 Mon Sep 17 00:00:00 2001 From: Rolf Reichle Date: Wed, 11 Dec 2024 13:02:20 -0500 Subject: [PATCH 4/4] additional documentation and minor cleanup for ASCAT soil moisture reader updates --- CHANGELOG.md | 2 +- .../clsm_ensupd_read_obs.F90 | 47 +++++++++++-------- GEOSldas_App/LDASsa_DEFAULT_inputs_ensupd.nml | 8 +++- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1e8aca..5ab148b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ 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 new and old filename formats. +- Updated read_obs_sm_ASCAT_EUMET to work with both original and revised file name templates. ### Fixed diff --git a/GEOSlandassim_GridComp/clsm_ensupd_read_obs.F90 b/GEOSlandassim_GridComp/clsm_ensupd_read_obs.F90 index 3dc348f..05eeaf6 100644 --- a/GEOSlandassim_GridComp/clsm_ensupd_read_obs.F90 +++ b/GEOSlandassim_GridComp/clsm_ensupd_read_obs.F90 @@ -1741,34 +1741,41 @@ 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 ! ! 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 - + + ! 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) + str_date_time = tmpfname(36:49) else if (index(tmpfname, "W_XX-EUMETSAT") /= 0) then - str_date_time = tmpfname(74:87) + str_date_time = tmpfname(74:87) else - err_msg = 'Unknown ASCAT observation filename format' - call ldas_abort(LDAS_GENERIC_ERROR, Iam, err_msg) + err_msg = 'Unknown ASCAT observation file name format' + call ldas_abort(LDAS_GENERIC_ERROR, Iam, err_msg) end if - ! Check that str_date_time only contains numeric characters - + ! 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 = 'The date-time string parsed from the ASCAT observation filename contains non-numeric characters' - call ldas_abort(LDAS_GENERIC_ERROR, Iam, err_msg) + 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 @@ -1779,15 +1786,15 @@ subroutine read_obs_sm_ASCAT_EUMET( & read(str_date_time(11:12), *) date_time_tmp%min read(str_date_time(13:14), *) date_time_tmp%sec - ! Check if date_time_tmp%year and date_time_tmp%month and date_time_tmp%day are valid + ! check if year, month, and day are valid - if (date_time_tmp%year < 1900 .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 = 'A valid date-time string has not been successfully parsed from the ASCAT observation filename' + 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 - + end if + if ( datetime_lt_refdatetime( date_time_low_fname, date_time_tmp ) .and. & datetime_le_refdatetime( date_time_tmp, date_time_up ) ) then diff --git a/GEOSldas_App/LDASsa_DEFAULT_inputs_ensupd.nml b/GEOSldas_App/LDASsa_DEFAULT_inputs_ensupd.nml index a6de8e0..5085098 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) !