public static Cigar invertCigar (Cigar cigar) { Stack<CigarElement> cigarStack = new Stack<CigarElement>(); for (CigarElement cigarElement : cigar.getCigarElements()) cigarStack.push(cigarElement); Cigar invertedCigar = new Cigar(); while (!cigarStack.isEmpty()) invertedCigar.add(cigarStack.pop()); return invertedCigar; }
static CigarOperator getCigarOperator(Cigar cigar, int ci) { CigarOperator operator = cigar.getCigarElement(ci).getOperator(); // Treat insertions at the edge as soft-clipping if ((ci == 0 || ci == cigar.numCigarElements() - 1) && operator == CigarOperator.I) { operator = CigarOperator.S; } return operator; }
/** * Trim cigar down to one that starts at start reference on the left and extends to end on the reference * * @param cigar a non-null Cigar to trim down * @param start Where should we start keeping bases on the reference? The first position is 0 * @param end Where should we stop keeping bases on the reference? The maximum value is cigar.getReferenceLength() * @return a new Cigar with reference length == start - end + 1 */ public static Cigar trimCigarByReference(final Cigar cigar, final int start, final int end) { if ( start < 0 ) throw new IllegalArgumentException("Start must be >= 0 but got " + start); if ( end < start ) throw new IllegalArgumentException("End " + end + " is < start start " + start); if ( end > cigar.getReferenceLength() ) throw new IllegalArgumentException("End is beyond the cigar's reference length " + end + " for cigar " + cigar ); final Cigar result = trimCigar(cigar, start, end, true); if ( result.getReferenceLength() != end - start + 1) throw new IllegalStateException("trimCigarByReference failure: start " + start + " end " + end + " for " + cigar + " resulted in cigar with wrong size " + result); return result; }
/** returns the last cigar element */ public CigarElement getLastCigarElement() { return isEmpty() ? null : this.cigarElements.get(this.numCigarElements() - 1 ); }
/** returns true if the cigar string ends With a clipping operator */ public boolean isRightClipped() { return !isEmpty() && isClippingOperator(getLastCigarElement().getOperator()); }
/** * Convert CIGAR from disk representation to object. * @param binaryCigar Array of unsigned ints, one for each CIGAR element. */ static Cigar decode(final int[] binaryCigar) { final Cigar ret = new Cigar(); for (final int cigarette : binaryCigar) { ret.add(binaryCigarToCigarElement(cigarette)); } return ret; }
protected static Cigar reclipCigar(Cigar cigar, SAMRecord read) { ArrayList<CigarElement> elements = new ArrayList<CigarElement>(); int i = 0; int n = read.getCigar().numCigarElements(); while ( i < n && isClipOperator(read.getCigar().getCigarElement(i).getOperator()) ) elements.add(read.getCigar().getCigarElement(i++)); elements.addAll(cigar.getCigarElements()); i++; while ( i < n && !isClipOperator(read.getCigar().getCigarElement(i).getOperator()) ) i++; while ( i < n && isClipOperator(read.getCigar().getCigarElement(i).getOperator()) ) elements.add(read.getCigar().getCigarElement(i++)); return new Cigar(elements); }
protected static Cigar unclipCigar(Cigar cigar) { ArrayList<CigarElement> elements = new ArrayList<CigarElement>(cigar.numCigarElements()); for ( CigarElement ce : cigar.getCigarElements() ) { if ( !isClipOperator(ce.getOperator()) ) elements.add(ce); } return new Cigar(elements); }
/** shortcut to <code>getCigarElements().iterator()</code> */ @Override public Iterator<CigarElement> iterator() { return this.getCigarElements().iterator(); }
/** * Convert from Cigar class representation to String. * @param cigar in Cigar class format * @return CIGAR in String form ala SAM text file. "*" means empty CIGAR. */ public String encode(final Cigar cigar) { if (cigar.isEmpty()) { return SAMRecord.NO_ALIGNMENT_CIGAR; } final StringBuilder ret = new StringBuilder(); for (final CigarElement cigarElement : cigar.getCigarElements()) { ret.append(cigarElement.getLength()); ret.append(cigarElement.getOperator()); } return ret.toString(); }
private boolean isLastNonSoftClippedElem(int idx, Cigar cigar) { int numElems = cigar.getCigarElements().size(); // Last element, not soft clipped. if ((idx == numElems-1) && (cigar.getCigarElement(idx).getOperator() != CigarOperator.S)) { return true; } // Second to last element, with last element soft clipped. if ((idx == numElems-2) && (cigar.getCigarElement(numElems-1).getOperator() == CigarOperator.S)) { return true; } return false; }
/** * Does cigar start or end with a deletion operation? * * @param cigar a non-null cigar to test * @return true if the first or last operator of cigar is a D */ public static boolean startsOrEndsWithInsertionOrDeletion(final Cigar cigar) { if ( cigar == null ) throw new IllegalArgumentException("Cigar cannot be null"); if ( cigar.isEmpty() ) return false; final CigarOperator first = cigar.getCigarElement(0).getOperator(); final CigarOperator last = cigar.getCigarElement(cigar.numCigarElements()-1).getOperator(); return first == CigarOperator.D || first == CigarOperator.I || last == CigarOperator.D || last == CigarOperator.I; }
public LIBSTest(final String cigarString) { final Cigar cigar = TextCigarCodec.decode(cigarString); this.cigarString = cigarString; this.elements = cigar.getCigarElements(); this.readLength = cigar.getReadLength(); }
@Test(dataProvider = "AddCigarElementsData", enabled = !DEBUG) public void testAddCigarElements(final String cigarString, final int pos, final int start, final int end, final String expectedCigarString) { final Cigar cigar = TextCigarCodec.decode(cigarString); final CigarElement elt = cigar.getCigarElement(0); final Cigar expectedCigar = TextCigarCodec.decode(expectedCigarString); final List<CigarElement> elts = new LinkedList<CigarElement>(); final int actualEndPos = AlignmentUtils.addCigarElements(elts, pos, start, end, elt); Assert.assertEquals(actualEndPos, pos + elt.getLength()); Assert.assertEquals(AlignmentUtils.consolidateCigar(new Cigar(elts)), expectedCigar); }
@Test(dataProvider = "longCigarsData") public void testSetCigarRemovesCgTagWhenNoLongerLong(final int numOps) throws Exception { final SAMRecordSetBuilder builder = new SAMRecordSetBuilder(true, SAMFileHeader.SortOrder.coordinate); final Cigar cigar = Cigar.fromCigarOperators(getCigarOperatorsForTest(numOps)); final SAMRecord frag1 = builder.addFrag("frag1", 0, 1, false, false, cigar.toString(), null, 30); frag1.setCigarString(String.format("%dM", cigar.getReadLength())); testHelper(builder, SAMFileHeader.SortOrder.coordinate, true); }
private boolean isFirstNonSoftClippedElem(int idx, Cigar cigar) { // First element, not soft clipped if ((idx == 0) && (cigar.getCigarElement(0).getOperator() != CigarOperator.S)) { return true; } // Second element, with first element soft clipped if ((idx == 1) && (cigar.getCigarElement(0).getOperator() == CigarOperator.S)) { return true; } return false; }
/** * @param rec the SAM record * @return number of cigar elements (number + operator) in the mate cigar string. */ public static int getMateCigarLength(final SAMRecord rec) { final Cigar mateCigar = getMateCigar(rec); return (mateCigar != null) ? mateCigar.numCigarElements() : 0; }
@Test(enabled = !DEBUG, dataProvider = "AlignmentByteArrayOffsetDataProvider") public void testAlignmentByteArrayOffsetData(final Cigar cigar, final int offset, final int expectedResult, final boolean isDeletion, final int lengthOfSoftClip) { final int actual = AlignmentUtils.calcAlignmentByteArrayOffset(cigar, isDeletion ? -1 : offset, isDeletion, 20, 20 + offset - lengthOfSoftClip); Assert.assertEquals(actual, expectedResult, "Wrong alignment offset detected for cigar " + cigar.toString()); }
public static GATKSAMRecord createRandomRead(int length) { List<CigarElement> cigarElements = new LinkedList<>(); cigarElements.add(new CigarElement(length, CigarOperator.M)); Cigar cigar = new Cigar(cigarElements); return ArtificialSAMUtils.createArtificialRead(cigar); }
/** * @return The number of read bases that the read covers. */ public int getReadLength() { return getReadLength(cigarElements); }