Beispiel #1
0
 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)
Beispiel #2
0
 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
Beispiel #4
0
 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
Beispiel #5
0
    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)
Beispiel #6
0
    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)
Beispiel #8
0
    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)
Beispiel #9
0
    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)