composite-step 2026.11.11__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,26 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ """
4
+ composite_step
5
+ A SEAMM plug-in for composite methods: energies from recipes of ordinary calculations
6
+ """
7
+
8
+ # Bring up the classes so that they appear to be directly in
9
+ # the composite_step package.
10
+
11
+ from .composite import Composite # noqa: F401, E501
12
+ from .composite_parameters import CompositeParameters # noqa: F401, E501
13
+ from .composite_step import CompositeStep # noqa: F401, E501
14
+ from .tk_composite import TkComposite # noqa: F401, E501
15
+
16
+ from .metadata import metadata # noqa: F401
17
+
18
+ # Handle versioneer
19
+ from ._version import get_versions
20
+
21
+ __author__ = "Paul Saxe"
22
+ __email__ = "psaxe@molssi.org"
23
+ versions = get_versions()
24
+ __version__ = versions["version"]
25
+ __git_revision__ = versions["full-revisionid"]
26
+ del get_versions, versions
@@ -0,0 +1,21 @@
1
+
2
+ # This file was generated by 'versioneer.py' (0.18) from
3
+ # revision-control system data, or from the parent directory name of an
4
+ # unpacked source archive. Distribution tarballs contain a pre-generated copy
5
+ # of this file.
6
+
7
+ import json
8
+
9
+ version_json = '''
10
+ {
11
+ "date": "2026-11-11T20:16:54-0500",
12
+ "dirty": false,
13
+ "error": null,
14
+ "full-revisionid": "bd87d3e0e8117b78603103c0d6b0de26ee0c75e7",
15
+ "version": "2026.11.11"
16
+ }
17
+ ''' # END VERSION_JSON
18
+
19
+
20
+ def get_versions():
21
+ return json.loads(version_json)
@@ -0,0 +1,147 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ """Non-graphical part of the Composite step in a SEAMM flowchart"""
4
+
5
+ import logging
6
+ import importlib.resources
7
+ import pprint # noqa: F401
8
+
9
+ import composite_step
10
+ import molsystem
11
+ import seamm
12
+ from seamm_util import ureg, Q_ # noqa: F401
13
+ import seamm_util.printing as printing
14
+ from seamm_util.printing import FormattedText as __
15
+
16
+ # In addition to the normal logger, two logger-like printing facilities are
17
+ # defined: "job" and "printer". "job" send output to the main job.out file for
18
+ # the job, and should be used very sparingly, typically to echo what this step
19
+ # will do in the initial summary of the job.
20
+ #
21
+ # "printer" sends output to the file "step.out" in this steps working
22
+ # directory, and is used for all normal output from this step.
23
+
24
+ logger = logging.getLogger(__name__)
25
+ job = printing.getPrinter()
26
+ printer = printing.getPrinter("Composite")
27
+
28
+ # Add this module's properties to the standard properties
29
+ path = importlib.resources.files("composite_step") / "data"
30
+ csv_file = path / "properties.csv"
31
+ if path.exists():
32
+ molsystem.add_properties_from_file(csv_file)
33
+
34
+
35
+ class Composite(seamm.Node):
36
+ """
37
+ The non-graphical part of a Composite step in a flowchart.
38
+
39
+ Attributes
40
+ ----------
41
+ parser : configargparse.ArgParser
42
+ The parser object.
43
+
44
+ options : tuple
45
+ It contains a two item tuple containing the populated namespace and the
46
+ list of remaining argument strings.
47
+
48
+ subflowchart : seamm.Flowchart
49
+ A SEAMM Flowchart object that represents a subflowchart, if needed.
50
+
51
+ parameters : CompositeParameters
52
+ The control parameters for Composite.
53
+
54
+ See Also
55
+ --------
56
+ TkComposite,
57
+ Composite, CompositeParameters
58
+ """
59
+
60
+ def __init__(
61
+ self, flowchart=None, title="Composite", extension=None, logger=logger
62
+ ):
63
+ """A step for Composite in a SEAMM flowchart.
64
+
65
+ You may wish to change the title above, which is the string displayed
66
+ in the box representing the step in the flowchart.
67
+
68
+ Parameters
69
+ ----------
70
+ flowchart: seamm.Flowchart
71
+ The non-graphical flowchart that contains this step.
72
+
73
+ title: str
74
+ The name displayed in the flowchart.
75
+ extension: None
76
+ Not yet implemented
77
+ logger : Logger = logger
78
+ The logger to use and pass to parent classes
79
+
80
+ Returns
81
+ -------
82
+ None
83
+ """
84
+ logger.debug(f"Creating Composite {self}")
85
+
86
+ super().__init__(
87
+ flowchart=flowchart,
88
+ title="Composite",
89
+ extension=extension,
90
+ module=__name__,
91
+ logger=logger,
92
+ ) # yapf: disable
93
+
94
+ self._metadata = composite_step.metadata
95
+ self.parameters = composite_step.CompositeParameters()
96
+
97
+ @property
98
+ def version(self):
99
+ """The semantic version of this module."""
100
+ return composite_step.__version__
101
+
102
+ @property
103
+ def git_revision(self):
104
+ """The git version of this module."""
105
+ return composite_step.__git_revision__
106
+
107
+ def description_text(self, P=None):
108
+ """Create the text description of what this step will do.
109
+ The dictionary of control values is passed in as P so that
110
+ the code can test values, etc.
111
+
112
+ Parameters
113
+ ----------
114
+ P: dict
115
+ An optional dictionary of the current values of the control
116
+ parameters.
117
+ Returns
118
+ -------
119
+ str
120
+ A description of the current step.
121
+ """
122
+ if not P:
123
+ P = self.parameters.values_to_dict()
124
+
125
+ text = (
126
+ "Composite methods are used through a Model Chemistry step, as "
127
+ "SEAMM:CMP@<recipe> (e.g. SEAMM:CMP@revDSD-r2SCAN-3c-HO), by the steps "
128
+ "that take a model chemistry, such as Thermochemistry. This step "
129
+ "itself does nothing yet."
130
+ )
131
+
132
+ return self.header + "\n" + __(text, **P, indent=4 * " ").__str__()
133
+
134
+ def run(self):
135
+ """Run a Composite step: print what it does, which is nothing yet.
136
+
137
+ Returns
138
+ -------
139
+ seamm.Node
140
+ The next node object in the flowchart.
141
+ """
142
+ next_node = super().run(printer)
143
+ printer.important(__(self.description_text({}), indent=self.indent))
144
+ return next_node
145
+
146
+ def analyze(self, indent="", **kwargs):
147
+ """Nothing to analyze yet."""
@@ -0,0 +1,101 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Control parameters for the Composite step in a SEAMM flowchart
4
+ """
5
+
6
+ import logging
7
+ import seamm
8
+ import pprint # noqa: F401
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ class CompositeParameters(seamm.Parameters):
14
+ """
15
+ The control parameters for Composite.
16
+
17
+ You need to replace the "time" entry in dictionary below these comments with the
18
+ definitions of parameters to control this step. The keys are parameters for the
19
+ current plugin,the values are dictionaries as outlined below.
20
+
21
+ Examples
22
+ --------
23
+ ::
24
+
25
+ parameters = {
26
+ "time": {
27
+ "default": 100.0,
28
+ "kind": "float",
29
+ "default_units": "ps",
30
+ "enumeration": tuple(),
31
+ "format_string": ".1f",
32
+ "description": "Simulation time:",
33
+ "help_text": ("The time to simulate in the dynamics run.")
34
+ },
35
+ }
36
+
37
+ parameters : {str: {str: str}}
38
+ A dictionary containing the parameters for the current step.
39
+ Each key of the dictionary is a dictionary that contains the
40
+ the following keys:
41
+
42
+ parameters["default"] :
43
+ The default value of the parameter, used to reset it.
44
+
45
+ parameters["kind"] : enum()
46
+ Specifies the kind of a variable. One of "integer", "float", "string",
47
+ "boolean", or "enum"
48
+
49
+ While the "kind" of a variable might be a numeric value, it may still have
50
+ enumerated custom values meaningful to the user. For instance, if the parameter
51
+ is a convergence criterion for an optimizer, custom values like "normal",
52
+ "precise", etc, might be adequate. In addition, any parameter can be set to a
53
+ variable of expression, indicated by having "$" as the first character in the
54
+ field. For example, $OPTIMIZER_CONV.
55
+
56
+ parameters["default_units"] : str
57
+ The default units, used for resetting the value.
58
+
59
+ parameters["enumeration"] : tuple
60
+ A tuple of enumerated values.
61
+
62
+ parameters["format_string"] : str
63
+ A format string for "pretty" output.
64
+
65
+ parameters["description"] : str
66
+ A short string used as a prompt in the GUI.
67
+
68
+ parameters["help_text"] : str
69
+ A longer string to display as help for the user.
70
+
71
+ See Also
72
+ --------
73
+ Composite, TkComposite, Composite CompositeParameters, CompositeStep
74
+ """
75
+
76
+ #: No parameters yet: composites are used through a Model Chemistry step.
77
+ parameters = {}
78
+
79
+ def __init__(self, defaults={}, data=None):
80
+ """
81
+ Initialize the parameters, by default with the parameters defined above
82
+
83
+ Parameters
84
+ ----------
85
+ defaults: dict
86
+ A dictionary of parameters to initialize. The parameters
87
+ above are used first and any given will override/add to them.
88
+ data: dict
89
+ A dictionary of keys and a subdictionary with value and units
90
+ for updating the current, default values.
91
+
92
+ Returns
93
+ -------
94
+ None
95
+ """
96
+
97
+ logger.debug("CompositeParameters.__init__")
98
+
99
+ super().__init__(
100
+ defaults={**CompositeParameters.parameters, **defaults}, data=data
101
+ )
@@ -0,0 +1,198 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import logging
4
+ from pathlib import Path
5
+
6
+ import composite_step
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ class CompositeStep(object):
12
+ """Helper class needed for the stevedore integration.
13
+
14
+ This must provide a `description()` method that returns a dict containing a
15
+ description of this node, and `create_node()` and `create_tk_node()` methods
16
+ for creating the graphical and non-graphical nodes.
17
+
18
+ The dictionary for the description is the class variable just below these
19
+ comments. The felds are as follows:
20
+
21
+ my_description : {str, str}
22
+ A human-readable description of this step. It can be
23
+ several lines long, and needs to be clear to non-expert users.
24
+ It contains the following keys: description, group, name.
25
+
26
+ my_description["description"] : tuple
27
+ A description of the Composite step. It must be
28
+ clear to non-experts.
29
+
30
+ my_description["group"] : str
31
+ Which group in the menus to put this step. If the group does
32
+ not exist it will be created. Common groups are "Building",
33
+ "Control", "Custom", "Data", and "Simulations".
34
+
35
+ my_description["name"] : str
36
+ The name of this step, to be displayed in the menus.
37
+ """
38
+
39
+ my_description = {
40
+ "description": "An interface for Composite",
41
+ "group": "Simulations",
42
+ "name": "Composite",
43
+ }
44
+
45
+ def __init__(self, flowchart=None, gui=None):
46
+ """Initialize this helper class, which is used by
47
+ the application via stevedore to get information about
48
+ and create node objects for the flowchart
49
+ """
50
+ pass
51
+
52
+ @classmethod
53
+ def get_model_chemistry_options(
54
+ cls, periodic_only=False, mdi_only=False, data_path=None
55
+ ):
56
+ """The composite methods SEAMM provides: ``SEAMM:CMP@<recipe>`` for the
57
+ newest version of each recipe found.
58
+
59
+ The recipes are the shipped set plus those in a ``recipes/`` directory of
60
+ each ``data_path`` entry (a job's data, the user's). Composites are
61
+ molecular and have no MDI engine or gradients yet, so a periodic-only or
62
+ MDI-only request gets nothing.
63
+
64
+ Whether the codes for a recipe's components are installed is not checked
65
+ here: that needs the other steps' model chemistries, and asking for them
66
+ from inside model-chemistry discovery would recurse. The step checks it
67
+ before it runs anything (:func:`composite_step.recipes.check_capabilities`).
68
+ """
69
+ from .recipes import RecipeLibrary
70
+
71
+ if periodic_only or mdi_only:
72
+ return {}
73
+ extra = []
74
+ for directory in data_path or ():
75
+ extra.append(Path(directory) / "recipes")
76
+ library = RecipeLibrary(extra_directories=extra)
77
+ for problem in library.problems:
78
+ logger.warning("Composite recipes: %s", problem)
79
+ options = {}
80
+ for name in library.names():
81
+ recipe = library.get(name)
82
+ scale, source = recipe.zpe_scale
83
+ options[recipe.model_chemistry] = {
84
+ "model_chemistry": recipe.model_chemistry,
85
+ "type": "CMP",
86
+ "method": recipe.name,
87
+ "basis": None,
88
+ "description": recipe.description or recipe.name,
89
+ "periodic": False,
90
+ "mdi_capable": False,
91
+ "analytic_hessian": False,
92
+ "parallel_tasks": True,
93
+ "prefers_batch": True,
94
+ "recipe": recipe.name,
95
+ "recipe_version": recipe.version,
96
+ "recipe_source": recipe.source,
97
+ "geometry_level": recipe.geometry.get("level"),
98
+ "components": {k: v.get("level") for k, v in recipe.components.items()},
99
+ "zpe_scale": scale,
100
+ "zpe_scale_source": source,
101
+ }
102
+ return options
103
+
104
+ @classmethod
105
+ def can_run_task(cls, configuration, model_chemistry, **kwargs):
106
+ """Whether one task per structure can compute this composite: only when
107
+ E0 depends on one energy (the component's own task), for a molecule."""
108
+ from .evaluate import delegate
109
+ from .recipes import RecipeError
110
+
111
+ if int(getattr(configuration, "periodicity", 0) or 0) != 0:
112
+ return False
113
+ try:
114
+ _, _, mc, provider = delegate(model_chemistry)
115
+ except RecipeError:
116
+ return False
117
+ check = getattr(provider, "can_run_task", None)
118
+ return True if check is None else check(configuration, mc, **kwargs)
119
+
120
+ @classmethod
121
+ def get_task(cls, configuration, model_chemistry, **kwargs):
122
+ """The task of a one-energy recipe: its component's task. A recipe that
123
+ combines several calculations runs through
124
+ :func:`composite_step.evaluate.evaluate_recipe` instead."""
125
+ from .evaluate import delegated_get_task
126
+
127
+ return delegated_get_task(configuration, model_chemistry, **kwargs)
128
+
129
+ @classmethod
130
+ def analyze_task(cls, result, model_chemistry, configuration, **kwargs):
131
+ """The component's results with the energy replaced by the recipe's E0
132
+ (kJ/mol), and the composite described under ``composite``."""
133
+ from .evaluate import delegated_analyze_task
134
+
135
+ return delegated_analyze_task(result, model_chemistry, configuration, **kwargs)
136
+
137
+ @classmethod
138
+ def expected_fingerprints(cls, configuration, model_chemistry, **kwargs):
139
+ """The component's own expected fingerprints, for a one-energy recipe."""
140
+ from .evaluate import delegate
141
+ from .recipes import RecipeError
142
+
143
+ try:
144
+ _, _, mc, provider = delegate(model_chemistry)
145
+ except RecipeError:
146
+ return None
147
+ predict = getattr(provider, "expected_fingerprints", None)
148
+ return None if predict is None else predict(configuration, mc, **kwargs)
149
+
150
+ def create_node(self, flowchart=None, **kwargs):
151
+ """Create and return the new node object.
152
+
153
+ Parameters
154
+ ----------
155
+ flowchart: seamm.Node
156
+ A non-graphical SEAMM node
157
+
158
+ **kwargs : keyword arguments
159
+ Various keyword arguments such as title, namespace or
160
+ extension representing the title displayed in the flowchart,
161
+ the namespace for the plugins of a subflowchart and
162
+ the extension, respectively.
163
+
164
+ Returns
165
+ -------
166
+ Composite
167
+ """
168
+
169
+ return composite_step.Composite(flowchart=flowchart, **kwargs)
170
+
171
+ def create_tk_node(self, canvas=None, **kwargs):
172
+ """Create and return the graphical Tk node object.
173
+
174
+ Parameters
175
+ ----------
176
+ canvas : tk.Canvas
177
+ The Tk Canvas widget
178
+
179
+ **kwargs : keyword arguments
180
+ Various keyword arguments such as tk_flowchart, node, x, y, w, h
181
+ representing a graphical flowchart object, a non-graphical node for
182
+ a step, and dimensions of the graphical node.
183
+
184
+ Returns
185
+ -------
186
+ TkComposite
187
+ """
188
+
189
+ return composite_step.TkComposite(canvas=canvas, **kwargs)
190
+
191
+ def description(self):
192
+ """Return a description of what this step does.
193
+
194
+ Returns
195
+ -------
196
+ description : dict(str, str)
197
+ """
198
+ return CompositeStep.my_description
@@ -0,0 +1 @@
1
+ Property,Type,Units,Description,URL
@@ -0,0 +1,21 @@
1
+ recipe: r2SCAN-3c-HO
2
+ version: 1
3
+ description: >-
4
+ r2SCAN-3c geometry, frequencies and energy (ORCA's own r2SCAN-3c composite),
5
+ with the ZPE scaled; HO = scaled harmonic thermal terms. The thermochemistry
6
+ step's 'quick' preset in 2026-11.
7
+ reference: Grimme, Hansen, Ehlert, Mewes, J. Chem. Phys. 154, 064103 (2021)
8
+ doi: 10.1063/5.0040021
9
+
10
+ geometry:
11
+ level: ORCA:CMP@R2SCAN-3C
12
+ frequencies:
13
+ scale_zpe: 0.9899
14
+ scale_source: >-
15
+ fitted to the anharmonic ZPVEs of 22 W4-2006 molecules (SEAMM, 2026-11);
16
+ seamm_thermochemistry's ZPE table for R2SCAN-3C
17
+
18
+ components: {}
19
+
20
+ combine: |
21
+ E0 = geometry
@@ -0,0 +1,25 @@
1
+ recipe: revDSD-r2SCAN-3c-HO
2
+ version: 1
3
+ description: >-
4
+ r2SCAN-3c geometry and frequencies (ZPE scaled), and the
5
+ revDSD-PBEP86-D4(2021)/def2-TZVPP energy at that geometry; HO = scaled
6
+ harmonic thermal terms. The thermochemistry step's 'default' preset in 2026-11.
7
+ reference: >-
8
+ Grimme, Hansen, Ehlert, Mewes, J. Chem. Phys. 154, 064103 (2021);
9
+ Santra, Sylvetsky, Martin, J. Phys. Chem. A 123, 5129 (2019)
10
+ doi: 10.1063/5.0040021
11
+
12
+ geometry:
13
+ level: ORCA:CMP@R2SCAN-3C
14
+ frequencies:
15
+ scale_zpe: 0.9899
16
+ scale_source: >-
17
+ fitted to the anharmonic ZPVEs of 22 W4-2006 molecules (SEAMM, 2026-11);
18
+ seamm_thermochemistry's ZPE table for R2SCAN-3C
19
+
20
+ components:
21
+ revdsd:
22
+ level: ORCA:DFT@REVDSD-PBEP86-D4_2021/def2-TZVPP
23
+
24
+ combine: |
25
+ E0 = revdsd
@@ -0,0 +1,40 @@
1
+ This is an initial library of BibTex references for the composite_step plug-in for SEAMM,
2
+ generated automatically by the cookiecutter. You may wish to edit the first entry to correct some
3
+ of the information.
4
+
5
+ Add other references to the end of the file and add code in the plug-in to cite the references as
6
+ appropriate. This is done with code like this:
7
+
8
+ self.references.cite(
9
+ raw=self._bibliography['doi:10.1002/jcc.21224'],
10
+ alias='packmol',
11
+ module='packmol_step',
12
+ level=1,
13
+ note='The principle PACKMOL citation.'
14
+ )
15
+
16
+ which is typically in the run() method of the plug-in.
17
+
18
+ The base node class in SEAMM automatically reads this list of references into a dictionary in
19
+ self._bibliography with the key being the key of the BibTex entry -- usually the name on the
20
+ first line of the entry after the 'article' or 'misc' (for software) keyword.
21
+
22
+ See the documentation for the Reference Handler for the other arguments to cite().
23
+
24
+ # End of initial comments #
25
+
26
+ # This is the citation for this plug-in, generated and used automatically.
27
+ # You might need to edit the author, address, etc. The month, year and version fields
28
+ # are automatically filled in with information about current version of the plug-in.
29
+ # This is handled in seamm/nody.py, the run() method.
30
+
31
+ @Misc{composite_step,
32
+ author = {Paul Saxe},
33
+ title = {Composite plug-in for SEAMM},
34
+ month = {$month},
35
+ year = {$year},
36
+ organization = {molssi-seamm},
37
+ url = {https://github.com/molssi-seamm/composite_step },
38
+ address = {USA},
39
+ version = {$version}
40
+ }