/* * 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.DataProvider; import org.testng.annotations.Test; import java.io.File; /** * Test that BAM writing doesn't blow up. For presorted writing, the resulting BAM file is read and contents are * compared with the original SAM file. */ public class BAMFileWriterTest { private SAMRecordSetBuilder getSAMReader(final boolean sortForMe, final SAMFileHeader.SortOrder sortOrder) { final SAMRecordSetBuilder ret = new SAMRecordSetBuilder(sortForMe, sortOrder); ret.addPair("readB", 20, 200, 300); ret.addPair("readA", 20, 100, 150); ret.addFrag("readC", 20, 140, true); ret.addFrag("readD", 20, 140, false); return ret; } /** * Parse some SAM text into a SAM object, then write as BAM. If SAM text was presorted, then the BAM file can * be read and compared with the SAM object. * @param samRecordSetBuilder source of input SAMFileReader to be written and compared with * @param sortOrder How the BAM should be written * @param presorted If true, samText is in the order specified by sortOrder */ private void testHelper(final SAMRecordSetBuilder samRecordSetBuilder, final SAMFileHeader.SortOrder sortOrder, final boolean presorted) throws Exception { SAMFileReader samReader = samRecordSetBuilder.getSamReader(); final File bamFile = File.createTempFile("test.", BamFileIoUtils.BAM_FILE_EXTENSION); bamFile.deleteOnExit(); samReader.getFileHeader().setSortOrder(sortOrder); final SAMFileWriter bamWriter = new SAMFileWriterFactory().makeSAMOrBAMWriter(samReader.getFileHeader(), presorted, bamFile); CloseableIterator<SAMRecord> it = samReader.iterator(); while (it.hasNext()) { bamWriter.addAlignment(it.next()); } bamWriter.close(); it.close(); samReader.close(); if (presorted) { // If SAM text input was presorted, then we can compare SAM object to BAM object final SAMFileReader bamReader = new SAMFileReader(bamFile); samReader = samRecordSetBuilder.getSamReader(); samReader.getFileHeader().setSortOrder(bamReader.getFileHeader().getSortOrder()); Assert.assertEquals(bamReader.getFileHeader(), samReader.getFileHeader()); it = samReader.iterator(); final CloseableIterator<SAMRecord> bamIt = bamReader.iterator(); while (it.hasNext()) { Assert.assertTrue(bamIt.hasNext()); final SAMRecord samRecord = it.next(); final SAMRecord bamRecord = bamIt.next(); // SAMRecords don't have this set, so stuff it in there samRecord.setIndexingBin(bamRecord.getIndexingBin()); // Force reference index attributes to be populated samRecord.getReferenceIndex(); bamRecord.getReferenceIndex(); samRecord.getMateReferenceIndex(); bamRecord.getMateReferenceIndex(); Assert.assertEquals(bamRecord, samRecord); } Assert.assertFalse(bamIt.hasNext()); } } @DataProvider(name = "test1") public Object[][] createTestData() { return new Object[][] { {"coordinate sorted", getSAMReader(false, SAMFileHeader.SortOrder.unsorted), SAMFileHeader.SortOrder.coordinate, false}, {"query sorted", getSAMReader(false, SAMFileHeader.SortOrder.unsorted), SAMFileHeader.SortOrder.queryname, false}, {"unsorted", getSAMReader(false, SAMFileHeader.SortOrder.unsorted), SAMFileHeader.SortOrder.unsorted, false}, {"coordinate presorted", getSAMReader(true, SAMFileHeader.SortOrder.coordinate), SAMFileHeader.SortOrder.coordinate, true}, {"query presorted", getSAMReader(true, SAMFileHeader.SortOrder.queryname), SAMFileHeader.SortOrder.queryname, true}, }; } @Test(dataProvider = "test1") public void testPositive(final String testName, final SAMRecordSetBuilder samRecordSetBuilder, final SAMFileHeader.SortOrder order, final boolean presorted) throws Exception { testHelper(samRecordSetBuilder, order, presorted); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNegativePresorted() throws Exception { testHelper(getSAMReader(true, SAMFileHeader.SortOrder.coordinate), SAMFileHeader.SortOrder.queryname, true); Assert.fail("Exception should be thrown"); } }