From d2e73edb134b0c0df9e52ad5fa26a85e822157ed Mon Sep 17 00:00:00 2001 From: Jakob Gamper <97gamjak@gmail.com> Date: Fri, 10 May 2024 21:21:03 +0200 Subject: [PATCH 1/5] added first implementation of combined cli tool --- PQAnalysis/cli/_cli_base.py | 42 +++++++ PQAnalysis/cli/build_nep_traj.py | 199 +++++++++++++++++-------------- PQAnalysis/cli/main.py | 24 ++++ pyproject.toml | 1 + 4 files changed, 174 insertions(+), 92 deletions(-) create mode 100644 PQAnalysis/cli/_cli_base.py create mode 100644 PQAnalysis/cli/main.py diff --git a/PQAnalysis/cli/_cli_base.py b/PQAnalysis/cli/_cli_base.py new file mode 100644 index 00000000..3dff11b4 --- /dev/null +++ b/PQAnalysis/cli/_cli_base.py @@ -0,0 +1,42 @@ +""" +This module contains the abstract base class for all the CLI classes. +""" + +from abc import ABCMeta, abstractmethod + + +class CLIBase(metaclass=ABCMeta): + """ + Abstract base class for all the CLI classes. + """ + + @classmethod + @abstractmethod + def program_name(cls) -> str: + """ + Return the name of the program. + + Returns + ------- + str + The name of the program. + """ + + @classmethod + @abstractmethod + def add_arguments(cls, parser): + """ + Add the arguments to the parser. + + Parameters + ---------- + parser : _type_ + _description_ + """ + + @classmethod + @abstractmethod + def run(cls, args): + """ + Run the CLI. + """ diff --git a/PQAnalysis/cli/build_nep_traj.py b/PQAnalysis/cli/build_nep_traj.py index fffbd4c7..51471369 100644 --- a/PQAnalysis/cli/build_nep_traj.py +++ b/PQAnalysis/cli/build_nep_traj.py @@ -10,6 +10,7 @@ from PQAnalysis.io.nep.nep_writer import NEPWriter from PQAnalysis.config import code_base_url from ._argument_parser import _ArgumentParser +from ._cli_base import CLIBase __outputdoc__ = """ @@ -25,6 +26,110 @@ __doc__ += __outputdoc__ +class BuildNEPTrajCLI(CLIBase): + @classmethod + def program_name(cls): + return 'build_nep_traj' + + @classmethod + def add_arguments(cls, parser): + parser.add_argument( + 'file_prefixes', + type=str, + nargs='+', + help='The file prefixes for all input files.' + ) + + parser.parse_output_file() + + parser.add_argument( + '--test-ratio', + type=float, + default=0.0, + help=( + "The ratio of testing frames to the total number of " + "frames, by default 0.0. If the test_ratio is 0.0 no " + "train and test files are created. If the test_ratio " + "is larger not equal to 0.0, the test_ratio is used " + "to determine the number of training and testing frames. " + "The final ratio will be as close to the test_ratio as " + "possible, but if it is not possible to have the exact " + "ratio, always the higher next higher ratio is chosen. " + "As output filenames the original filename is used with " + "the suffix _train or _test appended and the same " + "FileWritingMode as the original file is used." + ) + ) + + parser.add_argument( + '--total-ratios', + type=str, + default=None, + help=( + "The total_ratios keyword argument is used to " + "describe frame ratios including validation frames " + "in the format train_ratio:test_ratio:validation_ratio. " + "The validation_ratio is optional and if not given, " + "no validation frames are written. The total sum of " + "the integer values provided do not have to add up " + "to the total number of frames in the input trajectory " + "files. The ratios are used to determine the ratios of " + "the training, testing, and validation frames. The final" + "ratio will be as close to the given ratios as possible, " + "but if it is not possible to have the exact ratio, " + "always the next higher ratio is chosen. As output " + "filenames the original filename is used with the suffix " + "_train, _test, or _validation appended and the same " + "FileWritingMode as the original file is used. The " + "validation frames are written to a file with the " + "suffix _validation and a file with the suffix _validation.ref. " + "The _validation file contains only the coordinates and " + "box information to function as crude testing input and " + "the _validation.ref file contains all information " + "additionally provided in the original files. " + "Pay Attention: This keyword argument is mutually exclusive " + "with the test_ratio keyword argument. If both are given, " + "a ValueError is raised." + ) + ) + + parser.add_argument( + '--use-forces', + action='store_true', + default=False, + help='Whether to include forces in the output file.' + ) + + parser.add_argument( + '--use-virial', + action='store_true', + default=False, + help='Whether to include the virial in the output file.' + ) + + parser.add_argument( + '--use-stress', + action='store_true', + default=False, + help='Whether to include the stress tensor in the output file.' + ) + + parser.parse_mode() + + @classmethod + def run(cls, args): + writer = NEPWriter(filename=args.output, mode=args.mode) + + writer.write_from_files( + file_prefixes=args.file_prefixes, + test_ratio=args.test_ratio, + total_ratios=args.total_ratios, + use_forces=args.use_forces, + use_virial=args.use_virial, + use_stress=args.use_stress + ) + + def main(): """ Main function of the build_nep_traj command line tool, which is basically @@ -33,98 +138,8 @@ def main(): """ parser = _ArgumentParser(description=__outputdoc__, epilog=__epilog__) - parser.add_argument( - 'file_prefixes', - type=str, - nargs='+', - help='The file prefixes for all input files.' - ) - - parser.parse_output_file() - - parser.add_argument( - '--test-ratio', - type=float, - default=0.0, - help=( - "The ratio of testing frames to the total number of " - "frames, by default 0.0. If the test_ratio is 0.0 no " - "train and test files are created. If the test_ratio " - "is larger not equal to 0.0, the test_ratio is used " - "to determine the number of training and testing frames. " - "The final ratio will be as close to the test_ratio as " - "possible, but if it is not possible to have the exact " - "ratio, always the higher next higher ratio is chosen. " - "As output filenames the original filename is used with " - "the suffix _train or _test appended and the same " - "FileWritingMode as the original file is used." - ) - ) - - parser.add_argument( - '--total-ratios', - type=str, - default=None, - help=( - "The total_ratios keyword argument is used to " - "describe frame ratios including validation frames " - "in the format train_ratio:test_ratio:validation_ratio. " - "The validation_ratio is optional and if not given, " - "no validation frames are written. The total sum of " - "the integer values provided do not have to add up " - "to the total number of frames in the input trajectory " - "files. The ratios are used to determine the ratios of " - "the training, testing, and validation frames. The final" - "ratio will be as close to the given ratios as possible, " - "but if it is not possible to have the exact ratio, " - "always the next higher ratio is chosen. As output " - "filenames the original filename is used with the suffix " - "_train, _test, or _validation appended and the same " - "FileWritingMode as the original file is used. The " - "validation frames are written to a file with the " - "suffix _validation and a file with the suffix _validation.ref. " - "The _validation file contains only the coordinates and " - "box information to function as crude testing input and " - "the _validation.ref file contains all information " - "additionally provided in the original files. " - "Pay Attention: This keyword argument is mutually exclusive " - "with the test_ratio keyword argument. If both are given, " - "a ValueError is raised." - ) - ) - - parser.add_argument( - '--use-forces', - action='store_true', - default=False, - help='Whether to include forces in the output file.' - ) - - parser.add_argument( - '--use-virial', - action='store_true', - default=False, - help='Whether to include the virial in the output file.' - ) - - parser.add_argument( - '--use-stress', - action='store_true', - default=False, - help='Whether to include the stress tensor in the output file.' - ) - - parser.parse_mode() + BuildNEPTrajCLI.add_arguments(parser) args = parser.parse_args() - writer = NEPWriter(filename=args.output, mode=args.mode) - - writer.write_from_files( - file_prefixes=args.file_prefixes, - test_ratio=args.test_ratio, - total_ratios=args.total_ratios, - use_forces=args.use_forces, - use_virial=args.use_virial, - use_stress=args.use_stress - ) + BuildNEPTrajCLI.run(args) diff --git a/PQAnalysis/cli/main.py b/PQAnalysis/cli/main.py new file mode 100644 index 00000000..f2cc7c57 --- /dev/null +++ b/PQAnalysis/cli/main.py @@ -0,0 +1,24 @@ +from ._argument_parser import _ArgumentParser + +__outputdoc__ = """ + +This is the command line interface for the PQAnalysis package. +""" + +from .build_nep_traj import BuildNEPTrajCLI + + +def main(): + parser = _ArgumentParser(description=__outputdoc__, epilog=None) + + subparsers = parser.add_subparsers(dest='command') + + build_nep_traj_parser = subparsers.add_parser( + BuildNEPTrajCLI.program_name(), help=BuildNEPTrajCLI.__doc__ + ) + BuildNEPTrajCLI.add_arguments(build_nep_traj_parser) + + args = parser.parse_args() + + if args.command == BuildNEPTrajCLI.program_name(): + BuildNEPTrajCLI.run(args) diff --git a/pyproject.toml b/pyproject.toml index 4fe6c7d2..011d190c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,6 +56,7 @@ docs = [ version_file = "PQAnalysis/_version.py" [project.scripts] +pqanalysis = "PQAnalysis.cli.main:main" traj2box = "PQAnalysis.cli.traj2box:main" traj2qmcfc = "PQAnalysis.cli.traj2qmcfc:main" rst2xyz = "PQAnalysis.cli.rst2xyz:main" From 8edf8fc26a8ae2417c043f5fccfbd957d3f0bdb6 Mon Sep 17 00:00:00 2001 From: Jakob Gamper <97gamjak@gmail.com> Date: Fri, 10 May 2024 23:21:51 +0200 Subject: [PATCH 2/5] combining cli finished --- PQAnalysis/cli/_argument_parser.py | 7 +- PQAnalysis/cli/add_molecules.py | 344 +++++++++++++++-------------- PQAnalysis/cli/build_nep_traj.py | 4 + PQAnalysis/cli/continue_input.py | 61 +++-- PQAnalysis/cli/gen2xyz.py | 59 +++-- PQAnalysis/cli/main.py | 55 ++++- PQAnalysis/cli/rdf.py | 26 ++- PQAnalysis/cli/rst2xyz.py | 65 ++++-- PQAnalysis/cli/traj2box.py | 51 +++-- PQAnalysis/cli/traj2qmcfc.py | 32 ++- PQAnalysis/cli/xyz2gen.py | 73 +++--- pyproject.toml | 1 + tests/cli/test_traj2box.py | 2 + 13 files changed, 500 insertions(+), 280 deletions(-) diff --git a/PQAnalysis/cli/_argument_parser.py b/PQAnalysis/cli/_argument_parser.py index fc747db7..09d9fab8 100644 --- a/PQAnalysis/cli/_argument_parser.py +++ b/PQAnalysis/cli/_argument_parser.py @@ -13,8 +13,11 @@ from beartype.typing import Sequence +from rich_argparse import ArgumentDefaultsRichHelpFormatter import PQAnalysis.config as config # pylint: disable=consider-using-from-import # here needed to set the config attributes + +from PQAnalysis.utils.common import __header__ from PQAnalysis.traj import MDEngineFormat from PQAnalysis.io.formats import FileWritingMode from PQAnalysis._version import __version__ @@ -46,7 +49,7 @@ def __init__(self, *args, **kwargs): """ super().__init__( - formatter_class=argparse.ArgumentDefaultsHelpFormatter, + formatter_class=ArgumentDefaultsRichHelpFormatter, *args, **kwargs ) @@ -55,7 +58,7 @@ def __init__(self, *args, **kwargs): if 'prog' not in kwargs: kwargs['prog'] = self.prog.split(".")[0] super().__init__( - formatter_class=argparse.ArgumentDefaultsHelpFormatter, + formatter_class=ArgumentDefaultsRichHelpFormatter, *args, **kwargs ) diff --git a/PQAnalysis/cli/add_molecules.py b/PQAnalysis/cli/add_molecules.py index 65462890..110cd603 100644 --- a/PQAnalysis/cli/add_molecules.py +++ b/PQAnalysis/cli/add_molecules.py @@ -10,7 +10,9 @@ from PQAnalysis.config import code_base_url from PQAnalysis.tools.add_molecule import add_molecule from PQAnalysis.io.formats import OutputFileFormat + from ._argument_parser import _ArgumentParser +from ._cli_base import CLIBase __outputdoc__ = """ @@ -27,181 +29,199 @@ __epilog__ += "file keys please visit " __epilog__ += f"{code_base_url}PQAnalysis.cli.add_molecules.html." __epilog__ += "\n" +__epilog__ += "\n" __doc__ += __outputdoc__ -def main(): +class AddMoleculesCLI(CLIBase): """ - Main function of the add_molecules command line tool, - which is basically just a wrapper for the add_molecules - function. For more information on the add_molecules - function please visit :py:func:`PQAnalysis.tools.add_molecule`. + Command Line Tool for Adding Molecules to Restart Files """ - parser = _ArgumentParser(description=__outputdoc__, epilog=__epilog__) + @classmethod + def program_name(cls): + return 'add_molecules' + + @classmethod + def add_arguments(cls, parser): + parser.add_argument( + 'restart_file', + type=str, + help='The restart file where the molecules should be added.' + ) + + parser.add_argument( + 'molecule_file', + type=str, + help=( + "The molecule file that contains the coordinates " + "of the molecule that should be added. Can be in " + "any format that is supported by the PQAnalysis library." + ) + ) + + parser.parse_output_file() + parser.parse_mode() + + parser.add_argument( + '--mol-file-type', + dest='mol_file_type', + type=OutputFileFormat, + default=OutputFileFormat.AUTO, + choices=OutputFileFormat.__members__.values(), + help=( + 'The file format of the molecule file. ' + 'If not specified, the file format will ' + 'be inferred from the file extension.' + ) + ) + + parser.add_argument( + "--rst-mol-desc-file", + dest='rst_mol_desc_file', + type=str, + help=( + "The moldescriptor file that is associated with the " + "restart file. If not specified, the moldescriptor " + "file will not be used." + ), + default=None + ) - parser.add_argument( - 'restart_file', - type=str, - help='The restart file where the molecules should be added.' - ) - - parser.add_argument( - 'molecule_file', - type=str, - help=( - "The molecule file that contains the coordinates " - "of the molecule that should be added. Can be in " - "any format that is supported by the PQAnalysis library." + parser.add_argument( + "--molecule-mol-desc-file", + dest='molecule_mol_desc_file', + type=str, + help=( + "The moldescriptor file that is associated with " + "the molecule file. If not specified, the moldescriptor " + "file will not be used. Can only be used if the " + "molecule file is a restart file type." + ), + default=None ) - ) - - parser.parse_output_file() - parser.parse_mode() - - parser.add_argument( - '--mol-file-type', - dest='mol_file_type', - type=OutputFileFormat, - default=OutputFileFormat.AUTO, - choices=OutputFileFormat.__members__.values(), - help=( - 'The file format of the molecule file. ' - 'If not specified, the file format will ' - 'be inferred from the file extension.' + + parser.add_argument( + "-n, --n-molecules", + dest='n_molecules', + type=int, + default=1, + help="The number of molecules that should be added to the restart file." ) - ) - - parser.add_argument( - "--rst-mol-desc-file", - dest='rst_mol_desc_file', - type=str, - help=( - "The moldescriptor file that is associated with the " - "restart file. If not specified, the moldescriptor " - "file will not be used." - ), - default=None - ) - - parser.add_argument( - "--molecule-mol-desc-file", - dest='molecule_mol_desc_file', - type=str, - help=( - "The moldescriptor file that is associated with " - "the molecule file. If not specified, the moldescriptor " - "file will not be used. Can only be used if the " - "molecule file is a restart file type." - ), - default=None - ) - - parser.add_argument( - "-n, --n-molecules", - dest='n_molecules', - type=int, - default=1, - help="The number of molecules that should be added to the restart file." - ) - - parser.add_argument( - "--max-iter", - dest='max_iter', - type=int, - default=100, - help=( - "The maximum number of iterations that should " - "be used to fit the molecule to the restart file." + + parser.add_argument( + "--max-iter", + dest='max_iter', + type=int, + default=100, + help=( + "The maximum number of iterations that should " + "be used to fit the molecule to the restart file." + ) ) - ) - - parser.add_argument( - "-c", "--cut", - dest='cut', - type=float, - default=1.0, - help=( - "The distance cutoff that should be used " - "to fit the molecule to the restart file in Angstrom." + + parser.add_argument( + "-c", "--cut", + dest='cut', + type=float, + default=1.0, + help=( + "The distance cutoff that should be used " + "to fit the molecule to the restart file in Angstrom." + ) ) - ) - - parser.add_argument( - "--max-disp", "--max-displacement", - dest='max_disp', - type=float, - default=0.1, - help=( - "The maximum displacement that should be applied " - "to the given molecule geometry relative to " - "its center of mass in percentage." + + parser.add_argument( + "--max-disp", "--max-displacement", + dest='max_disp', + type=float, + default=0.1, + help=( + "The maximum displacement that should be applied " + "to the given molecule geometry relative to " + "its center of mass in percentage." + ) ) - ) - - parser.add_argument( - "--rot", "--rotation-angle-step", - dest='rot', - type=int, - default=10, - help=( - "If the randomly placed molecule does not " - "fit into the restart file, the molecule " - "is rotated by the given angle step in degrees." + + parser.add_argument( + "--rot", "--rotation-angle-step", + dest='rot', + type=int, + default=10, + help=( + "If the randomly placed molecule does not " + "fit into the restart file, the molecule " + "is rotated by the given angle step in degrees." + ) ) - ) - - parser.add_argument( - "--topology-file", "--top-file", - dest='top_file', - type=str, - help=( - "The topology file that is associated with " - "the restart file. If not specified, " - "the topology file will not be used." - ), - default=None - ) - - parser.add_argument( - "--added-topology-file", "--added-top-file", - dest='added_top_file', - type=str, - help=( - "The topology file that is associated with " - "the molecule file. If not specified, the " - "topology file will not be used." - ), - default=None - ) - - parser.add_argument( - "--output-topology-file", "--output-top-file", - dest='output_top_file', - type=str, - help="The output topology file. If not specified, the output is printed to stdout.", - default=None - ) - - parser.parse_engine() + + parser.add_argument( + "--topology-file", "--top-file", + dest='top_file', + type=str, + help=( + "The topology file that is associated with " + "the restart file. If not specified, " + "the topology file will not be used." + ), + default=None + ) + + parser.add_argument( + "--added-topology-file", "--added-top-file", + dest='added_top_file', + type=str, + help=( + "The topology file that is associated with " + "the molecule file. If not specified, the " + "topology file will not be used." + ), + default=None + ) + + parser.add_argument( + "--output-topology-file", "--output-top-file", + dest='output_top_file', + type=str, + help="The output topology file. If not specified, the output is printed to stdout.", + default=None + ) + + parser.parse_engine() + + @classmethod + def run(cls, args): + add_molecule( + args.restart_file, + args.molecule_file, + output_file=args.output, + molecule_file_type=args.mol_file_type, + restart_moldescriptor_file=args.rst_mol_desc_file, + molecule_moldescriptor_file=args.molecule_mol_desc_file, + number_of_additions=args.n_molecules, + max_iterations=args.max_iter, + distance_cutoff=args.cut, + max_displacement=args.max_disp, + rotation_angle_step=args.rot, + md_engine_format=args.engine, + mode=args.mode, + topology_file=args.top_file, + topology_file_to_add=args.added_top_file, + topology_file_output=args.output_top_file + ) + + +def main(): + """ + Main function of the add_molecules command line tool, + which is basically just a wrapper for the add_molecules + function. For more information on the add_molecules + function please visit :py:func:`PQAnalysis.tools.add_molecule`. + """ + parser = _ArgumentParser(description=__outputdoc__, epilog=__epilog__) + + AddMoleculesCLI.add_arguments(parser) args = parser.parse_args() - add_molecule( - args.restart_file, - args.molecule_file, - output_file=args.output, - molecule_file_type=args.mol_file_type, - restart_moldescriptor_file=args.rst_mol_desc_file, - molecule_moldescriptor_file=args.molecule_mol_desc_file, - number_of_additions=args.n_molecules, - max_iterations=args.max_iter, - distance_cutoff=args.cut, - max_displacement=args.max_disp, - rotation_angle_step=args.rot, - md_engine_format=args.engine, - mode=args.mode, - topology_file=args.top_file, - topology_file_to_add=args.added_top_file, - topology_file_output=args.output_top_file - ) + AddMoleculesCLI.run(args) diff --git a/PQAnalysis/cli/build_nep_traj.py b/PQAnalysis/cli/build_nep_traj.py index 51471369..86265ae9 100644 --- a/PQAnalysis/cli/build_nep_traj.py +++ b/PQAnalysis/cli/build_nep_traj.py @@ -22,11 +22,15 @@ __epilog__ += "For more information on required and optional input file keys please visit " __epilog__ += f"{code_base_url}PQAnalysis.cli.build_nep_traj.html." __epilog__ += "\n" +__epilog__ += "\n" __doc__ += __outputdoc__ class BuildNEPTrajCLI(CLIBase): + """ + Command Line Tool for Building Neuroevolution Potential (NEP) training/test trajectories + """ @classmethod def program_name(cls): return 'build_nep_traj' diff --git a/PQAnalysis/cli/continue_input.py b/PQAnalysis/cli/continue_input.py index 9ec17570..ada35686 100644 --- a/PQAnalysis/cli/continue_input.py +++ b/PQAnalysis/cli/continue_input.py @@ -8,6 +8,8 @@ from PQAnalysis.io import InputFileFormat, continue_input_file from PQAnalysis.config import code_base_url from ._argument_parser import _ArgumentParser +from ._cli_base import CLIBase + __outputdoc__ = """ @@ -23,6 +25,44 @@ __epilog__ += "For more information on required and optional input file keys please visit " __epilog__ += f"{code_base_url}PQAnalysis.cli.continue_input.html." __epilog__ += "\n" +__epilog__ += "\n" + + +class ContinueInputCLI(CLIBase): + """ + Command Line Tool for Extending PQ MD Simulation Input Files + """ + @classmethod + def program_name(cls): + return 'continue_input' + + @classmethod + def add_arguments(cls, parser): + parser.parse_input_file() + + parser.add_argument( + '-n', '--number', + type=int, + default=1, + help='The number of times the input file should be continued.' + ) + + parser.add_argument( + '--input-format', + type=str, + default='PQ', + help='The format of the input file. Default is PQ.' + ) + + @classmethod + def run(cls, args): + input_format = InputFileFormat(args.input_format) + + continue_input_file( + args.input_file, + args.number, + input_format + ) def main(): @@ -32,24 +72,9 @@ def main(): the continue_input_file function please visit :py:func:`PQAnalysis.io.api.continue_input_file`. """ parser = _ArgumentParser(description=__outputdoc__, epilog=__epilog__) - parser.parse_input_file() - - parser.add_argument( - '-n', '--number', - type=int, - default=1, - help='The number of times the input file should be continued.' - ) - - parser.add_argument( - '--input-format', - type=str, - default='PQ', - help='The format of the input file. Default is PQ.' - ) - args = parser.parse_args() + ContinueInputCLI.add_arguments(parser) - input_format = InputFileFormat(args.input_format) + args = parser.parse_args() - continue_input_file(args.input_file, args.number, input_format) + ContinueInputCLI.run(args) diff --git a/PQAnalysis/cli/gen2xyz.py b/PQAnalysis/cli/gen2xyz.py index 258f3f61..867a5e4b 100644 --- a/PQAnalysis/cli/gen2xyz.py +++ b/PQAnalysis/cli/gen2xyz.py @@ -10,6 +10,7 @@ from PQAnalysis.io import gen2xyz from PQAnalysis.config import code_base_url from ._argument_parser import _ArgumentParser +from ._cli_base import CLIBase __outputdoc__ = """ @@ -24,10 +25,49 @@ __epilog__ += "For more information on required and optional input file keys please visit " __epilog__ += f"{code_base_url}PQAnalysis.cli.gen2xyz.html." __epilog__ += "\n" +__epilog__ += "\n" __doc__ += __outputdoc__ +class GEN2XYZCLI(CLIBase): + """ + Command Line Tool for Converting GEN Files to XYZ Files + """ + @classmethod + def program_name(cls): + return 'gen2xyz' + + @classmethod + def add_arguments(cls, parser): + parser.add_argument( + 'gen_file', + type=str, + help='The gen file to be converted.' + ) + + parser.parse_output_file() + + parser.add_argument( + '--nobox', + action='store_true', + help='Do not print the box.' + ) + + parser.parse_engine() + parser.parse_mode() + + @classmethod + def run(cls, args): + gen2xyz( + gen_file=args.gen_file, + output=args.output, + print_box=not args.nobox, + md_format=args.engine, + mode=args.mode, + ) + + def main(): """ Main function of the gen2xyz command line tool, which is basically just @@ -36,23 +76,8 @@ def main(): """ parser = _ArgumentParser(description=__outputdoc__, epilog=__epilog__) - parser.add_argument('gen_file', type=str, - help='The gen file to be converted.') - - parser.parse_output_file() - - parser.add_argument('--nobox', action='store_true', - help='Do not print the box.') - - parser.parse_engine() - parser.parse_mode() + GEN2XYZCLI.add_arguments(parser) args = parser.parse_args() - gen2xyz( - gen_file=args.gen_file, - output=args.output, - print_box=not args.nobox, - md_format=args.engine, - mode=args.mode, - ) + GEN2XYZCLI.run(args) diff --git a/PQAnalysis/cli/main.py b/PQAnalysis/cli/main.py index f2cc7c57..4c1b47d3 100644 --- a/PQAnalysis/cli/main.py +++ b/PQAnalysis/cli/main.py @@ -1,3 +1,18 @@ +""" +A command line interface for the PQAnalysis package. +""" + +from PQAnalysis.config import code_base_url + +from .xyz2gen import XYZ2GENCLI +from .traj2qmcfc import Traj2QMCFCCLI +from .traj2box import Traj2BoxCLI +from .rst2xyz import Rst2XYZCLI +from .rdf import RDFCLI +from .gen2xyz import GEN2XYZCLI +from .continue_input import ContinueInputCLI +from .add_molecules import AddMoleculesCLI +from .build_nep_traj import BuildNEPTrajCLI from ._argument_parser import _ArgumentParser __outputdoc__ = """ @@ -5,20 +20,40 @@ This is the command line interface for the PQAnalysis package. """ -from .build_nep_traj import BuildNEPTrajCLI +__epilog__ = "\n" +__epilog__ += "For more information on required and optional input file keys please visit " +__epilog__ += f"{code_base_url}PQAnalysis.cli.html." +__epilog__ += "\n" +__epilog__ += "\n" def main(): - parser = _ArgumentParser(description=__outputdoc__, epilog=None) - - subparsers = parser.add_subparsers(dest='command') - - build_nep_traj_parser = subparsers.add_parser( - BuildNEPTrajCLI.program_name(), help=BuildNEPTrajCLI.__doc__ + """ + The main function of the PQAnalysis command line interface. + """ + parser = _ArgumentParser(description=__outputdoc__, epilog=__epilog__) + + subparsers = parser.add_subparsers( + dest='cli_command', + required=True ) - BuildNEPTrajCLI.add_arguments(build_nep_traj_parser) + + sub_parser_dict = { + AddMoleculesCLI.program_name(): AddMoleculesCLI, + BuildNEPTrajCLI.program_name(): BuildNEPTrajCLI, + ContinueInputCLI.program_name(): ContinueInputCLI, + GEN2XYZCLI.program_name(): GEN2XYZCLI, + RDFCLI.program_name(): RDFCLI, + Rst2XYZCLI.program_name(): Rst2XYZCLI, + Traj2BoxCLI.program_name(): Traj2BoxCLI, + Traj2QMCFCCLI.program_name(): Traj2QMCFCCLI, + XYZ2GENCLI.program_name(): XYZ2GENCLI, + } + + for key, value in sub_parser_dict.items(): + sub_parser = subparsers.add_parser(key, help=value.__doc__) + value.add_arguments(sub_parser) args = parser.parse_args() - if args.command == BuildNEPTrajCLI.program_name(): - BuildNEPTrajCLI.run(args) + sub_parser_dict[args.cli_command].run(args) diff --git a/PQAnalysis/cli/rdf.py b/PQAnalysis/cli/rdf.py index db00aa9f..fba4f2e6 100644 --- a/PQAnalysis/cli/rdf.py +++ b/PQAnalysis/cli/rdf.py @@ -10,6 +10,7 @@ from PQAnalysis.analysis.rdf.rdf_input_file_reader import input_keys_documentation from PQAnalysis.config import code_base_url from ._argument_parser import _ArgumentParser +from ._cli_base import CLIBase __outputdoc__ = """ @@ -24,6 +25,7 @@ __epilog__ += "For more information on required and optional input file keys please visit " __epilog__ += f"{code_base_url}PQAnalysis.cli.rdf.html." __epilog__ += "\n" +__epilog__ += "\n" __doc__ += __outputdoc__ __doc__ += "For more information on the general the " @@ -34,6 +36,24 @@ __doc__ += input_keys_documentation +class RDFCLI(CLIBase): + """ + Command Line Tool for RDF Analysis + """ + @classmethod + def program_name(cls): + return 'rdf' + + @classmethod + def add_arguments(cls, parser): + parser.parse_input_file() + parser.parse_engine() + + @classmethod + def run(cls, args): + rdf(args.input_file, args.engine) + + def main(): """ The main function of the RDF analysis command line tool, @@ -42,9 +62,9 @@ def main(): visit :py:func:`PQAnalysis.analysis.rdf.api.rdf`. """ parser = _ArgumentParser(description=__outputdoc__, epilog=__epilog__) - parser.parse_engine() - parser.parse_input_file() + + RDFCLI.add_arguments(parser) args = parser.parse_args() - rdf(args.input_file, args.engine) + RDFCLI.run(args) diff --git a/PQAnalysis/cli/rst2xyz.py b/PQAnalysis/cli/rst2xyz.py index 862d5a8b..b36ea95c 100644 --- a/PQAnalysis/cli/rst2xyz.py +++ b/PQAnalysis/cli/rst2xyz.py @@ -11,6 +11,7 @@ from PQAnalysis.io import rst2xyz from PQAnalysis.config import code_base_url from ._argument_parser import _ArgumentParser +from ._cli_base import CLIBase __outputdoc__ = """ @@ -25,10 +26,49 @@ __epilog__ += "For more information on required and optional input file keys please visit " __epilog__ += f"{code_base_url}PQAnalysis.cli.rst2xyz.html." __epilog__ += "\n" +__epilog__ += "\n" __doc__ += __outputdoc__ +class Rst2XYZCLI(CLIBase): + """ + Command Line Tool for Converting Restart Files to XYZ Files + """ + @classmethod + def program_name(cls): + return 'rst2xyz' + + @classmethod + def add_arguments(cls, parser): + parser.parse_output_file() + + parser.add_argument( + 'restart_file', + type=str, + help='The restart file to be converted.' + ) + + parser.add_argument( + '--nobox', + action='store_true', + help='Do not print the box.' + ) + + parser.parse_engine() + parser.parse_mode() + + @classmethod + def run(cls, args): + rst2xyz( + restart_file=args.restart_file, + output=args.output, + print_box=not args.nobox, + md_format=args.engine, + mode=args.mode, + ) + + def main(): """ Main function of the rst2xyz command line tool, which is basically just a wrapper @@ -37,29 +77,8 @@ def main(): """ parser = _ArgumentParser(description=__outputdoc__, epilog=__epilog__) - parser.parse_output_file() - - parser.add_argument( - 'restart_file', - type=str, - help='The restart file to be converted.' - ) - - parser.add_argument( - '--nobox', - action='store_true', - help='Do not print the box.' - ) - - parser.parse_engine() - parser.parse_mode() + Rst2XYZCLI.add_arguments(parser) args = parser.parse_args() - rst2xyz( - restart_file=args.restart_file, - output=args.output, - print_box=not args.nobox, - md_format=args.engine, - mode=args.mode, - ) + Rst2XYZCLI.run(args) diff --git a/PQAnalysis/cli/traj2box.py b/PQAnalysis/cli/traj2box.py index b8b4e4ab..b52b0cc9 100644 --- a/PQAnalysis/cli/traj2box.py +++ b/PQAnalysis/cli/traj2box.py @@ -9,6 +9,7 @@ from PQAnalysis.config import code_base_url from PQAnalysis.io import traj2box from ._argument_parser import _ArgumentParser +from ._cli_base import CLIBase __outputdoc__ = """ @@ -28,10 +29,43 @@ __epilog__ += "For more information on the VMD file format please visit " __epilog__ += f"{code_base_url}PQAnalysis.io.formats.html#PQAnalysis.io.formats.VMDFileFormat." __epilog__ += "\n" +__epilog__ += "\n" __doc__ += __outputdoc__ +class Traj2BoxCLI(CLIBase): + """ + Command Line Tool for Converting Trajectory Files to Box Files + """ + @classmethod + def program_name(cls): + return 'traj2box' + + @classmethod + def add_arguments(cls, parser): + parser.parse_output_file() + + parser.add_argument( + 'trajectory_file', + type=str, + nargs='+', + help='The trajectory file(s) to be converted.' + ) + + parser.add_argument( + '--vmd', + action='store_true', + help='Output in VMD format.' + ) + + parser.parse_mode() + + @classmethod + def run(cls, args): + traj2box(args.trajectory_file, args.vmd, args.output, args.mode) + + def main(): """ Main function of the traj2box command line tool, which is basically just a @@ -40,21 +74,8 @@ def main(): """ parser = _ArgumentParser(description=__outputdoc__, epilog=__epilog__) - parser.parse_output_file() - - parser.add_argument( - 'trajectory_file', - type=str, - nargs='+', - help='The trajectory file(s) to be converted.' - ) - - parser.add_argument( - '--vmd', - action='store_true', - help='Output in VMD format.' - ) + Traj2BoxCLI.add_arguments(parser) args = parser.parse_args() - traj2box(args.trajectory_file, args.vmd, args.output) + Traj2BoxCLI.run(args) diff --git a/PQAnalysis/cli/traj2qmcfc.py b/PQAnalysis/cli/traj2qmcfc.py index 0e4004e2..518175fd 100644 --- a/PQAnalysis/cli/traj2qmcfc.py +++ b/PQAnalysis/cli/traj2qmcfc.py @@ -9,6 +9,7 @@ from PQAnalysis.config import code_base_url from PQAnalysis.io import traj2qmcfc from ._argument_parser import _ArgumentParser +from ._cli_base import CLIBase __outputdoc__ = """ @@ -24,10 +25,36 @@ __epilog__ += "For more information on required and optional input file keys please visit " __epilog__ += f"{code_base_url}PQAnalysis.cli.traj2qmcfc.html." __epilog__ += "\n" +__epilog__ += "\n" __doc__ += __outputdoc__ +class Traj2QMCFCCLI(CLIBase): + """ + Command Line Tool for Converting PQ to QMCFC Trajectory Files + """ + @classmethod + def program_name(cls): + return 'traj2qmcfc' + + @classmethod + def add_arguments(cls, parser): + parser.parse_output_file() + + parser.add_argument( + 'trajectory_file', + type=str, + help='The trajectory file to be converted.' + ) + + parser.parse_mode() + + @classmethod + def run(cls, args): + traj2qmcfc(args.trajectory_file, args.output) + + def main(): """ Main function of the traj2qmcfc command line tool, which is basically just a @@ -36,9 +63,8 @@ def main(): """ parser = _ArgumentParser(description=__outputdoc__, epilog=__epilog__) - parser.parse_trajectory_file() - parser.parse_output_file() + Traj2QMCFCCLI.add_arguments(parser) args = parser.parse_args() - traj2qmcfc(args.trajectory_file, args.output) + Traj2QMCFCCLI.run(args) diff --git a/PQAnalysis/cli/xyz2gen.py b/PQAnalysis/cli/xyz2gen.py index ca854809..f4e59782 100644 --- a/PQAnalysis/cli/xyz2gen.py +++ b/PQAnalysis/cli/xyz2gen.py @@ -10,6 +10,7 @@ from PQAnalysis.config import code_base_url from PQAnalysis.io import xyz2gen from ._argument_parser import _ArgumentParser +from ._cli_base import CLIBase __outputdoc__ = """ @@ -21,10 +22,53 @@ __epilog__ += "For more information on required and optional input file keys please visit " __epilog__ += f"{code_base_url}PQAnalysis.cli.xyz2gen.html." __epilog__ += "\n" +__epilog__ += "\n" __doc__ += __outputdoc__ +class XYZ2GENCLI(CLIBase): + """ + Command Line Tool for Converting XYZ Files to GEN Files + """ + @classmethod + def program_name(cls): + return 'xyz2gen' + + @classmethod + def add_arguments(cls, parser): + parser.add_argument( + 'xyz_file', + type=str, + help='The gen file to be converted.' + ) + + parser.parse_output_file() + + parser.add_argument( + 'periodic', + choices=[True, False, None], + default=None, + help=( + 'If True, the box is printed. If False, the box is not printed. ' + 'If None, the box is printed if it is present in the xyz file.' + ) + ) + + parser.parse_engine() + parser.parse_mode() + + @classmethod + def run(cls, args): + xyz2gen( + xyz_file=args.xyz_file, + output=args.output, + periodic=args.periodic, + md_format=args.engine, + mode=args.mode, + ) + + def main(): """ Main function of the xyz2gen command line tool, which is basically just @@ -33,33 +77,8 @@ def main(): """ parser = _ArgumentParser(description=__outputdoc__, epilog=__epilog__) - parser.add_argument( - 'xyz_file', - type=str, - help='The gen file to be converted.' - ) - - parser.parse_output_file() - - parser.add_argument( - 'periodic', - choices=[True, False, None], - default=None, - help=( - 'If True, the box is printed. If False, the box is not printed. ' - 'If None, the box is printed if it is present in the xyz file.' - ) - ) - - parser.parse_engine() - parser.parse_mode() + XYZ2GENCLI.add_arguments(parser) args = parser.parse_args() - xyz2gen( - xyz_file=args.xyz_file, - output=args.output, - periodic=args.periodic, - md_format=args.engine, - mode=args.mode, - ) + XYZ2GENCLI.run(args) diff --git a/pyproject.toml b/pyproject.toml index 011d190c..c937f0df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,7 @@ dependencies = [ "decorator", "argcomplete", "unum", + "rich-argparse", ] [project.optional-dependencies] diff --git a/tests/cli/test_traj2box.py b/tests/cli/test_traj2box.py index 79dbd792..987484ab 100644 --- a/tests/cli/test_traj2box.py +++ b/tests/cli/test_traj2box.py @@ -34,6 +34,7 @@ def test_main(test_with_data_dir): output="test_box.dat", log_file=None, logging_level="INFO", + mode='w' ) ) def main_box_file(mock_args): @@ -49,6 +50,7 @@ def main_box_file(mock_args): output="test_box.vmd.xyz", log_file=None, logging_level="INFO", + mode='w' ) ) def main_vmd(mock_args): From 4b64cc48975c7866f8e2d270cc8c171a10159050 Mon Sep 17 00:00:00 2001 From: Jakob Gamper <97gamjak@gmail.com> Date: Fri, 10 May 2024 23:47:42 +0200 Subject: [PATCH 3/5] fixed docstring coverage --- .docstr.yaml | 26 +++++--------------------- PQAnalysis/cli/add_molecules.py | 29 +++++++++++++++++++++++++++-- PQAnalysis/cli/build_nep_traj.py | 30 +++++++++++++++++++++++++++--- PQAnalysis/cli/continue_input.py | 28 ++++++++++++++++++++++++++-- PQAnalysis/cli/gen2xyz.py | 28 ++++++++++++++++++++++++++-- PQAnalysis/cli/main.py | 6 ++++-- PQAnalysis/cli/rdf.py | 28 ++++++++++++++++++++++++++-- PQAnalysis/cli/rst2xyz.py | 28 ++++++++++++++++++++++++++-- PQAnalysis/cli/traj2box.py | 28 ++++++++++++++++++++++++++-- PQAnalysis/cli/traj2qmcfc.py | 30 +++++++++++++++++++++++++++--- PQAnalysis/cli/xyz2gen.py | 28 ++++++++++++++++++++++++++-- 11 files changed, 246 insertions(+), 43 deletions(-) diff --git a/.docstr.yaml b/.docstr.yaml index b572cfbe..fb7f98cc 100644 --- a/.docstr.yaml +++ b/.docstr.yaml @@ -1,27 +1,11 @@ paths: - PQAnalysis -#badge: docs -#exclude: .*/test # regex +exclude: ./tests # regex verbose: 2 # int (0-3) -skip_magic: True +skip_magic: False skip_file_doc: True -skip_init: True +skip_init: False skip_class_def: False -skip_private: True +skip_private: False follow_links: True -#ignore_names_file: .*/test # regex -#fail_under: 90 -percentage_only: False -#ignore_patterns: # Dict with key/value pairs of file-pattern/node-pattern -# .*: method_to_ignore_in_all_files -# FileWhereWeWantToIgnoreAllSpecialMethods: "__.+__" -# SomeFile: -# - method_to_ignore1 -# - method_to_ignore2 -# - method_to_ignore3 -# a_very_important_view_file: -# - "^get$" -# - "^set$" -# - "^post$" -# detect_.*: -# - "get_val.*" \ No newline at end of file +percentage_only: False \ No newline at end of file diff --git a/PQAnalysis/cli/add_molecules.py b/PQAnalysis/cli/add_molecules.py index 110cd603..e410ec95 100644 --- a/PQAnalysis/cli/add_molecules.py +++ b/PQAnalysis/cli/add_molecules.py @@ -39,11 +39,28 @@ class AddMoleculesCLI(CLIBase): Command Line Tool for Adding Molecules to Restart Files """ @classmethod - def program_name(cls): + def program_name(cls) -> str: + """ + Returns the name of the program. + + Returns + ------- + str + The name of the program. + """ return 'add_molecules' @classmethod - def add_arguments(cls, parser): + def add_arguments(cls, parser: _ArgumentParser) -> None: + """ + Adds the arguments to the parser. + + Parameters + ---------- + parser : _ArgumentParser + The parser to which the arguments should be added. + """ + parser.add_argument( 'restart_file', type=str, @@ -191,6 +208,14 @@ def add_arguments(cls, parser): @classmethod def run(cls, args): + """ + Runs the add_molecules function. + + Parameters + ---------- + args : argparse.Namespace + The parsed arguments. + """ add_molecule( args.restart_file, args.molecule_file, diff --git a/PQAnalysis/cli/build_nep_traj.py b/PQAnalysis/cli/build_nep_traj.py index 86265ae9..869cf95c 100644 --- a/PQAnalysis/cli/build_nep_traj.py +++ b/PQAnalysis/cli/build_nep_traj.py @@ -15,7 +15,7 @@ __outputdoc__ = """ -This command line tool can be used to converts output of PQ of QMCFC simulations to training and test files for the Neuroevolution Potential (NEP) method. The output is written to a xyz file. +This command line tool can be used to convert output of PQ of QMCFC simulations to training and test files for the Neuroevolution Potential (NEP) method. The output is written to a xyz file. """ __epilog__ = "\n" @@ -32,11 +32,27 @@ class BuildNEPTrajCLI(CLIBase): Command Line Tool for Building Neuroevolution Potential (NEP) training/test trajectories """ @classmethod - def program_name(cls): + def program_name(cls) -> str: + """ + Returns the name of the program. + + Returns + ------- + str + The name of the program. + """ return 'build_nep_traj' @classmethod - def add_arguments(cls, parser): + def add_arguments(cls, parser: _ArgumentParser) -> None: + """ + Adds the arguments to the parser. + + Parameters + ---------- + parser : _ArgumentParser + The parser to which the arguments should be added. + """ parser.add_argument( 'file_prefixes', type=str, @@ -122,6 +138,14 @@ def add_arguments(cls, parser): @classmethod def run(cls, args): + """ + Runs the build_nep_traj function with the given arguments. + + Parameters + ---------- + args : argparse.Namespace + The parsed arguments. + """ writer = NEPWriter(filename=args.output, mode=args.mode) writer.write_from_files( diff --git a/PQAnalysis/cli/continue_input.py b/PQAnalysis/cli/continue_input.py index ada35686..cec81596 100644 --- a/PQAnalysis/cli/continue_input.py +++ b/PQAnalysis/cli/continue_input.py @@ -33,11 +33,27 @@ class ContinueInputCLI(CLIBase): Command Line Tool for Extending PQ MD Simulation Input Files """ @classmethod - def program_name(cls): + def program_name(cls) -> str: + """ + Returns the name of the program. + + Returns + ------- + str + The name of the program. + """ return 'continue_input' @classmethod - def add_arguments(cls, parser): + def add_arguments(cls, parser: _ArgumentParser) -> None: + """ + Adds the arguments to the parser. + + Parameters + ---------- + parser : _ArgumentParser + The parser to which the arguments should be added. + """ parser.parse_input_file() parser.add_argument( @@ -56,6 +72,14 @@ def add_arguments(cls, parser): @classmethod def run(cls, args): + """ + Runs the command line tool. + + Parameters + ---------- + args : argparse.Namespace + The parsed arguments. + """ input_format = InputFileFormat(args.input_format) continue_input_file( diff --git a/PQAnalysis/cli/gen2xyz.py b/PQAnalysis/cli/gen2xyz.py index 867a5e4b..329e02aa 100644 --- a/PQAnalysis/cli/gen2xyz.py +++ b/PQAnalysis/cli/gen2xyz.py @@ -35,11 +35,27 @@ class GEN2XYZCLI(CLIBase): Command Line Tool for Converting GEN Files to XYZ Files """ @classmethod - def program_name(cls): + def program_name(cls) -> str: + """ + Returns the name of the program. + + Returns + ------- + str + The name of the program. + """ return 'gen2xyz' @classmethod - def add_arguments(cls, parser): + def add_arguments(cls, parser: _ArgumentParser) -> None: + """ + Adds the arguments to the parser. + + Parameters + ---------- + parser : _ArgumentParser + The parser to which the arguments should be added. + """ parser.add_argument( 'gen_file', type=str, @@ -59,6 +75,14 @@ def add_arguments(cls, parser): @classmethod def run(cls, args): + """ + Runs the command line tool. + + Parameters + ---------- + args : _ArgumentParser + The arguments that were parsed by the parser. + """ gen2xyz( gen_file=args.gen_file, output=args.output, diff --git a/PQAnalysis/cli/main.py b/PQAnalysis/cli/main.py index 4c1b47d3..a76d5603 100644 --- a/PQAnalysis/cli/main.py +++ b/PQAnalysis/cli/main.py @@ -35,7 +35,6 @@ def main(): subparsers = parser.add_subparsers( dest='cli_command', - required=True ) sub_parser_dict = { @@ -56,4 +55,7 @@ def main(): args = parser.parse_args() - sub_parser_dict[args.cli_command].run(args) + if args.cli_command in sub_parser_dict: + sub_parser_dict[args.cli_command].run(args) + else: + parser.print_help() diff --git a/PQAnalysis/cli/rdf.py b/PQAnalysis/cli/rdf.py index fba4f2e6..82c268af 100644 --- a/PQAnalysis/cli/rdf.py +++ b/PQAnalysis/cli/rdf.py @@ -41,16 +41,40 @@ class RDFCLI(CLIBase): Command Line Tool for RDF Analysis """ @classmethod - def program_name(cls): + def program_name(cls) -> str: + """ + Returns the name of the program. + + Returns + ------- + str + The name of the program. + """ return 'rdf' @classmethod - def add_arguments(cls, parser): + def add_arguments(cls, parser: _ArgumentParser) -> None: + """ + Adds the arguments to the parser. + + Parameters + ---------- + parser : _ArgumentParser + The parser to which the arguments should be added. + """ parser.parse_input_file() parser.parse_engine() @classmethod def run(cls, args): + """ + Runs the command line tool. + + Parameters + ---------- + args : argparse.Namespace + The arguments parsed by the parser. + """ rdf(args.input_file, args.engine) diff --git a/PQAnalysis/cli/rst2xyz.py b/PQAnalysis/cli/rst2xyz.py index b36ea95c..b77fb132 100644 --- a/PQAnalysis/cli/rst2xyz.py +++ b/PQAnalysis/cli/rst2xyz.py @@ -36,11 +36,27 @@ class Rst2XYZCLI(CLIBase): Command Line Tool for Converting Restart Files to XYZ Files """ @classmethod - def program_name(cls): + def program_name(cls) -> str: + """ + Returns the name of the program. + + Returns + ------- + str + The name of the program. + """ return 'rst2xyz' @classmethod - def add_arguments(cls, parser): + def add_arguments(cls, parser: _ArgumentParser) -> None: + """ + Adds the arguments to the parser. + + Parameters + ---------- + parser : _ArgumentParser + The parser to which the arguments should be added. + """ parser.parse_output_file() parser.add_argument( @@ -60,6 +76,14 @@ def add_arguments(cls, parser): @classmethod def run(cls, args): + """ + Runs the command line tool. + + Parameters + ---------- + args : argparse.Namespace + The arguments parsed by the parser. + """ rst2xyz( restart_file=args.restart_file, output=args.output, diff --git a/PQAnalysis/cli/traj2box.py b/PQAnalysis/cli/traj2box.py index b52b0cc9..7b423673 100644 --- a/PQAnalysis/cli/traj2box.py +++ b/PQAnalysis/cli/traj2box.py @@ -39,11 +39,27 @@ class Traj2BoxCLI(CLIBase): Command Line Tool for Converting Trajectory Files to Box Files """ @classmethod - def program_name(cls): + def program_name(cls) -> str: + """ + Returns the name of the program. + + Returns + ------- + str + The name of the program. + """ return 'traj2box' @classmethod - def add_arguments(cls, parser): + def add_arguments(cls, parser: _ArgumentParser) -> None: + """ + Adds the arguments to the parser. + + Parameters + ---------- + parser : _ArgumentParser + The parser to which the arguments should be added. + """ parser.parse_output_file() parser.add_argument( @@ -63,6 +79,14 @@ def add_arguments(cls, parser): @classmethod def run(cls, args): + """ + Runs the command line tool. + + Parameters + ---------- + args : argparse.Namespace + The arguments parsed by the parser. + """ traj2box(args.trajectory_file, args.vmd, args.output, args.mode) diff --git a/PQAnalysis/cli/traj2qmcfc.py b/PQAnalysis/cli/traj2qmcfc.py index 518175fd..8d2764ea 100644 --- a/PQAnalysis/cli/traj2qmcfc.py +++ b/PQAnalysis/cli/traj2qmcfc.py @@ -35,11 +35,27 @@ class Traj2QMCFCCLI(CLIBase): Command Line Tool for Converting PQ to QMCFC Trajectory Files """ @classmethod - def program_name(cls): + def program_name(cls) -> str: + """ + Returns the name of the program. + + Returns + ------- + str + The name of the program. + """ return 'traj2qmcfc' @classmethod - def add_arguments(cls, parser): + def add_arguments(cls, parser: _ArgumentParser) -> None: + """ + Adds the arguments to the parser. + + Parameters + ---------- + parser : _ArgumentParser + The parser to which the arguments should be added. + """ parser.parse_output_file() parser.add_argument( @@ -51,7 +67,15 @@ def add_arguments(cls, parser): parser.parse_mode() @classmethod - def run(cls, args): + def run(cls, args) -> None: + """ + Runs the command line tool. + + Parameters + ---------- + args : _Namespace + The arguments from the command line. + """ traj2qmcfc(args.trajectory_file, args.output) diff --git a/PQAnalysis/cli/xyz2gen.py b/PQAnalysis/cli/xyz2gen.py index f4e59782..770336a0 100644 --- a/PQAnalysis/cli/xyz2gen.py +++ b/PQAnalysis/cli/xyz2gen.py @@ -32,11 +32,27 @@ class XYZ2GENCLI(CLIBase): Command Line Tool for Converting XYZ Files to GEN Files """ @classmethod - def program_name(cls): + def program_name(cls) -> str: + """ + Returns the name of the program. + + Returns + ------- + str + The name of the program. + """ return 'xyz2gen' @classmethod - def add_arguments(cls, parser): + def add_arguments(cls, parser: _ArgumentParser) -> None: + """ + Adds the arguments to the parser. + + Parameters + ---------- + parser : _ArgumentParser + The parser to which the arguments should be added. + """ parser.add_argument( 'xyz_file', type=str, @@ -60,6 +76,14 @@ def add_arguments(cls, parser): @classmethod def run(cls, args): + """ + Runs the command line tool. + + Parameters + ---------- + args : _Namespace + The arguments from the command line. + """ xyz2gen( xyz_file=args.xyz_file, output=args.output, From 0804311552b4bca617e1076e9c25079fb082241e Mon Sep 17 00:00:00 2001 From: Jakob Gamper <97gamjak@gmail.com> Date: Fri, 10 May 2024 23:51:34 +0200 Subject: [PATCH 4/5] updated docstr.yml --- .github/workflows/docstr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docstr.yml b/.github/workflows/docstr.yml index 885fe9b3..ef82d64f 100644 --- a/.github/workflows/docstr.yml +++ b/.github/workflows/docstr.yml @@ -57,12 +57,12 @@ jobs: run: | echo "$BASE coverage was: $BASE_COV%" git checkout $HEAD - docstr-coverage --fail-under=$BASE_COV + docstr-coverage --fail-under=$BASE_COV PQAnalysis - name: Blame run: | git diff --name-only $(git merge-base $BASE $HEAD) | \ - xargs docstr-coverage --accept-empty + xargs docstr-coverage --accept-empty PQAnalysis if: failure() - name: Get new coverage From d041b18c791246cb6a4e8b9e252d176f0f04a0dc Mon Sep 17 00:00:00 2001 From: Jakob Gamper <97gamjak@gmail.com> Date: Fri, 10 May 2024 23:56:04 +0200 Subject: [PATCH 5/5] docstr.yml deleted - not necessary due to pylint --- .github/workflows/docstr.yml | 102 ----------------------------------- 1 file changed, 102 deletions(-) delete mode 100644 .github/workflows/docstr.yml diff --git a/.github/workflows/docstr.yml b/.github/workflows/docstr.yml deleted file mode 100644 index ef82d64f..00000000 --- a/.github/workflows/docstr.yml +++ /dev/null @@ -1,102 +0,0 @@ -name: Docstring Coverage - -on: - push: - branches: [dev, main] - pull_request: - branches: ['*'] - workflow_dispatch: - -env: - RANGE: 95..100 - ENDPOINT: https://jsonbin.org/${{ github.repository_owner }}/${{ github.event.repository.name }} - TOKEN: ${{ secrets.JSONBIN_APIKEY }} - BRANCH_NAME: ${{ github.head_ref || github.ref_name}} - - -jobs: - check: - runs-on: ubuntu-latest - steps: - - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - name: Setup Python - uses: actions/setup-python@v2 - with: - python-version: 3.x - - - name: Install docstr-coverage - run: | - pip install docstr-coverage - - - name: Get SHAs - run: | - if [[ ${{ github.event_name }} == 'push' ]]; then - echo "BASE=$(git rev-parse HEAD^)" >> $GITHUB_ENV - echo "HEAD=$(git rev-parse HEAD)" >> $GITHUB_ENV - - elif [[ ${{ github.event_name }} == 'pull_request' ]]; then - echo "BASE=${{ github.event.pull_request.base.sha }}" >> $GITHUB_ENV - echo "HEAD=${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV - - else - echo "Unexpected event trigger" - exit 1 - - fi - - - name: Get ${{ github.event.pull_request.base.sha }} coverage - run: | - git checkout $BASE - echo "BASE_COV=$(docstr-coverage PQAnalysis -p)" >> $GITHUB_ENV - - - name: Test ${{ github.event.pull_request.head.sha }} coverage - run: | - echo "$BASE coverage was: $BASE_COV%" - git checkout $HEAD - docstr-coverage --fail-under=$BASE_COV PQAnalysis - - - name: Blame - run: | - git diff --name-only $(git merge-base $BASE $HEAD) | \ - xargs docstr-coverage --accept-empty PQAnalysis - if: failure() - - - name: Get new coverage - run: echo "NEW_COV=$(printf "%.f" $(docstr-coverage -p))" >> $GITHUB_ENV - if: always() && github.event_name == 'push' - - - name: Set label color - run: | - if [[ $NEW_COV -ge $(echo {${{ env.RANGE }}} | awk '{print $NF;}') ]]; then - echo "COLOR=green" >> $GITHUB_ENV - - elif [[ $NEW_COV -lt $(echo {${{ env.RANGE }}} | awk '{print $1;}') ]]; then - echo "COLOR=red" >> $GITHUB_ENV - - else - echo "COLOR=orange" >> $GITHUB_ENV - - fi - if: always() && github.event_name == 'push' - - - name: Post results - run: | - echo "New coverage is: $NEW_COV%" - curl -X POST $ENDPOINT/badges/docstr-cov \ - -H "authorization: token $TOKEN" \ - -d "{ \"schemaVersion\": 1, \"label\": \"docstr-cov\", \ - \"message\": \"$NEW_COV%\", \"color\": \"$COLOR\" }" - if: always() && github.event_name == 'push' && ${{ env.BRANCH_NAME }} == 'main' - - - name: Set public endpoint - run: | - curl -X PUT $ENDPOINT/_perms -H "authorization: token $TOKEN" - if: always() && github.event_name == 'push' && ${{ env.BRANCH_NAME }} == 'main' - - - name: Show badge URL - run: echo "https://img.shields.io/endpoint?url=$ENDPOINT/badges/docstr-cov" - if: always() && github.event_name == 'push' && ${{ env.BRANCH_NAME }} == 'main' \ No newline at end of file