Example #1
0
def calc_tp_lab(tp_phi_tuple, eta, chi, phi, xyz_eta=[0, 0, 0]):
    tp_phi = matrix(tp_phi_tuple).T
    ETA = calcETA(eta * TORAD)
    CHI = calcCHI(chi * TORAD)
    PHI = calcPHI(phi * TORAD)
    xyz_eta = matrix(xyz_eta).T

    tp_lab = ETA * (xyz_eta + (CHI * PHI * tp_phi))
    return list(tp_lab.T.tolist()[0])
Example #2
0
def move_lab_origin_into_phi(chi, phi, xyz_eta_tuple):
    # the inverse of calc_tp_lab with tp_lab=0:
    CHI = calcCHI(chi * TORAD)
    PHI = calcPHI(phi * TORAD)
    xyz_eta = matrix(xyz_eta_tuple).T
    try:
        #work in IPython with numpy
        tp_phi = PHI.I * CHI.I * (-1.0 * xyz_eta)
    except:
        # work in GDA using jama_matrix_wrapper - definitely not nice
        tp_phi = PHI.I * CHI.I * (xyz_eta.__mul__(-1.0))
    return list(tp_phi.T.tolist()[0])
Example #3
0
    def _calc_sample_angles_given_two_sample_and_reference(
            self, samp_constraints, psi, theta, q_phi, n_phi):
        """Available combinations:
        chi, phi, reference
        mu, eta, reference,
        chi=90, mu=0, reference
        """

        N_phi = _calc_N(q_phi, n_phi)
        THETA = z_rotation(-theta)
        PSI = x_rotation(psi)

        if 'chi' in samp_constraints and 'phi' in samp_constraints:

            chi = samp_constraints['chi']
            phi = samp_constraints['phi']

            CHI = calcCHI(chi)
            PHI = calcPHI(phi)
            V = CHI * PHI * N_phi * PSI.T * THETA.T                     # (56)

            xi = atan2(-V[2, 0], V[2, 2])
            eta = atan2(-V[0, 1], V[1, 1])
            mu = atan2(-V[2, 1], sqrt(V[2, 2] ** 2 + V[2, 0] ** 2))

        elif 'mu' in samp_constraints and 'eta' in samp_constraints:

            mu = samp_constraints['mu']
            eta = samp_constraints['eta']

            V = N_phi * PSI.T * THETA.T                                  # (49)

            bot = sqrt(sin(eta) ** 2 * cos(mu) ** 2 + sin(mu) ** 2)
            chi_orig = (asin(-V[2, 1] / bot) -
                   atan2(sin(mu), (sin(eta) * cos(mu))))                 # (52)

            # Choose final chi solution here to obtain compatable xi and mu
            # TODO: This temporary solution works only for one case used on i07
            #       Return a list of possible solutions?
            if is_small(eta) and is_small(mu + pi / 2):
                for chi in _generate_transformed_values(chi_orig):
                    if  pi / 2 <= chi < pi:
                        break
            else:
                chi = chi_orig

            a = sin(chi) * cos(eta)
            b = sin(chi) * sin(eta) * sin(mu) - cos(chi) * cos(mu)
            xi = atan2(V[2, 2] * a + V[2, 0] * b,
                       V[2, 0] * a - V[2, 2] * b)                        # (54)

            a = sin(chi) * sin(mu) - cos(mu) * cos(chi) * sin(eta)
            b = cos(mu) * cos(eta)
            phi = atan2(V[1, 1] * a - V[0, 1] * b,
                        V[0, 1] * a + V[1, 1] * b)                       # (55)
#            if is_small(mu+pi/2) and is_small(eta) and False:
#                phi_general = phi
#                # solved in extensions_to_yous_paper.wxm
#                phi = atan2(V[1, 1], V[0, 1])
#                logger.info("phi = %.3f or %.3f (std)",
#                            phi*TODEG, phi_general*TODEG )

        elif 'chi' in samp_constraints and 'mu' in samp_constraints:
            # derived in extensions_to_yous_paper.wxm
            chi = samp_constraints['chi']
            mu = samp_constraints['mu']

            if not is_small(mu) and not is_small(chi - pi / 2):
                raise Exception('The fixed chi, mu, psi/alpha/beta modes only '
                                ' currently work with chi=90 and mu=0')
            V = N_phi * PSI.T * THETA.T
            eta = asin(-V[2, 1])
            xi = atan2(V[2, 2], V[2, 0])
            phi = -atan2(V[0, 1], V[1, 1])

        else:
            raise DiffcalcException(
                'No code yet to handle this combination of 2 sample '
                'constraints and one reference!:' + str(samp_constraints))
        return xi, psi, mu, eta, chi, phi
