diff --git a/src/main/java/Plate.java b/src/main/java/Plate.java index ee43632..c0d9f8d 100644 --- a/src/main/java/Plate.java +++ b/src/main/java/Plate.java @@ -241,7 +241,7 @@ public class Plate { sequencesAndMisreads.put(currentSequence, new ArrayList<>()); } //The specific misread hasn't happened before - if (rand.nextDouble() >= errorCollisionRate || sequencesAndMisreads.get(currentSequence).size() == 0) { + if (rand.nextDouble() >= errorCollisionRate || sequencesAndMisreads.get(currentSequence).isEmpty()) { //The misread doesn't collide with a real sequence already on the plate and some sequences have already been read if(rand.nextDouble() >= realSequenceCollisionRate || !sequenceMap.isEmpty()){ StringBuilder spurious = new StringBuilder(currentSequence); diff --git a/src/main/java/Simulator.java b/src/main/java/Simulator.java index ab0da02..4ba488d 100644 --- a/src/main/java/Simulator.java +++ b/src/main/java/Simulator.java @@ -70,58 +70,97 @@ public class Simulator implements GraphModificationFunctions { if(verbose){System.out.println("Total beta sequence wells removed: " + betaWellsRemoved);} } - //construct the graph. For simplicity, going to make - if(verbose){System.out.println("Making vertex maps");} - //For the SimpleWeightedBipartiteGraphMatrixGenerator, all vertices must have - //distinct numbers associated with them. Since I'm using a 2D array, that means - //distinct indices between the rows and columns. vertexStartValue lets me track where I switch - //from numbering rows to columns, so I can assign unique numbers to every vertex, and then - //subtract the vertexStartValue from betas to use their vertex labels as array indices - int vertexStartValue = 0; - //keys are sequential integer vertices, values are alphas - Map plateAtoVMap = makeSequenceToVertexMap(alphaSequences, vertexStartValue); - //new start value for vertex to beta map should be one more than final vertex value in alpha map - vertexStartValue += plateAtoVMap.size(); - //keys are betas, values are sequential integers - Map plateBtoVMap = makeSequenceToVertexMap(betaSequences, vertexStartValue); - if(verbose){System.out.println("Vertex maps made");} - //make adjacency matrix for bipartite graph generator - //(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.) - if(verbose){System.out.println("Making adjacency matrix");} - double[][] weights = new double[plateAtoVMap.size()][plateBtoVMap.size()]; - fillAdjacencyMatrix(weights, vertexStartValue, alphaSequences, betaSequences, plateAtoVMap, plateBtoVMap); - if(verbose){System.out.println("Adjacency matrix made");} + /* + * The commented out code below works beautifully for small enough graphs. However, after implementing a + * Zipf distribution and attempting to simulate Experiment 3 from the paper again, I discovered that + * this method uses too much memory. Even a 120GB heap is not enough to build this adjacency matrix. + * So I'm going to attempt to build this graph directly and see if that is less memory intensive + */ +// //construct the graph. For simplicity, going to make +// if(verbose){System.out.println("Making vertex maps");} +// //For the SimpleWeightedBipartiteGraphMatrixGenerator, all vertices must have +// //distinct numbers associated with them. Since I'm using a 2D array, that means +// //distinct indices between the rows and columns. vertexStartValue lets me track where I switch +// //from numbering rows to columns, so I can assign unique numbers to every vertex, and then +// //subtract the vertexStartValue from betas to use their vertex labels as array indices +// int vertexStartValue = 0; +// //keys are sequential integer vertices, values are alphas +// Map plateAtoVMap = makeSequenceToVertexMap(alphaSequences, vertexStartValue); +// //new start value for vertex to beta map should be one more than final vertex value in alpha map +// vertexStartValue += plateAtoVMap.size(); +// //keys are betas, values are sequential integers +// Map plateBtoVMap = makeSequenceToVertexMap(betaSequences, vertexStartValue); +// if(verbose){System.out.println("Vertex maps made");} +// //make adjacency matrix for bipartite graph generator +// //(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.) +// if(verbose){System.out.println("Making adjacency matrix");} +// double[][] weights = new double[plateAtoVMap.size()][plateBtoVMap.size()]; +// fillAdjacencyMatrix(weights, vertexStartValue, alphaSequences, betaSequences, plateAtoVMap, plateBtoVMap); +// if(verbose){System.out.println("Adjacency matrix made");} +// //make bipartite graph +// if(verbose){System.out.println("Making bipartite weighted graph");} +// //the graph object +// SimpleWeightedGraph graph = +// new SimpleWeightedGraph<>(DefaultWeightedEdge.class); +// //the graph generator +// SimpleWeightedBipartiteGraphMatrixGenerator graphGenerator = new SimpleWeightedBipartiteGraphMatrixGenerator(); +// //the list of alpha vertices +// List alphaVertices = new ArrayList<>(); +// for (String seq : plateAtoVMap.keySet()) { +// Vertex alphaVertex = new Vertex(alphaSequences.get(seq), plateAtoVMap.get(seq)); +// alphaVertices.add(alphaVertex); +// } +// //Sort to make sure the order of vertices in list matches the order of the adjacency matrix +// Collections.sort(alphaVertices); +// //Add ordered list of vertices to the graph +// graphGenerator.first(alphaVertices); +// //the list of beta vertices +// List betaVertices = new ArrayList<>(); +// for (String seq : plateBtoVMap.keySet()) { +// Vertex betaVertex = new Vertex(betaSequences.get(seq), plateBtoVMap.get(seq)); +// betaVertices.add(betaVertex); +// } +// //Sort to make sure the order of vertices in list matches the order of the adjacency matrix +// Collections.sort(betaVertices); +// //Add ordered list of vertices to the graph +// graphGenerator.second(betaVertices); +// //use adjacency matrix of weight created previously +// graphGenerator.weights(weights); +// graphGenerator.generateGraph(graph); + //make bipartite graph if(verbose){System.out.println("Making bipartite weighted graph");} //the graph object SimpleWeightedGraph graph = new SimpleWeightedGraph<>(DefaultWeightedEdge.class); - //the graph generator - SimpleWeightedBipartiteGraphMatrixGenerator graphGenerator = new SimpleWeightedBipartiteGraphMatrixGenerator(); - //the list of alpha vertices + int vertexLabelValue = 0; + //create and add alpha sequence vertices List alphaVertices = new ArrayList<>(); - for (String seq : plateAtoVMap.keySet()) { - Vertex alphaVertex = new Vertex(alphaSequences.get(seq), plateAtoVMap.get(seq)); - alphaVertices.add(alphaVertex); + for (Map.Entry entry: alphaSequences.entrySet()) { + alphaVertices.add(new Vertex(entry.getValue(), vertexLabelValue)); + vertexLabelValue++; } - //Sort to make sure the order of vertices in list matches the order of the adjacency matrix - Collections.sort(alphaVertices); - //Add ordered list of vertices to the graph - graphGenerator.first(alphaVertices); - //the list of beta vertices + alphaVertices.forEach(graph::addVertex); + //add beta sequence vertices List betaVertices = new ArrayList<>(); - for (String seq : plateBtoVMap.keySet()) { - Vertex betaVertex = new Vertex(betaSequences.get(seq), plateBtoVMap.get(seq)); - betaVertices.add(betaVertex); + for (Map.Entry entry: betaSequences.entrySet()) { + betaVertices.add(new Vertex(entry.getValue(), vertexLabelValue)); + vertexLabelValue++; } - //Sort to make sure the order of vertices in list matches the order of the adjacency matrix - Collections.sort(betaVertices); - //Add ordered list of vertices to the graph - graphGenerator.second(betaVertices); - //use adjacency matrix of weight created previously - graphGenerator.weights(weights); - graphGenerator.generateGraph(graph); + betaVertices.forEach(graph::addVertex); + //add edges + for(Vertex alpha: alphaVertices){ + for(Vertex beta: betaVertices) { + Set sharedWells = alpha.getRecord().getWells(); + sharedWells.retainAll(beta.getRecord().getWells()); + if(!sharedWells.isEmpty()) { + DefaultWeightedEdge edge = graph.addEdge(alpha, beta); + graph.setEdgeWeight(edge, sharedWells.size()); + } + } + } + if(verbose){System.out.println("Graph created");} //stop timing Instant stop = Instant.now();