All working, able to be built to .jar

This commit is contained in:
2021-11-12 10:41:44 -06:00
parent d39fdbee3b
commit e15cbc6672
21 changed files with 1003 additions and 12 deletions

3
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

15
.idea/artifacts/TCellSim_jar.xml generated Normal file
View File

@@ -0,0 +1,15 @@
<component name="ArtifactManager">
<artifact type="jar" name="TCellSim:jar">
<output-path>$PROJECT_DIR$/out/artifacts/TCellSim_jar</output-path>
<root id="archive" name="TCellSim.jar">
<element id="directory" name="META-INF">
<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="/" />
</root>
</artifact>
</component>

15
.idea/artifacts/TCellSim_jar2.xml generated Normal file
View File

@@ -0,0 +1,15 @@
<component name="ArtifactManager">
<artifact type="jar" name="TCellSim:jar2">
<output-path>$PROJECT_DIR$/out/artifacts/TCellSim_jar2</output-path>
<root id="archive" name="TCellSim.jar">
<element id="directory" name="META-INF">
<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="/" />
</root>
</artifact>
</component>

13
.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="TCellSim" />
</profile>
</annotationProcessing>
</component>
</project>

20
.idea/jarRepositories.xml generated Normal file
View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

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

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

11
.idea/libraries/jgrapht_core.xml generated Normal file
View File

@@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="jgrapht.core" type="repository">
<properties maven-id="org.jgrapht:jgrapht-core:1.5.1" />
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/jgrapht/jgrapht-core/1.5.1/jgrapht-core-1.5.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jheaps/jheaps/0.13/jheaps-0.13.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

14
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

10
.idea/runConfigurations.xml generated Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
</set>
</option>
</component>
</project>

124
.idea/uiDesigner.xml generated Normal file
View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

36
pom.xml Normal file
View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>TCellSim</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>14</source>
<target>14</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
</project>

View File

@@ -0,0 +1,50 @@
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
public class CellFileReader {
private List<Integer[]> distinctCells = new ArrayList<>();
public CellFileReader(String filename) {
if(!filename.matches(".*\\.csv")){
filename = filename + ".csv";
}
CSVFormat cellFileFormat = CSVFormat.Builder.create()
.setHeader("Alpha", "Beta")
.setSkipHeaderRecord(true)
.build();
try(//don't need to close reader bc of try-with-resources auto-closing
BufferedReader reader = Files.newBufferedReader(Path.of(filename));
CSVParser parser = new CSVParser(reader, cellFileFormat);
){
for(CSVRecord record: parser.getRecords()) {
Integer[] cell = new Integer[2];
cell[0] = Integer.valueOf(record.get("Alpha"));
cell[1] = Integer.valueOf(record.get("Beta"));
distinctCells.add(cell);
}
} catch(IOException ex){
System.out.println("cell file " + filename + " not found.");
System.err.println(ex);
}
}
public List<Integer[]> getCells(){
return distinctCells;
}
public Integer getCellCount() {
return distinctCells.size();
}
}

View File

@@ -0,0 +1,38 @@
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.List;
public class CellFileWriter {
private String[] headers = {"Alpha", "Beta"};
List<Integer[]> cells;
String filename;
public CellFileWriter(String filename, CellSample cells) {
if(!filename.matches(".*\\.csv")){
filename = filename + ".csv";
}
this.filename = filename;
this.cells = cells.getCells();
}
public void writeCellsToFile() {
CSVFormat cellFileFormat = CSVFormat.Builder.create()
.setHeader(headers)
.build();
try(BufferedWriter writer = Files.newBufferedWriter(Path.of(filename), StandardOpenOption.CREATE_NEW);
CSVPrinter printer = new CSVPrinter(writer, cellFileFormat);
){
printer.printRecords(cells);
} catch(IOException ex){
System.out.println("Could not make new file named "+filename);
System.err.println(ex);
}
}
}

View File

@@ -0,0 +1,19 @@
import java.util.List;
public class CellSample {
private List<Integer[]> cells;
public CellSample(List<Integer[]> cells){
this.cells = cells;
}
public List<Integer[]> getCells(){
return cells;
}
public Integer population(){
return cells.size();
}
}

View File

