Page MenuHomec4science

No OneTemporary

File Metadata

Created
Sat, Nov 23, 00:25
This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/DeconvolutionLab2/DeconvolutionLab2.config b/DeconvolutionLab2/DeconvolutionLab2.config
index 191f1f2..4b8bc9e 100644
--- a/DeconvolutionLab2/DeconvolutionLab2.config
+++ b/DeconvolutionLab2/DeconvolutionLab2.config
@@ -1,82 +1,72 @@
#DeconvolutionLab2 [Beta 2]
#DeconvolutionLab2 [Beta 2]
-#Tue Feb 21 19:20:33 WET 2017
-Algorithm.FISTA.iterations=10
-Algorithm.FISTA.reg=0.1
-Algorithm.FISTA.scale=3
-Algorithm.FISTA.step=1.0
-Algorithm.FISTA.wavelets=Haar
-Algorithm.ICTM.iterations=10
-Algorithm.ICTM.reg=0.1
-Algorithm.ICTM.step=1.0
-Algorithm.ISTA.iterations=10
-Algorithm.ISTA.reg=0.1
-Algorithm.ISTA.scale=3
-Algorithm.ISTA.step=1.0
-Algorithm.ISTA.wavelets=Haar
-Algorithm.LW+.iterations=10
-Algorithm.LW+.step=1.0
-Algorithm.LW.iterations=10
-Algorithm.LW.step=1.0
-Algorithm.RIF.reg=0.1
-Algorithm.RL.iterations=10
-Algorithm.RLTV.reg=0.1
-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=Regularized Inverse Filter
+#Wed Feb 22 13:06:29 WET 2017
+Algorithm.I.gaussian.mean=0.0
+Algorithm.I.gaussian.stdev=1.0
+Algorithm.I.iterations=10
+Algorithm.I.poisson=0.0
+Algorithm.I.reg=0.1
+Algorithm.I.scale=3
+Algorithm.I.step=1.0
+Algorithm.I.wavelets=Haar
+Algorithm.algorithm=Regularized Inverse Filter [RIF | LRIF]
Border.apoxy=Uniform
Border.apoz=Uniform
Border.extxy=0
Border.extz=0
Border.padxy=None
Border.padz=None
Computation.dim=XYZ
Computation.epsilon=1E-6
Computation.fft=Academic
Computation.normalization=1
Controller.constraint.enable=false
Controller.constraint.value=no
Controller.itmax.enable=true
Controller.reference.enable=false
Controller.reference.value=
Controller.residu.enable=false
Controller.residu.value=0.01
Controller.time.enable=false
Controller.time.value=3600
+DeconvolutionLab.DeconvolutionDialog.location.h=400
+DeconvolutionLab.DeconvolutionDialog.location.w=600
+DeconvolutionLab.DeconvolutionDialog.location.x=711
+DeconvolutionLab.DeconvolutionDialog.location.y=129
DeconvolutionLab.MainDialog.location.h=381
DeconvolutionLab.MainDialog.location.w=544
-DeconvolutionLab.MainDialog.location.x=334
-DeconvolutionLab.MainDialog.location.y=383
-Image.image.row0=IMG_0517.JPG;file;/Users/dsage/Desktop/IMG_0517.JPG;null
-Image.image.row1=RandomLines;synthetic;RandomLines 100.0 0.0 300.0 size 512 512 32 ;\u232B
+DeconvolutionLab.MainDialog.location.x=35
+DeconvolutionLab.MainDialog.location.y=165
+Image.image.row0=Pos1-1.tif;file;/Users/dsage/Desktop/Maria Azevedo/Pos1-1.tif;
+Image.image.row1=DoG;synthetic;DoG 100.0 0.0 3.0 35.0 size 128 128 32 ;\u232B
Image.image.row2=Cube;synthetic;Cube 100.0 0.0 10.0 1.0 size 128 128 32 ;\u232B
-Image.image.row3=Applications;platform;Applications;\u232B
-Image.image.row4=Applications;directory;/users/dsage/Applications;\u232B
+Image.image.row3=IMG_0517.JPG;file;/Users/dsage/Desktop/IMG_0517.JPG;null
+Image.image.row4=RandomLines;synthetic;RandomLines 100.0 0.0 300.0 size 512 512 32 ;\u232B
Image.image.row5=Cube;synthetic;Cube 100.0 0.0 10.0 1.0 size 128 128 32 ;\u232B
-Image.image.row6=lib;directory;/Users/dsage/git/deconvolution/DeconvolutionLab2/lib;\u232B
-Image.image.selected=IMG_0517.JPG;file;/Users/dsage/Desktop/IMG_0517.JPG;null
+Image.image.row6=Applications;platform;Applications;\u232B
+Image.image.row7=Applications;directory;/users/dsage/Applications;\u232B
+Image.image.row8=Cube;synthetic;Cube 100.0 0.0 10.0 1.0 size 128 128 32 ;\u232B
+Image.image.row9=lib;directory;/Users/dsage/git/deconvolution/DeconvolutionLab2/lib;\u232B
+Image.image.selected=Pos1-1.tif;file;/Users/dsage/Desktop/Maria Azevedo/Pos1-1.tif;
Language.headless=Run (Headless)
Language.job=Job
Language.language=Command line
Output.output.row0=stats;ST1;;;;\u2713;\u2713;\u232B
Output.output.row1=ortho;OR1;;;;\u2713;\u2713;\u232B
Output.output.selected=stats;ST1;;;;\u2713;\u2713;\u232B
PSF.psf.row0=AirySimulated;synthetic;AirySimulated 100.0 0.0 1.0 size 128 128 32 ;null
PSF.psf.row1=Chrome Apps.localized;directory;/users/dsage/applications/Chrome Apps.localized;\u232B
PSF.psf.row2=FI1.tif;file;/Users/dsage/git/deconvolution/DeconvolutionLab2/FI1.tif;\u232B
PSF.psf.selected=AirySimulated;synthetic;AirySimulated 100.0 0.0 1.0 size 128 128 32 ;null
Running.Directory=/Users/dsage/Applications
-Running.Display=final
-Running.Monitor=full
-Running.Multithreading=enable
+Running.Display=no
+Running.Monitor=no
+Running.Multithreading=yes
Running.Path=specify
-Running.Stats=no
-Running.System=yes
+Running.Stats=show save
+Running.System=no
Running.Verbose=log
+System.Frame.location.h=80
+System.Frame.location.w=637
+System.Frame.location.x=30
+System.Frame.location.y=564
diff --git a/DeconvolutionLab2/build.xml b/DeconvolutionLab2/build.xml
index 8254ace..8894410 100644
--- a/DeconvolutionLab2/build.xml
+++ b/DeconvolutionLab2/build.xml
@@ -1,17 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project name="Test" default="build" basedir=".">
- <property name="imagej" location="${user.home}/Desktop/ImageJ/plugins"/>
- <property name="fiji" location="${user.home}/Desktop/Fiji.app/plugins"/>
+<project name="DeconvolutionLab2" default="build" basedir=".">
+
+ <property name="imagej" location="${user.home}/Desktop/ImageJ/plugins" />
+ <property name="fiji" location="${user.home}/Desktop/Fiji-deconv.app/plugins" />
+ <property name="matlab" location="/Applications/MATLAB_R2014b.app/java/" />
<target name="build">
- <mkdir dir="bin"/>
- <copy toDir="${fiji}" file="./bin/Test_Orientation.class" />
- <copy toDir="${imagej}" file="./bin/Test_Orientation.class" />
- <copy toDir="${fiji}" file="./bin/Test_Cytoplasm_Segmentation.class" />
- <copy toDir="${imagej}" file="./bin/Test_Cytoplasm_Segmentation.class" />
- <copy toDir="${fiji}" file="./bin/Test_Tracing_Axon.class" />
- <copy toDir="${imagej}" file="./bin/Test_Tracing_Axon.class" />
- <copy toDir="${fiji}" file="./bin/Test_Tracing_Axon$Path.class" />
- <copy toDir="${imagej}" file="./bin/Test_Tracing_Axon$Path.class" />
+ <mkdir dir="bin" />
+ <copy todir="bin">
+ <fileset dir="ij">
+ </fileset>
+ </copy>
+ <copy file="plugins.config" toDir="bin" />
+
+ <zip destfile="../DeconvolutionLab2-src.zip" basedir="src" />
+ <zip destfile="../DeconvolutionLab2-cls.zip" basedir="bin" />
+ <jar destfile="../DeconvolutionLab_2.jar" basedir="bin">
+ <manifest>
+ <attribute name="Main-Class" value="DeconvolutionLab2" />
+ <attribute name="Class-Path" value="ij.jar jtransforms.jar" />
+ </manifest>
+ </jar>
+
+ <copy toDir="${fiji}" file="../DeconvolutionLab_2.jar" />
+ <copy toDir="${matlab}" file="../DeconvolutionLab_2.jar" />
+
+ <copy toDir="${imagej}" file="../DeconvolutionLab_2.jar" />
+
</target>
-</project>
\ No newline at end of file
+</project>
diff --git a/DeconvolutionLab2/src/DL2.java b/DeconvolutionLab2/src/DL2.java
index 3dd6620..700727b 100644
--- a/DeconvolutionLab2/src/DL2.java
+++ b/DeconvolutionLab2/src/DL2.java
@@ -1,237 +1,237 @@
import java.io.File;
import deconvolution.Deconvolution;
import deconvolutionlab.Imaging;
import deconvolutionlab.Lab;
-import deconvolutionlab.dialog.LabDialog;
+import deconvolutionlab.LabDialog;
import ij.ImagePlus;
import ij.WindowManager;
import matlab.Converter;
import signal.RealSignal;
/*
* 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/>.
*/
/**
* This class is dedicated to the Matlab interface for DeconvolutionLab2
* @author sage
*
*/
public class DL2 {
public static void lab() {
Lab.init(Imaging.Platform.MATLAB, System.getProperty("user.dir") + File.separator + "DeconvolutionLab2.config");
LabDialog dlg = new LabDialog();
Lab.setVisible(dlg, false);
}
public static void run(String command) {
new Deconvolution("Matlab", command).deconvolve();
}
public static void launch(String command) {
new Deconvolution("Matlab", command).launch();
}
public static Object get(String image) {
ImagePlus imp = WindowManager.getCurrentImage();
if (imp != null)
return Converter.get(imp);
return null;
}
public static Object run(Object arrayImage, Object arrayPSF, String algo) {
RealSignal image = Converter.createRealSignal(arrayImage);
RealSignal psf = Converter.createRealSignal(arrayPSF);
String command = " -image platform input -psf platform psf -algorithm " + algo;
Deconvolution d = new Deconvolution("Matlab", command);
RealSignal result = d.deconvolve(image, psf);
return Converter.createObject(result);
}
public static void help() {
Lab.help();
}
public static void clear() {
int ids[] = WindowManager.getIDList();
for(int id : ids) {
ImagePlus imp = WindowManager.getImage(id);
if (imp != null)
imp.close();
}
}
public static Object DIV(Object arrayImage, Object arrayPSF) {
return DIV(arrayImage, arrayPSF, "");
}
public static Object DIV(Object arrayImage, Object arrayPSF, String options) {
RealSignal image = Converter.createRealSignal(arrayImage);
RealSignal psf = Converter.createRealSignal(arrayPSF);
String command = " -algorithm DIV " + options;
Deconvolution d = new Deconvolution("Matlab DIV", command);
RealSignal result = d.deconvolve(image, psf);
return Converter.createObject(result);
}
public static Object CONV(Object arrayImage, Object arrayPSF) {
return CONV(arrayImage, arrayPSF, "");
}
public static Object CONV(Object arrayImage, Object arrayPSF, String options) {
RealSignal image = Converter.createRealSignal(arrayImage);
RealSignal psf = Converter.createRealSignal(arrayPSF);
String command = " -algorithm CONV " + options;
Deconvolution d = new Deconvolution("Matlab CONV", command);
RealSignal result = d.deconvolve(image, psf);
return Converter.createObject(result);
}
public static Object NIF(Object arrayImage, Object arrayPSF) {
return NIF(arrayImage, arrayPSF, "");
}
public static Object NIF(Object arrayImage, Object arrayPSF, String options) {
RealSignal image = Converter.createRealSignal(arrayImage);
RealSignal psf = Converter.createRealSignal(arrayPSF);
String command = " -algorithm NIF " + options;
Deconvolution d = new Deconvolution("Matlab NIF", command);
RealSignal result = d.deconvolve(image, psf);
return Converter.createObject(result);
}
public static Object TRIF(Object arrayImage, Object arrayPSF, double regularizationFactor) {
return TRIF(arrayImage, arrayPSF, regularizationFactor, "");
}
public static Object TRIF(Object arrayImage, Object arrayPSF, double regularizationFactor, String options) {
RealSignal image = Converter.createRealSignal(arrayImage);
RealSignal psf = Converter.createRealSignal(arrayPSF);
String command = " -algorithm TRIF " + regularizationFactor + " " + options;
Deconvolution d = new Deconvolution("Matlab TRIF", command);
RealSignal result = d.deconvolve(image, psf);
return Converter.createObject(result);
}
public static Object RIF(Object arrayImage, Object arrayPSF, double regularizationFactor) {
return RIF(arrayImage, arrayPSF, regularizationFactor, "");
}
public static Object RIF(Object arrayImage, Object arrayPSF, double regularizationFactor, String options) {
RealSignal image = Converter.createRealSignal(arrayImage);
RealSignal psf = Converter.createRealSignal(arrayPSF);
String command = " -algorithm RIF " + regularizationFactor + " " + options;
Deconvolution d = new Deconvolution("Matlab RIF", command);
RealSignal result = d.deconvolve(image, psf);
return Converter.createObject(result);
}
public static Object RL(Object arrayImage, Object arrayPSF, double itmax) {
return RL(arrayImage, arrayPSF, itmax, "");
}
public static Object RL(Object arrayImage, Object arrayPSF, double itmax, String options) {
RealSignal image = Converter.createRealSignal(arrayImage);
RealSignal psf = Converter.createRealSignal(arrayPSF);
String command = " -algorithm RL " + itmax + " " + options;
Deconvolution d = new Deconvolution("Matlab RL", command);
RealSignal result = d.deconvolve(image, psf);
return Converter.createObject(result);
}
public static Object RLTV(Object arrayImage, Object arrayPSF, double itmax, double regularizationFactor) {
return RLTV(arrayImage, arrayPSF, itmax, regularizationFactor, "");
}
public static Object RLTV(Object arrayImage, Object arrayPSF, double itmax, double regularizationFactor, String options) {
RealSignal image = Converter.createRealSignal(arrayImage);
RealSignal psf = Converter.createRealSignal(arrayPSF);
String command = " -algorithm RLTV " + itmax + " " + regularizationFactor + " " + options;
Deconvolution d = new Deconvolution("Matlab RLTV", command);
RealSignal result = d.deconvolve(image, psf);
return Converter.createObject(result);
}
public static Object LW(Object arrayImage, Object arrayPSF, double itmax, double gamma) {
return LW(arrayImage, arrayPSF, itmax, gamma, "");
}
public static Object LW(Object arrayImage, Object arrayPSF, double itmax, double gamma, String options) {
RealSignal image = Converter.createRealSignal(arrayImage);
RealSignal psf = Converter.createRealSignal(arrayPSF);
String command = " -algorithm LW " + itmax + " " + gamma + " " + options;
Deconvolution d = new Deconvolution("Matlab LW", command);
RealSignal result = d.deconvolve(image, psf);
return Converter.createObject(result);
}
public static Object NNLS(Object arrayImage, Object arrayPSF, double itmax, double gamma) {
return LW(arrayImage, arrayPSF, itmax, gamma, "");
}
public static Object NNLS(Object arrayImage, Object arrayPSF, double itmax, double gamma, String options) {
RealSignal image = Converter.createRealSignal(arrayImage);
RealSignal psf = Converter.createRealSignal(arrayPSF);
String command = " -algorithm LW+ " + itmax + " " + options;
Deconvolution d = new Deconvolution("Matlab NNLS", command);
RealSignal result = d.deconvolve(image, psf);
return Converter.createObject(result);
}
public static Object TM(Object arrayImage, Object arrayPSF, double itmax, double gamma, double lambda) {
return TM(arrayImage, arrayPSF, itmax, gamma, lambda, "");
}
public static Object TM(Object arrayImage, Object arrayPSF, double itmax, double gamma, double lambda, String options) {
RealSignal image = Converter.createRealSignal(arrayImage);
RealSignal psf = Converter.createRealSignal(arrayPSF);
String command = " -algorithm TM " + itmax + " " + gamma + " " + lambda + " " + options;
Deconvolution d = new Deconvolution("Matlab TM", command);
RealSignal result = d.deconvolve(image, psf);
return Converter.createObject(result);
}
public static Object ICTM(Object arrayImage, Object arrayPSF, double itmax, double gamma, double lambda) {
return ICTM(arrayImage, arrayPSF, itmax, gamma, lambda, "");
}
public static Object ICTM(Object arrayImage, Object arrayPSF, double itmax, double gamma, double lambda, String options) {
RealSignal image = Converter.createRealSignal(arrayImage);
RealSignal psf = Converter.createRealSignal(arrayPSF);
String command = " -algorithm ICTM " + itmax + " " + gamma + " " + lambda + " " + options;
Deconvolution d = new Deconvolution("Matlab ICTM", command);
RealSignal result = d.deconvolve(image, psf);
return Converter.createObject(result);
}
}
diff --git a/DeconvolutionLab2/src/DeconvolutionLab2.java b/DeconvolutionLab2/src/DeconvolutionLab2.java
index 2bbdc3e..ead7a4d 100644
--- a/DeconvolutionLab2/src/DeconvolutionLab2.java
+++ b/DeconvolutionLab2/src/DeconvolutionLab2.java
@@ -1,133 +1,133 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
import java.io.File;
import deconvolution.Command;
import deconvolution.Deconvolution;
import deconvolutionlab.Constants;
import deconvolutionlab.Imaging;
import deconvolutionlab.Imaging.Platform;
import deconvolutionlab.Lab;
-import deconvolutionlab.dialog.LabDialog;
+import deconvolutionlab.LabDialog;
import deconvolutionlab.monitor.Monitors;
public class DeconvolutionLab2 {
public static String ack = Constants.name + " " + Constants.version + " " + Constants.copyright;
public static void main(String arg[]) {
System.out.println(ack);
Lab.init(Platform.STANDALONE);
if (arg.length == 0) {
System.out.println("Starting lab");
lab(arg);
return;
}
String flag = arg[0].trim().toLowerCase();
if (flag.equalsIgnoreCase("help")) {
System.out.println("Starting help");
help();
return;
}
else if (flag.equalsIgnoreCase("lab")) {
System.out.println("Starting lab");
lab(arg);
}
else if (flag.equalsIgnoreCase("fft")) {
System.out.println("Starting fft");
Lab.checkFFT(Monitors.createDefaultMonitor());
}
else if (flag.equalsIgnoreCase("run")) {
System.out.println("Starting run");
String cmd = "";
for (int i = 1; i < arg.length; i++)
cmd += arg[i] + " ";
new Deconvolution("Run", cmd, Deconvolution.Finish.KILL).deconvolve();
}
else if (flag.equalsIgnoreCase("launch")) {
System.out.println("Starting launch");
String cmd = "";
for (int i = 1; i < arg.length; i++)
cmd += arg[i] + " ";
new Deconvolution("Launch", cmd, Deconvolution.Finish.KILL).launch();
}
else
System.out.println("" + flag + " command not found");
}
private static void lab(String arg[]) {
String config = System.getProperty("user.dir") + File.separator + "DeconvolutionLab2.config";
if (arg.length >= 2) {
String filename = arg[1].trim();
File file = new File(filename);
if (file.exists())
if (file.isFile())
if (file.canRead())
config = filename;
}
Lab.init(Platform.STANDALONE, config);
LabDialog dialog = new LabDialog();
dialog.setVisible(true);
}
public static void help() {
System.out.println("More info:" + Constants.url);
System.out.println("Syntax:");
System.out.println("java -jar DeconvolutionLab_2.jar lab");
System.out.println("java -jar DeconvolutionLab_2.jar run {command} ...");
System.out.println("java -jar DeconvolutionLab_2.jar launch {command} ...");
System.out.println("java -jar DeconvolutionLab_2.jar fft");
System.out.println("java -jar DeconvolutionLab_2.jar info");
System.out.println("java -jar DeconvolutionLab_2.jar help");
System.out.println("{command} is the full command line for running a deconvolution");
System.out.print("Keywords of {command}: ");
for (String keyword : Command.keywords)
System.out.print(keyword + " ");
}
public DeconvolutionLab2(String cmd) {
System.out.println("cmd: " + cmd);
Lab.init(Imaging.Platform.STANDALONE, System.getProperty("user.dir") + File.separator + "DeconvolutionLab2.config");
new Deconvolution("CommandLine", cmd).deconvolve();
}
}
diff --git a/DeconvolutionLab2/src/DeconvolutionLab2_Lab.java b/DeconvolutionLab2/src/DeconvolutionLab2_Lab.java
index 30480ac..62e260b 100644
--- a/DeconvolutionLab2/src/DeconvolutionLab2_Lab.java
+++ b/DeconvolutionLab2/src/DeconvolutionLab2_Lab.java
@@ -1,49 +1,49 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
import java.io.File;
import deconvolutionlab.Config;
import deconvolutionlab.Imaging;
import deconvolutionlab.Lab;
-import deconvolutionlab.dialog.LabDialog;
+import deconvolutionlab.LabDialog;
import ij.IJ;
import ij.plugin.PlugIn;
public class DeconvolutionLab2_Lab implements PlugIn {
@Override
public void run(String arg) {
Lab.init(Imaging.Platform.IMAGEJ, IJ.getDirectory("plugins") + File.separator + "DeconvolutionLab2.config");
LabDialog dlg = new LabDialog();
Lab.setVisible(dlg, false);
}
}
diff --git a/DeconvolutionLab2/src/DeconvolutionLab2_Launch.java b/DeconvolutionLab2/src/DeconvolutionLab2_Launch.java
index ce705e2..e387cd7 100644
--- a/DeconvolutionLab2/src/DeconvolutionLab2_Launch.java
+++ b/DeconvolutionLab2/src/DeconvolutionLab2_Launch.java
@@ -1,54 +1,54 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
import java.io.File;
import deconvolution.Deconvolution;
import deconvolutionlab.Imaging;
import deconvolutionlab.Lab;
-import deconvolutionlab.dialog.LabDialog;
+import deconvolutionlab.LabDialog;
import ij.IJ;
import ij.Macro;
import ij.plugin.PlugIn;
public class DeconvolutionLab2_Launch implements PlugIn {
@Override
public void run(String arg) {
Lab.init(Imaging.Platform.IMAGEJ, IJ.getDirectory("plugins") + File.separator + "DeconvolutionLab2.config");
if (Macro.getOptions() == null) {
LabDialog dlg = new LabDialog();
Lab.setVisible(dlg, false);
}
else
new Deconvolution("Macro", Macro.getOptions()).launch();
}
}
diff --git a/DeconvolutionLab2/src/DeconvolutionLab2_Run.java b/DeconvolutionLab2/src/DeconvolutionLab2_Run.java
index 528e7b4..bd023f7 100644
--- a/DeconvolutionLab2/src/DeconvolutionLab2_Run.java
+++ b/DeconvolutionLab2/src/DeconvolutionLab2_Run.java
@@ -1,55 +1,55 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
import java.io.File;
import deconvolution.Deconvolution;
import deconvolutionlab.Config;
import deconvolutionlab.Imaging;
import deconvolutionlab.Lab;
-import deconvolutionlab.dialog.LabDialog;
+import deconvolutionlab.LabDialog;
import ij.IJ;
import ij.Macro;
import ij.plugin.PlugIn;
public class DeconvolutionLab2_Run implements PlugIn {
@Override
public void run(String arg) {
Lab.init(Imaging.Platform.IMAGEJ, IJ.getDirectory("plugins") + File.separator + "DeconvolutionLab2.config");
if (Macro.getOptions() == null) {
LabDialog dlg = new LabDialog();
Lab.setVisible(dlg, false);
}
else
new Deconvolution("Run", Macro.getOptions()).deconvolve();
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/Command.java b/DeconvolutionLab2/src/deconvolution/Command.java
index 240bfb3..5c0e7b7 100644
--- a/DeconvolutionLab2/src/deconvolution/Command.java
+++ b/DeconvolutionLab2/src/deconvolution/Command.java
@@ -1,468 +1,469 @@
/*
* 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 deconvolution.algorithm.AbstractAlgorithm;
import deconvolution.algorithm.Algorithm;
import deconvolution.algorithm.Controller;
import deconvolutionlab.Output;
import deconvolutionlab.OutputCollection;
import deconvolutionlab.Output.View;
import deconvolutionlab.modules.AbstractModule;
import deconvolutionlab.modules.CommandModule;
import deconvolutionlab.monitor.Verbose;
import fft.AbstractFFT;
import fft.AbstractFFTLibrary;
import fft.FFT;
import lab.tools.NumFormat;
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 void decode(String command, Deconvolution deconvolution) {
AbstractAlgorithm algo = Algorithm.getDefaultAlgorithm();
boolean flagSystem = true;
boolean flagDisplay = true;
boolean flagMultithreading = true;
int monitor = 4;
int stats = 4;
Verbose verbose = Verbose.Log;
String path = System.getProperty("user.dir");
Controller controller = new Controller();
OutputCollection outs = new OutputCollection();
Padding pad = new Padding();
Apodization apo = new Apodization();
double norm = 1.0;
AbstractFFTLibrary fft = FFT.getLibraryByName("Academic");
ArrayList<Token> tokens = parse(command);
for (Token token : tokens) {
if (token.keyword.equalsIgnoreCase("-algorithm"))
algo = Command.decodeAlgorithm(token, controller);
if (token.keyword.equalsIgnoreCase("-path") && !token.parameters.equalsIgnoreCase("current"))
path = token.parameters;
if (token.keyword.equalsIgnoreCase("-monitor"))
monitor = decodeMonitor(token);
if (token.keyword.equalsIgnoreCase("-stats"))
stats = decodeStats(token);
if (token.keyword.equalsIgnoreCase("-system"))
flagSystem = decodeSystem(token);
if (token.keyword.equalsIgnoreCase("-display"))
flagDisplay = decodeDisplay(token);
if (token.keyword.equalsIgnoreCase("-multithreading"))
flagMultithreading = decodeMultithreading(token);
if (token.keyword.equalsIgnoreCase("-verbose"))
verbose = Verbose.getByName(token.parameters);
if (token.keyword.equalsIgnoreCase("-fft"))
fft = FFT.getLibraryByName(token.parameters);
if (token.keyword.equalsIgnoreCase("-pad"))
pad = decodePadding(token);
if (token.keyword.equalsIgnoreCase("-apo"))
apo = decodeApodization(token);
if (token.keyword.equalsIgnoreCase("-norm"))
norm = decodeNormalization(token);
if (token.keyword.equalsIgnoreCase("-constraint"))
decodeController(token, controller);
if (token.keyword.equalsIgnoreCase("-time"))
decodeController(token, controller);
if (token.keyword.equalsIgnoreCase("-residu"))
decodeController(token, controller);
if (token.keyword.equalsIgnoreCase("-reference"))
decodeController(token, controller);
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)
outs.add(out);
}
}
deconvolution.setAlgorithm(algo, controller);
deconvolution.setPath(path);
deconvolution.setNormalization(norm);
deconvolution.setPadding(pad);
deconvolution.setApodization(apo);
deconvolution.setOutput(outs);
deconvolution.setVerbose(verbose);
deconvolution.setFFT(fft);
deconvolution.setMonitor(monitor);
deconvolution.setStats(stats);
deconvolution.setFlags(flagDisplay, flagMultithreading, flagSystem);
}
/**
* 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, Controller controller) {
String option = token.option;
AbstractAlgorithm algo = Algorithm.createAlgorithm(option);
+ algo.setShortname(option);
double params[] = parseNumeric(token.parameters);
if (params != null) {
algo.setParameters(params);
if (algo.isIterative() && params.length >= 1)
controller.setIterationMax((int)params[0]);
}
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 void decodeController(Token token, Controller controller) {
String line = token.parameters;
if (token.parameters.startsWith("@")) {
String parts[] = token.parameters.split(" ");
if (parts.length >= 1) {
line = token.parameters.substring(parts[0].length(), token.parameters.length()).trim();
}
}
if (token.keyword.equals("-constraint"))
controller.setConstraint(Constraint.getByName(line.trim()));
else if (token.keyword.equals("-residu"))
controller.setResiduStop(NumFormat.parseNumber(line, -1));
else if (token.keyword.equals("-reference"))
controller.setReference(line);
else if (token.keyword.equals("-time"))
controller.setTimeStop(NumFormat.parseNumber(line, Double.MAX_VALUE));
}
public static double decodeNormalization(Token token) {
if (token.parameters.toLowerCase().endsWith("no"))
return 0;
else
return NumFormat.parseNumber(token.parameters, 1);
}
public static int decodeMonitor(Token token) {
String parts[] = token.parameters.toLowerCase().split(" ");
int m = 0;
for(String p : parts) {
if (p.startsWith("no"))
return 0;
if (p.equals("false"))
return 0;
if (p.equals("0"))
return 0;
if (p.equals("1"))
return 1;
if (p.equals("2"))
return 2;
if (p.equals("3"))
return 3;
if (p.equals("console"))
m += 1;
if (p.equals("table"))
m += 2;
}
return m;
}
public static int decodeStats(Token token) {
String parts[] = token.parameters.toLowerCase().split(" ");
int m = 0;
for(String p : parts) {
if (p.startsWith("no"))
return 0;
if (p.equals("false"))
return 0;
if (p.equals("0"))
return 0;
if (p.equals("1"))
return 1;
if (p.equals("2"))
return 2;
if (p.equals("3"))
return 3;
if (p.equals("show"))
m += 1;
if (p.equals("save"))
m += 2;
}
return m;
}
public static boolean decodeMonitorConsole(Token token) {
String p = token.parameters.toLowerCase();
if (p.startsWith("no"))
return false;
if (p.equals("0"))
return false;
if (p.equals("false"))
return false;
return true;
}
public static boolean decodeSystem(Token token) {
String p = token.parameters.toLowerCase();
if (p.startsWith("no"))
return false;
if (p.equals("0"))
return false;
if (p.equals("false"))
return false;
return true;
}
public static boolean decodeDisplay(Token token) {
String p = token.parameters.toLowerCase();
if (p.startsWith("no"))
return false;
if (p.equals("0"))
return false;
if (p.equals("false"))
return false;
return true;
}
public static boolean decodeMultithreading(Token token) {
String p = token.parameters.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;
}
public static Padding decodePadding(Token token) {
AbstractPadding padXY = new NoPadding();
AbstractPadding padZ = new NoPadding();
int extXY = 0;
int extZ = 0;
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);
if (ext.length > 0)
extXY = (int) Math.round(ext[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;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/Deconvolution.java b/DeconvolutionLab2/src/deconvolution/Deconvolution.java
index b8c3eda..d64f611 100644
--- a/DeconvolutionLab2/src/deconvolution/Deconvolution.java
+++ b/DeconvolutionLab2/src/deconvolution/Deconvolution.java
@@ -1,687 +1,736 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution;
import java.io.File;
import java.util.ArrayList;
import deconvolution.algorithm.AbstractAlgorithm;
import deconvolution.algorithm.Controller;
import deconvolutionlab.Constants;
import deconvolutionlab.Lab;
import deconvolutionlab.Output;
import deconvolutionlab.OutputCollection;
import deconvolutionlab.TableStats;
import deconvolutionlab.monitor.ConsoleMonitor;
import deconvolutionlab.monitor.Monitors;
import deconvolutionlab.monitor.StatusMonitor;
import deconvolutionlab.monitor.TableMonitor;
import deconvolutionlab.monitor.Verbose;
import deconvolutionlab.system.SystemInfo;
+import fft.AbstractFFT;
import fft.AbstractFFTLibrary;
import lab.tools.NumFormat;
import signal.RealSignal;
import signal.apodization.Apodization;
import signal.factory.SignalFactory;
import signal.padding.Padding;
public class Deconvolution implements Runnable {
public enum Finish {
DIE, ALIVE, KILL
};
private AbstractAlgorithm algo = null;
private String path;
private double norm = 1.0;
private Padding pad = new Padding();
private Apodization apo = new Apodization();
private OutputCollection outs;
private Verbose verbose = Verbose.Log;
private AbstractFFTLibrary fft;
private int flagMonitor = 3;
private int flagStats = 0;
private boolean flagDisplay = true;
private boolean flagMultithreading = true;
private boolean flagSystem = true;
private Monitors monitors = new Monitors();
private String command = "";
private boolean live = false;
private Features report = new Features();
private String name = "";
- private ArrayList<DeconvolutionListener> listeners = new ArrayList<DeconvolutionListener>(); private boolean imageLoaded = false;
+ private ArrayList<DeconvolutionListener> listeners = new ArrayList<DeconvolutionListener>();
+ private boolean imageLoaded = false;
private RealSignal image;
private RealSignal psf;
- private RealSignal result;
+ private RealSignal deconvolvedImage;
private Finish finish = Finish.DIE;
private DeconvolutionDialog dialog;
private TableStats tableStats;
private TableMonitor tableMonitor;
public Deconvolution(String name, String command) {
this.name = name;
tableStats = new TableStats(name, Constants.widthGUI, 240, path, (flagStats & 2) == 2);
tableMonitor = new TableMonitor(name , Constants.widthGUI, 240);
this.finish = Finish.DIE;
setCommand(command);
}
public Deconvolution(String name, String command, Finish finish) {
this.name = name;
tableStats = new TableStats(name, Constants.widthGUI, 240, path, (flagStats & 2) == 2);
tableMonitor = new TableMonitor(name , Constants.widthGUI, 240);
this.finish = finish;
setCommand(command);
}
public void setCommand(String command) {
this.command = command;
Command.decode(command, this);
this.command = command;
if (name.equals("") && algo != null)
name = algo.getShortname();
monitors = Monitors.createDefaultMonitor();
live = false;
}
public void close() {
if (dialog != null)
dialog.dispose();
finalize();
}
public void finalize() {
algo = null;
image = null;
psf = null;
monitors = null;
System.gc();
}
/**
* This method runs the deconvolution without graphical user interface.
*
* @param exit
* System.exit call is true
*/
public RealSignal deconvolve(RealSignal image, RealSignal psf) {
this.image = image;
this.psf = psf;
imageLoaded = true;
runDeconvolve();
- return result;
+ return deconvolvedImage;
}
public RealSignal deconvolve() {
this.image = null;
this.psf = null;
imageLoaded = false;
runDeconvolve();
- return result;
+ return deconvolvedImage;
}
/**
* This method runs the deconvolution without graphical user interface.
*
* @param exit
* System.exit call is true
*/
private void runDeconvolve() {
if ((flagMonitor & 2) == 2) {
monitors.add(tableMonitor);
tableMonitor.show();
}
if ((flagStats & 1) == 1) {
tableStats.show();
}
if (fft == null) {
run();
return;
}
if (!fft.isMultithreadable()) {
run();
return;
}
if (flagMultithreading) {
Thread thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}
else {
run();
}
}
/**
* This method runs the deconvolution with a graphical user interface.
*
* @param job
* Name of the job of deconvolution
*/
public void launch() {
- dialog = new DeconvolutionDialog(this, tableMonitor, tableStats);
+ dialog = new DeconvolutionDialog(DeconvolutionDialog.Module.ALL, this, tableMonitor, tableStats);
Lab.setVisible(dialog, false);
monitors = new Monitors();
monitors.add(new StatusMonitor(dialog.getProgressBar()));
if ((flagMonitor & 2) == 2) {
monitors.add(tableMonitor);
}
}
public Monitors createMonitors1() {
Monitors monitors = new Monitors();
return monitors;
}
@Override
public void run() {
double chrono = System.nanoTime();
if ((flagMonitor & 1) == 1)
monitors.add(new ConsoleMonitor());
if (flagSystem)
SystemInfo.activate();
for (DeconvolutionListener listener : listeners)
listener.started();
live = true;
if (monitors != null)
monitors.setVerbose(verbose);
report.add("Path", checkPath(path));
monitors.log("Path: " + checkPath(path));
if (!imageLoaded)
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());
if (!imageLoaded)
psf = openPSF();
if (psf == null) {
monitors.error("PSF: not valid");
report.add("PSF", "Not valid");
if (finish == Finish.KILL)
System.exit(-102);
return;
}
report.add("PSF", psf.dimAsString());
monitors.log("PSF: " + psf.dimAsString());
if (algo == null) {
monitors.error("Algorithm: not valid");
if (finish == Finish.KILL)
System.exit(-103);
return;
}
Controller controller = algo.getController();
if (controller == null) {
monitors.error("Controller: not valid");
if (finish == Finish.KILL)
System.exit(-104);
return;
}
if (flagStats > 0)
controller.setTableStats(tableStats);
report.add("FFT", fft.getLibraryName());
if (outs != null) {
outs.setPath(path);
controller.setOutputs(outs);
}
monitors.log("Algorithm: " + algo.getName());
report.add("Algorithm", algo.getName());
algo.setController(controller);
- result = algo.run(monitors, image, psf, fft, pad, apo, norm, true);
+
+ deconvolvedImage = algo.run(monitors, image, psf, fft, pad, apo, norm, true);
live = false;
for (DeconvolutionListener listener : listeners)
listener.finish();
report.add("End", algo.getName() + " in " + NumFormat.time(System.nanoTime() - chrono));
if (flagDisplay)
- Lab.show(monitors, result, "Result of " + algo.getShortname());
+ Lab.show(monitors, deconvolvedImage, "Result of " + algo.getShortname());
if (finish == Finish.KILL) {
System.out.println("End");
System.exit(0);
}
if (finish == Finish.DIE)
finalize();
}
/**
* This methods make a recap of the deconvolution. Useful before starting
* the processing.
*
* @return list of messages to print
*/
public Features recap() {
Features features = new Features();
Token image = Command.extract(command, "-image");
features.add("Image", image == null ? "keyword -image not found" : image.parameters);
String normf = (norm < 0 ? " (no normalization)" : " (normalization to " + norm + ")");
Token psf = Command.extract(command, "-psf");
features.add("PSF", psf == null ? "keyword -psf not found" : psf.parameters + " norm:" + normf);
if (algo == null) {
features.add("Algorithm", "not valid>");
}
else {
Controller controller = algo.getController();
features.add("Algorithm", algo.toString());
features.add("Stopping Criteria", controller.getStoppingCriteriaAsString(algo));
features.add("Reference", controller.getReference());
features.add("Constraint", controller.getConstraintAsString());
features.add("Padding", pad.toString());
features.add("Apodization", apo.toString());
features.add("FFT", algo.getFFT() == null ? "" : algo.getFFT().getName());
}
features.add("Path", path);
String monitor = "";
if (flagMonitor == 0)
monitor = " monitor: no ";
if (flagMonitor == 1)
monitor = " monitor: console (" + verbose.name().toLowerCase() + ")";
if (flagMonitor == 2)
monitor = " monitor: table (" + verbose.name().toLowerCase() + ")";
if (flagMonitor == 3)
monitor = " monitor: console table (" + verbose.name().toLowerCase() + ")";
String stats = "";
if (flagStats == 0)
stats = " stats: no ";
if (flagStats == 1)
stats = " stats: show ";
if (flagStats == 2)
stats = " stats: save ";
if (flagStats == 3)
stats = " stats: show save";
String running = "";
running += " multithreading: " + (flagMultithreading ? "on " : "off ");
running += " display: " + (flagDisplay ? "on " : "off ");
running += " system: " + (flagSystem ? "shown" : "hidden ");
features.add("Monitor", monitor);
features.add("Stats", stats);
features.add("Running", running);
if (outs == null)
features.add("Output", "not valid");
else
for (Output out : outs)
features.add("Output " + out.getName(), out.toString());
return features;
}
public Features checkAlgo() {
Features features = new Features();
RealSignal image = openImage();
if (image == null) {
features.add("Image", "No valid input image");
return features;
}
if (pad == null) {
features.add("Padding", "No valid padding");
return features;
}
if (apo == null) {
features.add("Apodization", "No valid apodization");
return features;
}
RealSignal psf = openPSF();
if (psf == null) {
features.add("Image", "No valid PSF");
return features;
}
if (algo == null) {
features.add("Algorithm", "No valid algorithm");
return features;
}
Controller controller = algo.getController();
if (controller == null) {
features.add("Controller", "No valid controller");
return features;
}
algo.setController(controller);
- int iter = controller.getIterationMax();
- controller.setIterationMax(1);
- RealSignal x = algo.run(monitors, image, psf, fft, pad, apo, norm, true);
- Lab.show(monitors, x, "Estimate after 1 iteration");
- features.add("Time", NumFormat.seconds(controller.getTimeNano()));
- features.add("Peak Memory", controller.getMemoryAsString());
- controller.setIterationMax(iter);
+ double chrono = System.nanoTime();
+ AbstractFFT f = fft.getDefaultFFT();
+ RealSignal slice = image.getSlice(0);
+ if (slice != null) {
+ f.init(Monitors.createDefaultMonitor(), slice.nx, slice.ny, 1);
+ f.transform(slice);
+ int n = algo.isIterative() ? controller.getIterationMax() : 1;
+ chrono = (System.nanoTime() - chrono) * 2 * slice.nz * n;
+
+ features.add("Estimated Time", NumFormat.time(chrono) );
+ }
+ else
+ features.add("Estimated Time", "Error" );
+ features.add("Estimated Memory", controller.getMemoryAsString());
+ features.add("Iterative", algo.isIterative() ? "" + controller.getIterationMax() : "Direct");
return features;
}
- public Features checkImage() {
+ public Features checkImage(RealSignal image) {
Features features = new Features();
- RealSignal image = openImage();
if (image == null) {
features.add("Image", "No valid input image");
return features;
}
if (pad == null) {
features.add("Padding", "No valid padding");
return features;
}
if (apo == null) {
features.add("Apodization", "No valid apodization");
return features;
}
RealSignal signal = pad.pad(monitors, getApodization().apodize(monitors, image));
float stats[] = signal.getStats();
float stati[] = image.getStats();
- features.add("Size", image.dimAsString() + " padded to " + signal.dimAsString());
- features.add("Mean", NumFormat.nice(stati[0]) + " > " + NumFormat.nice(stats[0]));
- features.add("Minimun", NumFormat.nice(stati[1]) + " > " + NumFormat.nice(stats[1]));
- features.add("Maximum", NumFormat.nice(stati[2]) + " > " + NumFormat.nice(stats[2]));
- features.add("Stdev", NumFormat.nice(stati[3]) + " > " + NumFormat.nice(stats[3]));
- features.add("Energy", NumFormat.nice(stati[5]) + " > " + NumFormat.nice(stats[5]));
+ int sizi = image.nx * image.ny * image.nz;
+ int sizs = signal.nx * signal.ny * signal.nz;
+ float totali = stati[0] * sizi;
+ float totals = stats[0] * sizs;
+ features.add("<html><b>Orignal Image</b></html>", "");
+ features.add("Size", image.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) + ")");
+
+ features.add("<html><b>Working Image</b></html>", "");
+ features.add("Size", signal.dimAsString() + " " + NumFormat.bytes(sizs*4));
+ features.add("Mean (stdev)", NumFormat.nice(stats[0]) + " (" + NumFormat.nice(stats[3]) + ")");
+ features.add("Min Max", NumFormat.nice(stats[1]) + " " + NumFormat.nice(stats[2]));
+ features.add("Energy (int)", NumFormat.nice(stats[5]) + " (" + NumFormat.nice(totals) + ")");
+ features.add("<html><b>Information</b></html>", "");
+ features.add("Size Increase ", NumFormat.nice((double)(sizs-sizi)/sizi*100.0));
+ features.add("Energy Lost", NumFormat.nice((stats[5]-stati[5])/stati[5]*100));
+
return features;
}
- public Features checkPSF() {
+ public Features checkPSF(RealSignal psf) {
Features features = new Features();
- RealSignal image = openImage();
+ if (!imageLoaded)
+ image = openImage();
+
if (image == null) {
features.add("Image", "No valid input image");
return features;
}
if (pad == null) {
features.add("Padding", "No valid padding");
return features;
}
if (apo == null) {
features.add("Apodization", "No valid apodization");
return features;
}
- RealSignal psf = openPSF();
if (psf == null) {
features.add("PSF", "No valid PSF");
return features;
}
- RealSignal signal = pad.pad(monitors, getApodization().apodize(monitors, image));
- RealSignal h = psf.changeSizeAs(signal);
- features.add("Original size", psf.dimAsString() + " padded to " + h.dimAsString());
-
- String e = NumFormat.nice(h.getEnergy());
-
+ RealSignal h = psf.changeSizeAs(image);
h.normalize(norm);
- float stath[] = h.getStats();
- float statp[] = psf.getStats();
+ float stats[] = h.getStats();
+ float stati[] = psf.getStats();
+ int sizi = psf.nx * psf.ny * psf.nz;
+ int sizs = h.nx * h.ny * h.nz;
+ float totali = stati[0] * sizi;
+ float totals = stats[0] * sizs;
+ features.add("<html><b>Orignal PSF</b></html>", "");
+ features.add("Size", psf.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) + ")");
+
+ features.add("<html><b>Working PSF</b></html>", "");
+ features.add("Size", h.dimAsString() + " " + NumFormat.bytes(sizs*4));
+ features.add("Mean (stdev)", NumFormat.nice(stats[0]) + " (" + NumFormat.nice(stats[3]) + ")");
+ features.add("Min Max", NumFormat.nice(stats[1]) + " " + NumFormat.nice(stats[2]));
+ features.add("Energy (int)", NumFormat.nice(stats[5]) + " (" + NumFormat.nice(totals) + ")");
+ features.add("<html><b>Information</b></html>", "");
+ features.add("Size Increase ", NumFormat.nice((double)(sizs-sizi)/sizi*100.0));
+ features.add("Energy Lost", NumFormat.nice((stats[5]-stati[5])/stati[5]*100));
+ return features;
+ }
- // return new float[] { (float) mean, min, max, (float) stdev, (float)
- // norm1, (float) norm2 };
+ public Features checkOutput() {
+ Features features = new Features();
+ if (deconvolvedImage == null) {
+ features.add("Image", "No valid output image");
+ return features;
+ }
- features.add("Size", psf.dimAsString() + " padded to " + h.dimAsString());
- features.add("Mean", NumFormat.nice(statp[0]) + " > " + NumFormat.nice(stath[0]));
- features.add("Minimun", NumFormat.nice(statp[1]) + " > " + NumFormat.nice(stath[1]));
- features.add("Maximum", NumFormat.nice(statp[2]) + " > " + NumFormat.nice(stath[2]));
- features.add("Stdev", NumFormat.nice(statp[3]) + " > " + NumFormat.nice(stath[3]));
- features.add("Energy", NumFormat.nice(statp[5]) + " > " + NumFormat.nice(stath[5]));
- features.add("Total", NumFormat.nice(statp[4]) + " > " + NumFormat.nice(stath[4]));
+ 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", image.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 RealSignal getOutput() {
+ return deconvolvedImage;
+ }
+
public Features getDeconvolutionReports() {
return report;
}
public String getName() {
return name;
}
public boolean isLive() {
return live;
}
public void abort() {
live = false;
algo.getController().abort();
}
public String checkPath(String path) {
File dir = new File(path);
if (dir.exists()) {
if (dir.isDirectory()) {
if (dir.canWrite())
return path + " (writable)";
else
return path + " (non-writable)";
}
else {
return path + " (non-directory)";
}
}
else {
return path + " (not-valid)";
}
}
public RealSignal openImage() {
Token token = Command.extract(command, "-image");
if (token == null)
return null;
if (token.parameters.startsWith(">>>"))
return null;
return getImage(monitors, token);
}
public RealSignal openPSF() {
Token token = Command.extract(command, "-psf");
if (token == null)
return null;
if (token.parameters.startsWith(">>>"))
return null;
return getImage(monitors, token);
}
private RealSignal getImage(Monitors monitors, Token token) {
String arg = token.option.trim();
String cmd = token.parameters.substring(arg.length(), token.parameters.length()).trim();
if (arg.equalsIgnoreCase("synthetic")) {
String parts[] = cmd.split(" ");
if (parts.length <= 0)
return null;
String shape = parts[0];
for (String name : SignalFactory.getAllName()) {
if (shape.equalsIgnoreCase(name.toLowerCase())) {
double params[] = Command.parseNumeric(cmd);
SignalFactory factory = SignalFactory.getFactoryByName(shape);
if (factory == null)
return null;
double amplitude = params.length > 0 ? params[0] : 1;
double background = params.length > 1 ? params[1] : 0;
factory.intensity(background, amplitude);
int np = factory.getParameters().length;
double[] features = new double[np];
for (int i = 0; i < Math.min(np, params.length); i++)
features[i] = params[i + 2];
factory.setParameters(features);
int nx = params.length > np + 2 ? (int) Math.round(params[np + 2]) : 128;
int ny = params.length > np + 3 ? (int) Math.round(params[np + 3]) : 128;
int nz = params.length > np + 4 ? (int) Math.round(params[np + 4]) : 128;
double cx = params.length > np + 5 ? params[np + 5] : 0.5;
double cy = params.length > np + 6 ? params[np + 6] : 0.5;
double cz = params.length > np + 7 ? params[np + 7] : 0.5;
factory = factory.center(cx, cy, cz);
RealSignal x = factory.generate(nx, ny, nz);
return x;
}
}
}
if (arg.equalsIgnoreCase("file") || arg.equalsIgnoreCase("dir") || arg.equalsIgnoreCase("directory")) {
RealSignal signal = null;
File file = new File(path + File.separator + cmd);
if (file != null) {
if (file.isFile())
signal = Lab.open(monitors, path + File.separator + cmd);
if (file.isDirectory())
signal = Lab.openDir(monitors, path + File.separator + cmd);
}
if (signal == null) {
File local = new File(cmd);
if (local != null) {
if (local.isFile())
signal = Lab.open(monitors, cmd);
if (local.isDirectory())
signal = Lab.openDir(monitors, cmd);
}
}
return signal;
}
if (arg.equalsIgnoreCase("platform")) {
return Lab.getImager().create(cmd);
}
return null;
}
public void addDeconvolutionListener(DeconvolutionListener listener) {
listeners.add(listener);
}
public OutputCollection getOuts() {
return outs;
}
public void setAlgorithm(AbstractAlgorithm algo, Controller controller) {
this.algo = algo;
if (algo != null && controller != null) {
algo.setController(controller);
}
}
public AbstractAlgorithm getAlgo() {
return algo;
}
public void setPath(String path) {
this.path = path;
}
public String getPath() {
return path;
}
public void setNormalization(double norm) {
this.norm = norm;
}
public void setPadding(Padding pad) {
this.pad = pad;
}
public Padding getPadding() {
return pad;
}
public void setApodization(Apodization apo) {
this.apo = apo;
}
public Apodization getApodization() {
return apo;
}
public void setOutput(OutputCollection outs) {
this.outs = outs;
}
public void setVerbose(Verbose verbose) {
this.verbose = verbose;
}
public void setFFT(AbstractFFTLibrary fft) {
this.fft = fft;
}
public void setMonitor(int flagMonitor) {
this.flagMonitor = flagMonitor;
}
public void setStats(int flagStats) {
this.flagStats = flagStats;
}
public void setFlags(boolean flagDisplay, boolean flagMultithreading, boolean flagSystem) {
this.flagDisplay = flagDisplay;
this.flagMultithreading = flagMultithreading;
this.flagSystem = flagSystem;
}
public String getCommand() {
return command;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/DeconvolutionDialog.java b/DeconvolutionLab2/src/deconvolution/DeconvolutionDialog.java
index a6d4307..5e572ad 100644
--- a/DeconvolutionLab2/src/deconvolution/DeconvolutionDialog.java
+++ b/DeconvolutionLab2/src/deconvolution/DeconvolutionDialog.java
@@ -1,350 +1,359 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Rectangle;
-import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
-import javax.swing.JSplitPane;
import javax.swing.JToolBar;
import deconvolution.modules.AlgorithmDModule;
-import deconvolution.modules.RecapDModule;
import deconvolution.modules.ImageDModule;
import deconvolution.modules.PSFDModule;
+import deconvolution.modules.RecapDModule;
import deconvolution.modules.ReportDModule;
import deconvolutionlab.Config;
+import deconvolutionlab.Constants;
import deconvolutionlab.Lab;
import deconvolutionlab.TableStats;
import deconvolutionlab.monitor.TableMonitor;
import lab.component.BorderToggledButton;
-import lab.component.CustomizedTable;
import lab.component.JPanelImage;
public class DeconvolutionDialog extends JDialog implements ActionListener, Runnable, DeconvolutionListener {
public enum State {
NOTDEFINED, READY, RUN, FINISH
};
+
+ public enum Module {
+ ALL, RECAP, IMAGE, PSF, ALGO
+ };
private JButton bnStart = new JButton("Run");
private JButton bnStop = new JButton("Stop");
private JButton bnReset = new JButton("Reset");
private JButton bnHelp = new JButton("Help");
private JButton bnQuit = new JButton("Quit");
private BorderToggledButton bnRecap = new BorderToggledButton("Recap");
private BorderToggledButton bnImage = new BorderToggledButton("Image");
private BorderToggledButton bnPSF = new BorderToggledButton("PSF");
private BorderToggledButton bnAlgo = new BorderToggledButton("Algorithm");
private BorderToggledButton bnReport = new BorderToggledButton("Report");
private BorderToggledButton bnMonitor = new BorderToggledButton("Monitor");
private BorderToggledButton bnStats = new BorderToggledButton("Stats");
private String job = "";
private Thread thread = null;
private Deconvolution deconvolution;
private State state = State.NOTDEFINED;
private JProgressBar progress = new JProgressBar();
public static Point location = new Point(0, 0);
private JPanel cards = new JPanel(new CardLayout());
private boolean flagMonitor = false;
private boolean flagStats = false;
private ImageDModule image;
private PSFDModule psf;
private RecapDModule recap;
private AlgorithmDModule algorithm;
private ReportDModule report;
- public DeconvolutionDialog(Deconvolution deconvolution, TableMonitor tableMonitor, TableStats tableStats) {
+ public DeconvolutionDialog(Module module, Deconvolution deconvolution, TableMonitor tableMonitor, TableStats tableStats) {
super(new JFrame(), deconvolution.getName());
this.deconvolution = deconvolution;
image = new ImageDModule(deconvolution);
psf = new PSFDModule(deconvolution);
recap = new RecapDModule(deconvolution);
algorithm = new AlgorithmDModule(deconvolution);
report = new ReportDModule(deconvolution);
- // Panel tool with all buttons
- JToolBar tool = new JToolBar();
- tool.setFloatable(false);
- tool.setLayout(new GridLayout(1, 6));
- tool.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
- tool.add(bnRecap);
- tool.add(bnImage);
- tool.add(bnPSF);
- tool.add(bnAlgo);
- tool.add(bnMonitor);
- tool.add(bnStats);
- tool.add(bnReport);
-
- // Panel buttons
- JPanelImage buttons = new JPanelImage("celegans.jpg");
- buttons.setLayout(new FlowLayout());
- buttons.setBorder(BorderFactory.createEtchedBorder());
- buttons.add(bnReset);
- buttons.add(bnStop);
- buttons.add(bnStart);
-
// Panel status bar on bottom
progress.setAlignmentX(JLabel.CENTER_ALIGNMENT);
progress.setBorder(BorderFactory.createLoweredBevelBorder());
JToolBar statusBar = new JToolBar();
statusBar.setBorder(BorderFactory.createLoweredBevelBorder());
statusBar.setFloatable(false);
statusBar.setLayout(new BorderLayout());
statusBar.add(bnHelp, BorderLayout.WEST);
statusBar.add(progress, BorderLayout.CENTER);
statusBar.add(bnQuit, BorderLayout.EAST);
// Panel bottom
JPanel bottom = new JPanel();
bottom.setLayout(new BoxLayout(bottom, BoxLayout.PAGE_AXIS));
- bottom.add(buttons);
bottom.add(statusBar);
+ // Panel buttons
+ if (module == Module.ALL) {
+ JPanelImage buttons = new JPanelImage("celegans.jpg");
+ buttons.setLayout(new FlowLayout());
+ buttons.setBorder(BorderFactory.createEtchedBorder());
+ buttons.add(bnReset);
+ buttons.add(bnStop);
+ buttons.add(bnStart);
+ bottom.add(buttons);
+ }
+
// Panel Image
cards.add(recap.getName(), recap.getPane());
cards.add(image.getName(), image.getPane());
cards.add(psf.getName(), psf.getPane());
cards.add(algorithm.getName(), algorithm.getPane());
cards.add(report.getName(), report.getPane());
if (tableMonitor != null)
cards.add("Monitor", tableMonitor.getPanel());
if (tableStats != null)
cards.add("Stats", tableStats.getPanel());
// Panel Main
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
- panel.add(tool, BorderLayout.NORTH);
panel.add(cards, BorderLayout.CENTER);
panel.add(bottom, BorderLayout.SOUTH);
+ // Panel tool with all buttons
+ if (module == Module.ALL) {
+ JToolBar tool = new JToolBar();
+ tool.setFloatable(false);
+ tool.setLayout(new GridLayout(1, 6));
+ tool.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
+ tool.add(bnRecap);
+ tool.add(bnImage);
+ tool.add(bnPSF);
+ tool.add(bnAlgo);
+ tool.add(bnMonitor);
+ tool.add(bnStats);
+ tool.add(bnReport);
+ panel.add(tool, BorderLayout.NORTH);
+ }
+
add(panel);
bnReset.addActionListener(this);
bnQuit.addActionListener(this);
bnStart.addActionListener(this);
bnStop.addActionListener(this);
- bnPSF.addActionListener(this);
+ bnHelp.addActionListener(this);
+
bnImage.addActionListener(this);
+ bnPSF.addActionListener(this);
bnAlgo.addActionListener(this);
bnRecap.addActionListener(this);
- bnHelp.addActionListener(this);
bnMonitor.addActionListener(this);
bnStats.addActionListener(this);
+ bnReport.addActionListener(this);
deconvolution.addDeconvolutionListener(this);
- setMinimumSize(new Dimension(400, 200));
+ setMinimumSize(new Dimension(Constants.widthGUI, 400));
+ setPreferredSize(new Dimension(Constants.widthGUI, 400));
pack();
Config.registerFrame("DeconvolutionLab", "DeconvolutionDialog", this);
-
Rectangle rect = Config.getDialog("DeconvolutionLab.DeconvolutionDialog");
if (rect.x > 0 && rect.y > 0)
setLocation(rect.x, rect.y);
bnStop.setEnabled(false);
- toggle(bnRecap);
+ if (module == Module.ALL)
+ toggle(bnRecap);
+ if (module == Module.IMAGE)
+ toggle(bnImage);
+ if (module == Module.PSF)
+ toggle(bnPSF);
+ if (module == Module.ALGO)
+ toggle(bnAlgo);
+ if (module == Module.RECAP)
+ toggle(bnPSF);
state = State.READY;
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == bnStart) {
if (flagMonitor)
toggle(bnMonitor);
else if (flagStats)
toggle(bnStats);
if (thread == null) {
job = bnStart.getText();
thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}
}
else if (e.getSource() == bnStop) {
toggle(bnReport);
finish();
if (deconvolution != null)
deconvolution.abort();
}
- else if (e.getSource() == bnRecap) {
- toggle(bnRecap);
- if (thread == null) {
- job = bnRecap.getText();
- thread = new Thread(this);
- thread.setPriority(Thread.MIN_PRIORITY);
- thread.start();
- }
- }
else if (e.getSource() == bnImage) {
toggle(bnImage);
if (thread == null) {
job = bnImage.getText();
thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}
}
else if (e.getSource() == bnPSF) {
toggle(bnPSF);
if (thread == null) {
job = bnPSF.getText();
thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}
}
else if (e.getSource() == bnAlgo) {
toggle(bnAlgo);
if (thread == null) {
job = bnAlgo.getText();
thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}
}
- else if (job.equals(bnRecap.getText())) {
+ else if (e.getSource() == bnRecap) {
toggle(bnRecap);
recap.update();
}
else if (e.getSource() == bnReport) {
toggle(bnReport);
report.update();
}
else if (e.getSource() == bnReset) {
toggle(bnRecap);
state = State.READY;
bnStart.setEnabled(true);
}
else if (e.getSource() == bnQuit) {
deconvolution.finalize();
deconvolution = null;
dispose();
}
else if (e.getSource() == bnHelp)
Lab.help();
else if (e.getSource() == bnMonitor)
toggle(bnMonitor);
else if (e.getSource() == bnStats)
toggle(bnStats);
}
@Override
public void run() {
bnRecap.setEnabled(false);
bnImage.setEnabled(false);
bnPSF.setEnabled(false);
bnAlgo.setEnabled(false);
deconvolution.setCommand(recap.getCommand());
if (job.equals(bnStart.getText())) {
bnStart.setEnabled(false);
bnStop.setEnabled(true);
deconvolution.run();
toggle(bnReport);
bnStop.setEnabled(false);
}
else if (job.equals(bnImage.getText()))
image.update();
else if (job.equals(bnPSF.getText()))
psf.update();
else if (job.equals(bnAlgo.getText()))
algorithm.update();
bnRecap.setEnabled(true);
bnAlgo.setEnabled(true);
bnPSF.setEnabled(true);
bnImage.setEnabled(true);
thread = null;
+ toggle(bnReport);
+ report.update();
}
@Override
public void started() {
state = State.RUN;
}
@Override
public void finish() {
state = State.FINISH;
}
public JProgressBar getProgressBar() {
return progress;
}
public static void setLocationLaunch(Point l) {
location = l;
}
private void toggle(BorderToggledButton bn) {
((CardLayout) (cards.getLayout())).show(cards, bn.getText());
bnRecap.setSelected(false);
bnImage.setSelected(false);
bnPSF.setSelected(false);
bnAlgo.setSelected(false);
bnMonitor.setSelected(false);
bnStats.setSelected(false);
bnReport.setSelected(false);
bn.setSelected(true);
-
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java b/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java
index 321badc..f80252b 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java
@@ -1,217 +1,223 @@
/*
* 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 java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import deconvolutionlab.monitor.Monitors;
import fft.AbstractFFT;
import fft.AbstractFFTLibrary;
import fft.FFT;
import lab.tools.NumFormat;
import signal.Operations;
import signal.RealSignal;
import signal.apodization.Apodization;
import signal.padding.Padding;
/**
* This class is the common part of every algorithm of deconvolution.
*
* @author Daniel Sage
*
*/
public abstract class AbstractAlgorithm implements Callable<RealSignal> {
protected RealSignal y = null;
protected RealSignal h = null;
protected Controller controller = null;
protected AbstractFFT fft = null;
+ protected String shortname = "I";
public AbstractAlgorithm() {
this.controller = new Controller();
}
- public abstract String getName();
+ public void setShortname(String shortname) {
+ this.shortname = shortname;
+ }
- public abstract String getShortname();
+ public String getShortname() {
+ return shortname;
+ }
+
+ public abstract String getName();
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(Monitors monitors,
RealSignal image, RealSignal psf,
AbstractFFTLibrary fftlib, Padding pad, Apodization apo, double norm, boolean threaded) {
if (image == null)
return null;
if (psf == null)
return null;
if (fftlib != null)
fft = FFT.createFFT(monitors, fftlib, image.nx, image.ny, image.nz);
else
fft = FFT.createDefaultFFT(monitors, image.nx, image.ny, image.nz);
controller.setFFT(fft);
y = (pad == null ? image.duplicate() : pad.pad(monitors, apo.apodize(monitors, image)));
monitors.log("Input: " + y.dimAsString());
h = psf.changeSizeAs(y).normalize(norm);
monitors.log("PSF: " + h.dimAsString());
monitors.log("PSF: normalization " + (norm <= 0 ? "no" : norm));
String iterations = (isIterative() ? controller.getIterationMax() + " iterations" : "direct");
monitors.log(getShortname() + " is starting (" + iterations + ")");
controller.setMonitors(monitors);
controller.start(y);
h = Operations.circularShift(h);
if (fft == null)
fft = FFT.createDefaultFFT(monitors, y.nx, y.ny, y.nz);
else
fft.init(monitors, y.nx, y.ny, y.nz);
monitors.log(getShortname() + " data ready");
double params[] = getParameters();
if (params != null) {
if (params.length > 0) {
String s = " ";
for (double param : params)
s += "" + param + " ";
monitors.log(getShortname() + 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();
}
controller.finish(x);
monitors.log(getName() + " is finished");
RealSignal result = pad.crop(monitors, x);
return result;
}
public AbstractFFT getFFT() {
return fft;
}
public void setFFT(AbstractFFT fft) {
this.fft = fft;
}
public Controller getController() {
return controller;
}
public void setController(Controller controller) {
this.controller = controller;
- controller.setAlgorithm(getName());
}
public int getIterations() {
return controller.getIterations();
}
public double getTime() {
return controller.getTimeNano();
}
public double getMemory() {
return controller.getMemory();
}
public void setWavelets(String waveletsName) {
}
@Override
public String toString() {
String s = "";
s += getName();
s += (isIterative() ? ", " + controller.getIterationMax() + " 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;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithmPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithmPanel.java
index 5c6b1b1..491076f 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithmPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithmPanel.java
@@ -1,56 +1,58 @@
/*
* 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;
public abstract class AbstractAlgorithmPanel {
public abstract JPanel getPanelParameters();
public abstract String getCommand();
public abstract String getName();
- public abstract String getShortname();
+ public abstract String[] getShortname();
public abstract String getDocumentation();
public boolean isNamed(String name) {
- if (name.equals(getShortname().toLowerCase()))
- return true;
- if (name.equals(getName().toLowerCase()))
- return true;
+ for(String sn : getShortname()) {
+ if (name.equals(sn.toLowerCase()))
+ return true;
+ if (name.equals(getName().toLowerCase()))
+ return true;
+ }
return false;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/Algorithm.java b/DeconvolutionLab2/src/deconvolution/algorithm/Algorithm.java
index 59f96d4..e61983e 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/Algorithm.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/Algorithm.java
@@ -1,162 +1,144 @@
/*
* 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 {
private static ArrayList<AbstractAlgorithmPanel> list;
static {
list = new ArrayList<AbstractAlgorithmPanel>();
list.add(new RegularizedInverseFilterPanel());
list.add(new TikhonovRegularizationInverseFilterPanel());
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 ArrayList<AbstractAlgorithmPanel> getAvailableDeconvolutionAlgorithms() {
- ArrayList<AbstractAlgorithmPanel> list = new ArrayList<AbstractAlgorithmPanel>();
- list = new ArrayList<AbstractAlgorithmPanel>();
- list.add(new RegularizedInverseFilterPanel());
- list.add(new TikhonovRegularizationInverseFilterPanel());
- list.add(new NaiveInverseFilterPanel());
- list.add(new FISTAPanel());
- list.add(new ISTAPanel());
- list.add(new LandweberPanel());
- list.add(new LandweberPositivityPanel());
- list.add(new RichardsonLucyPanel());
- list.add(new RichardsonLucyTVPanel());
- list.add(new TikhonovMillerPanel());
- list.add(new ICTMPanel());
- list.add(new VanCittertPanel());
- return list;
- }
-
- public static ArrayList<AbstractAlgorithmPanel> getAvailableSimulationAlgorithms() {
- ArrayList<AbstractAlgorithmPanel> list = new ArrayList<AbstractAlgorithmPanel>();
- list.add(new IdentityPanel());
- list.add(new ConvolutionPanel());
- list.add(new SimulationPanel());
- list.add(new NonStabilizedDivisionPanel());
- return list;
- }
-
public static AbstractAlgorithm getDefaultAlgorithm() {
return new Identity();
}
public static AbstractAlgorithm createAlgorithm(String name) {
- if (name == null)
- return getDefaultAlgorithm();
+ AbstractAlgorithm algo = getDefaultAlgorithm();
String n = name.trim().toLowerCase();
int i = 0;
if (list.get(i++).isNamed(n))
- return new RegularizedInverseFilter(0.1);
- if (list.get(i++).isNamed(n))
- return new TikhonovRegularizationInverseFilter(1.0);
- if (list.get(i++).isNamed(n))
- return new NaiveInverseFilter();
- if (list.get(i++).isNamed(n))
- return new FISTA(10, 1, 1, "Haar", 3);
- if (list.get(i++).isNamed(n))
- return new ISTA(10, 1, 1, "Haar", 3);
- if (list.get(i++).isNamed(n))
- return new Landweber(10, 1);
- if (list.get(i++).isNamed(n))
- return new LandweberPositivity(10, 1);
- if (list.get(i++).isNamed(n))
- return new RichardsonLucy(10);
- if (list.get(i++).isNamed(n))
- return new RichardsonLucyTV(10, 1);
- if (list.get(i++).isNamed(n))
- return new TikhonovMiller(10, 1, 0.1);
- if (list.get(i++).isNamed(n))
- return new ICTM(10, 1, 0.1);
- if (list.get(i++).isNamed(n))
- return new VanCittert(10, 1);
- if (list.get(i++).isNamed(n))
- return new Identity();
- if (list.get(i++).isNamed(n))
- return new Convolution();
- if (list.get(i++).isNamed(n))
- return new Simulation(0, 1, 0);
- if (list.get(i++).isNamed(n))
- return new NonStabilizedDivision();
- return getDefaultAlgorithm();
+ algo = new RegularizedInverseFilter(0.1);
+ else if (list.get(i++).isNamed(n))
+ algo = new TikhonovRegularizationInverseFilter(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();
+
+ if (algo != null)
+ algo.setShortname(name);
+ return algo;
}
public static AbstractAlgorithmPanel getPanel(String name) {
for (AbstractAlgorithmPanel panel : getAvailableAlgorithms()) {
- if (panel.getShortname().equals(name.trim()))
- return panel;
+ for(String sn : panel.getShortname())
+ if (sn.equals(name.trim()))
+ return panel;
if (panel.getName().equals(name.trim()))
return panel;
}
return null;
}
public static ArrayList<String> getShortnames() {
ArrayList<String> list = new ArrayList<String>();
for (AbstractAlgorithmPanel algo : getAvailableAlgorithms()) {
- list.add(algo.getShortname());
+ for(String sn : algo.getShortname())
+ 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 e74c18e..26c1b75 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java
@@ -1,345 +1,335 @@
/*
* 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.Timer;
import java.util.TimerTask;
import deconvolution.Deconvolution;
import deconvolutionlab.OutputCollection;
import deconvolutionlab.TableStats;
import deconvolutionlab.monitor.Monitors;
import deconvolutionlab.system.SystemUsage;
import fft.AbstractFFT;
import fft.FFT;
import lab.tools.NumFormat;
import signal.Assessment;
import signal.ComplexSignal;
import signal.Constraint;
import signal.RealSignal;
+import signal.SignalCollector;
public class Controller {
private int iterationsMax = 100;
private double timeMax = 1000;
private double residuMin = -1;
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 Constraint.Mode constraint = Constraint.Mode.NO;
private OutputCollection outs = null;
private String referenceName = "";
- private String showstatsName = "";
- private String savestatsName = "";
private RealSignal refImage;
private RealSignal prevImage;
private RealSignal x;
private Timer timer;
private AbstractFFT fft;
- private String algo = "";
private TableStats tableStats;
private float[] statsInput;
private Monitors monitors = new Monitors();
public Controller() {
constraint = Constraint.Mode.NO;
doResidu = false;
doTime = false;
doReference = false;
doConstraint = false;
}
public void setTableStats(TableStats tableStats) {
this.tableStats = tableStats;
}
public void setMonitors(Monitors monitors) {
this.monitors = monitors;
}
- public void setAlgorithm(String algo) {
- this.algo = algo;
- }
-
public void setFFT(AbstractFFT fft) {
this.fft = fft;
}
public void abort() {
this.abort = true;
}
public int getIterationMax() {
return iterationsMax;
}
public void setIterationMax(int iterationsMax) {
this.iterationsMax = iterationsMax;
}
public void setTimeStop(double timeMax) {
this.doTime = true;
this.timeMax = timeMax * 1e9;
}
public void setResiduStop(double residuMin) {
this.doResidu = true;
this.residuMin = residuMin;
}
public void setReference(String referenceName) {
this.doReference = true;
this.referenceName = referenceName;
}
public void setConstraint(Constraint.Mode constraint) {
this.doConstraint = true;
this.constraint = constraint;
}
public void setOutputs(OutputCollection outs) {
this.outs = outs;
}
public void start(RealSignal x) {
this.x = x;
statsInput = x.getStats();
if (tableStats != null)
tableStats.nextStats(monitors, stats());
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 " + referenceName).openImage();
if (refImage == null)
monitors.error("Impossible to load the reference image " + referenceName);
else
monitors.log("Reference image loaded");
}
if (outs != null)
outs.executeStarting(monitors, x, this);
this.prevImage = x;
}
public boolean ends(ComplexSignal X) {
boolean out = outs == null ? false : outs.hasShow(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);
if (outs != null)
outs.executeIterative(monitors, x, this, iterations);
iterations++;
double p = iterations * 100.0 / iterationsMax;
monitors.progress("Iterative " + iterations + "/" + iterationsMax, p);
double timeElapsed = getTimeNano();
boolean stopIter = (iterations >= iterationsMax);
boolean stopTime = doTime && (timeElapsed >= timeMax);
boolean stopResd = doResidu && (residu <= residuMin);
monitors.log("@" + iterations + " Time: " + NumFormat.seconds(timeElapsed));
if (tableStats != null)
tableStats.nextStats(monitors, stats());
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 + " > " + timeMax);
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);
if (tableStats != null)
tableStats.lastStats(monitors, stats());
if (outs != null)
outs.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 && constraint != null)
new Constraint(monitors).apply(x, constraint);
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));
}
-
}
public String[] stats() {
if (tableStats == null)
return null;
float params[] = null;
if (x != null)
params = x.getStats();
- String[] row = new String[15];
- row[0] = tableStats.getName();
- row[1] = algo;
- row[2] = "" + iterations;
- row[3] = (params == null ? "-" : "" + params[0]);
- row[4] = (params == null ? "-" : "" + params[1]);
- row[5] = (params == null ? "-" : "" + params[2]);
- row[6] = (params == null ? "-" : "" + params[3]);
- row[7] = (params == null ? "-" : "" + params[4]);
- row[8] = (params == null ? "-" : "" + params[5]);
- row[9] = NumFormat.seconds(getTimeNano());
- row[10] = NumFormat.bytes(SystemUsage.getHeapUsed());
- row[11] = NumFormat.bytes(memoryPeak);
- row[12] = doReference ? NumFormat.nice(psnr) : "n/a";
- row[13] = doReference ? NumFormat.nice(snr) : "n/a";
- row[14] = doResidu ? NumFormat.nice(residu) : "n/a";
+ String[] row = new String[12];
+ row[0] = "" + iterations;
+ row[1] = (params == null ? "-" : "" + params[0]);
+ row[2] = (params == null ? "-" : "" + params[1]);
+ row[3] = (params == null ? "-" : "" + params[2]);
+ row[4] = (params == null ? "-" : "" + params[3]);
+ row[5] = (params == null ? "-" : "" + params[5]);
+ row[6] = NumFormat.seconds(getTimeNano());
+ row[7] = NumFormat.bytes(SystemUsage.getHeapUsed());
+ row[8] = SignalCollector.sumarize();
+ row[9] = doReference ? NumFormat.nice(psnr) : "n/a";
+ row[10] = doReference ? NumFormat.nice(snr) : "n/a";
+ row[11] = doResidu ? NumFormat.nice(residu) : "n/a";
return row;
}
public double getTimeNano() {
return (System.nanoTime() - timeStarting);
}
public Constraint.Mode getConstraint() {
return constraint;
}
public String getReference() {
return doReference ? referenceName : "no ground-truth";
}
public String getConstraintAsString() {
if (!doConstraint)
return "no";
if (constraint == null)
return "null";
return constraint.name().toLowerCase();
}
public String getStoppingCriteriaAsString(AbstractAlgorithm algo) {
String stop = algo.isIterative() ? " iterations limit=" + getIterationMax() + ", " : "direct, ";
stop += doTime ? ", time limit=" + NumFormat.nice(timeMax * 1e-9) : " no time limit" + ", ";
stop += doResidu ? ", residu limit=" + NumFormat.nice(residuMin) : " no residu limit";
return stop;
}
public float[] getStatsInput() {
return statsInput;
}
public double getMemory() {
return memoryPeak - memoryStarting;
}
public String getMemoryAsString() {
return NumFormat.bytes(getMemory());
}
public int getIterations() {
return iterations;
}
private void update() {
memoryPeak = Math.max(memoryPeak, SystemUsage.getHeapUsed());
}
private class Updater extends TimerTask {
@Override
public void run() {
update();
}
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/Convolution.java b/DeconvolutionLab2/src/deconvolution/algorithm/Convolution.java
index 1317644..f320e91 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/Convolution.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/Convolution.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 java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
public class Convolution extends AbstractAlgorithm implements Callable<RealSignal> {
public Convolution() {
super();
}
@Override
public RealSignal call() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal X = Operations.multiply(H, Y);
RealSignal x = fft.inverse(X);
return x;
}
@Override
public String getName() {
- return "Convolution";
- }
-
- @Override
- public String getShortname() {
- return "CONV";
+ return "Convolution Noiseless [CONV]";
}
@Override
public boolean isRegularized() {
return false;
}
@Override
public boolean isStepControllable() {
return false;
}
@Override
public boolean isIterative() {
return false;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
public void setParameters(double[] params) {
}
@Override
public double[] getParameters() {
return new double[] {};
}
@Override
public double[] getDefaultParameters() {
return new double[] {};
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return 0;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/ConvolutionPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/ConvolutionPanel.java
index 90294ef..ce7fe4a 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/ConvolutionPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/ConvolutionPanel.java
@@ -1,72 +1,72 @@
/*
* 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 lab.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 getShortname() {
- return algo.getShortname();
+ public String[] getShortname() {
+ return new String[] {"CONV"};
}
@Override
public String getDocumentation() {
String s = "";
s += "<h1>" + getName() + "</h1>";
s += "<p>This algorithm is only used for simulation. It convolves the input image with the PSF.</p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/FISTA.java b/DeconvolutionLab2/src/deconvolution/algorithm/FISTA.java
index acfcbca..ded7bd0 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/FISTA.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/FISTA.java
@@ -1,169 +1,164 @@
/*
* 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 wavelets.AbstractWavelets;
import wavelets.Wavelets;
public class FISTA extends AbstractAlgorithm implements Callable<RealSignal> {
private double gamma = 1.0;
private double lambda = 0.1;
private String waveletsName = "Haar";
private int scale = 3;
public FISTA(int iter, double gamma, double lambda, String waveletsName, int scale) {
super();
controller.setIterationMax(iter);
this.gamma = gamma;
this.lambda = lambda;
this.waveletsName = waveletsName;
this.scale = scale;
}
@Override
public RealSignal call() throws Exception {
AbstractWavelets wavelets = Wavelets.getWaveletsByName(waveletsName);
wavelets.setScale(scale);
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal A = Operations.delta(gamma, H);
ComplexSignal G = Operations.multiplyConjugate(gamma, H, Y);
ComplexSignal Z = G.duplicate();
RealSignal x = fft.inverse(G);
RealSignal s = x.duplicate();
RealSignal z = x.duplicate();
RealSignal xprev = fft.inverse(G);
float pk1 = 1f;
float pk0 = 1f;
float threshold = (float) (lambda * gamma * 0.5);
RealSignal buffer = y.duplicate();
while (!controller.ends(x)) {
fft.transform(s, Z);
Z.times(A);
Z.plus(G);
fft.inverse(Z, z);
wavelets.shrinkage(threshold, z, x, buffer);
pk0 = pk1;
pk1 = (1f + (float) Math.sqrt(1f + 4f * pk0 * pk0)) * 0.5f;
update(xprev, x, (pk0 - 1f) / pk1, s);
}
return x;
}
public void update(RealSignal xprev, RealSignal x, double w, RealSignal s) {
int nxy = x.nx * x.ny;
for (int k = 0; k < x.nz; k++)
for (int i = 0; i < nxy; i++) {
float vx = x.data[k][i];
s.data[k][i] = (float) (vx + w * (vx - xprev.data[k][i]));
xprev.data[k][i] = vx;
}
}
@Override
public String getName() {
- return "FISTA";
- }
-
- @Override
- public String getShortname() {
- return "FISTA";
+ return "Fast Iterative Shrinkage-Thresholding [FISTA]";
}
@Override
public boolean isRegularized() {
return true;
}
@Override
public boolean isStepControllable() {
return true;
}
@Override
public boolean isIterative() {
return true;
}
@Override
public boolean isWaveletsBased() {
return true;
}
@Override
public void setWavelets(String waveletsName) {
this.waveletsName = waveletsName;
}
@Override
public void setParameters(double[] params) {
if (params == null)
return;
if (params.length > 0)
controller.setIterationMax((int) Math.round(params[0]));
if (params.length > 1)
gamma = (float) params[1];
if (params.length > 2)
lambda = (float) params[2];
if (params.length > 3)
scale = (int) params[3];
}
@Override
public double[] getDefaultParameters() {
return new double[] { 10, 1, 0.1 };
}
@Override
public double[] getParameters() {
return new double[] { controller.getIterationMax(), gamma, lambda };
}
@Override
public double getRegularizationFactor() {
return lambda;
}
@Override
public double getStepFactor() {
return gamma;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/FISTAPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/FISTAPanel.java
index 271d542..349e54a 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/FISTAPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/FISTAPanel.java
@@ -1,165 +1,167 @@
/*
* 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 deconvolution.Command;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
import lab.component.GridPanel;
import lab.component.RegularizationPanel;
import lab.component.SpinnerRangeDouble;
import lab.component.SpinnerRangeInteger;
import lab.tools.NumFormat;
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.getShortname(), "iterations", spnIter, params[0]);
Config.register("Algorithm." + algo.getShortname(), "step", spnStep, params[1]);
Config.register("Algorithm." + algo.getShortname(), "wavelets", cmbWav, wavdef.getName());
Config.register("Algorithm." + algo.getShortname(), "scale", cmbScale, wavdef.getScales());
Config.register("Algorithm." + algo.getShortname(), "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 getShortname() {
- return algo.getShortname();
+ public String[] getShortname() {
+ return new String[] {"FISTA"};
}
@Override
public String getDocumentation() {
String s = "";
s += "<h1>" + getName() + "</h1>";
+ s += "<h2>Shortname: FISTA</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 += "<p>Shortname: " + getShortname() + "</p>";
+ s += "<p></p>";
+ s += "<h3>Reference: Beck and Teboulle, SIAM <b>2</b> 2009</h3>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/ICTM.java b/DeconvolutionLab2/src/deconvolution/algorithm/ICTM.java
index 1e4a1fa..6c0d28f 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/ICTM.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/ICTM.java
@@ -1,135 +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.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Constraint;
import signal.Operations;
import signal.RealSignal;
import signal.factory.complex.ComplexSignalFactory;
public class ICTM extends AbstractAlgorithm implements Callable<RealSignal> {
private double gamma = 1.0;
private double lambda = 1.0;
public ICTM(int iter, double gamma, double lambda) {
super();
controller.setIterationMax(iter);
controller.setConstraint(Constraint.Mode.NONNEGATIVE);
this.gamma = gamma;
this.lambda = lambda;
}
@Override
public RealSignal call() throws Exception {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal A = Operations.delta(gamma, H);
ComplexSignal L = ComplexSignalFactory.laplacian(Y.nx, Y.ny, Y.nz);
ComplexSignal L2 = Operations.multiplyConjugate(lambda * gamma, L, L);
A.minus(L2);
ComplexSignal G = Operations.multiplyConjugate(gamma, H, Y);
ComplexSignal X = G.duplicate();
controller.setConstraint(Constraint.Mode.NONNEGATIVE);
while (!controller.ends(X)) {
X.times(A);
X.plus(G);
}
RealSignal x = fft.inverse(X);
return x;
}
@Override
public String getName() {
- return "Iterative Contraint Tikhonov-Miller";
- }
-
- @Override
- public String getShortname() {
- return "ICTM";
+ return "Iterative Contraint Tikhonov-Miller [ICTM]";
}
@Override
public boolean isRegularized() {
return true;
}
@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)
controller.setIterationMax((int) Math.round(params[0]));
if (params.length > 1)
gamma = (float) params[1];
if (params.length > 2)
lambda = (float) params[2];
}
@Override
public double[] getDefaultParameters() {
return new double[] { 10, 1, 0.1 };
}
@Override
public double[] getParameters() {
return new double[] { controller.getIterationMax(), gamma, lambda };
}
@Override
public double getRegularizationFactor() {
return lambda;
}
@Override
public double getStepFactor() {
return gamma;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/ICTMPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/ICTMPanel.java
index 7f210c3..3243e7c 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/ICTMPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/ICTMPanel.java
@@ -1,143 +1,144 @@
/*
* 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 deconvolution.Command;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
import lab.component.GridPanel;
import lab.component.RegularizationPanel;
import lab.component.SpinnerRangeDouble;
import lab.component.SpinnerRangeInteger;
import lab.tools.NumFormat;
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.getShortname(), "iterations", spnIter, params[0]);
Config.register("Algorithm." + algo.getShortname(), "step", spnStep, params[1]);
Config.register("Algorithm." + algo.getShortname(), "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 getShortname() {
- return algo.getShortname();
+ public String[] getShortname() {
+ return new String[] {"ICTM"};
}
+
@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>";
s += "<p>Shortname: " + getShortname() + "</p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/ISTA.java b/DeconvolutionLab2/src/deconvolution/algorithm/ISTA.java
index 75a979c..f92c932 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/ISTA.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/ISTA.java
@@ -1,161 +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.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import wavelets.AbstractWavelets;
import wavelets.Wavelets;
public class ISTA extends AbstractAlgorithm implements Callable<RealSignal> {
private double gamma = 1.0;
private double lambda = 1.0;
private String waveletsName = "Haar";
private int scale = 3;
public ISTA(int iter, double gamma, double lambda, String waveletsName, int scale) {
super();
controller.setIterationMax(iter);
this.gamma = gamma;
this.lambda = lambda;
this.waveletsName = waveletsName;
this.scale = scale;
}
@Override
public RealSignal call() throws Exception {
AbstractWavelets wavelets = Wavelets.getWaveletsByName(waveletsName);
wavelets.setScale(scale);
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal A = Operations.delta(gamma, H);
ComplexSignal G = Operations.multiplyConjugate(gamma, H, Y);
ComplexSignal Z = G.duplicate();
RealSignal x = fft.inverse(G);
RealSignal z = x.duplicate();
float threshold = (float)(lambda*gamma*0.5);
RealSignal buffer = y.duplicate();
while(!controller.ends(x)) {
fft.transform(x, Z);
Z.times(A);
Z.plus(G);
fft.inverse(Z, z);
wavelets.shrinkage(threshold, z, x, buffer);
}
return x;
}
public void update(RealSignal xprev, RealSignal x, double w, RealSignal s) {
int nxy = x.nx * x.ny;
for(int k=0; k<x.nz; k++)
for(int i=0; i< nxy; i++) {
float vx = x.data[k][i];
s.data[k][i] = (float)(vx + w*(vx - xprev.data[k][i]));
xprev.data[k][i] = vx;
}
}
@Override
public String getName() {
- return "ISTA";
- }
-
- @Override
- public String getShortname() {
- return "ISTA";
+ return "Iterative Shrinkage-Thresholding [ISTA]";
}
@Override
public boolean isRegularized() {
return true;
}
@Override
public boolean isStepControllable() {
return true;
}
@Override
public boolean isIterative() {
return true;
}
@Override
public boolean isWaveletsBased() {
return true;
}
@Override
public void setWavelets(String waveletsName) {
this.waveletsName = waveletsName;
}
@Override
public void setParameters(double[] params) {
if (params == null)
return;
if (params.length > 0)
controller.setIterationMax((int)Math.round(params[0]));
if (params.length > 1)
gamma = (float)params[1];
if (params.length > 2)
lambda = (float)params[2];
if (params.length > 3)
scale = (int)params[3];
}
@Override
public double[] getDefaultParameters() {
return new double[] {10, 1, 0.1};
}
@Override
public double[] getParameters() {
return new double[] {controller.getIterationMax(), gamma, lambda};
}
@Override
public double getRegularizationFactor() {
return lambda;
}
@Override
public double getStepFactor() {
return gamma;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/ISTAPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/ISTAPanel.java
index 8ffd206..526516c 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/ISTAPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/ISTAPanel.java
@@ -1,165 +1,165 @@
/*
* 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 deconvolution.Command;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
import lab.component.GridPanel;
import lab.component.RegularizationPanel;
import lab.component.SpinnerRangeDouble;
import lab.component.SpinnerRangeInteger;
import lab.tools.NumFormat;
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.getShortname(), "iterations", spnIter, params[0]);
Config.register("Algorithm." + algo.getShortname(), "step", spnStep, params[1]);
Config.register("Algorithm." + algo.getShortname(), "wavelets", cmbWav, wavdef.getName());
Config.register("Algorithm." + algo.getShortname(), "scale", cmbScale, wavdef.getScales());
Config.register("Algorithm." + algo.getShortname(), "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 getShortname() {
- return algo.getShortname();
+ public String[] getShortname() {
+ return new String[] {"ISTA"};
}
@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>";
s += "<p>Shortname: " + getShortname() + "</p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/Identity.java b/DeconvolutionLab2/src/deconvolution/algorithm/Identity.java
index c53fda8..7bbafb0 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/Identity.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/Identity.java
@@ -1,104 +1,99 @@
/*
* 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.RealSignal;
public class Identity extends AbstractAlgorithm implements Callable<RealSignal> {
public Identity() {
super();
}
@Override
public RealSignal call() {
return y.duplicate();
}
@Override
public String getName() {
- return "Identity";
- }
-
- @Override
- public String getShortname() {
- return "I";
+ return "Identity (copy)";
}
@Override
public boolean isRegularized() {
return false;
}
@Override
public boolean isStepControllable() {
return false;
}
@Override
public boolean isIterative() {
return false;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
public void setParameters(double[] params) {
}
@Override
public double[] getParameters() {
return new double[] {};
}
@Override
public double[] getDefaultParameters() {
return new double[] {};
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return 0;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
index d90764a..9689aec 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/IdentityPanel.java
@@ -1,72 +1,72 @@
/*
* 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 lab.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 getShortname() {
- return algo.getShortname();
+ public String[] getShortname() {
+ return new String[] {"I", "ID"};
}
-
+
@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/Landweber.java b/DeconvolutionLab2/src/deconvolution/algorithm/Landweber.java
index 693166d..2e3c64e 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/Landweber.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/Landweber.java
@@ -1,130 +1,125 @@
/*
* 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;
public class Landweber extends AbstractAlgorithm implements Callable<RealSignal> {
private double gamma = 1.0;
public Landweber(int iter, double gamma) {
super();
controller.setIterationMax(iter);
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();
while (!controller.ends(X)) {
X.times(A);
X.plus(G);
}
RealSignal x = fft.inverse(X);
return x;
}
@Override
public String getName() {
- return "Landweber";
- }
-
- @Override
- public String getShortname() {
- return "LW";
+ return "Landweber [LW | LLS]";
}
@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)
controller.setIterationMax((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[] { controller.getIterationMax(), gamma };
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return gamma;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPanel.java
index 66af4d4..4197e3b 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPanel.java
@@ -1,109 +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 deconvolution.Command;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
import lab.component.GridPanel;
import lab.component.SpinnerRangeDouble;
import lab.component.SpinnerRangeInteger;
import lab.tools.NumFormat;
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.getShortname(), "iterations", spnIter, params[0]);
Config.register("Algorithm." + algo.getShortname(), "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 getShortname() {
- return algo.getShortname();
+ public String[] getShortname() {
+ return new String[] {"LW", "LLS"};
}
@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>";
s += "<p>Shortname: " + getShortname() + "</p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivity.java b/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivity.java
index ac7b385..0f7eed6 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivity.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivity.java
@@ -1,133 +1,128 @@
/*
* 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;
public class LandweberPositivity extends AbstractAlgorithm implements Callable<RealSignal> {
private double gamma = 1.0;
public LandweberPositivity(int iter, double gamma) {
super();
controller.setIterationMax(iter);
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);
while (!controller.ends(X)) {
X.times(A);
X.plus(G);
}
RealSignal x = fft.inverse(X);
return x;
}
@Override
public String getName() {
- return "Landweber+Positivity";
- }
-
- @Override
- public String getShortname() {
- return "LW+";
+ return "Non-Negative Least-Square [NNLS | LW+]";
}
@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)
controller.setIterationMax((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[] { controller.getIterationMax(), 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 cc103bc..e9cc00b 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivityPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivityPanel.java
@@ -1,109 +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 deconvolution.Command;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
import lab.component.GridPanel;
import lab.component.SpinnerRangeDouble;
import lab.component.SpinnerRangeInteger;
import lab.tools.NumFormat;
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.getShortname(), "iterations", spnIter, params[0]);
Config.register("Algorithm." + algo.getShortname(), "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 getShortname() {
- return algo.getShortname();
+ public String[] getShortname() {
+ return new String[] {"NNLS", "LW+"};
}
@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>";
s += "<p>Shortname: " + getShortname() + "</p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/NaiveInverseFilter.java b/DeconvolutionLab2/src/deconvolution/algorithm/NaiveInverseFilter.java
index 089b7c2..9db63b0 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/NaiveInverseFilter.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/NaiveInverseFilter.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 java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
public class NaiveInverseFilter extends AbstractAlgorithm implements Callable<RealSignal> {
public NaiveInverseFilter() {
super();
}
@Override
public RealSignal call() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal X = Operations.divideStabilized(Y, H);
RealSignal x = fft.inverse(X);
return x;
}
- @Override
- public String getShortname() {
- return "NIF";
- }
-
@Override
public String getName() {
- return "Naive Inverse Filter";
+ return "Naive Inverse Filter [NIF | IF]";
}
@Override
public boolean isRegularized() {
return false;
}
@Override
public boolean isStepControllable() {
return false;
}
@Override
public boolean isIterative() {
return false;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
public void setParameters(double[] params) {
}
@Override
public double[] getDefaultParameters() {
return new double[] {};
}
@Override
public double[] getParameters() {
return new double[] {};
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return 0;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/NaiveInverseFilterPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/NaiveInverseFilterPanel.java
index aad48fe..bcabb4c 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/NaiveInverseFilterPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/NaiveInverseFilterPanel.java
@@ -1,76 +1,75 @@
/*
* 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 lab.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>");
return pn;
}
@Override
public String getCommand() {
return "";
}
@Override
public String getName() {
return algo.getName();
}
@Override
- public String getShortname() {
- return algo.getShortname();
+ public String[] getShortname() {
+ return new String[] {"NIF", "IF"};
}
@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>";
- s += "<p>Shortname: " + getShortname() + "</p>";
+ 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>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/NonStabilizedDivision.java b/DeconvolutionLab2/src/deconvolution/algorithm/NonStabilizedDivision.java
index 94c4421..6e43a42 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/NonStabilizedDivision.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/NonStabilizedDivision.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 java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
public class NonStabilizedDivision extends AbstractAlgorithm implements Callable<RealSignal> {
public NonStabilizedDivision() {
super();
}
@Override
public RealSignal call() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal X = Operations.divideNotStabilized(Y, H);
RealSignal x = fft.inverse(X);
return x;
}
@Override
public String getName() {
- return "Non Stablized Division";
- }
-
- @Override
- public String getShortname() {
- return "DIV";
+ return "Non Stablized Division [DIV]";
}
@Override
public boolean isRegularized() {
return false;
}
@Override
public boolean isStepControllable() {
return false;
}
@Override
public boolean isIterative() {
return false;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
public void setParameters(double[] params) {
}
@Override
public double[] getDefaultParameters() {
return new double[] {};
}
@Override
public double[] getParameters() {
return new double[] {};
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return 0;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/NonStabilizedDivisionPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/NonStabilizedDivisionPanel.java
index 40cd77e..d77ba67 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/NonStabilizedDivisionPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/NonStabilizedDivisionPanel.java
@@ -1,76 +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 lab.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 getShortname() {
- return algo.getShortname();
+ public String[] getShortname() {
+ return new String[] {"DIV"};
}
@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>";
s += "<p>Shortname: " + getShortname() + "</p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/RegularizedInverseFilter.java b/DeconvolutionLab2/src/deconvolution/algorithm/RegularizedInverseFilter.java
index 16211c6..41782ed 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/RegularizedInverseFilter.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/RegularizedInverseFilter.java
@@ -1,122 +1,117 @@
/*
* 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.factory.complex.ComplexSignalFactory;
public class RegularizedInverseFilter extends AbstractAlgorithm implements Callable<RealSignal> {
private double lambda = 0.001;
public RegularizedInverseFilter(double lambda) {
super();
this.lambda = lambda;
}
@Override
public RealSignal call() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal H2 = Operations.multiply(H, H);
ComplexSignal L = ComplexSignalFactory.laplacian(Y.nx, Y.ny, Y.nz);
ComplexSignal L2 = Operations.multiply(lambda, L, L);
ComplexSignal FA = Operations.add(H2, L2);
ComplexSignal FT = Operations.divideStabilized(H, FA);
ComplexSignal X = Operations.multiply(Y, FT);
RealSignal x = fft.inverse(X);
return x;
}
@Override
public String getName() {
- return "Regularized Inverse Filter";
- }
-
- @Override
- public String getShortname() {
- return "RIF";
+ return "Regularized Inverse Filter [RIF | LRIF]";
}
@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;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/RegularizedInverseFilterPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/RegularizedInverseFilterPanel.java
index 826279b..dd505b8 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/RegularizedInverseFilterPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/RegularizedInverseFilterPanel.java
@@ -1,115 +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.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import deconvolution.Command;
import deconvolutionlab.Config;
import lab.component.GridPanel;
import lab.component.RegularizationPanel;
import lab.tools.NumFormat;
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.getShortname(), "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 getShortname() {
- return algo.getShortname();
+ public String[] getShortname() {
+ return new String[] {"RIF", "LRIF"};
}
@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>";
- s += "<p>Shortname: " + getShortname() + "</p>";
+ 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>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucy.java b/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucy.java
index 3be1344..11fe33b 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucy.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucy.java
@@ -1,126 +1,121 @@
/*
* 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;
public class RichardsonLucy extends AbstractAlgorithm implements Callable<RealSignal> {
public RichardsonLucy(int iter) {
super();
controller.setIterationMax(iter);
}
// 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);
}
return x;
}
@Override
public String getName() {
- return "Richardson-Lucy";
- }
-
- @Override
- public String getShortname() {
- return "RL";
+ return "Richardson-Lucy [RL]";
}
@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)
controller.setIterationMax((int) Math.round(params[0]));
}
@Override
public double[] getDefaultParameters() {
return new double[] { 10 };
}
@Override
public double[] getParameters() {
return new double[] { controller.getIterationMax() };
}
@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 f15c342..60beba8 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyPanel.java
@@ -1,92 +1,92 @@
/*
* 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 deconvolution.Command;
import deconvolutionlab.Config;
import lab.component.GridPanel;
import lab.component.SpinnerRangeInteger;
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.getShortname(), "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 getShortname() {
- return algo.getShortname();
+ public String[] getShortname() {
+ return new String[] {"RL"};
}
@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>";
s += "<p>Shortname: " + getShortname() + "</p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyTV.java b/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyTV.java
index f16801a..b769aa3 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyTV.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyTV.java
@@ -1,219 +1,214 @@
/*
* 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;
public class RichardsonLucyTV extends AbstractAlgorithm implements Callable<RealSignal> {
private double lambda = 0.1;
public RichardsonLucyTV(int iter, double lambda) {
super();
controller.setIterationMax(iter);
this.lambda = lambda;
}
// x(k+1) = x(k) *. Hconj * ( y /. H x(k))
@Override
public RealSignal call() {
ComplexSignal H = fft.transform(h);
ComplexSignal U = new ComplexSignal("RLTV-U",y.nx, y.ny, y.nz);
RealSignal x = y.duplicate();
RealSignal gx = y.duplicate();
RealSignal gy = y.duplicate();
RealSignal gz = y.duplicate();
RealSignal ggx = y.duplicate();
RealSignal ggy = y.duplicate();
RealSignal ggz = y.duplicate();
RealSignal u = gx; // resued memory
RealSignal p = gy; // resued memory
RealSignal tv = gz; // resued memory
while(!controller.ends(x)) {
gradientX(x, gx);
gradientY(x, gy);
gradientZ(x, gz);
normalize(gx, gy, gz);
gradientX(gx, ggx);
gradientY(gy, ggy);
gradientZ(gz, ggz);
compute((float)lambda, ggx, ggy, ggz, tv);
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);
x.times(tv);
}
return x;
}
private void compute(float lambda, RealSignal gx, RealSignal gy, RealSignal gz, RealSignal tv) {
int nxy = gx.nx * gy.ny;
for(int k=0; k<gx.nz; k++)
for(int i=0; i< nxy; i++) {
double dx = gx.data[k][i];
double dy = gy.data[k][i];
double dz = gz.data[k][i];
tv.data[k][i] = (float)(1.0 / ( (dx+dy+dz) * lambda + 1.0));
}
//Log.info("Norm TV "+ Math.sqrt(norm));
}
public void gradientX(RealSignal signal, RealSignal output) {
int nx = signal.nx;
int ny = signal.ny;
int nz = signal.nz;
for(int k=0; k<nz; k++)
for(int j=0; j<ny; j++)
for(int i=0; i<nx-1; i++) {
int index = i + signal.nx*j;
output.data[k][index] = signal.data[k][index] - signal.data[k][index+1];
}
}
public void gradientY(RealSignal signal, RealSignal output) {
int nx = signal.nx;
int ny = signal.ny;
int nz = signal.nz;
for(int k=0; k<nz; k++)
for(int j=0; j<ny-1; j++)
for(int i=0; i<nx; i++) {
int index = i + signal.nx*j;
output.data[k][index] = signal.data[k][index] - signal.data[k][index+nx];
}
}
public void gradientZ(RealSignal signal, RealSignal output) {
int nx = signal.nx;
int ny = signal.ny;
int nz = signal.nz;
for(int k=0; k<nz-1; k++)
for(int j=0; j<ny; j++)
for(int i=0; i<nx; i++) {
int index = i + signal.nx*j;
output.data[k][index] = signal.data[k][index] - signal.data[k+1][index];
}
}
public void normalize(RealSignal x, RealSignal y, RealSignal z) {
int nx = x.nx;
int ny = y.ny;
int nz = z.nz;
float e = (float) Operations.epsilon;
for(int k=0; k<nz; k++)
for(int i=0; i<nx*ny; i++) {
double norm = Math.sqrt(x.data[k][i] * x.data[k][i] + y.data[k][i] * y.data[k][i] + z.data[k][i] * z.data[k][i]);
if (norm < e) {
x.data[k][i] = e;
y.data[k][i] = e;
z.data[k][i] = e;
}
else {
x.data[k][i] /= norm;
y.data[k][i] /= norm;
z.data[k][i] /= norm;
}
}
}
@Override
public String getName() {
- return "Richardson-Lucy TV";
+ return "Richardson-Lucy Total Variation [RLTV]";
}
- @Override
- public String getShortname() {
- return "RLTV";
- }
-
@Override
public boolean isRegularized() {
return true;
}
@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)
controller.setIterationMax((int)Math.round(params[0]));
if (params.length > 1)
lambda = (float)params[1];
}
@Override
public double[] getDefaultParameters() {
return new double[] {10, 0.1};
}
@Override
public double[] getParameters() {
return new double[] {controller.getIterationMax(), lambda};
}
@Override
public double getRegularizationFactor() {
return lambda;
}
@Override
public double getStepFactor() {
return 0.0;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyTVPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyTVPanel.java
index a4fbe82..f0d531c 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyTVPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyTVPanel.java
@@ -1,129 +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 deconvolution.Command;
import deconvolutionlab.Config;
import lab.component.GridPanel;
import lab.component.RegularizationPanel;
import lab.component.SpinnerRangeInteger;
import lab.tools.NumFormat;
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.getShortname(), "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 getShortname() {
- return algo.getShortname();
+ public String[] getShortname() {
+ return new String[] {"RLTV"};
}
@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>";
- s += "<p>Shortname: " + getShortname() + "</p>";
+ s += "<h2> Shortname: RLTV</h2>";
+ 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></p>";
+ s += "<h3>Reference: Dey et al., Microscopy Research and Technics, 2006 " + getShortname() + "</p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/Simulation.java b/DeconvolutionLab2/src/deconvolution/algorithm/Simulation.java
index 5fa917c..f589bab 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/Simulation.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/Simulation.java
@@ -1,150 +1,145 @@
/*
* 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 lab.tools.PsRandom;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
public class Simulation extends AbstractAlgorithm implements Callable<RealSignal> {
private static PsRandom rand = new PsRandom(1234);
private double mean = 0.0;
private double stdev = 10.0;
private double poisson = 0.0;
public Simulation(double mean, double stdev, double poisson) {
super();
this.mean = mean;
this.stdev = stdev;
this.poisson = poisson;
}
@Override
public RealSignal call() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal X = Operations.multiply(H, Y);
RealSignal x = fft.inverse(X);
gaussian(x, mean, stdev);
poisson(x, poisson);
return x;
}
public void gaussian(RealSignal x, double mean, double sd) {
for (int k = 0; k < x.nz; k++) {
float[] slice = x.getXY(k);
for (int j = 0; j < x.ny * x.nx; j++)
slice[j] += (float) rand.nextGaussian(mean, sd);
}
}
public void poisson(RealSignal x, double factor) {
if (factor < Operations.epsilon)
return;
double f = 1.0/(factor);
for (int k = 0; k < x.nz; k++) {
float[] slice = x.getXY(k);
for (int j = 0; j < x.ny * x.nx; j++)
if (slice[j] > Operations.epsilon) {
slice[j] = (float)(rand.nextPoissonian(f*(slice[j])) * factor);
}
}
}
@Override
public String getName() {
- return "Simulation";
- }
-
- @Override
- public String getShortname() {
- return "SIM";
+ return "Simulation with noise [SIM]";
}
@Override
public boolean isRegularized() {
return false;
}
@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)
mean = params[0];
if (params.length > 1)
stdev = params[1];
if (params.length > 2)
poisson = params[2];
}
@Override
public double[] getDefaultParameters() {
return new double[] {0, 1, 0};
}
@Override
public double[] getParameters() {
return new double[] {mean, stdev, poisson};
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return 0;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/SimulationPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/SimulationPanel.java
index 19dce0f..11d9f2f 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/SimulationPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/SimulationPanel.java
@@ -1,113 +1,114 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import javax.swing.JTextField;
import deconvolution.Command;
import deconvolutionlab.Config;
import lab.component.GridPanel;
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.getShortname(), "gaussian.mean", txtMean, params[0]);
Config.register("Algorithm." + algo.getShortname(), "gaussian.stdev", txtStdev, params[1]);
Config.register("Algorithm." + algo.getShortname(), "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 getShortname() {
- return algo.getShortname();
+ public String[] getShortname() {
+ return new String[] {"SIM", "SIMU"};
}
@Override
public String getDocumentation() {
String s = "";
s += "<h1>" + getName() + "</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;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovMiller.java b/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovMiller.java
index fde058c..24b0fc4 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovMiller.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovMiller.java
@@ -1,132 +1,127 @@
/*
* 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.factory.complex.ComplexSignalFactory;
public class TikhonovMiller extends AbstractAlgorithm implements Callable<RealSignal> {
private double gamma = 1.0;
private double lambda = 1.0;
public TikhonovMiller(int iter, double gamma, double lambda) {
super();
controller.setIterationMax(iter);
this.gamma = gamma;
this.lambda = lambda;
}
@Override
public RealSignal call() throws Exception {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal A = Operations.delta(gamma, H);
ComplexSignal L = ComplexSignalFactory.laplacian(Y.nx, Y.ny, Y.nz);
ComplexSignal L2 = Operations.multiplyConjugate(lambda*gamma, L, L);
A.minus(L2);
ComplexSignal G = Operations.multiplyConjugate(gamma, H, Y);
ComplexSignal X = G.duplicate();
while(!controller.ends(X)) {
X.times(A);
X.plus(G);
}
RealSignal x = fft.inverse(X);
return x;
}
@Override
public String getName() {
- return "Tikhonov-Miller";
- }
-
- @Override
- public String getShortname() {
- return "TM";
+ return "Tikhonov-Miller [TM]";
}
@Override
public boolean isRegularized() {
return true;
}
@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)
controller.setIterationMax((int)Math.round(params[0]));
if (params.length > 1)
gamma = (float)params[1];
if (params.length > 2)
lambda = (float)params[2];
}
@Override
public double[] getDefaultParameters() {
return new double[] {10, 1, 0.1};
}
@Override
public double[] getParameters() {
return new double[] {controller.getIterationMax(), gamma, lambda};
}
@Override
public double getRegularizationFactor() {
return lambda;
}
@Override
public double getStepFactor() {
return gamma;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovMillerPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovMillerPanel.java
index 62179db..b748877 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovMillerPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovMillerPanel.java
@@ -1,142 +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 deconvolution.Command;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
import lab.component.GridPanel;
import lab.component.RegularizationPanel;
import lab.component.SpinnerRangeDouble;
import lab.component.SpinnerRangeInteger;
import lab.tools.NumFormat;
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.getShortname(), "iterations", spnIter, params[0]);
Config.register("Algorithm." + algo.getShortname(), "step", spnStep, params[1]);
Config.register("Algorithm." + algo.getShortname(), "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 getShortname() {
- return algo.getShortname();
+ public String[] getShortname() {
+ return new String[] {"TM"};
}
@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>";
s += "<p>Shortname: " + getShortname() + "</p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizationInverseFilter.java b/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizationInverseFilter.java
index 9f534fe..3e9f2c2 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizationInverseFilter.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizationInverseFilter.java
@@ -1,140 +1,135 @@
/*
* 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;
public class TikhonovRegularizationInverseFilter extends AbstractAlgorithm implements Callable<RealSignal> {
private double lambda = 0.1;
public TikhonovRegularizationInverseFilter(double lambda) {
super();
this.lambda = lambda;
}
@Override
public RealSignal call() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal X = compute(Y, H);
RealSignal x = fft.inverse(X);
return x;
}
private ComplexSignal compute(ComplexSignal Y, ComplexSignal H) {
int nx = H.nx;
int ny = H.ny;
int nz = H.nz;
int nxy = nx * ny*2;
double ya, yb, ha, hb, fa, fb, mag, ta, tb;
double epsilon2 = Operations.epsilon * Operations.epsilon;
ComplexSignal result = new ComplexSignal("TM", nx, ny, nz);
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 + lambda;
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] = (float)(ya*ta - yb*tb);
result.data[k][i+1] = (float)(ya*tb + ta*yb);
}
return result;
}
@Override
public String getName() {
- return "Tikhonov Regularization";
- }
-
- @Override
- public String getShortname() {
- return "TRIF";
+ return "Tikhonov Regularization [TRIF]";
}
@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/TikhonovRegularizationInverseFilterPanel.java
index ff6c72d..de79415 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizationInverseFilterPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizationInverseFilterPanel.java
@@ -1,123 +1,123 @@
/*
* 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 deconvolution.Command;
import deconvolutionlab.Config;
import lab.component.GridPanel;
import lab.component.RegularizationPanel;
import lab.tools.NumFormat;
public class TikhonovRegularizationInverseFilterPanel extends AbstractAlgorithmPanel implements ActionListener, ChangeListener, KeyListener {
private RegularizationPanel reg;
private TikhonovRegularizationInverseFilter algo = new TikhonovRegularizationInverseFilter(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.getShortname(), "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 getShortname() {
- return algo.getShortname();
+ public String[] getShortname() {
+ return new String[] {"TRIF"};
}
@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 += "<p>Shortname: " + getShortname() + "</p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/VanCittert.java b/DeconvolutionLab2/src/deconvolution/algorithm/VanCittert.java
index 4f2a55f..030210f 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/VanCittert.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/VanCittert.java
@@ -1,130 +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.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
public class VanCittert extends AbstractAlgorithm implements Callable<RealSignal> {
private double gamma = 1.0;
public VanCittert(int iter, double gamma) {
super();
controller.setIterationMax(iter);
this.gamma = gamma;
}
@Override
// VAnCitter algorithm
// X(n+1) = X(n) + g*(Y-H*X(n))
// => X(n+1) = X(n) - g*H*X(n) + g*Y
// => X(n+1) = X(n) * (I-g*H) + g*Y
// => pre-compute: A = (I-g*H) and G = g*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.delta1(gamma, H);
ComplexSignal G = Operations.multiply(gamma, Y);
ComplexSignal X = G.duplicate();
while(!controller.ends(X)) {
X.times(A);
X.plus(G);
}
RealSignal x = fft.inverse(X);
return x;
}
@Override
public String getName() {
- return "Van Cittert";
+ return "Van Cittert [VC]";
}
- @Override
- public String getShortname() {
- return "VC";
- }
-
-
@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)
controller.setIterationMax((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[] {controller.getIterationMax(), gamma};
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return gamma;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/VanCittertPanel.java b/DeconvolutionLab2/src/deconvolution/algorithm/VanCittertPanel.java
index 996b573..b383959 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/VanCittertPanel.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/VanCittertPanel.java
@@ -1,106 +1,106 @@
/*
* 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 deconvolution.Command;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
import lab.component.GridPanel;
import lab.component.SpinnerRangeDouble;
import lab.component.SpinnerRangeInteger;
import lab.tools.NumFormat;
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.getShortname(), "iterations", spnIter, params[0]);
Config.register("Algorithm." + algo.getShortname(), "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 getShortname() {
- return algo.getShortname();
+ public String[] getShortname() {
+ return new String[] {"VC"};
}
-
+
@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>";
s += "<p>Shortname: " + getShortname() + "</p>";
return s;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/modules/AbstractDModule.java b/DeconvolutionLab2/src/deconvolution/modules/AbstractDModule.java
index af73615..d8f7a7a 100644
--- a/DeconvolutionLab2/src/deconvolution/modules/AbstractDModule.java
+++ b/DeconvolutionLab2/src/deconvolution/modules/AbstractDModule.java
@@ -1,31 +1,32 @@
package deconvolution.modules;
import javax.swing.JFrame;
import javax.swing.JSplitPane;
import deconvolution.Deconvolution;
+import deconvolutionlab.Lab;
public abstract class AbstractDModule {
protected Deconvolution deconvolution;
protected JSplitPane split;
public AbstractDModule(Deconvolution deconvolution) {
this.deconvolution = deconvolution;
}
public JSplitPane getPane() {
return split;
}
public void show(String name) {
JFrame frame = new JFrame(name);
update();
frame.getContentPane().add(split);
frame.pack();
- frame.setVisible(true);
+ Lab.setVisible(frame);
}
public abstract void update();
public abstract String getName();
}
diff --git a/DeconvolutionLab2/src/deconvolution/modules/AlgorithmDModule.java b/DeconvolutionLab2/src/deconvolution/modules/AlgorithmDModule.java
index 97cc404..431e97e 100644
--- a/DeconvolutionLab2/src/deconvolution/modules/AlgorithmDModule.java
+++ b/DeconvolutionLab2/src/deconvolution/modules/AlgorithmDModule.java
@@ -1,45 +1,46 @@
package deconvolution.modules;
-import java.awt.Graphics;
-import java.awt.image.BufferedImage;
-
-import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import deconvolution.Deconvolution;
+import deconvolution.algorithm.AbstractAlgorithmPanel;
+import deconvolution.algorithm.Algorithm;
import lab.component.CustomizedTable;
-import lab.component.JPanelImage;
+import lab.component.HTMLPane;
public class AlgorithmDModule extends AbstractDModule {
- private JPanelImage pnImage;
- private CustomizedTable table;
-
+ private CustomizedTable table;
+ private HTMLPane doc;
public AlgorithmDModule(Deconvolution deconvolution) {
super(deconvolution);
- pnImage = new JPanelImage();
+ doc = new HTMLPane(100, 1000);
table = new CustomizedTable(new String[] { "Features", "Values" }, false);
- split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, table.getPane(200, 200), pnImage);
+ split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, table.getPane(200, 200), doc.getPane());
update();
}
-
+
public void update() {
- if (pnImage == null)
+ if (doc == null)
return;
if (table == null)
return;
table.removeRows();
for (String[] feature : deconvolution.checkAlgo())
table.append(feature);
- split.setDividerLocation(0.5);
- split.repaint();
+
+ doc.clear();
+ String name = deconvolution.getAlgo().getShortname();
+ AbstractAlgorithmPanel algo = Algorithm.getPanel(name);
+ if (algo != null)
+ doc.append(algo.getDocumentation());
+ split.setDividerLocation(300);
}
@Override
public String getName() {
return "Algorithm";
}
-
}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/deconvolution/modules/ImageDModule.java b/DeconvolutionLab2/src/deconvolution/modules/ImageDModule.java
index 10bc92a..bb6d2a8 100644
--- a/DeconvolutionLab2/src/deconvolution/modules/ImageDModule.java
+++ b/DeconvolutionLab2/src/deconvolution/modules/ImageDModule.java
@@ -1,54 +1,51 @@
package deconvolution.modules;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import javax.swing.JSplitPane;
import deconvolution.Deconvolution;
import lab.component.CustomizedTable;
import lab.component.JPanelImage;
import signal.RealSignal;
public class ImageDModule extends AbstractDModule {
private JPanelImage pnImage;
private CustomizedTable table;
private BufferedImage img;
public ImageDModule(Deconvolution deconvolution) {
super(deconvolution);
pnImage = new JPanelImage();
table = new CustomizedTable(new String[] { "Features", "Values" }, false);
pnImage.setPreferredSize(new Dimension(300, 300));
- split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, table.getPane(300, 200), pnImage);
-
+ split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, table.getPane(300, 300), pnImage);
update();
}
public void update() {
+ split.setDividerLocation(300);
if (pnImage == null)
return;
if (table == null)
return;
-
+
RealSignal signal = deconvolution.openImage();
table.removeRows();
if (signal == null) {
table.append(new String[] {"ERROR", "No open image"});
return;
}
img = signal.createPreviewMIPZ();
pnImage.setImage(img);
- for (String[] feature : deconvolution.checkImage())
+ for (String[] feature : deconvolution.checkImage(signal))
table.append(feature);
- split.setDividerLocation(0.5);
}
@Override
public String getName() {
return "Image";
}
-
-
}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/deconvolution/modules/PSFDModule.java b/DeconvolutionLab2/src/deconvolution/modules/PSFDModule.java
index ecaa0e9..1d4bb8d 100644
--- a/DeconvolutionLab2/src/deconvolution/modules/PSFDModule.java
+++ b/DeconvolutionLab2/src/deconvolution/modules/PSFDModule.java
@@ -1,48 +1,54 @@
package deconvolution.modules;
+import java.awt.Dimension;
import java.awt.image.BufferedImage;
import javax.swing.JSplitPane;
import deconvolution.Deconvolution;
+import deconvolutionlab.Lab;
+import deconvolutionlab.monitor.Monitors;
import lab.component.CustomizedTable;
import lab.component.JPanelImage;
+import signal.Constraint;
import signal.RealSignal;
public class PSFDModule extends AbstractDModule {
private JPanelImage pnImage;
private CustomizedTable table;
public PSFDModule(Deconvolution deconvolution) {
super(deconvolution);
pnImage = new JPanelImage();
table = new CustomizedTable(new String[] { "Features", "Values" }, false);
- split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, table.getPane(200, 200), pnImage);
+ pnImage.setPreferredSize(new Dimension(300, 300));
+ split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, table.getPane(300, 300), pnImage);
+ update();
}
public void update() {
+ split.setDividerLocation(300);
if (pnImage == null)
return;
if (table == null)
return;
RealSignal signal = deconvolution.openPSF();
+
table.removeRows();
if (signal == null) {
- table.append(new String[] {"ERROR", "No open image"});
+ table.append(new String[] {"ERROR", "No PSF image"});
return;
}
BufferedImage img = signal.createPreviewMIPZ();
pnImage.setImage(img);
- for (String[] feature : deconvolution.checkPSF())
+ for (String[] feature : deconvolution.checkPSF(signal))
table.append(feature);
- split.setDividerLocation(0.5);
- split.repaint();
}
@Override
public String getName() {
return "PSF";
}
}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/deconvolution/modules/RecapDModule.java b/DeconvolutionLab2/src/deconvolution/modules/RecapDModule.java
index 4b343f8..2b88141 100644
--- a/DeconvolutionLab2/src/deconvolution/modules/RecapDModule.java
+++ b/DeconvolutionLab2/src/deconvolution/modules/RecapDModule.java
@@ -1,70 +1,75 @@
package deconvolution.modules;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JSplitPane;
import javax.swing.text.BadLocationException;
import deconvolution.Deconvolution;
import lab.component.CustomizedTable;
import lab.component.HTMLPane;
public class RecapDModule extends AbstractDModule implements KeyListener {
private HTMLPane pnCommand;
private CustomizedTable table;
public RecapDModule(Deconvolution deconvolution) {
super(deconvolution);
// Panel command
pnCommand = new HTMLPane("Monaco", "#10FF10", "100020", 100, 100);
pnCommand.append("p", deconvolution.getCommand());
pnCommand.setEditable(true);
pnCommand.addKeyListener(this);
table = new CustomizedTable(new String[] { "Features", "Values" }, false);
split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, table.getPane(200, 200), pnCommand.getPane());
update();
}
public void update() {
if (table == null)
return;
+ table.removeRows();
+ for (String[] feature : deconvolution.recap())
+ table.append(feature);
+
split.setDividerLocation(0.5);
split.repaint();
}
public String getCommand() {
return pnCommand.getText();
}
+
@Override
public String getName() {
- return "Command";
+ return "Recap";
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
try {
int len = pnCommand.getDocument().getLength();
String command = pnCommand.getDocument().getText(0, len);
deconvolution.setCommand(command);
table.removeRows();
for (String[] feature : deconvolution.recap())
table.append(feature);
}
catch (BadLocationException e1) {
e1.printStackTrace();
}
}
}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/deconvolution/modules/ReportDModule.java b/DeconvolutionLab2/src/deconvolution/modules/ReportDModule.java
index eecfe06..61c7a6c 100644
--- a/DeconvolutionLab2/src/deconvolution/modules/ReportDModule.java
+++ b/DeconvolutionLab2/src/deconvolution/modules/ReportDModule.java
@@ -1,42 +1,55 @@
package deconvolution.modules;
+import java.awt.Dimension;
import java.awt.image.BufferedImage;
import javax.swing.JSplitPane;
import deconvolution.Deconvolution;
import lab.component.CustomizedTable;
import lab.component.JPanelImage;
import signal.RealSignal;
public class ReportDModule extends AbstractDModule {
private JPanelImage pnImage;
private CustomizedTable table;
-
+ private BufferedImage img;
+
public ReportDModule(Deconvolution deconvolution) {
super(deconvolution);
pnImage = new JPanelImage();
- table = new CustomizedTable(new String[] { "Features", "Values" }, false);
- split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, table.getPane(200, 200), pnImage);
+ table = new CustomizedTable(new String[] { "Output", "Values" }, false);
+ pnImage.setPreferredSize(new Dimension(300, 300));
+ split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, table.getPane(300, 300), pnImage);
+ update();
}
public void update() {
+ split.setDividerLocation(300);
if (pnImage == null)
return;
if (table == null)
return;
table.removeRows();
+
for (String[] feature : deconvolution.getDeconvolutionReports())
table.append(feature);
- split.setDividerLocation(0.5);
- split.repaint();
+ RealSignal signal = deconvolution.getOutput();
+ if (signal == null) {
+ table.append(new String[] {"ERROR", "No output image"});
+ return;
+ }
+ img = signal.createPreviewMIPZ();
+ pnImage.setImage(img);
+
+ for (String[] feature : deconvolution.checkOutput())
+ table.append(feature);
+ split.setDividerLocation(300);
}
@Override
public String getName() {
return "Report";
}
-
-
-}
\ No newline at end of file
+}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/Constants.java b/DeconvolutionLab2/src/deconvolutionlab/Constants.java
index 97e9996..e71409d 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/Constants.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/Constants.java
@@ -1,65 +1,65 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab;
import java.awt.Dimension;
public class Constants {
public static String name = "DeconvolutionLab2 [Beta 2]";
public static String copyright = "\u00A9 2010-2017. Biomedical Imaging Group, EPFL.";
public static String url = "http://bigwww.epfl.ch/deconvolution/";
public static String reference =
"D. Sage, L. Donati, F. Soulez, D. Fortun, A. Seitz, R. Guiet, C. Vonesch, M Unser " +
"DeconvolutionLab2 : An open-source software for deconvolution microscopy " +
"Methods, 2017.";
public static String version = "(Beta 12.02.2017)";
public static String authors =
"Daniel Sage, " +
"Cédric Vonesch, " +
"Guillaume Schmit, " +
"Pierre Besson, " +
"Raquel Terrés Cristofani, " +
"Alessandra Griffa";
public static String help =
"<h1>" + name + "</h1>" +
"<h2>" + version + "</h2>";
- public static int widthGUI = 500;
+ public static int widthGUI = 600;
public static Dimension dimParameters = new Dimension(88, 25);
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/Lab.java b/DeconvolutionLab2/src/deconvolutionlab/Lab.java
index 2637431..9d7bacc 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/Lab.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/Lab.java
@@ -1,303 +1,322 @@
/*
* 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 deconvolutionlab.Imaging.ContainerImage;
import deconvolutionlab.monitor.Monitors;
import fft.AbstractFFT;
import fft.AbstractFFTLibrary;
import fft.FFT;
import imagej.IJImager;
import lab.tools.NumFormat;
import lab.tools.WebBrowser;
import plugins.sage.deconvolutionlab.IcyImager;
import signal.ComplexComponent;
import signal.ComplexSignal;
import signal.RealSignal;
import signal.factory.Sphere;
public class Lab {
private static Imaging imaging;
+ private static ArrayList<JFrame> frames;
+ private static ArrayList<JDialog> dialogs;
static {
+ frames = new ArrayList<JFrame>();
+ dialogs = new ArrayList<JDialog>();
imaging = new IJImager();
Config.init(System.getProperty("user.dir") + File.separator + "DeconvolutionLab2.config");
}
public static Imaging.Platform getPlatform() {
return imaging.getPlatform();
}
public static void init(Imaging.Platform p) {
init(p, System.getProperty("user.dir") + File.separator + "DeconvolutionLab2.config");
}
public static void init(Imaging.Platform platform, String config) {
switch (platform) {
case IMAGEJ:
imaging = new IJImager();
break;
case ICY:
imaging = new IcyImager();
break;
default:
imaging = new IJImager();
break;
}
Config.init(System.getProperty("user.dir")+File.separator+"DeconvolutionLab2.config");
}
public static void help() {
WebBrowser.open(Constants.url);
}
public static void checkFFT(Monitors monitors) {
ArrayList<AbstractFFTLibrary> libraries = FFT.getInstalledLibraries();
for (int k = 1; k <= 3; k++)
for (AbstractFFTLibrary library : libraries) {
RealSignal y = new Sphere(3, 1).generate(40, 30, 20);
double chrono = System.nanoTime();
AbstractFFT fft = library.getDefaultFFT();
fft.init(monitors, y.nx, y.ny, y.nz);
RealSignal x = fft.inverse(fft.transform(y));
chrono = System.nanoTime() - chrono;
double residu = y.getEnergy() - x.getEnergy();
monitors.log(fft.getName() + " Test " + k);
monitors.log("\t residu of reconstruction: " + residu);
monitors.log("\t computation time (" + x.nx + "x" + x.ny + "x" + x.nz + ") " + NumFormat.time(chrono));
}
}
public static ContainerImage createContainer(Monitors monitors, String title) {
monitors.log("Create Live Real Signal " + title);
return imaging.createContainer(title);
}
public static void append(Monitors monitors, ContainerImage container, RealSignal signal, String title) {
imaging.append(container, signal, title, Imaging.Type.FLOAT);
monitors.log("Add Live Real Signal " + title);
}
public static void append(Monitors monitors, ContainerImage container, RealSignal signal, String title, Imaging.Type type) {
imaging.append(container, signal, title, type);
monitors.log("Add Live Real Signal " + title);
}
public static void show(Monitors monitors, ComplexSignal signal, String title) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, ComplexComponent.MODULE);
}
public static void show(Monitors monitors, ComplexSignal signal, String title, ComplexComponent complex) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, complex);
}
public static void show(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, Imaging.Type.FLOAT, signal.nz / 2);
}
public static void show(Monitors monitors, RealSignal signal, String title, Imaging.Type type) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, type, signal.nz / 2);
}
public static void show(Monitors monitors, RealSignal signal, String title, Imaging.Type type, int z) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, type, z);
}
public static void save(Monitors monitors, RealSignal signal, String filename) {
imaging.save(signal, filename, Imaging.Type.FLOAT);
monitors.log("Save Real Signal " + filename);
}
public static void save(Monitors monitors, RealSignal signal, String filename, Imaging.Type type) {
imaging.save(signal, filename, type);
monitors.log("Save Real Signal " + filename);
}
public static RealSignal open(Monitors monitors, String filename) {
RealSignal signal = imaging.open(filename);
if (signal == null)
monitors.error("Unable to open " + filename);
else
monitors.log("Load " + filename);
return signal;
}
public static RealSignal openDir(Monitors monitors, String path) {
String parts[] = path.split(" pattern ");
String dirname = path;
String regex = "";
if (parts.length == 2) {
dirname = parts[0].trim();
regex = parts[1].trim();
}
File file = new File(dirname + File.separator);
if (!file.isDirectory()) {
monitors.error("Dir " + dirname + " is not a directory.");
return null;
}
String[] list = file.list();
ArrayList<RealSignal> slices = new ArrayList<RealSignal>();
int nx = 0;
int ny = 0;
Pattern pattern = Pattern.compile(regex);
for (String filename : list) {
if (pattern.matcher(filename).find()) {
RealSignal slice = imaging.open(dirname + File.separator + filename);
if (slice != null) {
slices.add(slice);
nx = Math.max(nx, slice.nx);
ny = Math.max(ny, slice.ny);
monitors.log("Image " + path + File.separator + filename + " is loaded.");
}
}
else {
monitors.error("Error in loading image " + path + File.separator + filename);
}
}
int nz = slices.size();
if (nz <= 0) {
monitors.error("Dir " + path + " do no contain valid images.");
return null;
}
RealSignal signal = new RealSignal(file.getName(), nx, ny, nz);
for (int z = 0; z < slices.size(); z++)
signal.setSlice(z, slices.get(z));
return signal;
}
public static void showOrthoview(Monitors monitors, RealSignal signal, String title, int hx, int hy, int hz) {
if (signal == null) {
monitors.error("Show Orthoview " + title + " this image does not exist.");
return;
}
imaging.show(signal.createOrthoview(hx, hy, hz), title, Imaging.Type.FLOAT, 0);
}
public static void showOrthoview(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show Orthoview " + title + " this image does not exist.");
return;
}
int hx = signal.nx / 2;
int hy = signal.ny / 2;
int hz = signal.nz / 2;
imaging.show(signal.createOrthoview(hx, hy, hz), title, Imaging.Type.FLOAT, 0);
}
public static void showMIP(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show MIP " + title + " this image does not exist.");
return;
}
imaging.show(signal.createMIP(), title, Imaging.Type.FLOAT, 0);
}
public static void showMontage(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show Montage " + title + " this image does not exist.");
return;
}
imaging.show(signal.createMontage(), title, Imaging.Type.FLOAT, 0);
}
public static RealSignal create(Monitors monitors, String name) {
RealSignal signal = imaging.create(name);
if (signal != null)
monitors.log("Created the real signal " + name + " " + signal.toString());
else
monitors.error("Impossible to create the real signal " + name);
return signal;
}
public static RealSignal create(Monitors monitors) {
RealSignal signal = imaging.create();
if (signal != null)
monitors.log("Created the real signal from the active window " + signal.toString());
else
monitors.error("Impossible to create the real signal from the active window");
return signal;
}
public static Imaging getImager() {
return imaging;
}
public static String getActiveImage() {
if (imaging.isSelectable())
return imaging.getSelectedImage();
return "";
}
public static void setVisible(JDialog dialog, boolean modal) {
if (dialog == null)
return;
+ dialogs.add(dialog);
imaging.setVisible(dialog, modal);
}
-
+
+ public static void setVisible(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/LabDialog.java b/DeconvolutionLab2/src/deconvolutionlab/LabDialog.java
similarity index 95%
rename from DeconvolutionLab2/src/deconvolutionlab/dialog/LabDialog.java
rename to DeconvolutionLab2/src/deconvolutionlab/LabDialog.java
index d5d1bcb..e2662b0 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/dialog/LabDialog.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/LabDialog.java
@@ -1,145 +1,144 @@
/*
* 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;
+package deconvolutionlab;
+import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import deconvolution.DeconvolutionDialog;
-import deconvolutionlab.Config;
-import deconvolutionlab.Constants;
-import deconvolutionlab.Imaging;
-import deconvolutionlab.Lab;
import deconvolutionlab.system.SystemInfo;
public class LabDialog extends JDialog implements ComponentListener, ActionListener, WindowListener {
private LabPanel panel;
private JButton bnClose = new JButton("Close");
public LabDialog() {
super(new JFrame(), Constants.name);
Config.registerFrame("DeconvolutionLab", "MainDialog", this);
panel = new LabPanel(bnClose);
getContentPane().add(panel);
pack();
addWindowListener(this);
addComponentListener(this);
bnClose.addActionListener(this);
Rectangle rect = Config.getDialog("DeconvolutionLab.MainDialog");
if (rect.x > 0 && rect.y > 0)
setLocation(rect.x, rect.y);
+ if (rect.width > 0 && rect.height > 0)
+ setPreferredSize(new Dimension(rect.width, rect.height));
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == bnClose) {
Config.store();
SystemInfo.close();
panel.close();
dispose();
return;
}
}
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
panel.close();
Config.store();
dispose();
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
@Override
public void dispose() {
super.dispose();
if (Lab.getPlatform() == Imaging.Platform.STANDALONE)
System.exit(0);
}
@Override
public void componentResized(ComponentEvent e) {
panel.sizeModule();
}
@Override
public void componentMoved(ComponentEvent e) {
Point p = this.getLocation();
p.x += this.getWidth();
DeconvolutionDialog.setLocationLaunch(p);
}
@Override
public void componentShown(ComponentEvent e) {
panel.sizeModule();
}
@Override
public void componentHidden(ComponentEvent e) {
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/dialog/LabPanel.java b/DeconvolutionLab2/src/deconvolutionlab/LabPanel.java
similarity index 96%
rename from DeconvolutionLab2/src/deconvolutionlab/dialog/LabPanel.java
rename to DeconvolutionLab2/src/deconvolutionlab/LabPanel.java
index 7e31acf..0f76389 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/dialog/LabPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/LabPanel.java
@@ -1,300 +1,295 @@
/*
* 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;
+package deconvolutionlab;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import deconvolution.Command;
import deconvolution.Deconvolution;
import deconvolution.DeconvolutionDialog;
-import deconvolutionlab.Config;
-import deconvolutionlab.Lab;
+import deconvolutionlab.dialog.BatchDialog;
import deconvolutionlab.modules.AboutModule;
import deconvolutionlab.modules.AbstractModule;
import deconvolutionlab.modules.AlgorithmModule;
import deconvolutionlab.modules.BatchModule;
import deconvolutionlab.modules.BorderModule;
import deconvolutionlab.modules.CommandModule;
import deconvolutionlab.modules.ConfigModule;
import deconvolutionlab.modules.ControllerModule;
import deconvolutionlab.modules.FFTModule;
import deconvolutionlab.modules.GroupedModulePanel;
import deconvolutionlab.modules.ImageModule;
import deconvolutionlab.modules.LanguageModule;
import deconvolutionlab.modules.LicenceModule;
import deconvolutionlab.modules.OutputModule;
import deconvolutionlab.modules.PSFModule;
import deconvolutionlab.modules.RunningModule;
import deconvolutionlab.system.SystemInfo;
import lab.component.JPanelImage;
public class LabPanel extends JPanel implements ActionListener, ChangeListener {
private JTabbedPane tab = new JTabbedPane();
private JButton bnHelp = new JButton("Help");
private JButton bnQuit = new JButton("Quit");
private JButton bnSystem = new JButton("System");
private JButton bnBatch = new JButton("Batch");
private JButton bnRun = new JButton("Run");
private JButton bnLaunch = new JButton("Launch");
private JButton bnClose;
private ImageModule image;
private PSFModule psf;
private AlgorithmModule algo;
private AboutModule about;
private LicenceModule licence;
private OutputModule output;
private FFTModule fourier;
private BorderModule border;
private ConfigModule config;
private BatchModule batch;
private LanguageModule language;
private CommandModule command;
private RunningModule running;
private ControllerModule controller;
private GroupedModulePanel panelDeconv;
private GroupedModulePanel panelAdvanc;
private GroupedModulePanel panelScript;
private GroupedModulePanel panelAbout;
private AbstractModule modules[];
-
- private ArrayList<Deconvolution> deconvolutions = new ArrayList<Deconvolution>();
public LabPanel(JButton bnClose) {
this.bnClose = bnClose;
image = new ImageModule(false);
psf = new PSFModule(false);
algo = new AlgorithmModule(true);
output = new OutputModule(true);
fourier = new FFTModule(false);
border = new BorderModule(false);
controller = new ControllerModule(false);
batch = new BatchModule(false);
language = new LanguageModule(false);
about = new AboutModule(true);
licence = new LicenceModule(false);
config = new ConfigModule(false);
command = new CommandModule();
running = new RunningModule(false);
modules = new AbstractModule[] { image, psf, algo, output, controller, border, fourier, batch, running };
Command.active(modules, command);
Command.command();
panelDeconv = new GroupedModulePanel(buildDeconvolutionPanel(), this);
panelAdvanc = new GroupedModulePanel(buildAdvancedPanel(), this);
panelScript = new GroupedModulePanel(buildProgrammingPanel(), this);
panelAbout = new GroupedModulePanel(buildAboutPanel(), this);
Border border = BorderFactory.createEmptyBorder(5, 5, 5, 5);
JPanelImage bottom = new JPanelImage("celegans.jpg");
bottom.setBorder(border);
bottom.setLayout(new GridLayout(1, 6));
bottom.setBorder(border);
bottom.add(bnHelp);
bottom.add(bnSystem);
bottom.add(bnClose);
bottom.add(bnBatch);
bottom.add(bnRun);
bottom.add(bnLaunch);
tab.add("Deconvolution", panelDeconv);
tab.add("Advanced", panelAdvanc);
tab.add("Scripting", panelScript);
tab.add("About", panelAbout);
tab.addChangeListener(this);
setLayout(new BorderLayout());
add(tab, BorderLayout.CENTER);
add(bottom, BorderLayout.SOUTH);
bnBatch.addActionListener(this);
bnRun.addActionListener(this);
bnLaunch.addActionListener(this);
bnClose.addActionListener(this);
bnQuit.addActionListener(this);
bnHelp.addActionListener(this);
bnSystem.addActionListener(this);
((GroupedModulePanel) tab.getSelectedComponent()).organize();
setMinimumSize(new Dimension(500, 500));
Config.load();
running.init();
- sizeModule();
+ //sizeModule();
Command.command();
running.update();
image.update();
psf.update();
output.update();
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == bnHelp)
Lab.help();
else if (e.getSource() == bnClose)
Config.store();
else if (e.getSource() == bnSystem)
SystemInfo.activate();
else if (e.getSource() == bnBatch) {
tab.setSelectedIndex(2);
batch.expand();
sizeModule();
BatchDialog dlg = new BatchDialog(batch);
Lab.setVisible(dlg, true);
}
else if (e.getSource() == bnLaunch) {
String job = language.getJobName() + " " + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date());
Deconvolution d = new Deconvolution(job, Command.command(), Deconvolution.Finish.ALIVE);
d.launch();
- deconvolutions.add(d);
}
else if (e.getSource() == bnRun) {
String job = language.getJobName() + " " + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date());
Deconvolution d = new Deconvolution(job, Command.command());
d.deconvolve();
- deconvolutions.add(d);
+// deconvolutions.add(d);
}
}
@Override
public void stateChanged(ChangeEvent e) {
((GroupedModulePanel) tab.getSelectedComponent()).organize();
Command.command();
}
private ArrayList<AbstractModule> buildDeconvolutionPanel() {
ArrayList<AbstractModule> list = new ArrayList<AbstractModule>();
list.add(image);
list.add(psf);
list.add(algo);
list.add(running);
return list;
}
private ArrayList<AbstractModule> buildAdvancedPanel() {
ArrayList<AbstractModule> list = new ArrayList<AbstractModule>();
list.add(output);
list.add(controller);
list.add(border);
list.add(fourier);
return list;
}
private ArrayList<AbstractModule> buildProgrammingPanel() {
ArrayList<AbstractModule> list = new ArrayList<AbstractModule>();
list.add(batch);
list.add(command);
list.add(language);
return list;
}
private ArrayList<AbstractModule> buildAboutPanel() {
ArrayList<AbstractModule> list = new ArrayList<AbstractModule>();
list.add(about);
list.add(licence);
list.add(config);
return list;
}
public void close() {
for (AbstractModule module : modules)
module.close();
bnLaunch.removeActionListener(this);
bnRun.removeActionListener(this);
bnBatch.removeActionListener(this);
bnClose.removeActionListener(this);
bnHelp.removeActionListener(this);
- for(Deconvolution deconvolution : deconvolutions)
- deconvolution.close();
+ Lab.close();
}
public void sizeModule() {
if (tab.getSelectedIndex() == 0)
sizePanel(panelDeconv);
if (tab.getSelectedIndex() == 1)
sizePanel(panelAdvanc);
if (tab.getSelectedIndex() == 2)
sizePanel(panelScript);
if (tab.getSelectedIndex() == 3)
sizePanel(panelAbout);
}
private void sizePanel(GroupedModulePanel panel) {
Dimension dim = getSize();
int hpc = 60;
int npc = hpc * panel.getModules().size();
Dimension small = new Dimension(dim.width, hpc);
Dimension large = new Dimension(dim.width, dim.height - npc);
for (AbstractModule module : panel.getModules()) {
if (module.isExpanded()) {
module.setPreferredSize(large);
module.setMaximumSize(large);
module.setMinimumSize(small);
module.getExpandedPanel().setPreferredSize(large);
module.getExpandedPanel().setMaximumSize(large);
module.getExpandedPanel().setMinimumSize(small);
}
else {
module.setPreferredSize(small);
module.setMaximumSize(small);
module.setMinimumSize(small);
module.getCollapsedPanel().setPreferredSize(small);
module.getCollapsedPanel().setMaximumSize(small);
module.getCollapsedPanel().setMinimumSize(small);
}
}
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/TableStats.java b/DeconvolutionLab2/src/deconvolutionlab/TableStats.java
index e4d3114..b456ea7 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/TableStats.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/TableStats.java
@@ -1,93 +1,90 @@
package deconvolutionlab;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.io.File;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import deconvolutionlab.monitor.Monitors;
import lab.component.CustomizedColumn;
import lab.component.CustomizedTable;
public class TableStats {
private JPanel panel;
private CustomizedTable table;
private String name;
private boolean save;
private String path;
public TableStats(String name, int width, int height, String path, boolean save) {
this.name = name;
this.save = save;
this.path = path;
ArrayList<CustomizedColumn> columns = new ArrayList<CustomizedColumn>();
- columns.add(new CustomizedColumn("Name", String.class, 100, false));
- columns.add(new CustomizedColumn("Algorithm", String.class, 100, false));
columns.add(new CustomizedColumn("Iterations", String.class, 100, false));
columns.add(new CustomizedColumn("Mean", String.class, 100, false));
columns.add(new CustomizedColumn("Minimum", String.class, 100, false));
columns.add(new CustomizedColumn("Maximum", String.class, 100, false));
columns.add(new CustomizedColumn("Stdev", String.class, 100, false));
- columns.add(new CustomizedColumn("Norm1", String.class, 100, false));
- columns.add(new CustomizedColumn("Norm2", String.class, 100, false));
+ columns.add(new CustomizedColumn("Energy", String.class, 100, false));
columns.add(new CustomizedColumn("Time", String.class, 100, false));
columns.add(new CustomizedColumn("Memory", String.class, 100, false));
- columns.add(new CustomizedColumn("Peak", String.class, 100, false));
+ columns.add(new CustomizedColumn("Signal", String.class, 100, false));
columns.add(new CustomizedColumn("PSNR", String.class, 100, false));
columns.add(new CustomizedColumn("SNR", String.class, 100, false));
columns.add(new CustomizedColumn("Residu", String.class, 100, false));
table = new CustomizedTable(columns, true);
JScrollPane scroll = new JScrollPane(table);
scroll.setPreferredSize(new Dimension(width, height));
JPanel main = new JPanel(new BorderLayout());
main.add(scroll, BorderLayout.CENTER);
panel = new JPanel(new BorderLayout());
panel.add(main);
panel.setBorder(BorderFactory.createEtchedBorder());
}
public String getName() {
return name;
}
public void nextStats(Monitors monitors, String[] stats) {
if (table == null)
return;
if (stats == null)
return;
table.append(stats);
monitors.log("Stats ");
}
public void lastStats(Monitors monitors, String[] stats) {
if (stats == null)
return;
if (table == null)
return;
if (save) {
String filename = path + File.separator + name + ".csv";
monitors.log("Stats save " + filename);
table.saveCSV(filename);
}
}
public JPanel getPanel() {
return panel;
}
public void show() {
JFrame frame = new JFrame(name);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/modules/AlgorithmModule.java b/DeconvolutionLab2/src/deconvolutionlab/modules/AlgorithmModule.java
index 4cdc1f8..5269524 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/modules/AlgorithmModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/modules/AlgorithmModule.java
@@ -1,144 +1,153 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab.modules;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import deconvolution.Command;
+import deconvolution.Deconvolution;
+import deconvolution.DeconvolutionDialog;
import deconvolution.algorithm.AbstractAlgorithmPanel;
import deconvolution.algorithm.Algorithm;
import deconvolutionlab.Config;
+import deconvolutionlab.Lab;
import lab.component.HTMLPane;
public class AlgorithmModule extends AbstractModule implements ActionListener, ChangeListener {
private JComboBox<String> cmb;
private HTMLPane doc;
private JPanel cards;
public AlgorithmModule(boolean expanded) {
- super("Algorithm", "-algorithm", "", "", 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.getShortname() + " " + algo.getCommand();
+ String cmd = "-algorithm " + algo.getShortname()[0] + " " + algo.getCommand();
String synopsis = name;
setSynopsis(synopsis);
setCommand(cmd);
return cmd;
}
@Override
public JPanel buildExpandedPanel() {
cmb = new JComboBox<String>();
JPanel pnc = new JPanel();
pnc.add(cmb);
doc = new HTMLPane(100, 1000);
cards = new JPanel(new CardLayout());
ArrayList<AbstractAlgorithmPanel> panels = Algorithm.getAvailableAlgorithms();
for (AbstractAlgorithmPanel panel : panels) {
JScrollPane scroll = new JScrollPane(panel.getPanelParameters());
scroll.setBorder(BorderFactory.createEmptyBorder());
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
cards.add(panel.getName(), scroll);
}
cmb.setMaximumRowCount(panels.size());
JPanel control = new JPanel();
control.setLayout(new BoxLayout(control, BoxLayout.PAGE_AXIS));
Border b1 = BorderFactory.createEtchedBorder();
Border b2 = BorderFactory.createEmptyBorder(10, 10, 10, 10);
control.setBorder(BorderFactory.createCompoundBorder(b1, b2));
control.add(cmb);
control.add(cards);
doc.append("h1", "Documentation");
JPanel panel = new JPanel(new BorderLayout());
panel.add(control, BorderLayout.NORTH);
panel.add(doc.getPane(), BorderLayout.CENTER);
// cmb.addActionListener(this);
-
+ getAction2Button().setToolTipText("Human readable of the command line");
+ getAction2Button().addActionListener(this);
Config.register(getName(), "algorithm", cmb, Algorithm.getDefaultAlgorithm());
panel.setBorder(BorderFactory.createEtchedBorder());
return panel;
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
if (e.getSource() == cmb) {
doc.clear();
String name = (String) cmb.getSelectedItem();
AbstractAlgorithmPanel algo = Algorithm.getPanel(name);
doc.append(algo.getDocumentation());
CardLayout cl = (CardLayout) (cards.getLayout());
cl.show(cards, name);
}
+ if (e.getSource() == getAction2Button()) {
+ Deconvolution deconvolution = new Deconvolution("Check Algorithm", Command.command());
+ DeconvolutionDialog d = new DeconvolutionDialog(DeconvolutionDialog.Module.ALGO, deconvolution, null, null);
+ Lab.setVisible(d, false);
+ }
setSynopsis((String) cmb.getSelectedItem());
setCommand(getCommand());
Command.command();
}
-
+
@Override
public void stateChanged(ChangeEvent e) {
setSynopsis((String) cmb.getSelectedItem());
setCommand(getCommand());
Command.command();
}
@Override
public void close() {
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/modules/BatchModule.java b/DeconvolutionLab2/src/deconvolutionlab/modules/BatchModule.java
index 60af627..4bf64ae 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/modules/BatchModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/modules/BatchModule.java
@@ -1,189 +1,169 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab.modules;
import java.awt.BorderLayout;
import java.awt.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 javax.swing.ListSelectionModel;
import deconvolution.Deconvolution;
import deconvolutionlab.Constants;
import lab.component.CustomizedColumn;
import lab.component.CustomizedTable;
public class BatchModule extends AbstractModule implements MouseListener, ActionListener {
private CustomizedTable table;
- private JButton bnScript;
- private JButton bnRunAll;
- private JButton bnRunJob;
- private JButton bnLaunchAll;
- private JButton bnLaunchJob;
+ private JButton bnRun;
+ private JButton bnLaunch;
public BatchModule(boolean expanded) {
super("Batch", "", "", "", expanded);
}
@Override
public String getCommand() {
return "";
}
@Override
public JPanel buildExpandedPanel() {
- bnScript = new JButton("Create Script (not yet implemented)");
- bnRunAll = new JButton("Run All Jobs");
- bnRunJob = new JButton("Run Selected Jobs");
- bnLaunchAll = new JButton("Launch All Jobs");
- bnLaunchJob = new JButton("Launch Selected Jobs");
+ bnRun = new JButton("Run Jobs");
+ bnLaunch = new JButton("Launch Jobs");
ArrayList<CustomizedColumn> columns = new ArrayList<CustomizedColumn>();
columns.add(new CustomizedColumn("Job", String.class, 120, false));
columns.add(new CustomizedColumn("Command", String.class, Constants.widthGUI, false));
columns.add(new CustomizedColumn("", String.class, 30, "\u232B", "Delete this job"));
table = new CustomizedTable(columns, true);
table.getColumnModel().getColumn(2).setMaxWidth(30);
table.getColumnModel().getColumn(2).setMinWidth(30);
table.addMouseListener(this);
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
JToolBar pn = new JToolBar("Controls Batch");
pn.setBorder(BorderFactory.createEmptyBorder());
- pn.setLayout(new GridLayout(1, 5));
+ pn.setLayout(new GridLayout(1, 2));
pn.setFloatable(false);
- pn.add(bnScript);
- pn.add(bnRunAll);
- pn.add(bnRunJob);
- pn.add(bnLaunchAll);
- pn.add(bnLaunchJob);
+ pn.add(bnRun);
+ pn.add(bnLaunch);
JPanel panel = new JPanel(new BorderLayout());
panel.add(table.getPane(100, 100), BorderLayout.CENTER);
panel.add(pn, BorderLayout.SOUTH);
getAction1Button().addActionListener(this);
- bnScript.addActionListener(this);
- bnRunAll.addActionListener(this);
- bnRunJob.addActionListener(this);
- bnLaunchAll.addActionListener(this);
- bnLaunchJob.addActionListener(this);
+ bnRun.addActionListener(this);
+ bnLaunch.addActionListener(this);
return panel;
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
- if (e.getSource() == bnRunJob) {
+ if (e.getSource() == bnRun) {
+ if (table.getSelectedRows().length == 0)
+ table.setColumnSelectionInterval(0, table.getRowCount());
int rows[] = table.getSelectedRows();
- for (int row : rows) {
+ for (int row : rows)
new Deconvolution("Batch" + table.getCell(row, 0), table.getCell(row, 1)).deconvolve();
- }
}
- else if (e.getSource() == bnLaunchJob) {
+ else if (e.getSource() == bnLaunch) {
+ if (table.getSelectedRows().length == 0)
+ table.setColumnSelectionInterval(0, table.getRowCount());
int rows[] = table.getSelectedRows();
- for (int row : rows) {
+ for (int row : rows)
new Deconvolution("Batch " + table.getCell(row, 0), table.getCell(row, 1)).launch();
- }
- }
- else if (e.getSource() == bnRunAll) {
- for (int row = 0; row < table.getRowCount(); row++) {
- new Deconvolution("Batch " + table.getCell(row, 0), table.getCell(row, 1)).deconvolve();
- }
- }
- else if (e.getSource() == bnLaunchAll) {
- for (int row = 0; row < table.getRowCount(); row++) {
- new Deconvolution("Batch " + table.getCell(row, 0), table.getCell(row, 1)).launch();
- }
}
}
private void update() {
setSynopsis("" + table.getRowCount() + " jobs");
}
public int getCountJob() {
return table.getRowCount();
}
public void addJob(String name, String command) {
table.append(new String[] { name, command, "" });
update();
}
@Override
public void mouseClicked(MouseEvent e) {
if (e.getSource() == table) {
int row = table.getSelectedRow();
if (row < 0)
return;
if (table.getSelectedColumn() == 2) {
table.removeRow(row);
if (table.getRowCount() > 0)
table.setRowSelectionInterval(0, 0);
}
}
update();
}
@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() {
getAction1Button().removeActionListener(this);
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/modules/CommandModule.java b/DeconvolutionLab2/src/deconvolutionlab/modules/CommandModule.java
index 4c51ec4..d242449 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/modules/CommandModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/modules/CommandModule.java
@@ -1,76 +1,100 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab.modules;
import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.io.File;
+import java.util.ArrayList;
import javax.swing.JPanel;
+import deconvolution.Command;
+import deconvolution.Deconvolution;
+import deconvolution.DeconvolutionDialog;
+import deconvolutionlab.Lab;
+import deconvolutionlab.dialog.PatternDialog;
+import deconvolutionlab.dialog.SyntheticDialog;
+import deconvolutionlab.monitor.Monitors;
import lab.component.HTMLPane;
+import lab.tools.Files;
+import signal.RealSignal;
+import signal.factory.SignalFactory;
public class CommandModule extends AbstractModule {
private HTMLPane window;
public CommandModule() {
- super("Command", "", "", "", true);
+ super("Command", "", "", "Check", true);
}
public HTMLPane getPane() {
return window;
}
@Override
public JPanel buildExpandedPanel() {
window = new HTMLPane("Monaco", 100, 100);
JPanel panel = new JPanel(new BorderLayout());
panel.add(window.getPane(), BorderLayout.CENTER);
+ getAction2Button().setToolTipText("Human readable of the command line");
+ getAction2Button().addActionListener(this);
return panel;
}
-
-
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ if (e.getSource() == getAction2Button()) {
+ Deconvolution deconvolution = new Deconvolution("Check Command", Command.command());
+ DeconvolutionDialog d = new DeconvolutionDialog(DeconvolutionDialog.Module.RECAP, deconvolution, null, null);
+ Lab.setVisible(d, false);
+ }
+ }
+
@Override
public void close() {
}
@Override
public void setCommand(String command) {
window.clear();
window.append("p", command);
}
@Override
public String getCommand() {
return "";
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/modules/GroupedModulePanel.java b/DeconvolutionLab2/src/deconvolutionlab/modules/GroupedModulePanel.java
index 7a9d389..8fec2b5 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/modules/GroupedModulePanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/modules/GroupedModulePanel.java
@@ -1,102 +1,102 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab.modules;
import java.awt.Dimension;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JPanel;
-import deconvolutionlab.dialog.LabPanel;
+import deconvolutionlab.LabPanel;
public class GroupedModulePanel extends JPanel {
private ArrayList<AbstractModule> modules;
private LabPanel parent;
private Dimension min;
public GroupedModulePanel(ArrayList<AbstractModule> modules, LabPanel parent) {
this.modules = modules;
this.parent = parent;
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
int minWidth = 0;
int minHeight = 0;
for (AbstractModule mpn : modules) {
mpn.setMultipleModulePanel(this);
add(mpn);
Dimension dim = mpn.getCollapsedPanel().getPreferredSize();
minWidth = Math.max(minWidth, dim.width);
minHeight += dim.height;
}
min = new Dimension(minWidth, minHeight);
}
public Dimension getMinimumSize() {
return min;
}
public void organize() {
parent.sizeModule();
}
public ArrayList<AbstractModule> getModules() {
return modules;
}
public Dimension getVisibleSize(Dimension goal) {
int height = 0;
for (AbstractModule mpn : modules) {
height += mpn.getPreferredSize().height;
}
if (height > goal.height) {
return new Dimension(goal.width, height);
}
else {
ArrayList<AbstractModule> visibles = new ArrayList<AbstractModule>();
for (AbstractModule mpn : modules) {
if (mpn.isExpanded())
visibles.add(mpn);
}
if (visibles.size() > 0) {
int supp = (goal.height - height) / visibles.size();
for (AbstractModule mpn : modules) {
Dimension dim = mpn.getPreferredSize();
mpn.setPreferredSize(new Dimension(dim.width, dim.height + supp));
}
}
return new Dimension(goal.width, goal.height);
}
}
}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/deconvolutionlab/modules/ImageModule.java b/DeconvolutionLab2/src/deconvolutionlab/modules/ImageModule.java
index 388f51b..b999140 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/modules/ImageModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/modules/ImageModule.java
@@ -1,351 +1,353 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab.modules;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import deconvolution.Command;
import deconvolution.Deconvolution;
+import deconvolution.DeconvolutionDialog;
import deconvolution.modules.ImageDModule;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
import deconvolutionlab.Imaging;
import deconvolutionlab.Lab;
import deconvolutionlab.dialog.PatternDialog;
import deconvolutionlab.dialog.SyntheticDialog;
import deconvolutionlab.monitor.Monitors;
import lab.component.CustomizedColumn;
import lab.component.CustomizedTable;
import lab.tools.Files;
import signal.RealSignal;
import signal.factory.SignalFactory;
public class ImageModule extends AbstractModule implements ActionListener, MouseListener {
private CustomizedTable table;
private JButton bnFile;
private JButton bnDirectory;
private JButton bnSynthetic;
private JButton bnPlatform;
public ImageModule(boolean expanded) {
super("Image", "-image", (Lab.getPlatform() == Imaging.Platform.IMAGEJ ? "Active" : ""), "Check", expanded);
}
@Override
public String getCommand() {
int row = table.getSelectedRow();
if (row < 0)
return "";
return "-image " + table.getCell(row, 1) + " " + table.getCell(row, 2);
}
@Override
public JPanel buildExpandedPanel() {
ArrayList<CustomizedColumn> columns = new ArrayList<CustomizedColumn>();
columns.add(new CustomizedColumn("Name", String.class, 100, false));
columns.add(new CustomizedColumn("Source", String.class, 100, false));
columns.add(new CustomizedColumn("Command", String.class, Constants.widthGUI - 200, true));
columns.add(new CustomizedColumn("", String.class, 30, "\u232B", "Delete this image source"));
table = new CustomizedTable(columns, true);
table.getColumnModel().getColumn(3).setMaxWidth(30);
table.getColumnModel().getColumn(3).setMinWidth(30);
table.addMouseListener(this);
bnFile = new JButton("\u2295 file");
bnDirectory = new JButton("\u2295 directory");
bnSynthetic = new JButton("\u2295 synthetic");
bnPlatform = new JButton("\u2295 platform");
JToolBar pn = new JToolBar("Controls Image");
pn.setBorder(BorderFactory.createEmptyBorder());
pn.setLayout(new GridLayout(1, 4));
pn.setFloatable(false);
pn.add(bnFile);
pn.add(bnDirectory);
pn.add(bnSynthetic);
if (Lab.getPlatform() == Imaging.Platform.IMAGEJ)
pn.add(bnPlatform);
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createEtchedBorder());
panel.setLayout(new BorderLayout());
panel.add(pn, BorderLayout.SOUTH);
panel.add(table.getMinimumPane(100, 100), BorderLayout.CENTER);
table.setDropTarget(new LocalDropTarget());
getCollapsedPanel().setDropTarget(new LocalDropTarget());
bnFile.addActionListener(this);
bnDirectory.addActionListener(this);
bnSynthetic.addActionListener(this);
bnPlatform.addActionListener(this);
getAction1Button().addActionListener(this);
getAction2Button().addActionListener(this);
getAction2Button().setToolTipText("Click to have a preview, Shift-click or Ctrl-click to show the complete stack");
getAction1Button().setToolTipText("Select the active window");
Config.registerTable(getName(), "image", table);
return panel;
}
public void update() {
int row = table.getSelectedRow();
if (row >= 0) {
setCommand(getCommand());
setSynopsis(table.getCell(row, 0));
Command.command();
}
else {
setSynopsis("");
setCommand("Drag your image file, here");
}
getAction2Button().setEnabled(table.getRowCount() > 0);
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
if (e.getSource() == bnFile)
file(Command.getPath());
else if (e.getSource() == bnDirectory)
dir(Command.getPath());
else if (e.getSource() == bnSynthetic)
synthetic(false);
else if (e.getSource() == bnPlatform)
platform();
else if (e.getSource() == getAction1Button()) {
int row = -1;
for(int i=0; i<table.getRowCount(); i++) {
if (table.getCell(i, 0).equalsIgnoreCase("active"))
if (table.getCell(i, 1).equalsIgnoreCase("platform"))
if (table.getCell(i, 2).equalsIgnoreCase("active"))
row = i;
}
if (row < 0)
table.insert(new String[] { "active", "platform", "active", "\u232B" });
else
table.setRowSelectionInterval(row, row);
}
else if (e.getSource() == getAction2Button()) {
boolean s = (e.getModifiers() & ActionEvent.SHIFT_MASK) == ActionEvent.SHIFT_MASK;
boolean c = (e.getModifiers() & ActionEvent.CTRL_MASK) == ActionEvent.CTRL_MASK;
display(s | c);
}
update();
}
public void platform() {
String name = Lab.getActiveImage();
if (name != "")
table.insert(new String[] { name, "platform", name, "\u232B" });
}
private void file(String path) {
File file = Files.browseFile(path);
if (file == null)
return;
table.insert(new String[] { file.getName(), "file", file.getAbsolutePath(), "\u232B" });
}
private void dir(String path) {
File file = Files.browseDirectory(path);
if (file == null)
return;
PatternDialog dlg = new PatternDialog(file);
Lab.setVisible(dlg, true);
if (dlg.wasCancel())
return;
table.insert(new String[] { dlg.getDirName(), "directory", dlg.getCommand(), "\u232B" });
}
private void synthetic(boolean edit) {
ArrayList<SignalFactory> list = SignalFactory.getImages();
SyntheticDialog dlg = new SyntheticDialog(list);
if (edit) {
int row = table.getSelectedRow();
if (row >= 0) {
dlg.setParameters(table.getCell(row, 0), table.getCell(row, 1));
}
}
Lab.setVisible(dlg, true);
if (dlg.wasCancel())
return;
if (edit) {
int row = table.getSelectedRow();
if (row <= 0)
table.removeRow(row);
}
table.insert(new String[] { dlg.getShapeName(), "synthetic", dlg.getCommand(), "\u232B" });
}
private void edit() {
int row = table.getSelectedRow();
if (row < 0)
return;
String name = table.getCell(row, 0).trim();
for (SignalFactory factory : SignalFactory.getAll()) {
if (name.equals(factory.getName().trim()))
synthetic(true);
return;
}
String filename = table.getCell(row, 1).trim();
File file = new File(filename);
if (!file.exists())
return;
if (file.isFile())
file(table.getCell(row, 21));
else
dir(table.getCell(row, 1));
}
private void display(boolean stack) {
int row = table.getSelectedRow();
if (row < 0)
return;
- Deconvolution deconvolution = new Deconvolution("ShowImage", getCommand());
+ Deconvolution deconvolution = new Deconvolution("Check Image", Command.command());
if (stack) {
RealSignal x = deconvolution.openImage();
if (x != null)
Lab.show(Monitors.createDefaultMonitor(), x, table.getCell(row, 0));
}
else {
- new ImageDModule(deconvolution).show(table.getCell(row, 0));
+ DeconvolutionDialog d = new DeconvolutionDialog(DeconvolutionDialog.Module.IMAGE, deconvolution, null, null);
+ Lab.setVisible(d, false);
}
}
@Override
public void mouseClicked(MouseEvent e) {
if (e.getSource() == table) {
int row = table.getSelectedRow();
if (row < 0)
return;
if (table.getSelectedColumn() == 3) {
table.removeRow(row);
if (table.getRowCount() > 0)
table.setRowSelectionInterval(0, 0);
}
update();
if (e.getClickCount() == 2) {
edit();
}
}
}
@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() {
bnFile.removeActionListener(this);
bnDirectory.removeActionListener(this);
bnSynthetic.removeActionListener(this);
bnPlatform.removeActionListener(this);
}
public class LocalDropTarget extends DropTarget {
@Override
public void drop(DropTargetDropEvent e) {
e.acceptDrop(DnDConstants.ACTION_COPY);
e.getTransferable().getTransferDataFlavors();
Transferable transferable = e.getTransferable();
DataFlavor[] flavors = transferable.getTransferDataFlavors();
for (DataFlavor flavor : flavors) {
if (flavor.isFlavorJavaFileListType()) {
try {
List<File> files = (List<File>) transferable.getTransferData(flavor);
for (File file : files) {
if (file.isDirectory()) {
table.insert(new String[] { file.getName(), "directory", file.getAbsolutePath(), "" });
table.setRowSelectionInterval(0, 0);
update();
}
if (file.isFile()) {
table.insert(new String[] { file.getName(), "file", file.getAbsolutePath(), "" });
update();
}
}
}
catch (UnsupportedFlavorException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}
e.dropComplete(true);
super.drop(e);
}
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/modules/LanguageModule.java b/DeconvolutionLab2/src/deconvolutionlab/modules/LanguageModule.java
index 04c1cd4..7951826 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/modules/LanguageModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/modules/LanguageModule.java
@@ -1,253 +1,251 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab.modules;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JTextField;
import deconvolution.Command;
import deconvolution.Deconvolution;
import deconvolution.Token;
import deconvolution.algorithm.AbstractAlgorithm;
import deconvolutionlab.Config;
import lab.component.HTMLPane;
public class LanguageModule extends AbstractModule implements ActionListener {
private HTMLPane language;
private JComboBox<String> cmb;
private JComboBox<String> gui;
private JTextField txt;
public LanguageModule(boolean expanded) {
super("Language", "", "", "", expanded);
}
public String getJobName() {
if (txt != null)
return txt.getText();
return "";
}
@Override
public JPanel buildExpandedPanel() {
language = new HTMLPane("Monaco", 100, 100);
cmb = new JComboBox<String>(new String[] { "Command line", "ImageJ Macro", "Java", "Matlab" });
gui = new JComboBox<String>(new String[] { "Run (Headless)", "Launch (with control panel)" });
txt = new JTextField("Job", 8);
JPanel pn = new JPanel(new BorderLayout());
pn.add(cmb, BorderLayout.WEST);
pn.add(txt, BorderLayout.CENTER);
pn.add(gui, BorderLayout.EAST);
JPanel panel = new JPanel(new BorderLayout());
panel.add(pn, BorderLayout.NORTH);
panel.add(language.getPane(), BorderLayout.CENTER);
cmb.addActionListener(this);
gui.addActionListener(this);
Config.register(getName(), "language", cmb, cmb.getItemAt(0));
Config.register(getName(), "headless", gui, gui.getItemAt(0));
Config.register(getName(), "job", txt, "Job");
language.clear();
return panel;
}
@Override
public void expand() {
super.expand();
update();
}
public void update() {
if (cmb.getSelectedIndex() == 0) {
language.clear();
String run = gui.getSelectedIndex() == 0 ? " Run " : " Launch ";
language.append("p", "java -jar DeconvolutionLab_2.jar " + run + Command.command());
language.append("p", "");
language.append("p", "java -cp JTransforms.jar:DeconvolutionLab_2.jar DeconvolutionLab2 "+ run + Command.command());
}
else if (cmb.getSelectedIndex() == 1) {
language.clear();
language.append("p", imagej(gui.getSelectedIndex() == 0));
}
else if (cmb.getSelectedIndex() == 2) {
language.clear();
language.append("p", java(gui.getSelectedIndex() == 0));
}
else if (cmb.getSelectedIndex() == 3) {
language.clear();
language.append("p", matlab());
}
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
if (e.getSource() == cmb)
update();
if (e.getSource() == gui)
update();
}
@Override
public void close() {
}
@Override
public void setCommand(String command) {
update();
}
@Override
public String getCommand() {
return "";
}
private String matlab() {
String job = txt.getText();
String script = "";
String cmd = Command.command();
Deconvolution d = new Deconvolution("Matlab", cmd);
String options = Command.extractOptions(cmd);
AbstractAlgorithm algo = d.getAlgo();
if (algo == null)
return "ERROR";
String s = algo.getShortname();
- if (s.equalsIgnoreCase("lw+"))
- s = "NNLW";
String param = algo.getParametersAsString();
script += p("% this function returns the deconvolved image as an 3D matrix");
script += p("% image is a 3D matrix containing the image");
script += p("% psf is a 3D matrix containing the PSF");
script += p("function result = " + job + "(image, psf)");
script += p1("% Install first DeconvolutionLab_2.jar into the java directory of Matlab");
script += p1("javaaddpath([matlabroot filesep 'java' filesep 'DeconvolutionLab_2.jar'])");
script += p1("% Run the deconvolution\n");
script += p1("result = DL2." + s + "(image, psf, " + param +" , '" + options +"');");
script += p("end");
return script;
}
private String imagej(boolean headless) {
String job = txt.getText();
String macro = p("// Job: " + job + " ");
macro += p("// Macro generated by DeconvolutionLab2 ");
macro += p("// " + new SimpleDateFormat("dd/MM/yy HH:m:s").format(new Date()) + " ");
String param = p("parameters = \"\" ");
ArrayList<Token> tokens = Command.parse(Command.command());
String image = "image = \" NOT DEFINED \" ";
String psf = "psf = \" NOT DEFINED \" ";
String algo = "algo = \" NOT DEFINED \" ";
for (Token token : tokens) {
if (token.keyword.equals("-image"))
image = p("image = \" -image " + token.parameters.trim() + "\" ");
else if (token.keyword.equals("-psf"))
psf = p("psf = \" -psf " + token.parameters.trim() + "\" ");
else if (token.keyword.equals("-algorithm"))
algo = p("algorithm = \" -algorithm " + token.parameters.trim() + "\" ");
else
param += p("parameters += \" " + token.keyword + " " + token.parameters.trim() + "\"");
}
String option = macro + image + psf + algo + param;
String cmd = "";
if (headless)
cmd = p("run(\"DeconvolutionLab2 Run\", image + psf + algorithm + parameters)");
else
cmd = p("run(\"DeconvolutionLab2 Launch\", image + psf + algorithm + parameters)");
return option + cmd;
}
private String java(boolean headless) {
String job = txt.getText();
String code = "";
code += p("import deconvolution.Deconvolution;");
code += p("import ij.plugin.PlugIn;");
code += p("");
code += p("public class DeconvolutionLab2_" + job + " implements PlugIn {");
code += p1("public DeconvolutionLab2_" + job + "() {");
String param = p2("String parameters = \"\";");
ArrayList<Token> tokens = Command.parse(Command.command());
String image = p2("String image = \" NOT DEFINED \";");
String psf = p2("String psf = \" NOT DEFINED \";");
String algo = p2("String algo = \" NOT DEFINED \";");
for (Token token : tokens) {
if (token.keyword.equals("-image"))
image = p2("String image = \" -image " + token.parameters.trim() + "\";");
else if (token.keyword.equals("-psf"))
psf = p2("String psf = \" -psf " + token.parameters.trim() + "\";");
else if (token.keyword.equals("-algorithm"))
algo = p2("String algorithm = \" -algorithm " + token.parameters.trim() + "\";");
else
param += p2("parameters += \" " + token.keyword + " " + token.parameters.trim() + "\";");
}
code += image + psf + algo + param;
code += p2("new Deconvolution(image + psf + algorithm + parameters)");
code += p1("}");
code += p1("");
code += p1("@Override");
code += p1("public void run(String arg0) {");
code += p2(" new DeconvolutionLab2_" + job + "();");
code += p1("}");
code += p("}");
return code;
}
private String p(String content) {
return "<p>" + content + "</p>";
}
private String p1(String content) {
return "<p style=\"padding-left:10px\">" + content + "</p>";
}
private String p2(String content) {
return "<p style=\"padding-left:20px\">" + content + "</p>";
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/modules/PSFModule.java b/DeconvolutionLab2/src/deconvolutionlab/modules/PSFModule.java
index efea6f0..ec01136 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/modules/PSFModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/modules/PSFModule.java
@@ -1,338 +1,340 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab.modules;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import deconvolution.Command;
import deconvolution.Deconvolution;
+import deconvolution.DeconvolutionDialog;
import deconvolution.modules.PSFDModule;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
import deconvolutionlab.Imaging;
import deconvolutionlab.Lab;
import deconvolutionlab.dialog.PatternDialog;
import deconvolutionlab.dialog.SyntheticDialog;
import deconvolutionlab.monitor.Monitors;
import lab.component.CustomizedColumn;
import lab.component.CustomizedTable;
import lab.tools.Files;
import signal.RealSignal;
import signal.factory.SignalFactory;
public class PSFModule extends AbstractModule implements ActionListener, MouseListener {
private CustomizedTable table;
private JButton bnFile;
private JButton bnDirectory;
private JButton bnSynthetic;
private JButton bnPlatform;
public PSFModule(boolean expanded) {
super("PSF", "-psf", "", "Check", expanded);
}
@Override
public String getCommand() {
int row = table.getSelectedRow();
if (row < 0)
return "";
return "-psf " + table.getCell(row, 1) + " " + table.getCell(row, 2);
}
@Override
public JPanel buildExpandedPanel() {
ArrayList<CustomizedColumn> columns = new ArrayList<CustomizedColumn>();
columns.add(new CustomizedColumn("Name", String.class, 100, false));
columns.add(new CustomizedColumn("Source", String.class, 100, false));
columns.add(new CustomizedColumn("Command", String.class, Constants.widthGUI - 200, true));
columns.add(new CustomizedColumn("", String.class, 30, "\u232B", "Delete this PSF source"));
table = new CustomizedTable(columns, true);
table.getColumnModel().getColumn(3).setMaxWidth(30);
table.getColumnModel().getColumn(3).setMinWidth(30);
table.addMouseListener(this);
bnFile = new JButton("\u2295 file");
bnDirectory = new JButton("\u2295 directory");
bnSynthetic = new JButton("\u2295 synthetic");
bnPlatform = new JButton("\u2295 platform");
JToolBar pn = new JToolBar("Controls PSF");
pn.setBorder(BorderFactory.createEmptyBorder());
pn.setLayout(new GridLayout(1, 5));
pn.setFloatable(false);
pn.add(bnFile);
pn.add(bnDirectory);
pn.add(bnSynthetic);
pn.add(bnPlatform);
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createEtchedBorder());
panel.setLayout(new BorderLayout());
panel.add(pn, BorderLayout.SOUTH);
panel.add(table.getMinimumPane(100, 100), BorderLayout.CENTER);
table.setDropTarget(new LocalDropTarget());
getCollapsedPanel().setDropTarget(new LocalDropTarget());
bnFile.addActionListener(this);
bnDirectory.addActionListener(this);
bnSynthetic.addActionListener(this);
if (Lab.getPlatform() == Imaging.Platform.IMAGEJ)
bnPlatform.addActionListener(this);
getAction1Button().addActionListener(this);
getAction2Button().addActionListener(this);
getAction2Button().setToolTipText("Click to have a preview, Shift-click or Ctrl-click to show the complete stack");
getAction1Button().setToolTipText("Select the active window");
Config.registerTable(getName(), "psf", table);
return panel;
}
public void update() {
int row = table.getSelectedRow();
if (row >= 0) {
setCommand(getCommand());
setSynopsis(table.getCell(row, 0));
Command.command();
}
else {
setSynopsis("");
setCommand("Drag your image file, here");
}
getAction2Button().setEnabled(table.getRowCount() > 0);
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
if (e.getSource() == bnFile)
file(Command.getPath());
else if (e.getSource() == bnDirectory)
dir(Command.getPath());
else if (e.getSource() == bnSynthetic)
synthetic(false);
else if (e.getSource() == bnPlatform)
platform();
else if (e.getSource() == getAction1Button())
platform();
else if (e.getSource() == getAction2Button()) {
boolean s = (e.getModifiers() & ActionEvent.SHIFT_MASK) == ActionEvent.SHIFT_MASK;
boolean c = (e.getModifiers() & ActionEvent.CTRL_MASK) == ActionEvent.CTRL_MASK;
display(s | c);
}
update();
}
public void platform() {
String name = Lab.getActiveImage();
if (name != "")
table.insert(new String[] {name, "platform", name, "\u232B" });
}
private void file(String path) {
File file = Files.browseFile(path);
if (file == null)
return;
table.insert(new String[] { file.getName(), "file", file.getAbsolutePath(), "\u232B" });
}
private void dir(String path) {
File file = Files.browseDirectory(path);
if (file == null)
return;
PatternDialog dlg = new PatternDialog(file);
Lab.setVisible(dlg, true);
if (dlg.wasCancel())
return;
table.insert(new String[] { dlg.getDirName(), "directory", dlg.getCommand(), "\u232B" });
}
private void synthetic(boolean edit) {
ArrayList<SignalFactory> list = SignalFactory.getPSF();
SyntheticDialog dlg = new SyntheticDialog(list);
if (edit) {
int row = table.getSelectedRow();
if (row >= 0) {
dlg.setParameters(table.getCell(row, 0), table.getCell(row, 1));
}
}
Lab.setVisible(dlg, true);
if (dlg.wasCancel())
return;
if (edit) {
int row = table.getSelectedRow();
if (row <= 0)
table.removeRow(row);
}
table.insert(new String[] { dlg.getShapeName(), "synthetic", dlg.getCommand(), "" });
}
private void edit() {
int row = table.getSelectedRow();
if (row < 0)
return;
String name = table.getCell(row, 0).trim();
for(SignalFactory factory : SignalFactory.getAll()) {
if (name.equals(factory.getName().trim()))
synthetic(true);
return;
}
String filename = table.getCell(row, 1).trim();
File file = new File(filename);
if (!file.exists())
return;
if (file.isFile())
file(table.getCell(row, 21));
else
dir(table.getCell(row, 1));
}
private void display(boolean stack) {
int row = table.getSelectedRow();
if (row < 0)
return;
- Deconvolution deconvolution = new Deconvolution("ShowPSF", getCommand());
+ Deconvolution deconvolution = new Deconvolution("Check PSF", Command.command());
if (stack) {
RealSignal x = deconvolution.openPSF();
if (x != null)
Lab.show(Monitors.createDefaultMonitor(), x, table.getCell(row, 0));
}
else {
- new PSFDModule(deconvolution).show(table.getCell(row, 0));
+ DeconvolutionDialog d = new DeconvolutionDialog(DeconvolutionDialog.Module.PSF, deconvolution, null, null);
+ Lab.setVisible(d, false);
}
}
@Override
public void mouseClicked(MouseEvent e) {
if (e.getSource() == table) {
int row = table.getSelectedRow();
if (row < 0)
return;
if (table.getSelectedColumn() == 3) {
table.removeRow(row);
if (table.getRowCount() > 0)
table.setRowSelectionInterval(0, 0);
}
update();
if (e.getClickCount() == 2) {
edit();
}
}
}
@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() {
bnFile.removeActionListener(this);
bnDirectory.removeActionListener(this);
bnSynthetic.removeActionListener(this);
bnPlatform.removeActionListener(this);
}
public class LocalDropTarget extends DropTarget {
@Override
public void drop(DropTargetDropEvent e) {
e.acceptDrop(DnDConstants.ACTION_COPY);
e.getTransferable().getTransferDataFlavors();
Transferable transferable = e.getTransferable();
DataFlavor[] flavors = transferable.getTransferDataFlavors();
for (DataFlavor flavor : flavors) {
if (flavor.isFlavorJavaFileListType()) {
try {
List<File> files = (List<File>) transferable.getTransferData(flavor);
for (File file : files) {
if (file.isDirectory()) {
table.insert(new String[] { file.getName(), "directory", file.getAbsolutePath(), "" });
table.setRowSelectionInterval(0, 0);
update();
}
if (file.isFile()) {
table.insert(new String[] { file.getName(), "file", file.getAbsolutePath(), "" });
update();
}
}
}
catch (UnsupportedFlavorException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}
e.dropComplete(true);
super.drop(e);
}
}
}
diff --git a/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/DeconvolutionLabIcyFrame.java b/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/DeconvolutionLabIcyFrame.java
index 277e4f8..2ba5c95 100644
--- a/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/DeconvolutionLabIcyFrame.java
+++ b/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/DeconvolutionLabIcyFrame.java
@@ -1,111 +1,111 @@
package plugins.sage.deconvolutionlab;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import javax.swing.JButton;
import deconvolution.DeconvolutionDialog;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
-import deconvolutionlab.dialog.LabPanel;
+import deconvolutionlab.LabPanel;
import icy.gui.frame.IcyFrame;
import icy.gui.frame.IcyFrameEvent;
import icy.gui.frame.IcyFrameListener;
public class DeconvolutionLabIcyFrame extends IcyFrame implements ComponentListener, IcyFrameListener, ActionListener {
private LabPanel panel = null;
private JButton bnClose = new JButton("Close");
public DeconvolutionLabIcyFrame() {
super(Constants.name);
panel = new LabPanel(bnClose);
getContentPane().add(panel);
pack();
addFrameListener(this);
toFront();
addToDesktopPane();
setVisible(true);
setResizable(true);
bnClose.addActionListener(this);
addComponentListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == bnClose) {
panel.close();
dispose();
return;
}
}
@Override
public void icyFrameOpened(IcyFrameEvent e) {
System.out.println("not yet implemented " + e);
}
@Override
public void icyFrameClosing(IcyFrameEvent e) {
panel.close();
Config.store();
dispose();
}
@Override
public void icyFrameClosed(IcyFrameEvent e) {
}
@Override
public void icyFrameIconified(IcyFrameEvent e) {
}
@Override
public void icyFrameDeiconified(IcyFrameEvent e) {
panel.sizeModule();
}
@Override
public void icyFrameActivated(IcyFrameEvent e) {
panel.sizeModule();
}
@Override
public void icyFrameDeactivated(IcyFrameEvent e) {
}
@Override
public void icyFrameInternalized(IcyFrameEvent e) {
panel.sizeModule();
}
@Override
public void icyFrameExternalized(IcyFrameEvent e) {
panel.sizeModule();
}
@Override
public void componentResized(ComponentEvent e) {
panel.sizeModule();
}
@Override
public void componentMoved(ComponentEvent e) {
Point p = this.getLocation();
p.x += this.getWidth();
DeconvolutionDialog.setLocationLaunch(p);
}
@Override
public void componentShown(ComponentEvent e) {
panel.sizeModule();
}
@Override
public void componentHidden(ComponentEvent e) {
}
}
diff --git a/DeconvolutionLab2/src/signal/RealSignal.java b/DeconvolutionLab2/src/signal/RealSignal.java
index 2cbe86b..b49a5f1 100644
--- a/DeconvolutionLab2/src/signal/RealSignal.java
+++ b/DeconvolutionLab2/src/signal/RealSignal.java
@@ -1,657 +1,658 @@
/*
* 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;
import java.awt.image.BufferedImage;
+import deconvolutionlab.Lab;
import deconvolutionlab.monitor.Monitors;
public class RealSignal extends Signal implements SignalListener {
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(name, nx, ny, ny, false);
this.addSignalListener(this);
}
@Override
public void notify(String name, double progress) {
SignalCollector.setProgress(progress);
}
@Override
public void finalize() {
data = null;
System.gc();
SignalCollector.free(name, nx, ny, ny, false);
}
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;
}
/**
* 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 BufferedImage createPreviewMIPZ() {
RealSignal mip = createMIPZ();
mip.rescale(Monitors.createDefaultMonitor());
BufferedImage img = 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)data[0][i + j * nx];
+ int v = (int)mip.data[0][i + j * nx];
img.setRGB(i, j, alpha | (v << 16) | (v << 8) | v);
}
return img;
}
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 + 1;
int vy = ny + nz + 1;
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 + 1 + 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 + 1 + z);
view.data[0][index] = Math.max(view.data[0][index], data[z][x + nx * y]);
}
return view;
}
public RealSignal createMIPZ() {
String n = "mipz(" + name + ")";
RealSignal view = new RealSignal(n, nx, ny, 1);
for (int x = 0; x < nx; x++)
for (int y = 0; y < ny; y++) {
int index = x + nx * y;
for (int k = 0; k < nz; k++) {
view.data[0][index] = Math.max(view.data[0][index], data[k][x + nx * y]);
}
}
return view;
}
public RealSignal createMontage() {
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 + "]";
}
}

Event Timeline