Esempio n. 1
0
    def subtract_and_intersect_circle(self, center, radius):
        '''Will throw a VennRegionException if the circle to be subtracted is completely inside and not touching the given region.'''

        # Check whether the target circle intersects us
        center = np.asarray(center, float)
        d = np.linalg.norm(center - self.center)
        if d > (radius + self.radius - tol):
            return [self,
                    VennEmptyRegion()]  # The circle does not intersect us
        elif d < tol:
            if radius > self.radius - tol:
                # We are completely covered by that circle or we are the same circle
                return [VennEmptyRegion(), self]
            else:
                # That other circle is inside us and smaller than us - we can't deal with it
                raise VennRegionException(
                    "Invalid configuration of circular regions (holes are not supported)."
                )
        else:
            # We *must* intersect the other circle. If it is not the case, then it is inside us completely,
            # and we'll complain.
            intersections = circle_circle_intersection(self.center,
                                                       self.radius, center,
                                                       radius)

            if intersections is None:
                raise VennRegionException(
                    "Invalid configuration of circular regions (holes are not supported)."
                )
            elif np.all(abs(intersections[0] -
                            intersections[1]) < tol) and self.radius < radius:
                # There is a single intersection point (i.e. we are touching the circle),
                # the circle to be subtracted is not outside of us (this was checked before), and is larger than us.
                # This is a particular corner case that is not dealt with correctly by the general-purpose code below and must
                # be handled separately
                return [VennEmptyRegion(), self]
            else:
                # Otherwise the subtracted region is a 2-arc-gon
                # Before we need to convert the intersection points as angles wrt each circle.
                a_1 = vector_angle_in_degrees(intersections[0] - self.center)
                a_2 = vector_angle_in_degrees(intersections[1] - self.center)
                b_1 = vector_angle_in_degrees(intersections[0] - center)
                b_2 = vector_angle_in_degrees(intersections[1] - center)

                # We must take care of the situation where the intersection points happen to be the same
                if (abs(b_1 - b_2) < tol):
                    b_1 = b_2 - tol / 2
                if (abs(a_1 - a_2) < tol):
                    a_2 = a_1 + tol / 2

                # The subtraction is a 2-arc-gon [(AB, B-), (BA, A+)]
                s_arc1 = Arc(center, radius, b_1, b_2, False)
                s_arc2 = Arc(self.center, self.radius, a_2, a_1, True)
                subtraction = VennArcgonRegion([s_arc1, s_arc2])

                # .. and the intersection is a 2-arc-gon [(AB, A+), (BA, B+)]
                i_arc1 = Arc(self.center, self.radius, a_1, a_2, True)
                i_arc2 = Arc(center, radius, b_2, b_1, True)
                intersection = VennArcgonRegion([i_arc1, i_arc2])
                return [subtraction, intersection]
Esempio n. 2
0
 def intersect_circle(self, center, radius):
     '''
     Given a circle, finds the intersection point(s) of the arc with the circle.
     Returns a list of 2x1 numpy arrays. The list has length 0, 1 or 2, depending on how many intesection points there are.
     If the circle touches the arc, it is reported as two intersection points (which are equal).
     Points are ordered along the arc.
     Intersection with the same circle as the arc's own (which means infinitely many points usually) is reported as no intersection at all.
     
     >>> a = Arc((0, 0), 1, -60, 60, True)
     >>> a.intersect_circle((1, 0), 1)
     [array([ 0.5..., -0.866...]), array([ 0.5...,  0.866...])]
     >>> a.intersect_circle((0.9, 0), 1)
     []
     >>> a.intersect_circle((1,-0.1), 1)
     [array([ 0.586...,  0.810...])]
     >>> a.intersect_circle((1, 0.1), 1)
     [array([ 0.586..., -0.810...])]
     >>> a.intersect_circle((0, 0), 1)  # Infinitely many intersection points
     []
     >>> a.intersect_circle((2, 0), 1)  # Touching point, hence repeated twice
     [array([ 1.,  0.]), array([ 1.,  0.])]
     
     >>> a = Arc((0, 0), 1, 60, -60, False) # Same arc, different direction
     >>> a.intersect_circle((1, 0), 1)
     [array([ 0.5...,  0.866...]), array([ 0.5..., -0.866...])]
     
     >>> a = Arc((0, 0), 1, 120, -120, True)
     >>> a.intersect_circle((-1, 0), 1)
     [array([-0.5...,  0.866...]), array([-0.5..., -0.866...])]
     >>> a.intersect_circle((-0.9, 0), 1)
     []
     >>> a.intersect_circle((-1,-0.1), 1)
     [array([-0.586...,  0.810...])]
     >>> a.intersect_circle((-1, 0.1), 1)
     [array([-0.586..., -0.810...])]
     >>> a.intersect_circle((-2, 0), 1)
     [array([-1.,  0.]), array([-1.,  0.])]
     >>> a = Arc((0, 0), 1, -120, 120, False)
     >>> a.intersect_circle((-1, 0), 1)
     [array([-0.5..., -0.866...]), array([-0.5...,  0.866...])]
     '''
     intersections = circle_circle_intersection(self.center, self.radius, center, radius)
     if intersections is None:
         return []
     
     # Check whether the points lie on the arc and order them accordingly
     _len = self.length_degrees()
     isections = [[self.sign * (self.point_as_angle(pt) - self.from_angle) % 360.0, pt] for pt in intersections]
     
     # Try to find as many candidate intersections as possible (i.e. +- tol within arc limits)
     # Unless arc's length is 360, interpret intersections just before the arc's starting point as belonging to the starting point.
     if _len < 360.0 - tol:
         for isec in isections:
             if isec[0] > 360.0 - tol:
                 isec[0] = 0.0
     
     isections = [(a, pt[0], pt[1]) for (a, pt) in isections if a < _len + tol or a > 360 - tol]
     isections.sort()
     return [np.array([b, c]) for (a, b, c) in isections]
