/* * MIT License * * Copyright 2019 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 org.broadinstitute.dropseqrna.utils; import htsjdk.samtools.SAMSequenceDictionary; import htsjdk.samtools.SAMSequenceRecord; import htsjdk.samtools.SamReader; import htsjdk.samtools.SamReaderFactory; import htsjdk.samtools.util.CloserUtil; import htsjdk.samtools.util.IntervalList; import htsjdk.variant.vcf.VCFFileReader; import org.testng.Assert; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class SequenceDictionaryIntersectionTest { private static final File TESTDATA_DIR = new File("testdata/org/broadinstitute/dropseq/utils/SequenceDictionaryIntersectionTest"); private static final String CHR_BASENAME = "chr."; private static final String NO_CHR_BASENAME = "no_chr."; private static final int NUM_SEQUENCES = 85; private static final int NUM_NON_CHR_SEQUENCES = 60; @Test(dataProvider = "ssdiDataProvider") public void testWithDescriptions( final Object o1, final Object o2, final String description1, final String description2, final int expectedIntersectionSize) { final SequenceDictionaryIntersection sdi = new SequenceDictionaryIntersection(o1, description1, o2, description2); Assert.assertEquals(sdi.getIntersection().size(), expectedIntersectionSize); System.out.println("Terse: " + sdi.message(false)); System.out.println("Verbose: " + sdi.message(true)); } @Test(dataProvider = "ssdiDataProvider") public void testWithoutDescriptions( final Object o1, final Object o2, final String description1, final String description2, final int expectedIntersectionSize) { final SequenceDictionaryIntersection sdi = new SequenceDictionaryIntersection(o1, o2); Assert.assertEquals(sdi.getIntersection().size(), expectedIntersectionSize); System.out.println("Terse: " + sdi.message(false)); System.out.println("Verbose: " + sdi.message(true)); } @DataProvider(name="ssdiDataProvider") public Object[][] ssdiDataProvider() { final ArrayList<Object[]> ret = new ArrayList<>(); final File leftDictFile = new File(TESTDATA_DIR, CHR_BASENAME + "sam"); final SamReader leftDict = SamReaderFactory.makeDefault().open(leftDictFile); for (final boolean chr: new boolean[]{true, false}) { final String basename; final int expectedIntersection; if (chr) { basename = CHR_BASENAME; expectedIntersection = NUM_SEQUENCES; } else { basename = NO_CHR_BASENAME; expectedIntersection = NUM_NON_CHR_SEQUENCES; } final File samFile = new File(TESTDATA_DIR, basename + "sam"); final SamReader samReader = SamReaderFactory.makeDefault().open(samFile); ret.add(new Object[]{leftDict, samReader, leftDictFile.getName(), samFile.getName(), expectedIntersection}); ret.add(new Object[]{leftDict, samReader.getFileHeader(), leftDictFile.getName(), samFile.getName(), expectedIntersection}); ret.add(new Object[]{leftDict, samReader.getFileHeader().getSequenceDictionary(), leftDictFile.getName(), samFile.getName(), expectedIntersection}); final File vcfFile = new File(TESTDATA_DIR, basename + "vcf"); final VCFFileReader vcfReader = new VCFFileReader(vcfFile, false); ret.add(new Object[]{leftDict, vcfReader, leftDictFile.getName(), vcfFile.getName(), expectedIntersection}); final File intervalListFile = new File(TESTDATA_DIR, basename + "interval_list"); final IntervalList intervalList = IntervalList.fromFile(intervalListFile); ret.add(new Object[]{leftDict, intervalList, leftDictFile.getName(), intervalListFile.getName(), expectedIntersection}); } return ret.toArray(new Object[ret.size()][]); } @Test public void testNoMatch() { final File leftDictFile = new File(TESTDATA_DIR, CHR_BASENAME + "sam"); final SamReader leftDict = SamReaderFactory.makeDefault().open(leftDictFile); try { final SAMSequenceDictionary nonMatchingDict = new SAMSequenceDictionary( leftDict.getFileHeader().getSequenceDictionary().getSequences().stream(). map((s) -> new SAMSequenceRecord("xyz_" + s.getSequenceName(), s.getSequenceLength())). collect(Collectors.toList())); SequenceDictionaryIntersection sdi = new SequenceDictionaryIntersection( leftDict, leftDictFile.getName(), nonMatchingDict, "with prefixes"); Assert.assertEquals(sdi.getIntersection().size(), 0); System.out.println("Terse with descriptions: " + sdi.message(false)); System.out.println("Verbose with descriptions: " + sdi.message(true)); sdi = new SequenceDictionaryIntersection(leftDict, nonMatchingDict); Assert.assertEquals(sdi.getIntersection().size(), 0); System.out.println("Terse without descriptions: " + sdi.message(false) + "\n"); System.out.println("Verbose without descriptions: " + sdi.message(true) + "\n"); } finally { CloserUtil.close(leftDict); } } @Test(expectedExceptions = IllegalArgumentException.class) public void testBadObject() { final File leftDictFile = new File(TESTDATA_DIR, CHR_BASENAME + "sam"); final SamReader leftDict = SamReaderFactory.makeDefault().open(leftDictFile); try { SequenceDictionaryIntersection sdi = new SequenceDictionaryIntersection( leftDict, leftDictFile.getName(), "Just a string", "not a sequence dictionary"); } finally { CloserUtil.close(leftDict);; } } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullObject() { final File leftDictFile = new File(TESTDATA_DIR, CHR_BASENAME + "sam"); final SamReader leftDict = SamReaderFactory.makeDefault().open(leftDictFile); try { SequenceDictionaryIntersection sdi = new SequenceDictionaryIntersection( leftDict, leftDictFile.getName(),null, "null"); } finally { CloserUtil.close(leftDict);; } } }