Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
379bebf
add format docs
njzjz Jul 28, 2023
07dfde3
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 28, 2023
281de64
kk
njzjz Jul 28, 2023
d2d1bdd
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 28, 2023
67941b9
kk
njzjz Jul 28, 2023
ea04b8b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 28, 2023
b179fb7
kk
njzjz Jul 29, 2023
eb4ee2a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 29, 2023
e8d5ecc
kk
njzjz Jul 29, 2023
eb7f30c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 29, 2023
80e6485
install rdkit
njzjz Jul 29, 2023
95175d9
kk
njzjz Jul 29, 2023
7fe8237
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 29, 2023
e54e8c2
kk
njzjz Jul 29, 2023
d824add
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 29, 2023
36feeee
fix from
njzjz Jul 29, 2023
4aa0f35
to_label_system falls back to to_system
njzjz Jul 29, 2023
000ebb7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 29, 2023
9851413
fix typo
njzjz Jul 29, 2023
880cfdd
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 29, 2023
7392eb2
skip
njzjz Jul 29, 2023
393ee76
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 29, 2023
cb84ee4
fix
njzjz Jul 29, 2023
ea4817c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 29, 2023
4e1c9ce
kk
njzjz Jul 29, 2023
3e667e8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 29, 2023
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@ _version.py
__pycache__
docs/_build
docs/formats.csv
docs/drivers.csv
docs/minimizers.csv
docs/api/
docs/formats/
7 changes: 7 additions & 0 deletions docs/formats.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,10 @@ dpdata supports the following formats:
.. csv-table:: Supported Formats
:file: formats.csv
:header-rows: 1


.. toctree::
:maxdepth: 1
:glob:

