Ejemplo n.º 1
0
def kabsch(name_from=None,
           name_to=None,
           coord_from=None,
           coord_to=None,
           centre_type="centroid",
           elements=None,
           centroid=None,
           verbosity=1):
    """Calculate the rotational and translational displacements between the two given coordinate sets.

    This uses the U{Kabsch algorithm<http://en.wikipedia.org/wiki/Kabsch_algorithm>}.


    @keyword name_from:     The name of the starting structure, used for the printouts.
    @type name_from:        str
    @keyword name_to:       The name of the ending structure, used for the printouts.
    @type name_to:          str
    @keyword coord_from:    The list of atomic coordinates for the starting structure.
    @type coord_from:       numpy rank-2, Nx3 array
    @keyword coord_to:      The list of atomic coordinates for the ending structure.
    @type coord_to:         numpy rank-2, Nx3 array
    @keyword centre_type:   The type of centre to superimpose over.  This can either be the standard centroid superimposition or the CoM could be used instead.
    @type centre_type:      str
    @keyword elements:      The list of elements corresponding to the atoms.
    @type elements:         list of str
    @keyword centroid:      An alternative position of the centroid, used for studying pivoted systems.
    @type centroid:         list of float or numpy rank-1, 3D array
    @return:                The translation vector T, translation distance d, rotation matrix R, rotation axis r, rotation angle theta, and the rotational pivot defined as the centroid of the ending structure.
    @rtype:                 numpy rank-1 3D array, float, numpy rank-2 3D array, numpy rank-1 3D array, float, numpy rank-1 3D array
    """

    # Calculate the centroids.
    if centroid is not None:
        centroid_from = centroid
        centroid_to = centroid
    elif centre_type == 'centroid':
        centroid_from = find_centroid(coord_from)
        centroid_to = find_centroid(coord_to)
    else:
        centroid_from, mass_from = centre_of_mass(pos=coord_from,
                                                  elements=elements)
        centroid_to, mass_to = centre_of_mass(pos=coord_to, elements=elements)

    # The translation.
    trans_vect = centroid_to - centroid_from
    trans_dist = norm(trans_vect)

    # Calculate the rotation.
    R = kabsch_rotation(coord_from=coord_from,
                        coord_to=coord_to,
                        centroid_from=centroid_from,
                        centroid_to=centroid_to)
    axis, angle = R_to_axis_angle(R)
    a, b, g = R_to_euler_zyz(R)

    # Print out.
    if verbosity >= 1:
        print(
            "\n\nCalculating the rotational and translational displacements from %s to %s using the Kabsch algorithm.\n"
            % (name_from, name_to))
        if centre_type == 'centroid':
            print("Start centroid:          [%20.15f, %20.15f, %20.15f]" %
                  (centroid_from[0], centroid_from[1], centroid_from[2]))
            print("End centroid:            [%20.15f, %20.15f, %20.15f]" %
                  (centroid_to[0], centroid_to[1], centroid_to[2]))
        else:
            print("Start CoM:               [%20.15f, %20.15f, %20.15f]" %
                  (centroid_from[0], centroid_from[1], centroid_from[2]))
            print("End CoM:                 [%20.15f, %20.15f, %20.15f]" %
                  (centroid_to[0], centroid_to[1], centroid_to[2]))
        print("Translation vector:      [%20.15f, %20.15f, %20.15f]" %
              (trans_vect[0], trans_vect[1], trans_vect[2]))
        print("Translation distance:    %.15f" % trans_dist)
        print("Rotation matrix:")
        print("   [[%20.15f, %20.15f, %20.15f]" % (R[0, 0], R[0, 1], R[0, 2]))
        print("    [%20.15f, %20.15f, %20.15f]" % (R[1, 0], R[1, 1], R[1, 2]))
        print("    [%20.15f, %20.15f, %20.15f]]" % (R[2, 0], R[2, 1], R[2, 2]))
        print("Rotation axis:           [%20.15f, %20.15f, %20.15f]" %
              (axis[0], axis[1], axis[2]))
        print("Rotation euler angles:   [%20.15f, %20.15f, %20.15f]" %
              (a, b, g))
        print("Rotation angle (deg):    %.15f" % (angle / 2.0 / pi * 360.0))

    # Return the data.
    return trans_vect, trans_dist, R, axis, angle, centroid_to
