5 Commits

11 changed files with 243 additions and 82 deletions

View File

@@ -6,10 +6,11 @@
<element id="file-copy" path="$PROJECT_DIR$/src/main/java/META-INF/MANIFEST.MF" /> <element id="file-copy" path="$PROJECT_DIR$/src/main/java/META-INF/MANIFEST.MF" />
</element> </element>
<element id="module-output" name="TCellSim" /> <element id="module-output" name="TCellSim" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/apache/commons/commons-csv/1.9.0/commons-csv-1.9.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/annotations/23.0.0/annotations-23.0.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jgrapht/jgrapht-core/1.5.1/jgrapht-core-1.5.1.jar" path-in-jar="/" /> <element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jgrapht/jgrapht-core/1.5.1/jgrapht-core-1.5.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jheaps/jheaps/0.13/jheaps-0.13.jar" path-in-jar="/" /> <element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jheaps/jheaps/0.13/jheaps-0.13.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/commons-cli/commons-cli/1.5.0/commons-cli-1.5.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/apache/commons/commons-csv/1.9.0/commons-csv-1.9.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/annotations/23.0.0/annotations-23.0.0.jar" path-in-jar="/" />
</root> </root>
</artifact> </artifact>
</component> </component>

10
.idea/libraries/commons_cli.xml generated Normal file
View File

