def checkSolution(omega, chi, phi): _, _, _, OMEGA, CHI, PHI = createVliegMatrices( None, None, None, omega, chi, phi) R = OMEGA * CHI * PHI RtimesH_phi = R * H_phi print ("R*H_phi=%s, Q_alpha=%s" % (R * H_phi.tolist(), Q_alpha.tolist())) return not differ(RtimesH_phi, Q_alpha, .0001)
def checkSolution(omega, chi, phi): _, _, _, OMEGA, CHI, PHI = createVliegMatrices( None, None, None, omega, chi, phi) R = OMEGA * CHI * PHI RtimesH_phi = R * H_phi print("R*H_phi=%s, Q_alpha=%s" % (R * H_phi.tolist(), Q_alpha.tolist())) return not differ(RtimesH_phi, Q_alpha, .0001)
def _verify_virtual_angles(self, h, k, l, wavelength, pos, virtualAngles): # Check that the virtual angles calculated/fixed during the hklToAngles # those read back from pos using anglesToVirtualAngles virtualAnglesReadback = self.anglesToVirtualAngles(pos, wavelength) for key, val in virtualAngles.items(): if val != None: # Some values calculated in some mode_selector r = virtualAnglesReadback[key] if ((differ(val, r, .00001) and differ(val, r + 360, .00001) and differ(val, r - 360, .00001))): s = "ERROR: The angles calculated for hkl=(%f,%f,%f) with"\ " mode=%s were %s.\n" % (h, k, l, self.repr_mode(), str(pos)) s += "During verification the virtual angle %s resulting "\ "from (or set for) this calculation of %f" % (key, val) s += "did not match that calculated by "\ "anglesToVirtualAngles of %f" % virtualAnglesReadback[key] if self.raiseExceptionsIfAnglesDoNotMapBackToHkl: raise DiffcalcException(s) else: print s return virtualAnglesReadback
def _verify_virtual_angles(self, h, k, l, wavelength, pos, virtualAngles): # Check that the virtual angles calculated/fixed during the hklToAngles # those read back from pos using anglesToVirtualAngles virtualAnglesReadback = self.anglesToVirtualAngles(pos, wavelength) for key, val in virtualAngles.items(): if val != None: # Some values calculated in some mode_selector r = virtualAnglesReadback[key] if ((differ(val, r, .00001) and differ(val, r + 360, .00001) and differ(val, r - 360, .00001))): s = "ERROR: The angles calculated for hkl=(%f,%f,%f) with"\ " mode=%s were %s.\n" % (h, k, l, self.repr_mode(), str(pos)) s += "During verification the virtual angle %s resulting "\ "from (or set for) this calculation of %f" % (key, val) s += "did not match that calculated by "\ "anglesToVirtualAngles of %f" % virtualAnglesReadback[key] if self.raiseExceptionsIfAnglesDoNotMapBackToHkl: raise DiffcalcException(s) else: print(s) return virtualAnglesReadback
def testDiffer(self): assert not differ([1., 2., 3.], [1., 2., 3.], .0000000000000001) assert not differ(1, 1.0, .000000000000000001) assert (differ([2., 4., 6.], [1., 2., 3.], .1) == '(2.0, 4.0, 6.0)!=(1.0, 2.0, 3.0)') assert not differ(1., 1.2, .2) assert differ(1., 1.2, .1999999999999) == '1.0!=1.2' assert not differ(1., 1.2, 1.20000000000001)
def testDiffer(self): self.assertFalse(differ([1., 2., 3.], [1., 2., 3.], .0000000000000001)) self.assertFalse(differ(1, 1.0, .000000000000000001)) self.assertEquals(differ([2., 4., 6.], [1., 2., 3.], .1), '(2.0, 4.0, 6.0)!=(1.0, 2.0, 3.0)') self.assertEquals(differ(1., 1.2, .2), False) self.assertEquals(differ(1., 1.2, .1999999999999), '1.0!=1.2') self.assertEquals(differ(1., 1.2, 1.20000000000001), False)
def _determineSampleAnglesInFourAndFiveCircleModes(self, hklPhiNorm, alpha, delta, gamma, Bin): """ (omega, chi, phi, psi)=determineNonZAxisSampleAngles(hklPhiNorm, alpha, delta, gamma, sigma, tau) where hkl has been normalised by the wavevector and is in the phi Axis coordinate frame. All angles in radians. hklPhiNorm is a 3X1 matrix """ def equation49through59(psi): # equation 49 R = (D^-1)*PI*D*Ro PSI = createVliegsPsiTransformationMatrix(psi) R = D.I * PSI * D * Ro # eq 57: extract omega from R if abs(R[0, 2]) < 1e-20: omega = -sign(R[1, 2]) * sign(R[0, 2]) * pi / 2 else: omega = -atan2(R[1, 2], R[0, 2]) # eq 58: extract chi from R sinchi = sqrt(pow(R[0, 2], 2) + pow(R[1, 2], 2)) sinchi = bound(sinchi) check(abs(sinchi) <= 1, 'could not compute chi') # (there are two roots to this equation, but only the first is also # a solution to R33=cos(chi)) chi = asin(sinchi) # eq 59: extract phi from R if abs(R[2, 0]) < 1e-20: phi = sign(R[2, 1]) * sign(R[2, 1]) * pi / 2 else: phi = atan2(-R[2, 1], -R[2, 0]) return omega, chi, phi def checkSolution(omega, chi, phi): _, _, _, OMEGA, CHI, PHI = createVliegMatrices( None, None, None, omega, chi, phi) R = OMEGA * CHI * PHI RtimesH_phi = R * H_phi print ("R*H_phi=%s, Q_alpha=%s" % (R * H_phi.tolist(), Q_alpha.tolist())) return not differ(RtimesH_phi, Q_alpha, .0001) # Using Vlieg section 7.2 # Needed througout: [ALPHA, DELTA, GAMMA, _, _, _] = createVliegMatrices( alpha, delta, gamma, None, None, None) ## Find Ro, one possible solution to equation 46: R*H_phi=Q_alpha # Normalise hklPhiNorm (As it is currently normalised only to the # wavevector) normh = norm(hklPhiNorm) check(normh >= 1e-10, "reciprical lattice vector too close to zero") H_phi = hklPhiNorm * (1 / normh) # Create Q_alpha from equation 47, (it comes normalised) Q_alpha = ((DELTA * GAMMA) - ALPHA.I) * matrix([[0], [1], [0]]) Q_alpha = Q_alpha * (1 / norm(Q_alpha)) if self._getMode().name == '4cPhi': ### Use the fixed value of phi as the final constraint ### phi = self._getParameter('phi') * TORAD PHI = calcPHI(phi) H_chi = PHI * H_phi omega, chi = _findOmegaAndChiToRotateHchiIntoQalpha(H_chi, Q_alpha) return (omega, chi, phi, None) # psi = None as not calculated else: ### Use Bin as the final constraint ### # Find a solution Ro to Ro*H_phi=Q_alpha Ro = self._findMatrixToTransformAIntoB(H_phi, Q_alpha) ## equation 50: Find a solution D to D*Q=norm(Q)*[[1],[0],[0]]) D = self._findMatrixToTransformAIntoB( Q_alpha, matrix([[1], [0], [0]])) ## Find psi and create PSI # eq 54: compute u=D*Ro*S*[[0],[0],[1]], the surface normal in # psi frame [SIGMA, TAU] = createVliegsSurfaceTransformationMatrices( self._getSigma() * TORAD, self._getTau() * TORAD) S = TAU * SIGMA [u1], [u2], [u3] = (D * Ro * S * matrix([[0], [0], [1]])).tolist() # TODO: If u points along 100, then any psi is a solution. Choose 0 if not differ([u1, u2, u3], [1, 0, 0], 1e-9): psi = 0 omega, chi, phi = equation49through59(psi) else: # equation 53: V=A*(D^-1) V = ALPHA * D.I v21 = V[1, 0] v22 = V[1, 1] v23 = V[1, 2] # equation 55 a = v22 * u2 + v23 * u3 b = v22 * u3 - v23 * u2 c = -sin(Bin) - v21 * u1 # TODO: changed sign from paper # equation 44 # Try first root: def myatan2(y, x): if abs(x) < 1e-20 and abs(y) < 1e-20: return pi / 2 else: return atan2(y, x) psi = 2 * myatan2(-(b - sqrt(b * b + a * a - c * c)), -(a + c)) #psi = -acos(c/sqrt(a*a+b*b))+atan2(b,a)# -2*pi omega, chi, phi = equation49through59(psi) # if u points along z axis, the psi could have been either 0 or 180 if (not differ([u1, u2, u3], [0, 0, 1], 1e-9) and abs(psi - pi) < 1e-10): # Choose 0 to match that read up by angles-to-virtual-angles psi = 0. # if u points a long return (omega, chi, phi, psi)
def _determineSampleAnglesInFourAndFiveCircleModes(self, hklPhiNorm, alpha, delta, gamma, Bin): """ (omega, chi, phi, psi)=determineNonZAxisSampleAngles(hklPhiNorm, alpha, delta, gamma, sigma, tau) where hkl has been normalised by the wavevector and is in the phi Axis coordinate frame. All angles in radians. hklPhiNorm is a 3X1 matrix """ def equation49through59(psi): # equation 49 R = (D^-1)*PI*D*Ro PSI = createVliegsPsiTransformationMatrix(psi) R = D.I * PSI * D * Ro # eq 57: extract omega from R if abs(R[0, 2]) < 1e-20: omega = -sign(R[1, 2]) * sign(R[0, 2]) * pi / 2 else: omega = -atan2(R[1, 2], R[0, 2]) # eq 58: extract chi from R sinchi = sqrt(pow(R[0, 2], 2) + pow(R[1, 2], 2)) sinchi = bound(sinchi) check(abs(sinchi) <= 1, 'could not compute chi') # (there are two roots to this equation, but only the first is also # a solution to R33=cos(chi)) chi = asin(sinchi) # eq 59: extract phi from R if abs(R[2, 0]) < 1e-20: phi = sign(R[2, 1]) * sign(R[2, 1]) * pi / 2 else: phi = atan2(-R[2, 1], -R[2, 0]) return omega, chi, phi def checkSolution(omega, chi, phi): _, _, _, OMEGA, CHI, PHI = createVliegMatrices( None, None, None, omega, chi, phi) R = OMEGA * CHI * PHI RtimesH_phi = R * H_phi print("R*H_phi=%s, Q_alpha=%s" % (R * H_phi.tolist(), Q_alpha.tolist())) return not differ(RtimesH_phi, Q_alpha, .0001) # Using Vlieg section 7.2 # Needed througout: [ALPHA, DELTA, GAMMA, _, _, _] = createVliegMatrices(alpha, delta, gamma, None, None, None) ## Find Ro, one possible solution to equation 46: R*H_phi=Q_alpha # Normalise hklPhiNorm (As it is currently normalised only to the # wavevector) normh = norm(hklPhiNorm) check(normh >= 1e-10, "reciprical lattice vector too close to zero") H_phi = hklPhiNorm * (1 / normh) # Create Q_alpha from equation 47, (it comes normalised) Q_alpha = ((DELTA * GAMMA) - ALPHA.I) * matrix([[0], [1], [0]]) Q_alpha = Q_alpha * (1 / norm(Q_alpha)) if self._getMode().name == '4cPhi': ### Use the fixed value of phi as the final constraint ### phi = self._getParameter('phi') * TORAD PHI = calcPHI(phi) H_chi = PHI * H_phi omega, chi = _findOmegaAndChiToRotateHchiIntoQalpha(H_chi, Q_alpha) return (omega, chi, phi, None) # psi = None as not calculated else: ### Use Bin as the final constraint ### # Find a solution Ro to Ro*H_phi=Q_alpha Ro = self._findMatrixToTransformAIntoB(H_phi, Q_alpha) ## equation 50: Find a solution D to D*Q=norm(Q)*[[1],[0],[0]]) D = self._findMatrixToTransformAIntoB(Q_alpha, matrix([[1], [0], [0]])) ## Find psi and create PSI # eq 54: compute u=D*Ro*S*[[0],[0],[1]], the surface normal in # psi frame [SIGMA, TAU] = createVliegsSurfaceTransformationMatrices( self._getSigma() * TORAD, self._getTau() * TORAD) S = TAU * SIGMA [u1], [u2], [u3] = (D * Ro * S * matrix([[0], [0], [1]])).tolist() # TODO: If u points along 100, then any psi is a solution. Choose 0 if not differ([u1, u2, u3], [1, 0, 0], 1e-9): psi = 0 omega, chi, phi = equation49through59(psi) else: # equation 53: V=A*(D^-1) V = ALPHA * D.I v21 = V[1, 0] v22 = V[1, 1] v23 = V[1, 2] # equation 55 a = v22 * u2 + v23 * u3 b = v22 * u3 - v23 * u2 c = -sin(Bin) - v21 * u1 # TODO: changed sign from paper # equation 44 # Try first root: def myatan2(y, x): if abs(x) < 1e-20 and abs(y) < 1e-20: return pi / 2 else: return atan2(y, x) psi = 2 * myatan2(-(b - sqrt(b * b + a * a - c * c)), -(a + c)) #psi = -acos(c/sqrt(a*a+b*b))+atan2(b,a)# -2*pi omega, chi, phi = equation49through59(psi) # if u points along z axis, the psi could have been either 0 or 180 if (not differ([u1, u2, u3], [0, 0, 1], 1e-9) and abs(psi - pi) < 1e-10): # Choose 0 to match that read up by angles-to-virtual-angles psi = 0. # if u points a long return (omega, chi, phi, psi)