Page MenuHomec4science

No OneTemporary

File Metadata

Created
Tue, May 7, 23:02
diff --git a/DeconvolutionLab2/.classpath b/DeconvolutionLab2/.classpath
index 5aa6316..da27baf 100644
--- a/DeconvolutionLab2/.classpath
+++ b/DeconvolutionLab2/.classpath
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="var" path="ICY_HOME/icy.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="ij"/>
- <classpathentry kind="lib" path="lib/JTransforms.jar"/>
+ <classpathentry kind="lib" path="lib/jtransforms.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/DeconvolutionLab2/DeconvolutionLab2.config b/DeconvolutionLab2/DeconvolutionLab2.config
index 06d248e..47aa668 100644
--- a/DeconvolutionLab2/DeconvolutionLab2.config
+++ b/DeconvolutionLab2/DeconvolutionLab2.config
@@ -1,63 +1,81 @@
#DeconvolutionLab2 [Beta 2]
#DeconvolutionLab2 [Beta 2]
-#Sat Mar 18 22:03:52 CET 2017
-Algorithm.I.gaussian.mean=0.0
-Algorithm.I.gaussian.stdev=1.0
-Algorithm.I.iterations=10
-Algorithm.I.poisson=0.0
-Algorithm.I.reg=0.1
-Algorithm.I.scale=3
-Algorithm.I.step=1.0
-Algorithm.I.wavelets=Haar
-Algorithm.algorithm=Landweber [LW |\u00A0LLS]
+#Mon Mar 20 09:47:20 CET 2017
+Algorithm.BVLS.iterations=10
+Algorithm.BVLS.step=1.0
+Algorithm.FISTA.iterations=10
+Algorithm.FISTA.reg=0.1
+Algorithm.FISTA.scale=3
+Algorithm.FISTA.step=1.0
+Algorithm.FISTA.wavelets=Haar
+Algorithm.ICTM.iterations=10
+Algorithm.ICTM.reg=0.1
+Algorithm.ICTM.step=1.0
+Algorithm.ISTA.iterations=10
+Algorithm.ISTA.reg=0.1
+Algorithm.ISTA.scale=3
+Algorithm.ISTA.step=1.0
+Algorithm.ISTA.wavelets=Haar
+Algorithm.LW.iterations=10
+Algorithm.LW.step=1.0
+Algorithm.NNLS.iterations=10
+Algorithm.NNLS.step=1.0
+Algorithm.RIF.reg=0.1
+Algorithm.RL.iterations=10
+Algorithm.RLTV.reg=1.000E-18
+Algorithm.SIM.gaussian.mean=0.0
+Algorithm.SIM.gaussian.stdev=1.0
+Algorithm.SIM.poisson=0.0
+Algorithm.TM.iterations=10
+Algorithm.TM.reg=0.1
+Algorithm.TM.step=1.0
+Algorithm.TRIF.reg=0.1
+Algorithm.VC.iterations=10
+Algorithm.VC.step=1.0
+Algorithm.algorithm=Fast Iterative Shrinkage-Thresholding [FISTA]
Border.apoxy=Hamming
Border.apoz=Uniform
Border.extxy=1
Border.extz=0
Border.padxy=None
Border.padz=None
Computation.dim=XYZ
Computation.epsilon=1E-6
Computation.fft=Fastest
Computation.normalization=1
Controller.constraint.enable=false
Controller.constraint.value=no
Controller.itmax.enable=true
Controller.reference.enable=false
Controller.reference.value=
Controller.residu.enable=false
Controller.residu.value=0.01
Controller.time.enable=false
Controller.time.value=3600
-DeconvolutionLab.MainDialog.location.h=597
+DeconvolutionLab.MainDialog.location.h=780
DeconvolutionLab.MainDialog.location.w=500
-DeconvolutionLab.MainDialog.location.x=72
-DeconvolutionLab.MainDialog.location.y=33
-Image.image.row0=Cell7.tif;file;/Users/dsage/Desktop/Maria Azevedo/Cell7.tif;null
+DeconvolutionLab.MainDialog.location.x=141
+DeconvolutionLab.MainDialog.location.y=51
+Image.image.row0=active;platform;active;\u232B
Image.image.row1=Cube;synthetic;Cube 100.0 0.0 10.0 1.0 size 128 128 32 ;\u232B
-Image.image.row2=DoG;synthetic;DoG 100.0 0.0 3.0 35.0 size 128 128 32 ;\u232B
+Image.image.row2=Applications;directory;/users/dsage/Applications;\u232B
Image.image.row3=Cube;synthetic;Cube 100.0 0.0 10.0 1.0 size 128 128 32 ;\u232B
-Image.image.row4=RandomLines;synthetic;RandomLines 100.0 0.0 300.0 size 512 512 32 ;\u232B
-Image.image.row5=Cube;synthetic;Cube 100.0 0.0 10.0 1.0 size 128 128 32 ;\u232B
-Image.image.row6=Applications;platform;Applications;\u232B
-Image.image.row7=Applications;directory;/users/dsage/Applications;\u232B
-Image.image.row8=Cube;synthetic;Cube 100.0 0.0 10.0 1.0 size 128 128 32 ;\u232B
-Image.image.row9=lib;directory;/Users/dsage/git/deconvolution/DeconvolutionLab2/lib;\u232B
-Image.image.selected=Cell7.tif;file;/Users/dsage/Desktop/Maria Azevedo/Cell7.tif;null
+Image.image.row4=lib;directory;/Users/dsage/git/deconvolution/DeconvolutionLab2/lib;\u232B
+Image.image.selected=active;platform;active;\u232B
Language.headless=Run (Headless)
Language.job=Job
-Language.language=Command line
+Language.language=Java
Output.output.row0=ortho;OR2;;;;\u2713;\u2713;\u232B
Output.output.selected=ortho;OR2;;;;\u2713;\u2713;\u232B
PSF.psf.row0=AirySimulated;synthetic;AirySimulated 100.0 0.0 1.0 size 128 128 32 ;null
PSF.psf.row1=Chrome Apps.localized;directory;/users/dsage/applications/Chrome Apps.localized;\u232B
PSF.psf.row2=FI1.tif;file;/Users/dsage/git/deconvolution/DeconvolutionLab2/FI1.tif;\u232B
PSF.psf.selected=AirySimulated;synthetic;AirySimulated 100.0 0.0 1.0 size 128 128 32 ;null
Running.Directory=/Users/dsage/Applications
Running.Display=no
Running.Monitor=console table
Running.Multithreading=yes
Running.Path=specify
Running.Stats=show
Running.System=no
Running.Verbose=log
diff --git a/DeconvolutionLab2/src/course/DeconvolutionLab2_JavaCoding.java b/DeconvolutionLab2/src/course/DeconvolutionLab2_JavaCoding.java
index 2a46496..91bb4ca 100644
--- a/DeconvolutionLab2/src/course/DeconvolutionLab2_JavaCoding.java
+++ b/DeconvolutionLab2/src/course/DeconvolutionLab2_JavaCoding.java
@@ -1,68 +1,67 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package course;
import java.io.File;
import javax.swing.filechooser.FileSystemView;
import deconvolution.algorithm.Simulation;
import deconvolutionlab.Lab;
import deconvolutionlab.monitor.Monitors;
import ij.plugin.PlugIn;
import signal.RealSignal;
public class DeconvolutionLab2_JavaCoding implements PlugIn {
private String desktop = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator + "Desktop" + File.separator;
public DeconvolutionLab2_JavaCoding() {
String path = desktop + "Deconvolution" + File.separator + "data" + File.separator + "bars" + File.separator;
- Monitors monitors = new Monitors();
+ Monitors monitors = Monitors.createDefaultMonitor();
RealSignal image = Lab.openFile(monitors, path + "bars.tif");
RealSignal psf = Lab.openFile(monitors, path + "psf.tif");
-
Simulation convolution = new Simulation(100, 100, 10);
RealSignal a = convolution.run(image, psf);
Lab.showMIP(monitors, a, "a");
}
public static void main(String arg[]) {
new DeconvolutionLab2_JavaCoding();
}
@Override
public void run(String arg) {
new DeconvolutionLab2_JavaCoding();
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/Deconvolution.java b/DeconvolutionLab2/src/deconvolution/Deconvolution.java
index 283126e..35cce6f 100644
--- a/DeconvolutionLab2/src/deconvolution/Deconvolution.java
+++ b/DeconvolutionLab2/src/deconvolution/Deconvolution.java
@@ -1,553 +1,595 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution;
import java.io.File;
import java.util.ArrayList;
import bilib.tools.NumFormat;
import deconvolution.algorithm.AbstractAlgorithm;
import deconvolution.algorithm.Controller;
import deconvolutionlab.Constants;
import deconvolutionlab.Lab;
import deconvolutionlab.Output;
import deconvolutionlab.OutputCollection;
import deconvolutionlab.TableStats;
import deconvolutionlab.monitor.ConsoleMonitor;
import deconvolutionlab.monitor.Monitors;
import deconvolutionlab.monitor.StatusMonitor;
import deconvolutionlab.monitor.TableMonitor;
import deconvolutionlab.monitor.Verbose;
import deconvolutionlab.system.SystemInfo;
import fft.AbstractFFTLibrary;
import signal.RealSignal;
import signal.SignalCollector;
import signal.apodization.Apodization;
+import signal.factory.SignalFactory;
import signal.padding.Padding;
public class Deconvolution implements Runnable {
public enum Finish {
DIE, ALIVE, KILL
};
public AbstractAlgorithm algo = null;
private String path;
public double norm = 1.0;
public Padding pad = new Padding();
public Apodization apo = new Apodization();
private OutputCollection outs;
private Verbose verbose = Verbose.Log;
private AbstractFFTLibrary fft;
private int flagMonitor = 3;
private int flagStats = 0;
private boolean flagDisplay = true;
private boolean flagMultithreading = true;
private boolean flagSystem = true;
public Monitors monitors = new Monitors();
private String command = "";
private boolean live = false;
private Features report = new Features();
private String name = "";
private ArrayList<DeconvolutionListener> listeners = new ArrayList<DeconvolutionListener>();
public RealSignal image;
public RealSignal psf;
private RealSignal deconvolvedImage;
private Finish finish = Finish.DIE;
private DeconvolutionDialog dialog;
private TableStats tableStats;
public Deconvolution(String name, String command) {
this.name = name;
this.finish = Finish.DIE;
setCommand(command);
tableStats = new TableStats(name, Constants.widthGUI, 240, path, (flagStats & 2) == 2);
}
public Deconvolution(String name, String command, Finish finish) {
this.name = name;
this.finish = finish;
setCommand(command);
tableStats = new TableStats(name, Constants.widthGUI, 240, path, (flagStats & 2) == 2);
}
public void setCommand(String command) {
this.command = command;
Command.decode(command, this);
this.command = command;
if (name.equals("") && algo != null)
name = algo.getShortnames()[0];
live = false;
}
/**
* This method runs the deconvolution without graphical user interface.
*
* @param exit
* System.exit call is true
*/
public RealSignal deconvolve(RealSignal image, RealSignal psf) {
this.image = image;
this.psf = psf;
runDeconvolve();
return deconvolvedImage;
}
public RealSignal deconvolve() {
this.image = null;
this.psf = null;
runDeconvolve();
return deconvolvedImage;
}
/**
* This method runs the deconvolution without graphical user interface.
*
* @param exit
* System.exit call is true
*/
private void runDeconvolve() {
if ((flagMonitor & 2) == 2) {
TableMonitor tableMonitor = new TableMonitor(name , Constants.widthGUI, 240);
monitors.add(tableMonitor);
Lab.setVisible(tableMonitor.getPanel(), "Monitor of " + name, 10, 10);
}
if ((flagMonitor & 1) == 1)
monitors.add(new ConsoleMonitor());
if ((flagStats & 1) == 1) {
Lab.setVisible(tableStats.getPanel(), "Stats of " + name, 50, 50);
}
if (fft == null) {
run();
return;
}
if (!fft.isMultithreadable()) {
run();
return;
}
if (flagMultithreading) {
Thread thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}
else {
run();
}
}
/**
* This method runs the deconvolution with a graphical user interface.
*
* @param job
* Name of the job of deconvolution
*/
public void launch() {
monitors = new Monitors();
TableMonitor tableMonitor = null;
if ((flagMonitor & 2) == 2) {
tableMonitor = new TableMonitor(name , Constants.widthGUI, 240);
monitors.add(tableMonitor);
}
if ((flagMonitor & 1) == 1)
monitors.add(new ConsoleMonitor());
if (flagStats == 0) {
tableStats = null;
}
dialog = new DeconvolutionDialog(DeconvolutionDialog.Module.ALL, this, tableMonitor, tableStats);
monitors.add(new StatusMonitor(dialog.getProgressBar()));
Lab.setVisible(dialog, false);
}
@Override
public void run() {
double chrono = System.nanoTime();
if (flagSystem)
SystemInfo.activate();
for (DeconvolutionListener listener : listeners)
listener.started();
live = true;
if (monitors != null)
monitors.setVerbose(verbose);
report.add("Path", checkPath(path));
monitors.log("Path: " + checkPath(path));
if (image == null)
image = openImage();
if (image == null) {
monitors.error("Image: Not valid " + command);
report.add("Image", "Not valid");
if (finish == Finish.KILL)
System.exit(-101);
return;
}
report.add("Image", image.dimAsString());
monitors.log("Image: " + image.dimAsString());
psf = openPSF();
if (psf == null) {
monitors.error("PSF: not valid");
report.add("PSF", "Not valid");
if (finish == Finish.KILL)
System.exit(-102);
return;
}
report.add("PSF", psf.dimAsString());
monitors.log("PSF: " + psf.dimAsString());
if (algo == null) {
monitors.error("Algorithm: not valid");
if (finish == Finish.KILL)
System.exit(-103);
return;
}
Controller controller = algo.getController();
if (controller == null) {
monitors.error("Controller: not valid");
if (finish == Finish.KILL)
System.exit(-104);
return;
}
if (flagStats > 0)
controller.setTableStats(tableStats);
report.add("FFT", fft.getLibraryName());
if (outs != null) {
outs.setPath(path);
controller.setOutputs(outs);
}
monitors.log("Algorithm: " + algo.getName());
report.add("Algorithm", algo.getName());
algo.setController(controller);
algo.setFFT(fft);
algo.setMonitors(monitors);
deconvolvedImage = algo.run(image, psf, pad, apo, norm);
live = false;
for (DeconvolutionListener listener : listeners)
listener.finish();
report.add("End", NumFormat.time(System.nanoTime() - chrono));
if (flagDisplay)
Lab.show(monitors, deconvolvedImage, "Result of " + algo.getShortnames()[0]);
if (finish == Finish.KILL) {
System.out.println("End");
System.exit(0);
}
if (finish == Finish.DIE)
die();
}
public void close() {
if (dialog != null)
dialog.dispose();
SignalCollector.free(image);
SignalCollector.free(psf);
SignalCollector.free(deconvolvedImage);
algo = null;
image = null;
psf = null;
deconvolvedImage = null;
monitors = null;
System.gc();
}
public void die() {
SignalCollector.free(image);
SignalCollector.free(psf);
}
/**
* This methods make a recap of the deconvolution. Useful before starting
* the processing.
*
* @return list of messages to print
*/
public Features recap() {
Features features = new Features();
Token image = Command.extract(command, "-image");
features.add("Image", image == null ? "keyword -image not found" : image.parameters);
String normf = (norm < 0 ? " (no normalization)" : " (normalization to " + norm + ")");
Token psf = Command.extract(command, "-psf");
features.add("PSF", psf == null ? "keyword -psf not found" : psf.parameters + " norm:" + normf);
if (algo == null) {
features.add("Algorithm", "not valid>");
}
else {
Controller controller = algo.getController();
features.add("Algorithm", algo.toString());
features.add("Stopping Criteria", controller.getStoppingCriteriaAsString(algo));
features.add("Reference", controller.getReference());
features.add("Constraint", controller.getConstraintAsString());
features.add("Padding", pad.toString());
features.add("Apodization", apo.toString());
features.add("FFT", fft == null ? "null" : fft.getLibraryName());
}
features.add("Path", path);
String monitor = "";
if (flagMonitor == 0)
monitor = "no ";
if (flagMonitor == 1)
monitor = "console (" + verbose.name().toLowerCase() + ")";
if (flagMonitor == 2)
monitor = "table (" + verbose.name().toLowerCase() + ")";
if (flagMonitor == 3)
monitor = "console table (" + verbose.name().toLowerCase() + ")";
String stats = "";
if (flagStats == 0)
stats = "no ";
if (flagStats == 1)
stats = "show ";
if (flagStats == 2)
stats = "save ";
if (flagStats == 3)
stats = "show save";
String running = "";
running += "multithreading: " + (flagMultithreading ? "on " : "off ");
running += " display: " + (flagDisplay ? "on " : "off ");
running += " system: " + (flagSystem ? "shown" : "hidden ");
features.add("Monitor", monitor);
features.add("Stats", stats);
features.add("Running", running);
if (outs == null)
features.add("Output", "not valid");
else
for (Output out : outs)
features.add("Output " + out.getName(), out.toString());
return features;
}
public Features checkOutput() {
Features features = new Features();
if (deconvolvedImage == null) {
features.add("Image", "No valid output image");
return features;
}
float stati[] = deconvolvedImage.getStats();
int sizi = deconvolvedImage.nx * deconvolvedImage.ny * deconvolvedImage.nz;
float totali = stati[0] * sizi;
features.add("<html><b>Deconvolved Image</b></html>", "");
features.add("Size", deconvolvedImage.dimAsString() + " " + NumFormat.bytes(sizi*4));
features.add("Mean (stdev)", NumFormat.nice(stati[0]) + " (" + NumFormat.nice(stati[3]) + ")");
features.add("Min ... Max", NumFormat.nice(stati[1]) + " ... " + NumFormat.nice(stati[2]));
features.add("Energy (int)", NumFormat.nice(stati[5]) + " (" + NumFormat.nice(totali) + ")");
return features;
}
public boolean isLive() {
return live;
}
public void abort() {
live = false;
algo.getController().abort();
}
public String checkPath(String path) {
File dir = new File(path);
if (dir.exists()) {
if (dir.isDirectory()) {
if (dir.canWrite())
return path + " (writable)";
else
return path + " (non-writable)";
}
else {
return path + " (non-directory)";
}
}
else {
return path + " (not-valid)";
}
}
public RealSignal openImage() {
Token token = Command.extract(command, "-image");
if (token == null)
return null;
if (token.parameters.startsWith(">>>"))
return null;
String arg = token.option.trim();
String cmd = token.parameters.substring(arg.length(), token.parameters.length()).trim();
- image = Lab.createRealSignal(monitors, arg, cmd, path);
+ image = createRealSignal(monitors, arg, cmd, path);
return image;
}
public RealSignal openPSF() {
Token token = Command.extract(command, "-psf");
if (token == null)
return null;
if (token.parameters.startsWith(">>>"))
return null;
String arg = token.option.trim();
String cmd = token.parameters.substring(arg.length(), token.parameters.length()).trim();
- psf = Lab.createRealSignal(monitors, arg, cmd, path);
+ psf = createRealSignal(monitors, arg, cmd, path);
return psf;
}
+ private static RealSignal createRealSignal(Monitors monitors, String arg, String cmd, String path) {
+ RealSignal signal = null;
+ if (arg.equalsIgnoreCase("synthetic")) {
+ signal = Lab.createSynthetic(monitors, cmd);
+ }
+
+ if (arg.equalsIgnoreCase("platform")) {
+ signal = Lab.getImage(monitors, cmd);
+ }
+
+ if (arg.equalsIgnoreCase("file")) {
+ File file = new File(path + File.separator + cmd);
+ if (file != null) {
+ if (file.isFile())
+ signal = Lab.openFile(monitors, path + File.separator + cmd);
+ }
+ if (signal == null) {
+ File local = new File(cmd);
+ if (local != null) {
+ if (local.isFile())
+ signal = Lab.openFile(monitors, cmd);
+ }
+ }
+ }
+
+ if (arg.equalsIgnoreCase("dir") || arg.equalsIgnoreCase("directory")) {
+ File file = new File(path + File.separator + cmd);
+ if (file != null) {
+ if (file.isDirectory())
+ signal = Lab.openDir(monitors, path + File.separator + cmd);
+ }
+ if (signal == null) {
+ File local = new File(cmd);
+ if (local != null) {
+ if (local.isDirectory())
+ signal = Lab.openDir(monitors, cmd);
+ }
+ }
+ }
+ return signal;
+ }
public void addDeconvolutionListener(DeconvolutionListener listener) {
listeners.add(listener);
}
public OutputCollection getOuts() {
return outs;
}
public void setAlgorithm(AbstractAlgorithm algo, Controller controller) {
this.algo = algo;
if (algo != null && controller != null) {
algo.setController(controller);
}
}
public AbstractAlgorithm getAlgo() {
return algo;
}
public void setPath(String path) {
this.path = path;
}
public String getPath() {
return path;
}
public void setNormalization(double norm) {
this.norm = norm;
}
public void setPadding(Padding pad) {
this.pad = pad;
}
public Padding getPadding() {
return pad;
}
public RealSignal getOutput() {
return deconvolvedImage;
}
public RealSignal getImage() {
return image;
}
public RealSignal getPSF() {
return psf;
}
public Features getDeconvolutionReports() {
return report;
}
public String getName() {
return name;
}
public void setApodization(Apodization apo) {
this.apo = apo;
}
public Apodization getApodization() {
return apo;
}
public void setOutput(OutputCollection outs) {
this.outs = outs;
}
public void setVerbose(Verbose verbose) {
this.verbose = verbose;
}
public void setFFT(AbstractFFTLibrary fft) {
this.fft = fft;
}
public void setMonitor(int flagMonitor) {
this.flagMonitor = flagMonitor;
}
public void setStats(int flagStats) {
this.flagStats = flagStats;
}
public void setFlags(boolean flagDisplay, boolean flagMultithreading, boolean flagSystem) {
this.flagDisplay = flagDisplay;
this.flagMultithreading = flagMultithreading;
this.flagSystem = flagSystem;
}
public String getCommand() {
return command;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/FISTA.java b/DeconvolutionLab2/src/deconvolution/algorithm/FISTA.java
index 2947d54..2454d9f 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/FISTA.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/FISTA.java
@@ -1,188 +1,188 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
import wavelets.AbstractWavelets;
import wavelets.Wavelets;
public class FISTA extends AbstractAlgorithm implements Callable<RealSignal> {
private double gamma = 1.0;
private double lambda = 0.1;
private String waveletsName = "Haar";
private int scale = 3;
public FISTA(int iter, double gamma, double lambda, String waveletsName, int scale) {
super();
controller.setIterationMax(iter);
this.gamma = gamma;
this.lambda = lambda;
this.waveletsName = waveletsName;
this.scale = scale;
}
@Override
public RealSignal call() throws Exception {
AbstractWavelets wavelets = Wavelets.getWaveletsByName(waveletsName);
wavelets.setScale(scale);
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal A = Operations.delta(gamma, H);
ComplexSignal G = Operations.multiplyConjugate(gamma, H, Y);
SignalCollector.free(Y);
SignalCollector.free(H);
ComplexSignal Z = G.duplicate();
RealSignal x = fft.inverse(G);
RealSignal s = x.duplicate();
RealSignal z = x.duplicate();
RealSignal xprev = fft.inverse(G);
float pk1 = 1f;
float pk0 = 1f;
float threshold = (float) (lambda * gamma * 0.5);
RealSignal buffer = y.duplicate();
while (!controller.ends(x)) {
fft.transform(s, Z);
Z.times(A);
Z.plus(G);
fft.inverse(Z, z);
wavelets.shrinkage(threshold, z, x, buffer);
pk0 = pk1;
pk1 = (1f + (float) Math.sqrt(1f + 4f * pk0 * pk0)) * 0.5f;
update(xprev, x, (pk0 - 1f) / pk1, s);
}
SignalCollector.free(A);
SignalCollector.free(Z);
SignalCollector.free(G);
SignalCollector.free(s);
SignalCollector.free(z);
SignalCollector.free(xprev);
SignalCollector.free(buffer);
return x;
}
public void update(RealSignal xprev, RealSignal x, double w, RealSignal s) {
int nxy = x.nx * x.ny;
for (int k = 0; k < x.nz; k++)
for (int i = 0; i < nxy; i++) {
float vx = x.data[k][i];
s.data[k][i] = (float) (vx + w * (vx - xprev.data[k][i]));
xprev.data[k][i] = vx;
}
}
@Override
public String getName() {
- return "Fast Iterative Shrinkage-Thresholding [FISTA]";
+ return "Fast Iterative Shrinkage-Thresholding";
}
@Override
public String[] getShortnames() {
return new String[] {"FISTA"};
}
@Override
public int getComplexityNumberofFFT() {
return 4 + 4 * controller.getIterationMax();
}
@Override
public double getMemoryFootprintRatio() {
return 15.0;
}
@Override
public boolean isRegularized() {
return true;
}
@Override
public boolean isStepControllable() {
return true;
}
@Override
public boolean isIterative() {
return true;
}
@Override
public boolean isWaveletsBased() {
return true;
}
@Override
public void setWavelets(String waveletsName) {
this.waveletsName = waveletsName;
}
@Override
public void setParameters(double[] params) {
if (params == null)
return;
if (params.length > 0)
controller.setIterationMax((int) Math.round(params[0]));
if (params.length > 1)
gamma = (float) params[1];
if (params.length > 2)
lambda = (float) params[2];
if (params.length > 3)
scale = (int) params[3];
}
@Override
public double[] getDefaultParameters() {
return new double[] { 10, 1, 0.1 };
}
@Override
public double[] getParameters() {
return new double[] { controller.getIterationMax(), gamma, lambda };
}
@Override
public double getRegularizationFactor() {
return lambda;
}
@Override
public double getStepFactor() {
return gamma;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/FISTAPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/FISTAPanel.java
index a94a846..ca37acf 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/FISTAPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/FISTAPanel.java
@@ -1,167 +1,166 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.GridPanel;
import bilib.component.SpinnerRangeDouble;
import bilib.component.SpinnerRangeInteger;
import bilib.tools.NumFormat;
import deconvolution.Command;
import deconvolution.RegularizationPanel;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
import wavelets.AbstractWavelets;
import wavelets.Wavelets;
public class FISTAPanel extends AbstractAlgorithmPanel implements KeyListener, ActionListener, ChangeListener {
private SpinnerRangeInteger spnIter = new SpinnerRangeInteger(10, 1, 99999, 1, "###");
private SpinnerRangeDouble spnStep = new SpinnerRangeDouble(1, 0, 2, 0.1, "#.#");
private RegularizationPanel reg;
private JComboBox<String> cmbWav = new JComboBox<String>(Wavelets.getWaveletsAsArray());
private JComboBox<String> cmbScale = new JComboBox<String>(new String[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" });
private FISTA algo = new FISTA(10, 1, 0.1, "Haar", 3);
@Override
public JPanel getPanelParameters() {
AbstractWavelets wavdef = Wavelets.getDefaultWavelets();
double[] params = algo.getDefaultParameters();
reg = new RegularizationPanel(params[2]);
spnIter.setPreferredSize(Constants.dimParameters);
spnStep.setPreferredSize(Constants.dimParameters);
cmbWav.setPreferredSize(Constants.dimParameters);
cmbScale.setPreferredSize(Constants.dimParameters);
GridPanel pn = new GridPanel(false);
pn.place(1, 0, "<html><span \"nowrap\"><b>Iterations</b></span></html>");
pn.place(1, 1, "<html><span \"nowrap\"><i>N</i></span></html>");
pn.place(1, 2, spnIter);
pn.place(1, 3, "<html><span \"nowrap\">Step <i>&gamma;</i></span></html>");
pn.place(1, 4, spnStep);
pn.place(2, 0, 5, 1, reg);
pn.place(5, 0, "<html><span \"nowrap\"><b>Wavelets</b></span></html>");
pn.place(5, 2, cmbWav);
pn.place(5, 3, "<html>Scale</html>");
pn.place(5, 4, cmbScale);
Config.register("Algorithm." + algo.getShortnames()[0], "iterations", spnIter, params[0]);
Config.register("Algorithm." + algo.getShortnames()[0], "step", spnStep, params[1]);
Config.register("Algorithm." + algo.getShortnames()[0], "wavelets", cmbWav, wavdef.getName());
Config.register("Algorithm." + algo.getShortnames()[0], "scale", cmbScale, wavdef.getScales());
Config.register("Algorithm." + algo.getShortnames()[0], "reg", reg.getText(), "0.1");
reg.getText().addKeyListener(this);
reg.getSlider().addChangeListener(this);
spnIter.addChangeListener(this);
spnStep.addChangeListener(this);
cmbWav.addActionListener(this);
cmbScale.addActionListener(this);
return pn;
}
@Override
public String getCommand() {
int iter = spnIter.get();
double gamma = spnStep.get();
double lambda = reg.getValue();
String waveletsName = (String) cmbWav.getSelectedItem();
int scale = Integer.parseInt((String) cmbScale.getSelectedItem());
return iter + " " + NumFormat.nice(gamma) + " " + NumFormat.nice(lambda) + " " + waveletsName + " " + scale;
}
@Override
public void actionPerformed(ActionEvent e) {
Command.command();
}
@Override
public void stateChanged(ChangeEvent e) {
reg.getText().removeKeyListener(this);
reg.updateFromSlider();
Command.command();
reg.getText().addKeyListener(this);
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
reg.getSlider().removeChangeListener(this);
reg.updateFromText();
Command.command();
reg.getSlider().addChangeListener(this);
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<h2>Shortname: FISTA</h2>";
+ s += "<h1>" + getName() + " (FISTA)</h1>";
s += "<p>Iterative: " + algo.isIterative() + "</p>";
s += "<p>Step controllable: " + algo.isStepControllable() + "</p>";
s += "<p>Regularization: " + algo.isRegularized() + "</p>";
s += "<p>Wavelet-base: " + algo.isWaveletsBased() + "</p>";
s += "<p></p>";
s += "<h3>Reference: Beck and Teboulle, SIAM <b>2</b> 2009</h3>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/ISTA.java b/DeconvolutionLab2/src/deconvolution/algorithm/ISTA.java
index 12217dc..e041133 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/ISTA.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/ISTA.java
@@ -1,180 +1,180 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
import wavelets.AbstractWavelets;
import wavelets.Wavelets;
public class ISTA extends AbstractAlgorithm implements Callable<RealSignal> {
private double gamma = 1.0;
private double lambda = 1.0;
private String waveletsName = "Haar";
private int scale = 3;
public ISTA(int iter, double gamma, double lambda, String waveletsName, int scale) {
super();
controller.setIterationMax(iter);
this.gamma = gamma;
this.lambda = lambda;
this.waveletsName = waveletsName;
this.scale = scale;
}
@Override
public RealSignal call() throws Exception {
AbstractWavelets wavelets = Wavelets.getWaveletsByName(waveletsName);
wavelets.setScale(scale);
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal A = Operations.delta(gamma, H);
ComplexSignal G = Operations.multiplyConjugate(gamma, H, Y);
SignalCollector.free(Y);
SignalCollector.free(H);
ComplexSignal Z = G.duplicate();
RealSignal x = fft.inverse(G);
RealSignal z = x.duplicate();
float threshold = (float)(lambda*gamma*0.5);
RealSignal buffer = y.duplicate();
while(!controller.ends(x)) {
fft.transform(x, Z);
Z.times(A);
Z.plus(G);
fft.inverse(Z, z);
wavelets.shrinkage(threshold, z, x, buffer);
}
SignalCollector.free(A);
SignalCollector.free(Z);
SignalCollector.free(G);
SignalCollector.free(z);
SignalCollector.free(buffer);
return x;
}
public void update(RealSignal xprev, RealSignal x, double w, RealSignal s) {
int nxy = x.nx * x.ny;
for(int k=0; k<x.nz; k++)
for(int i=0; i< nxy; i++) {
float vx = x.data[k][i];
s.data[k][i] = (float)(vx + w*(vx - xprev.data[k][i]));
xprev.data[k][i] = vx;
}
}
@Override
public String getName() {
- return "Iterative Shrinkage-Thresholding [ISTA]";
+ return "Iterative Shrinkage-Thresholding";
}
@Override
public String[] getShortnames() {
return new String[] {"ISTA"};
}
@Override
public int getComplexityNumberofFFT() {
return 3 + 4 * controller.getIterationMax();
}
@Override
public double getMemoryFootprintRatio() {
return 13.0;
}
@Override
public boolean isRegularized() {
return true;
}
@Override
public boolean isStepControllable() {
return true;
}
@Override
public boolean isIterative() {
return true;
}
@Override
public boolean isWaveletsBased() {
return true;
}
@Override
public void setWavelets(String waveletsName) {
this.waveletsName = waveletsName;
}
@Override
public void setParameters(double[] params) {
if (params == null)
return;
if (params.length > 0)
controller.setIterationMax((int)Math.round(params[0]));
if (params.length > 1)
gamma = (float)params[1];
if (params.length > 2)
lambda = (float)params[2];
if (params.length > 3)
scale = (int)params[3];
}
@Override
public double[] getDefaultParameters() {
return new double[] {10, 1, 0.1};
}
@Override
public double[] getParameters() {
return new double[] {controller.getIterationMax(), gamma, lambda};
}
@Override
public double getRegularizationFactor() {
return lambda;
}
@Override
public double getStepFactor() {
return gamma;
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/Lab.java b/DeconvolutionLab2/src/deconvolutionlab/Lab.java
index dd28e3f..44433ba 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/Lab.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/Lab.java
@@ -1,378 +1,354 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab;
import java.io.File;
import java.util.ArrayList;
import java.util.regex.Pattern;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import bilib.tools.NumFormat;
import bilib.tools.WebBrowser;
import deconvolutionlab.Imaging.ContainerImage;
import deconvolutionlab.monitor.Monitors;
import fft.AbstractFFT;
import fft.AbstractFFTLibrary;
import fft.FFT;
import imagej.IJImager;
import plugins.sage.deconvolutionlab.IcyImager;
import signal.ComplexComponent;
import signal.ComplexSignal;
import signal.RealSignal;
import signal.factory.SignalFactory;
import signal.factory.Sphere;
public class Lab {
private static Imaging imaging;
private static ArrayList<JFrame> frames;
private static ArrayList<JDialog> dialogs;
static {
frames = new ArrayList<JFrame>();
dialogs = new ArrayList<JDialog>();
imaging = new IJImager();
Config.init(System.getProperty("user.dir") + File.separator + "DeconvolutionLab2.config");
}
public static Imaging.Platform getPlatform() {
return imaging.getPlatform();
}
public static void init(Imaging.Platform p) {
init(p, System.getProperty("user.dir") + File.separator + "DeconvolutionLab2.config");
}
public static void init(Imaging.Platform platform, String config) {
switch (platform) {
case IMAGEJ:
imaging = new IJImager();
break;
case ICY:
imaging = new IcyImager();
break;
default:
imaging = new IJImager();
break;
}
Config.init(System.getProperty("user.dir")+File.separator+"DeconvolutionLab2.config");
}
public static void help() {
WebBrowser.open(Constants.url);
}
public static void checkFFT(Monitors monitors) {
ArrayList<AbstractFFTLibrary> libraries = FFT.getInstalledLibraries();
for (int k = 1; k <= 3; k++)
for (AbstractFFTLibrary library : libraries) {
RealSignal y = new Sphere(3, 1).generate(40, 30, 20);
double chrono = System.nanoTime();
AbstractFFT fft = library.getDefaultFFT();
fft.init(monitors, y.nx, y.ny, y.nz);
RealSignal x = fft.inverse(fft.transform(y));
chrono = System.nanoTime() - chrono;
double residu = y.getEnergy() - x.getEnergy();
monitors.log(fft.getName() + " Test " + k);
monitors.log("\t residu of reconstruction: " + residu);
monitors.log("\t computation time (" + x.nx + "x" + x.ny + "x" + x.nz + ") " + NumFormat.time(chrono));
}
}
public static ContainerImage createContainer(Monitors monitors, String title) {
monitors.log("Create Live Real Signal " + title);
return imaging.createContainer(title);
}
public static void append(Monitors monitors, ContainerImage container, RealSignal signal, String title) {
imaging.append(container, signal, title, Imaging.Type.FLOAT);
monitors.log("Add Live Real Signal " + title);
}
public static void append(Monitors monitors, ContainerImage container, RealSignal signal, String title, Imaging.Type type) {
imaging.append(container, signal, title, type);
monitors.log("Add Live Real Signal " + title);
}
public static void show(Monitors monitors, ComplexSignal signal, String title) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, ComplexComponent.MODULE);
}
public static void show(Monitors monitors, ComplexSignal signal, String title, ComplexComponent complex) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, complex);
}
public static void show(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, Imaging.Type.FLOAT, signal.nz / 2);
}
public static void show(Monitors monitors, RealSignal signal, String title, Imaging.Type type) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, type, signal.nz / 2);
}
public static void show(Monitors monitors, RealSignal signal, String title, Imaging.Type type, int z) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, type, z);
}
public static void save(Monitors monitors, RealSignal signal, String filename) {
imaging.save(signal, filename, Imaging.Type.FLOAT);
monitors.log("Save Real Signal " + filename);
}
public static void save(Monitors monitors, RealSignal signal, String filename, Imaging.Type type) {
imaging.save(signal, filename, type);
monitors.log("Save Real Signal " + filename);
}
- public static RealSignal createRealSignal(Monitors monitors, String arg, String cmd, String path) {
-
- RealSignal signal = null;
- if (arg.equalsIgnoreCase("synthetic")) {
- signal = SignalFactory.createFromCommand(cmd);
- }
-
- if (arg.equalsIgnoreCase("platform")) {
- signal = getImager().create(cmd);
- }
- if (arg.equalsIgnoreCase("file")) {
- File file = new File(path + File.separator + cmd);
- if (file != null) {
- if (file.isFile())
- signal = Lab.openFile(monitors, path + File.separator + cmd);
- }
- if (signal == null) {
- File local = new File(cmd);
- if (local != null) {
- if (local.isFile())
- signal = Lab.openFile(monitors, cmd);
- }
- }
- }
-
- if (arg.equalsIgnoreCase("dir") || arg.equalsIgnoreCase("directory")) {
- File file = new File(path + File.separator + cmd);
- if (file != null) {
- if (file.isDirectory())
- signal = Lab.openDir(monitors, path + File.separator + cmd);
- }
- if (signal == null) {
- File local = new File(cmd);
- if (local != null) {
- if (local.isDirectory())
- signal = Lab.openDir(monitors, cmd);
- }
- }
- }
+ public static RealSignal createSynthetic(Monitors monitors, String cmd) {
+ RealSignal signal = SignalFactory.createFromCommand(cmd);
+ if (signal == null)
+ monitors.error("Unable to create " + cmd);
+ else
+ monitors.log("Create " + cmd);
+ return signal;
+ }
+
+ public static RealSignal getImage(Monitors monitors, String name) {
+ RealSignal signal = getImager().create(name);
+ if (signal == null)
+ monitors.error("Unable to get " + name);
+ else
+ monitors.log("Load " + name);
return signal;
}
public static RealSignal openFile(Monitors monitors, String filename) {
RealSignal signal = imaging.open(filename);
if (signal == null)
monitors.error("Unable to open " + filename);
else
monitors.log("Load " + filename);
return signal;
}
public static RealSignal openDir(Monitors monitors, String path) {
String parts[] = path.split(" pattern ");
String dirname = path;
String regex = "";
if (parts.length == 2) {
dirname = parts[0].trim();
regex = parts[1].trim();
}
File file = new File(dirname + File.separator);
if (!file.isDirectory()) {
monitors.error("Dir " + dirname + " is not a directory.");
return null;
}
String[] list = file.list();
ArrayList<RealSignal> slices = new ArrayList<RealSignal>();
int nx = 0;
int ny = 0;
Pattern pattern = Pattern.compile(regex);
for (String filename : list) {
if (pattern.matcher(filename).find()) {
RealSignal slice = imaging.open(dirname + File.separator + filename);
if (slice != null) {
slices.add(slice);
nx = Math.max(nx, slice.nx);
ny = Math.max(ny, slice.ny);
monitors.log("Image " + path + File.separator + filename + " is loaded.");
}
}
else {
monitors.error("Error in loading image " + path + File.separator + filename);
}
}
int nz = slices.size();
if (nz <= 0) {
monitors.error("Dir " + path + " do no contain valid images.");
return null;
}
RealSignal signal = new RealSignal(file.getName(), nx, ny, nz);
for (int z = 0; z < slices.size(); z++)
signal.setSlice(z, slices.get(z));
return signal;
}
public static void showOrthoview(Monitors monitors, RealSignal signal, String title, int hx, int hy, int hz) {
if (signal == null) {
monitors.error("Show Orthoview " + title + " this image does not exist.");
return;
}
imaging.show(signal.createOrthoview(hx, hy, hz), title, Imaging.Type.FLOAT, 0);
}
public static void showOrthoview(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show Orthoview " + title + " this image does not exist.");
return;
}
int hx = signal.nx / 2;
int hy = signal.ny / 2;
int hz = signal.nz / 2;
imaging.show(signal.createOrthoview(hx, hy, hz), title, Imaging.Type.FLOAT, 0);
}
public static void showMIP(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show MIP " + title + " this image does not exist.");
return;
}
imaging.show(signal.createMIP(), title, Imaging.Type.FLOAT, 0);
}
public static void showMontage(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show Montage " + title + " this image does not exist.");
return;
}
imaging.show(signal.createMontage(), title, Imaging.Type.FLOAT, 0);
}
public static RealSignal create(Monitors monitors, String name) {
RealSignal signal = imaging.create(name);
if (signal != null)
monitors.log("Created the real signal " + name + " " + signal.toString());
else
monitors.error("Impossible to create the real signal " + name);
return signal;
}
public static RealSignal create(Monitors monitors) {
RealSignal signal = imaging.create();
if (signal != null)
monitors.log("Created the real signal from the active window " + signal.toString());
else
monitors.error("Impossible to create the real signal from the active window");
return signal;
}
public static Imaging getImager() {
return imaging;
}
public static String getActiveImage() {
if (imaging.isSelectable())
return imaging.getSelectedImage();
return "";
}
public static void setVisible(JDialog dialog, boolean modal) {
if (dialog == null)
return;
dialogs.add(dialog);
imaging.setVisible(dialog, modal);
}
public static void setVisible(JPanel panel, String name, int x, int y) {
JFrame frame = new JFrame(name);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocation(x, y);
frame.setVisible(true);
frames.add(frame);
}
public static void setVisible(JFrame frame) {
frames.add(frame);
frame.setVisible(true);
}
public static void close() {
for(JFrame frame : frames)
if (frame != null)
frame.dispose();
for(JDialog dialog : dialogs)
if (dialog != null)
dialog.dispose();
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/modules/AlgorithmModule.java b/DeconvolutionLab2/src/deconvolutionlab/modules/AlgorithmModule.java
index 0750aed..62230dc 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/modules/AlgorithmModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/modules/AlgorithmModule.java
@@ -1,153 +1,155 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab.modules;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.HTMLPane;
import deconvolution.Command;
import deconvolution.Deconvolution;
import deconvolution.DeconvolutionDialog;
import deconvolution.algorithm.AbstractAlgorithmPanel;
import deconvolution.algorithm.Algorithm;
import deconvolutionlab.Config;
import deconvolutionlab.Lab;
public class AlgorithmModule extends AbstractModule implements ActionListener, ChangeListener {
private JComboBox<String> cmb;
private HTMLPane doc;
private JPanel cards;
public AlgorithmModule(boolean expanded) {
super("Algorithm", "-algorithm", "", "Check", expanded);
ArrayList<AbstractAlgorithmPanel> deconv = Algorithm.getAvailableAlgorithms();
for (AbstractAlgorithmPanel panel : deconv)
cmb.addItem(panel.getName());
cmb.addActionListener(this);
}
@Override
public String getCommand() {
String name = (String) cmb.getSelectedItem();
AbstractAlgorithmPanel algo = Algorithm.getPanel(name);
String cmd = "-algorithm " + algo.getShortnames()[0] + " " + algo.getCommand();
- String synopsis = name;
+ String synopsis = algo.getShortnames()[0] + " " + algo.getCommand();
setSynopsis(synopsis);
setCommand(cmd);
return cmd;
}
@Override
public JPanel buildExpandedPanel() {
cmb = new JComboBox<String>();
JPanel pnc = new JPanel();
pnc.add(cmb);
doc = new HTMLPane(100, 1000);
cards = new JPanel(new CardLayout());
ArrayList<AbstractAlgorithmPanel> panels = Algorithm.getAvailableAlgorithms();
for (AbstractAlgorithmPanel panel : panels) {
JScrollPane scroll = new JScrollPane(panel.getPanelParameters());
scroll.setBorder(BorderFactory.createEmptyBorder());
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
cards.add(panel.getName(), scroll);
}
cmb.setMaximumRowCount(panels.size());
JPanel control = new JPanel();
control.setLayout(new BoxLayout(control, BoxLayout.PAGE_AXIS));
Border b1 = BorderFactory.createEtchedBorder();
Border b2 = BorderFactory.createEmptyBorder(10, 10, 10, 10);
control.setBorder(BorderFactory.createCompoundBorder(b1, b2));
+ cards.setBorder(BorderFactory.createEtchedBorder());
+
control.add(cmb);
control.add(cards);
doc.append("h1", "Documentation");
JPanel panel = new JPanel(new BorderLayout());
panel.add(control, BorderLayout.NORTH);
panel.add(doc.getPane(), BorderLayout.CENTER);
// cmb.addActionListener(this);
getAction2Button().setToolTipText("Human readable of the command line");
getAction2Button().addActionListener(this);
Config.register(getName(), "algorithm", cmb, Algorithm.getDefaultAlgorithm());
panel.setBorder(BorderFactory.createEtchedBorder());
return panel;
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
if (e.getSource() == cmb) {
doc.clear();
String name = (String) cmb.getSelectedItem();
AbstractAlgorithmPanel algo = Algorithm.getPanel(name);
doc.append(algo.getDocumentation());
CardLayout cl = (CardLayout) (cards.getLayout());
cl.show(cards, name);
}
if (e.getSource() == getAction2Button()) {
Deconvolution deconvolution = new Deconvolution("Check Algorithm", Command.command());
DeconvolutionDialog d = new DeconvolutionDialog(DeconvolutionDialog.Module.ALGO, deconvolution, null, null);
Lab.setVisible(d, false);
}
setSynopsis((String) cmb.getSelectedItem());
setCommand(getCommand());
Command.command();
}
@Override
public void stateChanged(ChangeEvent e) {
setSynopsis((String) cmb.getSelectedItem());
setCommand(getCommand());
Command.command();
}
@Override
public void close() {
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/monitor/Message.java b/DeconvolutionLab2/src/deconvolutionlab/monitor/Message.java
index 8d3ced9..5c54494 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/monitor/Message.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/monitor/Message.java
@@ -1,82 +1,85 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab.monitor;
import bilib.tools.NumFormat;
import deconvolutionlab.system.SystemUsage;
public class Message {
private static long id = 0;
private double chrono;
private String mem;
private Verbose level;
private String message;
private double progress;
public Message(Verbose level, String message, double chrono, double progress) {
id = id+1;
this.chrono = chrono;
this.mem = SystemUsage.getMemoryMB();
this.message = message;
this.level = level;
this.progress = progress;
}
public long getID() {
return id;
}
public String getMessage() {
return message;
}
public Verbose getLevel() {
return level;
}
public double getProgress() {
return progress;
}
public String formatProgress() {
return NumFormat.time(chrono) + " \t " + message + " (" + progress + "%)";
}
public String formatTab() {
- return level.name() + " \t " + NumFormat.time(chrono) + " \t " + mem + " \t " + message;
+ if (level.name().equalsIgnoreCase("quiet"))
+ return "Error" + " \t " + NumFormat.time(chrono) + " \t " + mem + " \t " + message;
+ else
+ return "Log " + " \t " + NumFormat.time(chrono) + " \t " + mem + " \t " + message;
}
public String[] formatArray() {
return new String[] {NumFormat.time(chrono), mem, message};
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/monitor/Monitors.java b/DeconvolutionLab2/src/deconvolutionlab/monitor/Monitors.java
index 0db6c4c..6d18f26 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/monitor/Monitors.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/monitor/Monitors.java
@@ -1,100 +1,100 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab.monitor;
import java.util.ArrayList;
public class Monitors extends ArrayList<AbstractMonitor> {
private double start;
private Verbose verbose;
private double progress;
public Monitors() {
super();
start = System.nanoTime();
verbose = Verbose.Log;
progress = 0;
}
public void setVerbose(Verbose v) {
verbose = v;
}
public Verbose getVerbose() {
return verbose;
}
public static Monitors createDefaultMonitor() {
Monitors monitors = new Monitors();
monitors.add(new ConsoleMonitor());
return monitors;
}
public static Monitors create(AbstractMonitor monitor) {
Monitors monitors = new Monitors();
monitors.add(new ConsoleMonitor());
monitors.add(monitor);
return monitors;
}
public void detail(String msg) {
if (verbose.ordinal() >= Verbose.Prolix.ordinal())
sendMessage(new Message(Verbose.Prolix, msg, System.nanoTime() - start, 0));
}
public void progress(String msg, double p) {
progress = Math.max(0, Math.min(100, p));
sendProgress(new Message(Verbose.Prolix, msg, System.nanoTime() - start, progress));
}
public void log(String msg) {
if (verbose.ordinal() >= Verbose.Log.ordinal())
sendMessage(new Message(Verbose.Log, msg, System.nanoTime() - start, progress));
}
public void error(String msg) {
if (verbose.ordinal() >= Verbose.Quiet.ordinal())
sendMessage(new Message(Verbose.Quiet, msg, System.nanoTime() - start, 0));
}
private void sendMessage(Message message) {
for (AbstractMonitor monitor : this)
- monitor.add(message);
+ monitor.add(message);
}
private void sendProgress(Message message) {
for (AbstractMonitor monitor : this)
if (monitor instanceof StatusMonitor)
monitor.add(message);
}
}
diff --git a/DeconvolutionLab2/src/fft/jtransforms/JTransforms.java b/DeconvolutionLab2/src/fft/jtransforms/JTransforms.java
index 98f47b4..ff5719b 100644
--- a/DeconvolutionLab2/src/fft/jtransforms/JTransforms.java
+++ b/DeconvolutionLab2/src/fft/jtransforms/JTransforms.java
@@ -1,89 +1,89 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package fft.jtransforms;
+import signal.ComplexSignal;
+import signal.RealSignal;
import deconvolutionlab.monitor.Monitors;
-import org.jtransforms.fft.FloatFFT_2D;
-import org.jtransforms.fft.FloatFFT_3D;
+import edu.emory.mathcs.jtransforms.fft.FloatFFT_2D;
+import edu.emory.mathcs.jtransforms.fft.FloatFFT_3D;
import fft.AbstractFFT;
import fft.Separability;
-import signal.ComplexSignal;
-import signal.RealSignal;
public class JTransforms extends AbstractFFT {
private FloatFFT_3D fftXYZ = null;
private FloatFFT_2D fftXY = null;
public JTransforms() {
super(Separability.XYZ);
}
@Override
public void init(Monitors monitors, int nx, int ny, int nz) {
super.init(monitors, nx, ny, nz);
try {
if (nz > 1)
fftXYZ = new FloatFFT_3D(nz, ny, nx);
else
fftXY = new FloatFFT_2D(ny, nx);
}
catch (Exception ex) {
System.out.println("check " + ex + ". " + nx + " " + ny + " " + nz);
}
}
@Override
public void transformInternal(RealSignal x, ComplexSignal X) {
float[] interleave = x.getInterleaveXYZAtReal();
if (fftXYZ != null)
fftXYZ.complexForward(interleave);
if (fftXY != null)
fftXY.complexForward(interleave);
X.setInterleaveXYZ(interleave);
}
@Override
public void inverseInternal(ComplexSignal X, RealSignal x) {
float[] interleave = X.getInterleaveXYZ();
if (fftXYZ != null)
fftXYZ.complexInverse(interleave, true);
if (fftXY != null)
fftXY.complexInverse(interleave, true);
x.setInterleaveXYZAtReal(interleave);
}
@Override
public String getName() {
return "JTransforms";
}
}
diff --git a/DeconvolutionLab2/src/fft/jtransforms/JTransformsFFT_XYZ.java b/DeconvolutionLab2/src/fft/jtransforms/JTransformsFFT_XYZ.java
index 5982742..da8d8c6 100644
--- a/DeconvolutionLab2/src/fft/jtransforms/JTransformsFFT_XYZ.java
+++ b/DeconvolutionLab2/src/fft/jtransforms/JTransformsFFT_XYZ.java
@@ -1,89 +1,89 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package fft.jtransforms;
+import signal.ComplexSignal;
+import signal.RealSignal;
import deconvolutionlab.monitor.Monitors;
-import org.jtransforms.fft.FloatFFT_2D;
-import org.jtransforms.fft.FloatFFT_3D;
+import edu.emory.mathcs.jtransforms.fft.FloatFFT_2D;
+import edu.emory.mathcs.jtransforms.fft.FloatFFT_3D;
import fft.AbstractFFT;
import fft.Separability;
-import signal.ComplexSignal;
-import signal.RealSignal;
public class JTransformsFFT_XYZ extends AbstractFFT {
private FloatFFT_3D fftXYZ = null;
private FloatFFT_2D fftXY = null;
public JTransformsFFT_XYZ() {
super(Separability.XYZ);
}
@Override
public void init(Monitors monitors, int nx, int ny, int nz) {
super.init(monitors, nx, ny, nz);
try {
if (nz > 1)
fftXYZ = new FloatFFT_3D(nz, ny, nx);
else
fftXY = new FloatFFT_2D(ny, nx);
}
catch (Exception ex) {
System.out.println("check " + ex + ". " + nx + " " + ny + " " + nz);
}
}
@Override
public void transformInternal(RealSignal x, ComplexSignal X) {
float[] interleave = x.getInterleaveXYZAtReal();
if (fftXYZ != null)
fftXYZ.complexForward(interleave);
if (fftXY != null)
fftXY.complexForward(interleave);
X.setInterleaveXYZ(interleave);
}
@Override
public void inverseInternal(ComplexSignal X, RealSignal x) {
float[] interleave = X.getInterleaveXYZ();
if (fftXYZ != null)
fftXYZ.complexInverse(interleave, true);
if (fftXY != null)
fftXY.complexInverse(interleave, true);
x.setInterleaveXYZAtReal(interleave);
}
@Override
public String getName() {
return "JTransforms XYZ";
}
}
diff --git a/DeconvolutionLab2/src/fft/jtransforms/JTransformsFFT_XY_Z.java b/DeconvolutionLab2/src/fft/jtransforms/JTransformsFFT_XY_Z.java
index 8403988..5f02651 100644
--- a/DeconvolutionLab2/src/fft/jtransforms/JTransformsFFT_XY_Z.java
+++ b/DeconvolutionLab2/src/fft/jtransforms/JTransformsFFT_XY_Z.java
@@ -1,103 +1,102 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package fft.jtransforms;
-import org.jtransforms.fft.FloatFFT_1D;
-import org.jtransforms.fft.FloatFFT_2D;
-
+import signal.ComplexSignal;
+import signal.RealSignal;
import deconvolutionlab.monitor.Monitors;
+import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D;
+import edu.emory.mathcs.jtransforms.fft.FloatFFT_2D;
import fft.AbstractFFT;
import fft.Separability;
-import signal.ComplexSignal;
-import signal.RealSignal;
public class JTransformsFFT_XY_Z extends AbstractFFT {
private FloatFFT_2D fftXY = null;
private FloatFFT_1D fftZ = null;
public JTransformsFFT_XY_Z() {
super(Separability.XY_Z);
}
@Override
public void init(Monitors monitors, int nx, int ny, int nz) {
super.init(monitors, nx, ny, nz);
try {
fftXY = new FloatFFT_2D(ny, nx);
if (nz > 1)
fftZ = new FloatFFT_1D(nz);
}
catch (Exception ex) {
}
}
@Override
public void transformInternal(RealSignal x, ComplexSignal X) {
for (int k = 0; k < nz; k++) {
float interleave[] = x.getInterleaveXYAtReal(k);
fftXY.complexForward(interleave);
X.setInterleaveXY(k, interleave);
}
if (fftZ == null)
return;
for (int i = 0; i < nx; i++)
for (int j = 0; j < ny; j++) {
float interleave[] = X.getInterleaveZ(i, j);
fftZ.complexForward(interleave);
X.setInterleaveZ(i, j, interleave);
}
}
@Override
public void inverseInternal(ComplexSignal X, RealSignal x) {
for (int k = 0; k < nz; k++) {
float interleave[] = X.getInterleaveXY(k);
fftXY.complexInverse(interleave, true);
X.setInterleaveXY(k, interleave);
}
if (fftZ != null) {
for (int i = 0; i < nx; i++)
for (int j = 0; j < ny; j++) {
float interleave[] = X.getInterleaveZ(i, j);
fftZ.complexInverse(interleave, true);
X.setInterleaveZ(i, j, interleave);
}
}
x = X.getRealSignal();
}
@Override
public String getName() {
return "JTransforms XY_Z";
}
}
diff --git a/DeconvolutionLab2/src/imagej/IJImager.java b/DeconvolutionLab2/src/imagej/IJImager.java
index 88caaaf..e20549c 100644
--- a/DeconvolutionLab2/src/imagej/IJImager.java
+++ b/DeconvolutionLab2/src/imagej/IJImager.java
@@ -1,348 +1,350 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package imagej;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import deconvolutionlab.Imaging;
import ij.ImagePlus;
import ij.ImageStack;
import ij.WindowManager;
import ij.gui.GUI;
import ij.io.FileSaver;
import ij.io.Opener;
import ij.process.FloatProcessor;
import ij.process.ImageProcessor;
import signal.ComplexComponent;
import signal.ComplexSignal;
import signal.RealSignal;
public class IJImager extends Imaging {
@Override
public Platform getPlatform() {
return Imaging.Platform.IMAGEJ;
}
@Override
public void setVisible(JDialog dialog, boolean modal) {
if (modal) {
dialog.setModal(modal);
GUI.center(dialog);
}
dialog.pack();
dialog.setVisible(true);
}
public static RealSignal create(ImagePlus imp) {
int nx = imp.getWidth();
int ny = imp.getHeight();
int nz = imp.getStackSize();
RealSignal signal = new RealSignal("ij-" + imp.getTitle(), nx, ny, nz);
for (int k = 0; k < nz; k++) {
ImageProcessor ip = imp.getStack().getProcessor(k + 1).convertToFloat();
signal.setXY(k, (float[]) ip.getPixels());
}
return signal;
}
@Override
public RealSignal create() {
return build(WindowManager.getCurrentImage());
}
@Override
public RealSignal create(String name) {
ImagePlus imp = null;
if (name.equalsIgnoreCase("active"))
imp = WindowManager.getCurrentImage();
else
imp = WindowManager.getImage(name);
if (imp == null)
imp = WindowManager.getCurrentImage();
return build(imp);
}
@Override
public RealSignal open(String filename) {
Opener opener = new Opener();
ImagePlus imp = opener.openImage(filename);
+ if (imp == null)
+ return null;
return build(imp);
}
@Override
public void show(RealSignal signal, String title, Imaging.Type type, int z) {
ImagePlus imp = build(signal, type);
if (imp != null) {
imp.setTitle(title);
int nz = imp.getStackSize();
imp.show();
imp.setSlice(Math.max(1, Math.min(nz, z)));
imp.getProcessor().resetMinAndMax();
}
}
public ContainerImage createContainer(String title) {
return new ContainerImage();
}
@Override
public void append(ContainerImage container, RealSignal signal, String title, Imaging.Type type) { ImagePlus cont = (ImagePlus) container.object;
if (container.object == null) {
ImageStack stack = new ImageStack(signal.nx, signal.ny);
stack.addSlice(build(signal, type).getProcessor());
stack.addSlice(build(signal, type).getProcessor());
container.object = new ImagePlus(title, stack);
((ImagePlus)container.object).show();
}
else {
cont.getStack().addSlice(build(signal, type).getProcessor());
cont.setSlice(cont.getStack().getSize());
cont.updateAndDraw();
cont.getProcessor().resetMinAndMax();
}
}
@Override
public void save(RealSignal signal, String filename, Imaging.Type type) {
ImagePlus imp = build(signal, type);
if (imp != null) {
if (imp.getStackSize() == 1) {
new FileSaver(imp).saveAsTiff(filename);
}
else {
new FileSaver(imp).saveAsTiffStack(filename);
}
}
}
@Override
public void show(ComplexSignal signal, String title, ComplexComponent complex) {
ImageStack stack = new ImageStack(signal.nx, signal.ny);
for (int k = 0; k < signal.nz; k++) {
float[] plane = null;
switch (complex) {
case REAL:
plane = signal.getRealXY(k);
break;
case IMAGINARY:
plane = signal.getImagXY(k);
break;
case MODULE:
plane = signal.getModuleXY(k);
break;
default:
plane = signal.getModuleXY_dB(k);
}
stack.addSlice(new FloatProcessor(signal.nx, signal.ny, plane));
}
new ImagePlus(title, stack).show();
}
private RealSignal build(ImagePlus imp) {
if (imp == null)
return null;
int nx = imp.getWidth();
int ny = imp.getHeight();
int nz = imp.getStackSize();
RealSignal signal = new RealSignal("ij-" + imp.getTitle(), nx, ny, nz);
for (int k = 0; k < nz; k++) {
ImageProcessor ip = imp.getStack().getProcessor(k + 1).convertToFloat();
signal.setXY(k, (float[]) ip.getPixels());
}
return signal;
}
private ImagePlus build(RealSignal signal, Imaging.Type type) {
if (signal == null)
return null;
ImageStack stack = new ImageStack(signal.nx, signal.ny);
for (int k = 0; k < signal.nz; k++) {
ImageProcessor ip = new FloatProcessor(signal.nx, signal.ny, signal.getXY(k));
switch (type) {
case BYTE:
stack.addSlice(ip.convertToByteProcessor(false));
break;
case SHORT:
stack.addSlice(ip.convertToShortProcessor(false));
break;
case FLOAT:
stack.addSlice(ip);
default:
break;
}
}
return new ImagePlus("", stack);
}
@Override
public String getName() {
return "ImageJ";
}
@Override
public boolean isSelectable() {
return true;
}
@Override
public String getSelectedImage() {
Dialog dialog = new Dialog();
dialog.setVisible(true);
if (dialog.wasCancel())
return "";
return dialog.getName();
}
public class Dialog extends JDialog implements ActionListener, WindowListener {
private JList<String> list;
private JButton bnOK = new JButton("OK");
private JButton bnCancel = new JButton("Cancel");
private boolean cancel = false;
private String name = "";
public Dialog() {
super(new JFrame(), "Image Selection");
JPanel bn = new JPanel(new GridLayout(1, 2));
bn.add(bnCancel);
bn.add(bnOK);
JPanel panel = new JPanel(new BorderLayout());
int[] ids = WindowManager.getIDList();
if (ids != null) {
DefaultListModel listModel = new DefaultListModel();
list = new JList(listModel);
for (int id : ids) {
ImagePlus idp = WindowManager.getImage(id);
if (idp != null) {
((DefaultListModel) listModel).addElement(idp.getTitle());
}
}
list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
JScrollPane listScroller = new JScrollPane(list);
listScroller.setPreferredSize(new Dimension(250, 80));
panel.add(listScroller, BorderLayout.CENTER);
}
else {
panel.add(new JLabel("No open images."));
}
panel.add(bn, BorderLayout.SOUTH);
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
bnOK.addActionListener(this);
bnCancel.addActionListener(this);
add(panel);
pack();
addWindowListener(this);
GUI.center(this);
setModal(true);
}
@Override
public void actionPerformed(ActionEvent e) {
bnOK.removeActionListener(this);
bnCancel.removeActionListener(this);
if (e.getSource() == bnCancel) {
cancel = true;
name = "";
dispose();
return;
}
else if (e.getSource() == bnOK) {
cancel = false;
name = (String) list.getSelectedValue();
dispose();
}
}
public String getName() {
return name;
}
public boolean wasCancel() {
return cancel;
}
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
dispose();
cancel = true;
name = "";
return;
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
}
}

Event Timeline