samFileWriterFactory.setAsyncOutputBufferSize(10000);
samFileWriterFactory.setCreateIndex(false);
samFileWriterFactory.setCreateMd5File(false);
samFileWriterFactory.setUseAsyncIo(true);
SAMFileWriter writer = createSAMFileWriter(params, cramHeader,
samFileWriterFactory);
Container c = null;
AlignmentSliceQuery location = null;
if (!params.locations.isEmpty() && params.cramFile != null
&& is instanceof SeekableStream) {
if (params.locations.size() > 1)
throw new RuntimeException("Only one location is supported.");
location = new AlignmentSliceQuery(params.locations.get(0));
c = skipToContainer(params.cramFile, cramHeader,
(SeekableStream) is, location);
if (c == null) {
log.error("Index file not found. ");
return;
}
}
long recordCount = 0;
long readTime = 0;
long parseTime = 0;
long normTime = 0;
long samTime = 0;
long writeTime = 0;
long time = 0;
ArrayList<CramRecord> cramRecords = new ArrayList<CramRecord>(10000);
CramNormalizer n = new CramNormalizer(cramHeader.samFileHeader);
byte[] ref = null;
int prevSeqId = -1;
while (true) {
// try {
time = System.nanoTime();
// cis = new CountingInputStream(is);
c = ReadWrite.readContainer(cramHeader.samFileHeader, is);
if (c == null) break ;
// c.offset = offset;
// offset += cis.getCount();
readTime += System.nanoTime() - time;
// } catch (EOFException e) {
// break;
// }
// for random access check if the sequence is the one look for:
if (location != null
&& cramHeader.samFileHeader.getSequence(location.sequence)
.getSequenceIndex() != c.sequenceId)
break;
if (params.countOnly && params.requiredFlags == 0
&& params.filteringFlags == 0) {
recordCount += c.nofRecords;
continue;
}
try {
time = System.nanoTime();
cramRecords.clear();
BLOCK_PROTO.getRecords(c.h, c, cramHeader.samFileHeader,
cramRecords);
parseTime += System.nanoTime() - time;
} catch (EOFException e) {
throw e;
}
if (c.sequenceId == SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX) {
ref = new byte[] {};
} else if (prevSeqId < 0 || prevSeqId != c.sequenceId) {
SAMSequenceRecord sequence = cramHeader.samFileHeader
.getSequence(c.sequenceId);
ReferenceSequence referenceSequence = Utils
.trySequenceNameVariants(referenceSequenceFile,
sequence.getSequenceName());
ref = referenceSequence.getBases();
{
// hack:
int newLines = 0;
for (byte b : ref)
if (b == 10)
newLines++;
byte[] ref2 = new byte[ref.length - newLines];
int j = 0;
for (int i = 0; i < ref.length; i++)
if (ref[i] == 10)
continue;
else
ref2[j++] = ref[i];
ref = ref2;
}
prevSeqId = c.sequenceId;
}
long time1 = System.nanoTime();
n.normalize(cramRecords, true, ref, c.alignmentStart, c.h.substitutionMatrix, c.h.AP_seriesDelta);
long time2 = System.nanoTime();
normTime += time2 - time1;
Cram2BamRecordFactory c2sFactory = new Cram2BamRecordFactory(
cramHeader.samFileHeader);
long c2sTime = 0;
long sWriteTime = 0;
boolean enough = false;
for (CramRecord r : cramRecords) {
// check if the record ends before the query start:
if (location != null && r.getAlignmentStart() < location.start)
continue;
time = System.nanoTime();
SAMRecord s = c2sFactory.create(r);
if (params.requiredFlags != 0
&& ((params.requiredFlags & s.getFlags()) == 0))
continue;
if (params.filteringFlags != 0
&& ((params.filteringFlags & s.getFlags()) != 0))
continue;
if (params.countOnly) {
recordCount++;
continue;
}
if (ref != null)
Utils.calculateMdAndNmTags(s, ref, params.calculateMdTag,
params.calculateNmTag);
c2sTime += System.nanoTime() - time;
samTime += System.nanoTime() - time;
time = System.nanoTime();
writer.addAlignment(s);
sWriteTime += System.nanoTime() - time;
writeTime += System.nanoTime() - time;
if (params.outputFile == null && System.out.checkError())
break;
// we got all the reads for random access:
if (location != null && location.end < s.getAlignmentStart()) {
enough = true;
break;
}
}
log.info(String
.format("CONTAINER READ: io %dms, parse %dms, norm %dms, convert %dms, BAM write %dms",
c.readTime / 1000000, c.parseTime / 1000000,
(time2 - time1) / 1000000, c2sTime / 1000000,
sWriteTime / 1000000));
if (enough
|| (params.outputFile == null && System.out.checkError()))
break;
}
if (params.countOnly)
System.out.println(recordCount);
// if (writer instanceof SAMTextWriter)
// ((SAMTextWriter)writer).getWriter().flush() ;
writer.close();
log.warn(String
.format("TIMES: io %ds, parse %ds, norm %ds, convert %ds, BAM write %ds",
readTime / 1000000000, parseTime / 1000000000,
normTime / 1000000000, samTime / 1000000000,