Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
82 changes: 52 additions & 30 deletions src/expreccs/core/expreccs.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,24 @@
from expreccs.visualization.plotting import plot_results


def main(argv=None) -> None:
def main(argv: list[str] | None = None) -> None:
"""Main function for the expreccs executable"""
cwd = os.getcwd()
cmdargs = load_parser(argv)
cmdargs = parse_args(argv)
check_cmdargs(cmdargs)
file = cmdargs["input"].split(" ")
dic = {"fol": os.path.abspath(cmdargs["output"])}
file = cmdargs.input.split(" ")
dic = {"fol": os.path.abspath(cmdargs.output)}
dic["pat"] = os.path.dirname(__file__)[:-5]
dic["mode"], dic["plot"] = cmdargs["mode"], cmdargs["plot"]
dic["rotate"] = float(cmdargs["transform"])
dic["explicit"] = int(cmdargs["explicit"]) == 1
dic["zones"] = int(cmdargs["zones"]) == 1
dic["freq"] = cmdargs["frequency"].split(",")
dic["subfolders"] = int(cmdargs["subfolders"]) == 1
dic["nonregular"] = int(cmdargs["nonregular"]) == 1
dic["acoeff"] = cmdargs["acoeff"].split(",")
dic["boundaries"] = [int(val) for val in cmdargs["boundaries"][1:-1].split(",")]
dic["compare"] = cmdargs["compare"]
dic["mode"], dic["plot"] = cmdargs.mode, cmdargs.plot
dic["rotate"] = float(cmdargs.transform)
dic["explicit"] = int(cmdargs.explicit) == 1
dic["zones"] = int(cmdargs.zones) == 1
dic["freq"] = cmdargs.frequency.split(",")
dic["subfolders"] = int(cmdargs.subfolders) == 1
dic["nonregular"] = int(cmdargs.nonregular) == 1
dic["acoeff"] = cmdargs.acoeff.split(",")
dic["boundaries"] = [int(val) for val in cmdargs.boundaries[1:-1].split(",")]
dic["compare"] = cmdargs.compare

if dic["compare"]:
print("\nExecuting the compare functionality in expreccs, please wait.")
Expand Down Expand Up @@ -131,7 +131,7 @@ def main(argv=None) -> None:
os.chdir(cwd)


def load_parser(argv):
def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
"""Argument options"""
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
Expand Down Expand Up @@ -254,10 +254,10 @@ def load_parser(argv):
help="Set to '1' for a site with irregular contour, i.e., not defined in a "
"rectangle",
)
return vars(parser.parse_args(argv))
return parser.parse_args(argv)


def check_cmdargs(cmdargs: dict[str, str]) -> None:
def check_cmdargs(cmdargs: argparse.Namespace) -> None:
"""Validate command-line arguments and incompatible operations.

The checks cover configuration and model-folder inputs, output names,
Expand All @@ -275,41 +275,48 @@ def check_cmdargs(cmdargs: dict[str, str]) -> None:
SystemExit
If an argument is invalid or an incompatible combination is requested.
"""
input_value = cmdargs["input"]
input_value = cmdargs.input
if not input_value:
print("\nInvalid value for '-i', the input cannot be empty.\n")
raise SystemExit(1)
if not cmdargs["output"]:

if not cmdargs.output:
print("\nInvalid value for '-o', the output folder cannot be empty.\n")
raise SystemExit(1)

input_paths = input_value.split()
if len(input_paths) not in [1, 2]:
print(
f"\nInvalid value '-i {input_value}', expected one configuration "
"file or two model-folder paths separated by a space.\n"
)
raise SystemExit(1)

configuration_input = len(input_paths) == 1
folder_input = len(input_paths) == 2

if configuration_input and not input_paths[0].lower().endswith(".toml"):
print(
f"\nInvalid extension for '-i {input_value}', the valid extension "
"is .toml, or provide paths to the regional and site model "
"folders.\n"
)
raise SystemExit(1)
transform = cmdargs["transform"]

transform = cmdargs.transform
try:
transform_value = float(transform)
except ValueError:
transform_value = float("nan")

if not math.isfinite(transform_value):
print(
f"\nInvalid value '-t {transform}', expected a finite number of "
"degrees.\n"
)
raise SystemExit(1)
boundaries = cmdargs["boundaries"]

boundaries = cmdargs.boundaries
boundary_pattern = re.fullmatch(
r"\[\s*-?\d+\s*,\s*-?\d+\s*,\s*-?\d+\s*,\s*-?\d+\s*\]",
boundaries,
Expand All @@ -320,26 +327,34 @@ def check_cmdargs(cmdargs: dict[str, str]) -> None:
"brackets, e.g., '-b [0,2,0,0]'.\n"
)
raise SystemExit(1)

boundary_values = [int(value.strip()) for value in boundaries[1:-1].split(",")]
if any(value < -1 for value in boundary_values):
print(
f"\nInvalid value '-b {boundaries}', boundary entries must be -1 "
"or non-negative integers.\n"
)
raise SystemExit(1)
frequency = cmdargs["frequency"]
if not re.fullmatch(r"[1-9]\d*(?:\s*,\s*[1-9]\d*)*", frequency):

