From 57fe9c161917e98afb029a576282b62287552d05 Mon Sep 17 00:00:00 2001 From: eugenefischer <66030419+eugenefischer@users.noreply.github.com> Date: Thu, 10 Apr 2025 12:42:19 -0500 Subject: [PATCH] Update graph modification functions to work with edges directly --- src/main/java/BiGpairSEQ.java | 10 +-- src/main/java/GraphModificationFunctions.java | 75 ++++++------------- src/main/java/Simulator.java | 11 ++- 3 files changed, 33 insertions(+), 63 deletions(-) diff --git a/src/main/java/BiGpairSEQ.java b/src/main/java/BiGpairSEQ.java index 674e9d2..cf5c385 100644 --- a/src/main/java/BiGpairSEQ.java +++ b/src/main/java/BiGpairSEQ.java @@ -13,7 +13,7 @@ public class BiGpairSEQ { private static boolean cacheCells = false; private static boolean cachePlate = false; private static boolean cacheGraph = false; - private static AlgorithmType matchingAlgoritmType = AlgorithmType.HUNGARIAN; + private static AlgorithmType matchingAlgorithmType = AlgorithmType.HUNGARIAN; private static HeapType priorityQueueHeapType = HeapType.PAIRING; private static DistributionType distributionType = DistributionType.ZIPF; private static boolean outputBinary = true; @@ -166,13 +166,13 @@ public class BiGpairSEQ { return priorityQueueHeapType; } - public static AlgorithmType getMatchingAlgoritmType() { return matchingAlgoritmType; } + public static AlgorithmType getMatchingAlgorithmType() { return matchingAlgorithmType; } - public static void setHungarianAlgorithm() { matchingAlgoritmType = AlgorithmType.HUNGARIAN; } + public static void setHungarianAlgorithm() { matchingAlgorithmType = AlgorithmType.HUNGARIAN; } - public static void setIntegerWeightScalingAlgorithm() { matchingAlgoritmType = AlgorithmType.INTEGER_WEIGHT_SCALING; } + public static void setIntegerWeightScalingAlgorithm() { matchingAlgorithmType = AlgorithmType.INTEGER_WEIGHT_SCALING; } - public static void setAuctionAlgorithm() { matchingAlgoritmType = AlgorithmType.AUCTION; } + public static void setAuctionAlgorithm() { matchingAlgorithmType = AlgorithmType.AUCTION; } public static void setPairingHeap() { priorityQueueHeapType = HeapType.PAIRING; diff --git a/src/main/java/GraphModificationFunctions.java b/src/main/java/GraphModificationFunctions.java index 10167dc..490f17f 100644 --- a/src/main/java/GraphModificationFunctions.java +++ b/src/main/java/GraphModificationFunctions.java @@ -1,72 +1,49 @@ import org.jgrapht.graph.DefaultWeightedEdge; import org.jgrapht.graph.SimpleWeightedGraph; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public interface GraphModificationFunctions { //remove over- and under-weight edges, return removed edges - static Map filterByOverlapThresholds(SimpleWeightedGraph graph, - int low, int high, boolean saveEdges) { - Map removedEdges = new HashMap<>(); + static Map filterByOverlapThresholds(SimpleWeightedGraph graph, + int low, int high, boolean saveEdges) { + Map removedEdges = new HashMap<>(); for (DefaultWeightedEdge e : graph.edgeSet()) { if ((graph.getEdgeWeight(e) > high) || (graph.getEdgeWeight(e) < low)) { if(saveEdges) { - Vertex source = graph.getEdgeSource(e); - Vertex target = graph.getEdgeTarget(e); - Integer weight = (int) graph.getEdgeWeight(e); - Vertex[] edge = {source, target}; - removedEdges.put(edge, weight); + Vertex[] vertices = {graph.getEdgeSource(e), graph.getEdgeTarget(e)}; + removedEdges.put(e, vertices); } - else { - graph.setEdgeWeight(e, 0.0); - } - } - } - if(saveEdges) { - for (Vertex[] edge : removedEdges.keySet()) { - graph.removeEdge(edge[0], edge[1]); + graph.removeEdge(e); } } return removedEdges; } //Remove edges for pairs with large occupancy discrepancy, return removed edges - static Map filterByRelativeOccupancy(SimpleWeightedGraph graph, + static Map filterByRelativeOccupancy(SimpleWeightedGraph graph, Integer maxOccupancyDifference, boolean saveEdges) { - Map removedEdges = new HashMap<>(); + Map removedEdges = new HashMap<>(); for (DefaultWeightedEdge e : graph.edgeSet()) { Integer alphaOcc = graph.getEdgeSource(e).getOccupancy(); Integer betaOcc = graph.getEdgeTarget(e).getOccupancy(); if (Math.abs(alphaOcc - betaOcc) >= maxOccupancyDifference) { if (saveEdges) { - Vertex source = graph.getEdgeSource(e); - Vertex target = graph.getEdgeTarget(e); - Integer weight = (int) graph.getEdgeWeight(e); - Vertex[] edge = {source, target}; - removedEdges.put(edge, weight); + Vertex[] vertices = {graph.getEdgeSource(e), graph.getEdgeTarget(e)}; + removedEdges.put(e, vertices); } - else { - graph.setEdgeWeight(e, 0.0); - } - } - } - if(saveEdges) { - for (Vertex[] edge : removedEdges.keySet()) { - graph.removeEdge(edge[0], edge[1]); + graph.removeEdge(e); } } return removedEdges; } //Remove edges for pairs where overlap size is significantly lower than the well occupancy, return removed edges - static Map filterByOverlapPercent(SimpleWeightedGraph graph, + static Map filterByOverlapPercent(SimpleWeightedGraph graph, Integer minOverlapPercent, boolean saveEdges) { - Map removedEdges = new HashMap<>(); + Map removedEdges = new HashMap<>(); for (DefaultWeightedEdge e : graph.edgeSet()) { Integer alphaOcc = graph.getEdgeSource(e).getOccupancy(); Integer betaOcc = graph.getEdgeTarget(e).getOccupancy(); @@ -74,20 +51,10 @@ public interface GraphModificationFunctions { double min = minOverlapPercent / 100.0; if ((weight / alphaOcc < min) || (weight / betaOcc < min)) { if (saveEdges) { - Vertex source = graph.getEdgeSource(e); - Vertex target = graph.getEdgeTarget(e); - Integer intWeight = (int) graph.getEdgeWeight(e); - Vertex[] edge = {source, target}; - removedEdges.put(edge, intWeight); + Vertex[] vertices = {graph.getEdgeSource(e), graph.getEdgeTarget(e)}; + removedEdges.put(e, vertices); } - else { - graph.setEdgeWeight(e, 0.0); - } - } - } - if(saveEdges) { - for (Vertex[] edge : removedEdges.keySet()) { - graph.removeEdge(edge[0], edge[1]); + graph.removeEdge(e); } } return removedEdges; @@ -126,10 +93,10 @@ public interface GraphModificationFunctions { } static void addRemovedEdges(SimpleWeightedGraph graph, - Map removedEdges) { - for (Vertex[] edge : removedEdges.keySet()) { - DefaultWeightedEdge e = graph.addEdge(edge[0], edge[1]); - graph.setEdgeWeight(e, removedEdges.get(edge)); + Map removedEdges) { + for (DefaultWeightedEdge edge : removedEdges.keySet()) { + Vertex[] vertices = removedEdges.get(edge); + graph.addEdge(vertices[0], vertices[1], edge); } } diff --git a/src/main/java/Simulator.java b/src/main/java/Simulator.java index 4ba488d..d0b4f77 100644 --- a/src/main/java/Simulator.java +++ b/src/main/java/Simulator.java @@ -1,9 +1,7 @@ import org.jgrapht.alg.interfaces.MatchingAlgorithm; import org.jgrapht.alg.matching.MaximumWeightBipartiteMatching; -import org.jgrapht.generate.SimpleWeightedBipartiteGraphMatrixGenerator; import org.jgrapht.graph.DefaultWeightedEdge; import org.jgrapht.graph.SimpleWeightedGraph; -import org.jheaps.tree.FibonacciHeap; import org.jheaps.tree.PairingHeap; import java.math.BigDecimal; @@ -184,7 +182,7 @@ public class Simulator implements GraphModificationFunctions { Integer minOverlapPercent, boolean verbose, boolean calculatePValue) { Instant start = Instant.now(); SimpleWeightedGraph graph = data.getGraph(); - Map removedEdges = new HashMap<>(); + Map removedEdges = new HashMap<>(); boolean saveEdges = BiGpairSEQ.cacheGraph(); int numWells = data.getNumWells(); //Integer alphaCount = data.getAlphaCount(); @@ -202,6 +200,7 @@ public class Simulator implements GraphModificationFunctions { } Integer graphAlphaCount = alphas.size(); Integer graphBetaCount = betas.size(); + Integer graphEdgeCount = graph.edgeSet().size(); //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");} @@ -221,12 +220,14 @@ public class Simulator implements GraphModificationFunctions { if(verbose){System.out.println("Edges between vertices of with excessively different occupancy values " + "removed");} + Integer filteredGraphEdgeCount = graph.edgeSet().size(); + //Find Maximum Weight Matching if(verbose){System.out.println("Finding maximum weight matching");} //The matching object MatchingAlgorithm maxWeightMatching; //Determine algorithm type - AlgorithmType algorithm = BiGpairSEQ.getMatchingAlgoritmType(); + AlgorithmType algorithm = BiGpairSEQ.getMatchingAlgorithmType(); switch (algorithm) { //Only two options now, but I have room to add more algorithms in the future this way case AUCTION -> { //create a new MaximumIntegerWeightBipartiteAuctionMatching @@ -372,8 +373,10 @@ public class Simulator implements GraphModificationFunctions { metadata.put("real sequence collision rate", data.getRealSequenceCollisionRate().toString()); metadata.put("total alphas read from plate", data.getAlphaCount().toString()); metadata.put("total betas read from plate", data.getBetaCount().toString()); + metadata.put("initial edges in graph", graphEdgeCount.toString()); metadata.put("alphas in graph (after pre-filtering)", graphAlphaCount.toString()); metadata.put("betas in graph (after pre-filtering)", graphBetaCount.toString()); + metadata.put("final edges in graph (after pre-filtering)", filteredGraphEdgeCount.toString()); metadata.put("high overlap threshold for pairing", highThreshold.toString()); metadata.put("low overlap threshold for pairing", lowThreshold.toString()); metadata.put("minimum overlap percent for pairing", minOverlapPercent.toString());