emmet-builders 0.84.7rc4__py3-none-any.whl → 0.84.9__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.

Potentially problematic release.


This version of emmet-builders might be problematic. Click here for more details.

Files changed (41) hide show
  1. emmet/builders/abinit/phonon.py +15 -11
  2. emmet/builders/abinit/sound_velocity.py +14 -10
  3. emmet/builders/feff/xas.py +1 -2
  4. emmet/builders/materials/absorption_spectrum.py +9 -4
  5. emmet/builders/materials/alloys.py +2 -3
  6. emmet/builders/materials/chemenv.py +2 -3
  7. emmet/builders/materials/corrected_entries.py +14 -8
  8. emmet/builders/materials/dielectric.py +9 -4
  9. emmet/builders/materials/elasticity.py +32 -25
  10. emmet/builders/materials/electrodes.py +23 -18
  11. emmet/builders/materials/electronic_structure.py +16 -16
  12. emmet/builders/materials/magnetism.py +9 -3
  13. emmet/builders/materials/ml.py +9 -11
  14. emmet/builders/materials/optimade.py +7 -3
  15. emmet/builders/materials/piezoelectric.py +1 -2
  16. emmet/builders/materials/provenance.py +11 -7
  17. emmet/builders/materials/robocrys.py +2 -3
  18. emmet/builders/materials/substrates.py +8 -7
  19. emmet/builders/materials/thermo.py +17 -11
  20. emmet/builders/matscholar/missing_compositions.py +12 -8
  21. emmet/builders/mobility/migration_graph.py +5 -5
  22. emmet/builders/molecules/atomic.py +27 -22
  23. emmet/builders/molecules/bonds.py +17 -12
  24. emmet/builders/molecules/electric.py +16 -11
  25. emmet/builders/molecules/metal_binding.py +19 -16
  26. emmet/builders/molecules/orbitals.py +15 -11
  27. emmet/builders/molecules/redox.py +27 -21
  28. emmet/builders/molecules/summary.py +21 -13
  29. emmet/builders/molecules/thermo.py +20 -15
  30. emmet/builders/molecules/trajectory.py +23 -18
  31. emmet/builders/molecules/vibration.py +15 -11
  32. emmet/builders/qchem/molecules.py +37 -32
  33. emmet/builders/settings.py +7 -8
  34. emmet/builders/utils.py +11 -7
  35. emmet/builders/vasp/materials.py +17 -11
  36. emmet/builders/vasp/task_validator.py +3 -5
  37. {emmet_builders-0.84.7rc4.dist-info → emmet_builders-0.84.9.dist-info}/METADATA +1 -1
  38. emmet_builders-0.84.9.dist-info/RECORD +54 -0
  39. emmet_builders-0.84.7rc4.dist-info/RECORD +0 -54
  40. {emmet_builders-0.84.7rc4.dist-info → emmet_builders-0.84.9.dist-info}/WHEEL +0 -0
  41. {emmet_builders-0.84.7rc4.dist-info → emmet_builders-0.84.9.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,6 @@
1
1
  import os
2
2
  import tempfile
3
3
  from math import ceil
4
- from typing import Dict, Iterator, List, Optional, Tuple
5
4
 
6
5
  import numpy as np
7
6
  from abipy.abio.inputs import AnaddbInput
@@ -36,6 +35,11 @@ from emmet.core.phonon import (
36
35
  from emmet.core.polar import BornEffectiveCharges, DielectricDoc, IRDielectric
37
36
  from emmet.core.utils import jsanitize
38
37
 
38
+ from typing import TYPE_CHECKING
39
+
40
+ if TYPE_CHECKING:
41
+ from collections.abc import Iterator
42
+
39
43
  SETTINGS = EmmetBuildSettings()
40
44
 
41
45
 
@@ -50,8 +54,8 @@ class PhononBuilder(Builder):
50
54
  ddb_files: Store,
51
55
  th_disp: Store,
52
56
  phonon_website: Store,
53
- query: Optional[Dict] = None,
54
- manager: Optional[TaskManager] = None,
57
+ query: dict | None = None,
58
+ manager: TaskManager | None = None,
55
59
  symprec: float = SETTINGS.SYMPREC,
56
60
  angle_tolerance: float = SETTINGS.ANGLE_TOL,
57
61
  chunk_size=100,
@@ -134,7 +138,7 @@ class PhononBuilder(Builder):
134
138
  for mpid_chunk in grouper(mats, N):
135
139
  yield {"query": {self.phonon_materials.key: {"$in": list(mpid_chunk)}}}
136
140
 
137
- def get_items(self) -> Iterator[Dict]:
141
+ def get_items(self) -> Iterator[dict]:
138
142
  """
139
143
  Gets all materials that need phonons
140
144
 
@@ -188,7 +192,7 @@ class PhononBuilder(Builder):
188
192
 
189
193
  yield item
190
194
 
191
- def process_item(self, item: Dict) -> Optional[Dict]:
195
+ def process_item(self, item: dict) -> dict | None:
192
196
  """
193
197
  Generates the full phonon document from an item
194
198
 
@@ -293,7 +297,7 @@ class PhononBuilder(Builder):
293
297
  )
294
298
  return None
295
299
 
296
- def get_phonon_properties(self, item: Dict) -> Dict:
300
+ def get_phonon_properties(self, item: dict) -> dict:
297
301
  """
298
302
  Extracts the phonon properties from the item
299
303
  """
@@ -511,7 +515,7 @@ class PhononBuilder(Builder):
511
515
  dos: str = "tetra",
512
516
  lo_to_splitting: bool = True,
513
517
  use_dieflag: bool = True,
514
- ) -> Tuple[AnaddbInput, Optional[List]]:
518
+ ) -> tuple[AnaddbInput, list | None]:
515
519
  """
516
520
  creates the AnaddbInput object to calculate the phonon properties.
517
521
  It also returns the list of qpoints labels for generating the PhononBandStructureSymmLine.
@@ -637,7 +641,7 @@ class PhononBuilder(Builder):
637
641
 
638
642
  @staticmethod
639
643
  def get_pmg_bs(
640
- phbands: PhononBands, labels_list: List
644
+ phbands: PhononBands, labels_list: list
641
645
  ) -> PhononBandStructureSymmLine:
642
646
  """
