aiida-chemshell 0.2.2__tar.gz → 0.3.0__tar.gz

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.
Files changed (36) hide show
  1. {aiida_chemshell-0.2.2/src/aiida_chemshell.egg-info → aiida_chemshell-0.3.0}/PKG-INFO +34 -33
  2. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/README.md +32 -32
  3. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/pyproject.toml +13 -1
  4. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell/workflows/batch_calculation.py +153 -1
  5. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell/workflows/isolated_atoms.py +1 -1
  6. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0/src/aiida_chemshell.egg-info}/PKG-INFO +34 -33
  7. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell.egg-info/requires.txt +1 -0
  8. aiida_chemshell-0.3.0/tests/test_batch_workcahin.py +234 -0
  9. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/tests/test_calculations.py +22 -45
  10. aiida_chemshell-0.3.0/tests/test_isolated_atoms_workchain.py +69 -0
  11. aiida_chemshell-0.3.0/tests/test_workflows.py +37 -0
  12. aiida_chemshell-0.2.2/tests/test_batch_workcahin.py +0 -175
  13. aiida_chemshell-0.2.2/tests/test_isolated_atoms_workchain.py +0 -27
  14. aiida_chemshell-0.2.2/tests/test_workflows.py +0 -95
  15. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/LICENSE +0 -0
  16. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/setup.cfg +0 -0
  17. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell/__init__.py +0 -0
  18. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell/calculations/__init__.py +0 -0
  19. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell/calculations/base.py +0 -0
  20. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell/calculations/file_conversion.py +0 -0
  21. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell/calculations/solvant_removal.py +0 -0
  22. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell/calculations/utils.py +0 -0
  23. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell/parsers/__init__.py +0 -0
  24. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell/parsers/base.py +0 -0
  25. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell/parsers/file_conversion.py +0 -0
  26. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell/periodic_table.py +0 -0
  27. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell/units.py +0 -0
  28. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell/utils.py +0 -0
  29. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell/workflows/__init__.py +0 -0
  30. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell/workflows/optimisation.py +0 -0
  31. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell.egg-info/SOURCES.txt +0 -0
  32. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell.egg-info/dependency_links.txt +0 -0
  33. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell.egg-info/entry_points.txt +0 -0
  34. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/src/aiida_chemshell.egg-info/top_level.txt +0 -0
  35. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/tests/test_error_codes.py +0 -0
  36. {aiida_chemshell-0.2.2 → aiida_chemshell-0.3.0}/tests/test_inputs.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiida-chemshell
3
- Version: 0.2.2
3
+ Version: 0.3.0
4
4
  Summary: AiiDA workflow plugin for the ChemShell chemical modelling software package
5
5
  Author-email: "Dr. Benjamin T. Speake" <benjamin.speake@stfc.ac.uk>
6
6
  License: BSD 3-Clause License
@@ -46,6 +46,7 @@ Provides-Extra: dev
46
46
  Requires-Dist: aiida-core>=2.8; extra == "dev"
47
47
  Requires-Dist: pytest>=8.0; extra == "dev"
48
48
  Requires-Dist: pytest-cov>=6.0; extra == "dev"
49
+ Requires-Dist: pytest-xdist>=3.0; extra == "dev"
49
50
  Requires-Dist: ruff>=0.11.0; extra == "dev"
50
51
  Requires-Dist: pre-commit; extra == "dev"
51
52
  Provides-Extra: docs
@@ -64,30 +65,28 @@ Dynamic: license-file
64
65
 
