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
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
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]]])
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
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
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