Skip to content

Commit eb6e827

Browse files
add run-MDTF [GFDL driver script] (#784)
* add run-MDTF [GFDL driver script] * update pathing * update readme * remove unused os import --------- Co-authored-by: Jess <20195932+wrongkindofdoctor@users.noreply.github.com>
1 parent ab6d50b commit eb6e827

File tree

9 files changed

+320
-0
lines changed

9 files changed

+320
-0
lines changed

tools/run-MDTF/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# run-MDTF
2+
MDTF shell driver to assist model development at the GFDL <br />
3+
Command-line usage:
4+
```
5+
run-mdtf.sh -i /path/to/pp/dir/pp -o out_dir/mdtf -s startyr -e endyr
6+
```
7+
This script requires a user inputted `pod_config.json`. One is supplied by default, but may need to be updated in order to launch more PODs or update realm information!
8+
A new one can be supplied with the `-l` OPTARG.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"Wheeler_Kiladis": {
3+
"realm": "atmos_cmip",
4+
"frequency": "day",
5+
"vars": ["rlut","pr","wap500","ua200","ua850"]
6+
},
7+
"MJO_suite": {
8+
"realm": "atmos_cmip",
9+
"frequency": "day",
10+
"vars": ["rlut","pr","ua200","ua850","va200","va850"]
11+
},
12+
"ocn_surf_flux_diag": {
13+
"realm": "atmos_cmip",
14+
"frequency": "day",
15+
"vars": ["ts","psl","sfcWind","huss","hfls","pr"]
16+
},
17+
"forcing_feedback": {
18+
"realm": "atmos_cmip",
19+
"frequency": "mon",
20+
"vars": ["ts","ta","hus","rsus","rsuscs","rsds","rsdscs","rsdt","rsut","rsutcs","rlut","rlutcs"]
21+
}
22+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"pod_list" : [],
3+
"case_list":
4+
{
5+
"case_name":
6+
{
7+
"model": "test",
8+
"convention": "CMIP",
9+
"startdate": "",
10+
"enddate": "",
11+
"realm": ""
12+
}
13+
},
14+
"DATA_CATALOG": "",
15+
16+
"OBS_DATA_ROOT": "/home/oar.gfdl.mdtf/mdtf/inputdata/obs_data",
17+
18+
"WORK_DIR": "",
19+
20+
"OUTPUT_DIR": "",
21+
22+
"conda_root": "/home/oar.gfdl.mdtf/miniconda3",
23+
24+
"conda_env_root": "/home/oar.gfdl.mdtf/miniconda3/envs",
25+
26+
"micromamba_exe": "",
27+
28+
"run_pp": true,
29+
"translate_data": true,
30+
"save_ps": false,
31+
32+
"large_file": false,
33+
34+
"save_pp_data": false,
35+
36+
"make_variab_tar": false,
37+
38+
"make_multicase_figure_html": false,
39+
40+
"overwrite": false,
41+
42+
"user_pp_scripts" : [],
43+
44+
"verbose": 1
45+
}

