From d2447edc903d48180107962cc9827c387637e1ce Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Tue, 22 Oct 2024 11:41:45 +0800 Subject: [PATCH 01/42] copy pyproject from 4073 --- pyproject.toml | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8805c438ae0..4e30b2c9612 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,40 +87,34 @@ Issues = "https://github.com/materialsproject/pymatgen/issues" Pypi = "https://pypi.org/project/pymatgen" [project.optional-dependencies] -ase = ["ase>=3.23.0"] -# tblite only support Python 3.12+ through conda-forge -# https://github.com/tblite/tblite/issues/175 -tblite = ["tblite[ase]>=0.3.0; python_version<'3.12'"] -vis = ["vtk>=6.0.0"] abinit = ["netcdf4>=1.7.1"] -mlp = ["chgnet>=0.3.8", "matgl>=1.1.3"] -electronic_structure = ["fdint>=2.0.2"] +ase = ["ase>=3.23.0"] ci = ["pytest-cov>=4", "pytest-split>=0.8", "pytest>=8"] docs = ["invoke", "sphinx", "sphinx_markdown_builder", "sphinx_rtd_theme"] +electronic_structure = ["fdint>=2.0.2"] +mlp = ["chgnet>=0.3.8", "matgl>=1.1.3"] +numba = ["numba>=0.55"] +numpy-v1 = ["numpy>=1.25.0,<2"] # Test NP1 on Windows (quite buggy ATM) optional = [ - "ase>=3.23.0", - "beautifulsoup4", + "pymatgen[abinit,ase,mlp,tblite]", + "beautifulsoup4>=4.6.0", # BoltzTraP2 build fails on Windows GitHub runners "BoltzTraP2>=24.9.4 ; platform_system != 'Windows'", "chemview>=0.6", - "chgnet>=0.3.8", "f90nml>=1.1.2", "galore>=0.6.1", "h5py>=3.11.0", "jarvis-tools>=2020.7.14", - "matgl>=1.1.3", "matplotlib>=3.8", - "netCDF4>=1.6.5", "phonopy>=2.23", "seekpath>=2.0.1", - # tblite only support Python 3.12+ through conda-forge - # https://github.com/tblite/tblite/issues/175 "hiphive>=1.3.1", "openbabel-wheel>=3.1.1.20", - "tblite[ase]>=0.3.0; platform_system=='Linux' and python_version<'3.12'", ] -numba = ["numba>=0.55"] -numpy-v1 = ["numpy>=1.25.0,<2"] # Test NP1 on Windows (quite buggy ATM) +# tblite only support Python 3.12+ through conda-forge +# https://github.com/tblite/tblite/issues/175 +tblite = ["tblite[ase]>=0.3.0; platform_system=='Linux' and python_version<'3.12'"] +vis = ["vtk>=6.0.0"] [project.scripts] pmg = "pymatgen.cli.pmg:main" From 1eb855b9074105034bd6b91cf837c4e5675e82d0 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Tue, 22 Oct 2024 11:50:01 +0800 Subject: [PATCH 02/42] bump monty --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4e30b2c9612..d5bf9cd6a3d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,7 +56,7 @@ classifiers = [ dependencies = [ "joblib>=1", "matplotlib>=3.8", - "monty>=2024.7.29", + "monty>=2024.10.21", "networkx>=3", # PR #4116 "palettable>=3.3.3", "pandas>=2", From aae9f4ba262d547011b60991d73172c442f3dcce Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Tue, 22 Oct 2024 13:50:26 +0800 Subject: [PATCH 03/42] recover networkx pin, and bump sympy --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d5bf9cd6a3d..e662142aa3c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,7 +57,7 @@ dependencies = [ "joblib>=1", "matplotlib>=3.8", "monty>=2024.10.21", - "networkx>=3", # PR #4116 + "networkx>=2.7", # PR #4116 "palettable>=3.3.3", "pandas>=2", "plotly>=4.5.0", @@ -69,7 +69,7 @@ dependencies = [ # https://github.com/scipy/scipy/issues/21052 "scipy>=1.14.1; platform_system == 'Windows'", "spglib>=2.5.0", - "sympy>=1.2", + "sympy>=1.3", # PR #4116 "tabulate>=0.9", "tqdm>=4.60", "uncertainties>=3.1.4", From e08454eaa2c73a6c997c6a8c468109893405fdbb Mon Sep 17 00:00:00 2001 From: Haoyu Yang Date: Tue, 22 Oct 2024 14:29:38 +0800 Subject: [PATCH 04/42] pin monty to lower ver to see what is causing the failure --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e662142aa3c..8c1d2e8dd90 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,7 +56,7 @@ classifiers = [ dependencies = [ "joblib>=1", "matplotlib>=3.8", - "monty>=2024.10.21", + "monty==2024.7.30", # DEBUG "networkx>=2.7", # PR #4116 "palettable>=3.3.3", "pandas>=2", From f8b572374a600e1608b052fb53d20cc74f34888c Mon Sep 17 00:00:00 2001 From: Haoyu Yang Date: Tue, 22 Oct 2024 14:50:46 +0800 Subject: [PATCH 05/42] revert all changes to pyproject but monty --- pyproject.toml | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8c1d2e8dd90..dd8e7f5dbf9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,8 +56,8 @@ classifiers = [ dependencies = [ "joblib>=1", "matplotlib>=3.8", - "monty==2024.7.30", # DEBUG - "networkx>=2.7", # PR #4116 + "monty==2024.10.21", # DEBUG + "networkx>=3", # PR #4116 "palettable>=3.3.3", "pandas>=2", "plotly>=4.5.0", @@ -69,7 +69,7 @@ dependencies = [ # https://github.com/scipy/scipy/issues/21052 "scipy>=1.14.1; platform_system == 'Windows'", "spglib>=2.5.0", - "sympy>=1.3", # PR #4116 + "sympy>=1.2", "tabulate>=0.9", "tqdm>=4.60", "uncertainties>=3.1.4", @@ -87,34 +87,40 @@ Issues = "https://github.com/materialsproject/pymatgen/issues" Pypi = "https://pypi.org/project/pymatgen" [project.optional-dependencies] -abinit = ["netcdf4>=1.7.1"] ase = ["ase>=3.23.0"] +# tblite only support Python 3.12+ through conda-forge +# https://github.com/tblite/tblite/issues/175 +tblite = ["tblite[ase]>=0.3.0; python_version<'3.12'"] +vis = ["vtk>=6.0.0"] +abinit = ["netcdf4>=1.7.1"] +mlp = ["chgnet>=0.3.8", "matgl>=1.1.3"] +electronic_structure = ["fdint>=2.0.2"] ci = ["pytest-cov>=4", "pytest-split>=0.8", "pytest>=8"] docs = ["invoke", "sphinx", "sphinx_markdown_builder", "sphinx_rtd_theme"] -electronic_structure = ["fdint>=2.0.2"] -mlp = ["chgnet>=0.3.8", "matgl>=1.1.3"] -numba = ["numba>=0.55"] -numpy-v1 = ["numpy>=1.25.0,<2"] # Test NP1 on Windows (quite buggy ATM) optional = [ - "pymatgen[abinit,ase,mlp,tblite]", - "beautifulsoup4>=4.6.0", + "ase>=3.23.0", + "beautifulsoup4", # BoltzTraP2 build fails on Windows GitHub runners "BoltzTraP2>=24.9.4 ; platform_system != 'Windows'", "chemview>=0.6", + "chgnet>=0.3.8", "f90nml>=1.1.2", "galore>=0.6.1", "h5py>=3.11.0", "jarvis-tools>=2020.7.14", + "matgl>=1.1.3", "matplotlib>=3.8", + "netCDF4>=1.6.5", "phonopy>=2.23", "seekpath>=2.0.1", + # tblite only support Python 3.12+ through conda-forge + # https://github.com/tblite/tblite/issues/175 "hiphive>=1.3.1", "openbabel-wheel>=3.1.1.20", + "tblite[ase]>=0.3.0; platform_system=='Linux' and python_version<'3.12'", ] -# tblite only support Python 3.12+ through conda-forge -# https://github.com/tblite/tblite/issues/175 -tblite = ["tblite[ase]>=0.3.0; platform_system=='Linux' and python_version<'3.12'"] -vis = ["vtk>=6.0.0"] +numba = ["numba>=0.55"] +numpy-v1 = ["numpy>=1.25.0,<2"] # Test NP1 on Windows (quite buggy ATM) [project.scripts] pmg = "pymatgen.cli.pmg:main" From 19484429fe1bd598e82e9ce63f2bd1c9f631b175 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Tue, 22 Oct 2024 16:01:12 +0800 Subject: [PATCH 06/42] bump sympy --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index dd8e7f5dbf9..5bf4e07963f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,7 +56,7 @@ classifiers = [ dependencies = [ "joblib>=1", "matplotlib>=3.8", - "monty==2024.10.21", # DEBUG + "monty>=2024.10.21", "networkx>=3", # PR #4116 "palettable>=3.3.3", "pandas>=2", @@ -69,7 +69,7 @@ dependencies = [ # https://github.com/scipy/scipy/issues/21052 "scipy>=1.14.1; platform_system == 'Windows'", "spglib>=2.5.0", - "sympy>=1.2", + "sympy>=1.3", # PR #4116 "tabulate>=0.9", "tqdm>=4.60", "uncertainties>=3.1.4", From 03df9b055459e90c7f1c077f058cba083775ecc6 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Tue, 22 Oct 2024 16:15:19 +0800 Subject: [PATCH 07/42] sort and group optional deps --- pyproject.toml | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5bf4e07963f..27585144659 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,40 +87,34 @@ Issues = "https://github.com/materialsproject/pymatgen/issues" Pypi = "https://pypi.org/project/pymatgen" [project.optional-dependencies] +abinit = ["netcdf4>=1.6.5"] ase = ["ase>=3.23.0"] -# tblite only support Python 3.12+ through conda-forge -# https://github.com/tblite/tblite/issues/175 -tblite = ["tblite[ase]>=0.3.0; python_version<'3.12'"] -vis = ["vtk>=6.0.0"] -abinit = ["netcdf4>=1.7.1"] -mlp = ["chgnet>=0.3.8", "matgl>=1.1.3"] -electronic_structure = ["fdint>=2.0.2"] ci = ["pytest-cov>=4", "pytest-split>=0.8", "pytest>=8"] docs = ["invoke", "sphinx", "sphinx_markdown_builder", "sphinx_rtd_theme"] +electronic_structure = ["fdint>=2.0.2"] +mlp = ["chgnet>=0.3.8", "matgl>=1.1.3"] +numba = ["numba>=0.55"] +numpy-v1 = ["numpy>=1.25.0,<2"] # Test NP1 on Windows (quite buggy ATM) optional = [ - "ase>=3.23.0", + "pymatgen[abinit,ase,mlp,tblite]", "beautifulsoup4", # BoltzTraP2 build fails on Windows GitHub runners "BoltzTraP2>=24.9.4 ; platform_system != 'Windows'", "chemview>=0.6", - "chgnet>=0.3.8", "f90nml>=1.1.2", "galore>=0.6.1", "h5py>=3.11.0", + "hiphive>=1.3.1", "jarvis-tools>=2020.7.14", - "matgl>=1.1.3", "matplotlib>=3.8", - "netCDF4>=1.6.5", + "openbabel-wheel>=3.1.1.20", "phonopy>=2.23", "seekpath>=2.0.1", - # tblite only support Python 3.12+ through conda-forge - # https://github.com/tblite/tblite/issues/175 - "hiphive>=1.3.1", - "openbabel-wheel>=3.1.1.20", - "tblite[ase]>=0.3.0; platform_system=='Linux' and python_version<'3.12'", ] -numba = ["numba>=0.55"] -numpy-v1 = ["numpy>=1.25.0,<2"] # Test NP1 on Windows (quite buggy ATM) +# tblite only support Python 3.12+ through conda-forge +# https://github.com/tblite/tblite/issues/175 +tblite = [ "tblite[ase]>=0.3.0; platform_system=='Linux' and python_version<'3.12'"] +vis = ["vtk>=6.0.0"] [project.scripts] pmg = "pymatgen.cli.pmg:main" From 4492816667cab80c4be1a903f57b676377f812de Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Tue, 22 Oct 2024 16:28:57 +0800 Subject: [PATCH 08/42] loose networkx pin for compatibility --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 27585144659..a55ade83109 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,7 +57,7 @@ dependencies = [ "joblib>=1", "matplotlib>=3.8", "monty>=2024.10.21", - "networkx>=3", # PR #4116 + "networkx>=2.7", # PR #4116 "palettable>=3.3.3", "pandas>=2", "plotly>=4.5.0", From a1231745dcb6ba572b02b351f400a8f90aae656c Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Tue, 22 Oct 2024 18:29:39 +0800 Subject: [PATCH 09/42] lazy import sympy --- src/pymatgen/symmetry/settings.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pymatgen/symmetry/settings.py b/src/pymatgen/symmetry/settings.py index 3abd7f547f3..8dbecb534f3 100644 --- a/src/pymatgen/symmetry/settings.py +++ b/src/pymatgen/symmetry/settings.py @@ -7,8 +7,6 @@ from typing import TYPE_CHECKING import numpy as np -from sympy import Matrix -from sympy.parsing.sympy_parser import parse_expr from pymatgen.core.lattice import Lattice from pymatgen.core.operations import MagSymmOp, SymmOp @@ -100,6 +98,10 @@ def parse_transformation_string( Returns: tuple[list[list[float]] | np.ndarray, list[float]]: transformation matrix & vector """ + # Import sympy is expensive + from sympy import Matrix + from sympy.parsing.sympy_parser import parse_expr + try: a, b, c = np.eye(3) b_change, o_shift = transformation_string.split(";") From 968824429c69efff73638791dfcb62dde590fa04 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Tue, 22 Oct 2024 18:31:48 +0800 Subject: [PATCH 10/42] lazy load scipy --- src/pymatgen/core/lattice.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pymatgen/core/lattice.py b/src/pymatgen/core/lattice.py index c98af8ca916..678ccd72f8c 100644 --- a/src/pymatgen/core/lattice.py +++ b/src/pymatgen/core/lattice.py @@ -16,7 +16,6 @@ import numpy as np from monty.dev import deprecated from monty.json import MSONable -from scipy.spatial import Voronoi from pymatgen.util.coord import pbc_shortest_vectors from pymatgen.util.due import Doi, due @@ -1263,6 +1262,9 @@ def get_wigner_seitz_cell(self) -> list[list[np.ndarray]]: Wigner Seitz cell. For instance, a list of four coordinates will represent a square facet. """ + # Import scipy is expensive + from scipy.spatial import Voronoi + vec1, vec2, vec3 = self._matrix list_k_points = [] From 6e0a89c0d3a00f765d14583cd386b41957c37be8 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Tue, 22 Oct 2024 18:40:33 +0800 Subject: [PATCH 11/42] Revert "lazy load scipy" This reverts commit 968824429c69efff73638791dfcb62dde590fa04. --- src/pymatgen/core/lattice.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pymatgen/core/lattice.py b/src/pymatgen/core/lattice.py index 678ccd72f8c..c98af8ca916 100644 --- a/src/pymatgen/core/lattice.py +++ b/src/pymatgen/core/lattice.py @@ -16,6 +16,7 @@ import numpy as np from monty.dev import deprecated from monty.json import MSONable +from scipy.spatial import Voronoi from pymatgen.util.coord import pbc_shortest_vectors from pymatgen.util.due import Doi, due @@ -1262,9 +1263,6 @@ def get_wigner_seitz_cell(self) -> list[list[np.ndarray]]: Wigner Seitz cell. For instance, a list of four coordinates will represent a square facet. """ - # Import scipy is expensive - from scipy.spatial import Voronoi - vec1, vec2, vec3 = self._matrix list_k_points = [] From 75e23b13b113f06e28bc6513a14485b0e0a0bb28 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Tue, 22 Oct 2024 19:03:07 +0800 Subject: [PATCH 12/42] try netcdf4 install with delvewheel, https://github.com/materialsproject/pymatgen/pull/3894/commits/1dfc9e4f7bbddaf5d93fe9b09b425ca1be6a58f4 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a55ade83109..7d643300d63 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,7 +87,7 @@ Issues = "https://github.com/materialsproject/pymatgen/issues" Pypi = "https://pypi.org/project/pymatgen" [project.optional-dependencies] -abinit = ["netcdf4>=1.6.5"] +abinit = ["netcdf4>=1.7.1.post1", "delvewheel>=1.7.4"] # DEBUG: #3894 ase = ["ase>=3.23.0"] ci = ["pytest-cov>=4", "pytest-split>=0.8", "pytest>=8"] docs = ["invoke", "sphinx", "sphinx_markdown_builder", "sphinx_rtd_theme"] From 4320868b19d6a6a21fdfcda029504d7a6f7b819b Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Tue, 22 Oct 2024 19:49:53 +0800 Subject: [PATCH 13/42] Revert "try netcdf4 install with delvewheel, https://github.com/materialsproject/pymatgen/pull/3894/commits/1dfc9e4f7bbddaf5d93fe9b09b425ca1be6a58f4" This reverts commit 75e23b13b113f06e28bc6513a14485b0e0a0bb28. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7d643300d63..a55ade83109 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,7 +87,7 @@ Issues = "https://github.com/materialsproject/pymatgen/issues" Pypi = "https://pypi.org/project/pymatgen" [project.optional-dependencies] -abinit = ["netcdf4>=1.7.1.post1", "delvewheel>=1.7.4"] # DEBUG: #3894 +abinit = ["netcdf4>=1.6.5"] ase = ["ase>=3.23.0"] ci = ["pytest-cov>=4", "pytest-split>=0.8", "pytest>=8"] docs = ["invoke", "sphinx", "sphinx_markdown_builder", "sphinx_rtd_theme"] From 206ea5216e91f6883ba2efa17d5704024f9a8023 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Wed, 23 Oct 2024 09:54:12 +0800 Subject: [PATCH 14/42] test netcdf4 1.7.1.post2, notice new release is out today --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a55ade83109..3ddbbf1c915 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,7 +87,7 @@ Issues = "https://github.com/materialsproject/pymatgen/issues" Pypi = "https://pypi.org/project/pymatgen" [project.optional-dependencies] -abinit = ["netcdf4>=1.6.5"] +abinit = ["netcdf4==1.7.1.post2"] ase = ["ase>=3.23.0"] ci = ["pytest-cov>=4", "pytest-split>=0.8", "pytest>=8"] docs = ["invoke", "sphinx", "sphinx_markdown_builder", "sphinx_rtd_theme"] From 25975dde6fd595e6f8e175f8bbb28a89bdb9fd4b Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Wed, 23 Oct 2024 10:08:48 +0800 Subject: [PATCH 15/42] netcdf4 1.7.1.post2 doesn't work, try latest 1.7.2 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3ddbbf1c915..812827c5bc7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,7 +87,7 @@ Issues = "https://github.com/materialsproject/pymatgen/issues" Pypi = "https://pypi.org/project/pymatgen" [project.optional-dependencies] -abinit = ["netcdf4==1.7.1.post2"] +abinit = ["netcdf4==1.7.2"] ase = ["ase>=3.23.0"] ci = ["pytest-cov>=4", "pytest-split>=0.8", "pytest>=8"] docs = ["invoke", "sphinx", "sphinx_markdown_builder", "sphinx_rtd_theme"] From 762b85a33fa4abd1b0272836d75c8d3bfdd8f170 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Wed, 23 Oct 2024 10:25:19 +0800 Subject: [PATCH 16/42] reset netcdf4 pin --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 812827c5bc7..f9edc4087ab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,7 +87,7 @@ Issues = "https://github.com/materialsproject/pymatgen/issues" Pypi = "https://pypi.org/project/pymatgen" [project.optional-dependencies] -abinit = ["netcdf4==1.7.2"] +abinit = ["netcdf4==1.6.5"] # PR4128: 1.7.[0/1] yanked, 1.7.1.post[1/2]/1.7.2 cause CI error ase = ["ase>=3.23.0"] ci = ["pytest-cov>=4", "pytest-split>=0.8", "pytest>=8"] docs = ["invoke", "sphinx", "sphinx_markdown_builder", "sphinx_rtd_theme"] From 038ce9af6daafdc8e46fa0277e9665866862562d Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Wed, 23 Oct 2024 10:42:19 +0800 Subject: [PATCH 17/42] why <= doesn't work? --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f9edc4087ab..b71e512ae9d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,7 +87,8 @@ Issues = "https://github.com/materialsproject/pymatgen/issues" Pypi = "https://pypi.org/project/pymatgen" [project.optional-dependencies] -abinit = ["netcdf4==1.6.5"] # PR4128: 1.7.[0/1] yanked, 1.7.1.post[1/2]/1.7.2 cause CI error +# PR4128: netcdf4 1.7.[0/1] yanked, 1.7.1.post[1/2]/1.7.2 cause CI error +abinit = ["netcdf4>=1.6.5,!=1.7.1.post1,!=1.7.1.post2"] ase = ["ase>=3.23.0"] ci = ["pytest-cov>=4", "pytest-split>=0.8", "pytest>=8"] docs = ["invoke", "sphinx", "sphinx_markdown_builder", "sphinx_rtd_theme"] @@ -107,7 +108,6 @@ optional = [ "hiphive>=1.3.1", "jarvis-tools>=2020.7.14", "matplotlib>=3.8", - "openbabel-wheel>=3.1.1.20", "phonopy>=2.23", "seekpath>=2.0.1", ] From 24fdcdcf7fa14be72b9abd3bcc3b1d3f01680956 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Wed, 23 Oct 2024 11:05:00 +0800 Subject: [PATCH 18/42] add comment --- tests/io/abinit/test_netcdf.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/io/abinit/test_netcdf.py b/tests/io/abinit/test_netcdf.py index 77c313c53c3..ddc0e95ec50 100644 --- a/tests/io/abinit/test_netcdf.py +++ b/tests/io/abinit/test_netcdf.py @@ -92,6 +92,8 @@ def test_read_fe(self): ref_magmom_collinear = [-0.5069359730980665] path = os.path.join(tmp_dir, "Fe_magmoms_collinear_GSR.nc") + # TODO: PR4128, EtsfReader would fail in Ubuntu CI with netCDF4 > 1.6.5 + # Need someone with knowledge in netCDF4 to fix it with EtsfReader(path) as data: structure = data.read_structure() assert structure.site_properties["magmom"] == ref_magmom_collinear From 022b91ad370c6b96072d1a2dea1d2186205c6aec Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Wed, 23 Oct 2024 16:11:18 +0800 Subject: [PATCH 19/42] exclude 1.7.2 as well (perhaps conditionally skip that test?) --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b71e512ae9d..9f68a690cdd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -88,7 +88,7 @@ Pypi = "https://pypi.org/project/pymatgen" [project.optional-dependencies] # PR4128: netcdf4 1.7.[0/1] yanked, 1.7.1.post[1/2]/1.7.2 cause CI error -abinit = ["netcdf4>=1.6.5,!=1.7.1.post1,!=1.7.1.post2"] +abinit = ["netcdf4>=1.6.5,!=1.7.1.post1,!=1.7.1.post2,!=1.7.2"] ase = ["ase>=3.23.0"] ci = ["pytest-cov>=4", "pytest-split>=0.8", "pytest>=8"] docs = ["invoke", "sphinx", "sphinx_markdown_builder", "sphinx_rtd_theme"] From 3dd2cdfd74cd0a9a0444ce6dd8d7f990dbf147a6 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Wed, 23 Oct 2024 17:45:35 +0800 Subject: [PATCH 20/42] add place holder --- tests/performance_tests/test_import_time.py | 69 +++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 tests/performance_tests/test_import_time.py diff --git a/tests/performance_tests/test_import_time.py b/tests/performance_tests/test_import_time.py new file mode 100644 index 00000000000..b08badec84c --- /dev/null +++ b/tests/performance_tests/test_import_time.py @@ -0,0 +1,69 @@ +""" +Test the import time of several important modules. +""" + +from __future__ import annotations + + +class TestCore: + def test_bonds(self): + pass + + def test_composition(self): + pass + + def test_interface(self): + pass + + def test_ion(self): + pass + + def test_lattice(self): + pass + + def test_libxcfunc(self): + pass + + def test_molecular_orbitals(self): + pass + + def test_operations(self): + pass + + def test_peridict_table(self): + pass + + def test_settings(self): + pass + + def test_sites(self): + pass + + def test_spectrum(self): + pass + + def test_structure(self): + pass + + def test_surface(self): + pass + + def test_tensors(self): + pass + + def test_trajectory(self): + pass + + def test_units(self): + pass + + def test_xcfunc(self): + pass + + +class TestIoVasp: + def test_inputs(self): + pass + + def test_outputs(self): + pass From 9b7f35adfffdac53a6596cafbfac8b660f3caa24 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 10:08:33 +0800 Subject: [PATCH 21/42] enhance comment --- src/pymatgen/symmetry/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pymatgen/symmetry/settings.py b/src/pymatgen/symmetry/settings.py index 5a914de3cfe..ae407b7a412 100644 --- a/src/pymatgen/symmetry/settings.py +++ b/src/pymatgen/symmetry/settings.py @@ -98,7 +98,7 @@ def parse_transformation_string( Returns: tuple[list[list[float]] | np.ndarray, list[float]]: transformation matrix & vector """ - # Import sympy is expensive + # Import sympy is expensive (PR4128) from sympy import Matrix from sympy.parsing.sympy_parser import parse_expr From 87267f4bc1255f136032c73aec66ed88b3034f98 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 10:08:46 +0800 Subject: [PATCH 22/42] add TODO tag --- tests/performance_tests/test_import_time.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/tests/performance_tests/test_import_time.py b/tests/performance_tests/test_import_time.py index b08badec84c..2ddbb6e14e0 100644 --- a/tests/performance_tests/test_import_time.py +++ b/tests/performance_tests/test_import_time.py @@ -12,13 +12,13 @@ def test_bonds(self): def test_composition(self): pass - def test_interface(self): + def test_interface(self): # TODO pass def test_ion(self): pass - def test_lattice(self): + def test_lattice(self): # TODO pass def test_libxcfunc(self): @@ -33,22 +33,19 @@ def test_operations(self): def test_peridict_table(self): pass - def test_settings(self): - pass - def test_sites(self): pass - def test_spectrum(self): + def test_spectrum(self): # TODO pass - def test_structure(self): + def test_structure(self): # TODO pass - def test_surface(self): + def test_surface(self): # TODO pass - def test_tensors(self): + def test_tensors(self): # TODO pass def test_trajectory(self): From 313d5530578f2ca2c8bd051d35f6deeaa5fc78c3 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 12:59:36 +0800 Subject: [PATCH 23/42] tweak placeholder --- tests/performance/test_performance.py | 14 +++++ tests/performance_tests/test_import_time.py | 66 --------------------- 2 files changed, 14 insertions(+), 66 deletions(-) create mode 100644 tests/performance/test_performance.py delete mode 100644 tests/performance_tests/test_import_time.py diff --git a/tests/performance/test_performance.py b/tests/performance/test_performance.py new file mode 100644 index 00000000000..5a6acc4c221 --- /dev/null +++ b/tests/performance/test_performance.py @@ -0,0 +1,14 @@ +""" +Test the import time of several important modules. + +TODO: + Test the runtime of several important modules. +""" + +from __future__ import annotations + + +class TestImportTime: + """ + Test import time of important modules. + """ diff --git a/tests/performance_tests/test_import_time.py b/tests/performance_tests/test_import_time.py deleted file mode 100644 index 2ddbb6e14e0..00000000000 --- a/tests/performance_tests/test_import_time.py +++ /dev/null @@ -1,66 +0,0 @@ -""" -Test the import time of several important modules. -""" - -from __future__ import annotations - - -class TestCore: - def test_bonds(self): - pass - - def test_composition(self): - pass - - def test_interface(self): # TODO - pass - - def test_ion(self): - pass - - def test_lattice(self): # TODO - pass - - def test_libxcfunc(self): - pass - - def test_molecular_orbitals(self): - pass - - def test_operations(self): - pass - - def test_peridict_table(self): - pass - - def test_sites(self): - pass - - def test_spectrum(self): # TODO - pass - - def test_structure(self): # TODO - pass - - def test_surface(self): # TODO - pass - - def test_tensors(self): # TODO - pass - - def test_trajectory(self): - pass - - def test_units(self): - pass - - def test_xcfunc(self): - pass - - -class TestIoVasp: - def test_inputs(self): - pass - - def test_outputs(self): - pass From fa17222a9ad12a3f5c25ca32fba96aff5c904f74 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 13:09:49 +0800 Subject: [PATCH 24/42] replace assert_allclose for scalar compare --- src/pymatgen/core/interface.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/pymatgen/core/interface.py b/src/pymatgen/core/interface.py index 823d009849f..4bb1d76eec8 100644 --- a/src/pymatgen/core/interface.py +++ b/src/pymatgen/core/interface.py @@ -14,7 +14,6 @@ import numpy as np from monty.fractions import lcm -from numpy.testing import assert_allclose from scipy.cluster.hierarchy import fcluster, linkage from scipy.spatial.distance import squareform @@ -2784,10 +2783,16 @@ def from_slabs( substrate_slab = substrate_slab.get_orthogonal_c_slab() if isinstance(film_slab, Slab): film_slab = film_slab.get_orthogonal_c_slab() - assert_allclose(film_slab.lattice.alpha, 90, 0.1) - assert_allclose(film_slab.lattice.beta, 90, 0.1) - assert_allclose(substrate_slab.lattice.alpha, 90, 0.1) - assert_allclose(substrate_slab.lattice.beta, 90, 0.1) + + if not math.isclose(film_slab.lattice.alpha, 90, rel_tol=0.1) or not math.isclose( + film_slab.lattice.beta, 90, rel_tol=0.1 + ): + raise ValueError("The lattice angles alpha or beta of the film slab are not approximately 90 degrees.") + + if not math.isclose(substrate_slab.lattice.alpha, 90, rel_tol=0.1) or not math.isclose( + substrate_slab.lattice.beta, 90, rel_tol=0.1 + ): + raise ValueError("The lattice angles alpha or beta of the substrate slab are not approximately 90 degrees.") # Ensure sub is right-handed # IE sub has surface facing "up" From 74ec0c92208c8d455813f791fa3af2d74ecd2dc7 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 13:21:09 +0800 Subject: [PATCH 25/42] replace assert_allclose with isclose --- .../interfaces/coherent_interfaces.py | 54 ++++++------------- src/pymatgen/io/vasp/outputs.py | 5 +- 2 files changed, 19 insertions(+), 40 deletions(-) diff --git a/src/pymatgen/analysis/interfaces/coherent_interfaces.py b/src/pymatgen/analysis/interfaces/coherent_interfaces.py index cce7bb2f2e0..dca5c5b33b5 100644 --- a/src/pymatgen/analysis/interfaces/coherent_interfaces.py +++ b/src/pymatgen/analysis/interfaces/coherent_interfaces.py @@ -2,11 +2,11 @@ from __future__ import annotations +import math from itertools import product from typing import TYPE_CHECKING import numpy as np -from numpy.testing import assert_allclose from scipy.linalg import polar from pymatgen.analysis.elasticity.strain import Deformation @@ -101,21 +101,15 @@ def _find_matches(self) -> None: for match in self.zsl_matches: xform = get_2d_transform(film_vectors, match.film_vectors) strain, _rot = polar(xform) - assert_allclose( - strain, - np.round(strain), - atol=1e-12, - err_msg="Film lattice vectors changed during ZSL match, check your ZSL Generator parameters", - ) + if not np.isclose(strain, np.round(strain), atol=1e-12): + raise ValueError("Film lattice vectors changed during ZSL match, check your ZSL Generator parameters") xform = get_2d_transform(substrate_vectors, match.substrate_vectors) strain, _rot = polar(xform) - assert_allclose( - strain, - strain.astype(int), - atol=1e-12, - err_msg="Substrate lattice vectors changed during ZSL match, check your ZSL Generator parameters", - ) + if not np.isclose(strain, strain.astype(int), atol=1e-12): + raise ValueError( + "Substrate lattice vectors changed during ZSL match, check your ZSL Generator parameters" + ) def _find_terminations(self): """Find all terminations.""" @@ -226,18 +220,12 @@ def get_interfaces( ).astype(int) film_sl_slab = film_slab.copy() film_sl_slab.make_supercell(super_film_transform) - assert_allclose( - film_sl_slab.lattice.matrix[2], - film_slab.lattice.matrix[2], - atol=1e-08, - err_msg="2D transformation affected C-axis for Film transformation", - ) - assert_allclose( - film_sl_slab.lattice.matrix[:2], - match.film_sl_vectors, - atol=1e-08, - err_msg="Transformation didn't make proper supercell for film", - ) + if not math.isclose(film_sl_slab.lattice.matrix[2], film_slab.lattice.matrix[2], abs_tol=1e-08): + raise ValueError( + "2D transformation affected C-axis for Film transformation", + ) + if not np.isclose(film_sl_slab.lattice.matrix[:2], match.film_sl_vectors, atol=1e-08): + raise ValueError("Transformation didn't make proper supercell for film") # Build substrate superlattice super_sub_transform = np.round( @@ -245,18 +233,10 @@ def get_interfaces( ).astype(int) sub_sl_slab = sub_slab.copy() sub_sl_slab.make_supercell(super_sub_transform) - assert_allclose( - sub_sl_slab.lattice.matrix[2], - sub_slab.lattice.matrix[2], - atol=1e-08, - err_msg="2D transformation affected C-axis for Film transformation", - ) - assert_allclose( - sub_sl_slab.lattice.matrix[:2], - match.substrate_sl_vectors, - atol=1e-08, - err_msg="Transformation didn't make proper supercell for substrate", - ) + if not math.isclose(sub_sl_slab.lattice.matrix[2], sub_slab.lattice.matrix[2], abs_tol=1e-08): + raise ValueError("2D transformation affected C-axis for Film transformation") + if not np.isclose(sub_sl_slab.lattice.matrix[:2], match.substrate_sl_vectors, atol=1e-08): + raise ValueError("Transformation didn't make proper supercell for substrate") # Add extra info match_dict = match.as_dict() diff --git a/src/pymatgen/io/vasp/outputs.py b/src/pymatgen/io/vasp/outputs.py index 19bf4e46589..93e35b4a0f9 100644 --- a/src/pymatgen/io/vasp/outputs.py +++ b/src/pymatgen/io/vasp/outputs.py @@ -24,7 +24,6 @@ from monty.json import MSONable, jsanitize from monty.os.path import zpath from monty.re import regrep -from numpy.testing import assert_allclose from tqdm import tqdm from pymatgen.core import Composition, Element, Lattice, Structure @@ -4978,8 +4977,8 @@ def __init__( if i_spin == 0: self.kpoints.append(kpoint) - else: - assert_allclose(self.kpoints[i_nk], kpoint) + elif not np.allclose(self.kpoints[i_nk], kpoint, rtol=1e-7, atol=0): + raise ValueError(f"kpoints of {i_nk=} mismatch") if verbose: print(f"kpoint {i_nk: 4} with {nplane: 5} plane waves at {kpoint}") From df8e2ff5d5e346252a21a5206c59ebd4915501d5 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 13:36:59 +0800 Subject: [PATCH 26/42] fix is close --- .../analysis/interfaces/coherent_interfaces.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/pymatgen/analysis/interfaces/coherent_interfaces.py b/src/pymatgen/analysis/interfaces/coherent_interfaces.py index dca5c5b33b5..0a0633e273a 100644 --- a/src/pymatgen/analysis/interfaces/coherent_interfaces.py +++ b/src/pymatgen/analysis/interfaces/coherent_interfaces.py @@ -2,7 +2,6 @@ from __future__ import annotations -import math from itertools import product from typing import TYPE_CHECKING @@ -101,12 +100,12 @@ def _find_matches(self) -> None: for match in self.zsl_matches: xform = get_2d_transform(film_vectors, match.film_vectors) strain, _rot = polar(xform) - if not np.isclose(strain, np.round(strain), atol=1e-12): + if not np.allclose(strain, np.round(strain), atol=1e-12): raise ValueError("Film lattice vectors changed during ZSL match, check your ZSL Generator parameters") xform = get_2d_transform(substrate_vectors, match.substrate_vectors) strain, _rot = polar(xform) - if not np.isclose(strain, strain.astype(int), atol=1e-12): + if not np.allclose(strain, strain.astype(int), atol=1e-12): raise ValueError( "Substrate lattice vectors changed during ZSL match, check your ZSL Generator parameters" ) @@ -220,11 +219,11 @@ def get_interfaces( ).astype(int) film_sl_slab = film_slab.copy() film_sl_slab.make_supercell(super_film_transform) - if not math.isclose(film_sl_slab.lattice.matrix[2], film_slab.lattice.matrix[2], abs_tol=1e-08): + if not np.allclose(film_sl_slab.lattice.matrix[2], film_slab.lattice.matrix[2], atol=1e-08): raise ValueError( "2D transformation affected C-axis for Film transformation", ) - if not np.isclose(film_sl_slab.lattice.matrix[:2], match.film_sl_vectors, atol=1e-08): + if not np.allclose(film_sl_slab.lattice.matrix[:2], match.film_sl_vectors, atol=1e-08): raise ValueError("Transformation didn't make proper supercell for film") # Build substrate superlattice @@ -233,9 +232,9 @@ def get_interfaces( ).astype(int) sub_sl_slab = sub_slab.copy() sub_sl_slab.make_supercell(super_sub_transform) - if not math.isclose(sub_sl_slab.lattice.matrix[2], sub_slab.lattice.matrix[2], abs_tol=1e-08): + if not np.allclose(sub_sl_slab.lattice.matrix[2], sub_slab.lattice.matrix[2], atol=1e-08): raise ValueError("2D transformation affected C-axis for Film transformation") - if not np.isclose(sub_sl_slab.lattice.matrix[:2], match.substrate_sl_vectors, atol=1e-08): + if not np.allclose(sub_sl_slab.lattice.matrix[:2], match.substrate_sl_vectors, atol=1e-08): raise ValueError("Transformation didn't make proper supercell for substrate") # Add extra info From 2778e2841b24da042e546e1fcc20e0d53fd3a6d1 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 13:43:34 +0800 Subject: [PATCH 27/42] use np.allclose over np.all(np.isclose()) --- src/pymatgen/core/operations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pymatgen/core/operations.py b/src/pymatgen/core/operations.py index d395c2c3d3b..5c6ea895a12 100644 --- a/src/pymatgen/core/operations.py +++ b/src/pymatgen/core/operations.py @@ -449,7 +449,7 @@ def as_xyz_str(self) -> str: Only works for integer rotation matrices. """ # Check for invalid rotation matrix - if not np.all(np.isclose(self.rotation_matrix, np.round(self.rotation_matrix))): + if not np.allclose(self.rotation_matrix, np.round(self.rotation_matrix)): warnings.warn("Rotation matrix should be integer") return transformation_to_string( From 8952c4a0bc101a6ba706a32cde21ca3f9a1d8fad Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 14:10:20 +0800 Subject: [PATCH 28/42] lazy import AseAtomsAdaptor --- src/pymatgen/core/trajectory.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pymatgen/core/trajectory.py b/src/pymatgen/core/trajectory.py index 06a58f77a3c..a7bc74ac2d6 100644 --- a/src/pymatgen/core/trajectory.py +++ b/src/pymatgen/core/trajectory.py @@ -15,7 +15,6 @@ from monty.json import MSONable from pymatgen.core.structure import Composition, DummySpecies, Element, Lattice, Molecule, Species, Structure -from pymatgen.io.ase import AseAtomsAdaptor if TYPE_CHECKING: from collections.abc import Iterator @@ -580,9 +579,12 @@ def from_file(cls, filename: str | Path, constant_lattice: bool = True, **kwargs try: from ase.io.trajectory import Trajectory as AseTrajectory + from pymatgen.io.ase import AseAtomsAdaptor + ase_traj = AseTrajectory(filename) # Periodic boundary conditions should be the same for all frames so just check the first pbc = ase_traj[0].pbc + if any(pbc): structures = [AseAtomsAdaptor.get_structure(atoms) for atoms in ase_traj] else: From c37ba45421977dab0e284fce581fbcd1f9358440 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 14:10:30 +0800 Subject: [PATCH 29/42] guard type check import --- src/pymatgen/core/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pymatgen/core/__init__.py b/src/pymatgen/core/__init__.py index 840b16e9b69..ad56b0f72b7 100644 --- a/src/pymatgen/core/__init__.py +++ b/src/pymatgen/core/__init__.py @@ -5,7 +5,7 @@ import os import warnings from importlib.metadata import PackageNotFoundError, version -from typing import Any +from typing import TYPE_CHECKING from ruamel.yaml import YAML @@ -17,6 +17,9 @@ from pymatgen.core.structure import IMolecule, IStructure, Molecule, PeriodicNeighbor, SiteCollection, Structure from pymatgen.core.units import ArrayWithUnit, FloatWithUnit, Unit +if TYPE_CHECKING: + from typing import Any + __author__ = "Pymatgen Development Team" __email__ = "pymatgen@googlegroups.com" __maintainer__ = "Shyue Ping Ong, Matthew Horton, Janosh Riebesell" From 1674a960ee1174bf2e40f78cc839390520a57313 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 14:26:47 +0800 Subject: [PATCH 30/42] lazy import matplotlib --- src/pymatgen/analysis/adsorption.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pymatgen/analysis/adsorption.py b/src/pymatgen/analysis/adsorption.py index 3e953ec00e7..fcb96a935e8 100644 --- a/src/pymatgen/analysis/adsorption.py +++ b/src/pymatgen/analysis/adsorption.py @@ -9,8 +9,6 @@ from typing import TYPE_CHECKING import numpy as np -from matplotlib import patches -from matplotlib.path import Path from monty.serialization import loadfn from scipy.spatial import Delaunay @@ -664,6 +662,10 @@ def plot_slab( decay (float): how the alpha-value decays along the z-axis inverse (bool): invert z axis to plot opposite surface """ + # Expensive import (PR4128) + from matplotlib import patches + from matplotlib.path import Path + orig_slab = slab.copy() slab = reorient_z(slab) orig_cell = slab.lattice.matrix.copy() From 8ac0c7f4b8eb7a36fb735bad6b74824bf0adc4d7 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 16:34:52 +0800 Subject: [PATCH 31/42] toggle reference generation --- tests/performance/test_import_time.py | 112 ++++++++++++++++++++++++++ tests/performance/test_performance.py | 14 ---- 2 files changed, 112 insertions(+), 14 deletions(-) create mode 100644 tests/performance/test_import_time.py delete mode 100644 tests/performance/test_performance.py diff --git a/tests/performance/test_import_time.py b/tests/performance/test_import_time.py new file mode 100644 index 00000000000..49adb49cddd --- /dev/null +++ b/tests/performance/test_import_time.py @@ -0,0 +1,112 @@ +""" +Test the import time of several important modules. +""" +# ruff: noqa: T201 (check for print statement) + +from __future__ import annotations + +import json +import os +import subprocess +import time +from typing import TYPE_CHECKING + +import pytest + +if TYPE_CHECKING: + from typing import Literal + +# Toggle this to generate reference import times +GEN_REF_TIME = True + +MODULES_TO_TEST = ( + "from pymatgen.core.bonds import CovalentBond", + "from pymatgen.core.composition import Composition", + "from pymatgen.core.interface import Interface", + "from pymatgen.core.ion import Ion", + "from pymatgen.core.lattice import Lattice", + "from pymatgen.core.libxcfunc import LibxcFunc", + "from pymatgen.core.molecular_orbitals import MolecularOrbitals", + "from pymatgen.core.operations import SymmOp", + "from pymatgen.core.periodic_table import Element", + "from pymatgen.core.sites import Site", + "from pymatgen.core.spectrum import Spectrum", + "from pymatgen.core.structure import Structure", + "from pymatgen.core.surface import Slab", + "from pymatgen.core.tensors import Tensor", + "from pymatgen.core.trajectory import Trajectory", + "from pymatgen.core.units import Unit", + "from pymatgen.core.xcfunc import XcFunc", +) + +# Get runner OS and reference file +RUNNER_OS: Literal["linux", "windows", "macos"] = os.getenv("RUNNER_OS", "").lower() # type: ignore[assignment] +assert RUNNER_OS in {"linux", "windows", "macos"} +REF_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), f"import_time_{RUNNER_OS}.json") + + +@pytest.mark.skipif(not GEN_REF_TIME, reason="Set GEN_REF_TIME to generate reference import time.") +def test_get_ref_import_time() -> None: + """A dummy test that would always fail, used to generate copyable reference time.""" + import_times = { + module_import_cmd: _measure_import_time_in_ms(module_import_cmd) for module_import_cmd in MODULES_TO_TEST + } + + # Print a copyable JSON format for easy reference updating + print("\nCopyable import time JSON:") + print(json.dumps(import_times, indent=4)) + + pytest.fail("Reference import times generated. Copy from output to update JSON file.") + + +@pytest.mark.skipif(GEN_REF_TIME, reason="Generating reference import time.") +def test_import_time(grace_percent: float = 0.20, hard_percent: float = 0.50) -> None: + """Test the import time of core modules to avoid performance regression. + + Args: + grace_percent (float): Maximum allowed percentage increase in import time + before a warning is raised. + hard_percent (float): Maximum allowed percentage increase in import time + before the test fails. + """ + try: + with open(REF_FILE, encoding="utf-8") as file: + ref_import_times = json.load(file) + except FileNotFoundError: + pytest.fail(f"Reference file {REF_FILE} not found. Please generate it.") + + for module_import_cmd, ref_time in ref_import_times.items(): + current_time = _measure_import_time_in_ms(module_import_cmd) + + # Calculate thresholds for grace and hard limits + grace_threshold = ref_time * (1 + grace_percent) + hard_threshold = ref_time * (1 + hard_percent) + + if current_time > grace_threshold: + if current_time > hard_threshold: + pytest.fail(f"{module_import_cmd} import too slow! {hard_threshold=:.2f} ms") + else: + pytest.warns( + UserWarning, + f"{module_import_cmd} import slightly slower than reference: {grace_threshold=:.2f} ms", + ) + + +def _measure_import_time_in_ms(module_import_cmd: str, count: int = 3) -> float: + """Measure import time of a module in milliseconds across several runs. + + Args: + module_import_cmd (str): The module import command. + count (int): Number of runs to average. + + Returns: + float: Import time in milliseconds. + """ + total_time = 0.0 + + for _ in range(count): + start_time = time.perf_counter() + subprocess.run(["python", "-c", f"{module_import_cmd}"], check=True) + total_time += time.perf_counter() - start_time + + return (total_time / count) * 1000 diff --git a/tests/performance/test_performance.py b/tests/performance/test_performance.py deleted file mode 100644 index 5a6acc4c221..00000000000 --- a/tests/performance/test_performance.py +++ /dev/null @@ -1,14 +0,0 @@ -""" -Test the import time of several important modules. - -TODO: - Test the runtime of several important modules. -""" - -from __future__ import annotations - - -class TestImportTime: - """ - Test import time of important modules. - """ From 2f7f99322a9a191c779a5704e2507e39a14c9633 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 16:54:02 +0800 Subject: [PATCH 32/42] update import time records --- .../files/performance/import_time_linux.json | 19 +++++++++++++ .../files/performance/import_time_macos.json | 19 +++++++++++++ .../performance/import_time_windows.json | 19 +++++++++++++ tests/performance/test_import_time.py | 28 +++++++++++-------- 4 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 tests/files/performance/import_time_linux.json create mode 100644 tests/files/performance/import_time_macos.json create mode 100644 tests/files/performance/import_time_windows.json diff --git a/tests/files/performance/import_time_linux.json b/tests/files/performance/import_time_linux.json new file mode 100644 index 00000000000..3492c93a840 --- /dev/null +++ b/tests/files/performance/import_time_linux.json @@ -0,0 +1,19 @@ +{ + "from pymatgen.core.bonds import CovalentBond": 289.5851116666108, + "from pymatgen.core.composition import Composition": 292.8479909999548, + "from pymatgen.core.interface import Interface": 969.5693099999593, + "from pymatgen.core.ion import Ion": 291.07530133334575, + "from pymatgen.core.lattice import Lattice": 288.8340153333881, + "from pymatgen.core.libxcfunc import LibxcFunc": 293.4184753333587, + "from pymatgen.core.molecular_orbitals import MolecularOrbitals": 294.19796566658835, + "from pymatgen.core.operations import SymmOp": 296.4627546666634, + "from pymatgen.core.periodic_table import Element": 295.95872066662804, + "from pymatgen.core.sites import Site": 292.66485499999817, + "from pymatgen.core.spectrum import Spectrum": 486.72776566669046, + "from pymatgen.core.structure import Structure": 291.01618733333606, + "from pymatgen.core.surface import Slab": 301.90875833329756, + "from pymatgen.core.tensors import Tensor": 304.27744800003137, + "from pymatgen.core.trajectory import Trajectory": 300.45536066666045, + "from pymatgen.core.units import Unit": 305.4779056666348, + "from pymatgen.core.xcfunc import XcFunc": 309.1085626666275 +} \ No newline at end of file diff --git a/tests/files/performance/import_time_macos.json b/tests/files/performance/import_time_macos.json new file mode 100644 index 00000000000..9ac1e63fc9d --- /dev/null +++ b/tests/files/performance/import_time_macos.json @@ -0,0 +1,19 @@ +{ + "from pymatgen.core.bonds import CovalentBond": 321.8502360000457, + "from pymatgen.core.composition import Composition": 292.35445800009074, + "from pymatgen.core.interface import Interface": 855.005861000033, + "from pymatgen.core.ion import Ion": 240.8930970000256, + "from pymatgen.core.lattice import Lattice": 329.09868066659936, + "from pymatgen.core.libxcfunc import LibxcFunc": 306.6966386666839, + "from pymatgen.core.molecular_orbitals import MolecularOrbitals": 281.78087466661356, + "from pymatgen.core.operations import SymmOp": 299.9741943333447, + "from pymatgen.core.periodic_table import Element": 293.6565829999533, + "from pymatgen.core.sites import Site": 280.3443330000543, + "from pymatgen.core.spectrum import Spectrum": 459.20266666666976, + "from pymatgen.core.structure import Structure": 265.4675833332476, + "from pymatgen.core.surface import Slab": 306.0919996667053, + "from pymatgen.core.tensors import Tensor": 310.54281933325, + "from pymatgen.core.trajectory import Trajectory": 335.25658333329983, + "from pymatgen.core.units import Unit": 294.03472200003006, + "from pymatgen.core.xcfunc import XcFunc": 309.3993196666058 +} \ No newline at end of file diff --git a/tests/files/performance/import_time_windows.json b/tests/files/performance/import_time_windows.json new file mode 100644 index 00000000000..270b73a9d65 --- /dev/null +++ b/tests/files/performance/import_time_windows.json @@ -0,0 +1,19 @@ +{ + "from pymatgen.core.bonds import CovalentBond": 443.7560000000455, + "from pymatgen.core.composition import Composition": 441.06553333335796, + "from pymatgen.core.interface import Interface": 1828.751033333295, + "from pymatgen.core.ion import Ion": 443.58053333333675, + "from pymatgen.core.lattice import Lattice": 445.729999999988, + "from pymatgen.core.libxcfunc import LibxcFunc": 459.24773333338936, + "from pymatgen.core.molecular_orbitals import MolecularOrbitals": 440.4825999999957, + "from pymatgen.core.operations import SymmOp": 440.62226666665083, + "from pymatgen.core.periodic_table import Element": 441.64050000002436, + "from pymatgen.core.sites import Site": 442.1802333333744, + "from pymatgen.core.spectrum import Spectrum": 737.3025000000174, + "from pymatgen.core.structure import Structure": 445.0546333332568, + "from pymatgen.core.surface import Slab": 463.0683333333157, + "from pymatgen.core.tensors import Tensor": 463.5761666666743, + "from pymatgen.core.trajectory import Trajectory": 443.9995333333779, + "from pymatgen.core.units import Unit": 446.352766666602, + "from pymatgen.core.xcfunc import XcFunc": 469.42599999996065 +} \ No newline at end of file diff --git a/tests/performance/test_import_time.py b/tests/performance/test_import_time.py index 49adb49cddd..d969ec50288 100644 --- a/tests/performance/test_import_time.py +++ b/tests/performance/test_import_time.py @@ -1,7 +1,9 @@ """ Test the import time of several important modules. + +NOTE: + - Toggle the "GEN_REF_TIME" to generate reference import time. """ -# ruff: noqa: T201 (check for print statement) from __future__ import annotations @@ -9,17 +11,20 @@ import os import subprocess import time +import warnings from typing import TYPE_CHECKING import pytest +from pymatgen.util.testing import TEST_FILES_DIR + if TYPE_CHECKING: from typing import Literal -# Toggle this to generate reference import times -GEN_REF_TIME = True +# NOTE: Toggle this to generate reference import time +GEN_REF_TIME: bool = False -MODULES_TO_TEST = ( +MODULES_TO_TEST: tuple[str, ...] = ( "from pymatgen.core.bonds import CovalentBond", "from pymatgen.core.composition import Composition", "from pymatgen.core.interface import Interface", @@ -42,7 +47,8 @@ # Get runner OS and reference file RUNNER_OS: Literal["linux", "windows", "macos"] = os.getenv("RUNNER_OS", "").lower() # type: ignore[assignment] assert RUNNER_OS in {"linux", "windows", "macos"} -REF_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), f"import_time_{RUNNER_OS}.json") + +REF_FILE: str = f"{TEST_FILES_DIR}/performance/import_time_{RUNNER_OS}.json" @pytest.mark.skipif(not GEN_REF_TIME, reason="Set GEN_REF_TIME to generate reference import time.") @@ -69,11 +75,9 @@ def test_import_time(grace_percent: float = 0.20, hard_percent: float = 0.50) -> hard_percent (float): Maximum allowed percentage increase in import time before the test fails. """ - try: - with open(REF_FILE, encoding="utf-8") as file: - ref_import_times = json.load(file) - except FileNotFoundError: - pytest.fail(f"Reference file {REF_FILE} not found. Please generate it.") + + with open(REF_FILE, encoding="utf-8") as file: + ref_import_times = json.load(file) for module_import_cmd, ref_time in ref_import_times.items(): current_time = _measure_import_time_in_ms(module_import_cmd) @@ -86,9 +90,9 @@ def test_import_time(grace_percent: float = 0.20, hard_percent: float = 0.50) -> if current_time > hard_threshold: pytest.fail(f"{module_import_cmd} import too slow! {hard_threshold=:.2f} ms") else: - pytest.warns( - UserWarning, + warnings.warn( f"{module_import_cmd} import slightly slower than reference: {grace_threshold=:.2f} ms", + stacklevel=2, ) From abf5f8ba7a983018c089b7cd3e9dca11b536d3c3 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 16:59:04 +0800 Subject: [PATCH 33/42] skip in not CI env --- tests/performance/test_import_time.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/performance/test_import_time.py b/tests/performance/test_import_time.py index d969ec50288..03ce60ef5f7 100644 --- a/tests/performance/test_import_time.py +++ b/tests/performance/test_import_time.py @@ -21,6 +21,9 @@ if TYPE_CHECKING: from typing import Literal +if not os.getenv("CI"): + pytest.skip("ref time only comparable in CI runner", allow_module_level=True) + # NOTE: Toggle this to generate reference import time GEN_REF_TIME: bool = False From de4dc3b30fdb1d2b96850ef0d7fc19de1ad1876b Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 17:10:24 +0800 Subject: [PATCH 34/42] include current time in err msg --- tests/performance/test_import_time.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/performance/test_import_time.py b/tests/performance/test_import_time.py index 03ce60ef5f7..c33381fbf48 100644 --- a/tests/performance/test_import_time.py +++ b/tests/performance/test_import_time.py @@ -91,7 +91,7 @@ def test_import_time(grace_percent: float = 0.20, hard_percent: float = 0.50) -> if current_time > grace_threshold: if current_time > hard_threshold: - pytest.fail(f"{module_import_cmd} import too slow! {hard_threshold=:.2f} ms") + pytest.fail(f"{module_import_cmd} import too slow at {current_time:.2f} ms! {hard_threshold=:.2f} ms") else: warnings.warn( f"{module_import_cmd} import slightly slower than reference: {grace_threshold=:.2f} ms", From 8f5c2ac56183619ee794249a6a6d2b69225b14c1 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 17:16:30 +0800 Subject: [PATCH 35/42] loose hard threshold to 100%, as it appear macos runner is prone to fluctuation --- tests/performance/test_import_time.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/performance/test_import_time.py b/tests/performance/test_import_time.py index c33381fbf48..66b790fba08 100644 --- a/tests/performance/test_import_time.py +++ b/tests/performance/test_import_time.py @@ -3,6 +3,13 @@ NOTE: - Toggle the "GEN_REF_TIME" to generate reference import time. + +Last update: 2024-10-26 + +Runner specs: +Linux: 4 CPU +Windows: 4 CPU +macOS: 3 CPU (M1) """ from __future__ import annotations @@ -69,7 +76,7 @@ def test_get_ref_import_time() -> None: @pytest.mark.skipif(GEN_REF_TIME, reason="Generating reference import time.") -def test_import_time(grace_percent: float = 0.20, hard_percent: float = 0.50) -> None: +def test_import_time(grace_percent: float = 0.5, hard_percent: float = 1.0) -> None: """Test the import time of core modules to avoid performance regression. Args: From 4849da01d75db6ba8a3e1901d17e097a1e5e8002 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 17:25:10 +0800 Subject: [PATCH 36/42] update type --- src/pymatgen/core/__init__.py | 1 + tests/performance/test_import_time.py | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pymatgen/core/__init__.py b/src/pymatgen/core/__init__.py index ad56b0f72b7..68343cac523 100644 --- a/src/pymatgen/core/__init__.py +++ b/src/pymatgen/core/__init__.py @@ -24,6 +24,7 @@ __email__ = "pymatgen@googlegroups.com" __maintainer__ = "Shyue Ping Ong, Matthew Horton, Janosh Riebesell" __maintainer_email__ = "shyuep@gmail.com" + try: __version__ = version("pymatgen") except PackageNotFoundError: # pragma: no cover diff --git a/tests/performance/test_import_time.py b/tests/performance/test_import_time.py index 66b790fba08..444a821e6fd 100644 --- a/tests/performance/test_import_time.py +++ b/tests/performance/test_import_time.py @@ -64,7 +64,7 @@ @pytest.mark.skipif(not GEN_REF_TIME, reason="Set GEN_REF_TIME to generate reference import time.") def test_get_ref_import_time() -> None: """A dummy test that would always fail, used to generate copyable reference time.""" - import_times = { + import_times: dict[str, float] = { module_import_cmd: _measure_import_time_in_ms(module_import_cmd) for module_import_cmd in MODULES_TO_TEST } @@ -87,10 +87,10 @@ def test_import_time(grace_percent: float = 0.5, hard_percent: float = 1.0) -> N """ with open(REF_FILE, encoding="utf-8") as file: - ref_import_times = json.load(file) + ref_import_times: dict[str, float] = json.load(file) for module_import_cmd, ref_time in ref_import_times.items(): - current_time = _measure_import_time_in_ms(module_import_cmd) + current_time: float = _measure_import_time_in_ms(module_import_cmd) # Calculate thresholds for grace and hard limits grace_threshold = ref_time * (1 + grace_percent) From aceb5b5b3a78a2a682035c2409e485b4b5b370e0 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 17:29:31 +0800 Subject: [PATCH 37/42] skip test for macos --- tests/performance/test_import_time.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/performance/test_import_time.py b/tests/performance/test_import_time.py index 444a821e6fd..c8ba6472a90 100644 --- a/tests/performance/test_import_time.py +++ b/tests/performance/test_import_time.py @@ -58,6 +58,10 @@ RUNNER_OS: Literal["linux", "windows", "macos"] = os.getenv("RUNNER_OS", "").lower() # type: ignore[assignment] assert RUNNER_OS in {"linux", "windows", "macos"} +# Skip test on macOS due to inconsistent import time results +if RUNNER_OS == "macos": + pytest.skip("Import time measurements are unstable on macOS", allow_module_level=True) + REF_FILE: str = f"{TEST_FILES_DIR}/performance/import_time_{RUNNER_OS}.json" From eb51fee96879fa6959d91378654a6b9441343a4f Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 17:32:12 +0800 Subject: [PATCH 38/42] add PR tag for easy tracing --- tests/performance/test_import_time.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/performance/test_import_time.py b/tests/performance/test_import_time.py index c8ba6472a90..66255dc1ffa 100644 --- a/tests/performance/test_import_time.py +++ b/tests/performance/test_import_time.py @@ -4,7 +4,7 @@ NOTE: - Toggle the "GEN_REF_TIME" to generate reference import time. -Last update: 2024-10-26 +Last update: 2024-10-26 (PR 4128) Runner specs: Linux: 4 CPU From c64ecaedd2561c4adeac00f91a6a9611a8825776 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Sat, 26 Oct 2024 17:38:15 +0800 Subject: [PATCH 39/42] use perf_counter_ns for precision --- tests/performance/test_import_time.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/performance/test_import_time.py b/tests/performance/test_import_time.py index 66255dc1ffa..9c9f9d5daf1 100644 --- a/tests/performance/test_import_time.py +++ b/tests/performance/test_import_time.py @@ -123,8 +123,8 @@ def _measure_import_time_in_ms(module_import_cmd: str, count: int = 3) -> float: total_time = 0.0 for _ in range(count): - start_time = time.perf_counter() + start_time = time.perf_counter_ns() subprocess.run(["python", "-c", f"{module_import_cmd}"], check=True) - total_time += time.perf_counter() - start_time + total_time += time.perf_counter_ns() - start_time - return (total_time / count) * 1000 + return (total_time / count) / 1e6 From 9c3d1865e632783519eb11d2009ad3d44e7041ec Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Wed, 30 Oct 2024 14:19:18 +0800 Subject: [PATCH 40/42] bump torch timeout all the way to 5 min --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fb481f6270b..e37e27d6826 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -82,7 +82,7 @@ jobs: # TODO1 (use uv over pip) uv install torch is flaky, track #3826 # TODO2 (pin torch version): DGL library (matgl) doesn't support torch > 2.2.1, # see: https://discuss.dgl.ai/t/filenotfounderror-cannot-find-dgl-c-graphbolt-library/4302 - pip install torch==2.2.1 + pip install --timeout=300 torch==2.2.1 uv pip install --editable '.[${{ matrix.config.extras }}]' --resolution=${{ matrix.config.resolution }} From 9ea93eba75b7c72578a941ad96a88c6f1cb44950 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Wed, 30 Oct 2024 14:32:53 +0800 Subject: [PATCH 41/42] Revert "bump torch timeout all the way to 5 min" This reverts commit 9c3d1865e632783519eb11d2009ad3d44e7041ec. --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e37e27d6826..fb481f6270b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -82,7 +82,7 @@ jobs: # TODO1 (use uv over pip) uv install torch is flaky, track #3826 # TODO2 (pin torch version): DGL library (matgl) doesn't support torch > 2.2.1, # see: https://discuss.dgl.ai/t/filenotfounderror-cannot-find-dgl-c-graphbolt-library/4302 - pip install --timeout=300 torch==2.2.1 + pip install torch==2.2.1 uv pip install --editable '.[${{ matrix.config.extras }}]' --resolution=${{ matrix.config.resolution }} From b0013611e222c514c36ede7cfb846de6440e36ed Mon Sep 17 00:00:00 2001 From: Haoyu Yang Date: Wed, 30 Oct 2024 18:44:19 +0800 Subject: [PATCH 42/42] migrate missing allclose relative tolerance --- .../analysis/interfaces/coherent_interfaces.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pymatgen/analysis/interfaces/coherent_interfaces.py b/src/pymatgen/analysis/interfaces/coherent_interfaces.py index 0a0633e273a..bc24592075a 100644 --- a/src/pymatgen/analysis/interfaces/coherent_interfaces.py +++ b/src/pymatgen/analysis/interfaces/coherent_interfaces.py @@ -100,12 +100,12 @@ def _find_matches(self) -> None: for match in self.zsl_matches: xform = get_2d_transform(film_vectors, match.film_vectors) strain, _rot = polar(xform) - if not np.allclose(strain, np.round(strain), atol=1e-12): + if not np.allclose(strain, np.round(strain), rtol=1e-7, atol=1e-12): raise ValueError("Film lattice vectors changed during ZSL match, check your ZSL Generator parameters") xform = get_2d_transform(substrate_vectors, match.substrate_vectors) strain, _rot = polar(xform) - if not np.allclose(strain, strain.astype(int), atol=1e-12): + if not np.allclose(strain, strain.astype(int), rtol=1e-7, atol=1e-12): raise ValueError( "Substrate lattice vectors changed during ZSL match, check your ZSL Generator parameters" ) @@ -219,11 +219,11 @@ def get_interfaces( ).astype(int) film_sl_slab = film_slab.copy() film_sl_slab.make_supercell(super_film_transform) - if not np.allclose(film_sl_slab.lattice.matrix[2], film_slab.lattice.matrix[2], atol=1e-08): + if not np.allclose(film_sl_slab.lattice.matrix[2], film_slab.lattice.matrix[2], rtol=1e-7, atol=1e-08): raise ValueError( "2D transformation affected C-axis for Film transformation", ) - if not np.allclose(film_sl_slab.lattice.matrix[:2], match.film_sl_vectors, atol=1e-08): + if not np.allclose(film_sl_slab.lattice.matrix[:2], match.film_sl_vectors, rtol=1e-7, atol=1e-08): raise ValueError("Transformation didn't make proper supercell for film") # Build substrate superlattice @@ -232,9 +232,9 @@ def get_interfaces( ).astype(int) sub_sl_slab = sub_slab.copy() sub_sl_slab.make_supercell(super_sub_transform) - if not np.allclose(sub_sl_slab.lattice.matrix[2], sub_slab.lattice.matrix[2], atol=1e-08): + if not np.allclose(sub_sl_slab.lattice.matrix[2], sub_slab.lattice.matrix[2], rtol=1e-7, atol=1e-08): raise ValueError("2D transformation affected C-axis for Film transformation") - if not np.allclose(sub_sl_slab.lattice.matrix[:2], match.substrate_sl_vectors, atol=1e-08): + if not np.allclose(sub_sl_slab.lattice.matrix[:2], match.substrate_sl_vectors, rtol=1e-7, atol=1e-08): raise ValueError("Transformation didn't make proper supercell for substrate") # Add extra info