def merge(self, other): # type: (AlignmentStorage) -> AlignmentStorage left_items = [(al, -1) for al in self] right_items = [(al, 1) for al in other] new_items = sorted(left_items + right_items, key = lambda (al, side): (al.seg_to.contig.id, al.seg_from.contig.id, al.seg_from.left)) new_storge = AlignmentStorage() for (c_to, c_from), it in itertools.groupby(new_items, lambda al: (al[0].seg_to.contig, al[0].seg_from.contig)): al_sides = list(it) als_left = [al for al, side in al_sides if side == -1] # type: List[AlignmentPiece] als_left = sorted(als_left, key = lambda al: al.seg_from.right) als_right = [al for al, side in al_sides if side == 1] # type: List[AlignmentPiece] als_right = sorted(als_right, key = lambda al: al.seg_from.left) merged = [] for al in als_left: for j in range(len(als_right)): # type: int if als_right[j] is None: continue if als_right[j].seg_from.left >= al.seg_from.right: break if als_right[j] is not None and al.canMergeTo(als_right[j]): tmp = AlignmentPiece.MergeOverlappingAlignments([al, als_right[j]]) if tmp is not None: al = tmp als_right[j] = None break merged.append(al) new_storge.addAll(merged) new_storge.addAll([al for al in als_right if al is not None]) return new_storge
def addAndMergeLeft(self, al): # type: (AlignmentPiece) -> None if self.isCanonical(): for i, al1 in enumerate(self.items): # type: int, AlignmentPiece if al.seg_from.inter(al1.seg_from) and al.seg_to.inter(al1.seg_to) and al1.seg_from.left >= al.seg_from.left: tmp = AlignmentPiece.MergeOverlappingAlignments([al, al1]) if tmp is not None: self.items[i] = tmp return self.add(al) else: self.rc.addAndMergeRight(al.rc)