From 2ab93dd4b7f827b7841590faaf390e7c0d8b2c40 Mon Sep 17 00:00:00 2001 From: efischer Date: Thu, 18 Nov 2021 15:38:29 -0600 Subject: [PATCH] Recording source file names in output files, allowing output of intermediate results --- src/main/java/CellFileReader.java | 6 +++- src/main/java/MatchingFileWriter.java | 16 ++++++----- src/main/java/MatchingResult.java | 8 +++++- src/main/java/Plate.java | 12 ++++++-- src/main/java/PlateFileReader.java | 5 ++++ src/main/java/PlateFileWriter.java | 7 ++--- src/main/java/Simulator.java | 8 ++++-- src/main/java/UserInterface.java | 40 +++++++++++++++++++-------- 8 files changed, 73 insertions(+), 29 deletions(-) diff --git a/src/main/java/CellFileReader.java b/src/main/java/CellFileReader.java index e405f1f..85a0f8c 100644 --- a/src/main/java/CellFileReader.java +++ b/src/main/java/CellFileReader.java @@ -11,17 +11,19 @@ import java.util.List; public class CellFileReader { + private String filename; private List 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 getCells(){ return distinctCells; } diff --git a/src/main/java/MatchingFileWriter.java b/src/main/java/MatchingFileWriter.java index d1de122..00cbc24 100644 --- a/src/main/java/MatchingFileWriter.java +++ b/src/main/java/MatchingFileWriter.java @@ -12,18 +12,20 @@ import java.util.List; public class MatchingFileWriter { private String filename; + private String sourceFileName; private List comments; private List headers; - private List> results; + private List> allResults; - public MatchingFileWriter(String filename, List comments, List headers, List> 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 writeResultsToFile(){ @@ -41,8 +43,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); diff --git a/src/main/java/MatchingResult.java b/src/main/java/MatchingResult.java index 1e2dc64..df87422 100644 --- a/src/main/java/MatchingResult.java +++ b/src/main/java/MatchingResult.java @@ -3,13 +3,15 @@ import java.util.List; import java.util.Map; public class MatchingResult { + private String sourceFile; private List comments; private List headers; private List> allResults; private Map matchMap; private Duration time; - public MatchingResult(List comments, List headers, List> allResults, MapmatchMap, Duration time){ + public MatchingResult(String sourceFileName, List comments, List headers, List> allResults, MapmatchMap, 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; + } } diff --git a/src/main/java/Plate.java b/src/main/java/Plate.java index 2da18b3..c989c25 100644 --- a/src/main/java/Plate.java +++ b/src/main/java/Plate.java @@ -5,6 +5,7 @@ TODO: Implement discrete frequency distributions using Vose's Alias Method */ public class Plate { + private String sourceFile; private List> 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> wells){ + public Plate(String sourceFileName, List> wells){ + this.sourceFile = sourceFileName; this.wells = wells; this.size = wells.size(); } - public void fillWells(List cells) { + public void fillWells(String sourceFileName, List cells) { + sourceFile = sourceFileName; int numSections = concentrations.length; int section = 0; double m; @@ -100,4 +104,8 @@ public class Plate { } } } + + public String getSourceFileName() { + return sourceFile; + } } diff --git a/src/main/java/PlateFileReader.java b/src/main/java/PlateFileReader.java index cbafcf2..7b95cee 100644 --- a/src/main/java/PlateFileReader.java +++ b/src/main/java/PlateFileReader.java @@ -14,12 +14,14 @@ import java.util.regex.Pattern; public class PlateFileReader { private List> 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; + } } \ No newline at end of file diff --git a/src/main/java/PlateFileWriter.java b/src/main/java/PlateFileWriter.java index ad68fd4..f96c07c 100644 --- a/src/main/java/PlateFileWriter.java +++ b/src/main/java/PlateFileWriter.java @@ -15,6 +15,7 @@ public class PlateFileWriter { private double stdDev; private Double error; private String filename; + private String sourceFileName; private String[] headers; private List 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> 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); diff --git a/src/main/java/Simulator.java b/src/main/java/Simulator.java index 5083ffd..9031c16 100644 --- a/src/main/java/Simulator.java +++ b/src/main/java/Simulator.java @@ -213,7 +213,7 @@ public class Simulator { 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 +466,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 +516,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; } diff --git a/src/main/java/UserInterface.java b/src/main/java/UserInterface.java index 9c4fe87..2d862e5 100644 --- a/src/main/java/UserInterface.java +++ b/src/main/java/UserInterface.java @@ -1,6 +1,8 @@ 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 { @@ -142,7 +144,7 @@ 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(); } @@ -175,7 +177,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."); @@ -192,8 +194,7 @@ public class UserInterface { List cells = cellReader.getCells(); MatchingResult results = Simulator.matchCDR3s(cells, plate, lowThreshold, highThreshold); //result writer - MatchingFileWriter writer = new MatchingFileWriter(filename, results.getComments(), - results.getHeaders(), results.getAllResults()); + MatchingFileWriter writer = new MatchingFileWriter(filename, results); writer.writeResultsToFile(); } } @@ -205,12 +206,14 @@ public class UserInterface { 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 +237,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."); @@ -261,14 +279,14 @@ public class UserInterface { MatchingResult preliminaryResults = Simulator.matchCDR3s(cells, plate, lowThresholdCDR3, highThresholdCDR3); 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(); + } } }