diff --git a/src/semeio/fmudesign/fmudesignrunner.py b/src/semeio/fmudesign/fmudesignrunner.py index b612074e4..d4073661c 100644 --- a/src/semeio/fmudesign/fmudesignrunner.py +++ b/src/semeio/fmudesign/fmudesignrunner.py @@ -1,45 +1,60 @@ """Script for generating a design matrix from config input""" import argparse +import traceback import warnings -from argparse import ArgumentParser +from argparse import ArgumentParser, Namespace from pathlib import Path +from packaging.version import Version + +import semeio from semeio.fmudesign import DesignMatrix, excel2dict_design def get_parser() -> ArgumentParser: parser = argparse.ArgumentParser( - description="Generate design matrix to be used with ert DESIGN2PARAMS", - formatter_class=argparse.ArgumentDefaultsHelpFormatter, + description="Generate design matrix to be used with ERT", + epilog=( + "Example usage:\n" + " fmudesign input_config_example.xlsx \n" + " fmudesign input_config_example.xlsx output_example.xlsx \n\n" + "For more information, refer to the documentation at https://equinor.github.io/fmu-tools/fmudesign.html" + ), + formatter_class=argparse.RawDescriptionHelpFormatter, + add_help=False, ) parser.add_argument( - "config", type=str, help="Input design config filename in Excel format" + "-h", "--help", action="help", help="Show this help message and exit" + ) + + parser.add_argument( + "config", type=str, help="Input design matrix filename in Excel format" ) parser.add_argument( "destination", type=str, nargs="?", - help="Destination filename for design matrix", + help="Destination filename for design matrix (default: generateddesignmatrix.xlsx)", default="generateddesignmatrix.xlsx", ) parser.add_argument( "--designinput", type=str, - help="Alternative sheetname for the worksheet designinput", + help="Alternative sheetname for the worksheet designinput (default: designinput)", default="designinput", ) parser.add_argument( "--defaultvalues", type=str, - help="Alternative sheetname for worksheet defaultvalues", + help="Alternative sheetname for worksheet defaultvalues (default: defaultvalues)", default="defaultvalues", ) parser.add_argument( "--general_input", type=str, - help="Alternative sheetname for the worksheet general_input", + help="Alternative sheetname for the worksheet general_input (default: general_input)", default="general_input", ) @@ -47,23 +62,15 @@ def get_parser() -> ArgumentParser: "-v", "--verbose", action="count", + help="Verbosity of terminal output and plotting", default=0, - help="Verbosity of terminal output and plotting.", ) return parser -def main() -> None: - """semeio.fmudesign is a command line utility for generating design matrices - - Wrapper for the the semeio.fmudesign module""" - warnings.filterwarnings("ignore", category=DeprecationWarning) - warnings.filterwarnings("ignore", category=FutureWarning) - - parser = get_parser() +def validate_args(parser: ArgumentParser) -> None: args = parser.parse_args() - for sheet in ["designinput", "defaultvalues", "general_input"]: default = parser.get_default(sheet) custom = getattr(args, sheet) @@ -72,7 +79,14 @@ def main() -> None: if not Path(args.config).is_file(): raise OSError(f"Input file {args.config} does not exist") + if args.config == args.destination: + raise OSError( + f'Identical name "{args.config}" have been provided for the input' + "file and the output file" + ) + +def generate_design_matrix(args: Namespace) -> None: input_dict = excel2dict_design( args.config, gen_input_sheet=args.general_input, @@ -80,21 +94,44 @@ def main() -> None: default_val_sheet=args.defaultvalues, ) - if args.config == args.destination: - raise OSError( - f'Identical name "{args.config}" have been provided for the input' - "file and the output file. " - ) - # If destination is 'analysis/generateddesignmatrix.xlsx', then plots # will be saved to 'analysis/generateddesignmatrix//.png' output_dir = Path(args.destination).parent / Path(args.destination).stem design = DesignMatrix(verbosity=args.verbose, output_dir=output_dir) design.generate(input_dict) - design.to_xlsx(args.destination) +def main() -> None: + """semeio.fmudesign is a command line utility for generating design matrices + + Wrapper for the the semeio.fmudesign module""" + warnings.filterwarnings("ignore", category=DeprecationWarning) + warnings.filterwarnings("ignore", category=FutureWarning) + + parser = get_parser() + args = parser.parse_args() + validate_args(parser) + try: + generate_design_matrix(args) + except Exception: + traceback.print_exc() + print( + "\n \n", + "fmudesign failed. Read the error message above and fix the input file. \n", + "Documentation: https://equinor.github.io/fmu-tools/fmudesign.html \n", + "Issue tracker: https://github.com/equinor/semeio/issues \n", + "If you believe this error is a bug or are unable to fix it, create an issue or contact the scout team \n", + ) + return + print( + "\n", + f"Thank you for using fmudesign {Version(semeio.__version__).base_version} \n", + "Documentation: https://equinor.github.io/fmu-tools/fmudesign.html \n", + "Issues/bugs/feature requests: https://github.com/equinor/semeio/issues \n", + ) + + if __name__ == "__main__": main() diff --git a/tests/fmudesign/test_designmatrix.py b/tests/fmudesign/test_designmatrix.py index dfd0c3239..e88fe2d9b 100644 --- a/tests/fmudesign/test_designmatrix.py +++ b/tests/fmudesign/test_designmatrix.py @@ -5,7 +5,9 @@ from pathlib import Path import pandas as pd +from packaging.version import Version +import semeio from semeio.fmudesign import DesignMatrix TESTDATA = Path(__file__).parent / "data" @@ -72,7 +74,7 @@ def test_endpoint(tmpdir, monkeypatch): ["fmudesign", str(designfile)], check=True, capture_output=True, text=True ) - expected_output = """Generating sensitivity : seed + expected_output = f"""Generating sensitivity : seed Added sensitivity : seed Generating sensitivity : faults Added sensitivity : faults @@ -115,7 +117,10 @@ def test_endpoint(tmpdir, monkeypatch): Provided number of background values (11) is smaller than number of realisations for sensitivity ('sens7', 'p10_p90') and parameter PARAM15. Will be filled with default values. Provided number of background values (11) is smaller than number of realisations for sensitivity ('sens7', 'p10_p90') and parameter PARAM16. Will be filled with default values. A total of 91 realizations were generated - Designmatrix written to generateddesignmatrix.xlsx""" + Designmatrix written to generateddesignmatrix.xlsx + Thank you for using fmudesign {Version(semeio.__version__).base_version} + Documentation: https://equinor.github.io/fmu-tools/fmudesign.html + Issues/bugs/feature requests: https://github.com/equinor/semeio/issues""" assert result.stdout.split() == expected_output.split() assert Path("generateddesignmatrix.xlsx").exists # Default output file