Skip to content
Merged
37 changes: 25 additions & 12 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Added ntasks-per-node.
- Added matlab reader for binary mwRTM vegopacity file.

### Changed

- Cleaned up ldas_setup. Split out ldas.py and setup_utils.py.
- Added reader for surface meteorological forcing from S2S-3.
- Update `GEOSlandassim_GridComp/io_hdf5.F90` to allow for use with HDF5 1.14.
- Changed default format of tile-space HISTORY output to nc4.

### Fixed

- Fixed bug in ASCAT EUMET soil moisture obs reader.
- Fixed Restart=1 when the domain is not global.

### Removed

### Deprecated

-----------------------------

## [v3.2.0] - 2025-11-26

- 0-diff vs. v3.1.0 (except for lat/lon fields in "1d" nc4 output, which have roundoff differences between files directly generated with MAPL [new default] and files generated with tile_bin2nc4 [discontinued]).

### Added

- Added reader for surface meteorological forcing from S2S-3 ([PR #138](https://github.com/GEOS-ESM/GEOSldas_GridComp/pull/138)).
- Added matlab reader for binary mwRTM vegopacity file ([PR #142](https://github.com/GEOS-ESM/GEOSldas_GridComp/pull/142)).

### Changed

- Changed default format of tile-space HISTORY output to nc4 ([PR #144](https://github.com/GEOS-ESM/GEOSldas_GridComp/pull/144)).
- Enable remapping of landice restarts from ldas_setup ([PR #146](https://github.com/GEOS-ESM/GEOSldas_GridComp/pull/146)).
- Commented out static QC mask in CYGNSS obs reader ([PR #151](https://github.com/GEOS-ESM/GEOSldas_GridComp/pull/151)).
- Cleaned up ldas_setup; split out ldas.py and setup_utils.py; restored ntasks-per-node option ([PR #107](https://github.com/GEOS-ESM/GEOSldas_GridComp/pull/107)).
- Update `GEOSlandassim_GridComp/io_hdf5.F90` to allow for use with HDF5 1.14 ([PR #139](https://github.com/GEOS-ESM/GEOSldas_GridComp/pull/139)).

### Fixed

- Fixed bug in ASCAT EUMET soil moisture obs reader; bumped max_obs limit ([PR #148](https://github.com/GEOS-ESM/GEOSldas_GridComp/pull/148), [PR #151](https://github.com/GEOS-ESM/GEOSldas_GridComp/pull/151)).
- Provide default "zoom" value for remap_restarts yaml file ([PR #137](https://github.com/GEOS-ESM/GEOSldas_GridComp/pull/137)).
- Fixed Restart=1 when the domain is not global ([PR #107](https://github.com/GEOS-ESM/GEOSldas_GridComp/pull/107)).

-----------------------------

## [v3.1.0] - 2025-06-26

- 0-diff vs. v3.0.0.
Expand Down Expand Up @@ -151,4 +165,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

-----------------------------


168 changes: 88 additions & 80 deletions GEOSlandassim_GridComp/clsm_ensupd_read_obs.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1643,7 +1643,7 @@ subroutine read_obs_sm_ASCAT_EUMET( &

integer, parameter :: lnbufr = 50 ! BUFR file unit number
integer, parameter :: max_rec = 50000 ! max number of obs after QC (expecting < 6 hr assim window)
integer, parameter :: max_obs = 250000 ! max number of obs read by subroutine (expecting < 6 hr assim window)
integer, parameter :: max_obs = 280000 ! max number of obs read by subroutine (expecting < 6 hr assim window)

integer :: idate, iret, ireadmg, ireadsb

Expand Down Expand Up @@ -2427,78 +2427,87 @@ subroutine read_obs_sm_CYGNSS( &
! close the obs file
ierr = nf90_close(ncid)

! get name for CYGNSS mask file

tmpmaskname = trim(this_obs_param%maskpath) // '/' // trim(this_obs_param%maskname) // '.nc'

inquire(file=tmpfname, exist=file_exists)

if (.not. file_exists) then
err_msg = 'CYGNSS mask file not found!'
call ldas_abort(LDAS_GENERIC_ERROR, Iam, err_msg)
end if

! open the CYGNSS mask file

ierr = nf90_open(trim(tmpmaskname), nf90_nowrite, ncid)

! get variable dimension IDs
ierr = nf90_inq_dimid(ncid, 'lon', lon_dimid)
ierr = nf90_inq_dimid(ncid, 'lat', lat_dimid)

! dimensions sizes
ierr = nf90_inquire_dimension(ncid, lon_dimid, len=N_lon_m)
ierr = nf90_inquire_dimension(ncid, lat_dimid, len=N_lat_m)

! get variable IDs
ierr = nf90_inq_varid(ncid, 'longitude', longitudes_m_varid)
ierr = nf90_inq_varid(ncid, 'latitude', latitudes_m_varid)
ierr = nf90_inq_varid(ncid, 'flag_small_SM_range', small_SM_range_varid)
ierr = nf90_inq_varid(ncid, 'flag_poor_SMAP', poor_SMAP_varid)
ierr = nf90_inq_varid(ncid, 'flag_high_ubrmsd', high_ubrmsd_varid)
ierr = nf90_inq_varid(ncid, 'flag_few_obs', few_obs_varid)
ierr = nf90_inq_varid(ncid, 'flag_low_signal', low_signal_varid)

! allocate memory for the variables
allocate(latitudes_m( N_lon_m, N_lat_m))
allocate(longitudes_m( N_lon_m, N_lat_m))
allocate(small_SM_range_flag(N_lon_m, N_lat_m))
allocate(poor_SMAP_flag( N_lon_m, N_lat_m))
allocate(high_ubrmsd_flag( N_lon_m, N_lat_m))
allocate(few_obs_flag( N_lon_m, N_lat_m))
allocate(low_signal_flag( N_lon_m, N_lat_m))

! read the variables
ierr = nf90_get_var(ncid, latitudes_m_varid, latitudes_m)
ierr = nf90_get_var(ncid, longitudes_m_varid, longitudes_m)
ierr = nf90_get_var(ncid, small_SM_range_varid, small_SM_range_flag)
ierr = nf90_get_var(ncid, poor_SMAP_varid, poor_SMAP_flag)
ierr = nf90_get_var(ncid, high_ubrmsd_varid, high_ubrmsd_flag)
ierr = nf90_get_var(ncid, few_obs_varid, few_obs_flag)
ierr = nf90_get_var(ncid, low_signal_varid, low_signal_flag)

! close the mask file
ierr = nf90_close(ncid)

! check the obs data and mask data are the same resolution
if (N_lon /= N_lon_m .or. N_lat /= N_lat_m) then
err_msg = 'The mask file ' // trim(this_obs_param%maskname) // ' does not match the obs resolution'
call ldas_abort(LDAS_GENERIC_ERROR, Iam, err_msg)
end if

good_flag_value = 255 ! should really be 0 but is 255 because of unsigned v. signed byte issues
! ----------------------------------------------------------------
! AMF, November 2025
! Original CYGNSS mask reading section commented out - masks not currently used
! Mask originally developed for version 1.0 of CYGNSS soil moisture product and
! not believed to be appropriate for version 3.2 product being used here.
! ----------------------------------------------------------------

! ! get name for CYGNSS mask file

! tmpmaskname = trim(this_obs_param%maskpath) // '/' // trim(this_obs_param%maskname) // '.nc'

! inquire(file=tmpfname, exist=file_exists)

! if (.not. file_exists) then
! err_msg = 'CYGNSS mask file not found!'
! call ldas_abort(LDAS_GENERIC_ERROR, Iam, err_msg)
! end if

! ! open the CYGNSS mask file

! ierr = nf90_open(trim(tmpmaskname), nf90_nowrite, ncid)

! ! get variable dimension IDs
! ierr = nf90_inq_dimid(ncid, 'lon', lon_dimid)
! ierr = nf90_inq_dimid(ncid, 'lat', lat_dimid)

! ! dimensions sizes
! ierr = nf90_inquire_dimension(ncid, lon_dimid, len=N_lon_m)
! ierr = nf90_inquire_dimension(ncid, lat_dimid, len=N_lat_m)

! ! get variable IDs
! ierr = nf90_inq_varid(ncid, 'longitude', longitudes_m_varid)
! ierr = nf90_inq_varid(ncid, 'latitude', latitudes_m_varid)
! ierr = nf90_inq_varid(ncid, 'flag_small_SM_range', small_SM_range_varid)
! ierr = nf90_inq_varid(ncid, 'flag_poor_SMAP', poor_SMAP_varid)
! ierr = nf90_inq_varid(ncid, 'flag_high_ubrmsd', high_ubrmsd_varid)
! ierr = nf90_inq_varid(ncid, 'flag_few_obs', few_obs_varid)
! ierr = nf90_inq_varid(ncid, 'flag_low_signal', low_signal_varid)

! ! allocate memory for the variables
! allocate(latitudes_m( N_lon_m, N_lat_m))
! allocate(longitudes_m( N_lon_m, N_lat_m))
! allocate(small_SM_range_flag(N_lon_m, N_lat_m))
! allocate(poor_SMAP_flag( N_lon_m, N_lat_m))
! allocate(high_ubrmsd_flag( N_lon_m, N_lat_m))
! allocate(few_obs_flag( N_lon_m, N_lat_m))
! allocate(low_signal_flag( N_lon_m, N_lat_m))

! ! read the variables
! ierr = nf90_get_var(ncid, latitudes_m_varid, latitudes_m)
! ierr = nf90_get_var(ncid, longitudes_m_varid, longitudes_m)
! ierr = nf90_get_var(ncid, small_SM_range_varid, small_SM_range_flag)
! ierr = nf90_get_var(ncid, poor_SMAP_varid, poor_SMAP_flag)
! ierr = nf90_get_var(ncid, high_ubrmsd_varid, high_ubrmsd_flag)
! ierr = nf90_get_var(ncid, few_obs_varid, few_obs_flag)
! ierr = nf90_get_var(ncid, low_signal_varid, low_signal_flag)

! ! close the mask file
! ierr = nf90_close(ncid)

! ! check the obs data and mask data are the same resolution
! if (N_lon /= N_lon_m .or. N_lat /= N_lat_m) then
! err_msg = 'The mask file ' // trim(this_obs_param%maskname) // ' does not match the obs resolution'
! call ldas_abort(LDAS_GENERIC_ERROR, Iam, err_msg)
! end if

! good_flag_value = 255 ! should really be 0 but is 255 because of unsigned v. signed byte issues

! fill tmp arrays
N_obs = 0

do i = 1, N_lon
do j = 1, N_lat
if (tmp_sm(i,j) .ne. this_obs_param%nodata .and. &
small_SM_range_flag(i,j) == good_flag_value .and. &
poor_SMAP_flag(i,j) == good_flag_value .and. &
high_ubrmsd_flag(i,j) == good_flag_value .and. &
few_obs_flag(i,j) == good_flag_value .and. &
low_signal_flag(i,j) == good_flag_value ) then
! if (tmp_sm(i,j) .ne. this_obs_param%nodata .and. &
! small_SM_range_flag(i,j) == good_flag_value .and. &
! poor_SMAP_flag(i,j) == good_flag_value .and. &
! high_ubrmsd_flag(i,j) == good_flag_value .and. &
! few_obs_flag(i,j) == good_flag_value .and. &
! low_signal_flag(i,j) == good_flag_value ) then

if (tmp_sm(i,j) .ne. this_obs_param%nodata) then

! valid observation
N_obs = N_obs + 1
Expand Down Expand Up @@ -2631,18 +2640,18 @@ subroutine read_obs_sm_CYGNSS( &

! clean up

deallocate(timeintervals)
deallocate(latitudes)
deallocate(longitudes)
deallocate(tmp_sm)
deallocate(tmp_sigma)
deallocate(latitudes_m)
deallocate(longitudes_m)
deallocate(small_SM_range_flag)
deallocate(poor_SMAP_flag)
deallocate(high_ubrmsd_flag)
deallocate(few_obs_flag)
deallocate(low_signal_flag)
if (allocated(timeintervals)) deallocate(timeintervals)
if (allocated(latitudes)) deallocate(latitudes)
if (allocated(longitudes)) deallocate(longitudes)
if (allocated(tmp_sm)) deallocate(tmp_sm)
if (allocated(tmp_sigma)) deallocate(tmp_sigma)
if (allocated(latitudes_m)) deallocate(latitudes_m)
if (allocated(longitudes_m)) deallocate(longitudes_m)
if (allocated(small_SM_range_flag)) deallocate(small_SM_range_flag)
if (allocated(poor_SMAP_flag)) deallocate(poor_SMAP_flag)
if (allocated(high_ubrmsd_flag)) deallocate(high_ubrmsd_flag)
if (allocated(few_obs_flag)) deallocate(few_obs_flag)
if (allocated(low_signal_flag)) deallocate(low_signal_flag)

if (associated(tmp_obs)) deallocate(tmp_obs)
if (associated(tmp_lon)) deallocate(tmp_lon)
Expand Down Expand Up @@ -11069,4 +11078,3 @@ end program test
#endif

! ******* EOF *************************************************************