65
66
  [![DOI](https://img.shields.io/badge/DOI-10.5281%2Fzenodo.18392782-blue.svg)](https://doi.org/10.5281/zenodo.18392782)
66
67
 
67
-
68
68
  # AiiDA ChemShell
69
69
 
70
- An [AiiDA](https://www.aiida.net) plugin for the [ChemShell](https://chemshell.org/) multiscale
71
- computational chemistry software package.
70
+ An [AiiDA](https://www.aiida.net) plugin for the [ChemShell](https://chemshell.org/) multiscale
71
+ computational chemistry software package.
72
72
 
73
- ## Installation
73
+ ## Installation
74
74
 
75
- This plugin is available through PyPI and should be installed using [`pip`](https://pip.pypa.io/en/stable/) python package manager.
75
+ This plugin is available through PyPI and should be installed using [`pip`](https://pip.pypa.io/en/stable/) python package manager.
76
76
 
77
- ```
77
+ ``` bash
78
78
  pip install aiida-chemshell
79
79
  ```
80
80
 
81
- ## Requirements
82
-
83
- To use this plugin a configured AiiDA profile and computer configuration are required, see the
84
- [AiiDa documentation](https://aiida.readthedocs.io/projects/aiida-core/en/latest/intro/get_started.html)
85
- for instructions on how to install and configure AiiDA.
81
+ ## Requirements
86
82
 
83
+ To use this plugin a configured AiiDA profile and computer configuration are required, see the
84
+ [AiiDa documentation](https://aiida.readthedocs.io/projects/aiida-core/en/latest/intro/get_started.html)
85
+ for instructions on how to install and configure AiiDA.
87
86
 
88
- ## Setup
87
+ ## Setup
89
88
 
90
- To configure the ChemShell plugin an AiiDA code instance needs to be configured for the ChemShell executable.
89
+ To configure the ChemShell plugin an AiiDA code instance needs to be configured for the ChemShell executable.
91
90
  The following is an example of a basic YAML configuration file:
92
91
 
93
92
  ```yaml
@@ -109,30 +108,31 @@ step. The code can then be configured by running:
109
108
  verdi code create core.code.installed --config chemshell.yml -n
110
109
  ```
111
110
 
112
- If successful this will have created a code with the label `chemsh` which can then be used to run ChemShell jobs within the AiiDA workflow.
111
+ If successful this will have created a code with the label `chemsh` which can then be used to run ChemShell jobs within the AiiDA workflow.
113
112
 
114
113
  ### ChemShell with MPI
115
114
 
116
- It is important to note that the configuration of an MPI enabled ChemShell code differs slightly depending on whether the code instance uses
115
+ It is important to note that the configuration of an MPI enabled ChemShell code differs slightly depending on whether the code instance uses
117
116
  the `chemsh` or `chemsh.x` executable. If you have a parallel (MPI enabled) build of ChemShell but are using the `chemsh` wrapper executable
118
117
  please set `with_mpi: false` as the underlying plugin will handle how to call the mpi runtime. If you are calling the `chemsh.x` executable
119
- directly then `with_mpi: true` is required to run parallel jobs.
118
+ directly then `with_mpi: true` is required to run parallel jobs.
120
119
 
121
- ## Examples
120
+ ## Examples
122
121
 
123
- ### QM Based Single Point Energy
122
+ ### QM Based Single Point Energy
124
123
 
125
- The following is a python script that will run a Quantum Mechanics based single point energy calculation using the NWChem ChemShell interface.
126
- The associated structure file can be found in the `tests/data/` folder.
124
+ The following is a python script that will run a Quantum Mechanics based single point energy calculation using the NWChem ChemShell interface.
125
+ The associated structure file can be found in the `tests/data/` folder.
127
126
 
128
- ```python
129
- from aiida.engine import run
127
+ ```python
128
+ from aiida.engine import run
130
129
  from aiida.orm import load_code, SinglefileData, Dict
131
- from aiida import load_profile
130
+ from aiida import load_profile
132
131
 
133
- load_profile("user_profile") # This is not required if running in a verdi shell environment
132
+ # This is not required if running in a verdi shell environment
133
+ load_profile("user_profile")
134
134
 
135
- builder = load_code("chemsh").get_builder()
135
+ builder = load_code("chemsh").get_builder()
136
136
  builder.structure = SinglefileData(file="/absolute/path/to/water.cjson")
137
137
  builder.qm_parameters = Dict({"theory": "NWChem", "method": "HF", "basis": "3-21G"})
138
138
  builder.calculation_parameters = Dict({"gradients": False, "hessian": False})
@@ -142,19 +142,20 @@ results, node = run.get_node(builder)
142
142
  print("Final Energy = ", results.get("energy"))
143
143
  ```
144
144
 
145
- This can either be run as a script or as directly within a verdi shell python environment.
145
+ This can either be run as a script or as directly within a verdi shell python environment.
146
146
 
147
- ### QM/MM Based Geometry Optimisation
147
+ ### QM/MM Based Geometry Optimisation
148
148
 
149
149
  The following is a python script that will run a combined QM/MM based geometry optimisation using the NWChem and DL_POLY ChemShell interfaces.
150
- The associated structure and force field files can be found in the `tests/data/` folder.
150
+ The associated structure and force field files can be found in the `tests/data/` folder.
151
151
 
152
- ```python
153
- from aiida.engine import run
152
+ ```python
153
+ from aiida.engine import run
154
154
  from aiida.orm import load_code, SinglefileData, Dict
155
- from aiida import load_profile
155
+ from aiida import load_profile
156
156
 
157
- load_profile("user_profile") # This is not required if running in a verdi shell environment
157
+ # This is not required if running in a verdi shell environment
158
+ load_profile("user_profile")
158
159
 
159
160
  builder = load_code("chemsh").get_builder()
160
161
  builder.structure = SinglefileData(file="/absolute/path/to/h2o_dimer.cjson")
@@ -7,30 +7,28 @@
7
7
 
8
8
  [![DOI](https://img.shields.io/badge/DOI-10.5281%2Fzenodo.18392782-blue.svg)](https://doi.org/10.5281/zenodo.18392782)
9
9
 
10
-
11
10
  # AiiDA ChemShell
12
11
 
13
- An [AiiDA](https://www.aiida.net) plugin for the [ChemShell](https://chemshell.org/) multiscale
14
- computational chemistry software package.
12
+ An [AiiDA](https://www.aiida.net) plugin for the [ChemShell](https://chemshell.org/) multiscale
13
+ computational chemistry software package.
15
14
 
16
- ## Installation
15
+ ## Installation
17
16
 
18
- This plugin is available through PyPI and should be installed using [`pip`](https://pip.pypa.io/en/stable/) python package manager.
17
+ This plugin is available through PyPI and should be installed using [`pip`](https://pip.pypa.io/en/stable/) python package manager.
19
18
 
20
- ```
19
+ ``` bash
21
20
  pip install aiida-chemshell
22
21
  ```
23
22
 
24
- ## Requirements
25
-
26
- To use this plugin a configured AiiDA profile and computer configuration are required, see the
27
- [AiiDa documentation](https://aiida.readthedocs.io/projects/aiida-core/en/latest/intro/get_started.html)
28
- for instructions on how to install and configure AiiDA.
23
+ ## Requirements
29
24
 
25
+ To use this plugin a configured AiiDA profile and computer configuration are required, see the
26
+ [AiiDa documentation](https://aiida.readthedocs.io/projects/aiida-core/en/latest/intro/get_started.html)
27
+ for instructions on how to install and configure AiiDA.
30
28
 
31
- ## Setup
29
+ ## Setup
32
30
 
33
- To configure the ChemShell plugin an AiiDA code instance needs to be configured for the ChemShell executable.
31
+ To configure the ChemShell plugin an AiiDA code instance needs to be configured for the ChemShell executable.
34
32
  The following is an example of a basic YAML configuration file:
35
33
 
36
34
  ```yaml
@@ -52,30 +50,31 @@ step. The code can then be configured by running:
52
50
  verdi code create core.code.installed --config chemshell.yml -n
53
51
  ```
54
52
 
55
- If successful this will have created a code with the label `chemsh` which can then be used to run ChemShell jobs within the AiiDA workflow.
53
+ If successful this will have created a code with the label `chemsh` which can then be used to run ChemShell jobs within the AiiDA workflow.
56
54
 
57
55
  ### ChemShell with MPI
58
56
 
59
- It is important to note that the configuration of an MPI enabled ChemShell code differs slightly depending on whether the code instance uses
57
+ It is important to note that the configuration of an MPI enabled ChemShell code differs slightly depending on whether the code instance uses
60
58
  the `chemsh` or `chemsh.x` executable. If you have a parallel (MPI enabled) build of ChemShell but are using the `chemsh` wrapper executable
61
59
  please set `with_mpi: false` as the underlying plugin will handle how to call the mpi runtime. If you are calling the `chemsh.x` executable
62
- directly then `with_mpi: true` is required to run parallel jobs.
60
+ directly then `with_mpi: true` is required to run parallel jobs.
63
61
 
64
- ## Examples
62
+ ## Examples
65
63
 
66
- ### QM Based Single Point Energy
64
+ ### QM Based Single Point Energy
67
65
 
68
- The following is a python script that will run a Quantum Mechanics based single point energy calculation using the NWChem ChemShell interface.
69
- The associated structure file can be found in the `tests/data/` folder.
66
+ The following is a python script that will run a Quantum Mechanics based single point energy calculation using the NWChem ChemShell interface.
67
+ The associated structure file can be found in the `tests/data/` folder.
70
68
 
71
- ```python
72
- from aiida.engine import run
69
+ ```python
70
+ from aiida.engine import run
73
71
  from aiida.orm import load_code, SinglefileData, Dict
74
- from aiida import load_profile
72
+ from aiida import load_profile
75
73
 
76
- load_profile("user_profile") # This is not required if running in a verdi shell environment
74
+ # This is not required if running in a verdi shell environment
75
+ load_profile("user_profile")
77
76
 
78
- builder = load_code("chemsh").get_builder()
77
+ builder = load_code("chemsh").get_builder()
79
78
  builder.structure = SinglefileData(file="/absolute/path/to/water.cjson")
80
79
  builder.qm_parameters = Dict({"theory": "NWChem", "method": "HF", "basis": "3-21G"})
81
80
  builder.calculation_parameters = Dict({"gradients": False, "hessian": False})
@@ -85,19 +84,20 @@ results, node = run.get_node(builder)
85
84
  print("Final Energy = ", results.get("energy"))
86
85
  ```
87
86
 
88
- This can either be run as a script or as directly within a verdi shell python environment.
87
+ This can either be run as a script or as directly within a verdi shell python environment.
89
88
 
90
- ### QM/MM Based Geometry Optimisation
89
+ ### QM/MM Based Geometry Optimisation
91
90
 
92
91
  The following is a python script that will run a combined QM/MM based geometry optimisation using the NWChem and DL_POLY ChemShell interfaces.
93
- The associated structure and force field files can be found in the `tests/data/` folder.
92
+ The associated structure and force field files can be found in the `tests/data/` folder.
94
93
 
95
- ```python
96
- from aiida.engine import run
94
+ ```python
95
+ from aiida.engine import run
97
96
  from aiida.orm import load_code, SinglefileData, Dict
98
- from aiida import load_profile
97
+ from aiida import load_profile
99
98
 
100
- load_profile("user_profile") # This is not required if running in a verdi shell environment
99
+ # This is not required if running in a verdi shell environment
100
+ load_profile("user_profile")
101
101
 
102
102
  builder = load_code("chemsh").get_builder()
103
103
  builder.structure = SinglefileData(file="/absolute/path/to/h2o_dimer.cjson")
@@ -3,7 +3,7 @@ requires = ["setuptools"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
- version = "0.2.2"
6
+ version = "0.3.0"
7
7
  name = "aiida-chemshell"
8
8
  description = "AiiDA workflow plugin for the ChemShell chemical modelling software package"
9
9
  authors = [
@@ -46,11 +46,23 @@ dev = [
46
46
  "aiida-core>=2.8",
47
47
  "pytest>=8.0",
48
48
  "pytest-cov>=6.0",
49
+ "pytest-xdist>=3.0",
49
50
  "ruff>=0.11.0",
50
51
  "pre-commit",
51
52
  ]
52
53
  docs = ["sphinx>=8.0.2", "piccolo-theme>=0.14.0", "sphinx-toolbox", "numpydoc"]
53
54
 
55
+ [tool.pytest.ini_options]
56
+ filterwarnings = [
57
+ # Third-party warnings we cannot act on and that only add noise:
58
+ # plumpy still calls the deprecated asyncio.get_event_loop().
59
+ "ignore:There is no current event loop:DeprecationWarning",
60
+ # AiiDA's SQLAlchemy storage backend emits autoflush session warnings.
61
+ "ignore::sqlalchemy.exc.SAWarning",
62
+ # AiiDA reports creating its config folder inside the temp test profile.
63
+ "ignore:Creating AiiDA configuration folder:UserWarning",
64
+ ]
65
+
54
66
  [tool.ruff]
55
67
  target-version = "py310"
56
68
  line-length = 88
@@ -1,9 +1,17 @@
1
1
  """Workflow for processing a series of structures from a single input."""
2
2
 
3
3
  import re
4
+ from io import BytesIO
4
5
 
5
6
  from aiida.engine import ProcessSpec, ToContext, WorkChain, calcfunction
6
- from aiida.orm import ProcessNode, SinglefileData, StructureData, TrajectoryData
7
+ from aiida.orm import (
8
+ ArrayData,
9
+ Float,
10
+ ProcessNode,
11
+ SinglefileData,
12
+ StructureData,
13
+ TrajectoryData,
14
+ )
7
15
  from aiida.plugins.factories import CalculationFactory
8
16
 
9
17
  ChemShellCalculation = CalculationFactory("chemshell")
@@ -49,6 +57,30 @@ class BatchProcessWorkChain(WorkChain):
49
57
  ),
50
58
  )
51
59
 
60
+ # Results combination key
61
+ spec.input(
62
+ "combine_results",
63
+ valid_type=bool,
64
+ required=False,
65
+ non_db=True,
66
+ help=(
67
+ "A key which tells the workchain to combine all the results from the "
68
+ "individual batch processing tasks into one final results object which "
69
+ 'is an extended xyz file (key="xyz").'
70
+ ),
71
+ # validator=cls.validate_combination_input_key,
72
+ )
73
+ # Results combination output node
74
+ spec.output(
75
+ "combined_results",
76
+ valid_type=SinglefileData,
77
+ required=False,
78
+ help=(
79
+ "An extended XYZ file with all the ChemShell results from the batch "
80
+ "processed input structures."
81
+ ),
82
+ )
83
+
52
84
  spec.exit_code(
53
85
  350,
54
86
  "ERROR_NO_INPUTS",
@@ -65,6 +97,16 @@ class BatchProcessWorkChain(WorkChain):
65
97
  cls.collate_results,
66
98
  )
67
99
 
100
+ # @classmethod
101
+ # def validate_combination_input_key(cls, key: str | None, _) -> str | None:
102
+ # """Validate the combine_results input key."""
103
+ # if key in ["xyz", "trajectory"]:
104
+ # return None
105
+ # return (
106
+ # f"Invalid input for 'combine_results'. {key} must be either 'xyz' or "
107
+ # "'trajectory'"
108
+ # )
109
+
68
110
  def validate_inputs(self):
69
111
  """Validate the inputs provided to the WorkChain."""
70
112
  has_trajectory = "trajectory" in self.inputs
@@ -130,6 +172,46 @@ class BatchProcessWorkChain(WorkChain):
130
172
 
131
173
  def collate_results(self) -> None:
132
174
  """Collect the WorkChain's results."""
175
+ if self.inputs.get("combine_results", None):
176
+ if "optimisation_parameters" in self.inputs:
177
+ self.logger.warning(
178
+ "Output combination is not currently supported for optimisation "
179
+ "jobs."
180
+ )
181
+ return
182
+ inputs = {}
183
+ include_forces = self.inputs.get("calculation_parameters", {}).get(
184
+ "gradients", False
185
+ )
186
+ if "trajectory" in self.inputs:
187
+ inputs["structure_trajectory"] = self.inputs.trajectory
188
+ for i in range(self.inputs.trajectory.numsteps):
189
+ inputs[f"energy_trajectory_frame_{i}"] = self.ctx[
190
+ f"trajectory_frame_{i}"
191
+ ].outputs.energy
192
+ if include_forces:
193
+ inputs[f"array_trajectory_frame_{i}"] = self.ctx[
194
+ f"trajectory_frame_{i}"
195
+ ].outputs.gradients
196
+ if "structures" in self.inputs:
197
+ for key, structure in self.inputs.structures.items():
198
+ inputs[f"structure_{key}"] = structure
199
+ inputs[f"energy_{key}"] = self.ctx[key].outputs.energy
200
+ if include_forces:
201
+ inputs[f"array_{key}"] = self.ctx[key].outputs.gradients
202
+ if "structure_files" in self.inputs:
203
+ for key, structure in self.structures_from_files.items():
204
+ inputs[f"structure_{key}"] = structure
205
+ inputs[f"energy_{key}"] = self.ctx[key].outputs.energy
206
+ if include_forces:
207
+ inputs[f"array_{key}"] = self.ctx[key].outputs.gradients
208
+ combined_output_node = combine_into_extended_xyz(**inputs)
209
+ combined_output_node.label = "ChemShell Batch Processed Structures"
210
+ combined_output_node.description = (
211
+ "Collection of structures processed by ChemShell from WorkChain: "
212
+ f" {self.node.pk}"
213
+ )
214
+ self.out("combined_results", combined_output_node)
133
215
  return
134
216
 
135
217
 
@@ -203,3 +285,73 @@ def extract_structures_from_xyz(file: SinglefileData):
203
285
  i += natoms
204
286
 
205
287
  return structures
288
+
289
+
290
+ @calcfunction
291
+ def combine_into_extended_xyz(**kwargs) -> SinglefileData:
292
+ """Combine a set of batch results into a single extxyz file."""
293
+ structures: list[StructureData] = []
294
+ energies: list[Float] = []
295
+ arrays: list[ArrayData] = []
296
+
297
+ # Extract individual structures and SP calculation results.
298
+ for _key, node in kwargs.items():
299
+ if isinstance(node, TrajectoryData):
300
+ for tindex in range(node.numsteps):
301
+ structures.append(node.get_step_structure(tindex))
302
+ elif isinstance(node, StructureData):
303
+ structures.append(node)
304
+ elif isinstance(node, Float):
305
+ energies.append(node)
306
+ elif isinstance(node, ArrayData): # Ensure after TrajectoryData !!
307
+ arrays.append(node)
308
+ else:
309
+ raise ValueError(
310
+ f"Invalid input of type {node} to 'combine_into_extended_xyz' "
311
+ "calcfunction."
312
+ )
313
+ if not structures:
314
+ raise ValueError("No StructureData nodes were provided.")
315
+ if len(structures) != len(energies):
316
+ raise ValueError(
317
+ f"Mismatched input lengths: received {len(structures)} structures and "
318
+ f"{len(energies)} energies."
319
+ )
320
+ if arrays:
321
+ if len(arrays) != len(energies):
322
+ raise ValueError(
323
+ f"Mismatched input lengths: received {len(arrays)} arrays and "
324
+ f"{len(energies)} energies."
325
+ )
326
+
327
+ xyz_lines = []
328
+
329
+ for i in range(len(structures)):
330
+ structure = structures[i]
331
+ energy = energies[i]
332
+
333
+ xyz_lines.append(str(len(structure.sites)))
334
+
335
+ header_line = f"Energy={energy.value}"
336
+ if arrays:
337
+ forces = arrays[i].get_array("gradients")
338
+ header_line += " Properties=species:S:1:pos:R:3:force:R:3"
339
+ else:
340
+ forces = None
341
+ header_line += " Properties=species:S:1:pos:R:3"
342
+ xyz_lines.append(header_line)
343
+
344
+ for j, site in enumerate(structure.sites):
345
+ kind = structure.get_kind(site.kind_name)
346
+ symbol = kind.symbols[0]
347
+ x, y, z = site.position
348
+ site_line = f"{symbol:<4} {x:15.8f} {y:15.8f} {z:15.8f}"
349
+ if forces is not None:
350
+ fx, fy, fz = forces[j]
351
+ site_line += f" {fx:15.8f} {fy:15.8f} {fz:15.8f}"
352
+ xyz_lines.append(site_line)
353
+
354
+ content = "\n".join(xyz_lines)
355
+ stream = BytesIO(content.encode("utf-8"))
356
+
357
+ return SinglefileData(file=stream, filename="chemshell_batch_workchain.extxyz")
@@ -22,7 +22,7 @@ class IsolatedAtomicEnergiesWorkChain(WorkChain):
22
22
  ChemShellCalculation, include=("structure", "qm_parameters", "code")
23
23
  )
24
24
  spec.expose_inputs(
25
- ChemShellCalculation, include=("metadata"), namespace="chemsh"
25
+ ChemShellCalculation, include=("metadata",), namespace="chemsh"
26
26
  )
27
27
 
28
28
  spec.output(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiida-chemshell
3
- Version: 0.2.2
3
+ Version: 0.3.0
4
4
  Summary: AiiDA workflow plugin for the ChemShell chemical modelling software package
5
5
  Author-email: "Dr. Benjamin T. Speake" <benjamin.speake@stfc.ac.uk>
6
6
  License: BSD 3-Clause License
@@ -46,6 +46,7 @@ Provides-Extra: dev
46
46
  Requires-Dist: aiida-core>=2.8; extra == "dev"
47
47
  Requires-Dist: pytest>=8.0; extra == "dev"
48
48
  Requires-Dist: pytest-cov>=6.0; extra == "dev"
49
+ Requires-Dist: pytest-xdist>=3.0; extra == "dev"
49
50
  Requires-Dist: ruff>=0.11.0; extra == "dev"
50
51
  Requires-Dist: pre-commit; extra == "dev"
51
52
  Provides-Extra: docs
@@ -64,30 +65,28 @@ Dynamic: license-file
64
65
 
65
66
  [![DOI](https://img.shields.io/badge/DOI-10.5281%2Fzenodo.18392782-blue.svg)](https://doi.org/10.5281/zenodo.18392782)
66
67
 
67
-
68
68
  # AiiDA ChemShell
69
69
 
70
- An [AiiDA](https://www.aiida.net) plugin for the [ChemShell](https://chemshell.org/) multiscale
71
- computational chemistry software package.
70
+ An [AiiDA](https://www.aiida.net) plugin for the [ChemShell](https://chemshell.org/) multiscale
71
+ computational chemistry software package.
72
72
 
73
- ## Installation
73
+ ## Installation
74
74
 
75
- This plugin is available through PyPI and should be installed using [`pip`](https://pip.pypa.io/en/stable/) python package manager.
75
+ This plugin is available through PyPI and should be installed using [`pip`](https://pip.pypa.io/en/stable/) python package manager.
76
76
 
77
- ```
77
+ ``` bash
78
78
  pip install aiida-chemshell
79
79
  ```
80
80
 
81
- ## Requirements
82
-
83
- To use this plugin a configured AiiDA profile and computer configuration are required, see the
84
- [AiiDa documentation](https://aiida.readthedocs.io/projects/aiida-core/en/latest/intro/get_started.html)
85
- for instructions on how to install and configure AiiDA.
81
+ ## Requirements
86
82
 
83
+ To use this plugin a configured AiiDA profile and computer configuration are required, see the
84
+ [AiiDa documentation](https://aiida.readthedocs.io/projects/aiida-core/en/latest/intro/get_started.html)
85
+ for instructions on how to install and configure AiiDA.
87
86
 
88
- ## Setup
87
+ ## Setup
89
88
 
90
- To configure the ChemShell plugin an AiiDA code instance needs to be configured for the ChemShell executable.
89
+ To configure the ChemShell plugin an AiiDA code instance needs to be configured for the ChemShell executable.
91
90
  The following is an example of a basic YAML configuration file:
92
91
 
93
92
  ```yaml
@@ -109,30 +108,31 @@ step. The code can then be configured by running:
109
108
  verdi code create core.code.installed --config chemshell.yml -n
110
109
  ```
111
110
 
112
- If successful this will have created a code with the label `chemsh` which can then be used to run ChemShell jobs within the AiiDA workflow.
111
+ If successful this will have created a code with the label `chemsh` which can then be used to run ChemShell jobs within the AiiDA workflow.
113
112
 
114
113
  ### ChemShell with MPI
115
114
 
116
- It is important to note that the configuration of an MPI enabled ChemShell code differs slightly depending on whether the code instance uses
115
+ It is important to note that the configuration of an MPI enabled ChemShell code differs slightly depending on whether the code instance uses
117
116
  the `chemsh` or `chemsh.x` executable. If you have a parallel (MPI enabled) build of ChemShell but are using the `chemsh` wrapper executable
118
117
  please set `with_mpi: false` as the underlying plugin will handle how to call the mpi runtime. If you are calling the `chemsh.x` executable
119
- directly then `with_mpi: true` is required to run parallel jobs.
118
+ directly then `with_mpi: true` is required to run parallel jobs.
120
119
 
121
- ## Examples
120
+ ## Examples
122
121
 
123
- ### QM Based Single Point Energy
122
+ ### QM Based Single Point Energy
124
123
 
125
- The following is a python script that will run a Quantum Mechanics based single point energy calculation using the NWChem ChemShell interface.
126
- The associated structure file can be found in the `tests/data/` folder.
124
+ The following is a python script that will run a Quantum Mechanics based single point energy calculation using the NWChem ChemShell interface.
125
+ The associated structure file can be found in the `tests/data/` folder.
127
126
 
128
- ```python
129
- from aiida.engine import run
127
+ ```python
128
+ from aiida.engine import run
130
129
  from aiida.orm import load_code, SinglefileData, Dict
131
- from aiida import load_profile
130
+ from aiida import load_profile
132
131
 
133
- load_profile("user_profile") # This is not required if running in a verdi shell environment
132
+ # This is not required if running in a verdi shell environment
133
+ load_profile("user_profile")
134
134
 
135
- builder = load_code("chemsh").get_builder()
135
+ builder = load_code("chemsh").get_builder()
136
136
  builder.structure = SinglefileData(file="/absolute/path/to/water.cjson")
137
137
  builder.qm_parameters = Dict({"theory": "NWChem", "method": "HF", "basis": "3-21G"})
138
138
  builder.calculation_parameters = Dict({"gradients": False, "hessian": False})
@@ -142,19 +142,20 @@ results, node = run.get_node(builder)
142
142
  print("Final Energy = ", results.get("energy"))
143
143
  ```
144
144
 
145
- This can either be run as a script or as directly within a verdi shell python environment.
145
+ This can either be run as a script or as directly within a verdi shell python environment.
146
146
 
147
- ### QM/MM Based Geometry Optimisation
147
+ ### QM/MM Based Geometry Optimisation
148
148
 
149
149
  The following is a python script that will run a combined QM/MM based geometry optimisation using the NWChem and DL_POLY ChemShell interfaces.
150
- The associated structure and force field files can be found in the `tests/data/` folder.
150
+ The associated structure and force field files can be found in the `tests/data/` folder.
151
151
 
152
- ```python
153
- from aiida.engine import run
152
+ ```python
153
+ from aiida.engine import run
154
154
  from aiida.orm import load_code, SinglefileData, Dict
155
- from aiida import load_profile
155
+ from aiida import load_profile
156
156
 
157
- load_profile("user_profile") # This is not required if running in a verdi shell environment
157
+ # This is not required if running in a verdi shell environment
158
+ load_profile("user_profile")
158
159
 
159
160
  builder = load_code("chemsh").get_builder()
160
161
  builder.structure = SinglefileData(file="/absolute/path/to/h2o_dimer.cjson")
@@ -4,6 +4,7 @@ aiida-core>=2.5
4
4
  aiida-core>=2.8
5
5
  pytest>=8.0
6
6
  pytest-cov>=6.0
7
+ pytest-xdist>=3.0
7
8
  ruff>=0.11.0
8
9
  pre-commit
9
10