def is_junction_valid(cigar, min_overlap=4):
    '''
        Does the genomic cigar alignment represent a 'good' alignment.
        Used for checking junction->genome alignments

        1) the alignment must not start at a splice junction
        2) the alignment must not start or end with an overhang
        3) the alignment must overhang the splice junction by min_overlap (4)

        |     Exon1       |     Intron     |      Exon2       |
        |-----------------|oooooooooooooooo|------------------|
                                            XXXXXXXXXXXXXXXXXXXXXXXX (bad 1)
      XXXXXXXXXXXXX (bad 2)                           XXXXXXXXXXXXXXXX (bad 2)
                        XX-----------------XXXXXXXXXXXXXXXXX (bad 3)

    >>> is_junction_valid(cigar_fromstr('1000N40M'))
    (False, 'Starts at gap (1000N40M)')

    >>> is_junction_valid(cigar_fromstr('100M'))
    (False, "Doesn't cover junction")

    >>> is_junction_valid(cigar_fromstr('100M1000N3M'), 4)
    (False, "Too short overlap at 3' (100M1000N3M)")

    >>> is_junction_valid(cigar_fromstr('2M1000N100M'), 4)
    (False, "Too short overlap at 5' (2M1000N100M)")

    >>> is_junction_valid(cigar_fromstr('4M1000N100M'), 4)
    (True, '')

    >>> is_junction_valid(cigar_fromstr('100M1000N4M'), 4)
    (True, '')

    >>> is_junction_valid(cigar_fromstr('4M0N100M'), 4)
    (True, '')

    '''
    first = True
    pre_gap = True

    pre_gap_count = 0
    post_gap_count = 0

    has_gap = False

    for op, length in cigar:
        # mapping can't start at a gap
        if first and op == 3:
            return (False, 'Starts at gap (%s)' % cigar_tostr(cigar))
        first = False

        if op == 3:
            pre_gap = False
            post_gap_count = 0
            has_gap = True

        elif pre_gap:
            pre_gap_count += length
        else:
            post_gap_count += length

        # mapping must start with more than min_overlap base match

    if not has_gap:
        return (False, "Doesn't cover junction")
    elif pre_gap_count < min_overlap:
        return (False, "Too short overlap at 5' (%s)" % cigar_tostr(cigar))
    elif post_gap_count < min_overlap:
        return (False, "Too short overlap at 3' (%s)" % cigar_tostr(cigar))

    return True, ''
dataset/ETHPy150Open ngsutils/ngsutils/ngsutils/bam/__init__.py/is_junction_valid/original