Page MenuHomec4science

No OneTemporary

File Metadata

Created
Tue, May 7, 10:55
diff --git a/DeconvolutionLab2/DeconvolutionLab2.config b/DeconvolutionLab2/DeconvolutionLab2.config
index e5da39c..47445e8 100644
--- a/DeconvolutionLab2/DeconvolutionLab2.config
+++ b/DeconvolutionLab2/DeconvolutionLab2.config
@@ -1,93 +1,101 @@
#DeconvolutionLab2
#DeconvolutionLab2
-#Fri Apr 21 22:58:03 CEST 2017
+#Mon Apr 24 13:08:32 CEST 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.4642
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=Non-Negative Least-Square
+Algorithm.algorithm=Landweber
Border.apoxy=Uniform
Border.apoz=Uniform
Border.extxy=0
Border.extz=0
Border.padxy=None
Border.padz=None
Computation.display=yes
Computation.epsilon=1E-6
Computation.fft=Fastest
Computation.multithreading=yes
Computation.normalization=1
Computation.system=no
Controller.constraint=no
Controller.monitor=console table
Controller.reference.enable=true
Controller.reference.value=/Users/dsage/Desktop/Screen Shot 2017-04-12 at 22.56.07.png
Controller.residu.enable=false
Controller.residu.value=0.01
-Controller.stats=show + save
+Controller.stats=no
Controller.time.enable=false
Controller.time.value=1
Controller.verbose=log
-DeconvolutionLab.MainDialog.location.h=841
-DeconvolutionLab.MainDialog.location.w=500
-DeconvolutionLab.MainDialog.location.x=896
-DeconvolutionLab.MainDialog.location.y=49
-Image.image.row0=workspace;directory;/Users/dsage/Desktop/workspace;\u232B
-Image.image.row10=Screen Shot 2017-04-12 at 22.56.07.png;file;/Users/dsage/Desktop/Screen Shot 2017-04-12 at 22.56.07.png;null
-Image.image.row11=RandomLines;synthetic;RandomLines 100.0 size 128 128 32 intensity 255.0 ;\u232B
-Image.image.row12=active;platform;active;\u232B
-Image.image.row13=Cube;synthetic;Cube 100.0 0.0 10.0 1.0 size 128 128 32 ;\u232B
-Image.image.row14=Applications;directory;/users/dsage/Applications;\u232B
+DeconvolutionLab.DeconvolutionDialog.location.h=400
+DeconvolutionLab.DeconvolutionDialog.location.w=600
+DeconvolutionLab.DeconvolutionDialog.location.x=0
+DeconvolutionLab.DeconvolutionDialog.location.y=23
+DeconvolutionLab.MainDialog.location.h=774
+DeconvolutionLab.MainDialog.location.w=507
+DeconvolutionLab.MainDialog.location.x=1248
+DeconvolutionLab.MainDialog.location.y=41
+FFT.epsilon=1E-6
+FFT.fft=Academic
+Image.image.row0=Cube;synthetic;Cube 50.0 1.0 size 300 128 300 intensity 255.0 ;\u232B
+Image.image.row10=20170302_AIDE-MEMOIRE.pdf;file;/Users/dsage/Desktop/20170302_AIDE-MEMOIRE.pdf;null
+Image.image.row11=Screen Shot 2017-04-12 at 22.56.07.png;file;/Users/dsage/Desktop/Screen Shot 2017-04-12 at 22.56.07.png;null
+Image.image.row12=Screen Shot 2017-04-12 at 22.56.07.png;file;/Users/dsage/Desktop/Screen Shot 2017-04-12 at 22.56.07.png;null
+Image.image.row13=RandomLines;synthetic;RandomLines 100.0 size 128 128 32 intensity 255.0 ;\u232B
+Image.image.row14=active;platform;active;\u232B
Image.image.row15=Cube;synthetic;Cube 100.0 0.0 10.0 1.0 size 128 128 32 ;\u232B
-Image.image.row16=lib;directory;/Users/dsage/git/deconvolution/DeconvolutionLab2/lib;\u232B
-Image.image.row1=CubeSphericalBeads;synthetic;CubeSphericalBeads 3.0 0.5 10.0 5.0 size 128 128 128 intensity 255.0 ;\u232B
-Image.image.row2=CubeSphericalBeads;synthetic;CubeSphericalBeads 3.0 0.5 8.0 16.0 size 128 128 32 intensity 255.0 ;\u232B
-Image.image.row3=Cube of Spherical Beads;synthetic;Cube of Spherical Beads 3.0 0.5 8.0 8.0 size 128 128 128 intensity 255.0 ;\u232B
-Image.image.row4=Screen Shot 2017-04-12 at 22.56.07.png;file;/Users/dsage/Desktop/Screen Shot 2017-04-12 at 22.56.07.png;null
-Image.image.row5=20170302_AIDE-MEMOIRE.pdf;file;/Users/dsage/Desktop/20170302_AIDE-MEMOIRE.pdf;null
+Image.image.row16=Applications;directory;/users/dsage/Applications;\u232B
+Image.image.row17=Cube;synthetic;Cube 100.0 0.0 10.0 1.0 size 128 128 32 ;\u232B
+Image.image.row18=lib;directory;/Users/dsage/git/deconvolution/DeconvolutionLab2/lib;\u232B
+Image.image.row1=Cube;synthetic;Cube 10.0 1.0 size 300 128 32 intensity 255.0 ;\u232B
+Image.image.row2=workspace;directory;/Users/dsage/Desktop/workspace;\u232B
+Image.image.row3=CubeSphericalBeads;synthetic;CubeSphericalBeads 3.0 0.5 10.0 5.0 size 128 128 128 intensity 255.0 ;\u232B
+Image.image.row4=CubeSphericalBeads;synthetic;CubeSphericalBeads 3.0 0.5 8.0 16.0 size 128 128 32 intensity 255.0 ;\u232B
+Image.image.row5=Cube of Spherical Beads;synthetic;Cube of Spherical Beads 3.0 0.5 8.0 8.0 size 128 128 128 intensity 255.0 ;\u232B
Image.image.row6=Screen Shot 2017-04-12 at 22.56.07.png;file;/Users/dsage/Desktop/Screen Shot 2017-04-12 at 22.56.07.png;null
-Image.image.row7=Screen Shot 2017-04-12 at 22.56.07.png;file;/Users/dsage/Desktop/Screen Shot 2017-04-12 at 22.56.07.png;null
-Image.image.row8=20170302_AIDE-MEMOIRE.pdf;file;/Users/dsage/Desktop/20170302_AIDE-MEMOIRE.pdf;null
+Image.image.row7=20170302_AIDE-MEMOIRE.pdf;file;/Users/dsage/Desktop/20170302_AIDE-MEMOIRE.pdf;null
+Image.image.row8=Screen Shot 2017-04-12 at 22.56.07.png;file;/Users/dsage/Desktop/Screen Shot 2017-04-12 at 22.56.07.png;null
Image.image.row9=Screen Shot 2017-04-12 at 22.56.07.png;file;/Users/dsage/Desktop/Screen Shot 2017-04-12 at 22.56.07.png;null
-Image.image.selected=RandomLines;synthetic;RandomLines 100.0 size 128 128 32 intensity 255.0 ;\u232B
+Image.image.selected=Cube;synthetic;Cube 50.0 1.0 size 300 128 300 intensity 255.0 ;\u232B
Language.headless=Run (Headless)
Language.job=Job
Language.language=Java
Output.output.row0=mip;MI1;rescaled;;;\u2713;\u2713;\u232B
Output.output.selected=mip;MI1;rescaled;;;\u2713;\u2713;\u232B
PSF.psf.row0=Double-Helix;synthetic;Double-Helix 3.0 30.0 10.0 size 128 128 32 intensity 255.0 ;null
PSF.psf.row1=Sinc;synthetic;Sinc 3.0 3.0 3.0 size 100 128 200 intensity 255.0 ;null
PSF.psf.selected=Double-Helix;synthetic;Double-Helix 3.0 30.0 10.0 size 128 128 32 intensity 255.0 ;null
Path.current=Current
-Path.path=/Users/dsage/git/deconvolution/DeconvolutionLab2
+Path.path=/Users/sage/Desktop/worksmlm/deconvolution/DeconvolutionLab2
Running.Directory=/Users/dsage/git/deconvolution/DeconvolutionLab2
Running.Monitor=table
Running.Path=specify
Running.Verbose=quiet
diff --git a/DeconvolutionLab2/src/deconvolution/Command.java b/DeconvolutionLab2/src/deconvolution/Command.java
index 3852952..fffa8c0 100644
--- a/DeconvolutionLab2/src/deconvolution/Command.java
+++ b/DeconvolutionLab2/src/deconvolution/Command.java
@@ -1,424 +1,424 @@
/*
* 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.util.ArrayList;
import java.util.Collections;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import bilib.tools.NumFormat;
import deconvolution.algorithm.AbstractAlgorithm;
import deconvolution.algorithm.Algorithm;
import deconvolution.algorithm.Controller;
import deconvolutionlab.Constants;
import deconvolutionlab.module.AbstractModule;
import deconvolutionlab.module.CommandModule;
import deconvolutionlab.monitor.ConsoleMonitor;
import deconvolutionlab.monitor.Monitors;
import deconvolutionlab.monitor.TableMonitor;
import deconvolutionlab.monitor.Verbose;
import deconvolutionlab.output.Output;
import deconvolutionlab.output.Output.View;
import fft.FFT;
import signal.Constraint;
import signal.Operations;
import signal.apodization.AbstractApodization;
import signal.apodization.Apodization;
import signal.apodization.UniformApodization;
import signal.padding.AbstractPadding;
import signal.padding.NoPadding;
import signal.padding.Padding;
import wavelets.Wavelets;
public class Command {
public static String keywords[] = { "-image", "-psf", "-algorithm", "-path", "-disable", "-verbose", "-monitor", "-display", "-multithreading", "-system", "-stats", "-constraint", "-time", "-residu", "-reference", "-out", "-pad", "-apo", "-norm", "-fft", "-epsilon" };
private static AbstractModule modules[];
private static CommandModule command;
public static void active(AbstractModule[] m, CommandModule c) {
modules = m;
command = c;
}
public static String command() {
if (modules == null)
return "";
String cmd = "";
for (AbstractModule m : modules)
cmd += m.getCommand() + " ";
if (command != null)
command.setCommand(cmd);
return cmd;
}
public static Controller decodeController(String command) {
Controller controller = new Controller();
ArrayList<Token> tokens = parse(command);
for (Token token : tokens) {
if (token.keyword.equalsIgnoreCase("-path") && !token.parameters.equalsIgnoreCase("current"))
controller.setPath(token.parameters);
if (token.keyword.equalsIgnoreCase("-monitor"))
controller.setMonitors(decodeMonitors(token.parameters));
if (token.keyword.equalsIgnoreCase("-verbose"))
controller.setVerbose(Verbose.getByName(token.parameters));
if (token.keyword.equalsIgnoreCase("-system"))
controller.setSystem(decodeBoolean(token.parameters));
if (token.keyword.equalsIgnoreCase("-multithreading"))
controller.setMultithreading(decodeBoolean(token.parameters));
if (token.keyword.equalsIgnoreCase("-display"))
controller.setDisplayFinal(decodeBoolean(token.parameters));
if (token.keyword.equalsIgnoreCase("-stats"))
controller.setStats(decodeStats(token));
if (token.keyword.equalsIgnoreCase("-constraint"))
controller.setConstraint(decodeConstraint(token));
if (token.keyword.equalsIgnoreCase("-time"))
controller.setTimeLimit(decodeTimeLimit(token));
if (token.keyword.equalsIgnoreCase("-residu"))
controller.setResiduMin(decodeResidu(token));
if (token.keyword.equalsIgnoreCase("-reference"))
controller.setReference(token.parameters);
if (token.keyword.equalsIgnoreCase("-pad"))
controller.setPadding(decodePadding(token));
if (token.keyword.equalsIgnoreCase("-apo"))
controller.setApodization(decodeApodization(token));
if (token.keyword.equalsIgnoreCase("-norm"))
controller.setNormalizationPSF(decodeNormalization(token));
if (token.keyword.equalsIgnoreCase("-epsilon"))
Operations.epsilon = NumFormat.parseNumber(token.parameters, 1e-6);
if (token.keyword.equalsIgnoreCase("-fft"))
controller.setFFT(FFT.getLibraryByName(token.parameters).getDefaultFFT());
if (token.keyword.equalsIgnoreCase("-epsilon"))
Operations.epsilon = NumFormat.parseNumber(token.parameters, 1e-6);
if (token.keyword.equals("-out")) {
Output out = decodeOut(token);
if (out != null)
controller.addOutput(out);
}
}
return controller;
}
public static AbstractAlgorithm decodeAlgorithm(String command) {
AbstractAlgorithm algo = Algorithm.getDefaultAlgorithm();
ArrayList<Token> tokens = parse(command);
for (Token token : tokens) {
if (token.keyword.equalsIgnoreCase("-algorithm"))
algo = Command.decodeAlgorithm(token);
}
return algo;
}
/**
* This methods first segments the command line, then create all the tokens
* of the command line
*
* @param command
* Command line
* @return the list of tokens extracted from the command line
*/
public static ArrayList<Token> parse(String command) {
ArrayList<CommandSegment> segments = new ArrayList<CommandSegment>();
for (String keyword : keywords)
segments.addAll(findSegment(command, keyword));
Collections.sort(segments);
ArrayList<Token> tokens = new ArrayList<Token>();
for (int i = 0; i < segments.size(); i++) {
String keyword = segments.get(i).keyword;
int begin = segments.get(i).index + keyword.length() + 1;
int end = (i < segments.size() - 1 ? segments.get(i + 1).index : command.length());
Token token = new Token(keyword, command, begin, end);
tokens.add(token);
}
return tokens;
}
public static Token extract(String command, String keyword) {
ArrayList<Token> tokens = parse(command);
for (Token token : tokens)
if (token.keyword.equalsIgnoreCase(keyword))
return token;
return (Token) null;
}
public static double[] parseNumeric(String line) {
ArrayList<String> num = new ArrayList<String>();
Pattern p = Pattern.compile("[-+]?[0-9]+[.]?[0-9]*([eE][-+]?[0-9]+)?");
Matcher m = p.matcher(line);
while (m.find()) {
num.add(m.group());
}
double number[] = new double[num.size()];
for (int i = 0; i < num.size(); i++)
number[i] = Double.parseDouble(num.get(i));
return number;
}
public static ArrayList<CommandSegment> findSegment(String command, String keyword) {
ArrayList<CommandSegment> segments = new ArrayList<CommandSegment>();
String regex = "(?<!\\w)" + keyword + "(?!\\w)";
if (command == null)
return segments;
Matcher matcher = Pattern.compile(regex).matcher(command);
while (matcher.find()) {
segments.add(new CommandSegment(keyword, matcher.start()));
}
return segments;
}
public static String extractOptions(String command) {
ArrayList<CommandSegment> segments = new ArrayList<CommandSegment>();
for (String keyword : keywords)
segments.addAll(findSegment(command, keyword));
Collections.sort(segments);
String options = "";
for (int i = 0; i < segments.size(); i++) {
String keyword = segments.get(i).keyword;
int begin = segments.get(i).index + keyword.length() + 1;
int end = (i < segments.size() - 1 ? segments.get(i + 1).index : command.length());
if (keyword != "-image" && keyword != "-psf" && keyword != "-algorithm")
options += keyword + " " + command.substring(begin, end);
}
return options;
}
public static AbstractAlgorithm decodeAlgorithm(Token token) {
String option = token.option;
AbstractAlgorithm algo = Algorithm.createAlgorithm(option);
double params[] = parseNumeric(token.parameters);
if (params != null) {
algo.setParameters(params);
}
if (algo.isWaveletsBased()) {
for (String wavelet : Wavelets.getWaveletsAsArray()) {
int pos = token.parameters.toLowerCase().indexOf(wavelet.toLowerCase());
if (pos >= 0)
algo.setWavelets(wavelet);
}
}
return algo;
}
public static Output decodeOut(Token token) {
int freq = 0;
String line = token.parameters;
String parts[] = token.parameters.split(" ");
for (int i = 0; i < Math.min(2, parts.length); i++) {
if (parts[i].startsWith("@"))
freq = (int) NumFormat.parseNumber(parts[i], 0);
}
String p = token.parameters.toLowerCase();
Output out = null;
if (p.startsWith("stack"))
out = new Output(View.STACK, freq, line.substring("stack".length(), line.length()));
if (p.startsWith("series"))
out = new Output(View.SERIES, freq, line.substring("series".length(), line.length()));
if (p.startsWith("mip"))
out = new Output(View.MIP, freq, line.substring("mip".length(), line.length()));
if (p.startsWith("ortho"))
out = new Output(View.ORTHO, freq, line.substring("ortho".length(), line.length()));
if (p.startsWith("figure"))
out = new Output(View.FIGURE, freq, line.substring("figure".length(), line.length()));
if (p.startsWith("planar"))
out = new Output(View.PLANAR, freq, line.substring("planar".length(), line.length()));
return out;
}
public static double decodeNormalization(Token token) {
if (token.parameters.toLowerCase().endsWith("no"))
return 0;
else
return NumFormat.parseNumber(token.parameters, 1);
}
public static Stats decodeStats(Token token) {
String parts[] = token.parameters.toLowerCase().split(" ");
int m = 0;
for (String p : parts) {
if (p.startsWith("no") || p.equals("false") || p.equals("0"))
return new Stats(Stats.Mode.NO);
if (p.equals("1"))
return new Stats(Stats.Mode.SHOW);
if (p.equals("2"))
return new Stats(Stats.Mode.SAVE);
if (p.equals("3"))
return new Stats(Stats.Mode.SHOWSAVE);
if (p.equals("show"))
m += 1;
if (p.equals("save"))
m += 2;
}
if (m==1)
return new Stats(Stats.Mode.SHOW);
if (m==2)
return new Stats(Stats.Mode.SAVE);
if (m==3)
return new Stats(Stats.Mode.SHOWSAVE);
return new Stats(Stats.Mode.NO);
}
public static Constraint.Mode decodeConstraint(Token token) {
String p = token.parameters.toLowerCase();
if (p.startsWith("non"))
return Constraint.Mode.NONNEGATIVE;
if (p.startsWith("no"))
return Constraint.Mode.NO;
if (p.startsWith("clip"))
return Constraint.Mode.CLIPPED;
if (p.equals("0"))
return Constraint.Mode.NO;
return Constraint.Mode.NO;
}
public static double decodeResidu(Token token) {
if (token.parameters.toLowerCase().endsWith("no"))
return -1;
else
return NumFormat.parseNumber(token.parameters, 1);
}
public static double decodeTimeLimit(Token token) {
if (token.parameters.toLowerCase().endsWith("no"))
return -1;
else
return NumFormat.parseNumber(token.parameters, 1);
}
public static Padding decodePadding(Token token) {
AbstractPadding padXY = new NoPadding();
AbstractPadding padZ = new NoPadding();
String param = token.parameters.trim();
String[] parts = param.split(" ");
if (parts.length > 0)
padXY = Padding.getByShortname(parts[0].trim());
if (parts.length > 1)
padZ = Padding.getByShortname(parts[1].trim());
double[] ext = NumFormat.parseNumbers(param);
int extXY = 0;
if (ext.length > 0)
extXY = (int) Math.round(ext[0]);
int extZ = 0;
if (ext.length > 1)
extZ = (int) Math.round(ext[1]);
return new Padding(padXY, padXY, padZ, extXY, extXY, extZ);
}
public static Apodization decodeApodization(Token token) {
AbstractApodization apoXY = new UniformApodization();
AbstractApodization apoZ = new UniformApodization();
String[] parts = token.parameters.trim().split(" ");
if (parts.length >= 1)
apoXY = Apodization.getByShortname(parts[0].trim());
if (parts.length >= 2)
apoZ = Apodization.getByShortname(parts[1].trim());
return new Apodization(apoXY, apoXY, apoZ);
}
public static String getPath() {
command();
ArrayList<Token> tokens = parse(command.getCommand());
String path = System.getProperty("user.dir");
for (Token token : tokens)
if (token.keyword.equalsIgnoreCase("-path") && !token.parameters.equalsIgnoreCase("current"))
path = token.parameters;
return path;
}
public static Monitors decodeMonitors(String cmd) {
String parts[] = cmd.toLowerCase().split(" ");
Monitors monitors = new Monitors();
for (String p : parts) {
if (p.equals("0") || p.startsWith("no"))
monitors.clear();
if (p.equals("1") || p.startsWith("console"))
monitors.add(new ConsoleMonitor());
if (p.equals("2"))
- monitors.add(new TableMonitor("Monitor", Constants.widthGUI, 240));
+ monitors.add(new TableMonitor(Constants.widthGUI, 240));
if (p.equals("3")) {
monitors.add(new ConsoleMonitor());
- monitors.add(new TableMonitor("Monitor", Constants.widthGUI, 240));
+ monitors.add(new TableMonitor(Constants.widthGUI, 240));
}
if (p.equals("console"))
monitors.add(new ConsoleMonitor());
if (p.equals("table"))
- monitors.add(new TableMonitor("Monitor", Constants.widthGUI, 240));
+ monitors.add(new TableMonitor(Constants.widthGUI, 240));
}
return monitors;
}
public static boolean decodeBoolean(String cmd) {
String p = cmd.toLowerCase();
if (p.startsWith("no"))
return false;
if (p.equals("0"))
return false;
if (p.equals("false"))
return false;
if (p.startsWith("dis"))
return false;
return true;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/Deconvolution.java b/DeconvolutionLab2/src/deconvolution/Deconvolution.java
index d58bea4..5358ec9 100644
--- a/DeconvolutionLab2/src/deconvolution/Deconvolution.java
+++ b/DeconvolutionLab2/src/deconvolution/Deconvolution.java
@@ -1,398 +1,406 @@
/*
* 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 com.esotericsoftware.minlog.Log;
+
import bilib.tools.NumFormat;
import deconvolution.algorithm.AbstractAlgorithm;
import deconvolution.algorithm.Controller;
import deconvolutionlab.Lab;
import deconvolutionlab.monitor.AbstractMonitor;
import deconvolutionlab.monitor.Monitors;
import deconvolutionlab.monitor.StatusMonitor;
import deconvolutionlab.monitor.TableMonitor;
import deconvolutionlab.output.Output;
import signal.RealSignal;
import signal.SignalCollector;
/**
* This class is the main class to run deconvolution with or without user interface.
*
* All the parameters are given in the command line (String variable command).
*
* @author Daniel Sage
*
*/
public class Deconvolution implements Runnable {
public enum Finish {
DIE, ALIVE, KILL
};
private AbstractAlgorithm algo = null;
private Controller controller = new Controller();
private String command = "";
private Features report = new Features();
private String name = "";
public RealSignal image;
public RealSignal psf;
private RealSignal deconvolvedImage;
private Finish finish = Finish.DIE;
private DeconvolutionDialog dialog;
private boolean embeddedStats = false;
public Deconvolution(String name, String command) {
this.name = name;
this.finish = Finish.DIE;
setCommand(command);
}
public Deconvolution(String name, String command, Finish finish) {
this.name = name;
this.finish = finish;
setCommand(command);
}
public void setCommand(String command) {
this.command = command;
controller = Command.decodeController(command);
algo = Command.decodeAlgorithm(command);
algo.setController(controller);
this.command = command;
if (name.equals("") && algo != null)
name = algo.getShortnames()[0];
}
public RealSignal deconvolve() {
return deconvolve(image, psf);
}
public RealSignal deconvolve(RealSignal image, RealSignal psf) {
this.image = image;
this.psf = psf;
for(AbstractMonitor monitor : controller.getMonitors())
if (monitor instanceof TableMonitor)
Lab.setVisible(((TableMonitor)monitor).getPanel(), "Monitor of " + name, 10, 10);
if (controller.getFFT() == null) {
run();
return deconvolvedImage;
}
if (!controller.getFFT().isMultithreadable()) {
run();
return deconvolvedImage;
}
if (controller.isMultithreading()) {
Thread thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}
else {
run();
}
return deconvolvedImage;
}
/**
* This method runs the deconvolution with a graphical user interface.
*/
public void launch() {
embeddedStats = true;
dialog = new DeconvolutionDialog(DeconvolutionDialog.Module.ALL, this);
- controller.getMonitors().add(new StatusMonitor(dialog.getProgressBar()));
-
Lab.setVisible(dialog, false);
}
@Override
public void run() {
double chrono = System.nanoTime();
Monitors monitors = controller.getMonitors();
report.add("Path", controller.toStringPath());
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());
if (algo == null) {
monitors.error("Algorithm: not valid");
if (finish == Finish.KILL)
System.exit(-103);
return;
}
report.add("FFT", controller.getFFT().getName());
report.add("Algorithm", algo.getName());
if (embeddedStats) {
TableMonitor tableMonitor = null;
for(AbstractMonitor monitor : controller.getMonitors())
if (monitor instanceof TableMonitor)
tableMonitor = (TableMonitor)monitor;
if (controller.getStats().getMode() == Stats.Mode.SHOW || controller.getStats().getMode() == Stats.Mode.SHOWSAVE) {
controller.getStats().setEmbeddedInFrame(embeddedStats);
dialog.addStats(controller.getStats());
}
if (tableMonitor != null) {
dialog.addMonitor(tableMonitor);
}
}
algo.setController(controller);
deconvolvedImage = algo.run(image, psf);
report.add("End", NumFormat.time(System.nanoTime() - chrono));
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;
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);
double norm = controller.getNormalizationPSF();
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", controller.getPadding().toString());
features.add("Apodization", controller.getApodization().toString());
features.add("FFT", controller.getFFT() == null ? "null" : controller.getFFT().getName());
}
features.add("Path", controller.getPath());
- features.add("Monitor", controller.toStringMonitor());
+ String s = "[" + controller.getVerbose().name() + "] ";
+ for(AbstractMonitor monitor : controller.getMonitors())
+ s+= monitor.getName() + " ";
+ features.add("Monitor", s);
if (controller.getStats() != null)
features.add("Stats", controller.getStats().toStringStats());
features.add("Running", controller.toStringRunning());
for (Output out : controller.getOuts())
features.add("Output " + out.getName(), out.toString());
+
+ Log.info("Recap deconvolution parameters");
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 void abort() {
algo.getController().abort();
}
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 = createRealSignal(controller.getMonitors(), arg, cmd, controller.getPath());
+ Log.info("Open image " + arg + " " + cmd);
+
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 = createRealSignal(controller.getMonitors(), arg, cmd, controller.getPath());
+ Log.info("Open PSF " + arg + " " + cmd);
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 setAlgorithm(AbstractAlgorithm algo) {
this.algo = algo;
}
public AbstractAlgorithm getAlgorithm() {
return algo;
}
public void setController(Controller controller) {
this.controller = controller;
}
public Controller getController() {
return controller;
}
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 Monitors getMonitors() {
return controller.getMonitors();
}
public String getCommand() {
return command;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/DeconvolutionDialog.java b/DeconvolutionLab2/src/deconvolution/DeconvolutionDialog.java
index b848d0e..e48c73d 100644
--- a/DeconvolutionLab2/src/deconvolution/DeconvolutionDialog.java
+++ b/DeconvolutionLab2/src/deconvolution/DeconvolutionDialog.java
@@ -1,374 +1,386 @@
/*
* 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.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Rectangle;
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.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JToolBar;
import bilib.component.BorderToggledButton;
import bilib.component.PanelImage;
import deconvolution.capsule.AlgorithmCapsule;
import deconvolution.capsule.ImageCapsule;
import deconvolution.capsule.PSFCapsule;
import deconvolution.capsule.RecapCapsule;
import deconvolution.capsule.ReportCapsule;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
import deconvolutionlab.Lab;
+import deconvolutionlab.monitor.AbstractMonitor;
+import deconvolutionlab.monitor.Monitors;
import deconvolutionlab.monitor.StatusMonitor;
import deconvolutionlab.monitor.TableMonitor;
public class DeconvolutionDialog extends JDialog implements WindowListener, ActionListener, Runnable {
public enum State {
NOTDEFINED, READY, RUN, FINISH
};
public enum Module {
ALL, RECAP, IMAGE, PSF, ALGO, RUN
};
private JButton bnStart = new JButton("Run");
private JButton bnStop = new JButton("Stop");
private JButton bnReset = new JButton("Reset");
private JButton bnHelp = new JButton("Help");
private JButton bnQuit = new JButton("Quit");
private BorderToggledButton bnRecap = new BorderToggledButton("Recap");
private BorderToggledButton bnImage = new BorderToggledButton("Image");
private BorderToggledButton bnPSF = new BorderToggledButton("PSF");
private BorderToggledButton bnAlgo = new BorderToggledButton("Algorithm");
private BorderToggledButton bnReport = new BorderToggledButton("Report");
private BorderToggledButton bnMonitor = new BorderToggledButton("Monitor");
private BorderToggledButton bnStats = new BorderToggledButton("Stats");
JToolBar tool = new JToolBar();
private Thread thread = null;
private Deconvolution deconvolution;
private JProgressBar progress = new JProgressBar();
public static Point location = new Point(0, 0);
private JPanel cards = new JPanel(new CardLayout());
private boolean flagMonitor = false;
private boolean flagStats = false;
private ImageCapsule image;
private PSFCapsule psf;
private RecapCapsule recap;
private AlgorithmCapsule algorithm;
private ReportCapsule report;
public DeconvolutionDialog(Module module, Deconvolution deconvolution) {
super(new JFrame(), deconvolution.getName());
this.deconvolution = deconvolution;
image = new ImageCapsule(deconvolution);
psf = new PSFCapsule(deconvolution);
recap = new RecapCapsule(deconvolution);
algorithm = new AlgorithmCapsule(deconvolution);
report = new ReportCapsule(deconvolution);
// Panel status bar on bottom
progress.setAlignmentX(JLabel.CENTER_ALIGNMENT);
progress.setBorder(BorderFactory.createLoweredBevelBorder());
JToolBar statusBar = new JToolBar();
statusBar.setBorder(BorderFactory.createLoweredBevelBorder());
statusBar.setFloatable(false);
statusBar.setLayout(new BorderLayout());
statusBar.add(bnHelp, BorderLayout.WEST);
statusBar.add(progress, BorderLayout.CENTER);
statusBar.add(bnQuit, BorderLayout.EAST);
// Panel bottom
JPanel bottom = new JPanel();
bottom.setLayout(new BoxLayout(bottom, BoxLayout.PAGE_AXIS));
// Panel buttons
if (module == Module.ALL) {
PanelImage buttons = new PanelImage("celegans.jpg");
buttons.setLayout(new FlowLayout());
buttons.setBorder(BorderFactory.createEtchedBorder());
buttons.add(bnReset);
buttons.add(bnStop);
buttons.add(bnStart);
bottom.add(buttons);
}
bottom.add(statusBar);
// Panel Image
cards.add(recap.getName(), recap.getPane());
cards.add(image.getName(), image.getPane());
cards.add(psf.getName(), psf.getPane());
cards.add(algorithm.getName(), algorithm.getPane());
cards.add(report.getName(), report.getPane());
// Panel Main
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(cards, BorderLayout.CENTER);
panel.add(bottom, BorderLayout.SOUTH);
// Panel tool with all buttons
if (module == Module.ALL) {
tool.setFloatable(false);
tool.setLayout(new GridLayout(1, 6));
tool.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
tool.add(bnRecap);
tool.add(bnImage);
tool.add(bnPSF);
tool.add(bnAlgo);
tool.add(bnReport);
panel.add(tool, BorderLayout.NORTH);
}
add(panel);
bnReset.addActionListener(this);
bnQuit.addActionListener(this);
bnStart.addActionListener(this);
bnStop.addActionListener(this);
bnHelp.addActionListener(this);
bnImage.addActionListener(this);
bnPSF.addActionListener(this);
bnAlgo.addActionListener(this);
bnRecap.addActionListener(this);
bnReport.addActionListener(this);
this.addWindowListener(this);
setMinimumSize(new Dimension(Constants.widthGUI, 400));
setPreferredSize(new Dimension(Constants.widthGUI, 400));
pack();
Config.registerFrame("DeconvolutionLab", "DeconvolutionDialog", this);
Rectangle rect = Config.getDialog("DeconvolutionLab.DeconvolutionDialog");
if (rect.x > 0 && rect.y > 0)
setLocation(rect.x, rect.y);
bnStop.setEnabled(false);
if (module == Module.ALL) {
toggle(bnRecap);
recap.update();
}
if (module == Module.IMAGE) {
toggle(bnImage);
- deconvolution.getMonitors().add(new StatusMonitor(getProgressBar()));
- image.update();
+ image.update();
}
if (module == Module.PSF) {
toggle(bnPSF);
- deconvolution.getMonitors().add(new StatusMonitor(getProgressBar()));
psf.update();
}
if (module == Module.ALGO) {
toggle(bnAlgo);
- deconvolution.getMonitors().add(new StatusMonitor(getProgressBar()));
algorithm.update();
}
if (module == Module.RECAP) {
toggle(bnRecap);
recap.update();
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == bnStart) {
if (flagMonitor)
toggle(bnMonitor);
else if (flagStats)
toggle(bnStats);
if (thread == null) {
thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}
}
else if (e.getSource() == bnStop) {
toggle(bnReport);
if (deconvolution != null)
deconvolution.abort();
}
else if (e.getSource() == bnImage) {
toggle(bnImage);
image.update();
}
else if (e.getSource() == bnPSF) {
toggle(bnPSF);
psf.update();
}
else if (e.getSource() == bnAlgo) {
toggle(bnAlgo);
algorithm.update();
}
else if (e.getSource() == bnRecap) {
toggle(bnRecap);
recap.update();
}
else if (e.getSource() == bnReport) {
toggle(bnReport);
report.update();
}
else if (e.getSource() == bnReset) {
toggle(bnRecap);
bnStart.setEnabled(true);
}
else if (e.getSource() == bnQuit) {
deconvolution.close();
deconvolution = null;
dispose();
}
else if (e.getSource() == bnHelp)
Lab.help();
else if (e.getSource() == bnMonitor)
toggle(bnMonitor);
else if (e.getSource() == bnStats)
toggle(bnStats);
+
+ addProgress();
+
}
@Override
public void run() {
- bnRecap.setEnabled(false);
- bnImage.setEnabled(false);
- bnPSF.setEnabled(false);
- bnAlgo.setEnabled(false);
+ //bnRecap.setEnabled(false);
+ //bnImage.setEnabled(false);
+ //bnPSF.setEnabled(false);
+ //bnAlgo.setEnabled(false);
bnStart.setEnabled(false);
bnStop.setEnabled(true);
-
- deconvolution.setCommand(recap.getCommand());
+ deconvolution.setCommand(recap.getCommand());
+ addProgress();
deconvolution.run();
toggle(bnReport);
bnStop.setEnabled(false);
report.update();
- bnRecap.setEnabled(true);
- bnAlgo.setEnabled(true);
- bnPSF.setEnabled(true);
- bnImage.setEnabled(true);
+ //bnRecap.setEnabled(true);
+ //bnAlgo.setEnabled(true);
+ //bnPSF.setEnabled(true);
+ //bnImage.setEnabled(true);
thread = null;
}
+ private void addProgress() {
+ Monitors monitors = deconvolution.getController().getMonitors();
+ boolean found = false;
+ for(AbstractMonitor monitor : monitors) {
+ if (monitor instanceof StatusMonitor)
+ found = true;
+ }
+ if (!found) {
+ monitors.add(new StatusMonitor(progress));
+ deconvolution.getController().setMonitors(monitors);
+ }
+
+ }
public void addStats(Stats stats) {
if (stats != null) {
cards.add("Stats", stats.getPanel());
tool.add(bnStats);
pack();
bnStats.addActionListener(this);
}
}
public void addMonitor(TableMonitor tableMonitor) {
if (tableMonitor != null) {
cards.add("Monitor", tableMonitor.getPanel());
tool.add(bnMonitor);
pack();
bnMonitor.addActionListener(this);
}
}
public static void setLocationLaunch(Point l) {
location = l;
}
private void toggle(BorderToggledButton bn) {
((CardLayout) (cards.getLayout())).show(cards, bn.getText());
bnRecap.setSelected(false);
bnImage.setSelected(false);
bnPSF.setSelected(false);
bnAlgo.setSelected(false);
bnMonitor.setSelected(false);
bnStats.setSelected(false);
bnReport.setSelected(false);
bn.setSelected(true);
}
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
deconvolution.close();
deconvolution = null;
dispose();
}
@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) {
}
- public JProgressBar getProgressBar() {
- return progress;
- }
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java b/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java
index 7bb4a73..71c7659 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java
@@ -1,464 +1,474 @@
/*
* 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.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import signal.Constraint;
import signal.RealSignal;
import signal.SignalCollector;
import signal.apodization.Apodization;
import signal.padding.Padding;
import bilib.tools.NumFormat;
import deconvolution.DeconvolutionDialog;
import deconvolution.Stats;
import deconvolutionlab.Lab;
import deconvolutionlab.monitor.Monitors;
import deconvolutionlab.monitor.Verbose;
import deconvolutionlab.output.Output;
import deconvolutionlab.system.SystemInfo;
import fft.AbstractFFT;
import fft.FFT;
/**
* This class is the common part of every algorithm of deconvolution.
*
* @author Daniel Sage
*
*/
public abstract class AbstractAlgorithm implements Callable<RealSignal> {
/** y is the input signal of the deconvolution. */
protected RealSignal y;
/** h is the PSF signal for the deconvolution. */
protected RealSignal h;
protected boolean threaded;
/** Optimized implementation in term of memory footprint */
protected boolean optimizedMemoryFootprint;
protected int iterMax = 0;
protected AbstractFFT fft;
protected Controller controller;
public AbstractAlgorithm() {
setController(new Controller());
optimizedMemoryFootprint = true;
threaded = true;
fft = FFT.getFastestFFT().getDefaultFFT();
}
public AbstractAlgorithm(Controller controller) {
this.controller = controller;
optimizedMemoryFootprint = true;
threaded = true;
fft = FFT.getFastestFFT().getDefaultFFT();
}
public void setOptimizedMemoryFootprint(boolean optimizedMemoryFootprint) {
this.optimizedMemoryFootprint = optimizedMemoryFootprint;
}
public abstract String getName();
public abstract String[] getShortnames();
public abstract double getMemoryFootprintRatio();
public abstract int getComplexityNumberofFFT();
public abstract boolean isRegularized();
public abstract boolean isStepControllable();
public abstract boolean isIterative();
public abstract boolean isWaveletsBased();
public abstract void setParameters(double[] params);
public abstract double getRegularizationFactor();
public abstract double getStepFactor();
public abstract double[] getParameters();
+
public abstract double[] getDefaultParameters();
public RealSignal run(RealSignal image, RealSignal psf) {
+ String sn = getShortnames()[0];
if (controller.isSystem())
SystemInfo.activate();
Padding pad = controller.getPadding();
Apodization apo = controller.getApodization();
double norm = controller.getNormalizationPSF();
fft = controller.getFFT();
controller.setIterationsMax(iterMax);
if (image == null)
return null;
if (psf == null)
return null;
// Prepare the controller and the outputs
Monitors monitors = controller.getMonitors();
monitors.setVerbose(controller.getVerbose());
monitors.log("Path: " + controller.toStringPath());
monitors.log("Algorithm: " + getName());
// Prepare the signal and the PSF
y = pad.pad(monitors, image);
y.setName("y");
apo.apodize(monitors, y);
monitors.log("Input: " + y.dimAsString());
h = psf.changeSizeAs(y);
h.setName("h");
h.normalize(norm);
monitors.log("PSF: " + h.dimAsString() + " normalized " + (norm <= 0 ? "no" : norm));
String iterations = (isIterative() ? iterMax + " iterations" : "direct");
controller.setIterationsMax(iterMax);
monitors.log(getShortnames()[0] + " is starting (" + iterations + ")");
controller.setMonitors(monitors);
controller.start(y);
h.circular();
// FFT
fft.init(monitors, y.nx, y.ny, y.nz);
controller.setFFT(fft);
monitors.log(getShortnames()[0] + " data ready");
+ monitors.log(getShortnames()[0] + "" + getParametersToString());
- double params[] = getParameters();
- if (params != null) {
- if (params.length > 0) {
- String s = " ";
- for (double param : params)
- s += "" + param + " ";
- monitors.log(getShortnames()[0] + s);
- }
- }
RealSignal x = null;
try {
if (threaded == true) {
ExecutorService pool = Executors.newSingleThreadExecutor();
Future<RealSignal> future = pool.submit(this);
x = future.get();
}
else {
x = call();
}
}
catch (InterruptedException ex) {
ex.printStackTrace();
x = y.duplicate();
}
catch (ExecutionException ex) {
ex.printStackTrace();
x = y.duplicate();
}
catch (Exception e) {
e.printStackTrace();
x = y.duplicate();
}
SignalCollector.free(y);
SignalCollector.free(h);
x.setName("x");
RealSignal result = pad.crop(monitors, x);
controller.finish(result);
monitors.log(getName() + " is finished");
SignalCollector.free(x);
if (controller.isDisplayFinal())
- Lab.show(monitors, result, "Final Display of " + getShortnames()[0]);
+ Lab.show(monitors, result, "Final Display of " + sn);
+
+ result.setName("Output of " + sn);
+
+ monitors.log("End of " + sn + " in " + NumFormat.seconds(controller.getTimeNano()) + " and " + controller.getMemoryAsString());
- result.setName("Output of " + this.getShortnames()[0]);
return result;
}
public AbstractAlgorithm setController(Controller controller) {
this.controller = controller;
return this;
}
public Controller getController() {
return controller;
}
public int getIterationsMax() {
return iterMax;
}
public int getIterations() {
return controller.getIterations();
}
public double getTime() {
return controller.getTimeNano();
}
public double getMemory() {
return controller.getMemory();
}
public double getResidu() {
return controller.getResidu();
}
public double getSNR() {
return controller.getSNR();
}
public double getPSNR() {
return controller.getPSNR();
}
public void setWavelets(String waveletsName) {
}
@Override
public String toString() {
String s = "";
s += getName();
s += (isIterative() ? ", " + iterMax + " iterations" : " (direct)");
s += (isRegularized() ? ", &lambda=" + NumFormat.nice(getRegularizationFactor()) : "");
s += (isStepControllable() ? ", &gamma=" + NumFormat.nice(getStepFactor()) : "");
return s;
}
public String getParametersAsString() {
double p[] = getParameters();
String param = "";
for (int i = 0; i < p.length; i++)
if (i == p.length - 1)
param += p[i];
else
param += p[i] + ", ";
return param;
}
public AbstractFFT getFFT() {
return controller.getFFT();
}
public AbstractAlgorithm setFFT(AbstractFFT fft) {
this.fft = fft;
controller.setFFT(fft);
return this;
}
public String getPath() {
return controller.getPath();
}
public AbstractAlgorithm setPath(String path) {
controller.setPath(path);
return this;
}
public boolean isSystem() {
return controller.isSystem();
}
public AbstractAlgorithm enableSystem() {
controller.setSystem(true);
return this;
}
public AbstractAlgorithm disableSystem() {
controller.setSystem(false);
return this;
}
public boolean isMultithreading() {
return controller.isMultithreading();
}
public AbstractAlgorithm enableMultithreading() {
controller.setMultithreading(true);
return this;
}
public AbstractAlgorithm disableMultithreading() {
controller.setMultithreading(false);
return this;
}
public boolean isDisplayFinal() {
return controller.isDisplayFinal();
}
public AbstractAlgorithm enableDisplayFinal() {
controller.setDisplayFinal(true);
return this;
}
public AbstractAlgorithm disableDisplayFinal() {
controller.setDisplayFinal(false);
return this;
}
public double getNormalizationPSF() {
return controller.getNormalizationPSF();
}
public AbstractAlgorithm setNormalizationPSF(double normalizationPSF) {
controller.setNormalizationPSF(normalizationPSF);
return this;
}
public double getEpsilon() {
return controller.getEpsilon();
}
public AbstractAlgorithm setEpsilon(double epsilon) {
controller.setEpsilon(epsilon);
return this;
}
public Padding getPadding() {
return controller.getPadding();
}
public AbstractAlgorithm setPadding(Padding padding) {
controller.setPadding(padding);
return this;
}
public Apodization getApodization() {
return controller.getApodization();
}
public AbstractAlgorithm setApodization(Apodization apodization) {
controller.setApodization(apodization);
return this;
}
public Monitors getMonitors() {
return controller.getMonitors();
}
public AbstractAlgorithm setMonitors(Monitors monitors) {
controller.setMonitors(monitors);
return this;
}
public Verbose getVerbose() {
return controller.getVerbose();
}
public AbstractAlgorithm setVerbose(Verbose verbose) {
controller.setVerbose(verbose);
return this;
}
public Constraint.Mode getConstraint() {
return controller.getConstraint();
}
public AbstractAlgorithm setConstraint(Constraint.Mode constraint) {
controller.setConstraint(constraint);
return this;
}
public Stats getStats() {
return controller.getStats();
}
public AbstractAlgorithm setStats(Stats stats) {
controller.setStats(stats);
return this;
}
public AbstractAlgorithm showStats() {
controller.setStats(new Stats(Stats.Mode.SHOW));
return this;
}
public AbstractAlgorithm saveStats(Stats stats) {
controller.setStats(new Stats(Stats.Mode.SAVE));
return this;
}
public AbstractAlgorithm setStats() {
controller.setStats(new Stats(Stats.Mode.SHOWSAVE));
return this;
}
public double getResiduMin() {
return controller.getResiduMin();
}
public AbstractAlgorithm setResiduMin(double residuMin) {
controller.setResiduMin(residuMin);
return this;
}
public double getTimeLimit() {
return controller.getTimeLimit();
}
public AbstractAlgorithm setTimeLimit(double timeLimit) {
controller.setTimeLimit(timeLimit);
return this;
}
public String getReference() {
return controller.getReference();
}
public AbstractAlgorithm setReference(String reference) {
controller.setReference(reference);
return this;
}
public ArrayList<Output> getOuts() {
return controller.getOuts();
}
public AbstractAlgorithm setOuts(ArrayList<Output> outs) {
controller.setOuts(outs);
return this;
}
public AbstractAlgorithm addOutput(Output out) {
controller.addOutput(out);
return this;
}
+
+ public String getParametersToString() {
+ double params[] = getParameters();
+ if (params != null) {
+ if (params.length > 0) {
+ String s = " ";
+ for (double param : params)
+ s += NumFormat.nice(param) + " ";
+ return s;
+ }
+ }
+ return "parameter-free";
+ }
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java b/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java
index 0d467a9..3acf55b 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java
@@ -1,642 +1,642 @@
/*
* 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.io.File;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import signal.Assessment;
import signal.ComplexSignal;
import signal.Constraint;
import signal.RealSignal;
import signal.apodization.Apodization;
import signal.padding.Padding;
import bilib.tools.NumFormat;
import deconvolution.Deconvolution;
import deconvolution.Stats;
import deconvolutionlab.Constants;
import deconvolutionlab.monitor.AbstractMonitor;
import deconvolutionlab.monitor.ConsoleMonitor;
import deconvolutionlab.monitor.Monitors;
import deconvolutionlab.monitor.TableMonitor;
import deconvolutionlab.monitor.Verbose;
import deconvolutionlab.output.Output;
import deconvolutionlab.system.SystemUsage;
import fft.AbstractFFT;
import fft.FFT;
/**
* This is an important class to manage all the common task of the algorithm.
* The method start() is called before at the starting of the algorithm. The
* method ends() is called at the end of every iterations for the iterative
* algorithm. It returns true if one the stopping criteria is true. The method
* finish() is called when the algorithm is completely terminated.
*
* @author Daniel Sage
*
*/
public class Controller {
private String path;
private boolean system;
private boolean multithreading;
private boolean displayFinal;
private double normalizationPSF;
private double epsilon;
private Padding padding;
private Apodization apodization;
private ArrayList<Output> outs;
private Stats stats;
private Constraint.Mode constraintMode;
private double residuMin;
private double timeLimit;
private String reference;
private Monitors monitors;
private Verbose verbose;
private AbstractFFT fft;
private int iterationsMax = 100;
private boolean doResidu = false;
private boolean doTime = false;
private boolean doReference = false;
private boolean doConstraint = false;
private boolean abort = false;
private double timeStarting = 0;
private double memoryStarting = 0;
private double residu = Double.MAX_VALUE;
private int iterations = 0;
private double memoryPeak = 0;
private double snr = 0;
private double psnr = 0;
private RealSignal refImage;
private RealSignal prevImage;
private RealSignal x;
private Timer timer;
public Controller() {
doResidu = false;
doTime = false;
doReference = false;
doConstraint = false;
timeStarting = System.nanoTime();
setPath(System.getProperty("user.dir"));
setSystem(true);
setMultithreading(true);
setDisplayFinal(true);
setFFT(FFT.getFastestFFT().getDefaultFFT());
setNormalizationPSF(1);
setEpsilon(1e-6);
setPadding(new Padding());
setApodization(new Apodization());
monitors = new Monitors();
monitors.add(new ConsoleMonitor());
- monitors.add(new TableMonitor("Monitor", Constants.widthGUI, 240));
+ monitors.add(new TableMonitor(Constants.widthGUI, 240));
setVerbose(Verbose.Log);
setStats(new Stats(Stats.Mode.NO));
setConstraint(Constraint.Mode.NO);
setResiduMin(-1);
setTimeLimit(-1);
setReference("");
setOuts(new ArrayList<Output>());
}
public void setFFT(AbstractFFT fft) {
this.fft = fft;
}
public void abort() {
this.abort = true;
}
public void setIterationsMax(int iterationsMax) {
this.iterationsMax = iterationsMax;
}
public boolean needSpatialComputation() {
return doConstraint || doResidu || doReference;
}
/**
* Call one time at the beginning of the algorithms
*
* @param x
* the input signal
*/
public void start(RealSignal x) {
this.x = x;
stats.show();
stats.addInput(x);
iterations = 0;
timer = new Timer();
timer.schedule(new Updater(), 0, 100);
timeStarting = System.nanoTime();
memoryStarting = SystemUsage.getHeapUsed();
if (doConstraint && x != null)
Constraint.setModel(x);
if (doReference) {
refImage = new Deconvolution("Reference", "-image file " + reference).openImage();
if (refImage == null)
monitors.error("Impossible to load the reference image " + reference);
else
monitors.log("Reference image loaded");
}
for (Output out : outs)
out.executeStarting(monitors, x, this);
this.prevImage = x;
}
public boolean ends(ComplexSignal X) {
boolean out = false;
for (Output output : outs)
out = out | output.is(iterations);
if (doConstraint || doResidu || doReference || out) {
if (fft == null)
fft = FFT.createDefaultFFT(monitors, X.nx, X.ny, X.nz);
x = fft.inverse(X, x);
return ends(x);
}
return ends((RealSignal) null);
}
public boolean ends(RealSignal x) {
this.x = x;
if (doConstraint || doResidu || doReference)
compute(iterations, x, doConstraint, doResidu, doReference);
for (Output out : outs)
out.executeIterative(monitors, x, this, iterations);
iterations++;
double p = iterations * 100.0 / iterationsMax;
monitors.progress("Iterative " + iterations + "/" + iterationsMax, p);
double timeElapsed = getTimeSecond();
boolean stopIter = (iterations >= iterationsMax);
boolean stopTime = doTime && (timeElapsed >= timeLimit);
boolean stopResd = doResidu && (residu <= residuMin);
- monitors.log("@" + iterations + " Time: " + NumFormat.seconds(timeElapsed));
+ monitors.log("@" + iterations + " Time: " + NumFormat.seconds(timeElapsed*1e9));
addStats();
String prefix = "Stopped>> by ";
if (abort)
monitors.log(prefix + "abort");
if (stopIter)
monitors.log(prefix + "iteration " + iterations + " > " + iterationsMax);
if (stopTime)
monitors.log(prefix + "time " + timeElapsed + " > " + timeLimit);
if (stopResd)
monitors.log(prefix + "residu " + NumFormat.nice(residu) + " < " + NumFormat.nice(residuMin));
return abort | stopIter | stopTime | stopResd;
}
public void finish(RealSignal x) {
this.x = x;
boolean ref = doReference;
boolean con = doConstraint;
boolean res = doResidu;
if (con || res || ref)
compute(iterations, x, con, res, ref);
addStats();
stats.save(monitors, path);
for (Output out : outs)
out.executeFinal(monitors, x, this);
monitors.log("Time: " + NumFormat.seconds(getTimeNano()) + " Peak:" + getMemoryAsString());
if (timer != null)
timer.cancel();
}
private void compute(int iterations, RealSignal x, boolean con, boolean res, boolean ref) {
if (x == null)
return;
if (con && constraintMode != null)
new Constraint(monitors).apply(x, constraintMode);
if (ref && refImage != null) {
String s = "";
psnr = Assessment.psnr(x, refImage);
snr = Assessment.snr(x, refImage);
s += " PSNR: " + NumFormat.nice(psnr);
s += " SNR: " + NumFormat.nice(snr);
monitors.log("@" + iterations + " " + s);
}
residu = Double.MAX_VALUE;
if (res && prevImage != null) {
residu = Assessment.relativeResidu(x, prevImage);
prevImage = x.duplicate();
monitors.log("@" + iterations + " Residu: " + NumFormat.nice(residu));
}
}
private void addStats() {
String pnsrText = doReference ? NumFormat.nice(psnr) : "n/a";
String snrText = doReference ? NumFormat.nice(snr) : "n/a";
String residuText = doResidu ? NumFormat.nice(residu) : "n/a";
stats.add(x, iterations, NumFormat.seconds(getTimeNano()), pnsrText, snrText, residuText);
}
public double getTimeNano() {
return (System.nanoTime() - timeStarting);
}
public double getTimeSecond() {
return (System.nanoTime() - timeStarting) * 1e-9;
}
public String getConstraintAsString() {
if (!doConstraint)
return "no";
if (constraintMode == null)
return "null";
return constraintMode.name().toLowerCase();
}
public String getStoppingCriteriaAsString(AbstractAlgorithm algo) {
String stop = algo.isIterative() ? "iterations limit=" + algo.getIterationsMax() + ", " : "direct, ";
stop += doTime ? ", time limit=" + NumFormat.nice(timeLimit * 1e-9) : " no time limit" + ", ";
stop += doResidu ? ", residu limit=" + NumFormat.nice(residuMin) : " no residu limit";
return stop;
}
public double getMemory() {
return memoryPeak - memoryStarting;
}
public String getMemoryAsString() {
return NumFormat.bytes(getMemory());
}
public int getIterations() {
return iterations;
}
public double getSNR() {
return snr;
}
public double getPSNR() {
return psnr;
}
public double getResidu() {
return residu;
}
private void update() {
memoryPeak = Math.max(memoryPeak, SystemUsage.getHeapUsed());
}
public AbstractFFT getFFT() {
return fft;
}
/**
* @return the path
*/
public String getPath() {
return path;
}
/**
* @param path
* the path to set
*/
public void setPath(String path) {
this.path = path;
}
/**
* @return the system
*/
public boolean isSystem() {
return system;
}
/**
* @param system
* the system to set
*/
public void setSystem(boolean system) {
this.system = system;
}
/**
* @return the multithreading
*/
public boolean isMultithreading() {
return multithreading;
}
/**
* @param multithreading
* the multithreading to set
*/
public void setMultithreading(boolean multithreading) {
this.multithreading = multithreading;
}
/**
* @return the displayFinal
*/
public boolean isDisplayFinal() {
return displayFinal;
}
/**
* @param displayFinal
* the displayFinal to set
*/
public void setDisplayFinal(boolean displayFinal) {
this.displayFinal = displayFinal;
}
/**
* @return the normalizationPSF
*/
public double getNormalizationPSF() {
return normalizationPSF;
}
/**
* @param normalizationPSF
* the normalizationPSF to set
*/
public void setNormalizationPSF(double normalizationPSF) {
this.normalizationPSF = normalizationPSF;
}
/**
* @return the epsilon
*/
public double getEpsilon() {
return epsilon;
}
/**
* @param epsilon
* the epsilon to set
*/
public void setEpsilon(double epsilon) {
this.epsilon = epsilon;
}
/**
* @return the padding
*/
public Padding getPadding() {
return padding;
}
/**
* @param padding
* the padding to set
*/
public void setPadding(Padding padding) {
this.padding = padding;
}
/**
* @return the apodization
*/
public Apodization getApodization() {
return apodization;
}
/**
* @param apodization
* the apodization to set
*/
public void setApodization(Apodization apodization) {
this.apodization = apodization;
}
/**
* @return the monitors
*/
public Monitors getMonitors() {
return monitors;
}
/**
* @param monitors
* the monitors to set
*/
public void setMonitors(Monitors monitors) {
this.monitors = monitors;
}
/**
* @return the verbose
*/
public Verbose getVerbose() {
return verbose;
}
/**
* @param verbose
* the verbose to set
*/
public void setVerbose(Verbose verbose) {
this.verbose = verbose;
}
public Constraint.Mode getConstraint() {
return constraintMode;
}
public void setConstraint(Constraint.Mode constraintMode) {
doConstraint = constraintMode != Constraint.Mode.NO;
this.constraintMode = constraintMode;
}
/**
* @return the stats
*/
public Stats getStats() {
return stats;
}
/**
* @param stats
* the stats to set
*/
public void setStats(Stats stats) {
this.stats = stats;
}
/**
* @return the residuMin
*/
public double getResiduMin() {
return residuMin;
}
/**
* @param residuMin
* the residuMin to set
*/
public void setResiduMin(double residuMin) {
doResidu = residuMin > 0;
this.residuMin = residuMin;
}
/**
* @return the timeLimit
*/
public double getTimeLimit() {
return timeLimit;
}
/**
* @param timeLimit
* the timeLimit to set
*/
public void setTimeLimit(double timeLimit) {
doTime = timeLimit > 0;
this.timeLimit = timeLimit;
}
/**
* @return the reference
*/
public String getReference() {
return reference;
}
/**
* @param reference
* the reference to set
*/
public void setReference(String reference) {
doReference = false;
if (reference == null)
return;
if (reference.equals(""))
return;
doReference = true;
this.reference = reference;
}
/**
* @return the outs
*/
public ArrayList<Output> getOuts() {
return outs;
}
/**
* @param outs
* the outs to set
*/
public void setOuts(ArrayList<Output> outs) {
this.outs = outs;
}
public void addOutput(Output out) {
this.outs.add(out);
}
public String toStringMonitor() {
String s = "[" + verbose.name().toLowerCase() + "] ";
for (AbstractMonitor monitor : monitors) {
s += "" + monitor.getName() + " ";
}
return s;
}
public Stats.Mode getStatsMode() {
return stats.getMode();
}
public void setStatsMode(Stats.Mode mode) {
this.stats = new Stats(mode);
}
public String toStringRunning() {
String s = "";
s += "system " + (system ? "shown" : "hidden ");
s += ", multithreading " + (multithreading ? "on" : "off ");
s += ", display final " + (displayFinal ? "on " : "off ");
return s;
}
public String toStringPath() {
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)";
}
}
private class Updater extends TimerTask {
@Override
public void run() {
update();
}
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/capsule/AlgorithmCapsule.java b/DeconvolutionLab2/src/deconvolution/capsule/AlgorithmCapsule.java
index 60af01a..699d490 100644
--- a/DeconvolutionLab2/src/deconvolution/capsule/AlgorithmCapsule.java
+++ b/DeconvolutionLab2/src/deconvolution/capsule/AlgorithmCapsule.java
@@ -1,183 +1,185 @@
/*
* 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.capsule;
import javax.swing.JSplitPane;
+import com.esotericsoftware.minlog.Log;
+
import bilib.component.HTMLPane;
import bilib.table.CustomizedTable;
import bilib.tools.NumFormat;
import deconvolution.Deconvolution;
import deconvolution.Features;
import deconvolution.algorithm.AbstractAlgorithm;
import deconvolution.algorithm.AbstractAlgorithmPanel;
import deconvolution.algorithm.Algorithm;
import deconvolutionlab.monitor.Monitors;
import fft.AbstractFFT;
import fft.FFT;
import signal.ComplexSignal;
import signal.RealSignal;
import signal.SignalCollector;
/**
* This class is a information module for the algorithm.
*
* @author Daniel Sage
*
*/
public class AlgorithmCapsule extends AbstractCapsule implements Runnable {
private CustomizedTable table;
private HTMLPane doc;
public AlgorithmCapsule(Deconvolution deconvolution) {
super(deconvolution);
doc = new HTMLPane(100, 1000);
table = new CustomizedTable(new String[] { "Features", "Values" }, false);
split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, table.getPane(200, 200), doc.getPane());
}
+ @Override
public void update() {
if (doc == null)
return;
if (table == null)
return;
table.removeRows();
table.append(new String[] { "PSF", "Waiting for loading ..." });
Thread thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
split.setDividerLocation(300);
}
@Override
public String getName() {
return "Algorithm";
}
@Override
public void run() {
Features features = new Features();
if (deconvolution.getAlgorithm() == null) {
features.add("Algorithm", "No valid algorithm");
return;
}
AbstractAlgorithm algo = deconvolution.getAlgorithm();
doc.clear();
String name = algo.getShortnames()[0];
AbstractAlgorithmPanel algoPanel = Algorithm.getPanel(name);
if (algoPanel != null)
doc.append(algoPanel.getDocumentation());
if (deconvolution.image == null) {
startAsynchronousTimer("Open image", 200);
deconvolution.image = deconvolution.openImage();
stopAsynchronousTimer();
}
if (deconvolution.image == null) {
features.add("Image", "No valid input image");
return;
}
if (deconvolution.getController().getPadding() == null) {
features.add("Padding", "No valid padding");
return;
}
if (deconvolution.getController().getApodization() == null) {
features.add("Apodization", "No valid apodization");
return;
}
if (deconvolution.psf == null) {
startAsynchronousTimer("Open PSF", 200);
deconvolution.psf = deconvolution.openPSF();
stopAsynchronousTimer();
}
if (deconvolution.psf == null) {
features.add("Image", "No valid PSF");
return;
}
- startAsynchronousTimer("Run FFT", 200);
+ startAsynchronousTimer("Check Algorithm", 200);
AbstractFFT f = FFT.getFastestFFT().getDefaultFFT();
double Q = Math.sqrt(2);
if (deconvolution.image != null) {
int mx = deconvolution.image.nx;
int my = deconvolution.image.ny;
int mz = deconvolution.image.nz;
while (mx * my * mz > Math.pow(2, 15)) {
mx = (int)(mx / Q);
my = (int)(my / Q);
mz = (int)(mz / Q);
}
double N = deconvolution.image.nx * deconvolution.image.ny * deconvolution.image.nz;
double M = mx * my * mz;
double ratio = 1;
if (M != 0)
ratio = (N * Math.log(N)) / (M * Math.log(M));
double chrono = System.nanoTime();
RealSignal x = new RealSignal("test", mx, my, mz);
ComplexSignal c = new ComplexSignal("test", mx, my, mz);
f.init(Monitors.createDefaultMonitor(), mx, my, mz);
f.transform(x, c);
SignalCollector.free(x);
SignalCollector.free(c);
chrono = (System.nanoTime() - chrono);
- features.add("Tested on", mx + "x" + my + "x" + mz);
- features.add("Estimated Time on small", NumFormat.time(chrono) );
+ features.add("Small dataset", mx + "x" + my + "x" + mz);
+ features.add("Elapsed time on small dataset", NumFormat.time(chrono) );
chrono = chrono * ratio * algo.getComplexityNumberofFFT();
- int n = algo.isIterative() ? algo.getIterationsMax() : 1;
- features.add("Estimated Time", NumFormat.time(chrono) );
- features.add("Estimated Number of FFT / Transform", ""+algo.getComplexityNumberofFFT());
+ features.add("Estimated time for input dataset", NumFormat.time(chrono) );
+ features.add("Estimated number of FFTs", "" + algo.getComplexityNumberofFFT());
}
else
- features.add("Estimated Time", "Error" );
+ features.add("Estimated time", "Error" );
double mem = (algo.getMemoryFootprintRatio() * deconvolution.image.nx * deconvolution.image.ny * deconvolution.image.nz * 4);
- features.add("Estimated Memory", NumFormat.bytes(mem));
+ features.add("Estimated required memory", NumFormat.bytes(mem));
features.add("Iterative", algo.isIterative() ? "" + algo.getIterationsMax() : "Direct");
table.removeRows();
for (String[] feature : features)
table.append(feature);
stopAsynchronousTimer();
}
}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/deconvolution/capsule/ImageCapsule.java b/DeconvolutionLab2/src/deconvolution/capsule/ImageCapsule.java
index 6091f29..c1155a1 100644
--- a/DeconvolutionLab2/src/deconvolution/capsule/ImageCapsule.java
+++ b/DeconvolutionLab2/src/deconvolution/capsule/ImageCapsule.java
@@ -1,151 +1,152 @@
/*
* 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.capsule;
import java.awt.Dimension;
import javax.swing.JSplitPane;
import bilib.component.PanelImage;
import bilib.table.CustomizedTable;
import bilib.tools.NumFormat;
import deconvolution.Deconvolution;
import deconvolution.Features;
import signal.RealSignal;
import signal.SignalCollector;
import signal.apodization.Apodization;
import signal.padding.Padding;
/**
* This class is a information module for the image source.
*
* @author Daniel Sage
*
*/
public class ImageCapsule extends AbstractCapsule implements Runnable {
private PanelImage pnImage;
private CustomizedTable table;
public ImageCapsule(Deconvolution deconvolution) {
super(deconvolution);
pnImage = new PanelImage();
table = new CustomizedTable(new String[] { "Features", "Values" }, false);
pnImage.setPreferredSize(new Dimension(300, 300));
split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, table.getPane(300, 300), pnImage);
}
+ @Override
public void update() {
split.setDividerLocation(300);
if (pnImage == null)
return;
if (table == null)
return;
table.removeRows();
table.append(new String[] {"Image", "Waiting for loading ..."});
Thread thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}
@Override
public String getName() {
return "Image";
}
@Override
public void run() {
Features features = new Features();
if (deconvolution.image == null) {
startAsynchronousTimer("Open image", 200);
deconvolution.image = deconvolution.openImage();
stopAsynchronousTimer();
}
if (deconvolution.image == null) {
features.add("Image", "No valid input image");
return;
}
if (deconvolution.getController().getPadding() == null) {
features.add("Padding", "No valid padding");
return;
}
if (deconvolution.getController().getApodization() == null) {
features.add("Apodization", "No valid apodization");
return;
}
- startAsynchronousTimer("Preprocessing image", 200);
+ startAsynchronousTimer("Open image", 200);
float stati[] = deconvolution.image.getStats();
int sizi = deconvolution.image.nx * deconvolution.image.ny * deconvolution.image.nz;
float totali = stati[0] * sizi;
features.add("<html><b>Orignal Image</b></html>", "");
features.add("Size", deconvolution.image.dimAsString() + " " + NumFormat.bytes(sizi*4));
features.add("Mean (stdev)", NumFormat.nice(stati[0]) + " (" + NumFormat.nice(stati[3]) + ")");
features.add("Extrema (min, max)", NumFormat.nice(stati[1]) + ", " + NumFormat.nice(stati[2]));
features.add("Energy (integral)", NumFormat.nice(stati[5]) + " (" + NumFormat.nice(totali) + ")");
table.removeRows();
for (String[] feature : features)
table.append(feature);
Padding pad = deconvolution.getController().getPadding();
Apodization apo = deconvolution.getController().getApodization();
RealSignal signal = pad.pad(deconvolution.getMonitors(), deconvolution.image);
apo.apodize(deconvolution.getMonitors(), signal);
float stats[] = signal.getStats();
int sizs = signal.nx * signal.ny * signal.nz;
float totals = stats[0] * sizs;
double incpad = (double)((sizs-sizi)/sizi*100.0);
features.add("<html><b>Working Image</b></html>", "");
features.add("Size", signal.dimAsString() + " " + NumFormat.bytes(sizs*4));
features.add("Mean (stdev)", NumFormat.nice(stats[0]) + " (" + NumFormat.nice(stats[3]) + ")");
features.add("Extrema (min, max)", NumFormat.nice(stats[1]) + ", " + NumFormat.nice(stats[2]));
features.add("Energy (integral)", NumFormat.nice(stats[5]) + " (" + NumFormat.nice(totals) + ")");
features.add("<html><b>Information</b></html>", "");
features.add("Size increase (pad.)", NumFormat.nice(incpad) + "%");
features.add("Energy lost (apo.)", NumFormat.nice((stats[5]-stati[5])/stati[5]*100));
SignalCollector.free(signal);
table.removeRows();
for (String[] feature : features)
table.append(feature);
pnImage.setImage(deconvolution.image.preview());
stopAsynchronousTimer();
}
}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/deconvolution/capsule/PSFCapsule.java b/DeconvolutionLab2/src/deconvolution/capsule/PSFCapsule.java
index 0d38cb1..4db52ab 100644
--- a/DeconvolutionLab2/src/deconvolution/capsule/PSFCapsule.java
+++ b/DeconvolutionLab2/src/deconvolution/capsule/PSFCapsule.java
@@ -1,157 +1,158 @@
/*
* 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.capsule;
import java.awt.Dimension;
import javax.swing.JSplitPane;
import bilib.component.PanelImage;
import bilib.table.CustomizedTable;
import bilib.tools.NumFormat;
import deconvolution.Deconvolution;
import deconvolution.Features;
import signal.RealSignal;
import signal.SignalCollector;
/**
* This class is a information module for the PSF source.
*
* @author Daniel Sage
*
*/
public class PSFCapsule extends AbstractCapsule implements Runnable {
private PanelImage pnImage;
private CustomizedTable table;
public PSFCapsule(Deconvolution deconvolution) {
super(deconvolution);
pnImage = new PanelImage();
table = new CustomizedTable(new String[] { "Features", "Values" }, false);
pnImage.setPreferredSize(new Dimension(300, 300));
split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, table.getPane(300, 300), pnImage);
}
+ @Override
public void update() {
split.setDividerLocation(300);
if (pnImage == null)
return;
if (table == null)
return;
table.removeRows();
table.append(new String[] { "PSF", "Waiting for loading ..." });
Thread thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}
@Override
public String getName() {
return "PSF";
}
@Override
public void run() {
Features features = new Features();
if (deconvolution.image == null) {
startAsynchronousTimer("Open image", 200);
deconvolution.image = deconvolution.openImage();
stopAsynchronousTimer();
}
if (deconvolution.getController().getPadding() == null) {
features.add("Padding", "No valid padding");
return;
}
if (deconvolution.getController().getApodization() == null) {
features.add("Apodization", "No valid apodization");
return;
}
if (deconvolution.psf == null) {
startAsynchronousTimer("Open PSF", 200);
deconvolution.psf = deconvolution.openPSF();
stopAsynchronousTimer();
}
if (deconvolution.psf == null) {
features.add("PSF", "No valid PSF");
return;
}
- startAsynchronousTimer("Preprocessing PSF", 200);
+ startAsynchronousTimer("Open PSF", 200);
float stati[] = deconvolution.psf.getStats();
int sizi = deconvolution.psf.nx * deconvolution.psf.ny * deconvolution.psf.nz;
float totali = stati[0] * sizi;
features.add("<html><b>Orignal PSF</b></html>", "");
features.add("Size", deconvolution.psf.dimAsString() + " " + NumFormat.bytes(sizi * 4));
features.add("Mean (stdev)", NumFormat.nice(stati[0]) + " (" + NumFormat.nice(stati[3]) + ")");
features.add("Extrema (min, max)", NumFormat.nice(stati[1]) + ", " + NumFormat.nice(stati[2]));
features.add("Energy (integral)", NumFormat.nice(stati[5]) + " (" + NumFormat.nice(totali) + ")");
table.removeRows();
for (String[] feature : features)
table.append(feature);
RealSignal h;
if (deconvolution.image == null) {
features.add("Image", "No valid input image to resize");
h = deconvolution.psf.duplicate();
}
else
h = deconvolution.psf.changeSizeAs(deconvolution.image);
h.normalize(deconvolution.getController().getNormalizationPSF());
float stats[] = h.getStats();
int sizs = h.nx * h.ny * h.nz;
float totals = stats[0] * sizs;
double incpad = (double)((sizs-sizi)/sizi*100.0);
features.add("<html><b>Working PSF</b></html>", "");
features.add("Size", h.dimAsString() + " " + NumFormat.bytes(sizs * 4));
features.add("Mean (stdev)", NumFormat.nice(stats[0]) + " (" + NumFormat.nice(stats[3]) + ")");
features.add("Extrema (min, max)", NumFormat.nice(stats[1]) + ", " + NumFormat.nice(stats[2]));
features.add("Energy (integral)", NumFormat.nice(stats[5]) + " (" + NumFormat.nice(totals) + ")");
features.add("<html><b>Information</b></html>", "");
features.add("Size increase (image)", NumFormat.nice(incpad) + "%");
features.add("Energy lost", NumFormat.nice((stats[5] - stati[5]) / stati[5] * 100));
SignalCollector.free(h);
table.removeRows();
for (String[] feature : features)
table.append(feature);
pnImage.setImage(deconvolution.psf.preview());
stopAsynchronousTimer();
}
}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/deconvolution/capsule/RecapCapsule.java b/DeconvolutionLab2/src/deconvolution/capsule/RecapCapsule.java
index 27e247f..2a4d302 100644
--- a/DeconvolutionLab2/src/deconvolution/capsule/RecapCapsule.java
+++ b/DeconvolutionLab2/src/deconvolution/capsule/RecapCapsule.java
@@ -1,111 +1,114 @@
/*
* 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.capsule;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JSplitPane;
import javax.swing.text.BadLocationException;
import bilib.component.HTMLPane;
import bilib.table.CustomizedTable;
import deconvolution.Deconvolution;
/**
* This class is a information module for a recapitulation of the command line.
*
* @author Daniel Sage
*
*/
public class RecapCapsule extends AbstractCapsule implements KeyListener {
private HTMLPane pnCommand;
private CustomizedTable table;
public RecapCapsule(Deconvolution deconvolution) {
super(deconvolution);
// Panel command
pnCommand = new HTMLPane("Monaco", "#10FF10", "100020", 100, 100);
pnCommand.append("p", deconvolution.getCommand());
pnCommand.setEditable(true);
pnCommand.addKeyListener(this);
table = new CustomizedTable(new String[] { "Features", "Values" }, false);
split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, table.getPane(200, 200), pnCommand.getPane());
}
+ @Override
public void update() {
if (table == null)
return;
+ startAsynchronousTimer("Recap", 200);
table.removeRows();
for (String[] feature : deconvolution.recap())
table.append(feature);
split.setDividerLocation(0.5);
split.repaint();
+ stopAsynchronousTimer();
}
public String getCommand() {
return pnCommand.getText();
}
@Override
public String getName() {
return "Recap";
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
try {
int len = pnCommand.getDocument().getLength();
String command = pnCommand.getDocument().getText(0, len);
deconvolution.setCommand(command);
table.removeRows();
for (String[] feature : deconvolution.recap())
table.append(feature);
}
catch (BadLocationException e1) {
e1.printStackTrace();
}
}
}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/deconvolution/capsule/ReportCapsule.java b/DeconvolutionLab2/src/deconvolution/capsule/ReportCapsule.java
index 7337fe3..47e6fe4 100644
--- a/DeconvolutionLab2/src/deconvolution/capsule/ReportCapsule.java
+++ b/DeconvolutionLab2/src/deconvolution/capsule/ReportCapsule.java
@@ -1,87 +1,88 @@
/*
* 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.capsule;
import java.awt.Dimension;
import javax.swing.JSplitPane;
import bilib.component.PanelImage;
import bilib.table.CustomizedTable;
import deconvolution.Deconvolution;
import signal.RealSignal;
/**
* This class is a information module for report the output.
*
* @author Daniel Sage
*
*/
public class ReportCapsule extends AbstractCapsule {
private PanelImage pnImage;
private CustomizedTable table;
public ReportCapsule(Deconvolution deconvolution) {
super(deconvolution);
pnImage = new PanelImage();
table = new CustomizedTable(new String[] { "Output", "Values" }, false);
pnImage.setPreferredSize(new Dimension(300, 300));
split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, table.getPane(300, 300), pnImage);
}
+ @Override
public void update() {
split.setDividerLocation(300);
if (pnImage == null)
return;
if (table == null)
return;
table.removeRows();
for (String[] feature : deconvolution.getDeconvolutionReports())
table.append(feature);
RealSignal image = deconvolution.getOutput();
if (image == null) {
table.append(new String[] {"ERROR", "No open output"});
return;
}
pnImage.setImage(image.preview());
for (String[] feature : deconvolution.checkOutput())
table.append(feature);
split.setDividerLocation(300);
}
@Override
public String getName() {
return "Report";
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/LabPanel.java b/DeconvolutionLab2/src/deconvolutionlab/LabPanel.java
index 6e768b9..16c604d 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/LabPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/LabPanel.java
@@ -1,297 +1,301 @@
/*
* 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.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.PanelImage;
import deconvolution.Command;
import deconvolution.Deconvolution;
import deconvolutionlab.dialog.BatchDialog;
import deconvolutionlab.module.AboutModule;
import deconvolutionlab.module.AbstractModule;
import deconvolutionlab.module.AlgorithmModule;
import deconvolutionlab.module.BatchModule;
import deconvolutionlab.module.BorderModule;
import deconvolutionlab.module.CommandModule;
import deconvolutionlab.module.ComputationModule;
import deconvolutionlab.module.ConfigModule;
import deconvolutionlab.module.ControllerModule;
import deconvolutionlab.module.DirectoryModule;
+import deconvolutionlab.module.FFTModule;
import deconvolutionlab.module.GroupedModulePanel;
import deconvolutionlab.module.ImageModule;
import deconvolutionlab.module.LanguageModule;
import deconvolutionlab.module.LicenceModule;
import deconvolutionlab.module.OutputModule;
import deconvolutionlab.module.PSFModule;
import deconvolutionlab.module.RunningModule;
import deconvolutionlab.system.SystemInfo;
public class LabPanel extends JPanel implements ActionListener, ChangeListener {
private JTabbedPane tab = new JTabbedPane();
private JButton bnHelp = new JButton("Help");
private JButton bnQuit = new JButton("Quit");
private JButton bnSystem = new JButton("System");
private JButton bnBatch = new JButton("Batch");
private JButton bnRun = new JButton("Run");
private JButton bnLaunch = new JButton("Launch");
private JButton bnClose;
private ImageModule image;
private PSFModule psf;
private AlgorithmModule algo;
private AboutModule about;
private LicenceModule licence;
private OutputModule output;
private ComputationModule computation;
private BorderModule border;
private ConfigModule config;
private BatchModule batch;
private LanguageModule language;
private CommandModule command;
private RunningModule running;
private DirectoryModule directory;
+ private FFTModule fft;
private ControllerModule controller;
private GroupedModulePanel panelDeconv;
private GroupedModulePanel panelAdvanc;
private GroupedModulePanel panelScript;
private GroupedModulePanel panelAbout;
private AbstractModule modules[];
public LabPanel(JButton bnClose) {
this.bnClose = bnClose;
image = new ImageModule(false);
psf = new PSFModule(false);
algo = new AlgorithmModule(true);
output = new OutputModule(true);
computation = new ComputationModule(false);
border = new BorderModule(false);
controller = new ControllerModule(false);
batch = new BatchModule(false);
language = new LanguageModule(false);
about = new AboutModule(true);
licence = new LicenceModule(false);
config = new ConfigModule(false);
command = new CommandModule();
running = new RunningModule(false);
directory = new DirectoryModule(false);
+ fft = new FFTModule(false);
- modules = new AbstractModule[] { image, psf, algo, output, controller, border, computation, batch, directory };
+ modules = new AbstractModule[] { image, psf, algo, output, controller, border, computation, batch, directory, fft };
Command.active(modules, command);
Command.command();
panelDeconv = new GroupedModulePanel(buildDeconvolutionPanel(), this);
panelAdvanc = new GroupedModulePanel(buildAdvancedPanel(), this);
panelScript = new GroupedModulePanel(buildProgrammingPanel(), this);
panelAbout = new GroupedModulePanel(buildAboutPanel(), this);
Border border = BorderFactory.createEmptyBorder(5, 5, 5, 5);
PanelImage bottom = new PanelImage("celegans.jpg");
bottom.setBorder(border);
bottom.setLayout(new GridLayout(1, 6));
bottom.setBorder(border);
bottom.add(bnHelp);
bottom.add(bnSystem);
bottom.add(bnClose);
bottom.add(bnBatch);
bottom.add(bnRun);
bottom.add(bnLaunch);
tab.add("Deconvolution", panelDeconv);
tab.add("Advanced", panelAdvanc);
tab.add("Scripting", panelScript);
tab.add("About", panelAbout);
tab.addChangeListener(this);
setLayout(new BorderLayout());
add(tab, BorderLayout.CENTER);
add(bottom, BorderLayout.SOUTH);
bnBatch.addActionListener(this);
bnRun.addActionListener(this);
bnLaunch.addActionListener(this);
bnClose.addActionListener(this);
bnQuit.addActionListener(this);
bnHelp.addActionListener(this);
bnSystem.addActionListener(this);
((GroupedModulePanel) tab.getSelectedComponent()).organize();
setMinimumSize(new Dimension(500, 500));
Config.load();
running.init();
//sizeModule();
Command.command();
running.update();
image.update();
psf.update();
output.update();
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == bnHelp)
Lab.help();
else if (e.getSource() == bnClose)
Config.store();
else if (e.getSource() == bnSystem)
SystemInfo.activate();
else if (e.getSource() == bnBatch) {
tab.setSelectedIndex(2);
batch.expand();
sizeModule();
BatchDialog dlg = new BatchDialog(batch);
Lab.setVisible(dlg, true);
}
else if (e.getSource() == bnLaunch) {
String job = language.getJobName() + " " + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date());
Deconvolution d = new Deconvolution(job, Command.command(), Deconvolution.Finish.ALIVE);
d.launch();
}
else if (e.getSource() == bnRun) {
String job = language.getJobName() + " " + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date());
Deconvolution d = new Deconvolution(job, Command.command());
d.deconvolve();
}
}
@Override
public void stateChanged(ChangeEvent e) {
((GroupedModulePanel) tab.getSelectedComponent()).organize();
Command.command();
}
private ArrayList<AbstractModule> buildDeconvolutionPanel() {
ArrayList<AbstractModule> list = new ArrayList<AbstractModule>();
list.add(image);
list.add(psf);
list.add(algo);
list.add(directory);
return list;
}
private ArrayList<AbstractModule> buildAdvancedPanel() {
ArrayList<AbstractModule> list = new ArrayList<AbstractModule>();
list.add(output);
list.add(controller);
list.add(computation);
list.add(border);
+ list.add(fft);
return list;
}
private ArrayList<AbstractModule> buildProgrammingPanel() {
ArrayList<AbstractModule> list = new ArrayList<AbstractModule>();
list.add(batch);
list.add(command);
list.add(language);
return list;
}
private ArrayList<AbstractModule> buildAboutPanel() {
ArrayList<AbstractModule> list = new ArrayList<AbstractModule>();
list.add(about);
list.add(licence);
list.add(config);
return list;
}
public void close() {
for (AbstractModule module : modules)
module.close();
bnLaunch.removeActionListener(this);
bnRun.removeActionListener(this);
bnBatch.removeActionListener(this);
bnClose.removeActionListener(this);
bnHelp.removeActionListener(this);
Lab.close();
}
public void sizeModule() {
if (tab.getSelectedIndex() == 0)
sizePanel(panelDeconv);
if (tab.getSelectedIndex() == 1)
sizePanel(panelAdvanc);
if (tab.getSelectedIndex() == 2)
sizePanel(panelScript);
if (tab.getSelectedIndex() == 3)
sizePanel(panelAbout);
}
private void sizePanel(GroupedModulePanel panel) {
Dimension dim = getSize();
int hpc = 70;
int npc = hpc * panel.getModules().size();
Dimension small = new Dimension(dim.width, hpc);
Dimension large = new Dimension(dim.width, dim.height - npc);
setMinimumSize(new Dimension(Constants.widthGUI, 4*hpc));
for (AbstractModule module : panel.getModules()) {
if (module.isExpanded()) {
module.setPreferredSize(large);
module.setMaximumSize(large);
module.setMinimumSize(small);
module.getExpandedPanel().setPreferredSize(large);
module.getExpandedPanel().setMaximumSize(large);
module.getExpandedPanel().setMinimumSize(small);
}
else {
module.setPreferredSize(small);
module.setMaximumSize(small);
module.setMinimumSize(small);
module.getCollapsedPanel().setPreferredSize(small);
module.getCollapsedPanel().setMaximumSize(small);
module.getCollapsedPanel().setMinimumSize(small);
}
}
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/module/ComputationModule.java b/DeconvolutionLab2/src/deconvolutionlab/module/ComputationModule.java
index 0e6ff1b..570b9a7 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/module/ComputationModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/module/ComputationModule.java
@@ -1,186 +1,185 @@
/*
* 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.module;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.GridPanel;
import bilib.tools.NumFormat;
import deconvolution.Command;
import deconvolution.algorithm.Algorithm;
import deconvolutionlab.Config;
import fft.FFT;
public class ComputationModule extends AbstractModule implements ActionListener, ChangeListener {
- private JComboBox<String> cmbFFT;
private JComboBox<String> cmbMultithreading;
private JComboBox<String> cmbSystem;
private JComboBox<String> cmbDisplayFinal;
+ private JComboBox<String> cmbFFT;
private JComboBox<String> cmbEpsilon;
private JComboBox<String> cmbNormalization;
boolean init = false;
public ComputationModule(boolean expanded) {
super("Computation", "", "Default", "", expanded);
}
@Override
public String getCommand() {
String cmd = "";
if (cmbNormalization.getSelectedIndex() != 0)
cmd += " -norm " + NumFormat.parseNumber((String)cmbNormalization.getSelectedItem(), 1);
if (cmbSystem.getSelectedIndex() != 0)
cmd += " -system no";
if (cmbMultithreading.getSelectedIndex() != 0)
cmd += " -multithreading no";
if (cmbDisplayFinal.getSelectedIndex() != 0)
cmd += " -display no";
if (cmbFFT.getSelectedIndex() != 0)
cmd += " -fft " + FFT.getLibraryByName((String) cmbFFT.getSelectedItem()).getLibraryName();
if (cmbEpsilon.getSelectedIndex() != 6)
cmd += " -epsilon " + (String) cmbEpsilon.getSelectedItem();
return cmd;
}
@Override
public JPanel buildExpandedPanel() {
- cmbFFT = new JComboBox<String>(FFT.getLibrariesAsArray());
cmbSystem = new JComboBox<String>(new String[] { "yes", "no" });
cmbMultithreading = new JComboBox<String>(new String[] { "yes", "no" });
cmbDisplayFinal = new JComboBox<String>(new String[] { "yes", "no" });
+ cmbFFT = new JComboBox<String>(FFT.getLibrariesAsArray());
cmbEpsilon = new JComboBox<String>(new String[] { "1E-0", "1E-1", "1E-2", "1E-3", "1E-4", "1E-5", "1E-6", "1E-7", "1E-8", "1E-9", "1E-10", "1E-11", "1E-12" });
cmbEpsilon.setSelectedItem("1E-6");
cmbNormalization = new JComboBox<String>(new String[] { "1", "10", "1000", "1E+6", "1E+9", "no" });
cmbNormalization.addActionListener(this);
cmbNormalization.setSelectedIndex(0);
cmbNormalization.removeActionListener(this);
GridPanel pnNumeric = new GridPanel(false, 2);
pnNumeric.place(1, 0, "norm");
pnNumeric.place(1, 1, cmbNormalization);
pnNumeric.place(1, 2, "PSF normalization (def:1)");
pnNumeric.place(3, 0, new JLabel("fft"));
pnNumeric.place(3, 1, cmbFFT);
pnNumeric.place(3, 2, new JLabel("FFT library (Fourier)"));
pnNumeric.place(6, 0, new JLabel("system"));
pnNumeric.place(6, 1, cmbSystem);
pnNumeric.place(6, 2, new JLabel("Show the system panel"));
pnNumeric.place(7, 0, new JLabel("display"));
pnNumeric.place(7, 1, cmbDisplayFinal);
pnNumeric.place(7, 2, new JLabel("Display the final output"));
pnNumeric.place(8, 0, new JLabel("multithreading"));
pnNumeric.place(8, 1, cmbMultithreading);
pnNumeric.place(8, 2, new JLabel("Activate multithreading"));
pnNumeric.place(9, 0, new JLabel("epsilon"));
pnNumeric.place(9, 1, cmbEpsilon);
pnNumeric.place(9, 2, new JLabel("<html>Machine Epsilon &epsilon;</html>"));
JScrollPane scroll = new JScrollPane(pnNumeric);
scroll.setBorder(BorderFactory.createEmptyBorder());
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEtchedBorder());
panel.add(scroll, BorderLayout.CENTER);
Config.register(getName(), "normalization", cmbNormalization, cmbNormalization.getItemAt(0));
Config.register(getName(), "fft", cmbFFT, Algorithm.getDefaultAlgorithm());
Config.register(getName(), "system", cmbSystem, cmbSystem.getItemAt(0));
Config.register(getName(), "display", cmbDisplayFinal, cmbDisplayFinal.getItemAt(0));
Config.register(getName(), "multithreading", cmbMultithreading, cmbMultithreading.getItemAt(0));
Config.register(getName(), "epsilon", cmbEpsilon, "1E-6");
cmbFFT.addActionListener(this);
cmbSystem.addActionListener(this);
cmbDisplayFinal.addActionListener(this);
cmbMultithreading.addActionListener(this);
cmbEpsilon.addActionListener(this);
cmbNormalization.addActionListener(this);
getAction1Button().addActionListener(this);
init = true;
return panel;
}
private void update() {
setCommand(getCommand());
if (init)
setSynopsis("Norm " + cmbNormalization.getSelectedItem() + " " + FFT.getLibraryByName((String) cmbFFT.getSelectedItem()).getLibraryName());
Command.command();
}
@Override
public void stateChanged(ChangeEvent e) {
update();
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
-System.out.println("" + e);
if (e.getSource() == getAction1Button()) {
cmbFFT.setSelectedIndex(0);
cmbMultithreading.setSelectedIndex(0);
cmbDisplayFinal.setSelectedIndex(0);
cmbSystem.setSelectedIndex(0);
cmbEpsilon.setSelectedIndex(0);
cmbNormalization.setSelectedIndex(0);
}
update();
}
@Override
public void close() {
getAction1Button().removeActionListener(this);
cmbFFT.removeActionListener(this);
cmbMultithreading.removeActionListener(this);
cmbDisplayFinal.removeActionListener(this);
cmbSystem.removeActionListener(this);
cmbEpsilon.removeActionListener(this);
cmbNormalization.removeActionListener(this);
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/module/ControllerModule.java b/DeconvolutionLab2/src/deconvolutionlab/module/ControllerModule.java
index aa8b097..acb7b86 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/module/ControllerModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/module/ControllerModule.java
@@ -1,265 +1,310 @@
/*
* 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.module;
import java.awt.BorderLayout;
import java.awt.Dimension;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DropTarget;
+import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
+import java.io.IOException;
+import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.GridPanel;
import bilib.tools.Files;
import deconvolution.Command;
import deconvolutionlab.Config;
+import deconvolutionlab.module.ImageModule.LocalDropTarget;
import signal.Constraint;
public class ControllerModule extends AbstractModule implements ActionListener, ChangeListener, KeyListener {
private JButton bnBrowse;
private JTextField txtReference;
private JTextField txtResidu;
private JTextField txtTime;
private JTextField txtIterations;
private JComboBox<String> cmbConstraint;
private JComboBox<String> cmbStats;
private JComboBox<String> cmbMonitor;
private JComboBox<String> cmbVerbose;
private JCheckBox chkResidu;
private JCheckBox chkReference;
private JCheckBox chkTime;
public ControllerModule(boolean expanded) {
super("Controller", "", "Default", "", expanded);
}
@Override
public String getCommand() {
String cmd = "";
if (cmbMonitor.getSelectedIndex() != 0)
cmd += "-monitor " + cmbMonitor.getSelectedItem() + " ";
if (cmbVerbose.getSelectedIndex() != 0)
cmd += "-verbose " + cmbVerbose.getSelectedItem() + " ";
if (cmbStats.getSelectedIndex() != 0)
cmd += "-stats " + cmbStats.getSelectedItem() + " ";
if (cmbConstraint.getSelectedIndex() != 0)
cmd += "-constraint " + cmbConstraint.getSelectedItem() + " ";
if (chkReference.isSelected())
cmd += "-reference " + txtReference.getText() + " ";
if (chkResidu.isSelected())
cmd += "-residu " + txtResidu.getText() + " ";
if (chkTime.isSelected())
cmd += "-time " + txtTime.getText() + " ";
return cmd;
}
@Override
public JPanel buildExpandedPanel() {
chkTime = new JCheckBox("");
chkResidu = new JCheckBox("");
chkReference = new JCheckBox("");
bnBrowse = new JButton("Browse");
txtReference = new JTextField("");
txtResidu = new JTextField("0.01");
txtTime = new JTextField("3600");
txtIterations = new JTextField("Iteration max (mandatory)");
txtIterations.setEditable(false);
cmbMonitor = new JComboBox<String>(new String[] {"console table", "console", "table", "no" });
cmbVerbose = new JComboBox<String>(new String[] {"log", "quiet", "mute", "prolix" });
cmbConstraint = new JComboBox<String>(Constraint.getContraintsAsArray());
cmbStats = new JComboBox<String>(new String[] {"no", "show", "show + save", "save"});
txtReference.setPreferredSize(new Dimension(200, 20));
GridPanel pn = new GridPanel(true, 2);
pn.place(0, 0, "monitor");
pn.place(0, 2, cmbMonitor);
pn.place(0, 3, "Monitoring message");
pn.place(1, 0, "verbose");
pn.place(1, 2, cmbVerbose);
pn.place(1, 3, "");
pn.place(3, 0, "stats");
pn.place(3, 2, cmbStats);
pn.place(3, 3, "Signal's statistics");
pn.place(4, 0, "constraint");
pn.place(4, 2, cmbConstraint);
pn.place(4, 3, "Additional constraint");
pn.place(5, 0, "residu");
pn.place(5, 1, chkResidu);
pn.place(5, 2, txtResidu);
pn.place(5, 3, "Additional stopping criteria");
pn.place(6, 0, "time");
pn.place(6, 1, chkTime);
pn.place(6, 2, txtTime);
pn.place(6, 3, "Additional stopping criteria");
pn.place(7, 0, "reference");
pn.place(7, 1, chkReference);
pn.place(7, 2, 2, 1, txtReference);
pn.place(8, 2, bnBrowse);
pn.place(8, 3, 1, 1, "Ground-truth file");
JScrollPane scroll = new JScrollPane(pn);
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
JPanel panel = new JPanel(new BorderLayout());
panel.add(scroll, BorderLayout.CENTER);
-
+
+ // Add drop area
+ txtReference.setDropTarget(new LocalDropTarget());
+ getCollapsedPanel().setDropTarget(new LocalDropTarget());
+ bnBrowse.setDropTarget(new LocalDropTarget());
+
Config.register(getName(), "residu.enable", chkResidu, false);
Config.register(getName(), "reference.enable", chkReference, false);
Config.register(getName(), "time.enable", chkTime, false);
Config.register(getName(), "reference.value", txtReference, "");
Config.register(getName(), "residu.value", txtResidu, "0.01");
Config.register(getName(), "time.value", txtTime, "3600");
Config.register(getName(), "constraint", cmbConstraint, cmbConstraint.getItemAt(0));
Config.register(getName(), "stats", cmbStats, cmbStats.getItemAt(0));
Config.register(getName(), "monitor", cmbMonitor, cmbMonitor.getItemAt(0));
Config.register(getName(), "verbose", cmbVerbose, cmbVerbose.getItemAt(0));
bnBrowse.addActionListener(this);
chkResidu.addChangeListener(this);
chkReference.addChangeListener(this);
chkTime.addChangeListener(this);
txtResidu.addKeyListener(this);
txtReference.addKeyListener(this);
txtTime.addKeyListener(this);
cmbConstraint.addActionListener(this);
cmbMonitor.addActionListener(this);
cmbVerbose.addActionListener(this);
getAction1Button().addActionListener(this);
return panel;
}
private void update() {
setCommand(getCommand());
int count = 0;
count += (chkResidu.isSelected() ? 1 : 0);
count += (chkTime.isSelected() ? 1 : 0);
count += (chkReference.isSelected() ? 1 : 0);
setSynopsis("" + count + " controls");
Command.command();
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
if (e.getSource() == bnBrowse) {
File file = Files.browseFile(Command.getPath());
if (file != null)
txtReference.setText(file.getAbsolutePath());
}
if (e.getSource() == getAction1Button()) {
chkResidu.removeChangeListener(this);
chkReference.removeChangeListener(this);
chkTime.removeChangeListener(this);
chkResidu.setSelected(false);
chkReference.setSelected(false);
chkTime.setSelected(false);
txtReference.setText("");
txtResidu.setText("0.01");
txtTime.setText("3600");
cmbConstraint.setSelectedIndex(0);
cmbStats.setSelectedIndex(0);
cmbMonitor.setSelectedIndex(0);
cmbVerbose.setSelectedIndex(0);
chkResidu.addChangeListener(this);
chkReference.addChangeListener(this);
chkTime.addChangeListener(this);
}
update();
}
@Override
public void stateChanged(ChangeEvent e) {
update();
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
update();
}
@Override
public void close() {
bnBrowse.removeActionListener(this);
chkReference.removeChangeListener(this);
chkResidu.removeChangeListener(this);
cmbVerbose.removeActionListener(this);
cmbMonitor.removeActionListener(this);
cmbConstraint.removeActionListener(this);
chkTime.removeChangeListener(this);
getAction1Button().removeChangeListener(this);
}
-
+ public class LocalDropTarget extends DropTarget {
+
+ @Override
+ public void drop(DropTargetDropEvent e) {
+ e.acceptDrop(DnDConstants.ACTION_COPY);
+ e.getTransferable().getTransferDataFlavors();
+ Transferable transferable = e.getTransferable();
+ DataFlavor[] flavors = transferable.getTransferDataFlavors();
+ for (DataFlavor flavor : flavors) {
+ if (flavor.isFlavorJavaFileListType()) {
+ try {
+ List<File> files = (List<File>) transferable.getTransferData(flavor);
+ for (File file : files) {
+ if (file.isFile()) {
+ txtReference.setText(file.getAbsolutePath());
+ chkReference.setSelected(true);
+ update();
+ }
+ }
+ }
+ catch (UnsupportedFlavorException ex) {
+ ex.printStackTrace();
+ }
+ catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+ e.dropComplete(true);
+ super.drop(e);
+ }
+ }
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/module/OutputModule.java b/DeconvolutionLab2/src/deconvolutionlab/module/OutputModule.java
index 7d98498..010cef9 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/module/OutputModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/module/OutputModule.java
@@ -1,236 +1,231 @@
/*
* 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.module;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import bilib.table.CustomizedColumn;
import bilib.table.CustomizedTable;
import deconvolution.Command;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
import deconvolutionlab.Lab;
import deconvolutionlab.dialog.OutputDialog;
import deconvolutionlab.output.Output;
import deconvolutionlab.output.Output.View;
public class OutputModule extends AbstractModule implements ActionListener, MouseListener {
private CustomizedTable table;
private JButton bnStack;
private JButton bnSeries;
private JButton bnMIP;
private JButton bnOrtho;
private JButton bnPlanar;
private JButton bnFigure;
public OutputModule(boolean expanded) {
super("Output", "", "Clear", "", expanded);
}
@Override
public String getCommand() {
String cmd = " ";
if (table == null)
return cmd;
for (int i = 0; i < table.getRowCount(); i++) {
String[] values = new String[table.getColumnCount()];
for(int c=0; c<table.getColumnCount(); c++)
values[c] = table.getCell(i, c) == null ? "" : table.getCell(i, c).trim();
cmd += " -out " + values[0] + " " + values[1] + " " + values[2] + " " + values[3] + " " + values[4];
if (values[5].equals(""))
cmd += " noshow";
if (values[6].equals(""))
cmd += " nosave";
}
return cmd;
}
public void update() {
setCommand(getCommand());
setSynopsis(table.getRowCount() + " output" + (table.getRowCount() > 1 ? "s" : ""));
Command.command();
getAction1Button().setEnabled(table.getRowCount() > 0);
}
@Override
public JPanel buildExpandedPanel() {
String[] dynamics = { "intact", "rescaled", "normalized", "clipped" };
String[] types = { "float", "short", "byte" };
ArrayList<CustomizedColumn> columns = new ArrayList<CustomizedColumn>();
columns.add(new CustomizedColumn("Mode", String.class, 80, false));
columns.add(new CustomizedColumn("Name", String.class, Constants.widthGUI, true));
columns.add(new CustomizedColumn("Dynamic", String.class, 100, dynamics, "Select the dynamic range"));
columns.add(new CustomizedColumn("Type", String.class, 100, types, "Select the type"));
columns.add(new CustomizedColumn("Origin", String.class, 120, false));
columns.add(new CustomizedColumn("Show", String.class, 50, false));
columns.add(new CustomizedColumn("Save", String.class, 50, false));
columns.add(new CustomizedColumn("Del", String.class, 30, "\u232B", "Delete this image source"));
table = new CustomizedTable(columns, true);
table.getColumnModel().getColumn(5).setMaxWidth(50);
table.getColumnModel().getColumn(6).setMaxWidth(50);
table.getColumnModel().getColumn(7).setMaxWidth(30);
table.getColumnModel().getColumn(0).setMaxWidth(100);
table.getColumnModel().getColumn(2).setMaxWidth(100);
table.getColumnModel().getColumn(3).setMaxWidth(100);
table.addMouseListener(this);
bnStack = new JButton("\u2295 stack");
bnSeries = new JButton("\u2295 series");
bnMIP = new JButton("\u2295 mip");
bnOrtho = new JButton("\u2295 ortho");
bnPlanar = new JButton("\u2295 planar");
bnFigure = new JButton("\u2295 figure");
JToolBar pn = new JToolBar("Controls Image");
pn.setBorder(BorderFactory.createEmptyBorder());
pn.setLayout(new GridLayout(1, 6));
pn.setFloatable(false);
pn.add(bnStack);
pn.add(bnSeries);
pn.add(bnMIP);
pn.add(bnOrtho);
pn.add(bnPlanar);
pn.add(bnFigure);
- JToolBar tool = new JToolBar("Path");
- tool.setBorder(BorderFactory.createEmptyBorder());
- tool.setLayout(new BorderLayout());
- tool.setFloatable(false);
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createEtchedBorder());
panel.setLayout(new BorderLayout());
- panel.add(tool, BorderLayout.NORTH);
panel.add(pn, BorderLayout.SOUTH);
panel.add(table.getMinimumPane(100, 100), BorderLayout.CENTER);
bnStack.addActionListener(this);
bnSeries.addActionListener(this);
bnMIP.addActionListener(this);
bnOrtho.addActionListener(this);
bnPlanar.addActionListener(this);
bnFigure.addActionListener(this);
getAction1Button().addActionListener(this);
Config.registerTable(getName(), "output", table);
return panel;
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
View view = null;
if (e.getSource() == bnStack)
view = View.STACK;
else if (e.getSource() == bnSeries)
view = View.SERIES;
else if (e.getSource() == bnMIP)
view = View.MIP;
else if (e.getSource() == bnOrtho)
view = View.ORTHO;
else if (e.getSource() == bnPlanar)
view = View.PLANAR;
else if (e.getSource() == bnFigure)
view = View.FIGURE;
if (view != null) {
OutputDialog dlg = new OutputDialog(view);
Lab.setVisible(dlg, true);
if (dlg.wasCancel())
return;
Output out = dlg.getOut();
if (out != null)
table.insert(out.getAsString());
//Lab.setVisible(new OutputPanel(view), "panel", 30, 30);
update();
}
if (e.getSource() == getAction1Button()) {
table.removeRows();
}
}
@Override
public void mouseClicked(MouseEvent e) {
int row = table.getSelectedRow();
if (table.getSelectedColumn() == 7) {
table.removeRow(row);
if (table.getRowCount() > 0)
table.setRowSelectionInterval(0, 0);
}
update();
Command.command();
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void close() {
bnStack.removeActionListener(this);
bnSeries.removeActionListener(this);
bnMIP.removeActionListener(this);
bnOrtho.removeActionListener(this);
bnPlanar.removeActionListener(this);
bnFigure.removeActionListener(this);
getAction1Button().removeActionListener(this);
getAction2Button().removeActionListener(this);
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/monitor/StatusMonitor.java b/DeconvolutionLab2/src/deconvolutionlab/monitor/StatusMonitor.java
index 54b66be..6432f56 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/monitor/StatusMonitor.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/monitor/StatusMonitor.java
@@ -1,86 +1,86 @@
/*
* 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.awt.FontMetrics;
import javax.swing.JProgressBar;
import deconvolutionlab.Constants;
public class StatusMonitor implements AbstractMonitor {
private JProgressBar progress;
public StatusMonitor(JProgressBar progress) {
super();
this.progress = progress;
progress.setMinimum(0);
progress.setMaximum(100);
progress.setStringPainted(true);
}
@Override
public void clear() {
progress.setValue(0);
progress.setString(Constants.copyright);
}
@Override
public void add(Message message) {
int w = progress.getWidth();
if (w <= 0)
return;
String m = message.formatProgress();
FontMetrics fm = progress.getFontMetrics(progress.getFont());
int tw = fm.stringWidth(m);
if (tw > w) {
String ellipsis = "...";
int ew = fm.stringWidth(ellipsis);
while (tw + ew > w) {
tw = fm.stringWidth(m);
m = m.substring(0, m.length() - 1);
}
m += "...";
}
double p = message.getProgress() % 100;
progress.setString(m);
progress.setValue((int) Math.round(p));
}
@Override
public String getName() {
- return "status";
+ return "progress";
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/monitor/TableMonitor.java b/DeconvolutionLab2/src/deconvolutionlab/monitor/TableMonitor.java
index 07eb775..6ff7f39 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/monitor/TableMonitor.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/monitor/TableMonitor.java
@@ -1,149 +1,147 @@
/*
* 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.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import bilib.table.CustomizedColumn;
import bilib.table.CustomizedTable;
public class TableMonitor implements AbstractMonitor, ActionListener {
private CustomizedTable table;
private JButton bnClear = new JButton("Clear");
private HashMap<Long, Color> colors = new HashMap<Long, Color>();
private JPanel panel;
- private String name;
- public TableMonitor(String name, int width, int height) {
- this.name = name;
+ public TableMonitor(int width, int height) {
ArrayList<CustomizedColumn> columns = new ArrayList<CustomizedColumn>();
columns.add(new CustomizedColumn("#", Long.class, 60, false));
columns.add(new CustomizedColumn("Time", String.class, 100, false));
columns.add(new CustomizedColumn("Memory", String.class, 100, false));
columns.add(new CustomizedColumn("Message", String.class, Math.max(60, width - 3 * 60), false));
table = new CustomizedTable(columns, true);
table.getColumnModel().getColumn(0).setMinWidth(60);
table.getColumnModel().getColumn(0).setMaxWidth(60);
table.getColumnModel().getColumn(1).setMaxWidth(100);
table.getColumnModel().getColumn(1).setMinWidth(100);
table.getColumnModel().getColumn(2).setMaxWidth(100);
table.getColumnModel().getColumn(2).setMinWidth(100);
RowRenderer renderer = new RowRenderer();
for (int i = 0; i < 4; i++)
table.getColumnModel().getColumn(i).setCellRenderer(renderer);
JScrollPane scroll = new JScrollPane(table);
scroll.setPreferredSize(new Dimension(width, height));
JPanel main = new JPanel(new BorderLayout());
main.add(scroll, BorderLayout.CENTER);
bnClear.addActionListener(this);
panel = new JPanel(new BorderLayout());
panel.add(main);
panel.setBorder(BorderFactory.createEtchedBorder());
}
public JPanel getPanel() {
return panel;
}
@Override
public void clear() {
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.setRowCount(0);
}
@Override
public void add(Message message) {
String msg[] = message.formatArray();
int n = msg.length;
Object[] row = new Object[n + 1];
row[0] = message.getID();
for (int i = 0; i < n; i++)
row[i + 1] = msg[i];
table.append(row);
Verbose level = message.getLevel();
Color c = new Color(0, 0, 0);
if (level == Verbose.Prolix)
c = new Color(255, 0, 0);
else if (level == Verbose.Quiet)
c = new Color(200, 200, 0);
colors.put(new Long(message.getID()), c);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == bnClear) {
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.setRowCount(0);
}
}
@Override
public String getName() {
- return name;
+ return "table";
}
class RowRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
DefaultTableModel model = (DefaultTableModel) table.getModel();
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (row >= 0) {
Long id = (Long) model.getValueAt(row, 0);
Color color = colors.get(id);
c.setForeground(color);
}
return c;
}
}
}
diff --git a/DeconvolutionLab2/src/fft/AbstractFFTLibrary.java b/DeconvolutionLab2/src/fft/AbstractFFTLibrary.java
index f1673ca..3a386ac 100644
--- a/DeconvolutionLab2/src/fft/AbstractFFTLibrary.java
+++ b/DeconvolutionLab2/src/fft/AbstractFFTLibrary.java
@@ -1,56 +1,55 @@
/*
* 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;
import java.util.ArrayList;
public abstract class AbstractFFTLibrary {
protected boolean installed = false;
protected ArrayList<AbstractFFT> ffts = new ArrayList<AbstractFFT>();
public abstract AbstractFFT getDefaultFFT();
public abstract String getLibraryName();
public abstract String getCredit();
public abstract String getLicence();
public abstract String getLocation();
public boolean isInstalled() {
return installed;
}
-
public ArrayList<AbstractFFT> getFFTs() {
return ffts;
}
}
diff --git a/DeconvolutionLab2/src/fft/academic/Academic.java b/DeconvolutionLab2/src/fft/academic/Academic.java
index 1f50501..92e6c6c 100644
--- a/DeconvolutionLab2/src/fft/academic/Academic.java
+++ b/DeconvolutionLab2/src/fft/academic/Academic.java
@@ -1,80 +1,80 @@
/*
* 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.academic;
import deconvolutionlab.monitor.Monitors;
import fft.AbstractFFT;
import fft.Separability;
import signal.ComplexSignal;
import signal.RealSignal;
public class Academic extends AbstractFFT {
private AcademicFFT fftXYZ;
public Academic() {
super(Separability.XYZ);
}
@Override
public void init(Monitors monitors, int nx, int ny, int nz) {
super.init(monitors, nx, ny, nz);
fftXYZ = new AcademicFFT(nx, ny, nz, 0, 0, 0);
}
@Override
public void transformInternal(RealSignal x, ComplexSignal X) {
float imag[] = new float[nx * ny * nz];
float real[] = x.getXYZ();
fftXYZ.directTransform(real, imag, null, null, AcademicFFT.InputDataType.REALINPUT);
X.setXYZ(real, imag);
}
@Override
public void inverseInternal(ComplexSignal X, RealSignal x) {
float real[] = X.getRealXYZ();
float imag[] = X.getImagXYZ();
fftXYZ.inverseTransform(real, imag, null, null);
x.setXYZ(real);
}
@Override
public String getName() {
return "AcademicFFT";
}
@Override
public boolean isMultithreadable() {
- return false;
+ return true;
}
}
diff --git a/DeconvolutionLab2/src/fft/academic/AcademicFFT_XYZ.java b/DeconvolutionLab2/src/fft/academic/AcademicFFT_XYZ.java
index 8ca6d97..df215a1 100644
--- a/DeconvolutionLab2/src/fft/academic/AcademicFFT_XYZ.java
+++ b/DeconvolutionLab2/src/fft/academic/AcademicFFT_XYZ.java
@@ -1,112 +1,112 @@
/*
* 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.academic;
/*
* 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/>.
*/
import deconvolutionlab.monitor.Monitors;
import fft.AbstractFFT;
import fft.Separability;
import signal.ComplexSignal;
import signal.RealSignal;
public class AcademicFFT_XYZ extends AbstractFFT {
private AcademicFFT fftXYZ;
public AcademicFFT_XYZ() {
super(Separability.XYZ);
}
@Override
public void init(Monitors monitors, int nx, int ny, int nz) {
super.init(monitors, nx, ny, nz);
fftXYZ = new AcademicFFT(nx, ny, nz, 0, 0, 0);
}
@Override
public void transformInternal(RealSignal x, ComplexSignal X) {
float imag[] = new float[nx * ny * nz];
float real[] = x.getXYZ();
fftXYZ.directTransform(real, imag, null, null, AcademicFFT.InputDataType.REALINPUT);
X.setXYZ(real, imag);
}
@Override
public void inverseInternal(ComplexSignal X, RealSignal x) {
float real[] = X.getRealXYZ();
float imag[] = X.getImagXYZ();
fftXYZ.inverseTransform(real, imag, null, null);
x.setXYZ(real);
}
@Override
public String getName() {
return "AcademicFFT XYZ";
}
@Override
public boolean isMultithreadable() {
- return false;
+ return true;
}
}
diff --git a/DeconvolutionLab2/src/fft/academic/AcademicFFT_XY_Z.java b/DeconvolutionLab2/src/fft/academic/AcademicFFT_XY_Z.java
index 301ca63..65db81e 100644
--- a/DeconvolutionLab2/src/fft/academic/AcademicFFT_XY_Z.java
+++ b/DeconvolutionLab2/src/fft/academic/AcademicFFT_XY_Z.java
@@ -1,105 +1,105 @@
/*
* 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.academic;
import deconvolutionlab.monitor.Monitors;
import fft.AbstractFFT;
import fft.Separability;
import signal.ComplexSignal;
import signal.RealSignal;
public class AcademicFFT_XY_Z extends AbstractFFT {
private AcademicFFT fftXY;
private AcademicFFT fftZ;
public AcademicFFT_XY_Z() {
super(Separability.XY_Z);
}
@Override
public void init(Monitors monitors, int nx, int ny, int nz) {
super.init(monitors, nx, ny, nz);
fftXY = new AcademicFFT(nx, ny, 0, 0);
fftZ = new AcademicFFT(nz, 0);
}
@Override
public void transformInternal(RealSignal x, ComplexSignal X) {
for (int k = 0; k < nz; k++) {
float real[] = new float[nx * ny];
float imag[] = new float[nx * ny];
System.arraycopy(x.data[k], 0, real, 0, nx * ny);
fftXY.directTransform(real, imag, null, null, AcademicFFT.InputDataType.REALINPUT);
X.setRealXY(k, real);
X.setImagXY(k, imag);
}
for (int i = 0; i < nx; i++)
for (int j = 0; j < ny; j++) {
float real[] = X.getRealZ(i, j);
float imag[] = X.getImagZ(i, j);
fftZ.directTransform(real, imag, null, null, AcademicFFT.InputDataType.COMPLEXINPUT);
X.setRealZ(i, j, real);
X.setImagZ(i, j, imag);
}
}
@Override
public void inverseInternal(ComplexSignal X, RealSignal x) {
for (int k = 0; k < nz; k++) {
float real[] = X.getRealXY(k);
float imag[] = X.getImagXY(k);
fftXY.inverseTransform(real, imag, null, null);
X.setRealXY(k, real);
X.setImagXY(k, imag);
}
for (int i = 0; i < nx; i++)
for (int j = 0; j < ny; j++) {
float real[] = X.getRealZ(i, j);
float imag[] = X.getImagZ(i, j);
fftZ.inverseTransform(real, imag, null, null);
x.setZ(i, j, real);
}
}
@Override
public String getName() {
return "AcademicFFT XY and Z";
}
@Override
public boolean isMultithreadable() {
- return false;
+ return true;
}
}
diff --git a/DeconvolutionLab2/src/fft/fftw/FFTWLibrary.java b/DeconvolutionLab2/src/fft/fftw/FFTWLibrary.java
index b0ceaa2..583854c 100644
--- a/DeconvolutionLab2/src/fft/fftw/FFTWLibrary.java
+++ b/DeconvolutionLab2/src/fft/fftw/FFTWLibrary.java
@@ -1,200 +1,201 @@
/*
* 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.fftw;
import java.io.File;
import java.security.CodeSource;
import deconvolutionlab.monitor.Monitors;
import fft.AbstractFFT;
import fft.AbstractFFTLibrary;
import jfftw.complex.nd.Plan;
public class FFTWLibrary extends AbstractFFTLibrary {
private String location;
+
public FFTWLibrary(Monitors monitors) {
String path = "";
boolean found = false;
if (!found) {
try {
CodeSource code = FFTWLibrary.class.getProtectionDomain().getCodeSource();
File file = new File(code.getLocation().toURI().getPath());
path = file.getParentFile().getPath() + File.separator + "FFTW" + File.separator;
found = existsWidsom(monitors, path);
location = path;
}
catch (Exception ex) {
monitors.log("FFTW Widsom not found in : " + path);
location = "Not found in " + path;
found = false;
}
}
if (!found) {
try {
CodeSource code = FFTWLibrary.class.getProtectionDomain().getCodeSource();
File file = new File(code.getLocation().toURI().getPath());
path = file.getParentFile().getPath() + File.separator;
found = existsWidsom(monitors, path);
location = path;
}
catch (Exception ex) {
monitors.log("FFTW Widsom not found in : " + path);
location = "Not found in " + path;
found = false;
}
}
if (!found) {
try {
path = System.getProperty("user.home") + File.separator + "FFTW" + File.separator;
found = existsWidsom(monitors, path);
location = path;
}
catch (Exception ex) {
monitors.log("FFTW Widsom not found in : " + path);
location = "Not found in " + path;
found = false;
}
}
if (!found) {
try {
path = System.getProperty("user.home") + File.separator;
found = existsWidsom(monitors, path);
location = path;
}
catch (Exception ex) {
monitors.log("FFTW Widsom not found in : " + path);
location = "Not found in " + path;
found = false;
}
}
if (!found)
return;
loadLibraries(monitors, path);
try {
new Plan(new int[] { 20, 20, 20 }, Plan.FORWARD, Plan.ESTIMATE | Plan.IN_PLACE | Plan.USE_WISDOM);
ffts.add(new FFTW3D());
installed = true;
}
catch (UnsatisfiedLinkError ex) {
ex.printStackTrace();
installed = false;
}
}
@Override
public String getLocation() {
return location;
}
@Override
public String getCredit() {
return "http://www.fftw.org (FFTW Version 2)";
}
@Override
public String getLibraryName() {
return "FFTW2";
}
@Override
public String getLicence() {
return "<h1>FFTW Version 2, " + "<p>http://www.fftw.org" + "<p>FFTW 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 2 of the License, or " + "(at your option) any later version.";
}
private static void loadLibraries(Monitors monitors, String path) {
try {
String osname = System.getProperty("os.name");
if (osname.startsWith("Linux")) {
String osarch = System.getProperty("os.arch");
if (osarch.contains("64")) {
System.load(path + "libFFTWJNI64.so");
monitors.log("Loading library FFTW for " + osarch + " " + osname + " " + path + "libFFTWJNI64.so");
}
else {
System.load(path + "libFFTWJNI32.so");
monitors.log("Loading library FFTW for " + osarch + " " + osname + " " + path + "libFFTWJNI32.so");
}
}
else if (osname.startsWith("Windows")) {
String osarch = System.getProperty("os.arch");
if (osarch.contains("64")) {
System.load(path + "FFTWJNIWin64.dll");
monitors.log("Loading library FFTW for " + osarch + " " + osname + " " + path + "FFTWJNIWin64.dll");
}
else {
System.load(path + "FFTWJNIWin32.dll");
monitors.log("Loading library FFTW for " + osarch + " " + osname + " " + path + "FFTWJNIWin32.dll");
}
}
else if (osname.startsWith("Mac")) {
System.load(path + "libFFTWJNIMac.jnilib");
monitors.log("Loading library FFTW for " + osname + " " + path + "libFFTWJNIMac.jnilib");
}
else {
monitors.log("FFTW is not provided for the architecture : " + osname);
}
}
catch (Exception ex) {
monitors.log("FFTW not found in : " + path);
}
}
private static boolean existsWidsom(Monitors monitors, String path) {
boolean found = false;
if (new File(path + "Wisdom").exists()) {
monitors.log("FFTW found in : " + path);
found = true;
}
else {
monitors.log("FFTW Widsom not found in : " + path);
found = false;
}
return found;
}
@Override
public AbstractFFT getDefaultFFT() {
return new FFTW3D();
}
}
diff --git a/DeconvolutionLab2/src/imagej/IJImager.java b/DeconvolutionLab2/src/imagej/IJImager.java
index 02107a1..3157c19 100644
--- a/DeconvolutionLab2/src/imagej/IJImager.java
+++ b/DeconvolutionLab2/src/imagej/IJImager.java
@@ -1,350 +1,351 @@
/*
* 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.Imager;
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 Imager {
@Override
public Platform getPlatform() {
return Imager.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 getActiveImage() {
return build(WindowManager.getCurrentImage());
}
@Override
public RealSignal getImageByName(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, Imager.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, Imager.Type type) { ImagePlus cont = (ImagePlus) container.object;
+ public void append(ContainerImage container, RealSignal signal, String title, Imager.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, Imager.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, Imager.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