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:
parent
1395714c87
commit
6211a9faad
|
@ -555,7 +555,7 @@ class Symmetry:
|
||||||
def __cmp__(self,other):
|
def __cmp__(self,other):
|
||||||
return cmp(Symmetry.lattices.index(self.lattice),Symmetry.lattices.index(other.lattice))
|
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.
|
List of symmetry operations as quaternions.
|
||||||
'''
|
'''
|
||||||
|
@ -623,15 +623,18 @@ class Symmetry:
|
||||||
symQuats = [
|
symQuats = [
|
||||||
[ 1.0,0.0,0.0,0.0 ],
|
[ 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.
|
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):
|
def inFZ(self,R):
|
||||||
|
@ -852,14 +855,14 @@ class Orientation:
|
||||||
return self.symmetry.inFZ(self.quaternion.asRodrigues())
|
return self.symmetry.inFZ(self.quaternion.asRodrigues())
|
||||||
infz = property(inFZ)
|
infz = property(inFZ)
|
||||||
|
|
||||||
def equivalentQuaternions(self):
|
def equivalentQuaternions(self,
|
||||||
return self.symmetry.equivalentQuaternions(self.quaternion)
|
who = []):
|
||||||
equiQuaternions = property(equivalentQuaternions)
|
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),
|
return map(lambda q: Orientation(quaternion = q, symmetry = self.symmetry.lattice),
|
||||||
self.equivalentQuaternions())
|
self.equivalentQuaternions(who))
|
||||||
equiOrientations = property(equivalentQuaternions)
|
|
||||||
|
|
||||||
def reduced(self):
|
def reduced(self):
|
||||||
'''
|
'''
|
||||||
|
@ -893,9 +896,8 @@ class Orientation:
|
||||||
theQ = sA.conjugated()*misQ*sB
|
theQ = sA.conjugated()*misQ*sB
|
||||||
for k in xrange(2):
|
for k in xrange(2):
|
||||||
theQ.conjugate()
|
theQ.conjugate()
|
||||||
hitFZ = self.symmetry.inFZ(theQ)
|
breaker = self.symmetry.inFZ(theQ) \
|
||||||
hitSST = other.symmetry.inDisorientationSST(theQ)
|
and (not SST or other.symmetry.inDisorientationSST(theQ))
|
||||||
breaker = hitFZ and (hitSST or not SST)
|
|
||||||
if breaker: break
|
if breaker: break
|
||||||
if breaker: break
|
if breaker: break
|
||||||
if breaker: break
|
if breaker: break
|
||||||
|
@ -936,7 +938,9 @@ class Orientation:
|
||||||
return color
|
return color
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def getAverageOrientation(cls, orientationList):
|
def average(cls,
|
||||||
|
orientations,
|
||||||
|
multiplicity = []):
|
||||||
"""RETURN THE AVERAGE ORIENTATION
|
"""RETURN THE AVERAGE ORIENTATION
|
||||||
ref: F. Landis Markley, Yang Cheng, John Lucas Crassidis, and Yaakov Oshman.
|
ref: F. Landis Markley, Yang Cheng, John Lucas Crassidis, and Yaakov Oshman.
|
||||||
Averaging Quaternions,
|
Averaging Quaternions,
|
||||||
|
@ -945,19 +949,24 @@ class Orientation:
|
||||||
usage:
|
usage:
|
||||||
a = Orientation(Eulers=np.radians([10, 10, 0]), symmetry='hexagonal')
|
a = Orientation(Eulers=np.radians([10, 10, 0]), symmetry='hexagonal')
|
||||||
b = Orientation(Eulers=np.radians([20, 0, 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.")
|
raise TypeError("Only instances of Orientation can be averaged.")
|
||||||
|
|
||||||
N = len(orientationList)
|
N = len(orientations)
|
||||||
M = orientationList.pop(0).quaternion.asM()
|
if multiplicity == [] or not multiplicity:
|
||||||
for o in orientationList:
|
multiplicity = np.ones(N,dtype='i')
|
||||||
M += o.quaternion.asM()
|
|
||||||
|
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)
|
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,
|
def related(self,
|
||||||
|
|
Loading…
Reference in New Issue