643
647
  Generates a PhononBandStructureSymmLine starting from a abipy PhononBands object
@@ -726,7 +730,7 @@ class PhononBuilder(Builder):
726
730
 
727
731
  return data
728
732
 
729
- def update_targets(self, items: List[Dict]):
733
+ def update_targets(self, items: list[dict]):
730
734
  """
731
735
  Inserts the new task_types into the task_types collection
732
736
 
@@ -769,7 +773,7 @@ class PhononBuilder(Builder):
769
773
 
770
774
  def get_warnings(
771
775
  asr_break: float, cnsr_break: float, ph_bs: PhononBandStructureSymmLine
772
- ) -> List[PhononWarnings]:
776
+ ) -> list[PhononWarnings]:
773
777
  """
774
778
 
775
779
  Args:
@@ -810,7 +814,7 @@ def get_warnings(
810
814
 
811
815
  def get_thermodynamic_properties(
812
816
  ph_dos: CompletePhononDos,
813
- ) -> Tuple[ThermodynamicProperties, VibrationalEnergy]:
817
+ ) -> tuple[ThermodynamicProperties, VibrationalEnergy]:
814
818
  """
815
819
  Calculates the thermodynamic properties from a phonon DOS
816
820
 
@@ -1,18 +1,22 @@
1
1
  import tempfile
2
2
  import traceback
3
3
  from math import ceil
4
- from maggma.utils import grouper
5
- from typing import Optional, Dict, List, Iterator
6
4
 
7
- from abipy.dfpt.vsound import SoundVelocity as AbiSoundVelocity
8
5
  from abipy.dfpt.ddb import DdbFile
6
+ from abipy.dfpt.vsound import SoundVelocity as AbiSoundVelocity
7
+ from abipy.flowtk.tasks import TaskManager
9
8
  from maggma.builders import Builder
10
9
  from maggma.core import Store
11
- from abipy.flowtk.tasks import TaskManager
10
+ from maggma.utils import grouper
12
11
 
13
12
  from emmet.core.phonon import SoundVelocity
14
13
  from emmet.core.utils import jsanitize
15
14
 
15
+ from typing import TYPE_CHECKING
16
+
17
+ if TYPE_CHECKING:
18
+ from collections.abc import Iterator
19
+
16
20
 
17
21
  class SoundVelocityBuilder(Builder):
18
22
  def __init__(
@@ -20,8 +24,8 @@ class SoundVelocityBuilder(Builder):
20
24
  phonon_materials: Store,
21
25
  ddb_source: Store,
22
26
  sound_vel: Store,
23
- query: Optional[dict] = None,
24
- manager: Optional[TaskManager] = None,
27
+ query: dict | None = None,
28
+ manager: TaskManager | None = None,
25
29
  **kwargs
26
30
  ):
27
31
  """
