def calc_offset_for_hkl(self, hkl_offset, hkl_ref):
     """
     Calculate polar and azimuthal angles and scaling factor
     relating offset and reference hkl values
     """
     d_ref = self._state.crystal.get_hkl_plane_distance(hkl_ref)
     hklref_nphi = self._UB * matrix([[hkl_ref[0]], [hkl_ref[1]],
                                      [hkl_ref[2]]])
     d_offset = self._state.crystal.get_hkl_plane_distance(hkl_offset)
     hkloff_nphi = self._UB * matrix([[hkl_offset[0]], [hkl_offset[1]],
                                      [hkl_offset[2]]])
     sc = d_ref / d_offset
     par_ref_off = cross3(hklref_nphi, hkloff_nphi)
     if norm3(par_ref_off) < SMALL:
         return 0, float('nan'), sc
     y_axis = cross3(hklref_nphi, matrix('0; 1; 0'))
     if norm3(y_axis) < SMALL:
         y_axis = cross3(hklref_nphi, matrix('0; 0; 1'))
     x_axis = cross3(y_axis, hklref_nphi)
     x_coord = cos(angle_between_vectors(hkloff_nphi, x_axis))
     y_coord = cos(angle_between_vectors(hkloff_nphi, y_axis))
     pol = angle_between_vectors(hklref_nphi, hkloff_nphi)
     if abs(y_coord) < SMALL and abs(x_coord) < SMALL:
         # Set azimuthal rotation matrix to identity
         az = 0
     else:
         az = atan2(y_coord, x_coord)
     return pol, az, sc
Exemple #2
0
 def get_hkl_plane_angle(self, hkl1, hkl2):
     '''Calculates and returns the angle between [hkl1] and [hkl2] planes'''
     hkl1 = matrix([hkl1]).T
     hkl2 = matrix([hkl2]).T
     nphi1 = self._bMatrix * hkl1
     nphi2 = self._bMatrix * hkl2
     angle = angle_between_vectors(nphi1, nphi2)
     return angle
Exemple #3
0
def _calc_N(Q, n):
    """Return N as described by Equation 31"""
    Q = normalised(Q)
    n = normalised(n)
    if is_small(angle_between_vectors(Q, n)):
        raise ValueError('Q and n are parallel and cannot be used to create '
                         'an orthonormal matrix')
    Qxn = cross3(Q, n)
    QxnxQ = cross3(Qxn, Q)
    QxnxQ = normalised(QxnxQ)
    Qxn = normalised(Qxn)
    return matrix([[Q[0, 0], QxnxQ[0, 0], Qxn[0, 0]],
                   [Q[1, 0], QxnxQ[1, 0], Qxn[1, 0]],
                   [Q[2, 0], QxnxQ[2, 0], Qxn[2, 0]]])
Exemple #4
0
def _calc_N(Q, n):
    """Return N as described by Equation 31"""
    Q = normalised(Q)
    n = normalised(n)
    if is_small(angle_between_vectors(Q, n)):
        raise ValueError('Q and n are parallel and cannot be used to create '
                         'an orthonormal matrix')
    Qxn = cross3(Q, n)
    QxnxQ = cross3(Qxn, Q)
    QxnxQ = normalised(QxnxQ)
    Qxn = normalised(Qxn)
    return matrix([[Q[0, 0], QxnxQ[0, 0], Qxn[0, 0]],
                   [Q[1, 0], QxnxQ[1, 0], Qxn[1, 0]],
                   [Q[2, 0], QxnxQ[2, 0], Qxn[2, 0]]])
Exemple #5
0
def _func_orient(vals, crystal, ref_data):
    quat = _get_quat_from_u123(*vals)
    trial_u = _get_rot_matrix(*quat)
    tmp_ub = trial_u * crystal.B

    res = 0
    I = matrix('1 0 0; 0 1 0; 0 0 1')
    for (hkl_vals, pos_vals, en) in ref_data:
        wl = 12.3984 / en
        [MU, DELTA, NU, ETA, CHI,
         PHI] = create_you_matrices(*pos_vals.totuple())
        q_del = (NU * DELTA - I) * matrix([[0], [2 * pi / wl], [0]])
        q_vals = PHI.I * CHI.I * ETA.I * MU.I * q_del

        q_hkl = tmp_ub * hkl_vals
        res += angle_between_vectors(q_hkl, q_vals)
    return res
