Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions news/deprecate-lattice.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
**Added:**

* Added ``set_latt_parms`` method into ``Lattice`` class
* Added ``set_new_latt_base_vec`` method into ``Lattice`` class

**Changed:**

* <news item>

**Deprecated:**

* Deprecated ``setLatPar`` method in ``Lattice`` class for removal in version 4.0.0
* Deprecated ``setLatBase`` method in ``Lattice`` class for removal in version 4.0.0

**Removed:**

* <news item>

**Fixed:**

* <news item>

**Security:**

* <news item>
2 changes: 1 addition & 1 deletion src/diffpy/structure/expansion/supercell_mod.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def supercell(S, mno):
newS.__setitem__(slice(None), newAtoms, copy=False)

# take care of lattice parameters
newS.lattice.setLatPar(a=mno[0] * S.lattice.a, b=mno[1] * S.lattice.b, c=mno[2] * S.lattice.c)
newS.lattice.set_latt_parms(a=mno[0] * S.lattice.a, b=mno[1] * S.lattice.b, c=mno[2] * S.lattice.c)
return newS


Expand Down
63 changes: 53 additions & 10 deletions src/diffpy/structure/lattice.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@
import numpy.linalg as numalg

from diffpy.structure.structureerrors import LatticeError
from diffpy.utils._deprecator import build_deprecation_message, deprecated

base = "diffpy.structure.Lattice"
removal_version = "4.0.0"
setLatPar_deprecation_msg = build_deprecation_message(
base,
"setLatPar",
"set_latt_parms",
removal_version,
)
setLatBase_deprecation_msg = build_deprecation_message(
base,
"setLatBase",
"set_new_latt_base_vec",
removal_version,
)

# Helper Functions -----------------------------------------------------------

Expand Down Expand Up @@ -168,37 +184,37 @@ class Lattice(object):

a = property(
lambda self: self._a,
lambda self, value: self.setLatPar(a=value),
lambda self, value: self.set_latt_parms(a=value),
doc="The unit cell length *a*.",
)

b = property(
lambda self: self._b,
lambda self, value: self.setLatPar(b=value),
lambda self, value: self.set_latt_parms(b=value),
doc="The unit cell length *b*.",
)

c = property(
lambda self: self._c,
lambda self, value: self.setLatPar(c=value),
lambda self, value: self.set_latt_parms(c=value),
doc="The unit cell length *c*.",
)

alpha = property(
lambda self: self._alpha,
lambda self, value: self.setLatPar(alpha=value),
lambda self, value: self.set_latt_parms(alpha=value),
doc="The cell angle *alpha* in degrees.",
)

beta = property(
lambda self: self._beta,
lambda self, value: self.setLatPar(beta=value),
lambda self, value: self.set_latt_parms(beta=value),
doc="The cell angle *beta* in degrees.",
)

gamma = property(
lambda self: self._gamma,
lambda self, value: self.setLatPar(gamma=value),
lambda self, value: self.set_latt_parms(gamma=value),
doc="The cell angle *gamma* in degrees.",
)

