diff --git a/.gitignore b/.gitignore index cc9376b..d67a835 100644 --- a/.gitignore +++ b/.gitignore @@ -2545,4 +2545,4 @@ bin/ /javafx/src/javafx.web/javafx/scene/web/WebView.java /javafx/src/javafx.web/module-info.java /javafx/src.zip -/test_output/ynb.xlsx +/test_output/ynb.xlsx \ No newline at end of file diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index a8a3bfb..0465793 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -7,6 +7,7 @@ requires javafx.graphics; requires javafx.controls; requires org.apache.commons.compress; + requires java.logging; exports org.awdevelopment.smithlab; exports org.awdevelopment.smithlab.gui; exports org.awdevelopment.smithlab.gui.controllers; diff --git a/src/main/java/org/awdevelopment/smithlab/MainApplication.java b/src/main/java/org/awdevelopment/smithlab/MainApplication.java index 159c750..2e0a094 100644 --- a/src/main/java/org/awdevelopment/smithlab/MainApplication.java +++ b/src/main/java/org/awdevelopment/smithlab/MainApplication.java @@ -19,7 +19,10 @@ public class MainApplication extends javafx.application.Application { private static final FXMLResourceType DEFAULT_FXML_RESOURCE = FXMLResourceType.APPLICATION; public static void main(String[] args) { - if (args.length == 0) launch(); + if (args.length == 0) { + launch(); + + } else { Arguments arguments = new Arguments(args, LOGGER); try { diff --git a/src/main/java/org/awdevelopment/smithlab/image_recognition/ImageReader.java b/src/main/java/org/awdevelopment/smithlab/image_recognition/ImageReader.java deleted file mode 100644 index 8f8abd1..0000000 --- a/src/main/java/org/awdevelopment/smithlab/image_recognition/ImageReader.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.awdevelopment.smithlab.image_recognition; - -public class ImageReader { - -} diff --git a/src/main/java/org/awdevelopment/smithlab/io/Headers.java b/src/main/java/org/awdevelopment/smithlab/io/Headers.java index 3d711b3..6b97ecc 100644 --- a/src/main/java/org/awdevelopment/smithlab/io/Headers.java +++ b/src/main/java/org/awdevelopment/smithlab/io/Headers.java @@ -50,6 +50,11 @@ public void addHeader(String header, int index) { } } + public Optional
getConditionColumn() { + if (!conditionColumn) return Optional.empty(); + return headers.stream().filter(header -> header.type() == HeaderType.CONDITION).findFirst(); + } + public void addDay(short dayNumber, int index) { for (short i = 0; i < 3; i++) { days.add(new Day(dayNumber, index + i, i)); diff --git a/src/main/java/org/awdevelopment/smithlab/io/input/XlsxInputReader.java b/src/main/java/org/awdevelopment/smithlab/io/input/XlsxInputReader.java index ef9cdfe..b1800a6 100644 --- a/src/main/java/org/awdevelopment/smithlab/io/input/XlsxInputReader.java +++ b/src/main/java/org/awdevelopment/smithlab/io/input/XlsxInputReader.java @@ -27,6 +27,7 @@ public class XlsxInputReader { private final HashSet strains; private final HashSet conditions; private final LoggerHelper LOGGER; + private static final Condition DEFAULT_CONDITION = new Condition("Unknown"); public XlsxInputReader(File xlsxFile, LoggerHelper logger) { this.xlsxFile = xlsxFile; @@ -75,7 +76,13 @@ private Optional readSampleFromRow(Headers headers, XSSFRow row) { } case HeaderType.STRAIN -> { try { - strainOptional = Optional.of(readStrain(curCell)); + Condition condition; + if (conditionOptional.isEmpty()) { + LOGGER.atWarn("Strain cell \"" + curCell.getRawValue() + "\" is missing a condition label! Labeling with \"Unknown\""); + condition = DEFAULT_CONDITION; + } + else condition = conditionOptional.get(); + strainOptional = Optional.of(readStrain(curCell, condition)); } catch (InvalidStrainValueException e) { LOGGER.atWarn(e + ": " + e.getMessage()); strainOptional = Optional.empty(); @@ -190,8 +197,29 @@ private int getInteger(XSSFCell cell) { } private Dilution readDilution(XSSFCell cell) throws InvalidDilutionValueException { - if (cell.getCellType() != CellType.NUMERIC) throw new InvalidDilutionValueException(cell.getRawValue(), cell.getRowIndex(), cell.getColumnIndex()); - double cellValue = cell.getNumericCellValue(); + double cellValue = -1.0; + LOGGER.atFatal("Reading dilution from cell with raw content: \""+cell.getRawValue()+"\""); + LOGGER.atFatal("Cell string value: \""+cell.getStringCellValue()+"\""); + LOGGER.atFatal("Cell address: "+cell.getAddress()); + LOGGER.atFatal("Cell type: "+cell.getCellType()); + if (cell.getCellType() == CellType.NUMERIC) { + cellValue = cell.getNumericCellValue(); + } else if (cell.getCellType() == CellType.STRING) { + String cellContent = cell.getStringCellValue(); + if (cellContent.equalsIgnoreCase("x1000")) { + return Dilution.x1000; + } else if (cellContent.equalsIgnoreCase("x100")) { + return Dilution.x100; + } else if (cellContent.equalsIgnoreCase("x10")) { + return Dilution.x10; + } else if (cellContent.equalsIgnoreCase("1")) { + return Dilution.x1000; + } else if (cellContent.equalsIgnoreCase("0.1")) { + return Dilution.x100; + } else if (cellContent.equalsIgnoreCase("0.01")) { + return Dilution.x10; + } + } if (Math.abs(cellValue - 1) < DELTA) { return Dilution.x1000; } else if (Math.abs(cellValue - 0.1) < DELTA) { @@ -225,7 +253,7 @@ private Condition readCondition(XSSFCell cell) throws InvalidConditionValueExcep } } - private Strain readStrain(XSSFCell cell) throws InvalidStrainValueException { + private Strain readStrain(XSSFCell cell, Condition condition) throws InvalidStrainValueException { CellType cellType = cell.getCellType(); if (cellType == CellType.STRING) { String cellContent = cell.getStringCellValue(); @@ -233,6 +261,7 @@ private Strain readStrain(XSSFCell cell) throws InvalidStrainValueException { if (strain.getName().equalsIgnoreCase(cellContent)) return strain; } Strain newStrain = new Strain(cellContent); + newStrain.setCondition(condition); strains.add(newStrain); return newStrain; } else if (cellType == CellType.BLANK || cellType == CellType._NONE) { @@ -240,7 +269,7 @@ private Strain readStrain(XSSFCell cell) throws InvalidStrainValueException { int colIndex = cell.getColumnIndex(); for (int i = rowIndex - 1; i > 1; i--) { XSSFCell nextCell = cell.getSheet().getRow(i).getCell(colIndex); - if (nextCell.getCellType() == CellType.STRING) return readStrain(nextCell); + if (nextCell.getCellType() == CellType.STRING) return readStrain(nextCell, condition); } throw new InvalidStrainValueException(cell.getRawValue(), cell.getRowIndex(), cell.getColumnIndex()); } else { diff --git a/src/main/java/org/awdevelopment/smithlab/io/output/formats/PrismOutputStyle.java b/src/main/java/org/awdevelopment/smithlab/io/output/formats/PrismOutputStyle.java index e711f52..3c7992a 100644 --- a/src/main/java/org/awdevelopment/smithlab/io/output/formats/PrismOutputStyle.java +++ b/src/main/java/org/awdevelopment/smithlab/io/output/formats/PrismOutputStyle.java @@ -5,11 +5,14 @@ import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.awdevelopment.smithlab.config.SortOption; +import org.awdevelopment.smithlab.data.DayOutOfBoundsException; import org.awdevelopment.smithlab.data.experiment.Experiment; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.awdevelopment.smithlab.data.Sample; import org.awdevelopment.smithlab.io.exceptions.NoStrainsOrConditionsException; +import java.util.logging.Logger; + public class PrismOutputStyle extends OutputStyle { public PrismOutputStyle(SortOption sortOption) { @@ -43,9 +46,16 @@ private void generateData(XSSFSheet sheet, Experiment experiment) { XSSFCell cell = row.createCell(j + 1); String sheetName = sample.getBaselineCell().getSheet().getSheetName(); String baselineCellAddress = getStringCellAddress(sample.getBaselineCell()); - String timepointCellAddress = getStringCellAddress(sample.getTimepointByDay(dayNumber).originalCell()); - String dilutionCellAddress = getStringCellAddress(sample.getTimepointByDay(dayNumber).dilutionCell()); - String cellFormula = "'" + sheetName + "'!" + timepointCellAddress + "*" + "'" + sheetName + "'!" + dilutionCellAddress + "/'" + sheetName + "'!" + baselineCellAddress; + String timepointCellAddress, dilutionCellAddress; + try { + timepointCellAddress = getStringCellAddress(sample.getTimepointByDay(dayNumber).originalCell()); + dilutionCellAddress = getStringCellAddress(sample.getTimepointByDay(dayNumber).dilutionCell()); + } catch (DayOutOfBoundsException d) { + Logger.getLogger(PrismOutputStyle.class.getName()).warning("Day " + dayNumber + " is out of bounds for sample " + sample.getOutputName() + ". Skipping..."); + continue; + } + String dilutionMultiplierFormula = "IF('" + sheetName + "'!" + dilutionCellAddress + "=\"x1000\",1,IF('" + sheetName + "'!" + dilutionCellAddress + "=\"x100\",0.1,IF('" + sheetName + "'!" + dilutionCellAddress + "=\"x10\",0.01," + dilutionCellAddress + ")))"; + String cellFormula = "'" + sheetName + "'!" + timepointCellAddress + "*" + dilutionMultiplierFormula + "/'" + sheetName + "'!" + baselineCellAddress; cell.setCellFormula(cellFormula); cell.setCellStyle(sheet.getWorkbook().createCellStyle()); cell.getCellStyle().setDataFormat(sheet.getWorkbook().createDataFormat().getFormat("0.000")); diff --git a/src/main/java/org/awdevelopment/smithlab/io/output/formats/StatisticalTestsOutputStyle.java b/src/main/java/org/awdevelopment/smithlab/io/output/formats/StatisticalTestsOutputStyle.java index a6d6696..14bc2a1 100644 --- a/src/main/java/org/awdevelopment/smithlab/io/output/formats/StatisticalTestsOutputStyle.java +++ b/src/main/java/org/awdevelopment/smithlab/io/output/formats/StatisticalTestsOutputStyle.java @@ -4,11 +4,14 @@ import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.awdevelopment.smithlab.config.SortOption; +import org.awdevelopment.smithlab.data.DayOutOfBoundsException; import org.awdevelopment.smithlab.data.experiment.Experiment; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.awdevelopment.smithlab.data.Sample; import org.awdevelopment.smithlab.io.exceptions.NoStrainsOrConditionsException; +import java.util.logging.Logger; + public class StatisticalTestsOutputStyle extends OutputStyle { private final short numberOfReplicates; @@ -125,9 +128,16 @@ private void generatePrimaryData(XSSFSheet sheet, Experiment experiment) { case SAMPLE_NUMBER -> experiment.getSampleNumber(sampleCounter + 1); }; String sheetName = sample.getBaselineCell().getSheet().getSheetName(); - String timepointCellAddress = getStringCellAddress(sample.getTimepointByDay(experiment.getDayNumbers()[j]).originalCell()); - String dilutionCellAddress = getStringCellAddress(sample.getTimepointByDay(experiment.getDayNumbers()[j]).dilutionCell()); - String cellFormula = "'" + sheetName + "'!" + timepointCellAddress + "*" + "'" + sheetName + "'!" + dilutionCellAddress; + String timepointCellAddress, dilutionCellAddress; + try { + timepointCellAddress = getStringCellAddress(sample.getTimepointByDay(experiment.getDayNumbers()[j]).originalCell()); + dilutionCellAddress = getStringCellAddress(sample.getTimepointByDay(experiment.getDayNumbers()[j]).dilutionCell()); + } catch (DayOutOfBoundsException d) { + Logger.getLogger(StatisticalTestsOutputStyle.class.getName()).warning("Day " + experiment.getDayNumbers()[j] + " is out of bounds for sample " + sample.getOutputName() + ". Skipping..."); + continue; + } + String dilutionMultiplierFormula = "IF('" + sheetName + "'!" + dilutionCellAddress + "=\"x1000\",1,IF('" + sheetName + "'!" + dilutionCellAddress + "=\"x100\",0.1,IF('" + sheetName + "'!" + dilutionCellAddress + "=\"x10\",0.01," + dilutionCellAddress + ")))"; + String cellFormula = "'" + sheetName + "'!" + timepointCellAddress + "*" + dilutionMultiplierFormula; cell.setCellFormula(cellFormula); } cell.setCellStyle(sheet.getWorkbook().createCellStyle());