Refactor cdr3 matching to use new Vertex class

This commit is contained in:
2022-02-26 09:49:16 -06:00
parent 75b2aa9553
commit 1ea68045ce
4 changed files with 81 additions and 75 deletions

View File

@@ -63,7 +63,7 @@ public class GraphMLFileWriter {
try(BufferedWriter writer = Files.newBufferedWriter(Path.of(filename), StandardOpenOption.CREATE_NEW); try(BufferedWriter writer = Files.newBufferedWriter(Path.of(filename), StandardOpenOption.CREATE_NEW);
){ ){
//create exporter. Let the vertex labels be the unique ids for the vertices //create exporter. Let the vertex labels be the unique ids for the vertices
GraphMLExporter<Vertex, SimpleWeightedGraph<Vertex, DefaultWeightedEdge>> exporter = new GraphMLExporter<>(Vertex::getVertexLabel); GraphMLExporter<Vertex, SimpleWeightedGraph<Vertex, DefaultWeightedEdge>> exporter = new GraphMLExporter<>(v -> v.getVertexLabel().toString());
//set to export weights //set to export weights
exporter.setExportEdgeWeights(true); exporter.setExportEdgeWeights(true);
//Set graph attributes //Set graph attributes
@@ -71,7 +71,7 @@ public class GraphMLFileWriter {
//set type, sequence, and occupancy attributes for each vertex //set type, sequence, and occupancy attributes for each vertex
exporter.setVertexAttributeProvider( v -> { exporter.setVertexAttributeProvider( v -> {
Map<String, Attribute> attributes = new HashMap<>(); Map<String, Attribute> attributes = new HashMap<>();
attributes.put("type", DefaultAttribute.createAttribute(v.getType())); attributes.put("type", DefaultAttribute.createAttribute(v.getType().name()));
attributes.put("sequence", DefaultAttribute.createAttribute(v.getSequence())); attributes.put("sequence", DefaultAttribute.createAttribute(v.getSequence()));
attributes.put("occupancy", DefaultAttribute.createAttribute(v.getOccupancy())); attributes.put("occupancy", DefaultAttribute.createAttribute(v.getOccupancy()));
return attributes; return attributes;

View File

@@ -2,23 +2,25 @@ import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.SimpleWeightedGraph; import org.jgrapht.graph.SimpleWeightedGraph;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public interface GraphModificationFunctions { public interface GraphModificationFunctions {
//remove over- and under-weight edges //remove over- and under-weight edges
static List<Integer[]> filterByOverlapThresholds(SimpleWeightedGraph<Integer, DefaultWeightedEdge> graph, static Map<Vertex[], Integer> filterByOverlapThresholds(SimpleWeightedGraph<Vertex, DefaultWeightedEdge> graph,
int low, int high, boolean saveEdges) { int low, int high, boolean saveEdges) {
List<Integer[]> removedEdges = new ArrayList<>(); Map<Vertex[], Integer> removedEdges = new HashMap<>();
//List<Integer[]> removedEdges = new ArrayList<>();
for (DefaultWeightedEdge e : graph.edgeSet()) { for (DefaultWeightedEdge e : graph.edgeSet()) {
if ((graph.getEdgeWeight(e) > high) || (graph.getEdgeWeight(e) < low)) { if ((graph.getEdgeWeight(e) > high) || (graph.getEdgeWeight(e) < low)) {
if(saveEdges) { if(saveEdges) {
Integer source = graph.getEdgeSource(e); Vertex source = graph.getEdgeSource(e);
Integer target = graph.getEdgeTarget(e); Vertex target = graph.getEdgeTarget(e);
Integer weight = (int) graph.getEdgeWeight(e); Integer weight = (int) graph.getEdgeWeight(e);
Integer[] edge = {source, target, weight}; Vertex[] edge = {source, target};
removedEdges.add(edge); removedEdges.put(edge, weight);
} }
else { else {
graph.setEdgeWeight(e, 0.0); graph.setEdgeWeight(e, 0.0);
@@ -26,7 +28,7 @@ public interface GraphModificationFunctions {
} }
} }
if(saveEdges) { if(saveEdges) {
for (Integer[] edge : removedEdges) { for (Vertex[] edge : removedEdges.keySet()) {
graph.removeEdge(edge[0], edge[1]); graph.removeEdge(edge[0], edge[1]);
} }
} }
@@ -34,23 +36,19 @@ public interface GraphModificationFunctions {
} }
//Remove edges for pairs with large occupancy discrepancy //Remove edges for pairs with large occupancy discrepancy
static List<Integer[]> filterByRelativeOccupancy(SimpleWeightedGraph<Integer, DefaultWeightedEdge> graph, static Map<Vertex[], Integer> filterByRelativeOccupancy(SimpleWeightedGraph<Vertex, DefaultWeightedEdge> graph,
Map<Integer, Integer> alphaWellCounts,
Map<Integer, Integer> betaWellCounts,
Map<Integer, Integer> plateVtoAMap,
Map<Integer, Integer> plateVtoBMap,
Integer maxOccupancyDifference, boolean saveEdges) { Integer maxOccupancyDifference, boolean saveEdges) {
List<Integer[]> removedEdges = new ArrayList<>(); Map<Vertex[], Integer> removedEdges = new HashMap<>();
for (DefaultWeightedEdge e : graph.edgeSet()) { for (DefaultWeightedEdge e : graph.edgeSet()) {
Integer alphaOcc = alphaWellCounts.get(plateVtoAMap.get(graph.getEdgeSource(e))); Integer alphaOcc = graph.getEdgeSource(e).getOccupancy();
Integer betaOcc = betaWellCounts.get(plateVtoBMap.get(graph.getEdgeTarget(e))); Integer betaOcc = graph.getEdgeTarget(e).getOccupancy();
if (Math.abs(alphaOcc - betaOcc) >= maxOccupancyDifference) { if (Math.abs(alphaOcc - betaOcc) >= maxOccupancyDifference) {
if (saveEdges) { if (saveEdges) {
Integer source = graph.getEdgeSource(e); Vertex source = graph.getEdgeSource(e);
Integer target = graph.getEdgeTarget(e); Vertex target = graph.getEdgeTarget(e);
Integer weight = (int) graph.getEdgeWeight(e); Integer weight = (int) graph.getEdgeWeight(e);
Integer[] edge = {source, target, weight}; Vertex[] edge = {source, target};
removedEdges.add(edge); removedEdges.put(edge, weight);
} }
else { else {
graph.setEdgeWeight(e, 0.0); graph.setEdgeWeight(e, 0.0);
@@ -58,7 +56,7 @@ public interface GraphModificationFunctions {
} }
} }
if(saveEdges) { if(saveEdges) {
for (Integer[] edge : removedEdges) { for (Vertex[] edge : removedEdges.keySet()) {
graph.removeEdge(edge[0], edge[1]); graph.removeEdge(edge[0], edge[1]);
} }
} }
@@ -66,26 +64,22 @@ public interface GraphModificationFunctions {
} }
//Remove edges for pairs where overlap size is significantly lower than the well occupancy //Remove edges for pairs where overlap size is significantly lower than the well occupancy
static List<Integer[]> filterByOverlapPercent(SimpleWeightedGraph<Integer, DefaultWeightedEdge> graph, static Map<Vertex[], Integer> filterByOverlapPercent(SimpleWeightedGraph<Vertex, DefaultWeightedEdge> graph,
Map<Integer, Integer> alphaWellCounts,
Map<Integer, Integer> betaWellCounts,
Map<Integer, Integer> plateVtoAMap,
Map<Integer, Integer> plateVtoBMap,
Integer minOverlapPercent, Integer minOverlapPercent,
boolean saveEdges) { boolean saveEdges) {
List<Integer[]> removedEdges = new ArrayList<>(); Map<Vertex[], Integer> removedEdges = new HashMap<>();
for (DefaultWeightedEdge e : graph.edgeSet()) { for (DefaultWeightedEdge e : graph.edgeSet()) {
Integer alphaOcc = alphaWellCounts.get(plateVtoAMap.get(graph.getEdgeSource(e))); Integer alphaOcc = graph.getEdgeSource(e).getOccupancy();
Integer betaOcc = betaWellCounts.get(plateVtoBMap.get(graph.getEdgeTarget(e))); Integer betaOcc = graph.getEdgeTarget(e).getOccupancy();
double weight = graph.getEdgeWeight(e); double weight = graph.getEdgeWeight(e);
double min = minOverlapPercent / 100.0; double min = minOverlapPercent / 100.0;
if ((weight / alphaOcc < min) || (weight / betaOcc < min)) { if ((weight / alphaOcc < min) || (weight / betaOcc < min)) {
if(saveEdges) { if (saveEdges) {
Integer source = graph.getEdgeSource(e); Vertex source = graph.getEdgeSource(e);
Integer target = graph.getEdgeTarget(e); Vertex target = graph.getEdgeTarget(e);
Integer intWeight = (int) graph.getEdgeWeight(e); Integer intWeight = (int) graph.getEdgeWeight(e);
Integer[] edge = {source, target, intWeight}; Vertex[] edge = {source, target};
removedEdges.add(edge); removedEdges.put(edge, intWeight);
} }
else { else {
graph.setEdgeWeight(e, 0.0); graph.setEdgeWeight(e, 0.0);
@@ -93,18 +87,18 @@ public interface GraphModificationFunctions {
} }
} }
if(saveEdges) { if(saveEdges) {
for (Integer[] edge : removedEdges) { for (Vertex[] edge : removedEdges.keySet()) {
graph.removeEdge(edge[0], edge[1]); graph.removeEdge(edge[0], edge[1]);
} }
} }
return removedEdges; return removedEdges;
} }
static void addRemovedEdges(SimpleWeightedGraph<Integer, DefaultWeightedEdge> graph, static void addRemovedEdges(SimpleWeightedGraph<Vertex, DefaultWeightedEdge> graph,
List<Integer[]> removedEdges) { Map<Vertex[], Integer> removedEdges) {
for (Integer[] edge : removedEdges) { for (Vertex[] edge : removedEdges.keySet()) {
DefaultWeightedEdge e = graph.addEdge(edge[0], edge[1]); DefaultWeightedEdge e = graph.addEdge(edge[0], edge[1]);
graph.setEdgeWeight(e, (double) edge[2]); graph.setEdgeWeight(e, removedEdges.get(edge));
} }
} }

View File

@@ -141,35 +141,39 @@ public class Simulator implements GraphModificationFunctions {
Integer highThreshold, Integer maxOccupancyDifference, Integer highThreshold, Integer maxOccupancyDifference,
Integer minOverlapPercent, boolean verbose) { Integer minOverlapPercent, boolean verbose) {
Instant start = Instant.now(); Instant start = Instant.now();
List<Integer[]> removedEdges = new ArrayList<>(); SimpleWeightedGraph<Vertex, DefaultWeightedEdge> graph = data.getGraph();
Map<Vertex[], Integer> removedEdges = new HashMap<>();
boolean saveEdges = BiGpairSEQ.cacheGraph(); boolean saveEdges = BiGpairSEQ.cacheGraph();
int numWells = data.getNumWells(); int numWells = data.getNumWells();
Integer alphaCount = data.getAlphaCount(); Integer alphaCount = data.getAlphaCount();
Integer betaCount = data.getBetaCount(); Integer betaCount = data.getBetaCount();
Map<Integer, Integer> distCellsMapAlphaKey = data.getDistCellsMapAlphaKey(); Map<Integer, Integer> distCellsMapAlphaKey = data.getDistCellsMapAlphaKey();
Map<Integer, Integer> plateVtoAMap = data.getPlateVtoAMap(); Set<Vertex> alphas = new HashSet<>();
Map<Integer, Integer> plateVtoBMap = data.getPlateVtoBMap(); Set<Vertex> betas = new HashSet<>();
Map<Integer, Integer> alphaWellCounts = data.getAlphaWellCounts(); for(Vertex v: graph.vertexSet()) {
Map<Integer, Integer> betaWellCounts = data.getBetaWellCounts(); if (SequenceType.CDR3_ALPHA.equals(v.getType())){
SimpleWeightedGraph<Integer, DefaultWeightedEdge> graph = data.getGraph(); alphas.add(v);
}
else {
betas.add(v);
}
}
//remove edges with weights outside given overlap thresholds, add those to removed edge list //remove edges with weights outside given overlap thresholds, add those to removed edge list
if(verbose){System.out.println("Eliminating edges with weights outside overlap threshold values");} if(verbose){System.out.println("Eliminating edges with weights outside overlap threshold values");}
removedEdges.addAll(GraphModificationFunctions.filterByOverlapThresholds(graph, lowThreshold, highThreshold, saveEdges)); removedEdges.putAll(GraphModificationFunctions.filterByOverlapThresholds(graph, lowThreshold, highThreshold, saveEdges));
if(verbose){System.out.println("Over- and under-weight edges removed");} if(verbose){System.out.println("Over- and under-weight edges removed");}
//remove edges between vertices with too small an overlap size, add those to removed edge list //remove edges between vertices with too small an overlap size, add those to removed edge list
if(verbose){System.out.println("Eliminating edges with weights less than " + minOverlapPercent.toString() + if(verbose){System.out.println("Eliminating edges with weights less than " + minOverlapPercent.toString() +
" percent of vertex occupancy value.");} " percent of vertex occupancy value.");}
removedEdges.addAll(GraphModificationFunctions.filterByOverlapPercent(graph, alphaWellCounts, betaWellCounts, removedEdges.putAll(GraphModificationFunctions.filterByOverlapPercent(graph, minOverlapPercent, saveEdges));
plateVtoAMap, plateVtoBMap, minOverlapPercent, saveEdges));
if(verbose){System.out.println("Edges with weights too far below a vertex occupancy value removed");} if(verbose){System.out.println("Edges with weights too far below a vertex occupancy value removed");}
//Filter by relative occupancy //Filter by relative occupancy
if(verbose){System.out.println("Eliminating edges between vertices with occupancy difference > " if(verbose){System.out.println("Eliminating edges between vertices with occupancy difference > "
+ maxOccupancyDifference);} + maxOccupancyDifference);}
removedEdges.addAll(GraphModificationFunctions.filterByRelativeOccupancy(graph, alphaWellCounts, betaWellCounts, removedEdges.putAll(GraphModificationFunctions.filterByRelativeOccupancy(graph, maxOccupancyDifference, saveEdges));
plateVtoAMap, plateVtoBMap, maxOccupancyDifference, saveEdges));
if(verbose){System.out.println("Edges between vertices of with excessively different occupancy values " + if(verbose){System.out.println("Edges between vertices of with excessively different occupancy values " +
"removed");} "removed");}
@@ -182,20 +186,20 @@ public class Simulator implements GraphModificationFunctions {
switch (heapType) { switch (heapType) {
case "PAIRING" -> { case "PAIRING" -> {
maxWeightMatching = new MaximumWeightBipartiteMatching(graph, maxWeightMatching = new MaximumWeightBipartiteMatching(graph,
plateVtoAMap.keySet(), alphas,
plateVtoBMap.keySet(), betas,
i -> new PairingHeap(Comparator.naturalOrder())); i -> new PairingHeap(Comparator.naturalOrder()));
} }
case "FIBONACCI" -> { case "FIBONACCI" -> {
maxWeightMatching = new MaximumWeightBipartiteMatching(graph, maxWeightMatching = new MaximumWeightBipartiteMatching(graph,
plateVtoAMap.keySet(), alphas,
plateVtoBMap.keySet(), betas,
i -> new FibonacciHeap(Comparator.naturalOrder())); i -> new FibonacciHeap(Comparator.naturalOrder()));
} }
default -> { default -> {
maxWeightMatching = new MaximumWeightBipartiteMatching(graph, maxWeightMatching = new MaximumWeightBipartiteMatching(graph,
plateVtoAMap.keySet(), alphas,
plateVtoBMap.keySet()); betas);
} }
} }
//get the matching //get the matching
@@ -225,11 +229,14 @@ public class Simulator implements GraphModificationFunctions {
Map<Integer, Integer> matchMap = new HashMap<>(); Map<Integer, Integer> matchMap = new HashMap<>();
while(weightIter.hasNext()) { while(weightIter.hasNext()) {
e = weightIter.next(); e = weightIter.next();
Integer source = graph.getEdgeSource(e); Vertex source = graph.getEdgeSource(e);
Integer target = graph.getEdgeTarget(e); Vertex target = graph.getEdgeTarget(e);
//Integer source = graph.getEdgeSource(e);
//Integer target = graph.getEdgeTarget(e);
//The match map is all matches found, not just true matches! //The match map is all matches found, not just true matches!
matchMap.put(plateVtoAMap.get(source), plateVtoBMap.get(target)); matchMap.put(source.getSequence(), target.getSequence());
check = plateVtoBMap.get(target).equals(distCellsMapAlphaKey.get(plateVtoAMap.get(source))); check = target.getOccupancy().equals(distCellsMapAlphaKey.get(source.getSequence()));
//check = plateVtoBMap.get(target).equals(distCellsMapAlphaKey.get(plateVtoAMap.get(source)));
if(check) { if(check) {
trueCount++; trueCount++;
} }
@@ -237,17 +244,19 @@ public class Simulator implements GraphModificationFunctions {
falseCount++; falseCount++;
} }
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
result.add(plateVtoAMap.get(source).toString()); //alpha sequence
result.add(source.getSequence().toString());
//alpha well count //alpha well count
result.add(alphaWellCounts.get(plateVtoAMap.get(source)).toString()); result.add(source.getOccupancy().toString());
result.add(plateVtoBMap.get(target).toString()); //beta sequence
result.add(target.getSequence().toString());
//beta well count //beta well count
result.add(betaWellCounts.get(plateVtoBMap.get(target)).toString()); result.add(target.getOccupancy().toString());
//overlap count //overlap count
result.add(Double.toString(graph.getEdgeWeight(e))); result.add(Double.toString(graph.getEdgeWeight(e)));
result.add(Boolean.toString(check)); result.add(Boolean.toString(check));
double pValue = Equations.pValue(numWells, alphaWellCounts.get(plateVtoAMap.get(source)), double pValue = Equations.pValue(numWells, source.getOccupancy(),
betaWellCounts.get(plateVtoBMap.get(target)), graph.getEdgeWeight(e)); target.getOccupancy(), graph.getEdgeWeight(e));
BigDecimal pValueTrunc = new BigDecimal(pValue, mc); BigDecimal pValueTrunc = new BigDecimal(pValue, mc);
result.add(pValueTrunc.toString()); result.add(pValueTrunc.toString());
allResults.add(result); allResults.add(result);

View File

@@ -6,6 +6,9 @@ public class Vertex implements Serializable {
private Integer sequence; private Integer sequence;
private Integer occupancy; private Integer occupancy;
public Vertex(Integer vertexLabel) {
this.vertexLabel = vertexLabel;
}
public Vertex(String vertexLabel) { public Vertex(String vertexLabel) {
this.vertexLabel = Integer.parseInt((vertexLabel)); this.vertexLabel = Integer.parseInt((vertexLabel));
} }
@@ -18,33 +21,33 @@ public class Vertex implements Serializable {
} }
public String getType() { public SequenceType getType() {
return type.name(); return type;
} }
public void setType(String type) { public void setType(String type) {
this.type = SequenceType.valueOf(type); this.type = SequenceType.valueOf(type);
} }
public String getVertexLabel() { public Integer getVertexLabel() {
return vertexLabel.toString(); return vertexLabel;
} }
public void setVertexLabel(String label) { public void setVertexLabel(String label) {
this.vertexLabel = Integer.parseInt(label); this.vertexLabel = Integer.parseInt(label);
} }
public String getSequence() { public Integer getSequence() {
return sequence.toString(); return sequence;
} }
public void setSequence(String sequence) { public void setSequence(String sequence) {
this.sequence = Integer.parseInt(sequence); this.sequence = Integer.parseInt(sequence);
} }
public String getOccupancy() { public Integer getOccupancy() {
return occupancy.toString(); return occupancy;
} }
public void setOccupancy(String occupancy) { public void setOccupancy(String occupancy) {