Revert "by-hand merge of needed code from custom vertex branch"

This reverts commit 29b844afd2.
This commit is contained in:
eugenefischer
2022-09-25 14:34:31 -05:00
parent bd6d010b0b
commit e699795521
6 changed files with 175 additions and 277 deletions

View File

@@ -3,9 +3,8 @@ import org.jgrapht.graph.SimpleWeightedGraph;
import org.jgrapht.nio.Attribute; import org.jgrapht.nio.Attribute;
import org.jgrapht.nio.AttributeType; import org.jgrapht.nio.AttributeType;
import org.jgrapht.nio.DefaultAttribute; import org.jgrapht.nio.DefaultAttribute;
import org.jgrapht.nio.dot.DOTExporter;
import org.jgrapht.nio.graphml.GraphMLExporter; import org.jgrapht.nio.graphml.GraphMLExporter;
import org.jgrapht.nio.graphml.GraphMLExporter.AttributeCategory;
import org.w3c.dom.Attr;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.IOException; import java.io.IOException;
@@ -13,14 +12,14 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
public class GraphMLFileWriter { public class GraphMLFileWriter {
String filename; String filename;
SimpleWeightedGraph graph;
GraphWithMapData data; GraphWithMapData data;
Map<String, Attribute> graphAttributes;
public GraphMLFileWriter(String filename, GraphWithMapData data) { public GraphMLFileWriter(String filename, GraphWithMapData data) {
if(!filename.matches(".*\\.graphml")){ if(!filename.matches(".*\\.graphml")){
@@ -28,61 +27,52 @@ public class GraphMLFileWriter {
} }
this.filename = filename; this.filename = filename;
this.data = data; this.data = data;
this.graph = data.getGraph();
graphAttributes = createGraphAttributes();
} }
public GraphMLFileWriter(String filename, SimpleWeightedGraph<Vertex, DefaultWeightedEdge> graph) { // public void writeGraphToFile() {
if(!filename.matches(".*\\.graphml")){ // try(BufferedWriter writer = Files.newBufferedWriter(Path.of(filename), StandardOpenOption.CREATE_NEW);
filename = filename + ".graphml"; // ){
} // GraphMLExporter<SimpleWeightedGraph, BufferedWriter> exporter = new GraphMLExporter<>();
this.filename = filename; // exporter.exportGraph(graph, writer);
this.graph = graph; // } catch(IOException ex){
} // System.out.println("Could not make new file named "+filename);
// System.err.println(ex);
private Map<String, Attribute> createGraphAttributes(){ // }
Map<String, Attribute> ga = new HashMap<>(); // }
//Sample plate filename
ga.put("sample plate filename", DefaultAttribute.createAttribute(data.getSourceFilename()));
// Number of wells
ga.put("well count", DefaultAttribute.createAttribute(data.getNumWells().toString()));
//Well populations
Integer[] wellPopulations = data.getWellPopulations();
StringBuilder populationsStringBuilder = new StringBuilder();
populationsStringBuilder.append(wellPopulations[0].toString());
for(int i = 1; i < wellPopulations.length; i++){
populationsStringBuilder.append(", ");
populationsStringBuilder.append(wellPopulations[i].toString());
}
String wellPopulationsString = populationsStringBuilder.toString();
ga.put("well populations", DefaultAttribute.createAttribute(wellPopulationsString));
return ga;
}
public void writeGraphToFile() { public void writeGraphToFile() {
SimpleWeightedGraph graph = data.getGraph();
Map<Integer, Integer> vertexToAlphaMap = data.getPlateVtoAMap();
Map<Integer, Integer> vertexToBetaMap = data.getPlateVtoBMap();
Map<Integer, Integer> alphaOccs = data.getAlphaWellCounts();
Map<Integer, Integer> betaOccs = data.getBetaWellCounts();
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<>(v -> v.getVertexLabel().toString()); GraphMLExporter<Integer, SimpleWeightedGraph<Vertex, DefaultWeightedEdge>> exporter = new GraphMLExporter<>(v -> v.toString());
//set to export weights //set to export weights
exporter.setExportEdgeWeights(true); exporter.setExportEdgeWeights(true);
//Set graph attributes
exporter.setGraphAttributeProvider( () -> graphAttributes);
//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().name())); if(vertexToAlphaMap.containsKey(v)) {
attributes.put("sequence", DefaultAttribute.createAttribute(v.getSequence())); attributes.put("type", DefaultAttribute.createAttribute("CDR3 Alpha"));
attributes.put("occupancy", DefaultAttribute.createAttribute(v.getOccupancy())); attributes.put("sequence", DefaultAttribute.createAttribute(vertexToAlphaMap.get(v)));
attributes.put("occupancy", DefaultAttribute.createAttribute(
alphaOccs.get(vertexToAlphaMap.get(v))));
}
else if(vertexToBetaMap.containsKey(v)) {
attributes.put("type", DefaultAttribute.createAttribute("CDR3 Beta"));
attributes.put("sequence", DefaultAttribute.createAttribute(vertexToBetaMap.get(v)));
attributes.put("occupancy", DefaultAttribute.createAttribute(
betaOccs.get(vertexToBetaMap.get(v))));
}
return attributes; return attributes;
}); });
//register the attributes //register the attributes
for(String s : graphAttributes.keySet()) { exporter.registerAttribute("type", GraphMLExporter.AttributeCategory.NODE, AttributeType.STRING);
exporter.registerAttribute(s, AttributeCategory.GRAPH, AttributeType.STRING); exporter.registerAttribute("sequence", GraphMLExporter.AttributeCategory.NODE, AttributeType.STRING);
} exporter.registerAttribute("occupancy", GraphMLExporter.AttributeCategory.NODE, AttributeType.STRING);
exporter.registerAttribute("type", AttributeCategory.NODE, AttributeType.STRING);
exporter.registerAttribute("sequence", AttributeCategory.NODE, AttributeType.STRING);
exporter.registerAttribute("occupancy", AttributeCategory.NODE, AttributeType.STRING);
//export the graph //export the graph
exporter.exportGraph(graph, writer); exporter.exportGraph(graph, writer);
} catch(IOException ex){ } catch(IOException ex){
@@ -91,3 +81,4 @@ public class GraphMLFileWriter {
} }
} }
} }

