Page MenuHomec4science

No OneTemporary

File Metadata

Created
Mon, Nov 4, 15:34
diff --git a/DeconvolutionLab2/DeconvolutionLab2.config b/DeconvolutionLab2/DeconvolutionLab2.config
index 08e1d75..d374650 100644
--- a/DeconvolutionLab2/DeconvolutionLab2.config
+++ b/DeconvolutionLab2/DeconvolutionLab2.config
@@ -1,99 +1,99 @@
#DeconvolutionLab2
#DeconvolutionLab2
-#Fri Apr 28 15:00:20 CEST 2017
+#Mon May 01 13:43:18 CEST 2017
Algorithm.BVLS.iterations=10
Algorithm.BVLS.step=1.0
Algorithm.FISTA.iterations=10
Algorithm.FISTA.reg=0.1
Algorithm.FISTA.scale=3
Algorithm.FISTA.step=1.0
Algorithm.FISTA.wavelets=Haar
Algorithm.ICTM.iterations=10
Algorithm.ICTM.reg=0.4642
Algorithm.ICTM.step=1.0
Algorithm.ISTA.iterations=10
Algorithm.ISTA.reg=0.1
Algorithm.ISTA.scale=3
Algorithm.ISTA.step=1.0
Algorithm.ISTA.wavelets=Haar
Algorithm.LW.iterations=10
Algorithm.LW.step=1.0
Algorithm.NNLS.iterations=10
Algorithm.NNLS.step=1.0
Algorithm.RIF.reg=0.1
Algorithm.RL.iterations=10
Algorithm.RLTV.reg=1.000E-18
Algorithm.SIM.gaussian.mean=0.0
Algorithm.SIM.gaussian.stdev=1.0
Algorithm.SIM.poisson=0.0
Algorithm.TM.iterations=10
Algorithm.TM.reg=0.1
Algorithm.TM.step=1.0
Algorithm.TRIF.reg=0.1
Algorithm.VC.iterations=10
Algorithm.VC.step=1.0
Algorithm.algorithm=Landweber
Controller.constraint=no
Controller.monitor=console table
Controller.reference.enable=true
Controller.reference.value=/Users/dsage/Desktop/Screen Shot 2017-04-12 at 22.56.07.png
Controller.residu.enable=false
Controller.residu.value=0.01
Controller.stats=no
Controller.time.enable=false
Controller.time.value=1
Controller.verbose=log
+DeconvolutionLab.DeconvolutionDialog.location.h=400
+DeconvolutionLab.DeconvolutionDialog.location.w=963
+DeconvolutionLab.DeconvolutionDialog.location.x=0
+DeconvolutionLab.DeconvolutionDialog.location.y=23
DeconvolutionLab.MainDialog.location.h=774
DeconvolutionLab.MainDialog.location.w=507
DeconvolutionLab.MainDialog.location.x=65
DeconvolutionLab.MainDialog.location.y=63
FFT.epsilon=1E-6
FFT.fft=Academic
FFT.multithreading=yes
Image.image.row0=Cube;synthetic;Cube 50.0 1.0 size 300 128 300 intensity 255.0 ;\u232B
Image.image.row10=20170302_AIDE-MEMOIRE.pdf;file;/Users/dsage/Desktop/20170302_AIDE-MEMOIRE.pdf;null
Image.image.row11=Screen Shot 2017-04-12 at 22.56.07.png;file;/Users/dsage/Desktop/Screen Shot 2017-04-12 at 22.56.07.png;null
Image.image.row12=Screen Shot 2017-04-12 at 22.56.07.png;file;/Users/dsage/Desktop/Screen Shot 2017-04-12 at 22.56.07.png;null
Image.image.row13=RandomLines;synthetic;RandomLines 100.0 size 128 128 32 intensity 255.0 ;\u232B
Image.image.row14=active;platform;active;\u232B
Image.image.row15=Cube;synthetic;Cube 100.0 0.0 10.0 1.0 size 128 128 32 ;\u232B
Image.image.row16=Applications;directory;/users/dsage/Applications;\u232B
Image.image.row17=Cube;synthetic;Cube 100.0 0.0 10.0 1.0 size 128 128 32 ;\u232B
Image.image.row18=lib;directory;/Users/dsage/git/deconvolution/DeconvolutionLab2/lib;\u232B
Image.image.row1=Cube;synthetic;Cube 10.0 1.0 size 300 128 32 intensity 255.0 ;\u232B
Image.image.row2=workspace;directory;/Users/dsage/Desktop/workspace;\u232B
Image.image.row3=CubeSphericalBeads;synthetic;CubeSphericalBeads 3.0 0.5 10.0 5.0 size 128 128 128 intensity 255.0 ;\u232B
Image.image.row4=CubeSphericalBeads;synthetic;CubeSphericalBeads 3.0 0.5 8.0 16.0 size 128 128 32 intensity 255.0 ;\u232B
Image.image.row5=Cube of Spherical Beads;synthetic;Cube of Spherical Beads 3.0 0.5 8.0 8.0 size 128 128 128 intensity 255.0 ;\u232B
Image.image.row6=Screen Shot 2017-04-12 at 22.56.07.png;file;/Users/dsage/Desktop/Screen Shot 2017-04-12 at 22.56.07.png;null
Image.image.row7=20170302_AIDE-MEMOIRE.pdf;file;/Users/dsage/Desktop/20170302_AIDE-MEMOIRE.pdf;null
Image.image.row8=Screen Shot 2017-04-12 at 22.56.07.png;file;/Users/dsage/Desktop/Screen Shot 2017-04-12 at 22.56.07.png;null
Image.image.row9=Screen Shot 2017-04-12 at 22.56.07.png;file;/Users/dsage/Desktop/Screen Shot 2017-04-12 at 22.56.07.png;null
Image.image.selected=Cube;synthetic;Cube 50.0 1.0 size 300 128 300 intensity 255.0 ;\u232B
-LabDialog.Algo=true
-LabDialog.Directory=false
-LabDialog.Image=false
-LabDialog.PSF=false
Language.headless=Run (Headless)
Language.job=Job
Language.language=Java
Output.output.row0=mip;MI1;rescaled;;;\u2713;\u2713;\u232B
Output.output.selected=mip;MI1;rescaled;;;\u2713;\u2713;\u232B
PSF.psf.row0=Double-Helix;synthetic;Double-Helix 3.0 30.0 10.0 size 128 128 32 intensity 255.0 ;null
PSF.psf.row1=Sinc;synthetic;Sinc 3.0 3.0 3.0 size 100 128 200 intensity 255.0 ;null
PSF.psf.selected=Double-Helix;synthetic;Double-Helix 3.0 30.0 10.0 size 128 128 32 intensity 255.0 ;null
-Path.current=Current
+Path.current=desktop
Path.display=true
-Path.path=/Users/sage/Desktop/worksmlm/deconvolution/DeconvolutionLab2
+Path.path=/Users/sage/Desktop/
Path.system=true
Preprocessing.apoxy=Uniform
Preprocessing.apoz=Uniform
Preprocessing.extxy=0
Preprocessing.extz=0
Preprocessing.normalization=1
Preprocessing.padxy=None
Preprocessing.padz=None
-Running.Directory=/Users/dsage/git/deconvolution/DeconvolutionLab2
-Running.Monitor=table
-Running.Path=specify
-Running.Verbose=quiet
+System.Frame.location.h=80
+System.Frame.location.w=637
+System.Frame.location.x=0
+System.Frame.location.y=23
diff --git a/DeconvolutionLab2/build.xml b/DeconvolutionLab2/build.xml
index 1f5e7ea..0cfdb6a 100644
--- a/DeconvolutionLab2/build.xml
+++ b/DeconvolutionLab2/build.xml
@@ -1,48 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="DeconvolutionLab2" default="build" basedir=".">
<property name="imagej" location="${user.home}/Desktop/ImageJ/plugins" />
- <property name="fiji" location="${user.home}/Desktop/Fiji.app/plugins" />
+ <property name="fiji" location="${user.home}/Desktop/Fiji-deconv.app/plugins" />
<property name="matlab" location="/Applications/MATLAB_R2014b.app/java/" />
<property name="doc" location="${user.home}/Desktop/doc/" />
<property name="javadoc.header" value="&lt;h3&gt;DeconvolutionLab2&lt;/h3&gt;&#09;v1.0" />
<property name="javadoc.footer" value="&lt;h4&gt;DeconvolutionLab2&lt;/h4&gt;&#09;&lt;script&gt; var tStamp=new Date(); document.write(tStamp.toUTCString()); &lt;/script&gt;" />
<property name="javadoc.bottom" value='Copyright &amp;copy; &lt;script&gt; var currYear=new Date(); document.write(currYear.getFullYear()); &lt;/script&gt;, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. All rights reserved.' />
<target name="build">
<mkdir dir="${doc}" />
<mkdir dir="bin" />
<copy todir="bin"><fileset dir="ij"></fileset></copy>
<copy file="plugins.config" toDir="bin" />
<zip destfile="../DeconvolutionLab2-src.zip" basedir="src" />
<zip destfile="../DeconvolutionLab2-cls.zip" basedir="bin" />
<jar destfile="../DeconvolutionLab_2.jar" basedir="bin">
<manifest>
<attribute name="Main-Class" value="DeconvolutionLab2" />
<attribute name="Class-Path" value="ij.jar jtransforms.jar" />
</manifest>
</jar>
<copy toDir="${fiji}" file="../DeconvolutionLab_2.jar" />
<copy toDir="${matlab}" file="../DeconvolutionLab_2.jar" />
<copy toDir="${imagej}" file="../DeconvolutionLab_2.jar" />
<javadoc destdir="${doc}" author="true" version="true" overview="${basedir}/overview.html" windowtitle="DeconvolutionLab2">
<fileset dir="src">
<include name="**/*.java" />
<exclude name="**/fft/**" />
<exclude name="**/jfftw/**" />
</fileset>
<header>
<![CDATA[${javadoc.header}]]>
</header>
<footer>
<![CDATA[${javadoc.footer}]]>
</footer>
<bottom>
<![CDATA[${javadoc.bottom}]]>
</bottom>
</javadoc>
</target>
</project>
diff --git a/DeconvolutionLab2/src/DeconvolutionLab2.java b/DeconvolutionLab2/src/DeconvolutionLab2.java
index 3034d78..fef4ab4 100644
--- a/DeconvolutionLab2/src/DeconvolutionLab2.java
+++ b/DeconvolutionLab2/src/DeconvolutionLab2.java
@@ -1,127 +1,128 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
import java.io.File;
+import bilib.tools.Files;
import deconvolution.Command;
import deconvolution.Deconvolution;
import deconvolutionlab.Constants;
import deconvolutionlab.Imager;
import deconvolutionlab.Imager.Platform;
import deconvolutionlab.Lab;
import deconvolutionlab.LabDialog;
import deconvolutionlab.monitor.Monitors;
public class DeconvolutionLab2 {
public static String ack = Constants.name + " " + Constants.version + " " + Constants.copyright;
public static void main(String arg[]) {
Lab.init(Platform.STANDALONE);
if (arg.length == 0) {
System.out.println("Starting lab");
lab(arg);
return;
}
String flag = arg[0].trim().toLowerCase();
if (flag.equalsIgnoreCase("help")) {
System.out.println("Starting help");
help();
return;
}
else if (flag.equalsIgnoreCase("lab")) {
System.out.println("Starting lab");
lab(arg);
}
else if (flag.equalsIgnoreCase("fft")) {
System.out.println("Starting fft");
Lab.checkFFT(Monitors.createDefaultMonitor());
}
else if (flag.equalsIgnoreCase("run")) {
System.out.println("Starting run");
String cmd = "";
for (int i = 1; i < arg.length; i++)
cmd += arg[i] + " ";
new Deconvolution("Run", cmd, Deconvolution.Finish.KILL).deconvolve();
}
else if (flag.equalsIgnoreCase("launch")) {
System.out.println("Starting launch");
String cmd = "";
for (int i = 1; i < arg.length; i++)
cmd += arg[i] + " ";
new Deconvolution("Launch", cmd, Deconvolution.Finish.KILL).launch();
}
else
System.out.println("" + flag + " command not found");
}
private static void lab(String arg[]) {
- String config = System.getProperty("user.dir") + File.separator + "DeconvolutionLab2.config";
+ String config = Files.getWorkingDirectory() + "DeconvolutionLab2.config";
if (arg.length >= 2) {
String filename = arg[1].trim();
File file = new File(filename);
if (file.exists())
if (file.isFile())
if (file.canRead())
config = filename;
}
Lab.init(Platform.STANDALONE, config);
LabDialog dialog = new LabDialog();
dialog.setVisible(true);
}
public static void help() {
System.out.println("More info:" + Constants.url);
System.out.println("Syntax:");
System.out.println("java -jar DeconvolutionLab_2.jar lab");
System.out.println("java -jar DeconvolutionLab_2.jar run {command} ...");
System.out.println("java -jar DeconvolutionLab_2.jar launch {command} ...");
System.out.println("java -jar DeconvolutionLab_2.jar fft");
System.out.println("java -jar DeconvolutionLab_2.jar info");
System.out.println("java -jar DeconvolutionLab_2.jar help");
System.out.println("{command} is the full command line for running a deconvolution");
System.out.println("Keywords of {command}: ");
for (String keyword : Command.keywords)
System.out.println("\t" + keyword);
}
public DeconvolutionLab2(String cmd) {
System.out.println("cmd: " + cmd);
- Lab.init(Imager.Platform.STANDALONE, System.getProperty("user.dir") + File.separator + "DeconvolutionLab2.config");
+ Lab.init(Imager.Platform.STANDALONE, Files.getWorkingDirectory() + "DeconvolutionLab2.config");
new Deconvolution("CommandLine", cmd).deconvolve();
}
}
diff --git a/DeconvolutionLab2/src/DeconvolutionLab2_Lab.java b/DeconvolutionLab2/src/DeconvolutionLab2_Lab.java
index 88d8d5f..b23c3f6 100644
--- a/DeconvolutionLab2/src/DeconvolutionLab2_Lab.java
+++ b/DeconvolutionLab2/src/DeconvolutionLab2_Lab.java
@@ -1,48 +1,49 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
import java.io.File;
+import bilib.tools.Files;
import deconvolutionlab.Imager;
import deconvolutionlab.Lab;
import deconvolutionlab.LabDialog;
import ij.IJ;
import ij.plugin.PlugIn;
public class DeconvolutionLab2_Lab implements PlugIn {
@Override
public void run(String arg) {
Lab.init(Imager.Platform.IMAGEJ, IJ.getDirectory("plugins") + File.separator + "DeconvolutionLab2.config");
LabDialog dlg = new LabDialog();
Lab.setVisible(dlg, false);
}
}
diff --git a/DeconvolutionLab2/src/Display_FactorySignals.java b/DeconvolutionLab2/src/Display_FactorySignals.java
index 57e2c07..3924a9a 100644
--- a/DeconvolutionLab2/src/Display_FactorySignals.java
+++ b/DeconvolutionLab2/src/Display_FactorySignals.java
@@ -1,254 +1,254 @@
import java.io.File;
import java.util.ArrayList;
import bilib.table.CustomizedTable;
import bilib.tools.Files;
import deconvolution.algorithm.Convolution;
import deconvolutionlab.Lab;
import deconvolutionlab.monitor.Monitors;
import fft.AbstractFFT;
import fft.FFT;
import ij.plugin.PlugIn;
import signal.ComplexSignal;
import signal.RealSignal;
import signal.factory.SignalFactory;
import signal.factory.Sphere;
import signal.factory.complex.ComplexSignalFactory;
public class Display_FactorySignals implements PlugIn {
- private String path = Files.getDesktop() + File.separator + "Deconvolution" + File.separator + "Signals" + File.separator;
+ private String path = Files.getDesktopDirectory() + File.separator + "Deconvolution" + File.separator + "Signals" + File.separator;
@Override
public void run(String arg0) {
}
public static void main(String arg[]) {
new Display_FactorySignals();
}
public Display_FactorySignals() {
new File(path).mkdir();
int nx = 128;
int ny = 96;
int nz = 100;
ArrayList<SignalFactory> factories = SignalFactory.getAll();
RealSignal image = new Sphere(20, 0.5).generate(nx, ny, nz);
Monitors monitors = Monitors.createDefaultMonitor();
CustomizedTable table = new CustomizedTable(new String[] {"Name", "mean", "min", "max"}, true);
table.show("Stats", 500, 500);
for(SignalFactory factory : factories) {
RealSignal psf = factory.intensity(133).generate(nx, ny, nz);
Lab.show(psf);
float s[] = psf.getStats();
table.append(new String[] {factory.getName(), ""+s[0], ""+s[1], ""+s[2]});
Lab.showOrthoview(psf);
Lab.save(monitors, psf, path + psf.name + ".tif");
Lab.save(monitors, psf.createMIP(), path + "mip-" + psf.name + ".tif");
Lab.save(monitors, psf.createOrthoview(), path + "ortho-" + psf.name + ".tif");
Convolution convolution = new Convolution();
RealSignal a = convolution.run(image, psf);
Lab.showMIP(monitors, a, "conv " + factory.getName());
Lab.save(monitors, a, path + "conv-"+psf.name + ".tif");
Lab.save(monitors, a.createMIP(), path + "conv-mip-" + psf.name + ".tif");
Lab.save(monitors, a.createOrthoview(), path + "conv-ortho-" + psf.name + ".tif");
}
}
public void d() {
int nx = 150;
int ny = 128;
int nz = 100;
int xsize = nx / 2;
int ysize = ny / 2;
int zsize = nz / 2;
double wx, wy, wz;
RealSignal psf = new RealSignal("psf", nx, ny, nz);
AbstractFFT fft = FFT.getFastestFFT().getDefaultFFT();
fft.init(Monitors.createDefaultMonitor(), nx, ny, 1);
double pupil = 10;
double defocus = 10;
double wave = 2;
double defocusTop = 2.0*Math.PI / (defocus*defocus*pupil);
double defocusCen = 2.0*Math.PI / pupil;
for (int z = 0; z <= zsize; z++) {
float[][][] real = new float[xsize + 1][ysize + 1][1];
float[][][] imag = new float[xsize + 1][ysize + 1][1];
wz = wave*(z-zsize)*2.0*Math.PI / zsize;
double cosz = Math.cos(wz);
double sinz = Math.sin(wz);
double fcz = z * Math.abs(defocusTop-defocusCen) / zsize+ defocusTop;
for (int y = 0; y <= ysize; y++)
for (int x = 0; x <= xsize; x++) {
wx = Math.PI * x / xsize;
wy = Math.PI * y / ysize;
double g = wy*wy+wx*wx >= fcz*fcz ? 0 : 1;
real[x][y][0] = (float) (g * cosz);
imag[x][y][0] = (float) (g * sinz);
}
ComplexSignal c = ComplexSignalFactory.createHermitian(""+z, nx, ny, 1, real, imag);
RealSignal pz = fft.inverse(c).circular();
//pz.plus(1);
//pz.normalize(1);
psf.setXY(z, pz.getXY(0));
psf.setXY(nz-1-z, pz.duplicate().getXY(0));
}
//psf = new Gaussian(3,4,4).generate(nx, ny, nz);
float min = psf.getExtrema()[0];
psf.minus(min);
float max = psf.getExtrema()[1];
psf.times(1/max);
float aft[] = psf.getExtrema();
System.out.println(" // " + aft[0] + " // " + aft[1]);
psf.normalize(1);
Lab.show(psf);
Lab.showOrthoview(psf);
Lab.save(Monitors.createDefaultMonitor(), psf, "psfdiffraction.tif");
/*
fft.init(Monitors.createDefaultMonitor(), nx, ny, nz);
ComplexSignal otf = fft.transform(psf);
Lab.show(otf.getModule().circular().log());
Lab.showOrthoview(otf.getModule().circular().log());
RealSignal r = new Cube(30, 1).generate(nx, ny, nz);
RealSignal a = new Convolution().run(r, psf);
Lab.showOrthoview(a);
*/
}
public void c() {
int nx = 128;
int ny = 128;
int nz = 128;
RealSignal otf = new RealSignal("psf", nx, ny, nz);
int cx = nx/2;
int cy = ny/2;
int cz = nz/2;
double pi = Math.PI;
double periodTop = 5;
double periodCenter = 15;
double attenuation = 10;
double aperture = 60;
double apernorm = (2.0*aperture)/(nx+ny);
double diag = Math.sqrt(nx*nx+ny*ny+nz*nz);
double step = (periodCenter-periodTop)/nz;
for(int i=0; i<nx; i++)
for(int j=0; j<ny; j++) {
double r = Math.sqrt((i-cx)*(i-cx)+(j-cy)*(j-cy));
for(int k=0; k<nx; k++) {
double z = Math.abs(k-cz);
double p = Math.sqrt(r*r + z*z)/diag;
double period = Math.max(1, periodCenter-step*z);
double sz = apernorm*z + period*0.25;
double s1 = 1.0 / (1.0+Math.exp(-(r+sz)));
double s2 = 1.0 / (1.0+Math.exp(-(r-sz)));
double s = Math.cos(2*pi*(r-apernorm*z)/period);
double g = (attenuation*p+1);
otf.data[k][i+j*nx] = (float)((s1-s2)*s*s/g);
}
}
Lab.show(otf);
Lab.showOrthoview(otf, "out", cx, cy, cz);
float[] stats = otf.getStats();
for(float s : stats)
System.out.println("" + s);
AbstractFFT fft = FFT.getFastestFFT().getDefaultFFT();
fft.init(Monitors.createDefaultMonitor(), nx, ny, nz);
ComplexSignal psf = fft.transform(otf);
float[] stats1 = psf.getModule().getStats();
for(float s : stats1)
System.out.println("PSF " + s);
Lab.show(psf.getModule().circular().log());
Lab.showOrthoview(psf.getModule().circular().log(), "out", cx, cy, cz);
}
public void b() {
int nx = 128;
int ny = 128;
int nz = 128;
RealSignal otf = new RealSignal("psf", nx, ny, nz);
int cx = nx/2;
int cy = ny/2;
int cz = nz/2;
for(int i=0; i<nx; i++)
for(int j=0; j<ny; j++) {
double r = Math.sqrt((i-cx)*(i-cx)+(j-cy)*(j-cy));
for(int k=0; k<nx; k++) {
double df = Math.abs(k-cz);
double dd = df - 6;
double sig = 3 + df * 0.2;
double sigd = 0.1 + dd * 0.2;
double norm = 1.0 / (Math.PI*sig*sig);
double g = norm * Math.exp(-r*r/(2.0*sig*sig));
double gd = (dd < 0 ? 0 : norm * Math.exp(-r*r/(2*sigd*sigd)));
otf.data[k][i+j*nx] = (float)(g-gd); //(Math.exp(-r*0.1));
}
}
Lab.show(otf);
Lab.showOrthoview(otf, "out", cx, cy, cz);
float[] stats = otf.getStats();
for(float s : stats)
System.out.println("" + s);
AbstractFFT fft = FFT.getFastestFFT().getDefaultFFT();
fft.init(Monitors.createDefaultMonitor(), nx, ny, nz);
ComplexSignal psf = fft.transform(otf);
float[] stats1 = psf.getModule().getStats();
for(float s : stats1)
System.out.println("PSF " + s);
Lab.show(Monitors.createDefaultMonitor(), psf.getModule().circular(), "psf");
}
public void va() {
int nx = 128;
int ny = 128;
int nz = 128;
RealSignal otf = new RealSignal("psf", nx, ny, nz);
int cx = nx/2;
int cy = ny/2;
int cz = nz/2;
double p = 1.3;
for(int i=0; i<nx; i++)
for(int j=0; j<ny; j++) {
double d = Math.sqrt((i-cx)*(i-cx) + (j-cy)*(j-cy));
double v = (p-Math.exp(-d*0.1));
for(int k=0; k<nx; k++) {
double dz = ((double)Math.abs(k-cz))/nz;
double g = Math.exp(-dz*dz*2*nx);
double vz = g*v*Math.cos(d*Math.PI*2/nx);
if (vz > 0) {
double r = Math.sqrt((i-cx)*(i-cx) + (j-cy)*(j-cy) + (k-cz)*(k-cz));
if (r < cx)
otf.data[k][i+j*nx] = (float)vz; //(Math.exp(-r*0.1));
}
}
}
Lab.show(otf);
Lab.showOrthoview(otf, "out", cx, cy, cz);
float[] stats = otf.getStats();
for(float s : stats)
System.out.println("" + s);
AbstractFFT fft = FFT.getFastestFFT().getDefaultFFT();
fft.init(Monitors.createDefaultMonitor(), nx, ny, nz);
ComplexSignal psf = fft.transform(otf);
float[] stats1 = psf.getModule().getStats();
for(float s : stats1)
System.out.println("PSF " + s);
Lab.show(Monitors.createDefaultMonitor(), psf.getModule().circular(), "psf");
}
}
diff --git a/DeconvolutionLab2/src/bilib/tools/Files.java b/DeconvolutionLab2/src/bilib/tools/Files.java
index f337d83..53cf5cf 100644
--- a/DeconvolutionLab2/src/bilib/tools/Files.java
+++ b/DeconvolutionLab2/src/bilib/tools/Files.java
@@ -1,79 +1,82 @@
/*
* bilib --- Java Bioimaging Library ---
*
* Author: Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland
*
* 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.
*/
/*
* 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 bilib.tools;
import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileSystemView;
public class Files {
- public static String getHome() {
- return FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath();
-
+ public static String getWorkingDirectory() {
+ return System.getProperty("user.dir");
+ }
+
+ public static String getHomeDirectory() {
+ return FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator;
}
- public static String getDesktop() {
- return getHome() + File.separator + "Desktop";
+ public static String getDesktopDirectory() {
+ return getHomeDirectory() + "Desktop" + File.separator;
}
public static File browseFile(String path) {
JFileChooser fc = new JFileChooser();
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
File dir = new File(path);
if (dir.exists())
fc.setCurrentDirectory(dir);
int ret = fc.showOpenDialog(null);
if (ret == JFileChooser.APPROVE_OPTION) {
File file = new File(fc.getSelectedFile().getAbsolutePath());
if (file.exists())
return file;
}
return null;
}
public static File browseDirectory(String path) {
JFileChooser fc = new JFileChooser();
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
File dir = new File(path);
if (dir.exists())
fc.setCurrentDirectory(dir);
int ret = fc.showOpenDialog(null);
if (ret == JFileChooser.APPROVE_OPTION) {
File file = new File(fc.getSelectedFile().getAbsolutePath());
if (file.exists())
return file;
}
return null;
}
}
diff --git a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Bigradient.java b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Bigradient.java
index fc67f0e..3d91c35 100644
--- a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Bigradient.java
+++ b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Bigradient.java
@@ -1,121 +1,121 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package course;
import java.io.File;
import bilib.tools.Files;
import deconvolution.Deconvolution;
import ij.plugin.PlugIn;
public class DeconvolutionLab2_Course_Bigradient implements PlugIn {
- private String root = Files.getDesktop() + File.separator + "Deconvolution" + File.separator;
+ private String root = Files.getDesktopDirectory() + "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("run", "-image file " + data + "ref.tif" + psf + " -algorithm SIM 0 1 1 -out stack convnoise -out stack conbnoise_8 rescaled byte noshow").deconvolve();
new Deconvolution("run", noisy + psf + " -algorithm NIF -out stack NIF").deconvolve();
new Deconvolution("run", noisy + psf + " -algorithm DIV -out stack DIV").deconvolve();
for(int i=0; i<=3; i++) {
double p = Math.pow(5, i-10);
String name = "RIF" + String.format("%02d", i);
new Deconvolution("run", noisy + psf + " -algorithm RIF " + p + out("RIF" + File.separator, name)).deconvolve();
}
for(int i=0; i<=3; i++) {
double p = Math.pow(5, i-10);
String name = "TRIF" + String.format("%02d", i);
new Deconvolution("run", noisy + psf + " -algorithm TRIF " + p + out("TRIF" + File.separator, name)).deconvolve();
}
String lw = " -algorithm LW 20 1 -out mip @2 LW-ITER/I -out stats @1 LW nosave";
new Deconvolution("run", noisy + psf + lw).deconvolve();
new File(res + "LW-ITER/I.tif").delete();
String lwp = " -algorithm LW+ 20 1 -out mip @2 LW+-ITER/I -out stats @1 LW+ nosave";
new Deconvolution("run", noisy + psf + lwp).deconvolve();
new File(res + "LW+-ITER/I.tif").delete();
String rl = " -algorithm RL 20 -out mip @2 RL-ITER/I -out stats @1 RL nosave";
new Deconvolution("run", noisy + psf + rl).deconvolve();
new File(res + "RL-ITER/I.tif").delete();
String rltv = " -algorithm RLTV 20 10 -out mip @2 RLTV-ITER/I -out stats @1 RLTV nosave";
new Deconvolution("run", noisy + psf + rltv).deconvolve();
new File(res + "RLTV-ITER/I.tif").delete();
String fista = " -algorithm FISTA 20 1 1 Spline3 3 -mip @2 FISTA-ITER/I -out stats @1 FISTA nosave";
new Deconvolution("run", noisy + psf + fista).deconvolve();
new File(res + "FISTA-ITER/I.tif").delete();
}
private static String out(String root, String 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 441d0b4..620eb15 100644
--- a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Border.java
+++ b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Border.java
@@ -1,138 +1,136 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package course;
import ij.plugin.PlugIn;
import java.io.File;
-import javax.swing.filechooser.FileSystemView;
-
import signal.RealSignal;
import signal.factory.Cube;
import signal.factory.Gaussian;
+import bilib.tools.Files;
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 + "Deconvolution" + File.separator;
+ private String root = Files.getDesktopDirectory() + "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(100).center(0.25, 0.00, 0.05).generate(nx, ny, nz);
RealSignal i0 = new Cube(22, .1).intensity(100).center(0.25, 0.05, 0.05).generate(nx, ny, nz);
RealSignal i1 = new Cube(22, .1).intensity(100).center(0.25, 0.10, 0.05).generate(nx, ny, nz);
RealSignal i2 = new Cube(22, .1).intensity(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(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("run", ref + " -psf synthetic impulse " + algo).deconvolve();
algo = " -algorithm CONV -stack CONV -out ortho CONVo rescaled byte (64,32,16) -out mip CONVp rescaled byte";
new Deconvolution("run", ref + psf + algo).deconvolve();
algo = " -algorithm CONV -pad NO NO 200 200 -out ortho PADo200 rescaled byte (64,32,16) -out mip PADp200 rescaled byte";
new Deconvolution("run", ref + psf + algo).deconvolve();
algo = " -algorithm CONV -pad NO NO 100 100 -out ortho PADo100 rescaled byte (64,32,16) -out mip PADp100 rescaled byte";
new Deconvolution("run", ref + psf + algo).deconvolve();
algo = " -algorithm CONV -pad NO NO 40 40 -out ortho PADo40 rescaled byte (64,32,16) -out mip PADp40 rescaled byte";
new Deconvolution("run", ref + psf + algo).deconvolve();
algo = " -algorithm CONV -pad NO NO 20 20 -out ortho PADo20 rescaled byte (64,32,16) -out mip PADp20 rescaled byte";
new Deconvolution("run", ref + psf + algo).deconvolve();
algo = " -algorithm CONV -pad NO NO 10 10 -out ortho PADo10 rescaled byte (64,32,16) -out mip PADp10 rescaled byte";
new Deconvolution("run", ref + psf + algo).deconvolve();
algo = " -algorithm CONV -pad NO NO 5 5 -out ortho PADo2 rescaled byte (64,32,16) -out mip PADp2 rescaled byte";
new Deconvolution("run", ref + psf + algo).deconvolve();
algo = " -algorithm CONV -apo HANN HANN -out ortho HANNo rescaled byte (64,32,16) -out mip HANNp rescaled byte";
new Deconvolution("run", ref + psf + algo).deconvolve();
algo = " -algorithm CONV -apo TUKEY TUKEY -out ortho TUKEYo rescaled byte (64,32,16) -out mip TUKEYp rescaled byte";
new Deconvolution("run", ref + psf + algo).deconvolve();
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("run", ref + psf + algo).deconvolve();
algo = " -algorithm CONV -apo HANN HANN -out ortho HANN_CSTo rescaled byte -out mip HANN_CSTp rescaled byte";
new Deconvolution("run", cst + psf + algo).deconvolve();
algo = " -algorithm CONV -apo TUKEY TUKEY -out ortho TUKEY_CSTo rescaled byte -out mip TUKEY_CSTp rescaled byte";
new Deconvolution("run", cst + psf + algo).deconvolve();
algo = " -algorithm CONV -pad E2 E2 -out ortho PADpPower2FFTW rescaled byte (64,32,16) -out mip PADpPower2FFTW rescaled byte";
new Deconvolution("run", cst + psf + algo + " -fft FFTW2 ").deconvolve();
new Deconvolution("run", cst + psf + algo + " -fft Academic ").deconvolve();
new Deconvolution("run", cst + psf + algo + " -fft JTransforms ").deconvolve();
}
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_Celegans.java b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Celegans.java
index 3baeca7..cc5fc72 100644
--- a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Celegans.java
+++ b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Celegans.java
@@ -1,120 +1,120 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package course;
import ij.ImagePlus;
import ij.io.FileSaver;
import ij.io.Opener;
import ij.plugin.PlugIn;
import ij.process.ColorProcessor;
import java.io.File;
import javax.swing.filechooser.FileSystemView;
+import bilib.tools.Files;
import deconvolution.Deconvolution;
public class DeconvolutionLab2_Course_Celegans implements PlugIn {
- private String desktop = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator + "Desktop";
- private String root = desktop + File.separator + "DeconvolutionLab2-Course" + File.separator;
+ private String root = Files.getDesktopDirectory() + "DeconvolutionLab2-Course" + File.separator;
private String res = root + "Results" + File.separator + "c-elegans" + File.separator;
private String data = root + "Data" + File.separator + "c-elegans" + File.separator;
public DeconvolutionLab2_Course_Celegans() {
new File(res).mkdir();
System.setProperty("user.dir", res);
run(" -algorithm RIF 0.000001 ", "RIF6_");
run(" -algorithm RIF 0.0000001 ", "RIF7_");
//run(" -algorithm RL 100 ", "RL_");
run(" -algorithm LW+ 200 1 ", "LW+_");
//run(" -algorithm I ", "IN_");
//run(" -algorithm RIF 0.001 ", "RIF3_");
//run(" -algorithm RIF 0.0001 ", "RIF4_");
//run(" -algorithm RIF 0.00001 ", "RIF5_");
//run(" -algorithm VC 100 ", "VC");
//run(" -algorithm RLTV 10 0.1 ", "RLTV");
//run(" -algorithm FISTA 50 1 0.1 ", "FISTA");
//run(" -algorithm ISTA 50 1 0.1 ", "ISTA");
}
private void run(String a, String name) {
String channels[] = new String[] { "CY3", "FITC", "DAPI"};
ImagePlus[] ort = new ImagePlus[3];
ImagePlus[] fig = new ImagePlus[3];
for (int i=0; i<3; i++) {
String channel = channels[i];
String psf = " -psf file " + data + "psf-CElegans-" + channel + ".tif";
String img = " -image file " + data + "CElegans-" + channel +".tif";
String param = " -fft JTransforms -disable display multithreading";
String algo = a + out(name + channel);
new Deconvolution("deconvolve", img + psf + algo + param).deconvolve();
ort[i] = new Opener().openImage( res + name + channel + "_ortho_8.tif");
fig[i] = new Opener().openImage( res + name + channel + "_figure_8.tif");
}
new FileSaver(color(ort)).saveAsTiff(res + name + "-ortho-rgb.tif");
new FileSaver(color(fig)).saveAsTiff(res + name + "-figure-rgb.tif");
}
private static String out(String name) {
return
" -out ortho " + name + "_ortho_8 rescaled byte (160,180,50) noshow" +
" -out mip " + name + "_mip_8 rescaled byte noshow" +
" -out figure " + name + "_figure_8 rescaled byte (160,180,50) ";
}
private static ImagePlus color(ImagePlus imp[]) {
int nx = imp[0].getWidth();
int ny = imp[0].getHeight();
ColorProcessor cp = new ColorProcessor(nx, ny);
byte r[] = (byte[])imp[0].getProcessor().getPixels();
byte g[] = (byte[])imp[1].getProcessor().getPixels();
byte b[] = (byte[])imp[2].getProcessor().getPixels();
cp.setRGB(r, g, b);
ImagePlus out = new ImagePlus( "rgb", cp);
out.show();
return out;
}
public static void main(String arg[]) {
new DeconvolutionLab2_Course_Celegans();
}
@Override
public void run(String arg) {
new DeconvolutionLab2_Course_Celegans();
}
}
\ 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 a2c2354..129cae6 100644
--- a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Noise.java
+++ b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Noise.java
@@ -1,98 +1,98 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package course;
import java.io.File;
import javax.swing.filechooser.FileSystemView;
+import bilib.tools.Files;
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 + "Deconvolution" + File.separator;
+ private String root = Files.getDesktopDirectory() + "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(100).center(0.2, 0.5, 0).generate(nx, ny, nz);
RealSignal i1 = new Cube(50, 0.25).intensity(70).center(0.4, 0.5, 0).generate(nx, ny, nz);
RealSignal i2 = new Cube(50, 0.25).intensity(40).center(0.6, 0.5, 0).generate(nx, ny, nz);
RealSignal i3 = new Cube(50, 0.25).intensity(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("noise", 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("noise", 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("noise", 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 8f2e87e..29cb717 100644
--- a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Piecewise.java
+++ b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Piecewise.java
@@ -1,116 +1,116 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package course;
import java.io.File;
import java.util.Random;
import javax.swing.filechooser.FileSystemView;
+import bilib.tools.Files;
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 + "Deconvolution" + File.separator;
+ private String root = Files.getDesktopDirectory() + "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(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(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 -out stats @3 PR nosave -out stack PR -out ortho PRo ";
new Deconvolution("run", ground + "-reference reference.tif -psf synthetic impulse 100 0 size 128 128 128 " + algo).deconvolve();
algo = " -algorithm SIM 0 1 1 -out stats @3 SIM nosave -out stack signal -out ortho SIGNALo ";
new Deconvolution("run", ground + psf + algo).deconvolve();
algo = " -algorithm NIF -out ortho NIF " + paramout;
new Deconvolution("run", signal + psf + algo).deconvolve();
algo = " -algorithm RLTV 15 0.01 -out stats @1 RLTV nosave -out ortho @1 RLTV/RLTV" + paramout;
new Deconvolution("run", signal + psf + algo).deconvolve();
}
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 38380e4..2399e6e 100644
--- a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Resolution.java
+++ b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_Resolution.java
@@ -1,198 +1,200 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package course;
import java.io.File;
import javax.swing.filechooser.FileSystemView;
+import bilib.tools.Files;
import deconvolution.algorithm.Convolution;
import deconvolution.algorithm.NaiveInverseFilter;
import deconvolution.algorithm.Simulation;
import deconvolution.algorithm.TikhonovRegularizedInverseFilter;
import deconvolutionlab.Lab;
import deconvolutionlab.monitor.Monitors;
import deconvolutionlab.output.ShowOrtho;
import ij.gui.Plot;
import ij.plugin.PlugIn;
import signal.Assessment;
import signal.RealSignal;
import signal.factory.BesselJ0;
import signal.factory.CubeSphericalBeads;
public class DeconvolutionLab2_Course_Resolution implements PlugIn {
- private String desktop = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator + "Desktop";
- private String root = desktop + File.separator + "Deconvolution" + File.separator;
+ private String root = Files.getDesktopDirectory() + "Deconvolution" + File.separator;
private String path = root + "results" + File.separator + "resolution" + File.separator;
public DeconvolutionLab2_Course_Resolution() {
Monitors monitors = Monitors.createDefaultMonitor();
new File(path).mkdir();
System.setProperty("user.dir", path);
new File(path + "RIF").mkdir();
new File(path + "LW").mkdir();
new File(path + "LW+").mkdir();
new File(path + "RL").mkdir();
- int nx = 128;
- int ny = 128;
- int nz = 128;
- int spacing = 11;
- int b = 11;
+ int nx = 160;
+ int ny = 160;
+ int nz = 160;
+ int spacing = 8;
+ int b = 8;
- RealSignal x = new CubeSphericalBeads(4, 0.1, spacing, b).intensity(100).generate(nx, ny, nz);
+ RealSignal x = new CubeSphericalBeads(2, 0.5, spacing, b).intensity(100).generate(nx, ny, nz);
+ x.plus(10);
Lab.save(monitors, x.createOrthoview(b, b, b), path + "ref.tif");
-
- RealSignal h = new BesselJ0(3, 6, 0.01, 0.01).generate(nx, ny, nz);
+System.out.println("mean x " + x.getStats()[0]);
+ RealSignal h = new BesselJ0(1, 10, 0.001, 0.00000001).generate(nx, ny, nz);
Lab.save(monitors, h, path + "psf.tif");
Lab.show(monitors, h, "psf");
Lab.showOrthoview(h);
Lab.showMIP(h);
- Lab.showPlanar(h);
Convolution convolution = new Convolution();
convolution.disableDisplayFinal().disableSystem();
convolution.addOutput(new ShowOrtho("convolution"));
RealSignal y = convolution.run(x, h);
Lab.save(monitors, y.createOrthoview(b, b, b), path + "conv.tif");
Lab.showPlanar(y);
-
- Simulation simulation = new Simulation(0, 1, 1);
+System.out.println("mean y " + y.getStats()[0]);
+
+ Simulation simulation = new Simulation(0, 0.25, 0.25);
simulation.disableDisplayFinal().disableSystem();
simulation.addOutput(new ShowOrtho("simualtion").origin(b, b, b));
RealSignal ys = simulation.run(x, h);
Lab.save(monitors, ys.createOrthoview(b, b, b), path + "simu.tif");
Lab.showPlanar(ys);
Lab.showMIP(ys);
- Lab.showPlanar(ys);
-
+System.out.println("mean ys " + ys.getStats()[0]);
+
plotProfile(x, "refY", b, 0, b, b, ny-1, b);
plotProfile(x, "refX", 0, b, b, nx-1, b, b);
plotProfile(x, "refZ", b, b, 0, b, b, nz-1);
plotProfile(y, "convY", b, 0, b, b, ny-1, b);
plotProfile(y, "convX", 0, b, b, nx-1, b, b);
plotProfile(y, "convZ", b, b, 0, b, b, nz-1);
plotProfile(ys, "simuY", b, 0, b, b, ny-1, b);
plotProfile(ys, "simuX", 0, b, b, nx-1, b, b);
plotProfile(ys, "simuZ", b, b, 0, b, b, nz-1);
NaiveInverseFilter nif = new NaiveInverseFilter();
nif.addOutput(new ShowOrtho("nif").origin(b, b, b));
nif.disableDisplayFinal().disableSystem().setReference(path + "ref.tif").setStats();
RealSignal nic = nif.run(y, h);
Lab.save(monitors, nic.createOrthoview(b, b, b), path + "nif_conv.tif");
Lab.showPlanar(monitors, nic, nic + "NIF_CONV //"+Assessment.rmse(nic, x));
RealSignal nis = nif.run(ys, h);
Lab.save(monitors, nis.createOrthoview(b, b, b), path + "nif_simu.tif");
Lab.showPlanar(monitors, nis, nis + "NIF_SIMU //"+Assessment.rmse(nis, x));
plotProfile(nic, "nicY", b, 0, b, b, ny-1, b);
plotProfile(nic, "nicX", 0, b, b, nx-1, b, b);
plotProfile(nic, "nicZ", b, b, 0, b, b, nz-1);
plotProfile(nis, "nisY", b, 0, b, b, ny-1, b);
plotProfile(nis, "nisX", 0, b, b, nx-1, b, b);
plotProfile(nis, "nisZ", b, b, 0, b, b, nz-1);
TikhonovRegularizedInverseFilter trif = new TikhonovRegularizedInverseFilter(1e-3);
trif.disableDisplayFinal().disableSystem().setReference(path + "ref.tif");
for(int i=-5; i<-1; i++) {
trif.setParameters(new double[] {Math.pow(10, i)});
RealSignal t = trif.run(ys, h);
Lab.save(monitors, t.createOrthoview(b, b, b), path + "trif" + i + ".tif");
Lab.showPlanar(monitors, t, "TRIF" + i + " //"+Assessment.rmse(t, x));
Lab.showOrthoview(monitors, t, "TRIF"+ i + " //"+Assessment.rmse(t, x), b, b, b);
plotProfile(t, "tirfY" + i, b, 0, b, b, ny-1, b);
plotProfile(t, "tirfX" + i, 0, b, b, nx-1, b, b);
plotProfile(t, "tirfZ" + i, b, b, 0, b, b, nz-1);
+ System.out.println("mean trif " + i + " " + t.getStats()[0]);
}
//plotProfile(t, "trifY", b, 0, b, b, ny-1, b);
//plotProfile(t, "trifX", 0, b, b, nx-1, b, b);
//plotProfile(t, "trifZ", b, b, 0, b, b, nz-1);
- /*
+ /*
RichardsonLucyTV rl = new RichardsonLucyTV(100, 0.00001);
rl.disableDisplayFinal().disableSystem().setReference(res + "ref.tif").setStats();
rl.addOutput(new ShowOrtho("rltv").frequency(1).origin(b, b, b));
RealSignal fli = rl.run(ys, h);
//RLTV 0.0001 100 Signals: 167.2 Mb 14.6724 0.9261 n/a
//RL 100 Signals: 138.6 Mb 14.6688 0.9224 n/a
//RLTV 0.001 100 Signals: 167.2 Mb 14.6979 0.9515 n/a
//LW+ 5000 Signals: 311.6 Mb 15.4276 1.6812 n/a
/*
LandweberPositivity lw = new LandweberPositivity(100, 1.95);
lw.disableDisplayFinal().disableSystem().setReference(res + "ref.tif").setStats();
lw.addOutput(new ShowOrtho("lw").frequency(20).origin(border, border, border));
RealSignal lwi = lw.run(ys, h);
Lab.show(lwi);
*/
}
private static void plotProfile(RealSignal signal, String name, int x1, int y1, int z1, int x2, int y2, int z2) {
double dx = x2 - x1;
double dy = y2 - y1;
double dz = z2 - z1;
double len = Math.sqrt(dx*dx + dy*dy + dz*dz);
int n = (int)Math.round(len * 2);
double ds = len / n;
dx = (double)(x2 - x1) / n;
dy = (double)(y2 - y1) / n;
dz = (double)(z2 - z1) / n;
double value[] = new double[n];
double dist[] = new double[n];
for(int s=0; s<n; s++) {
double x = x1 + s*dx;
double y = y1 + s*dy;
double z = z1 + s*dz;
dist[s] = s*ds;
value[s] = signal.getInterpolatedPixel(x, y, z);
}
Plot plot = new Plot(name, "distance", "intensity", dist, value);
plot.show();
}
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 9a85f11..c42cfa2 100644
--- a/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_SpectralAnaylsis.java
+++ b/DeconvolutionLab2/src/course/DeconvolutionLab2_Course_SpectralAnaylsis.java
@@ -1,190 +1,190 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package course;
import java.io.File;
import javax.swing.filechooser.FileSystemView;
+import bilib.tools.Files;
import deconvolution.Deconvolution;
import deconvolutionlab.Imager;
import deconvolutionlab.Lab;
import deconvolutionlab.monitor.Monitors;
import fft.AbstractFFT;
import fft.FFT;
import ij.plugin.PlugIn;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.factory.DoG;
import signal.factory.Gaussian;
import signal.factory.complex.ComplexSignalFactory;
public class DeconvolutionLab2_Course_SpectralAnaylsis implements PlugIn {
- private String desktop = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator + "Desktop";
- private String root = desktop + File.separator + "Deconvolution" + File.separator;
+ private String root = Files.getDesktopDirectory() + "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", Imager.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 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("run", psf + image + algo).deconvolve();
algo = " -algorithm CONV " + out("CONV-PERTURBATED");
new Deconvolution("run", psf + image + algo).deconvolve();
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("run", psf + image + algo).deconvolve();
algo = " -algorithm SIM " + (6*noise) + " " + noise + " " + poisson + " " + out("NOISE");
new Deconvolution("run", impulse + constant + algo).deconvolve();
// No Noise
String nonoise = " -image file CONV.tif -psf file psfPerturbated.tif";
new Deconvolution("run", nonoise + " -algorithm TRIF " + wiener + out("NOISELESS/WIF")).deconvolve();
new Deconvolution("run", nonoise + " -algorithm NIF -epsilon 1E0 " + out("NOISELESS/NIF0")).deconvolve();
new Deconvolution("run", nonoise + " -algorithm NIF -epsilon 1E-3 " + out("NOISELESS/NIF-1")).deconvolve();
new Deconvolution("run", nonoise + " -algorithm NIF -epsilon 1E-6 " + out("NOISELESS/NIF-6")).deconvolve();
new Deconvolution("run", nonoise + " -algorithm NIF -epsilon 1E-9 " + out("NOISELESS/NIF-9")).deconvolve();
new Deconvolution("run", nonoise + " -algorithm NIF -epsilon 1E-12 " + out("NOISELESS/NIF-12")).deconvolve();
new Deconvolution("run", nonoise + " -algorithm DIV " + out("NOISELESS/DIV")).deconvolve();
// Pertubatation
String pertubation = " -image file CONV.tif -psf file psfPerturbated.tif";
new Deconvolution("run", pertubation + " -algorithm TRIF " + wiener + out("PERTURBATION/WIF")).deconvolve();
new Deconvolution("run", pertubation + " -algorithm NIF " + out("PERTURBATION/NIF")).deconvolve();
new Deconvolution("run", pertubation + " -algorithm DIV " + out("PERTURBATION/DIV")).deconvolve();
// Noisy
String simulation = " -image file SIM.tif " + psf;
new Deconvolution("run", simulation + " -algorithm TRIF " + wiener + out("SIMULATION/WIF")).deconvolve();
new Deconvolution("run", simulation + " -algorithm NIF "+ out("SIMULATION/NIF")).deconvolve();
new Deconvolution("run", simulation + " -algorithm DIV" + out("SIMULATION/DIV")).deconvolve();
algo = " -algorithm LW+ 100 0.5 -out mip @1 LW+-ITER/I ";
new Deconvolution("run", simulation + algo + out("LW+/LW+")).deconvolve();
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("run", simulation + " -algorithm RIF " + p + out(name)).deconvolve();
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("run", simulation + " -algorithm TRIF " + p + out(name)).deconvolve();
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("run", simulation + algo + out("RL/RL")).deconvolve();
new File(res + "RL-ITER/I.tif").delete();
algo = " -algorithm ICTM 100 1.5 0.001 -out mip @1 ICTM-ITER/I ";
new Deconvolution("run", simulation + algo + out("ICTM/ICTM")).deconvolve();
new File(res + "ICTM-ITER/I.tif").delete();
}
private static String out(String name) {
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 7262f4e..6a66a7d 100644
--- a/DeconvolutionLab2/src/deconvolution/Command.java
+++ b/DeconvolutionLab2/src/deconvolution/Command.java
@@ -1,424 +1,432 @@
/*
* 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 ij.IJ;
import java.util.ArrayList;
import java.util.Collections;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import bilib.tools.Files;
import bilib.tools.NumFormat;
import deconvolution.algorithm.AbstractAlgorithm;
import deconvolution.algorithm.Algorithm;
import deconvolution.algorithm.Controller;
import deconvolutionlab.Constants;
import deconvolutionlab.module.AbstractModule;
import deconvolutionlab.module.CommandModule;
import deconvolutionlab.monitor.ConsoleMonitor;
import deconvolutionlab.monitor.Monitors;
import deconvolutionlab.monitor.TableMonitor;
import deconvolutionlab.monitor.Verbose;
import deconvolutionlab.output.Output;
import deconvolutionlab.output.Output.View;
import fft.FFT;
import signal.Constraint;
import signal.Operations;
import signal.apodization.AbstractApodization;
import signal.apodization.Apodization;
import signal.apodization.UniformApodization;
import signal.padding.AbstractPadding;
import signal.padding.NoPadding;
import signal.padding.Padding;
import wavelets.Wavelets;
public class Command {
public static String keywords[] = { "-image", "-psf", "-algorithm", "-path", "-disable", "-verbose", "-monitor", "-display", "-multithreading", "-system", "-stats", "-constraint", "-time", "-residu", "-reference", "-out", "-pad", "-apo", "-norm", "-fft", "-epsilon" };
private static AbstractModule modules[];
private static CommandModule command;
public static void active(AbstractModule[] m, CommandModule c) {
modules = m;
command = c;
}
public static String command() {
if (modules == null)
return "";
String cmd = "";
for (AbstractModule m : modules)
cmd += m.getCommand() + " ";
if (command != null)
command.setCommand(cmd);
return cmd;
}
public static Controller decodeController(String command) {
Controller controller = new Controller();
ArrayList<Token> tokens = parse(command);
for (Token token : tokens) {
- if (token.keyword.equalsIgnoreCase("-path") && !token.parameters.equalsIgnoreCase("current"))
- controller.setPath(token.parameters);
-
+ if (token.keyword.equalsIgnoreCase("-path")) {
+ if (token.parameters.trim().equals("current"))
+ controller.setPath(Files.getWorkingDirectory());
+ else if (token.parameters.trim().equals("home"))
+ controller.setPath(Files.getHomeDirectory());
+ else if (token.parameters.trim().equals("desktop"))
+ controller.setPath(Files.getDesktopDirectory());
+ else
+ controller.setPath(token.parameters);
+ }
if (token.keyword.equalsIgnoreCase("-monitor"))
controller.setMonitors(decodeMonitors(token.parameters));
if (token.keyword.equalsIgnoreCase("-verbose"))
controller.setVerbose(Verbose.getByName(token.parameters));
if (token.keyword.equalsIgnoreCase("-system"))
controller.setSystem(decodeBoolean(token.parameters));
if (token.keyword.equalsIgnoreCase("-multithreading"))
controller.setMultithreading(decodeBoolean(token.parameters));
if (token.keyword.equalsIgnoreCase("-display"))
controller.setDisplayFinal(decodeBoolean(token.parameters));
if (token.keyword.equalsIgnoreCase("-stats"))
controller.setStats(decodeStats(token));
if (token.keyword.equalsIgnoreCase("-constraint"))
controller.setConstraint(decodeConstraint(token));
if (token.keyword.equalsIgnoreCase("-time"))
controller.setTimeLimit(decodeTimeLimit(token));
if (token.keyword.equalsIgnoreCase("-residu"))
controller.setResiduMin(decodeResidu(token));
if (token.keyword.equalsIgnoreCase("-reference"))
controller.setReference(token.parameters);
if (token.keyword.equalsIgnoreCase("-pad"))
controller.setPadding(decodePadding(token));
if (token.keyword.equalsIgnoreCase("-apo"))
controller.setApodization(decodeApodization(token));
if (token.keyword.equalsIgnoreCase("-norm"))
controller.setNormalizationPSF(decodeNormalization(token));
if (token.keyword.equalsIgnoreCase("-epsilon"))
Operations.epsilon = NumFormat.parseNumber(token.parameters, 1e-6);
if (token.keyword.equalsIgnoreCase("-fft"))
controller.setFFT(FFT.getLibraryByName(token.parameters).getDefaultFFT());
if (token.keyword.equalsIgnoreCase("-epsilon"))
Operations.epsilon = NumFormat.parseNumber(token.parameters, 1e-6);
if (token.keyword.equals("-out")) {
Output out = decodeOut(token);
if (out != null)
controller.addOutput(out);
}
}
return controller;
}
public static AbstractAlgorithm decodeAlgorithm(String command) {
AbstractAlgorithm algo = Algorithm.getDefaultAlgorithm();
ArrayList<Token> tokens = parse(command);
for (Token token : tokens) {
if (token.keyword.equalsIgnoreCase("-algorithm"))
algo = Command.decodeAlgorithm(token);
}
return algo;
}
/**
* This methods first segments the command line, then create all the tokens
* of the command line
*
* @param command
* Command line
* @return the list of tokens extracted from the command line
*/
public static ArrayList<Token> parse(String command) {
ArrayList<CommandSegment> segments = new ArrayList<CommandSegment>();
for (String keyword : keywords)
segments.addAll(findSegment(command, keyword));
Collections.sort(segments);
ArrayList<Token> tokens = new ArrayList<Token>();
for (int i = 0; i < segments.size(); i++) {
String keyword = segments.get(i).keyword;
int begin = segments.get(i).index + keyword.length() + 1;
int end = (i < segments.size() - 1 ? segments.get(i + 1).index : command.length());
Token token = new Token(keyword, command, begin, end);
tokens.add(token);
}
return tokens;
}
public static Token extract(String command, String keyword) {
ArrayList<Token> tokens = parse(command);
for (Token token : tokens)
if (token.keyword.equalsIgnoreCase(keyword))
return token;
return (Token) null;
}
public static double[] parseNumeric(String line) {
ArrayList<String> num = new ArrayList<String>();
Pattern p = Pattern.compile("[-+]?[0-9]+[.]?[0-9]*([eE][-+]?[0-9]+)?");
Matcher m = p.matcher(line);
while (m.find()) {
num.add(m.group());
}
double number[] = new double[num.size()];
for (int i = 0; i < num.size(); i++)
number[i] = Double.parseDouble(num.get(i));
return number;
}
public static ArrayList<CommandSegment> findSegment(String command, String keyword) {
ArrayList<CommandSegment> segments = new ArrayList<CommandSegment>();
String regex = "(?<!\\w)" + keyword + "(?!\\w)";
if (command == null)
return segments;
Matcher matcher = Pattern.compile(regex).matcher(command);
while (matcher.find()) {
segments.add(new CommandSegment(keyword, matcher.start()));
}
return segments;
}
public static String extractOptions(String command) {
ArrayList<CommandSegment> segments = new ArrayList<CommandSegment>();
for (String keyword : keywords)
segments.addAll(findSegment(command, keyword));
Collections.sort(segments);
String options = "";
for (int i = 0; i < segments.size(); i++) {
String keyword = segments.get(i).keyword;
int begin = segments.get(i).index + keyword.length() + 1;
int end = (i < segments.size() - 1 ? segments.get(i + 1).index : command.length());
if (keyword != "-image" && keyword != "-psf" && keyword != "-algorithm")
options += keyword + " " + command.substring(begin, end);
}
return options;
}
public static AbstractAlgorithm decodeAlgorithm(Token token) {
String option = token.option;
AbstractAlgorithm algo = Algorithm.createAlgorithm(option);
double params[] = parseNumeric(token.parameters);
if (params != null) {
algo.setParameters(params);
}
if (algo.isWaveletsBased()) {
for (String wavelet : Wavelets.getWaveletsAsArray()) {
int pos = token.parameters.toLowerCase().indexOf(wavelet.toLowerCase());
if (pos >= 0)
algo.setWavelets(wavelet);
}
}
return algo;
}
public static Output decodeOut(Token token) {
int freq = 0;
String line = token.parameters;
String parts[] = token.parameters.split(" ");
for (int i = 0; i < Math.min(2, parts.length); i++) {
if (parts[i].startsWith("@"))
freq = (int) NumFormat.parseNumber(parts[i], 0);
}
String p = token.parameters.toLowerCase();
Output out = null;
if (p.startsWith("stack"))
out = new Output(View.STACK, freq, line.substring("stack".length(), line.length()));
if (p.startsWith("series"))
out = new Output(View.SERIES, freq, line.substring("series".length(), line.length()));
if (p.startsWith("mip"))
out = new Output(View.MIP, freq, line.substring("mip".length(), line.length()));
if (p.startsWith("ortho"))
out = new Output(View.ORTHO, freq, line.substring("ortho".length(), line.length()));
if (p.startsWith("figure"))
out = new Output(View.FIGURE, freq, line.substring("figure".length(), line.length()));
if (p.startsWith("planar"))
out = new Output(View.PLANAR, freq, line.substring("planar".length(), line.length()));
return out;
}
public static double decodeNormalization(Token token) {
if (token.parameters.toLowerCase().endsWith("no"))
return 0;
else
return NumFormat.parseNumber(token.parameters, 1);
}
public static Stats decodeStats(Token token) {
String parts[] = token.parameters.toLowerCase().split(" ");
int m = 0;
for (String p : parts) {
if (p.startsWith("no") || p.equals("false") || p.equals("0"))
return new Stats(Stats.Mode.NO);
if (p.equals("1"))
return new Stats(Stats.Mode.SHOW);
if (p.equals("2"))
return new Stats(Stats.Mode.SAVE);
if (p.equals("3"))
return new Stats(Stats.Mode.SHOWSAVE);
if (p.equals("show"))
m += 1;
if (p.equals("save"))
m += 2;
}
if (m==1)
return new Stats(Stats.Mode.SHOW);
if (m==2)
return new Stats(Stats.Mode.SAVE);
if (m==3)
return new Stats(Stats.Mode.SHOWSAVE);
return new Stats(Stats.Mode.NO);
}
public static Constraint.Mode decodeConstraint(Token token) {
String p = token.parameters.toLowerCase();
if (p.startsWith("non"))
return Constraint.Mode.NONNEGATIVE;
if (p.startsWith("no"))
return Constraint.Mode.NO;
if (p.startsWith("clip"))
return Constraint.Mode.CLIPPED;
if (p.equals("0"))
return Constraint.Mode.NO;
return Constraint.Mode.NO;
}
public static double decodeResidu(Token token) {
if (token.parameters.toLowerCase().endsWith("no"))
return -1;
else
return NumFormat.parseNumber(token.parameters, 1);
}
public static double decodeTimeLimit(Token token) {
if (token.parameters.toLowerCase().endsWith("no"))
return -1;
else
return NumFormat.parseNumber(token.parameters, 1);
}
public static Padding decodePadding(Token token) {
AbstractPadding padXY = new NoPadding();
AbstractPadding padZ = new NoPadding();
String param = token.parameters.trim();
String[] parts = param.split(" ");
if (parts.length > 0)
padXY = Padding.getByShortname(parts[0].trim());
if (parts.length > 1)
padZ = Padding.getByShortname(parts[1].trim());
double[] ext = NumFormat.parseNumbers(param);
int extXY = 0;
if (ext.length > 0)
extXY = (int) Math.round(ext[0]);
int extZ = 0;
if (ext.length > 1)
extZ = (int) Math.round(ext[1]);
return new Padding(padXY, padXY, padZ, extXY, extXY, extZ);
}
public static Apodization decodeApodization(Token token) {
AbstractApodization apoXY = new UniformApodization();
AbstractApodization apoZ = new UniformApodization();
String[] parts = token.parameters.trim().split(" ");
if (parts.length >= 1)
apoXY = Apodization.getByShortname(parts[0].trim());
if (parts.length >= 2)
apoZ = Apodization.getByShortname(parts[1].trim());
return new Apodization(apoXY, apoXY, apoZ);
}
public static String getPath() {
command();
ArrayList<Token> tokens = parse(command.getCommand());
String path = System.getProperty("user.dir");
for (Token token : tokens)
if (token.keyword.equalsIgnoreCase("-path") && !token.parameters.equalsIgnoreCase("current"))
path = token.parameters;
return path;
}
public static Monitors decodeMonitors(String cmd) {
String parts[] = cmd.toLowerCase().split(" ");
Monitors monitors = new Monitors();
for (String p : parts) {
if (p.equals("0") || p.startsWith("no"))
monitors.clear();
if (p.equals("1") || p.startsWith("console"))
monitors.add(new ConsoleMonitor());
if (p.equals("2"))
monitors.add(new TableMonitor(Constants.widthGUI, 240));
if (p.equals("3")) {
monitors.add(new ConsoleMonitor());
monitors.add(new TableMonitor(Constants.widthGUI, 240));
}
if (p.equals("console"))
monitors.add(new ConsoleMonitor());
if (p.equals("table"))
monitors.add(new TableMonitor(Constants.widthGUI, 240));
}
return monitors;
}
public static boolean decodeBoolean(String cmd) {
String p = cmd.toLowerCase();
if (p.startsWith("no"))
return false;
if (p.equals("0"))
return false;
if (p.equals("false"))
return false;
if (p.startsWith("dis"))
return false;
return true;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/Deconvolution.java b/DeconvolutionLab2/src/deconvolution/Deconvolution.java
index 08f08da..d3b0936 100644
--- a/DeconvolutionLab2/src/deconvolution/Deconvolution.java
+++ b/DeconvolutionLab2/src/deconvolution/Deconvolution.java
@@ -1,420 +1,410 @@
/*
* 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 ij.IJ;
import java.io.File;
-import com.esotericsoftware.minlog.Log;
-
import bilib.tools.NumFormat;
import deconvolution.algorithm.AbstractAlgorithm;
import deconvolution.algorithm.Controller;
import deconvolutionlab.Lab;
import deconvolutionlab.monitor.AbstractMonitor;
import deconvolutionlab.monitor.Monitors;
import deconvolutionlab.monitor.StatusMonitor;
import deconvolutionlab.monitor.TableMonitor;
import deconvolutionlab.output.Output;
import signal.RealSignal;
import signal.SignalCollector;
/**
* This class is the main class to run deconvolution with or without user interface.
*
* All the parameters are given in the command line (String variable command).
*
* @author Daniel Sage
*
*/
public class Deconvolution implements Runnable {
public enum Finish {
DIE, ALIVE, KILL
};
private AbstractAlgorithm algo = null;
private Controller controller = new Controller();
private String command = "";
private Features report = new Features();
private String name = "";
public RealSignal image;
public RealSignal psf;
private RealSignal deconvolvedImage;
private Finish finish = Finish.DIE;
private DeconvolutionDialog dialog;
private boolean embeddedStats = false;
public Deconvolution(String name, String command) {
this.name = name;
this.finish = Finish.DIE;
-IJ.log("Deconvolution, line 82 " + command);
-
setCommand(command);
-IJ.log("Deconvolution, line 84 " + command);
-
}
public Deconvolution(String name, String command, Finish finish) {
this.name = name;
this.finish = finish;
setCommand(command);
}
public void setCommand(String command) {
this.command = command;
controller = Command.decodeController(command);
algo = Command.decodeAlgorithm(command);
algo.setController(controller);
this.command = command;
if (name.equals("") && algo != null)
name = algo.getShortnames()[0];
}
public RealSignal deconvolve() {
return deconvolve(image, psf);
}
public RealSignal deconvolve(RealSignal image, RealSignal psf) {
this.image = image;
this.psf = psf;
for(AbstractMonitor monitor : controller.getMonitors())
if (monitor instanceof TableMonitor)
Lab.setVisible(((TableMonitor)monitor).getPanel(), "Monitor of " + name, 10, 10);
if (controller.getFFT() == null) {
run();
return deconvolvedImage;
}
if (!controller.getFFT().isMultithreadable()) {
run();
return deconvolvedImage;
}
if (controller.isMultithreading()) {
Thread thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}
else {
run();
}
return deconvolvedImage;
}
/**
* This method runs the deconvolution with a graphical user interface.
*/
public void launch() {
embeddedStats = true;
dialog = new DeconvolutionDialog(DeconvolutionDialog.Module.ALL, this);
Lab.setVisible(dialog, false);
}
@Override
public void run() {
double chrono = System.nanoTime();
Monitors monitors = controller.getMonitors();
report.add("Path", controller.toStringPath());
if (image == null)
image = openImage();
if (image == null) {
monitors.error("Image: Not valid " + command);
report.add("Image", "Not valid");
if (finish == Finish.KILL)
System.exit(-101);
return;
}
report.add("Image", image.dimAsString());
monitors.log("Image: " + image.dimAsString());
psf = openPSF();
if (psf == null) {
monitors.error("PSF: not valid");
report.add("PSF", "Not valid");
if (finish == Finish.KILL)
System.exit(-102);
return;
}
report.add("PSF", psf.dimAsString());
if (algo == null) {
monitors.error("Algorithm: not valid");
if (finish == Finish.KILL)
System.exit(-103);
return;
}
report.add("FFT", controller.getFFT().getName());
report.add("Algorithm", algo.getName());
if (embeddedStats) {
TableMonitor tableMonitor = null;
for(AbstractMonitor monitor : controller.getMonitors())
if (monitor instanceof TableMonitor)
tableMonitor = (TableMonitor)monitor;
if (controller.getStats().getMode() == Stats.Mode.SHOW || controller.getStats().getMode() == Stats.Mode.SHOWSAVE) {
controller.getStats().setEmbeddedInFrame(embeddedStats);
dialog.addStats(controller.getStats());
}
if (tableMonitor != null) {
dialog.addMonitor(tableMonitor);
}
}
algo.setController(controller);
deconvolvedImage = algo.run(image, psf);
report.add("End", NumFormat.time(System.nanoTime() - chrono));
if (finish == Finish.KILL) {
System.out.println("End");
System.exit(0);
}
if (finish == Finish.DIE)
die();
}
public void close() {
if (dialog != null)
dialog.dispose();
SignalCollector.free(image);
SignalCollector.free(psf);
SignalCollector.free(deconvolvedImage);
algo = null;
image = null;
psf = null;
deconvolvedImage = null;
System.gc();
}
public void die() {
SignalCollector.free(image);
SignalCollector.free(psf);
}
/**
* This methods make a recap of the deconvolution. Useful before starting
* the processing.
*
* @return list of messages to print
*/
public Features recap() {
Features features = new Features();
Token image = Command.extract(command, "-image");
features.add("Image", image == null ? "keyword -image not found" : image.parameters);
double norm = controller.getNormalizationPSF();
String normf = (norm < 0 ? " (no normalization)" : " (normalization to " + norm + ")");
Token psf = Command.extract(command, "-psf");
features.add("PSF", psf == null ? "keyword -psf not found" : psf.parameters + " norm:" + normf);
if (algo == null) {
features.add("Algorithm", "not valid>");
}
else {
Controller controller = algo.getController();
features.add("Algorithm", algo.toString());
features.add("Stopping Criteria", controller.getStoppingCriteriaAsString(algo));
features.add("Reference", controller.getReference());
features.add("Constraint", controller.getConstraintAsString());
features.add("Padding", controller.getPadding().toString());
features.add("Apodization", controller.getApodization().toString());
features.add("FFT", controller.getFFT() == null ? "null" : controller.getFFT().getName());
}
features.add("Path", controller.getPath());
String s = "[" + controller.getVerbose().name() + "] ";
for(AbstractMonitor monitor : controller.getMonitors())
s+= monitor.getName() + " ";
features.add("Monitor", s);
if (controller.getStats() != null)
features.add("Stats", controller.getStats().toStringStats());
features.add("Running", controller.toStringRunning());
for (Output out : controller.getOuts())
features.add("Output " + out.getName(), out.toString());
- Log.info("Recap deconvolution parameters");
+ controller.getMonitors().log("Recap deconvolution parameters");
return features;
}
public Features checkOutput() {
Features features = new Features();
if (deconvolvedImage == null) {
features.add("Image", "No valid output image");
return features;
}
float stati[] = deconvolvedImage.getStats();
int sizi = deconvolvedImage.nx * deconvolvedImage.ny * deconvolvedImage.nz;
float totali = stati[0] * sizi;
features.add("<html><b>Deconvolved Image</b></html>", "");
features.add("Size", deconvolvedImage.dimAsString() + " " + NumFormat.bytes(sizi * 4));
features.add("Mean (stdev)", NumFormat.nice(stati[0]) + " (" + NumFormat.nice(stati[3]) + ")");
features.add("Min ... Max", NumFormat.nice(stati[1]) + " ... " + NumFormat.nice(stati[2]));
features.add("Energy (int)", NumFormat.nice(stati[5]) + " (" + NumFormat.nice(totali) + ")");
return features;
}
public void abort() {
algo.getController().abort();
}
public RealSignal openImage() {
Token token = Command.extract(command, "-image");
if (token == null)
return null;
if (token.parameters.startsWith(">>>"))
return null;
String arg = token.option.trim();
String cmd = token.parameters.substring(arg.length(), token.parameters.length()).trim();
image = createRealSignal(controller.getMonitors(), arg, cmd, controller.getPath());
-IJ.log("Deconvolution, line 312 " + (image==null));
- Log.info("Open image " + arg + " " + cmd);
-IJ.log("Deconvolution, line 314 " + (image==null));
+ controller.getMonitors().log("Open image " + arg + " " + cmd);
return image;
}
public RealSignal openPSF() {
Token token = Command.extract(command, "-psf");
if (token == null)
return null;
if (token.parameters.startsWith(">>>"))
return null;
String arg = token.option.trim();
String cmd = token.parameters.substring(arg.length(), token.parameters.length()).trim();
psf = createRealSignal(controller.getMonitors(), arg, cmd, controller.getPath());
- Log.info("Open PSF " + arg + " " + cmd);
+ controller.getMonitors().log("Open PSF " + arg + " " + cmd);
return psf;
}
private static RealSignal createRealSignal(Monitors monitors, String arg, String cmd, String path) {
RealSignal signal = null;
-IJ.log("Deconvolution, line 337 " + arg);
if (arg.equalsIgnoreCase("synthetic")) {
-IJ.log("Deconvolution, synthetic 337 " + arg);
signal = Lab.createSynthetic(monitors, cmd);
}
if (arg.equalsIgnoreCase("platform")) {
signal = Lab.getImage(monitors, cmd);
}
if (arg.equalsIgnoreCase("file")) {
File file = new File(path + File.separator + cmd);
if (file != null) {
if (file.isFile())
signal = Lab.openFile(monitors, path + File.separator + cmd);
}
if (signal == null) {
File local = new File(cmd);
if (local != null) {
if (local.isFile())
signal = Lab.openFile(monitors, cmd);
}
}
}
if (arg.equalsIgnoreCase("dir") || arg.equalsIgnoreCase("directory")) {
File file = new File(path + File.separator + cmd);
if (file != null) {
if (file.isDirectory())
signal = Lab.openDir(monitors, path + File.separator + cmd);
}
if (signal == null) {
File local = new File(cmd);
if (local != null) {
if (local.isDirectory())
signal = Lab.openDir(monitors, cmd);
}
}
}
return signal;
}
public void setAlgorithm(AbstractAlgorithm algo) {
this.algo = algo;
}
public AbstractAlgorithm getAlgorithm() {
return algo;
}
public void setController(Controller controller) {
this.controller = controller;
}
public Controller getController() {
return controller;
}
public RealSignal getOutput() {
return deconvolvedImage;
}
public RealSignal getImage() {
return image;
}
public RealSignal getPSF() {
return psf;
}
public Features getDeconvolutionReports() {
return report;
}
public String getName() {
return name;
}
public Monitors getMonitors() {
return controller.getMonitors();
}
public String getCommand() {
return command;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java b/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java
index 71c7659..e6c15e7 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/AbstractAlgorithm.java
@@ -1,474 +1,477 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import signal.Constraint;
import signal.RealSignal;
import signal.SignalCollector;
import signal.apodization.Apodization;
import signal.padding.Padding;
import bilib.tools.NumFormat;
-import deconvolution.DeconvolutionDialog;
import deconvolution.Stats;
import deconvolutionlab.Lab;
import deconvolutionlab.monitor.Monitors;
import deconvolutionlab.monitor.Verbose;
import deconvolutionlab.output.Output;
import deconvolutionlab.system.SystemInfo;
import fft.AbstractFFT;
import fft.FFT;
/**
* This class is the common part of every algorithm of deconvolution.
*
* @author Daniel Sage
*
*/
public abstract class AbstractAlgorithm implements Callable<RealSignal> {
/** y is the input signal of the deconvolution. */
protected RealSignal y;
/** h is the PSF signal for the deconvolution. */
protected RealSignal h;
protected boolean threaded;
/** Optimized implementation in term of memory footprint */
protected boolean optimizedMemoryFootprint;
protected int iterMax = 0;
protected AbstractFFT fft;
protected Controller controller;
public AbstractAlgorithm() {
setController(new Controller());
optimizedMemoryFootprint = true;
threaded = true;
fft = FFT.getFastestFFT().getDefaultFFT();
}
public AbstractAlgorithm(Controller controller) {
this.controller = controller;
optimizedMemoryFootprint = true;
threaded = true;
fft = FFT.getFastestFFT().getDefaultFFT();
}
public void setOptimizedMemoryFootprint(boolean optimizedMemoryFootprint) {
this.optimizedMemoryFootprint = optimizedMemoryFootprint;
}
public abstract String getName();
public abstract String[] getShortnames();
public abstract double getMemoryFootprintRatio();
public abstract int getComplexityNumberofFFT();
public abstract boolean isRegularized();
public abstract boolean isStepControllable();
public abstract boolean isIterative();
public abstract boolean isWaveletsBased();
- public abstract void setParameters(double[] params);
+ public abstract AbstractAlgorithm setParameters(double... params);
public abstract double getRegularizationFactor();
public abstract double getStepFactor();
public abstract double[] getParameters();
public abstract double[] getDefaultParameters();
public RealSignal run(RealSignal image, RealSignal psf) {
String sn = getShortnames()[0];
if (controller.isSystem())
SystemInfo.activate();
Padding pad = controller.getPadding();
Apodization apo = controller.getApodization();
double norm = controller.getNormalizationPSF();
fft = controller.getFFT();
controller.setIterationsMax(iterMax);
if (image == null)
return null;
if (psf == null)
return null;
// Prepare the controller and the outputs
Monitors monitors = controller.getMonitors();
monitors.setVerbose(controller.getVerbose());
monitors.log("Path: " + controller.toStringPath());
monitors.log("Algorithm: " + getName());
// Prepare the signal and the PSF
y = pad.pad(monitors, image);
y.setName("y");
apo.apodize(monitors, y);
monitors.log("Input: " + y.dimAsString());
h = psf.changeSizeAs(y);
h.setName("h");
h.normalize(norm);
monitors.log("PSF: " + h.dimAsString() + " normalized " + (norm <= 0 ? "no" : norm));
String iterations = (isIterative() ? iterMax + " iterations" : "direct");
controller.setIterationsMax(iterMax);
monitors.log(getShortnames()[0] + " is starting (" + iterations + ")");
controller.setMonitors(monitors);
controller.start(y);
h.circular();
// FFT
fft.init(monitors, y.nx, y.ny, y.nz);
controller.setFFT(fft);
monitors.log(getShortnames()[0] + " data ready");
monitors.log(getShortnames()[0] + "" + getParametersToString());
RealSignal x = null;
try {
if (threaded == true) {
ExecutorService pool = Executors.newSingleThreadExecutor();
Future<RealSignal> future = pool.submit(this);
x = future.get();
}
else {
x = call();
}
}
catch (InterruptedException ex) {
ex.printStackTrace();
x = y.duplicate();
}
catch (ExecutionException ex) {
ex.printStackTrace();
x = y.duplicate();
}
catch (Exception e) {
e.printStackTrace();
x = y.duplicate();
}
SignalCollector.free(y);
SignalCollector.free(h);
x.setName("x");
RealSignal result = pad.crop(monitors, x);
controller.finish(result);
monitors.log(getName() + " is finished");
SignalCollector.free(x);
if (controller.isDisplayFinal())
Lab.show(monitors, result, "Final Display of " + sn);
result.setName("Output of " + sn);
monitors.log("End of " + sn + " in " + NumFormat.seconds(controller.getTimeNano()) + " and " + controller.getMemoryAsString());
return result;
}
+ public AbstractAlgorithm noPopup() {
+ return this.disableDisplayFinal().disableSystem();
+ }
+
public AbstractAlgorithm setController(Controller controller) {
this.controller = controller;
return this;
}
public Controller getController() {
return controller;
}
public int getIterationsMax() {
return iterMax;
}
public int getIterations() {
return controller.getIterations();
}
public double getTime() {
return controller.getTimeNano();
}
public double getMemory() {
return controller.getMemory();
}
public double getResidu() {
return controller.getResidu();
}
public double getSNR() {
return controller.getSNR();
}
public double getPSNR() {
return controller.getPSNR();
}
public void setWavelets(String waveletsName) {
}
@Override
public String toString() {
String s = "";
s += getName();
s += (isIterative() ? ", " + iterMax + " iterations" : " (direct)");
s += (isRegularized() ? ", &lambda=" + NumFormat.nice(getRegularizationFactor()) : "");
s += (isStepControllable() ? ", &gamma=" + NumFormat.nice(getStepFactor()) : "");
return s;
}
public String getParametersAsString() {
double p[] = getParameters();
String param = "";
for (int i = 0; i < p.length; i++)
if (i == p.length - 1)
param += p[i];
else
param += p[i] + ", ";
return param;
}
public AbstractFFT getFFT() {
return controller.getFFT();
}
public AbstractAlgorithm setFFT(AbstractFFT fft) {
this.fft = fft;
controller.setFFT(fft);
return this;
}
public String getPath() {
return controller.getPath();
}
public AbstractAlgorithm setPath(String path) {
controller.setPath(path);
return this;
}
public boolean isSystem() {
return controller.isSystem();
}
public AbstractAlgorithm enableSystem() {
controller.setSystem(true);
return this;
}
public AbstractAlgorithm disableSystem() {
controller.setSystem(false);
return this;
}
public boolean isMultithreading() {
return controller.isMultithreading();
}
public AbstractAlgorithm enableMultithreading() {
controller.setMultithreading(true);
return this;
}
public AbstractAlgorithm disableMultithreading() {
controller.setMultithreading(false);
return this;
}
public boolean isDisplayFinal() {
return controller.isDisplayFinal();
}
public AbstractAlgorithm enableDisplayFinal() {
controller.setDisplayFinal(true);
return this;
}
public AbstractAlgorithm disableDisplayFinal() {
controller.setDisplayFinal(false);
return this;
}
public double getNormalizationPSF() {
return controller.getNormalizationPSF();
}
public AbstractAlgorithm setNormalizationPSF(double normalizationPSF) {
controller.setNormalizationPSF(normalizationPSF);
return this;
}
public double getEpsilon() {
return controller.getEpsilon();
}
public AbstractAlgorithm setEpsilon(double epsilon) {
controller.setEpsilon(epsilon);
return this;
}
public Padding getPadding() {
return controller.getPadding();
}
public AbstractAlgorithm setPadding(Padding padding) {
controller.setPadding(padding);
return this;
}
public Apodization getApodization() {
return controller.getApodization();
}
public AbstractAlgorithm setApodization(Apodization apodization) {
controller.setApodization(apodization);
return this;
}
public Monitors getMonitors() {
return controller.getMonitors();
}
public AbstractAlgorithm setMonitors(Monitors monitors) {
controller.setMonitors(monitors);
return this;
}
public Verbose getVerbose() {
return controller.getVerbose();
}
public AbstractAlgorithm setVerbose(Verbose verbose) {
controller.setVerbose(verbose);
return this;
}
public Constraint.Mode getConstraint() {
return controller.getConstraint();
}
public AbstractAlgorithm setConstraint(Constraint.Mode constraint) {
controller.setConstraint(constraint);
return this;
}
public Stats getStats() {
return controller.getStats();
}
public AbstractAlgorithm setStats(Stats stats) {
controller.setStats(stats);
return this;
}
public AbstractAlgorithm showStats() {
controller.setStats(new Stats(Stats.Mode.SHOW));
return this;
}
public AbstractAlgorithm saveStats(Stats stats) {
controller.setStats(new Stats(Stats.Mode.SAVE));
return this;
}
public AbstractAlgorithm setStats() {
controller.setStats(new Stats(Stats.Mode.SHOWSAVE));
return this;
}
public double getResiduMin() {
return controller.getResiduMin();
}
public AbstractAlgorithm setResiduMin(double residuMin) {
controller.setResiduMin(residuMin);
return this;
}
public double getTimeLimit() {
return controller.getTimeLimit();
}
public AbstractAlgorithm setTimeLimit(double timeLimit) {
controller.setTimeLimit(timeLimit);
return this;
}
public String getReference() {
return controller.getReference();
}
public AbstractAlgorithm setReference(String reference) {
controller.setReference(reference);
return this;
}
public ArrayList<Output> getOuts() {
return controller.getOuts();
}
public AbstractAlgorithm setOuts(ArrayList<Output> outs) {
controller.setOuts(outs);
return this;
}
public AbstractAlgorithm addOutput(Output out) {
controller.addOutput(out);
return this;
}
public String getParametersToString() {
double params[] = getParameters();
if (params != null) {
if (params.length > 0) {
String s = " ";
for (double param : params)
s += NumFormat.nice(param) + " ";
return s;
}
}
return "parameter-free";
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java b/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java
index 3acf55b..7d29903 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java
@@ -1,642 +1,645 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.io.File;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import signal.Assessment;
import signal.ComplexSignal;
import signal.Constraint;
import signal.RealSignal;
import signal.apodization.Apodization;
import signal.padding.Padding;
+import bilib.tools.Files;
import bilib.tools.NumFormat;
import deconvolution.Deconvolution;
import deconvolution.Stats;
import deconvolutionlab.Constants;
import deconvolutionlab.monitor.AbstractMonitor;
import deconvolutionlab.monitor.ConsoleMonitor;
import deconvolutionlab.monitor.Monitors;
import deconvolutionlab.monitor.TableMonitor;
import deconvolutionlab.monitor.Verbose;
import deconvolutionlab.output.Output;
import deconvolutionlab.system.SystemUsage;
import fft.AbstractFFT;
import fft.FFT;
/**
* This is an important class to manage all the common task of the algorithm.
* The method start() is called before at the starting of the algorithm. The
* method ends() is called at the end of every iterations for the iterative
* algorithm. It returns true if one the stopping criteria is true. The method
* finish() is called when the algorithm is completely terminated.
*
* @author Daniel Sage
*
*/
public class Controller {
private String path;
private boolean system;
private boolean multithreading;
private boolean displayFinal;
private double normalizationPSF;
private double epsilon;
private Padding padding;
private Apodization apodization;
private ArrayList<Output> outs;
private Stats stats;
private Constraint.Mode constraintMode;
private double residuMin;
private double timeLimit;
private String reference;
private Monitors monitors;
private Verbose verbose;
private AbstractFFT fft;
private int iterationsMax = 100;
private boolean doResidu = false;
private boolean doTime = false;
private boolean doReference = false;
private boolean doConstraint = false;
private boolean abort = false;
private double timeStarting = 0;
private double memoryStarting = 0;
private double residu = Double.MAX_VALUE;
private int iterations = 0;
private double memoryPeak = 0;
private double snr = 0;
private double psnr = 0;
private RealSignal refImage;
private RealSignal prevImage;
private RealSignal x;
private Timer timer;
public Controller() {
doResidu = false;
doTime = false;
doReference = false;
doConstraint = false;
timeStarting = System.nanoTime();
- setPath(System.getProperty("user.dir"));
+ setPath(Files.getWorkingDirectory());
setSystem(true);
setMultithreading(true);
setDisplayFinal(true);
setFFT(FFT.getFastestFFT().getDefaultFFT());
setNormalizationPSF(1);
setEpsilon(1e-6);
setPadding(new Padding());
setApodization(new Apodization());
monitors = new Monitors();
monitors.add(new ConsoleMonitor());
monitors.add(new TableMonitor(Constants.widthGUI, 240));
setVerbose(Verbose.Log);
setStats(new Stats(Stats.Mode.NO));
setConstraint(Constraint.Mode.NO);
setResiduMin(-1);
setTimeLimit(-1);
setReference("");
setOuts(new ArrayList<Output>());
}
public void setFFT(AbstractFFT fft) {
this.fft = fft;
}
public void abort() {
this.abort = true;
}
public void setIterationsMax(int iterationsMax) {
this.iterationsMax = iterationsMax;
}
public boolean needSpatialComputation() {
return doConstraint || doResidu || doReference;
}
/**
* Call one time at the beginning of the algorithms
*
* @param x
* the input signal
*/
public void start(RealSignal x) {
this.x = x;
stats.show();
stats.addInput(x);
iterations = 0;
timer = new Timer();
timer.schedule(new Updater(), 0, 100);
timeStarting = System.nanoTime();
memoryStarting = SystemUsage.getHeapUsed();
if (doConstraint && x != null)
Constraint.setModel(x);
if (doReference) {
refImage = new Deconvolution("Reference", "-image file " + reference).openImage();
if (refImage == null)
monitors.error("Impossible to load the reference image " + reference);
else
monitors.log("Reference image loaded");
}
for (Output out : outs)
out.executeStarting(monitors, x, this);
this.prevImage = x;
}
public boolean ends(ComplexSignal X) {
boolean out = false;
for (Output output : outs)
out = out | output.is(iterations);
if (doConstraint || doResidu || doReference || out) {
if (fft == null)
fft = FFT.createDefaultFFT(monitors, X.nx, X.ny, X.nz);
x = fft.inverse(X, x);
return ends(x);
}
return ends((RealSignal) null);
}
public boolean ends(RealSignal x) {
this.x = x;
if (doConstraint || doResidu || doReference)
compute(iterations, x, doConstraint, doResidu, doReference);
for (Output out : outs)
out.executeIterative(monitors, x, this, iterations);
iterations++;
double p = iterations * 100.0 / iterationsMax;
monitors.progress("Iterative " + iterations + "/" + iterationsMax, p);
double timeElapsed = getTimeSecond();
boolean stopIter = (iterations >= iterationsMax);
boolean stopTime = doTime && (timeElapsed >= timeLimit);
boolean stopResd = doResidu && (residu <= residuMin);
monitors.log("@" + iterations + " Time: " + NumFormat.seconds(timeElapsed*1e9));
addStats();
String prefix = "Stopped>> by ";
if (abort)
monitors.log(prefix + "abort");
if (stopIter)
monitors.log(prefix + "iteration " + iterations + " > " + iterationsMax);
if (stopTime)
monitors.log(prefix + "time " + timeElapsed + " > " + timeLimit);
if (stopResd)
monitors.log(prefix + "residu " + NumFormat.nice(residu) + " < " + NumFormat.nice(residuMin));
return abort | stopIter | stopTime | stopResd;
}
public void finish(RealSignal x) {
this.x = x;
boolean ref = doReference;
boolean con = doConstraint;
boolean res = doResidu;
if (con || res || ref)
compute(iterations, x, con, res, ref);
addStats();
stats.save(monitors, path);
for (Output out : outs)
out.executeFinal(monitors, x, this);
monitors.log("Time: " + NumFormat.seconds(getTimeNano()) + " Peak:" + getMemoryAsString());
if (timer != null)
timer.cancel();
}
private void compute(int iterations, RealSignal x, boolean con, boolean res, boolean ref) {
if (x == null)
return;
if (con && constraintMode != null)
new Constraint(monitors).apply(x, constraintMode);
if (ref && refImage != null) {
String s = "";
psnr = Assessment.psnr(x, refImage);
snr = Assessment.snr(x, refImage);
s += " PSNR: " + NumFormat.nice(psnr);
s += " SNR: " + NumFormat.nice(snr);
monitors.log("@" + iterations + " " + s);
}
residu = Double.MAX_VALUE;
if (res && prevImage != null) {
residu = Assessment.relativeResidu(x, prevImage);
prevImage = x.duplicate();
monitors.log("@" + iterations + " Residu: " + NumFormat.nice(residu));
}
}
private void addStats() {
String pnsrText = doReference ? NumFormat.nice(psnr) : "n/a";
String snrText = doReference ? NumFormat.nice(snr) : "n/a";
String residuText = doResidu ? NumFormat.nice(residu) : "n/a";
stats.add(x, iterations, NumFormat.seconds(getTimeNano()), pnsrText, snrText, residuText);
}
public double getTimeNano() {
return (System.nanoTime() - timeStarting);
}
public double getTimeSecond() {
return (System.nanoTime() - timeStarting) * 1e-9;
}
public String getConstraintAsString() {
if (!doConstraint)
return "no";
if (constraintMode == null)
return "null";
return constraintMode.name().toLowerCase();
}
public String getStoppingCriteriaAsString(AbstractAlgorithm algo) {
String stop = algo.isIterative() ? "iterations limit=" + algo.getIterationsMax() + ", " : "direct, ";
stop += doTime ? ", time limit=" + NumFormat.nice(timeLimit * 1e-9) : " no time limit" + ", ";
stop += doResidu ? ", residu limit=" + NumFormat.nice(residuMin) : " no residu limit";
return stop;
}
public double getMemory() {
return memoryPeak - memoryStarting;
}
public String getMemoryAsString() {
return NumFormat.bytes(getMemory());
}
public int getIterations() {
return iterations;
}
public double getSNR() {
return snr;
}
public double getPSNR() {
return psnr;
}
public double getResidu() {
return residu;
}
private void update() {
memoryPeak = Math.max(memoryPeak, SystemUsage.getHeapUsed());
}
public AbstractFFT getFFT() {
return fft;
}
/**
* @return the path
*/
public String getPath() {
return path;
}
/**
* @param path
* the path to set
*/
public void setPath(String path) {
this.path = path;
}
/**
* @return the system
*/
public boolean isSystem() {
return system;
}
/**
* @param system
* the system to set
*/
public void setSystem(boolean system) {
this.system = system;
}
/**
* @return the multithreading
*/
public boolean isMultithreading() {
return multithreading;
}
/**
* @param multithreading
* the multithreading to set
*/
public void setMultithreading(boolean multithreading) {
this.multithreading = multithreading;
}
/**
* @return the displayFinal
*/
public boolean isDisplayFinal() {
return displayFinal;
}
/**
* @param displayFinal
* the displayFinal to set
*/
public void setDisplayFinal(boolean displayFinal) {
this.displayFinal = displayFinal;
}
/**
* @return the normalizationPSF
*/
public double getNormalizationPSF() {
return normalizationPSF;
}
/**
* @param normalizationPSF
* the normalizationPSF to set
*/
public void setNormalizationPSF(double normalizationPSF) {
this.normalizationPSF = normalizationPSF;
}
/**
* @return the epsilon
*/
public double getEpsilon() {
return epsilon;
}
/**
* @param epsilon
* the epsilon to set
*/
public void setEpsilon(double epsilon) {
this.epsilon = epsilon;
}
/**
* @return the padding
*/
public Padding getPadding() {
return padding;
}
/**
* @param padding
* the padding to set
*/
public void setPadding(Padding padding) {
this.padding = padding;
}
/**
* @return the apodization
*/
public Apodization getApodization() {
return apodization;
}
/**
* @param apodization
* the apodization to set
*/
public void setApodization(Apodization apodization) {
this.apodization = apodization;
}
/**
* @return the monitors
*/
public Monitors getMonitors() {
+ if (monitors == null)
+ return Monitors.createDefaultMonitor();
return monitors;
}
/**
* @param monitors
* the monitors to set
*/
public void setMonitors(Monitors monitors) {
this.monitors = monitors;
}
/**
* @return the verbose
*/
public Verbose getVerbose() {
return verbose;
}
/**
* @param verbose
* the verbose to set
*/
public void setVerbose(Verbose verbose) {
this.verbose = verbose;
}
public Constraint.Mode getConstraint() {
return constraintMode;
}
public void setConstraint(Constraint.Mode constraintMode) {
doConstraint = constraintMode != Constraint.Mode.NO;
this.constraintMode = constraintMode;
}
/**
* @return the stats
*/
public Stats getStats() {
return stats;
}
/**
* @param stats
* the stats to set
*/
public void setStats(Stats stats) {
this.stats = stats;
}
/**
* @return the residuMin
*/
public double getResiduMin() {
return residuMin;
}
/**
* @param residuMin
* the residuMin to set
*/
public void setResiduMin(double residuMin) {
doResidu = residuMin > 0;
this.residuMin = residuMin;
}
/**
* @return the timeLimit
*/
public double getTimeLimit() {
return timeLimit;
}
/**
* @param timeLimit
* the timeLimit to set
*/
public void setTimeLimit(double timeLimit) {
doTime = timeLimit > 0;
this.timeLimit = timeLimit;
}
/**
* @return the reference
*/
public String getReference() {
return reference;
}
/**
* @param reference
* the reference to set
*/
public void setReference(String reference) {
doReference = false;
if (reference == null)
return;
if (reference.equals(""))
return;
doReference = true;
this.reference = reference;
}
/**
* @return the outs
*/
public ArrayList<Output> getOuts() {
return outs;
}
/**
* @param outs
* the outs to set
*/
public void setOuts(ArrayList<Output> outs) {
this.outs = outs;
}
public void addOutput(Output out) {
this.outs.add(out);
}
public String toStringMonitor() {
String s = "[" + verbose.name().toLowerCase() + "] ";
for (AbstractMonitor monitor : monitors) {
s += "" + monitor.getName() + " ";
}
return s;
}
public Stats.Mode getStatsMode() {
return stats.getMode();
}
public void setStatsMode(Stats.Mode mode) {
this.stats = new Stats(mode);
}
public String toStringRunning() {
String s = "";
s += "system " + (system ? "shown" : "hidden ");
s += ", multithreading " + (multithreading ? "on" : "off ");
s += ", display final " + (displayFinal ? "on " : "off ");
return s;
}
public String toStringPath() {
File dir = new File(path);
if (dir.exists()) {
if (dir.isDirectory()) {
if (dir.canWrite())
return path + " (writable)";
else
return path + " (non-writable)";
}
else {
return path + " (non-directory)";
}
}
else {
return path + " (not-valid)";
}
}
private class Updater extends TimerTask {
@Override
public void run() {
update();
}
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/Convolution.java b/DeconvolutionLab2/src/deconvolution/algorithm/Convolution.java
index b4e49cf..9aa4a72 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/Convolution.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/Convolution.java
@@ -1,122 +1,123 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
public class Convolution extends AbstractAlgorithm implements Callable<RealSignal> {
public Convolution() {
super();
}
@Override
public RealSignal call() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal X = Operations.multiply(H, Y);
SignalCollector.free(Y);
SignalCollector.free(H);
RealSignal x = fft.inverse(X);
SignalCollector.free(X);
return x;
}
@Override
public String getName() {
return "Convolution Noiseless";
}
@Override
public String[] getShortnames() {
return new String[] {"CONV"};
}
@Override
public int getComplexityNumberofFFT() {
return 3;
}
@Override
public double getMemoryFootprintRatio() {
return 8.0;
}
@Override
public boolean isRegularized() {
return false;
}
@Override
public boolean isStepControllable() {
return false;
}
@Override
public boolean isIterative() {
return false;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
- public void setParameters(double[] params) {
+ public AbstractAlgorithm setParameters(double... params) {
+ return this;
}
@Override
public double[] getParameters() {
return new double[] {};
}
@Override
public double[] getDefaultParameters() {
return new double[] {};
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return 0;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/FISTA.java b/DeconvolutionLab2/src/deconvolution/algorithm/FISTA.java
index bbb5e4b..b7bd81a 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/FISTA.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/FISTA.java
@@ -1,188 +1,189 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
import wavelets.AbstractWavelets;
import wavelets.Wavelets;
public class FISTA extends AbstractAlgorithm implements Callable<RealSignal> {
private double gamma = 1.0;
private double lambda = 0.1;
private String waveletsName = "Haar";
private int scale = 3;
public FISTA(int iterMax, double gamma, double lambda, String waveletsName, int scale) {
super();
this.iterMax = iterMax;
this.gamma = gamma;
this.lambda = lambda;
this.waveletsName = waveletsName;
this.scale = scale;
}
@Override
public RealSignal call() throws Exception {
AbstractWavelets wavelets = Wavelets.getWaveletsByName(waveletsName);
wavelets.setScale(scale);
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal A = Operations.delta(gamma, H);
ComplexSignal G = Operations.multiplyConjugate(gamma, H, Y);
SignalCollector.free(Y);
SignalCollector.free(H);
ComplexSignal Z = G.duplicate();
RealSignal x = fft.inverse(G);
RealSignal s = x.duplicate();
RealSignal z = x.duplicate();
RealSignal xprev = fft.inverse(G);
float pk1 = 1f;
float pk0 = 1f;
float threshold = (float) (lambda * gamma * 0.5);
RealSignal buffer = y.duplicate();
while (!controller.ends(x)) {
fft.transform(s, Z);
Z.times(A);
Z.plus(G);
fft.inverse(Z, z);
wavelets.shrinkage(threshold, z, x, buffer);
pk0 = pk1;
pk1 = (1f + (float) Math.sqrt(1f + 4f * pk0 * pk0)) * 0.5f;
update(xprev, x, (pk0 - 1f) / pk1, s);
}
SignalCollector.free(A);
SignalCollector.free(Z);
SignalCollector.free(G);
SignalCollector.free(s);
SignalCollector.free(z);
SignalCollector.free(xprev);
SignalCollector.free(buffer);
return x;
}
public void update(RealSignal xprev, RealSignal x, double w, RealSignal s) {
int nxy = x.nx * x.ny;
for (int k = 0; k < x.nz; k++)
for (int i = 0; i < nxy; i++) {
float vx = x.data[k][i];
s.data[k][i] = (float) (vx + w * (vx - xprev.data[k][i]));
xprev.data[k][i] = vx;
}
}
@Override
public String getName() {
return "Fast Iterative Shrinkage-Thresholding";
}
@Override
public String[] getShortnames() {
return new String[] {"FISTA"};
}
@Override
public int getComplexityNumberofFFT() {
return 4 + 4 * iterMax;
}
@Override
public double getMemoryFootprintRatio() {
return 15.0;
}
@Override
public boolean isRegularized() {
return true;
}
@Override
public boolean isStepControllable() {
return true;
}
@Override
public boolean isIterative() {
return true;
}
@Override
public boolean isWaveletsBased() {
return true;
}
@Override
public void setWavelets(String waveletsName) {
this.waveletsName = waveletsName;
}
@Override
- public void setParameters(double[] params) {
+ public AbstractAlgorithm setParameters(double... params) {
if (params == null)
- return;
+ return this;
if (params.length > 0)
iterMax = (int) Math.round(params[0]);
if (params.length > 1)
gamma = (float) params[1];
if (params.length > 2)
lambda = (float) params[2];
if (params.length > 3)
scale = (int) params[3];
+ return this;
}
@Override
public double[] getDefaultParameters() {
return new double[] { 10, 1, 0.1 };
}
@Override
public double[] getParameters() {
return new double[] { iterMax, gamma, lambda };
}
@Override
public double getRegularizationFactor() {
return lambda;
}
@Override
public double getStepFactor() {
return gamma;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/ICTM.java b/DeconvolutionLab2/src/deconvolution/algorithm/ICTM.java
index 0e13a33..9b6109f 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/ICTM.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/ICTM.java
@@ -1,153 +1,154 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Constraint;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
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 iterMax, double gamma, double lambda) {
super();
this.iterMax = iterMax;
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);
SignalCollector.free(L);
A.minus(L2);
SignalCollector.free(L2);
ComplexSignal G = Operations.multiplyConjugate(gamma, H, Y);
SignalCollector.free(H);
SignalCollector.free(Y);
ComplexSignal X = G.duplicate();
controller.setConstraint(Constraint.Mode.NONNEGATIVE);
while (!controller.ends(X)) {
X.times(A);
X.plus(G);
}
SignalCollector.free(A);
SignalCollector.free(G);
RealSignal x = fft.inverse(X);
SignalCollector.free(X);
return x;
}
@Override
public String getName() {
return "Iterative Contraint Tikhonov-Miller";
}
@Override
public String[] getShortnames() {
return new String[] {"ICTM"};
}
@Override
public int getComplexityNumberofFFT() {
return 3 + iterMax * 2;
}
@Override
public double getMemoryFootprintRatio() {
return 10.0;
}
@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) {
+ public AbstractAlgorithm setParameters(double... params) {
if (params == null)
- return;
+ return this;
if (params.length > 0)
iterMax = (int) Math.round(params[0]);
if (params.length > 1)
gamma = (float) params[1];
if (params.length > 2)
lambda = (float) params[2];
+ return this;
}
@Override
public double[] getDefaultParameters() {
return new double[] { 10, 1, 0.1 };
}
@Override
public double[] getParameters() {
return new double[] { iterMax, gamma, lambda };
}
@Override
public double getRegularizationFactor() {
return lambda;
}
@Override
public double getStepFactor() {
return gamma;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/ISTA.java b/DeconvolutionLab2/src/deconvolution/algorithm/ISTA.java
index a81998b..6253d28 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/ISTA.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/ISTA.java
@@ -1,180 +1,181 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
import wavelets.AbstractWavelets;
import wavelets.Wavelets;
public class ISTA extends AbstractAlgorithm implements Callable<RealSignal> {
private double gamma = 1.0;
private double lambda = 1.0;
private String waveletsName = "Haar";
private int scale = 3;
public ISTA(int iterMax, double gamma, double lambda, String waveletsName, int scale) {
super();
this.iterMax = iterMax;
this.gamma = gamma;
this.lambda = lambda;
this.waveletsName = waveletsName;
this.scale = scale;
}
@Override
public RealSignal call() throws Exception {
AbstractWavelets wavelets = Wavelets.getWaveletsByName(waveletsName);
wavelets.setScale(scale);
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal A = Operations.delta(gamma, H);
ComplexSignal G = Operations.multiplyConjugate(gamma, H, Y);
SignalCollector.free(Y);
SignalCollector.free(H);
ComplexSignal Z = G.duplicate();
RealSignal x = fft.inverse(G);
RealSignal z = x.duplicate();
float threshold = (float)(lambda*gamma*0.5);
RealSignal buffer = y.duplicate();
while(!controller.ends(x)) {
fft.transform(x, Z);
Z.times(A);
Z.plus(G);
fft.inverse(Z, z);
wavelets.shrinkage(threshold, z, x, buffer);
}
SignalCollector.free(A);
SignalCollector.free(Z);
SignalCollector.free(G);
SignalCollector.free(z);
SignalCollector.free(buffer);
return x;
}
public void update(RealSignal xprev, RealSignal x, double w, RealSignal s) {
int nxy = x.nx * x.ny;
for(int k=0; k<x.nz; k++)
for(int i=0; i< nxy; i++) {
float vx = x.data[k][i];
s.data[k][i] = (float)(vx + w*(vx - xprev.data[k][i]));
xprev.data[k][i] = vx;
}
}
@Override
public String getName() {
return "Iterative Shrinkage-Thresholding";
}
@Override
public String[] getShortnames() {
return new String[] {"ISTA"};
}
@Override
public int getComplexityNumberofFFT() {
return 3 + 4 * iterMax;
}
@Override
public double getMemoryFootprintRatio() {
return 13.0;
}
@Override
public boolean isRegularized() {
return true;
}
@Override
public boolean isStepControllable() {
return true;
}
@Override
public boolean isIterative() {
return true;
}
@Override
public boolean isWaveletsBased() {
return true;
}
@Override
public void setWavelets(String waveletsName) {
this.waveletsName = waveletsName;
}
@Override
- public void setParameters(double[] params) {
+ public AbstractAlgorithm setParameters(double... params) {
if (params == null)
- return;
+ return this;
if (params.length > 0)
iterMax = (int) Math.round(params[0]);
if (params.length > 1)
gamma = (float)params[1];
if (params.length > 2)
lambda = (float)params[2];
if (params.length > 3)
scale = (int)params[3];
+ return this;
}
@Override
public double[] getDefaultParameters() {
return new double[] {10, 1, 0.1};
}
@Override
public double[] getParameters() {
return new double[] {iterMax, gamma, lambda};
}
@Override
public double getRegularizationFactor() {
return lambda;
}
@Override
public double getStepFactor() {
return gamma;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/Identity.java b/DeconvolutionLab2/src/deconvolution/algorithm/Identity.java
index e2fc317..d1c097e 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/Identity.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/Identity.java
@@ -1,114 +1,115 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.RealSignal;
public class Identity extends AbstractAlgorithm implements Callable<RealSignal> {
public Identity() {
super();
}
@Override
public RealSignal call() {
return y.duplicate();
}
@Override
public String getName() {
return "Identity (copy)";
}
@Override
public String[] getShortnames() {
return new String[] {"I"};
}
@Override
public double getMemoryFootprintRatio() {
return 5.0;
}
@Override
public int getComplexityNumberofFFT() {
return 1;
}
@Override
public boolean isRegularized() {
return false;
}
@Override
public boolean isStepControllable() {
return false;
}
@Override
public boolean isIterative() {
return false;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
- public void setParameters(double[] params) {
+ public AbstractAlgorithm setParameters(double... params) {
+ return this;
}
@Override
public double[] getParameters() {
return new double[] {};
}
@Override
public double[] getDefaultParameters() {
return new double[] {};
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return 0;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/Landweber.java b/DeconvolutionLab2/src/deconvolution/algorithm/Landweber.java
index b737e30..63781ed 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/Landweber.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/Landweber.java
@@ -1,147 +1,148 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
public class Landweber extends AbstractAlgorithm implements Callable<RealSignal> {
private double gamma = 1.0;
public Landweber(int iterMax, double gamma) {
super();
this.iterMax = iterMax;
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);
SignalCollector.free(Y);
SignalCollector.free(H);
ComplexSignal X = G.duplicate();
X.setName("X");
while (!controller.ends(X)) {
X.times(A);
X.plus(G);
}
SignalCollector.free(A);
SignalCollector.free(G);
RealSignal x = fft.inverse(X);
SignalCollector.free(X);
return x;
}
@Override
public String getName() {
return "Landweber";
}
@Override
public String[] getShortnames() {
return new String[] {"LW", "LLS"};
}
@Override
public int getComplexityNumberofFFT() {
return 3 + (controller.needSpatialComputation() ? 2 * iterMax : 0);
}
@Override
public double getMemoryFootprintRatio() {
return 9.0;
}
@Override
public boolean isRegularized() {
return false;
}
@Override
public boolean isStepControllable() {
return true;
}
@Override
public boolean isIterative() {
return true;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
- public void setParameters(double[] params) {
+ public AbstractAlgorithm setParameters(double... params) {
if (params == null)
- return;
+ return this;
if (params.length > 0)
iterMax = (int) Math.round(params[0]);
if (params.length > 1)
gamma = (float) params[1];
+ return this;
}
@Override
public double[] getDefaultParameters() {
return new double[] { 10, 1 };
}
@Override
public double[] getParameters() {
return new double[] { iterMax, gamma };
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return gamma;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivity.java b/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivity.java
index bfc1240..6e46302 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivity.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/LandweberPositivity.java
@@ -1,149 +1,150 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Constraint;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
public class LandweberPositivity extends AbstractAlgorithm implements Callable<RealSignal> {
private double gamma = 1.0;
public LandweberPositivity(int iterMax, double gamma) {
super();
this.iterMax = iterMax;
controller.setConstraint(Constraint.Mode.NONNEGATIVE);
this.gamma = gamma;
}
@Override
// Landweber algorithm
// X(n+1) = X(n) + g*H*(Y-H*X(n))
// => X(n+1) = X(n) - g*H*H*X(n) + g*H*Y
// => X(n+1) = X(n) * (I-g*H*H) + g*H*Y
// => pre-compute: A = (I-g*H*H) and G = g*H*Y
// => Iteration : X(n+1) = X(n) * A + G with F(0) = G
public RealSignal call() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal A = Operations.delta(gamma, H);
ComplexSignal G = Operations.multiplyConjugate(gamma, H, Y);
ComplexSignal X = G.duplicate();
controller.setConstraint(Constraint.Mode.NONNEGATIVE);
SignalCollector.free(Y);
SignalCollector.free(H);
while (!controller.ends(X)) {
X.times(A);
X.plus(G);
}
SignalCollector.free(A);
SignalCollector.free(G);
RealSignal x = fft.inverse(X);
SignalCollector.free(X);
return x;
}
@Override
public String getName() {
return "Non-Linear Least-Square";
}
@Override
public String[] getShortnames() {
return new String[] {"NNLS", "LW+"};
}
@Override
public int getComplexityNumberofFFT() {
return 3 + iterMax * 2;
}
@Override
public double getMemoryFootprintRatio() {
return 10.0;
}
@Override
public boolean isRegularized() {
return false;
}
@Override
public boolean isStepControllable() {
return true;
}
@Override
public boolean isIterative() {
return true;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
- public void setParameters(double[] params) {
+ public AbstractAlgorithm setParameters(double... params) {
if (params == null)
- return;
+ return this;
if (params.length > 0)
iterMax = (int) Math.round(params[0]);
if (params.length > 1)
gamma = (float) params[1];
+ return this;
}
@Override
public double[] getDefaultParameters() {
return new double[] { 10, 1 };
}
@Override
public double[] getParameters() {
return new double[] { iterMax, gamma };
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return gamma;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/NaiveInverseFilter.java b/DeconvolutionLab2/src/deconvolution/algorithm/NaiveInverseFilter.java
index 53314be..f2a3aab 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/NaiveInverseFilter.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/NaiveInverseFilter.java
@@ -1,123 +1,124 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
public class NaiveInverseFilter extends AbstractAlgorithm implements Callable<RealSignal> {
public NaiveInverseFilter() {
super();
}
@Override
public RealSignal call() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal X = Operations.divideStabilized(Y, H);
SignalCollector.free(Y);
SignalCollector.free(H);
RealSignal x = fft.inverse(X);
SignalCollector.free(X);
return x;
}
@Override
public String getName() {
return "Naive Inverse Filter";
}
@Override
public String[] getShortnames() {
return new String[] {"NIF", "IF"};
}
@Override
public int getComplexityNumberofFFT() {
return 3;
}
@Override
public double getMemoryFootprintRatio() {
return 8.0;
}
@Override
public boolean isRegularized() {
return false;
}
@Override
public boolean isStepControllable() {
return false;
}
@Override
public boolean isIterative() {
return false;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
- public void setParameters(double[] params) {
+ public AbstractAlgorithm setParameters(double... params) {
+ return this;
}
@Override
public double[] getDefaultParameters() {
return new double[] {};
}
@Override
public double[] getParameters() {
return new double[] {};
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return 0;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/NonStabilizedDivision.java b/DeconvolutionLab2/src/deconvolution/algorithm/NonStabilizedDivision.java
index 4dcd0e8..5f30c5b 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/NonStabilizedDivision.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/NonStabilizedDivision.java
@@ -1,123 +1,124 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
public class NonStabilizedDivision extends AbstractAlgorithm implements Callable<RealSignal> {
public NonStabilizedDivision() {
super();
}
@Override
public RealSignal call() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal X = Operations.divideNotStabilized(Y, H);
SignalCollector.free(Y);
SignalCollector.free(H);
RealSignal x = fft.inverse(X);
SignalCollector.free(X);
return x;
}
@Override
public String getName() {
return "Non Stablized Division";
}
@Override
public String[] getShortnames() {
return new String[] {"DIV"};
}
@Override
public int getComplexityNumberofFFT() {
return 3;
}
@Override
public double getMemoryFootprintRatio() {
return 8.0;
}
@Override
public boolean isRegularized() {
return false;
}
@Override
public boolean isStepControllable() {
return false;
}
@Override
public boolean isIterative() {
return false;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
- public void setParameters(double[] params) {
+ public AbstractAlgorithm setParameters(double... params) {
+ return this;
}
@Override
public double[] getDefaultParameters() {
return new double[] {};
}
@Override
public double[] getParameters() {
return new double[] {};
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return 0;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/RegularizedInverseFilter.java b/DeconvolutionLab2/src/deconvolution/algorithm/RegularizedInverseFilter.java
index a74440a..309f51e 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/RegularizedInverseFilter.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/RegularizedInverseFilter.java
@@ -1,189 +1,190 @@
/*
* 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 deconvolutionlab.Lab;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
import signal.factory.complex.ComplexSignalFactory;
public class RegularizedInverseFilter extends AbstractAlgorithm implements Callable<RealSignal> {
private double lambda = 0.001;
public RegularizedInverseFilter(double lambda) {
super();
this.lambda = lambda;
}
@Override
public RealSignal call() {
if (optimizedMemoryFootprint)
return runOptimizedMemoryFootprint();
else
return runTextBook();
}
public RealSignal runTextBook() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal H2 = Operations.multiply(H, H);
ComplexSignal L = ComplexSignalFactory.laplacian(Y.nx, Y.ny, Y.nz);
ComplexSignal L2 = Operations.multiply(lambda, L, L);
ComplexSignal FA = Operations.add(H2, L2);
ComplexSignal FT = Operations.divideStabilized(H, FA);
ComplexSignal X = Operations.multiply(Y, FT);
RealSignal x = fft.inverse(X);
SignalCollector.free(FT);
SignalCollector.free(Y);
SignalCollector.free(H);
SignalCollector.free(FA);
SignalCollector.free(L);
SignalCollector.free(H2);
SignalCollector.free(L2);
SignalCollector.free(X);
return x;
}
public RealSignal runOptimizedMemoryFootprint() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal X = filter(Y, H);
SignalCollector.free(Y);
SignalCollector.free(H);
RealSignal x = fft.inverse(X);
SignalCollector.free(X);
return x;
}
public ComplexSignal filter(ComplexSignal Y, ComplexSignal H) {
- ComplexSignal X = ComplexSignalFactory.laplacian(Y.nx, Y.ny, Y.nz);
- X.setName("X");
- int nx = X.nx;
- int ny = X.ny;
- int nz = X.nz;
+ ComplexSignal L = ComplexSignalFactory.laplacian(Y.nx, Y.ny, Y.nz);
+ L.setName("Laplacian");
+System.out.println(" >>>>>>>>>>>>>>>>>> " + L.getEnergy());
+Lab.show(controller.getMonitors(), L, "L");
float la, lb, ha, hb, fa, fb, ta, tb, ya, yb;
- int nxy = nx * ny * 2;
+ int nxy = Y.nx * Y.ny * 2;
float w = (float) lambda;
float epsilon = (float) Operations.epsilon;
- for (int k = 0; k < nz; k++)
+ for (int k = 0; k < Y.nz; k++)
for (int i = 0; i < nxy; i += 2) {
- la = X.data[k][i];
- lb = X.data[k][i + 1];
+ la = L.data[k][i];
+ lb = L.data[k][i + 1];
ha = H.data[k][i];
hb = H.data[k][i + 1];
fa = w * (la * la - lb * lb) + (ha * ha - hb * hb);
fb = w * (2f * la * lb) + (2f * ha * hb);
float mag = Math.max(epsilon, fa * fa + fb * fb);
ta = (ha * fa + hb * fb) / mag;
tb = (hb * fa - ha * fb) / mag;
ya = Y.data[k][i];
yb = Y.data[k][i + 1];
- X.data[k][i] = ya * ta - yb * tb;
- X.data[k][i + 1] = ya * tb + ta * yb;
+ L.data[k][i] = ya * ta - yb * tb;
+ L.data[k][i + 1] = ya * tb + ta * yb;
}
// SignalCollector.free(L);
- return X;
+ return L;
}
@Override
public String getName() {
return "Regularized Inverse Filter";
}
@Override
public String[] getShortnames() {
return new String[] {"RIF", "LRIF"};
}
@Override
public int getComplexityNumberofFFT() {
return 3;
}
@Override
public double getMemoryFootprintRatio() {
return 8.0;
}
@Override
public boolean isRegularized() {
return true;
}
@Override
public boolean isStepControllable() {
return false;
}
@Override
public boolean isIterative() {
return false;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
- public void setParameters(double[] params) {
+ public AbstractAlgorithm setParameters(double... params) {
if (params == null)
- return;
+ return this;
if (params.length > 0)
lambda = (float) params[0];
+ return this;
}
@Override
public double[] getDefaultParameters() {
return new double[] { 0.1 };
}
@Override
public double[] getParameters() {
return new double[] { lambda };
}
@Override
public double getRegularizationFactor() {
return lambda;
}
@Override
public double getStepFactor() {
return 0;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucy.java b/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucy.java
index db83522..3271f12 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucy.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucy.java
@@ -1,141 +1,142 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
public class RichardsonLucy extends AbstractAlgorithm implements Callable<RealSignal> {
public RichardsonLucy(int iterMax) {
super();
this.iterMax = iterMax;
}
// x(k+1) = x(k) *. Hconj * ( y /. H x(k))
@Override
public RealSignal call() {
ComplexSignal H = fft.transform(h);
ComplexSignal U = new ComplexSignal("RL-U", y.nx, y.ny, y.nz);
RealSignal x = y.duplicate();
RealSignal p = y.duplicate();
RealSignal u = y.duplicate();
while (!controller.ends(x)) {
fft.transform(x, U);
U.times(H);
fft.inverse(U, u);
Operations.divide(y, u, p);
fft.transform(p, U);
U.timesConjugate(H);
fft.inverse(U, u);
x.times(u);
}
SignalCollector.free(H);
SignalCollector.free(p);
SignalCollector.free(u);
SignalCollector.free(U);
return x;
}
@Override
public String getName() {
return "Richardson-Lucy";
}
@Override
public String[] getShortnames() {
return new String[] {"RL"};
}
@Override
public int getComplexityNumberofFFT() {
return 1 + 5 * iterMax;
}
@Override
public double getMemoryFootprintRatio() {
return 9.0;
}
@Override
public boolean isRegularized() {
return false;
}
@Override
public boolean isStepControllable() {
return false;
}
@Override
public boolean isIterative() {
return true;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
- public void setParameters(double[] params) {
+ public AbstractAlgorithm setParameters(double... params) {
if (params == null)
- return;
+ return this;
if (params.length > 0)
iterMax = (int) Math.round(params[0]);
+ return this;
}
@Override
public double[] getDefaultParameters() {
return new double[] { 10 };
}
@Override
public double[] getParameters() {
return new double[] { iterMax };
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return 0;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyTV.java b/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyTV.java
index 18e9e25..4440066 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyTV.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/RichardsonLucyTV.java
@@ -1,235 +1,236 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
public class RichardsonLucyTV extends AbstractAlgorithm implements Callable<RealSignal> {
private double lambda = 0.1;
public RichardsonLucyTV(int iterMax, double lambda) {
super();
this.iterMax = iterMax;
this.lambda = lambda;
}
// x(k+1) = x(k) *. Hconj * ( y /. H x(k))
@Override
public RealSignal call() {
ComplexSignal H = fft.transform(h);
ComplexSignal U = new ComplexSignal("RLTV-U",y.nx, y.ny, y.nz);
RealSignal x = y.duplicate();
RealSignal gx = y.duplicate();
RealSignal gy = y.duplicate();
RealSignal gz = y.duplicate();
RealSignal ggx = y.duplicate();
RealSignal ggy = y.duplicate();
RealSignal ggz = y.duplicate();
RealSignal u = gx; // resued memory
RealSignal p = gy; // resued memory
RealSignal tv = gz; // resued memory
while(!controller.ends(x)) {
gradientX(x, gx);
gradientY(x, gy);
gradientZ(x, gz);
normalize(gx, gy, gz);
gradientX(gx, ggx);
gradientY(gy, ggy);
gradientZ(gz, ggz);
compute((float)lambda, ggx, ggy, ggz, tv);
fft.transform(x, U);
U.times(H);
fft.inverse(U, u);
Operations.divide(y, u, p);
fft.transform(p, U);
U.timesConjugate(H);
fft.inverse(U, u);
x.times(u);
x.times(tv);
}
SignalCollector.free(H);
SignalCollector.free(U);
SignalCollector.free(ggx);
SignalCollector.free(ggy);
SignalCollector.free(ggz);
SignalCollector.free(tv);
SignalCollector.free(u);
SignalCollector.free(p);
return x;
}
private void compute(float lambda, RealSignal gx, RealSignal gy, RealSignal gz, RealSignal tv) {
int nxy = gx.nx * gy.ny;
for(int k=0; k<gx.nz; k++)
for(int i=0; i< nxy; i++) {
double dx = gx.data[k][i];
double dy = gy.data[k][i];
double dz = gz.data[k][i];
tv.data[k][i] = (float)(1.0 / ( (dx+dy+dz) * lambda + 1.0));
}
}
public void gradientX(RealSignal signal, RealSignal output) {
int nx = signal.nx;
int ny = signal.ny;
int nz = signal.nz;
for(int k=0; k<nz; k++)
for(int j=0; j<ny; j++)
for(int i=0; i<nx-1; i++) {
int index = i + signal.nx*j;
output.data[k][index] = signal.data[k][index] - signal.data[k][index+1];
}
}
public void gradientY(RealSignal signal, RealSignal output) {
int nx = signal.nx;
int ny = signal.ny;
int nz = signal.nz;
for(int k=0; k<nz; k++)
for(int j=0; j<ny-1; j++)
for(int i=0; i<nx; i++) {
int index = i + signal.nx*j;
output.data[k][index] = signal.data[k][index] - signal.data[k][index+nx];
}
}
public void gradientZ(RealSignal signal, RealSignal output) {
int nx = signal.nx;
int ny = signal.ny;
int nz = signal.nz;
for(int k=0; k<nz-1; k++)
for(int j=0; j<ny; j++)
for(int i=0; i<nx; i++) {
int index = i + signal.nx*j;
output.data[k][index] = signal.data[k][index] - signal.data[k+1][index];
}
}
public void normalize(RealSignal x, RealSignal y, RealSignal z) {
int nx = x.nx;
int ny = y.ny;
int nz = z.nz;
float e = (float) Operations.epsilon;
for(int k=0; k<nz; k++)
for(int i=0; i<nx*ny; i++) {
double norm = Math.sqrt(x.data[k][i] * x.data[k][i] + y.data[k][i] * y.data[k][i] + z.data[k][i] * z.data[k][i]);
if (norm < e) {
x.data[k][i] = e;
y.data[k][i] = e;
z.data[k][i] = e;
}
else {
x.data[k][i] /= norm;
y.data[k][i] /= norm;
z.data[k][i] /= norm;
}
}
}
@Override
public int getComplexityNumberofFFT() {
return 1 + 7 * iterMax;
}
@Override
public String getName() {
return "Richardson-Lucy Total Variation";
}
@Override
public String[] getShortnames() {
return new String[] {"RLTV"};
}
@Override
public double getMemoryFootprintRatio() {
return 13.0;
}
@Override
public boolean isRegularized() {
return true;
}
@Override
public boolean isStepControllable() {
return true;
}
@Override
public boolean isIterative() {
return true;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
- public void setParameters(double[] params) {
+ public AbstractAlgorithm setParameters(double... params) {
if (params == null)
- return;
+ return this;
if (params.length > 0)
iterMax = (int) Math.round(params[0]);
if (params.length > 1)
lambda = (float)params[1];
+ return this;
}
@Override
public double[] getDefaultParameters() {
return new double[] {10, 0.1};
}
@Override
public double[] getParameters() {
return new double[] {iterMax, lambda};
}
@Override
public double getRegularizationFactor() {
return lambda;
}
@Override
public double getStepFactor() {
return 0.0;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/Simulation.java b/DeconvolutionLab2/src/deconvolution/algorithm/Simulation.java
index 912e708..48f0d7f 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/Simulation.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/Simulation.java
@@ -1,165 +1,166 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import bilib.tools.PsRandom;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
public class Simulation extends AbstractAlgorithm implements Callable<RealSignal> {
private static PsRandom rand = new PsRandom(1234);
private double mean = 0.0;
private double stdev = 10.0;
private double poisson = 0.0;
public Simulation(double mean, double stdev, double poisson) {
super();
this.mean = mean;
this.stdev = stdev;
this.poisson = poisson;
}
@Override
public RealSignal call() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal X = Operations.multiply(H, Y);
SignalCollector.free(Y);
SignalCollector.free(H);
RealSignal x = fft.inverse(X);
SignalCollector.free(X);
gaussian(x, mean, stdev);
poisson(x, poisson);
return x;
}
public void gaussian(RealSignal x, double mean, double sd) {
for (int k = 0; k < x.nz; k++) {
float[] slice = x.getXY(k);
for (int j = 0; j < x.ny * x.nx; j++)
slice[j] += (float) rand.nextGaussian(mean, sd);
}
}
public void poisson(RealSignal x, double factor) {
if (factor < Operations.epsilon)
return;
double f = 1.0/(factor);
for (int k = 0; k < x.nz; k++) {
float[] slice = x.getXY(k);
for (int j = 0; j < x.ny * x.nx; j++)
if (slice[j] > Operations.epsilon) {
slice[j] = (float)(rand.nextPoissonian(f*(slice[j])) * factor);
}
}
}
@Override
public String getName() {
return "Simulation with noise";
}
@Override
public String[] getShortnames() {
return new String[] {"SIM", "SIMU"};
}
@Override
public int getComplexityNumberofFFT() {
return 3;
}
@Override
public double getMemoryFootprintRatio() {
return 8.0;
}
@Override
public boolean isRegularized() {
return false;
}
@Override
public boolean isStepControllable() {
return false;
}
@Override
public boolean isIterative() {
return false;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
- public void setParameters(double[] params) {
+ public AbstractAlgorithm setParameters(double... params) {
if (params == null)
- return;
+ return this;
if (params.length > 0)
mean = params[0];
if (params.length > 1)
stdev = params[1];
if (params.length > 2)
poisson = params[2];
+ return this;
}
@Override
public double[] getDefaultParameters() {
return new double[] {0, 1, 0};
}
@Override
public double[] getParameters() {
return new double[] {mean, stdev, poisson};
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return 0;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/StarkParker.java b/DeconvolutionLab2/src/deconvolution/algorithm/StarkParker.java
index eaa4476..3a283c6 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/StarkParker.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/StarkParker.java
@@ -1,148 +1,149 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Constraint;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
public class StarkParker extends AbstractAlgorithm implements Callable<RealSignal> {
private double gamma = 1.0;
public StarkParker(int iterMax, double gamma) {
super();
this.iterMax = iterMax;
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);
SignalCollector.free(H);
SignalCollector.free(Y);
ComplexSignal X = G.duplicate();
controller.setConstraint(Constraint.Mode.CLIPPED);
while (!controller.ends(X)) {
X.times(A);
X.plus(G);
}
SignalCollector.free(A);
SignalCollector.free(G);
RealSignal x = fft.inverse(X);
SignalCollector.free(X);
return x;
}
@Override
public String getName() {
return "Bounded-Variable Least Squares";
}
@Override
public String[] getShortnames() {
return new String[] {"BVLS", "SP"};
}
@Override
public int getComplexityNumberofFFT() {
return 3 + iterMax * 2;
}
@Override
public double getMemoryFootprintRatio() {
return 9.0;
}
@Override
public boolean isRegularized() {
return false;
}
@Override
public boolean isStepControllable() {
return true;
}
@Override
public boolean isIterative() {
return true;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
- public void setParameters(double[] params) {
+ public AbstractAlgorithm setParameters(double... params) {
if (params == null)
- return;
+ return this;
if (params.length > 0)
iterMax = (int) Math.round(params[0]);
if (params.length > 1)
gamma = (float) params[1];
+ return this;
}
@Override
public double[] getDefaultParameters() {
return new double[] { 10, 1 };
}
@Override
public double[] getParameters() {
return new double[] { iterMax, gamma };
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return gamma;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovMiller.java b/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovMiller.java
index ab67126..9f8f47e 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovMiller.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovMiller.java
@@ -1,151 +1,152 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
import signal.factory.complex.ComplexSignalFactory;
public class TikhonovMiller extends AbstractAlgorithm implements Callable<RealSignal> {
private double gamma = 1.0;
private double lambda = 1.0;
public TikhonovMiller(int iterMax, double gamma, double lambda) {
super();
this.iterMax = iterMax;
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);
SignalCollector.free(L);
A.minus(L2);
SignalCollector.free(L2);
ComplexSignal G = Operations.multiplyConjugate(gamma, H, Y);
SignalCollector.free(H);
SignalCollector.free(Y);
ComplexSignal X = G.duplicate();
while(!controller.ends(X)) {
X.times(A);
X.plus(G);
}
SignalCollector.free(A);
SignalCollector.free(G);
RealSignal x = fft.inverse(X);
SignalCollector.free(X);
return x;
}
@Override
public int getComplexityNumberofFFT() {
return 3 + (controller.needSpatialComputation() ? 2 * iterMax : 0);
}
@Override
public String getName() {
return "Tikhonov-Miller";
}
@Override
public String[] getShortnames() {
return new String[] {"TM"};
}
@Override
public double getMemoryFootprintRatio() {
return 10.0;
}
@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) {
+ public AbstractAlgorithm setParameters(double... params) {
if (params == null)
- return;
+ return this;
if (params.length > 0)
iterMax = (int) Math.round(params[0]);
if (params.length > 1)
gamma = (float)params[1];
if (params.length > 2)
lambda = (float)params[2];
+ return this;
}
@Override
public double[] getDefaultParameters() {
return new double[] {10, 1, 0.1};
}
@Override
public double[] getParameters() {
return new double[] {iterMax, gamma, lambda};
}
@Override
public double getRegularizationFactor() {
return lambda;
}
@Override
public double getStepFactor() {
return gamma;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizedInverseFilter.java b/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizedInverseFilter.java
index f1d6eb9..559e853 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizedInverseFilter.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/TikhonovRegularizedInverseFilter.java
@@ -1,183 +1,184 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
import signal.factory.complex.ComplexSignalFactory;
public class TikhonovRegularizedInverseFilter extends AbstractAlgorithm implements Callable<RealSignal> {
private double lambda = 0.1;
public TikhonovRegularizedInverseFilter(double lambda) {
super();
this.lambda = lambda;
}
@Override
public RealSignal call() {
if (optimizedMemoryFootprint)
return runOptimizedMemoryFootprint();
else
return runTextBook();
}
public RealSignal runTextBook() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal H2 = Operations.multiply(H, H);
ComplexSignal I = ComplexSignalFactory.identity(Y.nx, Y.ny, Y.nz);
I.times((float)lambda);
ComplexSignal FA = Operations.add(H2, I);
ComplexSignal FT = Operations.divideStabilized(H, FA);
ComplexSignal X = Operations.multiply(Y, FT);
RealSignal x = fft.inverse(X);
SignalCollector.free(FT);
SignalCollector.free(Y);
SignalCollector.free(H);
SignalCollector.free(FA);
SignalCollector.free(I);
SignalCollector.free(H2);
SignalCollector.free(X);
return x;
}
public RealSignal runOptimizedMemoryFootprint() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal X = filter(Y, H);
SignalCollector.free(H);
SignalCollector.free(Y);
RealSignal x = fft.inverse(X);
SignalCollector.free(X);
return x;
}
private ComplexSignal filter(ComplexSignal Y, ComplexSignal H) {
int nx = H.nx;
int ny = H.ny;
int nz = H.nz;
int nxy = nx * ny*2;
float ya, yb, ha, hb, fa, fb, mag, ta, tb;
float epsilon2 = (float)(Operations.epsilon * Operations.epsilon);
ComplexSignal result = new ComplexSignal("TRIF", nx, ny, nz);
float l = (float)lambda;
for(int k=0; k<nz; k++)
for(int i=0; i< nxy; i+=2) {
ha = H.data[k][i];
hb = H.data[k][i+1];
ya = Y.data[k][i];
yb = Y.data[k][i+1];
fa = ha*ha - hb*hb + l;
fb = 2f * ha * hb;
mag = fa*fa + fb*fb;
ta = (ha*fa + hb*fb) / (mag >= epsilon2 ? mag : epsilon2);
tb = (hb*fa - ha*fb) / (mag >= epsilon2 ? mag : epsilon2);
result.data[k][i] = ya*ta - yb*tb;
result.data[k][i+1] = ya*tb + ta*yb;
}
return result;
}
@Override
public int getComplexityNumberofFFT() {
return 3;
}
@Override
public String getName() {
return "Tikhonov Regularization Inverse Filter";
}
@Override
public String[] getShortnames() {
return new String[] {"TRIF", "TR"};
}
@Override
public double getMemoryFootprintRatio() {
return 8.0;
}
@Override
public boolean isRegularized() {
return true;
}
@Override
public boolean isStepControllable() {
return false;
}
@Override
public boolean isIterative() {
return false;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
- public void setParameters(double[] params) {
+ public AbstractAlgorithm setParameters(double... params ) {
if (params == null)
- return;
+ return this;
if (params.length > 0)
lambda = (float)params[0];
+ return this;
}
@Override
public double[] getDefaultParameters() {
return new double[] {0.1};
}
@Override
public double[] getParameters() {
return new double[] {lambda};
}
@Override
public double getRegularizationFactor() {
return lambda;
}
@Override
public double getStepFactor() {
return 0.0;
}
}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/VanCittert.java b/DeconvolutionLab2/src/deconvolution/algorithm/VanCittert.java
index 7dfccbc..040e264 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/VanCittert.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/VanCittert.java
@@ -1,145 +1,146 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.concurrent.Callable;
import signal.ComplexSignal;
import signal.Operations;
import signal.RealSignal;
import signal.SignalCollector;
public class VanCittert extends AbstractAlgorithm implements Callable<RealSignal> {
private double gamma = 1.0;
public VanCittert(int iterMax, double gamma) {
super();
this.iterMax = iterMax;
this.gamma = gamma;
}
@Override
// VAnCitter algorithm
// X(n+1) = X(n) + g*(Y-H*X(n))
// => X(n+1) = X(n) - g*H*X(n) + g*Y
// => X(n+1) = X(n) * (I-g*H) + g*Y
// => pre-compute: A = (I-g*H) and G = g*Y
// => Iteration : X(n+1) = X(n) * A + G with F(0) = G
public RealSignal call() {
ComplexSignal Y = fft.transform(y);
ComplexSignal H = fft.transform(h);
ComplexSignal A = Operations.delta1(gamma, H);
SignalCollector.free(H);
ComplexSignal G = Operations.multiply(gamma, Y);
SignalCollector.free(Y);
ComplexSignal X = G.duplicate();
while(!controller.ends(X)) {
X.times(A);
X.plus(G);
}
SignalCollector.free(G);
SignalCollector.free(A);
RealSignal x = fft.inverse(X);
SignalCollector.free(X);
return x;
}
@Override
public int getComplexityNumberofFFT() {
return 3 + (controller.needSpatialComputation() ? 2 * iterMax : 0);
}
@Override
public String getName() {
return "Van Cittert";
}
@Override
public String[] getShortnames() {
return new String[] {"VC"};
}
@Override
public double getMemoryFootprintRatio() {
return 8.0;
}
@Override
public boolean isRegularized() {
return false;
}
@Override
public boolean isStepControllable() {
return true;
}
@Override
public boolean isIterative() {
return true;
}
@Override
public boolean isWaveletsBased() {
return false;
}
@Override
- public void setParameters(double[] params) {
+ public AbstractAlgorithm setParameters(double... params) {
if (params == null)
- return;
+ return this;
if (params.length > 0)
iterMax = (int) Math.round(params[0]);
if (params.length > 1)
gamma = (float)params[1];
+ return this;
}
@Override
public double[] getDefaultParameters() {
return new double[] {10, 1};
}
@Override
public double[] getParameters() {
return new double[] {iterMax, gamma};
}
@Override
public double getRegularizationFactor() {
return 0.0;
}
@Override
public double getStepFactor() {
return gamma;
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/Lab.java b/DeconvolutionLab2/src/deconvolutionlab/Lab.java
index 5db0496..b6694a7 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/Lab.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/Lab.java
@@ -1,534 +1,534 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab;
import java.io.File;
import java.util.ArrayList;
import java.util.regex.Pattern;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
+import bilib.tools.Files;
import bilib.tools.NumFormat;
import bilib.tools.WebBrowser;
import deconvolutionlab.Imager.ContainerImage;
import deconvolutionlab.monitor.Monitors;
import fft.AbstractFFT;
import fft.AbstractFFTLibrary;
import fft.FFT;
import ij.IJ;
import imagej.IJImager;
import plugins.sage.deconvolutionlab.IcyImager;
import signal.ComplexComponent;
import signal.ComplexSignal;
import signal.RealSignal;
import signal.factory.SignalFactory;
import signal.factory.Sphere;
/**
* This class contains a collection of useful static methods to manage all the
* peripherical aspects of the deconvolution, such as load, display, or save an
* image.
* <p>
* At the construction of the class, the config is loaded. In practice, any
* deconvolution program has to start with Lab.init(Platform).
*
* @author Daniel Sage
*
*/
public class Lab {
private static Imager imaging;
private static ArrayList<JFrame> frames;
private static ArrayList<JDialog> dialogs;
static {
frames = new ArrayList<JFrame>();
dialogs = new ArrayList<JDialog>();
imaging = new IJImager();
- Config.init(System.getProperty("user.dir") + File.separator + "DeconvolutionLab2.config");
+ Config.init(Files.getWorkingDirectory() + "DeconvolutionLab2.config");
}
/**
* Initializes the Lab with a give platform.
*
* @param platform
* The platform is ImageJ, ICY, or Matlab.
*/
public static void init(Imager.Platform platform) {
- init(platform, System.getProperty("user.dir") + File.separator + "DeconvolutionLab2.config");
+ init(platform, Files.getWorkingDirectory() + "DeconvolutionLab2.config");
}
/**
* Initializes the Lab with a give platform and a given configuration file
*
* @param platform
* @param configFilename
*/
public static void init(Imager.Platform platform, String configFilename) {
switch (platform) {
case IMAGEJ:
imaging = new IJImager();
break;
case ICY:
imaging = new IcyImager();
break;
default:
imaging = new IJImager();
break;
}
Config.init(configFilename);
}
/**
* Returns the platform.
*
* @return
*/
public static Imager.Platform getPlatform() {
return imaging.getPlatform();
}
/**
* Open a web page on the DeconvolutionLab2.
*/
public static void help() {
WebBrowser.open(Constants.url);
}
/**
* Checks the installed FFT libraries on a small (40, 30, 20) signal.
*
* @param monitors
*/
public static void checkFFT(Monitors monitors) {
ArrayList<AbstractFFTLibrary> libraries = FFT.getInstalledLibraries();
for (AbstractFFTLibrary library : libraries) {
RealSignal y = new Sphere(3, 1).generate(40, 30, 20);
double chrono = System.nanoTime();
AbstractFFT fft = library.getDefaultFFT();
fft.init(monitors, y.nx, y.ny, y.nz);
RealSignal x = fft.inverse(fft.transform(y));
chrono = System.nanoTime() - chrono;
double residu = y.getEnergy() - x.getEnergy();
monitors.log("\t residu of reconstruction: " + residu);
monitors.log("\t computation time (" + x.nx + "x" + x.ny + "x" + x.nz + ") " + NumFormat.time(chrono));
}
}
public static ContainerImage createContainer(Monitors monitors, String title) {
monitors.log("Create Live Real Signal " + title);
return imaging.createContainer(title);
}
public static void append(Monitors monitors, ContainerImage container, RealSignal signal, String title) {
imaging.append(container, signal, title, Imager.Type.FLOAT);
monitors.log("Add Live Real Signal " + title);
}
public static void append(Monitors monitors, ContainerImage container, RealSignal signal, String title, Imager.Type type) {
imaging.append(container, signal, title, type);
monitors.log("Add Live Real Signal " + title);
}
/**
* Displays a the module of complex signal.
*
* @param monitors
* @param signal
* @param title
*/
public static void show(Monitors monitors, ComplexSignal signal, String title) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, ComplexComponent.MODULE);
}
/**
* Displays a real 3D signal a z-stack of images.
*
* @param signal
*/
public static void show(RealSignal signal) {
if (signal == null) {
return;
}
imaging.show(signal, signal.name, Imager.Type.FLOAT, signal.nz / 2);
}
/**
* Displays a real 3D signal a z-stack of images.
*
* @param monitors
* @param signal
*/
public static void show(Monitors monitors, RealSignal signal) {
if (signal == null) {
monitors.error("This image does not exist.");
return;
}
monitors.log("Show Real Signal " + signal.name);
imaging.show(signal, signal.name, Imager.Type.FLOAT, signal.nz / 2);
}
/**
* Displays a real 3D signal a z-stack of images.
*
* @param monitors
* @param signal
* @param title
*/
public static void show(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, Imager.Type.FLOAT, signal.nz / 2);
}
/**
* Displays a real 3D signal a z-stack of images using a given type.
*
* @param monitors
* @param signal
* @param title
* @param type
*/
public static void show(Monitors monitors, RealSignal signal, String title, Imager.Type type) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, type, signal.nz / 2);
}
/**
* Displays a real 3D signal a z-stack of images using a given type and
* shows the slice number z.
*
* @param monitors
* @param signal
* @param title
* @param type
* @param z
*/
public static void show(Monitors monitors, RealSignal signal, String title, Imager.Type type, int z) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imaging.show(signal, title, type, z);
}
public static void save(Monitors monitors, RealSignal signal, String path, String name) {
save(monitors, signal, path + File.separator + name + ".tif", Imager.Type.FLOAT);
}
public static void save(Monitors monitors, RealSignal signal, String path, String name, Imager.Type type) {
save(monitors, signal, path + File.separator + name + ".tif", type);
}
public static void save(Monitors monitors, RealSignal signal, String filename) {
imaging.save(signal, filename, Imager.Type.FLOAT);
monitors.log("Save Real Signal " + filename);
}
public static void save(Monitors monitors, RealSignal signal, String filename, Imager.Type type) {
imaging.save(signal, filename, type);
monitors.log("Save Real Signal " + filename);
}
public static RealSignal createSynthetic(Monitors monitors, String cmd) {
-IJ.log("Lab, synthetic 337 " + cmd);
RealSignal signal = SignalFactory.createFromCommand(cmd);
if (signal == null)
monitors.error("Unable to create " + cmd);
else
monitors.log("Create " + cmd);
return signal;
}
/**
* Return the active image.
*
* @return
*/
public static RealSignal getImage() {
return getImager().getActiveImage();
}
/**
* Return an image from the platform with a specified name.
*
* @param name
* @return
*/
public static RealSignal getImage(String name) {
return getImager().getImageByName(name);
}
/**
* Return an image from the platform with a specified name.
*
* @param monitors
* @param name
* @return
*/
public static RealSignal getImage(Monitors monitors, String name) {
RealSignal signal = getImager().getImageByName(name);
if (signal == null)
monitors.error("Unable to get " + name);
else
monitors.log("Load " + name);
return signal;
}
/**
* Open an image from the disk.
*
* @param filename
* @return
*/
public static RealSignal openFile(String filename) {
return imaging.open(filename);
}
/**
* Open an image from the disk.
*
* @param monitors
* @param filename
* @return
*/
public static RealSignal openFile(Monitors monitors, String filename) {
RealSignal signal = imaging.open(filename);
if (signal == null)
monitors.error("Unable to open " + filename);
else
monitors.log("Load " + filename);
return signal;
}
/**
* Open a series of image from a directory.
*
* @param path
* @return
*/
public static RealSignal openDir(String path) {
return openDir(Monitors.createDefaultMonitor(), path);
}
/**
* Open a series of image from a directory.
*
* @param monitors
* @param path
* @return
*/
public static RealSignal openDir(Monitors monitors, String path) {
String parts[] = path.split(" pattern ");
String dirname = path;
String regex = "";
if (parts.length == 2) {
dirname = parts[0].trim();
regex = parts[1].trim();
}
File file = new File(dirname + File.separator);
if (!file.isDirectory()) {
monitors.error("Dir " + dirname + " is not a directory.");
return null;
}
String[] list = file.list();
ArrayList<RealSignal> slices = new ArrayList<RealSignal>();
int nx = 0;
int ny = 0;
Pattern pattern = Pattern.compile(regex);
for (String filename : list) {
if (pattern.matcher(filename).find()) {
RealSignal slice = imaging.open(dirname + File.separator + filename);
if (slice != null) {
slices.add(slice);
nx = Math.max(nx, slice.nx);
ny = Math.max(ny, slice.ny);
monitors.log("Image " + path + File.separator + filename + " is loaded.");
}
}
else {
monitors.error("Error in loading image " + path + File.separator + filename);
}
}
int nz = slices.size();
if (nz <= 0) {
monitors.error("Dir " + path + " do no contain valid images.");
return null;
}
RealSignal signal = new RealSignal(file.getName(), nx, ny, nz);
for (int z = 0; z < slices.size(); z++)
signal.setSlice(z, slices.get(z));
return signal;
}
public static void showOrthoview(RealSignal signal, String title, int hx, int hy, int hz) {
if (signal == null) {
return;
}
imaging.show(signal.createOrthoview(hx, hy, hz), title, Imager.Type.FLOAT, 0);
}
public static void showOrthoview(Monitors monitors, RealSignal signal, String title, int hx, int hy, int hz) {
if (signal == null) {
monitors.error("Show Orthoview " + title + " this image does not exist.");
return;
}
imaging.show(signal.createOrthoview(hx, hy, hz), title, Imager.Type.FLOAT, 0);
}
public static void showOrthoview(RealSignal signal) {
if (signal == null) {
return;
}
int hx = signal.nx / 2;
int hy = signal.ny / 2;
int hz = signal.nz / 2;
imaging.show(signal.createOrthoview(hx, hy, hz), signal.name, Imager.Type.FLOAT, 0);
}
public static void showOrthoview(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show Orthoview " + title + " this image does not exist.");
return;
}
int hx = signal.nx / 2;
int hy = signal.ny / 2;
int hz = signal.nz / 2;
imaging.show(signal.createOrthoview(hx, hy, hz), title, Imager.Type.FLOAT, 0);
}
public static void showMIP(RealSignal signal) {
if (signal == null) {
return;
}
imaging.show(signal.createMIP(), signal.name, Imager.Type.FLOAT, 0);
}
public static void showMIP(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show MIP " + title + " this image does not exist.");
return;
}
imaging.show(signal.createMIP(), title, Imager.Type.FLOAT, 0);
}
public static void showPlanar(RealSignal signal) {
if (signal == null) {
return;
}
imaging.show(signal.createPlanar(), signal.name, Imager.Type.FLOAT, 0);
}
public static void showPlanar(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show Planar " + title + " this image does not exist.");
return;
}
imaging.show(signal.createPlanar(), title, Imager.Type.FLOAT, 0);
}
/*
public static RealSignal create(Monitors monitors, String name) {
RealSignal signal = imaging.create(name);
if (signal != null)
monitors.log("Created the real signal " + name + " " + signal.toString());
else
monitors.error("Impossible to create the real signal " + name);
return signal;
}
public static RealSignal create(Monitors monitors) {
RealSignal signal = imaging.create();
if (signal != null)
monitors.log("Created the real signal from the active window " + signal.toString());
else
monitors.error("Impossible to create the real signal from the active window");
return signal;
}
*/
public static Imager getImager() {
return imaging;
}
public static String getActiveImage() {
if (imaging.isSelectable())
return imaging.getSelectedImage();
return "";
}
public static void setVisible(JDialog dialog, boolean modal) {
if (dialog == null)
return;
dialogs.add(dialog);
imaging.setVisible(dialog, modal);
}
public static void setVisible(JPanel panel, String name, int x, int y) {
JFrame frame = new JFrame(name);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocation(x, y);
frame.setVisible(true);
frames.add(frame);
}
public static void setVisible(JFrame frame) {
frames.add(frame);
frame.setVisible(true);
}
public static void close() {
for (JFrame frame : frames)
if (frame != null)
frame.dispose();
for (JDialog dialog : dialogs)
if (dialog != null)
dialog.dispose();
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/LabPanel.java b/DeconvolutionLab2/src/deconvolutionlab/LabPanel.java
index 0018310..2b7255e 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/LabPanel.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/LabPanel.java
@@ -1,310 +1,303 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import bilib.component.PanelImage;
import deconvolution.Command;
import deconvolution.Deconvolution;
import deconvolutionlab.dialog.BatchDialog;
import deconvolutionlab.module.AboutModule;
import deconvolutionlab.module.AbstractModule;
import deconvolutionlab.module.AlgorithmModule;
import deconvolutionlab.module.BatchModule;
import deconvolutionlab.module.CommandModule;
import deconvolutionlab.module.ConfigModule;
import deconvolutionlab.module.ControllerModule;
import deconvolutionlab.module.DirectoryModule;
import deconvolutionlab.module.FFTModule;
import deconvolutionlab.module.GroupedModulePanel;
import deconvolutionlab.module.ImageModule;
import deconvolutionlab.module.LanguageModule;
import deconvolutionlab.module.LicenceModule;
import deconvolutionlab.module.OutputModule;
import deconvolutionlab.module.PSFModule;
import deconvolutionlab.module.PreprocessingModule;
-import deconvolutionlab.module.RunningModule;
import deconvolutionlab.system.SystemInfo;
/**
* This class build the main panel for DeconvolutionLab2. It consists to a
* series of collapse/expanded modules that are placed in different tabs. The size
* of the panel is dynamically computed,
*
* @author Daniel Sage
*
*/
public class LabPanel extends JPanel implements ActionListener, ChangeListener {
private JTabbedPane tab = new JTabbedPane();
private JButton bnHelp = new JButton("Help");
private JButton bnQuit = new JButton("Quit");
private JButton bnSystem = new JButton("System");
private JButton bnBatch = new JButton("Batch");
private JButton bnRun = new JButton("Run");
private JButton bnLaunch = new JButton("Launch");
private JButton bnClose;
private ImageModule image;
private PSFModule psf;
private AlgorithmModule algo;
private AboutModule about;
private LicenceModule licence;
private OutputModule output;
private PreprocessingModule preprocessing;
private ConfigModule config;
private BatchModule batch;
private LanguageModule language;
private CommandModule command;
- private RunningModule running;
private DirectoryModule directory;
private FFTModule fft;
private ControllerModule controller;
private GroupedModulePanel panelDeconv;
private GroupedModulePanel panelAdvanc;
private GroupedModulePanel panelScript;
private GroupedModulePanel panelAbout;
private AbstractModule modules[];
public LabPanel(JButton bnClose) {
this.bnClose = bnClose;
image = new ImageModule();
psf = new PSFModule();
algo = new AlgorithmModule();
output = new OutputModule();
preprocessing = new PreprocessingModule();
controller = new ControllerModule();
batch = new BatchModule();
language = new LanguageModule();
about = new AboutModule();
licence = new LicenceModule();
config = new ConfigModule();
command = new CommandModule();
- running = new RunningModule();
directory = new DirectoryModule();
fft = new FFTModule();
modules = new AbstractModule[] { image, psf, algo, output, controller, preprocessing, batch, directory, fft };
Command.active(modules, command);
Command.command();
panelDeconv = new GroupedModulePanel(buildDeconvolutionPanel(), this);
panelAdvanc = new GroupedModulePanel(buildAdvancedPanel(), this);
panelScript = new GroupedModulePanel(buildProgrammingPanel(), this);
panelAbout = new GroupedModulePanel(buildAboutPanel(), this);
Border border = BorderFactory.createEmptyBorder(5, 5, 5, 5);
PanelImage bottom = new PanelImage("celegans.jpg");
bottom.setBorder(border);
bottom.setLayout(new GridLayout(1, 6));
bottom.setBorder(border);
bottom.add(bnHelp);
bottom.add(bnSystem);
bottom.add(bnClose);
bottom.add(bnBatch);
bottom.add(bnRun);
bottom.add(bnLaunch);
tab.add("Deconvolution", panelDeconv);
tab.add("Advanced", panelAdvanc);
tab.add("Scripting", panelScript);
tab.add("About", panelAbout);
tab.addChangeListener(this);
setLayout(new BorderLayout());
add(tab, BorderLayout.CENTER);
add(bottom, BorderLayout.SOUTH);
bnBatch.addActionListener(this);
bnRun.addActionListener(this);
bnLaunch.addActionListener(this);
bnClose.addActionListener(this);
bnQuit.addActionListener(this);
bnHelp.addActionListener(this);
bnSystem.addActionListener(this);
((GroupedModulePanel) tab.getSelectedComponent()).organize();
setMinimumSize(new Dimension(500, 500));
Config.load();
- running.init();
algo.open();
controller.open();
about.open();
command.open();
// sizeModule();
Command.command();
- running.update();
image.update();
psf.update();
output.update();
}
@Override
public void actionPerformed(ActionEvent e) {
-
if (e.getSource() == bnHelp)
Lab.help();
else if (e.getSource() == bnClose)
Config.store();
else if (e.getSource() == bnSystem)
SystemInfo.activate();
else if (e.getSource() == bnBatch) {
tab.setSelectedIndex(2);
batch.expand();
sizeModule();
BatchDialog dlg = new BatchDialog(batch);
Lab.setVisible(dlg, true);
}
-
else if (e.getSource() == bnLaunch) {
String job = language.getJobName() + " " + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date());
Deconvolution d = new Deconvolution(job, Command.command(), Deconvolution.Finish.ALIVE);
d.launch();
}
else if (e.getSource() == bnRun) {
String job = language.getJobName() + " " + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date());
Deconvolution d = new Deconvolution(job, Command.command());
d.deconvolve();
}
}
@Override
public void stateChanged(ChangeEvent e) {
((GroupedModulePanel) tab.getSelectedComponent()).organize();
Command.command();
}
private ArrayList<AbstractModule> buildDeconvolutionPanel() {
ArrayList<AbstractModule> list = new ArrayList<AbstractModule>();
list.add(image);
list.add(psf);
list.add(algo);
list.add(directory);
return list;
}
private ArrayList<AbstractModule> buildAdvancedPanel() {
ArrayList<AbstractModule> list = new ArrayList<AbstractModule>();
list.add(output);
list.add(controller);
list.add(preprocessing);
list.add(fft);
return list;
}
private ArrayList<AbstractModule> buildProgrammingPanel() {
ArrayList<AbstractModule> list = new ArrayList<AbstractModule>();
list.add(batch);
list.add(command);
list.add(language);
return list;
}
private ArrayList<AbstractModule> buildAboutPanel() {
ArrayList<AbstractModule> list = new ArrayList<AbstractModule>();
list.add(about);
list.add(licence);
list.add(config);
return list;
}
public void close() {
for (AbstractModule module : modules)
module.close();
bnLaunch.removeActionListener(this);
bnRun.removeActionListener(this);
bnBatch.removeActionListener(this);
bnClose.removeActionListener(this);
bnHelp.removeActionListener(this);
Lab.close();
}
public void sizeModule() {
if (tab.getSelectedIndex() == 0)
sizePanel(panelDeconv);
if (tab.getSelectedIndex() == 1)
sizePanel(panelAdvanc);
if (tab.getSelectedIndex() == 2)
sizePanel(panelScript);
if (tab.getSelectedIndex() == 3)
sizePanel(panelAbout);
}
private void sizePanel(GroupedModulePanel panel) {
Dimension dim = getSize();
int hpc = 70;
int npc = hpc * panel.getModules().size();
Dimension small = new Dimension(dim.width, hpc);
Dimension large = new Dimension(dim.width, dim.height - npc);
setMinimumSize(new Dimension(Constants.widthGUI, 4 * hpc));
for (AbstractModule module : panel.getModules()) {
if (module.isExpanded()) {
module.setPreferredSize(large);
module.setMaximumSize(large);
module.setMinimumSize(small);
module.getExpandedPanel().setPreferredSize(large);
module.getExpandedPanel().setMaximumSize(large);
module.getExpandedPanel().setMinimumSize(small);
}
else {
module.setPreferredSize(small);
module.setMaximumSize(small);
module.setMinimumSize(small);
module.getCollapsedPanel().setPreferredSize(small);
module.getCollapsedPanel().setMaximumSize(small);
module.getCollapsedPanel().setMinimumSize(small);
}
}
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/module/DirectoryModule.java b/DeconvolutionLab2/src/deconvolutionlab/module/DirectoryModule.java
index cb67a9c..427a986 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/module/DirectoryModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/module/DirectoryModule.java
@@ -1,231 +1,248 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab.module;
+import ij.IJ;
+
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
-import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import bilib.component.GridPanel;
import bilib.tools.Files;
import deconvolution.Command;
import deconvolutionlab.Config;
public class DirectoryModule extends AbstractModule implements ActionListener, KeyListener {
private JComboBox<String> cmbPath;
private JTextField txtPath;
private JButton bnBrowse;
private JCheckBox chkSystem;
private JCheckBox chkDisplayFinal;
public DirectoryModule() {
super("Path", "", "Default", "");
}
@Override
public String getCommand() {
String cmd = "";
- if (cmbPath.getSelectedIndex() != 0)
+ if (cmbPath.getSelectedIndex() == 1)
+ cmd += "-path home ";
+ if (cmbPath.getSelectedIndex() == 2)
+ cmd += "-path desktop ";
+ if (cmbPath.getSelectedIndex() == 3)
cmd += " -path " + txtPath.getText();
if (!chkSystem.isSelected())
cmd += " -system no";
if (!chkDisplayFinal.isSelected())
cmd += " -display no";
return cmd;
}
@Override
public JPanel buildExpandedPanel() {
-
- cmbPath = new JComboBox<String>(new String[] { "Current", "Specify"});
+ cmbPath = new JComboBox<String>(new String[] { "current", "home", "desktop", "specify ..."});
txtPath = new JTextField("", 35);
bnBrowse = new JButton("Browse");
chkSystem = new JCheckBox("Show the system panel");
chkDisplayFinal = new JCheckBox("Display the final output");
-
-
GridPanel pn1 = new GridPanel(true, 3);
pn1.place(0, 0, 3, 1, "Working directory");
pn1.place(1, 0, cmbPath);
pn1.place(1, 1, bnBrowse);
pn1.place(2, 0, 3, 1, txtPath);
-
pn1.place(5, 0, 3, 1, " ");
pn1.place(6, 0, 3, 1, chkSystem);
pn1.place(7, 0, 3, 1, chkDisplayFinal);
-
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
panel.add(pn1);
- String dir = System.getProperty("user.dir");
+ String dir = Files.getWorkingDirectory();
Config.register(getName(), "current", cmbPath, cmbPath.getItemAt(0));
Config.register(getName(), "path", txtPath, dir);
Config.register(getName(), "system", chkSystem, true);
Config.register(getName(), "display", chkDisplayFinal, true);
-
// Add drop area
pn1.setDropTarget(new LocalDropTarget());
txtPath.setDropTarget(new LocalDropTarget());
getCollapsedPanel().setDropTarget(new LocalDropTarget());
bnTitle.setDropTarget(new LocalDropTarget());
bnSynopsis.setDropTarget(new LocalDropTarget());
bnExpand.setDropTarget(new LocalDropTarget());
chkSystem.addActionListener(this);
chkDisplayFinal.addActionListener(this);
cmbPath.addActionListener(this);
txtPath.addKeyListener(this);
bnBrowse.addActionListener(this);
getAction1Button().addActionListener(this);
return panel;
}
private void update() {
setCommand(getCommand());
if (cmbPath.getSelectedIndex() == 0) {
- txtPath.setText(System.getProperty("user.dir"));
+ txtPath.setText(Files.getWorkingDirectory());
+ txtPath.setEnabled(false);
+ bnBrowse.setEnabled(false);
+ }
+ if (cmbPath.getSelectedIndex() == 1) {
+ txtPath.setText(Files.getHomeDirectory());
txtPath.setEnabled(false);
bnBrowse.setEnabled(false);
}
- else {
+ if (cmbPath.getSelectedIndex() == 2) {
+ txtPath.setText(Files.getDesktopDirectory());
+ txtPath.setEnabled(false);
+ bnBrowse.setEnabled(false);
+ }
+ if (cmbPath.getSelectedIndex() == 3) {
txtPath.setEnabled(true);
bnBrowse.setEnabled(true);
}
setSynopsis(new File(txtPath.getText()).getName());
Command.command();
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
if (e.getSource() == bnBrowse) {
File f = Files.browseDirectory(txtPath.getText());
if (f != null) {
txtPath.setText(f.getAbsolutePath());
}
}
else if (e.getSource() == cmbPath) {
- if (cmbPath.getSelectedIndex() == 0) {
- File f = new File(System.getProperty("user.dir"));
+ if (cmbPath.getSelectedIndex() == 1) {
+ File f = new File(Files.getWorkingDirectory());
+ txtPath.setText(f.getAbsolutePath());
+ }
+ if (cmbPath.getSelectedIndex() == 2) {
+ File f = new File(Files.getHomeDirectory());
+ txtPath.setText(f.getAbsolutePath());
+ }
+ if (cmbPath.getSelectedIndex() == 3) {
+ File f = new File(Files.getDesktopDirectory());
txtPath.setText(f.getAbsolutePath());
}
}
else if (e.getSource() == getAction1Button()) {
- txtPath.setText(System.getProperty("user.dir"));
+ cmbPath.setSelectedIndex(0);
+ txtPath.setText(Files.getWorkingDirectory());
txtPath.setEnabled(false);
bnBrowse.setEnabled(false);
chkDisplayFinal.setSelected(true);
chkSystem.setSelected(true);
}
update();
}
@Override
public void close() {
chkDisplayFinal.removeActionListener(this);
chkSystem.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();
}
public class LocalDropTarget extends DropTarget {
@Override
public void drop(DropTargetDropEvent e) {
e.acceptDrop(DnDConstants.ACTION_COPY);
e.getTransferable().getTransferDataFlavors();
Transferable transferable = e.getTransferable();
DataFlavor[] flavors = transferable.getTransferDataFlavors();
for (DataFlavor flavor : flavors) {
if (flavor.isFlavorJavaFileListType()) {
try {
List<File> files = (List<File>) transferable.getTransferData(flavor);
for (File file : files) {
cmbPath.setSelectedIndex(1);
bnBrowse.setEnabled(true);
txtPath.setEnabled(true);
if (file.isDirectory())
txtPath.setText(file.getAbsolutePath());
else
txtPath.setText(file.getParent());
update();
}
}
catch (UnsupportedFlavorException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}
e.dropComplete(true);
super.drop(e);
}
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/module/ImageModule.java b/DeconvolutionLab2/src/deconvolutionlab/module/ImageModule.java
index 848c85d..02e47a2 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/module/ImageModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/module/ImageModule.java
@@ -1,372 +1,360 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab.module;
-import ij.IJ;
-
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import signal.RealSignal;
import signal.factory.SignalFactory;
import bilib.table.CustomizedColumn;
import bilib.table.CustomizedTable;
import bilib.tools.Files;
import deconvolution.Command;
import deconvolution.Deconvolution;
import deconvolution.DeconvolutionDialog;
import deconvolutionlab.Config;
import deconvolutionlab.Constants;
import deconvolutionlab.Imager;
import deconvolutionlab.Lab;
import deconvolutionlab.dialog.PatternDialog;
import deconvolutionlab.dialog.SyntheticDialog;
import deconvolutionlab.monitor.Monitors;
public class ImageModule extends AbstractModule implements ActionListener, MouseListener {
private CustomizedTable table;
private JButton bnFile;
private JButton bnDirectory;
private JButton bnSynthetic;
private JButton bnPlatform;
public ImageModule() {
super("Image", "-image", (Lab.getPlatform() == Imager.Platform.IMAGEJ ? "Active" : ""), "Check");
}
@Override
public String getCommand() {
int row = table.getSelectedRow();
if (row < 0)
return "";
return "-image " + table.getCell(row, 1) + " " + table.getCell(row, 2);
}
@Override
public JPanel buildExpandedPanel() {
ArrayList<CustomizedColumn> columns = new ArrayList<CustomizedColumn>();
columns.add(new CustomizedColumn("Name", String.class, 100, false));
columns.add(new CustomizedColumn("Source", String.class, 100, false));
columns.add(new CustomizedColumn("Command", String.class, Constants.widthGUI - 200, true));
columns.add(new CustomizedColumn("", String.class, 30, "\u232B", "Delete this image source"));
table = new CustomizedTable(columns, true);
table.getColumnModel().getColumn(3).setMaxWidth(30);
table.getColumnModel().getColumn(3).setMinWidth(30);
table.addMouseListener(this);
bnFile = new JButton("\u2295 file");
bnDirectory = new JButton("\u2295 directory");
bnSynthetic = new JButton("\u2295 synthetic");
bnPlatform = new JButton("\u2295 platform");
JToolBar pn = new JToolBar("Controls Image");
pn.setBorder(BorderFactory.createEmptyBorder());
pn.setLayout(new GridLayout(1, 4));
pn.setFloatable(false);
pn.add(bnFile);
pn.add(bnDirectory);
pn.add(bnSynthetic);
if (Lab.getPlatform() == Imager.Platform.IMAGEJ)
pn.add(bnPlatform);
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createEtchedBorder());
panel.setLayout(new BorderLayout());
panel.add(pn, BorderLayout.SOUTH);
panel.add(table.getMinimumPane(100, 100), BorderLayout.CENTER);
// Add drop area
table.setDropTarget(new LocalDropTarget());
getCollapsedPanel().setDropTarget(new LocalDropTarget());
bnTitle.setDropTarget(new LocalDropTarget());
bnSynopsis.setDropTarget(new LocalDropTarget());
bnExpand.setDropTarget(new LocalDropTarget());
bnFile.addActionListener(this);
bnDirectory.addActionListener(this);
bnSynthetic.addActionListener(this);
bnPlatform.addActionListener(this);
getAction1Button().addActionListener(this);
getAction2Button().addActionListener(this);
bnFile.setToolTipText("Add a new source read from a single file (3D z-stack)");
bnDirectory.setToolTipText("Add a new source read from the 2D images from a directory");
bnSynthetic.setToolTipText("Add a new source artificially created");
bnPlatform.setToolTipText("Add a new source from a list of images of the platform");
getAction2Button().setToolTipText("Click to have a preview, Shift-click or Ctrl-click to show the complete stack");
getAction1Button().setToolTipText("Select the active window from the running platform");
Config.registerTable(getName(), "image", table);
return panel;
}
public void update() {
int row = table.getSelectedRow();
if (row >= 0) {
setCommand(getCommand());
setSynopsis(table.getCell(row, 0));
Command.command();
}
else {
setSynopsis("");
setCommand("Drag your image file, here");
}
getAction2Button().setEnabled(table.getRowCount() > 0);
}
@Override
public void actionPerformed(ActionEvent e) {
-
-IJ.log("ImageModule, line 170 " + e);
super.actionPerformed(e);
if (e.getSource() == bnFile)
file(Command.getPath());
else if (e.getSource() == bnDirectory)
dir(Command.getPath());
else if (e.getSource() == bnSynthetic)
synthetic(false);
else if (e.getSource() == bnPlatform)
platform();
else if (e.getSource() == getAction1Button()) {
int row = -1;
for(int i=0; i<table.getRowCount(); i++) {
if (table.getCell(i, 0).equalsIgnoreCase("active"))
if (table.getCell(i, 1).equalsIgnoreCase("platform"))
if (table.getCell(i, 2).equalsIgnoreCase("active"))
row = i;
}
if (row < 0)
table.insert(new String[] { "active", "platform", "active", "\u232B" });
else
table.setRowSelectionInterval(row, row);
}
else if (e.getSource() == getAction2Button()) {
boolean s = (e.getModifiers() & ActionEvent.SHIFT_MASK) == ActionEvent.SHIFT_MASK;
boolean c = (e.getModifiers() & ActionEvent.CTRL_MASK) == ActionEvent.CTRL_MASK;
display(s | c);
}
update();
}
public void platform() {
String name = Lab.getActiveImage();
if (name != "")
table.insert(new String[] { name, "platform", name, "\u232B" });
}
private void file(String path) {
File file = Files.browseFile(path);
if (file == null)
return;
table.insert(new String[] { file.getName(), "file", file.getAbsolutePath(), "\u232B" });
}
private void dir(String path) {
File file = Files.browseDirectory(path);
if (file == null)
return;
PatternDialog dlg = new PatternDialog(file);
Lab.setVisible(dlg, true);
if (dlg.wasCancel())
return;
table.insert(new String[] { dlg.getDirName(), "directory", dlg.getCommand(), "\u232B" });
}
private void synthetic(boolean edit) {
ArrayList<SignalFactory> list = SignalFactory.getImages();
SyntheticDialog dlg = new SyntheticDialog(list);
if (edit) {
int row = table.getSelectedRow();
if (row >= 0) {
dlg.setParameters(table.getCell(row, 0), table.getCell(row, 2));
}
}
Lab.setVisible(dlg, true);
if (dlg.wasCancel())
return;
if (edit) {
int row = table.getSelectedRow();
if (row <= 0)
table.removeRow(row);
}
table.insert(new String[] { dlg.getShapeName(), "synthetic", dlg.getCommand(), "\u232B" });
}
private void edit() {
int row = table.getSelectedRow();
if (row < 0)
return;
String name = table.getCell(row, 0).trim();
for (SignalFactory factory : SignalFactory.getAll()) {
if (name.equals(factory.getName().trim())) {
synthetic(true);
return;
}
}
String filename = table.getCell(row, 1).trim();
File file = new File(filename);
if (!file.exists())
return;
if (file.isFile())
file(table.getCell(row, 21));
else
dir(table.getCell(row, 1));
}
private void display(boolean stack) {
int row = table.getSelectedRow();
if (row < 0)
return;
-
-IJ.log(">>>>>>>>>>>>>>> ImageModule, line 273 " + Command.command());
Deconvolution deconvolution = new Deconvolution("Check Image", Command.command());
-
-IJ.log("ImageModule, line 276 " + Command.command());
-
deconvolution.openImage();
-IJ.log("ImageModule, line 279 " + stack);
-
if (stack) {
RealSignal x = deconvolution.getImage();
-IJ.log("ImageModule, line 283 " + (x == null));
if (x != null)
Lab.show(Monitors.createDefaultMonitor(), x, table.getCell(row, 0));
}
else {
DeconvolutionDialog d = new DeconvolutionDialog(DeconvolutionDialog.Module.IMAGE, deconvolution);
Lab.setVisible(d, false);
}
}
@Override
public void mouseClicked(MouseEvent e) {
if (e.getSource() == table) {
int row = table.getSelectedRow();
if (row < 0)
return;
if (table.getSelectedColumn() == 3) {
table.removeRow(row);
if (table.getRowCount() > 0)
table.setRowSelectionInterval(0, 0);
}
update();
if (e.getClickCount() == 2) {
edit();
}
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void close() {
bnFile.removeActionListener(this);
bnDirectory.removeActionListener(this);
bnSynthetic.removeActionListener(this);
bnPlatform.removeActionListener(this);
}
public class LocalDropTarget extends DropTarget {
@Override
public void drop(DropTargetDropEvent e) {
e.acceptDrop(DnDConstants.ACTION_COPY);
e.getTransferable().getTransferDataFlavors();
Transferable transferable = e.getTransferable();
DataFlavor[] flavors = transferable.getTransferDataFlavors();
for (DataFlavor flavor : flavors) {
if (flavor.isFlavorJavaFileListType()) {
try {
List<File> files = (List<File>) transferable.getTransferData(flavor);
for (File file : files) {
if (file.isDirectory()) {
table.insert(new String[] { file.getName(), "directory", file.getAbsolutePath(), "\u232B" });
table.setRowSelectionInterval(0, 0);
update();
}
if (file.isFile()) {
table.insert(new String[] { file.getName(), "file", file.getAbsolutePath(), "\u232B" });
update();
}
}
}
catch (UnsupportedFlavorException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}
e.dropComplete(true);
super.drop(e);
}
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/module/RunningModule.java b/DeconvolutionLab2/src/deconvolutionlab/module/RunningModule.java
deleted file mode 100644
index 63a2ff8..0000000
--- a/DeconvolutionLab2/src/deconvolutionlab/module/RunningModule.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * DeconvolutionLab2
- *
- * Conditions of use: You are free to use this software for research or
- * educational purposes. In addition, we expect you to include adequate
- * citations and acknowledgments whenever you present or publish results that
- * are based on it.
- *
- * Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
- * Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
- * R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
- */
-
-/*
- * Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
- *
- * This file is part of DeconvolutionLab2 (DL2).
- *
- * DL2 is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later
- * version.
- *
- * DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * DL2. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package deconvolutionlab.module;
-
-import java.awt.BorderLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.io.File;
-import java.util.ArrayList;
-
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-
-import bilib.table.CustomizedColumn;
-import bilib.table.CustomizedTable;
-import bilib.tools.Files;
-import deconvolution.Command;
-import deconvolutionlab.Config;
-import deconvolutionlab.Constants;
-
-public class RunningModule extends AbstractModule implements MouseListener {
-
- private CustomizedTable table;
-
- private String[] valuesMonitor;
- private String[] valuesVerbose;
- private String[] valuesPath;
-
- private JTextField txtMonitor;
- private JTextField txtVerbose;
- private JTextField txtPath;
- private JTextField txtDirectory;
-
- public RunningModule() {
- super("Running", "", "Default", "Browse");
- }
-
- @Override
- public String getCommand() {
- String cmd = "";
- String p = txtPath.getText();
- if (!p.equalsIgnoreCase(valuesPath[0]))
- cmd += " -path " + txtDirectory.getText().toLowerCase();
- if (!txtMonitor.getText().equalsIgnoreCase(valuesMonitor[0]))
- cmd += " -monitor " + txtMonitor.getText().toLowerCase();
- if (!txtVerbose.getText().equalsIgnoreCase(valuesVerbose[0]))
- cmd += " -verbose " + txtVerbose.getText().toLowerCase();
-
- return cmd;
- }
-
- @Override
- public JPanel buildExpandedPanel() {
-
- valuesPath = new String[] { "current", "specify" };
- valuesMonitor = new String[] { "console table", "console", "table", "no" };
- valuesVerbose = new String[] { "log", "quiet", "mute", "prolix" };
-
- txtDirectory = new JTextField(System.getProperty("user.dir"));
- txtPath = new JTextField(valuesPath[0]);
- txtMonitor = new JTextField(valuesMonitor[0]);
- txtVerbose = new JTextField(valuesVerbose[0]);
-
- ArrayList<CustomizedColumn> columns = new ArrayList<CustomizedColumn>();
- columns.add(new CustomizedColumn("Settings", String.class, 150, false));
- columns.add(new CustomizedColumn("State", String.class, 100, false));
- columns.add(new CustomizedColumn("Information", String.class, Constants.widthGUI - 250, true));
- columns.add(new CustomizedColumn("", String.class, 100, "Change", "Change this setting"));
- table = new CustomizedTable(columns, false);
-
- table.getColumnModel().getColumn(3).setMaxWidth(140);
- table.getColumnModel().getColumn(3).setMaxWidth(140);
-
- JPanel panel = new JPanel(new BorderLayout());
- panel.add(table.getPane(100, 100), BorderLayout.CENTER);
-
- Config.register(getName(), "Path", txtPath, valuesPath[0]);
- Config.register(getName(), "Monitor", txtMonitor, valuesMonitor[0]);
- Config.register(getName(), "Verbose", txtVerbose, valuesVerbose[0]);
- Config.register(getName(), "Directory", txtDirectory, System.getProperty("user.dir"));
-
- getAction1Button().addActionListener(this);
- getAction2Button().addActionListener(this);
-
- table.addMouseListener(this);
-
- return panel;
- }
-
- public void init() {
- table.append(new String[] { "Path", txtPath.getText(), txtDirectory.getText(), "Change" });
- table.append(new String[] { "Monitor", txtMonitor.getText(), "Monitor in table and in console", "Change" });
- table.append(new String[] { "Verbose", txtVerbose.getText(), "Level of messages in monitor", "Change" });
- update();
- }
-
- public void update() {
- setCommand(getCommand());
- setSynopsis(txtDirectory.getText());
- Command.command();
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- super.actionPerformed(e);
- if (e.getSource() == getAction1Button()) {
- for (int row = 0; row < table.getRowCount(); row++) {
- if (table.getCell(row, 0).equalsIgnoreCase("path")) {
- setDefault(row, valuesPath, txtPath);
- txtDirectory.setText(System.getProperty("user.dir"));
- table.setCell(0, 2, System.getProperty("user.dir"));
- }
- if (table.getCell(row, 0).equalsIgnoreCase("monitor"))
- setDefault(row, valuesMonitor, txtMonitor);
- if (table.getCell(row, 0).equalsIgnoreCase("verbose"))
- setDefault(row, valuesVerbose, txtVerbose);
- }
- }
- if (e.getSource() == getAction2Button()) {
- File f = Files.browseDirectory(txtPath.getText());
- if (f != null) {
- txtDirectory.setText(f.getAbsolutePath());
- txtPath.setText(valuesPath[1]);
- table.setCell(0, 1, txtPath.getText());
- table.setCell(0, 2, txtDirectory.getText());
- }
- }
- update();
- }
-
- @Override
- public void close() {
- }
-
- @Override
- public void mouseClicked(MouseEvent e) {
- int row = table.getSelectedRow();
- if (table.getSelectedColumn() == 3) {
- if (table.getCell(row, 0).equalsIgnoreCase("path")) {
- toggle(row, valuesPath, txtPath);
- txtDirectory.setText(System.getProperty("user.dir"));
- table.setCell(0, 2, System.getProperty("user.dir"));
- }
- if (table.getCell(row, 0).equalsIgnoreCase("monitor"))
- toggle(row, valuesMonitor, txtMonitor);
- if (table.getCell(row, 0).equalsIgnoreCase("verbose"))
- toggle(row, valuesVerbose, txtVerbose);
- }
- 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) {
- }
-
- private void toggle(int row, String values[], JTextField txt) {
- for (int i = 0; i < values.length; i++) {
- if (table.getCell(row, 1).equalsIgnoreCase(values[i])) {
- int k = i == values.length - 1 ? 0 : i + 1;
- table.setCell(row, 1, values[k]);
- txt.setText(values[k]);
- return;
- }
- }
- setDefault(row, values, txt);
- }
-
- private void setDefault(int row, String values[], JTextField txt) {
- table.setCell(row, 1, values[0]);
- txt.setText(values[0]);
- }
-
-}
diff --git a/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/Deconvolutionlab2.java b/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/Deconvolutionlab2.java
index 2266eec..5c53994 100644
--- a/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/Deconvolutionlab2.java
+++ b/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/Deconvolutionlab2.java
@@ -1,48 +1,49 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package plugins.sage.deconvolutionlab;
import java.io.File;
+import bilib.tools.Files;
import deconvolutionlab.Imager;
import deconvolutionlab.Lab;
import icy.plugin.abstract_.PluginActionable;
public class Deconvolutionlab2 extends PluginActionable {
@Override
public void run() {
- Lab.init(Imager.Platform.ICY, System.getProperty("user.dir") + File.separator + "DeconvolutionLab2.config");
+ Lab.init(Imager.Platform.ICY, Files.getWorkingDirectory() + "DeconvolutionLab2.config");
new DeconvolutionLabIcyFrame();
}
}
diff --git a/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/Test.java b/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/Test.java
index 148ce2c..d7d1042 100644
--- a/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/Test.java
+++ b/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/Test.java
@@ -1,29 +1,30 @@
package plugins.sage.deconvolutionlab;
import java.io.File;
+import bilib.tools.Files;
import deconvolutionlab.Imager;
import deconvolutionlab.Lab;
import deconvolutionlab.dialog.OutputDialog;
import deconvolutionlab.output.Output.View;
import icy.gui.frame.IcyFrame;
import icy.plugin.abstract_.PluginActionable;
public class Test extends PluginActionable {
@Override
public void run() {
- Lab.init(Imager.Platform.ICY, System.getProperty("user.dir") + File.separator + "DeconvolutionLab2.config");
+ Lab.init(Imager.Platform.ICY, Files.getWorkingDirectory() + "DeconvolutionLab2.config");
IcyFrame icf = new IcyFrame();
icf.add(new OutputDialog(View.FIGURE).getContentPane());
icf.pack();
icf.toFront();
icf.addToDesktopPane();
icf.setVisible(true);
//icf.setResizable(true);
}
}
diff --git a/DeconvolutionLab2/src/signal/Signal.java b/DeconvolutionLab2/src/signal/Signal.java
index fa0c232..05a70b5 100644
--- a/DeconvolutionLab2/src/signal/Signal.java
+++ b/DeconvolutionLab2/src/signal/Signal.java
@@ -1,59 +1,60 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package signal;
import java.util.ArrayList;
public class Signal {
public int nx = 0;
public int ny;
public int nz;
public float data[][];
public String name = "untitled";
public Signal(String name, int nx, int ny, int nz) {
this.name = name;
this.nx = nx;
this.ny = ny;
this.nz = nz;
}
- public void setName(String name) {
+ public Signal setName(String name) {
this.name = name;
+ return this;
}
public String dimAsString() {
return nx + "x" + ny + "x" + nz + " ";
}
}

Event Timeline