Ejemplo n.º 2
0
def pipe_centre_of_mass(atom_id=None,
                        model=None,
                        return_mass=False,
                        verbosity=1,
                        missing_error=True):
    """Calculate and return the centre of mass of the structures in the current data pipe.

    @keyword atom_id:       The molecule, residue, and atom identifier string.  Only atoms matching this selection will be used.
    @type atom_id:          str or None
    @keyword model:         Only use a specific model.
    @type model:            int or None
    @keyword return_mass:   A flag which if False will cause only the centre of mass to be returned, but if True will cause the centre of mass and the mass itself to be returned as a tuple.
    @type return_mass:      bool
    @keyword verbosity:     The amount of text to print out.  0 results in no printouts, 1 the full amount.
    @type verbosity:        int
    @keyword missing_error: A flag which if True will cause an error to be raised if structural data is absent.  Otherwise if False, a warning will be given and the CoM of [0, 0, 0] will be returned.
    @type missing_error:    bool
    @return:                The centre of mass vector, and additionally the mass.
    @rtype:                 list of 3 floats (or tuple of a list of 3 floats and one float)
    """

    # Test if a structure has been loaded.
    if missing_error:
        check_structure()
    else:
        if not check_structure(escalate=1):
            return [0.0, 0.0, 0.0]

    # The selection object.
    selection = cdp.structure.selection(atom_id=atom_id)

    # Loop over all atoms.
    coord = []
    element_list = []
    for mol_name, res_num, res_name, atom_num, atom_name, element, pos in cdp.structure.atom_loop(
            selection=selection,
            model_num=model,
            mol_name_flag=True,
            res_num_flag=True,
            res_name_flag=True,
            atom_num_flag=True,
            atom_name_flag=True,
            element_flag=True,
            pos_flag=True,
            ave=True):
        # Initialise the spin
        id = ''

        # Get the corresponding molecule container.
        if mol_name != None:
            id = id + '#' + mol_name

        # Get the corresponding residue container.
        if res_num != None:
            id = id + ':' + repr(res_num)

        # Get the corresponding spin container.
        if atom_num != None:
            id = id + '@' + repr(atom_num)

        # No element?
        if element == None:
            warn(
                RelaxWarning(
                    "Skipping the atom '%s' as the element type cannot be determined."
                    % id))
            continue

        # Store the position and element.
        coord.append(pos)
        element_list.append(element)

    # Calculate the CoM.
    com, mass = centre_of_mass(pos=coord,
                               elements=element_list,
                               verbosity=verbosity)

    # Return the centre of mass.
    if return_mass:
        return com, mass
    else:
        return com
