Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include ILAMB output in notebook and provide link to full diagnostic package #165

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
daafc0b
preliminary ilamb update attempts
TeaganKing Jan 15, 2025
eae2ea4
update instructions for qinteractive ilamb
TeaganKing Jan 15, 2025
dcfc44a
helper script ilamb working
TeaganKing Jan 16, 2025
2e72ef3
updates for ilamb
TeaganKing Jan 21, 2025
39d155a
formatting
TeaganKing Jan 21, 2025
6fa116d
include ILAMB_output in gitignore
TeaganKing Jan 21, 2025
df797d1
move cfg files ilamb
TeaganKing Jan 21, 2025
caa2598
ilamb link is working now
TeaganKing Jan 16, 2025
2b2ccf1
plots working in line for ilamb
TeaganKing Jan 16, 2025
7f68daa
update key ilamb plots
TeaganKing Jan 21, 2025
c18fd96
update ilamb plots in config file
TeaganKing Jan 21, 2025
efb9bc3
remove prints and move key plots to parameter cell
TeaganKing Jan 21, 2025
96de2d4
list plots in config file for adf and ilamb
TeaganKing Jan 21, 2025
576d629
update notebook half of last commit
TeaganKing Jan 21, 2025
aadfbd1
include regrid dir and correct cupid example dir
TeaganKing Jan 21, 2025
718d4ed
ilamb updates per discussion at cupid meeting
TeaganKing Jan 22, 2025
b726b7d
include updates to other ilamb config files
TeaganKing Jan 24, 2025
3ba5df7
fix precommit
TeaganKing Jan 24, 2025
5e66869
add ilamb into key metrics and a couple minor fixes
TeaganKing Jan 24, 2025
927780b
update gitignroes
TeaganKing Jan 24, 2025
b1f14a8
include score chart as hidden option
TeaganKing Jan 24, 2025
65b8a6c
update helper script command suggestion
TeaganKing Jan 30, 2025
cf71813
remove ilamb from key metrics
TeaganKing Jan 30, 2025
20d8b76
use example root
TeaganKing Jan 30, 2025
6dcbe48
include regridding note, typo fix
TeaganKing Feb 5, 2025
b5ee7fa
fixes from review
TeaganKing Feb 7, 2025
4c8c87f
remove prints and typo fix
TeaganKing Feb 7, 2025
28d6771
Update generate_ilamb_config_files.py to use ilamb config loc
TeaganKing Feb 7, 2025
c07722e
fix parantheses
TeaganKing Feb 7, 2025
cab3e5b
add path existence check for copying adf/ilamb output
TeaganKing Feb 7, 2025
cec63e3
include warning in case ilamb output dir already exist, as this is a …
TeaganKing Feb 13, 2025
38964d8
formatting
TeaganKing Feb 13, 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
11 changes: 11 additions & 0 deletions cupid/cupid_webpage.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ def build(config_path):
f"{run_dir}/ADF_output",
f"{run_dir}/computed_notebooks/_build/html/ADF",
)
if "external_tool" in control["compute_notebooks"][component][notebook]:
if (
Comment on lines +63 to +64
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think line 63 is necessary, it's the same if statement as line 51. Removing it will let us change the current line 64 to an else-if, since control["compute_notebooks"][component][notebook]["external_tool"].get("tool_name") can't be "ILAMB" if it is "ADF".

control["compute_notebooks"][component][notebook][
"external_tool"
].get("tool_name")
== "ILAMB"
):
shutil.copytree(
f"{run_dir}/ILAMB_output",
f"{run_dir}/computed_notebooks/_build/html/ILAMB",
)

# Originally used this code to copy jupyter book HTML to a location to host it online

