Esempio n. 1
0
    def rotation(self, i, motion_index=0):
        """Set up the rotation for state i."""

        # Loop until a valid rotation matrix is found.
        while True:
            # The random rotation matrix.
            R_random_hypersphere(self.R)

            # Rotation in the eigenframe.
            R_eigen = dot(transpose(self.axes), dot(self.R, self.axes))

            # The angles.
            phi, theta, sigma = R_to_tilt_torsion(R_eigen)
            sigma = wrap_angles(sigma, -pi, pi)

            # Skip the rotation if the cone angle is violated.
            if theta > self.THETA_MAX:
                continue

            # Skip the rotation if the torsion angle is violated.
            if sigma > self.SIGMA_MAX or sigma < -self.SIGMA_MAX:
                continue

            # Rotation is ok, so stop looping.
            break
Esempio n. 2
0
    def rotation(self, i, motion_index=0):
        """Set up the rotation for state i."""

        # Loop until a valid rotation matrix is found.
        while True:
            # The random rotation matrix.
            R_random_hypersphere(self.R)

            # Rotate the Z-axis.
            rot_axis = dot(self.R, self.axes[:, 2])

            # Calculate the projection and angle.
            proj = dot(self.axes[:, 2], rot_axis)

            # Calculate the angle, taking float16 truncation errors into account.
            if proj > 1.0:
                proj = 1.0
            elif proj < -1.0:
                proj = -1.0
            theta = acos(proj)

            # Skip the rotation if the angle is violated.
            if theta > self.THETA_MAX:
                continue

            # Rotation is ok, so stop looping.
            break
Esempio n. 3
0
    def rotation(self, i, motion_index=0):
        """Set up the rotation for state i."""

        # Loop until a valid rotation matrix is found.
        while True:
            # The random rotation matrix.
            R_random_hypersphere(self.R)

            # Rotation in the eigenframe.
            R_eigen = dot(transpose(self.axes), dot(self.R, self.axes))

            # The angles.
            phi, theta, sigma = R_to_tilt_torsion(R_eigen)

            # Skip the rotation if the isotropic cone angle is violated.
            if theta > self.THETA_Y:
                continue

            # Determine theta_max.
            theta_max = 1.0 / sqrt((cos(phi) / self.THETA_X)**2 +
                                   (sin(phi) / self.THETA_Y)**2)

            # Skip the rotation if the cone angle is violated.
            if theta > theta_max:
                continue

            # Reconstruct the rotation matrix, in the eigenframe, without sigma.
            tilt_torsion_to_R(phi, theta, 0.0, R_eigen)

            # Rotate back out of the eigenframe.
            self.R = dot(self.axes, dot(R_eigen, transpose(self.axes)))

            # Rotation is ok, so stop looping.
            break
Esempio n. 4
0
    def rotation_hypersphere(self):
        """Random rotation using 4D hypersphere point picking and return of torsion-tilt angles."""

        # Generate a random rotation.
        R_random_hypersphere(self.rot)

        # Rotate the frame.
        frame = dot(self.eig_frame_T, dot(self.rot, EIG_FRAME))

        # Decompose the frame into the zyz Euler angles.
        alpha, beta, gamma = R_to_euler_zyz(frame)

        # Convert to tilt and torsion angles (properly wrapped) and return them.
        theta = beta
        phi = wrap_angles(gamma, -pi, pi)
        sigma = wrap_angles(alpha + gamma, -pi, pi)
        return theta, phi, sigma
