/*******************************************************************************
* Copyright 2013 EMBL-EBI
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package htsjdk.samtools;
import htsjdk.samtools.cram.lossy.PreservationPolicy;
import htsjdk.samtools.util.CloseableIterator;
import htsjdk.samtools.util.Log;
import htsjdk.samtools.util.Log.LogLevel;
import htsjdk.samtools.util.StringLineReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Set;
import net.sf.cram.ref.ReferenceSource;
@SuppressWarnings("UnusedDeclaration")
public class CRAMFileWriter extends SAMFileWriterImpl {
private CRAMContainerStreamWriter cramContainerStream;
private final SAMFileHeader samFileHeader;
private final String fileName;
private static final Log log = Log.getInstance(CRAMFileWriter.class);
public CRAMFileWriter(final OutputStream outputStream, final ReferenceSource referenceSource,
final SAMFileHeader samFileHeader, final String fileName) {
this(outputStream, null, referenceSource, samFileHeader, fileName, 1); // defaults
// to
// presorted
// ==
// true
}
/**
* Create a CRAMFileWriter on an output stream. Requires input records to be
* presorted to match the sort order defined by the input
* {@code samFileHeader}.
*
* @param outputStream
* where to write the output. Can not be null.
* @param referenceSource
* reference source. Can not be null.
* @param samFileHeader
* {@link SAMFileHeader} to be used. Can not be null. Sort order
* is determined by the sortOrder property of this arg.
* @param fileName
* used for display in error messages
*
* @throws IllegalArgumentException
* if the {@code outputStream}, {@code referenceSource} or
* {@code samFileHeader} are null
*/
public CRAMFileWriter(final OutputStream outputStream, final ReferenceSource referenceSource,
final SAMFileHeader samFileHeader, final String fileName, final int maxThreads) {
this(outputStream, null, referenceSource, samFileHeader, fileName, maxThreads); // defaults
// to
// presorted
// ==
// true
}
/**
* Create a CRAMFileWriter and optional index on output streams. Requires
* input records to be presorted to match the sort order defined by the
* input {@code samFileHeader}.
*
* @param outputStream
* where to write the output. Can not be null.
* @param indexOS
* where to write the output index. Can be null if no index is
* required.
* @param referenceSource
* reference source
* @param samFileHeader
* {@link SAMFileHeader} to be used. Can not be null. Sort order
* is determined by the sortOrder property of this arg.
* @param fileName
* used for display in error messages
*
* @throws IllegalArgumentException
* if the {@code outputStream}, {@code referenceSource} or
* {@code samFileHeader} are null
*/
public CRAMFileWriter(final OutputStream outputStream, final OutputStream indexOS,
final ReferenceSource referenceSource, final SAMFileHeader samFileHeader, final String fileName,
int maxThreads) {
this(outputStream, indexOS, true, referenceSource, samFileHeader, fileName, maxThreads); // defaults
// to
// presorted==true
}
/**
* Create a CRAMFileWriter and optional index on output streams.
*
* @param outputStream
* where to write the output. Can not be null.
* @param indexOS
* where to write the output index. Can be null if no index is
* required.
* @param presorted
* if true records written to this writer must already be sorted
* in the order specified by the header
* @param referenceSource
* reference source
* @param samFileHeader
* {@link SAMFileHeader} to be used. Can not be null. Sort order
* is determined by the sortOrder property of this arg.
* @param fileName
* used for display in error message display
*
* @throws IllegalArgumentException
* if the {@code outputStream}, {@code referenceSource} or
* {@code samFileHeader} are null
*/
public CRAMFileWriter(final OutputStream outputStream, final OutputStream indexOS, final boolean presorted,
final ReferenceSource referenceSource, final SAMFileHeader samFileHeader, final String fileName,
int maxThreads) {
if (outputStream == null) {
throw new IllegalArgumentException("CRAMWriter output stream can not be null.");
}
if (referenceSource == null) {
throw new IllegalArgumentException("A reference is required for CRAM writers");
}
if (samFileHeader == null) {
throw new IllegalArgumentException("A valid SAMFileHeader is required for CRAM writers");
}
this.samFileHeader = samFileHeader;
this.fileName = fileName;
setSortOrder(samFileHeader.getSortOrder(), presorted);
cramContainerStream = new CRAMContainerAsynchWriter(outputStream, indexOS, referenceSource, samFileHeader,
fileName, maxThreads);
setHeader(samFileHeader);
}
public static void main(String[] args) throws IOException {
Log.setGlobalLogLevel(LogLevel.INFO);
File bamFile = new File(args[0]);
File outCramFile = new File(args[1]);
ReferenceSource source = new ReferenceSource(new File(args[2]));
int maxThreads = Integer.valueOf(args[3]);
BAMFileReader reader = new BAMFileReader(bamFile, null, false, false, ValidationStringency.SILENT,
new DefaultSAMRecordFactory());
OutputStream os = new FileOutputStream(outCramFile);
CRAMFileWriter writer = new CRAMFileWriter(os, source, reader.getFileHeader(), outCramFile.getName(),
maxThreads);
CloseableIterator<SAMRecord> iterator = reader.getIterator();
while (iterator.hasNext()) {
SAMRecord record = iterator.next();
writer.addAlignment(record);
}
writer.close();
reader.close();
}
/**
* Write an alignment record.
*
* @param alignment
* must not be null and must have a valid SAMFileHeader.
*/
@Override
protected void writeAlignment(final SAMRecord alignment) {
cramContainerStream.writeAlignment(alignment);
}
@Override
protected void writeHeader(final String textHeader) {
cramContainerStream.writeHeader(new SAMTextHeaderCodec().decode(new StringLineReader(textHeader),
fileName != null ? fileName : null));
}
@Override
protected void finish() {
cramContainerStream.finish(true); // flush the last container and issue
// EOF
}
@Override
protected String getFilename() {
return fileName;
}
public boolean isPreserveReadNames() {
return cramContainerStream.lossyOptions.isPreserveReadNames();
}
public void setPreserveReadNames(final boolean preserveReadNames) {
cramContainerStream.lossyOptions.setPreserveReadNames(preserveReadNames);
}
public List<PreservationPolicy> getPreservationPolicies() {
return cramContainerStream.lossyOptions.getPreservation().getPreservationPolicies();
}
public boolean isCaptureAllTags() {
return cramContainerStream.lossyOptions.isCaptureAllTags();
}
public void setCaptureAllTags(final boolean captureAllTags) {
cramContainerStream.lossyOptions.setCaptureAllTags(captureAllTags);
}
public Set<String> getCaptureTags() {
return cramContainerStream.lossyOptions.getCaptureTags();
}
public void setCaptureTags(final Set<String> captureTags) {
cramContainerStream.lossyOptions.setCaptureTags(captureTags);
}
public Set<String> getIgnoreTags() {
return cramContainerStream.lossyOptions.getIgnoreTags();
}
public void setIgnoreTags(final Set<String> ignoreTags) {
cramContainerStream.lossyOptions.setIgnoreTags(ignoreTags);
}
}