Example #4
0
    def _calc_remaining_sample_angles(self, constraint_name, constraint_value,
                                      q_lab, n_lab, q_phi, n_phi):
        """Return phi, chi, eta and mu, given one of these"""
        #                                                         (section 5.3)
        # TODO: Sould return a valid solution, rather than just one that can
        # be mapped to a correct solution by applying +-x and 180+-x mappings?

        N_lab = _calc_N(q_lab, n_lab)
        N_phi = _calc_N(q_phi, n_phi)

        if constraint_name == 'mu':                                      # (35)
            mu = constraint_value
            V = calcMU(mu).I * N_lab * N_phi.T
            phi = atan2(V[2, 1], V[2, 0])
            eta = atan2(-V[1, 2], V[0, 2])
            chi = atan2(sqrt(V[2, 0] ** 2 + V[2, 1] ** 2), V[2, 2])
            if is_small(sin(chi)):
                # chi ~= 0 or 180 and therefor phi || eta The solutions for phi
                # and eta here will be valid but will be chosen unpredictably.
                # Choose eta=0:
                phi_orig, eta_orig = phi, eta
                # tan(phi+eta)=v12/v11 from docs/extensions_to_yous_paper.wxm
                eta = 0
                phi = atan2(V[0, 1], V[0, 0])
                logger.debug(
                    'Eta and phi cannot be chosen uniquely with chi so close '
                    'to 0 or 180. Ignoring solution phi=%.3f and eta=%.3f, and'
                    ' returning phi=%.3f and eta=%.3f', phi_orig * TODEG,
                    eta_orig * TODEG, phi * TODEG, eta * TODEG)
            return phi, chi, eta, mu

        if constraint_name == 'phi':                                     # (37)
            phi = constraint_value
            V = N_lab * N_phi.I * calcPHI(phi).T
            eta = atan2(V[0, 1], sqrt(V[1, 1] ** 2 + V[2, 1] ** 2))
            mu = atan2(V[2, 1], V[1, 1])
            chi = atan2(V[0, 2], V[0, 0])
            if is_small(cos(eta)):
                raise ValueError(
                    'Chi and mu cannot be chosen uniquely with eta so close '
                    'to +-90.')
            return phi, chi, eta, mu

        elif constraint_name in ('eta', 'chi'):
            V = N_lab * N_phi.T
            if constraint_name == 'eta':                                 # (39)
                eta = constraint_value
                cos_eta = cos(eta)
                if is_small(cos_eta):
                    #TODO: Not likely to happen in real world!?
                    raise ValueError(
                        'Chi and mu cannot be chosen uniquely with eta '
                        'constrained so close to +-90.')
                chi = asin(V[0, 2] / cos_eta)

            else:  # constraint_name == 'chi'                            # (40)
                chi = constraint_value
                sin_chi = sin(chi)
                if is_small(sin_chi):
                    raise ValueError(
                        'Eta and phi cannot be chosen uniquely with chi '
                        'constrained so close to 0. (Please contact developer '
                        'if this case is useful for you)')
                eta = acos(V[0, 2] / sin_chi)

            top_for_mu = V[2, 2] * sin(eta) * sin(chi) + V[1, 2] * cos(chi)
            bot_for_mu = -V[2, 2] * cos(chi) + V[1, 2] * sin(eta) * sin(chi)
            mu = atan2(-top_for_mu, -bot_for_mu)                         # (41)
            # (minus signs added from paper to pass (pieces) tests)
            if is_small(top_for_mu) and is_small(bot_for_mu):
                # chi == +-90, eta == 0/180 and therefor phi || mu cos(chi) ==
                # 0 and sin(eta) == 0 Experience shows that even though e.g.
                # the V[2, 2] and V[1, 2] values used to calculate mu may be
                # basically 0 (1e-34) their ratio in every case tested so far
                # still remains valid and using them will result in a phi
                # solution that is continous with neighbouring positions.
                #
                # We cannot test phi minus mu here unfortunetely as the final
                # phi and mu solutions have not yet been chosen (they may be
                # +-x or 180+-x). Otherwise we could choose a sensible solution
                # here if the one found was incorrect.

                # tan(phi+eta)=v12/v11 from extensions_to_yous_paper.wxm
                phi_minus_mu = -atan2(V[2, 0], V[1, 1])
                logger.debug(
                    'Mu and phi cannot be chosen uniquely with chi so close '
                    'to +-90 and eta so close 0 or 180.\n After the final '
                    'solution has been chose phi-mu should equal: %.3f',
                    phi_minus_mu * TODEG)

            top_for_phi = V[0, 1] * cos(eta) * cos(chi) - V[0, 0] * sin(eta)
            bot_for_phi = V[0, 1] * sin(eta) + V[0, 0] * cos(eta) * cos(chi)
            phi = atan2(top_for_phi, bot_for_phi)                        # (42)
