add methods for node coverage merge/add; serialize coverage
diff --git a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/data/Marshal.java b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/data/Marshal.java
index f61cb6f..90def56 100644
--- a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/data/Marshal.java
+++ b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/data/Marshal.java
@@ -34,6 +34,10 @@
// + ((bytes[offset + 6] & 0xff) << 8) + ((bytes[offset + 7] & 0xff) << 0);
}
+ public static float getFloat(byte[] bytes, int offset) {
+ return ByteBuffer.wrap(bytes, offset, 4).getFloat();
+ }
+
public static void putInt(int val, byte[] bytes, int offset) {
bytes[offset] = (byte)((val >>> 24) & 0xFF);
bytes[offset + 1] = (byte)((val >>> 16) & 0xFF);
@@ -54,6 +58,11 @@
// bytes[offset + 7] = (byte)((val >>> 0) & 0xFF);
}
+ public static void putFloat(float val, byte[] bytes, int offset) {
+ ByteBuffer byteBuffer = ByteBuffer.allocate(4);
+ System.arraycopy(byteBuffer.putFloat(val).array(), 0, bytes, offset, 4);
+ }
+
public static int hashBytes(byte[] bytes, int offset, int length) {
int hash = 1;
for (int i = offset; i < offset + length; i++)
diff --git a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/NodeWritable.java b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/NodeWritable.java
index d61f679..22fd374 100644
--- a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/NodeWritable.java
+++ b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/NodeWritable.java
@@ -10,18 +10,23 @@
import org.apache.hadoop.io.DataOutputBuffer;
import org.apache.hadoop.io.WritableComparable;
+import edu.uci.ics.genomix.data.Marshal;
+
public class NodeWritable implements WritableComparable<NodeWritable>, Serializable{
private static final long serialVersionUID = 1L;
public static final NodeWritable EMPTY_NODE = new NodeWritable();
+ private static final int SIZE_FLOAT = 4;
+
private PositionListWritable nodeIdList;
private VKmerListWritable forwardForwardList;
private VKmerListWritable forwardReverseList;
private VKmerListWritable reverseForwardList;
private VKmerListWritable reverseReverseList;
private VKmerBytesWritable kmer;
+ private float averageCoverage;
// merge/update directions
public static class DirectionFlag {
@@ -39,27 +44,29 @@
reverseForwardList = new VKmerListWritable();
reverseReverseList = new VKmerListWritable();
kmer = new VKmerBytesWritable(); // in graph construction - not set kmerlength Optimization: VKmer
+ averageCoverage = 0;
}
public NodeWritable(PositionListWritable nodeIdList, VKmerListWritable FFList, VKmerListWritable FRList,
- VKmerListWritable RFList, VKmerListWritable RRList, VKmerBytesWritable kmer) {
+ VKmerListWritable RFList, VKmerListWritable RRList, VKmerBytesWritable kmer, float coverage) {
this();
- set(nodeIdList, FFList, FRList, RFList, RRList, kmer);
+ set(nodeIdList, FFList, FRList, RFList, RRList, kmer, coverage);
}
public void set(NodeWritable node){
set(node.nodeIdList, node.forwardForwardList, node.forwardReverseList, node.reverseForwardList,
- node.reverseReverseList, node.kmer);
+ node.reverseReverseList, node.kmer, node.averageCoverage);
}
public void set(PositionListWritable nodeIdList, VKmerListWritable FFList, VKmerListWritable FRList,
- VKmerListWritable RFList, VKmerListWritable RRList, VKmerBytesWritable kmer2) {
+ VKmerListWritable RFList, VKmerListWritable RRList, VKmerBytesWritable kmer2, float coverage) {
this.nodeIdList.set(nodeIdList);
this.forwardForwardList.setCopy(FFList);
this.forwardReverseList.setCopy(FRList);
this.reverseForwardList.setCopy(RFList);
this.reverseReverseList.setCopy(RRList);
this.kmer.setAsCopy(kmer2);
+ this.averageCoverage = coverage;
}
public void reset() {
@@ -69,6 +76,7 @@
this.reverseForwardList.reset();
this.reverseReverseList.reset();
this.kmer.reset(0);
+ averageCoverage = 0;
}
@@ -140,11 +148,40 @@
}
/**
+ * Update my coverage to be the average of this and other. Used when merging paths.
+ */
+ public void mergeCoverage(NodeWritable other) {
+ // sequence considered in the average doesn't include anything overlapping with other kmers
+ float adjustedLength = kmer.getKmerLetterLength() + other.kmer.getKmerLetterLength() - (KmerBytesWritable.getKmerLength() - 1) * 2;
+
+ float myCount = (kmer.getKmerLetterLength() - KmerBytesWritable.getKmerLength() - 1) * averageCoverage;
+ float otherCount = (other.kmer.getKmerLetterLength() - KmerBytesWritable.getKmerLength() - 1) * other.averageCoverage;
+ averageCoverage = (myCount + otherCount) / adjustedLength;
+ }
+
+ /**
+ * Update my coverage as if all the reads in other became my own
+ */
+ public void addCoverage(NodeWritable other) {
+ float myAdjustedLength = kmer.getKmerLetterLength() - KmerBytesWritable.getKmerLength() - 1;
+ float otherAdjustedLength = other.kmer.getKmerLetterLength() - KmerBytesWritable.getKmerLength() - 1;
+ averageCoverage += other.averageCoverage * (otherAdjustedLength / myAdjustedLength);
+ }
+
+ public void setAvgCoverage(float coverage) {
+ averageCoverage = coverage;
+ }
+
+ public float getAvgCoverage() {
+ return averageCoverage;
+ }
+
+ /**
* Returns the length of the byte-array version of this node
*/
public int getSerializedLength() {
return nodeIdList.getLength() + forwardForwardList.getLength() + forwardReverseList.getLength() +
- reverseForwardList.getLength() + reverseReverseList.getLength() + kmer.getLength();
+ reverseForwardList.getLength() + reverseReverseList.getLength() + kmer.getLength() + SIZE_FLOAT;
}
/**
@@ -172,6 +209,9 @@
curOffset += reverseReverseList.getLength();
kmer.setAsCopy(data, curOffset);
+
+ curOffset += kmer.getLength();
+ averageCoverage = Marshal.getFloat(data, curOffset);
}
public void setAsReference(byte[] data, int offset) {
@@ -189,6 +229,9 @@
curOffset += reverseReverseList.getLength();
kmer.setAsReference(data, curOffset);
+
+ curOffset += kmer.getLength();
+ averageCoverage = Marshal.getFloat(data, curOffset);
}
@Override
@@ -199,6 +242,7 @@
this.reverseForwardList.write(out);
this.reverseReverseList.write(out);
this.kmer.write(out);
+ out.writeFloat(averageCoverage);
}
@Override
@@ -210,6 +254,7 @@
this.reverseForwardList.readFields(in);
this.reverseReverseList.readFields(in);
this.kmer.readFields(in);
+ averageCoverage = in.readFloat();
}
@Override