Ejemplo n.º 3
0
def pipe_centre_of_mass(atom_id=None, model=None, return_mass=False, verbosity=1, missing_error=True):
    """Calculate and return the centre of mass of the structures in the current data pipe.

    @keyword atom_id:       The molecule, residue, and atom identifier string.  Only atoms matching this selection will be used.
    @type atom_id:          str or None
    @keyword model:         Only use a specific model.
    @type model:            int or None
    @keyword return_mass:   A flag which if False will cause only the centre of mass to be returned, but if True will cause the centre of mass and the mass itself to be returned as a tuple.
    @type return_mass:      bool
    @keyword verbosity:     The amount of text to print out.  0 results in no printouts, 1 the full amount.
    @type verbosity:        int
    @keyword missing_error: A flag which if True will cause an error to be raised if structural data is absent.  Otherwise if False, a warning will be given and the CoM of [0, 0, 0] will be returned.
    @type missing_error:    bool
    @return:                The centre of mass vector, and additionally the mass.
    @rtype:                 list of 3 floats (or tuple of a list of 3 floats and one float)
    """

    # Test if a structure has been loaded.
    if missing_error:
        check_structure()
    else:
        if not check_structure(escalate=1):
            return [0.0, 0.0, 0.0]

    # The selection object.
    selection = cdp.structure.selection(atom_id=atom_id)

    # Loop over all atoms.
    coord = []
    element_list = []
    for mol_name, res_num, res_name, atom_num, atom_name, element, pos in cdp.structure.atom_loop(selection=selection, model_num=model, mol_name_flag=True, res_num_flag=True, res_name_flag=True, atom_num_flag=True, atom_name_flag=True, element_flag=True, pos_flag=True, ave=True):
        # Initialise the spin 
        id = ''

        # Get the corresponding molecule container.
        if mol_name != None:
            id = id + '#' + mol_name

        # Get the corresponding residue container.
        if res_num != None:
            id = id + ':' + repr(res_num)

        # Get the corresponding spin container.
        if atom_num != None:
            id = id + '@' + repr(atom_num)

        # No element?
        if element == None:
            warn(RelaxWarning("Skipping the atom '%s' as the element type cannot be determined." % id))
            continue

        # Store the position and element.
        coord.append(pos)
        element_list.append(element)

    # Calculate the CoM.
    com, mass = centre_of_mass(pos=coord, elements=element_list, verbosity=verbosity)

    # Return the centre of mass.
    if return_mass:
        return com, mass
    else:
        return com
Ejemplo n.º 4
0
def kabsch(name_from=None, name_to=None, coord_from=None, coord_to=None, centre_type="centroid", elements=None, centroid=None, verbosity=1):
    """Calculate the rotational and translational displacements between the two given coordinate sets.

    This uses the U{Kabsch algorithm<http://en.wikipedia.org/wiki/Kabsch_algorithm>}.


    @keyword name_from:     The name of the starting structure, used for the printouts.
    @type name_from:        str
    @keyword name_to:       The name of the ending structure, used for the printouts.
    @type name_to:          str
    @keyword coord_from:    The list of atomic coordinates for the starting structure.
    @type coord_from:       numpy rank-2, Nx3 array
    @keyword coord_to:      The list of atomic coordinates for the ending structure.
    @type coord_to:         numpy rank-2, Nx3 array
    @keyword centre_type:   The type of centre to superimpose over.  This can either be the standard centroid superimposition or the CoM could be used instead.
    @type centre_type:      str
    @keyword elements:      The list of elements corresponding to the atoms.
    @type elements:         list of str
    @keyword centroid:      An alternative position of the centroid, used for studying pivoted systems.
    @type centroid:         list of float or numpy rank-1, 3D array
    @return:                The translation vector T, translation distance d, rotation matrix R, rotation axis r, rotation angle theta, and the rotational pivot defined as the centroid of the ending structure.
    @rtype:                 numpy rank-1 3D array, float, numpy rank-2 3D array, numpy rank-1 3D array, float, numpy rank-1 3D array
    """

    # Calculate the centroids.
    if centroid is not None:
        centroid_from = centroid
        centroid_to = centroid
    elif centre_type == 'centroid':
        centroid_from = find_centroid(coord_from)
        centroid_to = find_centroid(coord_to)
    else:
        centroid_from, mass_from = centre_of_mass(pos=coord_from, elements=elements)
        centroid_to, mass_to = centre_of_mass(pos=coord_to, elements=elements)

    # The translation.
    trans_vect = centroid_to - centroid_from
    trans_dist = norm(trans_vect)

    # Calculate the rotation.
    R = kabsch_rotation(coord_from=coord_from, coord_to=coord_to, centroid_from=centroid_from, centroid_to=centroid_to)
    axis, angle = R_to_axis_angle(R)
    a, b, g = R_to_euler_zyz(R)

    # Print out.
    if verbosity >= 1:
        print("\n\nCalculating the rotational and translational displacements from %s to %s using the Kabsch algorithm.\n" % (name_from, name_to))
        if centre_type == 'centroid':
            print("Start centroid:          [%20.15f, %20.15f, %20.15f]" % (centroid_from[0], centroid_from[1], centroid_from[2]))
            print("End centroid:            [%20.15f, %20.15f, %20.15f]" % (centroid_to[0], centroid_to[1], centroid_to[2]))
        else:
            print("Start CoM:               [%20.15f, %20.15f, %20.15f]" % (centroid_from[0], centroid_from[1], centroid_from[2]))
            print("End CoM:                 [%20.15f, %20.15f, %20.15f]" % (centroid_to[0], centroid_to[1], centroid_to[2]))
        print("Translation vector:      [%20.15f, %20.15f, %20.15f]" % (trans_vect[0], trans_vect[1], trans_vect[2]))
        print("Translation distance:    %.15f" % trans_dist)
        print("Rotation matrix:")
        print("   [[%20.15f, %20.15f, %20.15f]" % (R[0, 0], R[0, 1], R[0, 2]))
        print("    [%20.15f, %20.15f, %20.15f]" % (R[1, 0], R[1, 1], R[1, 2]))
        print("    [%20.15f, %20.15f, %20.15f]]" % (R[2, 0], R[2, 1], R[2, 2]))
        print("Rotation axis:           [%20.15f, %20.15f, %20.15f]" % (axis[0], axis[1], axis[2]))
        print("Rotation euler angles:   [%20.15f, %20.15f, %20.15f]" % (a, b, g))
        print("Rotation angle (deg):    %.15f" % (angle / 2.0 / pi * 360.0))

    # Return the data.
    return trans_vect, trans_dist, R, axis, angle, centroid_to