formats/*
271 changes: 252 additions & 19 deletions docs/make_format.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import csv
import os
from collections import defaultdict
from inspect import Parameter, Signature, cleandoc, signature
from typing import Literal

from numpydoc.docscrape import Parameter as numpydoc_Parameter
from numpydoc.docscrape_sphinx import SphinxDocString

from dpdata.bond_order_system import BondOrderSystem

# ensure all plugins are loaded!
from dpdata.driver import Driver, Minimizer
from dpdata.format import Format
from dpdata.system import LabeledSystem, MultiSystems, System


def get_formats() -> dict:
Expand Down Expand Up @@ -64,7 +73,7 @@ def get_cls_link(cls: object) -> str:


def check_supported(fmt: Format):
methods = set()
methods = {}
for mtd in [
"from_system",
"to_system",
Expand All @@ -76,44 +85,267 @@ def check_supported(fmt: Format):
"to_multi_systems",
]:
if detect_overridden(fmt, mtd):
methods.add(mtd)
methods[mtd] = None
if mtd == "to_system":
methods.add("to_labeled_system")
methods["to_labeled_system"] = None
if fmt.MultiMode != fmt.MultiModes.NotImplemented:
methods.add("from_multi_systems")
methods.add("to_multi_systems")
return methods
methods["from_multi_systems"] = None
methods["to_multi_systems"] = None
return list(methods.keys())


method_links = {
"from_system": ":func:`System() <dpdata.system.System>`",
"to_system": ":func:`System.to() <dpdata.system.System.to>`",
"from_labeled_system": ":func:`LabeledSystem() <dpdata.system.LabeledSystem>`",
"to_labeled_system": ":func:`LabeledSystem.to() <dpdata.system.System.to>`",
"from_bond_order_system": ":func:`BondOrderSystem() <dpdata.bond_order_system.BondOrderSystem>`",
"to_bond_order_system": ":func:`BondOrderSystem.to() <dpdata.system.System.to>`",
"from_multi_systems": ":func:`MultiSystems.load_systems_from_file() <dpdata.system.MultiSystems.load_systems_from_file>`",
"to_multi_systems": ":func:`MultiSystems.to() <dpdata.system.MultiSystems.to>`",
"from_system": ":ref:`System() <{}_{}>`",
"to_system": ":ref:`System.to() <{}_{}>`",
"from_labeled_system": ":ref:`LabeledSystem() <{}_{}>`",
"to_labeled_system": ":ref:`LabeledSystem.to() <{}_{}>`",
"from_bond_order_system": ":ref:`BondOrderSystem() <{}_{}>`",
"to_bond_order_system": ":ref:`BondOrderSystem.to() <{}_{}>`",
"from_multi_systems": ":ref:`MultiSystems.load_systems_from_file() <{}_{}>`",
"to_multi_systems": ":ref:`MultiSystems.to() <{}_{}>`",
}

method_classes = {
"from_system": "System",
"to_system": "System",
"from_labeled_system": "LabeledSystem",
"to_labeled_system": "LabeledSystem",
"from_bond_order_system": "BondOrderSystem",
"to_bond_order_system": "BondOrderSystem",
"from_multi_systems": "MultiSystems",
"to_multi_systems": "MultiSystems",
}

method_cls_obj = {
"from_system": System,
"to_system": System,
"from_labeled_system": LabeledSystem,
"to_labeled_system": LabeledSystem,
"from_bond_order_system": BondOrderSystem,
"to_bond_order_system": BondOrderSystem,
"from_multi_systems": MultiSystems,
"to_multi_systems": MultiSystems,
}


def generate_sub_format_pages(formats: dict):
"""Generate sub format pages."""
os.makedirs("formats", exist_ok=True)
for format, alias in formats.items():
# format: Format, alias: list[str]
buff = []
buff.append(".. _%s:" % format.__name__)
buff.append("")
for aa in alias:
buff.append("%s format" % aa)
buff.append("=" * len(buff[-1]))
buff.append("")
buff.append("Class: %s" % get_cls_link(format))
buff.append("")

docstring = format.__doc__
if docstring is not None:
docstring = cleandoc(docstring)
rst = str(SphinxDocString(docstring))
buff.append(rst)
buff.append("")

buff.append("Conversions")
buff.append("-----------")
methods = check_supported(format)
for method in methods:
buff.append("")
buff.append(f".. _{format.__name__}_{method}:")
buff.append("")
if method.startswith("from_"):
buff.append("Convert from this format to %s" % method_classes[method])
buff.append("`" * len(buff[-1]))
elif method.startswith("to_"):
buff.append("Convert from %s to this format" % method_classes[method])
buff.append("`" * len(buff[-1]))
buff.append("")
method_obj = getattr(format, method)
if (
method == "to_labeled_system"
and method not in format.__dict__
and "to_system" in format.__dict__
):
method_obj = getattr(format, "to_system")
docstring = method_obj.__doc__
if docstring is not None:
docstring = cleandoc(docstring)
sig = signature(method_obj)
parameters = dict(sig.parameters)
return_annotation = sig.return_annotation
# del self
del parameters[list(parameters)[0]]
# del data
if method.startswith("to_"):
del parameters[list(parameters)[0]]
if "args" in parameters:
del parameters["args"]
if "kwargs" in parameters:
del parameters["kwargs"]
if method == "to_multi_systems" or method.startswith("from_"):
sig = Signature(
list(parameters.values()), return_annotation=method_cls_obj[method]
)
else:
sig = Signature(
list(parameters.values()), return_annotation=return_annotation
)
sig = str(sig)
if method.startswith("from_"):
if method != "from_multi_systems":
for aa in alias:
parameters["fmt"] = Parameter(
"fmt",
Parameter.POSITIONAL_OR_KEYWORD,
default=None,
annotation=Literal[aa],
)
sig_fmt = Signature(
list(parameters.values()),
return_annotation=method_cls_obj[method],
)
sig_fmt = str(sig_fmt)
buff.append(
f""".. py:function:: dpdata.{method_classes[method]}{sig_fmt}"""
)
buff.append(""" :noindex:""")
for aa in alias:
buff.append(
""".. py:function:: dpdata.{}.from_{}{}""".format(
method_classes[method],
aa.replace("/", "_").replace(".", ""),
sig,
)
)
buff.append(""" :noindex:""")
buff.append("")
if docstring is None or method not in format.__dict__:
docstring = """ Convert this format to :class:`%s`.""" % (
method_classes[method]
)
doc_obj = SphinxDocString(docstring)
if len(doc_obj["Parameters"]) > 0:
doc_obj["Parameters"] = [
xx
for xx in doc_obj["Parameters"]
if xx.name not in ("*args", "**kwargs")
]
else:
if method == "from_multi_systems":
doc_obj["Parameters"] = [
numpydoc_Parameter(
"directory",
"str",
["directory of systems"],
)
]
doc_obj["Yields"] = []
doc_obj["Returns"] = [
numpydoc_Parameter("", method_classes[method], ["converted system"])
]
rst = " " + str(doc_obj)
buff.append(rst)
buff.append("")
elif method.startswith("to_"):
for aa in alias:
parameters = {
"fmt": Parameter(
"fmt",
Parameter.POSITIONAL_OR_KEYWORD,
annotation=Literal[aa],
),
**parameters,
}
if method == "to_multi_systems":
sig_fmt = Signature(
list(parameters.values()),
return_annotation=method_cls_obj[method],
)
else:
sig_fmt = Signature(
list(parameters.values()),
return_annotation=return_annotation,
)
sig_fmt = str(sig_fmt)
buff.append(
f""".. py:function:: dpdata.{method_classes[method]}.to{sig_fmt}"""
)
buff.append(""" :noindex:""")
for aa in alias:
buff.append(
""".. py:function:: dpdata.{}.to_{}{}""".format(
method_classes[method],
aa.replace("/", "_").replace(".", ""),
sig,
)
)
buff.append(""" :noindex:""")
buff.append("")
if docstring is None or (
method not in format.__dict__
and not (
method == "to_labeled_system"
and method not in format.__dict__
and "to_system" in format.__dict__
)
):
docstring = "Convert :class:`%s` to this format." % (
method_classes[method]
)
doc_obj = SphinxDocString(docstring)
if len(doc_obj["Parameters"]) > 0:
doc_obj["Parameters"] = [
xx
for xx in doc_obj["Parameters"][1:]
if xx.name not in ("*args", "**kwargs")
]
else:
if method == "to_multi_systems":
doc_obj["Parameters"] = [
numpydoc_Parameter(
"directory",
"str",
["directory to save systems"],
)
]
if method == "to_multi_systems":
doc_obj["Yields"] = []
doc_obj["Returns"] = [
numpydoc_Parameter("", method_classes[method], ["this system"])
]
rst = " " + str(doc_obj)
buff.append(rst)
buff.append("")
buff.append("")
buff.append("")

with open("formats/%s.rst" % format.__name__, "w") as rstfile:
rstfile.write("\n".join(buff))


if __name__ == "__main__":
formats = get_formats()
with open("formats.csv", "w", newline="") as csvfile:
fieldnames = [
"Class",
"Format",
"Alias",
"Supported Functions",
"Supported Conversions",
]
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

writer.writeheader()
for kk, vv in formats.items():
writer.writerow(
{
"Class": get_cls_link(kk),
"Format": ":ref:`%s`" % kk.__name__,
"Alias": "\n".join("``%s``" % vvv for vvv in vv),
"Supported Functions": "\n".join(
method_links[mtd] for mtd in check_supported(kk)
"Supported Conversions": "\n".join(
method_links[mtd].format(kk.__name__, mtd)
for mtd in check_supported(kk)
),
}
)
Expand Down Expand Up @@ -151,3 +383,4 @@ def check_supported(fmt: Format):
"Alias": "\n".join("``%s``" % vvv for vvv in vv),
}
)
generate_sub_format_pages(formats)
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ docs = [
'm2r2',
'deepmodeling-sphinx>=0.1.1',
'sphinx-argparse',
'rdkit',
]

[tool.setuptools.packages.find]
Expand Down