Skip to content

Commit e4101d6

Browse files
committed
Trim source and sink of clustered bubbles, return source and sink as singletons
1 parent 883ea9d commit e4101d6

1 file changed

Lines changed: 30 additions & 8 deletions

File tree

dnainator-core/src/main/java/nl/tudelft/dnainator/graph/impl/query/AllClustersQuery.java

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,23 @@
1313

1414
import org.neo4j.graphalgo.GraphAlgoFactory;
1515
import org.neo4j.graphalgo.PathFinder;
16+
import org.neo4j.graphalgo.impl.util.PathImpl;
1617
import org.neo4j.graphdb.Direction;
1718
import org.neo4j.graphdb.GraphDatabaseService;
1819
import org.neo4j.graphdb.Node;
1920
import org.neo4j.graphdb.Path;
2021
import org.neo4j.graphdb.PathExpanders;
22+
import org.neo4j.graphdb.Relationship;
2123
import org.neo4j.graphdb.traversal.Evaluation;
2224
import org.neo4j.graphdb.traversal.TraversalDescription;
2325
import org.neo4j.helpers.collection.IteratorUtil;
2426

2527
import java.util.ArrayList;
2628
import java.util.Collection;
2729
import java.util.Collections;
30+
import java.util.HashMap;
2831
import java.util.HashSet;
32+
import java.util.Iterator;
2933
import java.util.List;
3034
import java.util.Map;
3135
import java.util.Set;
@@ -99,14 +103,13 @@ public Map<Integer, List<Cluster>> execute(GraphDatabaseService service) {
99103

100104
private Map<Integer, List<Cluster>> cluster(GraphDatabaseService service,
101105
Set<Long> bubbleSourcesToCluster, Set<Long> bubbleSourcesToKeepIntact) {
102-
Map<Integer, List<Cluster>> bubblesClustered = bubbleSourcesToCluster.stream()
106+
Stream<Map<Integer, List<Cluster>>> bubblesClustered = bubbleSourcesToCluster.stream()
103107
.map(service::getNodeById)
104-
.map(source -> collapseBubble(service, source, getSinkFromSource(source)))
105-
.collect(Collectors.groupingBy(Cluster::getStartRank));
108+
.map(source -> collapseBubble(service, source, getSinkFromSource(source)));
106109
Stream<Map<Integer, List<Cluster>>> singletonClusters = bubbleSourcesToKeepIntact.stream()
107110
.map(service::getNodeById)
108111
.map(source -> getSingletonClusters(service, source, getSinkFromSource(source)));
109-
return mergeMaps(Stream.concat(Stream.of(bubblesClustered), singletonClusters));
112+
return mergeMaps(Stream.concat(bubblesClustered, singletonClusters));
110113
}
111114

112115
private static Node getSinkFromSource(Node source) {
@@ -132,22 +135,41 @@ private Cluster createSingletonCluster(GraphDatabaseService service, Node n) {
132135
Collections.singletonList(sn), sn.getAnnotations());
133136
}
134137

135-
private Cluster collapseBubble(GraphDatabaseService service, Node source, Node sink) {
138+
private Map<Integer, List<Cluster>> collapseBubble(GraphDatabaseService service,
139+
Node source, Node sink) {
140+
Map<Integer, List<Cluster>> res = new HashMap<>(2 + 1); // source + sink + bubble.
136141
int sourceRank = (int) source.getProperty(SequenceProperties.RANK.name());
137142
int sinkRank = (int) sink.getProperty(SequenceProperties.RANK.name());
143+
// Set the rank of the cluster to be in the middle.
138144
int clusterRank = sourceRank + (sinkRank - sourceRank) / 2;
145+
res.put(sourceRank, Collections.singletonList(createSingletonCluster(service, source)));
146+
res.put(sinkRank, Collections.singletonList(createSingletonCluster(service, sink)));
147+
139148
PathFinder<Path> withinBubble = pathFinderBetweenRanks(sourceRank, sinkRank);
140-
// FIXME: don't collapse source and sink, keep those intact.
141149
List<EnrichedSequenceNode> nodes = stream(
142150
withinBubble.findAllPaths(source, sink))
143-
.flatMap(path -> stream(path.nodes()))
151+
.flatMap(path -> stream(trimPath(path).nodes()))
144152
.distinct()
145153
.map(n -> new Neo4jSequenceNode(service, n))
146154
.collect(Collectors.toList());
147155
List<Annotation> annotations = nodes.stream()
148156
.flatMap(e -> e.getAnnotations().stream())
149157
.collect(Collectors.toList());
150-
return new Cluster(clusterRank, nodes, annotations);
158+
Cluster cluster = new Cluster(clusterRank, nodes, annotations);
159+
res.put(clusterRank, Collections.singletonList(cluster));
160+
return res;
161+
}
162+
163+
private Path trimPath(Path path) {
164+
Iterator<Node> nodes = path.nodes().iterator();
165+
Iterator<Relationship> rels = path.relationships().iterator();
166+
nodes.next();
167+
rels.next();
168+
PathImpl.Builder builder = new PathImpl.Builder(nodes.next());
169+
for (int i = 1; i < path.length() - 2; i++) {
170+
builder = builder.push(rels.next());
171+
}
172+
return builder.build();
151173
}
152174

153175
private PathFinder<Path> pathFinderBetweenRanks(int minRank, int maxRank) {

0 commit comments

Comments
 (0)