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

Plumber2 Implementation #2406

Open
wants to merge 31 commits into
base: b4b-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
7d061f9
preliminary plumber files
TeaganKing Feb 21, 2024
a508497
include plumber2site values in config_component.xml
TeaganKing Feb 22, 2024
11cafe6
general setup to run plumber
TeaganKing Mar 7, 2024
fdbc70c
update cime config
TeaganKing Mar 8, 2024
dd028a3
reformat
TeaganKing Mar 8, 2024
80e94fe
remove run_length since overwritten by usermods dirs
TeaganKing Mar 25, 2024
83b3ed5
remove run_length from plumber_site and update args
TeaganKing Mar 25, 2024
0b6e209
update tests; include cases with experiment label in gitignore
TeaganKing Mar 26, 2024
7a0f7f2
update plumber for consistency and fix import
TeaganKing Jun 25, 2024
dc44a68
updates to run_tower
TeaganKing Jun 25, 2024
459f0ce
make adjustments for valid plumber vs neon sites
TeaganKing Jul 22, 2024
e3e806e
updates to checking plumber data
TeaganKing Jul 22, 2024
1bca632
now correctly finding all plumber sites
TeaganKing Jul 24, 2024
bf2dad3
allow for None for either plumber or neon sites
TeaganKing Jul 24, 2024
c82efb8
fixed location of plumber data
TeaganKing Jul 24, 2024
d523301
a few other fixes for having None option for either neon or plumber
TeaganKing Jul 24, 2024
cc2da4d
include plumber filesin gitignore
TeaganKing Aug 1, 2024
bc94326
update default run type to be ad for plumber and remain transient for…
TeaganKing Aug 12, 2024
1970863
resolve 'Do not know about batch job case.run' with updated run type …
TeaganKing Aug 12, 2024
df69f23
Update plumber_site.py script documentation
TeaganKing Aug 16, 2024
3e43097
Update run_tower.py to do's
TeaganKing Aug 16, 2024
f2e03b2
update testing for neon and plumber
TeaganKing Aug 20, 2024
4e93b99
black formatting for test
TeaganKing Aug 20, 2024
5164bb7
remove run_lenght arg
TeaganKing Aug 22, 2024
a7462b1
testing updates-- test_sys_run_tower still fails
TeaganKing Aug 23, 2024
24897b3
test updates
TeaganKing Aug 23, 2024
0e8375a
Update plumber_site.py with minor comment
TeaganKing Aug 23, 2024
b98f8ee
address some of Will's comments
TeaganKing Aug 23, 2024
52c9786
add clarifying comments
TeaganKing Aug 26, 2024
aa06d7a
allow skipping of modify_user_nl and also add a few other clarificati…
TeaganKing Aug 26, 2024
39b3023
formatting
TeaganKing Aug 26, 2024
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
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,18 @@ unit_test_build
/tools/site_and_regional/listing.csv
/tools/site_and_regional/????/
/tools/site_and_regional/????.ad/
/tools/site_and_regional/????.*.ad/
/tools/site_and_regional/????.postad/
/tools/site_and_regional/????.*.postad/
/tools/site_and_regional/????.transient/
/tools/site_and_regional/????.*.transient/
/tools/site_and_regional/??-???/
/tools/site_and_regional/??-???.ad/
/tools/site_and_regional/??-???.*.ad/
/tools/site_and_regional/??-???.postad/
/tools/site_and_regional/??-???.*.postad/
/tools/site_and_regional/??-???.transient/
/tools/site_and_regional/??-???.*.transient/
/tools/site_and_regional/archive/

