diff --git a/protected/java/src/org/broadinstitute/sting/gatk/walkers/haplotypecaller/graphs/BaseGraph.java b/protected/java/src/org/broadinstitute/sting/gatk/walkers/haplotypecaller/graphs/BaseGraph.java index bd179ef41..a1ec13882 100644 --- a/protected/java/src/org/broadinstitute/sting/gatk/walkers/haplotypecaller/graphs/BaseGraph.java +++ b/protected/java/src/org/broadinstitute/sting/gatk/walkers/haplotypecaller/graphs/BaseGraph.java @@ -95,10 +95,13 @@ public class BaseGraph extends Default */ public boolean isReferenceNode( final V v ) { if( v == null ) { throw new IllegalArgumentException("Attempting to test a null vertex."); } - for( final BaseEdge e : edgesOf(v) ) { - if( e.isRef() ) { return true; } + + for ( final BaseEdge e : edgesOf(v) ) { + if ( e.isRef() ) { return true; } } - return false; + + // edge case: if the graph only has one node then it's a ref node, otherwise it's not + return (vertexSet().size() == 1); } /** @@ -154,62 +157,46 @@ public class BaseGraph extends Default return v.getAdditionalSequence(isSource(v)); } - /** - * @param e the edge to test - * @return true if this edge is a reference source edge - */ - public boolean isRefSource( final E e ) { - if( e == null ) { throw new IllegalArgumentException("Attempting to test a null edge."); } - for( final E edgeToTest : incomingEdgesOf(getEdgeSource(e)) ) { - if( edgeToTest.isRef() ) { return false; } - } - return true; - } - /** * @param v the vertex to test * @return true if this vertex is a reference source */ public boolean isRefSource( final V v ) { if( v == null ) { throw new IllegalArgumentException("Attempting to test a null vertex."); } - for( final E edgeToTest : incomingEdgesOf(v) ) { - if( edgeToTest.isRef() ) { return false; } + + // confirm that no incoming edges are reference edges + for ( final E edgeToTest : incomingEdgesOf(v) ) { + if ( edgeToTest.isRef() ) { return false; } } - return true; + + // confirm that there is an outgoing reference edge + for ( final E edgeToTest : outgoingEdgesOf(v) ) { + if ( edgeToTest.isRef() ) { return true; } + } + + // edge case: if the graph only has one node then it's a ref sink, otherwise it's not + return (vertexSet().size() == 1); } /** - * @param e the edge to test - * @return true if this edge is a reference sink edge - */ - public boolean isRefSink( final E e ) { - if( e == null ) { throw new IllegalArgumentException("Attempting to test a null edge."); } - for( final E edgeToTest : outgoingEdgesOf(getEdgeTarget(e)) ) { - if( edgeToTest.isRef() ) { return false; } - } - return true; - } - - /** - * // TODO -- the logic of this test is just wrong * @param v the vertex to test * @return true if this vertex is a reference sink */ public boolean isRefSink( final V v ) { if( v == null ) { throw new IllegalArgumentException("Attempting to test a null vertex."); } - for( final E edgeToTest : outgoingEdgesOf(v) ) { - if( edgeToTest.isRef() ) { return false; } - } - return true; - } - /** - * Is this both a refsink node and a reference node - * @param v a non-null vertex - * @return true if v is both a sink and a reference node - */ - public boolean isRefNodeAndRefSink(final V v) { - return isRefSink(v) && isReferenceNode(v); + // confirm that no outgoing edges are reference edges + for ( final E edgeToTest : outgoingEdgesOf(v) ) { + if ( edgeToTest.isRef() ) { return false; } + } + + // confirm that there is an incoming reference edge + for ( final E edgeToTest : incomingEdgesOf(v) ) { + if ( edgeToTest.isRef() ) { return true; } + } + + // edge case: if the graph only has one node then it's a ref source, otherwise it's not + return (vertexSet().size() == 1); } /** @@ -217,7 +204,7 @@ public class BaseGraph extends Default */ public V getReferenceSourceVertex( ) { for( final V v : vertexSet() ) { - if( isReferenceNode(v) && isRefSource(v) ) { + if( isRefSource(v) ) { return v; } } @@ -229,7 +216,7 @@ public class BaseGraph extends Default */ public V getReferenceSinkVertex( ) { for( final V v : vertexSet() ) { - if( isReferenceNode(v) && isRefSink(v) ) { + if( isRefSink(v) ) { return v; } } @@ -490,7 +477,7 @@ public class BaseGraph extends Default // Run through the graph and clean up singular orphaned nodes final List verticesToRemove = new LinkedList<>(); for( final V v : vertexSet() ) { - if( inDegreeOf(v) == 0 && outDegreeOf(v) == 0 ) { + if( inDegreeOf(v) == 0 && outDegreeOf(v) == 0 && !isRefSource(v) ) { verticesToRemove.add(v); } } diff --git a/protected/java/src/org/broadinstitute/sting/gatk/walkers/haplotypecaller/readthreading/ReadThreadingGraph.java b/protected/java/src/org/broadinstitute/sting/gatk/walkers/haplotypecaller/readthreading/ReadThreadingGraph.java index 2a94ece96..04671a178 100644 --- a/protected/java/src/org/broadinstitute/sting/gatk/walkers/haplotypecaller/readthreading/ReadThreadingGraph.java +++ b/protected/java/src/org/broadinstitute/sting/gatk/walkers/haplotypecaller/readthreading/ReadThreadingGraph.java @@ -487,7 +487,7 @@ public class ReadThreadingGraph extends BaseGraph kept = new LinkedList(graph.vertexSet()); final SeqVertex rm1 = new SeqVertex("CAGT"); @@ -116,6 +116,52 @@ public class BaseGraphUnitTest extends BaseTest { Assert.assertFalse(graph.containsVertex(rm2)); } + @Test + public void testRemoveSingletonOrphanVerticesOnSingleRefNode() throws Exception { + final SeqGraph original = new SeqGraph(); + original.addVertex(v1); + original.removeSingletonOrphanVertices(); + Assert.assertTrue(original.containsVertex(v1)); + Assert.assertEquals(original.vertexSet().size(), 1); + } + + @Test + public void testIsRefSourceAndSink() throws Exception { + + final SeqGraph g = new SeqGraph(); + g.addVertex(v1); + Assert.assertTrue(g.isRefSource(v1)); + Assert.assertTrue(g.isRefSink(v1)); + Assert.assertTrue(g.isReferenceNode(v1)); + + g.addVertices(v2, v3, v4, v5); + g.addEdge(v1, v2); + g.addEdge(v2, v3); + final BaseEdge refEdge = new BaseEdge(true, 1); + g.addEdge(v3, v4, refEdge); + g.addEdge(v4, v5); + + Assert.assertFalse(g.isRefSource(v1)); + Assert.assertFalse(g.isRefSink(v1)); + Assert.assertFalse(g.isReferenceNode(v1)); + + Assert.assertFalse(g.isRefSource(v2)); + Assert.assertFalse(g.isRefSink(v2)); + Assert.assertFalse(g.isReferenceNode(v2)); + + Assert.assertTrue(g.isRefSource(v3)); + Assert.assertFalse(g.isRefSink(v3)); + Assert.assertTrue(g.isReferenceNode(v3)); + + Assert.assertFalse(g.isRefSource(v4)); + Assert.assertTrue(g.isRefSink(v4)); + Assert.assertTrue(g.isReferenceNode(v4)); + + Assert.assertFalse(g.isRefSource(v5)); + Assert.assertFalse(g.isRefSink(v5)); + Assert.assertFalse(g.isReferenceNode(v5)); + } + @Test public void testRemovePathsNotConnectedToRef() throws Exception { final SeqGraph graph = new SeqGraph();