Skip to content

Commit 77679c1

Browse files
authored
Merge pull request #90 from rubisco-sfa/ngeea
ADD: changes needed for NGEE-A
2 parents 69da277 + 3c0d2b8 commit 77679c1

File tree

6 files changed

+86
-17
lines changed

6 files changed

+86
-17
lines changed

ilamb3/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
units.define("Tg = 1e12 * g")
2121
units.define("Pg = 1e15 * g")
2222
units.define("Sv = 1e6 m**3 / s")
23+
units.define("gC = g")
2324
units.define("@alias W = Watt")
2425

2526
# we don't really have data versions for the collection :/

ilamb3/analysis/spatial_distribution.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ def __call__(
116116
# Spatial standard deviation
117117
ref_std = float(rref.std())
118118
com_std = float(rcom.std())
119+
if np.allclose(ref_std, 0):
120+
# There is no spatial variance for this region and we should skip
121+
continue
119122
norm_std = com_std / ref_std
120123

121124
# Correlation
@@ -170,6 +173,7 @@ def plots(
170173
) -> pd.DataFrame:
171174
# Add the Taylor diagram
172175
axs = []
176+
df = df[df["analysis"] == "Spatial Distribution"]
173177
for region in df["region"].unique():
174178
axs += [
175179
{
@@ -180,5 +184,5 @@ def plots(
180184
"axis": ilplt.plot_taylor_diagram(df[df["region"] == region]),
181185
}
182186
]
183-
axs = pd.DataFrame(axs).dropna(subset=["axis"])
187+
axs = pd.DataFrame(axs)
184188
return axs

ilamb3/compare.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,11 @@ def handle_timescale_mismatch(
295295
}
296296
)
297297
return ref, com
298+
if np.allclose(dt_ref, 30, atol=3) and dt_com < 28:
299+
com = dset.compute_monthly_mean(com)
300+
return ref, com
298301
raise NotImplementedError(
299-
f"We encountered a time scale mismatch that we have no logic to handle. {ref} {com}"
302+
f"We encountered a time scale mismatch ({dt_ref=:.1f} vs. {dt_com=:.1f}) that we have no logic to handle. {ref} {com}"
300303
)
301304

302305

@@ -327,8 +330,10 @@ def make_comparable(
327330
com = com.sortby([dset.get_dim_name(com, "lat"), dset.get_dim_name(com, "lon")])
328331

329332
# pick just the sites
330-
if dset.is_site(ref[varname]):
333+
if dset.is_site(ref[varname]) and dset.is_spatial(com[varname]):
331334
com = extract_sites(ref, com, varname)
335+
if dset.is_site(com[varname]) and dset.is_spatial(ref[varname]):
336+
ref = extract_sites(com, ref, varname)
332337

333338
# convert units
334339
com = dset.convert(com, ref[varname].attrs["units"], varname=varname)

ilamb3/dataset.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -864,18 +864,17 @@ def convert(
864864
xr.Dataset or xr.DataArray
865865
The converted dataset.
866866
"""
867-
dset = dset.pint.quantify()
868867
if isinstance(dset, xr.DataArray):
869868
da = dset
870869
else:
871870
assert varname is not None
872871
da = dset[varname]
872+
da = da.pint.quantify()
873873
da = scale_by_water_density(da, unit)
874874
da = da.pint.to(unit)
875875
if isinstance(dset, xr.DataArray):
876876
return da.pint.dequantify()
877-
dset[varname] = da
878-
dset = dset.pint.dequantify()
877+
dset[varname] = da.pint.dequantify()
879878
return dset
880879

881880

@@ -1007,3 +1006,18 @@ def compute_monthly_mean(ds: xr.Dataset) -> xr.Dataset:
10071006
raise ValueError(f"Input dataset is already coarser than monthly {dt=}.")
10081007
ds = ds.resample(time=xr.groupers.TimeResampler("MS")).mean()
10091008
return ds
1009+
1010+
1011+
def shift_time_by_years(ds: xr.Dataset, years: int) -> xr.Dataset:
1012+
"""
1013+
Return the dataset shifted by the given number of years.
1014+
"""
1015+
time_dim = get_dim_name(ds, "time")
1016+
cls = ds[time_dim].values[0].__class__
1017+
ds[time_dim] = [
1018+
cls(
1019+
t.dt.year + years, t.dt.month, t.dt.day, t.dt.hour, t.dt.minute, t.dt.second
1020+
)
1021+
for t in ds[time_dim]
1022+
]
1023+
return ds

ilamb3/run.py

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,21 @@ def _fix(units: str) -> str:
4949
return ds
5050

5151

52+
def fix_lndgrid_coords(ds: xr.Dataset) -> xr.Dataset:
53+
"""
54+
Return a dataset with coordinates properly assigned.
55+
56+
Note
57+
----
58+
E3SM/CESM2 raw land model output comes as if it were run over sites in the
59+
`lndgrid` dimension. Some of the variables that are listed in these files
60+
are only of this dimension and really belong in the coordinates. These tend
61+
to be things like `lat`, `lon`, etc. and ilamb3 needs them to be associated
62+
with the dataset coordinates to work.
63+
"""
64+
return ds.assign_coords({v: ds[v] for v in ds if ds[v].dims == ("lndgrid",)})
65+
66+
5267
def select_analysis_variable(setup: dict[str, Any]) -> str:
5368
"""
5469
Return the main variable to be used in this analysis.
@@ -358,6 +373,8 @@ def _load_comparison_data(
358373
# Fix bounds attributes (there is a bounds variable but it isn't in the
359374
# attributes)
360375
com = {var: dset.fix_missing_bounds_attrs(ds) for var, ds in com.items()}
376+
# Fix lndgrid cooridates if raw E3SM/CESM2 data is given
377+
com = {var: fix_lndgrid_coords(ds) for var, ds in com.items()}
361378
# Merge all the data together
362379
if len(com) > 1:
363380
# The grids should be the same, but sometimes models generate output
@@ -547,21 +564,34 @@ def run_single_block(
547564
"Reference intermediate data was not generated."
548565
) # pragma: no cover
549566

567+
log_file = output_path / "post.log"
568+
log_id = logger.add(log_file, backtrace=True, diagnose=True)
569+
550570
# Phase 2: get plots and combine scalars and save
551-
plt.rcParams.update({"figure.max_open_warning": 0})
552-
df = pd.concat(df_all).drop_duplicates(
553-
subset=["source", "region", "analysis", "name"]
554-
)
555-
df = add_overall_score(df)
556-
df_plots = plot_analyses(df, ds_ref, ds_com, analyses, output_path)
571+
try:
572+
plt.rcParams.update({"figure.max_open_warning": 0})
573+
df = pd.concat(df_all).drop_duplicates(
574+
subset=["source", "region", "analysis", "name"]
575+
)
576+
df = add_overall_score(df)
577+
df_plots = plot_analyses(df, ds_ref, ds_com, analyses, output_path)
578+
except Exception:
579+
logger.exception(f"ILAMB analysis '{block_name}' failed in plotting.")
580+
return
557581

558582
# Generate an output page
559-
if ilamb3.conf["debug_mode"] and (output_path / "index.html").is_file():
583+
try:
584+
if ilamb3.conf["debug_mode"] and (output_path / "index.html").is_file():
585+
logger.remove(log_id)
586+
return
587+
ds_ref.attrs["header"] = block_name
588+
html = generate_html_page(df, ds_ref, ds_com, df_plots)
589+
with open(output_path / "index.html", mode="w") as out:
590+
out.write(html)
591+
except Exception:
592+
logger.exception(f"ILAMB analysis '{block_name}' failed in generating html.")
560593
return
561-
ds_ref.attrs["header"] = block_name
562-
html = generate_html_page(df, ds_ref, ds_com, df_plots)
563-
with open(output_path / "index.html", mode="w") as out:
564-
out.write(html)
594+
logger.remove(log_id)
565595

566596

567597
def run_analyses(

ilamb3/templates/directory.html

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<title>Directory of Benchmarking Results</title>
7+
</head>
8+
<body>
9+
<ul>
10+
{% for name,link in links.items() %}
11+
<li><a href="{{link}}">{{name}}</a></li>
12+
{% endfor %}
13+
</ul>
14+
</body>
15+
</html>

0 commit comments

Comments
 (0)