/** * Calculates the reference coordinate for the end of the read taking into account soft clips but * not hard clips. * * <p>Note: getUnclippedEnd() adds soft and hard clips, this function only adds soft clips. * * @param read the read * @param cigar the read's cigar * <p>Note: this overload of the function takes the cigar as input for speed because getCigar * is an expensive operation. Most callers should use the overload that does not take the * cigar. * @return the unclipped end of the read taking soft clips (but not hard clips) into account */ public static int getSoftEnd(final GATKRead read, final Cigar cigar) { Utils.nonNull(read, "read"); Utils.nonNull(cigar, "cigar"); boolean foundAlignedBase = false; int softEnd = read.getEnd(); final List<CigarElement> cigs = cigar.getCigarElements(); for (int i = cigs.size() - 1; i >= 0; --i) { final CigarElement cig = cigs.get(i); final CigarOperator op = cig.getOperator(); if (op == CigarOperator .SOFT_CLIP) { // assumes the soft clip that we found is at the end of the aligned read softEnd += cig.getLength(); } else if (op != CigarOperator.HARD_CLIP) { foundAlignedBase = true; break; } } if (!foundAlignedBase) { // for example 64H14S, the soft end is actually the same as the // alignment end softEnd = read.getEnd(); } return softEnd; }
/** * 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(); } }
/** * Is a base inside a read? * * @param read the read to evaluate * @param referenceCoordinate the reference coordinate of the base to test * @return true if it is inside the read, false otherwise. */ public static boolean isInsideRead(final GATKRead read, final int referenceCoordinate) { return referenceCoordinate >= read.getStart() && referenceCoordinate <= read.getEnd(); }