From a9e53664317cdaccf70c78a966a36fde41a7104b Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Wed, 13 Apr 2022 01:21:27 -0400 Subject: [PATCH 1/2] generate formats table in doc Also fixes some typos --- .gitignore | 3 ++ docs/conf.py | 5 +++ docs/formats.rst | 9 ++++ docs/index.rst | 1 + docs/make_format.py | 90 ++++++++++++++++++++++++++++++++++++++++ dpdata/plugins/deepmd.py | 2 +- dpdata/plugins/qe.py | 2 +- dpdata/plugins/siesta.py | 2 +- dpdata/system.py | 14 ++++++- 9 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 docs/formats.rst create mode 100644 docs/make_format.py diff --git a/.gitignore b/.gitignore index 2c2699ebe..41ee080cf 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ _version.py !tests/cp2k/aimd/cp2k.log !tests/cp2k/restart_aimd/ch4.log __pycache__ +docs/_build +docs/formats.csv +docs/api/ diff --git a/docs/conf.py b/docs/conf.py index 01fe4d2a8..dbe2c0bf8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,6 +14,7 @@ # import os import sys +import subprocess as sp from datetime import date sys.path.insert(0, os.path.abspath('..')) @@ -171,8 +172,12 @@ def run_apidoc(_): module = os.path.join(cur_dir, "..", "dpdata") main(['-M', '--tocfile', 'api', '-H', 'API documentation', '-o', os.path.join(cur_dir, "api"), module, '--force']) +def run_formats(_): + sp.check_output([sys.executable, "make_format.py"]) + def setup(app): app.connect('builder-inited', run_apidoc) + app.connect('builder-inited', run_formats) intersphinx_mapping = { diff --git a/docs/formats.rst b/docs/formats.rst new file mode 100644 index 000000000..1920a8489 --- /dev/null +++ b/docs/formats.rst @@ -0,0 +1,9 @@ +Supported Formats +================= + +dpdata supports the following formats: + +.. csv-table:: Supported Formats + :file: formats.csv + :header-rows: 1 + diff --git a/docs/index.rst b/docs/index.rst index 116e3f690..85e837169 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -10,6 +10,7 @@ Welcome to dpdata's documentation! :maxdepth: 2 :caption: Contents: + formats api/api .. mdinclude:: ../README.md diff --git a/docs/make_format.py b/docs/make_format.py new file mode 100644 index 000000000..61fc10a46 --- /dev/null +++ b/docs/make_format.py @@ -0,0 +1,90 @@ +import csv +from collections import defaultdict + +# ensure all plugins are loaded! +import dpdata.plugins +from dpdata.format import Format +from dpdata.system import get_cls_name + + +def get_formats() -> dict: + formats = defaultdict(list) + for kk, ff in Format.get_formats().items(): + formats[ff].append(kk) + return formats + +def detect_overridden(cls: Format, method: str) -> bool: + """Check whether a method is override + + Parameters + ---------- + cls : Format + a format + method : str + method name + + Returns + ------- + bool + whether a method is overridden + """ + return method in cls.__dict__ + +def get_cls_link(cls: object) -> str: + """Returns class link. + + Parameters + ---------- + cls : object + the class + + Returns + ------- + str + the link of a class + """ + return ':class:`%s <%s>`' % (cls.__name__, ".".join([cls.__module__, cls.__name__])) + +def check_supported(fmt: Format): + methods = set() + for mtd in [ + 'from_system', 'to_system', + 'from_labeled_system', 'to_labeled_system', + 'from_bond_order_system', 'to_bond_order_system', + 'from_multi_systems', 'to_multi_systems', + ]: + if detect_overridden(fmt, mtd): + methods.add(mtd) + if mtd == 'to_system': + methods.add('to_labeled_system') + if fmt.MultiMode != fmt.MultiModes.NotImplemented: + methods.add('from_multi_systems') + methods.add('to_multi_systems') + return methods + +method_links = { + "from_system": ":func:`System() `", + "to_system": ":func:`System.to() `", + "from_labeled_system": ":func:`LabeledSystem() `", + "to_labeled_system": ":func:`LabeledSystem.to() `", + "from_bond_order_system": ":func:`BondOrderSystem() `", + "to_bond_order_system": ":func:`BondOrderSystem.to() `", + "from_multi_systems": ":func:`MultiSystems.load_systems_from_file() `", + "to_multi_systems": ":func:`MultiSystems.to() `", +} + +if __name__ == "__main__": + formats = get_formats() + with open('formats.csv', 'w', newline='') as csvfile: + fieldnames = [ + 'Class', 'Alias', 'Supported Functions', + ] + writer = csv.DictWriter(csvfile, fieldnames=fieldnames) + + writer.writeheader() + for kk, vv in formats.items(): + writer.writerow({ + 'Class': get_cls_link(kk), + 'Alias': '\n'.join(('``%s``' % vvv for vvv in vv)), + 'Supported Functions': '\n'.join(method_links[mtd] for mtd in check_supported(kk)), + }) diff --git a/dpdata/plugins/deepmd.py b/dpdata/plugins/deepmd.py index b8a520686..9379e9ecd 100644 --- a/dpdata/plugins/deepmd.py +++ b/dpdata/plugins/deepmd.py @@ -58,7 +58,7 @@ def from_labeled_system(self, file_name, type_map=None, **kwargs): MultiMode = Format.MultiModes.Directory @Format.register("deepmd/hdf5") -class DeePMDCompFormat(Format): +class DeePMDHDF5Format(Format): """HDF5 format for DeePMD-kit. Examples diff --git a/dpdata/plugins/qe.py b/dpdata/plugins/qe.py index 0e8149d00..e6a1665ac 100644 --- a/dpdata/plugins/qe.py +++ b/dpdata/plugins/qe.py @@ -27,7 +27,7 @@ def from_labeled_system(self, file_name, begin = 0, step = 1, **kwargs): return data @Format.register("qe/pw/scf") -class QECPTrajFormat(Format): +class QECPPWSCFFormat(Format): @Format.post("rot_lower_triangular") def from_labeled_system(self, file_name, **kwargs): data = {} diff --git a/dpdata/plugins/siesta.py b/dpdata/plugins/siesta.py index a601e1324..6838dac37 100644 --- a/dpdata/plugins/siesta.py +++ b/dpdata/plugins/siesta.py @@ -34,7 +34,7 @@ def from_labeled_system(self, file_name, **kwargs): @Format.register("siesta/aimd_output") @Format.register_from("from_siesta_aiMD_output") -class SiestaOutputFormat(Format): +class SiestaAIMDOutputFormat(Format): def from_system(self, file_name, **kwargs): data = {} data['atom_names'], \ diff --git a/dpdata/system.py b/dpdata/system.py index f65ea4c6a..4ccfbcac0 100644 --- a/dpdata/system.py +++ b/dpdata/system.py @@ -139,7 +139,19 @@ def from_fmt_obj(self, fmtobj, file_name, **kwargs): self.post_funcs.get_plugin(post_f)(self) return self - def to(self, fmt, *args, **kwargs): + def to(self, fmt: str, *args, **kwargs) -> System: + """Dump systems to the specific format. + + Parameters + ---------- + fmt : str + format + + Returns + ------- + System + self + """ return self.to_fmt_obj(load_format(fmt), *args, **kwargs) def to_fmt_obj(self, fmtobj, *args, **kwargs): From 077fe32ad1e6827afb542342987de60de6f31095 Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Wed, 13 Apr 2022 01:26:04 -0400 Subject: [PATCH 2/2] bugfix --- dpdata/system.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dpdata/system.py b/dpdata/system.py index 4ccfbcac0..b003461cd 100644 --- a/dpdata/system.py +++ b/dpdata/system.py @@ -139,7 +139,7 @@ def from_fmt_obj(self, fmtobj, file_name, **kwargs): self.post_funcs.get_plugin(post_f)(self) return self - def to(self, fmt: str, *args, **kwargs) -> System: + def to(self, fmt: str, *args, **kwargs) -> 'System': """Dump systems to the specific format. Parameters