Esempio n. 5
0
def uniform_distribution(file=None,
                         model=None,
                         structure=None,
                         parameters={},
                         eigenframe=None,
                         pivot=None,
                         atom_id=None,
                         total=1000,
                         max_rotations=100000):
    """Uniform distribution of the frame order motions.

    @keyword file:          The opened and writable file object to place the PDB models of the distribution into.
    @type file:             str
    @keyword structure:     The internal structural object containing the domain to distribute as a single model.
    @type structure:        lib.structure.internal.object.Internal instance
    @keyword model:         The frame order model to distribute.
    @type model:            str
    @keyword parameters:    The dictionary of model parameter values.  The key is the parameter name and the value is the value.
    @type parameters:       dict of float
    @keyword eigenframe:    The full 3D eigenframe of the frame order motions.
    @type eigenframe:       numpy rank-2, 3D float64 array
    @keyword pivot:         The list of pivot points of the frame order motions.
    @type pivot:            numpy rank-2 (N, 3) float64 array
    @keyword atom_id:       The atom ID string for the atoms in the structure to rotate - i.e. the moving domain.
    @type atom_id:          None or str
    @keyword total:         The total number of states in the distribution.
    @type total:            int
    @keyword max_rotations: The maximum number of rotations to generate the distribution from.  This prevents an execution for an infinite amount of time when a frame order amplitude parameter is close to zero so that the subset of all rotations within the distribution is close to zero.
    @type max_rotations:    int
    """

    # Check the structural object.
    if structure.num_models() > 1:
        raise RelaxError("Only a single model is supported.")

    # Set the model number.
    structure.set_model(model_orig=None, model_new=1)

    # Generate the internal structural selection object.
    selection = structure.selection(atom_id)

    # The initial states and motional limits.
    num_states = len(pivot)
    states = zeros((num_states, 3, 3), float64)
    theta_max = []
    sigma_max = []
    for i in range(num_states):
        states[i] = eye(3)
        theta_max.append(None)
        sigma_max.append(None)

    # Initialise the rotation matrix data structures.
    R = eye(3, dtype=float64)

    # Axis permutations.
    perm = [None]
    if model == MODEL_DOUBLE_ROTOR:
        perm = [[2, 0, 1], [1, 2, 0]]
        perm_rev = [[1, 2, 0], [2, 0, 1]]

    # The maximum cone opening angles (isotropic cones).
    if 'cone_theta' in parameters:
        theta_max[0] = parameters['cone_theta']

    # The maximum cone opening angles (isotropic cones).
    theta_x = None
    theta_y = None
    if 'cone_theta_x' in parameters:
        theta_x = parameters['cone_theta_x']
        theta_y = parameters['cone_theta_y']

    # The maximum torsion angle.
    if 'cone_sigma_max' in parameters:
        sigma_max[0] = parameters['cone_sigma_max']
    elif 'free rotor' in model:
        sigma_max[0] = pi

    # The second torsion angle.
    if 'cone_sigma_max_2' in parameters:
        sigma_max[1] = parameters['cone_sigma_max_2']

    # Printout.
    print("\nGenerating the distribution:")

    # Distribution.
    current_state = 1
    num = -1
    while True:
        # The total number of rotations.
        num += 1

        # End.
        if current_state == total:
            break
        if num >= max_rotations:
            sys.stdout.write('\n')
            warn(
                RelaxWarning(
                    "Maximum number of rotations encountered - the distribution only contains %i states."
                    % current_state))
            break

        # Loop over each state, or motional mode.
        inside = True
        for i in range(num_states):
            # The random rotation matrix.
            R_random_hypersphere(R)

            # Shift the current state.
            states[i] = dot(R, states[i])

            # Rotation in the eigenframe.
            R_eigen = dot(transpose(eigenframe), dot(states[i], eigenframe))

            # Axis permutation to shift each rotation axis to Z.
            if perm[i] != None:
                for j in range(3):
                    R_eigen[:, j] = R_eigen[perm[i], j]
                for j in range(3):
                    R_eigen[j, :] = R_eigen[j, perm[i]]

            # The angles.
            phi, theta, sigma = R_to_tilt_torsion(R_eigen)
            sigma = wrap_angles(sigma, -pi, pi)

            # Determine theta_max for the pseudo-ellipse models.
            if theta_x != None:
                theta_max[i] = 1.0 / sqrt((cos(phi) / theta_x)**2 +
                                          (sin(phi) / theta_y)**2)

            # The cone opening angle is outside of the limit.
            if theta_max[i] != None:
                if theta > theta_max[i]:
                    inside = False

            # No tilt component.
            else:
                theta = 0.0
                phi = 0.0

            # The torsion angle is outside of the limits.
            if sigma_max[i] != None:
                if sigma > sigma_max[i]:
                    inside = False
                elif sigma < -sigma_max[i]:
                    inside = False
            else:
                sigma = 0.0

            # Reconstruct the rotation matrix, in the eigenframe, without sigma.
            tilt_torsion_to_R(phi, theta, sigma, R_eigen)

            # Reverse axis permutation to shift each rotation z-axis back.
            if perm[i] != None:
                for j in range(3):
                    R_eigen[:, j] = R_eigen[perm_rev[i], j]
                for j in range(3):
                    R_eigen[j, :] = R_eigen[j, perm_rev[i]]

            # Rotate back out of the eigenframe.
            states[i] = dot(eigenframe, dot(R_eigen, transpose(eigenframe)))

        # The state is outside of the distribution.
        if not inside:
            continue

        # Progress.
        sys.stdout.write('.')
        sys.stdout.flush()

        # Increment the snapshot number.
        current_state += 1

        # Copy the original structural data.
        structure.add_model(model=current_state, coords_from=1)

        # Rotate the model.
        for i in range(num_states):
            structure.rotate(R=states[i],
                             origin=pivot[i],
                             model=current_state,
                             selection=selection)

    # Save the result.
    structure.write_pdb(file=file)