Skip to content

Commit 8944b82

Browse files
committed
Merge branch 'native_grids_viz' of github.com:E3SM-Project/e3sm_diags into native_grids_viz
2 parents d887088 + 8e5b847 commit 8944b82

File tree

39 files changed

+2907
-34
lines changed

39 files changed

+2907
-34
lines changed

.github/workflows/build_workflow.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,17 @@ jobs:
2929
uses: actions/checkout@v3
3030

3131
- if: ${{ steps.skip_check.outputs.should_skip != 'true' }}
32-
name: Set up Python 3.11
32+
name: Set up Python 3.13
3333
uses: actions/setup-python@v3
3434
with:
35-
python-version: "3.11"
35+
python-version: "3.13"
3636

3737
- if: ${{ steps.skip_check.outputs.should_skip != 'true' }}
3838
# Run all pre-commit hooks on all the files.
3939
# Getting only staged files can be tricky in case a new PR is opened
4040
# since the action is run on a branch in detached head state
4141
name: Install and Run Pre-commit
42-
uses: pre-commit/[email protected].0
42+
uses: pre-commit/[email protected].1
4343

4444
build:
4545
name: Build (Python ${{ matrix.python-version }})
@@ -50,7 +50,7 @@ jobs:
5050
shell: bash -l {0}
5151
strategy:
5252
matrix:
53-
python-version: ["3.10", "3.11", "3.12", "3.13"]
53+
python-version: ["3.11", "3.12", "3.13"]
5454
container:
5555
image: ghcr.io/e3sm-project/containers-e3sm-diags-test-data:e3sm-diags-test-data-0.0.2
5656
steps:

auxiliary_tools/cdat_regression_testing/940-xesmf-diffs/fix-polar-plots/25_08_27_regression_png.ipynb

Lines changed: 293 additions & 0 deletions
Large diffs are not rendered by default.

