Skip to content

Commit

Permalink
Merge pull request #111 from CABLE-LSM/62-remove-synonymous-names-for…
Browse files Browse the repository at this point in the history
…-fluxnet

Remove synonymous names for 'fluxsite'
  • Loading branch information
SeanBryan51 authored Jul 18, 2023
2 parents 6983bdc + b829293 commit f3ed8c0
Show file tree
Hide file tree
Showing 15 changed files with 323 additions and 298 deletions.
88 changes: 45 additions & 43 deletions benchcab/benchcab.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
from subprocess import CalledProcessError

from benchcab import internal
from benchcab.internal import get_met_sites
from benchcab.internal import get_met_forcing_file_names
from benchcab.bench_config import read_config
from benchcab.benchtree import setup_fluxnet_directory_tree, setup_src_dir
from benchcab.benchtree import setup_fluxsite_directory_tree, setup_src_dir
from benchcab.repository import CableRepository
from benchcab.task import (
get_fluxnet_tasks,
get_fluxnet_comparisons,
get_fluxsite_tasks,
get_fluxsite_comparisons,
run_tasks,
run_tasks_in_parallel,
Task,
Expand Down Expand Up @@ -46,7 +46,7 @@ def __init__(
CableRepository(**config, repo_id=id)
for id, config in enumerate(self.config["realisations"])
]
self.tasks: list[Task] = [] # initialise fluxnet tasks lazily
self.tasks: list[Task] = [] # initialise fluxsite tasks lazily

if validate_env:
self._validate_environment(
Expand Down Expand Up @@ -102,23 +102,25 @@ def _validate_environment(self, project: str, modules: list):

def _initialise_tasks(self) -> list[Task]:
"""A helper method that initialises and returns the `tasks` attribute."""
self.tasks = get_fluxnet_tasks(
self.tasks = get_fluxsite_tasks(
repos=self.repos,
science_configurations=self.config.get(
"science_configurations", internal.DEFAULT_SCIENCE_CONFIGURATIONS
),
met_sites=get_met_sites(self.config["experiment"]),
fluxsite_forcing_file_names=get_met_forcing_file_names(
self.config["experiment"]
),
)
return self.tasks

# TODO(Sean) this method should be the endpoint for the `fluxnet-submit-job`
# TODO(Sean) this method should be the endpoint for the `fluxsite-submit-job`
# command line argument.
def fluxnet_submit_job(self) -> None:
"""Submits the PBS job script step in the fluxnet test workflow."""
def fluxsite_submit_job(self) -> None:
"""Submits the PBS job script step in the fluxsite test workflow."""

job_script_path = self.root_dir / internal.QSUB_FNAME
print(
"Creating PBS job script to run FLUXNET tasks on compute "
"Creating PBS job script to run fluxsite tasks on compute "
f"nodes: {job_script_path.relative_to(self.root_dir)}"
)
with job_script_path.open("w", encoding="utf-8") as file:
Expand All @@ -128,7 +130,7 @@ def fluxnet_submit_job(self) -> None:
modules=self.config["modules"],
storage_flags=[], # TODO(Sean) add storage flags option to config
verbose=self.args.verbose,
skip_bitwise_cmp="fluxnet-bitwise-cmp" in self.args.skip,
skip_bitwise_cmp="fluxsite-bitwise-cmp" in self.args.skip,
)
file.write(contents)

Expand All @@ -146,11 +148,11 @@ def fluxnet_submit_job(self) -> None:
print(
f"PBS job submitted: {proc.stdout.strip()}\n"
"The CABLE log file for each task is written to "
f"{internal.SITE_LOG_DIR}/<task_name>_log.txt\n"
f"{internal.FLUXSITE_LOG_DIR}/<task_name>_log.txt\n"
"The CABLE standard output for each task is written to "
f"{internal.SITE_TASKS_DIR}/<task_name>/out.txt\n"
f"{internal.FLUXSITE_TASKS_DIR}/<task_name>/out.txt\n"
"The NetCDF output for each task is written to "
f"{internal.SITE_OUTPUT_DIR}/<task_name>_out.nc"
f"{internal.FLUXSITE_OUTPUT_DIR}/<task_name>_out.nc"
)

def checkout(self):
Expand Down Expand Up @@ -192,38 +194,38 @@ def build(self):
print(f"Successfully compiled CABLE for realisation {repo.name}")
print("")

def fluxnet_setup_work_directory(self):
"""Endpoint for `benchcab fluxnet-setup-work-dir`."""
def fluxsite_setup_work_directory(self):
"""Endpoint for `benchcab fluxsite-setup-work-dir`."""
tasks = self.tasks if self.tasks else self._initialise_tasks()
print("Setting up run directory tree for FLUXNET tests...")
setup_fluxnet_directory_tree(fluxnet_tasks=tasks, verbose=self.args.verbose)
print("Setting up run directory tree for fluxsite tests...")
setup_fluxsite_directory_tree(fluxsite_tasks=tasks, verbose=self.args.verbose)
print("Setting up tasks...")
for task in tasks:
task.setup_task(verbose=self.args.verbose)
print("Successfully setup FLUXNET tasks")
print("Successfully setup fluxsite tasks")
print("")

def fluxnet_run_tasks(self):
"""Endpoint for `benchcab fluxnet-run-tasks`."""
def fluxsite_run_tasks(self):
"""Endpoint for `benchcab fluxsite-run-tasks`."""
tasks = self.tasks if self.tasks else self._initialise_tasks()
print("Running FLUXNET tasks...")
print("Running fluxsite tasks...")
if internal.MULTIPROCESS:
run_tasks_in_parallel(tasks, verbose=self.args.verbose)
else:
run_tasks(tasks, verbose=self.args.verbose)
print("Successfully ran FLUXNET tasks")
print("Successfully ran fluxsite tasks")
print("")

def fluxnet_bitwise_cmp(self):
"""Endpoint for `benchcab fluxnet-bitwise-cmp`."""
def fluxsite_bitwise_cmp(self):
"""Endpoint for `benchcab fluxsite-bitwise-cmp`."""

if not self.modules_handler.module_is_loaded("nccmp/1.8.5.0"):
self.modules_handler.module_load(
"nccmp/1.8.5.0"
) # use `nccmp -df` for bitwise comparisons

tasks = self.tasks if self.tasks else self._initialise_tasks()
comparisons = get_fluxnet_comparisons(tasks)
comparisons = get_fluxsite_comparisons(tasks)

print("Running comparison tasks...")
if internal.MULTIPROCESS:
Expand All @@ -232,24 +234,24 @@ def fluxnet_bitwise_cmp(self):
run_comparisons(comparisons, verbose=self.args.verbose)
print("Successfully ran comparison tasks")

def fluxnet(self):
"""Endpoint for `benchcab fluxnet`."""
def fluxsite(self):
"""Endpoint for `benchcab fluxsite`."""
self.checkout()
self.build()
self.fluxnet_setup_work_directory()
self.fluxsite_setup_work_directory()
if self.args.no_submit:
self.fluxnet_run_tasks()
if "fluxnet-bitwise-cmp" not in self.args.skip:
self.fluxnet_bitwise_cmp()
self.fluxsite_run_tasks()
if "fluxsite-bitwise-cmp" not in self.args.skip:
self.fluxsite_bitwise_cmp()
else:
self.fluxnet_submit_job()
self.fluxsite_submit_job()

def spatial(self):
"""Endpoint for `benchcab spatial`."""

def run(self):
"""Endpoint for `benchcab run`."""
self.fluxnet()
self.fluxsite()
self.spatial()

def main(self):
Expand All @@ -264,17 +266,17 @@ def main(self):
if self.args.subcommand == "build":
self.build()

if self.args.subcommand == "fluxnet":
self.fluxnet()
if self.args.subcommand == "fluxsite":
self.fluxsite()

if self.args.subcommand == "fluxnet-setup-work-dir":
self.fluxnet_setup_work_directory()
if self.args.subcommand == "fluxsite-setup-work-dir":
self.fluxsite_setup_work_directory()

if self.args.subcommand == "fluxnet-run-tasks":
self.fluxnet_run_tasks()
if self.args.subcommand == "fluxsite-run-tasks":
self.fluxsite_run_tasks()

if self.args.subcommand == "fluxnet-bitwise-cmp":
self.fluxnet_bitwise_cmp()
if self.args.subcommand == "fluxsite-bitwise-cmp":
self.fluxsite_bitwise_cmp()

if self.args.subcommand == "spatial":
self.spatial()
Expand Down
57 changes: 29 additions & 28 deletions benchcab/benchtree.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,58 +28,59 @@ def setup_src_dir(root_dir=internal.CWD):
os.makedirs(src_dir)


def setup_fluxnet_directory_tree(
fluxnet_tasks: list[Task], root_dir=internal.CWD, verbose=False
def setup_fluxsite_directory_tree(
fluxsite_tasks: list[Task], root_dir=internal.CWD, verbose=False
):
"""Generate the directory structure used of `benchcab`."""

run_dir = Path(root_dir, internal.RUN_DIR)
if not run_dir.exists():
os.makedirs(run_dir)

site_run_dir = Path(root_dir, internal.SITE_RUN_DIR)
if not site_run_dir.exists():
os.makedirs(site_run_dir)
fluxsite_run_dir = Path(root_dir, internal.FLUXSITE_RUN_DIR)
if not fluxsite_run_dir.exists():
os.makedirs(fluxsite_run_dir)

site_log_dir = Path(root_dir, internal.SITE_LOG_DIR)
if not site_log_dir.exists():
fluxsite_log_dir = Path(root_dir, internal.FLUXSITE_LOG_DIR)
if not fluxsite_log_dir.exists():
print(
f"Creating {site_log_dir.relative_to(root_dir)} directory: {site_log_dir}"
f"Creating {fluxsite_log_dir.relative_to(root_dir)} directory: {fluxsite_log_dir}"
)
os.makedirs(site_log_dir)
os.makedirs(fluxsite_log_dir)

site_output_dir = Path(root_dir, internal.SITE_OUTPUT_DIR)
if not site_output_dir.exists():
fluxsite_output_dir = Path(root_dir, internal.FLUXSITE_OUTPUT_DIR)
if not fluxsite_output_dir.exists():
print(
f"Creating {site_output_dir.relative_to(root_dir)} directory: {site_output_dir}"
f"Creating {fluxsite_output_dir.relative_to(root_dir)} directory: {fluxsite_output_dir}"
)
os.makedirs(site_output_dir)
os.makedirs(fluxsite_output_dir)

site_tasks_dir = Path(root_dir, internal.SITE_TASKS_DIR)
if not site_tasks_dir.exists():
fluxsite_tasks_dir = Path(root_dir, internal.FLUXSITE_TASKS_DIR)
if not fluxsite_tasks_dir.exists():
print(
f"Creating {site_tasks_dir.relative_to(root_dir)} directory: {site_tasks_dir}"
f"Creating {fluxsite_tasks_dir.relative_to(root_dir)} directory: {fluxsite_tasks_dir}"
)
os.makedirs(site_tasks_dir)
os.makedirs(fluxsite_tasks_dir)

site_analysis_dir = Path(root_dir, internal.SITE_ANALYSIS_DIR)
if not site_analysis_dir.exists():
fluxsite_analysis_dir = Path(root_dir, internal.FLUXSITE_ANALYSIS_DIR)
if not fluxsite_analysis_dir.exists():
print(
f"Creating {site_analysis_dir.relative_to(root_dir)} directory: {site_analysis_dir}"
f"Creating {fluxsite_analysis_dir.relative_to(root_dir)} directory: "
f"{fluxsite_analysis_dir}"
)
os.makedirs(site_analysis_dir)
os.makedirs(fluxsite_analysis_dir)

site_bitwise_cmp_dir = Path(root_dir, internal.SITE_BITWISE_CMP_DIR)
if not site_bitwise_cmp_dir.exists():
fluxsite_bitwise_cmp_dir = Path(root_dir, internal.FLUXSITE_BITWISE_CMP_DIR)
if not fluxsite_bitwise_cmp_dir.exists():
print(
f"Creating {site_bitwise_cmp_dir.relative_to(root_dir)} directory: "
f"{site_bitwise_cmp_dir}"
f"Creating {fluxsite_bitwise_cmp_dir.relative_to(root_dir)} directory: "
f"{fluxsite_bitwise_cmp_dir}"
)
os.makedirs(site_bitwise_cmp_dir)
os.makedirs(fluxsite_bitwise_cmp_dir)

print("Creating task directories...")
for task in fluxnet_tasks:
task_dir = Path(root_dir, internal.SITE_TASKS_DIR, task.get_task_name())
for task in fluxsite_tasks:
task_dir = Path(root_dir, internal.FLUXSITE_TASKS_DIR, task.get_task_name())
if not task_dir.exists():
if verbose:
print(f"Creating {task_dir.relative_to(root_dir)}: " f"{task_dir}")
Expand Down
38 changes: 19 additions & 19 deletions benchcab/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,19 @@ def generate_parser() -> argparse.ArgumentParser:
"run",
parents=[args_help, args_subcommand, args_run_subcommand],
help="Run all test suites for CABLE.",
description="""Runs all test suites for CABLE: fluxnet sites and spatial test suites. This
description="""Runs all test suites for CABLE: fluxsite and spatial test suites. This
command runs the full default set of tests for CABLE.""",
add_help=False,
)

# subcommand: 'benchcab fluxnet'
# subcommand: 'benchcab fluxsite'
subparsers.add_parser(
"fluxnet",
"fluxsite",
parents=[args_help, args_subcommand, args_run_subcommand],
help="Run the fluxnet test suite for CABLE.",
description="""Runs the default fluxnet test suite for CABLE. This command is the
help="Run the fluxsite test suite for CABLE.",
description="""Runs the default fluxsite test suite for CABLE. This command is the
equivalent of running 'benchcab checkout', 'benchcab build', 'benchcab
fluxnet-setup-work-dir', and 'benchcab fluxnet-run-tasks' sequentially.""",
fluxsite-setup-work-dir', and 'benchcab fluxsite-run-tasks' sequentially.""",
add_help=False,
)

Expand All @@ -106,33 +106,33 @@ def generate_parser() -> argparse.ArgumentParser:
add_help=False,
)

# subcommand: 'benchcab fluxnet-setup-work-dir'
# subcommand: 'benchcab fluxsite-setup-work-dir'
subparsers.add_parser(
"fluxnet-setup-work-dir",
"fluxsite-setup-work-dir",
parents=[args_help, args_subcommand],
help="Run the work directory setup step of the fluxnet command.",
description="""Generates the benchcab site/run directory tree in the current working
directory so that tasks can be run.""",
help="Run the work directory setup step of the fluxsite command.",
description="""Generates the fluxsite run directory tree in the current working
directory so that fluxsite tasks can be run.""",
add_help=False,
)

# subcommand: 'benchcab fluxnet-run-tasks'
# subcommand: 'benchcab fluxsite-run-tasks'
subparsers.add_parser(
"fluxnet-run-tasks",
"fluxsite-run-tasks",
parents=[args_help, args_subcommand],
help="Run the fluxnet tasks of the main fluxnet command.",
description="""Runs the fluxnet tasks for the fluxnet test suite. Note, this command should
help="Run the fluxsite tasks of the main fluxsite command.",
description="""Runs the fluxsite tasks for the fluxsite test suite. Note, this command should
ideally be run inside a PBS job. This command is invoked by the PBS job script generated by
`benchcab run`.""",
add_help=False,
)

# subcommand: 'benchcab fluxnet-bitwise-cmp'
# subcommand: 'benchcab fluxsite-bitwise-cmp'
subparsers.add_parser(
"fluxnet-bitwise-cmp",
"fluxsite-bitwise-cmp",
parents=[args_help, args_subcommand],
help="Run the bitwise comparison step of the main fluxnet command.",
description="""Runs the bitwise comparison step for the fluxnet test suite. Bitwise
help="Run the bitwise comparison step of the main fluxsite command.",
description="""Runs the bitwise comparison step for the fluxsite test suite. Bitwise
comparisons are done on NetCDF output files using the `nccmp -df` command. Comparisons
are made between outputs that differ in their realisation and are matching in
all other configurations. Note, this command should ideally be run inside a PBS job.
Expand Down
4 changes: 3 additions & 1 deletion benchcab/comparison.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ def run(self, verbose=False) -> None:
print(f"Success: files {file_a.name} {file_b.name} are identical")
except CalledProcessError as exc:
output_file = (
self.root_dir / internal.SITE_BITWISE_CMP_DIR / f"{self.task_name}.txt"
self.root_dir
/ internal.FLUXSITE_BITWISE_CMP_DIR
/ f"{self.task_name}.txt"
)
with open(output_file, "w", encoding="utf-8") as file:
file.write(exc.stdout)
Expand Down
Loading

0 comments on commit f3ed8c0

Please sign in to comment.