frequency = cmdargs.frequency
if not re.fullmatch(
r"[1-9]\d*(?:\s*,\s*[1-9]\d*)*",
frequency,
):
print(
f"\nInvalid value '-f {frequency}', expected positive integers "
"separated by commas.\n"
)
raise SystemExit(1)

frequency_values = [int(value.strip()) for value in frequency.split(",")]
acoeff = cmdargs["acoeff"]

acoeff = cmdargs.acoeff
try:
acoeff_values = [float(value.strip()) for value in acoeff.split(",")]
except ValueError:
acoeff_values = []

if not acoeff_values or any(
value < 0 or not math.isfinite(value) for value in acoeff_values
):
Expand All @@ -348,13 +363,15 @@ def check_cmdargs(cmdargs: dict[str, str]) -> None:
"numbers separated by commas.\n"
)
raise SystemExit(1)

if len(acoeff_values) not in [1, len(frequency_values)]:
print(
f"\nInvalid value '-a {acoeff}', expected one coefficient or one "
"coefficient for each value provided with '-f'.\n"
)
raise SystemExit(1)
compare = cmdargs["compare"]

compare = cmdargs.compare
if compare:
compare_options = {
"-i": ("input", "input.toml"),
Expand All @@ -371,7 +388,7 @@ def check_cmdargs(cmdargs: dict[str, str]) -> None:
invalid_options = [
option
for option, (name, default) in compare_options.items()
if cmdargs[name] != default
if getattr(cmdargs, name) != default
]
if invalid_options:
print(
Expand All @@ -380,13 +397,16 @@ def check_cmdargs(cmdargs: dict[str, str]) -> None:
f"{', '.join(invalid_options)}.\n"
)
raise SystemExit(1)
if cmdargs["subfolders"] != "1":

if cmdargs.subfolders != "1":
print(
"\nInvalid combination, '-c compare' requires the subfolder "
"structure and cannot be used with '-s 0'.\n"
)
raise SystemExit(1)

return

if folder_input:
configuration_options = {
"-m": ("mode", "all"),
Expand All @@ -397,7 +417,7 @@ def check_cmdargs(cmdargs: dict[str, str]) -> None:
invalid_options = [
option
for option, (name, default) in configuration_options.items()
if cmdargs[name] != default
if getattr(cmdargs, name) != default
]
if invalid_options:
print(
Expand All @@ -406,6 +426,7 @@ def check_cmdargs(cmdargs: dict[str, str]) -> None:
f"{', '.join(invalid_options)}.\n"
)
raise SystemExit(1)

if configuration_input:
folder_options = {
"-b": ("boundaries", "[0,0,0,0]"),
Expand All @@ -418,7 +439,7 @@ def check_cmdargs(cmdargs: dict[str, str]) -> None:
invalid_options = [
option
for option, (name, default) in folder_options.items()
if cmdargs[name] != default
if getattr(cmdargs, name) != default
]
if invalid_options:
print(
Expand All @@ -427,7 +448,8 @@ def check_cmdargs(cmdargs: dict[str, str]) -> None:
"regional and site model folders.\n"
)
raise SystemExit(1)
if cmdargs["plot"] != "no" and cmdargs["subfolders"] != "1":

if cmdargs.plot != "no" and cmdargs.subfolders != "1":
print(
"\nInvalid combination, plot generation requires the subfolder "
"structure and cannot be used with '-s 0'.\n"
Expand Down
32 changes: 17 additions & 15 deletions tests/scripts/docs_check_outputs.sh
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
files=(
"test_outputs/hello_world/hello_world_distance_from_border.png"
"test_outputs/hello_world/hello_world_reference_watfluxi+.png"
"test_outputs/hello_world/hello_world_regional_watfluxi+.png"
"test_outputs/hello_world/hello_world_sensor_pressure_over_time.png"
"test_outputs/hello_world/hello_world_site_flux_watfluxi+.png"
"test_outputs/hello_world/hello_world_summary_BHP_site_reference.png"
"test_outputs/non-regular_boundaries/expreccs_opernum_i,j,1_t0.png"
"test_outputs/regular_boundaries/reference_sgas_i,j,1_t90.png"
"test_outputs/regular_boundaries/regional_rpr-3.png"
)
files="
test_outputs/hello_world/hello_world_distance_from_border.png
test_outputs/hello_world/hello_world_reference_watfluxi+.png
test_outputs/hello_world/hello_world_regional_watfluxi+.png
test_outputs/hello_world/hello_world_sensor_pressure_over_time.png
test_outputs/hello_world/hello_world_site_flux_watfluxi+.png
test_outputs/hello_world/hello_world_summary_BHP_site_reference.png
test_outputs/non-regular_boundaries/expreccs_opernum_i,j,1_t0.png
test_outputs/regular_boundaries/reference_sgas_i,j,1_t90.png
test_outputs/regular_boundaries/regional_rpr-3.png
"

missing_file="test_outputs/missing_docs_files.txt"
missing=0

rm -f "$missing_file"

for f in "${files[@]}"; do
if [[ ! -f "$f" ]]; then
printf '%s\n' "$files" | while IFS= read -r f; do
[ -z "$f" ] && continue
if [ ! -f "$f" ]; then
echo "$f" >> "$missing_file"
((missing++))
fi
done

if (( missing == 0 )); then
if [ "$missing" -eq 0 ]; then
echo "All figures and files exist."
return 0
else
echo "$missing figure(s) or file(s) missing."
echo "See $missing_file"
return 1
fi
62 changes: 32 additions & 30 deletions tests/scripts/paper_2025.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,48 @@ python3 $OUT/Case3/run_case3.py &
python3 $OUT/Case4/run_case4.py &
wait

files=(
"$OUT/Case4/Case_4_site_pres_pressure.png"
"$OUT/Case4/Case_4_reference_saturation.png"
"$OUT/Case4/Case_4_difference_site_pres_pressure.png"
"$OUT/Case4/Case_4_reference_pressure.png"
"$OUT/Case4/Case_4_difference_site_pres_saturation.png"
"$OUT/Case4/Case_4_regional_pressure.png"
"$OUT/Case4/Case_4_site_pres_saturation.png"
"$OUT/Case4/Case_4_regional_saturation.png"
"$OUT/Case2/comparegrid_0_40m_sensor_pressure_over_time.png"
"$OUT/Case2/comparegrid_0_40m_sensor_gasfluxi+_over_time.png"
"$OUT/Case3/compareeveryday_sensor_pressure_over_time.png"
"$OUT/Case1/Case_1_maximum_pressure_difference_over_time.png"
"$OUT/Case1/Case_1_difference_site_flux_pressure.png"
"$OUT/Case1/Case_1_difference_site_flux_gasfluxi+.png"
"$OUT/Case1/Case_1_maximum_gasfluxi+_difference_over_time.png"
"$OUT/Case1/Case_1_reference_saturation.png"
"$OUT/Case1/Case_1_reference_pressure.png"
"$OUT/Case1/Case_1_reference_watfluxi+.png"
"$OUT/Case1/Case_1_distance_from_border.png"
"$OUT/Case1/Case_1_difference_site_flux_saturation.png"
"$OUT/Case1/Case_1_difference_site_pres_saturation.png"
"$OUT/Case1/Case_1_summary_PR_site_reference.png"
"$OUT/Case1/Case_1_difference_site_pres_gasfluxi+.png"
"$OUT/Case1/Case_1_difference_site_pres_pressure.png"
)
files="
$OUT/Case4/Case_4_site_pres_pressure.png
$OUT/Case4/Case_4_reference_saturation.png
$OUT/Case4/Case_4_difference_site_pres_pressure.png
$OUT/Case4/Case_4_reference_pressure.png
$OUT/Case4/Case_4_difference_site_pres_saturation.png
$OUT/Case4/Case_4_regional_pressure.png
$OUT/Case4/Case_4_site_pres_saturation.png
$OUT/Case4/Case_4_regional_saturation.png
$OUT/Case2/comparegrid_0_40m_sensor_pressure_over_time.png
$OUT/Case2/comparegrid_0_40m_sensor_gasfluxi+_over_time.png
$OUT/Case3/compareeveryday_sensor_pressure_over_time.png
$OUT/Case1/Case_1_maximum_pressure_difference_over_time.png
$OUT/Case1/Case_1_difference_site_flux_pressure.png
$OUT/Case1/Case_1_difference_site_flux_gasfluxi+.png
$OUT/Case1/Case_1_maximum_gasfluxi+_difference_over_time.png
$OUT/Case1/Case_1_reference_saturation.png
$OUT/Case1/Case_1_reference_pressure.png
$OUT/Case1/Case_1_reference_watfluxi+.png
$OUT/Case1/Case_1_distance_from_border.png
$OUT/Case1/Case_1_difference_site_flux_saturation.png
$OUT/Case1/Case_1_difference_site_pres_saturation.png
$OUT/Case1/Case_1_summary_PR_site_reference.png
$OUT/Case1/Case_1_difference_site_pres_gasfluxi+.png
$OUT/Case1/Case_1_difference_site_pres_pressure.png
"

missing_file="test_outputs/missing_publication_files.txt"
missing=0

for f in "${files[@]}"; do
if [[ ! -f "$f" ]]; then
printf '%s\n' "$files" | while IFS= read -r f; do
[ -z "$f" ] && continue
if [ ! -f "$f" ]; then
echo "$f" >> "$missing_file"
((missing++))
fi
done

if (( missing == 0 )); then
if [ "$missing" -eq 0 ]; then
echo "All figures and files exist."
return 0
else
echo "$missing figure(s) or file(s) missing."
echo "See $missing_file"
return 1
fi
Loading