예제 #1
0
 def FireMergedLines(self, al1, al2):
     # type: (AlignmentPiece, AlignmentPiece) -> None
     sys.stdout.trace("Fire merged lines", al1, al2)
     new_line = al1.seg_to.contig
     line1 = al1.seg_from.contig
     line2 = al2.seg_from.contig
     sys.stdout.trace(list(self.allInter(line1.asSegment())))
     sys.stdout.trace(list(self.allInter(line2.asSegment())))
     self.addLine(new_line)
     self.auto_alignments[line1.id].setState(-1)
     self.auto_alignments[line2.id].setState(-1)
     auto1 = AutoAlignmentStorage(new_line).addAll([
         al1.composeTargetDifference(al.compose(al1))
         for al in self.auto_alignments[line1.id].content
     ])
     auto2 = AutoAlignmentStorage(new_line).addAll([
         al2.composeTargetDifference(al.compose(al2))
         for al in self.auto_alignments[line2.id].content
     ])
     auto3 = AutoAlignmentStorage(new_line).addAll([
         al2.composeTargetDifference(al.compose(al1))
         for al in self.getAlignmentsToFrom(line1, line2)
     ])
     self.auto_alignments[new_line.id].addAll(
         auto1.merge(auto3).merge(auto2).content)
     rc1 = RCAlignmentStorage(new_line).addAll([
         al1.rc.composeTargetDifference(al.compose(al1))
         for al in self.rc_alignments[line1.id]
     ])
     rc2 = RCAlignmentStorage(new_line).addAll([
         al2.rc.composeTargetDifference(al.compose(al2))
         for al in self.rc_alignments[line2.id]
     ])
     rc3 = RCAlignmentStorage(new_line).addAll([
         al2.rc.composeTargetDifference(al.compose(al1))
         for al in self.getAlignmentsToFrom(line1, line2.rc)
     ])
     self.rc_alignments[new_line.id].addAll(rc1.merge(rc3).merge(rc2))
     common = set(self.alignmentsToFrom[line1.id].keys()).intersection(
         set(self.alignmentsToFrom[line2.id].keys()))
     for storage in self.alignmentsToFrom[line1.id].values():
         if storage.line_from.id not in common and storage.line_from != line2 and storage.line_from != line2.rc:
             self.addTwoLineStorage(new_line, storage.line_from).addAll(
                 [al.compose(al1) for al in storage])
     for storage in self.alignmentsToFrom[line2.id].values():
         if storage.line_from.id not in common and storage.line_from != line1 and storage.line_from != line1.rc:
             self.addTwoLineStorage(new_line, storage.line_from).addAll(
                 [al.compose(al2) for al in storage])
     for c in common:
         storage1 = self.alignmentsToFrom[line1.id][c]
         storage2 = self.alignmentsToFrom[line2.id][c]
         als1 = AlignmentStorage().addAll(
             [al.compose(al1) for al in storage1])
         als2 = AlignmentStorage().addAll(
             [al.compose(al2) for al in storage2])
         self.addTwoLineStorage(new_line,
                                storage1.line_from).addAll(als1.merge(als2))
     self.removeLine(al1.seg_from.contig)
     self.removeLine(al2.seg_from.contig)
     sys.stdout.trace(list(self.allInter(new_line.asSegment())))