@@ -0,0 +1,52 @@
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.List;
public class MatchingFileWriter {
private String filename;
private List<String> comments;
private List<String> headers;
private List<List<String>> results;
public MatchingFileWriter(String filename, List<String> comments, List<String> headers, List<List<String>> results){
if(!filename.matches(".*\\.csv")){
filename = filename + ".csv";
}
this.filename = filename;
this.comments = comments;
this.headers = headers;
this.results = results;
}
public void writeResultsToFile(){
String[] headerStrings = new String[headers.size()];
for(int i = 0; i < headers.size(); i++){
headerStrings[i] = headers.get(i);
}
CSVFormat resultsFileFormat = CSVFormat.Builder.create()
.setCommentMarker('#')
//.setHeader(headerStrings)
.build();
try(BufferedWriter writer = Files.newBufferedWriter(Path.of(filename), StandardOpenOption.CREATE_NEW);
CSVPrinter printer = new CSVPrinter(writer, resultsFileFormat);
){
for(String comment: comments){
printer.printComment(comment);
}
results.add(0, headers);
printer.printRecords(results);
} catch(IOException ex){
System.out.println("Could not make new file named "+filename);
System.err.println(ex);
}
}
}

View File

@@ -8,14 +8,23 @@ public class Plate {
private Random rand = new Random();
private int size;
private double error;
private Integer[] concentrations;
private double stdDev;
public Plate (int size, double error) {
public Plate (int size, double error, Integer[] concentrations, double stdDev) {
this.size = size;
this.error = error;
this.concentrations = concentrations;
this.stdDev = stdDev;
wells = new ArrayList<>();
}
public void fillWells(List<Integer[]> cells, int[] concentrations, double stdDev) {
public Plate(List<List<Integer[]>> wells){
this.wells = wells;
this.size = wells.size();
}
public void fillWells(List<Integer[]> cells) {
int numSections = concentrations.length;
int section = 0;
double m;
@@ -26,8 +35,8 @@ public class Plate {
List<Integer[]> well = new ArrayList<>();
for (int j = 0; j < concentrations[section]; j++) {
do {
m = Math.abs(rand.nextGaussian()) * stdDev;
} while (m >= cells.size());
m = (rand.nextGaussian() * stdDev) + (cells.size() / 2);
} while (m >= cells.size() || m < 0);
n = (int) Math.floor(m);
Integer[] cellToAdd = cells.get(n).clone();
drop = Math.abs(rand.nextDouble()) < error;
@@ -46,6 +55,31 @@ public class Plate {
}
}
public void writePlateToFile(String filename) {
}
public Integer[] getConcentrations(){
return concentrations;
}
public int getSize(){
return size;
}
public double getStdDev() {
return stdDev;
}
public double getError() {
return error;
}
public List<List<Integer[]>> getWells() {
return wells;
}
public Map<Integer, Integer> assayWellsAlpha() {
return this.assayWellsAlpha(0, size);
}

View File

@@ -0,0 +1,61 @@
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
public class PlateFileReader {
private List<List<Integer[]>> wells = new ArrayList<>();
public PlateFileReader(String filename){
if(!filename.matches(".*\\.csv")){
filename = filename + ".csv";
}
CSVFormat plateFileFormat = CSVFormat.Builder.create()
.setCommentMarker('#')
.build();
try(//don't need to close reader bc of try-with-resources auto-closing
BufferedReader reader = Files.newBufferedReader(Path.of(filename));
CSVParser parser = new CSVParser(reader, plateFileFormat);
){
for(CSVRecord record: parser.getRecords()) {
List<Integer[]> well = new ArrayList<>();
for(String s: record) {
if(!"".equals(s)) {
String[] intString = s.replaceAll("\\[", "")
.replaceAll("]", "")
.replaceAll(" ", "")
.split(",");
//System.out.println(intString);
Integer[] arr = new Integer[intString.length];
for (int i = 0; i < intString.length; i++) {
arr[i] = Integer.valueOf(intString[i]);
}
well.add(arr);
}
}
wells.add(well);
}
} catch(IOException ex){
System.out.println("plate file " + filename + " not found.");
System.err.println(ex);
}
}
public List<List<Integer[]>> getWells() {
return wells;
}
}

View File

@@ -0,0 +1,93 @@
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.*;
import java.util.regex.Pattern;
public class PlateFileWriter {
private int size;
private List<List<Integer[]>> wells;
private double stdDev;
private Double error;
private String filename;
private String[] headers;
private List<Integer> concentrations;
public PlateFileWriter(String filename, Plate plate) {
if(!filename.matches(".*\\.csv")){
filename = filename + ".csv";
}
this.filename = filename;
this.size = plate.getSize();
this.stdDev = plate.getStdDev();
this.error = plate.getError();
this.wells = plate.getWells();
this.concentrations = Arrays.asList(plate.getConcentrations());
concentrations.sort(Comparator.reverseOrder());
}
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();
List<List<String>> wellsAsStrings = new ArrayList<>();
for (List<Integer[]> w: wells){
List<String> tmp = new ArrayList<>();
for(Integer[] c: w) {
tmp.add(Arrays.toString(c));
}
wellsAsStrings.add(tmp);
}
for(List<String> w: wellsAsStrings){
while(w.size() < maxLength){
w.add("");
}
}
//this took forever
List<List<String>> rows = new ArrayList<>();
List<String> tmp = new ArrayList<>();
for(int i = 0; i < wellsAsStrings.size(); i++){//List<Integer[]> w: wells){
tmp.add("well " + (i+1));
}
rows.add(tmp);
for(int row = 0; row < maxLength; row++){
tmp = new ArrayList<>();
for(List<String> c: wellsAsStrings){
tmp.add(c.get(row));
}
rows.add(tmp);
}
StringBuilder concen = new StringBuilder();
for(Integer i: concentrations){
concen.append(i.toString());
concen.append(" ");
}
String concenString = concen.toString();
CSVFormat plateFileFormat = CSVFormat.Builder.create().setCommentMarker('#').build();
try(BufferedWriter writer = Files.newBufferedWriter(Path.of(filename), StandardOpenOption.CREATE_NEW);
CSVPrinter printer = new CSVPrinter(writer, plateFileFormat);
){
printer.printComment("Each row represents one well on the plate.");
printer.printComment("Plate size: " + size);
printer.printComment("Error rate: " + error);
printer.printComment("Concentrations: " + concenString);
printer.printComment("Std. dev.: " + stdDev);
printer.printRecords(wellsAsStrings);
} catch(IOException ex){
System.out.println("Could not make new file named "+filename);
System.err.println(ex);
}
}
}

View File

@@ -13,21 +13,196 @@ import java.time.Instant;
import java.util.*;
import java.util.stream.IntStream;
public class Simulation {
private static Integer numDistinctCells = 15_000_000;
private static double stdDeviation = 1000; //square root of numDistCells would approximate poisson dist, supposedly
public class Simulator {
private static Integer numDistinctCells = 2_000_000;
private static double stdDeviation = 200; //square root of numDistCells would approximate poisson dist
private static int numWells = 96;
private static int numConcentrations = 1;
private static double errorRate = 0.1;
private static int[] concentrations = {500};
private static Integer[] concentrations = {500};
private static int lowThreshold = 2; //min number of shared wells to attempt pairing
private static int highThreshold = numWells - 3; //max number of shared wells to attempt pairing
private static boolean use2DArrayForGraph = true; //Doing this is much faster for larger graphs
private static boolean useJGraphTGraphMatrixGenerator = true; //fastest option
public static void main(String[] args) {
Instant start = Instant.now();
public static CellSample generateCellSample(Integer numDistinctCells) {
List<Integer> numbers = new ArrayList<>();
IntStream.range(1, (2 * numDistinctCells) + 1).forEach(i -> numbers.add(i));
Collections.shuffle(numbers);
//Each cell represented by two numbers from the random permutation
//These represent unique alpha and beta peptides
List<Integer[]> distinctCells = new ArrayList<>();
for(int i = 0; i < numbers.size() - 1; i = i + 2) {
Integer tmp1 = numbers.get(i);
Integer tmp2 = numbers.get(i+1);
Integer[] tmp = {tmp1, tmp2};
distinctCells.add(tmp);
}
return new CellSample(distinctCells);
}
public static void matchCells(String filename, List<Integer[]> distinctCells, Plate samplePlate, Integer lowThreshold, Integer highThreshold){
System.out.println("Cells: " + distinctCells.size());
System.out.println("Making cell maps");
//HashMap keyed to Alphas, values Betas
Map<Integer, Integer> distCellsMapAlphaKey = new HashMap<>();
for (Integer[] cell : distinctCells) {
distCellsMapAlphaKey.put(cell[0], cell[1]);
}
//HashMap keyed to Betas, values Alphas
Map<Integer, Integer> distCellsMapBetaKey = new HashMap<>();
for (Integer[] cell : distinctCells) {
distCellsMapBetaKey.put(cell[1], cell[0]);
}
System.out.println("Cell maps made");
System.out.println("Making well maps");
Map<Integer, Integer> allAlphas = samplePlate.assayWellsAlpha();
Map<Integer, Integer> allBetas = samplePlate.assayWellsBeta();
int alphaCount = allAlphas.size();
System.out.println("all alphas count: " + alphaCount);
int betaCount = allBetas.size();
System.out.println("all betas count: " + betaCount);
System.out.println("Well maps made");
System.out.println("Making vertex maps");
//Using Integers instead of Strings to label vertices so I can do clever stuff with indices if I need to
// when I refactor to use a 2d array to make the graph
//For the autogenerator, all vertices must have distinct numbers associated with them
Integer vertexStartValue = 0;
//keys are sequential integer vertices, values are alphas
Map<Integer, Integer> plateVtoAMap = getVertexToPeptideMap(allAlphas, vertexStartValue);
//New start value for vertex to beta map should be one more than final vertex value in alpha map
vertexStartValue += plateVtoAMap.size();
//keys are sequential integers vertices, values are betas
Map<Integer, Integer> plateVtoBMap = getVertexToPeptideMap(allBetas, vertexStartValue);
//keys are alphas, values are sequential integer vertices from previous map
Map<Integer, Integer> plateAtoVMap = invertVertexMap(plateVtoAMap);
System.out.println(plateAtoVMap.size());
//keys are betas, values are sequential integer vertices from previous map
Map<Integer, Integer> plateBtoVMap = invertVertexMap(plateVtoBMap);
System.out.println(plateAtoVMap.size());
System.out.println("Vertex maps made");
System.out.println("Creating Graph");
//Count how many wells each alpha appears in
Map<Integer, Integer> alphaWellCounts = new HashMap<>();
//count how many wells each beta appears in
Map<Integer, Integer> betaWellCounts = new HashMap<>();
//add edges, where weights are number of wells the peptides share in common.
//If this is too slow, can make a 2d array and use the SimpleWeightedGraphMatrixGenerator class
Map<Integer, Integer> wellNAlphas = null;
Map<Integer, Integer> wellNBetas = null;
SimpleWeightedGraph<Integer, DefaultWeightedEdge> graph =
new SimpleWeightedGraph<>(DefaultWeightedEdge.class);
double[][] weights = new double[plateVtoAMap.size()][plateVtoBMap.size()];
for (int n = 0; n < numWells; n++) {
wellNAlphas = samplePlate.assayWellsAlpha(n);
for (Integer a : wellNAlphas.keySet()) {
alphaWellCounts.merge(a, 1, (oldValue, newValue) -> oldValue + newValue);
}
wellNBetas = samplePlate.assayWellsBeta(n);
for (Integer b : wellNBetas.keySet()) {
betaWellCounts.merge(b, 1, (oldValue, newValue) -> oldValue + newValue);
}
for (Integer i : wellNAlphas.keySet()) {
for (Integer j : wellNBetas.keySet()) {
weights[plateAtoVMap.get(i)][plateBtoVMap.get(j) - vertexStartValue] += 1.0;
}
}
}
SimpleWeightedBipartiteGraphMatrixGenerator graphGenerator = new SimpleWeightedBipartiteGraphMatrixGenerator();
List<Integer> alphaVertices = new ArrayList<>();
alphaVertices.addAll(plateVtoAMap.keySet()); //This will work because LinkedHashMap preserves order of entry
graphGenerator.first(alphaVertices);
List<Integer> betaVertices = new ArrayList<>();
betaVertices.addAll(plateVtoBMap.keySet());
graphGenerator.second(betaVertices); //This will work because LinkedHashMap preserves order of entry
graphGenerator.weights(weights);
graphGenerator.generateGraph(graph);
System.out.println("Graph created");
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");
//Header for CSV file
List<String> header = new ArrayList<>();
header.add("Alpha");
header.add("Alpha well count");
header.add("Beta");
header.add("Beta well count");
header.add("Overlap well count");
header.add("Matched correctly?");
header.add("P-value");
//Results for csv file
List<List<String>> allResults = new ArrayList<>();
int size = samplePlate.getSize();
Iterator<DefaultWeightedEdge> weightIter = graphMatching.iterator();
DefaultWeightedEdge e = null;
int trueCount = 0;
int falseCount = 0;
boolean check = false;
while(weightIter.hasNext()) {
e = weightIter.next();
if(graph.getEdgeWeight(e) < lowThreshold || graph.getEdgeWeight(e) > highThreshold) {
continue;
}
Integer source = graph.getEdgeSource(e);
Integer target = graph.getEdgeTarget(e);
check = plateVtoBMap.get(target).equals(distCellsMapAlphaKey.get(plateVtoAMap.get(source)));
if(check) {
trueCount++;
}
else {
falseCount++;
}
List<String> result = new ArrayList<>();
result.add(plateVtoAMap.get(source).toString());
//alpha well count
result.add(alphaWellCounts.get(plateVtoAMap.get(source)).toString());
result.add(plateVtoBMap.get(target).toString());
//beta well count
result.add(betaWellCounts.get(plateVtoBMap.get(target)).toString());
//overlap count
result.add(Double.toString(graph.getEdgeWeight(e)));
result.add(Boolean.toString(check));
result.add(Double.toString(Equations.pValue(size, alphaWellCounts.get(plateVtoAMap.get(source)),
betaWellCounts.get(plateVtoBMap.get(target)), graph.getEdgeWeight(e))));
allResults.add(result);
}
//Metadate comments for CSV file
int min = alphaCount > betaCount ? betaCount : alphaCount;
double attemptRate = (double) (trueCount + falseCount) / min;
double pairingErrorRate = (double) falseCount / (trueCount + falseCount);
List<String> comments = new ArrayList<>();
comments.add("Total alphas found: " + alphaCount);
comments.add("Total betas found: " + betaCount);
comments.add("Pairing attempt rate: " + attemptRate);
comments.add("Correct pairings: " + trueCount);
comments.add("Incorrect pairings: " + falseCount);
comments.add("Pairing error rate: " + pairingErrorRate);
//result writer
MatchingFileWriter writer = new MatchingFileWriter(filename, comments, header, allResults);
writer.writeResultsToFile();
}
public static void Simulate() {
Instant start = Instant.now();
//Four things to try to improve this
//1. Run it on hardware with more memory
//2. implement p-values and just check exhaustively for strictly-bounded weights
@@ -76,8 +251,8 @@ public class Simulation {
distCellsMapBetaKey.put(cell[1], cell[0]);
}
Plate samplePlate = new Plate(numWells, errorRate);
samplePlate.fillWells(distinctCells, concentrations, stdDeviation);
Plate samplePlate = new Plate(numWells, errorRate, concentrations, stdDeviation);
samplePlate.fillWells(distinctCells);
//OUTPUT
System.out.println("Wells filled");

View File

@@ -0,0 +1,192 @@
import java.util.List;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.InputMismatchException;
//
public class UserInterface {
final static Scanner sc = new Scanner(System.in);
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 and 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 T-Cell matching");
System.out.println("4) Acknowledgements");
System.out.println("0) Exit");
try {
input = sc.nextInt();
switch(input){
case 1 -> makeCells();
case 2 -> makePlate();
case 3 -> matchCells();
//case 4 -> //method call goes here
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() {
String filename = null;
Integer numCells = 0;
try {
System.out.println("\nSimulated T-Cells consist of matched pairs of alpha and beta peptides, " +
"represented by unique integer values.");
System.out.println("(Note: peptide values are unique within a simulated population, " +
"but repeated between simulated populations.)");
System.out.println("\nThe cells will be written to a file.");
System.out.print("Please enter a file name: ");
filename = sc.next();
System.out.print("Please enter the number of T-cells to generate: ");
numCells = sc.nextInt();
if(numCells <= 0){
throw new InputMismatchException("Number of cells must be a positive integer.");
}
} catch (InputMismatchException ex) {
System.out.println(ex);
sc.next();
}
CellSample sample = Simulator.generateCellSample(numCells);
CellFileWriter writer = new CellFileWriter(filename, sample);
writer.writeCellsToFile();
}
//method to output a CSV of
private static void makePlate() {
String cellFile = null;
String filename = null;
Double stdDev = 0.0;
Integer numWells = 0;
Integer numSections = 0;
Integer[] concentrations = {1};
Double dropOutRate = 0.0;
boolean poisson = false;
try {
System.out.println("\nMaking a sample plate requires a population of distinct cells");
System.out.println("Please enter name of an existing cell sample file: ");
cellFile = sc.next();
System.out.println("\nThe sample plate will be written to file");
System.out.print("Please enter a name for the output file: ");
filename = sc.next();
System.out.println("Select T-cell frequency distribution function");
System.out.println("1) Poisson");
System.out.println("2) Gaussian");
System.out.println("(Note: wider distributions are more memory intensive to match)");
System.out.print("Enter selection value: ");
input = sc.nextInt();
switch(input) {
case 1:
poisson = true;
break;
case 2:
System.out.println("How many distinct T-cells within one standard deviation of peak frequency?");
System.out.println("(Note: wider distributions are more memory intensive to match)");
stdDev = sc.nextDouble();
if(stdDev <= 0.0){
throw new InputMismatchException("Value must be positive.");
}
break;
default:
System.out.println("Invalid input. Defaulting to Poisson.");
poisson = true;
}
System.out.print("Number of wells on plate: ");
numWells = sc.nextInt();
if(numWells < 1){
throw new InputMismatchException("No wells on plate");
}
System.out.println("The plate can be evenly sectioned to allow multiple concentrations of T-cells/well");
System.out.println("How many sections would you like to make (minimum 1)?");
numSections = sc.nextInt();
if(numSections < 1) {
throw new InputMismatchException("Too few sections.");
}
else if (numSections > numWells) {
throw new InputMismatchException("Cannot have more sections than wells.");
}
int i = 1;
concentrations = new Integer[numSections];
while(numSections > 0) {
System.out.print("Enter number of T-cells per well in section " + i +": ");
concentrations[i - 1] = sc.nextInt();
i++;
numSections--;
}
System.out.println("Errors in amplification can induce a well dropout rate for peptides");
System.out.print("Enter well dropout rate (0.0 to 1.0): ");
dropOutRate = sc.nextDouble();
if(dropOutRate < 0.0 || dropOutRate > 1.0) {
throw new InputMismatchException("The well dropout rate must be in the range [0.0, 1.0]");
}
}catch(InputMismatchException ex){
System.out.println(ex);
sc.next();
}
CellFileReader cellReader = new CellFileReader(cellFile);
if(poisson) {
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());
PlateFileWriter writer = new PlateFileWriter(filename, samplePlate);
writer.writePlateFile();
}
private static void matchCells() {
String filename = null;
String cellFile = null;
String plateFile = null;
Integer lowThreshold = 0;
Integer highThreshold = Integer.MAX_VALUE;
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: ");
cellFile = sc.next();
System.out.print("Please enter name of an existing sample plate file: ");
plateFile = sc.next();
System.out.println("The matching results will be written to a file.");
System.out.print("Please enter a name for the output file: ");
filename = sc.next();
System.out.println("What is the minimum number of alpha/beta overlap wells to attempt matching?");
lowThreshold = sc.nextInt();
if(lowThreshold < 1){
throw new InputMismatchException("Minimum value for low threshold is 1");
}
System.out.println("What is the maximum number of alpha/beta overlap wells to attempt matching?");
highThreshold = sc.nextInt();
} 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());
if (cellReader.getCells().size() == 0){
System.out.println("No cell sample found.");
System.out.println("Returning to main menu.");
}
else if(plate.getWells().size() == 0){
System.out.println("No sample plate found.");
System.out.println("Returning to main menu.");
}
else{
if(highThreshold > plate.getSize()){
highThreshold = plate.getSize();
}
List<Integer[]> cells = cellReader.getCells();
Simulator.matchCells(filename, cells, plate, lowThreshold, highThreshold);
}
}
}