Page MenuHomec4science

No OneTemporary

File Metadata

Created
Wed, Sep 11, 10:56
This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/DeconvolutionLab2/DeconvolutionLab2.config b/DeconvolutionLab2/DeconvolutionLab2.config
index ac617a2..e5da39c 100644
--- a/DeconvolutionLab2/DeconvolutionLab2.config
+++ b/DeconvolutionLab2/DeconvolutionLab2.config
@@ -1,97 +1,93 @@
#DeconvolutionLab2
#DeconvolutionLab2
-#Fri Apr 21 17:57:52 CEST 2017
+#Fri Apr 21 22:58:03 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=Richardson-Lucy Total Variation
+Algorithm.algorithm=Non-Negative Least-Square
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.time.enable=false
Controller.time.value=1
Controller.verbose=log
-DeconvolutionLab.DeconvolutionDialog.location.h=400
-DeconvolutionLab.DeconvolutionDialog.location.w=600
-DeconvolutionLab.DeconvolutionDialog.location.x=265
-DeconvolutionLab.DeconvolutionDialog.location.y=516
-DeconvolutionLab.MainDialog.location.h=633
+DeconvolutionLab.MainDialog.location.h=841
DeconvolutionLab.MainDialog.location.w=500
-DeconvolutionLab.MainDialog.location.x=1054
-DeconvolutionLab.MainDialog.location.y=111
+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
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.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.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
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/sage/Desktop/worksmlm/deconvolution/DeconvolutionLab2
+Path.path=/Users/dsage/git/deconvolution/DeconvolutionLab2
Running.Directory=/Users/dsage/git/deconvolution/DeconvolutionLab2
Running.Monitor=table
Running.Path=specify
Running.Verbose=quiet
diff --git a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Resolution.java b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Resolution.java
index de4efb0..6ad69c2 100644
--- a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Resolution.java
+++ b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Resolution.java
@@ -1,157 +1,143 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package course;
import java.io.File;
import javax.swing.filechooser.FileSystemView;
-import deconvolution.Stats;
-import deconvolution.algorithm.Controller;
import deconvolution.algorithm.Convolution;
+import deconvolution.algorithm.LandweberPositivity;
+import deconvolution.algorithm.NaiveInverseFilter;
+import deconvolution.algorithm.RichardsonLucyTV;
+import deconvolution.algorithm.Simulation;
import deconvolutionlab.Lab;
import deconvolutionlab.monitor.Monitors;
+import deconvolutionlab.output.ShowOrtho;
import ij.plugin.PlugIn;
import signal.RealSignal;
import signal.factory.Airy;
import signal.factory.CubeSphericalBeads;
public class DeconvolutionLab2_Course_Resolution implements PlugIn {
private String desktop = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator + "Desktop";
private String root = desktop + File.separator + "Deconvolution" + File.separator;
private String res = root + "results" + File.separator + "resolution" + File.separator;
public DeconvolutionLab2_Course_Resolution() {
Monitors monitors = Monitors.createDefaultMonitor();
new File(res).mkdir();
System.setProperty("user.dir", res);
new File(res + "RIF").mkdir();
new File(res + "LW").mkdir();
new File(res + "LW+").mkdir();
new File(res + "RL").mkdir();
int nx = 128;
int ny = 120;
int nz = 122;
int spacing = 12;
int border = 6;
- RealSignal x = new CubeSphericalBeads(4, 0.1, spacing, border).intensity(400).generate(nx, ny, nz);
+ RealSignal x = new CubeSphericalBeads(4, 0.1, spacing, border).intensity(100).generate(nx, ny, nz);
//RealSignal x = new Sphere(30, 1).generate(nx, ny, nz);
//RealSignal x = new Constant().intensity(0, 255).generate(nx, ny, nz);
//Lab.show(monitors, x, "reference");
//Lab.showOrthoview(x);
//Lab.showMIP(x);
- //Lab.save(monitors, x, res + "ref.tif");
+ Lab.showOrthoview(monitors, x, "Ref", border, border, border);
//RealSignal h = new Gaussian(3, 3, 1).generate(nx, ny, nz);
RealSignal h = new Airy(100, 50, 0.5, 0.1).generate(nx, ny, nz);
Lab.show(monitors, h, "psf");
- Lab.showOrthoview(h);
- Lab.showMIP(h);
- Lab.save(monitors, h, res + "psf.tif");
- Lab.save(monitors, h.createOrthoview(), res + "psfo.tif");
- Lab.save(monitors, h.createMIP(), res + "psfp.tif");
-
- String algo = " ";
- String param = " -reference " + res + "ref.tif -stats show -display no -monitor no -system no";
- String conv = " -image file " + res + "conv.tif ";
- String ref = " -image file " + res + "ref.tif ";
- String psf = " -psf file " + res + "psf.tif ";
-
- Controller controller = new Controller();
- controller.setSystem(true);
- controller.setReference(res + "ref.tif");
- controller.setStatsMode(Stats.Mode.SHOW);
-
- Convolution convo = new Convolution();
- convo.setSystem(true);
- convo.setReference(res + "ref.tif");
-
- RealSignal y = convo.run(x, h);
- Lab.show(y);
-
+ //Lab.showOrthoview(h);
+ //Lab.showMIP(h);
+
+ Convolution convolution = new Convolution();
+ convolution.disableDisplayFinal().disableSystem();
+ convolution.addOutput(new ShowOrtho("convolution"));
+ RealSignal y = convolution.run(x, h);
- /*
- algo = " -algorithm NIF -out mip NIFp ";
- new Deconvolution("nif", conv + psf + algo + param).deconvolve();
-/*
-// algo = " -algorithm TRIF 10e-5 -pad NO NO 0 32 -out mip trifppad -out ortho trifopad ";
-// new Deconvolution("trif", conv + psf + algo + param).deconvolve();
-
- algo = " -algorithm TRIF 10e-5 -out mip TRIFo ";
- new Deconvolution("trif", conv + psf + algo + param).deconvolve();
+ Simulation simulation = new Simulation(0, 0.25, 0);
+ simulation.disableDisplayFinal().disableSystem();
+ simulation.addOutput(new ShowOrtho("simualtion").origin(border, border, border));
+ RealSignal ys = simulation.run(x, h);
+ Lab.showOrthoview(monitors, ys, "Simulation", border, border, border);
+ //Lab.show(y);
- algo = " -algorithm TRIF 10e-5 -pad NO NO 100 100 -out mip TRIFoapo ";
- new Deconvolution("TRIF apo", conv + psf + algo + param).deconvolve();
-
-
-// algo = " -algorithm TRIF 10e-4 -pad NO NO 0 20 -out mip trif_ppad -out ortho trif_opad";
-// new Deconvolution("trif", conv + psf + algo + param).deconvolve();
-
- //algo = " -algorithm TRIF 10e-6 -out mip trif_p -out ortho trif_o -stats show";
- //new Deconvolution("trif", conv + psf + algo + param).deconvolve();
- /*
-
- for(int i=-8; i<=-2; i+=20) {
- algo = " -algorithm TRIF " + Math.pow(10, i) + " -out mip nifp" + i + " -out ortho nifo" + i + " -stats show";
- new Deconvolution("trif", conv + psf + algo + param).deconvolve();
+ NaiveInverseFilter nif = new NaiveInverseFilter();
+ nif.addOutput(new ShowOrtho("nif").origin(border, border, border));
+ nif.disableDisplayFinal().disableSystem().setReference(res + "ref.tif").setStats();
+ nif.run(ys, h);
+ //Lab.show(nifo);
+/*
+ TikhonovRegularizedInverseFilter rif = new TikhonovRegularizedInverseFilter(1e-8);
+ rif.disableDisplayFinal().disableSystem().setReference(res + "ref.tif");
+ rif.addOutput(new ShowOrtho("trif").origin(border, border, border));
+ for(int i=-8; i<=0; i+=1) {
+ rif.setParameters(new double[] {Math.pow(10, i)});
+ RealSignal t = rif.run(ys, h);
+ System.out.println("" + i + " " +Assessment.rmse(t, x));
}
-
- algo = " -algorithm SIM 0 1 0 -out ortho simo -system no -monitor no";
- new Deconvolution("run", ref + psf + algo).deconvolve();
-
- algo = " -algorithm NIF -out ortho nifo -system -monitor";
- new Deconvolution("run", signal + psf + algo).deconvolve();
- for(int i=0; i<=24; i++) {
- double p = Math.pow(10, i-18);
- algo = " -algorithm RIF " + p + " -out ortho @5 RIF/RIF" + i + paramout;
- new Deconvolution("run", signal + psf + algo).deconvolve();
- }
- algo = " -algorithm LW+ 30 1 -out stats @3 LW+ nosave -out ortho @s5 LW+/LW+" + paramout;
- new Deconvolution("run", signal + psf + algo).deconvolve();
- */
+*/
+
+ RichardsonLucyTV rl = new RichardsonLucyTV(100, 0.00001);
+ rl.disableDisplayFinal().disableSystem().setReference(res + "ref.tif").setStats();
+ rl.addOutput(new ShowOrtho("rltv").frequency(1).origin(border, border, border));
+ RealSignal fli = rl.run(ys, h);
+
+//RLTV 0.0001 100 Signals: 167.2 Mb 14.6724 0.9261 n/a
+//RL 100 Signals: 138.6 Mb 14.6688 0.9224 n/a
+//RLTV 0.001 100 Signals: 167.2 Mb 14.6979 0.9515 n/a
+//LW+ 5000 Signals: 311.6 Mb 15.4276 1.6812 n/a
+
+ LandweberPositivity lw = new LandweberPositivity(100, 1.95);
+ lw.disableDisplayFinal().disableSystem().setReference(res + "ref.tif").setStats();
+ lw.addOutput(new ShowOrtho("lw").frequency(20).origin(border, border, border));
+ RealSignal lwi = lw.run(ys, h);
+
+ Lab.show(lwi);
}
public static void main(String arg[]) {
new DeconvolutionLab2_Course_Resolution();
}
@Override
public void run(String arg) {
new DeconvolutionLab2_Course_Resolution();
}
}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/deconvolution/Command.java b/DeconvolutionLab2/src/deconvolution/Command.java
index 969f1fc..3852952 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.Output;
-import deconvolutionlab.Output.View;
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));
if (p.equals("3")) {
monitors.add(new ConsoleMonitor());
monitors.add(new TableMonitor("Monitor", Constants.widthGUI, 240));
}
if (p.equals("console"))
monitors.add(new ConsoleMonitor());
if (p.equals("table"))
monitors.add(new TableMonitor("Monitor", 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 e263ea8..d58bea4 100644
--- a/DeconvolutionLab2/src/deconvolution/Deconvolution.java
+++ b/DeconvolutionLab2/src/deconvolution/Deconvolution.java
@@ -1,398 +1,398 @@
/*
* 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 bilib.tools.NumFormat;
import deconvolution.algorithm.AbstractAlgorithm;
import deconvolution.algorithm.Controller;
import deconvolutionlab.Lab;
-import deconvolutionlab.Output;
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, controller.getStats());
+ 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());
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());
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());
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());
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/algorithm/AbstractAlgorithm.java b/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java
index 699f287..7bb4a73 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java
@@ -1,409 +1,464 @@
/*
* 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.Output;
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) {
- return run(image, psf, new Stats(Stats.Mode.NO));
- }
-
- public RealSignal run(RealSignal image, RealSignal psf, Stats stats) {
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, stats);
+ controller.start(y);
h.circular();
// FFT
fft.init(monitors, y.nx, y.ny, y.nz);
controller.setFFT(fft);
monitors.log(getShortnames()[0] + " data ready");
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]);
result.setName("Output of " + this.getShortnames()[0]);
return result;
}
- public void setController(Controller controller) {
+ 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 void setFFT(AbstractFFT fft) {
+ public AbstractAlgorithm setFFT(AbstractFFT fft) {
this.fft = fft;
controller.setFFT(fft);
+ return this;
}
public String getPath() {
return controller.getPath();
}
- public void setPath(String path) {
+ public AbstractAlgorithm setPath(String path) {
controller.setPath(path);
+ return this;
}
public boolean isSystem() {
return controller.isSystem();
}
- public void setSystem(boolean system) {
- controller.setSystem(system);
+ public AbstractAlgorithm enableSystem() {
+ controller.setSystem(true);
+ return this;
+ }
+
+ public AbstractAlgorithm disableSystem() {
+ controller.setSystem(false);
+ return this;
}
public boolean isMultithreading() {
return controller.isMultithreading();
}
- public void setMultithreading(boolean multithreading) {
- controller.setMultithreading(multithreading);
+ public AbstractAlgorithm enableMultithreading() {
+ controller.setMultithreading(true);
+ return this;
+ }
+
+ public AbstractAlgorithm disableMultithreading() {
+ controller.setMultithreading(false);
+ return this;
}
public boolean isDisplayFinal() {
return controller.isDisplayFinal();
}
- public void setDisplayFinal(boolean displayFinal) {
- controller.setDisplayFinal(displayFinal);
+ public AbstractAlgorithm enableDisplayFinal() {
+ controller.setDisplayFinal(true);
+ return this;
+ }
+
+ public AbstractAlgorithm disableDisplayFinal() {
+ controller.setDisplayFinal(false);
+ return this;
}
public double getNormalizationPSF() {
return controller.getNormalizationPSF();
}
- public void setNormalizationPSF(double normalizationPSF) {
+ public AbstractAlgorithm setNormalizationPSF(double normalizationPSF) {
controller.setNormalizationPSF(normalizationPSF);
+ return this;
}
public double getEpsilon() {
return controller.getEpsilon();
}
- public void setEpsilon(double epsilon) {
+ public AbstractAlgorithm setEpsilon(double epsilon) {
controller.setEpsilon(epsilon);
+ return this;
}
public Padding getPadding() {
return controller.getPadding();
}
- public void setPadding(Padding padding) {
+ public AbstractAlgorithm setPadding(Padding padding) {
controller.setPadding(padding);
+ return this;
}
public Apodization getApodization() {
return controller.getApodization();
}
- public void setApodization(Apodization apodization) {
+ public AbstractAlgorithm setApodization(Apodization apodization) {
controller.setApodization(apodization);
+ return this;
}
public Monitors getMonitors() {
return controller.getMonitors();
}
- public void setMonitors(Monitors monitors) {
+ public AbstractAlgorithm setMonitors(Monitors monitors) {
controller.setMonitors(monitors);
+ return this;
}
public Verbose getVerbose() {
return controller.getVerbose();
}
- public void setVerbose(Verbose verbose) {
+ public AbstractAlgorithm setVerbose(Verbose verbose) {
controller.setVerbose(verbose);
+ return this;
}
public Constraint.Mode getConstraint() {
return controller.getConstraint();
}
- public void setConstraint(Constraint.Mode constraint) {
+ public AbstractAlgorithm setConstraint(Constraint.Mode constraint) {
controller.setConstraint(constraint);
+ return this;
}
public Stats getStats() {
return controller.getStats();
}
- public void setStats(Stats stats) {
+ 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 void setResiduMin(double residuMin) {
+ public AbstractAlgorithm setResiduMin(double residuMin) {
controller.setResiduMin(residuMin);
+ return this;
}
public double getTimeLimit() {
return controller.getTimeLimit();
}
- public void setTimeLimit(double timeLimit) {
+ public AbstractAlgorithm setTimeLimit(double timeLimit) {
controller.setTimeLimit(timeLimit);
+ return this;
}
public String getReference() {
return controller.getReference();
}
- public void setReference(String reference) {
+ public AbstractAlgorithm setReference(String reference) {
controller.setReference(reference);
+ return this;
}
public ArrayList<Output> getOuts() {
return controller.getOuts();
}
- public void setOuts(ArrayList<Output> outs) {
+ public AbstractAlgorithm setOuts(ArrayList<Output> outs) {
controller.setOuts(outs);
+ return this;
}
- public void addOutput(Output out) {
+ public AbstractAlgorithm addOutput(Output out) {
controller.addOutput(out);
+ return this;
}
-
-
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/Algorithm.java b/DeconvolutionLab2/src/deconvolution/algorithm/Algorithm.java
index ff39c53..8bdcb9a 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/Algorithm.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/Algorithm.java
@@ -1,156 +1,156 @@
/*
* 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;
public class Algorithm {
/** This is the static list of all available algorithms. */
private static ArrayList<AbstractAlgorithmPanel> list;
static {
list = new ArrayList<AbstractAlgorithmPanel>();
list.add(new RegularizedInverseFilterPanel());
- list.add(new TikhonovRegularizationInverseFilterPanel());
+ list.add(new TikhonovRegularizedInverseFilterPanel());
list.add(new NaiveInverseFilterPanel());
list.add(new FISTAPanel());
list.add(new ISTAPanel());
list.add(new LandweberPanel());
list.add(new LandweberPositivityPanel());
list.add(new StarkParkerPanel());
list.add(new RichardsonLucyPanel());
list.add(new RichardsonLucyTVPanel());
list.add(new TikhonovMillerPanel());
list.add(new ICTMPanel());
list.add(new VanCittertPanel());
list.add(new IdentityPanel());
list.add(new ConvolutionPanel());
list.add(new SimulationPanel());
list.add(new NonStabilizedDivisionPanel());
}
public static ArrayList<AbstractAlgorithmPanel> getAvailableAlgorithms() {
return list;
}
public static AbstractAlgorithm getDefaultAlgorithm() {
return new Identity();
}
/**
* This static method return the algorithm specify by one of its shortname,
*
* @param shortname
* @return an algorithm
*/
public static AbstractAlgorithm createAlgorithm(String shortname) {
AbstractAlgorithm algo = getDefaultAlgorithm();
String n = shortname.trim().toLowerCase();
int i = 0;
if (list.get(i++).isNamed(n))
algo = new RegularizedInverseFilter(0.1);
else if (list.get(i++).isNamed(n))
- algo = new TikhonovRegularizationInverseFilter(1.0);
+ algo = new TikhonovRegularizedInverseFilter(1.0);
else if (list.get(i++).isNamed(n))
algo = new NaiveInverseFilter();
else if (list.get(i++).isNamed(n))
algo = new FISTA(10, 1, 1, "Haar", 3);
else if (list.get(i++).isNamed(n))
algo = new ISTA(10, 1, 1, "Haar", 3);
else if (list.get(i++).isNamed(n))
algo = new Landweber(10, 1);
else if (list.get(i++).isNamed(n))
algo = new LandweberPositivity(10, 1);
else if (list.get(i++).isNamed(n))
algo = new StarkParker(10, 1);
else if (list.get(i++).isNamed(n))
algo = new RichardsonLucy(10);
else if (list.get(i++).isNamed(n))
algo = new RichardsonLucyTV(10, 1);
else if (list.get(i++).isNamed(n))
algo = new TikhonovMiller(10, 1, 0.1);
else if (list.get(i++).isNamed(n))
algo = new ICTM(10, 1, 0.1);
else if (list.get(i++).isNamed(n))
algo = new VanCittert(10, 1);
else if (list.get(i++).isNamed(n))
algo = new Identity();
else if (list.get(i++).isNamed(n))
algo = new Convolution();
else if (list.get(i++).isNamed(n))
algo = new Simulation(0, 1, 0);
else if (list.get(i++).isNamed(n))
algo = new NonStabilizedDivision();
else
algo = getDefaultAlgorithm();
return algo;
}
/**
* This static method return the panel associated with
* the algorithm specify by one of its shortname,
*
* @param shortname
* @return an algorithm's panel
*/
public static AbstractAlgorithmPanel getPanel(String shortname) {
for (AbstractAlgorithmPanel panel : getAvailableAlgorithms()) {
for(String sn : panel.getShortnames())
if (sn.equals(shortname.trim()))
return panel;
if (panel.getName().equals(shortname.trim()))
return panel;
}
return null;
}
public static ArrayList<String> getShortnames() {
ArrayList<String> list = new ArrayList<String>();
for (AbstractAlgorithmPanel algo : getAvailableAlgorithms()) {
for(String sn : algo.getShortnames())
list.add(sn);
}
return list;
}
public static String getDocumentation(String name) {
for (AbstractAlgorithmPanel algo : getAvailableAlgorithms()) {
if (name.equals(algo.getName()))
return algo.getDocumentation();
}
return "Unknown Algorithm";
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java b/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java
index 0e2b292..0d467a9 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java
@@ -1,631 +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.Output;
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));
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, Stats stats) {
- this.x = x;
- this.stats = stats;
+ 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));
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/algorithm/ConvolutionPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/ConvolutionPanel.java
index 0679d91..58ca3f8 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/ConvolutionPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/ConvolutionPanel.java
@@ -1,72 +1,73 @@
/*
* 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 javax.swing.JPanel;
import bilib.component.GridPanel;
public class ConvolutionPanel extends AbstractAlgorithmPanel {
private Convolution algo = new Convolution();
@Override
public JPanel getPanelParameters() {
GridPanel pn = new GridPanel(false);
pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
return pn;
}
@Override
public String getCommand() {
return "";
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + "</h1>";
+ s += "<h1>" + getName();
+ s += " [<span style=\"color:#FF3333;font-family:georgia\">CONV</span>]</h1>";
s += "<p>This algorithm is only used for simulation. It make a pure convolution of the input image with the PSF in the Fourier domain.</p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/FISTAPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/FISTAPanel.java
index ca37acf..ea96406 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/FISTAPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/FISTAPanel.java
@@ -1,166 +1,168 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.GridPanel;
import bilib.component.SpinnerRangeDouble;
import bilib.component.SpinnerRangeInteger;
import bilib.tools.NumFormat;
import deconvolution.Command;
import deconvolution.RegularizationPanel;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
import wavelets.AbstractWavelets;
import wavelets.Wavelets;
public class FISTAPanel extends AbstractAlgorithmPanel implements KeyListener, ActionListener, ChangeListener {
private SpinnerRangeInteger spnIter = new SpinnerRangeInteger(10, 1, 99999, 1, "###");
private SpinnerRangeDouble spnStep = new SpinnerRangeDouble(1, 0, 2, 0.1, "#.#");
private RegularizationPanel reg;
private JComboBox<String> cmbWav = new JComboBox<String>(Wavelets.getWaveletsAsArray());
private JComboBox<String> cmbScale = new JComboBox<String>(new String[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" });
private FISTA algo = new FISTA(10, 1, 0.1, "Haar", 3);
@Override
public JPanel getPanelParameters() {
AbstractWavelets wavdef = Wavelets.getDefaultWavelets();
double[] params = algo.getDefaultParameters();
reg = new RegularizationPanel(params[2]);
spnIter.setPreferredSize(Constants.dimParameters);
spnStep.setPreferredSize(Constants.dimParameters);
cmbWav.setPreferredSize(Constants.dimParameters);
cmbScale.setPreferredSize(Constants.dimParameters);
GridPanel pn = new GridPanel(false);
pn.place(1, 0, "<html><span \"nowrap\"><b>Iterations</b></span></html>");
pn.place(1, 1, "<html><span \"nowrap\"><i>N</i></span></html>");
pn.place(1, 2, spnIter);
pn.place(1, 3, "<html><span \"nowrap\">Step <i>&gamma;</i></span></html>");
pn.place(1, 4, spnStep);
pn.place(2, 0, 5, 1, reg);
pn.place(5, 0, "<html><span \"nowrap\"><b>Wavelets</b></span></html>");
pn.place(5, 2, cmbWav);
pn.place(5, 3, "<html>Scale</html>");
pn.place(5, 4, cmbScale);
Config.register("Algorithm." + algo.getShortnames()[0], "iterations", spnIter, params[0]);
Config.register("Algorithm." + algo.getShortnames()[0], "step", spnStep, params[1]);
Config.register("Algorithm." + algo.getShortnames()[0], "wavelets", cmbWav, wavdef.getName());
Config.register("Algorithm." + algo.getShortnames()[0], "scale", cmbScale, wavdef.getScales());
Config.register("Algorithm." + algo.getShortnames()[0], "reg", reg.getText(), "0.1");
reg.getText().addKeyListener(this);
reg.getSlider().addChangeListener(this);
spnIter.addChangeListener(this);
spnStep.addChangeListener(this);
cmbWav.addActionListener(this);
cmbScale.addActionListener(this);
return pn;
}
@Override
public String getCommand() {
int iter = spnIter.get();
double gamma = spnStep.get();
double lambda = reg.getValue();
String waveletsName = (String) cmbWav.getSelectedItem();
int scale = Integer.parseInt((String) cmbScale.getSelectedItem());
return iter + " " + NumFormat.nice(gamma) + " " + NumFormat.nice(lambda) + " " + waveletsName + " " + scale;
}
@Override
public void actionPerformed(ActionEvent e) {
Command.command();
}
@Override
public void stateChanged(ChangeEvent e) {
reg.getText().removeKeyListener(this);
reg.updateFromSlider();
Command.command();
reg.getText().addKeyListener(this);
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
reg.getSlider().removeChangeListener(this);
reg.updateFromText();
Command.command();
reg.getSlider().addChangeListener(this);
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + " (FISTA)</h1>";
- s += "<p>Iterative: " + algo.isIterative() + "</p>";
- s += "<p>Step controllable: " + algo.isStepControllable() + "</p>";
- s += "<p>Regularization: " + algo.isRegularized() + "</p>";
- s += "<p>Wavelet-base: " + algo.isWaveletsBased() + "</p>";
- s += "<p></p>";
- s += "<h3>Reference: Beck and Teboulle, SIAM <b>2</b> 2009</h3>";
+ s += "<h1>" + getName();
+ s += " [<span style=\"color:#FF3333;font-family:georgia\">FISTA</span>]</h1>";
+ s += "<p>FISTA exploits the sparsity of the wavelet domain to better preserve ";
+ s += "image details and discontinuities. The associated cost function is: </p>";
+ s += "<p>C(<b>x</b>) = | <b>y</b> - <b>H</b><b>x</b> | + &lambda; |<b>W</b><b>x</b>|<sub>1</sub> </p>";
+ s += "<p>where <b>W</b> represents a wavelet transform. ";
+ s += "Due to the non-smoothness of the l<sub>1</sub> norm, ";
+ s += "the problem can be solved efficiently by fast iterative soft-thresholding </p>";
+ s += "<p>Reference: A. Beck, M. Teboulle, A fast iterative shrinkage-thresholding algorithm for linear inverse problems, SIAM J. Imag. Sci. 2, 2009. ";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/ICTMPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/ICTMPanel.java
index 01c1f54..724d85e 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/ICTMPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/ICTMPanel.java
@@ -1,146 +1,142 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.GridPanel;
import bilib.component.SpinnerRangeDouble;
import bilib.component.SpinnerRangeInteger;
import bilib.tools.NumFormat;
import deconvolution.Command;
import deconvolution.RegularizationPanel;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
public class ICTMPanel extends AbstractAlgorithmPanel implements KeyListener, ActionListener, ChangeListener {
private SpinnerRangeInteger spnIter = new SpinnerRangeInteger(10, 1, 99999, 1, "###");
private SpinnerRangeDouble spnStep = new SpinnerRangeDouble(1, 0, 2, 0.1, "#.#");
private RegularizationPanel reg;
private ICTM algo = new ICTM(10, 0.1, 1);
@Override
public JPanel getPanelParameters() {
double[] params = algo.getDefaultParameters();
spnIter.setPreferredSize(Constants.dimParameters);
spnStep.setPreferredSize(Constants.dimParameters);
reg = new RegularizationPanel(params[2]);
GridPanel pn = new GridPanel(false);
pn.place(1, 0, "<html><span \"nowrap\"><b>Iterations</b></span></html>");
pn.place(1, 1, "<html><span \"nowrap\"><i>N</i></span></html>");
pn.place(1, 2, spnIter);
pn.place(1, 3, "<html><span \"nowrap\">Step <i>&gamma;</i></span></html>");
pn.place(1, 4, spnStep);
pn.place(2, 0, 5, 1, reg);
Config.register("Algorithm." + algo.getShortnames()[0], "iterations", spnIter, params[0]);
Config.register("Algorithm." + algo.getShortnames()[0], "step", spnStep, params[1]);
Config.register("Algorithm." + algo.getShortnames()[0], "reg", reg.getText(), "0.1");
reg.getText().addKeyListener(this);
reg.getSlider().addChangeListener(this);
spnIter.addChangeListener(this);
spnStep.addChangeListener(this);
return pn;
}
@Override
public String getCommand() {
double gamma = spnStep.get();
double lambda = reg.getValue();
return spnIter.get() + " " + NumFormat.nice(gamma) + " " + NumFormat.nice(lambda);
}
@Override
public void actionPerformed(ActionEvent e) {
Command.command();
}
@Override
public void stateChanged(ChangeEvent e) {
reg.getText().removeKeyListener(this);
reg.updateFromSlider();
Command.command();
reg.getText().addKeyListener(this);
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
reg.getSlider().removeChangeListener(this);
reg.updateFromText();
Command.command();
reg.getSlider().addChangeListener(this);
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>Iterative: " + algo.isIterative() + "</p>";
- s += "<p>Step controllable: " + algo.isStepControllable() + "</p>";
- s += "<p>Regularization: " + algo.isRegularized() + "</p>";
- s += "<p>Wavelet-base: " + algo.isWaveletsBased() + "</p>";
- String shortname = "<p>Shortname: ";
- for(String name : getShortnames())
- shortname += name + " ";
- s += shortname + "</p>";
+ s += "<h1>" + getName();
+ s += " [<span style=\"color:#FF3333;font-family:georgia\">ICTM</span>]</h1>";
+ s += "<p>TM algorithm uses iterative gradient descent to minimize the regularized inverse filter cost.</p>";
+ s += "<p>The iterative scheme allows nonnegativity constraint at each iteration.</p>";
+ s += "<p>Reference: H. Van der Voort, K. Strasters, Restoration of confocal images for quantitative image analysis. J of Microscopy 178, 165-181, 1995</p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/ISTAPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/ISTAPanel.java
index 8b6d089..1383e3b 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/ISTAPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/ISTAPanel.java
@@ -1,168 +1,166 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.GridPanel;
import bilib.component.SpinnerRangeDouble;
import bilib.component.SpinnerRangeInteger;
import bilib.tools.NumFormat;
import deconvolution.Command;
import deconvolution.RegularizationPanel;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
import wavelets.AbstractWavelets;
import wavelets.Wavelets;
public class ISTAPanel extends AbstractAlgorithmPanel implements KeyListener, ActionListener, ChangeListener {
private SpinnerRangeInteger spnIter = new SpinnerRangeInteger(10, 1, 99999, 1);
private SpinnerRangeDouble spnStep = new SpinnerRangeDouble(1, 0, 2, 0.1);
private RegularizationPanel reg;
private JComboBox<String> cmbWav = new JComboBox<String>(Wavelets.getWaveletsAsArray());
private JComboBox<String> cmbScale = new JComboBox<String>(new String[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" });
private ISTA algo = new ISTA(0, 1, 0.1, "Haar", 3);
@Override
public JPanel getPanelParameters() {
AbstractWavelets wavdef = Wavelets.getDefaultWavelets();
double[] params = algo.getDefaultParameters();
reg = new RegularizationPanel(params[2]);
spnIter.setPreferredSize(Constants.dimParameters);
spnStep.setPreferredSize(Constants.dimParameters);
cmbWav.setPreferredSize(Constants.dimParameters);
cmbScale.setPreferredSize(Constants.dimParameters);
GridPanel pn = new GridPanel(false);
pn.place(1, 0, "<html><span \"nowrap\"><b>Iterations</b></span></html>");
pn.place(1, 1, "<html><span \"nowrap\"><i>N</i></span></html>");
pn.place(1, 2, spnIter);
pn.place(1, 3, "<html><span \"nowrap\">Step <i>&gamma;</i></span></html>");
pn.place(1, 4, spnStep);
pn.place(2, 0, 5, 1, reg);
pn.place(5, 0, "<html><span \"nowrap\"><b>Wavelets</b></span></html>");
pn.place(5, 2, cmbWav);
pn.place(5, 3, "<html>Scale</html>");
pn.place(5, 4, cmbScale);
Config.register("Algorithm." + algo.getShortnames()[0], "iterations", spnIter, params[0]);
Config.register("Algorithm." + algo.getShortnames()[0], "step", spnStep, params[1]);
Config.register("Algorithm." + algo.getShortnames()[0], "wavelets", cmbWav, wavdef.getName());
Config.register("Algorithm." + algo.getShortnames()[0], "scale", cmbScale, wavdef.getScales());
Config.register("Algorithm." + algo.getShortnames()[0], "reg", reg.getText(), "0.1");
reg.getText().addKeyListener(this);
reg.getSlider().addChangeListener(this);
spnIter.addChangeListener(this);
spnStep.addChangeListener(this);
cmbWav.addActionListener(this);
cmbScale.addActionListener(this);
return pn;
}
@Override
public String getCommand() {
int iter = spnIter.get();
double gamma = spnStep.get();
double lambda = reg.getValue();
String waveletsName = (String) cmbWav.getSelectedItem();
int scale = Integer.parseInt((String) cmbScale.getSelectedItem());
return iter + " " + NumFormat.nice(gamma) + " " + NumFormat.nice(lambda) + " " + waveletsName + " " + scale;
}
@Override
public void actionPerformed(ActionEvent e) {
Command.command();
}
@Override
public void stateChanged(ChangeEvent e) {
reg.getText().removeKeyListener(this);
reg.updateFromSlider();
Command.command();
reg.getText().addKeyListener(this);
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
reg.getSlider().removeChangeListener(this);
reg.updateFromText();
Command.command();
reg.getSlider().addChangeListener(this);
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>Iterative: " + algo.isIterative() + "</p>";
- s += "<p>Step controllable: " + algo.isStepControllable() + "</p>";
- s += "<p>Regularization: " + algo.isRegularized() + "</p>";
- s += "<p>Wavelet-base: " + algo.isWaveletsBased() + "</p>";
- String shortname = "<p>Shortname: ";
- for(String name : getShortnames())
- shortname += name + " ";
- s += shortname + "</p>";
+ s += "<h1>" + getName();
+ s += " [<span style=\"color:#FF3333;font-family:georgia\">ISTA</span>]</h1>";
+ s += "<p>ISTA exploits the sparsity of the wavelet domain to better preserve ";
+ s += "image details and discontinuities. The associated cost function is: </p>";
+ s += "<p>C(<b>x</b>) = | <b>y</b> - <b>H</b><b>x</b> | + &lambda; |<b>W</b><b>x</b>|<sub>1</sub> </p>";
+ s += "<p>where <b>W</b> represents a wavelet transform. ";
+ s += "<p>Reference: An EM algorithm for wavelet-based image restoration, MAT Figueiredo, RD Nowak, Image Processing, IEEE Transactions on 12 (8), 2003. ";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
index dbcc779..bb41c3b 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
@@ -1,72 +1,73 @@
/*
* 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 javax.swing.JPanel;
import bilib.component.GridPanel;
public class IdentityPanel extends AbstractAlgorithmPanel {
private Identity algo = new Identity();
@Override
public JPanel getPanelParameters() {
GridPanel pn = new GridPanel(false);
pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
return pn;
}
@Override
public String getCommand() {
return "";
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
+ s += "<h1>" + getName();
+ s += " [<span style=\"color:#FF3333;font-family:georgia\">I</span>]</h1>";
+ s += "<p>This algorithm does nothing. It returns a copy of the input image.</p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPanel.java
index 50bf183..6b9f79d 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPanel.java
@@ -1,112 +1,110 @@
/*
* 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 javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.GridPanel;
import bilib.component.SpinnerRangeDouble;
import bilib.component.SpinnerRangeInteger;
import bilib.tools.NumFormat;
import deconvolution.Command;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
public class LandweberPanel extends AbstractAlgorithmPanel implements ChangeListener {
private SpinnerRangeInteger spnIter = new SpinnerRangeInteger(10, 1, 99999, 1);
private SpinnerRangeDouble spnStep = new SpinnerRangeDouble(1, 0, 2, 0.1);
private Landweber algo = new Landweber(10, 1);
@Override
public JPanel getPanelParameters() {
double[] params = algo.getDefaultParameters();
spnIter.setPreferredSize(Constants.dimParameters);
spnStep.setPreferredSize(Constants.dimParameters);
GridPanel pn = new GridPanel(false);
pn.place(1, 0, "<html><span \"nowrap\"><b>Iterations</b></span></html>");
pn.place(1, 1, "<html><span \"nowrap\"><i>N</i></span></html>");
pn.place(1, 2, spnIter);
pn.place(1, 3, "<html><span \"nowrap\">Step <i>&gamma;</i></span></html>");
pn.place(1, 4, spnStep);
pn.place(2, 0, "<html><span \"nowrap\"><b>Regularization</b></span></html>");
pn.place(2, 1, 4, 1, "<html><span \"nowrap\">No regularization</i></span></html>");
Config.register("Algorithm." + algo.getShortnames()[0], "iterations", spnIter, params[0]);
Config.register("Algorithm." + algo.getShortnames()[0], "step", spnStep, params[1]);
spnIter.addChangeListener(this);
spnStep.addChangeListener(this);
return pn;
}
@Override
public String getCommand() {
int iter = spnIter.get();
double gamma = spnStep.get();
return iter + " " + NumFormat.nice(gamma);
}
@Override
public void stateChanged(ChangeEvent e) {
Command.command();
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>Iterative: " + algo.isIterative() + "</p>";
- s += "<p>Step controllable: " + algo.isStepControllable() + "</p>";
- s += "<p>Regularization: " + algo.isRegularized() + "</p>";
- s += "<p>Wavelet-base: " + algo.isWaveletsBased() + "</p>";
- String shortname = "<p>Shortname: ";
- for(String name : getShortnames())
- shortname += name + " ";
- s += shortname + "</p>";
+ s += "<h1>" + getName();
+ s += " [<span style=\"color:#FF3333;font-family:georgia\">LW</span> | ";
+ s += " <span style=\"color:#FF3333;font-family:georgia\">LLS</span>]</h1>";
+ s += "<p>The Landweber algorithm known as Linear Least-Square (LLS) minimizes the same least-squares cost function than NIF.</p>";
+ s += "<p>The Landweber algorithm proceeds by an iterative gradient-descent approach which allows ";
+ s += " to impose a nonnegativity constraint at each iteration (see LW+ or NLLS algorithm).</p>";
+ s += "<p>Reference: L. Landweber, An iteration formula for fredholm integral equations of the first kind, Am. J. Math. 73, 1951. ";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivity.java b/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivity.java
index 90fcda7..bfc1240 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivity.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivity.java
@@ -1,149 +1,149 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Constraint;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
public class LandweberPositivity extends AbstractAlgorithm implements Callable<RealSignal> {
private double gamma = 1.0;
public LandweberPositivity(int iterMax, double gamma) {
super();
this.iterMax = iterMax;
controller.setConstraint(Constraint.Mode.NONNEGATIVE);
this.gamma = gamma;
}
@Override
// Landweber algorithm
// X(n+1) = X(n) + g*H*(Y-H*X(n))
// => X(n+1) = X(n) - g*H*H*X(n) + g*H*Y
// => X(n+1) = X(n) * (I-g*H*H) + g*H*Y
// => pre-compute: A = (I-g*H*H) and G = g*H*Y
// => Iteration : X(n+1) = X(n) * A + G with F(0) = G
public RealSignal call() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal A = Operations.delta(gamma, H);
ComplexSignal G = Operations.multiplyConjugate(gamma, H, Y);
ComplexSignal X = G.duplicate();
controller.setConstraint(Constraint.Mode.NONNEGATIVE);
SignalCollector.free(Y);
SignalCollector.free(H);
while (!controller.ends(X)) {
X.times(A);
X.plus(G);
}
SignalCollector.free(A);
SignalCollector.free(G);
RealSignal x = fft.inverse(X);
SignalCollector.free(X);
return x;
}
@Override
public String getName() {
- return "Non-Negative Least-Square";
+ return "Non-Linear Least-Square";
}
@Override
public String[] getShortnames() {
return new String[] {"NNLS", "LW+"};
}
@Override
public int getComplexityNumberofFFT() {
return 3 + iterMax * 2;
}
@Override
public double getMemoryFootprintRatio() {
return 10.0;
}
@Override
public boolean isRegularized() {
return false;
}
@Override
public boolean isStepControllable() {
return true;
}
@Override
public boolean isIterative() {
return true;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
public void setParameters(double[] params) {
if (params == null)
return;
if (params.length > 0)
iterMax = (int) Math.round(params[0]);
if (params.length > 1)
gamma = (float) params[1];
}
@Override
public double[] getDefaultParameters() {
return new double[] { 10, 1 };
}
@Override
public double[] getParameters() {
return new double[] { iterMax, gamma };
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return gamma;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivityPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivityPanel.java
index 49c6d3c..bbbb263 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivityPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivityPanel.java
@@ -1,112 +1,108 @@
/*
* 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 javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.GridPanel;
import bilib.component.SpinnerRangeDouble;
import bilib.component.SpinnerRangeInteger;
import bilib.tools.NumFormat;
import deconvolution.Command;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
public class LandweberPositivityPanel extends AbstractAlgorithmPanel implements ChangeListener {
private SpinnerRangeInteger spnIter = new SpinnerRangeInteger(10, 1, 99999, 1);
private SpinnerRangeDouble spnStep = new SpinnerRangeDouble(1, 0, 2, 0.1);
private LandweberPositivity algo = new LandweberPositivity(10, 1);
@Override
public JPanel getPanelParameters() {
double[] params = algo.getDefaultParameters();
spnIter.setPreferredSize(Constants.dimParameters);
spnStep.setPreferredSize(Constants.dimParameters);
GridPanel pn = new GridPanel(false);
pn.place(1, 0, "<html><span \"nowrap\"><b>Iterations</b></span></html>");
pn.place(1, 1, "<html><span \"nowrap\"><i>N</i></span></html>");
pn.place(1, 2, spnIter);
pn.place(1, 3, "<html><span \"nowrap\">Step <i>&gamma;</i></span></html>");
pn.place(1, 4, spnStep);
pn.place(2, 0, "<html><span \"nowrap\"><b>Regularization</b></span></html>");
pn.place(2, 1, 4, 1, "<html><span \"nowrap\">No regularization</i></span></html>");
Config.register("Algorithm." + algo.getShortnames()[0], "iterations", spnIter, params[0]);
Config.register("Algorithm." + algo.getShortnames()[0], "step", spnStep, params[1]);
spnIter.addChangeListener(this);
spnStep.addChangeListener(this);
return pn;
}
@Override
public String getCommand() {
int iter = spnIter.get();
double gamma = spnStep.get();
return iter + " " + NumFormat.nice(gamma);
}
@Override
public void stateChanged(ChangeEvent e) {
Command.command();
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>Iterative: " + algo.isIterative() + "</p>";
- s += "<p>Step controllable: " + algo.isStepControllable() + "</p>";
- s += "<p>Regularization: " + algo.isRegularized() + "</p>";
- s += "<p>Wavelet-base: " + algo.isWaveletsBased() + "</p>";
- String shortname = "<p>Shortname: ";
- for(String name : getShortnames())
- shortname += name + " ";
- s += shortname + "</p>";
+ s += "<h1>" + getName();
+ s += " [<span style=\"color:#FF3333;font-family:georgia\">LW+</span> | ";
+ s += " <span style=\"color:#FF3333;font-family:georgia\">NNLS</span>]</h1>";
+ s += "<p>The Landweber+ algorithm known as Non-Negative Least-Square (NLLS) minimizes a least-squares cost function with a non-negative constraint.</p>";
+ s += "<p>Reference: L. Landweber, An iteration formula for fredholm integral equations of the first kind, Am. J. Math. 73, 1951. ";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/NaiveInverseFilterPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/NaiveInverseFilterPanel.java
index d79e65f..1813afc 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/NaiveInverseFilterPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/NaiveInverseFilterPanel.java
@@ -1,75 +1,76 @@
/*
* 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 javax.swing.JPanel;
import bilib.component.GridPanel;
public class NaiveInverseFilterPanel extends AbstractAlgorithmPanel {
private NaiveInverseFilter algo = new NaiveInverseFilter();
@Override
public JPanel getPanelParameters() {
GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
+ pn.place(1, 0, "<html><span \"nowrap\">NIF is parameter-free</span></html>");
return pn;
}
@Override
public String getCommand() {
return "";
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<h3>Shortname: NIF or IF</p>";
- s += "<p>This is the classical inverse filter.</p>";
- s += "<p>This algorithm only performs a stabilized division in the Fourier domain.</p>";
- s += "<p>The stabilization is controlled by the machine epsilon parameter &Epsilon; set by default at 1E-6.</p>";
+ s += "<h1>" + getName();
+ s += " [<span style=\"color:#FF3333;font-family:georgia\">NIF</span> | ";
+ s += " <span style=\"color:#FF3333;font-family:georgia\">IF</span>] </h1>";
+ s += "<p>The simplest approach to deconvolution consists in minimizing a least-squares cost function. ";
+ s += "Unfortunately, the NIF tends to amplify measurement noise, resulting in spurious high-frequency oscillations. ";
+ s += "It corresponds to maximum-likelihood estimation in the presence of Gaussian noise. ";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/NonStabilizedDivisionPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/NonStabilizedDivisionPanel.java
index e3484bf..c191dfe 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/NonStabilizedDivisionPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/NonStabilizedDivisionPanel.java
@@ -1,79 +1,73 @@
/*
* 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 javax.swing.JPanel;
import bilib.component.GridPanel;
public class NonStabilizedDivisionPanel extends AbstractAlgorithmPanel {
private NonStabilizedDivision algo = new NonStabilizedDivision();
@Override
public JPanel getPanelParameters() {
GridPanel pn = new GridPanel(false);
pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
return pn;
}
@Override
public String getCommand() {
return "";
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>Iterative: " + algo.isIterative() + "</p>";
- s += "<p>Step controllable: " + algo.isStepControllable() + "</p>";
- s += "<p>Regularization: " + algo.isRegularized() + "</p>";
- s += "<p>Wavelet-base: " + algo.isWaveletsBased() + "</p>";
- String shortname = "<p>Shortname: ";
- for(String name : getShortnames())
- shortname += name + " ";
- s += shortname + "</p>";
+ s += "<h1>" + getName() ;
+ s += " [<span style=\"color:#FF3333;font-family:georgia\">DIV</span>]</h1>";
+ s += "<p>It makes a division in the Fourier domain. Not stabilization is applied.";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/RegularizedInverseFilterPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/RegularizedInverseFilterPanel.java
index 0de764e..f815035 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/RegularizedInverseFilterPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/RegularizedInverseFilterPanel.java
@@ -1,115 +1,124 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.GridPanel;
import bilib.tools.NumFormat;
import deconvolution.Command;
import deconvolution.RegularizationPanel;
import deconvolutionlab.Config;
public class RegularizedInverseFilterPanel extends AbstractAlgorithmPanel implements KeyListener, ChangeListener {
private RegularizationPanel reg;
private RegularizedInverseFilter algo = new RegularizedInverseFilter(0.1);
@Override
public JPanel getPanelParameters() {
double[] params = algo.getDefaultParameters();
reg = new RegularizationPanel(params[0]);
GridPanel pn = new GridPanel(false);
pn.place(0, 0, reg);
Config.register("Algorithm." + algo.getShortnames()[0], "reg", reg.getText(), "0.1");
reg.getText().addKeyListener(this);
reg.getSlider().addChangeListener(this);
return pn;
}
@Override
public String getCommand() {
return NumFormat.nice(reg.getValue());
}
@Override
public void stateChanged(ChangeEvent e) {
reg.getText().removeKeyListener(this);
reg.updateFromSlider();
Command.command();
reg.getText().addKeyListener(this);
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
reg.getSlider().removeChangeListener(this);
reg.updateFromText();
Command.command();
reg.getSlider().addChangeListener(this);
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<h2>Shortname RIF or LRIF</h2>";
- s += "<p>Laplacian Regularized Inverse Filter</p>";
- s += "<p>This is a inverse filter with a Laplacian regularization that tends to have an effect on high frequency</p>";
- s += "<p>It is very fast, non-iterative algorithm</p>";
- s += "<p>The regularization blurs the noise and the image. It is controlled by &lambda;</p>";
+ s += "<h1>" + getName();
+ s += " [<span style=\"color:#FF3333;font-family:georgia\">RIF</span> | ";
+ s += " <span style=\"color:#FF3333;font-family:georgia\">LRIF</span>] </h1>";
+ s += "<p><i>Laplacian Regularized Inverse Filter</i></p>";
+ s += "<p>This algorithm is a direct inverse filter with a Laplacian regularization following this formalization: ";
+ s += "<b>x</b> = (<b>H</b><sup>T</sup><b>H</b> + &lambda; <b>L</b><sup>T</sup><b>L</b>)<sup>-1</sup> <b>H</b><sup>T</sup><b>y</b>";
+ s += "<p> where <b>H</b> is the PSF and <b>L</b> is the discretization of the Laplacian operator. ";
+ s += "This regularization tends to reduce high frequencies noisy and in the same time ";
+ s += "it tends to blur the image. It is controlled by the regularization factor &lambda;. ";
+ s += "</p>";
+ s += "<p>RIF or LRIF is very fast. It is non-iterative algorithm</p>";
+ s += "<p>When the filtering by <b>L</b><sup>T</sup><b>L</b> has a whitening effect on <b>x</b> ";
+ s += "and &lambda; is defined as the inverse of the noise variance, RIF amounts to Wiener filtering.</p>";
+
+ s += "<p>Reference: N. Wiener, Extrapolation, Interpolation, and Smoothing of Stationary Time Series, vol. 2, MIT press Cambridge, 1949.</p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucy.java b/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucy.java
index 4a25f4b..db83522 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucy.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucy.java
@@ -1,141 +1,141 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
public class RichardsonLucy extends AbstractAlgorithm implements Callable<RealSignal> {
- public RichardsonLucy(int iter) {
+ public RichardsonLucy(int iterMax) {
super();
this.iterMax = iterMax;
}
// x(k+1) = x(k) *. Hconj * ( y /. H x(k))
@Override
public RealSignal call() {
ComplexSignal H = fft.transform(h);
ComplexSignal U = new ComplexSignal("RL-U", y.nx, y.ny, y.nz);
RealSignal x = y.duplicate();
RealSignal p = y.duplicate();
RealSignal u = y.duplicate();
while (!controller.ends(x)) {
fft.transform(x, U);
U.times(H);
fft.inverse(U, u);
Operations.divide(y, u, p);
fft.transform(p, U);
U.timesConjugate(H);
fft.inverse(U, u);
x.times(u);
}
SignalCollector.free(H);
SignalCollector.free(p);
SignalCollector.free(u);
SignalCollector.free(U);
return x;
}
@Override
public String getName() {
return "Richardson-Lucy";
}
@Override
public String[] getShortnames() {
return new String[] {"RL"};
}
@Override
public int getComplexityNumberofFFT() {
return 1 + 5 * iterMax;
}
@Override
public double getMemoryFootprintRatio() {
return 9.0;
}
@Override
public boolean isRegularized() {
return false;
}
@Override
public boolean isStepControllable() {
return false;
}
@Override
public boolean isIterative() {
return true;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
public void setParameters(double[] params) {
if (params == null)
return;
if (params.length > 0)
iterMax = (int) Math.round(params[0]);
}
@Override
public double[] getDefaultParameters() {
return new double[] { 10 };
}
@Override
public double[] getParameters() {
return new double[] { iterMax };
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return 0;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyPanel.java
index dc2ce21..13bc401 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyPanel.java
@@ -1,94 +1,96 @@
/*
* 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 javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.GridPanel;
import bilib.component.SpinnerRangeInteger;
import deconvolution.Command;
import deconvolutionlab.Config;
public class RichardsonLucyPanel extends AbstractAlgorithmPanel implements ChangeListener {
private SpinnerRangeInteger spnIter = new SpinnerRangeInteger(10, 1, 99999, 1);
private RichardsonLucy algo = new RichardsonLucy(10);
@Override
public JPanel getPanelParameters() {
double[] params = algo.getDefaultParameters();
GridPanel pn = new GridPanel(false);
pn.place(1, 0, "<html><span \"nowrap\"><b>Iterations</b></span></html>");
pn.place(1, 1, "<html><span \"nowrap\"><i>N</i></span></html>");
pn.place(1, 2, spnIter);
Config.register("Algorithm." + algo.getShortnames()[0], "iterations", spnIter, params[0]);
spnIter.addChangeListener(this);
return pn;
}
@Override
public String getCommand() {
return "" + spnIter.get();
}
@Override
public void stateChanged(ChangeEvent e) {
Command.command();
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<h2> Shortname: RL</h2>";
-
+ s += "<h1>" + getName() + "";
+ s += " [<span style=\"color:#FF3333;font-family:georgia\">RL</span>]</h1>";
s += "<p>This is the well-known Richardson-Lucy algorithm.</p>";
s += "<p>It is an iterative with a slow convergence, it has only one parameter to tune: the maximum number of iterations</p>";
- s += "<p>RL is well appropiate for dominant Poison noise.</p>";
+ s += "<p>RL assumes that the noise follows a Poisson distribution.</p>";
s += "<p>It is a maximum likelihood estimator (MLE).</p>";
s += "<p>Warning: the input image should have only positive values</p>";
+ s += "<p>References:</p>";
+ s += "<p>W.H. Richardson, Bayesian-based iterative method of image restoration, J. Optical Soc. Am. 62, 1972.";
+ s += "<p>L.B. Lucy, An iterative technique for the rectification of observed distributions, Astrophys. J. 79 (6), 1974.";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyTVPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyTVPanel.java
index 5fb9be6..8d666b6 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyTVPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyTVPanel.java
@@ -1,130 +1,130 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.GridPanel;
import bilib.component.SpinnerRangeInteger;
import bilib.tools.NumFormat;
import deconvolution.Command;
import deconvolution.RegularizationPanel;
import deconvolutionlab.Config;
public class RichardsonLucyTVPanel extends AbstractAlgorithmPanel implements KeyListener, ActionListener, ChangeListener {
private SpinnerRangeInteger spnIter = new SpinnerRangeInteger(10, 1, 99999, 1);
private RegularizationPanel reg;
private RichardsonLucyTV algo = new RichardsonLucyTV(10, 0.1);
@Override
public JPanel getPanelParameters() {
double[] params = algo.getDefaultParameters();
reg = new RegularizationPanel(params[1]);
GridPanel pn = new GridPanel(false);
pn.place(1, 0, "<html><span \"nowrap\"><b>Iterations</b></span></html>");
pn.place(1, 1, "<html><span \"nowrap\"><i>N</i></span></html>");
pn.place(1, 2, spnIter);
pn.place(2, 0, 3, 1, reg);
Config.register("Algorithm." + algo.getShortnames()[0], "reg", reg.getText(), "0.1");
reg.getText().addKeyListener(this);
reg.getSlider().addChangeListener(this);
spnIter.addChangeListener(this);
return pn;
}
@Override
public String getCommand() {
double lambda = reg.getValue();
return spnIter.get() + " " + NumFormat.nice(lambda);
}
@Override
public void stateChanged(ChangeEvent e) {
reg.getText().removeKeyListener(this);
reg.updateFromSlider();
Command.command();
reg.getText().addKeyListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
Command.command();
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
reg.getSlider().removeChangeListener(this);
reg.updateFromText();
Command.command();
reg.getSlider().addChangeListener(this);
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<h2> Shortname: RLTV</h2>";
+ s += "<h1>" + getName();
+ s += " [<span style=\"color:#FF3333;font-family:georgia\">RLTV</span>]</h1>";
s += "<p>This algorithm is a combinaison of the Richardson–Lucy algorithm with a regularization constraint based on Total Variation, which tends to reduce unstable oscillations while preserving object edges.</p>";
- s += "<p>It is a iterative algorithm, relative slow to compute the Total Variation at every iteration.s</p>";
- s += "<p>It has a weighted parameter &lamdba; to control the effect of the total variation.</p>";
+ s += "<p>It is a iterative algorithm, relative slow to compute the Total Variation at every iteration.</p>";
+ s += "<p>It has a weighted parameter &lambda; to control the effect of the total variation.</p>";
s += "<p></p>";
- s += "<h3>Reference: Dey et al., Microscopy Research and Technics, 2006.</p>";
+ s += "<h3>Reference: N. Dey et al., Richardson–Lucy algorithm with total variation regularization for 3D confocal microscope deconvolution, Microsc. Res. Tech. 69, 2006. </p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/SimulationPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/SimulationPanel.java
index 8f721c1..579e371 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/SimulationPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/SimulationPanel.java
@@ -1,114 +1,115 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import javax.swing.JTextField;
import bilib.component.GridPanel;
import deconvolution.Command;
import deconvolutionlab.Config;
public class SimulationPanel extends AbstractAlgorithmPanel implements KeyListener {
private JTextField txtMean;
private JTextField txtStdev;
private JTextField txtPoisson;
private Simulation algo = new Simulation(0, 0, 0);
@Override
public JPanel getPanelParameters() {
double[] params = algo.getDefaultParameters();
txtMean = new JTextField("" + params[0], 5);
txtStdev = new JTextField("" + params[1], 5);
txtPoisson = new JTextField("" + params[2], 5);
GridPanel pn = new GridPanel(false);
pn.place(1, 0, "<html>Gaussian (Mean)</html>");
pn.place(1, 2, txtMean);
pn.place(2, 0, "<html>Gaussian (Stdev)</html>");
pn.place(2, 2, txtStdev);
pn.place(3, 0, "<html>Poisson</html>");
pn.place(3, 2, txtPoisson);
txtMean.addKeyListener(this);
txtStdev.addKeyListener(this);
txtPoisson.addKeyListener(this);
Config.register("Algorithm." + algo.getShortnames()[0], "gaussian.mean", txtMean, params[0]);
Config.register("Algorithm." + algo.getShortnames()[0], "gaussian.stdev", txtStdev, params[1]);
Config.register("Algorithm." + algo.getShortnames()[0], "poisson", txtPoisson, params[2]);
return pn;
}
@Override
public String getCommand() {
return txtMean.getText() + " " + txtStdev.getText() + " " + txtPoisson.getText();
}
@Override
public void keyTyped(KeyEvent e) {
Command.command();
}
@Override
public void keyPressed(KeyEvent e) {
Command.command();
}
@Override
public void keyReleased(KeyEvent e) {
Command.command();
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + "</h1>";
+ s += "<h1>" + getName();
+ s += " [<span style=\"color:#FF3333;font-family:georgia\">SIM</span>]</h1>";
s += "<p>This algorithm is only used for simulation. It convolves the input image with the PSF and adds some noise.</p>";
s += "<p>The noise has a Gaussian distribution (mean, stdev) and a Poisson distribution (poisson).</p>";
return s;
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/StarkParkerPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/StarkParkerPanel.java
index 6009cc6..8ce334f 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/StarkParkerPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/StarkParkerPanel.java
@@ -1,110 +1,109 @@
/*
* 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 javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.GridPanel;
import bilib.component.SpinnerRangeDouble;
import bilib.component.SpinnerRangeInteger;
import bilib.tools.NumFormat;
import deconvolution.Command;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
public class StarkParkerPanel extends AbstractAlgorithmPanel implements ChangeListener {
private SpinnerRangeInteger spnIter = new SpinnerRangeInteger(10, 1, 99999, 1);
private SpinnerRangeDouble spnStep = new SpinnerRangeDouble(1, 0, 2, 0.1);
private StarkParker algo = new StarkParker(10, 1);
@Override
public JPanel getPanelParameters() {
double[] params = algo.getDefaultParameters();
spnIter.setPreferredSize(Constants.dimParameters);
spnStep.setPreferredSize(Constants.dimParameters);
GridPanel pn = new GridPanel(false);
pn.place(1, 0, "<html><span \"nowrap\"><b>Iterations</b></span></html>");
pn.place(1, 1, "<html><span \"nowrap\"><i>N</i></span></html>");
pn.place(1, 2, spnIter);
pn.place(1, 3, "<html><span \"nowrap\">Step <i>&gamma;</i></span></html>");
pn.place(1, 4, spnStep);
pn.place(2, 0, "<html><span \"nowrap\"><b>Regularization</b></span></html>");
pn.place(2, 1, 4, 1, "<html><span \"nowrap\">No regularization</i></span></html>");
Config.register("Algorithm." + algo.getShortnames()[0], "iterations", spnIter, params[0]);
Config.register("Algorithm." + algo.getShortnames()[0], "step", spnStep, params[1]);
spnIter.addChangeListener(this);
spnStep.addChangeListener(this);
return pn;
}
@Override
public String getCommand() {
int iter = spnIter.get();
double gamma = spnStep.get();
return iter + " " + NumFormat.nice(gamma);
}
@Override
public void stateChanged(ChangeEvent e) {
Command.command();
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<h1>Stark-Parker Algorithm</p>";
- s += "<h2>Shortname: BVLS or SP</p>";
- s += "<p>This algorithm also known as Stark-Parker algorithm is a least squares variant with a bounded-variable constraint.</p>";
- s += "<p>In this implementation, the bounds are the bounds of the input image.</p>";
- s += "<p></p>";
- s += "<p>Reference: Stark and Parker, Computational Statistics <b>10</b>, 1995.</p>";
+ s += "<h1>" + getName();
+ s += " [<span style=\"color:#FF3333;font-family:georgia\">BVLS</span> | ";
+ s += " <span style=\"color:#FF3333;font-family:georgia\">SP</span>]</h1>";
+ s += "<p>The Bounded-Variables Least-Square algorithm is known also as Spark-Parker (SP) algorithm. ";
+ s += "It minimizes a least-squares cost function with a clipped values constraint.</p>";
+ s += "<p>Reference: P. Stark, R. Parker, Bounded-variable least-squares: an algorithm and applications. Computational Statistics 10, 1995.";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovMillerPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovMillerPanel.java
index 8b5ef79..3348628 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovMillerPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovMillerPanel.java
@@ -1,146 +1,140 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.GridPanel;
import bilib.component.SpinnerRangeDouble;
import bilib.component.SpinnerRangeInteger;
import bilib.tools.NumFormat;
import deconvolution.Command;
import deconvolution.RegularizationPanel;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
public class TikhonovMillerPanel extends AbstractAlgorithmPanel implements KeyListener, ActionListener, ChangeListener {
private SpinnerRangeInteger spnIter = new SpinnerRangeInteger(10, 1, 99999, 1, "###");
private SpinnerRangeDouble spnStep = new SpinnerRangeDouble(1, 0, 2, 0.1, "#.#");
private RegularizationPanel reg;
private TikhonovMiller algo = new TikhonovMiller(10, 1, 0.1);
@Override
public JPanel getPanelParameters() {
double[] params = algo.getDefaultParameters();
spnIter.setPreferredSize(Constants.dimParameters);
spnStep.setPreferredSize(Constants.dimParameters);
reg = new RegularizationPanel(params[2]);
GridPanel pn = new GridPanel(false);
pn.place(1, 0, "<html><span \"nowrap\"><b>Iterations</b></span></html>");
pn.place(1, 1, "<html><span \"nowrap\"><i>N</i></span></html>");
pn.place(1, 2, spnIter);
pn.place(1, 3, "<html><span \"nowrap\">Step <i>&gamma;</i></span></html>");
pn.place(1, 4, spnStep);
pn.place(2, 0, 5, 1, reg);
Config.register("Algorithm." + algo.getShortnames()[0], "iterations", spnIter, params[0]);
Config.register("Algorithm." + algo.getShortnames()[0], "step", spnStep, params[1]);
Config.register("Algorithm." + algo.getShortnames()[0], "reg", reg.getText(), "0.1");
reg.getText().addKeyListener(this);
reg.getSlider().addChangeListener(this);
spnIter.addChangeListener(this);
spnStep.addChangeListener(this);
return pn;
}
@Override
public String getCommand() {
double gamma = spnStep.get();
double lambda = reg.getValue();
return spnIter.get() + " " + NumFormat.nice(gamma) + " " + NumFormat.nice(lambda);
}
@Override
public void actionPerformed(ActionEvent e) {
Command.command();
}
@Override
public void stateChanged(ChangeEvent e) {
reg.getText().removeKeyListener(this);
reg.updateFromSlider();
Command.command();
reg.getText().addKeyListener(this);
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
reg.getSlider().removeChangeListener(this);
reg.updateFromText();
Command.command();
reg.getSlider().addChangeListener(this);
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>Iterative: " + algo.isIterative() + "</p>";
- s += "<p>Step controllable: " + algo.isStepControllable() + "</p>";
- s += "<p>Regularization: " + algo.isRegularized() + "</p>";
- s += "<p>Wavelet-base: " + algo.isWaveletsBased() + "</p>";
- String shortname = "<p>Shortname: ";
- for(String name : getShortnames())
- shortname += name + " ";
- s += shortname + "</p>";
-
+ s += "<h1>" + getName();
+ s += " [<span style=\"color:#FF3333;font-family:georgia\">TM</span>]</h1>";
+ s += "<p>TM algorithm uses iterative gradient descent to minimize the regularized inverse filter cost.</p>";
+ s += "<p>The iterative scheme allows nonnegativity constraint at each iteration (see ICTM).</p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizationInverseFilter.java b/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizedInverseFilter.java
similarity index 94%
rename from DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizationInverseFilter.java
rename to DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizedInverseFilter.java
index 09cca2c..f1d6eb9 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizationInverseFilter.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizedInverseFilter.java
@@ -1,184 +1,183 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
import signal.factory.complex.ComplexSignalFactory;
-public class TikhonovRegularizationInverseFilter extends AbstractAlgorithm implements Callable<RealSignal> {
+public class TikhonovRegularizedInverseFilter extends AbstractAlgorithm implements Callable<RealSignal> {
private double lambda = 0.1;
- public TikhonovRegularizationInverseFilter(double lambda) {
+ public TikhonovRegularizedInverseFilter(double lambda) {
super();
this.lambda = lambda;
}
@Override
public RealSignal call() {
if (optimizedMemoryFootprint)
return runOptimizedMemoryFootprint();
else
return runTextBook();
}
public RealSignal runTextBook() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal H2 = Operations.multiply(H, H);
ComplexSignal I = ComplexSignalFactory.identity(Y.nx, Y.ny, Y.nz);
I.times((float)lambda);
ComplexSignal FA = Operations.add(H2, I);
ComplexSignal FT = Operations.divideStabilized(H, FA);
ComplexSignal X = Operations.multiply(Y, FT);
RealSignal x = fft.inverse(X);
SignalCollector.free(FT);
SignalCollector.free(Y);
SignalCollector.free(H);
SignalCollector.free(FA);
SignalCollector.free(I);
SignalCollector.free(H2);
SignalCollector.free(X);
return x;
}
public RealSignal runOptimizedMemoryFootprint() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal X = filter(Y, H);
SignalCollector.free(H);
SignalCollector.free(Y);
RealSignal x = fft.inverse(X);
SignalCollector.free(X);
return x;
}
private ComplexSignal filter(ComplexSignal Y, ComplexSignal H) {
int nx = H.nx;
int ny = H.ny;
int nz = H.nz;
int nxy = nx * ny*2;
float ya, yb, ha, hb, fa, fb, mag, ta, tb;
float epsilon2 = (float)(Operations.epsilon * Operations.epsilon);
ComplexSignal result = new ComplexSignal("TRIF", nx, ny, nz);
float l = (float)lambda;
for(int k=0; k<nz; k++)
for(int i=0; i< nxy; i+=2) {
ha = H.data[k][i];
hb = H.data[k][i+1];
ya = Y.data[k][i];
yb = Y.data[k][i+1];
fa = ha*ha - hb*hb + l;
fb = 2f * ha * hb;
mag = fa*fa + fb*fb;
ta = (ha*fa + hb*fb) / (mag >= epsilon2 ? mag : epsilon2);
tb = (hb*fa - ha*fb) / (mag >= epsilon2 ? mag : epsilon2);
result.data[k][i] = ya*ta - yb*tb;
result.data[k][i+1] = ya*tb + ta*yb;
}
return result;
}
@Override
public int getComplexityNumberofFFT() {
return 3;
}
@Override
public String getName() {
- return "Tikhonov Regularization";
+ return "Tikhonov Regularization Inverse Filter";
}
@Override
public String[] getShortnames() {
- return new String[] {"TRIF"};
+ return new String[] {"TRIF", "TR"};
}
-
@Override
public double getMemoryFootprintRatio() {
return 8.0;
}
@Override
public boolean isRegularized() {
return true;
}
@Override
public boolean isStepControllable() {
return false;
}
@Override
public boolean isIterative() {
return false;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
public void setParameters(double[] params) {
if (params == null)
return;
if (params.length > 0)
lambda = (float)params[0];
}
@Override
public double[] getDefaultParameters() {
return new double[] {0.1};
}
@Override
public double[] getParameters() {
return new double[] {lambda};
}
@Override
public double getRegularizationFactor() {
return lambda;
}
@Override
public double getStepFactor() {
return 0.0;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizationInverseFilterPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizedInverseFilterPanel.java
similarity index 68%
rename from DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizationInverseFilterPanel.java
rename to DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizedInverseFilterPanel.java
index 1f1ac0a..eba186a 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizationInverseFilterPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizedInverseFilterPanel.java
@@ -1,123 +1,131 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.GridPanel;
import bilib.tools.NumFormat;
import deconvolution.Command;
import deconvolution.RegularizationPanel;
import deconvolutionlab.Config;
-public class TikhonovRegularizationInverseFilterPanel extends AbstractAlgorithmPanel implements ActionListener, ChangeListener, KeyListener {
+public class TikhonovRegularizedInverseFilterPanel extends AbstractAlgorithmPanel implements ActionListener, ChangeListener, KeyListener {
private RegularizationPanel reg;
- private TikhonovRegularizationInverseFilter algo = new TikhonovRegularizationInverseFilter(0.1);
+ private TikhonovRegularizedInverseFilter algo = new TikhonovRegularizedInverseFilter(0.1);
@Override
public JPanel getPanelParameters() {
double[] params = algo.getDefaultParameters();
reg = new RegularizationPanel(params[0]);
GridPanel pn = new GridPanel(false);
pn.place(0, 0, reg);
Config.register("Algorithm." + algo.getShortnames()[0], "reg", reg.getText(), "0.1");
reg.getText().addKeyListener(this);
reg.getSlider().addChangeListener(this);
return pn;
}
@Override
public String getCommand() {
return NumFormat.nice(reg.getValue());
}
@Override
public void stateChanged(ChangeEvent e) {
reg.getText().removeKeyListener(this);
reg.updateFromSlider();
Command.command();
reg.getText().addKeyListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
Command.command();
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
reg.getSlider().removeChangeListener(this);
reg.updateFromText();
Command.command();
reg.getSlider().addChangeListener(this);
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<h2>Shortname TRIF</h2>";
- s += "<p>Iterative: " + algo.isIterative() + "</p>";
- s += "<p>Step controllable: " + algo.isStepControllable() + "</p>";
- s += "<p>Regularization: " + algo.isRegularized() + "</p>";
- s += "<p>Wavelet-base: " + algo.isWaveletsBased() + "</p>";
+ s += "<h1>" + getName();
+ s += " [<span style=\"color:#FF3333;font-family:georgia\">TRIF</span> | ";
+ s += " <span style=\"color:#FF3333;font-family:georgia\">TR</span>] </h1>";
+ s += "<p>This algorithm is a direct inverse filter with a Tikhonov regularization following this formalization: ";
+ s += "<b>x</b> = (<b>H</b><sup>T</sup><b>H</b> + &lambda; <b>I</b>)<sup>-1</sup> <b>H</b><sup>T</sup><b>y</b>";
+ s += "<p> where <b>H</b> is the PSF and <b>I</b> is the identity operator. ";
+ s += "This regularization tends to reduce high frequencies noisy and in the same time ";
+ s += "it tends to blur the image. It is controlled by the regularization factor &lambda;. ";
+ s += "</p>";
+ s += "<p>TRIF or TR is very fast. It is non-iterative algorithm. </p>";
+ s += "<p>This formulation can also be interpreted as a maximum a posteriori model.";
+ s += "The regularization introduces prior information about the signal to guide the estimation.</p>";
+
+ s += "<p>Reference: A. Tikhonov, Solution of incorrectly formulated problems and the regularization method, Soviet Mathematics Dokl., vol. 5, 1963.</p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/VanCittertPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/VanCittertPanel.java
index fd2551c..debc0c7 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/VanCittertPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/VanCittertPanel.java
@@ -1,109 +1,104 @@
/*
* 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 javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.GridPanel;
import bilib.component.SpinnerRangeDouble;
import bilib.component.SpinnerRangeInteger;
import bilib.tools.NumFormat;
import deconvolution.Command;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
public class VanCittertPanel extends AbstractAlgorithmPanel implements ChangeListener {
private SpinnerRangeInteger spnIter = new SpinnerRangeInteger(10, 1, 99999, 1);
private SpinnerRangeDouble spnStep = new SpinnerRangeDouble(1, 0, 2, 0.1);
private VanCittert algo = new VanCittert(10, 1);
@Override
public JPanel getPanelParameters() {
double[] params = algo.getDefaultParameters();
spnIter.setPreferredSize(Constants.dimParameters);
spnStep.setPreferredSize(Constants.dimParameters);
GridPanel pn = new GridPanel(false);
pn.place(1, 0, "<html><span \"nowrap\"><b>Iterations</b></span></html>");
pn.place(1, 1, "<html><span \"nowrap\"><i>N</i></span></html>");
pn.place(1, 2, spnIter);
pn.place(1, 3, "<html><span \"nowrap\">Step <i>&gamma;</i></span></html>");
pn.place(1, 4, spnStep);
Config.register("Algorithm." + algo.getShortnames()[0], "iterations", spnIter, params[0]);
Config.register("Algorithm." + algo.getShortnames()[0], "step", spnStep, params[1]);
spnIter.addChangeListener(this);
spnStep.addChangeListener(this);
return pn;
}
@Override
public String getCommand() {
int iter = spnIter.get();
double gamma = spnStep.get();
return iter + " " + NumFormat.nice(gamma);
}
@Override
public void stateChanged(ChangeEvent e) {
Command.command();
}
@Override
public String getName() {
return algo.getName();
}
@Override
public String[] getShortnames() {
return algo.getShortnames();
}
@Override
public String getDocumentation() {
String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>Iterative: " + algo.isIterative() + "</p>";
- s += "<p>Step controllable: " + algo.isStepControllable() + "</p>";
- s += "<p>Regularization: " + algo.isRegularized() + "</p>";
- s += "<p>Wavelet-base: " + algo.isWaveletsBased() + "</p>";
- String shortname = "<p>Shortname: ";
- for(String name : getShortnames())
- shortname += name + " ";
- s += shortname + "</p>";
+ s += "<h1>" + getName();
+ s += " [<span style=\"color:#FF3333;font-family:georgia\">VC</span>]</h1>";
+ s += "<p>The simplest iterative algorithm for image deconvolution is the Van Cittert algorithm (1930)</p>";
+ s += "<p>The algorithm is sensitive to the presence of noise and tends to increase the noise </p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/Lab.java b/DeconvolutionLab2/src/deconvolutionlab/Lab.java
index 4bd3f9d..fd001aa 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/Lab.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/Lab.java
@@ -1,524 +1,532 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab;
import java.io.File;
import java.util.ArrayList;
import java.util.regex.Pattern;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import bilib.tools.NumFormat;
import bilib.tools.WebBrowser;
import deconvolutionlab.Imager.ContainerImage;
import deconvolutionlab.monitor.Monitors;
import fft.AbstractFFT;
import fft.AbstractFFTLibrary;
import fft.FFT;
import imagej.IJImager;
import plugins.sage.deconvolutionlab.IcyImager;
import signal.ComplexComponent;
import signal.ComplexSignal;
import signal.RealSignal;
import signal.factory.SignalFactory;
import signal.factory.Sphere;
/**
* This class contains a collection of useful static methods to manage all the
* peripherical aspects of the deconvolution, such as load, display, or save an
* image.
* <p>
* At the construction of the class, the config is loaded. In practice, any
* deconvolution program has to start with Lab.init(Platform).
*
* @author Daniel Sage
*
*/
public class Lab {
private static Imager imaging;
private static ArrayList<JFrame> frames;
private static ArrayList<JDialog> dialogs;
static {
frames = new ArrayList<JFrame>();
dialogs = new ArrayList<JDialog>();
imaging = new IJImager();
Config.init(System.getProperty("user.dir") + File.separator + "DeconvolutionLab2.config");
}
/**
* Initializes the Lab with a give platform.
*
* @param platform
* The platform is ImageJ, ICY, or Matlab.
*/
public static void init(Imager.Platform platform) {
init(platform, System.getProperty("user.dir") + File.separator + "DeconvolutionLab2.config");
}
/**
* Initializes the Lab with a give platform and a given configuration file
*
* @param platform
* @param configFilename
*/
public static void init(Imager.Platform platform, String configFilename) {
switch (platform) {
case IMAGEJ:
imaging = new IJImager();
break;
case ICY:
imaging = new IcyImager();
break;
default:
imaging = new IJImager();
break;
}
Config.init(configFilename);
}
/**
* Returns the platform.
*
* @return
*/
public static Imager.Platform getPlatform() {
return imaging.getPlatform();
}
/**
* Open a web page on the DeconvolutionLab2.
*/
public static void help() {
WebBrowser.open(Constants.url);
}
/**
* Checks the installed FFT libraries on a small (40, 30, 20) signal.
*
* @param monitors
*/
public static void checkFFT(Monitors monitors) {
ArrayList<AbstractFFTLibrary> libraries = FFT.getInstalledLibraries();
for (AbstractFFTLibrary library : libraries) {
RealSignal y = new Sphere(3, 1).generate(40, 30, 20);
double chrono = System.nanoTime();
AbstractFFT fft = library.getDefaultFFT();
fft.init(monitors, y.nx, y.ny, y.nz);
RealSignal x = fft.inverse(fft.transform(y));
chrono = System.nanoTime() - chrono;
double residu = y.getEnergy() - x.getEnergy();
monitors.log("\t residu of reconstruction: " + residu);
monitors.log("\t computation time (" + x.nx + "x" + x.ny + "x" + x.nz + ") " + NumFormat.time(chrono));
}
}
public static ContainerImage createContainer(Monitors monitors, String title) {
monitors.log("Create Live Real Signal " + title);
return imaging.createContainer(title);
}
public static void append(Monitors monitors, ContainerImage container, RealSignal signal, String title) {
imaging.append(container, signal, title, Imager.Type.FLOAT);
monitors.log("Add Live Real Signal " + title);
}
public static void append(Monitors monitors, ContainerImage container, RealSignal signal, String title, Imager.Type type) {
imaging.append(container, signal, title, type);
monitors.log("Add Live Real Signal " + title);
}
/**
* Displays a the module of complex signal.
*
* @param monitors
* @param signal
* @param title
*/
public static void show(Monitors monitors, ComplexSignal signal, String title) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, ComplexComponent.MODULE);
}
/**
* Displays a real 3D signal a z-stack of images.
*
* @param signal
*/
public static void show(RealSignal signal) {
if (signal == null) {
return;
}
imaging.show(signal, signal.name, Imager.Type.FLOAT, signal.nz / 2);
}
/**
* Displays a real 3D signal a z-stack of images.
*
* @param monitors
* @param signal
*/
public static void show(Monitors monitors, RealSignal signal) {
if (signal == null) {
monitors.error("This image does not exist.");
return;
}
monitors.log("Show Real Signal " + signal.name);
imaging.show(signal, signal.name, Imager.Type.FLOAT, signal.nz / 2);
}
/**
* Displays a real 3D signal a z-stack of images.
*
* @param monitors
* @param signal
* @param title
*/
public static void show(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, Imager.Type.FLOAT, signal.nz / 2);
}
/**
* Displays a real 3D signal a z-stack of images using a given type.
*
* @param monitors
* @param signal
* @param title
* @param type
*/
public static void show(Monitors monitors, RealSignal signal, String title, Imager.Type type) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, type, signal.nz / 2);
}
/**
* Displays a real 3D signal a z-stack of images using a given type and
* shows the slice number z.
*
* @param monitors
* @param signal
* @param title
* @param type
* @param z
*/
public static void show(Monitors monitors, RealSignal signal, String title, Imager.Type type, int z) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, type, z);
}
+ public static void save(Monitors monitors, RealSignal signal, String path, String name) {
+ save(monitors, signal, path + File.separator + name + ".tif", Imager.Type.FLOAT);
+ }
+
+ public static void save(Monitors monitors, RealSignal signal, String path, String name, Imager.Type type) {
+ save(monitors, signal, path + File.separator + name + ".tif", type);
+ }
+
public static void save(Monitors monitors, RealSignal signal, String filename) {
imaging.save(signal, filename, Imager.Type.FLOAT);
monitors.log("Save Real Signal " + filename);
}
public static void save(Monitors monitors, RealSignal signal, String filename, Imager.Type type) {
imaging.save(signal, filename, type);
monitors.log("Save Real Signal " + filename);
}
public static RealSignal createSynthetic(Monitors monitors, String cmd) {
RealSignal signal = SignalFactory.createFromCommand(cmd);
if (signal == null)
monitors.error("Unable to create " + cmd);
else
monitors.log("Create " + cmd);
return signal;
}
/**
* Return the active image.
*
* @return
*/
public static RealSignal getImage() {
return getImager().getActiveImage();
}
/**
* Return an image from the platform with a specified name.
*
* @param name
* @return
*/
public static RealSignal getImage(String name) {
return getImager().getImageByName(name);
}
/**
* Return an image from the platform with a specified name.
*
* @param monitors
* @param name
* @return
*/
public static RealSignal getImage(Monitors monitors, String name) {
RealSignal signal = getImager().getImageByName(name);
if (signal == null)
monitors.error("Unable to get " + name);
else
monitors.log("Load " + name);
return signal;
}
/**
* Open an image from the disk.
*
* @param filename
* @return
*/
public static RealSignal openFile(String filename) {
return imaging.open(filename);
}
/**
* Open an image from the disk.
*
* @param monitors
* @param filename
* @return
*/
public static RealSignal openFile(Monitors monitors, String filename) {
RealSignal signal = imaging.open(filename);
if (signal == null)
monitors.error("Unable to open " + filename);
else
monitors.log("Load " + filename);
return signal;
}
/**
* Open a series of image from a directory.
*
* @param path
* @return
*/
public static RealSignal openDir(String path) {
return openDir(Monitors.createDefaultMonitor(), path);
}
/**
* Open a series of image from a directory.
*
* @param monitors
* @param path
* @return
*/
public static RealSignal openDir(Monitors monitors, String path) {
String parts[] = path.split(" pattern ");
String dirname = path;
String regex = "";
if (parts.length == 2) {
dirname = parts[0].trim();
regex = parts[1].trim();
}
File file = new File(dirname + File.separator);
if (!file.isDirectory()) {
monitors.error("Dir " + dirname + " is not a directory.");
return null;
}
String[] list = file.list();
ArrayList<RealSignal> slices = new ArrayList<RealSignal>();
int nx = 0;
int ny = 0;
Pattern pattern = Pattern.compile(regex);
for (String filename : list) {
if (pattern.matcher(filename).find()) {
RealSignal slice = imaging.open(dirname + File.separator + filename);
if (slice != null) {
slices.add(slice);
nx = Math.max(nx, slice.nx);
ny = Math.max(ny, slice.ny);
monitors.log("Image " + path + File.separator + filename + " is loaded.");
}
}
else {
monitors.error("Error in loading image " + path + File.separator + filename);
}
}
int nz = slices.size();
if (nz <= 0) {
monitors.error("Dir " + path + " do no contain valid images.");
return null;
}
RealSignal signal = new RealSignal(file.getName(), nx, ny, nz);
for (int z = 0; z < slices.size(); z++)
signal.setSlice(z, slices.get(z));
return signal;
}
public static void showOrthoview(RealSignal signal, String title, int hx, int hy, int hz) {
if (signal == null) {
return;
}
imaging.show(signal.createOrthoview(hx, hy, hz), title, Imager.Type.FLOAT, 0);
}
public static void showOrthoview(Monitors monitors, RealSignal signal, String title, int hx, int hy, int hz) {
if (signal == null) {
monitors.error("Show Orthoview " + title + " this image does not exist.");
return;
}
imaging.show(signal.createOrthoview(hx, hy, hz), title, Imager.Type.FLOAT, 0);
}
public static void showOrthoview(RealSignal signal) {
if (signal == null) {
return;
}
int hx = signal.nx / 2;
int hy = signal.ny / 2;
int hz = signal.nz / 2;
imaging.show(signal.createOrthoview(hx, hy, hz), signal.name, Imager.Type.FLOAT, 0);
}
public static void showOrthoview(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show Orthoview " + title + " this image does not exist.");
return;
}
int hx = signal.nx / 2;
int hy = signal.ny / 2;
int hz = signal.nz / 2;
imaging.show(signal.createOrthoview(hx, hy, hz), title, Imager.Type.FLOAT, 0);
}
public static void showMIP(RealSignal signal) {
if (signal == null) {
return;
}
imaging.show(signal.createMIP(), signal.name, Imager.Type.FLOAT, 0);
}
public static void showMIP(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show MIP " + title + " this image does not exist.");
return;
}
imaging.show(signal.createMIP(), title, Imager.Type.FLOAT, 0);
}
public static void showPlanar(RealSignal signal) {
if (signal == null) {
return;
}
- imaging.show(signal.createMontage(), signal.name, Imager.Type.FLOAT, 0);
+ imaging.show(signal.createPlanar(), signal.name, Imager.Type.FLOAT, 0);
}
public static void showPlanar(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show Planar " + title + " this image does not exist.");
return;
}
- imaging.show(signal.createMontage(), title, Imager.Type.FLOAT, 0);
+ imaging.show(signal.createPlanar(), title, Imager.Type.FLOAT, 0);
}
/*
public static RealSignal create(Monitors monitors, String name) {
RealSignal signal = imaging.create(name);
if (signal != null)
monitors.log("Created the real signal " + name + " " + signal.toString());
else
monitors.error("Impossible to create the real signal " + name);
return signal;
}
public static RealSignal create(Monitors monitors) {
RealSignal signal = imaging.create();
if (signal != null)
monitors.log("Created the real signal from the active window " + signal.toString());
else
monitors.error("Impossible to create the real signal from the active window");
return signal;
}
*/
public static Imager getImager() {
return imaging;
}
public static String getActiveImage() {
if (imaging.isSelectable())
return imaging.getSelectedImage();
return "";
}
public static void setVisible(JDialog dialog, boolean modal) {
if (dialog == null)
return;
dialogs.add(dialog);
imaging.setVisible(dialog, modal);
}
public static void setVisible(JPanel panel, String name, int x, int y) {
JFrame frame = new JFrame(name);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocation(x, y);
frame.setVisible(true);
frames.add(frame);
}
public static void setVisible(JFrame frame) {
frames.add(frame);
frame.setVisible(true);
}
public static void close() {
for (JFrame frame : frames)
if (frame != null)
frame.dispose();
for (JDialog dialog : dialogs)
if (dialog != null)
dialog.dispose();
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/dialog/OutputDialog.java b/DeconvolutionLab2/src/deconvolutionlab/dialog/OutputDialog.java
index 399ca5e..7d0c63c 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/dialog/OutputDialog.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/dialog/OutputDialog.java
@@ -1,274 +1,283 @@
/*
* 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.dialog;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.GridPanel;
import bilib.component.HTMLPane;
import bilib.component.SpinnerRangeInteger;
import deconvolutionlab.Imager;
-import deconvolutionlab.Output;
-import deconvolutionlab.Output.Dynamic;
-import deconvolutionlab.Output.View;
+import deconvolutionlab.output.Output;
+import deconvolutionlab.output.Output.Action;
+import deconvolutionlab.output.Output.Dynamic;
+import deconvolutionlab.output.Output.View;
import ij.gui.GUI;
public class OutputDialog extends JDialog implements ActionListener, ChangeListener {
private JComboBox<String> cmbDynamic = new JComboBox<String>(new String[] { "intact", "rescaled", "normalized", "clipped" });
private JComboBox<String> cmbType = new JComboBox<String>(new String[] { "float", "short", "byte" });
private JCheckBox chkSave = new JCheckBox("Save output", true);
private JCheckBox chkShow = new JCheckBox("Show output", true);
private SpinnerRangeInteger snpSnapshot = new SpinnerRangeInteger(0, 0, 99999, 1);
private JComboBox<String> cmbSnapshot = new JComboBox<String>(new String[] { "Final Output", "Specify Iterations..." });
private SpinnerRangeInteger spnX = new SpinnerRangeInteger(128, 0, 99999, 1);
private SpinnerRangeInteger spnY = new SpinnerRangeInteger(128, 0, 99999, 1);
private SpinnerRangeInteger spnZ = new SpinnerRangeInteger(32, 0, 99999, 1);
private JTextField txtName = new JTextField("Noname", 18);
private JCheckBox chkCenter = new JCheckBox("Center of the volume", true);
private JButton bnOK = new JButton("OK");
private JButton bnCancel = new JButton("Cancel");
private boolean cancel = false;
private JLabel lblBit = new JLabel("32-bit");
private JLabel lblIter = new JLabel("iterations");
private JLabel lblSnapshot = new JLabel("Iterations");
private Output out;
private View view;
private GridPanel pnOrtho;
private HTMLPane info = new HTMLPane(200, 200);
private static int count = 1;
public OutputDialog(View view) {
super(new JFrame(), "Create a new output");
this.view = view;
lblBit.setBorder(BorderFactory.createEtchedBorder());
lblIter.setBorder(BorderFactory.createEtchedBorder());
txtName.setText(view.name().substring(0, 2) + (count++));
GridPanel pn = new GridPanel(true);
pn.place(0, 0, "Name");
pn.place(0, 1, txtName);
pn.place(1, 0, "Dynamic");
pn.place(1, 1, cmbDynamic);
pn.place(2, 0, "Type");
pn.place(2, 1, cmbType);
pn.place(3, 1, lblBit);
if (view != View.SERIES && view != View.STACK) {
pn.place(4, 0, "Snapshot");
pn.place(4, 1, cmbSnapshot);
pn.place(5, 0, lblSnapshot);
pn.place(5, 1, snpSnapshot);
pn.place(6, 1, lblIter);
}
pn.place(7, 1, 3, 1, chkShow);
pn.place(8, 1, 3, 1, chkSave);
GridPanel main = new GridPanel(false);
main.place(1, 0, 2, 1, pn);
if (view == View.ORTHO || view == View.FIGURE) {
pn.place(9, 1, 3, 1, chkCenter);
pnOrtho = new GridPanel("Keypoint");
pnOrtho.place(4, 0, "Position in X");
pnOrtho.place(4, 1, spnX);
pnOrtho.place(4, 2, "[pixel]");
pnOrtho.place(5, 0, "Position in Y");
pnOrtho.place(5, 1, spnY);
pnOrtho.place(5, 2, "[pixel]");
pnOrtho.place(6, 0, "Position in Z");
pnOrtho.place(6, 1, spnZ);
pnOrtho.place(5, 2, "[pixel]");
main.place(2, 0, 2, 1, pnOrtho);
}
pn.place(10, 0, 2, 1, info.getPane());
main.place(3, 0, bnCancel);
main.place(3, 1, bnOK);
info();
cmbSnapshot.addActionListener(this);
snpSnapshot.addChangeListener(this);
chkCenter.addActionListener(this);
cmbType.addActionListener(this);
bnOK.addActionListener(this);
bnCancel.addActionListener(this);
add(main);
update();
pack();
GUI.center(this);
setModal(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == chkCenter) {
update();
}
else if (e.getSource() == cmbSnapshot) {
update();
}
else if (e.getSource() == cmbType) {
if (cmbType.getSelectedIndex() == 0)
lblBit.setText("32-bits");
if (cmbType.getSelectedIndex() == 1)
lblBit.setText("16-bits");
if (cmbType.getSelectedIndex() == 2)
lblBit.setText("8-bits");
}
else if (e.getSource() == bnCancel) {
dispose();
cancel = true;
return;
}
else if (e.getSource() == bnOK) {
- int freq = snpSnapshot.get();
+ Action action = Action.SHOW;
+ if (chkShow.isSelected() && chkSave.isSelected())
+ action = Action.SHOWSAVE;
+ if (!chkShow.isSelected() && chkSave.isSelected())
+ action = Action.SAVE;
+ String name = txtName.getText();
+ out = new Output(view, action, name).frequency(snpSnapshot.get());
Dynamic dynamic = Output.Dynamic.values()[cmbDynamic.getSelectedIndex()];
+ if (dynamic == Dynamic.RESCALED)
+ out.rescale();
+ if (dynamic == Dynamic.CLIPPED)
+ out.clip();
+ if (dynamic == Dynamic.NORMALIZED)
+ out.normalize();
Imager.Type type = Imager.Type.values()[cmbType.getSelectedIndex()];
- boolean show = chkShow.isSelected();
- boolean save = chkSave.isSelected();
- String name = txtName.getText();
- if (chkCenter.isSelected()) {
- out = new Output(view, show, save, freq, name, dynamic, type, true);
- }
- else {
- int px = spnX.get();
- int py = spnY.get();
- int pz = spnZ.get();
- out = new Output(view, show, save, freq, name, dynamic, type, px, py, pz);
- }
- dispose();
+ if (type == Imager.Type.BYTE)
+ out.toByte();
+ if (type == Imager.Type.SHORT)
+ out.toShort();
+ if (type == Imager.Type.FLOAT)
+ out.toFloat();
+ if (!chkCenter.isSelected())
+ out.origin(spnX.get(), spnY.get(), spnZ.get());
cancel = false;
+ dispose();
}
}
private void update() {
if (cmbSnapshot.getSelectedIndex() == 0) {
snpSnapshot.set(0);
lblSnapshot.setEnabled(false);
lblIter.setEnabled(false);
lblSnapshot.setEnabled(false);
}
else {
lblSnapshot.setEnabled(true);
lblIter.setEnabled(true);
lblSnapshot.setEnabled(true);
}
if (snpSnapshot.get() == 0)
lblIter.setText("at the end (default)");
else
lblIter.setText("every " + snpSnapshot.get() + " iterations");
if (snpSnapshot.get() == 0)
lblIter.setText("at the end (default)");
else
lblIter.setText("every " + snpSnapshot.get() + " iterations");
boolean b = !chkCenter.isSelected();
if (pnOrtho != null) {
pnOrtho.setEnabled(b);
for (Component c : pnOrtho.getComponents())
c.setEnabled(b);
}
pack();
}
@Override
public void stateChanged(ChangeEvent e) {
if (e.getSource() == snpSnapshot)
update();
}
public Output getOut() {
return out;
}
public boolean wasCancel() {
return cancel;
}
private void info() {
if (view == View.FIGURE) {
info.append("h1", "figure");
info.append("h2", "Create a view with 2 panels (XY) and (YZ) with a border.");
}
if (view == View.MIP) {
info.append("h1", "mip");
info.append("h2", "Create a view 3 orthogonal projections.");
}
if (view == View.ORTHO) {
info.append("h1", "ortho");
- info.append("h2", "Create a view 3 orthogonal section centered on the keypoint.");
+ info.append("h2", "Create a view 3 orthogonal section centered on the origin.");
}
if (view == View.PLANAR) {
info.append("h1", "ortho");
info.append("h2", "Create a montage of all Z-slice in one large flatten plane.");
}
if (view == View.STACK) {
info.append("h1", "stack");
info.append("h2", "Create a z-stack of image.");
}
if (view == View.SERIES) {
info.append("h1", "series");
info.append("h2", "Create a series of z-slices.");
}
info.append("p", "<b>Name:</b> This string will be used as title of the window in <i>show</i> mode or a filename in <i>save</i> mode.");
info.append("p", "<b>Dynamic:</b> Select the dynamic range used for the display. The default value is <i>intact</i> which preserves the true values.");
info.append("p", "<b>Type:</b> Select the data type. The default value is <i>float</i> which preserves the true values without loosing precision.");
info.append("p", "<b>Snapshot:</b> The output is usually shown (or saved) at the end of the processing, optionally it is possible to specify to show (or save) every N iterations.");
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/dialog/OutputPanel.java b/DeconvolutionLab2/src/deconvolutionlab/dialog/OutputPanel.java
index 6be394f..8deaa41 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/dialog/OutputPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/dialog/OutputPanel.java
@@ -1,267 +1,276 @@
/*
* 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.dialog;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.GridPanel;
import bilib.component.HTMLPane;
import bilib.component.SpinnerRangeInteger;
import deconvolutionlab.Imager;
-import deconvolutionlab.Output;
-import deconvolutionlab.Output.Dynamic;
-import deconvolutionlab.Output.View;
+import deconvolutionlab.output.Output;
+import deconvolutionlab.output.Output.Action;
+import deconvolutionlab.output.Output.Dynamic;
+import deconvolutionlab.output.Output.View;
public class OutputPanel extends JPanel implements ActionListener, ChangeListener {
private JComboBox<String> cmbDynamic = new JComboBox<String>(new String[] { "intact", "rescaled", "normalized", "clipped" });
private JComboBox<String> cmbType = new JComboBox<String>(new String[] { "float", "short", "byte" });
private JCheckBox chkSave = new JCheckBox("Save output", true);
private JCheckBox chkShow = new JCheckBox("Show output", true);
private SpinnerRangeInteger snpSnapshot = new SpinnerRangeInteger(0, 0, 99999, 1);
private JComboBox<String> cmbSnapshot = new JComboBox<String>(new String[] { "Final Output", "Specify Iterations..." });
private SpinnerRangeInteger spnX = new SpinnerRangeInteger(128, 0, 99999, 1);
private SpinnerRangeInteger spnY = new SpinnerRangeInteger(128, 0, 99999, 1);
private SpinnerRangeInteger spnZ = new SpinnerRangeInteger(32, 0, 99999, 1);
private JTextField txtName = new JTextField("Noname", 18);
private JCheckBox chkCenter = new JCheckBox("Center of the volume", true);
private JButton bnOK = new JButton("OK");
private JButton bnCancel = new JButton("Cancel");
private boolean cancel = false;
private JLabel lblBit = new JLabel("32-bit");
private JLabel lblIter = new JLabel("iterations");
private JLabel lblSnapshot = new JLabel("Iterations");
private Output out;
private View view;
private GridPanel pnOrtho;
private HTMLPane info = new HTMLPane(200, 200);
private static int count = 1;
public OutputPanel(View view) {
this.view = view;
lblBit.setBorder(BorderFactory.createEtchedBorder());
lblIter.setBorder(BorderFactory.createEtchedBorder());
txtName.setText(view.name().substring(0, 2) + (count++));
GridPanel pn = new GridPanel(true);
pn.place(0, 0, "Name");
pn.place(0, 1, txtName);
pn.place(1, 0, "Dynamic");
pn.place(1, 1, cmbDynamic);
pn.place(2, 0, "Type");
pn.place(2, 1, cmbType);
pn.place(3, 1, lblBit);
if (view != View.SERIES && view != View.STACK) {
pn.place(4, 0, "Snapshot");
pn.place(4, 1, cmbSnapshot);
pn.place(5, 0, lblSnapshot);
pn.place(5, 1, snpSnapshot);
pn.place(6, 1, lblIter);
}
pn.place(7, 1, 3, 1, chkShow);
pn.place(8, 1, 3, 1, chkSave);
GridPanel main = new GridPanel(false);
main.place(1, 0, 2, 1, pn);
if (view == View.ORTHO || view == View.FIGURE) {
pn.place(9, 1, 3, 1, chkCenter);
- pnOrtho = new GridPanel("Keypoint");
- pnOrtho.place(4, 0, "Position in X");
+ pnOrtho = new GridPanel("Origin for orthoview");
+ pnOrtho.place(4, 0, "Origin in X");
pnOrtho.place(4, 1, spnX);
pnOrtho.place(4, 2, "[pixel]");
- pnOrtho.place(5, 0, "Position in Y");
+ pnOrtho.place(5, 0, "Origin in Y");
pnOrtho.place(5, 1, spnY);
pnOrtho.place(5, 2, "[pixel]");
- pnOrtho.place(6, 0, "Position in Z");
+ pnOrtho.place(6, 0, "Origin in Z");
pnOrtho.place(6, 1, spnZ);
pnOrtho.place(5, 2, "[pixel]");
main.place(2, 0, 2, 1, pnOrtho);
}
pn.place(10, 0, 2, 1, info.getPane());
main.place(3, 0, bnCancel);
main.place(3, 1, bnOK);
info();
cmbSnapshot.addActionListener(this);
snpSnapshot.addChangeListener(this);
chkCenter.addActionListener(this);
cmbType.addActionListener(this);
bnOK.addActionListener(this);
bnCancel.addActionListener(this);
add(main);
update();
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == chkCenter) {
update();
}
else if (e.getSource() == cmbSnapshot) {
update();
}
else if (e.getSource() == cmbType) {
if (cmbType.getSelectedIndex() == 0)
lblBit.setText("32-bits");
if (cmbType.getSelectedIndex() == 1)
lblBit.setText("16-bits");
if (cmbType.getSelectedIndex() == 2)
lblBit.setText("8-bits");
}
else if (e.getSource() == bnCancel) {
cancel = true;
return;
}
else if (e.getSource() == bnOK) {
- int freq = snpSnapshot.get();
+ Action action = Action.SHOW;
+ if (chkShow.isSelected() && chkSave.isSelected())
+ action = Action.SHOWSAVE;
+ if (!chkShow.isSelected() && chkSave.isSelected())
+ action = Action.SAVE;
+ String name = txtName.getText();
+ out = new Output(view, action, name).frequency(snpSnapshot.get());
Dynamic dynamic = Output.Dynamic.values()[cmbDynamic.getSelectedIndex()];
+ if (dynamic == Dynamic.RESCALED)
+ out.rescale();
+ if (dynamic == Dynamic.CLIPPED)
+ out.clip();
+ if (dynamic == Dynamic.NORMALIZED)
+ out.normalize();
Imager.Type type = Imager.Type.values()[cmbType.getSelectedIndex()];
- boolean show = chkShow.isSelected();
- boolean save = chkSave.isSelected();
- String name = txtName.getText();
- if (chkCenter.isSelected()) {
- out = new Output(view, show, save, freq, name, dynamic, type, true);
- }
- else {
- int px = spnX.get();
- int py = spnY.get();
- int pz = spnZ.get();
- out = new Output(view, show, save, freq, name, dynamic, type, px, py, pz);
- }
+ if (type == Imager.Type.BYTE)
+ out.toByte();
+ if (type == Imager.Type.SHORT)
+ out.toShort();
+ if (type == Imager.Type.FLOAT)
+ out.toFloat();
+ if (!chkCenter.isSelected())
+ out.origin(spnX.get(), spnY.get(), spnZ.get());
cancel = false;
}
}
private void update() {
if (cmbSnapshot.getSelectedIndex() == 0) {
snpSnapshot.set(0);
lblSnapshot.setEnabled(false);
lblIter.setEnabled(false);
lblSnapshot.setEnabled(false);
}
else {
lblSnapshot.setEnabled(true);
lblIter.setEnabled(true);
lblSnapshot.setEnabled(true);
}
if (snpSnapshot.get() == 0)
lblIter.setText("at the end (default)");
else
lblIter.setText("every " + snpSnapshot.get() + " iterations");
if (snpSnapshot.get() == 0)
lblIter.setText("at the end (default)");
else
lblIter.setText("every " + snpSnapshot.get() + " iterations");
boolean b = !chkCenter.isSelected();
if (pnOrtho != null) {
pnOrtho.setEnabled(b);
for (Component c : pnOrtho.getComponents())
c.setEnabled(b);
}
//pack();
}
@Override
public void stateChanged(ChangeEvent e) {
if (e.getSource() == snpSnapshot)
update();
}
public Output getOut() {
return out;
}
public boolean wasCancel() {
return cancel;
}
private void info() {
if (view == View.FIGURE) {
info.append("h1", "figure");
info.append("h2", "Create a view with 2 panels (XY) and (YZ) with a border.");
}
if (view == View.MIP) {
info.append("h1", "mip");
info.append("h2", "Create a view 3 orthogonal projections.");
}
if (view == View.ORTHO) {
info.append("h1", "ortho");
info.append("h2", "Create a view 3 orthogonal section centered on the keypoint.");
}
if (view == View.PLANAR) {
info.append("h1", "ortho");
info.append("h2", "Create a montage of all Z-slice in one large flatten plane.");
}
if (view == View.STACK) {
info.append("h1", "stack");
info.append("h2", "Create a z-stack of image.");
}
if (view == View.SERIES) {
info.append("h1", "series");
info.append("h2", "Create a series of z-slices.");
}
info.append("p", "<b>Name:</b> This string will be used as title of the window in <i>show</i> mode or a filename in <i>save</i> mode.");
info.append("p", "<b>Dynamic:</b> Select the dynamic range used for the display. The default value is <i>intact</i> which preserves the true values.");
info.append("p", "<b>Type:</b> Select the data type. The default value is <i>float</i> which preserves the true values without loosing precision.");
info.append("p", "<b>Snapshot:</b> The output is usually shown (or saved) at the end of the processing, optionally it is possible to specify to show (or save) every N iterations.");
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/module/AlgorithmModule.java b/DeconvolutionLab2/src/deconvolutionlab/module/AlgorithmModule.java
index 659c79e..2f15b41 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/module/AlgorithmModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/module/AlgorithmModule.java
@@ -1,170 +1,172 @@
/*
* 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.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.HTMLPane;
import deconvolution.Command;
import deconvolution.Deconvolution;
import deconvolution.DeconvolutionDialog;
import deconvolution.algorithm.AbstractAlgorithmPanel;
import deconvolution.algorithm.Algorithm;
import deconvolutionlab.Config;
import deconvolutionlab.Lab;
public class AlgorithmModule extends AbstractModule implements ActionListener, ChangeListener {
private JComboBox<String> cmb;
private HTMLPane doc;
private JPanel cards;
private JLabel shortname;
public AlgorithmModule(boolean expanded) {
super("Algorithm", "-algorithm", "", "Check", expanded);
ArrayList<AbstractAlgorithmPanel> deconv = Algorithm.getAvailableAlgorithms();
for (AbstractAlgorithmPanel panel : deconv)
cmb.addItem(panel.getName());
cmb.addActionListener(this);
}
@Override
public String getCommand() {
String name = (String) cmb.getSelectedItem();
AbstractAlgorithmPanel algo = Algorithm.getPanel(name);
String cmd = "-algorithm " + algo.getShortnames()[0] + " " + algo.getCommand();
String synopsis = algo.getShortnames()[0] + " " + algo.getCommand();
setSynopsis(synopsis);
setCommand(cmd);
return cmd;
}
@Override
public JPanel buildExpandedPanel() {
shortname = new JLabel("-------");
Border bl1 = BorderFactory.createEtchedBorder();
Border bl2 = BorderFactory.createEmptyBorder(0, 10, 0, 10);
shortname.setBorder(BorderFactory.createCompoundBorder(bl1, bl2));
cmb = new JComboBox<String>();
+ cmb.setBorder(BorderFactory.createEtchedBorder());
+
JPanel pnc = new JPanel();
pnc.add(cmb);
doc = new HTMLPane(100, 1000);
cards = new JPanel(new CardLayout());
ArrayList<AbstractAlgorithmPanel> panels = Algorithm.getAvailableAlgorithms();
for (AbstractAlgorithmPanel panel : panels) {
JScrollPane scroll = new JScrollPane(panel.getPanelParameters());
scroll.setBorder(BorderFactory.createEmptyBorder());
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
cards.add(panel.getName(), scroll);
}
cmb.setMaximumRowCount(panels.size());
JPanel top = new JPanel(new BorderLayout());
top.add(cmb, BorderLayout.CENTER);
top.add(shortname, BorderLayout.EAST);
JPanel control = new JPanel();
control.setLayout(new BoxLayout(control, BoxLayout.PAGE_AXIS));
Border b1 = BorderFactory.createEtchedBorder();
Border b2 = BorderFactory.createEmptyBorder(10, 10, 10, 10);
control.setBorder(BorderFactory.createCompoundBorder(b1, b2));
cards.setBorder(BorderFactory.createEtchedBorder());
control.add(top);
control.add(cards);
doc.append("h1", "Documentation");
JPanel panel = new JPanel(new BorderLayout());
panel.add(control, BorderLayout.NORTH);
panel.add(doc.getPane(), BorderLayout.CENTER);
// cmb.addActionListener(this);
getAction2Button().setToolTipText("Human readable of the command line");
getAction2Button().addActionListener(this);
Config.register(getName(), "algorithm", cmb, Algorithm.getDefaultAlgorithm());
panel.setBorder(BorderFactory.createEtchedBorder());
return panel;
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
if (e.getSource() == cmb) {
doc.clear();
String name = (String) cmb.getSelectedItem();
AbstractAlgorithmPanel algo = Algorithm.getPanel(name);
doc.append(algo.getDocumentation());
CardLayout cl = (CardLayout) (cards.getLayout());
cl.show(cards, name);
String s = "<html><b><p style =\"font-family:georgia\">";
for(int i=0; i<algo.getShortnames().length; i++)
s += (i==0 ? "" : " | ") + algo.getShortnames()[i] ;
shortname.setText(s + "</b></html>");
}
if (e.getSource() == getAction2Button()) {
Deconvolution deconvolution = new Deconvolution("Check Algorithm", Command.command());
DeconvolutionDialog d = new DeconvolutionDialog(DeconvolutionDialog.Module.ALGO, deconvolution);
Lab.setVisible(d, false);
}
setSynopsis((String) cmb.getSelectedItem());
setCommand(getCommand());
Command.command();
}
@Override
public void stateChanged(ChangeEvent e) {
setSynopsis((String) cmb.getSelectedItem());
setCommand(getCommand());
Command.command();
}
@Override
public void close() {
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/module/OutputModule.java b/DeconvolutionLab2/src/deconvolutionlab/module/OutputModule.java
index 7fbad60..7d98498 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/module/OutputModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/module/OutputModule.java
@@ -1,236 +1,236 @@
/*
* 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.Output;
-import deconvolutionlab.Output.View;
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("Keypoint", String.class, 120, false));
+ 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/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/OutFigure.java
similarity index 61%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/OutFigure.java
index dbcc779..6063b70 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/OutFigure.java
@@ -1,72 +1,44 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class OutFigure extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
- }
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
+ public OutFigure(String name) {
+ super(View.FIGURE, Action.SHOWSAVE, name);
}
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
+ public OutFigure(String path, String name) {
+ super(View.FIGURE, Action.SHOWSAVE, name);
+ setPath(name);
}
-
-}
+}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/OutMIP.java
similarity index 61%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/OutMIP.java
index dbcc779..1c46181 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/OutMIP.java
@@ -1,72 +1,44 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class OutMIP extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
- }
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
+ public OutMIP(String name) {
+ super(View.MIP, Action.SHOWSAVE, name);
}
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
+ public OutMIP(String path, String name) {
+ super(View.MIP, Action.SHOWSAVE, name);
+ setPath(name);
}
-
-}
+}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/OutOrtho.java
similarity index 61%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/OutOrtho.java
index dbcc779..74ccfd5 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/OutOrtho.java
@@ -1,72 +1,44 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class OutOrtho extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
- }
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
+ public OutOrtho(String name) {
+ super(View.ORTHO, Action.SHOWSAVE, name);
}
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
+ public OutOrtho(String path, String name) {
+ super(View.ORTHO, Action.SHOWSAVE, name);
+ setPath(name);
}
-
-}
+}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/OutPlanar.java
similarity index 61%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/OutPlanar.java
index dbcc779..df48c11 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/OutPlanar.java
@@ -1,72 +1,44 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class OutPlanar extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
- }
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
+ public OutPlanar(String name) {
+ super(View.PLANAR, Action.SHOWSAVE, name);
}
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
+ public OutPlanar(String path, String name) {
+ super(View.PLANAR, Action.SHOWSAVE, name);
+ setPath(name);
}
-
-}
+}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/OutSeries.java
similarity index 61%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/OutSeries.java
index dbcc779..ee91318 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/OutSeries.java
@@ -1,72 +1,44 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class OutSeries extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
- }
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
+ public OutSeries(String name) {
+ super(View.SERIES, Action.SHOWSAVE, name);
}
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
+ public OutSeries(String path, String name) {
+ super(View.SERIES, Action.SHOWSAVE, name);
+ setPath(name);
}
-
-}
+}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/OutStack.java
similarity index 61%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/OutStack.java
index dbcc779..ac6f7ba 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/OutStack.java
@@ -1,72 +1,44 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class OutStack extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
- }
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
+ public OutStack(String name) {
+ super(View.STACK, Action.SHOWSAVE, name);
}
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
+ public OutStack(String path, String name) {
+ super(View.STACK, Action.SHOWSAVE, name);
+ setPath(name);
}
-
-}
+}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/deconvolutionlab/Output.java b/DeconvolutionLab2/src/deconvolutionlab/output/Output.java
similarity index 81%
rename from DeconvolutionLab2/src/deconvolutionlab/Output.java
rename to DeconvolutionLab2/src/deconvolutionlab/output/Output.java
index e89ab05..ae8d789 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/Output.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/Output.java
@@ -1,371 +1,405 @@
/*
* 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;
+package deconvolutionlab.output;
import java.io.File;
import bilib.tools.NumFormat;
import deconvolution.algorithm.Controller;
+import deconvolutionlab.Imager;
import deconvolutionlab.Imager.ContainerImage;
+import deconvolutionlab.Lab;
import deconvolutionlab.monitor.Monitors;
import signal.Constraint;
import signal.RealSignal;
public class Output {
public enum View {
STACK, SERIES, ORTHO, MIP, PLANAR, FIGURE
};
public enum Dynamic {
INTACT, RESCALED, NORMALIZED, CLIPPED
};
+
+ public enum Action {
+ SHOW, SAVE, SHOWSAVE;
+ }
private ContainerImage container = null;
- private int px = 0;
- private int py = 0;
- private int pz = 0;
+ private int ox = 0;
+ private int oy = 0;
+ private int oz = 0;
private boolean center = true;
private String name = "";
private boolean save = true;
private boolean show = true;
private View view = View.STACK;
private Imager.Type type = Imager.Type.FLOAT;
private Dynamic dynamic = Dynamic.INTACT;
+ private String customPath = "$";
+
private int frequency = 0;
public Output(View view, int frequency, String param) {
String[] tokens = param.trim().split(" ");
this.view = view;
this.frequency = frequency;
this.name = "";
this.center = true;
this.save = true;
this.show = true;
this.container = Lab.createContainer(Monitors.createDefaultMonitor(), "");
for (int i = 0; i < tokens.length; i++) {
boolean found = false;
String p = tokens[i].trim().toLowerCase();
if (p.startsWith("@")) {
found = true;
}
if (p.startsWith("noshow")) {
show = false;
found = true;
}
if (p.startsWith("nosave")) {
save = false;
found = true;
}
for (Dynamic d : Dynamic.values()) {
if (p.toLowerCase().equals(d.name().toLowerCase())) {
dynamic = d;
found = true;
}
}
for (View v : View.values()) {
if (p.toLowerCase().equals(v.name().toLowerCase())) {
view = v;
found = true;
}
}
for (Imager.Type t : Imager.Type.values()) {
if (p.toLowerCase().equals(t.name().toLowerCase())) {
type = t;
found = true;
}
}
if (p.startsWith("(") && p.endsWith(")")) {
double pos[] = NumFormat.parseNumbers(p);
if (pos.length > 0)
- px = (int) Math.round(pos[0]);
+ ox = (int) Math.round(pos[0]);
if (pos.length > 1)
- py = (int) Math.round(pos[1]);
+ oy = (int) Math.round(pos[1]);
if (pos.length > 2)
- pz = (int) Math.round(pos[2]);
+ oz = (int) Math.round(pos[2]);
found = true;
center = false;
}
if (!found)
name += tokens[i] + " ";
name = name.trim();
}
}
- public Output(View view, boolean show, boolean save, int frequency, String name, Dynamic dynamic, Imager.Type type, boolean center) {
+ public Output(View view, Action action, String name) {
this.name = name;
- this.show = show;
- this.save = save;
+ this.show = action == Action.SHOW || action == Action.SHOWSAVE;
+ this.save = action == Action.SAVE || action == Action.SHOWSAVE;
this.view = view;
- this.type = type;
- this.dynamic = dynamic;
- this.center = center;
- this.frequency = frequency;
+ this.type = Imager.Type.FLOAT;
+ this.dynamic = Dynamic.INTACT;
+ this.center = true;
+ this.frequency = 0;
}
- public Output(View view, boolean show, boolean save, int frequency, String name, Dynamic dynamic, Imager.Type type, int px, int py, int pz) {
- this.name = name;
- this.show = show;
- this.save = save;
- this.view = view;
- this.type = type;
- this.dynamic = dynamic;
- this.center = false;
- this.px = px;
- this.py = py;
- this.pz = pz;
+ public Output rescale() {
+ this.dynamic = Dynamic.RESCALED;
+ return this;
+ }
+
+ public Output clip() {
+ this.dynamic = Dynamic.CLIPPED;
+ return this;
+ }
+
+ public Output normalize() {
+ this.dynamic = Dynamic.NORMALIZED;
+ return this;
+ }
+
+ public Output toFloat() {
+ this.type = Imager.Type.FLOAT;
+ return this;
+ }
+
+ public Output toShort() {
+ this.type = Imager.Type.SHORT;
+ return this;
+ }
+
+ public Output toByte() {
+ this.type = Imager.Type.BYTE;
+ return this;
+ }
+
+ public Output frequency(int frequency) {
this.frequency = frequency;
+ return this;
}
+ public Output origin(int ox, int oy, int oz) {
+ this.ox = ox;
+ this.oy = oy;
+ this.oz = oz;
+ this.center = false;
+ return this;
+ }
+
public boolean is(int iterations) {
if (frequency == 0)
return false;
return iterations % frequency == 0;
}
public View getView() {
return view;
}
public String getName() {
return name;
}
+
+ public void setPath(String customPath) {
+ this.customPath = customPath;
+ }
+
public int extractFrequency(String param) {
String line = param.trim();
if (!line.startsWith("@"))
line = "@0 " + line;
String parts[] = line.split(" ");
if (parts.length >= 1) {
return (int) Math.round(NumFormat.parseNumber(parts[0], 0));
}
return 0;
}
- public void setKeypoint(int px, int py, int pz) {
- this.px = px;
- this.py = py;
- this.pz = pz;
- this.center = false;
- }
-
public String[] getAsString() {
String t = (type == Imager.Type.FLOAT ? "" : type.name().toLowerCase());
String d = (dynamic == Dynamic.INTACT ? "" : dynamic.name().toLowerCase());
- String k = "";
+ String o = "";
if (!center)
- k = " (" + px + "," + py + "," + pz + ")";
- else
- k = "";
+ o = " (" + ox + "," + oy + "," + oz + ")";
String sa = save ? "\u2713" : "";
String sh = show ? "\u2713" : "";
String fr = frequency > 0 ? " @" + frequency : "";
- return new String[] { view.name().toLowerCase() + fr, name, d, t, k, sh, sa, "\u232B" };
+ return new String[] { view.name().toLowerCase() + fr, name, d, t, o, sh, sa, "\u232B" };
}
public void executeStarting(Monitors monitors, RealSignal signal, Controller controller) {
if (signal == null)
return;
execute(monitors, signal, controller, true, false, false, 0);
}
public void executeFinal(Monitors monitors, RealSignal signal, Controller controller) {
if (signal == null)
return;
execute(monitors, signal, controller, false, false, true, 0);
}
public void executeIterative(Monitors monitors, RealSignal signal, Controller controller, int iter) {
if (signal == null)
return;
execute(monitors, signal, controller, false, true, false, iter);
}
private void execute(Monitors monitors, RealSignal signal, Controller controller, boolean start, boolean live, boolean finish, int iter) {
String title = name;
if (live)
if (!is(iter))
return;
if (controller != null && live) {
if (controller.getIterations() > 0) {
title += "@" + controller.getIterations();
}
}
RealSignal x = null;
Constraint constraint = new Constraint(monitors);
switch (dynamic) {
case RESCALED:
x = signal.duplicate();
constraint.rescaled(x, 0, 255);
break;
case CLIPPED:
x = signal.duplicate();
float[] stats = controller.getStats().getStatsInput();
if (stats != null)
constraint.clipped(x, stats[1], stats[2]);
break;
case NORMALIZED:
x = signal.duplicate();
float[] stats1 = controller.getStats().getStatsInput();
if (stats1 != null)
constraint.normalized(x, stats1[0], stats1[3]);
break;
default:
x = signal;
}
- String filename = controller.getPath() + File.separator + title + ".tif";
+ String path = (customPath.equals("$") ? controller.getPath() : customPath) + File.separator;
+ String filename = path + title + ".tif";
switch (view) {
case STACK:
if (show && !live)
- Lab.show(monitors, x, title, type, (center ? x.nz / 2 : pz));
+ Lab.show(monitors, x, title, type, (center ? x.nz / 2 : oz));
if (save && !live)
Lab.save(monitors, x, filename, type);
break;
case SERIES:
for (int k = 0; k < x.nz; k++) {
RealSignal slice = x.getSlice(k);
String z = "-z" + String.format("%06d", k) ;
if (show && !live)
Lab.show(monitors, slice, title + z, type);
if (save && !live) {
- String zfilename = controller.getPath() + File.separator + title + z + ".tif";
+ String zfilename = path + title + z + ".tif";
Lab.save(monitors, slice, zfilename, type);
}
}
break;
case ORTHO:
if (!start)
orthoview(monitors, x, title, filename, live);
break;
case FIGURE:
if (!start)
figure(monitors, x, title, filename, live);
break;
case MIP:
if (!start)
mip(monitors, x, title, filename, live);
break;
case PLANAR:
if (!start)
planar(monitors, x, title, filename, live);
break;
default:
break;
}
}
private void mip(Monitors monitors, RealSignal signal, String title, String filename, boolean live) {
RealSignal plane = signal.createMIP();
if (show && live) {
Lab.append(monitors, container, plane, title, type);
}
if (show && !live)
Lab.show(monitors, plane, title, type);
if (save)
Lab.save(monitors, plane, filename, type);
}
private void orthoview(Monitors monitors, RealSignal signal, String title, String filename, boolean live) {
- int cx = px;
- int cy = py;
- int cz = pz;
+ int cx = ox;
+ int cy = oy;
+ int cz = oz;
if (center) {
cx = signal.nx / 2;
cy = signal.ny / 2;
cz = signal.nz / 2;
}
RealSignal plane = signal.createOrthoview(cx, cy, cz);
if (show && live) {
if (container == null)
container = Lab.createContainer(monitors, title);
Lab.append(monitors, container, plane, title, type);
}
if (show && !live)
Lab.show(monitors, plane, title, type);
if (save)
Lab.save(monitors, plane, filename, type);
}
private void figure(Monitors monitors, RealSignal signal, String title, String filename, boolean live) {
- int cx = px;
- int cy = py;
- int cz = pz;
+ int cx = ox;
+ int cy = oy;
+ int cz = oz;
if (center) {
cx = signal.nx / 2;
cy = signal.ny / 2;
cz = signal.nz / 2;
}
RealSignal plane = signal.createFigure(cx, cy, cz);
if (show && live) {
if (container == null)
container = Lab.createContainer(monitors, title);
Lab.append(monitors, container, plane, title, type);
}
if (show && !live)
Lab.show(monitors, plane, title, type);
if (save)
Lab.save(monitors, plane, filename, type);
}
private void planar(Monitors monitors, RealSignal signal, String title, String filename, boolean live) {
- RealSignal plane = signal.createMontage();
+ RealSignal plane = signal.createPlanar();
if (show && live) {
if (container == null)
container = Lab.createContainer(monitors, title);
Lab.append(monitors, container, plane, title, type);
}
if (show && !live)
Lab.show(monitors, plane, title, type);
if (save)
Lab.save(monitors, plane, filename, type);
}
@Override
public String toString() {
String t = type.name().toLowerCase();
String v = view.name().toLowerCase();
String d = dynamic.name().toLowerCase();
String f = frequency > 0 ? " every " + frequency + " iterations" : "";
- String k = (center ? "" : " keypoint = (" + px + "," + py + "," + pz + ")");
+ String k = (center ? "" : " keypoint = (" + ox + "," + oy + "," + oz + ")");
return v + " " + name + " format = (" + d + ", " + t + ") " + k + f;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/SaveFigure.java
similarity index 62%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/SaveFigure.java
index dbcc779..c61eabb 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/SaveFigure.java
@@ -1,72 +1,44 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class SaveFigure extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
- }
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
+ public SaveFigure(String path, String name) {
+ super(View.FIGURE, Action.SAVE, name);
+ setPath(path);
}
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
+ public SaveFigure(String name) {
+ super(View.FIGURE, Action.SAVE, name);
}
-
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/SaveMIP.java
similarity index 62%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/SaveMIP.java
index dbcc779..06fd73c 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/SaveMIP.java
@@ -1,72 +1,44 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class SaveMIP extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
- }
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
+ public SaveMIP(String path, String name) {
+ super(View.MIP, Action.SAVE, name);
+ setPath(path);
}
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
+ public SaveMIP(String name) {
+ super(View.MIP, Action.SAVE, name);
}
-
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/SaveOrtho.java
similarity index 62%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/SaveOrtho.java
index dbcc779..a49fd9c 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/SaveOrtho.java
@@ -1,72 +1,44 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class SaveOrtho extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
- }
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
+ public SaveOrtho(String path, String name) {
+ super(View.ORTHO, Action.SAVE, name);
+ setPath(path);
}
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
+ public SaveOrtho(String name) {
+ super(View.ORTHO, Action.SAVE, name);
}
-
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/SavePlanar.java
similarity index 62%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/SavePlanar.java
index dbcc779..400d45a 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/SavePlanar.java
@@ -1,72 +1,44 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class SavePlanar extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
- }
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
+ public SavePlanar(String path, String name) {
+ super(View.PLANAR, Action.SAVE, name);
+ setPath(path);
}
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
+ public SavePlanar(String name) {
+ super(View.PLANAR, Action.SAVE, name);
}
-
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/SaveSeries.java
similarity index 62%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/SaveSeries.java
index dbcc779..49870c0 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/SaveSeries.java
@@ -1,72 +1,44 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class SaveSeries extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
- }
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
+ public SaveSeries(String path, String name) {
+ super(View.SERIES, Action.SAVE, name);
+ setPath(path);
}
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
+ public SaveSeries(String name) {
+ super(View.SERIES, Action.SAVE, name);
}
-
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/SaveStack.java
similarity index 62%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/SaveStack.java
index dbcc779..9fc03ed 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/SaveStack.java
@@ -1,72 +1,44 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class SaveStack extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
- }
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
+ public SaveStack(String path, String name) {
+ super(View.STACK, Action.SAVE, name);
+ setPath(path);
}
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
+ public SaveStack(String name) {
+ super(View.STACK, Action.SAVE, name);
}
-
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/ShowFigure.java
similarity index 61%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/ShowFigure.java
index dbcc779..6823bb9 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/ShowFigure.java
@@ -1,72 +1,39 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class ShowFigure extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
+ public ShowFigure(String name) {
+ super(View.FIGURE, Action.SHOW, name);
}
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
- }
-
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
- }
-
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/ShowMIP.java
similarity index 61%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/ShowMIP.java
index dbcc779..92b11a5 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/ShowMIP.java
@@ -1,72 +1,39 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class ShowMIP extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
+ public ShowMIP(String name) {
+ super(View.MIP, Action.SHOW, name);
}
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
- }
-
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
- }
-
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/ShowOrtho.java
similarity index 61%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/ShowOrtho.java
index dbcc779..5d74133 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/ShowOrtho.java
@@ -1,72 +1,39 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class ShowOrtho extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
+ public ShowOrtho(String name) {
+ super(View.ORTHO, Action.SHOW, name);
}
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
- }
-
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
- }
-
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/ShowPlanar.java
similarity index 61%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/ShowPlanar.java
index dbcc779..215fedf 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/ShowPlanar.java
@@ -1,72 +1,39 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class ShowPlanar extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
+ public ShowPlanar(String name) {
+ super(View.PLANAR, Action.SHOW, name);
}
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
- }
-
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
- }
-
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/ShowSeries.java
similarity index 61%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/ShowSeries.java
index dbcc779..a455397 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/ShowSeries.java
@@ -1,72 +1,39 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class ShowSeries extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
+ public ShowSeries(String name) {
+ super(View.SERIES, Action.SHOW, name);
}
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
- }
-
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
- }
-
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolutionlab/output/ShowStack.java
similarity index 61%
copy from DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
copy to DeconvolutionLab2/src/deconvolutionlab/output/ShowStack.java
index dbcc779..8ae296f 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/output/ShowStack.java
@@ -1,72 +1,39 @@
/*
* 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;
+package deconvolutionlab.output;
-import javax.swing.JPanel;
+public class ShowStack extends Output {
-import bilib.component.GridPanel;
-
-public class IdentityPanel extends AbstractAlgorithmPanel {
-
- private Identity algo = new Identity();
-
- @Override
- public JPanel getPanelParameters() {
- GridPanel pn = new GridPanel(false);
- pn.place(1, 0, "<html><span \"nowrap\">No parameters</span></html>");
- return pn;
+ public ShowStack(String name) {
+ super(View.STACK, Action.SHOW, name);
}
-
- @Override
- public String getCommand() {
- return "";
- }
-
- @Override
- public String getName() {
- return algo.getName();
- }
-
- @Override
- public String[] getShortnames() {
- return algo.getShortnames();
- }
-
- @Override
- public String getDocumentation() {
- String s = "";
- s += "<h1>" + getName() + "</h1>";
- s += "<p>This algorithm does nothing. It returns the input image.</p>";
- return s;
- }
-
}
diff --git a/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/Test.java b/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/Test.java
index 855d303..148ce2c 100644
--- a/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/Test.java
+++ b/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/Test.java
@@ -1,29 +1,29 @@
package plugins.sage.deconvolutionlab;
import java.io.File;
import deconvolutionlab.Imager;
import deconvolutionlab.Lab;
-import deconvolutionlab.Output.View;
import deconvolutionlab.dialog.OutputDialog;
+import deconvolutionlab.output.Output.View;
import icy.gui.frame.IcyFrame;
import icy.plugin.abstract_.PluginActionable;
public class Test extends PluginActionable {
@Override
public void run() {
Lab.init(Imager.Platform.ICY, System.getProperty("user.dir") + File.separator + "DeconvolutionLab2.config");
IcyFrame icf = new IcyFrame();
icf.add(new OutputDialog(View.FIGURE).getContentPane());
icf.pack();
icf.toFront();
icf.addToDesktopPane();
icf.setVisible(true);
//icf.setResizable(true);
}
}
diff --git a/DeconvolutionLab2/src/signal/RealSignal.java b/DeconvolutionLab2/src/signal/RealSignal.java
index 1af1ba2..84b444a 100644
--- a/DeconvolutionLab2/src/signal/RealSignal.java
+++ b/DeconvolutionLab2/src/signal/RealSignal.java
@@ -1,732 +1,732 @@
/*
* 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 signal;
import java.awt.image.BufferedImage;
import deconvolutionlab.monitor.Monitors;
public class RealSignal extends Signal implements SignalListener {
private BufferedImage preview;
public RealSignal(String name, int nx, int ny, int nz) {
super(name, nx, ny, nz);
this.data = new float[nz][];
int step = Math.max(1, nz / SignalCollector.NOTIFICATION_RATE);
notify(name, 0);
for (int k = 0; k < nz; k++) {
data[k] = new float[nx * ny];
if (k % step == 0)
notify(name, k * 100.0 / nz);
}
notify(name, 100);
SignalCollector.alloc(this);//name, nx, ny, ny, false);
}
@Override
public void notify(String name, double progress) {
SignalCollector.setProgress(progress);
}
public void copy(RealSignal source) {
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
data[k][i] = source.data[k][i];
}
}
public void setSignal(RealSignal signal) {
int sx = signal.nx;
int mx = Math.min(nx, signal.nx);
int my = Math.min(ny, signal.ny);
int mz = Math.min(nz, signal.nz);
for (int i = 0; i < mx; i++)
for (int j = 0; j < my; j++)
for (int k = 0; k < mz; k++)
data[k][i + nx * j] = signal.data[k][i + sx * j];
}
public void getSignal(RealSignal signal) {
int sx = signal.nx;
int mx = Math.min(nx, signal.nx);
int my = Math.min(ny, signal.ny);
int mz = Math.min(nz, signal.nz);
for (int i = 0; i < mx; i++)
for (int j = 0; j < my; j++)
for (int k = 0; k < mz; k++)
signal.data[k][i + sx * j] = data[k][i + nx * j];
}
/**
* Applies a soft threshold (in-place processing)
*
* @param inferiorLimit
* @param superiorLimit
* @return the instance of the calling object
*/
public RealSignal thresholdSoft(float inferiorLimit, float superiorLimit) {
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
if (data[k][i] <= inferiorLimit)
data[k][i] += inferiorLimit;
else if (data[k][i] >= superiorLimit)
data[k][i] -= superiorLimit;
else
data[k][i] = 0f;
}
return this;
}
/**
* Multiplies by a signal pixelwise (in-place processing)
*
* @param factor
* @return the instance of the calling object
*/
public RealSignal times(RealSignal factor) {
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
data[k][i] *= factor.data[k][i];
}
return this;
}
/**
* Multiplies by a scalar factor (in-place processing)
*
* @param factor
* @return the instance of the calling object
*/
public RealSignal times(float factor) {
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
data[k][i] *= factor;
}
return this;
}
/**
* Adds a signal pixelwise (in-place processing)
*
* @param factor
* @return the instance of the calling object
*/
public RealSignal plus(RealSignal factor) {
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
data[k][i] += factor.data[k][i];
}
return this;
}
/**
* Subtracts by a signal pixelwise (in-place processing)
*
* @param factor
* @return the instance of the calling object
*/
public RealSignal minus(RealSignal factor) {
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
data[k][i] -= factor.data[k][i];
}
return this;
}
/**
* Adds a scalar term (in-place processing)
*
* @param term
* @return the instance of the calling object
*/
public RealSignal plus(float term) {
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
data[k][i] += term;
}
return this;
}
/**
* Subtracts a scalar term (in-place processing)
*
* @param term
* @return the instance of the calling object
*/
public RealSignal minus(float term) {
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
data[k][i] -= term;
}
return this;
}
/**
* Takes the maximum (in-place processing)
*
* @param factor
* @return the instance of the calling object
*/
public RealSignal max(RealSignal factor) {
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
data[k][i] = Math.max(data[k][i], factor.data[k][i]);
}
return this;
}
/**
* Takes the minimum (in-place processing)
*
* @param factor
* @return the instance of the calling object
*/
public RealSignal min(RealSignal factor) {
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
data[k][i] = Math.min(data[k][i], factor.data[k][i]);
}
return this;
}
public double[][][] get3DArrayAsDouble() {
double[][][] ar = new double[nx][ny][nz];
for (int k = 0; k < nz; k++) {
float[] s = data[k];
for (int i = 0; i < nx; i++)
for (int j = 0; j < ny; j++) {
ar[i][j][k] = s[i + j * nx];
}
}
return ar;
}
public void set3DArrayAsDouble(double[][][] real) {
for (int k = 0; k < nz; k++) {
float[] s = data[k];
for (int i = 0; i < nx; i++)
for (int j = 0; j < ny; j++) {
s[i + j * nx] = (float) real[i][j][k];
}
}
}
public RealSignal duplicate() {
RealSignal out = new RealSignal("copy(" + name + ")", nx, ny, nz);
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
System.arraycopy(data[k], 0, out.data[k], 0, nxy);
return out;
}
public float getEnergy() {
int nxy = nx * ny;
float energy = 0.f;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++)
energy += data[k][i];
return energy;
}
public float[] getStats() {
int nxy = nx * ny;
float min = Float.MAX_VALUE;
float max = -Float.MAX_VALUE;
double norm1 = 0.0;
double norm2 = 0.0;
double mean = 0.0;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
float v = data[k][i];
max = Math.max(max, v);
min = Math.min(min, v);
mean += v;
norm1 += (v > 0 ? v : -v);
norm2 += v * v;
}
mean = mean / (nz * nxy);
norm1 = norm1 / (nz * nxy);
norm2 = Math.sqrt(norm2 / (nz * nxy));
double stdev = 0.0;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
stdev += (data[k][i] - mean) * (data[k][i] - mean);
}
stdev = Math.sqrt(stdev / (nz * nxy));
return new float[] { (float) mean, min, max, (float) stdev, (float) norm1, (float) norm2 };
}
public float[] getExtrema() {
int nxy = nx * ny;
float min = Float.MAX_VALUE;
float max = -Float.MAX_VALUE;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
float v = data[k][i];
max = Math.max(max, v);
min = Math.min(min, v);
}
return new float[] { min, max };
}
public RealSignal normalize(double to) {
if (to == 0)
return this;
int nxy = nx * ny;
float sum = 0f;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++)
sum += data[k][i];
if (sum != 0f) {
double r = to / sum;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++)
data[k][i] *= r;
}
return this;
}
public void setSlice(int z, RealSignal slice) {
int mx = slice.nx;
int my = slice.ny;
for (int j = 0; j < Math.min(ny, my); j++)
for (int i = 0; i < Math.min(nx, mx); i++)
data[z][i + nx * j] = slice.data[0][i + mx * j];
}
public RealSignal getSlice(int z) {
RealSignal slice = new RealSignal(name + "_z=" + z, nx, ny, 1);
for (int j = 0; j < nx * ny; j++)
slice.data[0][j] = data[z][j];
return slice;
}
public void multiply(double factor) {
for (int k = 0; k < nz; k++)
for (int i = 0; i < nx * ny; i++)
data[k][i] *= factor;
}
public float[] getInterleaveXYZAtReal() {
float[] interleave = new float[2 * nz * nx * ny];
for (int k = 0; k < nz; k++)
for (int j = 0; j < ny; j++)
for (int i = 0; i < nx; i++)
interleave[2 * (k * nx * ny + j * nx + i)] = data[k][i + j * nx];
return interleave;
}
public void setInterleaveXYZAtReal(float[] interleave) {
for (int k = 0; k < nz; k++)
for (int j = 0; j < ny; j++)
for (int i = 0; i < nx; i++)
data[k][i + nx * j] = interleave[(k * nx * ny + j * nx + i) * 2];
}
public float[] getInterleaveXYAtReal(int k) {
float real[] = new float[nx * ny * 2];
for (int i = 0; i < nx; i++)
for (int j = 0; j < ny; j++) {
int index = i + j * nx;
real[2 * index] = data[k][index];
}
return real;
}
public void setInterleaveXYAtReal(int k, float real[]) {
for (int i = 0; i < nx; i++)
for (int j = 0; j < ny; j++) {
int index = i + j * nx;
data[k][index] = real[2 * index];
}
}
public float[] getXYZ() {
int nxy = nx * ny;
float[] d = new float[nz * nx * ny];
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++)
d[k * nxy + i] = data[k][i];
return d;
}
public void setXYZ(float[] data) {
if (nx * ny * nz != data.length)
return;
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++)
this.data[k][i] = data[k * nxy + i];
}
public float[] getXY(int k) {
return data[k];
}
public void setXY(int k, float slice[]) {
data[k] = slice;
}
public float[] getX(int j, int k) {
float line[] = new float[nx];
for (int i = 0; i < nx; i++)
line[i] = data[k][i + j * nx];
return line;
}
public float[] getZ(int i, int j) {
float line[] = new float[nz];
int index = i + j * nx;
for (int k = 0; k < nz; k++)
line[k] = data[k][index];
return line;
}
public float[] getY(int i, int k) {
float line[] = new float[ny];
for (int j = 0; j < ny; j++)
line[j] = data[k][i + j * nx];
return line;
}
public void setX(int j, int k, float line[]) {
for (int i = 0; i < nx; i++)
data[k][i + j * nx] = line[i];
}
public void setY(int i, int k, float line[]) {
for (int j = 0; j < ny; j++)
data[k][i + j * nx] = line[j];
}
public void setZ(int i, int j, float line[]) {
int index = i + j * nx;
for (int k = 0; k < nz; k++)
data[k][index] = line[k];
}
public void clip(float min, float max) {
for (int k = 0; k < nz; k++)
for (int j = 0; j < ny * nx; j++)
if (data[k][j] < min)
data[k][j] = min;
else if (data[k][j] > max)
data[k][j] = max;
}
public void fill(float constant) {
for (int k = 0; k < nz; k++)
for (int j = 0; j < ny * nx; j++)
data[k][j] = constant;
}
public RealSignal changeSizeAs(RealSignal model) {
return size(model.nx, model.ny, model.nz);
}
public RealSignal size(int mx, int my, int mz) {
String n = "resize(" + name + ")";
int ox = (mx - nx) / 2;
int oy = (my - ny) / 2;
int oz = (mz - nz) / 2;
RealSignal signal = new RealSignal(n, mx, my, mz);
int vx = Math.min(nx, mx);
int vy = Math.min(ny, my);
int vz = Math.min(nz, mz);
for (int k = 0; k < vz; k++)
for (int j = 0; j < vy; j++)
for (int i = 0; i < vx; i++) {
int pi = ox >= 0 ? i + ox : i;
int qi = ox >= 0 ? i : i - ox;
int pj = oy >= 0 ? j + oy : j;
int qj = oy >= 0 ? j : j - oy;
int pk = oz >= 0 ? k + oz : k;
int qk = oz >= 0 ? k : k - oz;
signal.data[pk][pi + pj * mx] = data[qk][qi + qj * nx];
}
return signal;
}
public RealSignal createOrthoview() {
return createOrthoview(nx / 2, ny / 2, nz / 2);
}
public RealSignal createOrthoview(int hx, int hy, int hz) {
String n = "ortho(" + name + ")";
int vx = nx + nz;
int vy = ny + nz;
RealSignal view = new RealSignal(n, vx, vy, 1);
hx = Math.min(nx - 1, Math.max(0, hx));
hy = Math.min(ny - 1, Math.max(0, hy));
hz = Math.min(nz - 1, Math.max(0, hz));
for (int x = 0; x < nx; x++)
for (int y = 0; y < ny; y++)
view.data[0][x + vx * y] = data[hz][x + nx * y];
for (int z = 0; z < nz; z++)
for (int y = 0; y < ny; y++)
view.data[0][nx + z + vx * y] = data[z][hx + nx * y];
for (int z = 0; z < nz; z++)
for (int x = 0; x < nx; x++)
view.data[0][x + vx * (ny + z)] = data[z][x + nx * hy];
return view;
}
public RealSignal createFigure(int hx, int hy, int hz) {
String n = "figure(" + name + ")";
int vx = nx + nz + 4;
int vy = ny + 2;
float max = this.getExtrema()[1];
RealSignal view = new RealSignal(n, vx, vy, 1);
for (int i = 0; i < vx * vy; i++)
view.data[0][i] = max;
hx = Math.min(nx - 1, Math.max(0, hx));
hy = Math.min(ny - 1, Math.max(0, hy));
hz = Math.min(nz - 1, Math.max(0, hz));
for (int x = 0; x < nx; x++)
for (int y = 0; y < ny; y++)
view.data[0][x + 1 + vx * (y + 1)] = data[hz][x + nx * y];
for (int z = 0; z < nz; z++)
for (int y = 0; y < ny; y++)
view.data[0][nx + 3 + z + vx * (y + 1)] = data[z][hx + nx * y];
return view;
}
public RealSignal createMIP() {
String n = "mip(" + name + ")";
int vx = nx + nz;
int vy = ny + nz;
RealSignal view = new RealSignal(n, vx, vy, 1);
for (int x = 0; x < nx; x++)
for (int y = 0; y < ny; y++)
for (int k = 0; k < nz; k++) {
int index = x + vx * y;
view.data[0][index] = Math.max(view.data[0][index], data[k][x + nx * y]);
}
for (int z = 0; z < nz; z++)
for (int y = 0; y < ny; y++)
for (int x = 0; x < nx; x++) {
int index = nx + z + vx * y;
view.data[0][index] = Math.max(view.data[0][index], data[z][x + nx * y]);
}
for (int z = 0; z < nz; z++)
for (int x = 0; x < nx; x++)
for (int y = 0; y < ny; y++) {
int index = x + vx * (ny + z);
view.data[0][index] = Math.max(view.data[0][index], data[z][x + nx * y]);
}
return view;
}
- public RealSignal createMontage() {
+ public RealSignal createPlanar() {
String n = "planar(" + name + ")";
int nr = (int) Math.sqrt(nz);
int nc = (int) Math.ceil(nz / nr) + 1;
int w = nx * nr;
int h = ny * nc;
RealSignal view = new RealSignal(n, w, h, 1);
for (int k = 0; k < nz; k++) {
int col = k % nr;
int row = k / nr;
int offx = col * nx;
int offy = row * ny;
for (int x = 0; x < nx; x++)
for (int y = 0; y < ny; y++)
view.data[0][x + offx + w * (y + offy)] = data[k][x + nx * y];
}
return view;
}
public RealSignal circular() {
for (int i = 0; i < nx; i++)
for (int j = 0; j < ny; j++)
setZ(i, j, rotate(getZ(i, j)));
for (int i = 0; i < nx; i++)
for (int k = 0; k < nz; k++)
setY(i, k, rotate(getY(i, k)));
for (int j = 0; j < ny; j++)
for (int k = 0; k < nz; k++)
setX(j, k, rotate(getX(j, k)));
return this;
}
public RealSignal rescale(Monitors monitors) {
new Constraint(monitors).rescaled(this, 0, 255);
return this;
}
public float[] rotate(float[] buffer) {
int len = buffer.length;
if (len <= 1)
return buffer;
int count = 0;
int offset = 0;
int start = len / 2;
while (count < len) {
int index = offset;
float tmp = buffer[index];
int index2 = (start + index) % len;
while (index2 != offset) {
buffer[index] = buffer[index2];
count++;
index = index2;
index2 = (start + index) % len;
}
buffer[index] = tmp;
count++;
offset++;
}
return buffer;
}
@Override
public String toString() {
return "Real Signal [" + nx + ", " + ny + ", " + nz + "]";
}
public BufferedImage preview() {
if (preview != null)
return preview;
int nxy = nx*ny;
float[] pixels = new float[nx*ny];
for (int i = 0; i < nxy; i++)
for (int k = 0; k < nz; k++) {
pixels[i] = Math.max(pixels[i], data[k][i]);
}
float max = -Float.MAX_VALUE;
float min = Float.MAX_VALUE;
for (int i = 0; i < nxy; i++) {
if (pixels[i] > max)
max = pixels[i];
if (pixels[i] < min)
min = pixels[i];
}
float a = 255f / Math.max(max-min, (float)Operations.epsilon);
preview = new BufferedImage(nx, ny, BufferedImage.TYPE_INT_ARGB);
int alpha = (255 << 24);
for (int i = 0; i < nx; i++)
for (int j = 0; j < ny; j++) {
int v = (int)(a*(pixels[i+j*nx] - min));
preview.setRGB(i, j, alpha | (v << 16) | (v << 8) | v);
}
return preview;
}
public RealSignal log10() {
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
data[k][i] = (float)Math.log10(data[k][i]);
}
return this;
}
public RealSignal log() {
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
data[k][i] = (float)Math.log(data[k][i]);
}
return this;
}
public RealSignal exp() {
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
data[k][i] = (float)Math.exp(data[k][i]);
}
return this;
}
public RealSignal abs() {
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
data[k][i] = (float)Math.abs(data[k][i]);
}
return this;
}
public RealSignal sqrt() {
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
data[k][i] = (float)Math.sqrt(data[k][i]);
}
return this;
}
public RealSignal sqr() {
int nxy = nx * ny;
for (int k = 0; k < nz; k++)
for (int i = 0; i < nxy; i++) {
data[k][i] = (float)(data[k][i]*data[k][i]);
}
return this;
}
public RealSignal rescale(double min, double max) {
int nxy = nx * ny;
float minf = (float)min;
float stats[] = getStats();
float a = ((float)max-minf) / (stats[2] - stats[1]);
for(int k=0; k<nz; k++)
for(int i=0; i<nxy; i++) {
data[k][i] = a*(data[k][i] - stats[1]) + minf;
}
return this;
}
}

Event Timeline