Esempio n. 3
0
 def intersect_circle(self, center, radius):
     '''
     Given a circle, finds the intersection point(s) of the arc with the circle.
     Returns a list of 2x1 numpy arrays. The list has length 0, 1 or 2, depending on how many intesection points there are.
     If the circle touches the arc, it is reported as two intersection points (which are equal).
     Points are ordered along the arc.
     Intersection with the same circle as the arc's own (which means infinitely many points usually) is reported as no intersection at all.
     
     >>> a = Arc((0, 0), 1, -60, 60, True)
     >>> a.intersect_circle((1, 0), 1)
     [array([ 0.5..., -0.866...]), array([ 0.5...,  0.866...])]
     >>> a.intersect_circle((0.9, 0), 1)
     []
     >>> a.intersect_circle((1,-0.1), 1)
     [array([ 0.586...,  0.810...])]
     >>> a.intersect_circle((1, 0.1), 1)
     [array([ 0.586..., -0.810...])]
     >>> a.intersect_circle((0, 0), 1)  # Infinitely many intersection points
     []
     >>> a.intersect_circle((2, 0), 1)  # Touching point, hence repeated twice
     [array([ 1.,  0.]), array([ 1.,  0.])]
     
     >>> a = Arc((0, 0), 1, 60, -60, False) # Same arc, different direction
     >>> a.intersect_circle((1, 0), 1)
     [array([ 0.5...,  0.866...]), array([ 0.5..., -0.866...])]
     
     >>> a = Arc((0, 0), 1, 120, -120, True)
     >>> a.intersect_circle((-1, 0), 1)
     [array([-0.5...,  0.866...]), array([-0.5..., -0.866...])]
     >>> a.intersect_circle((-0.9, 0), 1)
     []
     >>> a.intersect_circle((-1,-0.1), 1)
     [array([-0.586...,  0.810...])]
     >>> a.intersect_circle((-1, 0.1), 1)
     [array([-0.586..., -0.810...])]
     >>> a.intersect_circle((-2, 0), 1)
     [array([-1.,  0.]), array([-1.,  0.])]
     >>> a = Arc((0, 0), 1, -120, 120, False)
     >>> a.intersect_circle((-1, 0), 1)
     [array([-0.5..., -0.866...]), array([-0.5...,  0.866...])]
     '''
     intersections = circle_circle_intersection(self.center, self.radius, center, radius)
     if intersections is None:
         return []
     
     # Check whether the points lie on the arc and order them accordingly
     _len = self.length_degrees()
     isections = [[self.sign * (self.point_as_angle(pt) - self.from_angle) % 360.0, pt] for pt in intersections]
     
     # Try to find as many candidate intersections as possible (i.e. +- tol within arc limits)
     # Unless arc's length is 360, interpret intersections just before the arc's starting point as belonging to the starting point.
     if _len < 360.0 - tol:
         for isec in isections:
             if isec[0] > 360.0 - tol:
                 isec[0] = 0.0
     
     isections = [(a, pt[0], pt[1]) for (a, pt) in isections if a < _len + tol or a > 360 - tol]
     isections.sort()
     return [np.array([b, c]) for (a, b, c) in isections]
