@Override boolean processReadPair(Read r1, Read r2) { assert (r2 == null); final byte[] quals = r1.quality, bases = r1.bases; final byte[] match = (r1.match == null ? null : !r1.shortmatch() ? r1.match : Read.toLongMatchString(r1.match)); if (match == null || quals == null || bases == null) { return false; } int subs = 0; int indels = 0; for (int qpos = 0, mpos = 0, last = quals.length - 1; mpos < match.length; mpos++) { final byte m = match[mpos]; final byte mprev = match[Tools.max(mpos - 1, 0)]; final byte mnext = match[Tools.min(mpos + 1, match.length - 1)]; final byte q1 = quals[qpos]; final byte b2 = bases[qpos]; int sub = 0, indel = 0; if (m == 'S') { sub = 1; } else if (m == 'I') { indel = 1; } else if (m == 'm') { if (mprev == 'D' || mnext == 'D') { indel = 1; } } else if (m == 'D') { // do nothing } else if (m == 'C') { // do nothing } else { throw new RuntimeException( "Bad symbol m='" + ((char) m) + "'\n" + new String(match) + "\n" + new String(bases) + "\n"); } subs += sub; indels += indel; if (q1 >= minq && q1 <= maxq) { if (sub > 0 || (indel > 0 && countIndels)) { return true; } } if (m != 'D') { qpos++; } } return keepPerfect && subs == 0 && indels == 0; }