/* * The MIT License * * Copyright (c) 2009 The Broad Institute * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package htsjdk.samtools; import htsjdk.samtools.util.CloseableIterator; import org.testng.Assert; import org.testng.annotations.Test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; public class SAMTextReaderTest { // Simple input, spot check that parsed correctly, and make sure nothing blows up. @Test public void testBasic() throws Exception { final String seq1 = "AGCTTAGCTAGCTACCTATATCTTGGTCTTGGCCG"; final String seq2 = "ACCTATATCTTGGCCTTGGCCGATGCGGCCTTGCA"; final String qual1 = "<<<<<<<<<<<<<<<<<<<<<:<9/,&,22;;<<<"; final String qual2 = "<<<<<;<<<<7;:<<<6;<<<<<<<<<<<<7<<<<"; final String fileFormatVersion = "1.0"; final String sequence = "chr20"; final int sequenceLength = 62435964; final String charTag = "XC"; final char charValue = 'q'; final String intTag = "XI"; final int intValue = 12345; final String floatTag = "XF"; final float floatValue = 1.2345f; final String stringTag = "XS"; final String stringValue = "Hi,Mom!"; final String samExample = "@HD\tVN:" + fileFormatVersion + "\t" + charTag + ":" + charValue + "\n" + "@SQ\tSN:" + sequence + "\tAS:HG18\tLN:" + sequenceLength + "\t" + intTag + ":" + intValue + "\n" + "@RG\tID:L1\tPU:SC_1_10\tLB:SC_1\tSM:NA12891" + "\t" + floatTag + ":" + floatValue + "\n" + "@RG\tID:L2\tPU:SC_2_12\tLB:SC_2\tSM:NA12891\n" + "@PG\tID:0\tVN:1.0\tCL:yo baby\t" + stringTag + ":" + stringValue + "\n" + "@PG\tID:2\tVN:1.1\tCL:whassup? ? ? ?\n" + "read_28833_29006_6945\t99\tchr20\t28833\t20\t10M1D25M\t=\t28993\t195\t" + seq1.toLowerCase() + "\t" + qual1 + "\t" + "MF:i:130\tNm:i:1\tH0:i:0\tH1:i:0\tRG:Z:L1\n" + "read_28701_28881_323b\t147\tchr20\t28834\t30\t35M\t=\t28701\t-168\t" + seq2 + "\t" + qual2 + "\t" + "MF:i:18\tNm:i:0\tH0:i:1\tH1:i:0\tRG:Z:L2\n"; final String[] samResults = {"read_28833_29006_6945\t99\tchr20\t28833\t20\t10M1D25M\tchr20\t28993\t195\t" + seq1 + "\t" + qual1 + "\tH0:i:0\tH1:i:0\tMF:i:130\tRG:Z:L1\tNm:i:1", "read_28701_28881_323b\t147\tchr20\t28834\t30\t35M\tchr20\t28701\t-168\t" + seq2 + "\t" + qual2 + "\tH0:i:1\tH1:i:0\tMF:i:18\tRG:Z:L2\tNm:i:0" }; final SAMFileReader samReader = createSamFileReader(samExample); final SAMFileHeader fileHeader = samReader.getFileHeader(); Assert.assertEquals(fileHeader.getVersion(), fileFormatVersion); Assert.assertEquals(fileHeader.getAttribute(charTag), Character.toString(charValue)); final SAMSequenceRecord sequenceRecord = fileHeader.getSequence(sequence); Assert.assertNotNull(sequenceRecord); Assert.assertEquals(sequenceRecord.getSequenceLength(), sequenceLength); Assert.assertEquals(sequenceRecord.getAttribute(intTag), Integer.toString(intValue)); Assert.assertEquals(fileHeader.getReadGroup("L1").getAttribute(floatTag), Float.toString(floatValue)); Assert.assertEquals(fileHeader.getProgramRecord("0").getAttribute(stringTag), stringValue); final CloseableIterator<SAMRecord> iterator = samReader.iterator(); int i = 0; while (iterator.hasNext()) { final SAMRecord rec = iterator.next(); Assert.assertEquals(rec.format(), samResults[i++]); } iterator.close(); iterator.close(); samReader.close(); } private SAMFileReader createSamFileReader(final String samExample) { final ByteArrayInputStream inputStream = new ByteArrayInputStream(samExample.getBytes()); return new SAMFileReader(inputStream); } @Test public void testUnmapped() { final String alignmentFromKris = "0\t4\t*\t0\t0\t*\t*\t0\t0\tGCCTCGTAGTGCGCCATCAGTCTATCGATGTCGTTG\t44\"44===;;;;;;;;;::::88844\"4\"\"\"\"\"\"\"\"\n"; final SAMFileReader samReader = createSamFileReader(alignmentFromKris); final CloseableIterator<SAMRecord> iterator = samReader.iterator(); while (iterator.hasNext()) { iterator.next(); } iterator.close(); } /** * Colon separates fields of a text tag, but colon is also valid in a tag value, so assert that works properly. */ @Test public void testTagWithColon() { // Create a SAMRecord with a String tag containing a colon final SAMRecordSetBuilder samBuilder = new SAMRecordSetBuilder(); samBuilder.addUnmappedFragment("Hi,Mom!"); final SAMRecord rec = samBuilder.iterator().next(); final String valueWithColons = "A:B::C:::"; rec.setAttribute(SAMTag.CQ.name(), valueWithColons); // Write the record as SAM Text final ByteArrayOutputStream os = new ByteArrayOutputStream(); final SAMFileWriter textWriter = new SAMFileWriterFactory().makeSAMWriter(samBuilder.getHeader(), true, os); textWriter.addAlignment(rec); textWriter.close(); final SAMFileReader reader = new SAMFileReader(new ByteArrayInputStream(os.toByteArray())); final SAMRecord recFromText = reader.iterator().next(); Assert.assertEquals(recFromText.getAttribute(SAMTag.CQ.name()), valueWithColons); } }