@@ -72,7 +76,7 @@ class SoundVelocityBuilder(Builder):
72
76
  for mpid_chunk in grouper(mats, N):
73
77
  yield {"query": {self.phonon_materials.key: {"$in": list(mpid_chunk)}}}
74
78
 
75
- def get_items(self) -> Iterator[Dict]:
79
+ def get_items(self) -> Iterator[dict]:
76
80
  """
77
81
  Gets all materials that need sound velocity.
78
82
 
@@ -117,7 +121,7 @@ class SoundVelocityBuilder(Builder):
117
121
 
118
122
  yield item
119
123
 
120
- def process_item(self, item: Dict) -> Optional[Dict]:
124
+ def process_item(self, item: dict) -> dict | None:
121
125
  """
122
126
  Generates the sound velocity document from an item
123
127
 
@@ -153,7 +157,7 @@ class SoundVelocityBuilder(Builder):
153
157
  return None
154
158
 
155
159
  @staticmethod
156
- def get_sound_vel(item: Dict) -> Dict:
160
+ def get_sound_vel(item: dict) -> dict:
157
161
  """
158
162
  Runs anaddb and return the extracted data for the speed of sound.
159
163
 
@@ -187,7 +191,7 @@ class SoundVelocityBuilder(Builder):
187
191
 
188
192
  return sv_data
189
193
 
190
- def update_targets(self, items: List[Dict]):
194
+ def update_targets(self, items: list[dict]):
191
195
  """
192
196
  Inserts the new task_types into the task_types collection
193
197
 
@@ -1,7 +1,6 @@
1
1
  import traceback
2
2
  from datetime import datetime
3
3
  from itertools import chain
4
- from typing import Dict, List
5
4
 
6
5
  from maggma.builders import GroupBuilder
7
6
  from maggma.core import Store
@@ -27,7 +26,7 @@ class XASBuilder(GroupBuilder):
27
26
  super().__init__(source=tasks, target=xas, grouping_keys=["mp_id"])
28
27
  self._target_keys_field = "xas_ids"
29
28
 
30
- def process_item(self, spectra: List[Dict]) -> Dict:
29
+ def process_item(self, spectra: list[dict]) -> dict:
31
30
  # TODO: Change this to do structure matching against materials collection
32
31
  mpid = spectra[0]["mp_id"]
33
32
 
@@ -1,5 +1,5 @@
1
+ from __future__ import annotations
1
2
  from math import ceil
2
- from typing import Dict, Iterator, List, Optional
3
3
 
4
4
  import numpy as np
5
5
  from maggma.builders import Builder
@@ -10,6 +10,11 @@ from pymatgen.core.structure import Structure
10
10
  from emmet.core.absorption import AbsorptionDoc
11
11
  from emmet.core.utils import jsanitize
12
12
 
13
+ from typing import TYPE_CHECKING
14
+
15
+ if TYPE_CHECKING:
16
+ from collections.abc import Iterator
17
+
13
18
 
