Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F98368791
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Jan 12, 13:35
Size
216 KB
Mime Type
application/octet-stream
Expires
Tue, Jan 14, 13:35 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
23570679
Attached To
R2075 deconvolution
View Options
diff --git a/DeconvolutionLab2/src/DL2.java b/DeconvolutionLab2/src/DL2.java
index 0323a0e..deee0fa 100644
--- a/DeconvolutionLab2/src/DL2.java
+++ b/DeconvolutionLab2/src/DL2.java
@@ -1,94 +1,239 @@
-import ij.ImagePlus;
-import ij.Macro;
-import ij.WindowManager;
-
import java.io.File;
-import matlab.Converter;
import deconvolution.Deconvolution;
import deconvolutionlab.Config;
import deconvolutionlab.Lab;
import deconvolutionlab.dialog.LabDialog;
+import ij.ImagePlus;
+import ij.Macro;
+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() {
String config = System.getProperty("user.dir") + File.separator + "DeconvolutionLab2.config";
Config.getInstance(config);
LabDialog dialog = new LabDialog();
dialog.setVisible(true);
}
public static void run(String command) {
- new Deconvolution(Macro.getOptions()).deconvolve(false);
+ new Deconvolution(command).deconvolve(false);
}
public static void launch(String command) {
- new Deconvolution(Macro.getOptions()).launch("matlab", false);
+ new Deconvolution(command).launch("matlab", false);
}
public static Object get(String image) {
ImagePlus imp = WindowManager.getCurrentImage();
if (imp != null)
return Converter.get(imp);
return null;
}
- public static void run(Object image, Object psf, String algo) {
- Converter.createImage("input", image, true);
- Converter.createImage("psf", psf, true);
- String cmd = " -image platform input -psf platform psf -algorithm " + algo;
- Deconvolution d = new Deconvolution(cmd);
- d.deconvolve(false);
+ 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(command);
+ RealSignal result = d.deconvolve(image, psf, false);
+ 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(command);
+ RealSignal result = d.deconvolve(image, psf, false);
+ 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(command);
+ RealSignal result = d.deconvolve(image, psf, false);
+ 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(command);
+ RealSignal result = d.deconvolve(image, psf, false);
+ 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(command);
+ RealSignal result = d.deconvolve(image, psf, false);
+ 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(command);
+ RealSignal result = d.deconvolve(image, psf, false);
+ 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(command);
+ RealSignal result = d.deconvolve(image, psf, false);
+ 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(command);
+ RealSignal result = d.deconvolve(image, psf, false);
+ 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(command);
+ RealSignal result = d.deconvolve(image, psf, false);
+ 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(command);
+ RealSignal result = d.deconvolve(image, psf, false);
+ 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(command);
+ RealSignal result = d.deconvolve(image, psf, false);
+ 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(command);
+ RealSignal result = d.deconvolve(image, psf, false);
+ return Converter.createObject(result);
+ }
+
+
}
diff --git a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Bigradient.java b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Bigradient.java
index f25419c..d4ec21f 100644
--- a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Bigradient.java
+++ b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Bigradient.java
@@ -1,94 +1,92 @@
package course;
-import ij.plugin.PlugIn;
-
import java.io.File;
import javax.swing.filechooser.FileSystemView;
import deconvolution.Deconvolution;
-import deconvolutionlab.monitor.Monitors;
+import ij.plugin.PlugIn;
public class DeconvolutionLab2_Course_Bigradient implements PlugIn {
private String desktop = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator + "Desktop";
- private String root = desktop + File.separator + "DeconvolutionLab2-Course" + File.separator;
- private String res = root + "Results" + File.separator + "bigradient" + File.separator;
- private String data = root + "Data" + File.separator + "bigradient" + File.separator;
+ private String root = desktop + File.separator + "Deconvolution" + File.separator;
+ private String res = root + "results" + File.separator + "bigradient" + File.separator;
+ private String data = root + "data" + File.separator + "bigradient" + File.separator;
public DeconvolutionLab2_Course_Bigradient() {
new File(res).mkdir();
System.setProperty("user.dir", res);
new File(res + "TRIF").mkdir();
new File(res + "RIF").mkdir();
new File(res + "LW").mkdir();
new File(res + "LW-ITER").mkdir();
new File(res + "LW+").mkdir();
new File(res + "LW+-ITER").mkdir();
new File(res + "RL").mkdir();
new File(res + "RL-ITER").mkdir();
new File(res + "RLTV").mkdir();
new File(res + "RLTV-ITER").mkdir();
new File(res + "FISTA").mkdir();
new File(res + "FISTA-ITER").mkdir();
String psf = " -psf file " + data + "psf.tif -reference " + data + "ref.tif ";
String noisy = " -image file convnoise.tif";
new Deconvolution("-image file " + data + "ref.tif" + psf + " -algorithm SIM 0 1 1 -out stack convnoise -out stack conbnoise_8 rescaled byte noshow").deconvolve(false);
new Deconvolution(noisy + psf + " -algorithm NIF -out stack NIF").deconvolve(false);
new Deconvolution(noisy + psf + " -algorithm DIV -out stack DIV").deconvolve(false);
for(int i=0; i<=3; i++) {
double p = Math.pow(5, i-10);
String name = "RIF" + String.format("%02d", i);
new Deconvolution(noisy + psf + " -algorithm RIF " + p + out("RIF" + File.separator, name)).deconvolve(false);
}
for(int i=0; i<=3; i++) {
double p = Math.pow(5, i-10);
String name = "TRIF" + String.format("%02d", i);
new Deconvolution(noisy + psf + " -algorithm TRIF " + p + out("TRIF" + File.separator, name)).deconvolve(false);
}
- String lw = " -algorithm LW 20 1 -out mip @2 LW-ITER/I -showstats @1 LW";
+ String lw = " -algorithm LW 20 1 -out mip @2 LW-ITER/I -out stats @1 LW nosave";
new Deconvolution(noisy + psf + lw).deconvolve(false);
new File(res + "LW-ITER/I.tif").delete();
- String lwp = " -algorithm LW+ 20 1 -out mip @2 LW+-ITER/I -showstats @1 LW+";
+ String lwp = " -algorithm LW+ 20 1 -out mip @2 LW+-ITER/I -out stats @1 LW+ nosave";
new Deconvolution(noisy + psf + lwp).deconvolve(false);
new File(res + "LW+-ITER/I.tif").delete();
- String rl = " -algorithm RL 20 -out mip @2 RL-ITER/I -showstats @1 RL";
+ String rl = " -algorithm RL 20 -out mip @2 RL-ITER/I -out stats @1 RL nosave";
new Deconvolution(noisy + psf + rl).deconvolve(false);
new File(res + "RL-ITER/I.tif").delete();
- String rltv = " -algorithm RLRV 20 10 -out mip @2 RLTV-ITER/I -showstats @1 RLTV";
+ String rltv = " -algorithm RLRV 20 10 -out mip @2 RLTV-ITER/I -out stats @1 RLTV nosave";
new Deconvolution(noisy + psf + rltv).deconvolve(false);
new File(res + "RLTV-ITER/I.tif").delete();
- String fista = " -algorithm FISTA 20 1 1 Spline3 3 -mip @2 FISTA-ITER/I -showstats @1 FISTA";
+ String fista = " -algorithm FISTA 20 1 1 Spline3 3 -mip @2 FISTA-ITER/I -out stats @1 FISTA nosave";
new Deconvolution(noisy + psf + fista).deconvolve(false);
new File(res + "FISTA-ITER/I.tif").delete();
}
private static String out(String root, String name) {
- return "showstats " + root + name + " -savestats " + root + name +
+ return "out stats " + root + name +
" -out stack " + root + name + "_32 -out stack " + root + name + "_8 rescaled byte noshow";
}
public static void main(String arg[]) {
new DeconvolutionLab2_Course_Bigradient();
}
@Override
public void run(String arg) {
new DeconvolutionLab2_Course_Bigradient();
}
}
diff --git a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Border.java b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Border.java
index d9eb32d..e472c08 100644
--- a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Border.java
+++ b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Border.java
@@ -1,108 +1,108 @@
package course;
// Course Version 2
import ij.plugin.PlugIn;
import java.io.File;
import javax.swing.filechooser.FileSystemView;
import signal.RealSignal;
import signal.factory.Cube;
import signal.factory.Gaussian;
import deconvolution.Deconvolution;
import deconvolutionlab.Lab;
import deconvolutionlab.monitor.Monitors;
public class DeconvolutionLab2_Course_Border implements PlugIn {
private String desktop = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator + "Desktop";
- private String root = desktop + File.separator + "DeconvolutionLab2-Course" + File.separator;
- private String res = root + "Results" + File.separator + "border" + File.separator;
+ private String root = desktop + File.separator + "Deconvolution" + File.separator;
+ private String res = root + "results" + File.separator + "border" + File.separator;
public DeconvolutionLab2_Course_Border() {
Monitors monitors = Monitors.createDefaultMonitor();
new File(res).mkdir();
System.setProperty("user.dir", res);
int nx = 200;
int ny = 200;
int nz = 40;
RealSignal im = new Cube(22, .1).intensity(0, 100).center(0.25, 0.00, 0.05).generate(nx, ny, nz);
RealSignal i0 = new Cube(22, .1).intensity(0, 100).center(0.25, 0.05, 0.05).generate(nx, ny, nz);
RealSignal i1 = new Cube(22, .1).intensity(0, 100).center(0.25, 0.10, 0.05).generate(nx, ny, nz);
RealSignal i2 = new Cube(22, .1).intensity(0, 100).center(0.25, 0.15, 0.05).generate(nx, ny, nz);
im.max(i1.max(i2).max(i0));
RealSignal g = new Gaussian(10, 10, 10).intensity(0, 101).generate(nx, ny, nz);
Lab.save(monitors, im, res + "ref.tif");
Lab.save(monitors, g, res + "psf.tif");
String psf = " -psf file " + "psf.tif";
String ref = " -image file " + "ref.tif";
String cst = " -image synthetic constant 250 0 size 200 200 40";
String algo = " -algorithm CONV -out ortho REFo (64,32,16)";
new Deconvolution(ref + " -psf synthetic impulse " + algo).deconvolve(false);
algo = " -algorithm CONV -stack CONV -out ortho CONVo rescaled byte (64,32,16) -out mip CONVp rescaled byte";
new Deconvolution(ref + psf + algo).deconvolve(false);
algo = " -algorithm CONV -pad NO NO 200 200 -out ortho PADo200 rescaled byte (64,32,16) -out mip PADp200 rescaled byte";
new Deconvolution(ref + psf + algo).deconvolve(false);
algo = " -algorithm CONV -pad NO NO 100 100 -out ortho PADo100 rescaled byte (64,32,16) -out mip PADp100 rescaled byte";
new Deconvolution(ref + psf + algo).deconvolve(false);
algo = " -algorithm CONV -pad NO NO 40 40 -out ortho PADo40 rescaled byte (64,32,16) -out mip PADp40 rescaled byte";
new Deconvolution(ref + psf + algo).deconvolve(false);
algo = " -algorithm CONV -pad NO NO 20 20 -out ortho PADo20 rescaled byte (64,32,16) -out mip PADp20 rescaled byte";
new Deconvolution(ref + psf + algo).deconvolve(false);
algo = " -algorithm CONV -pad NO NO 10 10 -out ortho PADo10 rescaled byte (64,32,16) -out mip PADp10 rescaled byte";
new Deconvolution(ref + psf + algo).deconvolve(false);
algo = " -algorithm CONV -pad NO NO 5 5 -out ortho PADo2 rescaled byte (64,32,16) -out mip PADp2 rescaled byte";
new Deconvolution(ref + psf + algo).deconvolve(false);
algo = " -algorithm CONV -apo HANN HANN -out ortho HANNo rescaled byte (64,32,16) -out mip HANNp rescaled byte";
new Deconvolution(ref + psf + algo).deconvolve(false);
algo = " -algorithm CONV -apo TUKEY TUKEY -out ortho TUKEYo rescaled byte (64,32,16) -out mip TUKEYp rescaled byte";
new Deconvolution(ref + psf + algo).deconvolve(false);
algo = " -algorithm CONV --pad NO NO 8 8 apo HANN HANN -out ortho PAD8_HANNo rescaled byte (64,32,16) -out mip PAD8_HANNp rescaled byte";
new Deconvolution(ref + psf + algo).deconvolve(false);
algo = " -algorithm CONV -apo HANN HANN -out ortho HANN_CSTo rescaled byte -out mip HANN_CSTp rescaled byte";
new Deconvolution(cst + psf + algo).deconvolve(false);
algo = " -algorithm CONV -apo TUKEY TUKEY -out ortho TUKEY_CSTo rescaled byte -out mip TUKEY_CSTp rescaled byte";
new Deconvolution(cst + psf + algo).deconvolve(false);
algo = " -algorithm CONV -pad E2 E2 -out ortho PADpPower2FFTW rescaled byte (64,32,16) -out mip PADpPower2FFTW rescaled byte";
new Deconvolution(cst + psf + algo + " -fft FFTW2 ").deconvolve(false);
new Deconvolution(cst + psf + algo + " -fft Academic ").deconvolve(false);
new Deconvolution(cst + psf + algo + " -fft JTransforms ").deconvolve(false);
}
public static void main(String arg[]) {
new DeconvolutionLab2_Course_Border();
}
@Override
public void run(String arg) {
new DeconvolutionLab2_Course_Border();
}
}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Noise.java b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Noise.java
index 10b28b8..b2ab8a3 100644
--- a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Noise.java
+++ b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Noise.java
@@ -1,67 +1,67 @@
package course;
import java.io.File;
import javax.swing.filechooser.FileSystemView;
import deconvolution.Deconvolution;
import deconvolutionlab.Lab;
import deconvolutionlab.monitor.Monitors;
import ij.plugin.PlugIn;
import signal.RealSignal;
import signal.factory.Cube;
public class DeconvolutionLab2_Course_Noise implements PlugIn {
private String desktop = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator + "Desktop";
- private String root = desktop + File.separator + "DeconvolutionLab2-Course" + File.separator;
- private String res = root + "Results" + File.separator + "noise" + File.separator;
+ private String root = desktop + File.separator + "Deconvolution" + File.separator;
+ private String res = root + "results" + File.separator + "noise" + File.separator;
public DeconvolutionLab2_Course_Noise() {
Monitors monitors = Monitors.createDefaultMonitor();
new File(res).mkdir();
System.setProperty("user.dir", res);
int nx = 560;
int ny = 120;
int nz = 1;
String size = " size " + nx + " " + ny + " " + nz;
RealSignal im = new Cube(50, 0.25).intensity(0, 100).center(0.2, 0.5, 0).generate(nx, ny, nz);
RealSignal i1 = new Cube(50, 0.25).intensity(0, 70).center(0.4, 0.5, 0).generate(nx, ny, nz);
RealSignal i2 = new Cube(50, 0.25).intensity(0, 40).center(0.6, 0.5, 0).generate(nx, ny, nz);
RealSignal i3 = new Cube(50, 0.25).intensity(0, 10).center(0.8, 0.5, 0).generate(nx, ny, nz);
im.plus(i1);
im.plus(i2);
im.plus(i3);
Lab.show(monitors, im, "im.tif");
Lab.save(monitors, im, res + "im.tif");
String psf = " -psf synthetic impulse 1 0 " + size;
String image = " -image file im.tif";
// Simulation
String name = "SIM m 0 s 50 p 0";
String out = " -stack " + name + " -out stack " + name + "-BYTE rescaled byte noshow";
new Deconvolution(psf + image + " -algorithm " + name + out).run();
name = "SIM m 0 s 00 p 150";
out = " -stack " + name + " -out stack " + name + "-BYTE rescaled byte noshow";
new Deconvolution(psf + image + " -algorithm " + name + out).run();
name = "SIM m 0 s 15 p 30";
out = " -stack " + name + " -out stack " + name + "-BYTE rescaled byte noshow";
new Deconvolution(psf + image + " -algorithm " + name + out).run();
}
public static void main(String arg[]) {
new DeconvolutionLab2_Course_Noise();
}
@Override
public void run(String arg) {
new DeconvolutionLab2_Course_Noise();
}
}
diff --git a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Piecewise.java b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Piecewise.java
index db7f762..aac3931 100644
--- a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Piecewise.java
+++ b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Piecewise.java
@@ -1,105 +1,85 @@
package course;
import java.io.File;
import java.util.Random;
import javax.swing.filechooser.FileSystemView;
import deconvolution.Deconvolution;
import deconvolutionlab.Lab;
import deconvolutionlab.monitor.Monitors;
import ij.plugin.PlugIn;
import signal.RealSignal;
import signal.factory.Constant;
import signal.factory.Cube;
public class DeconvolutionLab2_Course_Piecewise implements PlugIn {
private String desktop = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator + "Desktop";
- private String root = desktop + File.separator + "DeconvolutionLab2-Course" + File.separator;
- private String res = root + "Results" + File.separator + "piecewise" + File.separator;
- private String data = root + "Data" + File.separator + "piecewise" + File.separator;
+ private String root = desktop + File.separator + "Deconvolution" + File.separator;
+ private String res = root + "results" + File.separator + "piecewise" + File.separator;
public DeconvolutionLab2_Course_Piecewise() {
Monitors monitors = Monitors.createDefaultMonitor();
new File(res).mkdir();
System.setProperty("user.dir", res);
new File(res + "RIF").mkdir();
new File(res + "LW").mkdir();
new File(res + "LW+").mkdir();
new File(res + "RL").mkdir();
new File(res + "RLTV").mkdir();
new File(res + "ISTA").mkdir();
new File(res + "FISTA").mkdir();
int nx = 128;
int ny = 128;
int nz = 128;
int spacing = 16;
Random rand = new Random(1234);
RealSignal x = new Constant().intensity(0, 10).generate(nx, ny, nz);
for(int i = 0; i< 12; i++) {
double xc = (rand.nextDouble()*0.6 + 0.2);
double yc = (rand.nextDouble()*0.6 + 0.2);
double zc = (rand.nextDouble()*0.6 + 0.2);
double size = 15 + (rand.nextDouble()*30);
double ampl = (rand.nextDouble()+0.5)*10;
x.plus(new Cube(size, 0.1).intensity(0, ampl).center(xc, yc, zc).generate(nx, ny, nz));
}
Lab.show(monitors, x, "reference");
Lab.save(monitors, x, res + "ref.tif");
String algo = " ";
String ground = " -image file " + res + "ref.tif ";
//String psf = " -psf file ../../Data/resolution/psfgl.tif";
String psf = " -psf synthetic gaussian 100.0 0.0 1.2 1.2 3.6 size ";
// nx + " " + ny + " " + nz;
String signal = " -image file signal.tif -reference " + res + "ref.tif -disable monitor";
String paramout = " intact float (" + spacing + "," + spacing + "," + spacing + ")";
- algo = " -algorithm CONV -showstats @3 PR -out stack PR -out ortho PRo ";
+ algo = " -algorithm CONV -out stats @3 PR nosave -out stack PR -out ortho PRo ";
new Deconvolution(ground + "-reference reference.tif -psf synthetic impulse 100 0 size 128 128 128 " + algo).deconvolve(false);
- algo = " -algorithm SIM 0 1 1 -showstats @3 SIM -out stack signal -out ortho SIGNALo ";
+ algo = " -algorithm SIM 0 1 1 -out stats @3 SIM nosave -out stack signal -out ortho SIGNALo ";
new Deconvolution(ground + psf + algo).deconvolve(false);
algo = " -algorithm NIF -out ortho NIF " + paramout;
new Deconvolution(signal + psf + algo).deconvolve(false);
-/*
- algo = " -algorithm LW+ 15 1.5 -showstats @1 LW+ -out ortho @1 LW+/LW+" + paramout;
- new Deconvolution(signal + psf + algo).deconvolve(false);
-
- algo = " -algorithm FISTA 15 1 1 -showstats @1 FISTA -out ortho @1 FISTA/FISTA" + paramout;
- new Deconvolution(signal + psf + algo).deconvolve(false);
- algo = " -algorithm ISTA 15 1 1 -showstats @1 ISTA -out ortho @1 ISTA/ISTA" + paramout;
- new Deconvolution(signal + psf + algo).deconvolve(false);
-*/
- algo = " -algorithm RLTV 15 0.01 -showstats @1 RLTV -out ortho @1 RLTV/RLTV" + paramout;
+ algo = " -algorithm RLTV 15 0.01 -out stats @1 RLTV nosave -out ortho @1 RLTV/RLTV" + paramout;
new Deconvolution(signal + psf + algo).deconvolve(false);
-
- /*
- for(int i=0; i<=24; i++) {
- double p = Math.pow(10, i-18);
- algo =" -algorithm RIF " + p + " -out ortho @5 RIF/RIF" + i + paramout;
- new Deconvolution(signal + psf + algo).deconvolve(false);
- }
- */
-
-
}
public static void main(String arg[]) {
new DeconvolutionLab2_Course_Piecewise();
}
@Override
public void run(String arg) {
new DeconvolutionLab2_Course_Piecewise();
}
}
diff --git a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Resolution.java b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Resolution.java
index 3655d16..8bb6558 100644
--- a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Resolution.java
+++ b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Resolution.java
@@ -1,84 +1,76 @@
package course;
import java.io.File;
import javax.swing.filechooser.FileSystemView;
import deconvolution.Deconvolution;
import deconvolutionlab.Lab;
import deconvolutionlab.monitor.Monitors;
import ij.plugin.PlugIn;
import signal.RealSignal;
import signal.factory.GridSpots;
public class DeconvolutionLab2_Course_Resolution implements PlugIn {
private String desktop = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator + "Desktop";
- private String root = desktop + File.separator + "DeconvolutionLab2-Course" + File.separator;
- private String res = root + "Results" + File.separator + "resolution" + File.separator;
- private String data = root + "Data" + File.separator + "resolution" + File.separator;
+ private String root = desktop + File.separator + "Deconvolution" + File.separator;
+ private String res = root + "results" + File.separator + "resolution" + File.separator;
public DeconvolutionLab2_Course_Resolution() {
Monitors monitors = Monitors.createDefaultMonitor();
new File(res).mkdir();
System.setProperty("user.dir", res);
new File(res + "RIF").mkdir();
new File(res + "LW").mkdir();
new File(res + "LW+").mkdir();
new File(res + "RL").mkdir();
int nx = 128;
int ny = 128;
int nz = 128;
int spacing = 16;
RealSignal x = new GridSpots(3, 0.1, spacing).intensity(0, 255).generate(nx, ny, nz);
Lab.show(monitors, x, "reference");
Lab.save(monitors, x, res + "ref.tif");
String algo = " ";
String ground = " -image file " + res + "ref.tif ";
//String psf = " -psf file ../../Data/resolution/psfgl.tif";
String psf = " -psf synthetic gaussian 100.0 0.0 1.2 1.2 3.6 size " + nx + " " + ny + " " + nz;
String signal = " -image file signal.tif -reference " + res + "ref.tif -disable monitor";
String paramout = " intact float (" + spacing + "," + spacing + "," + spacing + ")";
- algo = " -algorithm CONV -showstats @3 PR -out stack PR -out ortho PRo ";
+ algo = " -algorithm CONV -out stats @3 PR -out stack PR -out ortho PRo ";
new Deconvolution(ground + "-reference reference.tif -psf synthetic impulse 100 0 size 128 128 128 " + algo).deconvolve(false);
- algo = " -algorithm SIM 0 1.5 0 -showstats @3 SIM -out stack signal -out ortho SIGNALo ";
+ algo = " -algorithm SIM 0 1.5 0 -out stats @3 SIM -out stack signal -out ortho SIGNALo ";
new Deconvolution(ground + psf + algo).deconvolve(false);
algo = " -algorithm NIF -out ortho NIF " + paramout;
new Deconvolution(signal + psf + algo).deconvolve(false);
for(int i=0; i<=24; i++) {
double p = Math.pow(10, i-18);
algo = " -algorithm RIF " + p + " -out ortho @5 RIF/RIF" + i + paramout;
new Deconvolution(signal + psf + algo).deconvolve(false);
}
- algo = " -algorithm LW+ 305 1 -showstats @3 LW+ -out ortho @25 LW+/LW+" + paramout;
+ algo = " -algorithm LW+ 305 1 -out stats @3 LW+ nosave -out ortho @25 LW+/LW+" + paramout;
new Deconvolution(signal + psf + algo).deconvolve(false);
-
-// algo = " -algorithm LW 205 1 -showstats @3 LW -out ortho @25 LW/LW" + paramout;
-// new Deconvolution(signal + psf + algo).deconvolve(false);
-
-// algo = " -algorithm RL 205 1 -showstats @3 RL -constraint Non-negativity -out ortho @25 RL/RL" + paramout;
-// new Deconvolution(signal + psf + algo).deconvolve(false);
-
}
public static void main(String arg[]) {
new DeconvolutionLab2_Course_Resolution();
}
@Override
public void run(String arg) {
new DeconvolutionLab2_Course_Resolution();
}
}
\ No newline at end of file
diff --git a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_SpectralAnaylsis.java b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_SpectralAnaylsis.java
index bdbc99e..55ed4e0 100644
--- a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_SpectralAnaylsis.java
+++ b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_SpectralAnaylsis.java
@@ -1,159 +1,160 @@
package course;
import ij.plugin.PlugIn;
import java.io.File;
import javax.swing.filechooser.FileSystemView;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.factory.DoG;
import signal.factory.Gaussian;
import signal.factory.complex.ComplexSignalFactory;
import deconvolution.Deconvolution;
import deconvolutionlab.Lab;
import deconvolutionlab.PlatformImager;
import deconvolutionlab.monitor.Monitors;
import fft.AbstractFFT;
import fft.FFT;
public class DeconvolutionLab2_Course_SpectralAnaylsis implements PlugIn {
private String desktop = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator + "Desktop";
- private String root = desktop + File.separator + "DeconvolutionLab2-Course" + File.separator;
- private String res = root + "Results" + File.separator + "star" + File.separator;
- private String data = root + "Data" + File.separator + "star" + File.separator;
+ private String root = desktop + File.separator + "Deconvolution" + File.separator;
+ private String res = root + "results" + File.separator + "star" + File.separator;
+ private String data = root + "data" + File.separator + "star" + File.separator;
public DeconvolutionLab2_Course_SpectralAnaylsis() {
new File(res).mkdir();
System.setProperty("user.dir", res);
new File(res + "TRIF").mkdir();
new File(res + "TRIF-FILTER").mkdir();
new File(res + "RIF").mkdir();
new File(res + "RIF-FILTER").mkdir();
new File(res + "LW").mkdir();
new File(res + "LW-ITER").mkdir();
new File(res + "LW+").mkdir();
new File(res + "LW+-ITER").mkdir();
new File(res + "RL").mkdir();
new File(res + "RL-ITER").mkdir();
new File(res + "NOISELESS").mkdir();
new File(res + "PERTURBATION").mkdir();
new File(res + "SIMULATION").mkdir();
new File(res + "ICTM").mkdir();
new File(res + "ICTM-ITER").mkdir();
Monitors monitors = Monitors.createDefaultMonitor();
int nx = 256;
int ny = 256;
int nz = 1;
String size = " size " + nx + " " + ny + " " + nz;
double noise = 0.04;
double poisson = 0.01;
double wiener = Math.sqrt(noise * 2.0 / Math.PI);
System.out.println("Wiener value " + wiener);
AbstractFFT fft = FFT.createDefaultFFT(monitors, nx, ny, nz);
ComplexSignal L = ComplexSignalFactory.laplacian(nx, ny, nz);
RealSignal laplacian = fft.inverse(L).circular().rescale(monitors);
Lab.save(monitors, laplacian, res + "laplacian.tif", PlatformImager.Type.BYTE);
RealSignal h = new DoG(2, 3.6).generate(nx, ny, nz);
h.times(0.7f);
h.plus(new Gaussian(1.5, 1.5, 1.5).generate(nx, ny, nz));
Lab.save(monitors, h, res + "psf.tif");
h.plus(new Gaussian(0.5, 0.5, 0.5).generate(nx, ny, nz));
Lab.save(monitors, h, res + "psfPerturbated.tif");
- String psf = " -psf file psf.tif -fft FFTW2";
+ String psf = " -psf file psf.tif -fft FFTW2";
String impulse = " -psf synthetic impulse 100.0 0.0 " + size;
String image = " -image file " + data + "ref.tif";
String constant = " -image constant 0 0 " + size;
// Simulation
String algo = " -algorithm CONV " + out("CONV");
new Deconvolution(psf + image + algo).deconvolve(false);
algo = " -algorithm CONV " + out("CONV-PERTURBATED");
new Deconvolution(psf + image + algo).deconvolve(false);
ComplexSignal H = fft.transform(h);
ComplexSignal H2 = Operations.multiply(H, H);
ComplexSignal LP = ComplexSignalFactory.laplacian(nx, ny, nz);
algo = " -algorithm SIM " + (6*noise) + " " + noise + " " + poisson + " " + out("SIM");
new Deconvolution(psf + image + algo).deconvolve(false);
algo = " -algorithm SIM " + (6*noise) + " " + noise + " " + poisson + " " + out("NOISE");
new Deconvolution(impulse + constant + algo).deconvolve(false);
// No Noise
String nonoise = " -image file CONV.tif -psf file psfPerturbated.tif";
new Deconvolution(nonoise + " -algorithm TRIF " + wiener + out("NOISELESS/WIF")).deconvolve(false);
new Deconvolution(nonoise + " -algorithm NIF -epsilon 1E0 " + out("NOISELESS/NIF0")).deconvolve(false);
new Deconvolution(nonoise + " -algorithm NIF -epsilon 1E-3 " + out("NOISELESS/NIF-1")).deconvolve(false);
new Deconvolution(nonoise + " -algorithm NIF -epsilon 1E-6 " + out("NOISELESS/NIF-6")).deconvolve(false);
new Deconvolution(nonoise + " -algorithm NIF -epsilon 1E-9 " + out("NOISELESS/NIF-9")).deconvolve(false);
new Deconvolution(nonoise + " -algorithm NIF -epsilon 1E-12 " + out("NOISELESS/NIF-12")).deconvolve(false);
new Deconvolution(nonoise + " -algorithm DIV " + out("NOISELESS/DIV")).deconvolve(false);
// Pertubatation
String pertubation = " -image file CONV.tif -psf file psfPerturbated.tif";
new Deconvolution(pertubation + " -algorithm TRIF " + wiener + out("PERTURBATION/WIF")).deconvolve(false);
new Deconvolution(pertubation + " -algorithm NIF " + out("PERTURBATION/NIF")).deconvolve(false);
new Deconvolution(pertubation + " -algorithm DIV " + out("PERTURBATION/DIV")).deconvolve(false);
// Noisy
String simulation = " -image file SIM.tif " + psf;
new Deconvolution(simulation + " -algorithm TRIF " + wiener + out("SIMULATION/WIF")).deconvolve(false);
new Deconvolution(simulation + " -algorithm NIF "+ out("SIMULATION/NIF")).deconvolve(false);
new Deconvolution(simulation + " -algorithm DIV" + out("SIMULATION/DIV")).deconvolve(false);
algo = " -algorithm LW+ 100 0.5 -out mip @1 LW+-ITER/I ";
new Deconvolution(simulation + algo + out("LW+/LW+")).deconvolve(false);
new File(res + "LW+-ITER/I.tif").delete();
for(int i=0; i<=20; i++) {
double p = Math.pow(5, i-12);
String name = "RIF/RIF" + String.format("%02d", i);
new Deconvolution(simulation + " -algorithm RIF " + p + out(name)).deconvolve(false);
RealSignal fa = fft.inverse(Operations.add(H2, Operations.multiply(p, LP, LP))).circular();
Lab.save(monitors, fa, res + "RIF-FILTER/RIF" + String.format("%02d", i) + ".tif");
}
for(int i=0; i<=20; i++) {
double p = Math.pow(5, i-12);
String name = "TRIF/TRIF" + String.format("%02d", i);
new Deconvolution(simulation + " -algorithm TRIF " + p + out(name)).deconvolve(false);
RealSignal fa = fft.inverse(Operations.add(H2, Operations.multiply(p, LP, LP))).circular();
Lab.save(monitors, fa, res + "TRIF-FILTER/RIF" + String.format("%02d", i) + ".tif");
}
algo = " -algorithm RL 100 -out mip @1 RL-ITER/I ";
new Deconvolution(simulation + algo + out("RL/RL")).deconvolve(false);
new File(res + "RL-ITER/I.tif").delete();
algo = " -algorithm ICTM 100 1.5 0.001 -out mip @1 ICTM-ITER/I ";
new Deconvolution(simulation + algo + out("ICTM/ICTM")).deconvolve(false);
new File(res + "ICTM-ITER/I.tif").delete();
+
}
private static String out(String name) {
- return " -out stack " + name +
- " -out stack " + name + "-BYTE rescaled byte noshow";
+ return " -out stats " + name +
+ " -out stack " + name + " noshow -out ortho " + name + "-BYTE rescaled byte noshow";
}
public static void main(String arg[]) {
new DeconvolutionLab2_Course_SpectralAnaylsis();
}
@Override
public void run(String arg) {
new DeconvolutionLab2_Course_SpectralAnaylsis();
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/Command.java b/DeconvolutionLab2/src/deconvolution/Command.java
index b681ba2..8f358b8 100644
--- a/DeconvolutionLab2/src/deconvolution/Command.java
+++ b/DeconvolutionLab2/src/deconvolution/Command.java
@@ -1,290 +1,310 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package 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.Output.View;
+import deconvolutionlab.modules.AbstractModule;
+import deconvolutionlab.modules.CommandModule;
import lab.tools.NumFormat;
import signal.Constraint;
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;
-import deconvolution.algorithm.AbstractAlgorithm;
-import deconvolution.algorithm.Algorithm;
-import deconvolution.algorithm.Controller;
-import deconvolutionlab.Output;
-import deconvolutionlab.Output.View;
-import deconvolutionlab.modules.AbstractModule;
-import deconvolutionlab.modules.CommandModule;
-import deconvolutionlab.modules.LanguageModule;
-import deconvolutionlab.monitor.ConsoleMonitor;
-import deconvolutionlab.monitor.Monitors;
-import deconvolutionlab.monitor.TableMonitor;
public class Command {
- public static String keywords[] = { "-image", "-psf", "-algorithm", "-path", "-disable", "-verbose", "-time", "-constraint", "-residu", "-reference", "-savestats", "-showstats", "-out", "-pad", "-apo", "-norm", "-fft" };
+ public static String keywords[] = { "-image", "-psf", "-algorithm", "-path", "-disable", "-verbose", "-monitor", "-display", "-multithreading", "-constraint", "-time", "-residu", "-reference", "-out", "-pad", "-apo", "-norm", "-fft" };
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;
}
/**
* 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++) {
+ 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());
+ 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);
}
- /*
- for (int i = 0; i < segments.size(); i++) {
- CommandSegment segment = segments.get(i);
- String next = (i + 1 < segments.size() ? segments.get(i + 1).keyword : "");
- int end = (i + 1 < segments.size() ? segments.get(i + 1).index - next.length() : command.length());
- tokens.add(new Token(segment.keyword, command, segment.index, end));
- }
- */
-
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);
double params[] = parseNumeric(token.parameters);
if (params != null) {
algo.setParameters(params);
if (algo.isIterative())
controller.setIterationMax(algo.getController().getIterationMax());
}
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()));
+ if (p.startsWith("stats"))
+ out = new Output(View.STATS, freq, line.substring("stats".length(), line.length()));
+ if (p.startsWith("profile"))
+ out = new Output(View.PROFILE, freq, line.substring("profile".length(), line.length()));
return out;
}
public static void decodeController(Token token, Controller controller) {
int freq = 1;
String line = token.parameters;
if (token.parameters.startsWith("@")) {
String parts[] = token.parameters.split(" ");
if (parts.length >= 1) {
freq = (int) NumFormat.parseNumber(parts[0], 1);
line = token.parameters.substring(parts[0].length(), token.parameters.length()).trim();
}
}
- if (token.keyword.equals("-constraint")) {
- controller.setConstraint(freq, Constraint.getByName(line.trim()));
- }
-
- else if (token.keyword.equals("-residu")) {
- double stop = NumFormat.parseNumber(line, -1);
- controller.setResiduStop(freq, stop);
- }
-
- else if (token.keyword.equals("-reference")) {
- controller.setReference(freq, line);
- }
-
- else if (token.keyword.equals("-savestats")) {
- controller.setSaveStats(freq, line);
- }
-
- else if (token.keyword.equals("-showstats")) {
- controller.setShowStats(freq, line);
- }
+ 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));
- else if (token.keyword.equals("-time")) {
- double stop = NumFormat.parseNumber(line, Double.MAX_VALUE);
- controller.setTimeStop(stop);
- }
}
public static double decodeNormalization(Token token) {
if (token.parameters.toLowerCase().endsWith("no"))
return 0;
else
return NumFormat.parseNumber(token.parameters, 1);
}
- public static boolean decodeDisable(Token token, String word) {
+ public static boolean decodeMonitor(Token token) {
String p = token.parameters.toLowerCase();
- String parts[] = p.split(" ");
- for (String part : parts) {
- if (part.trim().equals(word))
- return false;
- }
+ if (p.startsWith("no"))
+ return false;
+ if (p.equals("0"))
+ return false;
+ if (p.equals("false"))
+ return false;
+ if (p.equals("console"))
+ 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);
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/Deconvolution.java b/DeconvolutionLab2/src/deconvolution/Deconvolution.java
index f5174bd..d6bb36d 100644
--- a/DeconvolutionLab2/src/deconvolution/Deconvolution.java
+++ b/DeconvolutionLab2/src/deconvolution/Deconvolution.java
@@ -1,642 +1,676 @@
/*
* 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 javax.swing.JFrame;
-
import deconvolution.algorithm.AbstractAlgorithm;
import deconvolution.algorithm.Controller;
import deconvolutionlab.Lab;
import deconvolutionlab.Output;
import deconvolutionlab.OutputCollection;
import deconvolutionlab.monitor.ConsoleMonitor;
import deconvolutionlab.monitor.Monitors;
import deconvolutionlab.monitor.StatusMonitor;
import deconvolutionlab.monitor.TableMonitor;
import deconvolutionlab.monitor.Verbose;
-import fft.AbstractFFT;
import fft.AbstractFFTLibrary;
import fft.FFT;
import lab.tools.NumFormat;
import signal.RealSignal;
import signal.apodization.AbstractApodization;
import signal.apodization.Apodization;
import signal.apodization.UniformApodization;
import signal.factory.SignalFactory;
import signal.padding.Padding;
public class Deconvolution implements Runnable {
private AbstractAlgorithm algo = null;
private String path;
private Monitors monitors = Monitors.createDefaultMonitor();
private Verbose verbose = Verbose.Log;
private Controller controller;
private OutputCollection outs;
private Padding pad = new Padding();
private Apodization apo = new Apodization();
private double norm = 1.0;
private AbstractFFTLibrary fft;
private String command = "";
private boolean live = false;
private ArrayList<String> report = new ArrayList<String>();
private String name = "";
private boolean exit = false;
private boolean watcherMonitor = true;
private boolean watcherConsole = true;
private boolean watcherDisplay = true;
private boolean watcherMultithreading = true;
private ArrayList<DeconvolutionListener> listeners = new ArrayList<DeconvolutionListener>();
+ private boolean imageLoaded = false;
+ private RealSignal image;
+ private RealSignal psf;
+ private RealSignal result;
+
public Deconvolution(String command) {
super();
monitors = Monitors.createDefaultMonitor();
this.command = command;
decode();
}
+
public void setCommand(String command) {
this.command = command;
decode();
}
public String getCommand() {
return command;
}
public Monitors getMonitors() {
if (monitors == null)
return Monitors.createDefaultMonitor();
return monitors;
}
/**
* This method runs the deconvolution without graphical user interface.
*
* @param exit
* System.exit call is true
*/
- public void deconvolve(boolean exit) {
+ public RealSignal deconvolve(RealSignal image, RealSignal psf, boolean exit) {
+ this.image = image;
+ this.psf = psf;
this.exit = exit;
-
- monitors = new Monitors();
- if (watcherConsole)
- monitors.add(new ConsoleMonitor());
-
- if (watcherMonitor) {
- TableMonitor m = new TableMonitor(440, 440);
- monitors.add(m);
- String t = algo == null ? "Monitor " + name : name + " " + algo.getName();
- JFrame frame = new JFrame(t);
- frame.add(m.getPanel());
- frame.pack();
- frame.setVisible(true);
- }
+ imageLoaded = true;
+ monitors = createMonitors();
+ deconvolve();
+ return result;
+ }
+
+ public RealSignal deconvolve(boolean exit) {
+ this.image = null;
+ this.psf = null;
+ this.exit = exit;
+ imageLoaded = false;
+ monitors = createMonitors();
+ deconvolve();
+ return result;
+ }
+ /**
+ * This method runs the deconvolution without graphical user interface.
+ *
+ * @param exit
+ * System.exit call is true
+ */
+ private void deconvolve() {
if (fft == null) {
run();
return;
}
+
if (!fft.isMultithreadable()) {
run();
return;
}
if (watcherMultithreading) {
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
* @param exit
* System.exit call is true
*/
public void launch(String job, boolean exit) {
this.name = job;
this.exit = exit;
DeconvolutionDialog d = new DeconvolutionDialog(this);
monitors = new Monitors();
monitors.add(new StatusMonitor(d.getProgressBar()));
if (watcherConsole)
monitors.add(new ConsoleMonitor());
if (watcherMonitor) {
TableMonitor m = new TableMonitor(440, 440);
monitors.add(m);
d.addTableMonitor("Monitor", m);
}
}
public void decode() {
algo = null;
path = System.getProperty("user.dir");
if (monitors==null)
monitors = Monitors.createDefaultMonitor();
verbose = Verbose.Log;
controller = new Controller();
outs = new OutputCollection();
pad = new Padding();
apo = new Apodization();
norm = 1.0;
fft = FFT.getLibraryByName("Academic");
live = false;
ArrayList<Token> tokens = Command.parse(command);
for (Token token : tokens) {
if (token.keyword.equalsIgnoreCase("-algorithm"))
algo = Command.decodeAlgorithm(token, controller);
- if (token.keyword.equalsIgnoreCase("-disable")) {
- watcherMonitor = Command.decodeDisable(token, "monitor");
- watcherConsole = Command.decodeDisable(token, "console");
- watcherDisplay = Command.decodeDisable(token, "display");
- watcherMultithreading = Command.decodeDisable(token, "multithreading");
- }
+ if (token.keyword.equalsIgnoreCase("-monitor"))
+ watcherMonitor = Command.decodeMonitor(token);
+
+ if (token.keyword.equalsIgnoreCase("-display"))
+ watcherDisplay = Command.decodeDisplay(token);
+
+ if (token.keyword.equalsIgnoreCase("-multithreading"))
+ watcherMultithreading = Command.decodeMultithreading(token);
if (token.keyword.equalsIgnoreCase("-verbose"))
verbose = Verbose.getByName(token.parameters);
- if (token.keyword.equalsIgnoreCase("-path") && !token.parameters.equalsIgnoreCase("current")) {
+ if (token.keyword.equalsIgnoreCase("-path") && !token.parameters.equalsIgnoreCase("current"))
path = token.parameters;
- }
if (token.keyword.equalsIgnoreCase("-fft"))
fft = FFT.getLibraryByName(token.parameters);
if (token.keyword.equalsIgnoreCase("-pad"))
pad = Command.decodePadding(token);
+
if (token.keyword.equalsIgnoreCase("-apo"))
apo = Command.decodeApodization(token);
+
if (token.keyword.equalsIgnoreCase("-norm"))
norm = Command.decodeNormalization(token);
+
if (token.keyword.equalsIgnoreCase("-constraint"))
Command.decodeController(token, controller);
+
if (token.keyword.equalsIgnoreCase("-time"))
Command.decodeController(token, controller);
+
if (token.keyword.equalsIgnoreCase("-residu"))
Command.decodeController(token, controller);
+
if (token.keyword.equalsIgnoreCase("-reference"))
Command.decodeController(token, controller);
- if (token.keyword.equalsIgnoreCase("-savestats"))
- Command.decodeController(token, controller);
- if (token.keyword.equalsIgnoreCase("-showstats"))
- Command.decodeController(token, controller);
if (token.keyword.equals("-out")) {
Output out = Command.decodeOut(token);
if (out != null)
outs.add(out);
}
}
if (name.equals("") && algo != null)
name = algo.getShortname();
-
}
+ public Monitors createMonitors() {
+ Monitors monitors = new Monitors();
+
+ if (watcherConsole)
+ monitors.add(new ConsoleMonitor());
+
+ if (watcherMonitor) {
+ TableMonitor m = new TableMonitor(440, 440);
+ monitors.add(m);
+ m.show(algo == null ? "Monitor " + name : name + " " + algo.getName());
+ }
+ return monitors;
+ }
+
public void setApodization(ArrayList<AbstractApodization> apos) {
AbstractApodization apoXY = new UniformApodization();
AbstractApodization apoZ = new UniformApodization();
if (apos.size() >= 1)
apoXY = apos.get(0);
if (apos.size() >= 2)
apoZ = apos.get(1);
this.apo = new Apodization(apoXY, apoXY, apoZ);
}
@Override
public void run() {
double chrono = System.nanoTime();
for(DeconvolutionListener listener : listeners)
listener.started();
live = true;
if (monitors != null)
monitors.setVerbose(verbose);
report.add("Path: " + checkPath(path));
monitors.log("Path: " + checkPath(path));
- RealSignal image = openImage();
+ if (!imageLoaded)
+ image = openImage();
+
if (image == null) {
monitors.error("Image: Not valid " + command);
report.add("Image: Not valid");
if (exit)
System.exit(-101);
return;
}
report.add( "Image: " + image.dimAsString());
monitors.log("Image: " + image.dimAsString());
- RealSignal psf = openPSF();
+ if (!imageLoaded)
+ psf = openPSF();
+
if (psf == null) {
monitors.error("PSF: not valid");
report.add("PSF: Not valid");
if (exit)
System.exit(-102);
return;
}
report.add( "PSF: " + psf.dimAsString());
monitors.log("PSF: " + psf.dimAsString());
if (algo == null) {
monitors.error("Algorithm: not valid");
if (exit)
System.exit(-103);
return;
}
if (controller == null) {
monitors.error("Controller: not valid");
if (exit)
System.exit(-104);
return;
}
report.add("FFT: " + fft.getLibraryName());
- algo.setController(controller);
if (outs != null) {
outs.setPath(path);
controller.setOutputs(outs);
}
monitors.log("Algorithm: " + algo.getName());
report.add("Algorithm: " + algo.getName());
-
- RealSignal result = algo.run(monitors, image, psf, fft, pad, apo, norm, true);
-
- if (outs != null)
- outs.executeFinal(monitors, result, controller);
+ algo.setController(controller);
+ result = 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 (watcherDisplay)
Lab.show(monitors, result, "Result of " + algo.getShortname());
if (exit) {
System.out.println("End");
System.exit(0);
}
}
/**
* This methods make a recap of the deconvolution. Useful before starting the processing.
*
* @return list of messages to print
*/
public ArrayList<String> recap() {
ArrayList<String> lines = new ArrayList<String>();
Token image = Command.extract(command, "-image");
if (image == null)
lines.add("<b>Image</b>: <span color=\"red\">keyword -image not found</span>");
else
lines.add("<b>Image</b>: " + image.parameters);
String normf = (norm < 0 ? " (no normalization)" : " (normalization to " + norm + ")");
Token psf = Command.extract(command, "-psf");
if (psf == null)
lines.add("<b>PSF</b>: <span color=\"red\">keyword -psf not found</span>");
else
lines.add("<b>PSF</b>: " + psf.parameters + normf);
if (algo == null) {
lines.add("<b>Algorithm</b>: <span color=\"red\">not valid</span>");
}
else {
- Controller controller = algo.getController();
- String con = ", " + controller.getConstraintAsString() + " constraint";
- lines.add("<b>Algorithm</b>: " + algo.toString() + con);
- lines.add("<b>Stopping Criteria</b>: " + controller.getStoppingCriteria(algo));
+
+ algo.setController(controller);
+ lines.add("<b>Algorithm</b>: " + algo.toString());
+ lines.add("<b>Stopping Criteria</b>: " + controller.getStoppingCriteriaAsString(algo));
lines.add("<b>Reference</b>: " + controller.getReference());
- lines.add("<b>Stats</b>: " + controller.getShowStats() + " " + controller.getSaveStats());
+ lines.add("<b>Constraint</b>: " + controller.getConstraintAsString());
lines.add("<b>Padding</b>: " + pad.toString());
lines.add("<b>Apodization</b>: " + apo.toString());
if (algo.getFFT() != null)
lines.add("<b>FFT</b>: " + algo.getFFT().getName());
}
lines.add("<b>Path</b>: " + path);
lines.add("<b>Verbose</b>: " + verbose.name().toLowerCase());
lines.add("<b>Monitor</b>: " + (watcherMonitor ? "on" : "off"));
- lines.add("<b>Console</b>: " + (watcherConsole ? "on" : "off"));
lines.add("<b>Final Display</b>: " + (watcherDisplay ? "on" : "off"));
lines.add("<b>Multithreading</b>: " + (watcherMultithreading ? "on" : "off"));
if (outs == null)
lines.add("<b>Outputs</b>: not valid");
else
lines.addAll(outs.getInformation());
return lines;
}
public ArrayList<String> checkAlgo() {
ArrayList<String> lines = new ArrayList<String>();
RealSignal image = openImage();
if (image == null) {
lines.add("No valid input image");
return lines;
}
if (pad == null) {
lines.add("No valid padding");
return lines;
}
if (apo == null) {
lines.add("No valid apodization");
return lines;
}
RealSignal psf = openPSF();
if (psf == null) {
lines.add("No valid PSF");
return lines;
}
if (algo == null) {
lines.add("No valid algorithm");
return lines;
}
- Controller controller = algo.getController();
+ if (controller == null) {
+ lines.add("No valid controller");
+ return lines;
+ }
+ algo.setController(controller);
int iter = controller.getIterationMax();
- algo.getController().setIterationMax(1);
+ controller.setIterationMax(1);
RealSignal x = algo.run(monitors, image, psf, fft, pad, apo, norm, true);
Lab.show(monitors, x, "Estimate after 1 iteration");
lines.add("Time: " + NumFormat.seconds(controller.getTimeNano()));
lines.add("Peak Memory: " + controller.getMemoryAsString());
controller.setIterationMax(iter);
return lines;
}
public ArrayList<String> checkImage() {
ArrayList<String> lines = new ArrayList<String>();
RealSignal image = openImage();
if (image == null) {
lines.add("No valid input image");
return lines;
}
if (pad == null) {
lines.add("No valid padding");
return lines;
}
if (apo == null) {
lines.add("No valid apodization");
return lines;
}
RealSignal signal = pad.pad(monitors, getApodization().apodize(monitors, image));
lines.add("<b>Image</b>");
lines.add("Original size " + image.dimAsString() + " padded to " + signal.dimAsString());
lines.add("Original: " + formatStats(image));
lines.add("Preprocessing: " + formatStats(signal));
Lab.show(monitors, signal, "Image");
return lines;
}
public ArrayList<String> checkPSF() {
ArrayList<String> lines = new ArrayList<String>();
RealSignal image = openImage();
if (image == null) {
lines.add("No valid input image");
return lines;
}
if (pad == null) {
lines.add("No valid padding");
return lines;
}
if (apo == null) {
lines.add("No valid apodization");
return lines;
}
RealSignal psf = openPSF();
if (psf == null) {
lines.add("No valid PSF");
return lines;
}
RealSignal signal = pad.pad(monitors, getApodization().apodize(monitors, image));
RealSignal h = psf.changeSizeAs(signal);
lines.add("<b>PSF</b>");
lines.add("Original size " + psf.dimAsString() + " padded to " + h.dimAsString());
String e = NumFormat.nice(h.getEnergy());
h.normalize(norm);
lines.add("Original: " + formatStats(psf));
lines.add("Preprocessing: " + formatStats(h));
lines.add("Energy = " + e + " and after normalization=" + NumFormat.nice(h.getEnergy()));
Lab.show(monitors, h, "Padded and Normalized PSF");
return lines;
}
public ArrayList<String> getDeconvolutionReports() {
return report;
}
public String getName() {
return name;
}
public boolean isLive() {
return live;
}
public void abort() {
live = false;
algo.getController().abort();
}
public Padding getPadding() {
return pad;
}
public Apodization getApodization() {
return apo;
}
public OutputCollection getOuts() {
return outs;
}
public AbstractAlgorithm getAlgo() {
return algo;
}
public String getPath() {
return path;
}
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;
}
private static String formatStats(RealSignal x) {
float stats[] = x.getStats();
String s = " mean=" + NumFormat.nice(stats[0]);
s += " stdev=" + NumFormat.nice(stats[1]);
s += " min=" + NumFormat.nice(stats[3]);
s += " max=" + NumFormat.nice(stats[2]);
return s;
}
public void addDeconvolutionListener(DeconvolutionListener listener) {
listeners.add(listener);
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java b/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java
index bcb8f27..c7dd629 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java
@@ -1,206 +1,217 @@
/*
* 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;
public AbstractAlgorithm() {
this.controller = new Controller();
}
public abstract String getName();
public abstract String getShortname();
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/Controller.java b/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java
index 5c6a7bb..d7f08f1 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java
@@ -1,381 +1,333 @@
/*
* 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.Lab;
import deconvolutionlab.OutputCollection;
import deconvolutionlab.monitor.Monitors;
import fft.AbstractFFT;
import fft.FFT;
import lab.system.SystemUsage;
import lab.tools.NumFormat;
import signal.Assessment;
import signal.ComplexSignal;
import signal.Constraint;
import signal.RealSignal;
import signal.Signal;
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 doShowStats = false;
- private boolean doSaveStats = false;
private boolean abort = false;
- private int snapshotResidu = 0;
- private int snapshotReference = 0;
- private int snapshotConstraint = 0;
- private int snapshotSaveStats = 0;
- private int snapshotShowStats = 0;
-
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 float statsInput[];
private Monitors monitors = new Monitors();
public Controller() {
constraint = Constraint.Mode.NO;
doResidu = false;
doTime = false;
doReference = false;
doConstraint = false;
- doShowStats = false;
- doSaveStats = false;
}
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(int snapshot, double residuMin) {
+ public void setResiduStop(double residuMin) {
this.doResidu = true;
- this.snapshotResidu = snapshot;
this.residuMin = residuMin;
}
- public void setReference(int snapshot, String referenceName) {
+ public void setReference(String referenceName) {
this.doReference = true;
- this.snapshotReference = snapshot;
this.referenceName = referenceName;
}
- public void setConstraint(int snapshot, Constraint.Mode constraint) {
+ public void setConstraint(Constraint.Mode constraint) {
this.doConstraint = true;
- this.snapshotConstraint = snapshot;
this.constraint = constraint;
}
-
- public void setSaveStats(int snapshot, String name) {
- this.doSaveStats = true;
- this.snapshotSaveStats = snapshot;
- this.savestatsName = name;
- }
-
- public void setShowStats(int snapshot, String name) {
- this.doShowStats = true;
- this.snapshotShowStats = snapshot;
- this.showstatsName = name;
- }
-
+
public void setOutputs(OutputCollection outs) {
this.outs = outs;
}
public void start(RealSignal x) {
this.x = x;
statsInput = x.getStats();
iterations = 0;
timer = new Timer();
timer.schedule(new Updater(), 0, 100);
timeStarting = System.nanoTime();
memoryStarting = SystemUsage.getHeapUsed();
Signal.bytes = 0;
if (doConstraint && x != null)
Constraint.setModel(x);
- if (doReference && snapshotReference >= 1) {
+ if (doReference) {
refImage = new Deconvolution("-image file " + referenceName).openImage();
if (refImage == null)
monitors.error("Impossible to load the reference image " + referenceName);
else
monitors.log("Reference image loaded");
}
- if (doShowStats || doSaveStats)
- if (monitors != null)
- Lab.firstStats(monitors, showstatsName, this, doShowStats, doSaveStats);
+ if (outs != null)
+ outs.executeStarting(monitors, x, this);
this.prevImage = x;
}
public boolean ends(ComplexSignal X) {
- boolean res = doResidu && snapshotResidu >= 1 ? (iterations % snapshotResidu == 0) : false;
- boolean con = doConstraint && snapshotConstraint >= 1 ? (iterations % snapshotConstraint == 0) : false;
- boolean ref = doReference && snapshotReference >= 1 ? (iterations % snapshotReference == 0) : false;
- boolean sav = doSaveStats && snapshotSaveStats >= 1 ? (iterations % snapshotSaveStats == 0) : false;
- boolean shw = doShowStats && snapshotShowStats >= 1 ? (iterations % snapshotShowStats == 0) : false;
boolean out = outs == null ? false : outs.hasShow(iterations);
- if (con || res || ref || sav || shw || out) {
+ if (doConstraint || doResidu || doReference || out) {
if (fft == null)
fft = FFT.createDefaultFFT(monitors, X.nx, X.ny, X.nz);
x = new RealSignal(X.nx, X.ny, X.nz, false);
fft.inverse(X, x);
return ends(x);
}
return ends((RealSignal) null);
}
public boolean ends(RealSignal x) {
this.x = x;
- boolean res = doResidu && snapshotResidu >= 1 ? (iterations % snapshotResidu == 0) : false;
- boolean con = doConstraint && snapshotConstraint >= 1 ? (iterations % snapshotConstraint == 0) : false;
- boolean ref = doReference && snapshotReference >= 1 ? (iterations % snapshotReference == 0) : false;
- boolean sav = doSaveStats && snapshotSaveStats >= 1 ? (iterations % snapshotSaveStats == 0) : false;
- boolean shw = doShowStats && snapshotShowStats >= 1 ? (iterations % snapshotShowStats == 0) : false;
- if (con || res || ref)
- compute(iterations, x, con, res, ref);
-
- if (sav || shw)
- Lab.nextStats(monitors, showstatsName, this, sav, shw);
+ if (doConstraint || doResidu || doReference)
+ compute(iterations, x, doConstraint, doResidu, doReference);
if (outs != null)
- outs.executeIterative(monitors, x, iterations, this);
+ 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) + " Memory: " + NumFormat.bytes(Signal.bytes));
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 (doShowStats || doSaveStats)
- Lab.lastStats(monitors, savestatsName, this, doShowStats, doSaveStats);
+ 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(String name) {
float params[] = null;
if (x != null)
params = x.getStats();
String[] row = new String[15];
row[0] = name;
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";
return row;
}
public double getTimeNano() {
return (System.nanoTime() - timeStarting);
}
public Constraint.Mode getConstraint() {
return constraint;
}
- public String getConstraintAsString() {
- if (!doConstraint)
- return "no";
- if (constraint == Constraint.Mode.NO)
- return "no";
- else
- return constraint.name().toLowerCase();
- }
-
public String getReference() {
return doReference ? referenceName : "no ground-truth";
}
- public String getShowStats() {
- return doShowStats ? showstatsName : "no stats";
- }
-
- public String getSaveStats() {
- return doSaveStats ? savestatsName : "no stats";
+ public String getConstraintAsString() {
+ if (!doConstraint)
+ return "no";
+ if (constraint == null)
+ return "null";
+ return constraint.name().toLowerCase();
}
- public String getStoppingCriteria(AbstractAlgorithm algo) {
- String stop = algo.isIterative() ? " iterations limit=" + getIterationMax() + " " : ", ";
+ 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/ICTM.java b/DeconvolutionLab2/src/deconvolution/algorithm/ICTM.java
index 7e7a7b8..1e4a1fa 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/ICTM.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/ICTM.java
@@ -1,135 +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.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(1, Constraint.Mode.NONNEGATIVE);
+ 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(1, Constraint.Mode.NONNEGATIVE);
+ 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";
}
@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/LandweberPositivity.java b/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivity.java
index 4c888cf..ac7b385 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivity.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivity.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/>.
*/
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(1, Constraint.Mode.NONNEGATIVE);
+ 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(1, Constraint.Mode.NONNEGATIVE);
+ 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+";
}
@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/deconvolutionlab/Constants.java b/DeconvolutionLab2/src/deconvolutionlab/Constants.java
index cabd770..97e9996 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 1]";
+ 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 11.02.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 Dimension dimParameters = new Dimension(88, 25);
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/Lab.java b/DeconvolutionLab2/src/deconvolutionlab/Lab.java
index 5b81719..98222ea 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/Lab.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/Lab.java
@@ -1,364 +1,362 @@
/*
* 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.JFrame;
import deconvolution.algorithm.Controller;
import deconvolutionlab.PlatformImager.ContainerImage;
import deconvolutionlab.monitor.Monitors;
import fft.AbstractFFT;
import fft.AbstractFFTLibrary;
import fft.FFT;
import imagej.IJImager;
import lab.component.CustomizedColumn;
import lab.component.CustomizedTable;
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 PlatformImager imager;
private static Lab instance = null;
private static Platform platform = Platform.IMAGEJ;
private static CustomizedTable tableStats = null;
private static JFrame frameStats = null;
static {
imager = new IJImager();
createStats();
}
private static void createStats() {
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("Image Mean", String.class, 100, false));
columns.add(new CustomizedColumn("Image Minimum", String.class, 100, false));
columns.add(new CustomizedColumn("Image Maximum", String.class, 100, false));
columns.add(new CustomizedColumn("Image Stdev", String.class, 100, false));
columns.add(new CustomizedColumn("Image norm1", String.class, 100, false));
columns.add(new CustomizedColumn("Image norm2", 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("PSNR", String.class, 100, false));
columns.add(new CustomizedColumn("SNR", String.class, 100, false));
columns.add(new CustomizedColumn("Residu", String.class, 100, false));
tableStats = new CustomizedTable(columns, true);
}
public static Platform getPlatform() {
return platform;
}
public static void getInstance(Platform p) {
platform = p;
if (instance == null) {
instance = new Lab();
switch (p) {
case STANDALONE:
imager = new LabImager();
break;
case IMAGEJ:
imager = new IJImager();
break;
case ICY:
imager = new IcyImager();
break;
default:
imager = new LabImager();
break;
}
}
}
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 imager.createContainer(title);
}
public static void append(Monitors monitors, ContainerImage container, RealSignal signal, String title) {
imager.append(container, signal, title);
monitors.log("Add Live Real Signal " + title);
}
public static void append(Monitors monitors, ContainerImage container, RealSignal signal, String title, PlatformImager.Type type) {
imager.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);
imager.show(signal, title);
}
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);
imager.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);
imager.show(signal, title);
}
public static void show(Monitors monitors, RealSignal signal, String title, PlatformImager.Type type) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imager.show(signal, title, type);
}
public static void show(Monitors monitors, RealSignal signal, String title, PlatformImager.Type type, int z) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imager.show(signal, title, type);
}
public static void save(Monitors monitors, RealSignal signal, String filename) {
imager.save(signal, filename);
monitors.log("Save Real Signal " + filename);
}
public static void save(Monitors monitors, RealSignal signal, String filename, PlatformImager.Type type) {
imager.save(signal, filename, type);
monitors.log("Save Real Signal " + filename);
}
- public static void firstStats(Monitors monitors, String name, Controller controller, boolean show, boolean save) {
- if (controller == null)
+ public static void firstStats(Monitors monitors, String name, String[] stats, boolean show, boolean save) {
+ if (stats == null)
return;
Lab.createStats();
if (show) {
frameStats = new JFrame(name);
frameStats.getContentPane().add(tableStats.getPane(600, 200));
frameStats.pack();
frameStats.setVisible(true);
}
- nextStats(monitors, "Start", controller, show, save);
}
- public static void nextStats(Monitors monitors, String name, Controller controller, boolean show, boolean save) {
+ public static void nextStats(Monitors monitors, String name, String[] stats, boolean show, boolean save) {
if (tableStats == null)
return;
- if (controller == null)
+ if (stats == null)
return;
- tableStats.append(controller.stats(name));
+ tableStats.append(stats);
monitors.log("Stats " + name);
if (show && frameStats != null) {
if (!frameStats.isVisible())
frameStats.setVisible(true);
frameStats.requestFocus();
}
}
- public static void lastStats(Monitors monitors, String filename, Controller controller, boolean show, boolean save) {
- if (controller == null)
+ public static void lastStats(Monitors monitors, String filename, String[] stats, boolean show, boolean save) {
+ if (stats == null)
return;
if (tableStats == null)
return;
- nextStats(monitors, "End", controller, show, save);
if (save) {
monitors.log("Stats " + filename);
tableStats.saveCSV(filename + ".csv");
}
}
public static RealSignal open(Monitors monitors, String filename) {
RealSignal signal = imager.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 = imager.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(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;
}
imager.show(signal.createOrthoview(hx, hy, hz), title);
}
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;
imager.show(signal.createOrthoview(hx, hy, hz), title);
}
public static void showMIP(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show MIP " + title + " this image does not exist.");
return;
}
imager.show(signal.createMIP(), title);
}
public static void showMontage(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show Montage " + title + " this image does not exist.");
return;
}
imager.show(signal.createMontage(), title);
}
public static RealSignal create(Monitors monitors, String name) {
RealSignal signal = imager.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 = imager.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 PlatformImager getImager() {
return imager;
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/Output.java b/DeconvolutionLab2/src/deconvolutionlab/Output.java
index 7cb9c24..aa6d7e4 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/Output.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/Output.java
@@ -1,353 +1,378 @@
/*
* 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 deconvolution.algorithm.Controller;
import deconvolutionlab.PlatformImager.ContainerImage;
import deconvolutionlab.monitor.Monitors;
import lab.tools.NumFormat;
import signal.Constraint;
import signal.RealSignal;
public class Output {
public enum View {
- STACK, SERIES, ORTHO, MIP, PLANAR, FIGURE
+ STACK, SERIES, ORTHO, MIP, PLANAR, FIGURE, STATS, PROFILE
};
public enum Dynamic {
INTACT, RESCALED, NORMALIZED, CLIPPED
};
private ContainerImage container = null;
private int px = 0;
private int py = 0;
private int pz = 0;
private boolean center = true;
private String name = "";
private boolean save = true;
private boolean show = true;
private View view = View.STACK;
private PlatformImager.Type type = PlatformImager.Type.FLOAT;
private Dynamic dynamic = Dynamic.INTACT;
private int frequency = 0;
private String path = "";
public Output(View view, int frequency, String param) {
String[] tokens = param.trim().split(" ");
this.view = view;
this.frequency = frequency;
this.name = "";
this.center = true;
this.save = true;
this.show = true;
this.container = Lab.createContainer(Monitors.createDefaultMonitor(), "");
for (int i = 0; i < tokens.length; i++) {
boolean found = false;
String p = tokens[i].trim().toLowerCase();
if (p.startsWith("@")) {
found = true;
}
if (p.startsWith("noshow")) {
show = false;
found = true;
}
if (p.startsWith("nosave")) {
save = false;
found = true;
}
for (Dynamic d : Dynamic.values()) {
if (p.toLowerCase().equals(d.name().toLowerCase())) {
dynamic = d;
found = true;
}
}
for (View v : View.values()) {
if (p.toLowerCase().equals(v.name().toLowerCase())) {
view = v;
found = true;
}
}
for (PlatformImager.Type t : PlatformImager.Type.values()) {
if (p.toLowerCase().equals(t.name().toLowerCase())) {
type = t;
found = true;
}
}
if (p.startsWith("(") && p.endsWith(")")) {
double pos[] = NumFormat.parseNumbers(p);
if (pos.length > 0)
px = (int) Math.round(pos[0]);
if (pos.length > 1)
py = (int) Math.round(pos[1]);
if (pos.length > 2)
pz = (int) Math.round(pos[2]);
found = true;
center = false;
}
if (!found)
name += tokens[i] + " ";
name = name.trim();
}
}
public Output(View view, boolean show, boolean save, int frequency, String name, Dynamic dynamic, PlatformImager.Type type, boolean center) {
this.name = name;
this.show = show;
this.save = save;
this.view = view;
this.type = type;
this.dynamic = dynamic;
this.center = center;
this.frequency = frequency;
}
public Output(View view, boolean show, boolean save, int frequency, String name, Dynamic dynamic, PlatformImager.Type type, int px, int py, int pz) {
this.name = name;
this.show = show;
this.save = save;
this.view = view;
this.type = type;
this.dynamic = dynamic;
this.center = false;
this.px = px;
this.py = py;
this.pz = pz;
this.frequency = frequency;
}
public boolean is(int iterations) {
if (frequency == 0)
return false;
return iterations % frequency == 0;
}
public View getView() {
return view;
}
public String getName() {
return name;
}
public void setPath(String path) {
this.path = path;
}
public int extractFrequency(String param) {
String line = param.trim();
if (!line.startsWith("@"))
line = "@0 " + line;
String parts[] = line.split(" ");
if (parts.length >= 1) {
return (int) Math.round(NumFormat.parseNumber(parts[0], 0));
}
return 0;
}
public void setKeypoint(int px, int py, int pz) {
this.px = px;
this.py = py;
this.pz = pz;
this.center = false;
}
public String[] getAsString() {
String t = (type == PlatformImager.Type.FLOAT ? "" : type.name().toLowerCase());
String d = (dynamic == Dynamic.INTACT ? "" : dynamic.name().toLowerCase());
String k = "";
if (!center)
k = " (" + px + "," + py + "," + pz + ")";
else
k = "";
String sa = save ? "\u2713" : "";
String sh = show ? "\u2713" : "";
String fr = frequency > 0 ? " @" + frequency : "";
return new String[] { view.name().toLowerCase() + fr, name, d, t, k, sh, sa, "" };
}
- public void execute(Monitors monitors, RealSignal signal, Controller controller, int iter, boolean live) {
+ public void executeStarting(Monitors monitors, RealSignal signal, Controller controller) {
+ execute(monitors, signal, controller, true, false, false, 0);
+ }
+
+ public void executeFinal(Monitors monitors, RealSignal signal, Controller controller) {
+ execute(monitors, signal, controller, false, false, true, 0);
+ }
+
+
+ public void executeIterative(Monitors monitors, RealSignal signal, Controller controller, int iter) {
+ execute(monitors, signal, controller, false, true, false, iter);
+ }
+
+ public void execute(Monitors monitors, RealSignal signal, Controller controller, boolean start, boolean live, boolean finish, int iter) {
if (signal == null)
return;
+
String title = name;
if (live)
if (!is(iter))
return;
-
+
if (controller != null && live) {
if (controller.getIterations() > 0) {
title += "@" + controller.getIterations();
}
}
RealSignal x = null;
Constraint constraint = new Constraint(monitors);
-
+
switch (dynamic) {
case RESCALED:
x = signal.duplicate();
constraint.rescaled(x, 0, 255);
break;
case CLIPPED:
x = signal.duplicate();
float[] stats = controller.getStatsInput();
if (stats != null)
constraint.clipped(x, stats[1], stats[2]);
break;
case NORMALIZED:
x = signal.duplicate();
float[] stats1 = controller.getStatsInput();
if (stats1 != null)
constraint.normalized(x, stats1[0], stats1[3]);
break;
default:
x = signal;
}
String filename = path + File.separator + title + ".tif";
switch (view) {
+ case STATS:
+ if (start)
+ Lab.firstStats(monitors, name, controller.stats(name), show, save);
+ Lab.nextStats(monitors, title, controller.stats(name), show, save);
+ if (finish)
+ Lab.lastStats(monitors, name, controller.stats(name), show, save);
+ break;
case STACK:
if (show && !live)
Lab.show(monitors, x, title, type, (center ? x.nz / 2 : pz));
if (save && !live)
Lab.save(monitors, x, filename, type);
break;
case SERIES:
for (int k = 0; k < x.nz; k++) {
RealSignal slice = x.getSlice(k);
if (show && !live)
Lab.show(monitors, slice, title, type);
if (save && !live)
Lab.save(monitors, slice, filename, type);
}
break;
case ORTHO:
- orthoview(monitors, x, title, filename, live);
+ if (!start)
+ orthoview(monitors, x, title, filename, live);
break;
case FIGURE:
- figure(monitors, x, title, filename, live);
+ if (!start)
+ figure(monitors, x, title, filename, live);
break;
case MIP:
- mip(monitors, x, title, filename, live);
+ if (!start)
+ mip(monitors, x, title, filename, live);
break;
case PLANAR:
- planar(monitors, x, title, filename, live);
+ if (!start)
+ planar(monitors, x, title, filename, live);
break;
default:
break;
}
}
private void mip(Monitors monitors, RealSignal signal, String title, String filename, boolean live) {
RealSignal plane = signal.createMIP();
if (show && live) {
Lab.append(monitors, container, plane, title, type);
}
if (show && !live)
Lab.show(monitors, plane, title, type);
if (save)
Lab.save(monitors, plane, filename, type);
}
private void orthoview(Monitors monitors, RealSignal signal, String title, String filename, boolean live) {
int cx = px;
int cy = py;
int cz = pz;
if (center) {
cx = signal.nx / 2;
cy = signal.ny / 2;
cz = signal.nz / 2;
}
RealSignal plane = signal.createOrthoview(cx, cy, cz);
if (show && live) {
if (container == null)
container = Lab.createContainer(monitors, title);
Lab.append(monitors, container, plane, title, type);
}
if (show && !live)
Lab.show(monitors, plane, title, type);
if (save)
Lab.save(monitors, plane, filename, type);
}
private void figure(Monitors monitors, RealSignal signal, String title, String filename, boolean live) {
int cx = px;
int cy = py;
int cz = pz;
if (center) {
cx = signal.nx / 2;
cy = signal.ny / 2;
cz = signal.nz / 2;
}
RealSignal plane = signal.createFigure(cx, cy, cz);
if (show && live) {
if (container == null)
container = Lab.createContainer(monitors, title);
Lab.append(monitors, container, plane, title, type);
}
if (show && !live)
Lab.show(monitors, plane, title, type);
if (save)
Lab.save(monitors, plane, filename, type);
}
private void planar(Monitors monitors, RealSignal signal, String title, String filename, boolean live) {
RealSignal plane = signal.createMontage();
if (show && live) {
if (container == null)
container = Lab.createContainer(monitors, title);
Lab.append(monitors, container, plane, title, type);
}
if (show && !live)
Lab.show(monitors, plane, title, type);
if (save)
Lab.save(monitors, plane, filename, type);
}
@Override
public String toString() {
String t = type.name().toLowerCase();
String v = view.name().toLowerCase();
String d = dynamic.name().toLowerCase();
String f = frequency > 0 ? " every " + frequency + " iterations" : "";
String k = (center ? "" : " keypoint = (" + px + "," + py + "," + pz + ")");
return v + " " + name + " format = (" + d + ", " + t + ") " + k + f;
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/OutputCollection.java b/DeconvolutionLab2/src/deconvolutionlab/OutputCollection.java
index 910648f..b7a5581 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/OutputCollection.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/OutputCollection.java
@@ -1,86 +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 deconvolutionlab;
import java.util.ArrayList;
import deconvolution.algorithm.Controller;
import deconvolutionlab.monitor.Monitors;
import signal.RealSignal;
public class OutputCollection {
private ArrayList<Output> list = new ArrayList<Output>();
public void setPath(String path) {
for (Output out : list)
out.setPath(path);
}
public void add(Output out) {
if (out != null) {
list.add(out);
}
}
public boolean hasShow(int iterations) {
boolean flag = false;
for (Output out : list)
flag = flag | out.is(iterations);
return flag;
}
+ public void executeStarting(Monitors monitors, RealSignal signal, Controller controller) {
+ for (Output out : list)
+ if (out != null)
+ out.executeStarting(monitors, signal, controller);
+ }
+
public void executeFinal(Monitors monitors, RealSignal signal, Controller controller) {
for (Output out : list)
if (out != null)
- out.execute(monitors, signal, controller, 0, false);
+ out.executeFinal(monitors, signal, controller);
}
- public void executeIterative(Monitors monitors, RealSignal signal, int iter, Controller controller) {
+ public void executeIterative(Monitors monitors, RealSignal signal, Controller controller, int iter) {
for (Output out : list)
if (out != null)
- out.execute(monitors, signal, controller, iter, true);
+ out.executeIterative(monitors, signal, controller, iter);
}
public ArrayList<String> getInformation() {
ArrayList<String> lines = new ArrayList<String>();
for (Output out : list) {
if (out == null)
lines.add("ERR>" + list.size());
else
lines.add("" + out.toString());
}
return lines;
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/dialog/LabDialog.java b/DeconvolutionLab2/src/deconvolutionlab/dialog/LabDialog.java
index 07f97e1..bef50a5 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/dialog/LabDialog.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/dialog/LabDialog.java
@@ -1,369 +1,362 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab.dialog;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
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 java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
+import java.io.File;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
+import javax.swing.JTextField;
+import javax.swing.JToolBar;
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.Constants;
import deconvolutionlab.Lab;
import deconvolutionlab.Platform;
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.PathModule;
import deconvolutionlab.modules.WatcherModule;
import lab.component.JPanelImage;
import lab.system.SystemPanel;
+import lab.tools.Files;
public class LabDialog extends JDialog implements ComponentListener, ActionListener, ChangeListener, WindowListener {
private JTabbedPane tab = new JTabbedPane();
private JButton bnHelp = new JButton("Help");
private JButton bnClose = new JButton("Close");
private JButton bnQuit = new JButton("Quit");
private JButton bnBatch = new JButton("Batch");
private JButton bnRun = new JButton("Run");
private JButton bnLaunch = new JButton("Launch");
- private JButton bnSystem = new JButton("System");
-
+
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 WatcherModule watcher;
private ControllerModule controller;
private GroupedModulePanel panelDeconv;
private GroupedModulePanel panelAdvanc;
private GroupedModulePanel panelScript;
private GroupedModulePanel panelAbout;
private AbstractModule modules[];
public LabDialog() {
super(new JFrame(), Constants.name);
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();
watcher = new WatcherModule(false);
doDialog();
- modules = new AbstractModule[] { image, psf, algo, output, controller, border, fourier, watcher, batch };
+ modules = new AbstractModule[] {image, psf, algo, output, controller, border, fourier, watcher, batch };
Command.active(modules, command);
Command.command();
addWindowListener(this);
addComponentListener(this);
((GroupedModulePanel) tab.getSelectedComponent()).organize();
setMinimumSize(new Dimension(500, 500));
Config.registerFrame("DeconvolutionLab", "MainDialog", this);
pack();
setVisible(true);
Config.load();
sizeModule();
Command.command();
image.update();
psf.update();
output.update();
}
private void doDialog() {
panelDeconv = new GroupedModulePanel(buildDeconvolutionPanel(), this);
panelAdvanc = new GroupedModulePanel(buildAdvancedPanel(), this);
panelScript = new GroupedModulePanel(buildProgrammingPanel(), this);
panelAbout = new GroupedModulePanel(buildAboutPanel(), this);
+ Border b2 = BorderFactory.createEmptyBorder(5, 5, 5, 5);
JPanelImage bottom = new JPanelImage("celegans.jpg");
- bottom.setLayout(new GridLayout(1, 7));
- Border b2 = BorderFactory.createEmptyBorder(10, 10, 10, 10);
+ bottom.setBorder(b2);
+
+ bottom.setLayout(new GridLayout(1, 5));
bottom.setBorder(b2);
bottom.add(bnHelp);
- bottom.add(bnSystem);
- //bottom.add(bnQuit);
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);
- JPanel base = new JPanel(new BorderLayout());
- base.add(bottom, BorderLayout.CENTER);
- //base.add(statusBar, BorderLayout.SOUTH);
- //PanelImage pi = new PanelImage("logo.png", 380, 75);
- //pi.setPreferredSize(new Dimension(400, 75));
- //add(pi, BorderLayout.NORTH);
add(tab, BorderLayout.CENTER);
- add(base, BorderLayout.SOUTH);
-
+ 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);
-
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == bnHelp) {
Lab.help();
}
- else if (e.getSource() == bnSystem) {
- SystemPanel.show(400, 400);
- }
else if (e.getSource() == bnClose) {
Config.store();
dispose();
}
else if (e.getSource() == bnQuit) {
dispose();
}
else if (e.getSource() == bnBatch) {
tab.setSelectedIndex(2);
batch.expand();
sizeModule();
new BatchDialog(batch);
}
else if (e.getSource() == bnLaunch) {
new Deconvolution(Command.command()).launch("", false);
}
else if (e.getSource() == bnRun) {
new Deconvolution(Command.command()).deconvolve(false);
}
}
@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(watcher);
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;
}
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
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) {
}
private void close() {
for (AbstractModule module : modules)
module.close();
bnLaunch.removeActionListener(this);
bnRun.removeActionListener(this);
bnBatch.removeActionListener(this);
bnClose.removeActionListener(this);
bnHelp.removeActionListener(this);
removeWindowListener(this);
}
@Override
public void dispose() {
super.dispose();
if (Lab.getPlatform() == Platform.STANDALONE) System.exit(0);
}
@Override
public void componentResized(ComponentEvent e) {
sizeModule();
}
@Override
public void componentMoved(ComponentEvent e) {
Point p = this.getLocation();
p.x += this.getWidth();
DeconvolutionDialog.setLocationLaunch(p);
}
@Override
public void componentShown(ComponentEvent e) {
sizeModule();
}
@Override
public void componentHidden(ComponentEvent e) {
}
-
+
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/modules/ControllerModule.java b/DeconvolutionLab2/src/deconvolutionlab/modules/ControllerModule.java
index cc09c44..51b1bb8 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/modules/ControllerModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/modules/ControllerModule.java
@@ -1,308 +1,252 @@
/*
* 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.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import deconvolution.Command;
import deconvolution.Deconvolution;
import deconvolutionlab.Config;
import lab.component.GridPanel;
-import lab.component.SpinnerRangeInteger;
import lab.tools.Files;
import signal.Constraint;
public class ControllerModule extends AbstractModule implements ActionListener, ChangeListener, KeyListener {
private JButton bnBrowse;
private JTextField txtReference;
private JTextField txtResidu;
- private JTextField txtSaveStats;
- private JTextField txtShowStats;
+ private JTextField txtTime;
+ private JTextField txtIterations;
+
private JComboBox<String> cmbConstraint;
private JCheckBox chkResidu;
private JCheckBox chkReference;
private JCheckBox chkConstraint;
- private JCheckBox chkSaveStats;
- private JCheckBox chkShowStats;
-
- private SpinnerRangeInteger snapshotResidu;
- private SpinnerRangeInteger snapshotConstraint;
- private SpinnerRangeInteger snapshotReference;
- private SpinnerRangeInteger snapshotSaveStats;
- private SpinnerRangeInteger snapshotShowStats;
+ private JCheckBox chkTime;
+ private JCheckBox chkItermax;
public ControllerModule(boolean expanded) {
super("Controller", "", "Default", "", expanded);
}
@Override
public String getCommand() {
String cmd = "";
- int sr = snapshotResidu.get();
- int sc = snapshotConstraint.get();
- int sg = snapshotReference.get();
- int ss = snapshotSaveStats.get();
- int sd = snapshotShowStats.get();
-
if (chkConstraint.isSelected())
- cmd += "-constraint " + (sc > 1 ? "@" + sc + " ": "") + cmbConstraint.getSelectedItem() + " ";
+ cmd += "-constraint " + cmbConstraint.getSelectedItem() + " ";
if (chkReference.isSelected())
- cmd += "-reference " + (sg > 1 ? "@" + sg + " " : "") + txtReference.getText() + " ";
+ cmd += "-reference " + txtReference.getText() + " ";
if (chkResidu.isSelected())
- cmd += "-residu " + (sr > 1 ? "@" + sr + " " : "") + txtResidu.getText() + " ";
- if (chkSaveStats.isSelected())
- cmd += "-savestats " + (ss > 1 ? "@" + ss + " " : "") + txtSaveStats.getText() + " ";
- if (chkShowStats.isSelected())
- cmd += "-showstats " + (sd > 1 ? "@" + sd + " " : "") + txtShowStats.getText() + " ";
+ cmd += "-residu " + txtResidu.getText() + " ";
+ if (chkTime.isSelected())
+ cmd += "-time " + txtTime.getText() + " ";
return cmd;
}
@Override
public JPanel buildExpandedPanel() {
- snapshotResidu = new SpinnerRangeInteger(10, 1, 99999, 1, "###");
- snapshotConstraint = new SpinnerRangeInteger(10, 1, 99999, 1, "###");
- snapshotReference = new SpinnerRangeInteger(10, 1, 99999, 1, "###");
- snapshotSaveStats = new SpinnerRangeInteger(10, 1, 99999, 1, "###");
- snapshotShowStats = new SpinnerRangeInteger(10, 1, 99999, 1, "###");
+ chkTime = new JCheckBox("Time Limitation (s)");
+ chkItermax = new JCheckBox("Early Stopping");
chkConstraint = new JCheckBox("Constraint");
chkResidu = new JCheckBox("Residu Minimun");
chkReference = new JCheckBox("Reference");
- chkSaveStats = new JCheckBox("Save Stats");
- chkShowStats = new JCheckBox("Show Stats");
bnBrowse = new JButton("Browse");
txtReference = new JTextField("");
txtResidu = new JTextField("0.01");
- txtSaveStats = new JTextField("stats");
- txtShowStats = new JTextField("stats");
-
+ txtTime = new JTextField("3600");
+ txtIterations = new JTextField("Iteration max (mandatory)");
+ txtIterations.setEditable(false);
+
cmbConstraint = new JComboBox<String>(Constraint.getContraintsAsArray());
txtReference.setPreferredSize(new Dimension(200, 20));
GridPanel pn = new GridPanel(true);
-
+
+ pn.place(0, 0, chkItermax);
+ pn.place(0, 1, txtIterations);
pn.place(1, 0, chkResidu);
pn.place(1, 1, txtResidu);
- pn.place(1, 2, snapshotResidu);
-
pn.place(4, 0, chkConstraint);
pn.place(4, 1, cmbConstraint);
- pn.place(4, 2, snapshotConstraint);
-
- pn.place(5, 0, chkSaveStats);
- pn.place(5, 1, txtSaveStats);
- pn.place(5, 2, snapshotSaveStats);
-
- pn.place(6, 0, chkShowStats);
- pn.place(6, 1, txtShowStats);
- pn.place(6, 2, snapshotShowStats);
-
+ pn.place(5, 0, chkTime);
+ pn.place(5, 1, txtTime);
pn.place(7, 0, chkReference);
pn.place(7, 1, txtReference);
- pn.place(7, 2, snapshotReference);
pn.place(8, 0, "Ground-truth file");
pn.place(8, 1, bnBrowse);
Border b1 = BorderFactory.createEtchedBorder();
Border b2 = BorderFactory.createEmptyBorder(10, 10, 10, 10);
pn.setBorder(BorderFactory.createCompoundBorder(b1, b2));
JScrollPane scroll = new JScrollPane(pn);
scroll.setBorder(BorderFactory.createEmptyBorder());
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEtchedBorder());
panel.add(scroll, BorderLayout.NORTH);
- bnBrowse.addActionListener(this);
+
+ Config.register(getName(), "residu.enable", chkResidu, false);
+ Config.register(getName(), "reference.enable", chkReference, false);
+ Config.register(getName(), "constraint.enable", chkConstraint, false);
+ Config.register(getName(), "time.enable", chkTime, false);
+ Config.register(getName(), "itmax.enable", chkItermax, true);
+
+ Config.register(getName(), "reference.value", txtReference, "");
+ Config.register(getName(), "residu.value", txtResidu, "0.01");
+ Config.register(getName(), "time.value", txtTime, "3600");
+ Config.register(getName(), "constraint.value", cmbConstraint, "No");
+ chkItermax.setSelected(true);
+
+ bnBrowse.addActionListener(this);
chkResidu.addChangeListener(this);
chkReference.addChangeListener(this);
chkConstraint.addChangeListener(this);
- chkSaveStats.addChangeListener(this);
- chkShowStats.addChangeListener(this);
-
- snapshotResidu.addChangeListener(this);
- snapshotConstraint.addChangeListener(this);
- snapshotReference.addChangeListener(this);
- snapshotShowStats.addChangeListener(this);
- snapshotSaveStats.addChangeListener(this);
+ chkTime.addChangeListener(this);
+ chkItermax.addChangeListener(this);
txtResidu.addKeyListener(this);
txtReference.addKeyListener(this);
- txtSaveStats.addKeyListener(this);
- txtShowStats.addKeyListener(this);
+ txtTime.addKeyListener(this);
cmbConstraint.addActionListener(this);
getAction1Button().addActionListener(this);
-
- Config.register(getName(), "residu.enable", chkResidu, false);
- Config.register(getName(), "reference.enable", chkReference, false);
- Config.register(getName(), "constraint.enable", chkConstraint, false);
- Config.register(getName(), "showstats.enable", chkShowStats, false);
- Config.register(getName(), "savestats.enable", chkSaveStats, false);
-
- Config.register(getName(), "reference.value", txtReference, "");
- Config.register(getName(), "residu.value", txtResidu, "0.01");
- Config.register(getName(), "showstats.value", txtShowStats, "Stats");
- Config.register(getName(), "savestats.value", txtSaveStats, "Stats");
- Config.register(getName(), "constraint.value", cmbConstraint, "No");
-
- Config.register(getName(), "residu.snapshot", snapshotResidu, "1");
- Config.register(getName(), "reference.snapshot", snapshotConstraint, "1");
- Config.register(getName(), "constraint.snapshot", snapshotReference, "1");
- Config.register(getName(), "showstats.snapshot", snapshotShowStats, "1");
- Config.register(getName(), "savestats.snapshot", snapshotSaveStats, "1");
+
return panel;
}
private void update() {
+ chkItermax.setSelected(true);
setCommand(getCommand());
int count = 0;
count += (chkResidu.isSelected() ? 1 : 0);
- count += (chkReference.isSelected() ? 1 : 0);
count += (chkConstraint.isSelected() ? 1 : 0);
- count += (chkSaveStats.isSelected() ? 1 : 0);
- count += (chkShowStats.isSelected() ? 1 : 0);
- setSynopsis("" + count + (count >= 2 ? " controls" : " control "));
+ count += (chkTime.isSelected() ? 1 : 0);
+ count += (chkItermax.isSelected() ? 1 : 0);
+ setSynopsis("" + count + " stopping criteria");
Command.command();
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
if (e.getSource() == bnBrowse) {
Deconvolution deconvolution = new Deconvolution(Command.command());
File file = Files.browseFile(deconvolution.getPath());
if (file != null)
txtReference.setText(file.getAbsolutePath());
}
if (e.getSource() == getAction1Button()) {
chkResidu.removeChangeListener(this);
chkReference.removeChangeListener(this);
chkConstraint.removeChangeListener(this);
- chkSaveStats.removeChangeListener(this);
- chkShowStats.removeChangeListener(this);
-
- snapshotResidu.removeChangeListener(this);
- snapshotConstraint.removeChangeListener(this);
- snapshotReference.removeChangeListener(this);
- snapshotShowStats.removeChangeListener(this);
- snapshotSaveStats.removeChangeListener(this);
+ chkTime.removeChangeListener(this);
+ chkItermax.removeChangeListener(this);
chkResidu.setSelected(false);
chkReference.setSelected(false);
chkConstraint.setSelected(false);
- chkShowStats.setSelected(false);
- chkSaveStats.setSelected(false);
+ chkTime.setSelected(false);
+ chkItermax.setSelected(true);
txtReference.setText("");
txtResidu.setText("0.01");
- txtShowStats.setText("Stats");
- txtSaveStats.setText("Stats");
+ txtTime.setText("3600");
cmbConstraint.setSelectedIndex(0);
- snapshotResidu.set(1);
- snapshotConstraint.set(1);
- snapshotReference.set(1);
- snapshotShowStats.set(1);
- snapshotSaveStats.set(1);
-
- chkResidu.addChangeListener(this);
+
+ chkResidu.addChangeListener(this);
chkReference.addChangeListener(this);
chkConstraint.addChangeListener(this);
- chkSaveStats.addChangeListener(this);
- chkShowStats.addChangeListener(this);
-
- snapshotResidu.addChangeListener(this);
- snapshotConstraint.addChangeListener(this);
- snapshotReference.addChangeListener(this);
- snapshotShowStats.addChangeListener(this);
- snapshotSaveStats.addChangeListener(this);
+ chkTime.addChangeListener(this);
+ chkItermax.addChangeListener(this);
}
update();
}
@Override
public void stateChanged(ChangeEvent e) {
update();
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
update();
}
@Override
public void close() {
bnBrowse.removeActionListener(this);
chkReference.removeChangeListener(this);
chkResidu.removeChangeListener(this);
- chkConstraint.removeChangeListener(this);
- chkShowStats.removeChangeListener(this);
- chkSaveStats.removeChangeListener(this);
+ chkConstraint.removeChangeListener(this);
+ chkItermax.removeChangeListener(this);
+ chkTime.removeChangeListener(this);
getAction1Button().removeChangeListener(this);
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/modules/LanguageModule.java b/DeconvolutionLab2/src/deconvolutionlab/modules/LanguageModule.java
index d846d99..6519392 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/modules/LanguageModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/modules/LanguageModule.java
@@ -1,211 +1,249 @@
/*
* 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.FlowLayout;
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);
}
@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 FlowLayout());
- pn.add(txt);
- pn.add(cmb);
- pn.add(gui);
+ 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();
- String text = "Matlab code, not yet implemented";
- language.append("p", text);
+ 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(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 + " </p>";
- macro += "<p>// Macro generated by DeconvolutionLab2 </p>";
- macro += "<p>// " + new SimpleDateFormat("dd/MM/yy HH:m:s").format(new Date()) + " </p>";
- String param = "<p>parameters = \"\"</p>";
+ 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 \" ";
+ 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() + "\" </p>";
+ image = p("image = \" -image " + token.parameters.trim() + "\" ");
else if (token.keyword.equals("-psf"))
- psf = "<p>psf = \" -psf " + token.parameters.trim() + "\" </p>";
+ psf = p("psf = \" -psf " + token.parameters.trim() + "\" ");
else if (token.keyword.equals("-algorithm"))
- algo = "<p>algorithm = \" -algorithm " + token.parameters.trim() + "\" </p>";
+ algo = p("algorithm = \" -algorithm " + token.parameters.trim() + "\" ");
else
- param += "<p>parameters += \" " + token.keyword + " " + token.parameters.trim() + "\" </p>";
+ 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)</p>";
+ cmd = p("run(\"DeconvolutionLab2 Run\", image + psf + algorithm + parameters)");
else
- cmd = "<p>run(\"DeconvolutionLab2 Launch\", image + psf + algorithm + parameters)</p>";
+ cmd = p("run(\"DeconvolutionLab2 Launch\", image + psf + algorithm + parameters)");
return option + cmd;
}
private String java(boolean headless) {
String job = txt.getText();
- String p = headless ? ".deconvolve(false);" : ".launch(\"" + job + "\", false);";
- String tab1 = "<p style=\"padding-left:10px\">";
- String tab2 = "<p style=\"padding-left:20px\">";
String code = "";
- code += "<p>import deconvolution.Deconvolution;</p>";
- code += "<p>import ij.plugin.PlugIn;</p>";
- code += "<p></p>";
+ code += p("import deconvolution.Deconvolution;");
+ code += p("import ij.plugin.PlugIn;");
+ code += p("");
- code += "<p>public class DeconvolutionLab2_" + job + " implements PlugIn {</p>";
- code += tab1 + "public DeconvolutionLab2_" + job + "() {</p>";
+ code += p("public class DeconvolutionLab2_" + job + " implements PlugIn {");
+ code += p1("public DeconvolutionLab2_" + job + "() {");
- String param = tab2 + "String parameters = \"\";</p>";
+ String param = p2("String parameters = \"\";");
ArrayList<Token> tokens = Command.parse(Command.command());
- String image = tab2 + "String image = \" NOT DEFINED \";";
- String psf = tab2 + "String psf = \" NOT DEFINED \";";
- String algo = tab2 + "String algo = \" NOT DEFINED \";";
+ 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 = tab2 + "String image = \" -image " + token.parameters.trim() + "\";</p>";
+ image = p2("String image = \" -image " + token.parameters.trim() + "\";");
else if (token.keyword.equals("-psf"))
- psf = tab2 + "String psf = \" -psf " + token.parameters.trim() + "\";</p>";
+ psf = p2("String psf = \" -psf " + token.parameters.trim() + "\";");
else if (token.keyword.equals("-algorithm"))
- algo = tab2 + "String algorithm = \" -algorithm " + token.parameters.trim() + "\";</p>";
+ algo = p2("String algorithm = \" -algorithm " + token.parameters.trim() + "\";");
else
- param += tab2 + "parameters += \" " + token.keyword + " " + token.parameters.trim() + "\";</p>";
+ param += p2("parameters += \" " + token.keyword + " " + token.parameters.trim() + "\";");
}
code += image + psf + algo + param;
- code += tab2 + "new Deconvolution(image + psf + algorithm + parameters)" + p;
- code += tab1 + "}</p>";
+ code += p2("new Deconvolution(image + psf + algorithm + parameters)");
+ code += p1("}");
- code += tab1 + "<p></p>";
+ code += p1("");
- code += tab1 + "@Override</p>";
- code += tab1 + "public void run(String arg0) {</p>";
- code += tab2 + " new DeconvolutionLab2_" + job + "();</p>";
+ code += p1("@Override");
+ code += p1("public void run(String arg0) {");
+ code += p2(" new DeconvolutionLab2_" + job + "();");
- code += tab1 + "}</p>";
- code += "<p>}</p>";
+ 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/OutputModule.java b/DeconvolutionLab2/src/deconvolutionlab/modules/OutputModule.java
index 146bff8..8b381c8 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/modules/OutputModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/modules/OutputModule.java
@@ -1,239 +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.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 lab.component.CustomizedColumn;
import lab.component.CustomizedTable;
import deconvolution.Command;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
import deconvolutionlab.Output;
import deconvolutionlab.Output.View;
import deconvolutionlab.dialog.OutputDialog;
public class OutputModule extends AbstractModule implements ActionListener, MouseListener {
private CustomizedTable table;
private JButton bnStack;
private JButton bnSeries;
private JButton bnMIP;
private JButton bnOrtho;
private JButton bnPlanar;
private JButton bnFigure;
-
+ private JButton bnStats;
+ private JButton bnProfile;
public OutputModule(boolean expanded) {
super("Output", "", "", "Default", expanded);
}
@Override
public String getCommand() {
String cmd = " ";
if (table == null)
return cmd;
for (int i = 0; i < table.getRowCount(); i++) {
String[] values = new String[table.getColumnCount()];
for(int c=0; c<table.getColumnCount(); c++)
values[c] = table.getCell(i, c) == null ? "" : table.getCell(i, c).trim();
cmd += " -out " + values[0] + " " + values[1] + " " + values[2] + " " + values[3] + " " + values[4];
if (values[5].equals(""))
cmd += " noshow";
if (values[6].equals(""))
cmd += " nosave";
}
return cmd;
}
public void update() {
setCommand(getCommand());
setSynopsis(table.getRowCount() + " output" + (table.getRowCount() > 1 ? "s" : ""));
Command.command();
getAction1Button().setEnabled(table.getRowCount() > 0);
}
@Override
public JPanel buildExpandedPanel() {
String[] dynamics = { "intact", "rescaled", "normalized", "clipped" };
String[] types = { "float", "short", "byte" };
ArrayList<CustomizedColumn> columns = new ArrayList<CustomizedColumn>();
columns.add(new CustomizedColumn("Mode", String.class, 80, false));
columns.add(new CustomizedColumn("Name", String.class, Constants.widthGUI, true));
columns.add(new CustomizedColumn("Dynamic", String.class, 100, dynamics, "Select the dynamic range"));
columns.add(new CustomizedColumn("Type", String.class, 100, types, "Select the type"));
columns.add(new CustomizedColumn("Keypoint", String.class, 120, false));
columns.add(new CustomizedColumn("Show", String.class, 50, false));
columns.add(new CustomizedColumn("Save", String.class, 50, false));
columns.add(new CustomizedColumn("Del", String.class, 30, "\u232B", "Delete this image source"));
table = new CustomizedTable(columns, true);
table.getColumnModel().getColumn(5).setMaxWidth(50);
table.getColumnModel().getColumn(6).setMaxWidth(50);
table.getColumnModel().getColumn(7).setMaxWidth(30);
table.getColumnModel().getColumn(0).setMaxWidth(100);
table.getColumnModel().getColumn(2).setMaxWidth(100);
table.getColumnModel().getColumn(3).setMaxWidth(100);
table.addMouseListener(this);
bnStack = new JButton("\u2295 stack");
bnSeries = new JButton("\u2295 series");
bnMIP = new JButton("\u2295 mip");
bnOrtho = new JButton("\u2295 ortho");
bnPlanar = new JButton("\u2295 planar");
+ bnStats = new JButton("\u2295 stats");
+ bnProfile = new JButton("\u2295 profile");
bnFigure = new JButton("\u2295 figure");
JToolBar pn = new JToolBar("Controls Image");
pn.setBorder(BorderFactory.createEmptyBorder());
pn.setLayout(new GridLayout(1, 6));
pn.setFloatable(false);
pn.add(bnStack);
pn.add(bnSeries);
pn.add(bnMIP);
pn.add(bnOrtho);
pn.add(bnPlanar);
pn.add(bnFigure);
+ pn.add(bnStats);
+ pn.add(bnProfile);
JToolBar tool = new JToolBar("Path");
tool.setBorder(BorderFactory.createEmptyBorder());
tool.setLayout(new BorderLayout());
tool.setFloatable(false);
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createEtchedBorder());
panel.setLayout(new BorderLayout());
panel.add(tool, BorderLayout.NORTH);
panel.add(pn, BorderLayout.SOUTH);
panel.add(table.getMinimumPane(100, 100), BorderLayout.CENTER);
bnStack.addActionListener(this);
bnSeries.addActionListener(this);
bnMIP.addActionListener(this);
bnOrtho.addActionListener(this);
bnPlanar.addActionListener(this);
bnFigure.addActionListener(this);
+ bnStats.addActionListener(this);
+ bnProfile.addActionListener(this);
getAction1Button().addActionListener(this);
Config.registerTable(getName(), "output", table);
return panel;
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
View view = null;
if (e.getSource() == bnStack)
view = View.STACK;
else if (e.getSource() == bnSeries)
view = View.SERIES;
else if (e.getSource() == bnMIP)
view = View.MIP;
else if (e.getSource() == bnOrtho)
view = View.ORTHO;
else if (e.getSource() == bnPlanar)
view = View.PLANAR;
else if (e.getSource() == bnFigure)
view = View.FIGURE;
+ else if (e.getSource() == bnStats)
+ view = View.STATS;
+ else if (e.getSource() == bnProfile)
+ view = View.PROFILE;
if (view != null) {
OutputDialog dlg = new OutputDialog(view);
if (dlg.wasCancel())
return;
Output out = dlg.getOut();
if (out == null)
System.out.println("Out is null");
else
table.insert(out.getAsString());
update();
}
if (e.getSource() == getAction1Button()) {
int n = table.getRowCount();
for (int i=0; i<n; i++)
table.removeRow(0);
String[] def = new String[] { "stack", "display", "intact", "float", "", "true", "false", "" };
-System.out.println("Default " + n);
table.append(def);
}
}
@Override
public void mouseClicked(MouseEvent e) {
int row = table.getSelectedRow();
if (table.getSelectedColumn() == 7) {
table.removeRow(row);
if (table.getRowCount() > 0)
table.setRowSelectionInterval(0, 0);
}
update();
Command.command();
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void close() {
bnStack.removeActionListener(this);
bnSeries.removeActionListener(this);
bnMIP.removeActionListener(this);
bnOrtho.removeActionListener(this);
bnPlanar.removeActionListener(this);
bnFigure.removeActionListener(this);
+ bnStats.removeActionListener(this);
+ bnProfile.removeActionListener(this);
getAction1Button().removeActionListener(this);
getAction2Button().removeActionListener(this);
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/modules/WatcherModule.java b/DeconvolutionLab2/src/deconvolutionlab/modules/WatcherModule.java
index 580553f..d78bf37 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/modules/WatcherModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/modules/WatcherModule.java
@@ -1,208 +1,196 @@
/*
* 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.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import javax.swing.BoxLayout;
import javax.swing.JButton;
-import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JTextField;
import deconvolution.Command;
import deconvolutionlab.Config;
+import ij.IJ;
import lab.component.GridPanel;
+import lab.system.SystemPanel;
import lab.tools.Files;
public class WatcherModule extends AbstractModule implements ActionListener, KeyListener {
- private JTextField txtTime;
+ private JComboBox<String> cmbVerbose;
+ private JComboBox<String> cmbMonitor;
+ private JComboBox<String> cmbDisplay;
+ private JComboBox<String> cmbMultithreading;
+ private JComboBox<String> cmbPath;
private JTextField txtPath;
private JButton bnBrowse;
- private JComboBox<String> cmbTime;
- private JComboBox<String> cmbPath;
- private JComboBox<String> cmbVerbose;
- private JCheckBox chkDisableTable;
- private JCheckBox chkDisableConsole;
- private JCheckBox chkDisableDisplay;
- private JCheckBox chkDisableMultithreading;
+
+ private JButton bnSystem;
public WatcherModule(boolean expanded) {
- super("Watcher", "", "Default", "", expanded);
+ super("Path & Watcher", "", "Default", "", expanded);
}
@Override
public String getCommand() {
String cmd = "";
- boolean t = chkDisableTable.isSelected();
- boolean c = chkDisableConsole.isSelected();
- boolean d = chkDisableDisplay.isSelected();
- boolean m = chkDisableMultithreading.isSelected();
if (cmbPath.getSelectedIndex() != 0)
cmd += " -path " + txtPath.getText();
- if (cmbTime.getSelectedIndex() != 0)
- cmd += " -time " + txtTime.getText();
- if (c || t || d || m)
- cmd += " -disable " + (t ? "monitor " : "") +
- (c ? "console " : "") + (d ? "display " : "") + (m ? "multithreading " : "");
- if (cmbVerbose.getSelectedIndex() != 0) {
- String parts[] = ((String)cmbVerbose.getSelectedItem()).split(" ");
- cmd += " -verbose " + parts[1];
- }
+ if (cmbMultithreading.getSelectedIndex() != 0)
+ cmd += " -" + (String)cmbMultithreading.getSelectedItem();
+ if (cmbDisplay.getSelectedIndex() != 0)
+ cmd += " -" + (String)cmbDisplay.getSelectedItem();
+ if (cmbMonitor.getSelectedIndex() != 0)
+ cmd += " -" + (String)cmbMonitor.getSelectedItem();
+ if (cmbVerbose.getSelectedIndex() != 0)
+ cmd += " -" + (String)cmbVerbose.getSelectedItem();
return cmd;
}
@Override
public JPanel buildExpandedPanel() {
- cmbTime = new JComboBox<String>(new String[] { "No time limitation", "Specify limit (s) ..." });
- cmbPath = new JComboBox<String>(new String[] { "Current", "Specify ..." });
- cmbVerbose = new JComboBox<String>(new String[] { "Verbose: log", "Verbose: quiet ", "Verbose: prolix", "Verbose: mute" });
- chkDisableTable = new JCheckBox("No Monitor");
- chkDisableConsole = new JCheckBox("No Console");
- chkDisableDisplay = new JCheckBox("No Display");
- chkDisableMultithreading = new JCheckBox("No Multithreading");
-
- txtTime = new JTextField("3600");
- txtPath = new JTextField("...", 30);
+ cmbVerbose = new JComboBox<String>(new String[] { "verbose log ", "verbose quiet ", "verbose prolix", "verbose mute" });
+ cmbDisplay = new JComboBox<String>(new String[] { "display final", "display no"});
+ cmbMonitor = new JComboBox<String>(new String[] { "monitor full", "monitor console", "monitor none"});
+ cmbMultithreading = new JComboBox<String>(new String[] { "multithreading enabled", "multithreading disabled"});
+ cmbPath = new JComboBox<String>(new String[] { "Current", "Specify"});
+ txtPath = new JTextField("", 30);
bnBrowse = new JButton("Browse");
-
- GridPanel pn = new GridPanel("Output Directory", 3);
- pn.place(0, 1, cmbPath);
- pn.place(0, 2, bnBrowse);
- pn.place(1, 0, 4, 1, txtPath);
-
- GridPanel pn2 = new GridPanel("Settings", 3);
- pn2.place(2, 0, 2, 1, cmbTime);
- pn2.place(2, 2, txtTime);
- pn2.place(2, 3, cmbVerbose);
- pn2.place(4, 0, chkDisableTable);
- pn2.place(4, 1, chkDisableConsole);
- pn2.place(4, 2, chkDisableDisplay);
- pn2.place(4, 3, chkDisableMultithreading);
+ bnSystem = new JButton("System");
+ GridPanel pn1 = new GridPanel(true, 3);
+ pn1.place(0, 0, 2, 1, "Working directory");
+ pn1.place(1, 0, cmbPath);
+ pn1.place(1, 1, bnBrowse);
+ pn1.place(2, 0, 2, 1, txtPath);
+
+ GridPanel pn2 = new GridPanel(true, 3);
+ pn2.place(2, 0, cmbVerbose);
+ pn2.place(2, 1, cmbMonitor);
+ pn2.place(3, 0, cmbDisplay);
+ pn2.place(3, 1, cmbMultithreading);
+ pn2.place(4, 1, bnSystem);
+
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
- panel.add(pn);
+ panel.add(pn1);
panel.add(pn2);
+ String dir = System.getProperty("user.dir");
Config.register(getName(), "verbose", cmbVerbose, cmbVerbose.getItemAt(0));
- Config.register(getName(), "path", cmbPath, cmbPath.getItemAt(0));
- Config.register(getName(), "time", cmbTime, cmbTime.getItemAt(0));
- Config.register(getName(), "time.value", txtTime, "3600");
- Config.register(getName(), "path", txtPath, new File(System.getProperty("user.dir")).getAbsolutePath());
- Config.register(getName(), "disable.table", chkDisableTable, "false");
- Config.register(getName(), "disable.console", chkDisableConsole, "false");
- Config.register(getName(), "disable.display", chkDisableDisplay, "false");
- Config.register(getName(), "disable.multithreading", chkDisableMultithreading, "false");
-
- cmbVerbose.addActionListener(this);
+ Config.register(getName(), "monitor", cmbMonitor, cmbMonitor.getItemAt(0));
+ Config.register(getName(), "display", cmbDisplay, cmbDisplay.getItemAt(0));
+ Config.register(getName(), "multithreading", cmbMultithreading, cmbMultithreading.getItemAt(0));
+ Config.register(getName(), "current", cmbPath, cmbPath.getItemAt(0));
+ Config.register(getName(), "path", txtPath, dir);
+
cmbPath.addActionListener(this);
- cmbTime.addActionListener(this);
- chkDisableTable.addActionListener(this);
- chkDisableConsole.addActionListener(this);
- chkDisableDisplay.addActionListener(this);
- chkDisableMultithreading.addActionListener(this);
-
- txtTime.addKeyListener(this);
- bnBrowse.addActionListener(this);
txtPath.addKeyListener(this);
-
+ cmbVerbose.addActionListener(this);
+ cmbDisplay.addActionListener(this);
+ cmbMultithreading.addActionListener(this);
+ cmbMonitor.addActionListener(this);
+ bnBrowse.addActionListener(this);
+ bnSystem.addActionListener(this);
return panel;
}
private void update() {
+
setCommand(getCommand());
- setSynopsis(txtPath.getText());
- if (cmbPath != null) {
- boolean b = cmbPath.getSelectedIndex() != 0;
- bnBrowse.setEnabled(b);
- txtPath.setEnabled(b);
+ if (cmbPath.getSelectedIndex() == 0) {
+ txtPath.setText(System.getProperty("user.dir"));
+ txtPath.setEnabled(false);
+ bnBrowse.setEnabled(false);
}
- if (txtTime != null) {
- boolean b = cmbTime.getSelectedIndex() != 0;
- txtTime.setEnabled(b);
+ else {
+ txtPath.setEnabled(true);
+ bnBrowse.setEnabled(true);
}
+ setSynopsis(txtPath.getText());
Command.command();
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
- if (e.getSource() == bnBrowse) {
+ if (e.getSource() == bnSystem) {
+ SystemPanel.show(400, 400);
+ }
+ else if (e.getSource() == bnBrowse) {
File f = Files.browseDirectory(txtPath.getText());
if (f != null) {
txtPath.setText(f.getAbsolutePath());
}
}
- if (e.getSource() == cmbPath) {
+ else if (e.getSource() == cmbPath) {
if (cmbPath.getSelectedIndex() == 0) {
File f = new File(System.getProperty("user.dir"));
txtPath.setText(f.getAbsolutePath());
}
-
}
update();
}
@Override
public void close() {
- chkDisableTable.removeActionListener(this);
- chkDisableConsole.removeActionListener(this);
- chkDisableDisplay.removeActionListener(this);
- chkDisableMultithreading.removeActionListener(this);
cmbVerbose.removeActionListener(this);
- cmbTime.removeActionListener(this);
- txtTime.removeActionListener(this);
+ cmbDisplay.removeActionListener(this);
+ cmbMultithreading.removeActionListener(this);
+ cmbMonitor.removeActionListener(this);
+ cmbPath.removeActionListener(this);
txtPath.removeKeyListener(this);
bnBrowse.removeActionListener(this);
- }
+}
+
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
update();
}
+
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/monitor/TableMonitor.java b/DeconvolutionLab2/src/deconvolutionlab/monitor/TableMonitor.java
index 2206ae1..d4e4e5c 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/monitor/TableMonitor.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/monitor/TableMonitor.java
@@ -1,179 +1,179 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab.monitor;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import lab.component.CustomizedColumn;
import lab.component.CustomizedTable;
public class TableMonitor implements AbstractMonitor, ActionListener {
private CustomizedTable table;
private JButton bnClear = new JButton("Clear");
private JButton bnProlix = new JButton("Prolix");
private JButton bnVerbose = new JButton("verbose");
private JButton bnQuiet = new JButton("Quiet");
private JButton bnMute = new JButton("Mute");
private HashMap<Long, Color> colors = new HashMap<Long, Color>();
private JPanel panel;
public TableMonitor(int width, int height) {
ArrayList<CustomizedColumn> columns = new ArrayList<CustomizedColumn>();
columns.add(new CustomizedColumn("#", Long.class, 60, false));
columns.add(new CustomizedColumn("Time", String.class, 100, false));
columns.add(new CustomizedColumn("Memory", String.class, 100, false));
columns.add(new CustomizedColumn("Message", String.class, Math.max(60, width - 3 * 60), false));
table = new CustomizedTable(columns, true);
table.getColumnModel().getColumn(0).setMinWidth(60);
table.getColumnModel().getColumn(0).setMaxWidth(60);
table.getColumnModel().getColumn(1).setMaxWidth(100);
table.getColumnModel().getColumn(1).setMinWidth(100);
table.getColumnModel().getColumn(2).setMaxWidth(100);
table.getColumnModel().getColumn(2).setMinWidth(100);
RowRenderer renderer = new RowRenderer();
for (int i = 0; i < 4; i++)
table.getColumnModel().getColumn(i).setCellRenderer(renderer);
JScrollPane scroll = new JScrollPane(table);
scroll.setPreferredSize(new Dimension(width, height));
/*
JToolBar tool = new JToolBar();
tool.setFloatable(false);
tool.setLayout(new GridLayout(1, 3));
tool.add(bnClear);
tool.add(new JLabel(""));
tool.add(new JLabel(""));
tool.add(bnProlix);
tool.add(bnVerbose);
tool.add(bnQuiet);
tool.add(bnMute);
*/
JPanel main = new JPanel(new BorderLayout());
//main.add(tool, BorderLayout.NORTH);
main.add(scroll, BorderLayout.CENTER);
bnClear.addActionListener(this);
bnVerbose.addActionListener(this);
bnQuiet.addActionListener(this);
bnProlix.addActionListener(this);
bnMute.addActionListener(this);
panel = new JPanel(new BorderLayout());
panel.add(main);
panel.setBorder(BorderFactory.createEtchedBorder());
}
public JPanel getPanel() {
return panel;
}
public void show(String title) {
JFrame frame = new JFrame(title);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
@Override
public void clear() {
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.setRowCount(0);
}
@Override
public void add(Message message) {
String msg[] = message.formatArray();
int n = msg.length;
Object[] row = new Object[n + 1];
row[0] = message.getID();
for (int i = 0; i < n; i++)
row[i + 1] = msg[i];
table.append(row);
Verbose level = message.getLevel();
Color c = new Color(0, 0, 0);
if (level == Verbose.Prolix)
c = new Color(255, 0, 0);
else if (level == Verbose.Quiet)
c = new Color(200, 200, 0);
colors.put(new Long(message.getID()), c);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == bnClear) {
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.setRowCount(0);
}
}
@Override
public String getName() {
return "table";
}
-
+
class RowRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
DefaultTableModel model = (DefaultTableModel) table.getModel();
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (row >= 0) {
Long id = (Long) model.getValueAt(row, 0);
Color color = colors.get(id);
c.setForeground(color);
}
return c;
}
}
}
diff --git a/DeconvolutionLab2/src/lab/component/CustomizedTable.java b/DeconvolutionLab2/src/lab/component/CustomizedTable.java
index 2cae066..ae489e7 100644
--- a/DeconvolutionLab2/src/lab/component/CustomizedTable.java
+++ b/DeconvolutionLab2/src/lab/component/CustomizedTable.java
@@ -1,284 +1,285 @@
/*
* 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 lab.component;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
public class CustomizedTable extends JTable {
private JScrollPane pane = null;
private ArrayList<CustomizedColumn> columns;
public CustomizedTable(String headers[], boolean sortable) {
ArrayList<CustomizedColumn> colums = new ArrayList<CustomizedColumn>();
for (int i = 0; i < headers.length; i++)
colums.add(new CustomizedColumn(headers[i], String.class, 150, false));
create(colums);
setAutoCreateRowSorter(sortable);
setRowHeight(20);
}
public CustomizedTable(ArrayList<CustomizedColumn> columns, boolean sortable) {
create(columns);
setAutoCreateRowSorter(sortable);
setRowHeight(20);
}
private void create(ArrayList<CustomizedColumn> column) {
columns = column;
DefaultTableModel model = new DefaultTableModel() {
@Override
public boolean isCellEditable(int row, int col) {
return columns.get(col).editable;
}
@Override
public Class<?> getColumnClass(int col) {
return columns.get(col).classe;
}
};
setModel(model);
int n = columns.size();
String headers[] = new String[n];
for (int col = 0; col < n; col++)
headers[col] = columns.get(col).header;
model.setColumnIdentifiers(headers);
setFillsViewportHeight(true);
for (int col = 0; col < n; col++) {
TableColumn tc = getColumnModel().getColumn(col);
tc.setPreferredWidth(columns.get(col).width);
if (columns.get(col).choices != null) {
JComboBox<String> cmb = new JComboBox<String>();
for (String p : columns.get(col).choices) {
cmb.addItem(p);
cmb.setToolTipText(columns.get(col).tooltip);
tc.setCellEditor(new DefaultCellEditor(cmb));
}
}
if (columns.get(col).button != null) {
ButtonRenderer bn = new ButtonRenderer();
bn.setToolTipText(columns.get(col).tooltip);
tc.setCellRenderer(bn);
}
}
+ getTableHeader().setReorderingAllowed(false);
}
public void setPreferredSize(int width, int height) {
if (pane != null)
pane.setPreferredSize(new Dimension(width, height));
}
public void removeRow(int row) {
if (row >= 0 && row < getRowCount())
((DefaultTableModel) getModel()).removeRow(row);
}
public String[] getRow(int row) {
if (row >= 0) {
int ncol = getColumnCount();
String items[] = new String[ncol];
for (int col = 0; col < ncol; col++)
items[col] = (String) getModel().getValueAt(row, col);
return items;
}
return new String[1];
}
public String getCell(int row, int col) {
if (row >= 0) {
return (String) getModel().getValueAt(row, col);
}
return "";
}
public String getRowCSV(int row, String seperator) {
if (row >= 0) {
int ncol = getColumnCount();
String items = "";
for (int col = 0; col < ncol - 1; col++) {
if ((String) getModel().getValueAt(row, col) == null)
items += "" + seperator;
else
items += (String) getModel().getValueAt(row, col) + seperator;
}
if (ncol >= 1)
items += (String) getModel().getValueAt(row, ncol - 1);
return items;
}
return "";
}
public void saveCSV(String filename) {
File file = new File(filename);
try {
BufferedWriter buffer = new BufferedWriter(new FileWriter(file));
int nrows = getRowCount();
int ncols = getColumnCount();
String row = "";
for (int c = 0; c < columns.size(); c++)
row += columns.get(c).header + (c == columns.size() - 1 ? "" : ", ");
buffer.write(row + "\n");
for (int r = 0; r < nrows; r++) {
row = "";
for (int c = 0; c < ncols; c++)
row += this.getCell(r, c) + (c == ncols - 1 ? "" : ", ");
buffer.write(row + "\n");
}
buffer.close();
}
catch (IOException ex) {
}
}
public String getSelectedAtColumn(int col) {
int row = getSelectedRow();
if (row >= 0)
return (String) getModel().getValueAt(row, col);
else
return "";
}
public void setSelectedAtColumn(int col, String selection) {
int nrows = this.getRowCount();
for (int i = 0; i < nrows; i++) {
String name = (String) getModel().getValueAt(i, col);
if (name.equals(selection))
this.setRowSelectionInterval(i, i + 1);
}
}
public void append(Object[] row) {
DefaultTableModel model = (DefaultTableModel) getModel();
int i = 0;
try {
model.addRow(row);
i = getRowCount() - 1;
if (i >= 0) {
getSelectionModel().setSelectionInterval(i, i);
scrollRectToVisible(new Rectangle(getCellRect(i, 0, true)));
}
}
catch (Exception e) {
}
repaint();
}
public void insert(Object[] row) {
DefaultTableModel model = (DefaultTableModel) getModel();
int i = 0;
try {
model.insertRow(0, row);
getSelectionModel().setSelectionInterval(i, i);
scrollRectToVisible(new Rectangle(getCellRect(i, 0, true)));
}
catch (Exception e) {
}
repaint();
}
@Override
public int getSelectedRow() {
int row = super.getSelectedRow();
if (row < 0) {
if (getRowCount() > 0) {
setRowSelectionInterval(0, 0);
row = super.getSelectedRow();
}
return row;
}
return row;
}
public void update(ArrayList<String[]> data) {
DefaultTableModel model = (DefaultTableModel) getModel();
model.getDataVector().removeAllElements();
for (String[] row : data)
model.addRow(row);
repaint();
}
public JScrollPane getPane(int width, int height) {
setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
setPreferredScrollableViewportSize(new Dimension(width, height));
setFillsViewportHeight(true);
pane = new JScrollPane(this);
return pane;
}
public JScrollPane getMinimumPane(int width, int height) {
setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
setMinimumSize(new Dimension(width, height));
setShowVerticalLines(true);
setPreferredScrollableViewportSize(new Dimension(width, height));
setFillsViewportHeight(true);
return new JScrollPane(this);
}
public JFrame show(String title, int w, int h) {
JFrame frame = new JFrame(title);
frame.add(getPane(w, h));
frame.pack();
frame.setVisible(true);
return frame;
}
public class ButtonRenderer extends JButton implements TableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
setText(columns.get(column).button);
return this;
}
}
}
diff --git a/DeconvolutionLab2/src/matlab/Converter.java b/DeconvolutionLab2/src/matlab/Converter.java
index 86001e3..79fca95 100644
--- a/DeconvolutionLab2/src/matlab/Converter.java
+++ b/DeconvolutionLab2/src/matlab/Converter.java
@@ -1,409 +1,553 @@
package matlab;
import ij.ImagePlus;
import ij.ImageStack;
import ij.process.ByteProcessor;
import ij.process.ColorProcessor;
import ij.process.FloatProcessor;
import ij.process.ShortProcessor;
+import signal.RealSignal;
public class Converter {
public static boolean verbose;
/**
* Get an image.
*
* @param imageplus image
* @return an N x M array representing the input image
*/
public static Object get(ImagePlus imageplus) {
if (imageplus == null)
return null;
int width = imageplus.getWidth();
int height = imageplus.getHeight();
int stackSize = imageplus.getStackSize();
int counter = 0;
ImageStack imagestack = imageplus.getStack();
switch (imageplus.getType()) {
case ImagePlus.COLOR_256: {
;
}
case ImagePlus.GRAY8: {
short[][][] is = new short[height][width][stackSize];
for (int sz = 0; sz < stackSize; sz++) {
ByteProcessor byteprocessor = (ByteProcessor) imagestack.getProcessor(sz + 1);
byte[] pixels = (byte[]) byteprocessor.getPixels();
counter = 0;
int h = 0;
while (h < height) {
int w = 0;
while (w < width) {
is[h][w][sz] = (short)(pixels[counter]&0xff);
w++;
counter++;
}
counter = ++h * width;
}
}
return is;
}
case ImagePlus.GRAY16: {
int[][][] is = new int[height][width][stackSize];
for (int sz = 0; sz < stackSize; sz++) {
counter = 0;
ShortProcessor shortprocessor = (ShortProcessor) imagestack.getProcessor(sz + 1);
short[] spixels = (short[]) shortprocessor.getPixels();
int h = 0;
while (h < height) {
int w = 0;
while (w < width) {
is[h][w][sz] = (int)(spixels[counter]&0xffff);
w++;
counter++;
}
counter = ++h * width;
}
}
return is;
}
case ImagePlus.GRAY32: {
double[][][] fs = new double[height][width][stackSize];
for (int sz = 0; sz < stackSize; sz++) {
FloatProcessor floatprocessor = (FloatProcessor) imagestack.getProcessor(sz + 1);
float[] fpixels = (float[]) floatprocessor.getPixels();
counter = 0;
int i = 0;
while (i < height) {
int j = 0;
while (j < width) {
fs[i][j][sz] = (double) fpixels[counter];
j++;
counter++;
}
counter = ++i * width;
}
}
return fs;
}
case ImagePlus.COLOR_RGB: {
if (stackSize == 1) {
short[][][] is = new short[height][width][3];
ColorProcessor colorprocessor = (ColorProcessor) imagestack.getProcessor(1);
byte[] red = new byte[width * height];
byte[] green = new byte[width * height];
byte[] blue = new byte[width * height];
colorprocessor.getRGB(red, green, blue);
counter = 0;
int h = 0;
while (h < height) {
int w = 0;
while (w < width) {
is[h][w][0] = (short)(red[counter]&0xff);
is[h][w][1] = (short)(green[counter]&0xff);
is[h][w][2] = (short)(blue[counter]&0xff);
w++;
counter++;
}
counter = ++h * width;
}
return is;
}
short[][][][] is = new short[height][width][stackSize][3];
for (int sz = 0; sz < stackSize; sz++) {
ColorProcessor colorprocessor = (ColorProcessor) imagestack.getProcessor(sz + 1);
byte[] red = new byte[width * height];
byte[] green = new byte[width * height];
byte[] blue = new byte[width * height];
colorprocessor.getRGB(red, green, blue);
counter = 0;
int h = 0;
while (h < height) {
int w = 0;
while (w < width) {
is[h][w][sz][0] = (short)red[counter];
is[h][w][sz][1] = (short)green[counter];
is[h][w][sz][2] = (short)blue[counter];
w++;
counter++;
}
counter = ++h * width;
}
}
return is;
}
default:
System.out.println("MIJ Error message: Unknow type of volumes.");
return null;
}
}
+
/**
* Create a new image in ImageJ from a Matlab variable with a specified
* title.
*
* This method try to create a image (ImagePlus of ImageJ) from a Matlab's
* variable which should be an 2D or 3D array The recognize type are byte,
* short, int, float and double. The dimensionality of the 2 (image) or 3
* (stack of images)
*
* @param title
* title of the new image
* @param object
* Matlab variable
* @param showImage
* Whether to display the newly created image or not
* @return the resulting ImagePlus instance
*/
public static ImagePlus createImage(String title, Object object, boolean showImage) {
ImagePlus imp = null;
int i = 0;
if (object instanceof byte[][]) {
byte[][] is = (byte[][]) object;
int height = is.length;
int width = is[0].length;
ByteProcessor byteprocessor = new ByteProcessor(width, height);
byte[] bp = (byte[]) byteprocessor.getPixels();
int h = 0;
while (h < height) {
int w = 0;
while (w < width) {
bp[i] = is[h][w];
w++;
i++;
}
i = ++h * width;
}
imp = new ImagePlus(title, byteprocessor);
}
else if (object instanceof short[][]) {
short[][] is = (short[][]) object;
int height = is.length;
int width = is[0].length;
ShortProcessor shortprocessor = new ShortProcessor(width, height);
short[] sp = (short[]) shortprocessor.getPixels();
int h = 0;
while (h < height) {
int w = 0;
while (w < width) {
sp[i] = is[h][w];
w++;
i++;
}
i = ++h * width;
}
imp = new ImagePlus(title, shortprocessor);
}
else if (object instanceof int[][]) {
if (verbose)
System.out.println("MIJ warning message: Loss of precision: convert int 32-bit to short 16-bit");
int[][] is = (int[][]) object;
int height = is.length;
int width = is[0].length;
ShortProcessor shortprocessor = new ShortProcessor(width, height);
short[] sp = (short[]) shortprocessor.getPixels();
int h = 0;
while (h < height) {
int w = 0;
while (w < width) {
sp[i] = (short) is[h][w];
w++;
i++;
}
i = ++h * width;
}
imp = new ImagePlus(title, shortprocessor);
}
else if (object instanceof float[][]) {
float[][] fs = (float[][]) object;
int height = fs.length;
int width = fs[0].length;
FloatProcessor floatprocessor = new FloatProcessor(width, height);
float[] fp = (float[]) floatprocessor.getPixels();
int h = 0;
while (h < height) {
int w = 0;
while (w < width) {
fp[i] = fs[h][w];
w++;
i++;
}
i = ++h * width;
}
floatprocessor.resetMinAndMax();
imp = new ImagePlus(title, floatprocessor);
}
else if (object instanceof double[][]) {
if (verbose)
System.out.println("MIJ warning message: Loss of precision: convert double 32-bit to float 32-bit");
double[][] ds = (double[][]) object;
int height = ds.length;
int width = ds[0].length;
FloatProcessor floatprocessor = new FloatProcessor(width, height);
float[] fp = (float[]) floatprocessor.getPixels();
int h = 0;
while (h < height) {
int w = 0;
while (w < width) {
fp[i] = (float) ds[h][w];
w++;
i++;
}
i = ++h * width;
}
floatprocessor.resetMinAndMax();
imp = new ImagePlus(title, floatprocessor);
}
else if (object instanceof byte[][][]) {
byte[][][] is = (byte[][][]) object;
int height = is.length;
int width = is[0].length;
int stackSize = is[0][0].length;
ImageStack imagestack = new ImageStack(width, height);
for (int sz = 0; sz < stackSize; sz++) {
ByteProcessor byteprocessor = new ByteProcessor(width, height);
byte[] bp = (byte[]) byteprocessor.getPixels();
i = 0;
int h = 0;
while (h < height) {
int w = 0;
while (w < width) {
bp[i] = is[h][w][sz];
w++;
i++;
}
i = ++h * width;
}
imagestack.addSlice("", byteprocessor);
}
imp = new ImagePlus(title, imagestack);
}
else if (object instanceof short[][][]) {
short[][][] is = (short[][][]) object;
int height = is.length;
int width = is[0].length;
int stackSize = is[0][0].length;
ImageStack imagestack = new ImageStack(width, height);
for (int sz = 0; sz < stackSize; sz++) {
ShortProcessor shortprocessor = new ShortProcessor(width, height);
short[] sp = (short[]) shortprocessor.getPixels();
i = 0;
int h = 0;
while (h < height) {
int w = 0;
while (w < width) {
sp[i] = is[h][w][sz];
w++;
i++;
}
i = ++h * width;
}
imagestack.addSlice("", shortprocessor);
}
imp = new ImagePlus(title, imagestack);
}
else if (object instanceof int[][][]) {
if (verbose)
System.out.println("MIJ warning message: Loss of precision: convert int 32 bits to short 16 bits");
int[][][] is = (int[][][]) object;
int height = is.length;
int width = is[0].length;
int stackSize = is[0][0].length;
ImageStack imagestack = new ImageStack(width, height);
for (int sz = 0; sz < stackSize; sz++) {
ShortProcessor shortprocessor = new ShortProcessor(width, height);
short[] sp = (short[]) shortprocessor.getPixels();
i = 0;
int h = 0;
while (h < height) {
int w = 0;
while (w < width) {
sp[i] = (short) is[h][w][sz];
w++;
i++;
}
i = ++h * width;
}
if (sz == 0)
shortprocessor.resetMinAndMax();
imagestack.addSlice("", shortprocessor);
}
imp = new ImagePlus(title, imagestack);
}
else if (object instanceof float[][][]) {
float[][][] fs = (float[][][]) object;
int height = fs.length;
int width = fs[0].length;
int stackSize = fs[0][0].length;
ImageStack imagestack = new ImageStack(width, height);
for (int sz = 0; sz < stackSize; sz++) {
FloatProcessor floatprocessor = new FloatProcessor(width, height);
float[] fp = (float[]) floatprocessor.getPixels();
i = 0;
int h = 0;
while (h < height) {
int w = 0;
while (w < width) {
fp[i] = fs[h][w][sz];
w++;
i++;
}
i = ++h * width;
}
if (sz == 0)
floatprocessor.resetMinAndMax();
imagestack.addSlice("", floatprocessor);
}
imp = new ImagePlus(title, imagestack);
}
else if (object instanceof double[][][]) {
if (verbose)
System.out.println("MIJ warning message: Loss of precision: convert double 32-bit to float 32-bit");
double[][][] ds = (double[][][]) object;
int height = ds.length;
int width = ds[0].length;
int stackSize = ds[0][0].length;
ImageStack imagestack = new ImageStack(width, height);
for (int sz = 0; sz < stackSize; sz++) {
FloatProcessor floatprocessor = new FloatProcessor(width, height);
float[] fp = (float[]) floatprocessor.getPixels();
i = 0;
int h = 0;
while (h < height) {
int w = 0;
while (w < width) {
fp[i] = (float) ds[h][w][sz];
w++;
i++;
}
i = ++h * width;
}
if (sz == 0)
floatprocessor.resetMinAndMax();
imagestack.addSlice("", floatprocessor);
}
imp = new ImagePlus(title, imagestack);
}
else {
System.out.println("MIJ Error message: Unknow type of images or volumes.");
return null;
}
if (showImage) {
imp.show();
imp.updateAndDraw();
}
return imp;
}
+
+ /**
+ * Create a new RealSignal from a Matlab variable with a specified
+ * title.
+ */
+ public static RealSignal createRealSignal(Object object) {
+ RealSignal signal = null;
+ if (object instanceof byte[][]) {
+ byte[][] data = (byte[][]) object;
+ int h = data.length;
+ int w = data[0].length;
+ signal = new RealSignal(h, w, 1);
+ for(int i=0; i<h; i++)
+ for(int j=0; j<w; j++)
+ signal.data[0][i+j*h]= data[i][j];
+ return signal;
+ }
+ if (object instanceof short[][]) {
+ short[][] data = (short[][]) object;
+ int h = data.length;
+ int w = data[0].length;
+ signal = new RealSignal(h, w, 1);
+ for(int i=0; i<h; i++)
+ for(int j=0; j<w; j++)
+ signal.data[0][i+j*h]= data[i][j];
+ return signal;
+ }
+
+ if (object instanceof int[][]) {
+ int[][] data = (int[][]) object;
+ int h = data.length;
+ int w = data[0].length;
+ signal = new RealSignal(h, w, 1);
+ for(int i=0; i<h; i++)
+ for(int j=0; j<w; j++)
+ signal.data[0][i+j*h]= data[i][j];
+ return signal;
+ }
+
+ if (object instanceof float[][]) {
+ float[][] data = (float[][]) object;
+ int h = data.length;
+ int w = data[0].length;
+ signal = new RealSignal(h, w, 1);
+ for(int i=0; i<h; i++)
+ for(int j=0; j<w; j++)
+ signal.data[0][i+j*h]= data[i][j];
+ return signal;
+ }
+
+ if (object instanceof double[][]) {
+ double[][] data = (double[][]) object;
+ int h = data.length;
+ int w = data[0].length;
+ signal = new RealSignal(h, w, 1);
+ for(int i=0; i<h; i++)
+ for(int j=0; j<w; j++)
+ signal.data[0][i+j*h]= (float)data[i][j];
+ return signal;
+ }
+
+ if (object instanceof byte[][][]) {
+ byte[][][] data = (byte[][][]) object;
+ int h = data.length;
+ int w = data[0].length;
+ int d = data[0][0].length;
+ signal = new RealSignal(h, w, d);
+ for(int k=0; k<d; k++)
+ for(int i=0; i<h; i++)
+ for(int j=0; j<w; j++)
+ signal.data[k][i+j*h]= (float)data[i][j][k];
+ return signal;
+ }
+
+ if (object instanceof short[][][]) {
+ short[][][] data = (short[][][]) object;
+ int h = data.length;
+ int w = data[0].length;
+ int d = data[0][0].length;
+ signal = new RealSignal(h, w, d);
+ for(int k=0; k<d; k++)
+ for(int i=0; i<h; i++)
+ for(int j=0; j<w; j++)
+ signal.data[k][i+j*h]= (float)data[i][j][k];
+ return signal;
+ }
+
+ if (object instanceof int[][][]) {
+ int[][][] data = (int[][][]) object;
+ int h = data.length;
+ int w = data[0].length;
+ int d = data[0][0].length;
+ signal = new RealSignal(h, w, d);
+ for(int k=0; k<d; k++)
+ for(int i=0; i<h; i++)
+ for(int j=0; j<w; j++)
+ signal.data[k][i+j*h]= (float)data[i][j][k];
+ return signal;
+ }
+
+ if (object instanceof float[][][]) {
+ float[][][] data = (float[][][]) object;
+ int h = data.length;
+ int w = data[0].length;
+ int d = data[0][0].length;
+ signal = new RealSignal(h, w, d);
+ for(int k=0; k<d; k++)
+ for(int i=0; i<h; i++)
+ for(int j=0; j<w; j++)
+ signal.data[k][i+j*h]= data[i][j][k];
+ return signal;
+ }
+
+ if (object instanceof double[][][]) {
+ double[][][] data = (double[][][]) object;
+ int h = data.length;
+ int w = data[0].length;
+ int d = data[0][0].length;
+ signal = new RealSignal(h, w, d);
+ for(int k=0; k<d; k++)
+ for(int i=0; i<h; i++)
+ for(int j=0; j<w; j++)
+ signal.data[k][i+j*h]= (float)data[i][j][k];
+ return signal;
+ }
+
+ return null;
+ }
+ public static Object createObject(RealSignal signal) {
+ if (signal == null)
+ return null;
+ int nx = signal.nx;
+ int ny = signal.ny;
+ int nz = signal.nz;
+ double[][][] object = new double[ny][nx][nz];
+ for(int k=0; k<nz; k++)
+ for(int i=0; i<nx; i++)
+ for(int j=0; j<ny; j++)
+ object[j][i][k] = signal.data[k][i+j*nx];
+ return object;
+ }
+
}
diff --git a/DeconvolutionLab2/src/signal/Constraint.java b/DeconvolutionLab2/src/signal/Constraint.java
index f8df207..6673ee0 100644
--- a/DeconvolutionLab2/src/signal/Constraint.java
+++ b/DeconvolutionLab2/src/signal/Constraint.java
@@ -1,137 +1,137 @@
/*
* 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 deconvolutionlab.monitor.Monitors;
public class Constraint {
public static enum Mode {NO, NONNEGATIVE, CLIPPED, RESCALED, NORMALIZED};
private static float min = -Float.MAX_VALUE;
private static float max = Float.MAX_VALUE;
private static float mean;
private static float stdev;
private Monitors monitors = new Monitors();
public Constraint(Monitors monitors) {
this.monitors = monitors;
}
public static String[] getContraintsAsArray() {
- return new String[] {"No", "Non-negativity", "Clipped"};
+ return new String[] {"no", "nonnegativity", "clipped"};
}
public static Constraint.Mode getByName(String c) {
- if (c.toLowerCase().equalsIgnoreCase("Non-negativity"))
+ if (c.toLowerCase().equalsIgnoreCase("nonnegativity"))
return Constraint.Mode.NONNEGATIVE;
if (c.toLowerCase().equalsIgnoreCase("clipped"))
return Constraint.Mode.CLIPPED;
return Constraint.Mode.NO;
}
public static void setModel(RealSignal signal) {
float
stats[] = signal.getStats();
mean = stats[0];
min = stats[1];
max = stats[2];
stdev = stats[3];
}
public void apply(RealSignal x, Constraint.Mode constraint) {
if (constraint == null)
return;
switch(constraint) {
case NONNEGATIVE:
nonnegative(x);
break;
case CLIPPED:
clipped(x, min, max);
break;
case RESCALED:
rescaled(x, 0, 255);
break;
case NORMALIZED:
normalized(x, mean, stdev);
break;
default:
return;
}
}
public void nonnegative(RealSignal x) {
monitors.log("Apply non-negative constraint");
int nxy = x.nx * x.ny;
for(int k=0; k<x.nz; k++)
for(int i=0; i<nxy; i++) {
if (x.data[k][i] < 0)
x.data[k][i] = 0;
}
}
public void clipped(RealSignal x, float ming, float maxg) {
monitors.log("Apply clipped constraint (" + ming + " ..." + maxg + ")");
int nxy = x.nx * x.ny;
for(int k=0; k<x.nz; k++)
for(int i=0; i<nxy; i++) {
if (x.data[k][i] <= ming)
x.data[k][i] = ming;
if (x.data[k][i] >= maxg)
x.data[k][i] = maxg;
}
}
public void normalized(RealSignal x, float meang, float stdevg) {
monitors.log("Apply normalized constraint (" + meang + ", " + stdevg + ")");
float stats[] = x.getStats();
int nxy = x.nx * x.ny;
for(int k=0; k<x.nz; k++)
for(int i=0; i<nxy; i++) {
float d = (x.data[k][i] - stats[0]) / stats[3];
x.data[k][i] = d * stdevg + meang;
}
}
public void rescaled(RealSignal x, float ming, float maxg) {
monitors.log("Apply rescaled constraint (" + ming + " ... " + maxg + ")");
int nxy = x.nx * x.ny;
float stats[] = x.getStats();
float a = (maxg-ming) / (stats[2] - stats[1]);
for(int k=0; k<x.nz; k++)
for(int i=0; i<nxy; i++) {
x.data[k][i] = a*(x.data[k][i] - stats[1]) + ming;
}
}
}
Event Timeline
Log In to Comment