Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
a629ef2
cleaned up "domain" variables in ObsFcstAna postprocessing package
gmao-rreichle Jun 12, 2025
9267abb
add read_tilegrids() function
gmao-qliu Jun 16, 2025
60c3019
update tile2grid options
gmao-qliu Jun 16, 2025
0b81664
add tilegrid info. in config
gmao-qliu Jun 16, 2025
33b9123
add tilegrids info
gmao-qliu Jun 16, 2025
79ff6a1
change remap_1d_to_2d() to tile2grid()
gmao-qliu Jun 16, 2025
b706b90
correct module name for tile2grid
gmao-qliu Jun 16, 2025
861923b
change to save stats of individual species
gmao-qliu Jun 16, 2025
546733d
Merge branch 'develop' into feature/rreichle/postproc_ObsFcstAna_fixes
gmao-rreichle Jun 17, 2025
57bae3c
cleanup: corrected comments, removed redundant import statements, con…
gmao-rreichle Jun 17, 2025
25270fe
removed "qliu" from sample output path (user_config.py)
gmao-rreichle Jun 17, 2025
2a3d6e7
fixed vertical alignment (postproc_ObsFcstAna.py)
gmao-rreichle Jun 17, 2025
2423fb3
replaced variable name start/end/current_month with start/end/current…
gmao-rreichle Jun 17, 2025
80a68eb
clarify saved stats variables
gmao-qliu Jun 17, 2025
6237a89
minor changes in processing of temporal stats (postproc_ObsFcstAna.py…
gmao-rreichle Jun 17, 2025
a285d6a
fixed vertical alignment (Plot_stats_timeseries.py)
gmao-rreichle Jun 17, 2025
8df8196
dummy white-space change to facilitate Github comments (Get_ObsFcstAn…
gmao-rreichle Jun 17, 2025
719297b
Merge branch 'develop' into feature/rreichle/postproc_ObsFcstAna_fixes
gmao-rreichle Jun 18, 2025
4c9755d
Updated CHANGELOG.md
gmao-rreichle Jun 18, 2025
133eef9
added more 2D outputs to sample HISTORY.rc
weiyuan-jiang Jun 23, 2025
5160c6c
rename file and remove plotting options to avoid confusion
gmao-qliu Jun 23, 2025
4e04764
edit da_t0 for off-the-hour, move spatial stats time loop inside func…
gmao-qliu Jun 23, 2025
f82e55f
change 1-d to 2-d regridding
gmao-qliu Jun 23, 2025
54d822d
minor change
gmao-qliu Jun 23, 2025
6dfe1c3
minor clean up and move time loop out
gmao-qliu Jun 23, 2025
76ccea9
minor changes
gmao-qliu Jun 23, 2025
caa0f90
minor correction
gmao-qliu Jun 23, 2025
978fdbf
refactoring...
weiyuan-jiang Jun 23, 2025
f5fa08c
remove old file
gmao-qliu Jun 23, 2025
dc78876
corrected intro comments (Get_ObsFcstAna_sums.py)
gmao-rreichle Jun 24, 2025
387834b
revised computation of plotting grid spacing; removed obsolete functi…
gmao-rreichle Jun 24, 2025
abdeace
renamed tile_to_latlon.py -> tile_to_latlongrid.py for clarity
gmao-rreichle Jun 24, 2025
693ff65
add tile2grid.py; revised computation of spatial avg of temporal stat…
gmao-rreichle Jun 24, 2025
b4db565
minor fixes to comments, variable names, and vertical alignment (post…
gmao-rreichle Jun 24, 2025
65abe5e
cleaned up and simplified process_hist.csh (GEOSldas_HIST.rc, ldas_se…
gmao-rreichle Jun 24, 2025
1ed3029
edited CHANGELOG.md
gmao-rreichle Jun 24, 2025
33f2fca
add missing return line and minor edits
gmao-qliu Jun 24, 2025
88739fa
change max to mean tile values for grid
gmao-qliu Jun 24, 2025
bc8e44b
reverse comment change
gmao-qliu Jun 24, 2025
f97f620
nodata_tol -> nodata_tol_frac
gmao-qliu Jun 24, 2025
e07721c
fix imports, minor modification
gmao-qliu Jun 24, 2025
351e0a0
minimal edits of comments; white-space changes (Plot_stats_maps.py, t…
gmao-rreichle Jun 24, 2025
a48ac51
correction for missing files
gmao-qliu Jun 25, 2025
6293a9f
change loop order
gmao-qliu Jun 25, 2025
0df22b1
Revised processing of HISTORY template (#118)
gmao-rreichle Jun 25, 2025
6567edc
path fix for ncra
weiyuan-jiang Jun 25, 2025
34bd3e7
tg bug fix and typos
amfox37 Jun 25, 2025
b0b3ed1
quiet divide by nan
amfox37 Jun 25, 2025
a3ff296
fix path for ncra (#123)
gmao-rreichle Jun 25, 2025
145de6c
Merge branch 'develop' into feature/rreichle/postproc_ObsFcstAna_fixes
gmao-rreichle Jun 25, 2025
c287bc0
revisions of ObsFcstAna postprocessing package (#111)
gmao-rreichle Jun 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Added optional SLURM "constraint".
- Added functionality to run on tile space of stretched cube-sphere grids.
- Added python package for post-processing ObsFcstAna output.
- Added (and later revised) python package for post-processing ObsFcstAna output.


### Changed

- Revised processing of HISTORY template (GEOSldas_HIST.rc).
- Switch to using EASE grid tools in MAPL.
- Specify only ntasks_model for SLURM resource request.
- Revisions for handling of Nens and special nml and mwtrm path/files in coupled land-atm DAS.
- Updated some defaults in LDASsa_DEFAULT_inputs_*.nml files.

### Fixed

- Fixed ncra path for monthly compression
- Fixed error from MAPL's ApplicationSupport.F90 to init UDUNITS.

### Removed
Expand Down
74 changes: 42 additions & 32 deletions GEOSldas_App/GEOSldas_HIST.rc
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
# Sample HISTORY.rc file for GEOSldas
#
# This HISTORY template is edited by "ldas_setup" via "process_hist.csh".
# The strings '#ASSIM', '#EASE', and '#CUBE' are *not* linked to MAPL HISTORY
# functionality. For example, the line
# "#CUBE 'tavg24_2d_lnd_Nx'"
# does *not* mean that the 'lnd' output will be on a cube-sphere grid.

#CUBE VERSION: 1
VERSION: 1

# Must edit 'EXPID' manually if HISTORY file is re-used without going through "ldas_setup".

# Must edit 'EXPID' manually if HISTORY file is re-used without going
# through "ldas_setup".
#
EXPID: GEOSldas_expid

# ------------------------------------------------------------------------------------------------

# pre-defined Collections

COLLECTIONS:
#EASE 'tavg24_1d_lfs_Nt'
#CUBE 'tavg24_2d_lfs_Nx'
#EASE 'tavg24_1d_lnd_Nt'
#CUBE 'tavg24_2d_lnd_Nx'
#ASSIM 'SMAP_L4_SM_gph'
#OUT1d 'tavg24_1d_lfs_Nt'
#OUT2d 'tavg24_2d_lfs_Nx'
#OUT1d 'tavg24_1d_lnd_Nt'
#OUT2d 'tavg24_2d_lnd_Nx'
# 'SMAP_L4_SM_gph'
# 'inst1_1d_lnr_Nt'
# 'catch_progn_incr'
# 'inst3_1d_lndfcstana_Nt'
Expand All @@ -29,24 +28,34 @@ COLLECTIONS:
# 'tavg24_1d_glc_Nt'
::

#CUBE GRID_LABELS: PC720x361-DC
#CUBE PC1440x721-DC
# --------------------------------------------------------------------------------------------------

# 2d output can be on the following grids (see [COLLECTION_NAME].grid_label])

GRID_LABELS: PC720x361-DC
PC1440x721-DC
EASEv2_M36
::

PC720x361-DC.GRID_TYPE: LatLon
PC720x361-DC.IM_WORLD: 720
PC720x361-DC.JM_WORLD: 361
PC720x361-DC.POLE: PC
PC720x361-DC.DATELINE: DC
PC720x361-DC.LM: 1

#CUBE ::
PC1440x721-DC.GRID_TYPE: LatLon
PC1440x721-DC.IM_WORLD: 1440
PC1440x721-DC.JM_WORLD: 721
PC1440x721-DC.POLE: PC
PC1440x721-DC.DATELINE: DC
PC1440x721-DC.LM: 1

#CUBE PC720x361-DC.GRID_TYPE: LatLon
#CUBE PC720x361-DC.IM_WORLD: 720
#CUBE PC720x361-DC.JM_WORLD: 361
#CUBE PC720x361-DC.POLE: PC
#CUBE PC720x361-DC.DATELINE: DC
#CUBE PC720x361-DC.LM: 1
EASEv2_M36.GRID_TYPE: EASE
EASEv2_M36.GRIDNAME: EASEv2_M36
EASEv2_M36.LM: 1

#CUBE PC1440x721-DC.GRID_TYPE: LatLon
#CUBE PC1440x721-DC.IM_WORLD: 1440
#CUBE PC1440x721-DC.JM_WORLD: 721
#CUBE PC1440x721-DC.POLE: PC
#CUBE PC1440x721-DC.DATELINE: DC
#CUBE PC1440x721-DC.LM: 1
# --------------------------------------------------------------------------------------------------

# Detailed definition of the collections listed above
#
Expand Down Expand Up @@ -219,15 +228,16 @@ COLLECTIONS:

tavg24_2d_lnd_Nx.format: 'CFIO',
tavg24_2d_lnd_Nx.descr: '2d,Daily,Time-Averaged,Single-Level,Assimilation,Land Surface Diagnostics',
tavg24_2d_lnd_Nx.nbits: 12,
tavg24_2d_lnd_Nx.nbits: 12,
tavg24_2d_lnd_Nx.template: '%y4%m2%d2_%h2%n2z.nc4',
tavg24_2d_lnd_Nx.mode: 'time-averaged',
tavg24_2d_lnd_Nx.frequency: 240000,
tavg24_2d_lnd_Nx.ref_time: 000000,
tavg24_2d_lnd_Nx.regrid_exch: '../input/tile.data'
tavg24_2d_lnd_Nx.regrid_name: 'GRIDNAME'
tavg24_2d_lnd_Nx.regrid_exch: '../input/tile.data',
tavg24_2d_lnd_Nx.regrid_name: 'GRIDNAME',
# tavg24_2d_lnd_Nx.regrid_method: 'BILINEAR_MONOTONIC' ,
tavg24_2d_lnd_Nx.grid_label: PC720x361-DC
tavg24_2d_lnd_Nx.grid_label: PC720x361-DC,
# tavg24_2d_lnd_Nx.grid_label: EASEv2_M36,
tavg24_2d_lnd_Nx.deflate: 2,
tavg24_2d_lnd_Nx.fields: 'GRN' , 'VEGDYN' ,
'LAI' , 'VEGDYN' ,
Expand Down
18 changes: 12 additions & 6 deletions GEOSldas_App/ldas_setup
Original file line number Diff line number Diff line change
Expand Up @@ -1283,12 +1283,18 @@ class LDASsetup:
shutil.copy2(histrc_file,tmprcfile)
else :
shutil.copy2(histrc_file,tmprcfile)
GRID='EASE ' + self.rqdExeInp['GRIDNAME'] + ' ' +tmprcfile
if '-CF' in self.rqdExeInp['GRIDNAME'] :
GRID ='CUBE ' + self.rqdExeInp['GRIDNAME'] + ' ' +tmprcfile
_assim = '1' if self.assim else '0'
cmd =self.bindir +'/process_hist.csh '+ str(self.rqdExeInp['LSM_CHOICE']) + ' ' + str(self.rqdExeInp['AEROSOL_DEPOSITION']) + \
' ' + GRID + ' ' + str(self.rqdExeInp['RUN_IRRIG']) + ' ' + _assim + ' '+ str(self.nens)
if 'EASE' in self.rqdExeInp['GRIDNAME'] :
TMPSTR='OUT1d'
else :
TMPSTR='OUT2d'
cmd = self.bindir +'/process_hist.csh' + ' ' \
+ tmprcfile + ' ' \
+ TMPSTR + ' ' \
+ self.rqdExeInp['GRIDNAME'] + ' ' \
+ str(self.rqdExeInp['LSM_CHOICE']) + ' ' \
+ str(self.rqdExeInp['AEROSOL_DEPOSITION']) + ' ' \
+ str(self.rqdExeInp['RUN_IRRIG']) + ' ' \
+ str(self.nens)
print(cmd)
#os.system(cmd)
sp.call(shlex.split(cmd))
Expand Down
2 changes: 1 addition & 1 deletion GEOSldas_App/lenkf_j_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@
if($NAVAIL != $NDAYS) continue

# create monthly-mean nc4 file
ncra -h $EXPID.$ThisCol.${{YYYY}}${{MM}}*.nc4 ${{EXPID}}.${{ThisCol}}.monthly.$YYYY$MM.nc4
$BASEBIN/ncra -h $EXPID.$ThisCol.${{YYYY}}${{MM}}*.nc4 ${{EXPID}}.${{ThisCol}}.monthly.$YYYY$MM.nc4

if($POSTPROC_HIST == 2) then
# rudimentary check for desired nc4 file; if ok, delete daily files
Expand Down
94 changes: 51 additions & 43 deletions GEOSldas_App/process_hist.csh
Original file line number Diff line number Diff line change
@@ -1,56 +1,74 @@
#!/bin/csh -f

## I am changed the CUBE/EASE logic
## if CUBE we produce 2D
## anything else, SMAP and other offline grids we produce tile space

setenv LSM_CHOICE $1
setenv AEROSOL_DEPOSITION $2
setenv GRID $3
setenv GRIDNAME $4
setenv HISTRC $5
setenv RUN_IRRIG $6
setenv ASSIM $7
setenv NENS $8
# process GEOSldas_HIST.rc (=$HISTRC) template
#
# - turn on/off HIST collections depending on tile space
# - EASE: turn on tile-space (1d) output
# - otherwise: turn on gridded (2d) output
# - turn on/off output variables depending on LSM_CHOICE, AEROSOL_DEPOSITION, and RUN_IRRIG
# - fill in source 'GridComp' info for variables depending on NENS

# process command line args

setenv HISTRC $1 # file name of HIST rc template (GEOSldas_HIST.rc)
setenv OUTxd $2 # "OUT1d" or "OUT2d" (to turn on/off collections)
setenv GRIDNAME "'$3'" # full name of grid associated with tile space
setenv LSM_CHOICE $4
setenv AEROSOL_DEPOSITION $5
setenv RUN_IRRIG $6
setenv NENS $7

# -------------------------------------------------

echo $GRIDNAME

if($ASSIM == 1) then
sed -i 's|\#ASSIM|''|g' $HISTRC
sed -i '/^\#EASE/d' $HISTRC
sed -i '/^\#CUBE/d' $HISTRC
else
sed -i '/^\#ASSIM/d' $HISTRC
endif
# uncomment 2d or 1d collections, depending on "OUT1d" (EASE tile space) or "OUT2d" (non-EASE tile space)

if($GRID == CUBE) then
sed -i '/^\#EASE/d' $HISTRC
sed -i 's|\#CUBE|''|g' $HISTRC
sed -i 's|GRIDNAME|'"$GRIDNAME"'|g' $HISTRC
if($OUTxd == OUT1d) then
sed -i 's|\#OUT1d|''|g' $HISTRC
else
sed -i '/^\#CUBE/d' $HISTRC
sed -i 's|\#EASE|''|g' $HISTRC
sed -i 's|GRIDNAME|'"$GRIDNAME"'|g' $HISTRC
sed -i 's|\#OUT2d|''|g' $HISTRC
endif

# fill in name of grid associated with tile space

sed -i -e s/\'GRIDNAME\'/$GRIDNAME/g $HISTRC

# set 'GridComp' based on LSM_CHOICE;
# turn on/off variables associated with CATCHCN, AEROSOL_DEPOSITION, RUN_IRRIG

if($LSM_CHOICE == 1) then
set GridComp = CATCH
sed -i '/^>>>HIST_CATCHCN<<</d' $HISTRC
sed -i '/^>>>HIST_CATCHCNCLM45<<</d' $HISTRC
sed -i '/^>>>HIST_CATCHCN<<</d' $HISTRC
sed -i '/^>>>HIST_CATCHCNCLM45<<</d' $HISTRC
endif

if($LSM_CHOICE == 2) then
set GridComp = CATCHCN
sed -i '/^>>>HIST_CATCHCNCLM45<<</d' $HISTRC
sed -i 's/>>>HIST_CATCHCN<<</''/g' $HISTRC
sed -i '/^>>>HIST_CATCHCNCLM45<<</d' $HISTRC
sed -i 's/>>>HIST_CATCHCN<<</''/g' $HISTRC
endif

if($LSM_CHOICE == 3) then
set GridComp = CATCHCN
sed -i 's/>>>HIST_CATCHCN<<</''/g' $HISTRC
sed -i 's/>>>HIST_CATCHCN<<</''/g' $HISTRC
sed -i 's/>>>HIST_CATCHCNCLM45<<</''/g' $HISTRC
endif

if($AEROSOL_DEPOSITION == 0) then
sed -i '/^>>>HIST_AEROSOL<<</d' $HISTRC
else
sed -i 's/>>>HIST_AEROSOL<<</''/g' $HISTRC
endif

if($RUN_IRRIG == 0) then
sed -i '/^>>>HIST_IRRIG<<</d' $HISTRC
else
sed -i 's/>>>HIST_IRRIG<<</''/g' $HISTRC
endif

# for ensemble simulations, set 'GridComp' to ENSAVG

if($NENS > 1) then
set GridComp = ENSAVG
sed -i 's|VEGDYN|'VEGDYN_e0000'|g' $HISTRC
Expand All @@ -63,16 +81,6 @@ if($NENS > 1) then
# sed -i 's|DATAATM|'DATAATM0000'|g' $HISTRC
endif

sed -i 's|GridComp|'$GridComp'|g' $HISTRC
# fill in source 'GridComp' information for output variables

if($AEROSOL_DEPOSITION == 0) then
sed -i '/^>>>HIST_AEROSOL<<</d' $HISTRC
else
sed -i 's/>>>HIST_AEROSOL<<</''/g' $HISTRC
endif

if($RUN_IRRIG == 0) then
sed -i '/^>>>HIST_IRRIG<<</d' $HISTRC
else
sed -i 's/>>>HIST_IRRIG<<</''/g' $HISTRC
endif
sed -i 's|GridComp|'$GridComp'|g' $HISTRC
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,21 @@

"""
Sample script for post-processing GEOSldas ObsFcstAna output into data assimilation diagnostics.
First, compute and store monthly sums and sums of squares and cross-products of raw ObsFcstAna output.
Computes and stores monthly sums and sums of squares and cross-products of raw ObsFcstAna output.
Data assimilation diagnostics ("stats") such as the mean and std-dev of the observation-minus-forecast
residuals can then be diagnosed quickly from these intermediate "sums" files.
Sample script optionally computes and plots:
- Maps of long-term data assimilation diagnostics (see also Plot_stats_maps.py).
- Monthly time series of spatially averaged data assimilation diagnostics (see also Plot_stats_timeseries.py).
residuals can then be diagnosed quickly from these intermediate "sums" files. See Plot_stats_*.py.

Usage:
1. Edit "user_config.py" with experiments information.
2. Run this script as follows (on Discover):
$ module load python/GEOSpyD
$ ./Get_ObsFcstAna_stats.py
$ ./Get_ObsFcstAna_sums.py

# Background execution:
$ nohup ./Get_ObsFcstAna_stats.py > out.log &
$ nohup ./Get_ObsFcstAna_sums.py > out.log &

Authors: Q. Liu, R. Reichle, A. Fox
Last Modified: May 2025
Last Modified: June 2025
"""

import sys; sys.path.append('../../shared/python/')
Expand Down Expand Up @@ -64,33 +61,6 @@ def main():
# Compute and save monthly sums
postproc.save_monthly_sums()

# --------------------------------------------------------------------------------------
# Optionally compute long-term temporal/spatial statistics and create plots.
# The plotting scripts can also run standalone using the individual Plot_stats_*.py scripts,
# as long as the monthly sum files are available.

plot_maps = False
plot_timeseries = False

if plot_maps: # Compute long-term temporal stats and plot maps

stats_file = out_path + 'temporal_stats_'+exp_list[0]['exptag']+ '_'+start_time.strftime('%Y%m%d')+'_'+ \
(end_time+timedelta(days=-1)).strftime('%Y%m%d')+'.nc4'

# temporal_stats is a dictionary that contains all mean/variances fields for computing long-term O-F/O-A stats
# each field has the dimension [N_tile, N_species]

temporal_stats = postproc.calc_temporal_stats_from_sums(write_to_nc=True, fout_stats=stats_file)

# Example to plot some O-F maps
from Plot_stats_maps import plot_OmF_maps
plot_OmF_maps(postproc, temporal_stats, fig_path=out_path )

if plot_timeseries: # Compute spatially averaged stats and plot monthly time series of stats

from Plot_stats_timeseries import Plot_monthly_OmF_bars
Plot_monthly_OmF_bars(postproc, fig_path=out_path)

if __name__ == '__main__':
main()

Expand Down
Loading