14
19
  class AbsorptionBuilder(Builder):
15
20
  def __init__(
@@ -17,7 +22,7 @@ class AbsorptionBuilder(Builder):
17
22
  materials: Store,
18
23
  tasks: Store,
19
24
  absorption: Store,
20
- query: Optional[Dict] = None,
25
+ query: dict | None = None,
21
26
  **kwargs,
22
27
  ):
23
28
  self.materials = materials
@@ -32,7 +37,7 @@ class AbsorptionBuilder(Builder):
32
37
 
33
38
  super().__init__(sources=[materials, tasks], targets=[absorption], **kwargs)
34
39
 
35
- def prechunk(self, number_splits: int) -> Iterator[Dict]: # pragma: no cover
40
+ def prechunk(self, number_splits: int) -> Iterator[dict]: # pragma: no cover
36
41
  """
37
42
  Prechunk method to perform chunking by the key field
38
43
  """
@@ -44,7 +49,7 @@ class AbsorptionBuilder(Builder):
44
49
  for split in grouper(keys, N):
45
50
  yield {"query": {self.materials.key: {"$in": list(split)}}}
46
51
 
47
- def get_items(self) -> Iterator[List[Dict]]:
52
+ def get_items(self) -> Iterator[list[dict]]:
48
53
  """
49
54
  Gets all items to process
50
55
 
@@ -1,5 +1,4 @@
1
1
  from itertools import chain, combinations
2
- from typing import Dict, List, Tuple, Union
3
2
 
4
3
  from maggma.builders import Builder
5
4
  from matminer.datasets import load_dataset
@@ -40,7 +39,7 @@ class AlloyPairBuilder(Builder):
40
39
  provenance,
41
40
  oxi_states,
42
41
  alloy_pairs,
43
- thermo_type: Union[ThermoType, str] = ThermoType.GGA_GGA_U_R2SCAN,
42
+ thermo_type: ThermoType | str = ThermoType.GGA_GGA_U_R2SCAN,
44
43
  ):
45
44
  self.materials = materials
46
45
  self.thermo = thermo
@@ -274,7 +273,7 @@ class AlloyPairMemberBuilder(Builder):
274
273
  if structures:
275
274
  yield (pairs, structures)
276
275
 
277
- def process_item(self, item: Tuple[List[AlloyPair], Dict[str, Structure]]):
276
+ def process_item(self, item: tuple[list[AlloyPair], dict[str, Structure]]):
278
277
  pairs, structures = item
279
278
 
280
279
  all_pair_members = []
@@ -1,8 +1,7 @@
1
- from typing import Dict, Optional
2
1
  from maggma.builders.map_builder import MapBuilder
3
2
  from maggma.core import Store
4
-
5
3
  from pymatgen.core.structure import Structure
4
+
6
5
  from emmet.core.chemenv import ChemEnvDoc
7
6
  from emmet.core.utils import jsanitize
8
7
 
@@ -12,7 +11,7 @@ class ChemEnvBuilder(MapBuilder):
12
11
  self,
13
12
  oxidation_states: Store,
14
13
  chemenv: Store,
15
- query: Optional[Dict] = None,
14
+ query: dict | None = None,
16
15
  **kwargs
17
16
  ):
18
17
  self.oxidation_states = oxidation_states
@@ -1,10 +1,11 @@
1
+ from __future__ import annotations
2
+
1
3
  import copy
2
4
  import warnings
3
5
  from collections import defaultdict
4
6
  from datetime import datetime
5
7
  from itertools import chain
6
8
  from math import ceil
7
- from typing import Dict, Iterable, Iterator, List, Optional, Union
8
9
 
9
10
  from maggma.core import Builder, Store
10
11
  from maggma.utils import grouper
@@ -16,15 +17,20 @@ from emmet.core.corrected_entries import CorrectedEntriesDoc
16
17
  from emmet.core.thermo import ThermoType
17
18
  from emmet.core.utils import jsanitize
18
19
 
20
+ from typing import TYPE_CHECKING
21
+
22
+ if TYPE_CHECKING:
23
+ from collections.abc import Iterable, Iterator
24
+
19
25
 
20
26
  class CorrectedEntriesBuilder(Builder):
21
27
  def __init__(
22
28
  self,
23
29
  materials: Store,
24
30
  corrected_entries: Store,
25
- oxidation_states: Optional[Store] = None,
26
- query: Optional[Dict] = None,
27
- compatibility: Optional[Union[List[Compatibility], List[None]]] = [None],
31
+ oxidation_states: Store | None = None,
32
+ query: dict | None = None,
33
+ compatibility: list[Compatibility] | list[None] | None = [None],
28
34
  chunk_size: int = 1000,
29
35
  **kwargs,
30
36
  ):
@@ -48,7 +54,7 @@ class CorrectedEntriesBuilder(Builder):
48
54
  self.compatibility = compatibility
49
55
  self.oxidation_states = oxidation_states
50
56
  self.chunk_size = chunk_size
51
- self._entries_cache: Dict[str, List[Dict]] = defaultdict(list)
57
+ self._entries_cache: dict[str, list[dict]] = defaultdict(list)
52
58
 
53
59
  if self.corrected_entries.key != "chemsys":
54
60
  warnings.warn(
@@ -93,7 +99,7 @@ class CorrectedEntriesBuilder(Builder):
93
99
  # Search index for corrected_entries
94
100
  self.corrected_entries.ensure_index("chemsys")
95
101
 
96
- def prechunk(self, number_splits: int) -> Iterable[Dict]: # pragma: no cover
102
+ def prechunk(self, number_splits: int) -> Iterable[dict]: # pragma: no cover
97
103
  to_process_chemsys = self._get_chemsys_to_process()
98
104
 
99
105
  N = ceil(len(to_process_chemsys) / number_splits)
@@ -101,7 +107,7 @@ class CorrectedEntriesBuilder(Builder):
101
107
  for chemsys_chunk in grouper(to_process_chemsys, N):
102
108
  yield {"query": {"chemsys": {"$in": list(chemsys_chunk)}}}
103
109
 
104
- def get_items(self) -> Iterator[List[Dict]]:
110
+ def get_items(self) -> Iterator[list[dict]]:
105
111
  """
