/** * Finds the adaptor boundary around the read and returns the first base inside the adaptor that * is closest to the read boundary. If the read is in the positive strand, this is the first base * after the end of the fragment (Picard calls it 'insert'), if the read is in the negative * strand, this is the first base before the beginning of the fragment. * * <p>There are two cases we need to treat here: * * <p>1) Our read is in the reverse strand : * * <p><----------------------| * |---------------------> * * <p>in these cases, the adaptor boundary is at the mate start (minus one) * * <p>2) Our read is in the forward strand : * * <p>|----------------------> * <----------------------| * * <p>in these cases the adaptor boundary is at the start of the read plus the inferred insert * size (plus one) * * @param read the read being tested for the adaptor boundary * @return the reference coordinate for the adaptor boundary (effectively the first base IN the * adaptor, closest to the read. CANNOT_COMPUTE_ADAPTOR_BOUNDARY if the read is unmapped or * the mate is mapped to another contig. */ public static int getAdaptorBoundary(final GATKRead read) { if (!hasWellDefinedFragmentSize(read)) { return CANNOT_COMPUTE_ADAPTOR_BOUNDARY; } else if (read.isReverseStrand()) { return read.getMateStart() - 1; // case 1 (see header) } else { final int insertSize = Math.abs( read .getFragmentLength()); // the inferred insert size can be negative if the mate is // mapped before the read (so we take the absolute value) return read.getStart() + insertSize + 1; // case 2 (see header) } }
/** * Can the adaptor sequence of read be reliably removed from the read based on the alignment of * read and its mate? * * @param read the read to check * @return true if it can, false otherwise */ public static boolean hasWellDefinedFragmentSize(final GATKRead read) { if (read.getFragmentLength() == 0) // no adaptors in reads with mates in another chromosome or unmapped pairs { return false; } if (!read.isPaired()) // only reads that are paired can be adaptor trimmed { return false; } if (read.isUnmapped() || read.mateIsUnmapped()) // only reads when both reads are mapped can be trimmed { return false; } // if ( ! read.isProperlyPaired() ) // // note this flag isn't always set properly in BAMs, can will stop us from // eliminating some proper pairs // // reads that aren't part of a proper pair (i.e., have strange alignments) can't // be trimmed // return false; if (read.isReverseStrand() == read.mateIsReverseStrand()) // sanity check on isProperlyPaired to ensure that read1 and read2 aren't on the same strand { return false; } if (read.isReverseStrand()) { // we're on the negative strand, so our read runs right to left return read.getEnd() > read.getMateStart(); } else { // we're on the positive strand, so our mate should be to our right (his start + insert size // should be past our start) return read.getStart() <= read.getMateStart() + read.getFragmentLength(); } }