def matrix_discrepancy(centers1, rotations1, centers2, rotations2,
                       angle_weight=1.0, center_weight=[1.0]):
    """Compute discrepancies given matrices, not components.
    :param list centers1: A list (or list numpy.array) of all centers.
    :param list rotations1: A list of all rotation matrices.
    :param list centers2: A list (or list numpy.array) of all centers.
    :param list rotations2: A list of all rotation matrices.
    :param float angle_weight: The weight to give to the angle component of
    discrepancy.
    :param float center_weight: The weight to give to the center component of
    discrepancy.
    :returns: A float, the discprenacy.
    """
    assert len(centers1) == len(centers2)
    assert len(rotations1) == len(rotations2)
    assert len(centers1) == len(rotations1)
    assert len(centers1) >= 3

    rotation_matrix, new1, mean1, RMSD, sse, mean2 = \
        besttransformation_weighted(centers1, centers2, center_weight)
    rotation_matrix = np.transpose(rotation_matrix)
   
    orientation_error = 0
    for r1, r2 in zip(rotations1, rotations2):
        angle = angle_of_rotation(np.dot(np.dot(rotation_matrix, r1),
                                         np.transpose(r2)))
        orientation_error += np.square(angle)

    n = len(centers1)
    discrepancy = np.sqrt(sse + angle_weight * orientation_error) / n
    return discrepancy
Esempio n. 2
0
 def test_can_transform_a_4_x_3_45degreezrotation(self):
     theta = numpy.pi/4.0        
     ans = array([[numpy.cos(theta), -1*numpy.sin(theta), 0.0000],
                  [numpy.sin(theta), numpy.cos(theta), 0.0000],
                  [0.0000, 0.0000, 1.0000]])
     a = array([[3.0000, 7.0000, 1.0000],
                [5.0000, 9.0000, 2.0000],
                [7.0000, 4.0000, 6.0000],
                [1.0000, 1.0000, 1.0000]])
     J = numpy.ones((4, 4))
     meana = numpy.dot(J,a)/4.0
     b = numpy.dot(a-meana,ans)
     rotation, _, _, _, _ = besttransformation(a, b)
     assert_almost_equal(ans, rotation)
     angle = angle_of_rotation(rotation)
     assert_almost_equal(angle, 45.0*numpy.pi/180.)
def matrix_discrepancy(centers1,
                       rotations1,
                       centers2,
                       rotations2,
                       angle_weight=None,
                       center_weight=None):
    """Compute discrepancies given matrices, not components.

    :param list centers1: A list (or list numpy.array) of all centers.
    :param list rotations1: A list of all rotation matrices.
    :param list centers2: A list (or list numpy.array) of all centers.
    :param list rotations2: A list of all rotation matrices.
    :param float angle_weight: The weight to give to the angle component of
    discrepancy.
    :param float center_weight: The weight to give to the center component of
    discrepancy.
    :returns: A float, the discprenacy.
    """

    assert len(centers1) == len(centers2)
    assert len(rotations1) == len(rotations2)
    assert len(centers1) == len(rotations1)
    assert len(centers1) >= 3

    if not angle_weight:
        angle_weight = [1] * len(centers1)

    if not center_weight:
        center_weight = [1] * len(centers1)

    rotation_matrix, new1, mean1, RMSD, sse = \
        besttransformation_weighted(centers1, centers2, center_weight)

    orientation_error = 0
    angles = []
    for r1, r2 in zip(rotations1, rotations2):
        if r1.shape[0] > 0 and r2.shape[0] > 0:
            angle = angle_of_rotation(
                np.dot(np.dot(rotation_matrix, r2), np.transpose(r1)))
            orientation_error += np.square(angle)
    n = len(centers1)
    discrepancy = np.sqrt(sse + orientation_error) / n
    return discrepancy