106
112
  Gets whole chemical systems of entries to process
107
113
  """
@@ -210,7 +216,7 @@ class CorrectedEntriesBuilder(Builder):
210
216
  else:
211
217
  self.logger.info("No corrected entry items to update")
212
218
 
213
- def get_entries(self, chemsys: str) -> List[Dict]:
219
+ def get_entries(self, chemsys: str) -> list[dict]:
214
220
  """
215
221
  Gets entries from the materials collection for the corresponding chemical systems
216
222
  Args:
@@ -1,6 +1,6 @@
1
- from math import ceil
2
- from typing import Dict, Optional, Iterator
1
+ from __future__ import annotations
3
2
 
3
+ from math import ceil
4
4
 
5
5
  import numpy as np
6
6
  from maggma.builders import Builder
@@ -11,6 +11,11 @@ from pymatgen.core.structure import Structure
11
11
  from emmet.core.polar import DielectricDoc
12
12
  from emmet.core.utils import jsanitize
13
13
 
14
+ from typing import TYPE_CHECKING
15
+
16
+ if TYPE_CHECKING:
17
+ from collections.abc import Iterator
18
+
14
19
 
15
20
  class DielectricBuilder(Builder):
16
21
  def __init__(
@@ -18,7 +23,7 @@ class DielectricBuilder(Builder):
18
23
  materials: Store,
19
24
  tasks: Store,
20
25
  dielectric: Store,
21
- query: Optional[Dict] = None,
26
+ query: dict | None = None,
22
27
  **kwargs,
23
28
  ):
24
29
  self.materials = materials
@@ -33,7 +38,7 @@ class DielectricBuilder(Builder):
33
38
 
34
39
  super().__init__(sources=[materials, tasks], targets=[dielectric], **kwargs)
35
40
 