Exemple #6
0
    def _hklToAngles(self, h, k, l, wavelength, return_all_solutions=False):
        """(pos, virtualAngles) = hklToAngles(h, k, l, wavelength) --- with
        Position object pos and the virtual angles returned in degrees. Some
        modes may not calculate all virtual angles.
        """

        if not self.constraints.is_fully_constrained():
            raise DiffcalcException(
                "Diffcalc is not fully constrained.\n"
                "Type 'help con' for instructions")

        if not self.constraints.is_current_mode_implemented():
            raise DiffcalcException(
                "Sorry, the selected constraint combination is valid but "
                "is not implemented. Type 'help con' for implemented combinations")
              
        # constraints are dictionaries  
        ref_constraint = self.constraints.reference
        if ref_constraint:
            ref_constraint_name, ref_constraint_value = ref_constraint.items()[0]
        det_constraint = self.constraints.detector
        naz_constraint = self.constraints.naz
        samp_constraints = self.constraints.sample
            
        assert not (det_constraint and naz_constraint), (
               "Two 'detector' constraints given")


        h_phi = self._get_ubmatrix() * matrix([[h], [k], [l]])
        theta = self._calc_theta(h_phi, wavelength)
        tau = angle_between_vectors(h_phi, self._get_n_phi())

        ### Reference constraint column ###

        if ref_constraint:
            # An angle for the reference vector (n) is given      (Section 5.2)         
            psi, alpha, _ = self._calc_remaining_reference_angles(
                ref_constraint_name, ref_constraint_value, theta, tau)

        ### Detector constraint column ###

        if det_constraint or naz_constraint:
            qaz, naz, delta, nu = self._calc_det_angles_given_det_or_naz_constraint(
                                  det_constraint, naz_constraint, theta, tau, alpha)
        
        ### Sample constraint column ###

        if len(samp_constraints) == 1:
            # a detector and reference constraint will have been given
            mu, eta, chi, phi = self._calc_sample_angles_from_one_sample_constraint(
                h, k, l, wavelength, samp_constraints, h_phi, theta,
                ref_constraint_name, ref_constraint_value, alpha, qaz, naz,
                delta, nu)
            solution_tuples = [(mu, delta, nu, eta, chi, phi)]

        elif len(samp_constraints) == 2:
            assert ref_constraint, ('No code yet to handle 2 sample '
                                    'without a reference constraint!')
            angles = self._calc_sample_given_two_sample_and_reference(
                h, k, l, wavelength, samp_constraints, h_phi, theta,
                ref_constraint_name, ref_constraint_value, psi)
            solution_tuples = [angles]

        elif len(samp_constraints) == 3:
            solution_tuples = self._calc_angles_given_three_sample_constraints(
                h, k, l, wavelength, return_all_solutions, samp_constraints,
                 h_phi, theta)
            
        position_pseudo_angles_pairs = []
        for mu, delta, nu, eta, chi, phi in solution_tuples:
            pair = self._create_position_pseudo_angles_pair(
                wavelength, mu, delta, nu, eta, chi, phi)
            position_pseudo_angles_pairs.append(pair)

        return position_pseudo_angles_pairs
Exemple #7
0
    def _hklToAngles(self, h, k, l, wavelength, return_all_solutions=False):
        """(pos, virtualAngles) = hklToAngles(h, k, l, wavelength) --- with
        Position object pos and the virtual angles returned in degrees. Some
        modes may not calculate all virtual angles.
        """

        if not self.constraints.is_fully_constrained():
            raise DiffcalcException(
                "Diffcalc is not fully constrained.\n"
                "Type 'help con' for instructions")

        if not self.constraints.is_current_mode_implemented():
            raise DiffcalcException(
                "Sorry, the selected constraint combination is valid but "
                "is not implemented. Type 'help con' for implemented combinations")
              
        # constraints are dictionaries  
        ref_constraint = self.constraints.reference
        if ref_constraint:
            ref_constraint_name, ref_constraint_value = ref_constraint.items()[0]
        det_constraint = self.constraints.detector
        naz_constraint = self.constraints.naz
        samp_constraints = self.constraints.sample
            
        assert not (det_constraint and naz_constraint), (
               "Two 'detector' constraints given")


        h_phi = self._get_ubmatrix() * matrix([[h], [k], [l]])
        theta = self._calc_theta(h_phi, wavelength)
        tau = angle_between_vectors(h_phi, self._get_n_phi())

        ### Reference constraint column ###

        if ref_constraint:
            # An angle for the reference vector (n) is given      (Section 5.2)         
            psi, alpha, _ = self._calc_remaining_reference_angles(
                ref_constraint_name, ref_constraint_value, theta, tau)
            # IMPORTNANT: other psi solutions are possibly valid.
            # TODO: ensure this is handled consistently in all paths below
            #       currently only handled in 
            #       self._calc_sample_given_two_sample_and_reference(...)

        ### Detector constraint column ###

        if det_constraint or naz_constraint:
            qaz, naz, delta, nu = self._calc_det_angles_given_det_or_naz_constraint(
                                  det_constraint, naz_constraint, theta, tau, alpha)
        
        ### Sample constraint column ###

        if len(samp_constraints) == 1:
            # a detector and reference constraint will have been given
            mu, eta, chi, phi = self._calc_sample_angles_from_one_sample_constraint(
                h, k, l, wavelength, samp_constraints, h_phi, theta,
                ref_constraint_name, ref_constraint_value, alpha, qaz, naz,
                delta, nu)
            solution_tuples = [(mu, delta, nu, eta, chi, phi)]

        elif len(samp_constraints) == 2:
            assert ref_constraint, ('No code yet to handle 2 sample '
                                    'without a reference constraint!')
            angles = self._calc_sample_given_two_sample_and_reference(
                h, k, l, wavelength, samp_constraints, h_phi, theta,
                ref_constraint_name, ref_constraint_value, psi)
            solution_tuples = [angles]

        elif len(samp_constraints) == 3:
            solution_tuples = self._calc_angles_given_three_sample_constraints(
                h, k, l, wavelength, return_all_solutions, samp_constraints,
                 h_phi, theta)
            
        position_pseudo_angles_pairs = []
        for mu, delta, nu, eta, chi, phi in solution_tuples:
            pair = self._create_position_pseudo_angles_pair(
                wavelength, mu, delta, nu, eta, chi, phi)
            position_pseudo_angles_pairs.append(pair)

        return position_pseudo_angles_pairs