def detectPolyA(query_id, matches, options, queries_fasta=None):
    max_total = matches[0].mQueryLength
    best_start, best_end, best_pA, best_pT, best_tail = 0, 0, 0, 0, ""

    tail_matches = []
    new_matches = []
    for match in matches:
        missing_start = match.mQueryFrom
        missing_end = match.mQueryLength - match.mQueryTo
        if missing_start < missing_end:
            smaller = missing_start
            larger = missing_end
            start, end = match.mQueryTo, match.mQueryLength
        else:
            smaller = missing_end
            larger = missing_start
            start, end = 0, match.mQueryFrom

        # check if tail is at least polyA_min_aligned and at most polyA_max_unaligned
        # are missing from the other end.
        if not(smaller < options.polyA_max_unaligned and larger > options.polyA_min_unaligned):
            new_matches.append(match)
            continue

        tail = queries_fasta.getSequence(query_id)[start:end]

        counts = {"A": 0, "T": 0, "N": 0}
        for c in tail.upper():
            counts[c] = counts.get(c, 0) + 1
        total = end - start
        pA = 100.0 * (counts["A"] + counts["N"]) / total
        pT = 100.0 * (counts["T"] + counts["N"]) / total

        if options.loglevel >= 5:
            options.stdlog.write(
                "# polyA detection: %s:%i-%i pA=%5.2f pT=%5.2f tail=%s\n" % (query_id, start, end, pA, pT, tail))

        if max(pA, pT) < options.polyA_min_percent:
            new_matches.append(match)
            continue

        if total < max_total:
            max_total = total
            best_start, best_end, best_pA, best_pT, best_tail = start, end, pA, pT, tail

        if not(best_start == start or best_end == end):
            if options.loglevel >= 1:
                options.stdlog.write("# inconsistent polyA tails for %s: %i-%i, %i-%i - analysis skipped\n" %
                                     (query_id, best_start, best_end, start, end))
            return matches

        tail_matches.append(match)

    if tail_matches:
        for match in tail_matches:
            match.mQueryCoverage += 100.0 * \
                float(len(best_tail)) / match.mQueryLength
            assert match.mQueryCoverage <= 100.0, "%s: coverage %f > 100.0: incr=%f\n%s" % (
                query_id, match.mQueryCoverage, float(len(best_tail)) / match.mQueryLength, str(match))
            new_matches.append(match)

        options.outfile_polyA.write("%s\t%i\t%i\t%i\t%5.2f\t%5.2f\t%s\n" %
                                    (query_id,
                                     len(tail_matches),
                                     best_start, best_end,
                                     best_pA, best_pT, best_tail))

    assert len(new_matches) == len(matches)

    return new_matches
detect PolyA tails and adjust coverage.
dataset/ETHPy150Open CGATOxford/cgat/scripts/psl2map.py/detectPolyA