@@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="commons.cli" type="repository">
<properties maven-id="commons-cli:commons-cli:1.5.0" />
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/commons-cli/commons-cli/1.5.0/commons-cli-1.5.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -11,17 +11,19 @@ import java.util.List;
public class CellFileReader { public class CellFileReader {
private String filename;
private List<Integer[]> distinctCells = new ArrayList<>(); private List<Integer[]> distinctCells = new ArrayList<>();
public CellFileReader(String filename) { public CellFileReader(String filename) {
if(!filename.matches(".*\\.csv")){ if(!filename.matches(".*\\.csv")){
filename = filename + ".csv"; filename = filename + ".csv";
} }
this.filename = filename;
CSVFormat cellFileFormat = CSVFormat.Builder.create() CSVFormat cellFileFormat = CSVFormat.Builder.create()
.setHeader("Alpha CDR3", "Beta CDR3", "Alpha CDR1", "Beta CDR1") .setHeader("Alpha CDR3", "Beta CDR3", "Alpha CDR1", "Beta CDR1")
.setSkipHeaderRecord(true) .setSkipHeaderRecord(true)
.setCommentMarker('#')
.build(); .build();
try(//don't need to close reader bc of try-with-resources auto-closing try(//don't need to close reader bc of try-with-resources auto-closing
@@ -42,6 +44,8 @@ public class CellFileReader {
} }
} }
public String getFilename() { return filename;}
public List<Integer[]> getCells(){ public List<Integer[]> getCells(){
return distinctCells; return distinctCells;
} }

View File

@@ -7,25 +7,35 @@ 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 {
private String filename; private String filename;
private String sourceFileName;
private List<String> comments; private List<String> comments;
private List<String> headers; private List<String> headers;
private List<List<String>> results; private List<List<String>> allResults;
public MatchingFileWriter(String filename, List<String> comments, List<String> headers, List<List<String>> results){ public MatchingFileWriter(String filename, MatchingResult result){
if(!filename.matches(".*\\.csv")){ if(!filename.matches(".*\\.csv")){
filename = filename + ".csv"; filename = filename + ".csv";
} }
this.filename = filename; this.filename = filename;
this.comments = comments; this.sourceFileName = result.getSourceFileName();
this.headers = headers; this.comments = result.getComments();
this.results = results; this.headers = result.getHeaders();
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++){
@@ -41,8 +51,8 @@ public class MatchingFileWriter {
for(String comment: comments){ for(String comment: comments){
printer.printComment(comment); printer.printComment(comment);
} }
results.add(0, headers); allResults.add(0, headers);
printer.printRecords(results); printer.printRecords(allResults);
} catch(IOException ex){ } catch(IOException ex){
System.out.println("Could not make new file named "+filename); System.out.println("Could not make new file named "+filename);

View File

@@ -3,13 +3,15 @@ import java.util.List;
import java.util.Map; import java.util.Map;
public class MatchingResult { public class MatchingResult {
private String sourceFile;
private List<String> comments; private List<String> comments;
private List<String> headers; private List<String> headers;
private List<List<String>> allResults; private List<List<String>> allResults;
private Map<Integer, Integer> matchMap; private Map<Integer, Integer> matchMap;
private Duration time; private Duration time;
public MatchingResult(List<String> comments, List<String> headers, List<List<String>> allResults, Map<Integer, Integer>matchMap, Duration time){ public MatchingResult(String sourceFileName, List<String> comments, List<String> headers, List<List<String>> allResults, Map<Integer, Integer>matchMap, Duration time){
this.sourceFile = sourceFileName;
this.comments = comments; this.comments = comments;
this.headers = headers; this.headers = headers;
this.allResults = allResults; this.allResults = allResults;
@@ -37,4 +39,8 @@ public class MatchingResult {
public Duration getTime() { public Duration getTime() {
return time; return time;
} }
public String getSourceFileName() {
return sourceFile;
}
} }

View File

@@ -5,6 +5,7 @@ TODO: Implement discrete frequency distributions using Vose's Alias Method
*/ */
public class Plate { public class Plate {
private String sourceFile;
private List<List<Integer[]>> wells; private List<List<Integer[]>> wells;
private Random rand = new Random(); private Random rand = new Random();
private int size; private int size;
@@ -12,6 +13,7 @@ public class Plate {
private Integer[] concentrations; private Integer[] concentrations;
private double stdDev; private double stdDev;
public Plate (int size, double error, Integer[] concentrations, double stdDev) { public Plate (int size, double error, Integer[] concentrations, double stdDev) {
this.size = size; this.size = size;
this.error = error; this.error = error;
@@ -20,12 +22,14 @@ public class Plate {
wells = new ArrayList<>(); wells = new ArrayList<>();
} }
public Plate(List<List<Integer[]>> wells){ public Plate(String sourceFileName, List<List<Integer[]>> wells){
this.sourceFile = sourceFileName;
this.wells = wells; this.wells = wells;
this.size = wells.size(); this.size = wells.size();
} }
public void fillWells(List<Integer[]> cells) { public void fillWells(String sourceFileName, List<Integer[]> cells) {
sourceFile = sourceFileName;
int numSections = concentrations.length; int numSections = concentrations.length;
int section = 0; int section = 0;
double m; double m;
@@ -100,4 +104,8 @@ public class Plate {
} }
} }
} }
public String getSourceFileName() {
return sourceFile;
}
} }

View File

@@ -14,12 +14,14 @@ import java.util.regex.Pattern;
public class PlateFileReader { public class PlateFileReader {
private List<List<Integer[]>> wells = new ArrayList<>(); private List<List<Integer[]>> wells = new ArrayList<>();
private String filename;
public PlateFileReader(String filename){ public PlateFileReader(String filename){
if(!filename.matches(".*\\.csv")){ if(!filename.matches(".*\\.csv")){
filename = filename + ".csv"; filename = filename + ".csv";
} }
this.filename = filename;
CSVFormat plateFileFormat = CSVFormat.Builder.create() CSVFormat plateFileFormat = CSVFormat.Builder.create()
.setCommentMarker('#') .setCommentMarker('#')
@@ -58,4 +60,7 @@ public class PlateFileReader {
return wells; return wells;
} }
public String getFilename() {
return filename;
}
} }

View File

@@ -15,6 +15,7 @@ public class PlateFileWriter {
private double stdDev; private double stdDev;
private Double error; private Double error;
private String filename; private String filename;
private String sourceFileName;
private String[] headers; private String[] headers;
private List<Integer> concentrations; private List<Integer> concentrations;
@@ -23,6 +24,7 @@ public class PlateFileWriter {
filename = filename + ".csv"; filename = filename + ".csv";
} }
this.filename = filename; this.filename = filename;
this.sourceFileName = plate.getSourceFileName();
this.size = plate.getSize(); this.size = plate.getSize();
this.stdDev = plate.getStdDev(); this.stdDev = plate.getStdDev();
this.error = plate.getError(); this.error = plate.getError();
@@ -32,10 +34,6 @@ public class PlateFileWriter {
} }
public void writePlateFile(){ public void writePlateFile(){
//works as is, but too many columns in csv, need to make them all rows.
//will now redo it so that every column is a well, with well names as headers
//need to give plate error, sample pop size, stdDev, num sections, concentration per section as comments
Comparator<List<Integer[]>> listLengthDescending = Comparator.comparingInt(List::size); Comparator<List<Integer[]>> listLengthDescending = Comparator.comparingInt(List::size);
wells.sort(listLengthDescending.reversed()); wells.sort(listLengthDescending.reversed());
int maxLength = wells.get(0).size(); int maxLength = wells.get(0).size();
@@ -79,6 +77,7 @@ public class PlateFileWriter {
try(BufferedWriter writer = Files.newBufferedWriter(Path.of(filename), StandardOpenOption.CREATE_NEW); try(BufferedWriter writer = Files.newBufferedWriter(Path.of(filename), StandardOpenOption.CREATE_NEW);
CSVPrinter printer = new CSVPrinter(writer, plateFileFormat); CSVPrinter printer = new CSVPrinter(writer, plateFileFormat);
){ ){
printer.printComment("Cell source file name: " + sourceFileName);
printer.printComment("Each row represents one well on the plate."); printer.printComment("Each row represents one well on the plate.");
printer.printComment("Plate size: " + size); printer.printComment("Plate size: " + size);
printer.printComment("Error rate: " + error); printer.printComment("Error rate: " + error);

View File

@@ -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,11 +210,14 @@ 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");
if(verbose){
for(String s: comments){ for(String s: comments){
System.out.println(s); System.out.println(s);
} }
}
return new MatchingResult(comments, header, allResults, matchMap, time);
return new MatchingResult(samplePlate.getSourceFileName(), comments, header, allResults, matchMap, time);
} }
//Simulated matching of CDR1s to CDR3s. Requires MatchingResult from prior run of matchCDR3s. //Simulated matching of CDR1s to CDR3s. Requires MatchingResult from prior run of matchCDR3s.
@@ -466,7 +470,8 @@ public class Simulator {
headers.add("second matched CDR1"); headers.add("second matched CDR1");
headers.add("Correct match?"); headers.add("Correct match?");
MatchingResult firstTest = new MatchingResult(comments, headers, allResults, dualMatchesMap, time); MatchingResult firstTest = new MatchingResult(samplePlate.getSourceFileName(),
comments, headers, allResults, dualMatchesMap, time);
//results for dual map //results for dual map
System.out.println("RESULTS FOR SECOND PASS MATCHING"); System.out.println("RESULTS FOR SECOND PASS MATCHING");
@@ -515,7 +520,8 @@ public class Simulator {
} }
System.out.println("Simulation time: " + nf.format(time.toSeconds()) + " seconds"); System.out.println("Simulation time: " + nf.format(time.toSeconds()) + " seconds");
MatchingResult dualTest = new MatchingResult(comments, headers, allResults, dualMatchesMap, time); MatchingResult dualTest = new MatchingResult(samplePlate.getSourceFileName(), comments, headers,
allResults, dualMatchesMap, time);
MatchingResult[] output = {firstTest, dualTest}; MatchingResult[] output = {firstTest, dualTest};
return output; return output;
} }

View File

@@ -1,6 +1,10 @@
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;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
// //
public class UserInterface { public class UserInterface {
@@ -9,8 +13,59 @@ 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) {
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("\nALPHA/BETA T-CELL RECEPTOR MATCHING SIMULATOR");
System.out.println("Please select an option:"); System.out.println("Please select an option:");
System.out.println("1) Generate a population of distinct cells"); System.out.println("1) Generate a population of distinct cells");
@@ -21,22 +76,23 @@ public class UserInterface {
System.out.println("0) Exit"); System.out.println("0) Exit");
try { try {
input = sc.nextInt(); input = sc.nextInt();
switch(input){ switch (input) {
case 1 -> makeCells(); case 1 -> makeCells();
case 2 -> makePlate(); case 2 -> makePlate();
case 3 -> matchCells(); case 3 -> matchCells();
case 4 -> matchCellsExpanded(); case 4 -> matchCellsCDR1();
case 5 -> acknowledge(); case 5 -> acknowledge();
case 0 -> quit = true; case 0 -> quit = true;
default -> throw new InputMismatchException("Invalid input."); default -> throw new InputMismatchException("Invalid input.");
} }
}catch(InputMismatchException ex){ } catch (InputMismatchException ex) {
System.out.println(ex); System.out.println(ex);
sc.next(); sc.next();
} }
} }
sc.close(); sc.close();
} }
}
private static void makeCells() { private static void makeCells() {
String filename = null; String filename = null;
@@ -66,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;
@@ -142,11 +214,35 @@ public class UserInterface {
stdDev = Math.sqrt(cellReader.getCellCount()); //gaussian with square root of elements approximates poisson stdDev = Math.sqrt(cellReader.getCellCount()); //gaussian with square root of elements approximates poisson
} }
Plate samplePlate = new Plate(numWells, dropOutRate, concentrations, stdDev); Plate samplePlate = new Plate(numWells, dropOutRate, concentrations, stdDev);
samplePlate.fillWells(cellReader.getCells()); samplePlate.fillWells(cellReader.getFilename(), cellReader.getCells());
PlateFileWriter writer = new PlateFileWriter(filename, samplePlate); PlateFileWriter writer = new PlateFileWriter(filename, samplePlate);
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("", results);
writer.writeErrorRateToTerminal();
}
}
private static void matchCells() { private static void matchCells() {
String filename = null; String filename = null;
String cellFile = null; String cellFile = null;
@@ -175,7 +271,7 @@ public class UserInterface {
} }
CellFileReader cellReader = new CellFileReader(cellFile); CellFileReader cellReader = new CellFileReader(cellFile);
PlateFileReader plateReader = new PlateFileReader(plateFile); PlateFileReader plateReader = new PlateFileReader(plateFile);
Plate plate = new Plate(plateReader.getWells()); Plate plate = new Plate(plateReader.getFilename(), plateReader.getWells());
if (cellReader.getCells().size() == 0){ if (cellReader.getCells().size() == 0){
System.out.println("No cell sample found."); System.out.println("No cell sample found.");
System.out.println("Returning to main menu."); System.out.println("Returning to main menu.");
@@ -190,27 +286,28 @@ 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.getComments(), MatchingFileWriter writer = new MatchingFileWriter(filename, results);
results.getHeaders(), results.getAllResults());
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
match match
*/ */
String filename = null; String filename = null;
String preliminaryResultsFilename = null;
String cellFile = null; String cellFile = null;
String plateFile = null; String plateFile = null;
Integer lowThresholdCDR3 = 0; Integer lowThresholdCDR3 = 0;
Integer highThresholdCDR3 = Integer.MAX_VALUE; Integer highThresholdCDR3 = Integer.MAX_VALUE;
Integer lowThresholdCDR1 = 0; Integer lowThresholdCDR1 = 0;
Integer highThresholdCDR1 = Integer.MAX_VALUE; Integer highThresholdCDR1 = Integer.MAX_VALUE;
boolean outputCDR3Matches = false;
try { try {
System.out.println("\nSimulated experiment requires a cell sample file and a sample plate file."); System.out.println("\nSimulated experiment requires a cell sample file and a sample plate file.");
System.out.print("Please enter name of an existing cell sample file: "); System.out.print("Please enter name of an existing cell sample file: ");
@@ -234,13 +331,28 @@ public class UserInterface {
} }
System.out.println("What is the maximum number of CDR3/CDR1 overlap wells to attempt matching?"); System.out.println("What is the maximum number of CDR3/CDR1 overlap wells to attempt matching?");
highThresholdCDR1 = sc.nextInt(); highThresholdCDR1 = sc.nextInt();
System.out.println("Matching CDR3s to CDR1s requires first matching CDR3 alpha/betas.");
System.out.println("Output a file for CDR3 alpha/beta match results as well?");
System.out.print("Please enter y/n: ");
String ans = sc.next();
Pattern pattern = Pattern.compile("(?:yes|y)", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(ans);
if(matcher.matches()){
outputCDR3Matches = true;
System.out.println("Please enter filename for CDR3 alpha/beta match results");
preliminaryResultsFilename = sc.next();
System.out.println("CDR3 alpha/beta matches will be output to file");
}
else{
System.out.println("CDR3 alpha/beta matches will not be output to file");
}
} catch (InputMismatchException ex) { } catch (InputMismatchException ex) {
System.out.println(ex); System.out.println(ex);
sc.next(); sc.next();
} }
CellFileReader cellReader = new CellFileReader(cellFile); CellFileReader cellReader = new CellFileReader(cellFile);
PlateFileReader plateReader = new PlateFileReader(plateFile); PlateFileReader plateReader = new PlateFileReader(plateFile);
Plate plate = new Plate(plateReader.getWells()); Plate plate = new Plate(plateReader.getFilename(), plateReader.getWells());
if (cellReader.getCells().size() == 0){ if (cellReader.getCells().size() == 0){
System.out.println("No cell sample found."); System.out.println("No cell sample found.");
System.out.println("Returning to main menu."); System.out.println("Returning to main menu.");
@@ -258,17 +370,17 @@ 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]);
//result writer
MatchingFileWriter writer = new MatchingFileWriter(filename + "First", results[0].getComments(),
results[0].getHeaders(), results[0].getAllResults());
writer.writeResultsToFile(); writer.writeResultsToFile();
writer = new MatchingFileWriter(filename + "Dual", results[1].getComments(), writer = new MatchingFileWriter(filename + "_SecondPass", results[1]);
results[1].getHeaders(), results[1].getAllResults());
writer.writeResultsToFile(); writer.writeResultsToFile();
if(outputCDR3Matches){
writer = new MatchingFileWriter(preliminaryResultsFilename, preliminaryResults);
writer.writeResultsToFile();
}
} }
} }