Skip to content

Commit

Permalink
Fix minor issues and include input writer in doc
Browse files Browse the repository at this point in the history
  • Loading branch information
tovrstra committed Mar 12, 2021
1 parent 0ba9f7f commit ee99dd0
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .cardboardlint.yml
Expand Up @@ -3,7 +3,7 @@ linters:
packages: ['iodata']
- namespace:
filefilter: ['- */__init__.py', '- */test_*.py', '- *setup.py', '- tools/*',
'- doc/conf.py', '+ *.py', '+ *.pyx']
'- doc/*.py', '+ *.py', '+ *.pyx']
- pylint:
- pycodestyle:
config: .pycodestylerc
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -20,6 +20,7 @@ iodata/overlap_accel.c
doc/_build
doc/pyapi
doc/formats.rst
doc/inputs.rst
doc/formats_tab.inc

# Distribution / packaging
Expand Down
7 changes: 5 additions & 2 deletions doc/changelog.rst
Expand Up @@ -31,14 +31,17 @@ modernized and ported to Python 3. In this process, the API was seriously
refactored, essentially designed from scratch. Compared to HORTON2, IOData 1.0.0
contains the following API-breaking changes:

* The user-facing API is now a set of four *free* functions:
* The user-facing API is now a set of five functions:
:py:func:`iodata.api.load_one`, :py:func:`iodata.api.dump_one`,
:py:func:`iodata.api.load_many`, :py:func:`iodata.api.dump_many`.
:py:func:`iodata.api.load_many`, :py:func:`iodata.api.dump_many` and
:py:func:`iodata.api.write_input`.
* The :py:class:`iodata.iodata.IOData` object is implemented with the
`attrs <https://www.attrs.org>`_ module, which facilites type hinting and
checking.
* The ``load_many`` and ``dump_many`` functions can handle trajectories and
database formats. (At the time of writing, only XYZ and FCHK are supported.)
* The ``write_input`` function can be used to prepare inputs for quantum
chemistry software. This function supports user-provided templates.
* IOData does not impose a specific ordering of the atomic orbital basis
functions (within one shell). Practically all possible conventions are
supported and one can easily convert from one to another.
Expand Down
4 changes: 3 additions & 1 deletion doc/gen_docs.sh
@@ -1,6 +1,8 @@
#!/usr/bin/env bash

SPHINX_APIDOC_OPTIONS=members,undoc-members,show-inheritance,inherited-members sphinx-apidoc -o pyapi/ ../iodata/ ../iodata/test/test_*.py ../iodata/test/cached --separate
SPHINX_APIDOC_OPTIONS=members,undoc-members,show-inheritance,inherited-members sphinx-apidoc \
-a -o pyapi/ ../iodata/ --separate

./gen_formats.py > formats.rst
./gen_inputs.py > inputs.rst
./gen_formats_tab.py > formats_tab.inc
71 changes: 71 additions & 0 deletions doc/gen_inputs.py
@@ -0,0 +1,71 @@
#!/usr/bin/env python3
# IODATA is an input and output module for quantum chemistry.
# Copyright (C) 2011-2019 The IODATA Development Team
#
# This file is part of IODATA.
#
# IODATA is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# IODATA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>
# --
# pylint: disable=unused-argument,redefined-builtin
"""Generate formats.rst."""

from gen_formats import _format_words, _print_section
from iodata.api import INPUT_MODULES


__all__ = []


HEADER = """
.. _input_formats:
Supported Input Formats
#######################
"""


def main():
"""Write inputs.rst to stdout."""
print(HEADER)
for modname, module in sorted(INPUT_MODULES.items()):
if not hasattr(module, "write_input"):
continue
lines = module.__doc__.split('\n')
# add labels for cross-referencing format (e.g. in formats table)
print(f".. _input_{modname}:")
print()
_print_section('{} (``{}``)'.format(lines[0][:-1], modname), "=")
print()
for line in lines[2:]:
print(line)