Esempio n. 4
0
def discrepancy(ntlist1, ntlist2, centers=['base'], base_weights=1.0,
                P_weights=1.0, C1star_weights = 1.0, angleweight=1.0):
    """Compute the geometric discrepancy between two lists of components.

    :ntlist1: The first list of components.
    :ntlist2: The second list of components.
    :centers: A list of center names to use, such as
        ['base', 'P', 'C1*', 'ribose']
    :base_weights: The base weights to use. If only one weight is given
    it is used for all centers.  Otherwise, provide list of base weights with
    same length as the length of ntlist1
    :P_weigths: The phosphate weights to use. If only one weight is given
    it is used for all.  Otherwise, provide list of phosphate weights
    with same length as the length of ntlist1
    :C1star_weights: The C1* weights to use. If only one weight is given
    it is used for all.  Otherwise, provide list of C1* weights with
    same length as the length of ntlist1
    :angleweight: The weighting for angles to use.
    :returns: The geometric discrepancy.
    """

    assert len(ntlist1) == len(ntlist2)

    # TODO: Should we allow users to pass a tuple too?
    if not isinstance(centers, list):
        centers = [centers]

    if not isinstance(base_weights, list):
        base_weights = [base_weights] * len(ntlist1)

    if len(base_weights)!= len(ntlist1):
        raise LengthofBaseWeightError('Weight length does not match # of nucl.')

    if not isinstance(P_weights, list):
        P_weights = [P_weights] * len(ntlist1)

    if len(P_weights)!= len(ntlist1):
        raise LengthofPWeightError('Weight length does not match # of nucl.')

    if not isinstance(C1star_weights, list):
        C1star_weights = [C1star_weights] * len(ntlist1)

    if len(C1star_weights)!= len(ntlist1):
        raise LengthofC1starWeightError('Weight length does not match # of nucl.')

    R = []
    S = []
    W = []

    for i in xrange(len(ntlist1)):
        nt1 = ntlist1[i]
        nt2 = ntlist2[i]
        for c in centers:
            if c=='base':
                if c in nt1.centers:
                    R.append(nt1.centers[c])
                    S.append(nt2.centers[c])
                    W.append(base_weights[i])
                else:
                    if c=='base':
                        raise MissingBaseException(centers)
            if c=='P':
                if nt1.coordinates(type = 'P')!=[]:
                    R.append(nt1.coordinates(type = 'P')[0])
                    S.append(nt2.coordinates(type = 'P')[0])
                    l=len(nt1.coordinates(type = 'P'))
                    for z in range(0,l):
                        W.append(P_weights[i])
                else:
                    raise MissingPhosphateException(centers)
            if c=='C1*':
                if nt1.coordinates(type = 'C1*')!=[] and nt2.coordinates(type = 'C1*')!=[]:
                    R.append(nt1.coordinates(type = 'C1*')[0])
                    S.append(nt2.coordinates(type = 'C1*')[0])
                    l=len(nt1.coordinates(type = 'C1*'))
                    for q in range(0,l):
                        W.append(C1star_weights[i])
                else:
                    raise MissingPhosphateException(centers)
    #rotation_matrix, _, _, RMSD = besttransformation(R, S)
    # Superimpose R and S with weights? I need to make changes.
    rotation_matrix, new1, mean1, RMSD, sse = besttransformation_weighted(R, S, W)
    rotation_matrix = np.transpose(rotation_matrix)
    #The rotation_matrix that is outputted from besttransformation is the
    #transpose of the one you want.

    # loop through the bases and calculate angles between them
    orientationerror = 0
    if 'base' in centers:
        for i in xrange(len(ntlist1)):
            R1 = ntlist1[i].rotation_matrix
            R2 = ntlist2[i].rotation_matrix
            # calculate angle in radians
            angle = angle_of_rotation(np.dot(np.dot(rotation_matrix,R1), np.transpose(R2)))
            orientationerror += np.square(angle)
    discrepancy = np.sqrt(sse + angleweight*orientationerror) / len(ntlist1)
    return discrepancy
