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>
<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/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>
</artifact>
</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 {
private String filename;
private List<Integer[]> distinctCells = new ArrayList<>();
public CellFileReader(String filename) {
if(!filename.matches(".*\\.csv")){
filename = filename + ".csv";
}
this.filename = filename;
CSVFormat cellFileFormat = CSVFormat.Builder.create()
.setHeader("Alpha CDR3", "Beta CDR3", "Alpha CDR1", "Beta CDR1")
.setSkipHeaderRecord(true)
.setCommentMarker('#')
.build();
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(){
return distinctCells;
}

View File

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

View File

@@ -3,13 +3,15 @@ import java.util.List;
import java.util.Map;
public class MatchingResult {
private String sourceFile;
private List<String> comments;
private List<String> headers;
private List<List<String>> allResults;
private Map<Integer, Integer> matchMap;
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.headers = headers;
this.allResults = allResults;
@@ -37,4 +39,8 @@ public class MatchingResult {
public Duration getTime() {
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 {
private String sourceFile;
private List<List<Integer[]>> wells;
private Random rand = new Random();
private int size;
@@ -12,6 +13,7 @@ public class Plate {
private Integer[] concentrations;
private double stdDev;
public Plate (int size, double error, Integer[] concentrations, double stdDev) {
this.size = size;
this.error = error;
@@ -20,12 +22,14 @@ public class Plate {
wells = new ArrayList<>();
}
public Plate(List<List<Integer[]>> wells){
public Plate(String sourceFileName, List<List<Integer[]>> wells){
this.sourceFile = sourceFileName;
this.wells = wells;
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 section = 0;
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 {
private List<List<Integer[]>> wells = new ArrayList<>();
private String filename;
public PlateFileReader(String filename){
if(!filename.matches(".*\\.csv")){
filename = filename + ".csv";
}
this.filename = filename;
CSVFormat plateFileFormat = CSVFormat.Builder.create()
.setCommentMarker('#')
@@ -58,4 +60,7 @@ public class PlateFileReader {
return wells;
}
public String getFilename() {
return filename;
}
}

View File

@@ -15,6 +15,7 @@ public class PlateFileWriter {
private double stdDev;
private Double error;
private String filename;
private String sourceFileName;
private String[] headers;
private List<Integer> concentrations;
@@ -23,6 +24,7 @@ public class PlateFileWriter {
filename = filename + ".csv";
}
this.filename = filename;
this.sourceFileName = plate.getSourceFileName();
this.size = plate.getSize();
this.stdDev = plate.getStdDev();
this.error = plate.getError();
@@ -32,10 +34,6 @@ public class PlateFileWriter {
}
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);
wells.sort(listLengthDescending.reversed());
int maxLength = wells.get(0).size();
@@ -79,6 +77,7 @@ public class PlateFileWriter {
try(BufferedWriter writer = Files.newBufferedWriter(Path.of(filename), StandardOpenOption.CREATE_NEW);
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("Plate size: " + size);
printer.printComment("Error rate: " + error);

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,11 +210,14 @@ public class Simulator {
comments.add("Pairing error rate: " + pairingErrorRateTrunc);
Duration time = Duration.between(start, stop);
comments.add("Simulation time: " + nf.format(time.toSeconds()) + " seconds");
for(String s: comments){
System.out.println(s);
if(verbose){
for(String s: comments){
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.
@@ -466,7 +470,8 @@ public class Simulator {
headers.add("second matched CDR1");
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
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");
MatchingResult dualTest = new MatchingResult(comments, headers, allResults, dualMatchesMap, time);
MatchingResult dualTest = new MatchingResult(samplePlate.getSourceFileName(), comments, headers,
allResults, dualMatchesMap, time);
MatchingResult[] output = {firstTest, dualTest};
return output;
}

View File

@@ -1,6 +1,10 @@
import org.apache.commons.cli.*;
import java.util.List;
import java.util.Scanner;
import java.util.InputMismatchException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
//
public class UserInterface {
@@ -9,33 +13,85 @@ public class UserInterface {
static int input;
static boolean quit = false;
public static void main(String args[]) {
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");
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 {
input = sc.nextInt();
switch(input){
case 1 -> makeCells();
case 2 -> makePlate();
case 3 -> matchCells();
case 4 -> matchCellsExpanded();
case 5 -> acknowledge();
case 0 -> quit = true;
default -> throw new InputMismatchException("Invalid input.");
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(InputMismatchException ex){
System.out.println(ex);
sc.next();
}
catch (ParseException exp) {
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() {
@@ -66,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;
@@ -142,11 +214,35 @@ public class UserInterface {
stdDev = Math.sqrt(cellReader.getCellCount()); //gaussian with square root of elements approximates poisson
}
Plate samplePlate = new Plate(numWells, dropOutRate, concentrations, stdDev);
samplePlate.fillWells(cellReader.getCells());
samplePlate.fillWells(cellReader.getFilename(), cellReader.getCells());
PlateFileWriter writer = new PlateFileWriter(filename, samplePlate);
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() {
String filename = null;
String cellFile = null;
@@ -175,7 +271,7 @@ public class UserInterface {
}
CellFileReader cellReader = new CellFileReader(cellFile);
PlateFileReader plateReader = new PlateFileReader(plateFile);
Plate plate = new Plate(plateReader.getWells());
Plate plate = new Plate(plateReader.getFilename(), plateReader.getWells());
if (cellReader.getCells().size() == 0){
System.out.println("No cell sample found.");
System.out.println("Returning to main menu.");
@@ -190,27 +286,28 @@ 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.getComments(),
results.getHeaders(), results.getAllResults());
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
match
*/
String filename = null;
String preliminaryResultsFilename = null;
String cellFile = null;
String plateFile = null;
Integer lowThresholdCDR3 = 0;
Integer highThresholdCDR3 = Integer.MAX_VALUE;
Integer lowThresholdCDR1 = 0;
Integer highThresholdCDR1 = Integer.MAX_VALUE;
boolean outputCDR3Matches = false;
try {
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: ");
@@ -234,13 +331,28 @@ public class UserInterface {
}
System.out.println("What is the maximum number of CDR3/CDR1 overlap wells to attempt matching?");
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) {
System.out.println(ex);
sc.next();
}
CellFileReader cellReader = new CellFileReader(cellFile);
PlateFileReader plateReader = new PlateFileReader(plateFile);
Plate plate = new Plate(plateReader.getWells());
Plate plate = new Plate(plateReader.getFilename(), plateReader.getWells());
if (cellReader.getCells().size() == 0){
System.out.println("No cell sample found.");
System.out.println("Returning to main menu.");
@@ -258,17 +370,17 @@ 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);
//result writer
MatchingFileWriter writer = new MatchingFileWriter(filename + "First", results[0].getComments(),
results[0].getHeaders(), results[0].getAllResults());
MatchingFileWriter writer = new MatchingFileWriter(filename + "_FirstPass", results[0]);
writer.writeResultsToFile();
writer = new MatchingFileWriter(filename + "Dual", results[1].getComments(),
results[1].getHeaders(), results[1].getAllResults());
writer = new MatchingFileWriter(filename + "_SecondPass", results[1]);
writer.writeResultsToFile();
if(outputCDR3Matches){
writer = new MatchingFileWriter(preliminaryResultsFilename, preliminaryResults);
writer.writeResultsToFile();
}
}
}