def calcCell(cell): """Calculate reciprocal lattice vectors from real space cell parameters""" a1, a2, a3, alpha1, alpha2, alpha3 = cell realVectorA = np.array([a1, 0, 0]) realVectorB = a2 * np.array([ cosd(alpha3), sind(alpha3), 0.0 ]) #np.dot(np.array([b,0,0]),rotationMatrix(0,0,gamma)) realVectorC = a3 * np.array([ cosd(alpha2), (cosd(alpha1) - cosd(alpha2) * cosd(alpha3)) / sind(alpha3), np.sqrt(1 - cosd(alpha2)**2 - ( (cosd(alpha1) - cosd(alpha2) * cosd(alpha3)) / sind(alpha3))**2) ]) #np.dot(np.array([c,0,0]),rotationMatrix(0,beta,0)) volume = np.abs(np.dot(realVectorA, np.cross(realVectorB, realVectorC))) reciprocalVectorA = 2 * np.pi * np.cross(realVectorB, realVectorC) / volume reciprocalVectorB = 2 * np.pi * np.cross(realVectorC, realVectorA) / volume reciprocalVectorC = 2 * np.pi * np.cross(realVectorA, realVectorB) / volume bv1, bv2, bv3 = reciprocalVectorA, reciprocalVectorB, reciprocalVectorC b1, b2, b3 = [np.linalg.norm(x) for x in [bv1, bv2, bv3]] beta1 = np.rad2deg(_tools.vectorAngle(bv2, bv3)) beta2 = np.rad2deg(_tools.vectorAngle(bv3, bv1)) beta3 = np.rad2deg(_tools.vectorAngle(bv1, bv2)) cell = [ a1, a2, a3, b1, b2, b3, alpha1, alpha2, alpha3, beta1, beta2, beta3 ] return cell
def updateCell(self,unitCell=None): """Update cell parameters with current unit cell values. Kwargs: - unitCell (list): List of a,b,c,alpha,beta,gamma. If None, use self.unitCell (default None) """ if unitCell is None: unitCell = self.unitCell else: self.unitCell = unitCell self.realVectorA = np.array([self.a,0,0]) self.realVectorB = self.b*np.array([cosd(self.gamma),sind(self.gamma),0.0])#np.dot(np.array([self.b,0,0]),rotationMatrix(0,0,self.gamma)) self.realVectorC = self.c*np.array([cosd(self.beta),(cosd(self.alpha)-cosd(self.beta)*cosd(self.gamma))/sind(self.gamma), np.sqrt(1-cosd(self.beta)**2-((cosd(self.alpha)-cosd(self.beta)*cosd(self.gamma))/sind(self.gamma))**2)])#np.dot(np.array([self.c,0,0]),rotationMatrix(0,self.beta,0)) self.volume = np.abs(np.dot(self.realVectorA,np.cross(self.realVectorB,self.realVectorC))) self.reciprocalVectorA = 2*np.pi*np.cross(self.realVectorB,self.realVectorC)/self.volume self.reciprocalVectorB = 2*np.pi*np.cross(self.realVectorC,self.realVectorA)/self.volume self.reciprocalVectorC = 2*np.pi*np.cross(self.realVectorA,self.realVectorB)/self.volume bv1,bv2,bv3 = self.reciprocalVectorA,self.reciprocalVectorB,self.reciprocalVectorC a1,a2,a3,alpha1,alpha2,alpha3= self.unitCell b1,b2,b3 = [np.linalg.norm(x) for x in [bv1,bv2,bv3]] beta1 = np.rad2deg(_tools.vectorAngle(bv2,bv3)) beta2 = np.rad2deg(_tools.vectorAngle(bv3,bv1)) beta3 = np.rad2deg(_tools.vectorAngle(bv1,bv2)) self.cell = [a1,a2,a3,b1,b2,b3,alpha1,alpha2,alpha3,beta1,beta2,beta3]
def test_vectorAngle(): v1 = np.array([1, 0, 0]) v2 = np.array([0, 1, 0]) v3 = np.array([1, 1, 1]) theta1 = vectorAngle(v1, v2) theta2 = vectorAngle(v1, v3) theta3 = vectorAngle(v2, v3) print(theta2) assert (np.isclose(theta1, np.pi / 2)) assert (np.isclose(theta2, theta3)) assert (np.isclose(theta2, 0.955316618125))
def test_DataFile_Sample_UB(): df = MJOLNIR.Data.DataFile.DataFile(os.path.join(dataPath,'camea2018n000136.hdf')) s = df.sample b1,b2,b3 = [np.linalg.norm(x) for x in [s.reciprocalVectorA,s.reciprocalVectorB,s.reciprocalVectorC]] a1,a2,a3 = [np.linalg.norm(x) for x in [s.realVectorA,s.realVectorB,s.realVectorC]] beta1,beta2,beta3 = _tools.vectorAngle(s.reciprocalVectorB,s.reciprocalVectorC),_tools.vectorAngle(s.reciprocalVectorC,s.reciprocalVectorA),_tools.vectorAngle(s.reciprocalVectorA,s.reciprocalVectorB) alpha1,alpha2,alpha3 = _tools.vectorAngle(s.realVectorB,s.realVectorC),_tools.vectorAngle(s.realVectorC,s.realVectorA),_tools.vectorAngle(s.realVectorA,s.realVectorB) cell = s.cell#[a1,a2,a3,b1,b2,b3,alpha1,alpha2,alpha3,beta1,beta2,beta3] r1 = s.plane_vector1 r2 = s.plane_vector2 UBCalc = TasUBlib.calcTasUBFromTwoReflections(cell,r1,r2) comparison = np.isclose(UBCalc,s.orientationMatrix,atol=1e-5) # Assert that they are equal to 1e-5 (Numerical error) print(np.round(UBCalc,5)) print(np.round(s.orientationMatrix,5)) assert(np.all(comparison))
def calculateProjections(self): """Calculate projections and generate projection angles.""" checks = np.array(['unitCell','orientationMatrix','projectionVector1','projectionVector2']) # boolcheck = np.logical_not(np.array([hasattr(self,x) for x in checks])) if np.any(boolcheck): raise AttributeError('Sample object is missing: {}.'.format(', '.join(str(x) for x in checks[boolcheck]))) if self.projectionVector1[np.argmax(np.abs(self.projectionVector1))]<0: self.projectionVector1*=-1 if self.projectionVector2[np.argmax(np.abs(self.projectionVector2))]<0: self.projectionVector2*=-1 V1 = self.projectionVector1.copy() #V1/=np.linalg.norm(V1) V2 = self.projectionVector2.copy() #V2/=np.linalg.norm(V2) pV1Q = np.dot(self.B,V1) pV2Q = np.dot(self.B,V2) self.projectionAngle = _tools.vectorAngle(pV1Q,pV2Q) if np.isclose(0.0,self.projectionAngle): raise AttributeError("The provided orientations are equal.") UB= self.orientationMatrix self.UB = UB self.orientationMatrixINV = np.linalg.inv(UB) p23 = np.array([[1,0,0],[0,1,0]]) # To extract Qx, Qy only PM = np.array([V1,V2]).T # Projection matrix self.PM = PM self.convert = np.dot(p23,np.einsum('ij,jk->ik',UB,PM)) # Convert from projX,projY to Qx, Qy self.convertHKL = np.dot(p23,UB) # Convert from HKL to Qx, Qy # Calculate 'misalignment' of the projection vector 1 try: self.theta = -TasUBlib.calcTasMisalignment(UB,self.planeNormal,V1) except AttributeError: self.theta = 0 self.RotMat = _tools.Rot(self.theta) # Create 2x2 rotation matrix self.convertinv = np.linalg.inv(self.convert) # Convert from Qx, Qy to projX, projY self.convertHKLINV = _tools.invert(self.convertHKL) # Convert from Qx, Qy to HKL # Calcualte RotationMatrix for UB as block diagonal matrix. Only Qx,Qy part rotates as' # calculated in RotMat self.RotMat3D = np.eye(3) self.RotMat3D[:2,:2] = self.RotMat #self.orientationMatrixINV = np.linalg.inv(np.dot(self.RotMat3D,UB)) self.orientationMatrixINV = np.linalg.inv(self.UB)
def initialize(self): """Initialize the Sample object. Automatically called during __init__method.""" # From http://gisaxs.com/index.php/Unit_cell self.realVectorA = np.array([self.a, 0, 0]) self.realVectorB = self.b * np.array([ cosd(self.gamma), sind(self.gamma), 0.0 ]) #np.dot(np.array([self.b,0,0]),rotationMatrix(0,0,self.gamma)) self.realVectorC = self.c * np.array([ cosd(self.beta), (cosd(self.alpha) - cosd(self.beta) * cosd(self.gamma)) / sind(self.gamma), np.sqrt(1 - cosd(self.beta)**2 - ((cosd(self.alpha) - cosd(self.beta) * cosd(self.gamma)) / sind(self.gamma))**2) ]) #np.dot(np.array([self.c,0,0]),rotationMatrix(0,self.beta,0)) self.volume = np.abs( np.dot(self.realVectorA, np.cross(self.realVectorB, self.realVectorC))) self.reciprocalVectorA = 2 * np.pi * np.cross( self.realVectorB, self.realVectorC) / self.volume self.reciprocalVectorB = 2 * np.pi * np.cross( self.realVectorC, self.realVectorA) / self.volume self.reciprocalVectorC = 2 * np.pi * np.cross( self.realVectorA, self.realVectorB) / self.volume bv1, bv2, bv3 = self.reciprocalVectorA, self.reciprocalVectorB, self.reciprocalVectorC a1, a2, a3, alpha1, alpha2, alpha3 = self.unitCell b1, b2, b3 = [np.linalg.norm(x) for x in [bv1, bv2, bv3]] beta1 = np.rad2deg(_tools.vectorAngle(bv2, bv3)) beta2 = np.rad2deg(_tools.vectorAngle(bv3, bv1)) beta3 = np.rad2deg(_tools.vectorAngle(bv1, bv2)) self.cell = [ a1, a2, a3, b1, b2, b3, alpha1, alpha2, alpha3, beta1, beta2, beta3 ] self.B = TasUBlib.calculateBMatrix(self.cell)