예제 #2
0
class TwoLineAlignmentStorage(LineListener):

    def __init__(self, line_from, line_to, rc = None, reverse = None):
        # type: (Contig, Contig, Optional[TwoLineAlignmentStorage], Optional[TwoLineAlignmentStorage]) -> None
        assert line_from.id != line_to.id and line_from.rc.id != line_to.id
        self.line_from = line_from
        self.line_to = line_to
        self.reverse = reverse
        if rc is None:
            self.content = AlignmentStorage()
            self.rc = TwoLineAlignmentStorage(line_from.rc, line_to.rc, self, None)
        else:
            self.rc = rc
            self.content = rc.content.rc # type: AlignmentStorage
        LineListener.__init__(self, self.rc)
        self.rc = self.rc # type: TwoLineAlignmentStorage
        if reverse is None and rc is None:
            reverse = TwoLineAlignmentStorage(line_to, line_from, None, self)
            self.reverse = reverse
            self.reverse.reverse = self
            self.rc.reverse = self.reverse.rc
            self.rc.reverse.reverse = self.rc

    def add(self, al):
        # type: (AlignmentPiece) -> None
        assert al.seg_from.contig == self.line_from
        assert al.seg_to.contig == self.line_to
        self.content.add(al)
        reverse = al.reverse()
        self.reverse.content.add(reverse)

    def addAll(self, als):
        for al in als:
            self.add(al)
        return self

    def __iter__(self):
        # type: () -> Generator[AlignmentPiece]
        return self.content.__iter__()

    def getAlignmentsTo(self, seg):
        # type: (Segment) -> Generator[AlignmentPiece]
        return self.content.getAlignmentsTo(seg)

    def allInter(self, seg):
        return self.content.allInter(seg)

    def normalizeReverse(self):
        self.reverse.content = self.content.reverse()
        self.reverse.rc.content = self.reverse.content.rc

    def fireBeforeExtendRight(self, line, new_seq, seq):
        # type: (Any, Contig, str) -> None
        self.content.fireBeforeExtendRight(line, new_seq, seq)
        self.normalizeReverse()

    def fireBeforeCutRight(self, line, new_seq, pos):
        # type: (Any, Contig, int) -> None
        self.content.fireBeforeCutRight(line, new_seq, pos)
        self.normalizeReverse()

    # alignments from new sequence to new sequence

    def fireBeforeCorrect(self, alignments):
        # type: (Correction) -> None
        self.content.fireBeforeCorrect(alignments)
        self.normalizeReverse()

    def fireAfterExtendRight(self, line, seq, relevant_als = None):
        # type: (Any, str, Optional[List[AlignmentPiece]]) -> None
        self.content.fireAfterExtendRight(line, seq)
        self.normalizeReverse()

    def fireAfterCutRight(self, line, pos):
        # type: (Any, int) -> None
        self.content.fireAfterCutRight(line, pos)
        self.normalizeReverse()

    def fireAfterCorrect(self, line, alignments):
        # type: (Any, Correction) -> None
        self.content.fireAfterCorrect(line, alignments)
        self.normalizeReverse()

    def addAndMergeRight(self, al):
        self.content.addAndMergeRight(al)
        self.normalizeReverse()

    def merge(self, other):
        # type: (TwoLineAlignmentStorage) -> TwoLineAlignmentStorage
        res = TwoLineAlignmentStorage(self.line_from, self.line_to)
        res.content.addAll(self.content.merge(other.content))
        res.normalizeReverse()

    def save(self, handler):
        # type: (TokenWriter) -> None
        self.content.save(handler)

    def load(self, handler, lines):
        # type: (TokenReader, Any) -> None
        self.content.load(handler, lines, lines)
        self.normalizeReverse()
예제 #3
0
class RCAlignmentStorage(LineListener):

    def __init__(self, line, rc = None):
        # type: (Contig, Optional[RCAlignmentStorage]) -> None
        self.line = line
        if rc is None:
            self.content = AlignmentStorage()
            rc = RCAlignmentStorage(line.rc, self)
            rc.content = self.content.rc
        LineListener.__init__(self, rc)
        self.rc = rc # type: AutoAlignmentStorage

    def __iter__(self):
        # type: () -> Generator[AlignmentPiece]
        return self.content.__iter__()

    def getAlignmentsTo(self, seg):
        # type: (Segment) -> Generator[AlignmentPiece]
        return self.content.getAlignmentsTo(seg)

    def allInter(self, seg):
        return self.content.allInter(seg)

    def add(self, alignment):
        self.content.add(alignment)
        self.content.add(alignment.reverse().rc)

    def addAndMergeRight(self, al):
        # type: (AlignmentPiece) -> None
        self.content.addAndMergeRight(al)
        self.content.addAndMergeLeft(al.reverse().rc)

    def addAll(self, als):
        for al in als:
            self.add(al)
        return self

    def fireBeforeExtendRight(self, line, new_seq, seq):
        # type: (Any, Contig, str) -> None
        self.content.fireBeforeExtendRight(line, new_seq, seq)
        self.reverse()
        self.content.fireBeforeExtendRight(line, new_seq, seq)

    def fireBeforeCutRight(self, line, new_seq, pos):
        # type: (Any, Contig, int) -> None
        self.content.fireBeforeCutRight(line, new_seq, pos)
        self.reverse()
        self.content.fireBeforeCutRight(line, new_seq, pos)
    # alignments from new sequence to new sequence

    def fireBeforeCorrect(self, alignments):
        # type: (Correction) -> None
        self.content.fireBeforeCorrect(alignments)
        self.reverse()
        self.content.fireBeforeCorrect(alignments)

    def fireAfterExtendRight(self, line, seq, relevant_als = None):
        # type: (Any, str, Optional[List[AlignmentPiece]]) -> None
        self.content.fireAfterExtendRight(line, seq)
        self.reverse()
        self.content.fireAfterExtendRight(line, seq)

    def fireAfterCutRight(self, line, pos):
        # type: (Any, int) -> None
        self.content.fireAfterCutRight(line, pos)
        self.reverse()
        self.content.fireAfterCutRight(line, pos)

    def fireAfterCorrect(self, line, alignments):
        # type: (Any, Correction) -> None
        self.content.fireAfterCorrect(line, alignments)
        self.reverse()
        self.content.fireAfterCorrect(line, alignments)
    # This is CRAAAZY!!! But correct.

    def reverse(self):
        self.rc.content = self.content.reverse()
        self.content = self.rc.content.rc

    def merge(self, other):
        # type: (RCAlignmentStorage) -> RCAlignmentStorage
        res = RCAlignmentStorage(self.line)
        res.content.addAll(self.content.merge(other.content))
        return res

    def save(self, handler):
        # type: (TokenWriter) -> None
        self.content.save(handler)

    def load(self, handler):
        # type: (TokenReader) -> None
        self.content.load(handler, self.line.rc, self.line)