36
- def prechunk(self, number_splits: int) -> Iterator[Dict]: # pragma: no cover
41
+ def prechunk(self, number_splits: int) -> Iterator[dict]: # pragma: no cover
37
42
  """
38
43
  Prechunk method to perform chunking by the key field
39
44
  """
@@ -17,8 +17,9 @@ The build proceeds in the below steps:
17
17
  7. Fit the elastic tensor.
18
18
  """
19
19
 
20
+ from __future__ import annotations
21
+
20
22
  from datetime import datetime
21
- from typing import Any, Dict, Generator, List, Optional, Tuple, Union
22
23
 
23
24
  import numpy as np
24
25
  from maggma.core import Builder, Store
@@ -33,6 +34,12 @@ from emmet.core.mpid import MPID
33
34
  from emmet.core.utils import jsanitize
34
35
  from emmet.core.vasp.calc_types import CalcType
35
36
 
37
+ from typing import TYPE_CHECKING
38
+
39
+ if TYPE_CHECKING:
40
+ from collections.abc import Generator
41
+ from typing import Any
42
+
36
43
 
37
44
  class ElasticityBuilder(Builder):
38
45
  def __init__(
@@ -40,7 +47,7 @@ class ElasticityBuilder(Builder):
40
47
  tasks: Store,
41
48
  materials: Store,
42
49
  elasticity: Store,
43
- query: Optional[Dict] = None,
50
+ query: dict | None = None,
44
51
  fitting_method: str = "finite_difference",
45
52
  **kwargs,
46
53
  ):
@@ -78,7 +85,7 @@ class ElasticityBuilder(Builder):
78
85
 
79
86
  def get_items(
80
87
  self,
81
- ) -> Generator[Tuple[str, Dict[str, str], List[Dict]], None, None]:
88
+ ) -> Generator[tuple[str, dict[str, str], list[dict]], None, None]:
82
89
  """
83
90
  Gets all items to process into elasticity docs.
84
91
 
@@ -129,8 +136,8 @@ class ElasticityBuilder(Builder):
129
136
  yield material_id, calc_types, tasks
130
137
 
131
138
  def process_item(
132
- self, item: Tuple[MPID, Dict[str, str], List[Dict]]
133
- ) -> Union[Dict, None]:
139
+ self, item: tuple[MPID, dict[str, str], list[dict]]
140
+ ) -> dict | None:
134
141
  """
135
142
  Process all tasks belong to the same material into an elasticity doc.
136
143
 
@@ -220,7 +227,7 @@ class ElasticityBuilder(Builder):
220
227
 
221
228
  return elasticity_doc
222
229
 
223
- def update_targets(self, items: List[Dict]):
230
+ def update_targets(self, items: list[dict]):
224
231
  """
225
232
  Insert the new elasticity docs into the elasticity collection.
226
233
 
@@ -233,10 +240,10 @@ class ElasticityBuilder(Builder):
233
240
 
234
241
 
235
242
  def filter_opt_tasks(
236
- tasks: List[Dict],
237
- calc_types: Dict[str, str],
243
+ tasks: list[dict],
244
+ calc_types: dict[str, str],
238
245
  target_calc_type: str = CalcType.GGA_Structure_Optimization,
239
- ) -> List[Dict]:
246
+ ) -> list[dict]:
240
247
  """
241
248
  Filter optimization tasks, by
242
249
  - calculation type
@@ -247,10 +254,10 @@ def filter_opt_tasks(
247
254
 
248
255
 
249
256
  def filter_deform_tasks(
250
- tasks: List[Dict],
251
- calc_types: Dict[str, str],
257
+ tasks: list[dict],
258
+ calc_types: dict[str, str],
252
259
  target_calc_type: str = CalcType.GGA_Deformation,
253
- ) -> List[Dict]:
260
+ ) -> list[dict]:
254
261
  """
255
262
  Filter deformation tasks, by
256
263
  - calculation type
