First attempt at command line arguments
This commit is contained in:
@@ -7,6 +7,7 @@ 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.List;
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
||||||
public class MatchingFileWriter {
|
public class MatchingFileWriter {
|
||||||
@@ -28,6 +29,13 @@ public class MatchingFileWriter {
|
|||||||
this.allResults = result.getAllResults();
|
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(){
|
public void writeResultsToFile(){
|
||||||
String[] headerStrings = new String[headers.size()];
|
String[] headerStrings = new String[headers.size()];
|
||||||
for(int i = 0; i < headers.size(); i++){
|
for(int i = 0; i < headers.size(); i++){
|
||||||
|
|||||||
@@ -48,43 +48,44 @@ public class Simulator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static MatchingResult matchCDR3s(List<Integer[]> distinctCells,
|
public static MatchingResult matchCDR3s(List<Integer[]> distinctCells,
|
||||||
Plate samplePlate, Integer lowThreshold, Integer highThreshold){
|
Plate samplePlate, Integer lowThreshold,
|
||||||
System.out.println("Cells: " + distinctCells.size());
|
Integer highThreshold, boolean verbose){
|
||||||
|
if(verbose){System.out.println("Cells: " + distinctCells.size());}
|
||||||
|
|
||||||
Instant start = Instant.now();
|
Instant start = Instant.now();
|
||||||
int numWells = samplePlate.getSize();
|
int numWells = samplePlate.getSize();
|
||||||
int[] alphaIndex = {cdr3AlphaIndex};
|
int[] alphaIndex = {cdr3AlphaIndex};
|
||||||
int[] betaIndex = {cdr3BetaIndex};
|
int[] betaIndex = {cdr3BetaIndex};
|
||||||
|
|
||||||
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 = makePeptideToPeptideMap(distinctCells, 0, 1);
|
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> allAlphas = samplePlate.assayWellsPeptideP(alphaIndex);
|
||||||
Map<Integer, Integer> allBetas = samplePlate.assayWellsPeptideP(betaIndex);
|
Map<Integer, Integer> allBetas = samplePlate.assayWellsPeptideP(betaIndex);
|
||||||
int alphaCount = allAlphas.size();
|
int alphaCount = allAlphas.size();
|
||||||
System.out.println("all alphas count: " + alphaCount);
|
if(verbose){System.out.println("all alphas count: " + alphaCount);}
|
||||||
int betaCount = allBetas.size();
|
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 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
|
//Remove below-minimum-overlap-threshold peptides because they can't possibly have an overlap with another
|
||||||
//peptide that's above the threshold.
|
//peptide that's above the threshold.
|
||||||
System.out.println("Removing peptides present in all wells.");
|
if(verbose){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 with occupancy below the minimum overlap threshold");}
|
||||||
filterByOccupancyThreshold(allAlphas, lowThreshold, numWells - 1);
|
filterByOccupancyThreshold(allAlphas, lowThreshold, numWells - 1);
|
||||||
filterByOccupancyThreshold(allBetas, lowThreshold, numWells - 1);
|
filterByOccupancyThreshold(allBetas, lowThreshold, numWells - 1);
|
||||||
System.out.println("Peptides removed");
|
if(verbose){System.out.println("Peptides removed");}
|
||||||
int pairableAlphaCount = allAlphas.size();
|
int pairableAlphaCount = allAlphas.size();
|
||||||
System.out.println("Remaining alpha count: " + pairableAlphaCount);
|
if(verbose){System.out.println("Remaining alpha count: " + pairableAlphaCount);}
|
||||||
int pairableBetaCount = allBetas.size();
|
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
|
//For the SimpleWeightedBipartiteGraphMatrixGenerator, all vertices must have
|
||||||
// distinct numbers associated with them. Since I'm using a 2D array, that means
|
// 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
|
// 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);
|
Map<Integer, Integer> plateAtoVMap = invertVertexMap(plateVtoAMap);
|
||||||
//keys are betas, values are sequential integer vertices from previous map
|
//keys are betas, values are sequential integer vertices from previous map
|
||||||
Map<Integer, Integer> plateBtoVMap = invertVertexMap(plateVtoBMap);
|
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
|
//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 appears in
|
//count how many wells each beta appears in
|
||||||
@@ -112,9 +113,9 @@ public class Simulator {
|
|||||||
|
|
||||||
countPeptidesAndFillMatrix(samplePlate, allAlphas, allBetas, plateAtoVMap,
|
countPeptidesAndFillMatrix(samplePlate, allAlphas, allBetas, plateAtoVMap,
|
||||||
plateBtoVMap, alphaIndex, betaIndex, alphaWellCounts, betaWellCounts, weights);
|
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 =
|
SimpleWeightedGraph<Integer, DefaultWeightedEdge> graph =
|
||||||
new SimpleWeightedGraph<>(DefaultWeightedEdge.class);
|
new SimpleWeightedGraph<>(DefaultWeightedEdge.class);
|
||||||
SimpleWeightedBipartiteGraphMatrixGenerator graphGenerator = new SimpleWeightedBipartiteGraphMatrixGenerator();
|
SimpleWeightedBipartiteGraphMatrixGenerator graphGenerator = new SimpleWeightedBipartiteGraphMatrixGenerator();
|
||||||
@@ -126,18 +127,18 @@ public class Simulator {
|
|||||||
graphGenerator.second(betaVertices); //This will work because LinkedHashMap preserves order of entry
|
graphGenerator.second(betaVertices); //This will work because LinkedHashMap preserves order of entry
|
||||||
graphGenerator.weights(weights);
|
graphGenerator.weights(weights);
|
||||||
graphGenerator.generateGraph(graph);
|
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);
|
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 =
|
MaximumWeightBipartiteMatching maxWeightMatching =
|
||||||
new MaximumWeightBipartiteMatching(graph, plateVtoAMap.keySet(), plateVtoBMap.keySet());
|
new MaximumWeightBipartiteMatching(graph, plateVtoAMap.keySet(), plateVtoBMap.keySet());
|
||||||
MatchingAlgorithm.Matching<String, DefaultWeightedEdge> graphMatching = maxWeightMatching.getMatching();
|
MatchingAlgorithm.Matching<String, DefaultWeightedEdge> graphMatching = maxWeightMatching.getMatching();
|
||||||
System.out.println("Matching completed");
|
if(verbose){System.out.println("Matching completed");}
|
||||||
Instant stop = Instant.now();
|
Instant stop = Instant.now();
|
||||||
|
|
||||||
//Header for CSV file
|
//Header for CSV file
|
||||||
@@ -209,10 +210,13 @@ public class Simulator {
|
|||||||
comments.add("Pairing error rate: " + pairingErrorRateTrunc);
|
comments.add("Pairing error rate: " + pairingErrorRateTrunc);
|
||||||
Duration time = Duration.between(start, stop);
|
Duration time = Duration.between(start, stop);
|
||||||
comments.add("Simulation time: " + nf.format(time.toSeconds()) + " seconds");
|
comments.add("Simulation time: " + nf.format(time.toSeconds()) + " seconds");
|
||||||
for(String s: comments){
|
if(verbose){
|
||||||
System.out.println(s);
|
for(String s: comments){
|
||||||
|
System.out.println(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return new MatchingResult(samplePlate.getSourceFileName(), comments, header, allResults, matchMap, time);
|
return new MatchingResult(samplePlate.getSourceFileName(), comments, header, allResults, matchMap, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import org.apache.commons.cli.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.util.InputMismatchException;
|
import java.util.InputMismatchException;
|
||||||
@@ -11,33 +13,85 @@ public class UserInterface {
|
|||||||
static int input;
|
static int input;
|
||||||
static boolean quit = false;
|
static boolean quit = false;
|
||||||
|
|
||||||
public static void main(String args[]) {
|
public static void main(String[] args) {
|
||||||
while(!quit) {
|
|
||||||
System.out.println("\nALPHA/BETA T-CELL RECEPTOR MATCHING SIMULATOR");
|
if(args.length != 0){
|
||||||
System.out.println("Please select an option:");
|
Options options = new Options();
|
||||||
System.out.println("1) Generate a population of distinct cells");
|
Option matchCDR3 = Option.builder("m")
|
||||||
System.out.println("2) Generate a sample plate of T cells");
|
.longOpt("match")
|
||||||
System.out.println("3) Simulate CDR3 alpha/beta T cell matching");
|
.desc("Match CDR3s. Requires a cell sample file and any number of plate files.")
|
||||||
System.out.println("4) Simulate CDR3/CDR1 T cell matching");
|
.build();
|
||||||
System.out.println("5) Acknowledgements");
|
options.addOption(matchCDR3);
|
||||||
System.out.println("0) Exit");
|
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 {
|
try {
|
||||||
input = sc.nextInt();
|
CommandLine line = parser.parse(options, args);
|
||||||
switch(input){
|
if(line.hasOption("m")){
|
||||||
case 1 -> makeCells();
|
String cellFile = line.getOptionValue("c");
|
||||||
case 2 -> makePlate();
|
Integer lowThreshold = Integer.valueOf(line.getOptionValue(lowThresh));
|
||||||
case 3 -> matchCells();
|
Integer highThreshold = Integer.valueOf(line.getOptionValue(highThresh));
|
||||||
case 4 -> matchCellsExpanded();
|
for(String plate: line.getOptionValues("p")) {
|
||||||
case 5 -> acknowledge();
|
matchCDR3s(cellFile, plate, lowThreshold, highThreshold);
|
||||||
case 0 -> quit = true;
|
}
|
||||||
default -> throw new InputMismatchException("Invalid input.");
|
|
||||||
}
|
}
|
||||||
}catch(InputMismatchException ex){
|
}
|
||||||
System.out.println(ex);
|
catch (ParseException exp) {
|
||||||
sc.next();
|
System.err.println("Parsing failed. Reason: " + exp.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sc.close();
|
else {
|
||||||
|
while (!quit) {
|
||||||
|
System.out.println("\nALPHA/BETA T-CELL RECEPTOR MATCHING SIMULATOR");
|
||||||
|
System.out.println("Please select an option:");
|
||||||
|
System.out.println("1) Generate a population of distinct cells");
|
||||||
|
System.out.println("2) Generate a sample plate of T cells");
|
||||||
|
System.out.println("3) Simulate CDR3 alpha/beta T cell matching");
|
||||||
|
System.out.println("4) Simulate CDR3/CDR1 T cell matching");
|
||||||
|
System.out.println("5) Acknowledgements");
|
||||||
|
System.out.println("0) Exit");
|
||||||
|
try {
|
||||||
|
input = sc.nextInt();
|
||||||
|
switch (input) {
|
||||||
|
case 1 -> makeCells();
|
||||||
|
case 2 -> makePlate();
|
||||||
|
case 3 -> matchCells();
|
||||||
|
case 4 -> matchCellsCDR1();
|
||||||
|
case 5 -> acknowledge();
|
||||||
|
case 0 -> quit = true;
|
||||||
|
default -> throw new InputMismatchException("Invalid input.");
|
||||||
|
}
|
||||||
|
} catch (InputMismatchException ex) {
|
||||||
|
System.out.println(ex);
|
||||||
|
sc.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sc.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void makeCells() {
|
private static void makeCells() {
|
||||||
@@ -68,6 +122,22 @@ public class UserInterface {
|
|||||||
writer.writeCellsToFile();
|
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
|
//method to output a CSV of
|
||||||
private static void makePlate() {
|
private static void makePlate() {
|
||||||
String cellFile = null;
|
String cellFile = null;
|
||||||
@@ -149,6 +219,30 @@ public class UserInterface {
|
|||||||
writer.writePlateFile();
|
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() {
|
private static void matchCells() {
|
||||||
String filename = null;
|
String filename = null;
|
||||||
String cellFile = null;
|
String cellFile = null;
|
||||||
@@ -192,14 +286,14 @@ public class UserInterface {
|
|||||||
highThreshold = plate.getSize() - 1;
|
highThreshold = plate.getSize() - 1;
|
||||||
}
|
}
|
||||||
List<Integer[]> cells = cellReader.getCells();
|
List<Integer[]> cells = cellReader.getCells();
|
||||||
MatchingResult results = Simulator.matchCDR3s(cells, plate, lowThreshold, highThreshold);
|
MatchingResult results = Simulator.matchCDR3s(cells, plate, lowThreshold, highThreshold, true);
|
||||||
//result writer
|
//result writer
|
||||||
MatchingFileWriter writer = new MatchingFileWriter(filename, results);
|
MatchingFileWriter writer = new MatchingFileWriter(filename, results);
|
||||||
writer.writeResultsToFile();
|
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
|
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
|
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;
|
highThresholdCDR1 = plate.getSize() - 1;
|
||||||
}
|
}
|
||||||
List<Integer[]> cells = cellReader.getCells();
|
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,
|
MatchingResult[] results = Simulator.matchCDR1s(cells, plate, lowThresholdCDR1,
|
||||||
highThresholdCDR1, preliminaryResults);
|
highThresholdCDR1, preliminaryResults);
|
||||||
MatchingFileWriter writer = new MatchingFileWriter(filename + "_FirstPass", results[0]);
|
MatchingFileWriter writer = new MatchingFileWriter(filename + "_FirstPass", results[0]);
|
||||||
|
|||||||
Reference in New Issue
Block a user