Skip to content

Commit

Permalink
Add Path options for SAMFileWriterFactory
Browse files Browse the repository at this point in the history
Also:
- use jimfs for most CRAM compliance tests
- handle codec filenames starting with "file://"
- add jimfs test for bam/cram writer
- protect against null path
  • Loading branch information
jean-philippe-martin committed Aug 31, 2017
1 parent e110f44 commit a8a680f
Show file tree
Hide file tree
Showing 11 changed files with 443 additions and 95 deletions.
31 changes: 21 additions & 10 deletions src/main/java/htsjdk/samtools/BAMFileWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import htsjdk.samtools.util.BinaryCodec;
import htsjdk.samtools.util.BlockCompressedOutputStream;
import htsjdk.samtools.util.IOUtil;
import htsjdk.samtools.util.RuntimeIOException;
import htsjdk.samtools.util.zip.DeflaterFactory;

Expand All @@ -34,6 +35,9 @@
import java.io.OutputStream;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
* Concrete implementation of SAMFileWriter for writing gzipped BAM files.
Expand Down Expand Up @@ -75,7 +79,13 @@ protected BAMFileWriter(final OutputStream os, final File file, final int compre
outputBinaryCodec.setOutputFileName(getPathString(file));
}

private void prepareToWriteAlignments() {
protected BAMFileWriter(final OutputStream os, final String absoluteFilename, final int compressionLevel, final DeflaterFactory deflaterFactory) {
blockCompressedOutputStream = new BlockCompressedOutputStream(os, null, compressionLevel, deflaterFactory);
outputBinaryCodec = new BinaryCodec(new DataOutputStream(blockCompressedOutputStream));
outputBinaryCodec.setOutputFileName(absoluteFilename);
}

private void prepareToWriteAlignments() {
if (bamRecordCodec == null) {
bamRecordCodec = new BAMRecordCodec(getFileHeader());
bamRecordCodec.setOutputStream(outputBinaryCodec.getOutputStream(), getFilename());
Expand All @@ -99,17 +109,17 @@ void enableBamIndexConstruction () {
bamIndexer = createBamIndex(getFilename());
}

private BAMIndexer createBamIndex(final String path) {
private BAMIndexer createBamIndex(final String pathURI) {
try {
final String indexFileBase = path.endsWith(BamFileIoUtils.BAM_FILE_EXTENSION) ?
path.substring(0, path.lastIndexOf('.')) : path;
final File indexFile = new File(indexFileBase + BAMIndex.BAMIndexSuffix);
if (indexFile.exists()) {
if (!indexFile.canWrite()) {
throw new SAMException("Not creating BAM index since unable to write index file " + indexFile);
final String indexFileBase = pathURI.endsWith(BamFileIoUtils.BAM_FILE_EXTENSION) ?
pathURI.substring(0, pathURI.lastIndexOf('.')) : pathURI;
final Path indexPath = IOUtil.getPath(indexFileBase + BAMIndex.BAMIndexSuffix);
if (Files.exists(indexPath)) {
if (!Files.isWritable(indexPath)) {
throw new SAMException("Not creating BAM index since unable to write index file " + indexPath.toUri());
}
}
return new BAMIndexer(indexFile, getFileHeader());
return new BAMIndexer(indexPath, getFileHeader());
} catch (Exception e) {
throw new SAMException("Not creating BAM index", e);
}
Expand Down Expand Up @@ -153,7 +163,8 @@ protected void finish() {
}
}

/** @return absolute path, or null if this writer does not correspond to a file. */
/** @return absolute path in URI format, or null if this writer does not correspond to a file.
* To get a Path from this, use: IOUtil.getPath(getFilename()) */
@Override
protected String getFilename() {
return outputBinaryCodec.getOutputFileName();
Expand Down
37 changes: 33 additions & 4 deletions src/main/java/htsjdk/samtools/BAMIndexer.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import java.io.File;
import java.io.OutputStream;
import java.nio.file.Path;
import java.util.function.Function;

/**
Expand Down Expand Up @@ -56,10 +57,18 @@ public class BAMIndexer {
* @param output binary BAM Index (.bai) file
* @param fileHeader header for the corresponding bam file
*/
public BAMIndexer(final File output, final SAMFileHeader fileHeader) {
public BAMIndexer(final Path output, final SAMFileHeader fileHeader) {
this(fileHeader, numRefs -> new BinaryBAMIndexWriter(numRefs, output));
}

/**
* @param output binary BAM Index (.bai) file
* @param fileHeader header for the corresponding bam file
*/
public BAMIndexer(final File output, final SAMFileHeader fileHeader) {
this(output.toPath(), fileHeader);
}

/**
* Prepare to index a BAM.
*
Expand Down Expand Up @@ -283,9 +292,9 @@ void startNewReference() {
* Generates a BAM index file from an input BAM file
*
* @param reader SamReader for input BAM file
* @param output File for output index file
* @param output Path for output index file
*/
public static void createIndex(SamReader reader, File output) {
public static void createIndex(SamReader reader, Path output) {
createIndex(reader, output, null);
}

Expand All @@ -295,7 +304,17 @@ public static void createIndex(SamReader reader, File output) {
* @param reader SamReader for input BAM file
* @param output File for output index file
*/
public static void createIndex(SamReader reader, File output, Log log) {
public static void createIndex(SamReader reader, File output) {
createIndex(reader, output.toPath(), null);
}

/**
* Generates a BAM index file from an input BAM file
*
* @param reader SamReader for input BAM file
* @param output Path for output index file
*/
public static void createIndex(SamReader reader, Path output, Log log) {

BAMIndexer indexer = new BAMIndexer(output, reader.getFileHeader());

Expand All @@ -310,4 +329,14 @@ public static void createIndex(SamReader reader, File output, Log log) {
}
indexer.finish();
}

/**
* Generates a BAM index file from an input BAM file
*
* @param reader SamReader for input BAM file
* @param output File for output index file
*/
public static void createIndex(SamReader reader, File output, Log log) {
createIndex(reader, output.toPath(), log);
}
}
11 changes: 10 additions & 1 deletion src/main/java/htsjdk/samtools/BinaryBAMIndexWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Path;
import java.util.List;

/**
Expand All @@ -41,12 +42,20 @@ class BinaryBAMIndexWriter implements BAMIndexWriter {
private int count = 0;

/**
* constructor
*
* @param nRef Number of reference sequences
* @param output BAM Index output file
*/
public BinaryBAMIndexWriter(final int nRef, final File output) {
this(nRef, null == output ? null : output.toPath());
}

/**
*
* @param nRef Number of reference sequences
* @param output BAM Index output file
*/
public BinaryBAMIndexWriter(final int nRef, final Path output) {

this.nRef = nRef;

Expand Down
Loading

0 comments on commit a8a680f

Please sign in to comment.