SMACT 2.5.2__tar.gz → 2.5.4__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.
- {SMACT-2.5.2 → SMACT-2.5.4}/PKG-INFO +22 -2
- SMACT-2.5.2/SMACT.egg-info/PKG-INFO → SMACT-2.5.4/README.md +13 -25
- SMACT-2.5.2/README.md → SMACT-2.5.4/SMACT.egg-info/PKG-INFO +45 -1
- {SMACT-2.5.2 → SMACT-2.5.4}/setup.py +3 -2
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/__init__.py +38 -4
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/element_data.txt +1 -1
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data_loader.py +56 -9
- SMACT-2.5.4/smact/dopant_prediction/doper.py +212 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/screening.py +8 -2
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/structure_prediction/database.py +1 -3
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/structure_prediction/mutation.py +1 -2
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/structure_prediction/prediction.py +1 -2
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/structure_prediction/structure.py +5 -5
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/tests/test_core.py +15 -5
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/tests/test_structure.py +1 -3
- SMACT-2.5.2/smact/dopant_prediction/doper.py +0 -186
- {SMACT-2.5.2 → SMACT-2.5.4}/LICENSE +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/MANIFEST.in +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/SMACT.egg-info/SOURCES.txt +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/SMACT.egg-info/dependency_links.txt +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/SMACT.egg-info/not-zip-safe +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/SMACT.egg-info/requires.txt +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/SMACT.egg-info/top_level.txt +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/pyproject.toml +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/setup.cfg +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/builder.py +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/Covalent_radii.csv +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/HHIs.txt +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/SSE.csv +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/SSE_2015.csv +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/SSE_Pauling.csv +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/ionic_radii.csv +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/ordered_periodic.txt +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/oxidation_state_probability_table.json +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/oxidation_states.txt +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/oxidation_states_SP.txt +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/oxidation_states_icsd.txt +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/oxidation_states_pmg.txt +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/oxidation_states_wiki.txt +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/oxidationstates.data +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/shannon_radii.csv +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/shannon_radii_ML_extended.csv +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/solid_properties.txt +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/data/solid_properties.xlsx +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/distorter.py +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/dopant_prediction/__init__.py +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/lattice.py +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/lattice_parameters.py +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/mainpage.py +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/oxidation_states.py +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/properties.py +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/structure_prediction/__init__.py +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/structure_prediction/probability_models.py +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/structure_prediction/utilities.py +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/tests/__init__.py +0 -0
- {SMACT-2.5.2 → SMACT-2.5.4}/smact/tests/test_doper.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: SMACT
|
|
3
|
-
Version: 2.5.
|
|
3
|
+
Version: 2.5.4
|
|
4
4
|
Summary: Semiconducting Materials by Analogy and Chemical Theory
|
|
5
5
|
Home-page: https://github.com/WMD-group/SMACT
|
|
6
6
|
Author: Daniel W. Davies
|
|
@@ -12,6 +12,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.8
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.9
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
16
|
Classifier: Development Status :: 5 - Production/Stable
|
|
16
17
|
Classifier: Intended Audience :: Science/Research
|
|
17
18
|
Classifier: Operating System :: OS Independent
|
|
@@ -21,6 +22,13 @@ Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
|
21
22
|
Requires-Python: >=3.8
|
|
22
23
|
Description-Content-Type: text/markdown
|
|
23
24
|
License-File: LICENSE
|
|
25
|
+
Requires-Dist: scipy
|
|
26
|
+
Requires-Dist: numpy
|
|
27
|
+
Requires-Dist: spglib
|
|
28
|
+
Requires-Dist: pymatgen
|
|
29
|
+
Requires-Dist: ase
|
|
30
|
+
Requires-Dist: pandas
|
|
31
|
+
Requires-Dist: pathos
|
|
24
32
|
|
|
25
33
|
[](https://doi.org/10.21105/joss.01361)
|
|
26
34
|
[](https://doi.org/10.5281/zenodo.5553202)
|
|
@@ -29,6 +37,7 @@ License-File: LICENSE
|
|
|
29
37
|

|
|
30
38
|
[](https://github.com/psf/black)
|
|
31
39
|
[](https://pypi.org/project/SMACT/)
|
|
40
|
+
[](https://anaconda.org/conda-forge/smact)
|
|
32
41
|
[](https://github.com/WMD-group/SMACT/issues)
|
|
33
42
|

|
|
34
43
|
[](https://github.com/WMD-group/SMACT/actions/workflows/ci.yml)
|
|
@@ -83,7 +92,9 @@ Code features
|
|
|
83
92
|
- The code also has some tools for manipulating common crystal lattice types:
|
|
84
93
|
- Common crystal structure types can be built using the [builder module](https://smact.readthedocs.io/en/latest/smact.builder.html)
|
|
85
94
|
- Lattice parameters can be quickly estimated using ionic radii of the elements for various common crystal structure types using the [lattice_parameters module](https://smact.readthedocs.io/en/latest/smact.lattice_parameters.html).
|
|
86
|
-
- The [lattice module](https://smact.readthedocs.io/en/latest/smact.lattice.html) and [distorter module](https://smact.readthedocs.io/en/latest/smact.distorter.html) rely on the [Atomic Simulation Environment](https://wiki.fysik.dtu.dk/ase/) and can be used to generate unique atomic substitutions on a given crystal structure.
|
|
95
|
+
- The [lattice module](https://smact.readthedocs.io/en/latest/smact.lattice.html) and [distorter module](https://smact.readthedocs.io/en/latest/smact.distorter.html) rely on the [Atomic Simulation Environment](https://wiki.fysik.dtu.dk/ase/) and can be used to generate unique atomic substitutions on a given crystal structure.
|
|
96
|
+
- The [structure prediction](https://smact.readthedocs.io/en/latest/smact.structure_prediction.html) module can be used to predict the structure of hypothetical compositions using species similarity measures.
|
|
97
|
+
- The [dopant prediction](https://smact.readthedocs.io/en/latest/smact.dopant_prediction.html) module can be used to facilitate high-throughput predictions of p-type and n-type dopants of multicomponent solids.
|
|
87
98
|
|
|
88
99
|
List of modules
|
|
89
100
|
-------
|
|
@@ -101,6 +112,9 @@ List of modules
|
|
|
101
112
|
* **lattice_parameters.py** Estimation of lattice parameters for various lattice types using covalent/ionic radii.
|
|
102
113
|
* **distorter.py** A collection of functions for enumerating and then
|
|
103
114
|
substituting on inequivalent sites of a sub-lattice.
|
|
115
|
+
* **oxidation_states.py**: Used for predicting the likelihood of species coexisting in a compound based on a statistical model.
|
|
116
|
+
* **structure_prediction**: A submodule which contains a collection of tools for facilitating crystal structure predictions via ionic substitutions
|
|
117
|
+
* **dopant_prediction**: A submodule which contains a collections of tools for predicting n-type and p-type dopants.
|
|
104
118
|
|
|
105
119
|
Requirements
|
|
106
120
|
------------
|
|
@@ -115,6 +129,12 @@ The latest stable release of SMACT can be installed via pip which will automatic
|
|
|
115
129
|
|
|
116
130
|
pip install smact
|
|
117
131
|
|
|
132
|
+
SMACT is also available via conda through the conda-forge channel on Anaconda Cloud:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
conda install -c conda-forge smact
|
|
136
|
+
```
|
|
137
|
+
|
|
118
138
|
Alternatively, the very latest version can be installed using:
|
|
119
139
|
|
|
120
140
|
pip install git+git://github.com/WMD-group/SMACT.git
|
|
@@ -1,27 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: SMACT
|
|
3
|
-
Version: 2.5.2
|
|
4
|
-
Summary: Semiconducting Materials by Analogy and Chemical Theory
|
|
5
|
-
Home-page: https://github.com/WMD-group/SMACT
|
|
6
|
-
Author: Daniel W. Davies
|
|
7
|
-
Author-email: d.w.davies@imperial.ac.uk
|
|
8
|
-
Maintainer: Anthony O. Onwuli
|
|
9
|
-
Maintainer-email: anthony.onwuli16@imperial.ac.uk
|
|
10
|
-
License: MIT
|
|
11
|
-
Classifier: Programming Language :: Python :: 3
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
16
|
-
Classifier: Intended Audience :: Science/Research
|
|
17
|
-
Classifier: Operating System :: OS Independent
|
|
18
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
19
|
-
Classifier: Topic :: Scientific/Engineering
|
|
20
|
-
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
21
|
-
Requires-Python: >=3.8
|
|
22
|
-
Description-Content-Type: text/markdown
|
|
23
|
-
License-File: LICENSE
|
|
24
|
-
|
|
25
1
|
[](https://doi.org/10.21105/joss.01361)
|
|
26
2
|
[](https://doi.org/10.5281/zenodo.5553202)
|
|
27
3
|
[](http://smact.readthedocs.org/en/latest/?badge=latest)
|
|
@@ -29,6 +5,7 @@ License-File: LICENSE
|
|
|
29
5
|

|
|
30
6
|
[](https://github.com/psf/black)
|
|
31
7
|
[](https://pypi.org/project/SMACT/)
|
|
8
|
+
[](https://anaconda.org/conda-forge/smact)
|
|
32
9
|
[](https://github.com/WMD-group/SMACT/issues)
|
|
33
10
|

|
|
34
11
|
[](https://github.com/WMD-group/SMACT/actions/workflows/ci.yml)
|
|
@@ -83,7 +60,9 @@ Code features
|
|
|
83
60
|
- The code also has some tools for manipulating common crystal lattice types:
|
|
84
61
|
- Common crystal structure types can be built using the [builder module](https://smact.readthedocs.io/en/latest/smact.builder.html)
|
|
85
62
|
- Lattice parameters can be quickly estimated using ionic radii of the elements for various common crystal structure types using the [lattice_parameters module](https://smact.readthedocs.io/en/latest/smact.lattice_parameters.html).
|
|
86
|
-
- The [lattice module](https://smact.readthedocs.io/en/latest/smact.lattice.html) and [distorter module](https://smact.readthedocs.io/en/latest/smact.distorter.html) rely on the [Atomic Simulation Environment](https://wiki.fysik.dtu.dk/ase/) and can be used to generate unique atomic substitutions on a given crystal structure.
|
|
63
|
+
- The [lattice module](https://smact.readthedocs.io/en/latest/smact.lattice.html) and [distorter module](https://smact.readthedocs.io/en/latest/smact.distorter.html) rely on the [Atomic Simulation Environment](https://wiki.fysik.dtu.dk/ase/) and can be used to generate unique atomic substitutions on a given crystal structure.
|
|
64
|
+
- The [structure prediction](https://smact.readthedocs.io/en/latest/smact.structure_prediction.html) module can be used to predict the structure of hypothetical compositions using species similarity measures.
|
|
65
|
+
- The [dopant prediction](https://smact.readthedocs.io/en/latest/smact.dopant_prediction.html) module can be used to facilitate high-throughput predictions of p-type and n-type dopants of multicomponent solids.
|
|
87
66
|
|
|
88
67
|
List of modules
|
|
89
68
|
-------
|
|
@@ -101,6 +80,9 @@ List of modules
|
|
|
101
80
|
* **lattice_parameters.py** Estimation of lattice parameters for various lattice types using covalent/ionic radii.
|
|
102
81
|
* **distorter.py** A collection of functions for enumerating and then
|
|
103
82
|
substituting on inequivalent sites of a sub-lattice.
|
|
83
|
+
* **oxidation_states.py**: Used for predicting the likelihood of species coexisting in a compound based on a statistical model.
|
|
84
|
+
* **structure_prediction**: A submodule which contains a collection of tools for facilitating crystal structure predictions via ionic substitutions
|
|
85
|
+
* **dopant_prediction**: A submodule which contains a collections of tools for predicting n-type and p-type dopants.
|
|
104
86
|
|
|
105
87
|
Requirements
|
|
106
88
|
------------
|
|
@@ -115,6 +97,12 @@ The latest stable release of SMACT can be installed via pip which will automatic
|
|
|
115
97
|
|
|
116
98
|
pip install smact
|
|
117
99
|
|
|
100
|
+
SMACT is also available via conda through the conda-forge channel on Anaconda Cloud:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
conda install -c conda-forge smact
|
|
104
|
+
```
|
|
105
|
+
|
|
118
106
|
Alternatively, the very latest version can be installed using:
|
|
119
107
|
|
|
120
108
|
pip install git+git://github.com/WMD-group/SMACT.git
|
|
@@ -1,3 +1,35 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: SMACT
|
|
3
|
+
Version: 2.5.4
|
|
4
|
+
Summary: Semiconducting Materials by Analogy and Chemical Theory
|
|
5
|
+
Home-page: https://github.com/WMD-group/SMACT
|
|
6
|
+
Author: Daniel W. Davies
|
|
7
|
+
Author-email: d.w.davies@imperial.ac.uk
|
|
8
|
+
Maintainer: Anthony O. Onwuli
|
|
9
|
+
Maintainer-email: anthony.onwuli16@imperial.ac.uk
|
|
10
|
+
License: MIT
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
17
|
+
Classifier: Intended Audience :: Science/Research
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
22
|
+
Requires-Python: >=3.8
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: scipy
|
|
26
|
+
Requires-Dist: numpy
|
|
27
|
+
Requires-Dist: spglib
|
|
28
|
+
Requires-Dist: pymatgen
|
|
29
|
+
Requires-Dist: ase
|
|
30
|
+
Requires-Dist: pandas
|
|
31
|
+
Requires-Dist: pathos
|
|
32
|
+
|
|
1
33
|
[](https://doi.org/10.21105/joss.01361)
|
|
2
34
|
[](https://doi.org/10.5281/zenodo.5553202)
|
|
3
35
|
[](http://smact.readthedocs.org/en/latest/?badge=latest)
|
|
@@ -5,6 +37,7 @@
|
|
|
5
37
|

|
|
6
38
|
[](https://github.com/psf/black)
|
|
7
39
|
[](https://pypi.org/project/SMACT/)
|
|
40
|
+
[](https://anaconda.org/conda-forge/smact)
|
|
8
41
|
[](https://github.com/WMD-group/SMACT/issues)
|
|
9
42
|

|
|
10
43
|
[](https://github.com/WMD-group/SMACT/actions/workflows/ci.yml)
|
|
@@ -59,7 +92,9 @@ Code features
|
|
|
59
92
|
- The code also has some tools for manipulating common crystal lattice types:
|
|
60
93
|
- Common crystal structure types can be built using the [builder module](https://smact.readthedocs.io/en/latest/smact.builder.html)
|
|
61
94
|
- Lattice parameters can be quickly estimated using ionic radii of the elements for various common crystal structure types using the [lattice_parameters module](https://smact.readthedocs.io/en/latest/smact.lattice_parameters.html).
|
|
62
|
-
- The [lattice module](https://smact.readthedocs.io/en/latest/smact.lattice.html) and [distorter module](https://smact.readthedocs.io/en/latest/smact.distorter.html) rely on the [Atomic Simulation Environment](https://wiki.fysik.dtu.dk/ase/) and can be used to generate unique atomic substitutions on a given crystal structure.
|
|
95
|
+
- The [lattice module](https://smact.readthedocs.io/en/latest/smact.lattice.html) and [distorter module](https://smact.readthedocs.io/en/latest/smact.distorter.html) rely on the [Atomic Simulation Environment](https://wiki.fysik.dtu.dk/ase/) and can be used to generate unique atomic substitutions on a given crystal structure.
|
|
96
|
+
- The [structure prediction](https://smact.readthedocs.io/en/latest/smact.structure_prediction.html) module can be used to predict the structure of hypothetical compositions using species similarity measures.
|
|
97
|
+
- The [dopant prediction](https://smact.readthedocs.io/en/latest/smact.dopant_prediction.html) module can be used to facilitate high-throughput predictions of p-type and n-type dopants of multicomponent solids.
|
|
63
98
|
|
|
64
99
|
List of modules
|
|
65
100
|
-------
|
|
@@ -77,6 +112,9 @@ List of modules
|
|
|
77
112
|
* **lattice_parameters.py** Estimation of lattice parameters for various lattice types using covalent/ionic radii.
|
|
78
113
|
* **distorter.py** A collection of functions for enumerating and then
|
|
79
114
|
substituting on inequivalent sites of a sub-lattice.
|
|
115
|
+
* **oxidation_states.py**: Used for predicting the likelihood of species coexisting in a compound based on a statistical model.
|
|
116
|
+
* **structure_prediction**: A submodule which contains a collection of tools for facilitating crystal structure predictions via ionic substitutions
|
|
117
|
+
* **dopant_prediction**: A submodule which contains a collections of tools for predicting n-type and p-type dopants.
|
|
80
118
|
|
|
81
119
|
Requirements
|
|
82
120
|
------------
|
|
@@ -91,6 +129,12 @@ The latest stable release of SMACT can be installed via pip which will automatic
|
|
|
91
129
|
|
|
92
130
|
pip install smact
|
|
93
131
|
|
|
132
|
+
SMACT is also available via conda through the conda-forge channel on Anaconda Cloud:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
conda install -c conda-forge smact
|
|
136
|
+
```
|
|
137
|
+
|
|
94
138
|
Alternatively, the very latest version can be installed using:
|
|
95
139
|
|
|
96
140
|
pip install git+git://github.com/WMD-group/SMACT.git
|
|
@@ -5,10 +5,10 @@ __author_email__ = "d.w.davies@imperial.ac.uk"
|
|
|
5
5
|
__copyright__ = (
|
|
6
6
|
"Copyright Daniel W. Davies, Adam J. Jackson, Keith T. Butler (2019)"
|
|
7
7
|
)
|
|
8
|
-
__version__ = "2.5.
|
|
8
|
+
__version__ = "2.5.4"
|
|
9
9
|
__maintainer__ = "Anthony O. Onwuli"
|
|
10
10
|
__maintaier_email__ = "anthony.onwuli16@imperial.ac.uk"
|
|
11
|
-
__date__ = "
|
|
11
|
+
__date__ = "November 30 2023"
|
|
12
12
|
|
|
13
13
|
import os
|
|
14
14
|
import unittest
|
|
@@ -61,6 +61,7 @@ if __name__ == "__main__":
|
|
|
61
61
|
"Programming Language :: Python :: 3.8",
|
|
62
62
|
"Programming Language :: Python :: 3.9",
|
|
63
63
|
"Programming Language :: Python :: 3.10",
|
|
64
|
+
"Programming Language :: Python :: 3.11",
|
|
64
65
|
"Development Status :: 5 - Production/Stable",
|
|
65
66
|
"Intended Audience :: Science/Research",
|
|
66
67
|
"Operating System :: OS Independent",
|
|
@@ -59,6 +59,8 @@ class Element:
|
|
|
59
59
|
|
|
60
60
|
Element.oxidation_states_wiki (list): List of oxidation states that appear wikipedia (https://en.wikipedia.org/wiki/Template:List_of_oxidation_states_of_the_elements) Data retrieved: 2022-09-22
|
|
61
61
|
|
|
62
|
+
Element.oxidation_states_custom (list | None ): List of oxidation states that appear in the custom data file supplied (if any)
|
|
63
|
+
|
|
62
64
|
Element.coord_envs (list): The allowed coordination enviroments for the ion
|
|
63
65
|
|
|
64
66
|
Element.covalent_radius (float) : Covalent radius of the element
|
|
@@ -77,15 +79,35 @@ class Element:
|
|
|
77
79
|
|
|
78
80
|
"""
|
|
79
81
|
|
|
80
|
-
def __init__(
|
|
82
|
+
def __init__(
|
|
83
|
+
self, symbol: str, oxi_states_custom_filepath: Optional[str] = None
|
|
84
|
+
):
|
|
81
85
|
"""Initialise Element class
|
|
82
86
|
|
|
83
87
|
Args:
|
|
84
88
|
symbol (str): Chemical element symbol (e.g. 'Fe')
|
|
89
|
+
oxi_states_custom_filepath (str): Path to custom oxidation states file
|
|
85
90
|
|
|
86
91
|
"""
|
|
92
|
+
# Get the oxidation states from the custom file if it exists
|
|
93
|
+
if oxi_states_custom_filepath:
|
|
94
|
+
try:
|
|
95
|
+
self._oxidation_states_custom = (
|
|
96
|
+
data_loader.lookup_element_oxidation_states_custom(
|
|
97
|
+
symbol, oxi_states_custom_filepath
|
|
98
|
+
)
|
|
99
|
+
)
|
|
100
|
+
self.oxidation_states_custom = self._oxidation_states_custom
|
|
101
|
+
except TypeError:
|
|
102
|
+
warnings.warn(
|
|
103
|
+
"Custom oxidation states file not found. Please check the file path."
|
|
104
|
+
)
|
|
105
|
+
self.oxidation_states_custom = None
|
|
106
|
+
else:
|
|
107
|
+
self.oxidation_states_custom = None
|
|
108
|
+
self.symbol = symbol
|
|
87
109
|
|
|
88
|
-
dataset = data_loader.lookup_element_data(symbol, copy=False)
|
|
110
|
+
dataset = data_loader.lookup_element_data(self.symbol, copy=False)
|
|
89
111
|
|
|
90
112
|
if dataset == None:
|
|
91
113
|
raise NameError(f"Elemental data for {symbol} not found.")
|
|
@@ -307,7 +329,10 @@ def ordered_elements(x: int, y: int) -> List[str]:
|
|
|
307
329
|
return ordered_elements
|
|
308
330
|
|
|
309
331
|
|
|
310
|
-
def element_dictionary(
|
|
332
|
+
def element_dictionary(
|
|
333
|
+
elements: Optional[Iterable[str]] = None,
|
|
334
|
+
oxi_states_custom_filepath: Optional[str] = None,
|
|
335
|
+
):
|
|
311
336
|
"""
|
|
312
337
|
Create a dictionary of initialised smact.Element objects
|
|
313
338
|
|
|
@@ -317,13 +342,22 @@ def element_dictionary(elements: Optional[Iterable[str]] = None):
|
|
|
317
342
|
Args:
|
|
318
343
|
elements (iterable of strings) : Elements to include. If None,
|
|
319
344
|
use all elements up to 103.
|
|
345
|
+
oxi_states_custom_filepath (str): Path to custom oxidation states file
|
|
346
|
+
|
|
347
|
+
|
|
320
348
|
Returns:
|
|
321
349
|
dict: Dictionary with element symbols as keys and smact.Element
|
|
322
350
|
objects as data
|
|
323
351
|
"""
|
|
324
352
|
if elements == None:
|
|
325
353
|
elements = ordered_elements(1, 103)
|
|
326
|
-
|
|
354
|
+
if oxi_states_custom_filepath:
|
|
355
|
+
return {
|
|
356
|
+
symbol: Element(symbol, oxi_states_custom_filepath)
|
|
357
|
+
for symbol in elements
|
|
358
|
+
}
|
|
359
|
+
else:
|
|
360
|
+
return {symbol: Element(symbol) for symbol in elements}
|
|
327
361
|
|
|
328
362
|
|
|
329
363
|
def are_eq(A: list, B: list, tolerance: float = 1e-4):
|
|
@@ -97,7 +97,7 @@ Kr Krypton 36 83.7980000000 1.16 None -13.00 -26.50 1
|
|
|
97
97
|
Rb Rubidium 37 85.4678000000 2.20 0.485916 None -3.94 9.00e+01 0.82 4.177128 316.20
|
|
98
98
|
Sr Strontium 38 87.6200000000 1.95 0.05206 None -5.00 3.70e+02 0.95 5.69486720 190.82
|
|
99
99
|
Y Yttrium 39 88.9058400000 1.90 0.307 None -5.53 3.30e+01 1.22 6.21726 153.00
|
|
100
|
-
Zr Zirconium 40 91.2240000000 1.75 0.426 None None 1.65e+02
|
|
100
|
+
Zr Zirconium 40 91.2240000000 1.75 0.426 None None 1.65e+02 1.33 6.63390 121.00
|
|
101
101
|
Nb Niobium 41 92.9063700000 1.64 0.893 None None 2.20e+02 1.6 6.75885 106.00
|
|
102
102
|
Mo Molybdenum 42 95.9500000000 1.54 0.7472 None None 1.20e+00 2.16 7.09243 72.50
|
|
103
103
|
Tc Technetium 43 98.0000000000 1.47 0.55 None None None 2.10 7.11938 80.40
|
|
@@ -269,6 +269,59 @@ def lookup_element_oxidation_states_wiki(symbol, copy=True):
|
|
|
269
269
|
return None
|
|
270
270
|
|
|
271
271
|
|
|
272
|
+
_el_ox_states_custom = None
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def lookup_element_oxidation_states_custom(symbol, filepath, copy=True):
|
|
276
|
+
"""
|
|
277
|
+
Retrieve a list of known oxidation states for an element.
|
|
278
|
+
The oxidation states list is specified by the user in a text file.
|
|
279
|
+
|
|
280
|
+
Args:
|
|
281
|
+
symbol (str) : the atomic symbol of the element to look up.
|
|
282
|
+
copy (Optional(bool)): if True (default), return a copy of the
|
|
283
|
+
oxidation-state list, rather than a reference to the cached
|
|
284
|
+
data -- only use copy=False in performance-sensitive code
|
|
285
|
+
and where the list will not be modified!
|
|
286
|
+
|
|
287
|
+
Returns:
|
|
288
|
+
list: List of known oxidation states for the element.
|
|
289
|
+
|
|
290
|
+
Return None if oxidation states for the Element were not
|
|
291
|
+
found in the external data.
|
|
292
|
+
"""
|
|
293
|
+
|
|
294
|
+
global _el_ox_states_custom
|
|
295
|
+
|
|
296
|
+
if _el_ox_states_custom is None:
|
|
297
|
+
_el_ox_states_custom = {}
|
|
298
|
+
|
|
299
|
+
for items in _get_data_rows(filepath):
|
|
300
|
+
_el_ox_states_custom[items[0]] = [
|
|
301
|
+
int(oxidationState) for oxidationState in items[1:]
|
|
302
|
+
]
|
|
303
|
+
|
|
304
|
+
if symbol in _el_ox_states_custom:
|
|
305
|
+
if copy:
|
|
306
|
+
# _el_ox_states_custom stores lists -> if copy is set, make an implicit
|
|
307
|
+
# deep copy. The elements of the lists are integers, which are
|
|
308
|
+
# "value types" in Python.
|
|
309
|
+
|
|
310
|
+
return [
|
|
311
|
+
oxidationState
|
|
312
|
+
for oxidationState in _el_ox_states_custom[symbol]
|
|
313
|
+
]
|
|
314
|
+
else:
|
|
315
|
+
return _el_ox_states_custom[symbol]
|
|
316
|
+
else:
|
|
317
|
+
if _print_warnings:
|
|
318
|
+
print(
|
|
319
|
+
"WARNING: Oxidation states for element {} "
|
|
320
|
+
"not found.".format(symbol)
|
|
321
|
+
)
|
|
322
|
+
return None
|
|
323
|
+
|
|
324
|
+
|
|
272
325
|
# Loader and cache for the element HHI scores.
|
|
273
326
|
|
|
274
327
|
_element_hhis = None
|
|
@@ -367,9 +420,7 @@ def lookup_element_data(symbol, copy=True):
|
|
|
367
420
|
# or, if not clearly a number, to None
|
|
368
421
|
clean_items = items[0:2] + list(map(float_or_None, items[2:]))
|
|
369
422
|
|
|
370
|
-
_element_data.update(
|
|
371
|
-
{items[0]: dict(list(zip(keys, clean_items)))}
|
|
372
|
-
)
|
|
423
|
+
_element_data.update({items[0]: dict(list(zip(keys, clean_items)))})
|
|
373
424
|
|
|
374
425
|
if symbol in _element_data:
|
|
375
426
|
if copy:
|
|
@@ -384,9 +435,7 @@ def lookup_element_data(symbol, copy=True):
|
|
|
384
435
|
return _element_data[symbol]
|
|
385
436
|
else:
|
|
386
437
|
if _print_warnings:
|
|
387
|
-
print(
|
|
388
|
-
"WARNING: Elemental data for {}" " not found.".format(symbol)
|
|
389
|
-
)
|
|
438
|
+
print("WARNING: Elemental data for {}" " not found.".format(symbol))
|
|
390
439
|
print(_element_data)
|
|
391
440
|
return None
|
|
392
441
|
|
|
@@ -471,9 +520,7 @@ def lookup_element_shannon_radius_data(symbol, copy=True):
|
|
|
471
520
|
# function on each element.
|
|
472
521
|
# The dictionary values are all Python "value types", so
|
|
473
522
|
# nothing further is required to make a deep copy.
|
|
474
|
-
return [
|
|
475
|
-
item.copy() for item in _element_shannon_radii_data[symbol]
|
|
476
|
-
]
|
|
523
|
+
return [item.copy() for item in _element_shannon_radii_data[symbol]]
|
|
477
524
|
else:
|
|
478
525
|
return _element_shannon_radii_data[symbol]
|
|
479
526
|
else:
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
from typing import List, Tuple
|
|
2
|
+
|
|
3
|
+
from pymatgen.util import plotting
|
|
4
|
+
|
|
5
|
+
import smact
|
|
6
|
+
from smact.structure_prediction import mutation, utilities
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Doper:
|
|
10
|
+
"""
|
|
11
|
+
A class to search for n & p type dopants
|
|
12
|
+
Methods: get_dopants, plot_dopants
|
|
13
|
+
|
|
14
|
+
Attributes:
|
|
15
|
+
_original_species: A tuple which describes the constituent species of a material. For example:
|
|
16
|
+
|
|
17
|
+
>>> test= Doper(("Zn2+","S2-"))
|
|
18
|
+
>>> test.original_species
|
|
19
|
+
('Zn2+','S2-')
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self, _original_species: Tuple[str, ...], filepath: str = None
|
|
25
|
+
):
|
|
26
|
+
"""
|
|
27
|
+
Intialise the `Doper` class with a tuple of species
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
_original_species: See :class:`~.Doper`.
|
|
31
|
+
filepath (str): lambda table json file
|
|
32
|
+
|
|
33
|
+
"""
|
|
34
|
+
self._original_species = _original_species
|
|
35
|
+
self._filepath = filepath
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def original_species(self):
|
|
39
|
+
return self._original_species
|
|
40
|
+
|
|
41
|
+
@original_species.setter
|
|
42
|
+
def original_species(self, original_species):
|
|
43
|
+
self._original_species = original_species
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def filepath(self):
|
|
47
|
+
return self._filepath
|
|
48
|
+
|
|
49
|
+
@filepath.setter
|
|
50
|
+
def filepath(self, filepath):
|
|
51
|
+
self._filepath = filepath
|
|
52
|
+
|
|
53
|
+
def _get_cation_dopants(
|
|
54
|
+
self, element_objects: List[smact.Element], cations: List[str]
|
|
55
|
+
):
|
|
56
|
+
poss_n_type_cat = set()
|
|
57
|
+
poss_p_type_cat = set()
|
|
58
|
+
|
|
59
|
+
for element in element_objects:
|
|
60
|
+
# [-2, -1, 0, +1, +2]
|
|
61
|
+
oxi_state = element.oxidation_states
|
|
62
|
+
el_symbol = element.symbol
|
|
63
|
+
for state in oxi_state:
|
|
64
|
+
for cation in cations:
|
|
65
|
+
ele = utilities.unparse_spec((el_symbol, state))
|
|
66
|
+
_, charge = utilities.parse_spec(cation)
|
|
67
|
+
if state > charge:
|
|
68
|
+
poss_n_type_cat.add(ele)
|
|
69
|
+
elif state < charge and state > 0:
|
|
70
|
+
poss_p_type_cat.add(ele)
|
|
71
|
+
|
|
72
|
+
return list(poss_n_type_cat), list(poss_p_type_cat)
|
|
73
|
+
|
|
74
|
+
def _get_anion_dopants(
|
|
75
|
+
self, element_objects: List[smact.Element], anions: List[str]
|
|
76
|
+
):
|
|
77
|
+
poss_n_type_an = set()
|
|
78
|
+
poss_p_type_an = set()
|
|
79
|
+
|
|
80
|
+
for element in element_objects:
|
|
81
|
+
oxi_state = element.oxidation_states
|
|
82
|
+
el_symbol = element.symbol
|
|
83
|
+
for state in oxi_state:
|
|
84
|
+
for anion in anions:
|
|
85
|
+
ele = utilities.unparse_spec((el_symbol, state))
|
|
86
|
+
_, charge = utilities.parse_spec(anion)
|
|
87
|
+
if state > charge and state < 0:
|
|
88
|
+
poss_n_type_an.add(ele)
|
|
89
|
+
elif state < charge:
|
|
90
|
+
poss_p_type_an.add(ele)
|
|
91
|
+
return list(poss_n_type_an), list(poss_p_type_an)
|
|
92
|
+
|
|
93
|
+
def get_dopants(
|
|
94
|
+
self,
|
|
95
|
+
num_dopants: int = 5,
|
|
96
|
+
) -> dict:
|
|
97
|
+
"""
|
|
98
|
+
Args:
|
|
99
|
+
num_dopants (int): The number of suggestions to return for n- and p-type dopants.
|
|
100
|
+
Returns:
|
|
101
|
+
(dict): Dopant suggestions, given as a dictionary with keys
|
|
102
|
+
"n_type_cation", "p_type_cation", "n_type_anion", "p_type_anion".
|
|
103
|
+
|
|
104
|
+
Examples:
|
|
105
|
+
>>> test = Doper(('Ti4+','O2-'))
|
|
106
|
+
>>> print(test.get_dopants(num_dopants=2))
|
|
107
|
+
{'n-type cation substitutions': [('Ta5+', 8.790371775858281e-05),
|
|
108
|
+
('Nb5+', 7.830035204694342e-05)],
|
|
109
|
+
'p-type cation substitutions': [('Na1+', 0.00010060400812977031),
|
|
110
|
+
('Zn2+', 8.56373996146833e-05)],
|
|
111
|
+
'n-type anion substitutions': [('F1-', 0.01508116810515677),
|
|
112
|
+
('Cl1-', 0.004737202729901607)],
|
|
113
|
+
'p-type anion substitutions': [('N3-', 0.0014663800608945628),
|
|
114
|
+
('C4-', 9.31310255126729e-08)]}
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
cations = []
|
|
118
|
+
anions = []
|
|
119
|
+
try:
|
|
120
|
+
for ion in self._original_species:
|
|
121
|
+
_, charge = utilities.parse_spec(ion)
|
|
122
|
+
if charge > 0:
|
|
123
|
+
cations.append(ion)
|
|
124
|
+
elif charge < 0:
|
|
125
|
+
anions.append(ion)
|
|
126
|
+
except Exception as e:
|
|
127
|
+
print(f"{e}: charge is not defined for {ion}!")
|
|
128
|
+
|
|
129
|
+
CM = mutation.CationMutator.from_json(self._filepath)
|
|
130
|
+
|
|
131
|
+
# call all elements
|
|
132
|
+
element_objects = list(smact.element_dictionary().values())
|
|
133
|
+
|
|
134
|
+
poss_n_type_cat, poss_p_type_cat = self._get_cation_dopants(
|
|
135
|
+
element_objects, cations
|
|
136
|
+
)
|
|
137
|
+
poss_n_type_an, poss_p_type_an = self._get_anion_dopants(
|
|
138
|
+
element_objects, anions
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
n_type_cat, p_type_cat, n_type_an, p_type_an = [], [], [], []
|
|
142
|
+
for cation in cations:
|
|
143
|
+
cation_charge = utilities.parse_spec(cation)[1]
|
|
144
|
+
for n_specie in poss_n_type_cat:
|
|
145
|
+
n_specie_charge = utilities.parse_spec(n_specie)[1]
|
|
146
|
+
if cation_charge >= n_specie_charge:
|
|
147
|
+
continue
|
|
148
|
+
n_type_cat.append(
|
|
149
|
+
(n_specie, cation, CM.sub_prob(cation, n_specie))
|
|
150
|
+
)
|
|
151
|
+
for p_specie in poss_p_type_cat:
|
|
152
|
+
p_specie_charge = utilities.parse_spec(p_specie)[1]
|
|
153
|
+
if cation_charge <= p_specie_charge:
|
|
154
|
+
continue
|
|
155
|
+
p_type_cat.append(
|
|
156
|
+
(p_specie, cation, CM.sub_prob(cation, p_specie))
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
for anion in anions:
|
|
160
|
+
anion_charge = utilities.parse_spec(anion)[1]
|
|
161
|
+
for n_specie in poss_n_type_an:
|
|
162
|
+
n_specie_charge = utilities.parse_spec(n_specie)[1]
|
|
163
|
+
if anion == n_specie or anion_charge >= n_specie_charge:
|
|
164
|
+
continue
|
|
165
|
+
n_type_an.append(
|
|
166
|
+
(n_specie, anion, CM.sub_prob(anion, n_specie))
|
|
167
|
+
)
|
|
168
|
+
for p_specie in poss_p_type_an:
|
|
169
|
+
p_specie_charge = utilities.parse_spec(p_specie)[1]
|
|
170
|
+
if anion == p_specie or anion_charge <= p_specie_charge:
|
|
171
|
+
continue
|
|
172
|
+
p_type_an.append(
|
|
173
|
+
(p_specie, anion, CM.sub_prob(anion, p_specie))
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
# [('B3+', 0.003), ('C4+', 0.001), (), (), ...] : list(tuple(str, float))
|
|
177
|
+
# sort by probability
|
|
178
|
+
n_type_cat.sort(key=lambda x: x[-1], reverse=True)
|
|
179
|
+
p_type_cat.sort(key=lambda x: x[-1], reverse=True)
|
|
180
|
+
n_type_an.sort(key=lambda x: x[-1], reverse=True)
|
|
181
|
+
p_type_an.sort(key=lambda x: x[-1], reverse=True)
|
|
182
|
+
|
|
183
|
+
self.results = {
|
|
184
|
+
"n-type cation substitutions": n_type_cat[:num_dopants],
|
|
185
|
+
"p-type cation substitutions": p_type_cat[:num_dopants],
|
|
186
|
+
"n-type anion substitutions": n_type_an[:num_dopants],
|
|
187
|
+
"p-type anion substitutions": p_type_an[:num_dopants],
|
|
188
|
+
}
|
|
189
|
+
# return the top (num_dopants) results for each case
|
|
190
|
+
return self.results
|
|
191
|
+
|
|
192
|
+
def plot_dopants(self) -> None:
|
|
193
|
+
"""
|
|
194
|
+
Uses pymatgen plotting utilities to plot the results of doping search
|
|
195
|
+
Args:
|
|
196
|
+
None
|
|
197
|
+
Returns:
|
|
198
|
+
None
|
|
199
|
+
"""
|
|
200
|
+
try:
|
|
201
|
+
for val in self.results.values():
|
|
202
|
+
dict_results = {
|
|
203
|
+
utilities.parse_spec(x)[0]: y for x, _, y in val
|
|
204
|
+
}
|
|
205
|
+
plotting.periodic_table_heatmap(
|
|
206
|
+
elemental_data=dict_results,
|
|
207
|
+
cmap="rainbow",
|
|
208
|
+
blank_color="gainsboro",
|
|
209
|
+
edge_color="white",
|
|
210
|
+
)
|
|
211
|
+
except AttributeError as e:
|
|
212
|
+
print(f"Dopants are not calculated. Run get_dopants first.")
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import itertools
|
|
2
|
+
import os
|
|
2
3
|
import warnings
|
|
3
4
|
from collections import namedtuple
|
|
4
5
|
from itertools import combinations
|
|
5
6
|
from typing import Iterable, List, Optional, Tuple, Union
|
|
6
7
|
|
|
7
8
|
from smact import Element, neutral_ratios
|
|
9
|
+
from smact.data_loader import (
|
|
10
|
+
lookup_element_oxidation_states_custom as oxi_custom,
|
|
11
|
+
)
|
|
8
12
|
|
|
9
13
|
# Use named tuple to improve readability of smact_filter outputs
|
|
10
14
|
_allowed_compositions = namedtuple(
|
|
@@ -324,7 +328,7 @@ def smact_filter(
|
|
|
324
328
|
threshold (int): Threshold for stoichiometry limit, default = 8
|
|
325
329
|
stoichs (list[int]): A selection of valid stoichiometric ratios for each site.
|
|
326
330
|
species_unique (bool): Whether or not to consider elements in different oxidation states as unique in the results.
|
|
327
|
-
oxidation_states_set (string): A string to choose which set of oxidation states should be chosen. Options are 'default', 'icsd', 'pymatgen' and 'wiki' for the default, icsd, pymatgen structure predictor and Wikipedia (https://en.wikipedia.org/wiki/Template:List_of_oxidation_states_of_the_elements) oxidation states respectively.
|
|
331
|
+
oxidation_states_set (string): A string to choose which set of oxidation states should be chosen. Options are 'default', 'icsd', 'pymatgen' and 'wiki' for the default, icsd, pymatgen structure predictor and Wikipedia (https://en.wikipedia.org/wiki/Template:List_of_oxidation_states_of_the_elements) oxidation states respectively. A filepath to an oxidation states text file can also be supplied as well.
|
|
328
332
|
comp_tuple (bool): Whether or not to return the results as a named tuple of elements and stoichiometries (True) or as a normal tuple of elements and stoichiometries (False).
|
|
329
333
|
Returns:
|
|
330
334
|
allowed_comps (list): Allowed compositions for that chemical system
|
|
@@ -371,10 +375,12 @@ def smact_filter(
|
|
|
371
375
|
}
|
|
372
376
|
if oxidation_states_set in oxi_set:
|
|
373
377
|
ox_combos = oxi_set[oxidation_states_set]
|
|
378
|
+
elif os.path.exists(oxidation_states_set):
|
|
379
|
+
ox_combos = [oxi_custom(e.symbol, oxidation_states_set) for e in els]
|
|
374
380
|
else:
|
|
375
381
|
raise (
|
|
376
382
|
Exception(
|
|
377
|
-
f'{oxidation_states_set} is not valid. Enter either "default", "icsd", "pymatgen"
|
|
383
|
+
f'{oxidation_states_set} is not valid. Enter either "default", "icsd", "pymatgen","wiki" or a filepath to a textfile of oxidation states.'
|
|
378
384
|
)
|
|
379
385
|
)
|
|
380
386
|
if oxidation_states_set == "wiki":
|
|
@@ -202,9 +202,7 @@ class StructureDB:
|
|
|
202
202
|
|
|
203
203
|
return num
|
|
204
204
|
|
|
205
|
-
def get_structs(
|
|
206
|
-
self, composition: str, table: str
|
|
207
|
-
) -> List[SmactStructure]:
|
|
205
|
+
def get_structs(self, composition: str, table: str) -> List[SmactStructure]:
|
|
208
206
|
"""Get SmactStructures for a given composition.
|
|
209
207
|
|
|
210
208
|
Args:
|
|
@@ -373,8 +373,7 @@ class CationMutator:
|
|
|
373
373
|
def cond_sub_prob(self, s1: str, s2: str) -> float:
|
|
374
374
|
"""Calculate the probability of substitution of one species with another."""
|
|
375
375
|
return (
|
|
376
|
-
np.exp(self.get_lambda(s1, s2))
|
|
377
|
-
/ np.exp(self.get_lambdas(s2)).sum()
|
|
376
|
+
np.exp(self.get_lambda(s1, s2)) / np.exp(self.get_lambdas(s2)).sum()
|
|
378
377
|
)
|
|
379
378
|
|
|
380
379
|
def cond_sub_probs(self, s1: str) -> pd.Series:
|
|
@@ -183,8 +183,7 @@ class StructurePredictor:
|
|
|
183
183
|
sub_species = list(map(list, sub_species))
|
|
184
184
|
|
|
185
185
|
potential_nary_parents: List[List[SmactStructure]] = list(
|
|
186
|
-
self.db.get_with_species(specs, self.table)
|
|
187
|
-
for specs in sub_species
|
|
186
|
+
self.db.get_with_species(specs, self.table) for specs in sub_species
|
|
188
187
|
)
|
|
189
188
|
|
|
190
189
|
for spec_idx, parents in enumerate(potential_nary_parents):
|
|
@@ -274,9 +274,12 @@ class SmactStructure:
|
|
|
274
274
|
)
|
|
275
275
|
struct = oxi_transform.apply_transformation(structure)
|
|
276
276
|
print("Oxidation states assigned based on ICSD statistics")
|
|
277
|
+
elif determine_oxi == "predecorated":
|
|
278
|
+
struct = structure
|
|
279
|
+
|
|
277
280
|
else:
|
|
278
281
|
raise ValueError(
|
|
279
|
-
f"Argument for 'determine_oxi', <{determine_oxi}> is not valid. Choose either 'BV','comp_ICSD' or '
|
|
282
|
+
f"Argument for 'determine_oxi', <{determine_oxi}> is not valid. Choose either 'BV','comp_ICSD','both' or 'predecorated'."
|
|
280
283
|
)
|
|
281
284
|
|
|
282
285
|
sites, species = SmactStructure.__parse_py_sites(struct)
|
|
@@ -433,10 +436,7 @@ class SmactStructure:
|
|
|
433
436
|
lattice_param = float(lines[1])
|
|
434
437
|
|
|
435
438
|
lattice = np.array(
|
|
436
|
-
[
|
|
437
|
-
[float(point) for point in line.split(" ")]
|
|
438
|
-
for line in lines[2:5]
|
|
439
|
-
]
|
|
439
|
+
[[float(point) for point in line.split(" ")] for line in lines[2:5]]
|
|
440
440
|
)
|
|
441
441
|
|
|
442
442
|
sites = defaultdict(list)
|
|
@@ -15,12 +15,17 @@ from smact import Species
|
|
|
15
15
|
from smact.builder import wurtzite
|
|
16
16
|
from smact.properties import band_gap_Harrison, compound_electroneg
|
|
17
17
|
|
|
18
|
+
files_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "files")
|
|
19
|
+
TEST_OX_STATES = os.path.join(files_dir, "test_oxidation_states.txt")
|
|
20
|
+
|
|
18
21
|
|
|
19
22
|
class TestSequenceFunctions(unittest.TestCase):
|
|
20
23
|
# ---------------- TOP-LEVEL ----------------
|
|
21
24
|
|
|
22
25
|
def test_Element_class_Pt(self):
|
|
23
|
-
Pt = smact.Element(
|
|
26
|
+
Pt = smact.Element(
|
|
27
|
+
"Pt",
|
|
28
|
+
)
|
|
24
29
|
self.assertEqual(Pt.name, "Platinum")
|
|
25
30
|
self.assertEqual(Pt.ionpot, 8.95883)
|
|
26
31
|
self.assertEqual(Pt.number, 78)
|
|
@@ -34,9 +39,10 @@ class TestSequenceFunctions(unittest.TestCase):
|
|
|
34
39
|
|
|
35
40
|
def test_element_dictionary(self):
|
|
36
41
|
newlist = ["O", "Rb", "W"]
|
|
37
|
-
dictionary = smact.element_dictionary(newlist)
|
|
42
|
+
dictionary = smact.element_dictionary(newlist, TEST_OX_STATES)
|
|
38
43
|
self.assertEqual(dictionary["O"].crustal_abundance, 461000.0)
|
|
39
44
|
self.assertEqual(dictionary["Rb"].oxidation_states, [-1, 1])
|
|
45
|
+
self.assertEqual(dictionary["Rb"].oxidation_states_custom, [-1, 1])
|
|
40
46
|
self.assertEqual(dictionary["W"].name, "Tungsten")
|
|
41
47
|
self.assertTrue("Rn" in smact.element_dictionary())
|
|
42
48
|
|
|
@@ -46,9 +52,7 @@ class TestSequenceFunctions(unittest.TestCase):
|
|
|
46
52
|
[1.00, 2.00, 3.00], [1.001, 1.999, 3.00], tolerance=1e-2
|
|
47
53
|
)
|
|
48
54
|
)
|
|
49
|
-
self.assertFalse(
|
|
50
|
-
smact.are_eq([1.00, 2.00, 3.00], [1.001, 1.999, 3.00])
|
|
51
|
-
)
|
|
55
|
+
self.assertFalse(smact.are_eq([1.00, 2.00, 3.00], [1.001, 1.999, 3.00]))
|
|
52
56
|
|
|
53
57
|
def test_gcd_recursive(self):
|
|
54
58
|
self.assertEqual(smact._gcd_recursive(4, 12, 10, 32), 2)
|
|
@@ -346,6 +350,12 @@ class TestSequenceFunctions(unittest.TestCase):
|
|
|
346
350
|
(("Na", "Fe", "Cl"), (1, 1, -1), (1, 1, 2)),
|
|
347
351
|
],
|
|
348
352
|
)
|
|
353
|
+
self.assertEqual(
|
|
354
|
+
result,
|
|
355
|
+
smact.screening.smact_filter(
|
|
356
|
+
[Na, Fe, Cl], threshold=2, oxidation_states_set=TEST_OX_STATES
|
|
357
|
+
),
|
|
358
|
+
)
|
|
349
359
|
result_comp_tuple = smact.screening.smact_filter(
|
|
350
360
|
[Na, Fe, Cl], threshold=2, comp_tuple=True
|
|
351
361
|
)
|
|
@@ -363,9 +363,7 @@ class CationMutatorTest(unittest.TestCase):
|
|
|
363
363
|
"""Set up the test initial structure and mutator."""
|
|
364
364
|
cls.test_struct = SmactStructure.from_file(TEST_POSCAR)
|
|
365
365
|
|
|
366
|
-
cls.test_mutator = CationMutator.from_json(
|
|
367
|
-
lambda_json=TEST_LAMBDA_JSON
|
|
368
|
-
)
|
|
366
|
+
cls.test_mutator = CationMutator.from_json(lambda_json=TEST_LAMBDA_JSON)
|
|
369
367
|
cls.test_pymatgen_mutator = CationMutator.from_json(
|
|
370
368
|
lambda_json=None, alpha=lambda x, y: -5
|
|
371
369
|
)
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
### This Jupyter notebook creates ntype ptype possiblie dopants for input species
|
|
2
|
-
### using SMACT structure prediction
|
|
3
|
-
### Working with Kieth from SCIML and Anthony
|
|
4
|
-
|
|
5
|
-
###Doper ver 2
|
|
6
|
-
|
|
7
|
-
# Now 'Doper' can generate possible n-type p-type dopants for multicomponent materials (i.e. Ternary, Quaternary etc).
|
|
8
|
-
# Can plot the result of doping search within a single step
|
|
9
|
-
# """ex) test= Doper(('Cu1+','Zn2+','Ge4+','S2-'))
|
|
10
|
-
# test.get_dopants(num_dopants = 10, plot_heatmap = True)"""
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
from typing import List, Tuple
|
|
14
|
-
|
|
15
|
-
from pymatgen.util import plotting
|
|
16
|
-
|
|
17
|
-
import smact
|
|
18
|
-
from smact.structure_prediction import mutation, utilities
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class Doper:
|
|
22
|
-
"""
|
|
23
|
-
A class to search for n & p type dopants
|
|
24
|
-
Methods: get_dopants, plot_dopants
|
|
25
|
-
|
|
26
|
-
Attributes:
|
|
27
|
-
original_species: A tuple which describes the constituent species of a material. For example:
|
|
28
|
-
|
|
29
|
-
>>> test= Doper(('Cu1+','Zn2+','Ge4+','S2-'))
|
|
30
|
-
>>> test.original_species
|
|
31
|
-
('Cu1+','Zn2+','Ge4+','S2-')
|
|
32
|
-
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
def __init__(self, original_species: Tuple[str, ...]):
|
|
36
|
-
"""
|
|
37
|
-
Intialise the `Doper` class with a tuple of species
|
|
38
|
-
|
|
39
|
-
Args:
|
|
40
|
-
original_species: See :class:`~.Doper`.
|
|
41
|
-
|
|
42
|
-
"""
|
|
43
|
-
self.original_species = original_species
|
|
44
|
-
|
|
45
|
-
def _get_cation_dopants(
|
|
46
|
-
self, element_objects: List[smact.Element], cations: List[str]
|
|
47
|
-
):
|
|
48
|
-
poss_n_type_cat = []
|
|
49
|
-
poss_p_type_cat = []
|
|
50
|
-
|
|
51
|
-
for element in element_objects:
|
|
52
|
-
# [-2, -1, 0, +1, +2]
|
|
53
|
-
oxi_state = element.oxidation_states
|
|
54
|
-
el_symbol = element.symbol
|
|
55
|
-
for state in oxi_state:
|
|
56
|
-
for cation in cations:
|
|
57
|
-
_, charge = utilities.parse_spec(cation)
|
|
58
|
-
if state > charge:
|
|
59
|
-
poss_n_type_cat.append(
|
|
60
|
-
utilities.unparse_spec((el_symbol, state))
|
|
61
|
-
)
|
|
62
|
-
elif state < charge and state > 0:
|
|
63
|
-
poss_p_type_cat.append(
|
|
64
|
-
utilities.unparse_spec((el_symbol, state))
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
return poss_n_type_cat, poss_p_type_cat
|
|
68
|
-
|
|
69
|
-
def _get_anion_dopants(
|
|
70
|
-
self, element_objects: List[smact.Element], anions: List[str]
|
|
71
|
-
):
|
|
72
|
-
poss_n_type_an = []
|
|
73
|
-
poss_p_type_an = []
|
|
74
|
-
|
|
75
|
-
for element in element_objects:
|
|
76
|
-
oxi_state = element.oxidation_states
|
|
77
|
-
el_symbol = element.symbol
|
|
78
|
-
for state in oxi_state:
|
|
79
|
-
for anion in anions:
|
|
80
|
-
_, charge = utilities.parse_spec(anion)
|
|
81
|
-
if state > charge and state < 0:
|
|
82
|
-
poss_n_type_an.append(
|
|
83
|
-
utilities.unparse_spec((el_symbol, state))
|
|
84
|
-
)
|
|
85
|
-
elif state < charge:
|
|
86
|
-
poss_p_type_an.append(
|
|
87
|
-
utilities.unparse_spec((el_symbol, state))
|
|
88
|
-
)
|
|
89
|
-
return poss_n_type_an, poss_p_type_an
|
|
90
|
-
|
|
91
|
-
def _plot_dopants(self, results: dict):
|
|
92
|
-
"""
|
|
93
|
-
Uses pymatgen plotting utilities to plot the results of doping search
|
|
94
|
-
"""
|
|
95
|
-
for key, val in results.items():
|
|
96
|
-
dict_results = {utilities.parse_spec(x)[0]: y for x, y in val}
|
|
97
|
-
plotting.periodic_table_heatmap(
|
|
98
|
-
elemental_data=dict_results,
|
|
99
|
-
cmap="rainbow",
|
|
100
|
-
blank_color="gainsboro",
|
|
101
|
-
edge_color="white",
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
def get_dopants(
|
|
105
|
-
self,
|
|
106
|
-
num_dopants: int = 5,
|
|
107
|
-
plot_heatmap: bool = False,
|
|
108
|
-
) -> dict:
|
|
109
|
-
"""
|
|
110
|
-
Args:
|
|
111
|
-
num_dopants (int): The number of suggestions to return for n- and p-type dopants.
|
|
112
|
-
plot_heatmap (bool): If True, the results of the doping search are plotted as heatmaps
|
|
113
|
-
|
|
114
|
-
Returns:
|
|
115
|
-
(dict): Dopant suggestions, given as a dictionary with keys
|
|
116
|
-
"n_type_cation", "p_type_cation", "n_type_anion", "p_type_anion".
|
|
117
|
-
|
|
118
|
-
Examples:
|
|
119
|
-
>>> test = Doper(('Ti4+','O2-'))
|
|
120
|
-
>>> print(test.get_dopants(num_dopants=2))
|
|
121
|
-
{'n-type cation substitutions': [('Ta5+', 8.790371775858281e-05),
|
|
122
|
-
('Nb5+', 7.830035204694342e-05)],
|
|
123
|
-
'p-type cation substitutions': [('Na1+', 0.00010060400812977031),
|
|
124
|
-
('Zn2+', 8.56373996146833e-05)],
|
|
125
|
-
'n-type anion substitutions': [('F1-', 0.01508116810515677),
|
|
126
|
-
('Cl1-', 0.004737202729901607)],
|
|
127
|
-
'p-type anion substitutions': [('N3-', 0.0014663800608945628),
|
|
128
|
-
('C4-', 9.31310255126729e-08)]}
|
|
129
|
-
"""
|
|
130
|
-
|
|
131
|
-
cations = []
|
|
132
|
-
anions = []
|
|
133
|
-
try:
|
|
134
|
-
for ion in self.original_species:
|
|
135
|
-
_, charge = utilities.parse_spec(ion)
|
|
136
|
-
if charge > 0:
|
|
137
|
-
cations.append(ion)
|
|
138
|
-
elif charge < 0:
|
|
139
|
-
anions.append(ion)
|
|
140
|
-
except Exception as e:
|
|
141
|
-
print(e, "charge is not defined")
|
|
142
|
-
|
|
143
|
-
CM = mutation.CationMutator.from_json()
|
|
144
|
-
|
|
145
|
-
# call all elements
|
|
146
|
-
element_objects = list(smact.element_dictionary().values())
|
|
147
|
-
|
|
148
|
-
poss_n_type_cat, poss_p_type_cat = self._get_cation_dopants(
|
|
149
|
-
element_objects, cations
|
|
150
|
-
)
|
|
151
|
-
poss_n_type_an, poss_p_type_an = self._get_anion_dopants(
|
|
152
|
-
element_objects, anions
|
|
153
|
-
)
|
|
154
|
-
|
|
155
|
-
n_type_cat, p_type_cat, n_type_an, p_type_an = [], [], [], []
|
|
156
|
-
for cation in cations:
|
|
157
|
-
for n_specie, p_specie in zip(poss_n_type_cat, poss_p_type_cat):
|
|
158
|
-
n_type_cat.append((n_specie, CM.sub_prob(cation, n_specie)))
|
|
159
|
-
p_type_cat.append((p_specie, CM.sub_prob(cation, p_specie)))
|
|
160
|
-
|
|
161
|
-
for anion in anions:
|
|
162
|
-
for n_specie, p_specie in zip(poss_n_type_an, poss_p_type_an):
|
|
163
|
-
n_type_an.append((n_specie, CM.sub_prob(anion, n_specie)))
|
|
164
|
-
p_type_an.append((p_specie, CM.sub_prob(anion, p_specie)))
|
|
165
|
-
|
|
166
|
-
# [('B3+', 0.003), ('C4+', 0.001), (), (), ...] : list(tuple(str, float))
|
|
167
|
-
# sort by probability
|
|
168
|
-
n_type_cat.sort(key=lambda x: x[1], reverse=True)
|
|
169
|
-
p_type_cat.sort(key=lambda x: x[1], reverse=True)
|
|
170
|
-
n_type_an.sort(key=lambda x: x[1], reverse=True)
|
|
171
|
-
p_type_an.sort(key=lambda x: x[1], reverse=True)
|
|
172
|
-
|
|
173
|
-
results = {
|
|
174
|
-
"n-type cation substitutions": n_type_cat[:num_dopants],
|
|
175
|
-
"p-type cation substitutions": p_type_cat[:num_dopants],
|
|
176
|
-
"n-type anion substitutions": n_type_an[:num_dopants],
|
|
177
|
-
"p-type anion substitutions": p_type_an[:num_dopants],
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
# plot heatmap
|
|
181
|
-
|
|
182
|
-
if plot_heatmap:
|
|
183
|
-
self._plot_dopants(results)
|
|
184
|
-
|
|
185
|
-
# return the top (num_dopants) results for each case
|
|
186
|
-
return results
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|