diff --git a/src/py/mat3ra/made/lattice.py b/src/py/mat3ra/made/lattice.py index 3eb95fe8f..6f739d7c5 100644 --- a/src/py/mat3ra/made/lattice.py +++ b/src/py/mat3ra/made/lattice.py @@ -128,6 +128,20 @@ def cell_volume(self) -> float: def cell_volume_rounded(self) -> float: return self.vectors.volume_rounded + @property + def reciprocal_vectors(self): + return np.linalg.inv(np.array(self.vector_arrays, dtype=float)).T.tolist() + + @property + def reciprocal_vector_norms(self) -> List[float]: + return [float(np.linalg.norm(vector)) for vector in self.reciprocal_vectors] + + @property + def reciprocal_vector_ratios(self) -> List[float]: + norms = self.reciprocal_vector_norms + max_norm = max(norms) + return [round(float(value / max_norm), 3) for value in norms] + def get_hash_string(self, is_scaled: bool = False) -> str: """Mirrors JS Lattice.getHashString(isScaled). Rounds to HASH_TOLERANCE decimal places.""" scale = self.a if is_scaled else 1 diff --git a/tests/py/unit/test_lattice.py b/tests/py/unit/test_lattice.py index d0ccf6890..a57bee13c 100644 --- a/tests/py/unit/test_lattice.py +++ b/tests/py/unit/test_lattice.py @@ -1,3 +1,5 @@ +import pytest + from mat3ra.code.vector import RoundedVector3D from mat3ra.made.lattice import Lattice from mat3ra.utils import assertion as assertion_utils @@ -75,5 +77,28 @@ def test_lattice_get_scaled_by_matrix(): assertion_utils.assert_deep_almost_equal(lattice.vector_arrays, expected_vector_values) +def test_reciprocal_vectors(): + lattice = Lattice(a=2.0, b=3.0, c=4.0) + expected_vectors = [[0.5, 0.0, 0.0], [0.0, 1 / 3, 0.0], [0.0, 0.0, 0.25]] + assertion_utils.assert_deep_almost_equal(lattice.reciprocal_vectors, expected_vectors) + + +def test_reciprocal_vector_norms(): + lattice = Lattice(a=2.0, b=3.0, c=4.0) + expected_norms = [0.5, 1 / 3, 0.25] + assertion_utils.assert_deep_almost_equal(lattice.reciprocal_vector_norms, expected_norms) + + +@pytest.mark.parametrize( + "lattice, expected", + [ + (Lattice(a=2.0, b=3.0, c=4.0), [1.0, 0.667, 0.5]), + (Lattice(a=5.43, b=5.43, c=5.43), [1.0, 1.0, 1.0]), + ], +) +def test_reciprocal_vector_ratios(lattice, expected): + assert lattice.reciprocal_vector_ratios == expected + + # to test: create, calculate_vectors, from_vectors, get_lattice_type, clone # from_vectors, to_dict, cell, cell_volume, scale_by_matrix, update_from_lattice,