# build output
Expand Down
6 changes: 1 addition & 5 deletions python/ctsm/site_and_regional/neon_site.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
This module contains the NeonSite class and class functions which are used in run_neon.py
This module contains the NeonSite class and class functions which are used in run_tower.py
"""

# Import libraries
Expand Down Expand Up @@ -57,7 +57,6 @@ def run_case(
base_case_root,
run_type,
prism,
run_length,
user_version,
tower_type=None,
user_mods_dirs=None,
Expand All @@ -78,8 +77,6 @@ def run_case(
transient, post_ad, or ad case, default transient
prism: bool, opt
if True, use PRISM precipitation, default False
run_length: str, opt
length of run, default '4Y'
user_version: str, opt
default 'latest'
overwrite: bool, opt
Expand All @@ -102,7 +99,6 @@ def run_case(
base_case_root,
run_type,
prism,
run_length,
user_version,
tower_type,
user_mods_dirs,
Expand Down
115 changes: 115 additions & 0 deletions python/ctsm/site_and_regional/plumber_site.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
"""
This module contains the Plumber2Site class and class functions which are used in run_tower.py
"""

# Import libraries
import logging
import os
import sys

# Get the ctsm util tools and then the cime tools.
_CTSM_PYTHON = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "python"))
sys.path.insert(1, _CTSM_PYTHON)

# -- import local classes for this script
# pylint: disable=wrong-import-position
from ctsm.site_and_regional.tower_site import TowerSite

# pylint: disable=wrong-import-position, import-error, unused-import, wrong-import-order
from ctsm import add_cime_to_path
from ctsm.path_utils import path_to_ctsm_root

from CIME import build
from CIME.case import Case
from CIME.utils import safe_copy, expect, symlink_force

logger = logging.getLogger(__name__)


# pylint: disable=too-many-instance-attributes
class Plumber2Site(TowerSite):
"""
A class for encapsulating plumber sites.
"""

def build_base_case(
self,
cesmroot,
output_root,
res,
compset,
user_mods_dirs=None,
overwrite=False,
setup_only=False,
):
if user_mods_dirs is None:
user_mods_dirs = [
os.path.join(self.cesmroot, "cime_config", "usermods_dirs", "PLUMBER2", self.name)
]
case_path = super().build_base_case(cesmroot, output_root, res, compset, user_mods_dirs)

return case_path

# pylint: disable=too-many-statements
def run_case(
self,
base_case_root,
run_type,
prism,
TeaganKing marked this conversation as resolved.
Show resolved Hide resolved
user_version,
tower_type=None,
user_mods_dirs=None,
overwrite=False,
setup_only=False,
no_batch=False,
rerun=False,
experiment=False,
):
"""
Run case.

Args:
self
base_case_root: str, opt
file path of base case
run_type: str, opt
transient, post_ad, or ad case, default ad
(ad case is default because PLUMBER requires spinup)
prism: bool, opt
if True, use PRISM precipitation, default False
Note: only supported for NEON sites
user_version: str, opt
default 'latest'; this could be useful later
This is currently only implemented with neon (not plumber) sites
overwrite: bool, opt
default False
setup_only: bool, opt
default False; if True, set up but do not run case
no_batch: bool, opt
default False
rerun: bool, opt
default False
experiment: str, opt
name of experiment, default False
"""
user_mods_dirs = [
os.path.join(self.cesmroot, "cime_config", "usermods_dirs", "PLUMBER2", self.name)
]
tower_type = "PLUMBER"
super().run_case(
base_case_root,
run_type,
prism,
user_version,
tower_type,
user_mods_dirs,
overwrite,
setup_only,
no_batch,
rerun,
experiment,
)

def set_ref_case(self, case):
super().set_ref_case(case)
return True ### Check if super returns false, if this will still return True?
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
|--------------------- Instructions -----------------------------|
|------------------------------------------------------------------|
This is a wrapper script for running CTSM simulation for one or more
neon sites.
tower (neon or plumber) sites.

This script is only for neon site and we will develop a more general
code later.
This script is only for supported tower sites and we will develop a
more general code later.

This script first creates and builds a generic base case.
Next, it will clone the base_case for different neon sites and run
Next, it will clone the base_case for different tower sites and run
types to reduce the need to build ctsm everytime.

This script will do the following:
1) Create a generic base case for cloning.
2) Make the case for the specific neon site(s).
2) Make the case for the specific neon or plumber site(s).
3) Make changes to the case, for:
a. AD spinup
b. post-AD spinup
Expand All @@ -33,11 +33,10 @@

-------------------------------------------------------------------
To see the available options:
./run_neon.py --help
./run_tower.py --help
-------------------------------------------------------------------
"""
# TODO (NS)
# - [ ]
# - [ ] Case dependency and the ability to check case status
# - [ ] If Case dependency works we don't need finidat given explicilty for post-ad and transient.

Expand All @@ -64,8 +63,9 @@
# pylint: disable=wrong-import-position
from ctsm.path_utils import path_to_ctsm_root
from ctsm.download_utils import download_file
from ctsm.site_and_regional.neon_arg_parse import get_parser
from ctsm.site_and_regional.tower_arg_parse import get_parser
from ctsm.site_and_regional.neon_site import NeonSite
from ctsm.site_and_regional.plumber_site import Plumber2Site

# pylint: disable=import-error, wildcard-import, wrong-import-order
from standard_script_setup import *
Expand Down Expand Up @@ -130,7 +130,7 @@ def parse_neon_listing(listing_file, valid_neon_sites):
# versions = tmp_df[7].unique()
# print ("all versions available for ", site_name,":", *versions)
latest_version = tmp_df[7].iloc[-1]
# print ("latests version available for ", site_name,":", latest_version)
# print ("latest version available for ", site_name,":", latest_version)