예제 #4
0
class AutoAlignmentStorage(LineListener):

    def __init__(self, line, rc = None):
        # type: (Contig, Optional[AutoAlignmentStorage]) -> None
        self.line = line
        if rc is None:
            self.content = AlignmentStorage()
            rc = AutoAlignmentStorage(line.rc, self)
            rc.content = self.content.rc
            rc.state = -1
        LineListener.__init__(self, rc)
        self.rc = rc # type: AutoAlignmentStorage
        self.state = 1 # from precedes to

    def makeCanonical(self, al):
        if (self.state == 1) == (al.seg_from.left < al.seg_to.left):
            return al
        else:
            return al.reverse()

    def isCanonical(self, al):
        return (self.state == 1) == (al.seg_from.left < al.seg_to.left)

    def add(self, al):
        # type: (AlignmentPiece) -> None
        if al.isIdentical():
            return
        self.content.add(self.makeCanonical(al))

    def addAll(self, als):
        for al in als:
            self.add(al)
        return self

    def addAndMergeRight(self, al):
        if al.isIdentical():
            return
        if self.isCanonical(al):
            self.content.addAndMergeRight(al)
        else:
            self.content.addAndMergeRight(al.reverse())

    def __iter__(self):
        # type: () -> Generator[AlignmentPiece]
        for al in self.content:
            yield al
        for al in self.content:
            yield al.reverse()
        yield AlignmentPiece.Identical(self.line.asSegment())

    def getAlignmentsTo(self, seg):
        # type: (Segment) -> Generator[AlignmentPiece]
        for al in self:
            if al.seg_to.contains(seg):
                yield al

    def allInter(self, seg):
        for al in self:
            if al.seg_to.inter(seg):
                yield al

    def fireBeforeExtendRight(self, line, new_seq, seq):
        # type: (Any, Contig, str) -> None
        self.content.fireBeforeExtendRight(line, new_seq, seq)
        self.reverse()
        self.content.fireBeforeExtendRight(line, new_seq, seq)
    # alignments from new sequence to new sequence

    def fireBeforeCutRight(self, line, new_seq, pos):
        # type: (Any, Contig, int) -> None
        self.content.fireBeforeCutRight(line, new_seq, pos)
        self.reverse()
        self.content.fireBeforeCutRight(line, new_seq, pos)

    def fireBeforeCorrect(self, alignments):
        # type: (Correction) -> None
        self.content.fireBeforeCorrect(alignments)
        self.reverse()
        self.content.fireBeforeCorrect(alignments)

    def fireAfterExtendRight(self, line, seq, relevant_als = None):
        # type: (Any, str, Optional[List[AlignmentPiece]]) -> None
        self.content.fireAfterExtendRight(line, seq)
        self.reverse()
        self.content.fireAfterExtendRight(line, seq)

    def fireAfterCutRight(self, line, pos):
        # type: (Any, int) -> None
        self.content.fireAfterCutRight(line, pos)
        self.reverse()
        self.content.fireAfterCutRight(line, pos)

    def fireAfterCorrect(self, line, alignments):
        # type: (Any, Correction) -> None
        self.content.fireAfterCorrect(line, alignments)
        self.reverse()
        self.content.fireAfterCorrect(line, alignments)

    def reverse(self):
        self.state = -self.state
        self.rc.state = -self.rc.state
        self.content = self.content.reverse()
        self.rc.content = self.content.rc

    def merge(self, other):
        # type: (AutoAlignmentStorage) -> AutoAlignmentStorage
        if self.state != other.state:
            self.reverse()
        res = AutoAlignmentStorage(self.line)
        res.state = self.state
        res.content.addAll(self.content.merge(other.content))
        return res

    def save(self, handler):
        # type: (TokenWriter) -> None
        self.content.save(handler)

    def load(self, handler):
        # type: (TokenReader) -> None
        self.content.load(handler, self.line, self.line)

    def setState(self, state):
        assert state in [-1, 1]
        if self.state != state:
            self.reverse()