xtalmet 0.1.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.
- xtalmet-0.1.0/LICENSE +21 -0
- xtalmet-0.1.0/PKG-INFO +131 -0
- xtalmet-0.1.0/README.md +92 -0
- xtalmet-0.1.0/pyproject.toml +64 -0
- xtalmet-0.1.0/src/xtalmet/__init__.py +0 -0
- xtalmet-0.1.0/src/xtalmet/crystal.py +243 -0
- xtalmet-0.1.0/src/xtalmet/distance.py +239 -0
- xtalmet-0.1.0/src/xtalmet/evaluator.py +505 -0
- xtalmet-0.1.0/src/xtalmet/py.typed +0 -0
- xtalmet-0.1.0/src/xtalmet/screen.py +164 -0
xtalmet-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Materials Design Group
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
xtalmet-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: xtalmet
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python package containing a variety of distance functions for crystals, as well as evaluation metrics for crystal generation.
|
|
5
|
+
Author: Masahiro Negishi
|
|
6
|
+
Author-email: Masahiro Negishi <m.negishi25@imperial.ac.uk>
|
|
7
|
+
License: MIT License
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2025 Materials Design Group
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in all
|
|
19
|
+
copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
|
28
|
+
Requires-Dist: pymatgen>=2025.5.28
|
|
29
|
+
Requires-Dist: torch>=2.7.0
|
|
30
|
+
Requires-Dist: matminer>=0.9.3
|
|
31
|
+
Requires-Dist: average-minimum-distance>=1.5.3
|
|
32
|
+
Requires-Dist: smact>=3.1.0
|
|
33
|
+
Requires-Dist: mace-torch>=0.3.13
|
|
34
|
+
Requires-Dist: huggingface-hub
|
|
35
|
+
Requires-Python: >=3.12
|
|
36
|
+
Project-URL: Documentation, https://wmd-group.github.io/xtalmets/
|
|
37
|
+
Project-URL: Repository, https://github.com/WMD-group/xtalmet/
|
|
38
|
+
Description-Content-Type: text/markdown
|
|
39
|
+
|
|
40
|
+
# xtalmet
|
|
41
|
+
[](https://opensource.org/licenses/MIT)
|
|
42
|
+
[](https://docs.astral.sh/ruff/)
|
|
43
|
+
[](https://docs.astral.sh/ruff/)
|
|
44
|
+
[](https://docs.astral.sh/uv/)
|
|
45
|
+
[](https://www.sphinx-doc.org/en/master/index.html)
|
|
46
|
+
[](https://github.com/WMD-group/xtalmet/issues)
|
|
47
|
+
[](https://github.com/WMD-group/xtalmet/actions/workflows/sphinx.yml)
|
|
48
|
+
|
|
49
|
+
The **xtalmet** package offers a variety of distance functions for comparing crystal structures.
|
|
50
|
+
These include both binary and continuous as well as compositional and structural functions.
|
|
51
|
+
It also enables you to evaluate a set of crystals using uniqueness and novelty metrics derived from these distances.
|
|
52
|
+
|
|
53
|
+
- Documentation: https://wmd-group.github.io/xtalmet/
|
|
54
|
+
- Examples: https://github.com/WMD-group/xtalmet/examples
|
|
55
|
+
|
|
56
|
+
## Motivation
|
|
57
|
+
A central challenge in materials science is the efficient discovery of functional crystals from the vast chemical space.
|
|
58
|
+
Recently, the inverse design of crystals using advanced machine learning generative models has emerged as a promising approach due to their ability to rapidly generate numerous candidates.
|
|
59
|
+
However, while these models have become increasingly sophisticated, their evaluation metrics have remained largely unchanged since the seminal work of Xie et al [1] and Zeni et al [2].
|
|
60
|
+
To effectively guide model development, these evaluation metrics must also continue to improve.
|
|
61
|
+
We aim to refine two primary metrics, uniqueness and novelty, by revising the underlying distance function used to compare crystal structures.
|
|
62
|
+
|
|
63
|
+
[1] Tian Xie et al. Crystal diffusion variational autoencoder for periodic material generation. International Conference on Learning Representations 2022.
|
|
64
|
+
|
|
65
|
+
[2] Claudio Zeni et al. A generative model for inorganic materials design. Nature 2025.
|
|
66
|
+
|
|
67
|
+
## Installation
|
|
68
|
+
The latest stable version can be installed via pip:
|
|
69
|
+
```bash
|
|
70
|
+
pip install xtalmet
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Usage
|
|
74
|
+
Two primary features of xtalmet are the calculation of distances between crystals and the uniqueness/novelty evaluation.
|
|
75
|
+
For the former usage, suppose you have two crystals `xtal_1` and `xtal_2` (`pymatgen.core.Structure`) whose distance you want to measure.
|
|
76
|
+
You can do so with one line of code:
|
|
77
|
+
```python
|
|
78
|
+
from xtalmet.distance import d_amd
|
|
79
|
+
distance = d_amd(xtal_1, xtal_2)
|
|
80
|
+
```
|
|
81
|
+
Here, d_amd is a type of continuous distance based on structural fingerprints.
|
|
82
|
+
For a complete list of available distances, please refer to the [documentation](https://wmd-group.github.io/xtalmet/api/xtalmet.distance.html).
|
|
83
|
+
|
|
84
|
+
For the uniqueness/novelty evaluation, imagine that you want to assess a set of crystals `gen_xtals` (`list[pymatgen.core.Structure]`) generated from a model trained on the MP20 dataset.
|
|
85
|
+
This can be done with just a few lines of code:
|
|
86
|
+
```python
|
|
87
|
+
from xtalmet.evaluator import Evaluator
|
|
88
|
+
evaluator = Evaluator(gen_xtals)
|
|
89
|
+
uniqueness = evaluator.uniqueness(distance="d_amd")
|
|
90
|
+
novelty = evaluator.novelty(train_xtals="mp20", distance="d_amd")
|
|
91
|
+
```
|
|
92
|
+
A more detailed tutorial notebook is provided in the [examples directory](https://github.com/WMD-group/xtalmet/tree/main/examples).
|
|
93
|
+
|
|
94
|
+
## Acknowledgements
|
|
95
|
+
Although we have argued that the progress on evaluation metrics is slower than that on generative models, we are not the sole contributors to this field.
|
|
96
|
+
Our work builds upon several influential studies.
|
|
97
|
+
We particularly acknowledge the following contributions:
|
|
98
|
+
|
|
99
|
+
- Zeni et al. [2]: For their implementation of the S.U.N. (Stability / Uniqueness / Novelty) metric.
|
|
100
|
+
|
|
101
|
+
- Baird et al. [3]: For their code for uniqueness and novelty, and their framework for creating a Python benchmarking package.
|
|
102
|
+
|
|
103
|
+
- Widdowson et al. [4, 5]: For their work on a continuous structural distance between crystals.
|
|
104
|
+
|
|
105
|
+
Other studies, while not directly related, were also inspiring in shaping our approach to measuring distances between crystals.
|
|
106
|
+
These include the work of Onwuli et al. [6] on distances between compositional embeddings, as well as Hargreaves et al.'s [7] development of optimal transport-based methods for inorganic compositions.
|
|
107
|
+
|
|
108
|
+
[3] Baird et al. matbench-genmetrics: A Python library for benchmarking crystal structure generative models using time-based splits of Materials Project structures. Journal of Open Source Software 2024.
|
|
109
|
+
|
|
110
|
+
[4] Widdowson et al. Resolving the data ambiguity for periodic crystals. Advances in Neural Information Processing Systems 2022.
|
|
111
|
+
|
|
112
|
+
[5] Widdson et al. Average Minimum Distances of periodic point sets - foundational invariants for mapping periodic crystals. MATCH Communications in Mathematical and in Computer Chemistry 2022.
|
|
113
|
+
|
|
114
|
+
[6] A. Onwuli et al. Element similarity in high-dimensional materials representations. Digital Discovery 2023.
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
[7] Hargreaves et al. The earth mover’s distance as a metric for the space of inorganic compositions. Chemistry of Materials 2020.
|
|
118
|
+
|
|
119
|
+
## Citation
|
|
120
|
+
If you find xtalmet useful in your research, please consider citing:
|
|
121
|
+
```bibtex
|
|
122
|
+
@misc{negishi2025continuousuniquenessnoveltymetrics,
|
|
123
|
+
title={Continuous Uniqueness and Novelty Metrics for Generative Modeling of Inorganic Crystals},
|
|
124
|
+
author={Masahiro Negishi and Hyunsoo Park and Kinga O. Mastej and Aron Walsh},
|
|
125
|
+
year={2025},
|
|
126
|
+
eprint={2510.12405},
|
|
127
|
+
archivePrefix={arXiv},
|
|
128
|
+
primaryClass={cs.LG},
|
|
129
|
+
url={https://arxiv.org/abs/2510.12405},
|
|
130
|
+
}
|
|
131
|
+
```
|
xtalmet-0.1.0/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# xtalmet
|
|
2
|
+
[](https://opensource.org/licenses/MIT)
|
|
3
|
+
[](https://docs.astral.sh/ruff/)
|
|
4
|
+
[](https://docs.astral.sh/ruff/)
|
|
5
|
+
[](https://docs.astral.sh/uv/)
|
|
6
|
+
[](https://www.sphinx-doc.org/en/master/index.html)
|
|
7
|
+
[](https://github.com/WMD-group/xtalmet/issues)
|
|
8
|
+
[](https://github.com/WMD-group/xtalmet/actions/workflows/sphinx.yml)
|
|
9
|
+
|
|
10
|
+
The **xtalmet** package offers a variety of distance functions for comparing crystal structures.
|
|
11
|
+
These include both binary and continuous as well as compositional and structural functions.
|
|
12
|
+
It also enables you to evaluate a set of crystals using uniqueness and novelty metrics derived from these distances.
|
|
13
|
+
|
|
14
|
+
- Documentation: https://wmd-group.github.io/xtalmet/
|
|
15
|
+
- Examples: https://github.com/WMD-group/xtalmet/examples
|
|
16
|
+
|
|
17
|
+
## Motivation
|
|
18
|
+
A central challenge in materials science is the efficient discovery of functional crystals from the vast chemical space.
|
|
19
|
+
Recently, the inverse design of crystals using advanced machine learning generative models has emerged as a promising approach due to their ability to rapidly generate numerous candidates.
|
|
20
|
+
However, while these models have become increasingly sophisticated, their evaluation metrics have remained largely unchanged since the seminal work of Xie et al [1] and Zeni et al [2].
|
|
21
|
+
To effectively guide model development, these evaluation metrics must also continue to improve.
|
|
22
|
+
We aim to refine two primary metrics, uniqueness and novelty, by revising the underlying distance function used to compare crystal structures.
|
|
23
|
+
|
|
24
|
+
[1] Tian Xie et al. Crystal diffusion variational autoencoder for periodic material generation. International Conference on Learning Representations 2022.
|
|
25
|
+
|
|
26
|
+
[2] Claudio Zeni et al. A generative model for inorganic materials design. Nature 2025.
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
The latest stable version can be installed via pip:
|
|
30
|
+
```bash
|
|
31
|
+
pip install xtalmet
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
Two primary features of xtalmet are the calculation of distances between crystals and the uniqueness/novelty evaluation.
|
|
36
|
+
For the former usage, suppose you have two crystals `xtal_1` and `xtal_2` (`pymatgen.core.Structure`) whose distance you want to measure.
|
|
37
|
+
You can do so with one line of code:
|
|
38
|
+
```python
|
|
39
|
+
from xtalmet.distance import d_amd
|
|
40
|
+
distance = d_amd(xtal_1, xtal_2)
|
|
41
|
+
```
|
|
42
|
+
Here, d_amd is a type of continuous distance based on structural fingerprints.
|
|
43
|
+
For a complete list of available distances, please refer to the [documentation](https://wmd-group.github.io/xtalmet/api/xtalmet.distance.html).
|
|
44
|
+
|
|
45
|
+
For the uniqueness/novelty evaluation, imagine that you want to assess a set of crystals `gen_xtals` (`list[pymatgen.core.Structure]`) generated from a model trained on the MP20 dataset.
|
|
46
|
+
This can be done with just a few lines of code:
|
|
47
|
+
```python
|
|
48
|
+
from xtalmet.evaluator import Evaluator
|
|
49
|
+
evaluator = Evaluator(gen_xtals)
|
|
50
|
+
uniqueness = evaluator.uniqueness(distance="d_amd")
|
|
51
|
+
novelty = evaluator.novelty(train_xtals="mp20", distance="d_amd")
|
|
52
|
+
```
|
|
53
|
+
A more detailed tutorial notebook is provided in the [examples directory](https://github.com/WMD-group/xtalmet/tree/main/examples).
|
|
54
|
+
|
|
55
|
+
## Acknowledgements
|
|
56
|
+
Although we have argued that the progress on evaluation metrics is slower than that on generative models, we are not the sole contributors to this field.
|
|
57
|
+
Our work builds upon several influential studies.
|
|
58
|
+
We particularly acknowledge the following contributions:
|
|
59
|
+
|
|
60
|
+
- Zeni et al. [2]: For their implementation of the S.U.N. (Stability / Uniqueness / Novelty) metric.
|
|
61
|
+
|
|
62
|
+
- Baird et al. [3]: For their code for uniqueness and novelty, and their framework for creating a Python benchmarking package.
|
|
63
|
+
|
|
64
|
+
- Widdowson et al. [4, 5]: For their work on a continuous structural distance between crystals.
|
|
65
|
+
|
|
66
|
+
Other studies, while not directly related, were also inspiring in shaping our approach to measuring distances between crystals.
|
|
67
|
+
These include the work of Onwuli et al. [6] on distances between compositional embeddings, as well as Hargreaves et al.'s [7] development of optimal transport-based methods for inorganic compositions.
|
|
68
|
+
|
|
69
|
+
[3] Baird et al. matbench-genmetrics: A Python library for benchmarking crystal structure generative models using time-based splits of Materials Project structures. Journal of Open Source Software 2024.
|
|
70
|
+
|
|
71
|
+
[4] Widdowson et al. Resolving the data ambiguity for periodic crystals. Advances in Neural Information Processing Systems 2022.
|
|
72
|
+
|
|
73
|
+
[5] Widdson et al. Average Minimum Distances of periodic point sets - foundational invariants for mapping periodic crystals. MATCH Communications in Mathematical and in Computer Chemistry 2022.
|
|
74
|
+
|
|
75
|
+
[6] A. Onwuli et al. Element similarity in high-dimensional materials representations. Digital Discovery 2023.
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
[7] Hargreaves et al. The earth mover’s distance as a metric for the space of inorganic compositions. Chemistry of Materials 2020.
|
|
79
|
+
|
|
80
|
+
## Citation
|
|
81
|
+
If you find xtalmet useful in your research, please consider citing:
|
|
82
|
+
```bibtex
|
|
83
|
+
@misc{negishi2025continuousuniquenessnoveltymetrics,
|
|
84
|
+
title={Continuous Uniqueness and Novelty Metrics for Generative Modeling of Inorganic Crystals},
|
|
85
|
+
author={Masahiro Negishi and Hyunsoo Park and Kinga O. Mastej and Aron Walsh},
|
|
86
|
+
year={2025},
|
|
87
|
+
eprint={2510.12405},
|
|
88
|
+
archivePrefix={arXiv},
|
|
89
|
+
primaryClass={cs.LG},
|
|
90
|
+
url={https://arxiv.org/abs/2510.12405},
|
|
91
|
+
}
|
|
92
|
+
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "xtalmet"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Python package containing a variety of distance functions for crystals, as well as evaluation metrics for crystal generation."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Masahiro Negishi", email = "m.negishi25@imperial.ac.uk" }
|
|
8
|
+
]
|
|
9
|
+
requires-python = ">=3.12"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"pymatgen>=2025.5.28",
|
|
12
|
+
"torch>=2.7.0",
|
|
13
|
+
"matminer>=0.9.3",
|
|
14
|
+
"average-minimum-distance>=1.5.3",
|
|
15
|
+
"smact>=3.1.0",
|
|
16
|
+
"mace-torch>=0.3.13",
|
|
17
|
+
"huggingface_hub"
|
|
18
|
+
]
|
|
19
|
+
license = { file = "LICENSE" }
|
|
20
|
+
|
|
21
|
+
[project.urls]
|
|
22
|
+
Repository = "https://github.com/WMD-group/xtalmet/"
|
|
23
|
+
Documentation = "https://wmd-group.github.io/xtalmets/"
|
|
24
|
+
|
|
25
|
+
[dependency-groups]
|
|
26
|
+
dev = [
|
|
27
|
+
"pytest",
|
|
28
|
+
"colorama",
|
|
29
|
+
"seaborn",
|
|
30
|
+
"ipykernel",
|
|
31
|
+
"sphinx",
|
|
32
|
+
"sphinx-rtd-theme",
|
|
33
|
+
"sphinx-github-style",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[build-system]
|
|
37
|
+
requires = ["uv_build>=0.8.22,<0.9.0"]
|
|
38
|
+
build-backend = "uv_build"
|
|
39
|
+
|
|
40
|
+
[tool.ruff]
|
|
41
|
+
line-length = 88
|
|
42
|
+
|
|
43
|
+
[tool.ruff.lint]
|
|
44
|
+
select = [
|
|
45
|
+
"F", # flake8
|
|
46
|
+
"E", # pycodestyle
|
|
47
|
+
"W", # pycodestyle
|
|
48
|
+
"UP", # pyupgrade
|
|
49
|
+
"B", # flake8-bugbear
|
|
50
|
+
"SIM", # flake8-simplify
|
|
51
|
+
"I", # isort
|
|
52
|
+
"D", # pydocstyle
|
|
53
|
+
]
|
|
54
|
+
ignore = ["E101", "E501", "W191", "E111", "E114", "E117", "D206", "D300"]
|
|
55
|
+
fixable = ["ALL"]
|
|
56
|
+
pycodestyle.max-doc-length = 88
|
|
57
|
+
|
|
58
|
+
[tool.ruff.lint.pydocstyle]
|
|
59
|
+
convention = "google"
|
|
60
|
+
|
|
61
|
+
[tool.ruff.format]
|
|
62
|
+
quote-style = "double"
|
|
63
|
+
indent-style = "tab"
|
|
64
|
+
docstring-code-format = true
|
|
File without changes
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"""This module defines the Crystal class to store information about a single crystal."""
|
|
2
|
+
|
|
3
|
+
import warnings
|
|
4
|
+
from collections.abc import Sequence
|
|
5
|
+
|
|
6
|
+
import amd
|
|
7
|
+
import numpy as np
|
|
8
|
+
from amd import periodicset_from_pymatgen_structure
|
|
9
|
+
from ase import Atoms
|
|
10
|
+
from matminer.featurizers.composition.composite import ElementProperty
|
|
11
|
+
from numpy.typing import ArrayLike
|
|
12
|
+
from pymatgen.core import Composition, Lattice, Species, Structure
|
|
13
|
+
from pymatgen.io.ase import AseAtomsAdaptor
|
|
14
|
+
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
|
|
15
|
+
from pymatgen.util.typing import CompositionLike
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Crystal(Structure):
|
|
19
|
+
"""Container for a single crystal structure."""
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
lattice: ArrayLike | Lattice,
|
|
24
|
+
species: Sequence[CompositionLike],
|
|
25
|
+
coords: Sequence[ArrayLike],
|
|
26
|
+
charge: float | None = None,
|
|
27
|
+
validate_proximity: bool = False,
|
|
28
|
+
to_unit_cell: bool = False,
|
|
29
|
+
coords_are_cartesian: bool = False,
|
|
30
|
+
site_properties: dict | None = None,
|
|
31
|
+
labels: Sequence[str | None] | None = None,
|
|
32
|
+
properties: dict | None = None,
|
|
33
|
+
) -> None:
|
|
34
|
+
"""Initialize a Crystal object.
|
|
35
|
+
|
|
36
|
+
The parameters are the same as those used in the __init__() method of the
|
|
37
|
+
pymatgen.core.Structure class.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
lattice (Lattice/3x3 array): The lattice, either as a
|
|
41
|
+
pymatgen.core.Lattice or
|
|
42
|
+
simply as any 2D array. Each row should correspond to a lattice
|
|
43
|
+
vector. e.g. [[10,0,0], [20,10,0], [0,0,30]] specifies a
|
|
44
|
+
lattice with lattice vectors [10,0,0], [20,10,0] and [0,0,30].
|
|
45
|
+
species ([Species]): Sequence of species on each site. Can take in
|
|
46
|
+
flexible input, including:
|
|
47
|
+
|
|
48
|
+
i. A sequence of element / species specified either as string
|
|
49
|
+
symbols, e.g. ["Li", "Fe2+", "P", ...] or atomic numbers,
|
|
50
|
+
e.g. (3, 56, ...) or actual Element or Species objects.
|
|
51
|
+
|
|
52
|
+
ii. List of dict of elements/species and occupancies, e.g.
|
|
53
|
+
[{"Fe" : 0.5, "Mn":0.5}, ...]. This allows the setup of
|
|
54
|
+
disordered structures.
|
|
55
|
+
coords (Nx3 array): list of fractional/Cartesian coordinates of
|
|
56
|
+
each species.
|
|
57
|
+
charge (int): overall charge of the structure. Defaults to behavior
|
|
58
|
+
in SiteCollection where total charge is the sum of the oxidation
|
|
59
|
+
states.
|
|
60
|
+
validate_proximity (bool): Whether to check if there are sites
|
|
61
|
+
that are less than 0.01 Ang apart. Defaults to False.
|
|
62
|
+
to_unit_cell (bool): Whether to map all sites into the unit cell,
|
|
63
|
+
i.e. fractional coords between 0 and 1. Defaults to False.
|
|
64
|
+
coords_are_cartesian (bool): Set to True if you are providing
|
|
65
|
+
coordinates in Cartesian coordinates. Defaults to False.
|
|
66
|
+
site_properties (dict): Properties associated with the sites as a
|
|
67
|
+
dict of sequences, e.g. {"magmom":[5, 5, 5, 5]}. The sequences
|
|
68
|
+
have to be the same length as the atomic species and
|
|
69
|
+
fractional_coords. Defaults to None for no properties.
|
|
70
|
+
labels (list[str]): Labels associated with the sites as a
|
|
71
|
+
list of strings, e.g. ['Li1', 'Li2']. Must have the same
|
|
72
|
+
length as the species and fractional coords. Defaults to
|
|
73
|
+
None for no labels.
|
|
74
|
+
properties (dict): Properties associated with the whole structure.
|
|
75
|
+
Will be serialized when writing the structure to JSON or YAML but is
|
|
76
|
+
lost when converting to other formats.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
None
|
|
80
|
+
|
|
81
|
+
Note:
|
|
82
|
+
descriptions for args are copied from pymatgen.core.Structure class.
|
|
83
|
+
"""
|
|
84
|
+
super().__init__(
|
|
85
|
+
lattice,
|
|
86
|
+
[
|
|
87
|
+
specie.element if isinstance(specie, Species) else specie
|
|
88
|
+
for specie in species
|
|
89
|
+
], # not considering oxidation states
|
|
90
|
+
coords,
|
|
91
|
+
charge,
|
|
92
|
+
validate_proximity,
|
|
93
|
+
to_unit_cell,
|
|
94
|
+
coords_are_cartesian,
|
|
95
|
+
site_properties,
|
|
96
|
+
labels,
|
|
97
|
+
properties,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
@classmethod
|
|
101
|
+
def from_Structure(cls, structure: Structure) -> "Crystal":
|
|
102
|
+
"""Create a Crystal object from a pymatgen Structure object.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
structure (Structure): A pymatgen Structure object.
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
Crystal: A Crystal object created from the Structure.
|
|
109
|
+
"""
|
|
110
|
+
# internally calls __init__
|
|
111
|
+
return cls(
|
|
112
|
+
lattice=structure.lattice,
|
|
113
|
+
species=structure.species,
|
|
114
|
+
coords=structure.frac_coords,
|
|
115
|
+
charge=structure._charge,
|
|
116
|
+
validate_proximity=False,
|
|
117
|
+
to_unit_cell=False,
|
|
118
|
+
coords_are_cartesian=False,
|
|
119
|
+
site_properties=structure.site_properties,
|
|
120
|
+
labels=structure.labels,
|
|
121
|
+
properties=structure.properties,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
def get_composition_tuple(self) -> tuple[tuple[str, int]]:
|
|
125
|
+
"""Get the composition of the crystal as a tuple of (element, count).
|
|
126
|
+
|
|
127
|
+
Embedding for d_comp.
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
tuple: A tuple containing elements and their counts (divided by gcd).
|
|
131
|
+
"""
|
|
132
|
+
composition_unnorm = [
|
|
133
|
+
(elem, int(count))
|
|
134
|
+
for elem, count in dict(sorted(self.composition.as_dict().items())).items()
|
|
135
|
+
]
|
|
136
|
+
gcd = np.gcd.reduce([count for _, count in composition_unnorm]).item()
|
|
137
|
+
composition = tuple((elem, count // gcd) for elem, count in composition_unnorm)
|
|
138
|
+
return composition
|
|
139
|
+
|
|
140
|
+
def get_wyckoff(self) -> tuple[int, tuple[str]] | Exception:
|
|
141
|
+
"""Get the Wyckoff representation of the crystal.
|
|
142
|
+
|
|
143
|
+
Embedding for d_wyckoff.
|
|
144
|
+
|
|
145
|
+
Returns:
|
|
146
|
+
tuple | Exception: A tuple containing the space group number and a tuple of
|
|
147
|
+
Wyckoff letters, or an Exception from SpacegroupAnalyzer.
|
|
148
|
+
"""
|
|
149
|
+
sga = SpacegroupAnalyzer(self)
|
|
150
|
+
sym = sga.get_symmetrized_structure()
|
|
151
|
+
sg = sga.get_space_group_number()
|
|
152
|
+
wyckoff_letters = sorted(
|
|
153
|
+
[x[-1] for x in sym.wyckoff_symbols]
|
|
154
|
+
) # Don't use sym.wyckoff_letters
|
|
155
|
+
return sg, tuple(wyckoff_letters)
|
|
156
|
+
|
|
157
|
+
def get_magpie(self) -> list[float]:
|
|
158
|
+
"""Get the magpie embedding of the crystal.
|
|
159
|
+
|
|
160
|
+
Embedding for d_magpie. Not influenced by oxidation states.
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
list[float]: Magpie feature vector of the crystal.
|
|
164
|
+
|
|
165
|
+
References:
|
|
166
|
+
- Ward et al., (2016). A general-purpose machine learning framework for
|
|
167
|
+
predicting properties of inorganic materials. npj Computational Materials,
|
|
168
|
+
2(1), 1-7. https://doi.org/10.1038/npjcompumats.2016.28
|
|
169
|
+
"""
|
|
170
|
+
if not hasattr(self, "featurizer"):
|
|
171
|
+
self.featurizer = ElementProperty.from_preset("magpie", impute_nan=True)
|
|
172
|
+
feature = self.featurizer.featurize(self.composition)
|
|
173
|
+
return [float(x) for x in feature]
|
|
174
|
+
|
|
175
|
+
def get_PDD(
|
|
176
|
+
self, k: int = 100, **kwargs
|
|
177
|
+
) -> np.ndarray[np.float32 | np.float64] | Exception:
|
|
178
|
+
"""Get the pointwise distance distribution (PDD) of the crystal.
|
|
179
|
+
|
|
180
|
+
Embedding for d_ppd.
|
|
181
|
+
|
|
182
|
+
Args:
|
|
183
|
+
k (int): Number of nearest neighbors to consider.
|
|
184
|
+
**kwargs: Additional arguments for amd.PDD, except k.
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
np.ndarray[np.float32 | np.float64] | Exception: PDD or an Exception
|
|
188
|
+
from periodicset_from_pymatgen_structure
|
|
189
|
+
|
|
190
|
+
References:
|
|
191
|
+
- Widdowson et al., (2022). Resolving the data ambiguity for periodic
|
|
192
|
+
crystals. Advances in Neural Information Processing Systems, 35,
|
|
193
|
+
24625--24638. https://openreview.net/forum?id=4wrB7Mo9_OQ
|
|
194
|
+
"""
|
|
195
|
+
if "return_row_data" in kwargs and kwargs["return_row_data"] is True:
|
|
196
|
+
warnings.warn(
|
|
197
|
+
"return_row_data=True is not supported. Automatically set to False.",
|
|
198
|
+
UserWarning,
|
|
199
|
+
stacklevel=2,
|
|
200
|
+
)
|
|
201
|
+
kwargs["return_row_data"] = False
|
|
202
|
+
|
|
203
|
+
return amd.PDD(periodicset_from_pymatgen_structure(self), k, **kwargs)
|
|
204
|
+
|
|
205
|
+
def get_AMD(self, k: int = 100) -> np.ndarray[np.float32 | np.float64] | Exception:
|
|
206
|
+
"""Get the average minimum distance (AMD) of the crystal.
|
|
207
|
+
|
|
208
|
+
Embedding for d_amd.
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
k (int): Number of nearest neighbors to consider. Also the embedding length.
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
np.ndarray[np.float32 | np.float64] | Exception: AMD or an Exception
|
|
215
|
+
from periodicset_from_pymatgen_structure
|
|
216
|
+
|
|
217
|
+
References:
|
|
218
|
+
- Widdson et al., (2022). Average Minimum Distances of periodic point sets -
|
|
219
|
+
foundational invariants for mapping periodic crystals. MATCH
|
|
220
|
+
Communications in Mathematical and in Computer Chemistry, 87(3), 529-559,
|
|
221
|
+
https://doi.org/10.46793/match.87-3.529W
|
|
222
|
+
"""
|
|
223
|
+
return amd.AMD(periodicset_from_pymatgen_structure(self), k)
|
|
224
|
+
|
|
225
|
+
def get_composition_pymatgen(self) -> Composition:
|
|
226
|
+
"""Get the pymatgen composition of the crystal.
|
|
227
|
+
|
|
228
|
+
Called when screening using SMACT or E_hull.
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
Composition: Pymatgen Composition object.
|
|
232
|
+
"""
|
|
233
|
+
return self.composition
|
|
234
|
+
|
|
235
|
+
def get_ase_atoms(self) -> Atoms:
|
|
236
|
+
"""Get the ASE Atoms object of the crystal.
|
|
237
|
+
|
|
238
|
+
Called when screening using E_hull. Not influenced by oxidation states.
|
|
239
|
+
|
|
240
|
+
Returns:
|
|
241
|
+
Atoms: ASE Atoms object.
|
|
242
|
+
"""
|
|
243
|
+
return AseAtomsAdaptor.get_atoms(self)
|