tools/run-MDTF/run-MDTF.sh

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#!/bin/bash -f
2+
#SBATCH --job-name=run-MDTF.sh
3+
#SBATCH --time=4:00:00
4+
#set -x
5+
6+
# dir references
7+
run_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
8+
mdtf_dir=/home/oar.gfdl.mdtf/mdtf/MDTF-diagnostics
9+
#mdtf_dir=/home/Jacob.Mims/mdtf/MDTF-diagnostics
10+
activate=/home/oar.gfdl.mdtf/miniconda3/bin/activate
11+
12+
#TEST: /archive/jpk/fre/FMS2024.02_OM5_20240819/CM4.5v01_om5b06_piC_noBLING_xrefine_test4/gfdl.ncrc5-intel23-prod-openmp/pp/ starts 0001
13+
14+
#TEST 2: /archive/djp/am5/am5f7b12r1/c96L65_am5f7b12r1_amip/gfdl.ncrc5-intel23-classic-prod-openmp/pp/ starts 1990
15+
16+
usage() {
17+
echo "USAGE: run-mdtf.sh -i /path/to/pp/dir/pp -o out_dir/mdtf -s startyr -e endyr"
18+
echo "ADDITONAL OPTS:"
19+
echo "-l: custom config file for pods (default: config/pod_config.json) this can be used to set which PODs you would like to run and define the realm to grab vars from"
20+
}
21+
22+
# handle arguments
23+
tempdir=""
24+
pod_config=""
25+
declare -a pods=()
26+
while getopts "hi:o:s:e:p:t:l:" arg; do
27+
case "${arg}" in
28+
h)
29+
usage
30+
exit
31+
;;
32+
i)
33+
if [ -d $OPTARG ]; then
34+
ppdir="${OPTARG}"
35+
else
36+
echo "ERROR: $1 is not a directory"
37+
usage
38+
exit
39+
fi
40+
;;
41+
o)
42+
if [ -d "${OPTARG}" ]; then
43+
outdir="${OPTARG}"
44+
else
45+
mkdir -p "${OPTARG}"
46+
outdir="${OPTARG}"
47+
fi
48+
;;
49+
s)
50+
startyr="${OPTARG}"
51+
;;
52+
e)
53+
endyr="${OPTARG}"
54+
;;
55+
p)
56+
pods+=("$OPTARG")
57+
;;
58+
t)
59+
tempdir="${OPTARG}"
60+
;;
61+
l)
62+
pod_config="${OPTARG}"
63+
esac
64+
done
65+
shift $((OPTIND-1))
66+
if ! [ -d $outdir/config ]; then
67+
mkdir -p $outdir/config
68+
fi
69+
if [ -z $tempdir ]; then
70+
wkdir=$outdir
71+
else
72+
wkdir=$tempdir
73+
fi
74+
if [ -z $pod_config ]; then
75+
pod_config="$run_dir/config/pod_config.json"
76+
fi
77+
78+
# check to see if catalog exists
79+
# ^..^
80+
# /o o\
81+
# oo--oo~~~
82+
echo "looking for catalog in $ppdir"
83+
cat=$(grep -s -H "esmcat_version" $ppdir/*.json | cut -d: -f1)
84+
if [[ "$cat" == "" ]]; then
85+
env=/nbhome/fms/conda/envs/fre-2025.01
86+
source $activate $env
87+
fre catalog builder --overwrite $ppdir $outdir/catalog
88+
cat=$outdir/catalog.json
89+
echo "new catalog generated: $cat"
90+
else
91+
echo "found catalog: $cat"
92+
fi
93+
94+
# edit template config file
95+
cp $run_dir/config/template_config.jsonc $outdir
96+
f=$outdir/template_config.jsonc
97+
if [ ! -f $f ]; then
98+
echo "ERROR: failed to find $f"
99+
exit 0
100+
fi
101+
config='"DATA_CATALOG": "",'
102+
config_edit='"DATA_CATALOG": "'"${cat}"'",'
103+
sed -i "s|$config|$config_edit|ig" $f
104+
config='"WORK_DIR": "",'
105+
config_edit='"WORK_DIR": "'"${wkdir}"'",'
106+
sed -i "s|$config|$config_edit|ig" $f
107+
config='"OUTPUT_DIR": "",'
108+
config_edit='"OUTPUT_DIR": "'"${outdir}"'",'
109+
sed -i "s|$config|$config_edit|ig" $f
110+
config='"startdate": "",'
111+
config_edit='"startdate": "'"${startyr}"'",'
112+
sed -i "s|$config|$config_edit|ig" $f
113+
config='"enddate": ""'
114+
config_edit='"enddate": "'"${endyr}"'"'
115+
sed -i "s|$config|$config_edit|ig" $f
116+
echo "edited file $f"
117+
118+
# load mdtf base conda env
119+
env=/home/oar.gfdl.mdtf/miniconda3/envs/_MDTF_base
120+
source $activate $env
121+
#generate config files
122+
python $run_dir/scripts/gen_config.py $outdir/ $pod_config
123+
124+
# launch the mdtf with the config files
125+
for f in $(ls ${outdir}/config) ; do
126+
echo "launching MDTF with $f"
127+
"$mdtf_dir"/mdtf -f $outdir/config/$f
128+
done
129+
130+
# consolidate outputs into index
131+
cp $run_dir/scripts/index.html $outdir/
132+
cp $run_dir/scripts/mdtf_diag_banner.png $outdir/
133+
python $run_dir/scripts/gen_index.py $outdir/ $pod_config
134+
135+
exit 0

tools/run-MDTF/run-MDTF_frepp.csh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/csh -f
2+
#--------------------------------------
3+
#PBS -N mdtf_frepp_driver
4+
#PBS -l size=1
5+
#PBS -l walltime=60:00:00
6+
#PBS -r y
7+
#PBS -j oe
8+
#PBS -o
9+
#PBS -q batch
10+
#--------------------------------------
11+
12+
# clean up tmpdir
13+
wipetmp
14+
15+
# fields set by frepp
16+
set argu
17+
set descriptor
18+
set in_data_dir
19+
set out_dir
20+
set WORKDIR
21+
set mode
22+
set yr1
23+
set yr2
24+
set databegyr
25+
set dataendyr
26+
set datachunk
27+
set staticfile
28+
set script_path
29+
set fremodule
30+
set mode = "GFDL"
31+
32+
if (-d ${out_dir}/mdtf) then
33+
echo "Output directory already exists, removing"
34+
rm -fr ${out_dir}/mdtf
35+
endif
36+
37+
set ppdir = `echo ${in_data_dir} | sed 's|\(.*pp\).*|\1|'`
38+
39+
/home/oar.gfdl.mdtf/mdtf/MDTF-diagnostics/tools/run-MDTF/run-MDTF.sh -i ${ppdir} -o ${out_dir}/mdtf -s $yr1 -e $yr2
40+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# script to make the MDTF runtime configs for each realm/freq to run requested PODs
2+
import sys
3+
import json
4+
import copy
5+
6+
# load pod information
7+
with open(sys.argv[2]) as f:
8+
pods = json.load(f)
9+
10+
# load template config information
11+
with open(sys.argv[1]+'template_config.jsonc') as f:
12+
template_config = json.load(f)
13+
14+
# create dict object for each pod
15+
config_files = {}
16+
for p in pods:
17+
config_name = f'{p}_config'
18+
config_realm = pods[p]['realm']
19+
config_files[config_name] = copy.deepcopy(template_config)
20+
config_files[config_name]['case_list']['case_name']['realm'] = config_realm
21+
config_files[config_name]['case_list'][config_realm] = config_files[config_name]['case_list'].pop('case_name')
22+
23+
# add pods to cooresponding config file
24+
for p in pods:
25+
config_file = f"{p}_config"
26+
config_files[config_file]['pod_list'].append(p)
27+
28+
#write out config files
29+
for c in config_files:
30+
with open(sys.argv[1]+f"config/{c}.jsonc", "w") as f:
31+
f.write(json.dumps(config_files[c], indent=2))
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# script to create a simple index.html for automated mdtf runs
2+
import sys
3+
import os
4+
import json
5+
6+
out_dir = sys.argv[1]
7+
8+
# load pod information
9+
with open(sys.argv[2]) as f:
10+
pods = json.load(f)
11+
12+
index_file = open(f'{out_dir}/index.html', 'a')
13+
14+
pod_htmls = {}
15+
pods = [p for p in pods]
16+
mdtf_outputs = [os.path.join(out_dir, d) for d in os.listdir(out_dir) if 'MDTF_output' in d]
17+
18+
for d in mdtf_outputs:
19+
list_d = os.listdir(d)
20+
for p in pods:
21+
if p in list_d:
22+
pod_dir = os.path.join(d, p)
23+
file_path = os.path.join(pod_dir, f'{p}.html')
24+
if os.path.exists(file_path):
25+
print(p)
26+
index_file.write(f'<a href="{file_path}"> {p} </a>')
27+
28+
index_file.close()

tools/run-MDTF/scripts/index.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<HTML>
2+
<HEAD>
3+
<meta http-equiv="expires" content="Fri, 01 Sep 00:00:00 EST 2025">
4+
<TITLE>MDTF-Diagnostics</TITLE>
5+
</HEAD>
6+
<BODY BGCOLOR="white">
7+
<IMG SRC="mdtf_diag_banner.png" border=0 usemap="#logo">
8+
<br clear=left>
9+
<p> Completed PODs </p>
10+
<HR SIZE=2 WIDTH="100%" ALIGN="LEFT" NOSHADE>
11+
18.3 KB
Loading

0 commit comments

Comments
 (0)