First attempt at command line arguments

This commit is contained in:
2021-11-19 17:31:18 -06:00
parent 3d0a843cea
commit 981e24011d
3 changed files with 157 additions and 51 deletions

View File

@@ -7,6 +7,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.regex.Pattern;
public class MatchingFileWriter {
@@ -28,6 +29,13 @@ public class MatchingFileWriter {
this.allResults = result.getAllResults();
}
public void writeErrorRateToTerminal(){
for(String s: comments){
if(s.matches("(Pairing error rate: )(\\d*.\\d+)")){
System.out.println(s);
}
}
}
public void writeResultsToFile(){
String[] headerStrings = new String[headers.size()];
for(int i = 0; i < headers.size(); i++){

View File

@@ -48,43 +48,44 @@ public class Simulator {
}
public static MatchingResult matchCDR3s(List<Integer[]> distinctCells,
Plate samplePlate, Integer lowThreshold, Integer highThreshold){
System.out.println("Cells: " + distinctCells.size());
Plate samplePlate, Integer lowThreshold,
Integer highThreshold, boolean verbose){
if(verbose){System.out.println("Cells: " + distinctCells.size());}
Instant start = Instant.now();
int numWells = samplePlate.getSize();
int[] alphaIndex = {cdr3AlphaIndex};
int[] betaIndex = {cdr3BetaIndex};
System.out.println("Making cell maps");
if(verbose){System.out.println("Making cell maps");}
//HashMap keyed to Alphas, values Betas
Map<Integer, Integer> distCellsMapAlphaKey = makePeptideToPeptideMap(distinctCells, 0, 1);
System.out.println("Cell maps made");
if(verbose){System.out.println("Cell maps made");}
System.out.println("Making well maps");
if(verbose){System.out.println("Making well maps");}
Map<Integer, Integer> allAlphas = samplePlate.assayWellsPeptideP(alphaIndex);
Map<Integer, Integer> allBetas = samplePlate.assayWellsPeptideP(betaIndex);
int alphaCount = allAlphas.size();
System.out.println("all alphas count: " + alphaCount);
if(verbose){System.out.println("all alphas count: " + alphaCount);}
int betaCount = allBetas.size();
System.out.println("all betas count: " + betaCount);
if(verbose){System.out.println("all betas count: " + betaCount);}
System.out.println("Well maps made");
if(verbose){System.out.println("Well maps made");}
//Remove saturating-occupancy peptides because they have no signal value.
//Remove below-minimum-overlap-threshold peptides because they can't possibly have an overlap with another
//peptide that's above the threshold.
System.out.println("Removing peptides present in all wells.");
System.out.println("Removing peptides with occupancy below the minimum overlap threshold");
if(verbose){System.out.println("Removing peptides present in all wells.");}
if(verbose){System.out.println("Removing peptides with occupancy below the minimum overlap threshold");}
filterByOccupancyThreshold(allAlphas, lowThreshold, numWells - 1);
filterByOccupancyThreshold(allBetas, lowThreshold, numWells - 1);
System.out.println("Peptides removed");
if(verbose){System.out.println("Peptides removed");}
int pairableAlphaCount = allAlphas.size();
System.out.println("Remaining alpha count: " + pairableAlphaCount);
if(verbose){System.out.println("Remaining alpha count: " + pairableAlphaCount);}
int pairableBetaCount = allBetas.size();
System.out.println("Remaining beta count: " + pairableBetaCount);
if(verbose){System.out.println("Remaining beta count: " + pairableBetaCount);}
System.out.println("Making vertex maps");
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
@@ -101,9 +102,9 @@ public class Simulator {
Map<Integer, Integer> plateAtoVMap = invertVertexMap(plateVtoAMap);
//keys are betas, values are sequential integer vertices from previous map
Map<Integer, Integer> plateBtoVMap = invertVertexMap(plateVtoBMap);
System.out.println("Vertex maps made");
if(verbose){System.out.println("Vertex maps made");}
System.out.println("Creating adjacency matrix");
if(verbose){System.out.println("Creating adjacency matrix");}
//Count how many wells each alpha appears in
Map<Integer, Integer> alphaWellCounts = new HashMap<>();
//count how many wells each beta appears in
@@ -112,9 +113,9 @@ public class Simulator {
countPeptidesAndFillMatrix(samplePlate, allAlphas, allBetas, plateAtoVMap,
plateBtoVMap, alphaIndex, betaIndex, alphaWellCounts, betaWellCounts, weights);
System.out.println("matrix created");
if(verbose){System.out.println("matrix created");}
System.out.println("creating graph");
if(verbose){System.out.println("creating graph");}
SimpleWeightedGraph<Integer, DefaultWeightedEdge> graph =
new SimpleWeightedGraph<>(DefaultWeightedEdge.class);
SimpleWeightedBipartiteGraphMatrixGenerator graphGenerator = new SimpleWeightedBipartiteGraphMatrixGenerator();
@@ -126,18 +127,18 @@ public class Simulator {
graphGenerator.second(betaVertices); //This will work because LinkedHashMap preserves order of entry
graphGenerator.weights(weights);
graphGenerator.generateGraph(graph);
System.out.println("Graph created");
if(verbose){System.out.println("Graph created");}
System.out.println("Eliminating edges with weights outside threshold values");
if(verbose){System.out.println("Eliminating edges with weights outside threshold values");}
filterByOccupancyThreshold(graph, lowThreshold, highThreshold);
System.out.println("Over- and under-weight edges set to 0.0");
if(verbose){System.out.println("Over- and under-weight edges set to 0.0");}
System.out.println("Finding maximum weighted matching");
if(verbose){System.out.println("Finding maximum weighted matching");}
MaximumWeightBipartiteMatching maxWeightMatching =
new MaximumWeightBipartiteMatching(graph, plateVtoAMap.keySet(), plateVtoBMap.keySet());
MatchingAlgorithm.Matching<String, DefaultWeightedEdge> graphMatching = maxWeightMatching.getMatching();
System.out.println("Matching completed");
if(verbose){System.out.println("Matching completed");}
Instant stop = Instant.now();
//Header for CSV file
@@ -209,9 +210,12 @@ public class Simulator {
comments.add("Pairing error rate: " + pairingErrorRateTrunc);
Duration time = Duration.between(start, stop);
comments.add("Simulation time: " + nf.format(time.toSeconds()) + " seconds");
if(verbose){
for(String s: comments){
System.out.println(s);
}
}
return new MatchingResult(samplePlate.getSourceFileName(), comments, header, allResults, matchMap, time);
}

View File

@@ -1,3 +1,5 @@
import org.apache.commons.cli.*;
import java.util.List;
import java.util.Scanner;
import java.util.InputMismatchException;
@@ -11,7 +13,58 @@ public class UserInterface {
static int input;
static boolean quit = false;
public static void main(String args[]) {
public static void main(String[] args) {
if(args.length != 0){
Options options = new Options();
Option matchCDR3 = Option.builder("m")
.longOpt("match")
.desc("Match CDR3s. Requires a cell sample file and any number of plate files.")
.build();
options.addOption(matchCDR3);
Option inputCells = Option.builder("c")
.longOpt("cellfile")
.hasArg()
.argName("file")
.desc("The cell sample file used for matching")
.required().build();
options.addOption(inputCells);
Option lowThresh = Option.builder("low")
.hasArg()
.argName("number")
.desc("Sets the minimum occupancy overlap to attempt matching")
.required().build();
options.addOption(lowThresh);
Option highThresh = Option.builder("high")
.hasArg()
.argName("number")
.desc("Sets the maximum occupancy overlap to attempt matching")
.required().build();
options.addOption(highThresh);
Option inputPlates = Option.builder("p")
.longOpt("platefiles")
.hasArgs()
.desc("Plate files to match")
.required().build();
options.addOption(inputPlates);
CommandLineParser parser = new DefaultParser();
try {
CommandLine line = parser.parse(options, args);
if(line.hasOption("m")){
String cellFile = line.getOptionValue("c");
Integer lowThreshold = Integer.valueOf(line.getOptionValue(lowThresh));
Integer highThreshold = Integer.valueOf(line.getOptionValue(highThresh));
for(String plate: line.getOptionValues("p")) {
matchCDR3s(cellFile, plate, lowThreshold, highThreshold);
}
}
}
catch (ParseException exp) {
System.err.println("Parsing failed. Reason: " + exp.getMessage());
}
}
else {
while (!quit) {
System.out.println("\nALPHA/BETA T-CELL RECEPTOR MATCHING SIMULATOR");
System.out.println("Please select an option:");
@@ -27,7 +80,7 @@ public class UserInterface {
case 1 -> makeCells();
case 2 -> makePlate();
case 3 -> matchCells();
case 4 -> matchCellsExpanded();
case 4 -> matchCellsCDR1();
case 5 -> acknowledge();
case 0 -> quit = true;
default -> throw new InputMismatchException("Invalid input.");
@@ -39,6 +92,7 @@ public class UserInterface {
}
sc.close();
}
}
private static void makeCells() {
String filename = null;
@@ -68,6 +122,22 @@ public class UserInterface {
writer.writeCellsToFile();
}
private static void makeCells(String filename, Integer numCells, Integer cdr1Freq){
CellSample sample = Simulator.generateCellSample(numCells, cdr1Freq);
CellFileWriter writer = new CellFileWriter(filename, sample);
writer.writeCellsToFile();
}
private static void makePlate(String cellFile, String filename, Double stdDev,
Integer numWells, Integer numSections,
Integer[] concentrations, Double dropOutRate){
CellFileReader cellReader = new CellFileReader(cellFile);
Plate samplePlate = new Plate(numWells, dropOutRate, concentrations, stdDev);
samplePlate.fillWells(cellReader.getFilename(), cellReader.getCells());
PlateFileWriter writer = new PlateFileWriter(filename, samplePlate);
writer.writePlateFile();
}
//method to output a CSV of
private static void makePlate() {
String cellFile = null;
@@ -149,6 +219,30 @@ public class UserInterface {
writer.writePlateFile();
}
private static void matchCDR3s(String cellFile, String plateFile, Integer lowThreshold, Integer highThreshold){
CellFileReader cellReader = new CellFileReader(cellFile);
PlateFileReader plateReader = new PlateFileReader(plateFile);
Plate plate = new Plate(plateReader.getFilename(), plateReader.getWells());
if (cellReader.getCells().size() == 0){
System.exit(0);
}
else if(plate.getWells().size() == 0){
System.exit(0);
}
else{
if(highThreshold >= plate.getSize()){
highThreshold = plate.getSize() - 1;
}
List<Integer[]> cells = cellReader.getCells();
MatchingResult results = Simulator.matchCDR3s(cells, plate, lowThreshold, highThreshold, false);
//result writer
MatchingFileWriter writer = new MatchingFileWriter(null, results);
writer.writeErrorRateToTerminal();
}
}
private static void matchCells() {
String filename = null;
String cellFile = null;
@@ -192,14 +286,14 @@ public class UserInterface {
highThreshold = plate.getSize() - 1;
}
List<Integer[]> cells = cellReader.getCells();
MatchingResult results = Simulator.matchCDR3s(cells, plate, lowThreshold, highThreshold);
MatchingResult results = Simulator.matchCDR3s(cells, plate, lowThreshold, highThreshold, true);
//result writer
MatchingFileWriter writer = new MatchingFileWriter(filename, results);
writer.writeResultsToFile();
}
}
public static void matchCellsExpanded(){
public static void matchCellsCDR1(){
/*
The idea here is that we'll get the CDR3 alpha/beta matches first. Then we'll try to match CDR3s to CDR1s by
looking at the top two matches for each CDR3. If CDR3s in the same cell simply swap CDR1s, we assume a correct
@@ -276,7 +370,7 @@ public class UserInterface {
highThresholdCDR1 = plate.getSize() - 1;
}
List<Integer[]> cells = cellReader.getCells();
MatchingResult preliminaryResults = Simulator.matchCDR3s(cells, plate, lowThresholdCDR3, highThresholdCDR3);
MatchingResult preliminaryResults = Simulator.matchCDR3s(cells, plate, lowThresholdCDR3, highThresholdCDR3, true);
MatchingResult[] results = Simulator.matchCDR1s(cells, plate, lowThresholdCDR1,
highThresholdCDR1, preliminaryResults);
MatchingFileWriter writer = new MatchingFileWriter(filename + "_FirstPass", results[0]);