Skip to content

Commit aff9cac

Browse files
committed
Support array arguments in Lattice dist, angle.
1 parent 85361f6 commit aff9cac

File tree

2 files changed

+59
-9
lines changed

2 files changed

+59
-9
lines changed

diffpy/Structure/lattice.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,9 +330,15 @@ def rnorm(self, hkl):
330330

331331

332332
def dist(self, u, v):
333-
"""Return distance of 2 points in lattice coordinates.
333+
"""Return distance between 2 points in lattice coordinates.
334+
335+
u -- vector or N-by-3 matrix of fractional coordinates.
336+
v -- vector or N-by-3 matrix of fractional coordinates.
337+
Sizes of u, v must match when both of them are matrices.
338+
339+
Return float or an array of the same length as the matrix.
334340
"""
335-
duv = numpy.array(u) - v
341+
duv = numpy.asarray(u) - v
336342
return self.norm(duv)
337343

338344

@@ -341,8 +347,14 @@ def angle(self, u, v):
341347
"""
342348
ca = self.dot(u, v)/( self.norm(u)*self.norm(v) )
343349
# avoid round-off errors that would make abs(ca) greater than 1
344-
ca = max(min(ca, 1), -1)
345-
return math.degrees(math.acos(ca))
350+
if numpy.isscalar(ca):
351+
ca = max(min(ca, 1), -1)
352+
rv = math.degrees(math.acos(ca))
353+
else:
354+
ca[ca < -1] = -1
355+
ca[ca > +1] = +1
356+
rv = numpy.degrees(numpy.arccos(ca))
357+
return rv
346358

347359

348360
def isanisotropic(self, umx):

diffpy/Structure/tests/TestLattice.py

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import unittest
2020
import numpy
21+
import numpy.linalg as numalg
2122

2223
from diffpy.Structure import Lattice, LatticeError
2324

@@ -168,8 +169,6 @@ def test_readonly_properties(self):
168169

169170
def test_setLatBase(self):
170171
"""check calculation of unit cell rotation"""
171-
import numpy
172-
import numpy.linalg as numalg
173172
base = numpy.array([[ 1.0, 1.0, 0.0],
174173
[ 0.0, 1.0, 1.0],
175174
[ 1.0, 0.0, 1.0]])
@@ -214,7 +213,7 @@ def test_dot(self):
214213
'''check dot product of lattice vectors.'''
215214
L = self.lattice
216215
L.setLatPar(gamma=120)
217-
self.assertAlmostEqual(-0.5, L.dot([1, 0, 0], [0, 1, 0]))
216+
self.assertAlmostEqual(-0.5, L.dot([1, 0, 0], [0, 1, 0]), self.places)
218217
va5 = numpy.tile([1.0, 0.0, 0.0], (5, 1))
219218
vb5 = numpy.tile([0.0, 1.0, 0.0], (5, 1))
220219
self.assertTrue(numpy.array_equal(5 * [-0.5], L.dot(va5, vb5)))
@@ -229,7 +228,7 @@ def test_norm(self):
229228
u = numpy.array([[3, 4, 0], [1, 1, 1]])
230229
self.assertListAlmostEqual([5, 3**0.5], self.lattice.norm(u))
231230
self.lattice.setLatPar(gamma=120)
232-
self.assertAlmostEqual(1, self.lattice.norm([1, 1, 0]))
231+
self.assertAlmostEqual(1, self.lattice.norm([1, 1, 0]), self.places)
233232
return
234233

235234

@@ -239,12 +238,51 @@ def test_rnorm(self):
239238
L.setLatPar(1, 1.5, 2.3, 80, 95, 115)
240239
r = L.reciprocal()
241240
hkl = [0.5, 0.3, 0.2]
242-
self.assertAlmostEqual(r.norm(hkl), L.rnorm(hkl))
241+
self.assertAlmostEqual(r.norm(hkl), L.rnorm(hkl), self.places)
243242
hkl5 = numpy.tile(hkl, (5, 1))
244243
self.assertListAlmostEqual(5 * [r.norm(hkl)], L.rnorm(hkl5))
245244
return
246245

247246

247+
def test_dist(self):
248+
'''check dist function for distance between lattice points.'''
249+
L = self.lattice
250+
L.setLatPar(1, 1.5, 2.3, 80, 95, 115)
251+
u = [0.1, 0.3, 0.7]
252+
v = [0.3, 0.7, 0.7]
253+
d0 = numalg.norm(L.cartesian(numpy.array(u) - v))
254+
self.assertAlmostEqual(d0, L.dist(u, v), self.places)
255+
self.assertAlmostEqual(d0, L.dist(v, u), self.places)
256+
u5 = numpy.tile(u, (5, 1))
257+
v5 = numpy.tile(v, (5, 1))
258+
self.assertListAlmostEqual(5 * [d0], L.dist(u, v5))
259+
self.assertListAlmostEqual(5 * [d0], L.dist(u5, v))
260+
self.assertListAlmostEqual(5 * [d0], L.dist(v5, u5))
261+
return
262+
263+
264+
def test_angle(self):
265+
'''check angle calculation between lattice vectors.'''
266+
from math import degrees, acos
267+
L = self.lattice
268+
L.setLatPar(1, 1.5, 2.3, 80, 95, 115)
269+
u = [0.1, 0.3, 0.7]
270+
v = [0.3, 0.7, 0.7]
271+
uc = L.cartesian(u)
272+
vc = L.cartesian(v)
273+
a0 = degrees(acos(numpy.dot(uc, vc) /
274+
(numalg.norm(uc) * numalg.norm(vc))))
275+
self.assertAlmostEqual(a0, L.angle(u, v), self.places)
276+
self.assertAlmostEqual(a0, L.angle(v, u), self.places)
277+
u5 = numpy.tile(u, (5, 1))
278+
v5 = numpy.tile(v, (5, 1))
279+
self.assertListAlmostEqual(5 * [a0], L.angle(u, v5))
280+
self.assertListAlmostEqual(5 * [a0], L.angle(u5, v))
281+
self.assertListAlmostEqual(5 * [a0], L.angle(v5, u5))
282+
return
283+
284+
285+
248286
def test_repr(self):
249287
"""check string representation of this lattice"""
250288
r = repr(self.lattice)

0 commit comments

Comments
 (0)