add Synchronized to the has_next and next methods

git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@301 348d0f76-0448-11de-a6fe-93d51630548a
This commit is contained in:
aaron 2009-04-06 21:17:11 +00:00
parent 97d14abe85
commit af5a443e5a
2 changed files with 98 additions and 66 deletions

View File

@ -50,8 +50,8 @@ public class MergingSamRecordIterator2 implements Iterator<SAMRecord> {
final SAMRecordComparator comparator = getComparator();
for (final SAMFileReader reader : samHeaderMerger.getReaders()) {
if (this.sortOrder != SAMFileHeader.SortOrder.unsorted && reader.getFileHeader().getSortOrder() != this.sortOrder){
throw new PicardException("Files are not compatible with sort order: " + this.sortOrder );
if (this.sortOrder != SAMFileHeader.SortOrder.unsorted && reader.getFileHeader().getSortOrder() != this.sortOrder) {
throw new PicardException("Files are not compatible with sort order: " + reader.getFileHeader().getSortOrder() + " vrs " + this.sortOrder);
}
final ComparableSamRecordIterator iterator = new ComparableSamRecordIterator(reader, comparator);
@ -59,18 +59,41 @@ public class MergingSamRecordIterator2 implements Iterator<SAMRecord> {
}
}
/**
* Constructs a new merging iterator with the same set of readers and sort order as
* provided by the header merger parameter.
*/
public MergingSamRecordIterator2(MergingSamRecordIterator2 iter) {
this.samHeaderMerger = iter.samHeaderMerger;
this.sortOrder = iter.sortOrder;
initializePQ();
final SAMRecordComparator comparator = getComparator();
for (final SAMFileReader reader : samHeaderMerger.getReaders()) {
if (this.sortOrder != SAMFileHeader.SortOrder.unsorted && reader.getFileHeader().getSortOrder() != this.sortOrder) {
throw new PicardException("Files are not compatible with sort order: " + this.sortOrder);
}
final ComparableSamRecordIterator iterator = new ComparableSamRecordIterator(reader, comparator);
addIfNotEmpty(iterator);
}
}
protected void initializePQ() {
this.pq = new PriorityQueue<ComparableSamRecordIterator>(samHeaderMerger.getReaders().size());
}
public boolean supportsSeeking() { return true; }
public boolean supportsSeeking() {
return true;
}
public void queryOverlapping( final String contig, final int start, final int stop ) {
public void queryOverlapping(final String contig, final int start, final int stop) {
initializePQ(); // reinitialize the system
final SAMRecordComparator comparator = getComparator();
for (final SAMFileReader reader : samHeaderMerger.getReaders()) {
Iterator<SAMRecord> recordIter = reader.queryOverlapping( contig, start, stop);
Iterator<SAMRecord> recordIter = reader.queryOverlapping(contig, start, stop);
final ComparableSamRecordIterator iterator = new ComparableSamRecordIterator(reader, recordIter, comparator);
addIfNotEmpty(iterator);
}
@ -80,7 +103,7 @@ public class MergingSamRecordIterator2 implements Iterator<SAMRecord> {
initializePQ(); // reinitialize the system
final SAMRecordComparator comparator = getComparator();
for (final SAMFileReader reader : samHeaderMerger.getReaders()) {
Iterator<SAMRecord> recordIter = reader.query( contig, start, stop, contained);
Iterator<SAMRecord> recordIter = reader.query(contig, start, stop, contained);
final ComparableSamRecordIterator iterator = new ComparableSamRecordIterator(reader, recordIter, comparator);
addIfNotEmpty(iterator);
}
@ -90,19 +113,19 @@ public class MergingSamRecordIterator2 implements Iterator<SAMRecord> {
initializePQ(); // reinitialize the system
final SAMRecordComparator comparator = getComparator();
for (final SAMFileReader reader : samHeaderMerger.getReaders()) {
Iterator<SAMRecord> recordIter = reader.queryContained( contig, start, stop );
Iterator<SAMRecord> recordIter = reader.queryContained(contig, start, stop);
final ComparableSamRecordIterator iterator = new ComparableSamRecordIterator(reader, recordIter, comparator);
addIfNotEmpty(iterator);
}
}
/** Returns true if any of the underlying iterators has more records, otherwise false. */
public boolean hasNext() {
public synchronized boolean hasNext() {
return !this.pq.isEmpty();
}
/** Returns the next record from the top most iterator during merging. */
public SAMRecord next() {
public synchronized SAMRecord next() {
final ComparableSamRecordIterator iterator = this.pq.poll();
final SAMRecord record = iterator.next();
addIfNotEmpty(iterator);
@ -131,8 +154,7 @@ public class MergingSamRecordIterator2 implements Iterator<SAMRecord> {
//System.out.printf("Adding %s %s %d%n", iterator.peek().getReadName(), iterator.peek().getReferenceName(), iterator.peek().getAlignmentStart());
if (iterator.hasNext()) {
pq.offer(iterator);
}
else {
} else {
iterator.close();
}
}
@ -196,7 +218,7 @@ class ComparableSamRecordIterator extends PeekableIterator<SAMRecord> implements
* able to compare itself to other ComparableSAMRecordIterator instances using
* the supplied comparator for ordering SAMRecords.
*
* @param sam the SAM file to read records from
* @param sam the SAM file to read records from
* @param comparator the Comparator to use to provide ordering fo SAMRecords
*/
public ComparableSamRecordIterator(final SAMFileReader sam, final Comparator<SAMRecord> comparator) {

View File

@ -1,17 +1,14 @@
package org.broadinstitute.sting.gatk.iterators;
import edu.mit.broad.picard.reference.ReferenceSequenceFile;
import edu.mit.broad.picard.reference.ReferenceSequence;
import net.sf.samtools.util.StringUtil;
import net.sf.samtools.util.RuntimeIOException;
import net.sf.samtools.util.StringUtil;
import org.apache.log4j.Logger;
import org.broadinstitute.sting.utils.FastaSequenceFile2;
import org.broadinstitute.sting.utils.GenomeLoc;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.io.IOException;
import org.broadinstitute.sting.utils.GenomeLoc;
import org.broadinstitute.sting.utils.FastaSequenceFile2;
import org.apache.log4j.Logger;
/**
* Created by IntelliJ IDEA.
@ -32,61 +29,74 @@ public class ReferenceIterator implements Iterator<ReferenceIterator> {
//private ReferenceSequence nextContig = null;
private long offset = -1;
public ReferenceIterator( FastaSequenceFile2 refFile ) {
public ReferenceIterator(FastaSequenceFile2 refFile) {
this.refFile = refFile;
}
/**
* our log, which we want to capture anything from this class
*/
/** our log, which we want to capture anything from this class */
private static Logger logger = Logger.getLogger(ReferenceIterator.class);
// --------------------------------------------------------------------------------------------------------------
//
// Accessing data
//
// --------------------------------------------------------------------------------------------------------------
public byte getBaseAsByte() { return currentContig.getBases()[(int)offset]; }
public String getBaseAsString() {
assert offset > -1 : currentContig.getName() + " index is " + offset;
//assert offset < currentContig.getBases().();
return StringUtil.bytesToString(currentContig.getBases(), (int)offset, 1);
public byte getBaseAsByte() {
return currentContig.getBases()[(int) offset];
}
public char getBaseAsChar() { return getBaseAsString().charAt(0); }
public ReferenceSequence getCurrentContig() { return currentContig; }
public long getPosition() { return offset + 1; }
public GenomeLoc getLocation() { return new GenomeLoc( getCurrentContig().getName(), getPosition() ); }
public String getBaseAsString() {
assert offset > -1 : currentContig.getName() + " index is " + offset;
//assert offset < currentContig.getBases().();
return StringUtil.bytesToString(currentContig.getBases(), (int) offset, 1);
}
public char getBaseAsChar() {
return getBaseAsString().charAt(0);
}
public ReferenceSequence getCurrentContig() {
return currentContig;
}
public long getPosition() {
return offset + 1;
}
public GenomeLoc getLocation() {
return new GenomeLoc(getCurrentContig().getName(), getPosition());
}
// --------------------------------------------------------------------------------------------------------------
//
// Iterator routines
//
// --------------------------------------------------------------------------------------------------------------
public boolean hasNext() {
if ( currentContig == null || offset + 1 < currentContig.length() ) {
public synchronized boolean hasNext() {
if (currentContig == null || offset + 1 < currentContig.length()) {
return true;
}
else {
} else {
return readNextContig();
}
}
public ReferenceIterator next() {
if ( currentContig != null ) {
if ( DEBUG ) logger.debug(String.format(" -> %s:%d %d%n", currentContig.getName(), offset, currentContig.length()));
public synchronized ReferenceIterator next() {
if (currentContig != null) {
if (DEBUG)
logger.debug(String.format(" -> %s:%d %d%n", currentContig.getName(), offset, currentContig.length()));
}
offset++; // move on to the next position
if ( currentContig == null || offset >= currentContig.length() ) {
if (currentContig == null || offset >= currentContig.length()) {
// We need to update the contig
if ( readNextContig() ){
if (readNextContig()) {
// We sucessfully loaded the next contig, recursively call next
return next();
}
else {
} else {
throw new NoSuchElementException();
}
}
else {
} else {
// We're good to go -- we're in the current contig
return this;
}
@ -96,7 +106,7 @@ public class ReferenceIterator implements Iterator<ReferenceIterator> {
throw new UnsupportedOperationException();
}
// --------------------------------------------------------------------------------------------------------------
//
// Jumping forward
@ -104,7 +114,7 @@ public class ReferenceIterator implements Iterator<ReferenceIterator> {
// --------------------------------------------------------------------------------------------------------------
public ReferenceIterator seekForward(final GenomeLoc loc) {
assert loc != null : "seekForward location is null";
return seekForwardOffset(loc.getContig(), loc.getStart() - 1);
}
@ -115,25 +125,24 @@ public class ReferenceIterator implements Iterator<ReferenceIterator> {
/**
* Helper routine that doesn't move the contigs around, it just checks that everything is kosher in the seek
* within this chromosome
*
* @param seekContigName name for printing pursues, asserted to be the current contig name
* @param seekOffset where we want to be in this contig
* @return this setup to be at seekoffset within seekContigName
* @param seekOffset where we want to be in this contig
* @return this setup to be at seekoffset within seekContigName
*/
private ReferenceIterator seekForwardOffsetOnSameContig(final String seekContigName, final long seekOffset) {
assert seekContigName.equals(currentContig.getName()) : String.format("only works on this contig, but the current %s and sought %s contigs are different!", currentContig.getName(), seekContigName);
// we're somewhere on this contig
if ( seekOffset < offset ) {
if (seekOffset < offset) {
// bad boy -- can't go backward safely
throw new IllegalArgumentException(String.format("Invalid seek %s => %s, which is usually due to out of order reads%n",
new GenomeLoc(currentContig.getName(), offset), new GenomeLoc(currentContig.getName(), seekOffset)));
}
else if ( seekOffset >= currentContig.length() ) {
} else if (seekOffset >= currentContig.length()) {
// bad boy -- can't go beyond the contig length
throw new IllegalArgumentException(String.format("Invalid seek to %s, which is beyond the end of the contig%n",
new GenomeLoc(currentContig.getName(), seekOffset+1)));
}
else {
new GenomeLoc(currentContig.getName(), seekOffset + 1)));
} else {
offset = seekOffset - 1;
return next();
}
@ -145,23 +154,24 @@ public class ReferenceIterator implements Iterator<ReferenceIterator> {
assert seekOffset >= 0 : "seekOffset < 0: " + seekOffset;
// jumps us forward in the sequence to the contig / pos
if ( currentContig == null )
if (currentContig == null)
next();
if ( DEBUG ) logger.debug(String.format(" -> Seeking to %s %d from %s %d%n", seekContigName, seekOffset, currentContig.getName(), offset));
if (DEBUG)
logger.debug(String.format(" -> Seeking to %s %d from %s %d%n", seekContigName, seekOffset, currentContig.getName(), offset));
int cmpContigs = GenomeLoc.compareContigs(seekContigName, currentContig.getName());
if ( cmpContigs == -1 && false ) { // todo: fixed
if (cmpContigs == -1 && false) { // todo: fixed
// The contig we are looking for is before the currentContig -- it's an error
throw new IllegalArgumentException(String.format("Invalid seek %s => %s, which is usually due to out of order reads%n",
new GenomeLoc(currentContig.getName(), offset), new GenomeLoc(currentContig.getName(), seekOffset)));
}
else if ( cmpContigs == 1 ) {
} else if (cmpContigs == 1) {
// we need to jump forward
if ( DEBUG ) logger.debug(String.format(" -> Seeking in the fasta file to %s from %s%n", seekContigName, currentContig.getName()));
if (DEBUG)
logger.debug(String.format(" -> Seeking in the fasta file to %s from %s%n", seekContigName, currentContig.getName()));
if ( ! refFile.seekToContig(seekContigName) ) { // ok, do the seek
if (!refFile.seekToContig(seekContigName)) { // ok, do the seek
// a false result indicates a failure, throw a somewhat cryptic call
throw new RuntimeIOException(String.format("Unexpected seek failure from %s to %s%n",
new GenomeLoc(currentContig.getName(), offset), new GenomeLoc(currentContig.getName(), seekOffset)));
@ -171,7 +181,7 @@ public class ReferenceIterator implements Iterator<ReferenceIterator> {
}
// at this point, the current contig is seekContigName, so just do a bit more error checking and be done
return seekForwardOffsetOnSameContig( seekContigName, seekOffset );
return seekForwardOffsetOnSameContig(seekContigName, seekOffset);
}
@ -189,7 +199,7 @@ public class ReferenceIterator implements Iterator<ReferenceIterator> {
/**
* Simple forwarding method to the refFile itself
*
*
* @return
*/
public String nextContigName() {