Expand Down
2 changes: 2 additions & 0 deletions examples/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
*/ADF_output
*/ILAMB_output
*/model_setup.txt
76 changes: 15 additions & 61 deletions examples/external_diag_packages/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,58 +115,24 @@ compute_notebooks:
parameter_groups:
none:
adf_root: ../../examples/external_diag_packages/ADF_output/
key_plots: ["Surface_Wind_Stress_ANN_LatLon_Vector_Mean.png", "PRECT_ANN_LatLon_Mean.png", "PS_DJF_SHPolar_Mean.png", "TaylorDiag_ANN_Special_Mean.png"]
external_tool:
tool_name: 'ADF'
vars: ['PRECT', 'SST']
plotting_scripts: ["global_latlon_map", "global_latlon_vect_map"]
analysis_scripts: ["amwg_table"]
base_regridded_output: True

# glc:
# LIWG_SMB_diagnostic:
# parameter_groups:
# none:
# obs_path: '/glade/u/home/gunterl/obs_diagnostic_cesm/'
# obs_name: 'GrIS_MARv3.12_climo_1960_1999.nc'
# climo_nyears: 40

# ice:
# seaice:
# parameter_groups:
# none:
# cases:
# - g.e23_a16g.GJRAv4.TL319_t232_hycom1_N75.2024.005
# - g.e23_a16g.GJRAv4.TL319_t232_zstar_N65.2024.004
# begyr1: 245
# endyr1: 305
# begyr2: 245
# endyr2: 305
# nyears: 25

# lnd:
# land_comparison:
# parameter_groups:
# none:
# cases:
# - ctsm51d159_f45_GSWP3_bgccrop_1850pAD
# - ctsm51d159_f45_GSWP3_bgccrop_1850pSASU
# type:
# - 1850pAD
# - 1850pSASU

# ocn:
# ocean_surface:
# parameter_groups:
# none:
# Case: b.e23_alpha16b.BLT1850.ne30_t232.054
# savefigs: False
# mom6_tools_config:
# start_date: '0091-01-01'
# end_date: '0101-01-01'
# Fnames:
# native: 'mom6.h.native.????-??.nc'
# static: 'mom6.h.static.nc'
# oce_cat: /glade/u/home/gmarques/libs/oce-catalogs/reference-datasets.yml
lnd:
link_to_ILAMB:
parameter_groups:
none:
ilamb_root: ../../examples/external_diag_packages/ILAMB_output
key_plots: ["EcosystemandCarbonCycle/GrossPrimaryProductivity/FLUXCOM/CTSM51_global_bias.png", "EcosystemandCarbonCycle/LeafAreaIndex/AVHRR/CTSM51_global_bias.png", "EcosystemandCarbonCycle/GlobalNetEcosystemCarbonBalance/GCP/CTSM51_global_accumulate.png", "ILAMB_output_backup/HydrologyCycle/Permafrost/Brown2002/CTSM51_global_bias.png"]
print_table: False
external_tool:
tool_name: 'ILAMB'
ilamb_config_data_loc: '/glade/campaign/cesm/community/lmwg/diag/ILAMB/'

########### JUPYTER BOOK CONFIG ###########

Expand All @@ -192,23 +158,11 @@ book_toc:

- caption: Atmosphere
chapters:
- file: atm/link_to_ADF

# - caption: Ocean
# chapters:
# - file: ocn/ocean_surface
- file: atm/link_to_ADF
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the spacing changed here? comparing old line 195 to new line 161 I see

-         - file: atm/link_to_ADF
+        - file: atm/link_to_ADF


# - caption: Land
# chapters:
# - file: lnd/land_comparison

# - caption: Sea Ice
# chapters:
# - file: ice/seaice

# - caption: Land Ice
# chapters:
# - file: glc/LIWG_SMB_diagnostic
- caption: Land
chapters:
- file: lnd/link_to_ILAMB

#####################################
# Keys for Jupyter Book _config.yml #
Expand Down
1 change: 0 additions & 1 deletion examples/ilamb/.gitignore

This file was deleted.

5 changes: 0 additions & 5 deletions examples/ilamb/test_run.sh

This file was deleted.

