This is an automated email from the git hooks/post-receive script. tille pushed a commit to branch master in repository htsjdk.
commit 022e46ce85643acf2e0da5cdbd3502439bce96c3 Author: Andreas Tille <[email protected]> Date: Thu Dec 8 08:53:00 2016 +0100 Revert latest change since upstream has intentionally removed an old API (https://github.com/samtools/htsjdk/issues/767) --- debian/changelog | 8 - debian/patches/add_lost_SAMFileReader.java.patch | 767 ----------------------- debian/patches/series | 1 - 3 files changed, 776 deletions(-) diff --git a/debian/changelog b/debian/changelog index de3755a..cb0f147 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,11 +1,3 @@ -htsjdk (2.7.0+dfsg-3) UNRELEASED; urgency=medium - - * Re-add file SAMFileReader.java featuring an outdated API which is - used by Artemis and FastQC - Closes: #846708, #846671 - - -- Andreas Tille <[email protected]> Mon, 05 Dec 2016 12:55:27 +0100 - htsjdk (2.7.0+dfsg-2) unstable; urgency=medium * Fix mess in this changelog (the previous upload is missing the diff --git a/debian/patches/add_lost_SAMFileReader.java.patch b/debian/patches/add_lost_SAMFileReader.java.patch deleted file mode 100644 index 82e1a3d..0000000 --- a/debian/patches/add_lost_SAMFileReader.java.patch +++ /dev/null @@ -1,767 +0,0 @@ -Author: Andreas Tille <[email protected]> -Last-Update: Mon, 05 Dec 2016 12:55:27 +0100 -Bug-Debian: https://bugs.debian.org/846671 - https://bugs.debian.org/846708 -Description: Upstream has changed the API to read SAM files. - As upstream explains in #767 - https://github.com/samtools/htsjdk/issues/767 - FastQC and Artemis should switch to the new API. - . - However, as long as this has not happened yet restoring the old file - src/main/java/htsjdk/samtools/SAMFileReader.java - fixes the FTBFS errors of both packages. - ---- /dev/null -+++ b/src/main/java/htsjdk/samtools/SAMFileReader.java -@@ -0,0 +1,751 @@ -+/* -+ * 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.seekablestream.SeekableBufferedStream; -+import htsjdk.samtools.seekablestream.SeekableHTTPStream; -+import htsjdk.samtools.seekablestream.SeekableStream; -+import htsjdk.samtools.util.*; -+ -+import java.io.*; -+import java.net.URL; -+import java.util.NoSuchElementException; -+import java.util.zip.GZIPInputStream; -+ -+/** -+ * Class for reading and querying SAM/BAM files. Delegates to appropriate concrete implementation. -+ * -+ * @see SamReaderFactory -+ */ -+@Deprecated -+public class SAMFileReader implements SamReader, SamReader.Indexing { -+ -+ private static ValidationStringency defaultValidationStringency = ValidationStringency.DEFAULT_STRINGENCY; -+ -+ public static ValidationStringency getDefaultValidationStringency() { -+ return defaultValidationStringency; -+ } -+ -+ /** -+ * Set validation stringency for all subsequently-created SAMFileReaders. This is the only way to -+ * change the validation stringency for SAM header. -+ * NOTE: Programs that change this should make sure to have a try/finally clause wrapping the work that -+ * they do, so that the original stringency can be restored after the program's work is done. This facilitates -+ * calling a program that is usually run stand-alone from another program, without messing up the original -+ * validation stringency. -+ */ -+ public static void setDefaultValidationStringency(final ValidationStringency defaultValidationStringency) { -+ SAMFileReader.defaultValidationStringency = defaultValidationStringency; -+ } -+ -+ /** -+ * Returns the SAMSequenceDictionary from the provided FASTA. -+ */ -+ public static SAMSequenceDictionary getSequenceDictionary(final File dictionaryFile) { -+ final SAMFileReader samFileReader = new SAMFileReader(dictionaryFile); -+ final SAMSequenceDictionary dict = samFileReader.getFileHeader().getSequenceDictionary(); -+ CloserUtil.close(dictionaryFile); -+ return dict; -+ } -+ -+ private boolean mIsBinary = false; -+ private BAMIndex mIndex = null; -+ private SAMRecordFactory samRecordFactory = new DefaultSAMRecordFactory(); -+ private ReaderImplementation mReader = null; -+ private boolean useAsyncIO = Defaults.USE_ASYNC_IO_READ_FOR_SAMTOOLS; -+ -+ private File samFile = null; -+ -+ private static class EmptySamIterator implements CloseableIterator<SAMRecord> { -+ @Override -+ public boolean hasNext() { -+ return false; -+ } -+ -+ @Override -+ public SAMRecord next() { -+ throw new NoSuchElementException("next called on empty iterator"); -+ } -+ -+ @Override -+ public void remove() { -+ throw new UnsupportedOperationException("Not supported: remove"); -+ } -+ -+ @Override -+ public void close() { -+ //no-op -+ } -+ } -+ -+ -+ /** -+ * Prepare to read a SAM or BAM file. Indexed lookup not allowed because reading from InputStream. -+ */ -+ public SAMFileReader(final InputStream stream) { -+ this(stream, false); -+ } -+ -+ /** -+ * Prepare to read a SAM or BAM file. If the given file is a BAM, and has a companion BAI index file -+ * that is named according to the convention, it will be found and opened, and indexed query will be allowed. -+ */ -+ public SAMFileReader(final File file) { -+ this(file, null, false); -+ } -+ -+ /** -+ * Prepare to read a SAM or BAM file. If the given file is a BAM, and an index is present, indexed query -+ * will be allowed. -+ * -+ * @param file SAM or BAM to read. -+ * @param indexFile Index file that is companion to BAM, or null if no index file, or if index file -+ * should be found automatically. -+ */ -+ public SAMFileReader(final File file, final File indexFile) { -+ this(file, indexFile, false); -+ } -+ -+ /** -+ * Read a SAM or BAM file. Indexed lookup not allowed because reading from InputStream. -+ * -+ * @param stream input SAM or BAM. This is buffered internally so caller need not buffer. -+ * @param eagerDecode if true, decode SAM record entirely when reading it. -+ */ -+ public SAMFileReader(final InputStream stream, final boolean eagerDecode) { -+ init(stream, null, null, eagerDecode, defaultValidationStringency); -+ } -+ -+ /** -+ * Read a SAM or BAM file, possibly with an index file if present. -+ * If the given file is a BAM, and an index is present, indexed query will be allowed. -+ * -+ * @param file SAM or BAM. -+ * @param eagerDecode if true, decode SAM record entirely when reading it. -+ */ -+ public SAMFileReader(final File file, final boolean eagerDecode) { -+ this(file, null, eagerDecode); -+ } -+ -+ /** -+ * Read a SAM or BAM file, possibly with an index file. If the given file is a BAM, and an index is present, -+ * indexed query will be allowed. -+ * -+ * @param file SAM or BAM. -+ * @param indexFile Location of index file, or null in order to use the default index file (if present). -+ * @param eagerDecode eagerDecode if true, decode SAM record entirely when reading it. -+ */ -+ public SAMFileReader(final File file, final File indexFile, final boolean eagerDecode) { -+ init(null, file, indexFile, eagerDecode, defaultValidationStringency); -+ } -+ -+ /** -+ * Read a BAM file by http -+ * indexed query will be allowed. -+ * -+ * @param url BAM. -+ * @param indexFile Location of index file, or null if indexed access not required. -+ * @param eagerDecode eagerDecode if true, decode SAM record entirely when reading it. -+ */ -+ public SAMFileReader(final URL url, final File indexFile, final boolean eagerDecode) { -+ init(new SeekableBufferedStream(new SeekableHTTPStream(url)), -+ indexFile, eagerDecode, defaultValidationStringency); -+ } -+ -+ /** -+ * Read a BAM file via caller-supplied mechanism. Indexed query will be allowed, but -+ * index file must be provided in that case. -+ * -+ * @param strm BAM -- If the stream is not buffered, caller should wrap in SeekableBufferedStream for -+ * better performance. -+ * @param indexFile Location of index file, or null indexed access not required. -+ * @param eagerDecode if true, decode SAM record entirely when reading it. -+ */ -+ public SAMFileReader(final SeekableStream strm, final File indexFile, final boolean eagerDecode) { -+ init(strm, indexFile, eagerDecode, defaultValidationStringency); -+ } -+ -+ /** -+ * @param strm BAM -- If the stream is not buffered, caller should wrap in SeekableBufferedStream for -+ * better performance. -+ */ -+ public SAMFileReader(final SeekableStream strm, final SeekableStream indexStream, final boolean eagerDecode) { -+ init(strm, indexStream, eagerDecode, defaultValidationStringency); -+ } -+ -+ public void close() { -+ if (mReader != null) { -+ mReader.close(); -+ } -+ mReader = null; -+ mIndex = null; -+ } -+ -+ /** -+ * If true, this reader will use asynchronous IO. -+ */ -+ public void setUseAsyncIO(final boolean useAsyncIO) { -+ this.useAsyncIO = useAsyncIO; -+ } -+ -+ /** -+ * If true, writes the source of every read into the source SAMRecords. -+ * -+ * @param enabled true to write source information into each SAMRecord. -+ */ -+ public void enableFileSource(final boolean enabled) { -+ mReader.enableFileSource(this, enabled); -+ } -+ -+ /** -+ * If true, uses the caching version of the index reader. -+ * -+ * @param enabled true to use the caching version of the reader. -+ */ -+ public void enableIndexCaching(final boolean enabled) { -+ if (mIndex != null) -+ throw new SAMException("Unable to turn on index caching; index file has already been loaded."); -+ mReader.enableIndexCaching(enabled); -+ } -+ -+ /** -+ * If false, disable the use of memory mapping for accessing index files (default behavior is to use memory mapping). -+ * This is slower but more scalable when accessing large numbers of BAM files sequentially. -+ * -+ * @param enabled True to use memory mapping, false to use regular I/O. -+ */ -+ public void enableIndexMemoryMapping(final boolean enabled) { -+ if (mIndex != null) { -+ throw new SAMException("Unable to change index memory mapping; index file has already been loaded."); -+ } -+ mReader.enableIndexMemoryMapping(enabled); -+ } -+ -+ /** -+ * Only meaningful for BAM file readers - enables or disables checking of checksums on uncompressed -+ * data during decompression. Enabling this will increase decompression time by 15-30%. -+ */ -+ public void enableCrcChecking(final boolean enabled) { -+ this.mReader.enableCrcChecking(enabled); -+ } -+ -+ /** -+ * Override the default SAMRecordFactory class used to instantiate instances of SAMRecord and BAMRecord. -+ */ -+ public void setSAMRecordFactory(final SAMRecordFactory factory) { -+ this.samRecordFactory = factory; -+ this.mReader.setSAMRecordFactory(factory); -+ } -+ -+ /** -+ * @return True if this is a BAM reader. -+ */ -+ public boolean isBinary() { -+ return mIsBinary; -+ } -+ -+ /** -+ * @return true if ths is a BAM file, and has an index -+ */ -+ public boolean hasIndex() { -+ return mReader.hasIndex(); -+ } -+ -+ @Override -+ public Indexing indexing() { -+ return this; -+ } -+ -+ /** -+ * Retrieves the index for the given file type. Ensure that the index is of the specified type. -+ * -+ * @return An index of the given type. -+ */ -+ public BAMIndex getIndex() { -+ return mReader.getIndex(); -+ } -+ -+ /** -+ * Returns true if the supported index is browseable, meaning the bins in it can be traversed -+ * and chunk data inspected and retrieved. -+ * -+ * @return True if the index supports the BrowseableBAMIndex interface. False otherwise. -+ */ -+ public boolean hasBrowseableIndex() { -+ return hasIndex() && getIndex() instanceof BrowseableBAMIndex; -+ } -+ -+ /** -+ * Gets an index tagged with the BrowseableBAMIndex interface. Throws an exception if no such -+ * index is available. -+ * -+ * @return An index with a browseable interface, if possible. -+ * @throws SAMException if no such index is available. -+ */ -+ public BrowseableBAMIndex getBrowseableIndex() { -+ final BAMIndex index = getIndex(); -+ if (!(index instanceof BrowseableBAMIndex)) -+ throw new SAMException("Cannot return index: index created by BAM is not browseable."); -+ return BrowseableBAMIndex.class.cast(index); -+ } -+ -+ public SAMFileHeader getFileHeader() { -+ return mReader.getFileHeader(); -+ } -+ -+ @Override -+ public Type type() { -+ return mReader.type(); -+ } -+ -+ @Override -+ public String getResourceDescription() { -+ return this.toString(); -+ } -+ -+ /** -+ * Control validation of SAMRecords as they are read from file. -+ * In order to control validation stringency for SAM Header, call SAMFileReader.setDefaultValidationStringency -+ * before constructing a SAMFileReader. -+ */ -+ public void setValidationStringency(final ValidationStringency validationStringency) { -+ mReader.setValidationStringency(validationStringency); -+ } -+ -+ /** -+ * Iterate through file in order. For a SAMFileReader constructed from an InputStream, and for any SAM file, -+ * a 2nd iteration starts where the 1st one left off. For a BAM constructed from a File, each new iteration -+ * starts at the first record. -+ * <p/> -+ * Only a single open iterator on a SAM or BAM file may be extant at any one time. If you want to start -+ * a second iteration, the first one must be closed first. -+ */ -+ public SAMRecordIterator iterator() { -+ return new AssertingIterator(mReader.getIterator()); -+ } -+ -+ /** -+ * Iterate through the given chunks in the file. -+ * -+ * @param chunks List of chunks for which to retrieve data. -+ * @return An iterator over the given chunks. -+ */ -+ public SAMRecordIterator iterator(final SAMFileSpan chunks) { -+ return new AssertingIterator(mReader.getIterator(chunks)); -+ } -+ -+ /** -+ * Gets a pointer spanning all reads in the BAM file. -+ * -+ * @return Unbounded pointer to the first record, in chunk format. -+ */ -+ public SAMFileSpan getFilePointerSpanningReads() { -+ return mReader.getFilePointerSpanningReads(); -+ } -+ -+ /** -+ * Iterate over records that match the given interval. Only valid to call this if hasIndex() == true. -+ * <p/> -+ * Only a single open iterator on a given SAMFileReader may be extant at any one time. If you want to start -+ * a second iteration, the first one must be closed first. You can use a second SAMFileReader to iterate -+ * in parallel over the same underlying file. -+ * <p/> -+ * Note that indexed lookup is not perfectly efficient in terms of disk I/O. I.e. some SAMRecords may be read -+ * and then discarded because they do not match the interval of interest. -+ * <p/> -+ * Note that an unmapped read will be returned by this call if it has a coordinate for the purpose of sorting that -+ * is in the query region. -+ * -+ * @param sequence Reference sequence of interest. -+ * @param start 1-based, inclusive start of interval of interest. Zero implies start of the reference sequence. -+ * @param end 1-based, inclusive end of interval of interest. Zero implies end of the reference sequence. -+ * @param contained If true, each SAMRecord returned is will have its alignment completely contained in the -+ * interval of interest. If false, the alignment of the returned SAMRecords need only overlap the interval of interest. -+ * @return Iterator over the SAMRecords matching the interval. -+ */ -+ public SAMRecordIterator query(final String sequence, final int start, final int end, final boolean contained) { -+ final int referenceIndex = getFileHeader().getSequenceIndex(sequence); -+ final CloseableIterator<SAMRecord> currentIterator; -+ if (referenceIndex == -1) { -+ currentIterator = new EmptySamIterator(); -+ } else { -+ final QueryInterval[] queryIntervals = {new QueryInterval(referenceIndex, start, end)}; -+ currentIterator = mReader.query(queryIntervals, contained); -+ } -+ return new AssertingIterator(currentIterator); -+ } -+ -+ /** -+ * Iterate over records that overlap the given interval. Only valid to call this if hasIndex() == true. -+ * <p/> -+ * Only a single open iterator on a given SAMFileReader may be extant at any one time. If you want to start -+ * a second iteration, the first one must be closed first. -+ * <p/> -+ * Note that indexed lookup is not perfectly efficient in terms of disk I/O. I.e. some SAMRecords may be read -+ * and then discarded because they do not match the interval of interest. -+ * <p/> -+ * Note that an unmapped read will be returned by this call if it has a coordinate for the purpose of sorting that -+ * is in the query region. -+ * -+ * @param sequence Reference sequence of interest. -+ * @param start 1-based, inclusive start of interval of interest. Zero implies start of the reference sequence. -+ * @param end 1-based, inclusive end of interval of interest. Zero implies end of the reference sequence. -+ * @return Iterator over the SAMRecords overlapping the interval. -+ */ -+ public SAMRecordIterator queryOverlapping(final String sequence, final int start, final int end) { -+ return query(sequence, start, end, false); -+ } -+ -+ /** -+ * Iterate over records that are contained in the given interval. Only valid to call this if hasIndex() == true. -+ * <p/> -+ * Only a single open iterator on a given SAMFileReader may be extant at any one time. If you want to start -+ * a second iteration, the first one must be closed first. -+ * <p/> -+ * Note that indexed lookup is not perfectly efficient in terms of disk I/O. I.e. some SAMRecords may be read -+ * and then discarded because they do not match the interval of interest. -+ * <p/> -+ * Note that an unmapped read will be returned by this call if it has a coordinate for the purpose of sorting that -+ * is in the query region. -+ * -+ * @param sequence Reference sequence of interest. -+ * @param start 1-based, inclusive start of interval of interest. Zero implies start of the reference sequence. -+ * @param end 1-based, inclusive end of interval of interest. Zero implies end of the reference sequence. -+ * @return Iterator over the SAMRecords contained in the interval. -+ */ -+ public SAMRecordIterator queryContained(final String sequence, final int start, final int end) { -+ return query(sequence, start, end, true); -+ } -+ -+ /** -+ * Iterate over records that match one of the given intervals. This may be more efficient than querying -+ * each interval separately, because multiple reads of the same SAMRecords is avoided. -+ * <p/> -+ * Only valid to call this if hasIndex() == true. -+ * <p/> -+ * Only a single open iterator on a given SAMFileReader may be extant at any one time. If you want to start -+ * a second iteration, the first one must be closed first. You can use a second SAMFileReader to iterate -+ * in parallel over the same underlying file. -+ * <p/> -+ * Note that indexed lookup is not perfectly efficient in terms of disk I/O. I.e. some SAMRecords may be read -+ * and then discarded because they do not match an interval of interest. -+ * <p/> -+ * Note that an unmapped read will be returned by this call if it has a coordinate for the purpose of sorting that -+ * is in the query region. -+ * -+ * @param intervals Intervals to be queried. The intervals must be optimized, i.e. in order, with overlapping -+ * and abutting intervals merged. This can be done with {@link htsjdk.samtools.QueryInterval#optimizeIntervals} -+ * @param contained If true, each SAMRecord returned is will have its alignment completely contained in one of the -+ * intervals of interest. If false, the alignment of the returned SAMRecords need only overlap one of -+ * the intervals of interest. -+ * @return Iterator over the SAMRecords matching the interval. -+ */ -+ public SAMRecordIterator query(final QueryInterval[] intervals, final boolean contained) { -+ return new AssertingIterator(mReader.query(intervals, contained)); -+ } -+ -+ /** -+ * Iterate over records that overlap any of the given intervals. This may be more efficient than querying -+ * each interval separately, because multiple reads of the same SAMRecords is avoided. -+ * <p/> -+ * Only valid to call this if hasIndex() == true. -+ * <p/> -+ * Only a single open iterator on a given SAMFileReader may be extant at any one time. If you want to start -+ * a second iteration, the first one must be closed first. -+ * <p/> -+ * Note that indexed lookup is not perfectly efficient in terms of disk I/O. I.e. some SAMRecords may be read -+ * and then discarded because they do not match the interval of interest. -+ * <p/> -+ * Note that an unmapped read will be returned by this call if it has a coordinate for the purpose of sorting that -+ * is in the query region. -+ * -+ * @param intervals Intervals to be queried. The intervals must be optimized, i.e. in order, with overlapping -+ * and abutting intervals merged. This can be done with {@link htsjdk.samtools.QueryInterval#optimizeIntervals} -+ * @return Iterator over the SAMRecords overlapping any of the intervals. -+ */ -+ public SAMRecordIterator queryOverlapping(final QueryInterval[] intervals) { -+ return query(intervals, false); -+ } -+ -+ /** -+ * Iterate over records that are contained in the given interval. This may be more efficient than querying -+ * each interval separately, because multiple reads of the same SAMRecords is avoided. -+ * <p/> -+ * Only valid to call this if hasIndex() == true. -+ * <p/> -+ * Only a single open iterator on a given SAMFileReader may be extant at any one time. If you want to start -+ * a second iteration, the first one must be closed first. -+ * <p/> -+ * Note that indexed lookup is not perfectly efficient in terms of disk I/O. I.e. some SAMRecords may be read -+ * and then discarded because they do not match the interval of interest. -+ * <p/> -+ * Note that an unmapped read will be returned by this call if it has a coordinate for the purpose of sorting that -+ * is in the query region. -+ * -+ * @param intervals Intervals to be queried. The intervals must be optimized, i.e. in order, with overlapping -+ * and abutting intervals merged. This can be done with {@link htsjdk.samtools.QueryInterval#optimizeIntervals} -+ * @return Iterator over the SAMRecords contained in any of the intervals. -+ */ -+ public SAMRecordIterator queryContained(final QueryInterval[] intervals) { -+ return query(intervals, true); -+ } -+ -+ -+ public SAMRecordIterator queryUnmapped() { -+ return new AssertingIterator(mReader.queryUnmapped()); -+ } -+ -+ /** -+ * Iterate over records that map to the given sequence and start at the given position. Only valid to call this if hasIndex() == true. -+ * <p/> -+ * Only a single open iterator on a given SAMFileReader may be extant at any one time. If you want to start -+ * a second iteration, the first one must be closed first. -+ * <p/> -+ * Note that indexed lookup is not perfectly efficient in terms of disk I/O. I.e. some SAMRecords may be read -+ * and then discarded because they do not match the interval of interest. -+ * <p/> -+ * Note that an unmapped read will be returned by this call if it has a coordinate for the purpose of sorting that -+ * matches the arguments. -+ * -+ * @param sequence Reference sequence of interest. -+ * @param start Alignment start of interest. -+ * @return Iterator over the SAMRecords with the given alignment start. -+ */ -+ public SAMRecordIterator queryAlignmentStart(final String sequence, final int start) { -+ return new AssertingIterator(mReader.queryAlignmentStart(sequence, start)); -+ } -+ -+ /** -+ * Fetch the mate for the given read. Only valid to call this if hasIndex() == true. -+ * This will work whether the mate has a coordinate or not, so long as the given read has correct -+ * mate information. This method iterates over the SAM file, so there may not be an unclosed -+ * iterator on the SAM file when this method is called. -+ * <p/> -+ * Note that it is not possible to call queryMate when iterating over the SAMFileReader, because queryMate -+ * requires its own iteration, and there cannot be two simultaneous iterations on the same SAMFileReader. The -+ * work-around is to open a second SAMFileReader on the same input file, and call queryMate on the second -+ * reader. -+ * -+ * @param rec Record for which mate is sought. Must be a paired read. -+ * @return rec's mate, or null if it cannot be found. -+ */ -+ public SAMRecord queryMate(final SAMRecord rec) { -+ if (!rec.getReadPairedFlag()) { -+ throw new IllegalArgumentException("queryMate called for unpaired read."); -+ } -+ if (rec.getFirstOfPairFlag() == rec.getSecondOfPairFlag()) { -+ throw new IllegalArgumentException("SAMRecord must be either first and second of pair, but not both."); -+ } -+ final boolean firstOfPair = rec.getFirstOfPairFlag(); -+ final CloseableIterator<SAMRecord> it; -+ if (rec.getMateReferenceIndex() == SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX) { -+ it = queryUnmapped(); -+ } else { -+ it = queryAlignmentStart(rec.getMateReferenceName(), rec.getMateAlignmentStart()); -+ } -+ try { -+ SAMRecord mateRec = null; -+ while (it.hasNext()) { -+ final SAMRecord next = it.next(); -+ if (!next.getReadPairedFlag()) { -+ if (rec.getReadName().equals(next.getReadName())) { -+ throw new SAMFormatException("Paired and unpaired reads with same name: " + rec.getReadName()); -+ } -+ continue; -+ } -+ if (firstOfPair) { -+ if (next.getFirstOfPairFlag()) continue; -+ } else { -+ if (next.getSecondOfPairFlag()) continue; -+ } -+ if (rec.getReadName().equals(next.getReadName())) { -+ if (mateRec != null) { -+ throw new SAMFormatException("Multiple SAMRecord with read name " + rec.getReadName() + -+ " for " + (firstOfPair ? "second" : "first") + " end."); -+ } -+ mateRec = next; -+ } -+ } -+ return mateRec; -+ } finally { -+ it.close(); -+ } -+ } -+ -+ -+ private void init(final SeekableStream strm, final File indexFile, final boolean eagerDecode, -+ final ValidationStringency validationStringency) { -+ -+ try { -+ if (streamLooksLikeBam(strm)) { -+ mIsBinary = true; -+ mReader = new BAMFileReader(strm, indexFile, eagerDecode, useAsyncIO, validationStringency, this.samRecordFactory); -+ } else { -+ throw new SAMFormatException("Unrecognized file format: " + strm); -+ } -+ setValidationStringency(validationStringency); -+ } catch (final IOException e) { -+ throw new RuntimeIOException(e); -+ } -+ } -+ -+ private void init(final SeekableStream strm, final SeekableStream indexStream, final boolean eagerDecode, -+ final ValidationStringency validationStringency) { -+ -+ try { -+ if (streamLooksLikeBam(strm)) { -+ mIsBinary = true; -+ mReader = new BAMFileReader(strm, indexStream, eagerDecode, useAsyncIO, validationStringency, this.samRecordFactory); -+ } else { -+ throw new SAMFormatException("Unrecognized file format: " + strm); -+ } -+ setValidationStringency(validationStringency); -+ } catch (final IOException e) { -+ throw new RuntimeIOException(e); -+ } -+ } -+ -+ // Its too expensive to examine the remote file to determine type. -+ // Rely on file extension. -+ private boolean streamLooksLikeBam(final SeekableStream strm) { -+ String source = strm.getSource(); -+ if (source == null) return true; -+ source = source.toLowerCase(); -+ //Source will typically be a file path or URL -+ //If it's a URL we require one of the query parameters to be bam file -+ return source.endsWith(".bam") || source.contains(".bam?") || source.contains(".bam&") || source.contains(".bam%26"); -+ } -+ -+ private void init(final InputStream stream, File file, final File indexFile, final boolean eagerDecode, -+ final ValidationStringency validationStringency) { -+ if (stream != null && file != null) throw new IllegalArgumentException("stream and file are mutually exclusive"); -+ this.samFile = file; -+ -+ try { -+ BufferedInputStream bufferedStream; -+ // Buffering is required because mark() and reset() are called on the input stream. -+ final int bufferSize = Math.max(Defaults.BUFFER_SIZE, BlockCompressedStreamConstants.MAX_COMPRESSED_BLOCK_SIZE); -+ if (file != null) bufferedStream = new BufferedInputStream(new FileInputStream(file), bufferSize); -+ else bufferedStream = IOUtil.toBufferedStream(stream); -+ if (SamStreams.isBAMFile(bufferedStream)) { -+ mIsBinary = true; -+ if (file == null || !file.isFile()) { -+ // Handle case in which file is a named pipe, e.g. /dev/stdin or created by mkfifo -+ mReader = new BAMFileReader(bufferedStream, indexFile, eagerDecode, useAsyncIO, validationStringency, this.samRecordFactory); -+ } else { -+ bufferedStream.close(); -+ mReader = new BAMFileReader(file, indexFile, eagerDecode, useAsyncIO, validationStringency, this.samRecordFactory); -+ } -+ } else if (BlockCompressedInputStream.isValidFile(bufferedStream)) { -+ mIsBinary = false; -+ mReader = new SAMTextReader(new BlockCompressedInputStream(bufferedStream), validationStringency, this.samRecordFactory); -+ } else if (SamStreams.isGzippedSAMFile(bufferedStream)) { -+ mIsBinary = false; -+ mReader = new SAMTextReader(new GZIPInputStream(bufferedStream), validationStringency, this.samRecordFactory); -+ } else if (SamStreams.isCRAMFile(bufferedStream)) { -+ if (file == null || !file.isFile()) { -+ file = null; -+ } else { -+ bufferedStream.close(); -+ bufferedStream = null; -+ } -+ mReader = new CRAMFileReader(file, bufferedStream); -+ } else if (isSAMFile(bufferedStream)) { -+ if (indexFile != null) { -+ bufferedStream.close(); -+ throw new RuntimeException("Cannot use index file with textual SAM file"); -+ } -+ mIsBinary = false; -+ mReader = new SAMTextReader(bufferedStream, file, validationStringency, this.samRecordFactory); -+ } else { -+ bufferedStream.close(); -+ throw new SAMFormatException("Unrecognized file format"); -+ } -+ -+ setValidationStringency(validationStringency); -+ mReader.setSAMRecordFactory(this.samRecordFactory); -+ } catch (final IOException e) { -+ throw new RuntimeIOException(e); -+ } -+ } -+ -+ private static int readBytes(final InputStream stream, final byte[] buffer, final int offset, final int length) -+ throws IOException { -+ int bytesRead = 0; -+ while (bytesRead < length) { -+ final int count = stream.read(buffer, offset + bytesRead, length - bytesRead); -+ if (count <= 0) { -+ break; -+ } -+ bytesRead += count; -+ } -+ return bytesRead; -+ } -+ -+ private boolean isSAMFile(final InputStream stream) { -+ // For now, assume every non-binary file is a SAM text file. -+ return true; -+ } -+ -+ @Override -+ public String toString() { -+ if (this.samFile == null) { -+ return getClass().getSimpleName() + "{initialized with stream}"; -+ } else { -+ return getClass().getSimpleName() + "{" + this.samFile.getAbsolutePath() + "}"; -+ } -+ } -+ -+ /** -+ * Convenience method to create a QueryInterval -+ * -+ * @param sequence sequence of interest, must exist in sequence dictionary -+ * @param start 1-based start position, must be >= 1 -+ * @param end 1-based end position. -+ * @throws java.lang.IllegalArgumentException if sequence not found in sequence dictionary, or start position < 1 -+ */ -+ public QueryInterval makeQueryInterval(final String sequence, int start, int end) { -+ int referenceIndex = getFileHeader().getSequenceIndex(sequence); -+ if (referenceIndex < 0) { -+ throw new IllegalArgumentException(String.format("Sequence '%s' not found in sequence dictionary", sequence)); -+ } -+ if (start < 1) { -+ throw new IllegalArgumentException("Start position must be >= 1"); -+ } -+ return new QueryInterval(referenceIndex, start, end); -+ } -+ -+ /** -+ * Convenience method to create a QueryInterval that goes from start to end of given sequence. -+ * -+ * @param sequence sequence of interest, must exist in sequence dictionary -+ * @param start 1-based start position, must be >= 1 -+ * @throws java.lang.IllegalArgumentException if sequence not found in sequence dictionary, or start position < 1 -+ */ -+ public QueryInterval makeQueryInterval(final String sequence, int start) { -+ return makeQueryInterval(sequence, start, 0); -+ } -+ -+} diff --git a/debian/patches/series b/debian/patches/series index 670b29f..1a7872a 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -2,4 +2,3 @@ 11-snappy-java-compatibility.patch 13-skip_network_tests 20-fix-version.patch -add_lost_SAMFileReader.java.patch -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/htsjdk.git _______________________________________________ debian-med-commit mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/debian-med-commit
