structuretoolkit 0.0.29__tar.gz → 0.0.32__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 (58) hide show
  1. {structuretoolkit-0.0.29/structuretoolkit.egg-info → structuretoolkit-0.0.32}/PKG-INFO +17 -16
  2. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/README.md +2 -2
  3. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/pyproject.toml +59 -12
  4. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/__init__.py +58 -0
  5. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/_version.py +3 -3
  6. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/__init__.py +36 -0
  7. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/dscribe.py +3 -1
  8. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/neighbors.py +37 -37
  9. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/phonopy.py +1 -3
  10. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/pyscal.py +3 -4
  11. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/snap.py +17 -19
  12. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/spatial.py +6 -3
  13. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/strain.py +2 -2
  14. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/symmetry.py +0 -2
  15. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/build/__init__.py +15 -0
  16. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/build/aimsgb.py +1 -2
  17. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/build/mesh.py +5 -8
  18. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/build/random.py +12 -9
  19. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/build/sqs.py +38 -47
  20. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/common/__init__.py +17 -0
  21. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/common/helper.py +1 -5
  22. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/visualize.py +36 -31
  23. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32/structuretoolkit.egg-info}/PKG-INFO +17 -16
  24. structuretoolkit-0.0.32/structuretoolkit.egg-info/requires.txt +39 -0
  25. structuretoolkit-0.0.29/structuretoolkit.egg-info/requires.txt +0 -39
  26. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/LICENSE +0 -0
  27. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/MANIFEST.in +0 -0
  28. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/setup.cfg +0 -0
  29. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/setup.py +0 -0
  30. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/distance.py +0 -0
  31. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/build/compound.py +0 -0
  32. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/build/surface.py +0 -0
  33. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/common/error.py +0 -0
  34. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/common/phonopy.py +0 -0
  35. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/common/pymatgen.py +0 -0
  36. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/common/pyscal.py +0 -0
  37. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit.egg-info/SOURCES.txt +0 -0
  38. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit.egg-info/dependency_links.txt +0 -0
  39. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit.egg-info/top_level.txt +0 -0
  40. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_aimsgb.py +0 -0
  41. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_analyse.py +0 -0
  42. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_analyse_distance.py +0 -0
  43. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_analyse_phonopy.py +0 -0
  44. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_analyse_symmetry.py +0 -0
  45. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_compound.py +0 -0
  46. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_dscribe.py +0 -0
  47. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_helpers.py +0 -0
  48. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_high_index_surface.py +0 -0
  49. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_mesh.py +0 -0
  50. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_neighbors.py +0 -0
  51. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_pymatgen.py +0 -0
  52. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_pyscal.py +0 -0
  53. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_pyxtal.py +0 -0
  54. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_snap.py +0 -0
  55. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_sqs.py +0 -0
  56. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_strain.py +0 -0
  57. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_symmetry.py +0 -0
  58. {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_visualize.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: structuretoolkit
3
- Version: 0.0.29
3
+ Version: 0.0.32
4
4
  Summary: build, analyse and visualise atomistic structures for materials science
5
5
  Author-email: Jan Janssen <janssen@mpie.de>
6
6
  License: BSD 3-Clause License
@@ -49,39 +49,40 @@ Classifier: Programming Language :: Python :: 3.12
49
49
  Requires-Python: <3.13,>=3.9
50
50
  Description-Content-Type: text/markdown
51
51
  License-File: LICENSE
52
- Requires-Dist: ase<=3.24.0,>=3.20.1
52
+ Requires-Dist: ase<=3.25.0,>=3.20.1
53
53
  Requires-Dist: numpy<=1.26.4,>=1.23.5
54
- Requires-Dist: scipy<=1.15.0,>=1.9.3
54
+ Requires-Dist: scipy<=1.15.2,>=1.9.3
55
55
  Provides-Extra: dscribe
56
56
  Requires-Dist: dscribe==2.1.1; extra == "dscribe"
57
57
  Provides-Extra: grainboundary
58
58
  Requires-Dist: aimsgb<=1.1.1,>=1.0.2; extra == "grainboundary"
59
- Requires-Dist: pymatgen<=2024.11.13,>=2022.2.1; extra == "grainboundary"
59
+ Requires-Dist: pymatgen<=2025.3.10,>=2022.2.1; extra == "grainboundary"
60
60
  Provides-Extra: pyscal
61
61
  Requires-Dist: pyscal3<=3.2.7,>=3.2.5; extra == "pyscal"
62
62
  Provides-Extra: nglview
63
63
  Requires-Dist: nglview<=3.1.4,>=2.7.7; extra == "nglview"
64
64
  Provides-Extra: matplotlib
65
- Requires-Dist: matplotlib==3.10.0; extra == "matplotlib"
65
+ Requires-Dist: matplotlib==3.10.1; extra == "matplotlib"
66
66
  Provides-Extra: plotly
67
- Requires-Dist: plotly<=5.24.1,>=4.14.3; extra == "plotly"
67
+ Requires-Dist: plotly<=6.0.1,>=4.14.3; extra == "plotly"
68
68
  Provides-Extra: clusters
69
- Requires-Dist: scikit-learn==1.6.0; extra == "clusters"
69
+ Requires-Dist: scikit-learn==1.6.1; extra == "clusters"
70
70
  Provides-Extra: symmetry
71
- Requires-Dist: spglib<=2.5.0,>=1.16.5; extra == "symmetry"
71
+ Requires-Dist: spglib<=2.6.0,>=1.16.5; extra == "symmetry"
72
72
  Provides-Extra: surface
73
- Requires-Dist: spglib<=2.5.0,>=1.16.5; extra == "surface"
74
- Requires-Dist: pymatgen<=2024.11.13,>=2022.2.1; extra == "surface"
73
+ Requires-Dist: spglib<=2.6.0,>=1.16.5; extra == "surface"
74
+ Requires-Dist: pymatgen<=2025.3.10,>=2022.2.1; extra == "surface"
75
75
  Provides-Extra: phonopy
76
- Requires-Dist: phonopy<=2.34.0,>=2.16.2; extra == "phonopy"
77
- Requires-Dist: spglib<=2.5.0,>=1.16.5; extra == "phonopy"
76
+ Requires-Dist: phonopy<=2.38.0,>=2.16.2; extra == "phonopy"
77
+ Requires-Dist: spglib<=2.6.0,>=1.16.5; extra == "phonopy"
78
78
  Provides-Extra: pyxtal
79
- Requires-Dist: pyxtal<=1.0.6,>=0.5.5; extra == "pyxtal"
79
+ Requires-Dist: pyxtal<=1.0.7,>=0.5.5; extra == "pyxtal"
80
+ Dynamic: license-file
80
81
 
81
82
  # structuretoolkit
82
83
 
83
- [![Unittests](https://github.com/pyiron/structuretoolkit/actions/workflows/unittests.yml/badge.svg)](https://github.com/pyiron/structuretoolkit/actions/workflows/unittests.yml)
84
- [![Coverage Status](https://coveralls.io/repos/github/pyiron/structuretoolkit/badge.svg?branch=main)](https://coveralls.io/github/pyiron/structuretoolkit?branch=main)
84
+ [![Pipeline](https://github.com/pyiron/structuretoolkit/actions/workflows/pipeline.yml/badge.svg)](https://github.com/pyiron/structuretoolkit/actions/workflows/pipeline.yml)
85
+ [![codecov](https://codecov.io/gh/pyiron/structuretoolkit/graph/badge.svg?token=B6I4OACKND)](https://codecov.io/gh/pyiron/structuretoolkit)
85
86
 
86
87
  Originally developed as part of the `pyiron_atomistics` module the `structuretoolkit` was release as standalone library
87
88
  for analysing, building and visualising atomistic structures. Internally it uses the `ase.atoms.Atoms` class to
@@ -1,7 +1,7 @@
1
1
  # structuretoolkit
2
2
 
3
- [![Unittests](https://github.com/pyiron/structuretoolkit/actions/workflows/unittests.yml/badge.svg)](https://github.com/pyiron/structuretoolkit/actions/workflows/unittests.yml)
4
- [![Coverage Status](https://coveralls.io/repos/github/pyiron/structuretoolkit/badge.svg?branch=main)](https://coveralls.io/github/pyiron/structuretoolkit?branch=main)
3
+ [![Pipeline](https://github.com/pyiron/structuretoolkit/actions/workflows/pipeline.yml/badge.svg)](https://github.com/pyiron/structuretoolkit/actions/workflows/pipeline.yml)
4
+ [![codecov](https://codecov.io/gh/pyiron/structuretoolkit/graph/badge.svg?token=B6I4OACKND)](https://codecov.io/gh/pyiron/structuretoolkit)
5
5
 
6
6
  Originally developed as part of the `pyiron_atomistics` module the `structuretoolkit` was release as standalone library
7
7
  for analysing, building and visualising atomistic structures. Internally it uses the `ase.atoms.Atoms` class to
@@ -24,9 +24,9 @@ classifiers = [
24
24
  "Programming Language :: Python :: 3.12",
25
25
  ]
26
26
  dependencies = [
27
- "ase>=3.20.1,<=3.24.0",
27
+ "ase>=3.20.1,<=3.25.0",
28
28
  "numpy>=1.23.5,<=1.26.4",
29
- "scipy>=1.9.3,<=1.15.0",
29
+ "scipy>=1.9.3,<=1.15.2",
30
30
  ]
31
31
  dynamic = ["version"]
32
32
 
@@ -39,23 +39,23 @@ Repository = "https://github.com/pyiron/structuretoolkit"
39
39
  dscribe = ["dscribe==2.1.1"]
40
40
  grainboundary = [
41
41
  "aimsgb>=1.0.2,<=1.1.1",
42
- "pymatgen>=2022.2.1,<=2024.11.13",
42
+ "pymatgen>=2022.2.1,<=2025.3.10",
43
43
  ]
44
44
  pyscal = ["pyscal3>=3.2.5,<=3.2.7"]
45
45
  nglview = ["nglview>=2.7.7,<=3.1.4"]
46
- matplotlib = ["matplotlib==3.10.0"]
47
- plotly = ["plotly>=4.14.3,<=5.24.1"]
48
- clusters = ["scikit-learn==1.6.0"]
49
- symmetry = ["spglib>=1.16.5,<=2.5.0"]
46
+ matplotlib = ["matplotlib==3.10.1"]
47
+ plotly = ["plotly>=4.14.3,<=6.0.1"]
48
+ clusters = ["scikit-learn==1.6.1"]
49
+ symmetry = ["spglib>=1.16.5,<=2.6.0"]
50
50
  surface = [
51
- "spglib>=1.16.5,<=2.5.0",
52
- "pymatgen>=2022.2.1,<=2024.11.13",
51
+ "spglib>=1.16.5,<=2.6.0",
52
+ "pymatgen>=2022.2.1,<=2025.3.10",
53
53
  ]
54
54
  phonopy = [
55
- "phonopy>=2.16.2,<=2.34.0",
56
- "spglib>=1.16.5,<=2.5.0",
55
+ "phonopy>=2.16.2,<=2.38.0",
56
+ "spglib>=1.16.5,<=2.6.0",
57
57
  ]
58
- pyxtal = ["pyxtal>=0.5.5,<=1.0.6"]
58
+ pyxtal = ["pyxtal>=0.5.5,<=1.0.7"]
59
59
 
60
60
  [tool.setuptools.packages.find]
61
61
  include = ["structuretoolkit*"]
@@ -63,6 +63,53 @@ include = ["structuretoolkit*"]
63
63
  [tool.setuptools.dynamic]
64
64
  version = {attr = "structuretoolkit.__version__"}
65
65
 
66
+ [tool.ruff]
67
+ exclude = [".ci_support", "tests", "setup.py", "_version.py"]
68
+
69
+ [tool.ruff.lint]
70
+ select = [
71
+ # pycodestyle
72
+ "E",
73
+ # Pyflakes
74
+ "F",
75
+ # pyupgrade
76
+ "UP",
77
+ # flake8-bugbear
78
+ "B",
79
+ # flake8-simplify
80
+ "SIM",
81
+ # isort
82
+ "I",
83
+ # flake8-comprehensions
84
+ "C4",
85
+ # eradicate
86
+ "ERA",
87
+ # pylint
88
+ "PL",
89
+ ]
90
+ ignore = [
91
+ # ignore functions in argument defaults
92
+ "B008",
93
+ # ignore exception naming
94
+ "B904",
95
+ # ignore line-length violations
96
+ "E501",
97
+ # ignore equality comparisons for numpy arrays
98
+ "E712",
99
+ # ignore bare except
100
+ "E722",
101
+ # ignore ambiguous variable name
102
+ "E741",
103
+ # Too many arguments in function definition
104
+ "PLR0913",
105
+ # Magic value used in comparison
106
+ "PLR2004",
107
+ # Too many branches
108
+ "PLR0912",
109
+ # Too many statements
110
+ "PLR0915",
111
+ ]
112
+
66
113
  [tool.versioneer]
67
114
  VCS = "git"
68
115
  style = "pep440-pre"
@@ -98,4 +98,62 @@ from structuretoolkit.visualize import plot3d
98
98
 
99
99
  from . import _version
100
100
 
101
+ __all__ = [
102
+ "find_mic",
103
+ "find_solids",
104
+ "get_adaptive_cna_descriptors",
105
+ "get_average_of_unique_labels",
106
+ "get_centro_symmetry_descriptors",
107
+ "get_cluster_positions",
108
+ "get_delaunay_neighbors",
109
+ "get_diamond_structure_descriptors",
110
+ "get_distances_array",
111
+ "get_equivalent_atoms",
112
+ "get_interstitials",
113
+ "get_layers",
114
+ "get_mean_positions",
115
+ "get_neighborhood",
116
+ "get_neighbors",
117
+ "get_steinhardt_parameters",
118
+ "get_strain",
119
+ "get_symmetry",
120
+ "get_voronoi_neighbors",
121
+ "get_voronoi_vertices",
122
+ "get_voronoi_volumes",
123
+ "analyse_find_solids",
124
+ "analyse_cna_adaptive",
125
+ "analyse_centro_symmetry",
126
+ "cluster_positions",
127
+ "analyse_diamond_structure",
128
+ "analyse_phonopy_equivalent_atoms",
129
+ "get_steinhardt_parameter_structure",
130
+ "analyse_voronoi_volume",
131
+ "B2",
132
+ "C14",
133
+ "C15",
134
+ "C36",
135
+ "D03",
136
+ "create_mesh",
137
+ "get_grainboundary_info",
138
+ "get_high_index_surface_info",
139
+ "grainboundary",
140
+ "high_index_surface",
141
+ "sqs_structures",
142
+ "grainboundary_info",
143
+ "high_index_surface_info",
144
+ "grainboundary_build",
145
+ "get_sqs_structures",
146
+ "SymmetryError",
147
+ "apply_strain",
148
+ "ase_to_pymatgen",
149
+ "ase_to_pyscal",
150
+ "center_coordinates_in_unit_cell",
151
+ "get_cell",
152
+ "get_extended_positions",
153
+ "get_vertical_length",
154
+ "get_wrapped_coordinates",
155
+ "pymatgen_to_ase",
156
+ "select_index",
157
+ "plot3d",
158
+ ]
101
159
  __version__ = _version.get_versions()["version"]
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2025-01-08T12:24:58+0100",
11
+ "date": "2025-04-13T08:36:36+0200",
12
12
  "dirty": true,
13
13
  "error": null,
14
- "full-revisionid": "1d3dc72ffec6f8278719c0551754cf405880e393",
15
- "version": "0.0.29"
14
+ "full-revisionid": "6a0b89e67ab34d999e56a93afceaa1fbedf249bc",
15
+ "version": "0.0.32"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -254,3 +254,39 @@ def get_ir_reciprocal_mesh(
254
254
  is_shift=is_shift,
255
255
  is_time_reversal=is_time_reversal,
256
256
  )
257
+
258
+
259
+ __all__ = [
260
+ "find_mic",
261
+ "get_distances_array",
262
+ "soap_descriptor_per_atom",
263
+ "get_neighborhood",
264
+ "get_neighbors",
265
+ "get_equivalent_atoms",
266
+ "find_solids",
267
+ "get_adaptive_cna_descriptors",
268
+ "get_centro_symmetry_descriptors",
269
+ "get_diamond_structure_descriptors",
270
+ "get_steinhardt_parameters",
271
+ "get_voronoi_volumes",
272
+ "get_snap_descriptor_derivatives",
273
+ "get_snap_descriptor_names",
274
+ "get_snap_descriptors_per_atom",
275
+ "get_average_of_unique_labels",
276
+ "get_cluster_positions",
277
+ "get_delaunay_neighbors",
278
+ "get_interstitials",
279
+ "get_layers",
280
+ "get_mean_positions",
281
+ "get_voronoi_neighbors",
282
+ "get_voronoi_vertices",
283
+ "get_strain",
284
+ "get_ir_reciprocal_mesh",
285
+ "get_symmetry",
286
+ "symmetrize_vectors",
287
+ "group_points_by_symmetry",
288
+ "get_primitive_cell",
289
+ "get_spacegroup",
290
+ "get_symmetry_dataset",
291
+ "get_equivalent_points",
292
+ ]
@@ -13,7 +13,7 @@ def soap_descriptor_per_atom(
13
13
  rbf: str = "gto",
14
14
  weighting: Optional[np.ndarray] = None,
15
15
  average: str = "off",
16
- compression: dict = {"mode": "off", "species_weighting": None},
16
+ compression: dict = None,
17
17
  species: Optional[list] = None,
18
18
  periodic: bool = True,
19
19
  sparse: bool = False,
@@ -50,6 +50,8 @@ def soap_descriptor_per_atom(
50
50
  """
51
51
  from dscribe.descriptors import SOAP
52
52
 
53
+ if compression is None:
54
+ compression = {"mode": "off", "species_weighting": None}
53
55
  if species is None:
54
56
  species = list(set(structure.get_chemical_symbols()))
55
57
  periodic_soap = SOAP(
@@ -1,10 +1,9 @@
1
- # coding: utf-8
2
1
  # Copyright (c) Max-Planck-Institut für Eisenforschung GmbH - Computational Materials Design (CM) Department
3
2
  # Distributed under the terms of "New BSD License", see the LICENSE file.
4
3
 
5
4
  import itertools
6
5
  import warnings
7
- from typing import Dict, List, Optional, Tuple, Union
6
+ from typing import Optional, Union
8
7
 
9
8
  import numpy as np
10
9
  from ase.atoms import Atoms
@@ -104,11 +103,11 @@ class Tree:
104
103
  Raises:
105
104
  KeyError: If the new mode is not found in the available modes.
106
105
  """
107
- if new_mode not in self._mode.keys():
106
+ if new_mode not in self._mode:
108
107
  raise KeyError(
109
108
  f"{new_mode} not found. Available modes: {', '.join(self._mode.keys())}"
110
109
  )
111
- self._mode = {key: False for key in self._mode.keys()}
110
+ self._mode = dict.fromkeys(self._mode, False)
112
111
  self._mode[new_mode] = True
113
112
 
114
113
  def __repr__(self) -> str:
@@ -366,7 +365,7 @@ class Tree:
366
365
  num_neighbors: Optional[int] = None,
367
366
  cutoff_radius: float = np.inf,
368
367
  width_buffer: float = 1.2,
369
- ) -> Tuple[np.ndarray, np.ndarray]:
368
+ ) -> tuple[np.ndarray, np.ndarray]:
370
369
  """
371
370
  Get the distances and indices of the neighbors for the given positions.
372
371
 
@@ -406,7 +405,8 @@ class Tree:
406
405
  warnings.warn(
407
406
  "Number of neighbors found within the cutoff_radius is equal to (estimated) "
408
407
  + "num_neighbors. Increase num_neighbors (or set it to None) or "
409
- + "width_buffer to find all neighbors within cutoff_radius."
408
+ + "width_buffer to find all neighbors within cutoff_radius.",
409
+ stacklevel=2,
410
410
  )
411
411
  self._extended_indices = indices.copy()
412
412
  indices[distances < np.inf] = self._get_wrapped_indices()[
@@ -508,7 +508,8 @@ class Tree:
508
508
  if num_neighbors > self.num_neighbors:
509
509
  warnings.warn(
510
510
  "Taking a larger search area after initialization has the risk of "
511
- + "missing neighborhood atoms"
511
+ + "missing neighborhood atoms",
512
+ stacklevel=2,
512
513
  )
513
514
  return num_neighbors
514
515
 
@@ -632,15 +633,14 @@ class Tree:
632
633
  bool: True if the width exceeds the specified value, False otherwise.
633
634
 
634
635
  """
635
- if any(pbc) and np.prod(self.filled.distances.shape) > 0:
636
- if (
637
- np.linalg.norm(
638
- self.flattened.vecs[..., pbc], axis=-1, ord=self.norm_order
639
- ).max()
640
- > width
641
- ):
642
- return True
643
- return False
636
+ return bool(
637
+ any(pbc)
638
+ and np.prod(self.filled.distances.shape) > 0
639
+ and np.linalg.norm(
640
+ self.flattened.vecs[..., pbc], axis=-1, ord=self.norm_order
641
+ ).max()
642
+ > width
643
+ )
644
644
 
645
645
  def get_spherical_harmonics(
646
646
  self,
@@ -811,9 +811,9 @@ class Mode:
811
811
  def __dir__(self):
812
812
  """Show value names which are available for different filling modes."""
813
813
  return list(
814
- set(
815
- ["distances", "vecs", "indices", "shells", "atom_numbers"]
816
- ).intersection(self.ref_neigh.__dir__())
814
+ {"distances", "vecs", "indices", "shells", "atom_numbers"}.intersection(
815
+ self.ref_neigh.__dir__()
816
+ )
817
817
  )
818
818
 
819
819
 
@@ -1008,7 +1008,7 @@ class Neighbors(Tree):
1008
1008
 
1009
1009
  def get_shell_matrix(
1010
1010
  self,
1011
- chemical_pair: Optional[List[str]] = None,
1011
+ chemical_pair: Optional[list[str]] = None,
1012
1012
  cluster_by_distances: bool = False,
1013
1013
  cluster_by_vecs: bool = False,
1014
1014
  ):
@@ -1225,7 +1225,7 @@ class Neighbors(Tree):
1225
1225
 
1226
1226
  def cluster_analysis(
1227
1227
  self, id_list: list, return_cluster_sizes: bool = False
1228
- ) -> Union[Dict[int, List[int]], Tuple[Dict[int, List[int]], List[int]]]:
1228
+ ) -> Union[dict[int, list[int]], tuple[dict[int, list[int]], list[int]]]:
1229
1229
  """
1230
1230
  Perform cluster analysis on a list of atom IDs.
1231
1231
 
@@ -1240,11 +1240,8 @@ class Neighbors(Tree):
1240
1240
  """
1241
1241
  self._cluster = [0] * len(self._ref_structure)
1242
1242
  c_count = 1
1243
- # element_list = self.get_atomic_numbers()
1244
1243
  for ia in id_list:
1245
- # el0 = element_list[ia]
1246
1244
  nbrs = self.ragged.indices[ia]
1247
- # print ("nbrs: ", ia, nbrs)
1248
1245
  if self._cluster[ia] == 0:
1249
1246
  self._cluster[ia] = c_count
1250
1247
  self.__probe_cluster(c_count, nbrs, id_list)
@@ -1261,7 +1258,7 @@ class Neighbors(Tree):
1261
1258
  return cluster_dict # sizes
1262
1259
 
1263
1260
  def __probe_cluster(
1264
- self, c_count: int, neighbors: List[int], id_list: List[int]
1261
+ self, c_count: int, neighbors: list[int], id_list: list[int]
1265
1262
  ) -> None:
1266
1263
  """
1267
1264
  Recursively probe the cluster and assign cluster IDs to neighbors.
@@ -1275,11 +1272,12 @@ class Neighbors(Tree):
1275
1272
  None
1276
1273
  """
1277
1274
  for nbr_id in neighbors:
1278
- if self._cluster[nbr_id] == 0:
1279
- if nbr_id in id_list: # TODO: check also for ordered structures
1280
- self._cluster[nbr_id] = c_count
1281
- nbrs = self.ragged.indices[nbr_id]
1282
- self.__probe_cluster(c_count, nbrs, id_list)
1275
+ if (
1276
+ self._cluster[nbr_id] == 0 and nbr_id in id_list
1277
+ ): # TODO: check also for ordered structures
1278
+ self._cluster[nbr_id] = c_count
1279
+ nbrs = self.ragged.indices[nbr_id]
1280
+ self.__probe_cluster(c_count, nbrs, id_list)
1283
1281
 
1284
1282
  # TODO: combine with corresponding routine in plot3d
1285
1283
  def get_bonds(
@@ -1287,7 +1285,7 @@ class Neighbors(Tree):
1287
1285
  radius: float = np.inf,
1288
1286
  max_shells: Optional[int] = None,
1289
1287
  prec: float = 0.1,
1290
- ) -> List[Dict[str, List[List[int]]]]:
1288
+ ) -> list[dict[str, list[list[int]]]]:
1291
1289
  """
1292
1290
  Get the bonds in the structure.
1293
1291
 
@@ -1303,7 +1301,7 @@ class Neighbors(Tree):
1303
1301
 
1304
1302
  def get_cluster(
1305
1303
  dist_vec: np.ndarray, ind_vec: np.ndarray, prec: float = prec
1306
- ) -> List[np.ndarray]:
1304
+ ) -> list[np.ndarray]:
1307
1305
  """
1308
1306
  Get clusters from a distance vector and index vector.
1309
1307
 
@@ -1326,7 +1324,6 @@ class Neighbors(Tree):
1326
1324
  ind_shell = []
1327
1325
  for d, i in zip(dist, ind):
1328
1326
  id_list = get_cluster(d[d < radius], i[d < radius])
1329
- # print ("id: ", d[d<radius], id_list, dist_lst)
1330
1327
  ia_shells_dict = {}
1331
1328
  for i_shell_list in id_list:
1332
1329
  ia_shell_dict = {}
@@ -1338,9 +1335,11 @@ class Neighbors(Tree):
1338
1335
  for el, ia_lst in ia_shell_dict.items():
1339
1336
  if el not in ia_shells_dict:
1340
1337
  ia_shells_dict[el] = []
1341
- if max_shells is not None:
1342
- if len(ia_shells_dict[el]) + 1 > max_shells:
1343
- continue
1338
+ if (
1339
+ max_shells is not None
1340
+ and len(ia_shells_dict[el]) + 1 > max_shells
1341
+ ):
1342
+ continue
1344
1343
  ia_shells_dict[el].append(ia_lst)
1345
1344
  ind_shell.append(ia_shells_dict)
1346
1345
  return ind_shell
@@ -1457,7 +1456,8 @@ def _get_neighbors(
1457
1456
  if neigh._check_width(width=width, pbc=structure.pbc):
1458
1457
  warnings.warn(
1459
1458
  "width_buffer may have been too small - "
1460
- "most likely not all neighbors properly assigned"
1459
+ "most likely not all neighbors properly assigned",
1460
+ stacklevel=2,
1461
1461
  )
1462
1462
  return neigh
1463
1463
 
@@ -1,8 +1,6 @@
1
- # coding: utf-8
2
1
  # Copyright (c) Max-Planck-Institut für Eisenforschung GmbH - Computational Materials Design (CM) Department
3
2
  # Distributed under the terms of "New BSD License", see the LICENSE file.
4
3
 
5
- from typing import List
6
4
 
7
5
  import numpy as np
8
6
  from ase.atoms import Atoms
@@ -21,7 +19,7 @@ __date__ = "Sep 1, 2018"
21
19
 
22
20
  def get_equivalent_atoms(
23
21
  structure: Atoms, symprec: float = 1e-5, angle_tolerance: float = -1.0
24
- ) -> List[int]:
22
+ ) -> list[int]:
25
23
  """
26
24
  Get the indices of atoms that are equivalent under symmetry operations.
27
25
 
@@ -1,8 +1,7 @@
1
- # coding: utf-8
2
1
  # Copyright (c) Max-Planck-Institut für Eisenforschung GmbH - Computational Materials Design (CM) Department
3
2
  # Distributed under the terms of "New BSD License", see the LICENSE file.
4
3
 
5
- from typing import Any, Dict, Optional, Tuple, Union
4
+ from typing import Any, Optional, Union
6
5
 
7
6
  import numpy as np
8
7
  from ase.atoms import Atoms
@@ -28,7 +27,7 @@ def get_steinhardt_parameters(
28
27
  n_clusters: Optional[int] = 2,
29
28
  q: Optional[tuple] = None,
30
29
  averaged: bool = False,
31
- ) -> Union[Tuple[np.ndarray], Tuple[np.ndarray, np.ndarray]]:
30
+ ) -> Union[tuple[np.ndarray], tuple[np.ndarray, np.ndarray]]:
32
31
  """
33
32
  Calculate Steinhardts parameters
34
33
 
@@ -81,7 +80,7 @@ def get_centro_symmetry_descriptors(
81
80
 
82
81
  def get_diamond_structure_descriptors(
83
82
  structure: Atoms, mode: str = "total", ovito_compatibility: bool = False
84
- ) -> Union[Dict[str, int], np.ndarray]:
83
+ ) -> Union[dict[str, int], np.ndarray]:
85
84
  """
86
85
  Analyse diamond structure
87
86
 
@@ -64,7 +64,7 @@ def get_snap_descriptors_per_atom(
64
64
  structure: Atoms,
65
65
  atom_types: list[str],
66
66
  twojmax: int = 6,
67
- element_radius: list[int] = [4.0],
67
+ element_radius: list[int] = None,
68
68
  rcutfac: float = 1.0,
69
69
  rfac0: float = 0.99363,
70
70
  rmin0: float = 0.0,
@@ -92,6 +92,8 @@ def get_snap_descriptors_per_atom(
92
92
  Returns:
93
93
  np.ndarray: Numpy array with the calculated descriptor derivatives
94
94
  """
95
+ if element_radius is None:
96
+ element_radius = [4.0]
95
97
  lmp, bispec_options, cutoff = _get_default_parameters(
96
98
  atom_types=atom_types,
97
99
  twojmax=twojmax,
@@ -113,7 +115,7 @@ def get_snap_descriptor_derivatives(
113
115
  structure: Atoms,
114
116
  atom_types: list[str],
115
117
  twojmax: int = 6,
116
- element_radius: list[int] = [4.0],
118
+ element_radius: list[int] = None,
117
119
  rcutfac: float = 1.0,
118
120
  rfac0: float = 0.99363,
119
121
  rmin0: float = 0.0,
@@ -141,6 +143,8 @@ def get_snap_descriptor_derivatives(
141
143
  Returns:
142
144
  np.ndarray: Numpy array with the calculated descriptor derivatives
143
145
  """
146
+ if element_radius is None:
147
+ element_radius = [4.0]
144
148
  lmp, bispec_options, cutoff = _get_default_parameters(
145
149
  atom_types=atom_types,
146
150
  twojmax=twojmax,
@@ -420,7 +424,7 @@ def _calc_snap_per_atom(
420
424
  return np.array([])
421
425
  else:
422
426
  if (
423
- "quadraticflag" in bispec_options.keys()
427
+ "quadraticflag" in bispec_options
424
428
  and int(bispec_options["quadraticflag"]) == 1
425
429
  ):
426
430
  return _extract_compute_np(
@@ -521,7 +525,7 @@ def _set_computes_snap(lmp, bispec_options: dict):
521
525
  kw_substrings = [f"{k} {v}" for k, v in kw_options.items()]
522
526
  kwargs = " ".join(kw_substrings)
523
527
 
524
- for op, base in zip(("b", "db", "vb"), (base_b, base_db, base_vb)):
528
+ for _op, base in zip(("b", "db", "vb"), (base_b, base_db, base_vb)):
525
529
  command = f"{base} {radelem} {wj} {kwargs}"
526
530
  lmp.command(command)
527
531
 
@@ -545,16 +549,15 @@ def _extract_computes_snap(
545
549
  np.ndarray: Output of the LAMMPS compute command
546
550
  """
547
551
  lmp_atom_ids = lmp.numpy.extract_atom_iarray("id", num_atoms).flatten()
548
- assert np.all(
549
- lmp_atom_ids == 1 + np.arange(num_atoms)
550
- ), "LAMMPS seems to have lost atoms"
552
+ cond = np.all(lmp_atom_ids == 1 + np.arange(num_atoms))
553
+ assert cond, "LAMMPS seems to have lost atoms"
551
554
 
552
555
  # Extract types
553
556
  lmp_types = lmp.numpy.extract_atom_iarray(name="type", nelem=num_atoms).flatten()
554
557
  lmp_volume = lmp.get_thermo("vol")
555
558
 
556
559
  # Extract Bsum
557
- lmp_bsum = _extract_compute_np(lmp, "b_sum", 0, 1, (n_coeff))
560
+ _extract_compute_np(lmp, "b_sum", 0, 1, (n_coeff))
558
561
 
559
562
  # Extract B
560
563
  lmp_barr = _extract_compute_np(lmp, "b", 1, 2, (num_atoms, n_coeff))
@@ -569,16 +572,14 @@ def _extract_computes_snap(
569
572
 
570
573
  lmp_dbarr = _extract_compute_np(lmp, "db", 1, 2, (num_atoms, num_types, 3, n_coeff))
571
574
  lmp_dbsum = _extract_compute_np(lmp, "db_sum", 0, 1, (num_types, 3, n_coeff))
572
- assert np.allclose(
573
- lmp_dbsum, lmp_dbarr.sum(axis=0), rtol=1e-12, atol=1e-12
574
- ), "db_sum doesn't match sum of db"
575
+ cond = np.allclose(lmp_dbsum, lmp_dbarr.sum(axis=0), rtol=1e-12, atol=1e-12)
576
+ assert cond, "db_sum doesn't match sum of db"
575
577
  db_atom = np.transpose(lmp_dbarr, (0, 2, 1, 3))
576
578
 
577
579
  lmp_vbarr = _extract_compute_np(lmp, "vb", 1, 2, (num_atoms, num_types, 6, n_coeff))
578
580
  lmp_vbsum = _extract_compute_np(lmp, "vb_sum", 0, 1, (num_types, 6, n_coeff))
579
- assert np.allclose(
580
- lmp_vbsum, lmp_vbarr.sum(axis=0), rtol=1e-12, atol=1e-12
581
- ), "vb_sum doesn't match sum of vb"
581
+ cond = np.allclose(lmp_vbsum, lmp_vbarr.sum(axis=0), rtol=1e-12, atol=1e-12)
582
+ assert cond, "vb_sum doesn't match sum of vb"
582
583
  vb_sum = np.transpose(lmp_vbsum, (1, 0, 2)) / lmp_volume * eV_div_A3_to_bar
583
584
 
584
585
  dbatom_shape = db_atom.shape
@@ -631,7 +632,7 @@ def _calc_snap_derivatives(
631
632
  return np.array([])
632
633
  else:
633
634
  if (
634
- "quadraticflag" in bispec_options.keys()
635
+ "quadraticflag" in bispec_options
635
636
  and int(bispec_options["quadraticflag"]) == 1
636
637
  ):
637
638
  return _extract_computes_snap(
@@ -681,10 +682,7 @@ def _get_default_parameters(
681
682
  """
682
683
  from lammps import lammps
683
684
 
684
- if weights is None:
685
- wj = [1.0] * len(atom_types)
686
- else:
687
- wj = weights
685
+ wj = [1.0] * len(atom_types) if weights is None else weights
688
686
  if isinstance(element_radius, float):
689
687
  radelem = [element_radius] * len(atom_types)
690
688
  else: