Skip to content

Commit 8464969

Browse files
authored
Merge pull request NCAR#161 from mnlevy1981/workflow_updates
Workflow updates
2 parents 6cba064 + f5bd90a commit 8464969

9 files changed

+106
-67
lines changed

cupid/run_timeseries.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,10 @@ def run_timeseries(
112112
if isinstance(timeseries_params["case_name"], list):
113113
ts_input_dirs = []
114114
for cname in timeseries_params["case_name"]:
115-
ts_input_dirs.append(global_params["CESM_output_dir"]+"/"+cname+f"/{component}/hist/")
115+
if cname == global_params["base_case_name"]:
116+
ts_input_dirs.append(global_params["base_case_output_dir"]+"/"+cname+f"/{component}/hist/")
117+
else:
118+
ts_input_dirs.append(global_params["CESM_output_dir"]+"/"+cname+f"/{component}/hist/")
116119
else:
117120
ts_input_dirs = [
118121
global_params["CESM_output_dir"] + "/" +

cupid/timeseries.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def create_time_series(
111111

112112
# Check that path actually exists:
113113
if not starting_location.is_dir():
114-
emsg = "Provided 'cam_hist_loc' directory '{starting_location}' not found."
114+
emsg = f"Provided 'cam_hist_loc' directory '{starting_location}' not found."
115115
emsg += " Script is ending here."
116116

117117
raise FileNotFoundError(emsg)

examples/key_metrics/config.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ compute_notebooks:
142142
Greenland_SMB_visual_compare_obs:
143143
parameter_groups:
144144
none:
145-
obs_path: '/glade/u/home/gunterl/obs_diagnostic_cesm/'
145+
obs_path: '/glade/campaign/cesm/development/cross-wg/diagnostic_framework/SMB_data'
146146
obs_name: 'GrIS_MARv3.12_climo_1960_1999.nc'
147147
climo_nyears: 40
148148

helper_scripts/generate_adf_config_file.py

+18-27
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ def _parse_args():
2525
)
2626
# Command line argument for CUPiD example from which to get config.yml
2727
parser.add_argument(
28-
"--cupid-example",
28+
"--cupid-config-loc",
2929
action="store",
30-
dest="cupid_example",
31-
default="external_diag_packages",
30+
dest="cupid_config_loc",
31+
default=None,
3232
help="CUPiD example to use as template for config.yml",
3333
)
3434
parser.add_argument(
@@ -46,27 +46,20 @@ def _parse_args():
4646
return parser.parse_args()
4747

4848

49-
def generate_adf_config(cesm_root, cupid_example, adf_file, out_file):
50-
"""Use cupid config file (YAML) from cupid_example and adf_file (YAML)
49+
def generate_adf_config(cesm_root, cupid_config_loc, adf_file, out_file):
50+
"""Use cupid config file (YAML) from cupid_config_loc and adf_file (YAML)
5151
to produce out_file by modifying adf_file with data from cupid config file.
5252
"""
5353
sys.path.append(os.path.join(cesm_root, "cime"))
5454

55-
# Is cupid_example a valid value?
5655
cupid_root = os.path.join(cesm_root, "tools", "CUPiD")
57-
cupid_examples = os.path.join(cupid_root, "examples")
58-
valid_examples = [
59-
example
60-
for example in next(os.walk(cupid_examples))[1]
61-
if example not in ["ilamb"]
62-
]
63-
if cupid_example not in valid_examples:
64-
error_msg = f"argument --cupid-example: invalid choice '{cupid_example}'"
65-
raise KeyError(
66-
f"{error_msg} (choose from subdirectories of {cupid_examples}: {valid_examples})",
67-
)
56+
# Is cupid_config_loc a valid value?
57+
if cupid_config_loc is None:
58+
cupid_config_loc = os.path.join(cupid_root, "examples", "key_metrics")
59+
if not os.path.exists(os.path.join(cupid_config_loc, "config.yml")):
60+
raise KeyError(f"Can not find config.yml in {cupid_config_loc}")
6861

69-
with open(os.path.join(cupid_root, "examples", cupid_example, "config.yml")) as c:
62+
with open(os.path.join(cupid_config_loc, "config.yml")) as c:
7063
c_dict = yaml.safe_load(c)
7164
with open(adf_file, encoding="UTF-8") as a:
7265
a_dict = yaml.safe_load(a)
@@ -141,9 +134,9 @@ def generate_adf_config(cesm_root, cupid_example, adf_file, out_file):
141134
ts_case_names.index(base_case_name) if base_case_name in ts_case_names else None
142135
)
143136

144-
base_case_output_dir = c_dict["global_params"].get(
145-
"base_case_output_dir",
146-
DOUT + "/" + base_case_name,
137+
base_case_output_dir = os.path.join(
138+
c_dict["global_params"].get("base_case_output_dir", DOUT),
139+
base_case_name,
147140
)
148141
base_start_date = get_date_from_ts(
149142
c_ts["atm"],
@@ -208,9 +201,7 @@ def generate_adf_config(cesm_root, cupid_example, adf_file, out_file):
208201
"regrid",
209202
) # This is where ADF will make "regrid" files
210203
a_dict["diag_basic_info"]["cam_diag_plot_loc"] = os.path.join(
211-
cupid_root,
212-
"examples",
213-
cupid_example,
204+
cupid_config_loc,
214205
"ADF_output",
215206
) # this is where ADF will put plots, and "website" directory
216207
a_dict["user"] = os.environ["USER"]
@@ -255,10 +246,10 @@ def generate_adf_config(cesm_root, cupid_example, adf_file, out_file):
255246
f.write(
256247
"# This file has been auto-generated using generate_adf_config_file.py\n",
257248
)
258-
f.write(f"# It is based off of examples/{cupid_example}/config.yml\n")
249+
f.write(f"# It is based off of {cupid_config_loc}/config.yml\n")
259250
f.write("# Arguments:\n")
260251
f.write(f"# {cesm_root=}\n")
261-
f.write(f"# {cupid_example=}\n")
252+
f.write(f"# {cupid_config_loc=}\n")
262253
f.write(f"# {adf_file=}\n")
263254
f.write(f"# Output: {out_file=}\n")
264255
# enter in each element of the dictionary into the new file
@@ -284,7 +275,7 @@ def get_date_from_ts(data: dict, keyname: str, listindex: int, default=None):
284275
print(args)
285276
generate_adf_config(
286277
args["cesm_root"],
287-
args["cupid_example"],
278+
args["cupid_config_loc"],
288279
args["adf_template"],
289280
args["out_file"],
290281
)

helper_scripts/generate_cupid_config_for_cesm_case.py

+29-6
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,11 @@ def generate_cupid_config(case_root, cesm_root, cupid_example):
108108
dout_s_root = cesm_case.get_value("DOUT_S_ROOT")
109109

110110
# Additional options we need to get from env_cupid.xml
111+
base_case = "b.e23_alpha17f.BLT1850.ne30_t232.092"
111112
nyears = 1
112113
start_date = "0001-01-01"
113114
end_date = f"{nyears+1:04d}-01-01"
114-
climo_nyears = 1
115+
climo_nyears = nyears
115116
base_case_output_dir = "/glade/campaign/cesm/development/cross-wg/diagnostic_framework/CESM_output_for_testing"
116117
base_nyears = 100
117118
base_end_date = f"{base_nyears+1:04d}-01-01"
@@ -120,18 +121,40 @@ def generate_cupid_config(case_root, cesm_root, cupid_example):
120121
with open(os.path.join(cupid_root, "examples", cupid_example, "config.yml")) as f:
121122
my_dict = yaml.safe_load(f)
122123

124+
my_dict["data_sources"]["nb_path_root"] = os.path.join(
125+
cesm_root,
126+
"tools",
127+
"CUPiD",
128+
"nblibrary",
129+
)
123130
my_dict["global_params"]["case_name"] = case
124131
my_dict["global_params"]["start_date"] = start_date
125132
my_dict["global_params"]["end_date"] = end_date
126-
my_dict["global_params"]["climo_nyears"] = climo_nyears
133+
my_dict["global_params"]["base_case_name"] = base_case
127134
my_dict["global_params"]["base_case_output_dir"] = base_case_output_dir
128135
my_dict["global_params"]["base_end_date"] = base_end_date
129-
my_dict["global_params"]["base_climo_nyears"] = base_climo_nyears
130-
my_dict["timeseries"]["case_name"] = case
131-
my_dict["timeseries"]["atm"]["end_years"] = [nyears, base_nyears]
136+
my_dict["timeseries"]["case_name"] = [case, base_case]
137+
138+
for component in my_dict["timeseries"]:
139+
if (
140+
isinstance(my_dict["timeseries"][component], dict)
141+
and "end_years" in my_dict["timeseries"][component]
142+
):
143+
my_dict["timeseries"][component]["end_years"] = [nyears, base_nyears]
144+
if "link_to_ADF" in my_dict["compute_notebooks"]["atm"]:
145+
my_dict["compute_notebooks"]["atm"]["link_to_ADF"]["parameter_groups"]["none"][
146+
"adf_root"
147+
] = os.path.join(case_root, "ADF_output")
148+
if "Greenland_SMB_visual_compare_obs" in my_dict["compute_notebooks"]["glc"]:
149+
my_dict["compute_notebooks"]["glc"]["Greenland_SMB_visual_compare_obs"][
150+
"parameter_groups"
151+
]["none"]["climo_nyears"] = climo_nyears
152+
my_dict["compute_notebooks"]["glc"]["Greenland_SMB_visual_compare_obs"][
153+
"parameter_groups"
154+
]["none"]["base_climo_nyears"] = base_climo_nyears
132155

133156
# replace with environment variable
134-
my_dict["global_params"]["CESM_output_dir"] = dout_s_root
157+
my_dict["global_params"]["CESM_output_dir"] = os.path.dirname(dout_s_root)
135158

136159
# create new file, make it writeable
137160
with open("config.yml", "w") as f:

nblibrary/atm/Global_PSL_NMSE_compare_obs_lens.ipynb

+1-1
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@
204204
" fix_time_dim(\n",
205205
" xr.open_mfdataset(f\"{base_file_path}/*PSL*.nc\", decode_times=False)\n",
206206
" )\n",
207-
" .sel(time=slice(start_date, end_date))\n",
207+
" .sel(time=slice(base_start_date, base_end_date))\n",
208208
" .assign_coords({\"lon\": lon, \"lat\": lat})\n",
209209
" .PSL\n",
210210
" / 100.0\n",

nblibrary/atm/averaging_utils.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ def seasonal_climatology_weighted(dat):
3636
datw_am = dat * wgts_am
3737

3838
ds_season = (
39-
datw.rolling(min_periods=3, center=True, time=3).sum().dropna("time", how="all")
39+
datw.load()
40+
.rolling(min_periods=3, center=True, time=3)
41+
.sum()
42+
.dropna("time", how="all")
4043
)
4144
dat_djf = ds_season.where(ds_season.time.dt.month == 1, drop=True).mean("time")
4245
dat_mam = ds_season.where(ds_season.time.dt.month == 4, drop=True).mean("time")

nblibrary/glc/Greenland_SMB_visual_compare_obs.ipynb

+20-9
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
"outputs": [],
3737
"source": [
3838
"# Import packages\n",
39+
"import os\n",
40+
"\n",
3941
"import numpy as np\n",
4042
"import matplotlib.pyplot as plt\n",
4143
"import matplotlib.cm as mcm\n",
@@ -121,7 +123,7 @@
121123
{
122124
"cell_type": "code",
123125
"execution_count": null,
124-
"id": "cef60ddb-9ff4-4a14-a8ea-0d5740b6c18a",
126+
"id": "08146fd8-d631-46c5-abc3-04fc1a004b77",
125127
"metadata": {
126128
"editable": true,
127129
"slideshow": {
@@ -135,18 +137,27 @@
135137
"source": [
136138
"last_year = int(end_date.split(\"-\")[0])\n",
137139
"\n",
138-
"case_init_file = f\"{CESM_output_dir}/{case_name}/glc/hist/{case_name}.cism.gris.initial_hist.0001-01-01-00000.nc\" # name of glc file output\n",
140+
"case_init_file = os.path.join(\n",
141+
" obs_path, \"cism.gris.initial_hist.0001-01-01-00000.nc\"\n",
142+
") # name of glc file output\n",
139143
"\n",
140-
"case_path = f\"{CESM_output_dir}/{case_name}/cpl/hist\" # path to glc output\n",
141-
"case_file = f\"{case_path}/{case_name}.cpl.hx.1yr2glc.{last_year:04d}-01-01-00000.nc\" # name of glc file output\n",
142-
"obs_file = f\"{obs_path}/{obs_name}\" # name of observed dataset file\n",
144+
"case_path = os.path.join(\n",
145+
" CESM_output_dir, case_name, \"cpl\", \"hist\"\n",
146+
") # path to glc output\n",
147+
"case_file = os.path.join(\n",
148+
" case_path, f\"{case_name}.cpl.hx.1yr2glc.{last_year:04d}-01-01-00000.nc\"\n",
149+
") # name of glc file output\n",
150+
"obs_file = os.path.join(obs_path, obs_name) # name of observed dataset file\n",
143151
"\n",
144152
"if base_case_name is not None:\n",
145153
" base_last_year = int(base_end_date.split(\"-\")[0])\n",
146-
" base_case_path = (\n",
147-
" f\"{base_case_output_dir}/{base_case_name}/cpl/hist\" # path to cpl output\n",
148-
" )\n",
149-
" base_file = f\"{base_case_path}/{base_case_name}.cpl.hx.1yr2glc.{base_last_year:04d}-01-01-00000.nc\" # name of last cpl simulation output"
154+
" base_case_path = os.path.join(\n",
155+
" base_case_output_dir, base_case_name, \"cpl\", \"hist\"\n",
156+
" ) # path to cpl output\n",
157+
" base_file = os.path.join(\n",
158+
" base_case_path,\n",
159+
" f\"{base_case_name}.cpl.hx.1yr2glc.{base_last_year:04d}-01-01-00000.nc\",\n",
160+
" ) # name of last cpl simulation output"
150161
]
151162
},
152163
{

nblibrary/lnd/Global_TerrestrialCouplingIndex_VisualCompareObs.ipynb

+28-20
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,16 @@
8484
"# obsDir = '/glade/campaign/cgd/tss/people/mdfowler/FLUXNET2015/' ## Need to copy into CUPiD Data\n",
8585
"\n",
8686
"## Where CESM timeseries data is stored\n",
87-
"CESM_output_dir = \"/glade/campaign/cesm/development/cross-wg/diagnostic_framework/CESM_output_for_testing/\"\n",
87+
"CESM_output_dir = os.path.join(\n",
88+
" os.path.sep,\n",
89+
" \"glade\",\n",
90+
" \"campaign\",\n",
91+
" \"cesm\",\n",
92+
" \"development\",\n",
93+
" \"cross-wg\",\n",
94+
" \"diagnostic_framework\",\n",
95+
" \"CESM_output_for_testing\",\n",
96+
")\n",
8897
"\n",
8998
"\n",
9099
"## Full casenames that are present in CESM_output_dir and in individual filenames\n",
@@ -123,6 +132,14 @@
123132
"## - - - - - - - - - - - - - - - - - - - - - -\n",
124133
"## Settings for computing coupling index\n",
125134
"## - - - - - - - - - - - - - - - - - - - - - -\n",
135+
"\n",
136+
"# Set up directory for aux output like coupling index file\n",
137+
"if \"SCRATCH\" in os.environ:\n",
138+
" cupid_temp = os.path.join(os.path.sep, os.environ[\"SCRATCH\"], \"CUPiD_scratch\")\n",
139+
" os.makedirs(cupid_temp, exist_ok=True)\n",
140+
"else:\n",
141+
" cupid_temp = \".\"\n",
142+
"\n",
126143
"startYrs = [start_date.split(\"-\")[0]]\n",
127144
"endYrs = [f\"{int(end_date.split('-')[0])-1:04d}\"]\n",
128145
"\n",
@@ -200,10 +217,8 @@
200217
"source": [
201218
"for iCase in range(len(caseNames)):\n",
202219
" ## Check first if coupling index has already been created:\n",
203-
" TCI_filePath = (\n",
204-
" \"/glade/derecho/scratch/mdfowler/\"\n",
205-
" + caseNames[0]\n",
206-
" + \"_TerrestrialCouplingIndex_SHvsSM.nc\"\n",
220+
" TCI_filePath = os.path.join(\n",
221+
" cupid_temp, f\"{caseNames[iCase]}_TerrestrialCouplingIndex_SHvsSM.nc\"\n",
207222
" )\n",
208223
"\n",
209224
" if os.path.exists(TCI_filePath): # Use previously computed TCI\n",
@@ -280,22 +295,16 @@
280295
" yDS = shflx_DS\n",
281296
"\n",
282297
" couplingInd = compute_couplingIndex_cesm(xname, yname, xDS, yDS)\n",
283-
"\n",
284-
" filePath = (\n",
285-
" \"/glade/derecho/scratch/mdfowler/\"\n",
286-
" + caseNames[0]\n",
287-
" + \"_TerrestrialCouplingIndex_SHvsSM.nc\"\n",
288-
" )\n",
289-
" couplingInd.to_netcdf(filePath)\n",
290-
" print(\"File created: \", filePath)"
298+
" couplingInd.to_netcdf(TCI_filePath)\n",
299+
" print(\"File created: \", TCI_filePath)"
291300
]
292301
},
293302
{
294303
"cell_type": "markdown",
295304
"id": "5f8fba2a-98d2-4e94-9d71-3b2625e16032",
296305
"metadata": {},
297306
"source": [
298-
"### 1.1 Read in FLUXNET data if requested"
307+
"### 2.1 Read in FLUXNET data if requested"
299308
]
300309
},
301310
{
@@ -659,7 +668,7 @@
659668
"id": "bc387253-cdd7-4a36-956b-8ce548e963bd",
660669
"metadata": {},
661670
"source": [
662-
"## 2. Make plots"
671+
"## 3. Make plots"
663672
]
664673
},
665674
{
@@ -701,12 +710,11 @@
701710
"outputs": [],
702711
"source": [
703712
"for iCase in range(len(caseNames)):\n",
704-
" filePath = (\n",
705-
" \"/glade/derecho/scratch/mdfowler/\"\n",
706-
" + caseNames[iCase]\n",
707-
" + \"_TerrestrialCouplingIndex_SHvsSM.nc\"\n",
713+
" TCI_filePath = os.path.join(\n",
714+
" cupid_temp, f\"{caseNames[iCase]}_TerrestrialCouplingIndex_SHvsSM.nc\"\n",
708715
" )\n",
709-
" couplingIndex_case = uxr.open_dataset(gridFile, filePath)\n",
716+
"\n",
717+
" couplingIndex_case = uxr.open_dataset(gridFile, TCI_filePath)\n",
710718
" # Rename the variable:\n",
711719
" couplingIndex_case = couplingIndex_case.rename(\n",
712720
" {\"__xarray_dataarray_variable__\": \"CouplingIndex\"}\n",

0 commit comments

Comments
 (0)