From 1fdffdcca3d461c7ae1df949c39568807c5814f8 Mon Sep 17 00:00:00 2001 From: Leopold Talirz Date: Tue, 1 Oct 2019 09:13:40 +0200 Subject: [PATCH] Generalize Sphinx workchain extension to processes (#3314) * Generalize the Sphinx `WorkChain` extension to `Processes` * Use it to replace documentation of the `CalcJob` interface --- aiida/sphinxext/__init__.py | 11 +- aiida/sphinxext/calcjob.py | 40 ++++ aiida/sphinxext/process.py | 181 ++++++++++++++++++ .../tests/reference_results/workchain.py2.xml | 37 ++-- .../tests/reference_results/workchain.py3.xml | 37 ++-- .../sphinxext/tests/workchain_source/conf.py | 15 +- .../tests/workchain_source/index.rst | 4 +- aiida/sphinxext/workchain.py | 170 ++-------------- docs/source/conf.py | 2 +- docs/source/working/calculations.rst | 128 +------------ 10 files changed, 276 insertions(+), 349 deletions(-) create mode 100644 aiida/sphinxext/calcjob.py create mode 100644 aiida/sphinxext/process.py diff --git a/aiida/sphinxext/__init__.py b/aiida/sphinxext/__init__.py index 2b3a3a2e19..cf6774ab8b 100644 --- a/aiida/sphinxext/__init__.py +++ b/aiida/sphinxext/__init__.py @@ -15,14 +15,17 @@ from __future__ import print_function from __future__ import absolute_import -import aiida -from . import workchain - def setup(app): """ Setup function to add the extension classes / nodes to Sphinx. """ - workchain.setup_aiida_workchain(app) + import aiida + + from . import process, workchain, calcjob + + process.setup_extension(app) + workchain.setup_extension(app) + calcjob.setup_extension(app) return {'version': aiida.__version__, 'parallel_read_safe': True} diff --git a/aiida/sphinxext/calcjob.py b/aiida/sphinxext/calcjob.py new file mode 100644 index 0000000000..c86cb2fb4e --- /dev/null +++ b/aiida/sphinxext/calcjob.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +########################################################################### +# Copyright (c), The AiiDA team. All rights reserved. # +# This file is part of the AiiDA code. # +# # +# The code is hosted on GitHub at https://github.com/aiidateam/aiida-core # +# For further information on the license, see the LICENSE.txt file # +# For further information please visit http://www.aiida.net # +########################################################################### +""" +Defines an rst directive to auto-document AiiDA calculation job. +""" + +from __future__ import division +from __future__ import print_function +from __future__ import absolute_import + +from .process import AiidaProcessDocumenter, AiidaProcessDirective + + +def setup_extension(app): + app.add_directive_to_domain('py', AiidaCalcJobDocumenter.directivetype, AiidaCalcJobDirective) + app.add_autodocumenter(AiidaCalcJobDocumenter) + + +class AiidaCalcJobDocumenter(AiidaProcessDocumenter): + """Sphinx Documenter for AiiDA CalcJobs.""" + directivetype = 'aiida-calcjob' + objtype = 'calcjob' + priority = 20 + + @classmethod + def can_document_member(cls, member, membername, isattr, parent): + from aiida.engine import CalcJob + return issubclass(cls, CalcJob) + + +class AiidaCalcJobDirective(AiidaProcessDirective): + signature = 'CalcJob' + annotation = 'calcjob' diff --git a/aiida/sphinxext/process.py b/aiida/sphinxext/process.py new file mode 100644 index 0000000000..23c77c7f52 --- /dev/null +++ b/aiida/sphinxext/process.py @@ -0,0 +1,181 @@ +# -*- coding: utf-8 -*- +########################################################################### +# Copyright (c), The AiiDA team. All rights reserved. # +# This file is part of the AiiDA code. # +# # +# The code is hosted on GitHub at https://github.com/aiidateam/aiida-core # +# For further information on the license, see the LICENSE.txt file # +# For further information please visit http://www.aiida.net # +########################################################################### +""" +Defines an rst directive to auto-document AiiDA processes. +""" + +from __future__ import division +from __future__ import print_function +from __future__ import absolute_import + +from docutils import nodes +from docutils.core import publish_doctree +from docutils.parsers.rst import Directive, directives +from sphinx import addnodes +from sphinx.ext.autodoc import ClassDocumenter + +from plumpy.ports import OutputPort +from aiida.common.utils import get_object_from_string + + +def setup_extension(app): + app.add_directive_to_domain('py', AiidaProcessDocumenter.directivetype, AiidaProcessDirective) + app.add_autodocumenter(AiidaProcessDocumenter) + + +class AiidaProcessDocumenter(ClassDocumenter): + """Sphinx Documenter class for AiiDA Processes.""" + directivetype = 'aiida-process' + objtype = 'process' + priority = 10 + + @classmethod + def can_document_member(cls, member, membername, isattr, parent): + from aiida.engine import Process + return issubclass(cls, Process) + + +class AiidaProcessDirective(Directive): + """ + Directive to auto-document AiiDA processes. + """ + required_arguments = 1 + optional_arguments = 0 + final_argument_whitespace = True + + HIDE_UNSTORED_INPUTS_FLAG = 'hide-nondb-inputs' + option_spec = {'module': directives.unchanged, HIDE_UNSTORED_INPUTS_FLAG: directives.flag} + signature = 'Process' + annotation = 'process' + + has_content = True + + def run(self): + self.initialize() + return self.build_node_tree() + + def initialize(self): + """Set internal attributes of the class. + + Includes importing the process class. + """ + # pylint: disable=attribute-defined-outside-init + from aiida.manage.configuration import load_profile + load_profile() + + self.class_name = self.arguments[0].split('(')[0] + self.module_name = self.options['module'] + self.process_name = self.module_name + '.' + self.class_name + self.process = get_object_from_string(self.process_name) + self.process_spec = self.process.spec() + + def build_node_tree(self): + """Returns the docutils node tree.""" + process_node = addnodes.desc(desctype='class', domain='py', noindex=False, objtype='class') + process_node += self.build_signature() + process_node += self.build_content() + return [process_node] + + def build_signature(self): + """Returns the signature of the process.""" + signature = addnodes.desc_signature(first=False, fullname=self.signature) + signature += addnodes.desc_annotation(text=self.annotation) + signature += addnodes.desc_addname(text=self.module_name + '.') + signature += addnodes.desc_name(text=self.class_name) + return signature + + def build_content(self): + """ + Returns the main content (docstring, inputs, outputs) of the documentation. + """ + content = nodes.paragraph(text=self.process.__doc__) + + content += self.build_doctree( + title='Inputs:', + port_namespace=self.process_spec.inputs, + ) + content += self.build_doctree(title='Outputs:', port_namespace=self.process_spec.outputs) + + return content + + def build_doctree(self, title, port_namespace): + """ + Returns a doctree for a given port namespace, including a title. + """ + paragraph = nodes.paragraph() + paragraph += nodes.strong(text=title) + namespace_doctree = self.build_portnamespace_doctree(port_namespace) + if namespace_doctree: + paragraph += namespace_doctree + else: + paragraph += nodes.paragraph(text='None defined.') + + return paragraph + + def build_portnamespace_doctree(self, port_namespace): + """ + Builds the doctree for a port namespace. + """ + from aiida.engine.processes.ports import InputPort, PortNamespace + + result = nodes.bullet_list(bullet='*') + for name, port in sorted(port_namespace.items()): + item = nodes.list_item() + if _is_non_db(port) and self.HIDE_UNSTORED_INPUTS_FLAG in self.options: + continue + if isinstance(port, (InputPort, OutputPort)): + item += self.build_port_paragraph(name, port) + elif isinstance(port, PortNamespace): + item += addnodes.literal_strong(text=name) + item += nodes.Text(', ') + item += nodes.emphasis(text='Namespace') + if port.help is not None: + item += nodes.Text(' -- ') + item.extend(publish_doctree(port.help)[0].children) + item += self.build_portnamespace_doctree(port) + else: + raise NotImplementedError + result += item + return result + + def build_port_paragraph(self, name, port): + """ + Build the paragraph that describes a single port. + """ + paragraph = nodes.paragraph() + paragraph += addnodes.literal_strong(text=name) + paragraph += nodes.Text(', ') + paragraph += nodes.emphasis(text=self.format_valid_types(port.valid_type)) + paragraph += nodes.Text(', ') + paragraph += nodes.Text('required' if port.required else 'optional') + if _is_non_db(port): + paragraph += nodes.Text(', ') + paragraph += nodes.emphasis(text='non_db') + if port.help: + paragraph += nodes.Text(' -- ') + # publish_doctree returns >. + # Here we only want the content (children) of the paragraph. + paragraph.extend(publish_doctree(port.help)[0].children) + return paragraph + + @staticmethod + def format_valid_types(valid_type): + """Format valid types.""" + try: + return valid_type.__name__ + except AttributeError: + try: + return '(' + ', '.join(v.__name__ for v in valid_type) + ')' + except (AttributeError, TypeError): + return str(valid_type) + + +def _is_non_db(port): + return getattr(port, 'non_db', False) diff --git a/aiida/sphinxext/tests/reference_results/workchain.py2.xml b/aiida/sphinxext/tests/reference_results/workchain.py2.xml index 7a83fa979f..b2c056318e 100644 --- a/aiida/sphinxext/tests/reference_results/workchain.py2.xml +++ b/aiida/sphinxext/tests/reference_results/workchain.py2.xml @@ -8,38 +8,27 @@ - workchaindemo_workchain.DemoWorkChain - - - A demo workchain to show how the workchain auto-documentation works. - - Inputs:metadata, Namespacecall_link_label, (basestring), optional, non_db – The label to use for the CALL link if the process is called by another process.description, (basestring), optional, non_db – Description to set on the process node.label, (basestring), optional, non_db – Label to set on the process node.store_provenance, bool, optional, non_db – If set to False provenance will not be stored in the database.nsp, Namespace – A separate namespace, nsp.nsp2, Namespacex, Float, required – First input argument.y, Namespacez, Int, required – Input in a separate namespace. - Outputs:z, Bool, required – Output of the demoworkchain. - + workchaindemo_workchain.DemoWorkChain + + A demo workchain to show how the workchain auto-documentation works. + Inputs:metadata, Namespacecall_link_label, (basestring), optional, non_db – The label to use for the CALL link if the process is called by another process.description, (basestring), optional, non_db – Description to set on the process node.label, (basestring), optional, non_db – Label to set on the process node.store_provenance, bool, optional, non_db – If set to False provenance will not be stored in the database.nsp, Namespace – A separate namespace, nsp.nsp2, Namespacex, Float, required – First input argument.y, Namespacez, Int, required – Input in a separate namespace.Outputs:z, Bool, required – Output of the demoworkchain. - You can use the :hide-unstored-inputs: option to not show the inputs which are not stored in the DB: + If you want to hide the inputs that are not stored as nodes in the database, use the :hide-unstored-inputs: option. - workchaindemo_workchain.DemoWorkChain - - - A demo workchain to show how the workchain auto-documentation works. - - Inputs:nsp, Namespace – A separate namespace, nsp.nsp2, Namespacex, Float, required – First input argument.y, Namespacez, Int, required – Input in a separate namespace. - Outputs:z, Bool, required – Output of the demoworkchain. - + workchaindemo_workchain.DemoWorkChain + + A demo workchain to show how the workchain auto-documentation works. + Inputs:nsp, Namespace – A separate namespace, nsp.nsp2, Namespacex, Float, required – First input argument.y, Namespacez, Int, required – Input in a separate namespace.Outputs:z, Bool, required – Output of the demoworkchain. - The command is also hooked into sphinx.ext.autodoc, so you can also use that. + The command is also hooked into sphinx.ext.autodoc, so AiiDA processes will be properly documented using .. automodule:: as well. This module defines an example workchain for the aiida-workchain documentation directive. + - workchaindemo_workchain.DemoWorkChain + class demo_workchain.DemoWorkChaininputs=Nonelogger=Nonerunner=Noneenable_persistence=True - - A demo workchain to show how the workchain auto-documentation works. - - Inputs:metadata, Namespacecall_link_label, (basestring), optional, non_db – The label to use for the CALL link if the process is called by another process.description, (basestring), optional, non_db – Description to set on the process node.label, (basestring), optional, non_db – Label to set on the process node.store_provenance, bool, optional, non_db – If set to False provenance will not be stored in the database.nsp, Namespace – A separate namespace, nsp.nsp2, Namespacex, Float, required – First input argument.y, Namespacez, Int, required – Input in a separate namespace. - Outputs:z, Bool, required – Output of the demoworkchain. + A demo workchain to show how the workchain auto-documentation works. diff --git a/aiida/sphinxext/tests/reference_results/workchain.py3.xml b/aiida/sphinxext/tests/reference_results/workchain.py3.xml index ba7755bfe4..1dd357ed40 100644 --- a/aiida/sphinxext/tests/reference_results/workchain.py3.xml +++ b/aiida/sphinxext/tests/reference_results/workchain.py3.xml @@ -8,38 +8,27 @@ - workchaindemo_workchain.DemoWorkChain - - - A demo workchain to show how the workchain auto-documentation works. - - Inputs:metadata, Namespacecall_link_label, (str), optional, non_db – The label to use for the CALL link if the process is called by another process.description, (str), optional, non_db – Description to set on the process node.label, (str), optional, non_db – Label to set on the process node.store_provenance, bool, optional, non_db – If set to False provenance will not be stored in the database.nsp, Namespace – A separate namespace, nsp.nsp2, Namespacex, Float, required – First input argument.y, Namespacez, Int, required – Input in a separate namespace. - Outputs:z, Bool, required – Output of the demoworkchain. - + workchaindemo_workchain.DemoWorkChain + + A demo workchain to show how the workchain auto-documentation works. + Inputs:metadata, Namespacecall_link_label, (str), optional, non_db – The label to use for the CALL link if the process is called by another process.description, (str), optional, non_db – Description to set on the process node.label, (str), optional, non_db – Label to set on the process node.store_provenance, bool, optional, non_db – If set to False provenance will not be stored in the database.nsp, Namespace – A separate namespace, nsp.nsp2, Namespacex, Float, required – First input argument.y, Namespacez, Int, required – Input in a separate namespace.Outputs:z, Bool, required – Output of the demoworkchain. - You can use the :hide-unstored-inputs: option to not show the inputs which are not stored in the DB: + If you want to hide the inputs that are not stored as nodes in the database, use the :hide-unstored-inputs: option. - workchaindemo_workchain.DemoWorkChain - - - A demo workchain to show how the workchain auto-documentation works. - - Inputs:nsp, Namespace – A separate namespace, nsp.nsp2, Namespacex, Float, required – First input argument.y, Namespacez, Int, required – Input in a separate namespace. - Outputs:z, Bool, required – Output of the demoworkchain. - + workchaindemo_workchain.DemoWorkChain + + A demo workchain to show how the workchain auto-documentation works. + Inputs:nsp, Namespace – A separate namespace, nsp.nsp2, Namespacex, Float, required – First input argument.y, Namespacez, Int, required – Input in a separate namespace.Outputs:z, Bool, required – Output of the demoworkchain. - The command is also hooked into sphinx.ext.autodoc, so you can also use that. + The command is also hooked into sphinx.ext.autodoc, so AiiDA processes will be properly documented using .. automodule:: as well. This module defines an example workchain for the aiida-workchain documentation directive. + - workchaindemo_workchain.DemoWorkChain + class demo_workchain.DemoWorkChaininputs=Nonelogger=Nonerunner=Noneenable_persistence=True - - A demo workchain to show how the workchain auto-documentation works. - - Inputs:metadata, Namespacecall_link_label, (str), optional, non_db – The label to use for the CALL link if the process is called by another process.description, (str), optional, non_db – Description to set on the process node.label, (str), optional, non_db – Label to set on the process node.store_provenance, bool, optional, non_db – If set to False provenance will not be stored in the database.nsp, Namespace – A separate namespace, nsp.nsp2, Namespacex, Float, required – First input argument.y, Namespacez, Int, required – Input in a separate namespace. - Outputs:z, Bool, required – Output of the demoworkchain. + A demo workchain to show how the workchain auto-documentation works. diff --git a/aiida/sphinxext/tests/workchain_source/conf.py b/aiida/sphinxext/tests/workchain_source/conf.py index 431d6814cd..94364908d2 100644 --- a/aiida/sphinxext/tests/workchain_source/conf.py +++ b/aiida/sphinxext/tests/workchain_source/conf.py @@ -130,20 +130,14 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - ( - master_doc, 'sphinx-aiida-demo.tex', - u'sphinx-aiida-demo Documentation', u'Dominik Gresch', 'manual' - ), + (master_doc, 'sphinx-aiida-demo.tex', u'sphinx-aiida-demo Documentation', u'Dominik Gresch', 'manual'), ] # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [( - master_doc, 'sphinx-aiida-demo', u'sphinx-aiida-demo Documentation', - [author], 1 -)] +man_pages = [(master_doc, 'sphinx-aiida-demo', u'sphinx-aiida-demo Documentation', [author], 1)] # -- Options for Texinfo output ------------------------------------------- @@ -152,8 +146,7 @@ # dir menu entry, description, category) texinfo_documents = [ ( - master_doc, 'sphinx-aiida-demo', u'sphinx-aiida-demo Documentation', - author, 'sphinx-aiida-demo', 'One line description of project.', - 'Miscellaneous' + master_doc, 'sphinx-aiida-demo', u'sphinx-aiida-demo Documentation', author, 'sphinx-aiida-demo', + 'One line description of project.', 'Miscellaneous' ), ] diff --git a/aiida/sphinxext/tests/workchain_source/index.rst b/aiida/sphinxext/tests/workchain_source/index.rst index 48353c2637..e83b97fb42 100644 --- a/aiida/sphinxext/tests/workchain_source/index.rst +++ b/aiida/sphinxext/tests/workchain_source/index.rst @@ -11,13 +11,13 @@ This is a demo documentation to show off the features of the ``sphinx-aiida`` ex :module: demo_workchain -You can use the ``:hide-unstored-inputs:`` option to not show the inputs which are not stored in the DB: +If you want to hide the inputs that are not stored as nodes in the database, use the ``:hide-unstored-inputs:`` option. .. aiida-workchain:: DemoWorkChain :module: demo_workchain :hide-nondb-inputs: -The command is also hooked into ``sphinx.ext.autodoc``, so you can also use that. +The command is also hooked into ``sphinx.ext.autodoc``, so AiiDA processes will be properly documented using ``.. automodule::`` as well. .. automodule:: demo_workchain :members: diff --git a/aiida/sphinxext/workchain.py b/aiida/sphinxext/workchain.py index 3260ee4879..f4e5efe277 100644 --- a/aiida/sphinxext/workchain.py +++ b/aiida/sphinxext/workchain.py @@ -15,174 +15,26 @@ from __future__ import print_function from __future__ import absolute_import -from docutils import nodes -from docutils.core import publish_doctree -from docutils.parsers.rst import Directive, directives -from sphinx import addnodes -from sphinx.ext.autodoc import ClassDocumenter +from .process import AiidaProcessDocumenter, AiidaProcessDirective -from plumpy.ports import OutputPort -from aiida.common.utils import get_object_from_string +def setup_extension(app): + app.add_directive_to_domain('py', AiidaWorkChainDocumenter.directivetype, AiidaWorkchainDirective) + app.add_autodocumenter(AiidaWorkChainDocumenter) -def setup_aiida_workchain(app): - """Add sphinx directive.""" - app.add_directive_to_domain('py', 'aiida-workchain', AiidaWorkchainDirective) - app.add_autodocumenter(WorkChainDocumenter) - -class WorkChainDocumenter(ClassDocumenter): - """Documenter class for AiiDA WorkChains.""" +class AiidaWorkChainDocumenter(AiidaProcessDocumenter): + """Sphinx Documenter class for AiiDA WorkChains.""" directivetype = 'aiida-workchain' objtype = 'workchain' priority = 20 @classmethod def can_document_member(cls, member, membername, isattr, parent): - try: - from aiida.manage.configuration import load_profile - load_profile() - from aiida.engine import WorkChain - return issubclass(member, WorkChain) - except Exception: # pylint: disable=broad-except - return False - - -class AiidaWorkchainDirective(Directive): - """Directive to auto-document AiiDA workchains.""" - required_arguments = 1 - optional_arguments = 0 - final_argument_whitespace = True - - HIDE_UNSTORED_INPUTS_FLAG = 'hide-nondb-inputs' - option_spec = {'module': directives.unchanged, HIDE_UNSTORED_INPUTS_FLAG: directives.flag} - - has_content = True - - def run(self): - from aiida.manage.configuration import load_profile - load_profile() - self.load_workchain() - return self.build_node_tree() - - def load_workchain(self): - """Loads the workchain and sets up additional attributes.""" - # pylint: disable=attribute-defined-outside-init - from aiida.manage.configuration import load_profile - load_profile() - - self.class_name = self.arguments[0].split('(')[0] - self.module_name = self.options['module'] - self.workchain_name = self.module_name + '.' + self.class_name - self.workchain = get_object_from_string(self.workchain_name) - self.workchain_spec = self.workchain.spec() - - def build_node_tree(self): - """Returns the docutils node tree.""" - workchain_node = addnodes.desc(desctype='class', domain='py', noindex=False, objtype='class') - workchain_node += self.build_signature() - workchain_node += self.build_content() - return [workchain_node] - - def build_signature(self): - """Returns the signature of the workchain.""" - signature = addnodes.desc_signature(first=False, fullname='Workchain') - signature += addnodes.desc_annotation(text='workchain') - signature += addnodes.desc_addname(text=self.module_name + '.') - signature += addnodes.desc_name(text=self.class_name) - return signature - - def build_content(self): - """ - Returns the main content (docstring, inputs, outputs) of the workchain documentation. - """ - content = addnodes.desc_content() - content += nodes.paragraph(text=self.workchain.__doc__) - - content += self.build_doctree( - title='Inputs:', - port_namespace=self.workchain_spec.inputs, - ) - content += self.build_doctree(title='Outputs:', port_namespace=self.workchain_spec.outputs) - - return content - - def build_doctree(self, title, port_namespace): - """ - Returns a doctree for a given port namespace, including a title. - """ - paragraph = nodes.paragraph() - paragraph += nodes.strong(text=title) - namespace_doctree = self.build_portnamespace_doctree(port_namespace) - if namespace_doctree: - paragraph += namespace_doctree - else: - paragraph += nodes.paragraph(text='None defined.') - - return paragraph - - def build_portnamespace_doctree(self, port_namespace): - """ - Builds the doctree for a port namespace. - """ - from aiida.engine.processes.ports import InputPort, PortNamespace - - result = nodes.bullet_list(bullet='*') - for name, port in sorted(port_namespace.items()): - item = nodes.list_item() - if _is_non_db(port) and self.HIDE_UNSTORED_INPUTS_FLAG in self.options: - continue - if isinstance(port, (InputPort, OutputPort)): - item += self.build_port_paragraph(name, port) - elif isinstance(port, PortNamespace): - item += addnodes.literal_strong(text=name) - item += nodes.Text(', ') - item += nodes.emphasis(text='Namespace') - if port.help is not None: - item += nodes.Text(' -- ') - item.extend(publish_doctree(port.help)[0].children) - item += self.build_portnamespace_doctree(port) - else: - raise NotImplementedError - result += item - return result - - def build_port_paragraph(self, name, port): - """ - Build the paragraph that describes a single port. - """ - paragraph = nodes.paragraph() - paragraph += addnodes.literal_strong(text=name) - paragraph += nodes.Text(', ') - paragraph += nodes.emphasis(text=self.format_valid_types(port.valid_type)) - paragraph += nodes.Text(', ') - paragraph += nodes.Text('required' if port.required else 'optional') - if _is_non_db(port): - paragraph += nodes.Text(', ') - paragraph += nodes.emphasis(text='non_db') - if port.help: - paragraph += nodes.Text(' -- ') - # publish_doctree returns >. - # Here we only want the content (children) of the paragraph. - paragraph.extend(publish_doctree(port.help)[0].children) - return paragraph - - @staticmethod - def format_valid_types(valid_type): - """ - Format valid input/output types. - - :param valid_type: class - :return: formatted string - """ - try: - return valid_type.__name__ - except AttributeError: - try: - return '(' + ', '.join(v.__name__ for v in valid_type) + ')' - except (AttributeError, TypeError): - return str(valid_type) + from aiida.engine import WorkChain + return issubclass(cls, WorkChain) -def _is_non_db(port): - return getattr(port, 'non_db', False) +class AiidaWorkchainDirective(AiidaProcessDirective): + signature = 'WorkChain' + annotation = 'workchain' diff --git a/docs/source/conf.py b/docs/source/conf.py index 6e4863112c..f48be81538 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -44,7 +44,7 @@ # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.imgmath', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode', 'IPython.sphinxext.ipython_console_highlighting', 'IPython.sphinxext.ipython_directive', 'sphinxcontrib.contentui'] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.imgmath', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode', 'IPython.sphinxext.ipython_console_highlighting', 'IPython.sphinxext.ipython_directive', 'sphinxcontrib.contentui', 'aiida.sphinxext'] ipython_mplbackend = '' todo_include_todos = True diff --git a/docs/source/working/calculations.rst b/docs/source/working/calculations.rst index 46edc15177..41f51be329 100644 --- a/docs/source/working/calculations.rst +++ b/docs/source/working/calculations.rst @@ -319,130 +319,10 @@ Options ------- In addition to the common metadata inputs, such as ``label`` and ``description``, that all processes have, the :py:class:`~aiida.engine.processes.calcjobs.calcjob.CalcJob` has an additonal input called ``options``. These options allow to subtly change the behavior of the calculation job, for example which parser should be used once it is finished and special scheduler directives. -The full list of available options are as follows: - - * :ref:`parser_name` - * :ref:`input_filename` - * :ref:`output_filename` - * :ref:`scheduler_stdout` - * :ref:`scheduler_stderr` - * :ref:`resources` - * :ref:`max_wallclock_seconds` - * :ref:`custom_scheduler_commands` - * :ref:`queue_name` - * :ref:`account` - * :ref:`qos` - * :ref:`computer` - * :ref:`withmpi` - * :ref:`mpirun_extra_params` - * :ref:`import_sys_environment` - * :ref:`environment_variables` - * :ref:`priority` - * :ref:`max_memory_kb` - * :ref:`prepend_text` - * :ref:`append_text` - -More detailed information about their usage, follows below. - -.. _working_calcjobs_options_parser_name: - -``parser_name`` -~~~~~~~~~~~~~~~ - -.. _working_calcjobs_options_input_filename: - -``input_filename`` -~~~~~~~~~~~~~~~~~~ - -.. _working_calcjobs_options_output_filename: - -``output_filename`` -~~~~~~~~~~~~~~~~~~~ - -.. _working_calcjobs_options_scheduler_stdout: - -``scheduler_stdout`` -~~~~~~~~~~~~~~~~~~~~ - -.. _working_calcjobs_options_scheduler_stderr: - -``scheduler_stderr`` -~~~~~~~~~~~~~~~~~~~~ - -.. _working_calcjobs_options_resources: - -``resources`` -~~~~~~~~~~~~~ - -.. _working_calcjobs_options_max_wallclock_seconds: - -``max_wallclock_seconds`` -~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. _working_calcjobs_options_custom_scheduler_commands: - -``custom_scheduler_commands`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. _working_calcjobs_options_queue_name: - -``queue_name`` -~~~~~~~~~~~~~~ - -.. _working_calcjobs_options_account: - -``account`` -~~~~~~~~~~~ - -.. _working_calcjobs_options_qos: +The full list of available options are documented below as part of the ``CalcJob`` interface: -``qos`` -~~~~~~~ - -.. _working_calcjobs_options_computer: - -``computer`` -~~~~~~~~~~~~ - -.. _working_calcjobs_options_withmpi: - -``withmpi`` -~~~~~~~~~~~ - -.. _working_calcjobs_options_mpirun_extra_params: - -``mpirun_extra_params`` -~~~~~~~~~~~~~~~~~~~~~~~ - -.. _working_calcjobs_options_import_sys_environment: - -``import_sys_environment`` -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. _working_calcjobs_options_environment_variables: - -``environment_variables`` -~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. _working_calcjobs_options_priority: - -``priority`` -~~~~~~~~~~~~ - -.. _working_calcjobs_options_max_memory_kb: - -``max_memory_kb`` -~~~~~~~~~~~~~~~~~ - -.. _working_calcjobs_options_prepend_text: - -``prepend_text`` -~~~~~~~~~~~~~~~~ - -.. _working_calcjobs_options_append_text: - -``append_text`` -~~~~~~~~~~~~~~~ +.. aiida-calcjob:: CalcJob + :module: aiida.engine.processes.calcjobs .. _working_calcjobs_launch: @@ -511,7 +391,7 @@ Parsing The previous sections explained in detail how the execution of an external executable is wrapped by the ``CalcJob`` class to make it runnable by AiiDA's engine. From the first steps of preparing the input files on the remote machine, to retrieving the relevant files and storing them in a :py:class:`~aiida.orm.nodes.data.folder.FolderData` node, that is attached as the ``retrieved`` output. This is the last *required* step for a ``CalcJob`` to terminate, but often we would *like* to parse the raw output and attach them as queryable output nodes to the calculation job node. -To automatically trigger the parsing of a calculation job after its output has been retrieved, is to specify the :ref:`parser name option`. +To automatically trigger the parsing of a calculation job after its output has been retrieved, is to specify the :ref:`parser name option`. If the engine find this option specified, it will load the corresponding parser class, which should be a sub class of :py:class:`~aiida.parsers.parser.Parser` and calls its :py:meth:`~aiida.parsers.parser.Parser.parse` method. To explain the interface of the ``Parser`` class and the ``parse`` method, let's take the :py:class:`~aiida.parsers.plugins.arithmetic.add.ArithmeticAddParser` as an example.