Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F90775170
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Mon, Nov 4, 15:34
Size
253 KB
Mime Type
application/octet-stream
Expires
Wed, Nov 6, 15:34 (2 d)
Engine
blob
Format
Raw Data
Handle
22132698
Attached To
R2075 deconvolution
View Options
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="<h3>DeconvolutionLab2</h3>	v1.0" />
<property name="javadoc.footer" value="<h4>DeconvolutionLab2</h4>	<script> var tStamp=new Date(); document.write(tStamp.toUTCString()); </script>" />
<property name="javadoc.bottom" value='Copyright &copy; <script> var currYear=new Date(); document.write(currYear.getFullYear()); </script>, 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
Log In to Comment