@Override public void setCigar(final Cigar cigar) { super.setCigar(cigar); mBinaryDataStale = true; mCigarLengthValid = false; mCigarDecoded = true; }
private void testNullHeaderCigar(SAMRecord rec) { Cigar origCigar = rec.getCigar(); Assert.assertNotNull(origCigar); String originalCigarString = rec.getCigarString(); // set the cigar to null and then reset the cigar string in order to force getCigar to decode it rec.setCigar(null); Assert.assertNull(rec.getCigar()); rec.setCigarString(originalCigarString); rec.setValidationStringency(ValidationStringency.STRICT); rec.setHeader(null); Assert.assertTrue(rec.getValidationStringency() == ValidationStringency.STRICT); // force getCigar to decode the cigar string, validate that SAMRecord doesn't try to validate the cigar Cigar cig = rec.getCigar(); Assert.assertNotNull(cig); String cigString = TextCigarCodec.encode(cig); Assert.assertEquals(cigString, originalCigarString); }
@Override public void setCigar(final Cigar cigar) { super.setCigar(cigar); mBinaryDataStale = true; mCigarLengthValid = false; mCigarDecoded = true; }
@Override public void setCigar(final Cigar cigar) { super.setCigar(cigar); mBinaryDataStale = true; mCigarLengthValid = false; mCigarDecoded = true; }
@Override public void setCigar(final Cigar value) { if (!initializedFields.contains(LazyField.CIGAR_STRING)) { initializedFields.add(LazyField.CIGAR_STRING); } super.setCigar(value); }
@Override public void setCigar(final Cigar value) { if (!initializedFields.contains(LazyField.CIGAR_STRING)) { initializedFields.add(LazyField.CIGAR_STRING); } super.setCigar(value); }
private static void padCigar(SAMRecord record, int pre, int post) { List<CigarElement> cigar = Lists.newArrayList(record.getCigar().getCigarElements()); if (record.getReadNegativeStrandFlag()) { cigar.add(0, new CigarElement(post, CigarOperator.SOFT_CLIP)); cigar.add(new CigarElement(pre, CigarOperator.SOFT_CLIP)); } else { cigar.add(0, new CigarElement(pre, CigarOperator.SOFT_CLIP)); cigar.add(new CigarElement(post, CigarOperator.SOFT_CLIP)); } cigar = CigarUtil.clean(cigar, false); record.setCigar(new Cigar(cigar)); } private static void convertToSupplementaryAlignmentRecord(SAMRecord primary, SAMRecord supplementary) {
@Test(dataProvider = "deepCopyTestData") public void testDeepCopyCigar(SAMRecord sam) { sam.setCigar(sam.getCigar()); final SAMRecord deepCopy = sam.deepCopy(); Assert.assertTrue(sam.equals(deepCopy)); }
private SAMRecord cleanCigar(SAMRecord next) { Cigar cigar = next.getCigar(); if (cigar != null && cigar.getCigarElements().size() > 0) { Cigar newCigar = new Cigar(CigarUtil.clean(cigar.getCigarElements(), true)); if (!cigar.equals(newCigar)) { if (!MessageThrottler.Current.shouldSupress(log, "minimal CIGAR representation")) { log.warn(String.format("Cigar %s of read %s is not a minimal representation.", cigar, next.getReadName())); } next.setCigar(newCigar); } } return next; }
private static SAMRecord primaryAlignmentForSupplementary(SAMRecord r) { if (r.getSupplementaryAlignmentFlag()) { SAMRecord record = SAMRecordUtil.clone(r); List<ChimericAlignment> calist = ChimericAlignment.getChimericAlignments(r); if (calist.size() > 0) { ChimericAlignment ca = calist.get(0); record.setReferenceName(ca.rname); record.setAlignmentStart(ca.pos); record.setReadNegativeStrandFlag(ca.isNegativeStrand); record.setCigar(ca.cigar); record.setMappingQuality(ca.mapq); record.setReadBases(SAMRecord.NULL_SEQUENCE); record.setBaseQualities(SAMRecord.NULL_QUALS); return record; } } return r; } public static void main(String[] argv) {
public static void trim(SAMRecord read, int startCount, int endCount) { int readLength = read.getReadLength(); read.setReadBases(Arrays.copyOfRange(read.getReadBases(), startCount, readLength - endCount)); read.setBaseQualities(Arrays.copyOfRange(read.getBaseQualities(), startCount, readLength - endCount)); if (read.getCigar() != null && read.getCigar().getCigarElements().size() > 0) { read.setAlignmentStart(read.getAlignmentStart() + CigarUtil.offsetOf(read.getCigar(), startCount)); read.setCigar(CigarUtil.trimReadBases(read.getCigar(), startCount, endCount)); assert (read.getReadLength() == read.getCigar().getReadLength()); } }
/** * Adjusts the start/end alignment bounds of the given alignment. Expanded alignments are converted * @param r * @param expandStartBy * @param expandEndBy * @return record passed in */ public static SAMRecord adjustAlignmentBounds(SAMRecord r, int expandStartBy, int expandEndBy) { Cigar newCigar = softClipToAligned(r.getCigar(), expandStartBy, 0); r.setAlignmentStart(r.getAlignmentStart() + r.getCigar().getReferenceLength() - newCigar.getReferenceLength()); newCigar = softClipToAligned(newCigar, 0, expandEndBy); r.setCigar(newCigar); return r; } private static Cigar softClipToAligned(Cigar cigar, int startunclip, int endunclip) {
@Test(dataProvider = "longCigarsData") public void testSetCigarRemovesCgTagWhenStillLong(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); final List<CigarOperator> cigarOperatorsForTest = getCigarOperatorsForTest(numOps); cigarOperatorsForTest.add(CigarOperator.H); final Cigar cigar2 = Cigar.fromCigarOperators(cigarOperatorsForTest); frag1.setCigar(cigar2); testHelper(builder, SAMFileHeader.SortOrder.coordinate, true); }
@Override public String getRemoteEvidenceID() { SAMRecord remote = this.getSAMRecord().deepCopy(); remote.setReferenceName(remoteAlignment.rname); remote.setAlignmentStart(remoteAlignment.pos); remote.setReadUnmappedFlag(false); remote.setReadNegativeStrandFlag(remoteAlignment.isNegativeStrand); remote.setCigar(remoteAlignment.cigar); remote.setAttribute(SAMTag.SA.name(), new ChimericAlignment(this.getSAMRecord()).toString()); SplitReadEvidence remoteEvidence = SplitReadEvidence.create(source, remote).get(0); return source.getContext().getEvidenceIDGenerator().getEvidenceID(remoteEvidence); } @Override
protected void updateCigarForTrimmedOrClippedBases(final SAMRecord rec, final SAMRecord alignment) { // If the read was trimmed or not all the bases were sent for alignment, clip it final int alignmentReadLength = alignment.getReadLength(); final int originalReadLength = rec.getReadLength(); final int trimmed = (!rec.getReadPairedFlag()) || rec.getFirstOfPairFlag() ? this.read1BasesTrimmed != null ? this.read1BasesTrimmed : 0 : this.read2BasesTrimmed != null ? this.read2BasesTrimmed : 0; final int notWritten = originalReadLength - (alignmentReadLength + trimmed); // Update cigar if the mate maps off the reference createNewCigarsIfMapsOffEndOfReference(rec); rec.setCigar(CigarUtil.addSoftClippedBasesToEndsOfCigar( rec.getCigar(), rec.getReadNegativeStrandFlag(), notWritten, trimmed)); // If the adapter sequence is marked and clipAdapter is true, clip it if (this.clipAdapters && rec.getAttribute(ReservedTagConstants.XT) != null) { CigarUtil.softClip3PrimeEndOfRead(rec, rec.getIntegerAttribute(ReservedTagConstants.XT)); removeNmMdAndUqTags(rec); // these tags are now invalid! } }
protected void updateCigarForTrimmedOrClippedBases(final SAMRecord rec, final SAMRecord alignment) { // If the read was trimmed or not all the bases were sent for alignment, clip it final int alignmentReadLength = alignment.getReadLength(); final int originalReadLength = rec.getReadLength(); final int trimmed = (!rec.getReadPairedFlag()) || rec.getFirstOfPairFlag() ? this.read1BasesTrimmed != null ? this.read1BasesTrimmed : 0 : this.read2BasesTrimmed != null ? this.read2BasesTrimmed : 0; final int notWritten = originalReadLength - (alignmentReadLength + trimmed); // Update cigar if the mate maps off the reference createNewCigarsIfMapsOffEndOfReference(rec); rec.setCigar(CigarUtil.addSoftClippedBasesToEndsOfCigar( rec.getCigar(), rec.getReadNegativeStrandFlag(), notWritten, trimmed)); // If the adapter sequence is marked and clipAdapter is true, clip it if (this.clipAdapters && rec.getAttribute(ReservedTagConstants.XT) != null) { CigarUtil.softClip3PrimeEndOfRead(rec, rec.getIntegerAttribute(ReservedTagConstants.XT)); removeNmMdAndUqTags(rec); // these tags are now invalid! } }
@Test public void testClippingOfRecordWithInsertion() { /** * Tests that if we need to clip a read with an insertion that overlaps */ // setup the record final SAMFileHeader header = new SAMFileHeader(); header.addSequence(new SAMSequenceRecord("1", 1000)); final SAMRecord record = new SAMRecord(header); record.setReadPairedFlag(true); record.setCigar(TextCigarCodec.decode("5M1I5M")); record.setReferenceIndex(0); record.setAlignmentStart(1); record.setMateReferenceIndex(0); record.setMateAlignmentStart(5); // should overlap the 1M1I5M record.setReadBases("AAAAAAAAAAA".getBytes()); final int numToClip = SAMUtils.getNumOverlappingAlignedBasesToClip(record); Assert.assertEquals(numToClip, 7); SAMUtils.clipOverlappingAlignedBases(record, numToClip, false); // Side-effects are OK Assert.assertTrue(record.getCigar().equals(TextCigarCodec.decode("4M7S"))); }
@Test public void testSimpleClippingOfRecord() { // setup the record final SAMFileHeader header = new SAMFileHeader(); header.addSequence(new SAMSequenceRecord("1", 1000)); final SAMRecord record = new SAMRecord(header); record.setReadPairedFlag(true); record.setCigar(TextCigarCodec.decode("10M")); record.setReferenceIndex(0); record.setAlignmentStart(1); record.setMateReferenceIndex(0); record.setMateAlignmentStart(6); // should overlap 5M record.setReadBases("AAAAAAAAAA".getBytes()); final int numToClip = SAMUtils.getNumOverlappingAlignedBasesToClip(record); Assert.assertEquals(numToClip, 5); SAMUtils.clipOverlappingAlignedBases(record, numToClip, false); // Side-effects are OK Assert.assertTrue(record.getCigar().equals(TextCigarCodec.decode("5M5S"))); }
SAMRecord secondSAMRecord(SAMFileHeader header) { SAMRecord r = new SAMRecord(header); r.setReadName(evidenceRecord.getReadName()); r.setReferenceName(evidenceRecord.Chromosome); r.setAlignmentStart(Integer.valueOf(evidenceRecord.MateOffsetInReference) + 1); r.setMappingQuality(Integer.valueOf(evidenceRecord.ScoreAllele0)); r.setReadPairedFlag(true); r.setReadUnmappedFlag(false); r.setReadNegativeStrandFlag(negative); r.setFirstOfPairFlag(evidenceRecord.side == 1); r.setSecondOfPairFlag(!r.getFirstOfPairFlag()); r.setCigar(new Cigar(Utils.toCigarOperatorList(secondHalf.samCigarElements))); r.setReadBases(Utils.toByteArray(secondHalf.readBasesBuf)); r.setBaseQualities(Utils.toByteArray(secondHalf.readScoresBuf)); r.setAttribute("GC", Utils.toString(secondHalf.gcList)); r.setAttribute("GS", Utils.toString(secondHalf.gsBuf)); r.setAttribute("GQ", SAMUtils.phredToFastq(Utils.toByteArray(secondHalf.gqBuf))); return r; }
/** * Build a SAM record featuring the absolute minimum required dataset. * TODO: Blatantly copied from LocusViewTemplate. Refactor these into a set of tools. * @param contig Contig to populate. * @param alignmentStart start of alignment * @param alignmentEnd end of alignment * @return New SAM Record */ protected SAMRecord buildSAMRecord( String contig, int alignmentStart, int alignmentEnd ) { SAMFileHeader header = new SAMFileHeader(); header.setSequenceDictionary(sequenceFile.getSequenceDictionary()); SAMRecord record = new SAMRecord(header); record.setReferenceIndex(sequenceFile.getSequenceDictionary().getSequenceIndex(contig)); record.setAlignmentStart(alignmentStart); Cigar cigar = new Cigar(); cigar.add(new CigarElement(alignmentEnd-alignmentStart+1, CigarOperator.M)); record.setCigar(cigar); return record; }