View File

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

View File

@@ -15,33 +15,32 @@ public class GraphWithMapData implements java.io.Serializable {
private Integer alphaCount; private Integer alphaCount;
private Integer betaCount; private Integer betaCount;
private final Map<Integer, Integer> distCellsMapAlphaKey; private final Map<Integer, Integer> distCellsMapAlphaKey;
// private final Map<Integer, Integer> plateVtoAMap; private final Map<Integer, Integer> plateVtoAMap;
// private final Map<Integer, Integer> plateVtoBMap; private final Map<Integer, Integer> plateVtoBMap;
// private final Map<Integer, Integer> plateAtoVMap; private final Map<Integer, Integer> plateAtoVMap;
// private final Map<Integer, Integer> plateBtoVMap; private final Map<Integer, Integer> plateBtoVMap;
// private final Map<Integer, Integer> alphaWellCounts; private final Map<Integer, Integer> alphaWellCounts;
// private final Map<Integer, Integer> betaWellCounts; private final Map<Integer, Integer> betaWellCounts;
private final Duration time; private final Duration time;
public GraphWithMapData(SimpleWeightedGraph graph, Integer numWells, Integer[] wellConcentrations, public GraphWithMapData(SimpleWeightedGraph graph, Integer numWells, Integer[] wellConcentrations,
Map<Integer, Integer> distCellsMapAlphaKey, Duration time){ Integer alphaCount, Integer betaCount,
Map<Integer, Integer> distCellsMapAlphaKey, Map<Integer, Integer> plateVtoAMap,
// Map<Integer, Integer> plateVtoAMap, Integer alphaCount, Integer betaCount, Map<Integer,Integer> plateVtoBMap, Map<Integer, Integer> plateAtoVMap,
// Map<Integer,Integer> plateVtoBMap, Map<Integer, Integer> plateAtoVMap, Map<Integer, Integer> plateBtoVMap, Map<Integer, Integer> alphaWellCounts,
// Map<Integer, Integer> plateBtoVMap, Map<Integer, Integer> alphaWellCounts, Map<Integer, Integer> betaWellCounts, Duration time) {
// Map<Integer, Integer> betaWellCounts,) {
this.graph = graph; this.graph = graph;
this.numWells = numWells; this.numWells = numWells;
this.wellPopulations = wellConcentrations; this.wellPopulations = wellConcentrations;
this.alphaCount = alphaCount; this.alphaCount = alphaCount;
this.betaCount = betaCount; this.betaCount = betaCount;
this.distCellsMapAlphaKey = distCellsMapAlphaKey; this.distCellsMapAlphaKey = distCellsMapAlphaKey;
// this.plateVtoAMap = plateVtoAMap; this.plateVtoAMap = plateVtoAMap;
// this.plateVtoBMap = plateVtoBMap; this.plateVtoBMap = plateVtoBMap;
// this.plateAtoVMap = plateAtoVMap; this.plateAtoVMap = plateAtoVMap;
// this.plateBtoVMap = plateBtoVMap; this.plateBtoVMap = plateBtoVMap;
// this.alphaWellCounts = alphaWellCounts; this.alphaWellCounts = alphaWellCounts;
// this.betaWellCounts = betaWellCounts; this.betaWellCounts = betaWellCounts;
this.time = time; this.time = time;
} }
@@ -57,41 +56,41 @@ public class GraphWithMapData implements java.io.Serializable {
return wellPopulations; return wellPopulations;
} }
// public Integer getAlphaCount() { public Integer getAlphaCount() {
// return alphaCount; return alphaCount;
// } }
//
// public Integer getBetaCount() { public Integer getBetaCount() {
// return betaCount; return betaCount;
// } }
public Map<Integer, Integer> getDistCellsMapAlphaKey() { public Map<Integer, Integer> getDistCellsMapAlphaKey() {
return distCellsMapAlphaKey; return distCellsMapAlphaKey;
} }
// public Map<Integer, Integer> getPlateVtoAMap() { public Map<Integer, Integer> getPlateVtoAMap() {
// return plateVtoAMap; return plateVtoAMap;
// } }
//
// public Map<Integer, Integer> getPlateVtoBMap() { public Map<Integer, Integer> getPlateVtoBMap() {
// return plateVtoBMap; return plateVtoBMap;
// } }
//
// public Map<Integer, Integer> getPlateAtoVMap() { public Map<Integer, Integer> getPlateAtoVMap() {
// return plateAtoVMap; return plateAtoVMap;
// } }
//
// public Map<Integer, Integer> getPlateBtoVMap() { public Map<Integer, Integer> getPlateBtoVMap() {
// return plateBtoVMap; return plateBtoVMap;
// } }
//
// public Map<Integer, Integer> getAlphaWellCounts() { public Map<Integer, Integer> getAlphaWellCounts() {
// return alphaWellCounts; return alphaWellCounts;
// } }
//
// public Map<Integer, Integer> getBetaWellCounts() { public Map<Integer, Integer> getBetaWellCounts() {
// return betaWellCounts; return betaWellCounts;
// } }
public Duration getTime() { public Duration getTime() {
return time; return time;

View File

@@ -1,8 +0,0 @@
//enum for tagging types of sequences
//Listed in order that they appear in a cell array, so ordinal() method will return correct index
public enum SequenceType {
CDR3_ALPHA,
CDR3_BETA,
CDR1_ALPHA,
CDR1_BETA
}

View File

@@ -18,29 +18,29 @@ import static java.lang.Float.*;
//NOTE: "sequence" in method and variable names refers to a peptide sequence from a simulated T cell //NOTE: "sequence" in method and variable names refers to a peptide sequence from a simulated T cell
public class Simulator implements GraphModificationFunctions { public class Simulator implements GraphModificationFunctions {
private static final int cdr3AlphaIndex = 0;
private static final int cdr3BetaIndex = 1;
private static final int cdr1AlphaIndex = 2;
private static final int cdr1BetaIndex = 3;
//Make the graph needed for matching sequences. //Make the graph needed for matching CDR3s
//sourceVertexIndices and targetVertexIndices are indices within the cell to use as for the two sets of vertices
//in the bipartite graph. "Source" and "target" are JGraphT terms for the two vertices an edge touches,
//even if not directed.
public static GraphWithMapData makeGraph(CellSample cellSample, Plate samplePlate, boolean verbose) { public static GraphWithMapData makeGraph(CellSample cellSample, Plate samplePlate, boolean verbose) {
Instant start = Instant.now(); Instant start = Instant.now();
List<Integer[]> distinctCells = cellSample.getCells(); List<Integer[]> distinctCells = cellSample.getCells();
int[] alphaIndices = {SequenceType.CDR3_ALPHA.ordinal()}; int[] alphaIndex = {cdr3AlphaIndex};
int[] betaIndices = {SequenceType.CDR3_BETA.ordinal()}; int[] betaIndex = {cdr3BetaIndex};
int numWells = samplePlate.getSize(); int numWells = samplePlate.getSize();
if(verbose){System.out.println("Making cell maps");} if(verbose){System.out.println("Making cell maps");}
//HashMap keyed to Alphas, values Betas //HashMap keyed to Alphas, values Betas
Map<Integer, Integer> distCellsMapAlphaKey = makeSequenceToSequenceMap(distinctCells, 0, 1); Map<Integer, Integer> distCellsMapAlphaKey = makeSequenceToSequenceMap(distinctCells, cdr3AlphaIndex, cdr3BetaIndex);
if(verbose){System.out.println("Cell maps made");} if(verbose){System.out.println("Cell maps made");}
if(verbose){System.out.println("Making well maps");} if(verbose){System.out.println("Making well maps");}
Map<Integer, Integer> allAlphas = samplePlate.assayWellsSequenceS(alphaIndex);
Map<Integer, Integer> allAlphas = samplePlate.assayWellsSequenceS(alphaIndices); Map<Integer, Integer> allBetas = samplePlate.assayWellsSequenceS(betaIndex);
Map<Integer, Integer> allBetas = samplePlate.assayWellsSequenceS(betaIndices);
int alphaCount = allAlphas.size(); int alphaCount = allAlphas.size();
if(verbose){System.out.println("All alphas count: " + alphaCount);} if(verbose){System.out.println("All alphas count: " + alphaCount);}
int betaCount = allBetas.size(); int betaCount = allBetas.size();
@@ -80,40 +80,29 @@ public class Simulator implements GraphModificationFunctions {
//(technically this is only 1/4 of an adjacency matrix, but that's all you need //(technically this is only 1/4 of an adjacency matrix, but that's all you need
//for a bipartite graph, and all the SimpleWeightedBipartiteGraphMatrixGenerator class expects.) //for a bipartite graph, and all the SimpleWeightedBipartiteGraphMatrixGenerator class expects.)
if(verbose){System.out.println("Creating adjacency matrix");} if(verbose){System.out.println("Creating adjacency matrix");}
//Count how many wells each alpha sequence appears in //Count how many wells each alpha appears in
Map<Integer, Integer> alphaWellCounts = new HashMap<>(); Map<Integer, Integer> alphaWellCounts = new HashMap<>();
//count how many wells each beta sequence appears in //count how many wells each beta appears in
Map<Integer, Integer> betaWellCounts = new HashMap<>(); Map<Integer, Integer> betaWellCounts = new HashMap<>();
//the adjacency matrix to be used by the graph generator //the adjacency matrix to be used by the graph generator
double[][] weights = new double[plateVtoAMap.size()][plateVtoBMap.size()]; double[][] weights = new double[plateVtoAMap.size()][plateVtoBMap.size()];
countSequencesAndFillMatrix(samplePlate, allAlphas, allBetas, plateAtoVMap, countSequencesAndFillMatrix(samplePlate, allAlphas, allBetas, plateAtoVMap,
plateBtoVMap, alphaIndices, betaIndices, alphaWellCounts, betaWellCounts, weights); plateBtoVMap, alphaIndex, betaIndex, alphaWellCounts, betaWellCounts, weights);
if(verbose){System.out.println("Matrix created");} if(verbose){System.out.println("Matrix created");}
//create bipartite graph //create bipartite graph
if(verbose){System.out.println("Creating graph");} if(verbose){System.out.println("Creating graph");}
//the graph object //the graph object
SimpleWeightedGraph<Vertex, DefaultWeightedEdge> graph = SimpleWeightedGraph<Integer, DefaultWeightedEdge> graph =
new SimpleWeightedGraph<>(DefaultWeightedEdge.class); new SimpleWeightedGraph<>(DefaultWeightedEdge.class);
//the graph generator //the graph generator
SimpleWeightedBipartiteGraphMatrixGenerator graphGenerator = new SimpleWeightedBipartiteGraphMatrixGenerator(); SimpleWeightedBipartiteGraphMatrixGenerator graphGenerator = new SimpleWeightedBipartiteGraphMatrixGenerator();
//the list of alpha vertices //the list of alpha vertices
//List<Integer> alphaVertices = new ArrayList<>(plateVtoAMap.keySet()); //This will work because LinkedHashMap preserves order of entry List<Integer> alphaVertices = new ArrayList<>(plateVtoAMap.keySet()); //This will work because LinkedHashMap preserves order of entry
List<Vertex> alphaVertices = new ArrayList<>();
//start with map of all alphas mapped to vertex values, get occupancy from the alphaWellCounts map
for (Integer seq : plateAtoVMap.keySet()) {
Vertex alphaVertex = new Vertex(SequenceType.CDR3_ALPHA, seq, alphaWellCounts.get(seq), plateAtoVMap.get(seq));
alphaVertices.add(alphaVertex);
}
graphGenerator.first(alphaVertices); graphGenerator.first(alphaVertices);
//the list of beta vertices //the list of beta vertices
//List<Integer> betaVertices = new ArrayList<>(plateVtoBMap.keySet());//This will work because LinkedHashMap preserves order of entry List<Integer> betaVertices = new ArrayList<>(plateVtoBMap.keySet());
List<Vertex> betaVertices = new ArrayList<>(); graphGenerator.second(betaVertices); //This will work because LinkedHashMap preserves order of entry
for (Integer seq : plateBtoVMap.keySet()) {
Vertex betaVertex = new Vertex(SequenceType.CDR3_BETA, seq, betaWellCounts.get(seq), plateBtoVMap.get(seq));
betaVertices.add(betaVertex);
}
graphGenerator.second(betaVertices);
//use adjacency matrix of weight created previously //use adjacency matrix of weight created previously
graphGenerator.weights(weights); graphGenerator.weights(weights);
graphGenerator.generateGraph(graph); graphGenerator.generateGraph(graph);
@@ -123,7 +112,9 @@ public class Simulator implements GraphModificationFunctions {
Duration time = Duration.between(start, stop); Duration time = Duration.between(start, stop);
//create GraphWithMapData object //create GraphWithMapData object
GraphWithMapData output = new GraphWithMapData(graph, numWells, samplePlate.getPopulations(), distCellsMapAlphaKey, time); GraphWithMapData output = new GraphWithMapData(graph, numWells, samplePlate.getPopulations(), alphaCount, betaCount,
distCellsMapAlphaKey, plateVtoAMap, plateVtoBMap, plateAtoVMap,
plateBtoVMap, alphaWellCounts, betaWellCounts, time);
//Set source file name in graph to name of sample plate //Set source file name in graph to name of sample plate
output.setSourceFilename(samplePlate.getFilename()); output.setSourceFilename(samplePlate.getFilename());
//return GraphWithMapData object //return GraphWithMapData object
@@ -135,46 +126,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();
SimpleWeightedGraph<Vertex, DefaultWeightedEdge> graph = data.getGraph(); List<Integer[]> removedEdges = new ArrayList<>();
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();
Set<Vertex> alphas = new HashSet<>(); Map<Integer, Integer> plateVtoAMap = data.getPlateVtoAMap();
Set<Vertex> betas = new HashSet<>(); Map<Integer, Integer> plateVtoBMap = data.getPlateVtoBMap();
for(Vertex v: graph.vertexSet()) { Map<Integer, Integer> alphaWellCounts = data.getAlphaWellCounts();
if (SequenceType.CDR3_ALPHA.equals(v.getType())){ Map<Integer, Integer> betaWellCounts = data.getBetaWellCounts();
alphas.add(v); SimpleWeightedGraph<Integer, DefaultWeightedEdge> graph = data.getGraph();
}
else {
betas.add(v);
}
}
Integer alphaCount = alphas.size();
Integer betaCount = betas.size();
//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.putAll(GraphModificationFunctions.filterByOverlapThresholds(graph, lowThreshold, highThreshold, saveEdges)); removedEdges.addAll(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.putAll(GraphModificationFunctions.filterByOverlapPercent(graph, minOverlapPercent, saveEdges)); removedEdges.addAll(GraphModificationFunctions.filterByOverlapPercent(graph, alphaWellCounts, betaWellCounts,
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.putAll(GraphModificationFunctions.filterByRelativeOccupancy(graph, maxOccupancyDifference, saveEdges)); removedEdges.addAll(GraphModificationFunctions.filterByRelativeOccupancy(graph, alphaWellCounts, betaWellCounts,
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");}
//Find Maximum Weighted Matching //Find Maximum Weighted Matching
//using jheaps library class PairingHeap for improved efficiency
if(verbose){System.out.println("Finding maximum weighted matching");} if(verbose){System.out.println("Finding maximum weighted matching");}
MaximumWeightBipartiteMatching maxWeightMatching; MaximumWeightBipartiteMatching maxWeightMatching;
//Use correct heap type for priority queue //Use correct heap type for priority queue
@@ -182,20 +166,20 @@ public class Simulator implements GraphModificationFunctions {
switch (heapType) { switch (heapType) {
case "PAIRING" -> { case "PAIRING" -> {
maxWeightMatching = new MaximumWeightBipartiteMatching(graph, maxWeightMatching = new MaximumWeightBipartiteMatching(graph,
alphas, plateVtoAMap.keySet(),
betas, plateVtoBMap.keySet(),
i -> new PairingHeap(Comparator.naturalOrder())); i -> new PairingHeap(Comparator.naturalOrder()));
} }
case "FIBONACCI" -> { case "FIBONACCI" -> {
maxWeightMatching = new MaximumWeightBipartiteMatching(graph, maxWeightMatching = new MaximumWeightBipartiteMatching(graph,
alphas, plateVtoAMap.keySet(),
betas, plateVtoBMap.keySet(),
i -> new FibonacciHeap(Comparator.naturalOrder())); i -> new FibonacciHeap(Comparator.naturalOrder()));
} }
default -> { default -> {
maxWeightMatching = new MaximumWeightBipartiteMatching(graph, maxWeightMatching = new MaximumWeightBipartiteMatching(graph,
alphas, plateVtoAMap.keySet(),
betas); plateVtoBMap.keySet());
} }
} }
//get the matching //get the matching
@@ -225,14 +209,11 @@ 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();
Vertex source = graph.getEdgeSource(e); Integer source = graph.getEdgeSource(e);
Vertex target = graph.getEdgeTarget(e); Integer 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(source.getSequence(), target.getSequence()); matchMap.put(plateVtoAMap.get(source), plateVtoBMap.get(target));
check = target.getSequence().equals(distCellsMapAlphaKey.get(source.getSequence())); check = plateVtoBMap.get(target).equals(distCellsMapAlphaKey.get(plateVtoAMap.get(source)));
//check = plateVtoBMap.get(target).equals(distCellsMapAlphaKey.get(plateVtoAMap.get(source)));
if(check) { if(check) {
trueCount++; trueCount++;
} }
@@ -240,19 +221,17 @@ public class Simulator implements GraphModificationFunctions {
falseCount++; falseCount++;
} }
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
//alpha sequence result.add(plateVtoAMap.get(source).toString());
result.add(source.getSequence().toString());
//alpha well count //alpha well count
result.add(source.getOccupancy().toString()); result.add(alphaWellCounts.get(plateVtoAMap.get(source)).toString());
//beta sequence result.add(plateVtoBMap.get(target).toString());
result.add(target.getSequence().toString());
//beta well count //beta well count
result.add(target.getOccupancy().toString()); result.add(betaWellCounts.get(plateVtoBMap.get(target)).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, source.getOccupancy(), double pValue = Equations.pValue(numWells, alphaWellCounts.get(plateVtoAMap.get(source)),
target.getOccupancy(), graph.getEdgeWeight(e)); betaWellCounts.get(plateVtoBMap.get(target)), 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

@@ -1,92 +1,23 @@
import java.io.Serializable;
public class Vertex implements Serializable {
private SequenceType type;
private Integer vertexLabel;
private Integer sequence;
private Integer occupancy;
public Vertex(Integer vertexLabel) { public class Vertex {
this.vertexLabel = vertexLabel; private final Integer vertexLabel;
} private final Integer sequence;
public Vertex(String vertexLabel) { private final Integer occupancy;
this.vertexLabel = Integer.parseInt((vertexLabel));
}
public Vertex(SequenceType type, Integer sequence, Integer occupancy, Integer vertexLabel) { public Vertex(Integer vertexLabel, Integer sequence, Integer occupancy) {
this.type = type;
this.vertexLabel = vertexLabel; this.vertexLabel = vertexLabel;
this.sequence = sequence; this.sequence = sequence;
this.occupancy = occupancy; this.occupancy = occupancy;
} }
public Integer getVertexLabel() { return vertexLabel; }
public SequenceType getType() {
return type;
}
public void setType(String type) {
this.type = SequenceType.valueOf(type);
}
public Integer getVertexLabel() {
return vertexLabel;
}
public void setVertexLabel(String label) {
this.vertexLabel = Integer.parseInt(label);
}
public Integer getSequence() { public Integer getSequence() {
return sequence; return sequence;
} }
public void setSequence(String sequence) {
this.sequence = Integer.parseInt(sequence);
}
public Integer getOccupancy() { public Integer getOccupancy() {
return occupancy; return occupancy;
} }
public void setOccupancy(String occupancy) {
this.occupancy = Integer.parseInt(occupancy);
}
@Override //adapted from JGraphT example code
public int hashCode()
{
return (sequence == null) ? 0 : sequence.hashCode();
}
@Override //adapted from JGraphT example code
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Vertex other = (Vertex) obj;
if (sequence == null) {
return other.sequence == null;
} else {
return sequence.equals(other.sequence);
}
}
@Override //adapted from JGraphT example code
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("(").append(vertexLabel)
.append(", Type: ").append(type.name())
.append(", Sequence: ").append(sequence)
.append(", Occupancy: ").append(occupancy).append(")");
return sb.toString();
}
} }