@@ -271,8 +278,8 @@ def filter_deform_tasks(
271
278
 
272
279
 
273
280
  def filter_by_incar_settings(
274
- tasks: List[Dict], incar_settings: Optional[Dict[str, Any]] = None
275
- ) -> List[Dict]:
281
+ tasks: list[dict], incar_settings: dict[str, Any] | None = None
282
+ ) -> list[dict]:
276
283
  """
277
284
  Filter tasks by incar parameters.
278
285
  """
@@ -315,7 +322,7 @@ def filter_by_incar_settings(
315
322
  return selected
316
323
 
317
324
 
318
- def filter_opt_tasks_by_time(tasks: List[Dict], logger) -> Dict:
325
+ def filter_opt_tasks_by_time(tasks: list[dict], logger) -> dict:
319
326
  """
320
327
  Filter a set of tasks to select the latest completed one.
321
328
 
@@ -330,8 +337,8 @@ def filter_opt_tasks_by_time(tasks: List[Dict], logger) -> Dict:
330
337
 
331
338
 
332
339
  def filter_deform_tasks_by_time(
333
- tasks: List[Dict], deform_comp_tol: float = 1e-5, logger=None
334
- ) -> List[Dict]:
340
+ tasks: list[dict], deform_comp_tol: float = 1e-5, logger=None
341
+ ) -> list[dict]:
335
342
  """
336
343
  For deformation tasks with the same deformation, select the latest completed one.
337
344
 
@@ -364,7 +371,7 @@ def filter_deform_tasks_by_time(
364
371
  return selected
365
372
 
366
373
 
367
- def _filter_tasks_by_time(tasks: List[Dict], mode: str, logger) -> Dict:
374
+ def _filter_tasks_by_time(tasks: list[dict], mode: str, logger) -> dict:
368
375
  """
369
376
  Helper function to filter a set of tasks to select the latest completed one.
370
377
  """
@@ -388,11 +395,11 @@ def _filter_tasks_by_time(tasks: List[Dict], mode: str, logger) -> Dict:
388
395
 
389
396
 
390
397
  def select_final_opt_deform_tasks(
391
- opt_tasks: List[Tuple[np.ndarray, Dict]],
392
- deform_tasks: List[Tuple[np.ndarray, List[Dict]]],
398
+ opt_tasks: list[tuple[np.ndarray, dict]],
399
+ deform_tasks: list[tuple[np.ndarray, list[dict]]],
393
400
  logger,
394
401
  lattice_comp_tol: float = 1e-5,
395
- ) -> Tuple[Union[Dict, None], Union[List[Dict], None]]:
402
+ ) -> tuple[dict | None, list[dict] | None]:
396
403
  """
397
404
  Select the final opt task and deform tasks for fitting.
398
405
 
@@ -445,8 +452,8 @@ def select_final_opt_deform_tasks(
445
452
 
446
453
 
447
454
  def group_by_parent_lattice(
448
- tasks: List[Dict], mode: str, lattice_comp_tol: float = 1e-5
449
- ) -> List[Tuple[np.ndarray, List[Dict]]]:
455
+ tasks: list[dict], mode: str, lattice_comp_tol: float = 1e-5
456
+ ) -> list[tuple[np.ndarray, list[dict]]]:
450
457
  """
451
458
  Groups a set of task docs by parent lattice equivalence.
452
459
 
@@ -459,11 +466,11 @@ def group_by_parent_lattice(
459
466
  lattice_comp_tol: tolerance for comparing lattice equivalence.
460
467
 
461
468
  Returns:
462
- [(lattice, List[tasks])]: each tuple gives the common parent lattice of a
469
+ [(lattice, list[tasks])]: each tuple gives the common parent lattice of a
463
470
  list of the structures before deformation (if any), and the list tasks
464
471
  from which the structures are taken.
465
472
  """
466
- docs_by_lattice: List[Tuple[np.ndarray, List[Dict]]] = []
473
+ docs_by_lattice: list[tuple[np.ndarray, list[dict]]] = []
467
474
 
468
475
  for doc in tasks:
469
476
  sim_lattice = get(doc, "output.structure.lattice.matrix")