Esempio n. 5
0
def discrepancy(ntlist1,
                ntlist2,
                centers=['base'],
                base_weights=1.0,
                P_weights=1.0,
                C1star_weights=1.0,
                angleweight=1.0):
    """Compute the geometric discrepancy between two lists of components.

    :ntlist1: The first list of components.
    :ntlist2: The second list of components.
    :centers: A list of center names to use, such as
        ['base', 'P', 'C1*', 'ribose']
    :base_weights: The base weights to use. If only one weight is given
    it is used for all centers.  Otherwise, provide list of base weights with
    same length as the length of ntlist1
    :P_weigths: The phosphate weights to use. If only one weight is given
    it is used for all.  Otherwise, provide list of phosphate weights
    with same length as the length of ntlist1
    :C1star_weights: The C1* weights to use. If only one weight is given
    it is used for all.  Otherwise, provide list of C1* weights with
    same length as the length of ntlist1
    :angleweight: The weighting for angles to use.
    :returns: The geometric discrepancy.
    """

    assert len(ntlist1) == len(ntlist2)

    # TODO: Should we allow users to pass a tuple too?
    if not isinstance(centers, list):
        centers = [centers]

    if not isinstance(base_weights, list):
        base_weights = [base_weights] * len(ntlist1)

    if len(base_weights) != len(ntlist1):
        raise LengthofBaseWeightError(
            'Weight length does not match # of nucl.')

    if not isinstance(P_weights, list):
        P_weights = [P_weights] * len(ntlist1)

    if len(P_weights) != len(ntlist1):
        raise LengthofPWeightError('Weight length does not match # of nucl.')

    if not isinstance(C1star_weights, list):
        C1star_weights = [C1star_weights] * len(ntlist1)

    if len(C1star_weights) != len(ntlist1):
        raise LengthofC1starWeightError(
            'Weight length does not match # of nucl.')

    R = []
    S = []
    W = []

    for i in xrange(len(ntlist1)):
        nt1 = ntlist1[i]
        nt2 = ntlist2[i]
        for c in centers:
            if c == 'base':
                if c in nt1.centers:
                    R.append(nt1.centers[c])
                    S.append(nt2.centers[c])
                    W.append(base_weights[i])
                else:
                    if c == 'base':
                        raise MissingBaseException(centers)
            if c == 'P':
                if nt1.coordinates(type='P') != []:
                    R.append(nt1.coordinates(type='P')[0])
                    S.append(nt2.coordinates(type='P')[0])
                    l = len(nt1.coordinates(type='P'))
                    for z in range(0, l):
                        W.append(P_weights[i])
                else:
                    raise MissingPhosphateException(centers)
            if c == 'C1*':
                if nt1.coordinates(type='C1*') != [] and nt2.coordinates(
                        type='C1*') != []:
                    R.append(nt1.coordinates(type='C1*')[0])
                    S.append(nt2.coordinates(type='C1*')[0])
                    l = len(nt1.coordinates(type='C1*'))
                    for q in range(0, l):
                        W.append(C1star_weights[i])
                else:
                    raise MissingPhosphateException(centers)
    #rotation_matrix, _, _, RMSD = besttransformation(R, S)
    # Superimpose R and S with weights? I need to make changes.
    rotation_matrix, new1, mean1, RMSD, sse = besttransformation_weighted(
        R, S, W)
    rotation_matrix = np.transpose(rotation_matrix)
    #The rotation_matrix that is outputted from besttransformation is the
    #transpose of the one you want.

    # loop through the bases and calculate angles between them
    orientationerror = 0
    if 'base' in centers:
        for i in xrange(len(ntlist1)):
            R1 = ntlist1[i].rotation_matrix
            R2 = ntlist2[i].rotation_matrix
            # calculate angle in radians
            angle = angle_of_rotation(
                np.dot(np.dot(rotation_matrix, R1), np.transpose(R2)))
            orientationerror += np.square(angle)
    discrepancy = np.sqrt(sse + angleweight * orientationerror) / len(ntlist1)
    return discrepancy