Ejemplo n.º 5
0
def pipe_centre_of_mass(atom_id=None, model=None, return_mass=False, verbosity=1):
    """Calculate and return the centre of mass of the structures in the current data pipe.

    @keyword atom_id:       The molecule, residue, and atom identifier string.  Only atoms matching this selection will be used.
    @type atom_id:          str or None
    @keyword model:         Only use a specific model.
    @type model:            int or None
    @keyword return_mass:   A flag which if False will cause only the centre of mass to be returned, but if True will cause the centre of mass and the mass itself to be returned as a tuple.
    @type return_mass:      bool
    @keyword verbosity:     The amount of text to print out.  0 results in no printouts, 1 the full amount.
    @type verbosity:        int
    @return:                The centre of mass vector, and additionally the mass.
    @rtype:                 list of 3 floats (or tuple of a list of 3 floats and one float)
    """

    # Test if a structure has been loaded.
    if not hasattr(cdp, 'structure'):
        raise RelaxNoPdbError

    # Loop over all atoms.
    coord = []
    element_list = []
    for mol_name, res_num, res_name, atom_num, atom_name, element, pos in cdp.structure.atom_loop(atom_id=atom_id, model_num=model, mol_name_flag=True, res_num_flag=True, res_name_flag=True, atom_num_flag=True, atom_name_flag=True, element_flag=True, pos_flag=True, ave=True):
        # Initialise the spin id string.
        id = ''

        # Get the corresponding molecule container.
        if mol_name == None:
            mol_cont = cdp.mol[0]
        else:
            id = id + '#' + mol_name
            mol_cont = return_molecule(id)

        # Get the corresponding residue container.
        if res_name == None and res_num == None:
            res_cont = mol_cont.res[0]
        else:
            id = id + ':' + repr(res_num)
            res_cont = return_residue(id)

        # Get the corresponding spin container.
        if atom_name == None and atom_num == None:
            spin_cont = res_cont.spin[0]
        else:
            id = id + '@' + repr(atom_num)
            spin_cont = return_spin(id)

        # Deselected spins.
        if spin_cont and not spin_cont.select:
            continue

        # No element?
        if element == None:
            warn(RelaxWarning("Skipping the atom '%s' as the element type cannot be determined." % id))
            continue

        # Store the position and element.
        coord.append(pos)
        element_list.append(element)

    # Calculate the CoM.
    com, mass = centre_of_mass(pos=coord, elements=element_list)

    # Return the centre of mass.
    if return_mass:
        return com, mass
    else:
        return com