Skip to content

Commit

Permalink
Merge pull request #50 from virtualcell/enhanced-open-in-memory-button
Browse files Browse the repository at this point in the history
Enhanced open in memory button
  • Loading branch information
AvocadoMoon authored Sep 19, 2024
2 parents 2cb19bd + 002e3a5 commit 4164c3a
Show file tree
Hide file tree
Showing 5 changed files with 259 additions and 60 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.vcell.N5;


import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.scijava.command.Command;
Expand Down Expand Up @@ -42,6 +43,13 @@ public void run() {
setExampleJSONData();
// N5ImageHandler.logService.setLevel(LogService.DEBUG);
exportTable.displayExportTable();
Thread thread = new Thread(() -> {
// For some reason getting a standard client takes three seconds.
// So create one upon initialization, while the user is focused on the GUI
// and by the time they open an Image it's already loaded.
SimResultsLoader.s3ClientBuilder = AmazonS3ClientBuilder.standard();
});
thread.start();
}

public static Logger getLogger(Class classToLog){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.google.gson.GsonBuilder;
import ij.ImagePlus;
import ij.plugin.Duplicator;
import net.imglib2.cache.img.CachedCellImg;
import net.imglib2.img.display.imagej.ImageJFunctions;
import net.imglib2.type.numeric.real.DoubleType;
Expand All @@ -24,6 +23,7 @@
import org.janelia.saalfeldlab.n5.s3.N5AmazonS3Reader;
import org.scijava.log.Logger;
import org.vcell.N5.UI.N5ExportTable;
import org.vcell.N5.UI.ImageIntoMemory;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
Expand All @@ -49,10 +49,12 @@ public class SimResultsLoader {
private String s3ObjectKey;
private URI uri;
private String dataSetChosen;
private String userSetFileName = null;
public String userSetFileName = null;
private static final String defaultS3Region = "site2-low";
private N5Reader n5AmazonS3Reader;

private static final Logger logger = N5ImageHandler.getLogger(SimResultsLoader.class);
public static AmazonS3ClientBuilder s3ClientBuilder;

public SimResultsLoader(){

Expand All @@ -70,10 +72,8 @@ public SimResultsLoader(String stringURI, String userSetFileName){
}
}

void createS3Client(){
void createS3ClientAndReader(){
logger.debug("Creating S3 Client with url: " + uri);
AmazonS3ClientBuilder s3ClientBuilder = AmazonS3ClientBuilder.standard();

if (uri.getHost().equals("minikube.remote") || uri.getHost().equals("minikube.island")){
SSLContext sslContext = null;
try {
Expand Down Expand Up @@ -104,6 +104,8 @@ public boolean verify(String hostname, SSLSession session) {
s3ClientBuilder.withCredentials(new AWSStaticCredentialsProvider(new AnonymousAWSCredentials()));
s3ClientBuilder.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(uri.getScheme() + "://" + uri.getAuthority(), defaultS3Region));
this.s3Client = s3ClientBuilder.build();
S3KeyValueAccess amazonS3KeyValueAccess = new S3KeyValueAccess(s3Client, bucketName, false);
n5AmazonS3Reader = new N5KeyValueReader(amazonS3KeyValueAccess, s3ObjectKey, new GsonBuilder(), false);
}

/**
Expand All @@ -112,9 +114,7 @@ public boolean verify(String hostname, SSLSession session) {
don't originate from amazon this is not a format we can possibly mimic, so we have to use path based buckets because
it's the fallback style chosen by the N5 libraries if standard format is unavailable.
*/
ImagePlus getImgPlusFromN5File() throws IOException {
S3KeyValueAccess amazonS3KeyValueAccess = new S3KeyValueAccess(s3Client, bucketName, false);
N5KeyValueReader n5AmazonS3Reader = new N5KeyValueReader(amazonS3KeyValueAccess, s3ObjectKey, new GsonBuilder(), false);
public ImagePlus getImgPlusFromN5File() throws IOException {

// N5AmazonS3Reader n5AmazonS3Reader = new N5AmazonS3Reader(s3Client, bucketName, "/" + s3ObjectKey);
long start = System.currentTimeMillis();
Expand Down Expand Up @@ -155,53 +155,41 @@ private void setUnits(N5Reader n5Reader, ImagePlus imagePlus){
}
}

// private static ImagePlus getSetOfImage(ImagePlus imagePlus){
// int startZ = 0, startTime = 0, startChannel = 0;
// int endZ = 5, endTime = 2, endChannel = 1;
// ImagePlus newImage = IJ.createHyperStack(imagePlus.getTitle() + " In Memory", imagePlus.getWidth(),
// imagePlus.getHeight(), endChannel, endZ, endTime, imagePlus.getBitDepth());
// for (startChannel = startChannel; startChannel < endChannel; startChannel++){
// for (startZ = startZ; startZ < endZ; startZ++){
// for (startTime = startTime; startTime < endTime; startTime++){
// int index = imagePlus.getStackIndex(startChannel, startZ, startTime);
// newImage.getImageStack().addSlice("" + startTime + "" + startChannel + "" + startZ,
// imagePlus.getStack().getProcessor(index), index);
// }
// }
// }
// newImage.setDimensions(endChannel, endZ, endTime);
// return newImage;
// }
public ArrayList getN5Dimensions(){
return n5AmazonS3Reader.getAttribute(dataSetChosen, "dimensions", ArrayList.class);
}


public static void openN5FileDataset(ArrayList<SimResultsLoader> filesToOpen, boolean openInMemory){
N5ExportTable.enableCriticalButtons(false);
N5ExportTable.exportTableDialog.setCursor(new Cursor(Cursor.WAIT_CURSOR));
Thread openN5FileDataset = new Thread(() -> {
try{
for(SimResultsLoader simResultsLoader: filesToOpen){
simResultsLoader.createS3Client();
ImagePlus imagePlus = simResultsLoader.getImgPlusFromN5File();
if(openInMemory){
long start = System.currentTimeMillis();
logger.debug("Loading Virtual N5 File " + simResultsLoader.userSetFileName + " Into Memory");

imagePlus = new Duplicator().run(imagePlus);
// imagePlus = SimResultsLoader.getSetOfImage(imagePlus);
long end = System.currentTimeMillis();
imagePlus.show();
logger.debug("Loaded Virtual N5 File " + simResultsLoader.userSetFileName + " Into Memory taking: " + ((end - start)/ 1000) + "s");
simResultsLoader.createS3ClientAndReader();
ImageIntoMemory imageIntoMemory;
if (openInMemory){
ArrayList<Double> dimensions = simResultsLoader.getN5Dimensions();
imageIntoMemory = new ImageIntoMemory(dimensions.get(2), dimensions.get(3), dimensions.get(4), simResultsLoader);
imageIntoMemory.displayRangeMenu();
} else{
ImagePlus imagePlus = simResultsLoader.getImgPlusFromN5File();
imagePlus.show();
}

}
} catch (IOException ex) {
} catch (Exception ex) {
N5ExportTable.exportTableDialog.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
N5ExportTable.enableCriticalButtons(true);
throw new RuntimeException(ex);
} finally {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
N5ExportTable.exportTableDialog.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
N5ExportTable.enableCriticalButtons(true);
if (!openInMemory) {
N5ExportTable.exportTableDialog.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
N5ExportTable.enableCriticalButtons(true);
}
}
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
package org.vcell.N5.UI;

import ij.ImagePlus;
import ij.plugin.Duplicator;
import org.scijava.log.Logger;
import org.vcell.N5.N5ImageHandler;
import org.vcell.N5.SimResultsLoader;

import javax.swing.*;
import javax.swing.event.EventListenerList;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.io.IOException;

public class ImageIntoMemory extends EventListenerList implements ActionListener {
public int startC;
public int endC;
public int startT;
public int endT;
public int startZ;
public int endZ;

private final JTextField channelStartTextField;
private final JTextField channelEndTextField;
private final JTextField timeStartTextField;
private final JTextField timeEndTextField;
private final JTextField zStartTextField;
private final JTextField zEndTextField;

private final JButton okayButton;
private final JButton cancelButton;
private final JFrame frame;
private final SimResultsLoader simResultsLoader;

private static final Logger logger = N5ImageHandler.getLogger(ImageIntoMemory.class);

public ImageIntoMemory(double cDim, double tDim, double zDim, SimResultsLoader simResultsLoader){
this.simResultsLoader = simResultsLoader;
channelStartTextField = new HintTextField("1");
channelEndTextField = new HintTextField("" + (int) cDim);

timeStartTextField = new HintTextField("1");
timeEndTextField = new HintTextField("" + (int) tDim);

zStartTextField = new HintTextField("1");
zEndTextField = new HintTextField("" + (int) zDim);

// Create the frame
frame = new JFrame("Select " + simResultsLoader.userSetFileName + " Dimensions");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 200);

// Create a panel to hold the input boxes and buttons
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(4, 4, 10, 10)); // 4 rows: 3 for input, 1 for buttons

panel.add(new JLabel("Channel Start: "));
panel.add(channelStartTextField);
panel.add(new JLabel("Channel End: "));
panel.add(channelEndTextField);

panel.add(new JLabel("Z-Slice Start: "));
panel.add(zStartTextField);
panel.add(new JLabel("Z-Slice End: "));
panel.add(zEndTextField);

panel.add(new JLabel("Time Start: "));
panel.add(timeStartTextField);
panel.add(new JLabel("Time End: "));
panel.add(timeEndTextField);


// Create the "Okay" and "Cancel" buttons
panel.add(new JLabel());
okayButton = new JButton("Okay");
cancelButton = new JButton("Cancel");

// Add action listeners to the buttons
okayButton.addActionListener(this);

cancelButton.addActionListener(this);

// Add the buttons to the panel
panel.add(okayButton);
panel.add(cancelButton);

// Add the panel to the frame
frame.add(panel);
}

public void displayRangeMenu(){
// Make the window visible
frame.setVisible(true);
}

public static void usePopUp(){

}

public static void useExistingParameters(int startC, int endC, int startT, int endT, int startZ, int endZ){

}

public static void main(String[] args) {
ImageIntoMemory inMemoryPopUp = new ImageIntoMemory(1, 2, 3, null);
}

@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(okayButton)){
frame.dispose();

startC = Integer.parseInt(channelStartTextField.getText()) - 1;
endC = Integer.parseInt(channelEndTextField.getText()) - 1;
startT = Integer.parseInt(timeStartTextField.getText()) - 1;
endT = Integer.parseInt(timeEndTextField.getText()) - 1;
startZ = Integer.parseInt(zStartTextField.getText()) - 1;
endZ = Integer.parseInt(zEndTextField.getText()) - 1;

Thread openInMemory = new Thread(() -> {
try {
ImagePlus imagePlus = simResultsLoader.getImgPlusFromN5File();
long start = System.currentTimeMillis();
logger.debug("Loading Virtual N5 File " + simResultsLoader.userSetFileName + " Into Memory");
imagePlus = new Duplicator().run(imagePlus, startC, endC, startZ,
endZ, startT, endT);
long end = System.currentTimeMillis();
logger.debug("Loaded Virtual N5 File " + simResultsLoader.userSetFileName + " Into Memory taking: " + ((end - start)/ 1000) + "s");
imagePlus.show();
} catch (IOException ex) {
throw new RuntimeException(ex);
} finally {
N5ExportTable.exportTableDialog.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
N5ExportTable.enableCriticalButtons(true);
}
});
openInMemory.setName("Open N5 Image in Memory");
openInMemory.start();
}

else if (e.getSource().equals(cancelButton)) {
N5ExportTable.exportTableDialog.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
N5ExportTable.enableCriticalButtons(true);
frame.dispose();
}
}

static class HintTextField extends JTextField {

Font gainFont = new Font("Tahoma", Font.PLAIN, 11);
Font lostFont = new Font("Tahoma", Font.ITALIC, 11);

public HintTextField(final String hint) {

setText(hint);
setFont(lostFont);
setForeground(Color.GRAY);

this.addFocusListener(new FocusAdapter() {

@Override
public void focusGained(FocusEvent e) {
if (getText().equals(hint)) {
setText("");
setFont(gainFont);
} else {
setText(getText());
setFont(gainFont);
}
}

@Override
public void focusLost(FocusEvent e) {
if (getText().equals(hint)|| getText().isEmpty()) {
setText(hint);
setFont(lostFont);
setForeground(Color.GRAY);
} else {
setText(getText());
setFont(gainFont);
setForeground(Color.BLACK);
}
}
});

}
}
}
Loading

0 comments on commit 4164c3a

Please sign in to comment.