#            if is_small(bot_for_phi) and is_small(top_for_phi):
#                raise ValueError(
#                    'phi=%.3f cannot be known with confidence as top and '
#                    'bottom are both close to zero. chi=%.3f, eta=%.3f'
#                    % (mu * TODEG, chi * TODEG, eta * TODEG))
            return phi, chi, eta, mu

        raise ValueError('Given angle must be one of phi, chi, eta or mu')
 def calcUB(self):
     CHI = calcCHI(self.chiMissmount * TORAD)
     PHI = calcPHI(self.phiMissmount * TORAD)
     self.UB = CHI * PHI * self.cut.B
Example #6
0
 def calcUB(self):
     CHI = calcCHI(self.chiMissmount * TORAD)
     PHI = calcPHI(self.phiMissmount * TORAD)
     self.UB = CHI * PHI * self.cut.B
Example #7
0
    def _calc_sample_angles_given_two_sample_and_reference(
            self, samp_constraints, psi, theta, q_phi, n_phi):
        """Available combinations:
        chi, phi, reference
        mu, eta, reference,
        chi=90, mu=0, reference
        """

        N_phi = _calc_N(q_phi, n_phi)
        THETA = z_rotation(-theta)
        PSI = x_rotation(psi)

        if 'chi' in samp_constraints and 'phi' in samp_constraints:

            chi = samp_constraints['chi']
            phi = samp_constraints['phi']

            CHI = calcCHI(chi)
            PHI = calcPHI(phi)
            V = CHI * PHI * N_phi * PSI.T * THETA.T                     # (56)

            xi = atan2(-V[2, 0], V[2, 2])
            eta = atan2(-V[0, 1], V[1, 1])
            mu = atan2(-V[2, 1], sqrt(V[2, 2] ** 2 + V[2, 0] ** 2))

        elif 'mu' in samp_constraints and 'eta' in samp_constraints:

            mu = samp_constraints['mu']
            eta = samp_constraints['eta']

            V = N_phi * PSI.T * THETA.T                                  # (49)

            bot = sqrt(sin(eta) ** 2 * cos(mu) ** 2 + sin(mu) ** 2)
            chi_orig = (asin(-V[2, 1] / bot) -
                   atan2(sin(mu), (sin(eta) * cos(mu))))                 # (52)

            # Choose final chi solution here to obtain compatable xi and mu
            # TODO: This temporary solution works only for one case used on i07
            #       Return a list of possible solutions?
            if is_small(eta) and is_small(mu + pi / 2):
                for chi in _generate_transformed_values(chi_orig):
                    if  pi / 2 <= chi < pi:
                        break
            else:
                chi = chi_orig

            a = sin(chi) * cos(eta)
            b = sin(chi) * sin(eta) * sin(mu) - cos(chi) * cos(mu)
            xi = atan2(V[2, 2] * a + V[2, 0] * b,
                       V[2, 0] * a - V[2, 2] * b)                        # (54)

            a = sin(chi) * sin(mu) - cos(mu) * cos(chi) * sin(eta)
            b = cos(mu) * cos(eta)
            phi = atan2(V[1, 1] * a - V[0, 1] * b,
                        V[0, 1] * a + V[1, 1] * b)                       # (55)
#            if is_small(mu+pi/2) and is_small(eta) and False:
#                phi_general = phi
#                # solved in extensions_to_yous_paper.wxm
#                phi = atan2(V[1, 1], V[0, 1])
#                logger.info("phi = %.3f or %.3f (std)",
#                            phi*TODEG, phi_general*TODEG )

        elif 'chi' in samp_constraints and 'mu' in samp_constraints:
            # derived in extensions_to_yous_paper.wxm
            chi = samp_constraints['chi']
            mu = samp_constraints['mu']

            if not is_small(mu) and not is_small(chi - pi / 2):
                raise Exception('The fixed chi, mu, psi/alpha/beta modes only '
                                ' currently work with chi=90 and mu=0')
            V = N_phi * PSI.T * THETA.T
            eta = asin(-V[2, 1])
            xi = atan2(V[2, 2], V[2, 0])
            phi = -atan2(V[0, 1], V[1, 1])

        else:
            raise DiffcalcException(
                'No code yet to handle this combination of 2 sample '
                'constraints and one reference!:' + str(samp_constraints))
        return xi, psi, mu, eta, chi, phi