auxiliary_tools/cdat_regression_testing/940-xesmf-diffs/fix-polar-plots/v2_run_script.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
"""
2-
Source: /lcrc/group/e3sm/public_html/diagnostic_output/ac.forsyth2/zppy_weekly_comprehensive_v2_www/test_pr651_both_commits_20250117/v2.LR.historical_0201/e3sm_diags/atm_monthly_180x360_aave/model_vs_obs_1982-1983/prov/e3sm.py
2+
Source: /lcrc/group/e3sm/public_html/diagnostic_output/ac.forsyth2/zppy_weekly_comprehensive_v2_www/test_weekly_20250825/v2.LR.historical_0201/e3sm_diags/atm_monthly_180x360_aave/model_vs_obs_1982-1983/prov/e3sm.py
33
4-
Webpage: https://web.lcrc.anl.gov/public/e3sm/diagnostic_output/ac.forsyth2/zppy_weekly_comprehensive_v2_www/test_pr651_both_commits_20250117/v2.LR.historical_0201/e3sm_diags/atm_monthly_180x360_aave/model_vs_obs_1982-1983/prov/e3sm.py
4+
Webpage: https://web.lcrc.anl.gov/public/e3sm/diagnostic_output/ac.forsyth2/zppy_weekly_comprehensive_v2_www/test_weekly_20250825/v2.LR.historical_0201/e3sm_diags/atm_monthly_180x360_aave/model_vs_obs_1982-1983/prov/e3sm.py
55
66
Diffs: https://github.com/E3SM-Project/zppy/pull/651#issuecomment-2628445196
7-
/lcrc/group/e3sm/public_html/diagnostic_output/ac.forsyth2/zppy_weekly_comprehensive_v2_www/test_pr651_both_commits_20250117/v2.LR.historical_0201/image_check_failures_comprehensive_v2/e3sm_diags/atm_monthly_180x360_aave/model_vs_obs_1982-1983
7+
/lcrc/group/e3sm/public_html/diagnostic_output/ac.forsyth2/zppy_weekly_comprehensive_v2_www/test_weekly_20250825/v2.LR.historical_0201/image_check_failures_comprehensive_v2/e3sm_diags/atm_monthly_180x360_aave/model_vs_obs_1982-1983
88
99
ERA5-TREFHT-ANN-land.png
1010
ERA5_ext-QREFHT-ANN-global.png
@@ -44,7 +44,7 @@
4444
from e3sm_diags.run import runner
4545

4646
short_name = 'v2.LR.historical_0201'
47-
test_ts = '/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/test_pr651_both_commits_20250117/v2.LR.historical_0201/post/atm/180x360_aave/ts/monthly/2yr'
47+
test_ts = '/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/test_weekly_20250825/v2.LR.historical_0201/post/atm/180x360_aave/ts/monthly/2yr'
4848
start_yr = int('1982')
4949
end_yr = int('1983')
5050
num_years = end_yr - start_yr + 1
@@ -54,7 +54,7 @@
5454

5555
# Model
5656
# param.test_data_path = 'climo'
57-
param.test_data_path = "/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/test_pr651_both_commits_20250117/v2.LR.historical_0201/post/atm/180x360_aave/clim/2yr"
57+
param.test_data_path = "/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/test_weekly_20250825/v2.LR.historical_0201/post/atm/180x360_aave/clim/2yr"
5858
param.test_name = 'v2.LR.historical_0201'
5959
param.short_test_name = short_name
6060

@@ -66,7 +66,7 @@
6666

6767
# Output dir
6868
# param.results_dir = 'model_vs_obs_1982-1983'
69-
param.results_dir = "/lcrc/group/e3sm/public_html/cdat-migration-fy24/25-02-18-branch-939-polar"
69+
param.results_dir = "/lcrc/group/e3sm/public_html/cdat-migration-fy24/25-08-27-branch-945-xesmf-bnds"
7070

7171
# Additional settings
7272
param.run_type = 'model_vs_obs'
@@ -92,7 +92,7 @@
9292

9393
params.append(enso_param)
9494
trop_param = TropicalSubseasonalParameter()
95-
trop_param.test_data_path = '/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/test_pr651_both_commits_20250117/v2.LR.historical_0201/post/atm/180x360_aave/ts/daily/2yr'
95+
trop_param.test_data_path = '/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/test_weekly_20250825/v2.LR.historical_0201/post/atm/180x360_aave/ts/daily/2yr'
9696
trop_param.test_name = short_name
9797
trop_param.test_start_yr = f'{start_yr:04}'
9898
trop_param.test_end_yr = f'{end_yr:04}'
@@ -130,7 +130,7 @@
130130

131131
params.append(dc_param)
132132
streamflow_param = StreamflowParameter()
133-
streamflow_param.test_data_path = '/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/test_pr651_both_commits_20250117/v2.LR.historical_0201/post/rof/native/ts/monthly/2yr'
133+
streamflow_param.test_data_path = '/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/test_weekly_20250825/v2.LR.historical_0201/post/rof/native/ts/monthly/2yr'
134134
streamflow_param.test_name = short_name
135135
streamflow_param.test_start_yr = start_yr
136136
streamflow_param.test_end_yr = end_yr
@@ -142,7 +142,7 @@
142142

143143
params.append(streamflow_param)
144144
tc_param = TCAnalysisParameter()
145-
tc_param.test_data_path = "/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/test_pr651_both_commits_20250117/v2.LR.historical_0201/post/atm/tc-analysis_1982_1983"
145+
tc_param.test_data_path = "/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/test_weekly_20250825/v2.LR.historical_0201/post/atm/tc-analysis_1982_1983"
146146
tc_param.short_test_name = short_name
147147
tc_param.test_start_yr = "1982"
148148
tc_param.test_end_yr = "1983"
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#%%
2+
"""
3+
This script compares the latitude bounds generated by two different Python libraries, xCDAT and CDAT,
4+
when working with a NetCDF dataset. The purpose is to ensure consistency between the bounds added
5+
by xCDAT's `add_bounds` method and CDAT's `getBounds` method. The script performs the following steps:
6+
7+
1. Opens a NetCDF dataset containing climatological data using xCDAT and CDAT.
8+
2. Adds latitude bounds to the dataset using xCDAT.
9+
3. Retrieves latitude bounds from the dataset using CDAT.
10+
4. Compares the latitude bounds from both libraries using NumPy to verify their equality.
11+
12+
This comparison is useful for debugging and validating the behavior of the xCDAT library in handling
13+
latitude bounds, ensuring compatibility with CDAT's established functionality.
14+
15+
# conda create -n xcdat_cdat_latest python xcdat=0.8.0 cdms2=3.1.5 ipykernel
16+
"""
17+
import xcdat as xc
18+
import cdms2
19+
import numpy as np
20+
21+
filepath = (
22+
"/global/cfs/cdirs/e3sm/diagnostics/observations/Atm/climatology/"
23+
"GPCP_v3.2/GPCP_v3.2_ANN_198301_202112_climo.nc"
24+
)
25+
26+
#%%
27+
# Open the dataset using xCDAT and add bounds.
28+
ds_xc = xc.open_dataset(filepath, add_bounds=None)
29+
ds_xc_bnds = ds_xc.bounds.add_bounds(axis="Y")
30+
lat_bnds_xc = ds_xc_bnds["lat_bnds"]
31+
32+
# Open the dataset using CDAT and add bounds.
33+
ds_cd = cdms2.open(filepath)
34+
var = ds_cd["gauge_precip"]
35+
lat_bnds_cd = var.getLatitude().getBounds()
36+
37+
# %%
38+
# Compare the latitude bounds using numpy
39+
are_bounds_equal = np.allclose(lat_bnds_xc, lat_bnds_cd)
40+
41+
print("Are the latitude bounds equal?", are_bounds_equal)
42+
np.testing.assert_equal(lat_bnds_xc, lat_bnds_cd) # True
43+
44+
#%%
45+
print(lat_bnds_xc)
46+
print(lat_bnds_cd)
47+
# %%
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#%%
2+
import numpy as np
3+
import xarray as xr
4+
import xcdat as xc
5+
6+
ds_b = xr.open_dataset("/lcrc/group/e3sm/diagnostics/observations/Atm/climatology/GPCP_v3.2/GPCP_v3.2_ANN_198301_202112_climo.nc")
7+
8+
# Check for existing lat bounds -- False
9+
print("lat_bnds" in ds_b) # False
10+
11+
# Add lat bounds and check the orientation
12+
ds_b = ds_b.bounds.add_bounds(axis="Y")
13+
14+
#%%
15+
# Print the first 5 latitude coordinates of ds_b
16+
latitudes = ds_b["lat"].values
17+
print("\nLatitude Coordinates (First 5):")
18+
print(latitudes[:5])
19+
20+
# Check if latitude coordinates are ascending or descending
21+
lat_order = "ascending" if np.all(latitudes[:-1] <= latitudes[1:]) else "descending"
22+
print(f"Latitude coordinates are {lat_order}.")
23+
24+
# Print the first 5 latitude bounds of ds_b
25+
lat_bnds = ds_b["lat_bnds"].values
26+
print("\nLatitude Bounds (First 5):")
27+
for i, bounds in enumerate(lat_bnds[:5]):
28+
print(f"Bounds {i + 1}: {bounds}")
29+
30+
# Check if latitude bounds are ascending or descending
31+
bnds_order = "ascending" if np.all(lat_bnds[:, 0] <= lat_bnds[:, 1]) else "descending"
32+
print(f"Latitude bounds are {bnds_order}.")
33+
34+
# %%
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
"""
2+
This script demonstrates the behavior of the `cdms2` library in handling axis bounds,
3+
specifically for latitude axes. It includes tests to verify the automatic generation
4+
and preservation of bounds under different scenarios. The findings are summarized below:
5+
6+
1. **Automatic Bounds Generation**:
7+
- When a latitude axis is created without explicitly setting bounds,
8+
`cdms2` automatically generates bounds for the axis.
9+
10+
2. **Preservation of Existing Bounds**:
11+
- If bounds are explicitly set for a latitude axis, `cdms2` preserves
12+
these bounds without overwriting them.
13+
14+
3. **Bounds Preservation in NetCDF Files**:
15+
- When a latitude axis with explicitly set bounds is written to a NetCDF file
16+
and subsequently read back, the bounds are preserved as expected.
17+
18+
The script includes three tests:
19+
- **Test 1**: Verifies that bounds are auto-generated for a latitude axis.
20+
- **Test 2**: Confirms that explicitly set bounds for a latitude axis are preserved.
21+
- **Test 3**: Ensures that bounds for a latitude axis are preserved when written
22+
to and read from a NetCDF file.
23+
24+
cdms2.setAutoBounds(mode) controls automatic generation of bounds for axes:
25+
0 or 'off' = No bounds are generated automatically.
26+
1 or 'on' = Bounds are auto-generated for all 1D axes (if missing).
27+
2 or 'grid' = Bounds are auto-generated only for lat/lon axes (default).
28+
Use cdms2.getAutoBounds() to check the current setting.
29+
"""
30+
31+
# %%x
32+
import cdms2
33+
import numpy as np
34+
35+
# Check the current setting for auto bounds generation
36+
print(cdms2.getAutoBounds())
37+
# Expected output: 2 (default setting for lat/lon axes)
38+
39+
# %%
40+
# Test 1: Check if lat bounds are auto-generated with no bounds existing (True)
41+
# -----------------------------------------------------------------------------
42+
axis = cdms2.createAxis([0, 1, 2])
43+
axis.id = "lat" # Identify the axis as latitude
44+
45+
print(axis.getBounds()) # These are the auto-generated ones, not manually set.
46+
# [[0. 0.5]
47+
# [0.5 1.5]
48+
# [1.5 2.5]]
49+
50+
# %%
51+
# Test 2: Check if existing lat bounds are preserved (True)
52+
# -----------------------------------------------------------------------------
53+
axis = cdms2.createAxis([0, 1, 2])
54+
axis.id = "lat" # Identify the axis as latitude
55+
axis.setBounds(np.array([[0, 0.2], [0.5, 1.5], [1.5, 2.5]]))
56+
57+
print(axis.getBounds()) # These are the manually set ones.
58+
# [[0. 0.2]
59+
# [0.5 1.5]
60+
# [1.5 2.5]]
61+
62+
# %%
63+
# Test 3: Create a dummy netCDF file with lat axis, read it, and check bounds are preserved (True)
64+
# -----------------------------------------------------------------------------
65+
# Create a dummy netCDF file
66+
with cdms2.open("dummy.nc", "w") as f:
67+
lat = cdms2.createAxis([0, 1, 2])
68+
lat.id = "lat"
69+
lat.setBounds(np.array([[0, 0.2], [0.5, 1.5], [1.5, 2.5]]))
70+
71+
var = cdms2.createVariable([0, 1, 2], id="var", axes=[lat])
72+
f.write(var)
73+
74+
obj = cdms2.open("dummy.nc")["var"]
75+
76+
# %%
77+
print(obj.getLatitude().getBounds()) # These are the manually set ones.
78+
# [[0. 0.2]
79+
# [0.5 1.5]
80+
# [1.5 2.5]]
81+
82+
# %%

0 commit comments

Comments
 (0)