symQuats-related functions can take optional argument to downselect return values.

“getAverageOrientations” —> “average” and takes optional multiplicities of orientations in list.
This commit is contained in:
Philip Eisenlohr 2015-11-14 01:46:44 +00:00
parent 1395714c87
commit 6211a9faad
1 changed files with 31 additions and 22 deletions

View File

@ -555,7 +555,7 @@ class Symmetry:
def __cmp__(self,other):
return cmp(Symmetry.lattices.index(self.lattice),Symmetry.lattices.index(other.lattice))
def symmetryQuats(self):
def symmetryQuats(self,who = []):
'''
List of symmetry operations as quaternions.
'''
@ -623,15 +623,18 @@ class Symmetry:
symQuats = [
[ 1.0,0.0,0.0,0.0 ],
]
return map(Quaternion,symQuats)
return map(Quaternion,
np.array(symQuats)[np.atleast_1d(np.array(who)) if who != [] else xrange(len(symQuats))])
def equivalentQuaternions(self,quaternion):
def equivalentQuaternions(self,
quaternion,
who = []):
'''
List of symmetrically equivalent quaternions based on own symmetry.
'''
return [quaternion*Quaternion(q) for q in self.symmetryQuats()]
return [quaternion*q for q in self.symmetryQuats(who)]
def inFZ(self,R):
@ -852,14 +855,14 @@ class Orientation:
return self.symmetry.inFZ(self.quaternion.asRodrigues())
infz = property(inFZ)
def equivalentQuaternions(self):
return self.symmetry.equivalentQuaternions(self.quaternion)
equiQuaternions = property(equivalentQuaternions)
def equivalentQuaternions(self,
who = []):
return self.symmetry.equivalentQuaternions(self.quaternion,who)
def equivalentOrientations(self):
def equivalentOrientations(self,
who = []):
return map(lambda q: Orientation(quaternion = q, symmetry = self.symmetry.lattice),
self.equivalentQuaternions())
equiOrientations = property(equivalentQuaternions)
self.equivalentQuaternions(who))
def reduced(self):
'''
@ -893,9 +896,8 @@ class Orientation:
theQ = sA.conjugated()*misQ*sB
for k in xrange(2):
theQ.conjugate()
hitFZ = self.symmetry.inFZ(theQ)
hitSST = other.symmetry.inDisorientationSST(theQ)
breaker = hitFZ and (hitSST or not SST)
breaker = self.symmetry.inFZ(theQ) \
and (not SST or other.symmetry.inDisorientationSST(theQ))
if breaker: break
if breaker: break
if breaker: break
@ -936,7 +938,9 @@ class Orientation:
return color
@classmethod
def getAverageOrientation(cls, orientationList):
def average(cls,
orientations,
multiplicity = []):
"""RETURN THE AVERAGE ORIENTATION
ref: F. Landis Markley, Yang Cheng, John Lucas Crassidis, and Yaakov Oshman.
Averaging Quaternions,
@ -945,19 +949,24 @@ class Orientation:
usage:
a = Orientation(Eulers=np.radians([10, 10, 0]), symmetry='hexagonal')
b = Orientation(Eulers=np.radians([20, 0, 0]), symmetry='hexagonal')
avg = Orientation.getAverageOrientation([a,b])
avg = Orientation.average([a,b])
"""
if not all(isinstance(item, Orientation) for item in orientationList):
if not all(isinstance(item, Orientation) for item in orientations):
raise TypeError("Only instances of Orientation can be averaged.")
N = len(orientationList)
M = orientationList.pop(0).quaternion.asM()
for o in orientationList:
M += o.quaternion.asM()
N = len(orientations)
if multiplicity == [] or not multiplicity:
multiplicity = np.ones(N,dtype='i')
reference = orientations[0] # take first as reference
for i,(o,n) in enumerate(zip(orientations,multiplicity)):
closest = o.equivalentOrientations(reference.disorientation(o,SST = False)[2])[0] # select sym orientation with lowest misorientation
M = closest.quaternion.asM() * n if i == 0 else M + closest.quaternion.asM() * n # add (multiples) of this orientation to average
eig, vec = np.linalg.eig(M/N)
return Orientation(quaternion = Quaternion(quatArray = vec.T[eig.argmax()]))
return Orientation(quaternion = Quaternion(quatArray = np.real(vec.T[eig.argmax()])))
def related(self,