Skip to content

Commit

Permalink
5D Data Reduction and Tests
Browse files Browse the repository at this point in the history
  • Loading branch information
AvocadoMoon committed Oct 29, 2024
1 parent bafda86 commit 9e5ce30
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,7 @@ public class DataReduction implements SimLoadingListener {

public final DataReductionGUI.DataReductionSubmission submission;

/*
Open an image from file (assume 2D for now).
Open a saved ROI (or allow one to be created and saved).
Apply the ROI to a selected channel(s) in the image.
collect the average intensity value for all times in the image.
Save to cvs file of some kind (something that can be imported into excel).
Open a set of N5 exported files- in reality these will likely be scanned parameters all from the same "simulation". From each N5 data set, select the appropriate channel and z plane.
Apply the same ROI used previously and measure average intensity for each time.
save data to the cvs or equivalent file. Ideally, these should be organized so they are easy to use excel.
If possible would like to compare N5 data to image data using a least squares analysis. Users should be able to see the summed square differences and have the "best fit" identified.
Would be extra nice to plot the experimental data vs the "best fit" VCell simulation.
*/
//

// GUI:

Expand All @@ -53,17 +42,23 @@ public DataReduction(DataReductionGUI.DataReductionSubmission submission){
this.numOfImagesToBeOpened = submission.numOfSimImages + 1; // Plus one for the lab image
this.file = submission.fileToSaveResultsTo;
this.normalize = submission.normalizeMeasurementsBool;
ArrayList<String> headers = new ArrayList<String>(){{add("Time Frame");}};
ArrayList<String> headers = new ArrayList<String>(){{add("Time Frame"); add("Z Index"); add("Channel");}};
csvMatrix.add(headers);

double normValue = calculateNormalValue(submission.labResults, submission.imageStartPointNorm, submission.imageEndPointNorm);

HashMap<String, ArrayList<Double>> reducedData = calculateMean(submission.labResults, submission.arrayOfLabRois, normValue);
synchronized (csvMatrixLock){
for (int t = 0; t < submission.labResults.getNFrames(); t++){
ArrayList<String> rowForTime = new ArrayList<>();
rowForTime.add(String.valueOf(t));
csvMatrix.add(rowForTime);
for (int z = 0; z < submission.labResults.getNSlices(); z++){
for (int c = 0; c < submission.labResults.getNChannels(); c++){
ArrayList<String> rowForTime = new ArrayList<>();
rowForTime.add(String.valueOf(t));
rowForTime.add(String.valueOf(z));
rowForTime.add(String.valueOf(c));
csvMatrix.add(rowForTime);
}
}
}

}
Expand All @@ -76,10 +71,13 @@ private void addValuesToCSVMatrix(ImagePlus imagePlus, HashMap<String, ArrayList
csvMatrix.get(0).add("");
for (String roiName: reducedData.keySet()){
csvMatrix.get(0).add(imagePlus.getTitle()+" : " + roiName);
for(int t = 0; t < imagePlus.getNFrames(); t++){
double mean = reducedData.get(roiName).get(t);
csvMatrix.get(t + 1).add("");
csvMatrix.get(t + 1).add(String.valueOf(mean));
int tN = imagePlus.getNFrames();
int zN = imagePlus.getNSlices();
int cN = imagePlus.getNChannels();
for (int i = 0; i < (tN * zN * cN); i++){
double mean = reducedData.get(roiName).get(i);
csvMatrix.get(i + 1).add(""); // every array is a row
csvMatrix.get(i + 1).add(String.valueOf(mean));
}
}
numOfImagesToBeOpened -= 1;
Expand All @@ -89,7 +87,7 @@ private void addValuesToCSVMatrix(ImagePlus imagePlus, HashMap<String, ArrayList
}
}

private double calculateNormalValue(ImagePlus imagePlus, int startT, int endT){
double calculateNormalValue(ImagePlus imagePlus, int startT, int endT){
if (normalize){
double normal = 0;
for (int k = startT; k <= endT; k++){
Expand All @@ -106,7 +104,7 @@ private double calculateNormalValue(ImagePlus imagePlus, int startT, int endT){



private HashMap<String, ArrayList<Double>> calculateMean(ImagePlus imagePlus, ArrayList<Roi> roiList,
HashMap<String, ArrayList<Double>> calculateMean(ImagePlus imagePlus, ArrayList<Roi> roiList,
double normalizationValue){
// ResultsTable resultsTable = new ResultsTable();

Expand All @@ -115,15 +113,16 @@ private HashMap<String, ArrayList<Double>> calculateMean(ImagePlus imagePlus, Ar
imagePlus.setRoi(roi);
ArrayList<Double> meanValues = new ArrayList<>();
for (int t = 0; t < imagePlus.getNFrames(); t++){
// Analyzer analyzer = new Analyzer(imagePlus, Analyzer.MEAN, resultsTable);
// analyzer.measure();
//
// double meanValue = resultsTable.getValueAsDouble(resultsTable.getColumnIndex("Mean"), 0);
double meanValue = imagePlus.getProcessor().getStatistics().mean;
if (normalizationValue != Double.MIN_NORMAL){
meanValue = meanValue / normalizationValue;
for (int z = 0; z < imagePlus.getNSlices(); z++){
for (int c = 0; c < imagePlus.getNChannels(); c++){
imagePlus.setPosition(c + 1, z + 1, t + 1);
double meanValue = imagePlus.getStatistics().mean;
if (normalize){
meanValue = meanValue / normalizationValue;
}
meanValues.add(meanValue);
}
}
meanValues.add(meanValue);
}
roiListOfMeans.put(roi.getName(), meanValues);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public class DataReductionGUI extends JPanel implements ActionListener {

// private TemporalAnalysis temporalAnalysis = new TemporalAnalysis();

public class DataReductionSubmission{
public static class DataReductionSubmission{
public final boolean normalizeMeasurementsBool;
public final ArrayList<Roi> arrayOfSimRois;
public final ArrayList<Roi> arrayOfLabRois;
Expand All @@ -56,20 +56,38 @@ public class DataReductionSubmission{
public final int imageEndPointNorm;
public final int numOfSimImages;
public final File fileToSaveResultsTo;
public DataReductionSubmission(){
normalizeMeasurementsBool = normalizeMeasurement.isSelected();
arrayOfSimRois = simROIList;
arrayOfLabRois = imageROIList;
labResults = WindowManager.getImage((String) chosenImage.getSelectedItem());
simStartPointNorm = createNormFromSimStart.getText().isEmpty() ? Integer.MIN_VALUE : Integer.parseInt(createNormFromSimStart.getText());
simEndPointNorm = createNormFromSimEnd.getText().isEmpty() ? Integer.MIN_VALUE: Integer.parseInt(createNormFromSimEnd.getText());
imageStartPointNorm = createNormFromImageStart.getText().isEmpty() ? Integer.MIN_VALUE: Integer.parseInt(createNormFromImageStart.getText());
imageEndPointNorm = createNormFromImageEnd.getText().isEmpty() ? Integer.MIN_VALUE: Integer.parseInt(createNormFromImageEnd.getText());
numOfSimImages = numSimsToOpen;
fileToSaveResultsTo = chosenFile;
public DataReductionSubmission(boolean normalizeMeasurementsBool,ArrayList<Roi> arrayOfSimRois, ArrayList<Roi> arrayOfLabRois,
ImagePlus labResults, int numOfSimImages, File fileToSaveResultsTo){
this(normalizeMeasurementsBool, arrayOfSimRois, arrayOfLabRois, labResults,
0,0,0,0, numOfSimImages, fileToSaveResultsTo);
}

public DataReductionSubmission(boolean normalizeMeasurementsBool, ArrayList<Roi> arrayOfSimRois, ArrayList<Roi> arrayOfLabRois,
ImagePlus labResults, int simStartPointNorm, int simEndPointNorm, int imageStartPointNorm,
int imageEndPointNorm, int numOfSimImages, File fileToSaveResultsTo){
this.normalizeMeasurementsBool = normalizeMeasurementsBool;
this.arrayOfLabRois = arrayOfLabRois;
this.arrayOfSimRois = arrayOfSimRois;
this.labResults = labResults;
this.simStartPointNorm = simStartPointNorm;
this.simEndPointNorm = simEndPointNorm;
this.imageStartPointNorm = imageStartPointNorm;
this.imageEndPointNorm = imageEndPointNorm;
this.numOfSimImages = numOfSimImages;
this.fileToSaveResultsTo = fileToSaveResultsTo;

}
}

private DataReductionSubmission createSubmission(){
int simStartPointNorm = createNormFromSimStart.getText().isEmpty() ? Integer.MIN_VALUE : Integer.parseInt(createNormFromSimStart.getText());
int simEndPointNorm = createNormFromSimEnd.getText().isEmpty() ? Integer.MIN_VALUE: Integer.parseInt(createNormFromSimEnd.getText());
int imageStartPointNorm = createNormFromImageStart.getText().isEmpty() ? Integer.MIN_VALUE: Integer.parseInt(createNormFromImageStart.getText());
int imageEndPointNorm = createNormFromImageEnd.getText().isEmpty() ? Integer.MIN_VALUE: Integer.parseInt(createNormFromImageEnd.getText());
return new DataReductionSubmission(normalizeMeasurement.isSelected(), simROIList, imageROIList, WindowManager.getImage((String) chosenImage.getSelectedItem()),
simStartPointNorm, simEndPointNorm, imageStartPointNorm, imageEndPointNorm, numSimsToOpen, chosenFile);
}

public DataReductionGUI(int numSimsToOpen){
this.numSimsToOpen = numSimsToOpen;
setLayout(new BorderLayout());
Expand All @@ -94,7 +112,7 @@ public void displayGUI(){
chosenFile = saveToFile.getSelectedFile();
MainPanel.controlButtonsPanel.enableCriticalButtons(false);
Thread thread = new Thread(() -> {
DataReduction dataReduction = new DataReduction(new DataReductionSubmission());
DataReduction dataReduction = new DataReduction(createSubmission());
N5ImageHandler.loadingManager.addSimLoadingListener(dataReduction);
});
thread.start();
Expand Down Expand Up @@ -166,18 +184,6 @@ public void actionPerformed(ActionEvent e) {
}
}

private ArrayList<Roi> fillROIList(JFileChooser fileChooser){
fileChooser.setMultiSelectionEnabled(true);
int choice = fileChooser.showDialog(this, "");
ArrayList<Roi> roiList = new ArrayList<>();
if (choice == JFileChooser.APPROVE_OPTION){
for (File file: fileChooser.getSelectedFiles()){
roiList.add(RoiDecoder.open(file.getAbsolutePath()));
}
}
return roiList;
}

enum AvailableMeasurements{
AVERAGE("Average");

Expand Down Expand Up @@ -256,6 +262,17 @@ public void actionPerformed(ActionEvent e) {
simROITable.updateUI();
}
}
private ArrayList<Roi> fillROIList(JFileChooser fileChooser){
fileChooser.setMultiSelectionEnabled(true);
int choice = fileChooser.showDialog(this, "Open ROI's");
ArrayList<Roi> roiList = new ArrayList<>();
if (choice == JFileChooser.APPROVE_OPTION){
for (File file: fileChooser.getSelectedFiles()){
roiList.add(RoiDecoder.open(file.getAbsolutePath()));
}
}
return roiList;
}

class ROIDataModel extends AbstractTableModel {
private final ArrayList<String> data = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public SimResultsLoader(String stringURI, String userSetFileName){
}
}

void createS3ClientAndReader(){
public void createS3ClientAndReader(){
logger.debug("Creating S3 Client with url: " + uri);
if (uri.getHost().equals("minikube.remote") || uri.getHost().equals("minikube.island")){
SSLContext sslContext = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package org.vcell.N5.analysis;

import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import ij.ImagePlus;
import ij.gui.Roi;
import ij.io.RoiDecoder;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.vcell.N5.N5ImageHandler;
import org.vcell.N5.retrieving.SimResultsLoader;

import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;

public class DataReductionTest {
private final double[] labMeans2DLabROI = new double[]{6, 0, 6.489, 0, 7.247, 0}; //calculated through IJ measurement tool
private final double[] labMeans2DSimROI = new double[]{18, 0, 16.341, 0, 14.469, 0};

private final double[] threeDMeans = new double[]{2884.526,3102.159, 3884.279, 4668.205, 5016.744, 5524.792, 4794.329, 5624.351,
4559.778, 5510.099
};

private File getTestResourceFiles(String filePath){
try {
URL url = ClassLoader.getSystemClassLoader().getResource(filePath);
return new File(url.toURI().getPath());
}
catch (URISyntaxException e){
throw new RuntimeException(e);
}
}

@BeforeClass
public static void init(){
N5ImageHandler.initializeLogService();
SimResultsLoader.s3ClientBuilder = AmazonS3ClientBuilder.standard();
}

private void compareExpectedCalculations(ImagePlus imagePlus, ArrayList<Roi> roiList, HashMap<String, double[]> expectedResults){
DataReductionGUI.DataReductionSubmission dataReductionSubmission = new DataReductionGUI.DataReductionSubmission(
false, roiList, roiList, imagePlus,4, null);
DataReduction dataReduction = new DataReduction(dataReductionSubmission);
HashMap<String, ArrayList<Double>> result = dataReduction.calculateMean(imagePlus, roiList, Double.MIN_VALUE);
for (Roi roi : roiList){
for (int i = 0; i < expectedResults.get(roi.getName()).length; i++){
Assert.assertEquals(expectedResults.get(roi.getName())[i], result.get(roi.getName()).get(i), 0.0009);
}
}
}

@Test
public void testMean2DCalculation(){
// Ensure the mean calculated for each ROI, and each time point is what's to be expected
SimResultsLoader simResultsLoader = new SimResultsLoader("https://vcell.cam.uchc.edu/n5Data/ezequiel23/ddf7f4f0c77dffd.n5?dataSetName=4864003788", "test1");
simResultsLoader.createS3ClientAndReader();
ImagePlus labResultImage2D = simResultsLoader.getImgPlusFromN5File();

Roi labRoi = RoiDecoder.open(getTestResourceFiles("ROIs/Lab ROI.roi").getAbsolutePath());
Roi simROI = RoiDecoder.open(getTestResourceFiles("ROIs/Sim ROI.roi").getAbsolutePath());
ArrayList<Roi> roiList = new ArrayList<Roi>(){{add(labRoi); add(simROI);}};
HashMap<String, double[]> expectedResults = new HashMap<String, double[]>(){{put(labRoi.getName(), labMeans2DLabROI); put(simROI.getName(), labMeans2DSimROI);}};
compareExpectedCalculations(labResultImage2D, roiList, expectedResults);
}

@Test
public void testMean3DCalculation(){
ImagePlus mitosis = new ImagePlus(getTestResourceFiles("mitosis.tif").getAbsolutePath());
Roi mitosisROI = RoiDecoder.open(getTestResourceFiles("ROIs/Mitosis Center.roi").getAbsolutePath());
ArrayList<Roi> roiList = new ArrayList<Roi>(){{add(mitosisROI);}};
HashMap<String, double[]> expectedResults = new HashMap<String, double[]>(){{put(mitosisROI.getName(), threeDMeans);}};
compareExpectedCalculations(mitosis, roiList, expectedResults);
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 comments on commit 9e5ce30

Please sign in to comment.