Skip to content

Commit 334fa42

Browse files
committed
Add some kind of indep-mut-detection.
First stab at independent mutations.
1 parent f33bd01 commit 334fa42

File tree

11 files changed

+250
-16
lines changed

11 files changed

+250
-16
lines changed

dnainator-core/src/main/java/nl/tudelft/dnainator/graph/impl/command/AnalyzeCommand.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,22 @@ public void execute(GraphDatabaseService service) {
7979
// It is automatically closed after the try block, which frees the allocated memory.
8080
PrimitiveLongSet processed = Primitive.offHeapLongSet(INIT_CAP)
8181
) {
82+
System.out.println("executing");
83+
long start = System.nanoTime();
8284
for (Node n : topologicalOrder(service, processed)) {
8385
rankDest(n);
86+
scoreIndependentMutation(service, n);
8487
}
88+
System.out.println((System.nanoTime() - start) * 1e-6 + " ms");
8589
scoreDRMutations(service);
8690
tx.success();
8791
}
8892
}
8993

94+
private void scoreIndependentMutation(GraphDatabaseService service, Node n) {
95+
new MutationFinderCommand(n).execute(service);
96+
}
97+
9098
/**
9199
* Rank the destination nodes of the outgoing edges of the given node.
92100
* @param n the source node of the destination nodes to be ranked.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package nl.tudelft.dnainator.graph.impl.command;
2+
3+
import nl.tudelft.dnainator.graph.impl.RelTypes;
4+
import nl.tudelft.dnainator.graph.interestingness.Scores;
5+
6+
import org.neo4j.graphdb.Direction;
7+
import org.neo4j.graphdb.GraphDatabaseService;
8+
import org.neo4j.graphdb.Node;
9+
import org.neo4j.graphdb.Path;
10+
import org.neo4j.graphdb.Transaction;
11+
12+
import java.util.HashMap;
13+
import java.util.HashSet;
14+
import java.util.Map;
15+
import java.util.Set;
16+
17+
public class MutationFinderCommand implements Command {
18+
private Map<Node, Set<Node>> sources;
19+
private Node mutation;
20+
21+
public MutationFinderCommand(Node mutation) {
22+
this.mutation = mutation;
23+
this.sources = new HashMap<>();
24+
25+
}
26+
27+
@Override
28+
public void execute(GraphDatabaseService service) {
29+
Set<Node> commonancestors = new HashSet<>();
30+
try (Transaction tx = service.beginTx()) {
31+
for (Path p : service.traversalDescription()
32+
.breadthFirst()
33+
.relationships(RelTypes.SOURCE, Direction.OUTGOING)
34+
.relationships(RelTypes.ANCESTOR_OF, Direction.INCOMING)
35+
.evaluator(new PhyloEvaluator())
36+
.traverse(mutation)
37+
) {
38+
commonancestors.add(p.endNode());
39+
}
40+
mutation.setProperty(Scores.INDEP_MUT.name(), commonancestors.size());
41+
tx.success();
42+
}
43+
}
44+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package nl.tudelft.dnainator.graph.impl.command;
2+
3+
import nl.tudelft.dnainator.graph.impl.NodeLabels;
4+
import nl.tudelft.dnainator.graph.impl.RelTypes;
5+
6+
import org.neo4j.graphdb.Direction;
7+
import org.neo4j.graphdb.Node;
8+
import org.neo4j.graphdb.Path;
9+
import org.neo4j.graphdb.Relationship;
10+
import org.neo4j.graphdb.traversal.Evaluation;
11+
import org.neo4j.graphdb.traversal.Evaluator;
12+
13+
import java.util.HashSet;
14+
import java.util.Set;
15+
16+
public class PhyloEvaluator implements Evaluator {
17+
private Set<Node> clusters = new HashSet<>();
18+
19+
@Override
20+
public Evaluation evaluate(Path path) {
21+
if (path.endNode().hasLabel(NodeLabels.NODE)) {
22+
return Evaluation.EXCLUDE_AND_CONTINUE;
23+
} else if (path.endNode().hasLabel(NodeLabels.SOURCE)) {
24+
clusters.add(path.endNode());
25+
return Evaluation.EXCLUDE_AND_CONTINUE;
26+
}
27+
28+
for (Relationship rel : path.endNode().getRelationships(Direction.OUTGOING,
29+
RelTypes.ANCESTOR_OF)) {
30+
if (!clusters.contains(rel.getEndNode())) {
31+
return Evaluation.INCLUDE_AND_PRUNE;
32+
}
33+
}
34+
35+
clusters.add(path.endNode());
36+
return Evaluation.EXCLUDE_AND_CONTINUE;
37+
}
38+
39+
}

dnainator-core/src/main/java/nl/tudelft/dnainator/graph/interestingness/Scores.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ public int applyImportanceModifier(int rawScore) {
2222
}
2323
return multipliers[rawScore];
2424
}
25+
},
26+
INDEP_MUT("independentMutation") {
27+
@Override
28+
public int applyImportanceModifier(int rawScore) {
29+
return rawScore * 100;
30+
}
2531
};
2632

2733
private String name;

dnainator-core/src/test/java/nl/tudelft/dnainator/graph/impl/Neo4jGraphTest.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import java.util.stream.Collectors;
4141

4242
import static nl.tudelft.dnainator.graph.impl.properties.SequenceProperties.ID;
43-
4443
import static org.hamcrest.Matchers.lessThan;
4544
import static org.junit.Assert.assertEquals;
4645
import static org.junit.Assert.assertFalse;
@@ -111,9 +110,10 @@ private static File getTreeFile() throws URISyntaxException {
111110
@Test
112111
public void testNodeLookup() {
113112
// CHECKSTYLE.OFF: MagicNumber
114-
SequenceNode node1 = new SequenceNodeImpl("2", Arrays.asList("ASDF", "ASD"), 1, 5, "TATA");
115-
SequenceNode node2 = new SequenceNodeImpl("3", Arrays.asList("ASDF"), 5, 9, "TATA");
116-
SequenceNode node3 = new SequenceNodeImpl("5", Arrays.asList("ASDF"), 4, 8, "TATA");
113+
SequenceNode node1 = new SequenceNodeImpl("2", Arrays.asList("TKK_001",
114+
"TKK_002"), 1, 5, "TATA");
115+
SequenceNode node2 = new SequenceNodeImpl("3", Arrays.asList("TKK_001"), 5, 9, "TATA");
116+
SequenceNode node3 = new SequenceNodeImpl("5", Arrays.asList("TKK_001"), 4, 8, "TATA");
117117
assertEquals(node1, db.getNode("2"));
118118
assertEquals(node2, db.getNode("3"));
119119
assertEquals(node3, db.getNode("5"));
@@ -126,7 +126,7 @@ public void testNodeLookup() {
126126
@Test
127127
public void testRootLookup() {
128128
// CHECKSTYLE.OFF: MagicNumber
129-
SequenceNode root = new SequenceNodeImpl("5", Arrays.asList("ASDF"), 4, 8, "TATA");
129+
SequenceNode root = new SequenceNodeImpl("5", Arrays.asList("TKK_001"), 4, 8, "TATA");
130130
assertEquals(root, db.getRootNode());
131131
// CHECKSTYLE.ON: MagicNumber
132132
}
@@ -239,13 +239,13 @@ public void testQueryFilter() {
239239
@Test
240240
public void testQuerySources() {
241241
GraphQueryDescription qd = new GraphQueryDescription()
242-
.containsSource("ASDF");
242+
.containsSource("TKK_001");
243243
Set<String> expect = new HashSet<>();
244244
Collections.addAll(expect, "2", "5", "3", "7", "8", "11");
245245
assertUnorderedIDEquals(expect, db.queryNodes(qd));
246246

247247
// Also test for multiple sources (reusing the old one)
248-
qd = qd.containsSource("ASD");
248+
qd = qd.containsSource("TKK_002");
249249
Collections.addAll(expect, "9", "10");
250250
assertUnorderedIDEquals(expect, db.queryNodes(qd));
251251

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package nl.tudelft.dnainator.graph.impl.command;
2+
3+
import nl.tudelft.dnainator.annotation.impl.AnnotationCollectionImpl;
4+
import nl.tudelft.dnainator.annotation.impl.AnnotationImpl;
5+
import nl.tudelft.dnainator.core.EnrichedSequenceNode;
6+
import nl.tudelft.dnainator.core.impl.SequenceNodeFactoryImpl;
7+
import nl.tudelft.dnainator.graph.impl.Neo4jBatchBuilder;
8+
import nl.tudelft.dnainator.graph.impl.Neo4jGraph;
9+
import nl.tudelft.dnainator.graph.impl.NodeLabels;
10+
import nl.tudelft.dnainator.graph.impl.command.MutationFinderCommand;
11+
import nl.tudelft.dnainator.graph.impl.properties.SequenceProperties;
12+
import nl.tudelft.dnainator.parser.EdgeParser;
13+
import nl.tudelft.dnainator.parser.NodeParser;
14+
import nl.tudelft.dnainator.parser.TreeParser;
15+
import nl.tudelft.dnainator.parser.exceptions.ParseException;
16+
import nl.tudelft.dnainator.parser.impl.EdgeParserImpl;
17+
import nl.tudelft.dnainator.parser.impl.NodeParserImpl;
18+
import nl.tudelft.dnainator.tree.TreeNode;
19+
20+
import org.junit.AfterClass;
21+
import org.junit.BeforeClass;
22+
import org.junit.Test;
23+
import org.neo4j.graphdb.Node;
24+
import org.neo4j.io.fs.FileUtils;
25+
26+
import java.io.BufferedReader;
27+
import java.io.File;
28+
import java.io.IOException;
29+
import java.io.InputStream;
30+
import java.io.InputStreamReader;
31+
import java.net.URISyntaxException;
32+
import java.util.Collection;
33+
import java.util.stream.Collectors;
34+
35+
import static org.junit.Assert.assertEquals;
36+
import static org.junit.Assert.fail;
37+
38+
public class MutationFinderCommandTest {
39+
private static final String DB_PATH = "target/neo4j-tree-junit";
40+
private static Neo4jGraph db;
41+
private static InputStream nodeFile;
42+
private static InputStream edgeFile;
43+
private static AnnotationImpl first;
44+
private static AnnotationImpl middle;
45+
private static AnnotationImpl last;
46+
47+
/**
48+
* Setup the database and construct the graph.
49+
* @throws URISyntaxException
50+
*/
51+
@BeforeClass
52+
public static void setUp() throws URISyntaxException {
53+
try {
54+
FileUtils.deleteRecursively(new File(DB_PATH));
55+
nodeFile = getNodeFile();
56+
edgeFile = getEdgeFile();
57+
NodeParser np = new NodeParserImpl(new SequenceNodeFactoryImpl(),
58+
new BufferedReader(new InputStreamReader(nodeFile, "UTF-8")));
59+
EdgeParser ep = new EdgeParserImpl(new BufferedReader(
60+
new InputStreamReader(edgeFile, "UTF-8")));
61+
TreeNode phylo = new TreeParser(getTreeFile()).parse();
62+
db = (Neo4jGraph) new Neo4jBatchBuilder(DB_PATH, new AnnotationCollectionImpl(), phylo)
63+
.constructGraph(np, ep)
64+
.build();
65+
} catch (IOException e) {
66+
fail("Couldn't initialize DB");
67+
} catch (ParseException e) {
68+
fail("Couldn't parse file: " + e.getMessage());
69+
}
70+
//CHECKSTYLE.OFF: MagicNumber
71+
first = new AnnotationImpl("first", 0, 10, true);
72+
middle = new AnnotationImpl("middle", 5, 25, true);
73+
last = new AnnotationImpl("last", 20, 30, true);
74+
//CHECKSTYLE.ON: MagicNumber
75+
db.addAnnotation(first);
76+
db.addAnnotation(middle);
77+
db.addAnnotation(last);
78+
}
79+
80+
private static InputStream getNodeFile() {
81+
return MutationFinderCommandTest.class.getResourceAsStream("/strains/advancedtopo.node.graph");
82+
}
83+
84+
private static InputStream getEdgeFile() {
85+
return MutationFinderCommandTest.class.getResourceAsStream("/strains/advancedtopo.edge.graph");
86+
}
87+
88+
private static File getTreeFile() throws URISyntaxException {
89+
return new File(MutationFinderCommandTest.class.getResource("/strains/advancedtopo.nwk")
90+
.toURI());
91+
}
92+
93+
/**
94+
* Test returning a source set.
95+
* @param expected
96+
* @param actual
97+
*/
98+
@Test
99+
public void testIndependentMutations() {
100+
db.execute(e -> {
101+
Node node = e.findNode(NodeLabels.NODE, SequenceProperties.ID.name(), "6");
102+
new MutationFinderCommand(node).execute(e);
103+
});
104+
}
105+
106+
/**
107+
* Clean up after ourselves.
108+
* @throws IOException when the database could not be deleted
109+
*/
110+
@AfterClass
111+
public static void cleanUp() throws IOException {
112+
db.shutdown();
113+
}
114+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
1 2
2+
2 3
3+
3 4
4+
5 6
5+
6 7
6+
7 8
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
> 1 | TKK_001 | 1 | 5
2+
TATA
3+
> 2 | TKK_001,TKK_002 | 2 | 6
4+
TATA
5+
> 3 | TKK_001,TKK_002,TKK_003 | 3 | 7
6+
TATA
7+
> 4 | TKK_003,TKK_004,TKK_005,TKK_006 | 4 | 8
8+
TATA
9+
> 5 | TKK_006 | 5 | 9
10+
TATA
11+
> 6 | TKK_001,TKK_003,TKK_005 | 6 | 10
12+
TATA
13+
> 7 | TKK_004,TKK_002,TKK_003 | 7 | 11
14+
TATA
15+
> 8 | TKK_001,TKK_002,TKK_003,TKK_004,TKK_005,TKK_006 | 8 | 12
16+
TATA
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
((TKK_001:0.1,TKK_002:0.2),(TKK_003:0.3,((TKK_004:0.4,TKK_005:0.5),TKK_005:0.6)))
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
> 2 | ASDF,ASD | 1 | 5
1+
> 2 | TKK_001,TKK_002 | 1 | 5
22
TATA
3-
> 9 | ASD | 2 | 6
3+
> 9 | TKK_002 | 2 | 6
44
TATA
5-
> 10 | ASD | 3 | 7
5+
> 10 | TKK_002 | 3 | 7
66
TATA
7-
> 5 | ASDF | 4 | 8
7+
> 5 | TKK_001 | 4 | 8
88
TATA
9-
> 3 | ASDF | 5 | 9
9+
> 3 | TKK_001 | 5 | 9
1010
TATA
11-
> 7 | ASDF | 6 | 10
11+
> 7 | TKK_001,TKK_004 | 6 | 10
1212
TATA
13-
> 11 | ASD,FDSA,ASDF | 7 | 11
13+
> 11 | TKK_001,TKK_002,TKK_003 | 7 | 11
1414
TATA
15-
> 8 | ASDF | 8 | 12
15+
> 8 | TKK_001,TKK_002 | 8 | 12
1616
TATA

0 commit comments

Comments
 (0)