1 change: 1 addition & 0 deletions examples/key_metrics/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ compute_notebooks:
parameter_groups:
none:
adf_root: ../../examples/key_metrics/ADF_output/
key_plots: ["Surface_Wind_Stress_ANN_LatLon_Vector_Mean.png", "PRECT_ANN_LatLon_Mean.png", "PS_DJF_SHPolar_Mean.png", "TaylorDiag_ANN_Special_Mean.png"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised these weren't already included in the config.yml, thanks for getting rid of the hard-coded list and replacing it with something configurable!

external_tool:
tool_name: 'ADF'
vars: ['SST', 'TS', 'SWCF', 'LWCF', 'PRECT', 'TAUX', 'TAUY', 'TGCLDLWP']
Expand Down
2 changes: 2 additions & 0 deletions helper_scripts/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
*.cfg
*.txt
*.yml
128 changes: 128 additions & 0 deletions helper_scripts/generate_ilamb_config_files.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#!/usr/bin/env python3
from __future__ import annotations

import argparse
import os
import sys

import yaml


def _parse_args():
"""Parse command line arguments"""

parser = argparse.ArgumentParser(
description="Generate an ILAMB model_setup.txt file based on an existing CUPID YAML file",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
# Command line argument for location of CESM source code (required)
parser.add_argument(
"--cesm-root",
action="store",
dest="cesm_root",
required=True,
help="Location of CESM source code",
)
# Command line argument for CUPiD example from which to get config.yml
parser.add_argument(
"--cupid-config-loc",
action="store",
dest="cupid_config_loc",
default=None,
help="CUPiD config file to use information from for model_setup.txt",
)
parser.add_argument(
"--run-type",
action="store",
required=True,
help="either 'BGC' (biogeochemistry) or 'SP' (satellite phenology)",
)
return parser.parse_args()


def generate_ilamb_cfg(cesm_root, cupid_config_loc, run_type):
"""Create config file for use in ILAMB"""
sys.path.append(os.path.join(cesm_root, "cime"))

cupid_root = os.path.join(cesm_root, "tools", "CUPiD")
# Is cupid_config_loc a valid value?
if cupid_config_loc is None:
cupid_config_loc = os.path.join(cupid_root, "examples", "key_metrics")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this default be "external_diag_packages" instead of key_metrics since we won't be able to add link_to_ILAMB.ipynb in this PR?

if not os.path.exists(os.path.join(cupid_config_loc, "config.yml")):
raise KeyError(f"Can not find config.yml in {cupid_config_loc}")

with open(os.path.join(cupid_config_loc, "config.yml")) as c:
c_dict = yaml.safe_load(c)
ilamb_config_data_loc = c_dict["compute_notebooks"]["lnd"]["link_to_ILAMB"][
"external_tool"
]["ilamb_config_data_loc"]

ilamb_config_loc = os.path.join(cesm_root, "tools", "CUPiD", "ilamb_aux")
print(run_type)
with open(
os.path.join(
ilamb_config_loc,
f"ilamb_nohoff_final_CLM_{run_type}_template.cfg",
),
) as cfg:
cfg_content = cfg.read()
cfg_content = cfg_content.replace("PATH/", ilamb_config_data_loc)
print(f"writing ilamb_nohoff_final_CLM_{run_type}.cfg")
with open(
os.path.join(ilamb_config_loc, f"ilamb_nohoff_final_CLM_{run_type}.cfg"),
"w",
) as cfg:
cfg.write(cfg_content)
print(f"wrote {ilamb_config_loc}/ilamb_nohoff_final_CLM_{run_type}.cfg")


def generate_ilamb_model_setup(cesm_root, cupid_config_loc, run_type):
"""Create model_setup.txt file for use in ILAMB"""
sys.path.append(os.path.join(cesm_root, "cime"))

cupid_root = os.path.join(cesm_root, "tools", "CUPiD")
# Is cupid_config_loc a valid value?
if cupid_config_loc is None:
cupid_config_loc = os.path.join(cupid_root, "examples", "key_metrics")
if not os.path.exists(os.path.join(cupid_config_loc, "config.yml")):
raise KeyError(f"Can not find config.yml in {cupid_config_loc}")

with open(os.path.join(cupid_config_loc, "config.yml")) as c:
c_dict = yaml.safe_load(c)
base_case_output_dir = os.path.join(
c_dict["global_params"]["CESM_output_dir"],
c_dict["global_params"]["base_case_name"],
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the spec, users can specify c_dict["global_params"]["base_case_output_dir"] if the baseline is not in the same directory as the experimental case... so I think you want something like:

if "base_case_output_dir" in c_dict["global_params"]:
    base_case_output_dir = os.path.join(
        c_dict["global_params"]["base_case_output_dir"],
        c_dict["global_params"]["base_case_name"],
    )
else:
    base_case_output_dir = os.path.join(
        c_dict["global_params"]["CESM_output_dir"],
        c_dict["global_params"]["base_case_name"],
    )

with open(cupid_config_loc + "model_setup.txt", "w") as ms:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be os.path.join(cupid_config_loc, "model_setup.txt") instead of cupid_config_loc + "model_setup.txt" -- cupid_config_loc isn't guaranteed to have the trailing /

ms.write(
"# Model Name , Location of Files , Shift From, Shift To\n", # noqa: E501
)
ms.write(
f"CTSM51 , {base_case_output_dir}/lnd/hist/regrid/",
Copy link
Collaborator Author

@TeaganKing TeaganKing Jan 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should add some sort of "if regrid" then append the regrid directory here. Perhaps this would be useful to in the long term create the regridded files if they don't yet exist, and in the short term print out a "warning: please run regridding with command below"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a note that regridded files are required

) # TODO: aslo update model name? Add to cupid config file?
print(f"wrote {cupid_config_loc}model_setup.txt")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment about using os.path.join because cupid_config_loc might not have the trailing /

print("You can now run ILAMB with the following commands:")
print("---")
print("qinteractive -l select=1:ncpus=16:mpiprocs=16:mem=100G -l walltime=06:00:00")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The qinteractive is only necessary on the NCAR computers. Maybe we could do something like

print("You can now run ILAMB with the following commands:")
print("(Users on a super computer should make sure they are on a compute node rather than a login node)")
print("---")

I'm not sure what to do about the fact that we're having trouble with MPI on derecho and casper; in general, users will need the mpiexec but for now it's probably okay to stick with the serial recommendation

print("conda activate cupid-analysis")
print("export ILAMB_ROOT=../ilamb_aux")
if run_type == "SP":
print(
f"ilamb-run --config ../ilamb_aux/ilamb_nohoff_final_CLM_SP.cfg --build_dir {cupid_config_loc}ILAMB_output/ --df_errs ../ilamb_aux/quantiles_Whittaker_cmip5v6.parquet --define_regions ../ilamb_aux/DATA/regions/LandRegions.nc ../ilamb_aux/DATA/regions/Whittaker.nc --regions global --model_setup {cupid_config_loc}odel_setup.txt --filter .clm2.h0.", # noqa: E501
TeaganKing marked this conversation as resolved.
Show resolved Hide resolved
)
elif run_type == "BGC":
print(
f"ilamb-run --config ../ilamb_aux/ilamb_nohoff_final_CLM_BGC.cfg --build_dir {cupid_config_loc}ILAMB_output/ --df_errs ../ilamb_aux/quantiles_Whittaker_cmip5v6.parquet --define_regions ../ilamb_aux/DATA/regions/LandRegions.nc ../ilamb_aux/DATA/regions/Whittaker.nc --regions global --model_setup {cupid_config_loc}model_setup.txt --filter .clm2.h0.", # noqa: E501
)
print("---------")


if __name__ == "__main__":
args = vars(_parse_args())
print(args)
generate_ilamb_cfg(args["cesm_root"], args["cupid_config_loc"], args["run_type"])
generate_ilamb_model_setup(
args["cesm_root"],
args["cupid_config_loc"],
args["run_type"],
)
2 changes: 2 additions & 0 deletions ilamb_aux/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ilamb_nohoff_final_CLM_BGC.cfg
ilamb_nohoff_final_CLM_SP.cfg
Loading