Expand Down Expand Up @@ -323,12 +339,12 @@ def __init__(
# work out argument variants
# Lattice()
if not argset:
self.setLatPar(1.0, 1.0, 1.0, 90.0, 90.0, 90.0, baserot)
self.set_latt_parms(1.0, 1.0, 1.0, 90.0, 90.0, 90.0, baserot)
# Lattice(base=abc)
elif base is not None:
if len(argset) > 1:
raise ValueError("'base' must be the only argument.")
self.setLatBase(base)
self.set_new_latt_base_vec(base)
# Lattice(lat)
elif isinstance(a, Lattice):
if len(argset) > 1:
Expand All @@ -339,10 +355,10 @@ def __init__(
abcabg = ("a", "b", "c", "alpha", "beta", "gamma")
if not argset.issuperset(abcabg):
raise ValueError("Provide all 6 cell parameters.")
self.setLatPar(a, b, c, alpha, beta, gamma, baserot=baserot)
self.set_latt_parms(a, b, c, alpha, beta, gamma, baserot=baserot)
return

def setLatPar(
def set_latt_parms(
self,
a=None,
b=None,
Expand Down Expand Up @@ -441,7 +457,34 @@ def setLatPar(
self.isotropicunit = _isotropicunit(self.recnormbase)
return

@deprecated(setLatPar_deprecation_msg)
def setLatPar(
self,
a=None,
b=None,
c=None,
alpha=None,
beta=None,
gamma=None,
baserot=None,
):
"""This function has been deprecated and will be removed in
version 4.0.0.

Please use diffpy.structure.Lattice.set_lat_par instead.
"""
return self.set_latt_parms(a, b, c, alpha, beta, gamma, baserot)

@deprecated(setLatBase_deprecation_msg)
def setLatBase(self, base):
"""This function has been deprecated and will be removed in
version 4.0.0.

Please use diffpy.structure.Lattice.set_lat_base instead.
"""
return self.set_new_latt_base_vec(base)

def set_new_latt_base_vec(self, base):
"""Set new base vectors for this lattice.

This updates the cell lengths and cell angles according to the
Expand Down
2 changes: 1 addition & 1 deletion src/diffpy/structure/parsers/p_discus.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ def _parse_cell(self, words):
words = self.line.replace(",", " ").split()
latpars = [float(w) for w in words[1:7]]
try:
self.stru.lattice.setLatPar(*latpars)
self.stru.lattice.set_latt_parms(*latpars)
except ZeroDivisionError:
emsg = "%d: Invalid lattice parameters - zero cell volume" % self.nl
raise StructureFormatError(emsg)
Expand Down
4 changes: 2 additions & 2 deletions src/diffpy/structure/parsers/p_pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def parseLines(self, lines):
alpha = float(line[33:40])
beta = float(line[40:47])
gamma = float(line[47:54])
stru.lattice.setLatPar(a, b, c, alpha, beta, gamma)
stru.lattice.set_latt_parms(a, b, c, alpha, beta, gamma)
scale = numpy.transpose(stru.lattice.recbase)
elif record == "SCALE1":
sc = numpy.zeros((3, 3), dtype=float)
Expand All @@ -171,7 +171,7 @@ def parseLines(self, lines):
scaleU[2] = float(line[45:55])
base = numpy.transpose(numpy.linalg.inv(sc))
abcABGcryst = numpy.array(stru.lattice.abcABG())
stru.lattice.setLatBase(base)
stru.lattice.set_new_latt_base_vec(base)
abcABGscale = numpy.array(stru.lattice.abcABG())
reldiff = numpy.fabs(1.0 - abcABGscale / abcABGcryst)
if not numpy.all(reldiff < 1.0e-4):
Expand Down
2 changes: 1 addition & 1 deletion src/diffpy/structure/parsers/p_xcfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ def parseLines(self, lines):
emsg = ("%d: auxiliary fields are " "not consistent with entry_count") % p_nl
raise StructureFormatError(emsg)
# define proper lattice
stru.lattice.setLatBase(xcfg_H0)
stru.lattice.set_new_latt_base_vec(xcfg_H0)
# here we are inside the data block
p_element = None
for line in ilines:
Expand Down
75 changes: 65 additions & 10 deletions tests/test_lattice.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def test___init__(self):
self.assertRaises(ValueError, Lattice, 1, 2, 3)
self.assertRaises(ValueError, Lattice, 1, 2, 3, 80, 90)
L0 = self.lattice
L0.setLatBase(L0.cartesian([[1, 1, 0], [0, 1, 1], [1, 0, 1]]))
L0.set_new_latt_base_vec(L0.cartesian([[1, 1, 0], [0, 1, 1], [1, 0, 1]]))
L1 = Lattice(L0)
self.assertTrue(numpy.array_equal(L0.base, L1.base))
L2 = Lattice(base=L0.base)
Expand Down Expand Up @@ -77,6 +77,28 @@ def cosd(x):
self.assertAlmostEqual(cosd(120.0), dot(base[0], base[1]) / (1 * 2), self.places)
return

def test_set_lat_par(self):
"""Check calculation of standard unit cell vectors."""
from math import cos, radians, sqrt

from numpy import dot

def norm(x):
return sqrt(sum([xi**2 for xi in x]))

def cosd(x):
return cos(radians(x))

self.lattice.set_latt_parms(1.0, 2.0, 3.0, 80, 100, 120)
base = self.lattice.base
self.assertAlmostEqual(1.0, norm(base[0]), self.places)
self.assertAlmostEqual(2.0, norm(base[1]), self.places)
self.assertAlmostEqual(3.0, norm(base[2]), self.places)
self.assertAlmostEqual(cosd(80.0), dot(base[1], base[2]) / (2 * 3), self.places)
self.assertAlmostEqual(cosd(100.0), dot(base[0], base[2]) / (1 * 3), self.places)
self.assertAlmostEqual(cosd(120.0), dot(base[0], base[1]) / (1 * 2), self.places)
return

def test_latpar_properties(self):
"""Check assignment to a, b, c, alpha, beta, gamma."""
lat = self.lattice
Expand Down Expand Up @@ -152,9 +174,9 @@ def test_setLatBase(self):
self.assertAlmostEqual(detR0, 1.0, self.places)
# try if rotation matrix works
self.assertEqual(numpy.all(base == self.lattice.base), True)
self.lattice.setLatPar(alpha=44, beta=66, gamma=88)
self.lattice.set_latt_parms(alpha=44, beta=66, gamma=88)
self.assertNotEqual(numpy.all(base == self.lattice.base), True)
self.lattice.setLatPar(alpha=60, beta=60, gamma=60)
self.lattice.set_latt_parms(alpha=60, beta=60, gamma=60)
self.assertTrue(numpy.allclose(base[0], self.lattice.base[0]))
self.assertTrue(numpy.allclose(base[1], self.lattice.base[1]))
self.assertTrue(numpy.allclose(base[2], self.lattice.base[2]))
Expand All @@ -171,6 +193,39 @@ def test_setLatBase(self):
)
return

def test_set_lat_base(self):
"""Check calculation of unit cell rotation."""
base = numpy.array([[1.0, 1.0, 0.0], [0.0, 1.0, 1.0], [1.0, 0.0, 1.0]])
self.lattice.set_new_latt_base_vec(base)
self.assertAlmostEqual(self.lattice.a, numpy.sqrt(2.0), self.places)
self.assertAlmostEqual(self.lattice.b, numpy.sqrt(2.0), self.places)
self.assertAlmostEqual(self.lattice.c, numpy.sqrt(2.0), self.places)
self.assertAlmostEqual(self.lattice.alpha, 60.0, self.places)
self.assertAlmostEqual(self.lattice.beta, 60.0, self.places)
self.assertAlmostEqual(self.lattice.gamma, 60.0, self.places)
detR0 = numalg.det(self.lattice.baserot)
self.assertAlmostEqual(detR0, 1.0, self.places)
# try if rotation matrix works
self.assertEqual(numpy.all(base == self.lattice.base), True)
self.lattice.set_latt_parms(alpha=44, beta=66, gamma=88)
self.assertNotEqual(numpy.all(base == self.lattice.base), True)
self.lattice.set_latt_parms(alpha=60, beta=60, gamma=60)
self.assertTrue(numpy.allclose(base[0], self.lattice.base[0]))
self.assertTrue(numpy.allclose(base[1], self.lattice.base[1]))
self.assertTrue(numpy.allclose(base[2], self.lattice.base[2]))
# try base checking
self.assertRaises(
LatticeError,
self.lattice.set_new_latt_base_vec,
[[1, 0, 0], [1, 0, 0], [0, 0, 1]],
)
self.assertRaises(
LatticeError,
self.lattice.set_new_latt_base_vec,
[[1, 0, 0], [0, 0, 1], [0, 1, 0]],
)
return

def test_reciprocal(self):
"""Check calculation of reciprocal lattice."""
r1 = self.lattice.reciprocal()
Expand All @@ -185,7 +240,7 @@ def test_reciprocal(self):
def test_dot(self):
"""Check dot product of lattice vectors."""
L = self.lattice
L.setLatPar(gamma=120)
L.set_latt_parms(gamma=120)
self.assertAlmostEqual(-0.5, L.dot([1, 0, 0], [0, 1, 0]), self.places)
va5 = numpy.tile([1.0, 0.0, 0.0], (5, 1))
vb5 = numpy.tile([0.0, 1.0, 0.0], (5, 1))
Expand All @@ -199,14 +254,14 @@ def test_norm(self):
self.assertEqual(1, self.lattice.norm([1, 0, 0]))
u = numpy.array([[3, 4, 0], [1, 1, 1]])
self.assertTrue(numpy.allclose([5, 3**0.5], self.lattice.norm(u)))
self.lattice.setLatPar(gamma=120)
self.lattice.set_latt_parms(gamma=120)
self.assertAlmostEqual(1, self.lattice.norm([1, 1, 0]), self.places)
return

def test_rnorm(self):
"""Check norm of a reciprocal vector."""
L = self.lattice
L.setLatPar(1, 1.5, 2.3, 80, 95, 115)
L.set_latt_parms(1, 1.5, 2.3, 80, 95, 115)
r = L.reciprocal()
hkl = [0.5, 0.3, 0.2]
self.assertAlmostEqual(r.norm(hkl), L.rnorm(hkl), self.places)
Expand All @@ -217,7 +272,7 @@ def test_rnorm(self):
def test_dist(self):
"""Check dist function for distance between lattice points."""
L = self.lattice
L.setLatPar(1, 1.5, 2.3, 80, 95, 115)
L.set_latt_parms(1, 1.5, 2.3, 80, 95, 115)
u = [0.1, 0.3, 0.7]
v = [0.3, 0.7, 0.7]
d0 = numalg.norm(L.cartesian(numpy.array(u) - v))
Expand All @@ -235,7 +290,7 @@ def test_angle(self):
from math import acos, degrees

L = self.lattice
L.setLatPar(1, 1.5, 2.3, 80, 95, 115)
L.set_latt_parms(1, 1.5, 2.3, 80, 95, 115)
u = [0.1, 0.3, 0.7]
v = [0.3, 0.7, 0.7]
uc = L.cartesian(u)
Expand All @@ -254,12 +309,12 @@ def test_repr(self):
"""Check string representation of this lattice."""
r = repr(self.lattice)
self.assertEqual(r, "Lattice()")
self.lattice.setLatPar(1, 2, 3, 10, 20, 30)
self.lattice.set_latt_parms(1, 2, 3, 10, 20, 30)
r = repr(self.lattice)
r0 = "Lattice(a=1, b=2, c=3, alpha=10, beta=20, gamma=30)"
self.assertEqual(r, r0)
base = [[1.0, 1.0, 0.0], [0.0, 2.0, 2.0], [3.0, 0.0, 3.0]]
self.lattice.setLatBase(base)
self.lattice.set_new_latt_base_vec(base)
r = repr(self.lattice)
self.assertEqual(r, "Lattice(base=%r)" % self.lattice.base)

Expand Down
Loading