From f16a2e8794300d0addc49c090735ff14c8842e69 Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Tue, 22 Mar 2022 16:30:27 -0400 Subject: [PATCH 1/4] add cli --- dpdata/cli.py | 75 +++++++++++++++++++++++++++++++++++++++++++++++ dpdata/system.py | 15 ++++++++++ setup.py | 3 +- tests/test_cli.py | 18 ++++++++++++ 4 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 dpdata/cli.py create mode 100644 tests/test_cli.py diff --git a/dpdata/cli.py b/dpdata/cli.py new file mode 100644 index 000000000..eaa7c76eb --- /dev/null +++ b/dpdata/cli.py @@ -0,0 +1,75 @@ +"""Command line interface for dpdata.""" +import argparse + +from . import __version__ +from .system import System, LabeledSystem, MultiSystems + + +def dpdata_cli(): + """dpdata cli. + + Examples + -------- + .. code-block:: bash + + $ dpdata -iposcar POSCAR -odeepmd/npy -O data -n + """ + parser = argparse.ArgumentParser( + description="dpdata: Manipulating multiple atomic simulation data formats", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + + parser.add_argument("from_file", type=str, help="read data from a file") + parser.add_argument("--to_file", "-O", type=str, help="dump data to a file") + parser.add_argument("--from_format", "-i", type=str, default="auto", help="the format of from_file") + parser.add_argument("--to_format", "-o", type=str, help="the format of to_file") + parser.add_argument("--no-labeled", "-n", action="store_true", help="labels aren't provided") + parser.add_argument("--multi", "-m", action="store_true", help="the system contains multiple directories") + parser.add_argument("--type-map", "-t", type=str, nargs="+", help="type map") + + parser.add_argument('--version', action='version', version='dpdata v%s' % __version__) + + parsed_args = parser.parse_args() + convert(**vars(parsed_args)) + + +def convert(*, + from_file: str, + from_format: str = "auto", + to_file: str = None, + to_format: str = None, + no_labeled: bool = False, + multi: bool = False, + type_map: list = None, + **kwargs): + """Convert files from one format to another one. + + Parameters + ---------- + from_file : str + read data from a file + from_format : str + the format of from_file + to_file : str + dump data to a file + to_format : str + the format of to_file + no_labeled : bool + labels aren't provided + multi : bool + the system contains multiple directories + type_map : list + type map + """ + if multi: + s = MultiSystems.from_file(from_file, fmt=from_format, type_map=type_map, labeled=not no_labeled) + elif not no_labeled: + s = LabeledSystem(from_file, fmt=from_format, type_map=type_map) + else: + s = System(from_file, fmt=from_format, type_map=type_map) + if to_format is not None: + out = s.to(to_format, to_file) + if isinstance(out, str): + print(out) + else: + print(s) diff --git a/dpdata/system.py b/dpdata/system.py index 20d7ced06..a59fc681e 100644 --- a/dpdata/system.py +++ b/dpdata/system.py @@ -1082,6 +1082,21 @@ def to_fmt_obj(self, fmtobj, directory, *args, **kwargs): for fn, ss in zip(fmtobj.to_multi_systems(self.systems.keys(), directory, **kwargs), self.systems.values()): ss.to_fmt_obj(fmtobj, fn, *args, **kwargs) return self + + def to(self, fmt: str, *args, **kwargs) -> "MultiSystems": + """Dump systems to the specific format. + + Parameters + ---------- + fmt : str + format + + Returns + ------- + MultiSystems + self + """ + return self.to_fmt_obj(load_format(fmt), *args, **kwargs) def __getitem__(self, key): """Returns proerty stored in System by key or by idx""" diff --git a/setup.py b/setup.py index 00d4975b0..a0ee7c336 100644 --- a/setup.py +++ b/setup.py @@ -55,6 +55,7 @@ 'amber': ['parmed'], 'pymatgen': ['pymatgen'], 'docs': ['sphinx', 'recommonmark', 'sphinx_rtd_theme>=1.0.0rc1', 'numpydoc', 'm2r2', 'deepmodeling-sphinx'], - } + }, + entry_points={"console_scripts": ["dpdata = dpdata.cli:dpdata_cli"]}, ) diff --git a/tests/test_cli.py b/tests/test_cli.py new file mode 100644 index 000000000..315ff3c5a --- /dev/null +++ b/tests/test_cli.py @@ -0,0 +1,18 @@ +import unittest +from context import dpdata +from poscars.poscar_ref_oh import TestPOSCARoh +import subprocess as sp + + +class TestCli(unittest.TestCase, TestPOSCARoh): + + @classmethod + def setUpClass(cls) -> None: + with sp.Popen(["dpdata", "poscars/conf.lmp", "--type-map O H", "-olammps/lmp", "-O tmp.lmp", "--nolabeled"]): + pass + cls.system = dpdata.System('tmp.lmp', fmt='lammps/lmp', + type_map = ['O', 'H']) + + @classmethod + def tearDownClass(cls) -> None: + cls.system = None From 141222670ffb376d9da79d050938ec5b8b18c8ad Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Tue, 22 Mar 2022 16:46:49 -0400 Subject: [PATCH 2/4] fix tests --- tests/test_cli.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 315ff3c5a..8f08f2bd4 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -8,8 +8,7 @@ class TestCli(unittest.TestCase, TestPOSCARoh): @classmethod def setUpClass(cls) -> None: - with sp.Popen(["dpdata", "poscars/conf.lmp", "--type-map O H", "-olammps/lmp", "-O tmp.lmp", "--nolabeled"]): - pass + sp.check_output(["dpdata", "poscars/conf.lmp", "--type-map O H", "-olammps/lmp", "-O tmp.lmp", "--nolabeled"]) cls.system = dpdata.System('tmp.lmp', fmt='lammps/lmp', type_map = ['O', 'H']) From 32e2e4c2618116b3ef69e102dd6727d38b2bbffd Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Tue, 22 Mar 2022 17:57:40 -0400 Subject: [PATCH 3/4] fix the typo in doc --- tests/test_cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 8f08f2bd4..9c1dccc5d 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -8,7 +8,7 @@ class TestCli(unittest.TestCase, TestPOSCARoh): @classmethod def setUpClass(cls) -> None: - sp.check_output(["dpdata", "poscars/conf.lmp", "--type-map O H", "-olammps/lmp", "-O tmp.lmp", "--nolabeled"]) + sp.check_output(["dpdata", "poscars/conf.lmp", "--type-map O H", "-olammps/lmp", "-O tmp.lmp", "--no-labeled"]) cls.system = dpdata.System('tmp.lmp', fmt='lammps/lmp', type_map = ['O', 'H']) From dae232e6e512b37ec2f9423a83b54f657e297e9e Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Tue, 22 Mar 2022 18:03:21 -0400 Subject: [PATCH 4/4] fix tests --- tests/test_cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 9c1dccc5d..3d6d29e47 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -8,7 +8,7 @@ class TestCli(unittest.TestCase, TestPOSCARoh): @classmethod def setUpClass(cls) -> None: - sp.check_output(["dpdata", "poscars/conf.lmp", "--type-map O H", "-olammps/lmp", "-O tmp.lmp", "--no-labeled"]) + sp.check_output(["dpdata", "poscars/conf.lmp", "--type-map", "O", "H", "-olammps/lmp", "-O", "tmp.lmp", "--no-labeled"]) cls.system = dpdata.System('tmp.lmp', fmt='lammps/lmp', type_map = ['O', 'H'])