Example #8
0
    def _calc_remaining_sample_angles(self, constraint_name, constraint_value,
                                      q_lab, n_lab, q_phi, n_phi):
        """Return phi, chi, eta and mu, given one of these"""
        #                                                         (section 5.3)
        # TODO: Sould return a valid solution, rather than just one that can
        # be mapped to a correct solution by applying +-x and 180+-x mappings?

        N_lab = _calc_N(q_lab, n_lab)
        N_phi = _calc_N(q_phi, n_phi)

        if constraint_name == 'mu':                                      # (35)
            mu = constraint_value
            V = calcMU(mu).I * N_lab * N_phi.T
            phi = atan2(V[2, 1], V[2, 0])
            eta = atan2(-V[1, 2], V[0, 2])
            chi = atan2(sqrt(V[2, 0] ** 2 + V[2, 1] ** 2), V[2, 2])
            if is_small(sin(chi)):
                # chi ~= 0 or 180 and therefor phi || eta The solutions for phi
                # and eta here will be valid but will be chosen unpredictably.
                # Choose eta=0:
                phi_orig, eta_orig = phi, eta
                # tan(phi+eta)=v12/v11 from docs/extensions_to_yous_paper.wxm
                eta = 0
                phi = atan2(V[0, 1], V[0, 0])
                logger.debug(
                    'Eta and phi cannot be chosen uniquely with chi so close '
                    'to 0 or 180. Ignoring solution phi=%.3f and eta=%.3f, and'
                    ' returning phi=%.3f and eta=%.3f', phi_orig * TODEG,
                    eta_orig * TODEG, phi * TODEG, eta * TODEG)
            return phi, chi, eta, mu

        if constraint_name == 'phi':                                     # (37)
            phi = constraint_value
            V = N_lab * N_phi.I * calcPHI(phi).T
            eta = atan2(V[0, 1], sqrt(V[1, 1] ** 2 + V[2, 1] ** 2))
            mu = atan2(V[2, 1], V[1, 1])
            chi = atan2(V[0, 2], V[0, 0])
            if is_small(cos(eta)):
                raise ValueError(
                    'Chi and mu cannot be chosen uniquely with eta so close '
                    'to +-90.')
            return phi, chi, eta, mu

        elif constraint_name in ('eta', 'chi'):
            V = N_lab * N_phi.T
            if constraint_name == 'eta':                                 # (39)
                eta = constraint_value
                cos_eta = cos(eta)
                if is_small(cos_eta):
                    #TODO: Not likely to happen in real world!?
                    raise ValueError(
                        'Chi and mu cannot be chosen uniquely with eta '
                        'constrained so close to +-90.')
                chi = asin(V[0, 2] / cos_eta)

            else:  # constraint_name == 'chi'                            # (40)
                chi = constraint_value
                sin_chi = sin(chi)
                if is_small(sin_chi):
                    raise ValueError(
                        'Eta and phi cannot be chosen uniquely with chi '
                        'constrained so close to 0. (Please contact developer '
                        'if this case is useful for you)')
                eta = acos(V[0, 2] / sin_chi)

            top_for_mu = V[2, 2] * sin(eta) * sin(chi) + V[1, 2] * cos(chi)
            bot_for_mu = -V[2, 2] * cos(chi) + V[1, 2] * sin(eta) * sin(chi)
            mu = atan2(-top_for_mu, -bot_for_mu)                         # (41)
            # (minus signs added from paper to pass (pieces) tests)
            if is_small(top_for_mu) and is_small(bot_for_mu):
                # chi == +-90, eta == 0/180 and therefor phi || mu cos(chi) ==
                # 0 and sin(eta) == 0 Experience shows that even though e.g.
                # the V[2, 2] and V[1, 2] values used to calculate mu may be
                # basically 0 (1e-34) their ratio in every case tested so far
                # still remains valid and using them will result in a phi
                # solution that is continous with neighbouring positions.
                #
                # We cannot test phi minus mu here unfortunetely as the final
                # phi and mu solutions have not yet been chosen (they may be
                # +-x or 180+-x). Otherwise we could choose a sensible solution
                # here if the one found was incorrect.

                # tan(phi+eta)=v12/v11 from extensions_to_yous_paper.wxm
                phi_minus_mu = -atan2(V[2, 0], V[1, 1])
                logger.debug(
                    'Mu and phi cannot be chosen uniquely with chi so close '
                    'to +-90 and eta so close 0 or 180.\n After the final '
                    'solution has been chose phi-mu should equal: %.3f',
                    phi_minus_mu * TODEG)

            top_for_phi = V[0, 1] * cos(eta) * cos(chi) - V[0, 0] * sin(eta)
            bot_for_phi = V[0, 1] * sin(eta) + V[0, 0] * cos(eta) * cos(chi)
            phi = atan2(top_for_phi, bot_for_phi)                        # (42)
#            if is_small(bot_for_phi) and is_small(top_for_phi):
#                raise ValueError(
#                    'phi=%.3f cannot be known with confidence as top and '
#                    'bottom are both close to zero. chi=%.3f, eta=%.3f'
#                    % (mu * TODEG, chi * TODEG, eta * TODEG))
            return phi, chi, eta, mu

        raise ValueError('Given angle must be one of phi, chi, eta or mu')