_print_section(":py:func:`iodata.formats.{}.write_input`".format(modname), "-")
fn = getattr(module, "write_input", None)
print("- Requires", _format_words(fn.required))
if fn.optional:
print("- May use", _format_words(fn.optional))
if fn.kwdocs:
print("- Keyword arguments", _format_words(fn.kwdocs))
if fn.notes:
print()
print(fn.notes)
print()
print()
print()


if __name__ == '__main__':
main()
36 changes: 36 additions & 0 deletions doc/getting_started.rst
Expand Up @@ -25,6 +25,7 @@ Getting Started

IOData can be used to read and write different quantum chemistry file formats.


Script usage
------------

Expand All @@ -36,12 +37,14 @@ The simplest way to use IOData, without writing any code is to use the ``iodata-
See the :code:`--help` option for more details on usage.


Code usage
----------

More complex use cases can be implemented in Python, using IOData as a library.
IOData stores an object containing the data read from the file.


Reading
^^^^^^^

Expand Down Expand Up @@ -139,6 +142,38 @@ example. The following approach would be more memory efficient.
dump_many(itermols(), "traj2.xyz")
Input files
^^^^^^^^^^^

IOData can be used to write input files for quantum-chemistry software. By
default minimal settings are used, which can be changed if needed. For example,
the following will prepare a Gaussian input for a HF/STO-3G calculation from
a PDB file:

.. code-block:: python
from iodata import load_one, write_input
write_input(load_one("water.pdf"), "water.com", fmt="gaussian")
The level of theory and other settings can be modified by setting corresponding
attributes in the IOData object:

.. code-block:: python
from iodata import load_one, write_input
mol = load_one("water.pdf")
mol.lot = "B3LYP"
mol.obasis_name = "6-31g*"
mol.run_type = "opt"
write_input(mold, "water.com", fmt="gaussian")
The run types can be any of the following: ``energy``, ``energy_force``,
``opt``, ``scan`` or ``freq``. These are translated into program-specific
keywords when the file is written.


Data storage
^^^^^^^^^^^^

Expand All @@ -156,6 +191,7 @@ IOData can be used to store data in a consistent format for writing at a future
.. _units:


Unit conversion
^^^^^^^^^^^^^^^

Expand Down
1 change: 1 addition & 0 deletions doc/index.rst
Expand Up @@ -70,6 +70,7 @@ User Documentation
install
getting_started
formats
inputs
basis
changelog
acknowledgments
Expand Down
14 changes: 8 additions & 6 deletions iodata/api.py
Expand Up @@ -83,16 +83,17 @@ def _find_input_modules():
result = {}
for module_info in iter_modules(import_module('iodata.inputs').__path__):
if not module_info.ispkg:
format_module = import_module('iodata.inputs.' + module_info.name)
result[module_info.name] = format_module
input_module = import_module('iodata.inputs.' + module_info.name)
if hasattr(input_module, "write_input"):
result[module_info.name] = input_module
return result


INPUT_MODULES = _find_input_modules()


def _select_input_module(fmt: str) -> ModuleType:
"""Find an input module with the requested attribute name.
"""Find an input module.
Parameters
----------
Expand Down Expand Up @@ -131,16 +132,17 @@ def load_one(filename: str, fmt: str = None, **kwargs) -> IOData:
Returns
-------
out: IOData
out
The instance of IOData with data loaded from the input files.
"""
format_module = _select_format_module(filename, 'load_one', fmt)
lit = LineIterator(filename)
try:
return IOData(**format_module.load_one(lit, **kwargs))
iodata = IOData(**format_module.load_one(lit, **kwargs))
except StopIteration:
lit.error("File ended before all data was read.")
return iodata


def load_many(filename: str, fmt: str = None, **kwargs) -> Iterator[IOData]:
Expand All @@ -162,7 +164,7 @@ def load_many(filename: str, fmt: str = None, **kwargs) -> Iterator[IOData]:
Yields
------
out: IOData
out
An instance of IOData with data for one frame loaded for the file.
"""
Expand Down

0 comments on commit ee99dd0

Please sign in to comment.