public Node addSAMRecord(SAMRecord record, ReferenceSequence sequence) throws Exception
{
Alignment alignment;
PriorityQueue<Node> nodeQueue = null;
int i, ref_i, offset, node_type, alignment_start, alignment_reference_index;
Node prev=null, cur=null, ret=null;
boolean strand = false;
// DEBUG
//String readName = record.getReadName();
alignment_start = record.getAlignmentStart();
alignment_reference_index = record.getReferenceIndex();
if(alignment_reference_index != sequence.getContigIndex()) {
throw new Exception("SAMRecord contig does not match the current reference sequence contig");
}
// Get the alignment
alignment = new Alignment(record, sequence);
strand = record.getReadNegativeStrandFlag();
synchronized (this) {
/*
System.err.println("HERE alignment_start=" + alignment_start
+ " this.position_start=" + this.position_start
+ " this.position_end=" + this.position_end);
*/
//alignment.print(System.err);
//System.err.println("Cigar=" + record.getCigar().toString());
if(alignment_start < this.position_start) {
for(i=alignment_start;i<this.position_start;i++) {
this.nodes.add(0, new PriorityQueue<Node>(1, this.nodeComparator));
this.coverage.add(0, new Integer(0));
}
this.position_start = alignment_start;
}
// Reset if there are no nodes
if(this.isEmpty) {
this.position_start = alignment_start;
if(Alignment.GAP == alignment.reference[0]) { // insertion
this.position_start--;
}
// TODO: could be insertions then deletions at the start, which will cause errors, not implemented yet
this.position_end = this.position_start;
this.contig = alignment_reference_index + 1;
this.nodes.clear();
this.coverage.clear();
this.nodes.add(new PriorityQueue<Node>(1, this.nodeComparator));
this.coverage.add(new Integer(0));
this.isEmpty = false;
}
}
/* Reminders:
i - index from 0 to 'alignment.length'
ref_i - index within 'alignment.reference'
*/
for(i=0,ref_i=-1;i<alignment.length;i++,prev=cur)
{ // go through the alignment
// Skip over a deletion
while(i<alignment.length && Alignment.GAP == alignment.read[i]) {
i++;
ref_i++;
}
if(alignment.length <= i) {
break;
}
// Get the node type
if(alignment.read[i] == alignment.reference[i]) { // match
node_type = Node.MATCH;
}
else if(alignment.reference[i] == Alignment.GAP) { // insertion
node_type = Node.INSERTION;
}
else { // mismatch
node_type = Node.MISMATCH;
}
if(null == prev || Node.INSERTION != prev.type) { // previous was an insertion, already on the position
ref_i++;
}
// Create the node
cur = this.addNode(new Node((char)alignment.read[i],
node_type,
alignment_reference_index + 1,
alignment_start + ref_i,
prev,
this.nodeRecordComparator),