Esempio n. 4
0
    def subtract_and_intersect_circle(self, center, radius):
        '''Will throw a VennRegionException if the circle to be subtracted is completely inside and not touching the given region.'''
        
        # Check whether the target circle intersects us
        center = np.asarray(center, float)
        d = np.linalg.norm(center - self.center)
        if d > (radius + self.radius - tol):
            return [self, VennEmptyRegion()] # The circle does not intersect us
        elif d < tol:
            if radius > self.radius - tol:
                # We are completely covered by that circle or we are the same circle
                return [VennEmptyRegion(), self]
            else:
                # That other circle is inside us and smaller than us - we can't deal with it
                raise VennRegionException("Invalid configuration of circular regions (holes are not supported).")
        else:
            # We *must* intersect the other circle. If it is not the case, then it is inside us completely,
            # and we'll complain.            
            intersections = circle_circle_intersection(self.center, self.radius, center, radius)
            
            if intersections is None:
                raise VennRegionException("Invalid configuration of circular regions (holes are not supported).")
            elif np.all(abs(intersections[0] - intersections[1]) < tol) and self.radius < radius:
                # There is a single intersection point (i.e. we are touching the circle),
                # the circle to be subtracted is not outside of us (this was checked before), and is larger than us.
                # This is a particular corner case that is not dealt with correctly by the general-purpose code below and must
                # be handled separately
                return [VennEmptyRegion(), self]
            else:
                # Otherwise the subtracted region is a 2-arc-gon
                # Before we need to convert the intersection points as angles wrt each circle.
                a_1 = vector_angle_in_degrees(intersections[0] - self.center)
                a_2 = vector_angle_in_degrees(intersections[1] - self.center)
                b_1 = vector_angle_in_degrees(intersections[0] - center)
                b_2 = vector_angle_in_degrees(intersections[1] - center)

                # We must take care of the situation where the intersection points happen to be the same
                if (abs(b_1 - b_2) < tol):
                    b_1 = b_2 - tol/2
                if (abs(a_1 - a_2) < tol):
                    a_2 = a_1 + tol/2
                
                # The subtraction is a 2-arc-gon [(AB, B-), (BA, A+)]
                s_arc1 = Arc(center, radius, b_1, b_2, False)
                s_arc2 = Arc(self.center, self.radius, a_2, a_1, True)                
                subtraction = VennArcgonRegion([s_arc1, s_arc2])
                
                # .. and the intersection is a 2-arc-gon [(AB, A+), (BA, B+)]
                i_arc1 = Arc(self.center, self.radius, a_1, a_2, True)
                i_arc2 = Arc(center, radius, b_2, b_1, True)
                intersection = VennArcgonRegion([i_arc1, i_arc2])
                return [subtraction, intersection]
Esempio n. 5
0
def plot_venn(search_one, search_two, output_location):
    """
    search_one and search_two should both be dictionaries, mapping each scan to the peptide
    """
    spectra_one = set(search_one.keys())
    print('spectra one:')
    print(spectra_one)
    spectra_two = set(search_two.keys())
    common_spectra = spectra_one.intersection(spectra_two)
    print('common spectra')
    print(common_spectra)
    #the number of spectra shared between the two searches that match against different peptides
    discordant_spectra = 0
    #the number of spectra shared between the two searches that match against the same peptide 
    concordant_spectra = 0
    for spectra in common_spectra:
        if search_one[spectra] == search_two[spectra]:
            concordant_spectra += 1
        else:
            discordant_spectra += 1
    
    circles = venn2_circles([spectra_one, spectra_two])
    sorted_circles = sorted(circles, key=lambda x: x.center[0])
    bigger_circle = max(circles, key=lambda x: x.radius)
    bigger_radius = bigger_circle.radius
    left_point = np.array([sorted_circles[0].center[0] - sorted_circles[0].radius, sorted_circles[0].center[1]])
    right_point = np.array([sorted_circles[1].center[0] + sorted_circles[1].radius, sorted_circles[1].center[1]])
    left_intersection = max(_math.circle_line_intersection(sorted_circles[0].center, sorted_circles[0].radius, left_point, right_point), key=lambda x: x[0])
    right_intersection = min(_math.circle_line_intersection(sorted_circles[1].center, sorted_circles[1].radius, left_point, right_point), key=lambda x: x[0])
    line = ConnectionPatch(left_intersection, right_intersection, 'data', 'data')
    plt.gca().add_patch(line)
    print(sorted_circles[0].center)
    print(sorted_circles[1].center)
    circle_intersections = _math.circle_circle_intersection(sorted_circles[0].center, sorted_circles[0].radius, sorted_circles[1].center, sorted_circles[1].radius)
    upper_circle_intersection = max(circle_intersections, key=lambda x: x[1])
    #take the centroid
    upper_text_location = (left_intersection + right_intersection + upper_circle_intersection)/3.0
    #plt.rc('text', usetex=True)
    plt.text(upper_text_location[0], upper_text_location[1], str(concordant_spectra) + '\n' + r'$p_i = p_j$')
    lower_circle_intersection = min(circle_intersections, key=lambda x: x[1])
    lower_text_location = (left_intersection + right_intersection + lower_circle_intersection)/3.0
    plt.text(lower_text_location[0], lower_text_location[1], str(discordant_spectra) + '\n' + r'$p_i \neq p_j$')
    venn_diagram = venn2([spectra_one, spectra_two], ['Unfiltered', 'Filtered'])
    venn_diagram.get_label_by_id('11').set_text('')
    matplotlib.pyplot.savefig(output_location, format='png')