tmp_df = tmp_df[tmp_df[7].str.contains(latest_version)]
# -- remove .nc from the file names
Expand Down Expand Up @@ -167,9 +167,41 @@ def parse_neon_listing(listing_file, valid_neon_sites):
return available_list


def setup_plumber_data(valid_plumber_sites):
"""
A function to set up plumber site objects
with dummy start and end years and months.
This allows us to use the list of plumber site objects.

Returns:
available_list :
list of plumber_site objects that is found
"""

available_list = []

for site_name in valid_plumber_sites:

# start_year and end_year are set in shell commands, so these get overwritten
start_year = 8888
end_year = 9999
start_month = 1
end_month = 12

logger.debug("Valid plumber site %s found!", site_name)
finidat = None

plumber_site = Plumber2Site(
site_name, start_year, end_year, start_month, end_month, finidat
)
available_list.append(plumber_site)

return available_list


def main(description):
"""
Determine valid neon sites. Make an output directory if it does not exist.
Determine valid tower sites. Make an output directory if it does not exist.
Loop through requested sites and run CTSM at that site.
"""
cesmroot = path_to_ctsm_root()
Expand All @@ -181,21 +213,28 @@ def main(description):
)
valid_neon_sites = sorted([v.split("/")[-1] for v in valid_neon_sites])

# Get the list of supported plumber sites from usermods
valid_plumber_sites = glob.glob(
os.path.join(cesmroot, "cime_config", "usermods_dirs", "PLUMBER2", "[!d]*")
)

valid_plumber_sites = sorted([v.split("/")[-1] for v in valid_plumber_sites])

(
site_list,
neon_site_list,
plumber_site_list,
output_root,
run_type,
experiment,
prism,
overwrite,
run_length,
base_case_root,
run_from_postad,
setup_only,
no_batch,
rerun,
user_version,
) = get_parser(sys.argv, description, valid_neon_sites)
) = get_parser(sys.argv, description, valid_neon_sites, valid_plumber_sites)

if output_root:
logger.debug("output_root : %s", output_root)
Expand All @@ -206,7 +245,7 @@ def main(description):
available_list = check_neon_listing(valid_neon_sites)

# =================================
# -- all neon sites can be cloned from one generic case
# -- all tower sites can be cloned from one generic case
# -- so no need to define a base_case for every site.

res = "CLM_USRDAT"
Expand All @@ -216,28 +255,55 @@ def main(description):
compset = "I1PtClm60Bgc"

# -- Looping over neon sites
if neon_site_list:
for neon_site in available_list:
if neon_site.name in neon_site_list:
if run_from_postad:
neon_site.finidat = None
if not base_case_root:
user_mods_dirs = None
base_case_root = neon_site.build_base_case(
cesmroot, output_root, res, compset, user_mods_dirs, overwrite, setup_only
)
logger.info("-----------------------------------")
logger.info("Running CTSM for neon site : %s", neon_site.name)

neon_site.run_case(
base_case_root,
run_type,
prism,
user_version,
overwrite=overwrite,
setup_only=setup_only,
no_batch=no_batch,
rerun=rerun,
experiment=experiment,
)

for neon_site in available_list:
if neon_site.name in site_list:
if run_from_postad:
neon_site.finidat = None
if not base_case_root:
user_mods_dirs = None
base_case_root = neon_site.build_base_case(
cesmroot, output_root, res, compset, user_mods_dirs, overwrite, setup_only
# -- check for available plumber data:
available_plumber_list = setup_plumber_data(valid_plumber_sites)

# -- Looping over plumber sites
if plumber_site_list:
for plumber_site in available_plumber_list:
if plumber_site.name in plumber_site_list:
if run_from_postad:
plumber_site.finidat = None
if not base_case_root:
user_mods_dirs = None
base_case_root = plumber_site.build_base_case(
cesmroot, output_root, res, compset, user_mods_dirs, overwrite, setup_only
)
logger.info("-----------------------------------")
logger.info("Running CTSM for plumber site : %s", plumber_site.name)
plumber_site.run_case(
base_case_root,
run_type,
prism,
user_version,
overwrite=overwrite,
setup_only=setup_only,
no_batch=no_batch,
rerun=rerun,
experiment=experiment,
)
logger.info("-----------------------------------")
logger.info("Running CTSM for neon site : %s", neon_site.name)

neon_site.run_case(
base_case_root,
run_type,
prism,
run_length,
user_version,
overwrite=overwrite,
setup_only=setup_only,
no_batch=no_batch,
rerun=rerun,
experiment=experiment,
)
Loading
Loading