def make_complement(self): """Complements the link inplace. The tags are left unchanged. Note: The path references are not complemented by this method; therefore the method shall be used before the link is embedded in a graph. Note: This method shall be overridden if custom tags are defined, which have a complementation operation which determines their value in the complement link. Returns: gfapy.line.edge.Link: self """ tmp = self.from_segment self.from_segment = self.to_segment self.to_segment = tmp tmp = self.from_orient self.from_orient = gfapy.invert(self.to_orient) self.to_orient = gfapy.invert(tmp) self.overlap = self.overlap.complement() return self
def is_cut_link(self, link): """Does the removal of a dovetail overlap split a connected component? Note: only dovetail overlaps are considered as connections Parameters: link (Line) : an edge instance, which represents a dovetail overlap Returns: bool """ if link.is_circular(): return False if not link.get("from").dovetails_of_end(\ gfapy.invert(link.from_end.end_type)): return True if not link.to.dovetails_of_end(gfapy.invert(link.to_end.end_type)): return True c = {} for et in ["from", "to"]: c[et] = set() visited = set() segend = link.get("from") if et == "from" else link.to visited.add(segend.name) visited.add(link.other_end(segend).name) self.__traverse_component(segend, c[et], visited) return c["from"] != c["to"]
def __link_merged(self, merged_name, segment_end, is_reversed): for l in self.segment(segment_end.segment).dovetails_of_end( segment_end.end_type): l2 = l.clone() if l2.to_segment == segment_end.segment: l2.to_segment = merged_name if is_reversed: l2.to_orient = gfapy.invert(l2.to_orient) else: l2.from_segment = merged_name if is_reversed: l2.from_orient = gfapy.invert(l2.from_orient) l.disconnect() self.add_line(l2)
def invert(self): """Invert the orientation of the OrientedLine instance. Note: the inverted() method returns an OrientedLine with inverted orientation; the invert() method inverts the orientation in place (and returns None) """ self.orient = gfapy.invert(self.orient)
def inverted(self): """An oriented line with the same line element, but inverted orientation. Note: the inverted() method returns an OrientedLine with inverted orientation; the invert() method inverts the orientation in place (and returns None) """ return OrientedLine(self.line, gfapy.invert(self.orient))
def link_merged(gfa, merged_name, segment_end, is_reversed): #print("") #print("Linking to", segment_end, " ", is_reversed) #print("Details", segment_end.segment, " ", segment_end.end_type) for l in gfa.segment(segment_end.segment).dovetails_of_end( segment_end.end_type).copy(): #print("Linking ", l) l2 = l.clone() if l2.to_segment == segment_end.segment: l2.to_segment = merged_name if is_reversed: l2.to_orient = gfapy.invert(l2.to_orient) else: l2.from_segment = merged_name if is_reversed: l2.from_orient = gfapy.invert(l2.from_orient) l.disconnect() gfa.add_line(l2)
def _extend_linear_path_to_junctions(self, segpath): segfirst = self.segment(segpath[0].segment) segfirst_d = segfirst.dovetails_of_end(gfapy.invert(segpath[0].end_type)) redundant_first = (len(segfirst_d) > 0) if len(segfirst_d) == 1: segpath.insert(0, segfirst_d[0].other_end(segpath[0].inverted())) segpath.insert(0, redundant_first) seglast = self.segment(segpath[-1].segment) seglast_d = seglast.dovetails_of_end(segpath[-1].end_type) redundant_last = (len(seglast_d) > 0) if len(seglast_d) == 1: segpath.append(seglast_d[0].other_end(segpath[-1].inverted())) segpath.append(redundant_last)
def complement(self): """Creates the equivalent link with from and to inverted. The CIGAR operations (order and type) are inverted as well. Tags are left unchanged. Note: The path references are not copied to the complement link. Note: This method shall be overridden if custom tags are defined, which have a complementation operation which determines their value in the equivalent complement link. Returns: gfapy.line.edge.Link: The inverted link. """ l = self.clone() l.from_segment = self.to l.from_orient = gfapy.invert(self.to_orient) l.to_segment = self.from_segment l.to_orient = gfapy.invert(self.from_orient) l.overlap = self.overlap.complement() return l
def __update_reference_in_list(self, lst, oldref, newref): found = False for idx, elem in enumerate(lst): if isinstance(elem, gfapy.Line): if elem is oldref: lst[idx] = newref found = True elif isinstance(elem, gfapy.OrientedLine): if elem.line is oldref: if hasattr(oldref, "is_complement") and \ oldref.is_complement(newref): elem.orient = gfapy.invert(elem.orient) elem.line = newref found = True if newref is None and found: lst[:] = [e for e in lst if e is not None]
def __traverse_linear_path(self, segment_end, exclude): lst = gfapy.SegmentEndsPath() current = gfapy.SegmentEnd(segment_end) current.segment = self.segment(current.segment) while True: after = current.segment.dovetails_of_end(current.end_type) before = current.segment.dovetails_of_end( gfapy.invert(current.end_type)) if (len(before) == 1 and len(after) == 1) or not lst: lst.append(gfapy.SegmentEnd(current.name, current.end_type)) exclude.add(current.name) current = after[0].other_end(current).inverted() if current.name in exclude: break elif len(before) == 1: lst.append(gfapy.SegmentEnd(current.name, current.end_type)) exclude.add(current.name) break else: break if segment_end.end_type == "L": return list(reversed(lst)) else: return lst
def test_invert_segment_ends(self): self.assertEqual("L", gfapy.invert("R")) self.assertEqual("R", gfapy.invert("L"))
def test_invert_orientations(self): self.assertEqual("+", gfapy.invert("-")) self.assertEqual("-", gfapy.invert("+"))
def inverted(self): return SegmentEnd(self.__segment, gfapy.invert(self.end_type))