Page MenuHomec4science

No OneTemporary

File Metadata

Created
Thu, Dec 19, 15:28
diff --git a/DeconvolutionLab2/DeconvolutionLab2.config b/DeconvolutionLab2/DeconvolutionLab2.config
index d929b86..48b59a1 100644
--- a/DeconvolutionLab2/DeconvolutionLab2.config
+++ b/DeconvolutionLab2/DeconvolutionLab2.config
@@ -1,80 +1,82 @@
#DeconvolutionLab2 [Beta 1]
#DeconvolutionLab2 [Beta 1]
-#Thu Feb 02 15:10:59 CET 2017
+#Fri Feb 03 08:33:07 CET 2017
Algorithm.FISTA.iterations=10
Algorithm.FISTA.reg=0.1
Algorithm.FISTA.scale=3
Algorithm.FISTA.step=1.0
Algorithm.FISTA.wavelets=Haar
Algorithm.ICTM.iterations=10
Algorithm.ICTM.reg=0.1
Algorithm.ICTM.step=1.0
Algorithm.ISTA.iterations=10
Algorithm.ISTA.reg=0.1
Algorithm.ISTA.scale=3
Algorithm.ISTA.step=1.0
Algorithm.ISTA.wavelets=Haar
Algorithm.LW+.iterations=10
Algorithm.LW+.step=1.0
Algorithm.LW.iterations=10
Algorithm.LW.step=1.0
Algorithm.RIF.reg=0.1
Algorithm.RL.iterations=10
Algorithm.RLTV.reg=0.1
Algorithm.SIM.gaussian.mean=0.0
Algorithm.SIM.gaussian.stdev=1.0
Algorithm.SIM.poisson=0.0
Algorithm.TM.iterations=10
Algorithm.TM.reg=0.1
Algorithm.TM.step=1.0
Algorithm.TRIF.reg=0.1
Algorithm.VC.iterations=10
Algorithm.VC.step=1.0
-Algorithm.algorithm=Regularized Inverse Filter
+Algorithm.algorithm=Landweber
Border.apoxy=Uniform
Border.apoz=Uniform
Border.extxy=0
Border.extz=0
Border.normalization=1
Border.padxy=None
Border.padz=None
Controller.constraint.enable=false
Controller.constraint.snapshot=1
Controller.constraint.value=No
Controller.reference.enable=false
Controller.reference.snapshot=1
Controller.reference.value=
Controller.residu.enable=false
Controller.residu.snapshot=1
Controller.residu.value=0.01
Controller.savestats.enable=false
Controller.savestats.snapshot=1
Controller.savestats.value=Stats
Controller.showstats.enable=false
Controller.showstats.snapshot=1
Controller.showstats.value=Stats
DeconvolutionLab.MainDialog.location.h=579
DeconvolutionLab.MainDialog.location.w=573
-DeconvolutionLab.MainDialog.location.x=5
-DeconvolutionLab.MainDialog.location.y=23
+DeconvolutionLab.MainDialog.location.x=124
+DeconvolutionLab.MainDialog.location.y=52
Fourier.dim=XYZ
Fourier.epsilon=1E-6
Fourier.fft=Academic
Image.image.row0=Cube;synthetic;Cube 100.0 0.0 10.0 1.0 size 128 128 32 ;null
Image.image.row1=resolution;directory;/Users/dsage/Desktop/DeconvolutionLab2-Course/resolution;null
Image.image.selected=Cube;synthetic;Cube 100.0 0.0 10.0 1.0 size 128 128 32 ;null
Language.headless=Run (Headless)
-Language.language=Command line
-Monitor.disable.console=false
-Monitor.disable.display=false
-Monitor.disable.multithreading=false
-Monitor.disable.table=false
-Monitor.path=/Users/dsage/git/deconvolution/DeconvolutionLab2
-Monitor.time.value=3600
-Monitor.time=No time limitation
-Monitor.verbose=Verbose\: log
-Output.output.row0=ortho;Noname;;;;\u2713;\u2713;null
-Output.output.selected=ortho;Noname;;;;\u2713;\u2713;null
-PSF.psf.row0=Airy;synthetic;Airy 100.0 0.0 1.0 size 128 128 32 ;null
-PSF.psf.row1=Defocus;synthetic;Defocus 100.0 0.0 3.0 10.0 10.0 size 3 3 100 ;null
-PSF.psf.selected=Airy;synthetic;Airy 100.0 0.0 1.0 size 128 128 32 ;null
+Language.job=Job
+Language.language=ImageJ Macro
+Output.output.row0=mip @1;MI1;;;;\u2713;null;null
+Output.output.selected=mip @1;MI1;;;;\u2713;null;null
+PSF.psf.row0=MotionBlur;synthetic;MotionBlur 100.0 0.0 3.0 30.0 3.0 size 128 128 32 ;
+PSF.psf.row1=Airy;synthetic;Airy 100.0 0.0 1.0 size 128 128 32 ;null
+PSF.psf.row2=Defocus;synthetic;Defocus 100.0 0.0 3.0 10.0 10.0 size 3 3 100 ;null
+PSF.psf.selected=MotionBlur;synthetic;MotionBlur 100.0 0.0 3.0 30.0 3.0 size 128 128 32 ;
+Watcher.disable.console=false
+Watcher.disable.display=false
+Watcher.disable.multithreading=false
+Watcher.disable.table=false
+Watcher.path=/Users/dsage/git/deconvolution/DeconvolutionLab2
+Watcher.time.value=3600
+Watcher.time=No time limitation
+Watcher.verbose=Verbose\: log
diff --git a/DeconvolutionLab2/src/deconvolution/DeconvolutionListener.java b/DeconvolutionLab2/src/deconvolution/DeconvolutionListener.java
new file mode 100644
index 0000000..fe4542b
--- /dev/null
+++ b/DeconvolutionLab2/src/deconvolution/DeconvolutionListener.java
@@ -0,0 +1,7 @@
+package deconvolution;
+
+public interface DeconvolutionListener {
+
+ public abstract void started();
+ public abstract void finish();
+}
diff --git a/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java b/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java
index f7859cd..5c6a7bb 100644
--- a/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java
+++ b/DeconvolutionLab2/src/deconvolution/algorithm/Controller.java
@@ -1,381 +1,381 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolution.algorithm;
import java.util.Timer;
import java.util.TimerTask;
import deconvolution.Deconvolution;
import deconvolutionlab.Lab;
import deconvolutionlab.OutputCollection;
import deconvolutionlab.monitor.Monitors;
import fft.AbstractFFT;
import fft.FFT;
import lab.system.SystemUsage;
import lab.tools.NumFormat;
import signal.Assessment;
import signal.ComplexSignal;
import signal.Constraint;
import signal.RealSignal;
import signal.Signal;
public class Controller {
private int iterationsMax = 100;
private double timeMax = 1000;
private double residuMin = -1;
private boolean doResidu = false;
private boolean doTime = false;
private boolean doReference = false;
private boolean doConstraint = false;
private boolean doShowStats = false;
private boolean doSaveStats = false;
private boolean abort = false;
private int snapshotResidu = 0;
private int snapshotReference = 0;
private int snapshotConstraint = 0;
private int snapshotSaveStats = 0;
private int snapshotShowStats = 0;
private double timeStarting = 0;
private double memoryStarting = 0;
private double residu = Double.MAX_VALUE;
private int iterations = 0;
private double memoryPeak = 0;
private double snr = 0;
private double psnr = 0;
private Constraint.Mode constraint = Constraint.Mode.NO;
private OutputCollection outs = null;
private String referenceName = "";
private String showstatsName = "";
private String savestatsName = "";
private RealSignal refImage;
private RealSignal prevImage;
private RealSignal x;
private Timer timer;
private AbstractFFT fft;
private String algo = "";
private float statsInput[];
private Monitors monitors = new Monitors();
public Controller() {
constraint = Constraint.Mode.NO;
doResidu = false;
doTime = false;
doReference = false;
doConstraint = false;
doShowStats = false;
doSaveStats = false;
}
public void setMonitors(Monitors monitors) {
this.monitors = monitors;
}
public void setAlgorithm(String algo) {
this.algo = algo;
}
public void setFFT(AbstractFFT fft) {
this.fft = fft;
}
public void abort() {
this.abort = true;
}
public int getIterationMax() {
return iterationsMax;
}
public void setIterationMax(int iterationsMax) {
this.iterationsMax = iterationsMax;
}
public void setTimeStop(double timeMax) {
this.doTime = true;
this.timeMax = timeMax * 1e9;
}
public void setResiduStop(int snapshot, double residuMin) {
this.doResidu = true;
this.snapshotResidu = snapshot;
this.residuMin = residuMin;
}
public void setReference(int snapshot, String referenceName) {
this.doReference = true;
this.snapshotReference = snapshot;
this.referenceName = referenceName;
}
public void setConstraint(int snapshot, Constraint.Mode constraint) {
this.doConstraint = true;
this.snapshotConstraint = snapshot;
this.constraint = constraint;
}
public void setSaveStats(int snapshot, String name) {
this.doSaveStats = true;
this.snapshotSaveStats = snapshot;
this.savestatsName = name;
}
public void setShowStats(int snapshot, String name) {
this.doShowStats = true;
this.snapshotShowStats = snapshot;
this.showstatsName = name;
}
public void setOutputs(OutputCollection outs) {
this.outs = outs;
}
public void start(RealSignal x) {
this.x = x;
statsInput = x.getStats();
iterations = 0;
timer = new Timer();
timer.schedule(new Updater(), 0, 100);
timeStarting = System.nanoTime();
memoryStarting = SystemUsage.getHeapUsed();
Signal.bytes = 0;
if (doConstraint && x != null)
Constraint.setModel(x);
if (doReference && snapshotReference >= 1) {
refImage = new Deconvolution("-image file " + referenceName).openImage();
if (refImage == null)
monitors.error("Impossible to load the reference image " + referenceName);
else
monitors.log("Reference image loaded");
}
if (doShowStats || doSaveStats)
if (monitors != null)
Lab.firstStats(monitors, showstatsName, this, doShowStats, doSaveStats);
this.prevImage = x;
}
public boolean ends(ComplexSignal X) {
boolean res = doResidu && snapshotResidu >= 1 ? (iterations % snapshotResidu == 0) : false;
boolean con = doConstraint && snapshotConstraint >= 1 ? (iterations % snapshotConstraint == 0) : false;
boolean ref = doReference && snapshotReference >= 1 ? (iterations % snapshotReference == 0) : false;
boolean sav = doSaveStats && snapshotSaveStats >= 1 ? (iterations % snapshotSaveStats == 0) : false;
boolean shw = doShowStats && snapshotShowStats >= 1 ? (iterations % snapshotShowStats == 0) : false;
boolean out = outs == null ? false : outs.hasShow(iterations);
if (con || res || ref || sav || shw || out) {
if (fft == null)
fft = FFT.createDefaultFFT(monitors, X.nx, X.ny, X.nz);
x = new RealSignal(X.nx, X.ny, X.nz, false);
fft.inverse(X, x);
return ends(x);
}
return ends((RealSignal) null);
}
public boolean ends(RealSignal x) {
this.x = x;
boolean res = doResidu && snapshotResidu >= 1 ? (iterations % snapshotResidu == 0) : false;
boolean con = doConstraint && snapshotConstraint >= 1 ? (iterations % snapshotConstraint == 0) : false;
boolean ref = doReference && snapshotReference >= 1 ? (iterations % snapshotReference == 0) : false;
boolean sav = doSaveStats && snapshotSaveStats >= 1 ? (iterations % snapshotSaveStats == 0) : false;
boolean shw = doShowStats && snapshotShowStats >= 1 ? (iterations % snapshotShowStats == 0) : false;
if (con || res || ref)
compute(iterations, x, con, res, ref);
if (sav || shw)
Lab.nextStats(monitors, showstatsName, this, sav, shw);
if (outs != null)
- outs.executeIterative(monitors, x, this);
+ outs.executeIterative(monitors, x, iterations, this);
iterations++;
double p = iterations * 100.0 / iterationsMax;
monitors.progress("Iterative " + iterations + "/" + iterationsMax, p);
double timeElapsed = getTimeNano();
boolean stopIter = (iterations >= iterationsMax);
boolean stopTime = doTime && (timeElapsed >= timeMax);
boolean stopResd = doResidu && (residu <= residuMin);
monitors.log("@" + iterations + " Time: " + NumFormat.seconds(timeElapsed) + " Memory: " + NumFormat.bytes(Signal.bytes));
String prefix = "Stopped>> by ";
if (abort)
monitors.log(prefix + "abort");
if (stopIter)
monitors.log(prefix + "iteration " + iterations + " > " + iterationsMax);
if (stopTime)
monitors.log(prefix + "time " + timeElapsed + " > " + timeMax);
if (stopResd)
monitors.log(prefix + "residu " + NumFormat.nice(residu) + " < " + NumFormat.nice(residuMin));
return abort | stopIter | stopTime | stopResd;
}
public void finish(RealSignal x) {
this.x = x;
boolean ref = doReference;
boolean con = doConstraint;
boolean res = doResidu;
if (con || res || ref)
compute(iterations, x, con, res, ref);
if (doShowStats || doSaveStats)
Lab.lastStats(monitors, savestatsName, this, doShowStats, doSaveStats);
monitors.log("Time: " + NumFormat.seconds(getTimeNano()) + " Peak:" + getMemoryAsString());
if (timer != null)
timer.cancel();
}
private void compute(int iterations, RealSignal x, boolean con, boolean res, boolean ref) {
if (x == null)
return;
if (con && constraint != null)
new Constraint(monitors).apply(x, constraint);
if (ref && refImage != null) {
String s = "";
psnr = Assessment.psnr(x, refImage);
snr = Assessment.snr(x, refImage);
s += " PSNR: " + NumFormat.nice(psnr);
s += " SNR: " + NumFormat.nice(snr);
monitors.log("@" + iterations + " " + s);
}
residu = Double.MAX_VALUE;
if (res && prevImage != null) {
residu = Assessment.relativeResidu(x, prevImage);
prevImage = x.duplicate();
monitors.log("@" + iterations + " Residu: " + NumFormat.nice(residu));
}
}
public String[] stats(String name) {
float params[] = null;
if (x != null)
params = x.getStats();
String[] row = new String[15];
row[0] = name;
row[1] = algo;
row[2] = "" + iterations;
row[3] = (params == null ? "-" : "" + params[0]);
row[4] = (params == null ? "-" : "" + params[1]);
row[5] = (params == null ? "-" : "" + params[2]);
row[6] = (params == null ? "-" : "" + params[3]);
row[7] = (params == null ? "-" : "" + params[4]);
row[8] = (params == null ? "-" : "" + params[5]);
row[9] = NumFormat.seconds(getTimeNano());
row[10] = NumFormat.bytes(SystemUsage.getHeapUsed());
row[11] = NumFormat.bytes(memoryPeak);
row[12] = doReference ? NumFormat.nice(psnr) : "n/a";
row[13] = doReference ? NumFormat.nice(snr) : "n/a";
row[14] = doResidu ? NumFormat.nice(residu) : "n/a";
return row;
}
public double getTimeNano() {
return (System.nanoTime() - timeStarting);
}
public Constraint.Mode getConstraint() {
return constraint;
}
public String getConstraintAsString() {
if (!doConstraint)
return "no";
if (constraint == Constraint.Mode.NO)
return "no";
else
return constraint.name().toLowerCase();
}
public String getReference() {
return doReference ? referenceName : "no ground-truth";
}
public String getShowStats() {
return doShowStats ? showstatsName : "no stats";
}
public String getSaveStats() {
return doSaveStats ? savestatsName : "no stats";
}
public String getStoppingCriteria(AbstractAlgorithm algo) {
String stop = algo.isIterative() ? " iterations limit=" + getIterationMax() + " " : ", ";
stop += doTime ? ", time limit=" + NumFormat.nice(timeMax * 1e-9) : " no time limit" + ", ";
stop += doResidu ? ", residu limit=" + NumFormat.nice(residuMin) : " no residu limit";
return stop;
}
public float[] getStatsInput() {
return statsInput;
}
public double getMemory() {
return memoryPeak - memoryStarting;
}
public String getMemoryAsString() {
return NumFormat.bytes(getMemory());
}
public int getIterations() {
return iterations;
}
private void update() {
memoryPeak = Math.max(memoryPeak, SystemUsage.getHeapUsed());
}
private class Updater extends TimerTask {
@Override
public void run() {
update();
}
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/Lab.java b/DeconvolutionLab2/src/deconvolutionlab/Lab.java
index 895597e..2d2504b 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/Lab.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/Lab.java
@@ -1,359 +1,363 @@
/*
* 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 imagej.IJImager;
-
import java.io.File;
import java.util.ArrayList;
import java.util.regex.Pattern;
import javax.swing.JFrame;
+import deconvolution.algorithm.Controller;
+import deconvolutionlab.PlatformImager.ContainerImage;
+import deconvolutionlab.monitor.Monitors;
+import fft.AbstractFFT;
+import fft.AbstractFFTLibrary;
+import fft.FFT;
+import imagej.IJImager;
import lab.component.CustomizedColumn;
import lab.component.CustomizedTable;
import lab.tools.NumFormat;
import lab.tools.WebBrowser;
import plugins.sage.deconvolutionlab.IcyImager;
import signal.ComplexComponent;
import signal.ComplexSignal;
import signal.RealSignal;
import signal.factory.Sphere;
-import deconvolution.algorithm.Controller;
-import deconvolutionlab.monitor.ConsoleMonitor;
-import deconvolutionlab.monitor.Monitors;
-import fft.AbstractFFT;
-import fft.AbstractFFTLibrary;
-import fft.FFT;
public class Lab {
private static PlatformImager imager;
private static Lab instance = null;
private static Platform platform = Platform.IMAGEJ;
private static CustomizedTable tableStats = null;
private static JFrame frameStats = null;
static {
imager = new IJImager();
createStats();
}
private static void createStats() {
ArrayList<CustomizedColumn> columns = new ArrayList<CustomizedColumn>();
columns.add(new CustomizedColumn("Name", String.class, 100, false));
columns.add(new CustomizedColumn("Algorithm", String.class, 100, false));
columns.add(new CustomizedColumn("Iterations", String.class, 100, false));
columns.add(new CustomizedColumn("Image Mean", String.class, 100, false));
columns.add(new CustomizedColumn("Image Minimum", String.class, 100, false));
columns.add(new CustomizedColumn("Image Maximum", String.class, 100, false));
columns.add(new CustomizedColumn("Image Stdev", String.class, 100, false));
columns.add(new CustomizedColumn("Image norm1", String.class, 100, false));
columns.add(new CustomizedColumn("Image norm2", String.class, 100, false));
columns.add(new CustomizedColumn("Time", String.class, 100, false));
columns.add(new CustomizedColumn("Memory", String.class, 100, false));
columns.add(new CustomizedColumn("Peak", String.class, 100, false));
columns.add(new CustomizedColumn("PSNR", String.class, 100, false));
columns.add(new CustomizedColumn("SNR", String.class, 100, false));
columns.add(new CustomizedColumn("Residu", String.class, 100, false));
tableStats = new CustomizedTable(columns, true);
}
public static Platform getPlatform() {
return platform;
}
public static void getInstance(Platform p) {
platform = p;
if (instance == null) {
instance = new Lab();
switch (p) {
case STANDALONE:
imager = new LabImager();
break;
case IMAGEJ:
imager = new IJImager();
break;
case ICY:
imager = new IcyImager();
break;
default:
imager = new LabImager();
break;
}
}
}
public static void help() {
WebBrowser.open(Constants.url);
}
public static void checkFFT(Monitors monitors) {
ArrayList<AbstractFFTLibrary> libraries = FFT.getInstalledLibraries();
for (int k = 1; k <= 3; k++)
for (AbstractFFTLibrary library : libraries) {
RealSignal y = new Sphere(3, 1).generate(40, 30, 20);
double chrono = System.nanoTime();
AbstractFFT fft = FFT.createDefaultFFT(monitors, y.nx, y.ny, y.nz);
RealSignal x = fft.inverse(fft.transform(y));
chrono = System.nanoTime() - chrono;
double residu = y.getEnergy() - x.getEnergy();
monitors.log(fft.getName() + " Test " + k);
monitors.log("\t residu of reconstruction: " + residu);
monitors.log("\t computation time (" + x.nx + "x" + x.ny + "x" + x.nz + ") " + NumFormat.time(chrono));
}
}
- public static void appendShowLive(Monitors monitors, String key, RealSignal signal, String title, String code) {
- imager.appendShowLive(key, signal, title);
+ public static ContainerImage createContainer(Monitors monitors, String title) {
+ monitors.log("Create Live Real Signal " + title);
+ return imager.createContainer(title);
+ }
+
+ public static void append(Monitors monitors, ContainerImage container, RealSignal signal, String title) {
+ imager.append(container, signal, title);
monitors.log("Add Live Real Signal " + title);
}
- public static void appendShowLive(Monitors monitors, String key, RealSignal signal, String title, PlatformImager.Type type) {
- imager.appendShowLive(key, signal, title, type);
+ public static void append(Monitors monitors, ContainerImage container, RealSignal signal, String title, PlatformImager.Type type) {
+ imager.append(container, signal, title, type);
monitors.log("Add Live Real Signal " + title);
}
public static void show(Monitors monitors, ComplexSignal signal, String title) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imager.show(signal, title);
}
public static void show(Monitors monitors, ComplexSignal signal, String title, ComplexComponent complex) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imager.show(signal, title, complex);
}
public static void show(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imager.show(signal, title);
}
public static void show(Monitors monitors, RealSignal signal, String title, PlatformImager.Type type) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imager.show(signal, title, type);
}
public static void show(Monitors monitors, RealSignal signal, String title, PlatformImager.Type type, int z) {
if (signal == null) {
monitors.error("Show " + title + " this image does not exist.");
return;
}
monitors.log("Show Real Signal " + title);
imager.show(signal, title, type);
}
public static void save(Monitors monitors, RealSignal signal, String filename) {
imager.save(signal, filename);
monitors.log("Save Real Signal " + filename);
}
public static void save(Monitors monitors, RealSignal signal, String filename, PlatformImager.Type type) {
imager.save(signal, filename, type);
monitors.log("Save Real Signal " + filename);
}
public static void firstStats(Monitors monitors, String name, Controller controller, boolean show, boolean save) {
if (controller == null)
return;
Lab.createStats();
if (show) {
frameStats = new JFrame(name);
frameStats.getContentPane().add(tableStats.getPane(600, 200));
frameStats.pack();
frameStats.setVisible(true);
}
nextStats(monitors, "Start", controller, show, save);
}
public static void nextStats(Monitors monitors, String name, Controller controller, boolean show, boolean save) {
if (tableStats == null)
return;
if (controller == null)
return;
tableStats.append(controller.stats(name));
monitors.log("Stats " + name);
if (show && frameStats != null) {
if (!frameStats.isVisible())
frameStats.setVisible(true);
frameStats.requestFocus();
}
}
public static void lastStats(Monitors monitors, String filename, Controller controller, boolean show, boolean save) {
if (controller == null)
return;
if (tableStats == null)
return;
nextStats(monitors, "End", controller, show, save);
if (save) {
monitors.log("Stats " + filename);
tableStats.saveCSV(filename + ".csv");
}
}
public static RealSignal open(Monitors monitors, String filename) {
RealSignal signal = imager.open(filename);
if (signal == null)
monitors.error("Unable to open " + filename);
else
monitors.log("Load " + filename);
return signal;
}
public static RealSignal openDir(Monitors monitors, String path) {
String parts[] = path.split(" pattern ");
String dirname = path;
String regex = "";
if (parts.length == 2) {
dirname = parts[0].trim();
regex = parts[1].trim();
}
File file = new File(dirname + File.separator);
if (!file.isDirectory()) {
monitors.error("Dir " + dirname + " is not a directory.");
return null;
}
String[] list = file.list();
ArrayList<RealSignal> slices = new ArrayList<RealSignal>();
int nx = 0;
int ny = 0;
Pattern pattern = Pattern.compile(regex);
for (String filename : list) {
if (pattern.matcher(filename).find()) {
RealSignal slice = imager.open(dirname + File.separator + filename);
if (slice != null) {
slices.add(slice);
nx = Math.max(nx, slice.nx);
ny = Math.max(ny, slice.ny);
monitors.log("Image " + path + File.separator + filename + " is loaded.");
}
}
else {
monitors.error("Error in loading image " + path + File.separator + filename);
}
}
int nz = slices.size();
if (nz <= 0) {
monitors.error("Dir " + path + " do no contain valid images.");
return null;
}
RealSignal signal = new RealSignal(nx, ny, nz);
for (int z = 0; z < slices.size(); z++)
signal.setSlice(z, slices.get(z));
return signal;
}
public static void showOrthoview(Monitors monitors, RealSignal signal, String title, int hx, int hy, int hz) {
if (signal == null) {
monitors.error("Show Orthoview " + title + " this image does not exist.");
return;
}
imager.show(signal.createOrthoview(hx, hy, hz), title);
}
public static void showOrthoview(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show Orthoview " + title + " this image does not exist.");
return;
}
int hx = signal.nx / 2;
int hy = signal.ny / 2;
int hz = signal.nz / 2;
imager.show(signal.createOrthoview(hx, hy, hz), title);
}
public static void showMIP(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show MIP " + title + " this image does not exist.");
return;
}
imager.show(signal.createMIP(), title);
}
public static void showMontage(Monitors monitors, RealSignal signal, String title) {
if (signal == null) {
monitors.error("Show Montage " + title + " this image does not exist.");
return;
}
imager.show(signal.createMontage(), title);
}
public static RealSignal create(Monitors monitors, String name) {
RealSignal signal = imager.create(name);
if (signal != null)
monitors.log("Created the real signal " + name + " " + signal.toString());
else
monitors.error("Impossible to create the real signal " + name);
return signal;
}
public static RealSignal create(Monitors monitors) {
RealSignal signal = imager.create();
if (signal != null)
monitors.log("Created the real signal from the active window " + signal.toString());
else
monitors.error("Impossible to create the real signal from the active window");
return signal;
}
public static PlatformImager getImager() {
return imager;
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/LabImager.java b/DeconvolutionLab2/src/deconvolutionlab/LabImager.java
index c796f02..2667f60 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/LabImager.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/LabImager.java
@@ -1,214 +1,214 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab;
import ij.ImagePlus;
import ij.ImageStack;
import ij.WindowManager;
import ij.io.FileSaver;
import ij.io.Opener;
import ij.process.FloatProcessor;
import ij.process.ImageProcessor;
-
-import java.util.HashMap;
-
import signal.ComplexComponent;
import signal.ComplexSignal;
import signal.RealSignal;
public class LabImager extends PlatformImager {
- private static HashMap<String, ImageStack> stacks = new HashMap<String, ImageStack>();
- private static HashMap<String, ImagePlus> images = new HashMap<String, ImagePlus>();
-
public static RealSignal create(ImagePlus imp) {
int nx = imp.getWidth();
int ny = imp.getHeight();
int nz = imp.getStackSize();
RealSignal signal = new RealSignal(nx, ny, nz);
for (int k = 0; k < nz; k++) {
ImageProcessor ip = imp.getStack().getProcessor(k + 1).convertToFloat();
signal.setXY(k, (float[]) ip.getPixels());
}
return signal;
- }
+ }
@Override
public RealSignal create() {
return build(WindowManager.getCurrentImage());
}
@Override
public RealSignal create(String name) {
ImagePlus imp = WindowManager.getImage(name);
if (imp == null)
imp = WindowManager.getCurrentImage();
return build(imp);
}
@Override
public RealSignal open(String filename) {
Opener opener = new Opener();
ImagePlus imp = opener.openImage(filename);
return build(imp);
}
-
+
@Override
public void show(RealSignal signal, String title) {
show(signal, title, PlatformImager.Type.FLOAT);
}
@Override
public void show(RealSignal signal, String title, PlatformImager.Type type) {
- show(signal, title, type, signal.nz/2);
+ show(signal, title, type, signal.nz / 2);
}
@Override
public void show(RealSignal signal, String title, PlatformImager.Type type, int z) {
ImagePlus imp = build(signal, type);
if (imp != null) {
imp.setTitle(title);
int nz = imp.getStackSize();
imp.show();
imp.setSlice(Math.max(1, Math.min(nz, z)));
imp.getProcessor().resetMinAndMax();
}
}
-
+
+ public ContainerImage createContainer(String title) {
+ return new ContainerImage();
+ }
+
@Override
- public void appendShowLive(String key, RealSignal signal, String title) {
- appendShowLive(key, signal, title, PlatformImager.Type.FLOAT);
+ public void append(ContainerImage container, RealSignal signal, String title) {
+ append(container, signal, title, PlatformImager.Type.FLOAT);
}
@Override
- public void appendShowLive(String key, RealSignal signal, String title, PlatformImager.Type type) {
- ImagePlus imp = build(signal, type);
- ImagePlus image = images.get(key);
- ImageStack stack = stacks.get(key);
- if (image == null || stack == null) {
- stack = new ImageStack(signal.nx, signal.ny);
- stack.addSlice(imp.getProcessor());
- image = new ImagePlus(title, stack);
- image.show();
- images.put(key, image);
- stacks.put(key, stack);
+ public void append(ContainerImage container, RealSignal signal, String title, PlatformImager.Type type) { ImagePlus cont = (ImagePlus) container.object;
+ if (container.object == null) {
+ ImageStack stack = new ImageStack(signal.nx, signal.ny);
+ stack.addSlice(build(signal, type).getProcessor());
+ stack.addSlice(build(signal, type).getProcessor());
+ container.object = new ImagePlus(title, stack);
+ ((ImagePlus)container.object).show();
}
else {
- stack.addSlice(imp.getProcessor());
- image.setStack(stack);
+ cont.getStack().addSlice(build(signal, type).getProcessor());
+ cont.setSlice(cont.getStack().getSize());
+ cont.updateAndDraw();
+ cont.getProcessor().resetMinAndMax();
}
- image.updateAndDraw();
- image.setSlice(image.getStack().getSize());
- image.getProcessor().resetMinAndMax();
}
@Override
public void save(RealSignal signal, String filename) {
save(signal, filename, PlatformImager.Type.FLOAT);
}
@Override
public void save(RealSignal signal, String filename, PlatformImager.Type type) {
ImagePlus imp = build(signal, type);
if (imp != null) {
if (imp.getStackSize() == 1) {
new FileSaver(imp).saveAsTiff(filename);
}
else {
new FileSaver(imp).saveAsTiffStack(filename);
}
}
}
@Override
- public void show(ComplexSignal signal, String title) {
+ public void show(ComplexSignal signal, String title) {
show(signal, title, ComplexComponent.MODULE);
}
-
+
@Override
- public void show(ComplexSignal signal, String title, ComplexComponent complex) {
+ public void show(ComplexSignal signal, String title, ComplexComponent complex) {
ImageStack stack = new ImageStack(signal.nx, signal.ny);
for (int k = 0; k < signal.nz; k++) {
float[] plane = null;
- switch(complex) {
- case REAL: plane = signal.getRealXY(k); break;
- case IMAGINARY: plane = signal.getImagXY(k); break;
- case MODULE: plane = signal.getModuleXY(k); break;
- default: plane = signal.getModuleXY_dB(k);
+ switch (complex) {
+ case REAL:
+ plane = signal.getRealXY(k);
+ break;
+ case IMAGINARY:
+ plane = signal.getImagXY(k);
+ break;
+ case MODULE:
+ plane = signal.getModuleXY(k);
+ break;
+ default:
+ plane = signal.getModuleXY_dB(k);
}
stack.addSlice(new FloatProcessor(signal.nx, signal.ny, plane));
}
new ImagePlus(title, stack).show();
}
-
+
private RealSignal build(ImagePlus imp) {
if (imp == null)
return null;
int nx = imp.getWidth();
int ny = imp.getHeight();
int nz = imp.getStackSize();
RealSignal signal = new RealSignal(nx, ny, nz);
for (int k = 0; k < nz; k++) {
ImageProcessor ip = imp.getStack().getProcessor(k + 1).convertToFloat();
signal.setXY(k, (float[]) ip.getPixels());
}
return signal;
}
-
+
private ImagePlus build(RealSignal signal, PlatformImager.Type type) {
if (signal == null)
return null;
-
+
ImageStack stack = new ImageStack(signal.nx, signal.ny);
for (int k = 0; k < signal.nz; k++) {
ImageProcessor ip = new FloatProcessor(signal.nx, signal.ny, signal.getXY(k));
- switch(type) {
- case BYTE:
- stack.addSlice(ip.convertToByteProcessor(false));
- break;
- case SHORT:
- stack.addSlice(ip.convertToShortProcessor(false));
- break;
- case FLOAT:
- stack.addSlice(ip);
- default:
- break;
+ switch (type) {
+ case BYTE:
+ stack.addSlice(ip.convertToByteProcessor(false));
+ break;
+ case SHORT:
+ stack.addSlice(ip.convertToShortProcessor(false));
+ break;
+ case FLOAT:
+ stack.addSlice(ip);
+ default:
+ break;
}
}
return new ImagePlus("", stack);
}
-
+
@Override
public String getName() {
return "ImageJ";
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/Output.java b/DeconvolutionLab2/src/deconvolutionlab/Output.java
index 41e5c88..7cb9c24 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/Output.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/Output.java
@@ -1,335 +1,353 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab;
import java.io.File;
import deconvolution.algorithm.Controller;
+import deconvolutionlab.PlatformImager.ContainerImage;
import deconvolutionlab.monitor.Monitors;
import lab.tools.NumFormat;
import signal.Constraint;
import signal.RealSignal;
public class Output {
public enum View {
STACK, SERIES, ORTHO, MIP, PLANAR, FIGURE
};
public enum Dynamic {
INTACT, RESCALED, NORMALIZED, CLIPPED
};
+ private ContainerImage container = null;
private int px = 0;
private int py = 0;
private int pz = 0;
private boolean center = true;
private String name = "";
private boolean save = true;
private boolean show = true;
private View view = View.STACK;
private PlatformImager.Type type = PlatformImager.Type.FLOAT;
private Dynamic dynamic = Dynamic.INTACT;
private int frequency = 0;
private String path = "";
public Output(View view, int frequency, String param) {
String[] tokens = param.trim().split(" ");
this.view = view;
this.frequency = frequency;
this.name = "";
this.center = true;
this.save = true;
this.show = true;
+ this.container = Lab.createContainer(Monitors.createDefaultMonitor(), "");
for (int i = 0; i < tokens.length; i++) {
boolean found = false;
String p = tokens[i].trim().toLowerCase();
if (p.startsWith("@")) {
found = true;
}
if (p.startsWith("noshow")) {
show = false;
found = true;
}
if (p.startsWith("nosave")) {
save = false;
found = true;
}
for (Dynamic d : Dynamic.values()) {
if (p.toLowerCase().equals(d.name().toLowerCase())) {
dynamic = d;
found = true;
}
}
for (View v : View.values()) {
if (p.toLowerCase().equals(v.name().toLowerCase())) {
view = v;
found = true;
}
}
for (PlatformImager.Type t : PlatformImager.Type.values()) {
if (p.toLowerCase().equals(t.name().toLowerCase())) {
type = t;
found = true;
}
}
if (p.startsWith("(") && p.endsWith(")")) {
double pos[] = NumFormat.parseNumbers(p);
if (pos.length > 0)
px = (int) Math.round(pos[0]);
if (pos.length > 1)
py = (int) Math.round(pos[1]);
if (pos.length > 2)
pz = (int) Math.round(pos[2]);
found = true;
center = false;
}
if (!found)
name += tokens[i] + " ";
name = name.trim();
}
}
public Output(View view, boolean show, boolean save, int frequency, String name, Dynamic dynamic, PlatformImager.Type type, boolean center) {
this.name = name;
this.show = show;
this.save = save;
this.view = view;
this.type = type;
this.dynamic = dynamic;
this.center = center;
this.frequency = frequency;
}
public Output(View view, boolean show, boolean save, int frequency, String name, Dynamic dynamic, PlatformImager.Type type, int px, int py, int pz) {
this.name = name;
this.show = show;
this.save = save;
this.view = view;
this.type = type;
this.dynamic = dynamic;
this.center = false;
this.px = px;
this.py = py;
this.pz = pz;
this.frequency = frequency;
}
public boolean is(int iterations) {
if (frequency == 0)
return false;
return iterations % frequency == 0;
}
public View getView() {
return view;
}
public String getName() {
return name;
}
- public void setPath1(String path) {
+ public void setPath(String path) {
this.path = path;
}
public int extractFrequency(String param) {
String line = param.trim();
if (!line.startsWith("@"))
line = "@0 " + line;
String parts[] = line.split(" ");
if (parts.length >= 1) {
return (int) Math.round(NumFormat.parseNumber(parts[0], 0));
}
return 0;
}
public void setKeypoint(int px, int py, int pz) {
this.px = px;
this.py = py;
this.pz = pz;
this.center = false;
}
public String[] getAsString() {
String t = (type == PlatformImager.Type.FLOAT ? "" : type.name().toLowerCase());
String d = (dynamic == Dynamic.INTACT ? "" : dynamic.name().toLowerCase());
String k = "";
if (!center)
k = " (" + px + "," + py + "," + pz + ")";
else
k = "";
String sa = save ? "\u2713" : "";
String sh = show ? "\u2713" : "";
String fr = frequency > 0 ? " @" + frequency : "";
return new String[] { view.name().toLowerCase() + fr, name, d, t, k, sh, sa, "" };
}
- public void execute(Monitors monitors, RealSignal signal, Controller controller, boolean live) {
+ public void execute(Monitors monitors, RealSignal signal, Controller controller, int iter, boolean live) {
if (signal == null)
return;
String title = name;
+ if (live)
+ if (!is(iter))
+ return;
+
if (controller != null && live) {
if (controller.getIterations() > 0) {
title += "@" + controller.getIterations();
}
}
RealSignal x = null;
Constraint constraint = new Constraint(monitors);
+
switch (dynamic) {
case RESCALED:
x = signal.duplicate();
constraint.rescaled(x, 0, 255);
break;
case CLIPPED:
x = signal.duplicate();
float[] stats = controller.getStatsInput();
if (stats != null)
constraint.clipped(x, stats[1], stats[2]);
break;
case NORMALIZED:
x = signal.duplicate();
float[] stats1 = controller.getStatsInput();
if (stats1 != null)
constraint.normalized(x, stats1[0], stats1[3]);
break;
default:
x = signal;
}
String filename = path + File.separator + title + ".tif";
- String key = name + "-" + type.name() + "-" + view.name() + "-" + dynamic.name() + "-" + (px + py + pz);
+
switch (view) {
case STACK:
if (show && !live)
Lab.show(monitors, x, title, type, (center ? x.nz / 2 : pz));
if (save && !live)
Lab.save(monitors, x, filename, type);
break;
case SERIES:
for (int k = 0; k < x.nz; k++) {
RealSignal slice = x.getSlice(k);
if (show && !live)
Lab.show(monitors, slice, title, type);
if (save && !live)
Lab.save(monitors, slice, filename, type);
}
break;
case ORTHO:
- orthoview(monitors, x, title, filename, live, key);
+ orthoview(monitors, x, title, filename, live);
break;
case FIGURE:
- figure(monitors, x, title, filename, live, key);
+ figure(monitors, x, title, filename, live);
break;
case MIP:
- mip(monitors, x, title, filename, live, key);
+ mip(monitors, x, title, filename, live);
break;
case PLANAR:
- planar(monitors, x, title, filename, live, key);
+ planar(monitors, x, title, filename, live);
break;
default:
break;
}
}
- private void mip(Monitors monitors, RealSignal signal, String title, String filename, boolean live, String key) {
+ private void mip(Monitors monitors, RealSignal signal, String title, String filename, boolean live) {
RealSignal plane = signal.createMIP();
- if (show && live)
- Lab.appendShowLive(monitors, key, plane, title, type);
+ if (show && live) {
+ Lab.append(monitors, container, plane, title, type);
+ }
if (show && !live)
Lab.show(monitors, plane, title, type);
if (save)
Lab.save(monitors, plane, filename, type);
}
- private void orthoview(Monitors monitors, RealSignal signal, String title, String filename, boolean live, String key) {
+ private void orthoview(Monitors monitors, RealSignal signal, String title, String filename, boolean live) {
int cx = px;
int cy = py;
int cz = pz;
if (center) {
cx = signal.nx / 2;
cy = signal.ny / 2;
cz = signal.nz / 2;
}
RealSignal plane = signal.createOrthoview(cx, cy, cz);
- if (show && live)
- Lab.appendShowLive(monitors, key, plane, title, type);
+ if (show && live) {
+ if (container == null)
+ container = Lab.createContainer(monitors, title);
+ Lab.append(monitors, container, plane, title, type);
+ }
if (show && !live)
Lab.show(monitors, plane, title, type);
if (save)
Lab.save(monitors, plane, filename, type);
}
- private void figure(Monitors monitors, RealSignal signal, String title, String filename, boolean live, String key) {
+ private void figure(Monitors monitors, RealSignal signal, String title, String filename, boolean live) {
int cx = px;
int cy = py;
int cz = pz;
if (center) {
cx = signal.nx / 2;
cy = signal.ny / 2;
cz = signal.nz / 2;
}
RealSignal plane = signal.createFigure(cx, cy, cz);
- if (show && live)
- Lab.appendShowLive(monitors, key, plane, title, type);
+ if (show && live) {
+ if (container == null)
+ container = Lab.createContainer(monitors, title);
+ Lab.append(monitors, container, plane, title, type);
+ }
if (show && !live)
Lab.show(monitors, plane, title, type);
if (save)
Lab.save(monitors, plane, filename, type);
}
- private void planar(Monitors monitors, RealSignal signal, String title, String filename, boolean live, String key) {
+ private void planar(Monitors monitors, RealSignal signal, String title, String filename, boolean live) {
RealSignal plane = signal.createMontage();
- if (show && live)
- Lab.appendShowLive(monitors, key, plane, title, type);
+ if (show && live) {
+ if (container == null)
+ container = Lab.createContainer(monitors, title);
+ Lab.append(monitors, container, plane, title, type);
+ }
if (show && !live)
Lab.show(monitors, plane, title, type);
if (save)
Lab.save(monitors, plane, filename, type);
}
@Override
public String toString() {
String t = type.name().toLowerCase();
String v = view.name().toLowerCase();
String d = dynamic.name().toLowerCase();
String f = frequency > 0 ? " every " + frequency + " iterations" : "";
String k = (center ? "" : " keypoint = (" + px + "," + py + "," + pz + ")");
return v + " " + name + " format = (" + d + ", " + t + ") " + k + f;
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/OutputCollection.java b/DeconvolutionLab2/src/deconvolutionlab/OutputCollection.java
index 65a34a8..910648f 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/OutputCollection.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/OutputCollection.java
@@ -1,86 +1,86 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab;
import java.util.ArrayList;
import deconvolution.algorithm.Controller;
import deconvolutionlab.monitor.Monitors;
import signal.RealSignal;
public class OutputCollection {
private ArrayList<Output> list = new ArrayList<Output>();
public void setPath(String path) {
for (Output out : list)
- out.setPath1(path);
+ out.setPath(path);
}
public void add(Output out) {
if (out != null) {
list.add(out);
}
}
public boolean hasShow(int iterations) {
boolean flag = false;
for (Output out : list)
flag = flag | out.is(iterations);
return flag;
}
public void executeFinal(Monitors monitors, RealSignal signal, Controller controller) {
for (Output out : list)
if (out != null)
- out.execute(monitors, signal, controller, false);
+ out.execute(monitors, signal, controller, 0, false);
}
- public void executeIterative(Monitors monitors, RealSignal signal, Controller controller) {
+ public void executeIterative(Monitors monitors, RealSignal signal, int iter, Controller controller) {
for (Output out : list)
if (out != null)
- out.execute(monitors, signal, controller, true);
+ out.execute(monitors, signal, controller, iter, true);
}
public ArrayList<String> getInformation() {
ArrayList<String> lines = new ArrayList<String>();
for (Output out : list) {
if (out == null)
lines.add("ERR>" + list.size());
else
lines.add("" + out.toString());
}
return lines;
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/PlatformImager.java b/DeconvolutionLab2/src/deconvolutionlab/PlatformImager.java
index 3dac786..5f2c155 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/PlatformImager.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/PlatformImager.java
@@ -1,63 +1,69 @@
/*
* 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 signal.ComplexComponent;
import signal.ComplexSignal;
import signal.RealSignal;
import deconvolutionlab.monitor.Monitors;
public abstract class PlatformImager {
+ public class ContainerImage {
+ public Object object;
+ }
+
public enum Type {FLOAT, SHORT, BYTE};
public abstract RealSignal create();
public abstract RealSignal create(String name);
+ public abstract ContainerImage createContainer(String title);
+
public abstract void show(ComplexSignal signal, String title, ComplexComponent complex);
public abstract void show(ComplexSignal signal, String title);
- public abstract void appendShowLive(String key, RealSignal signal, String title);
- public abstract void appendShowLive(String key, RealSignal signal, String title, Type type);
+ public abstract void append(ContainerImage container, RealSignal signal, String title);
+ public abstract void append(ContainerImage container, RealSignal signal, String title, Type type);
public abstract void show(RealSignal signal, String title);
public abstract void show(RealSignal signal, String title, Type type);
public abstract void show(RealSignal signal, String title, PlatformImager.Type type, int z);
public abstract void save(RealSignal signal, String filename);
public abstract void save(RealSignal signal, String filename, Type type);
public abstract RealSignal open(String filename);
public abstract String getName();
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/dialog/OutputDialog.java b/DeconvolutionLab2/src/deconvolutionlab/dialog/OutputDialog.java
index 42637fc..6a8111b 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/dialog/OutputDialog.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/dialog/OutputDialog.java
@@ -1,239 +1,238 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab.dialog;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import deconvolutionlab.Output;
import deconvolutionlab.Output.Dynamic;
import deconvolutionlab.Output.View;
import deconvolutionlab.PlatformImager;
import ij.gui.GUI;
import lab.component.GridPanel;
import lab.component.SpinnerRangeInteger;
public class OutputDialog extends JDialog implements ActionListener, ChangeListener {
private JComboBox<String> cmbDynamic = new JComboBox<String>(new String[] { "intact", "rescaled", "normalized", "clipped" });
private JComboBox<String> cmbType = new JComboBox<String>(new String[] { "float", "short", "byte" });
private JCheckBox chkSave = new JCheckBox("Save output", true);
private JCheckBox chkShow = new JCheckBox("Show output", true);
private SpinnerRangeInteger snpSnapshot = new SpinnerRangeInteger(0, 0, 99999, 1);
private JComboBox<String> cmbSnapshot = new JComboBox<String>(new String[] { "Final Output", "Specify Iterations..." });
private SpinnerRangeInteger spnX = new SpinnerRangeInteger(128, 0, 99999, 1);
private SpinnerRangeInteger spnY = new SpinnerRangeInteger(128, 0, 99999, 1);
private SpinnerRangeInteger spnZ = new SpinnerRangeInteger(32, 0, 99999, 1);
private JTextField txtName = new JTextField("Noname", 18);
private JCheckBox chkCenter = new JCheckBox("Center of the volume", true);
private JButton bnOK = new JButton("OK");
private JButton bnCancel = new JButton("Cancel");
private boolean cancel = false;
private JLabel lblBit = new JLabel("32-bit");
private JLabel lblIter = new JLabel("iterations");
private JLabel lblSnapshot = new JLabel("Snapshot");
private Output out;
private View view;
private GridPanel pnOrtho;
private static int count = 1;
public OutputDialog(View view) {
super(new JFrame(), "Create a new output");
this.view = view;
lblBit.setBorder(BorderFactory.createEtchedBorder());
lblIter.setBorder(BorderFactory.createEtchedBorder());
txtName.setText(view.name().substring(0, 2) + (count++));
GridPanel pn = new GridPanel(view.name());
pn.place(0, 0, "Name");
pn.place(0, 1, 2, 1, txtName);
-
pn.place(1, 0, "Dynamic");
pn.place(1, 1, cmbDynamic);
pn.place(2, 0, "Type");
pn.place(2, 1, cmbType);
pn.place(2, 2, lblBit);
if (view != View.SERIES && view != View.STACK) {
pn.place(4, 0, "Snapshot");
pn.place(4, 1, cmbSnapshot);
pn.place(5, 0, lblSnapshot);
pn.place(5, 1, snpSnapshot);
pn.place(5, 2, lblIter);
}
pn.place(6, 0, 3, 1, chkShow);
pn.place(7, 0, 3, 1, chkSave);
GridPanel main = new GridPanel(false);
main.place(1, 0, 2, 1, pn);
if (view == View.ORTHO || view == View.FIGURE) {
- pn.place(7, 0, 3, 1, chkCenter);
+ pn.place(8, 0, 3, 1, chkCenter);
pnOrtho = new GridPanel("Keypoint");
pnOrtho.place(4, 0, "Position in X");
pnOrtho.place(4, 1, spnX);
pnOrtho.place(4, 2, "[pixel]");
pnOrtho.place(5, 0, "Position in Y");
pnOrtho.place(5, 1, spnY);
pnOrtho.place(5, 2, "[pixel]");
pnOrtho.place(6, 0, "Position in Z");
pnOrtho.place(6, 1, spnZ);
pnOrtho.place(5, 2, "[pixel]");
main.place(2, 0, 2, 1, pnOrtho);
}
main.place(3, 0, bnCancel);
main.place(3, 1, bnOK);
cmbSnapshot.addActionListener(this);
snpSnapshot.addChangeListener(this);
chkCenter.addActionListener(this);
cmbType.addActionListener(this);
bnOK.addActionListener(this);
bnCancel.addActionListener(this);
add(main);
update();
pack();
GUI.center(this);
setModal(true);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == chkCenter) {
update();
}
else if (e.getSource() == cmbSnapshot) {
update();
}
else if (e.getSource() == cmbType) {
if (cmbType.getSelectedIndex() == 0)
lblBit.setText("32-bits");
if (cmbType.getSelectedIndex() == 1)
lblBit.setText("16-bits");
if (cmbType.getSelectedIndex() == 2)
lblBit.setText("8-bits");
}
else if (e.getSource() == bnCancel) {
dispose();
cancel = true;
return;
}
else if (e.getSource() == bnOK) {
int freq = snpSnapshot.get();
Dynamic dynamic = Output.Dynamic.values()[cmbDynamic.getSelectedIndex()];
PlatformImager.Type type = PlatformImager.Type.values()[cmbType.getSelectedIndex()];
boolean show = chkShow.isSelected();
boolean save = chkSave.isSelected();
String name = txtName.getText();
if (chkCenter.isSelected()) {
out = new Output(view, show, save, freq, name, dynamic, type, true);
}
else {
int px = spnX.get();
int py = spnY.get();
int pz = spnZ.get();
out = new Output(view, show, save, freq, name, dynamic, type, px, py, pz);
}
dispose();
cancel = false;
}
}
private void update() {
if (cmbSnapshot.getSelectedIndex() == 0) {
snpSnapshot.set(0);
lblSnapshot.setEnabled(false);
lblIter.setEnabled(false);
lblSnapshot.setEnabled(false);
}
else {
lblSnapshot.setEnabled(true);
lblIter.setEnabled(true);
lblSnapshot.setEnabled(true);
}
if (snpSnapshot.get() == 0)
lblIter.setText("at the end (default)");
else
lblIter.setText("every " + snpSnapshot.get() + " iterations");
if (snpSnapshot.get() == 0)
lblIter.setText("at the end (default)");
else
lblIter.setText("every " + snpSnapshot.get() + " iterations");
boolean b = !chkCenter.isSelected();
if (pnOrtho != null) {
pnOrtho.setEnabled(b);
for (Component c : pnOrtho.getComponents())
c.setEnabled(b);
}
pack();
}
@Override
public void stateChanged(ChangeEvent e) {
if (e.getSource() == snpSnapshot)
update();
}
public Output getOut() {
return out;
}
public boolean wasCancel() {
return cancel;
}
}
diff --git a/DeconvolutionLab2/src/deconvolutionlab/modules/LanguageModule.java b/DeconvolutionLab2/src/deconvolutionlab/modules/LanguageModule.java
index b7631ba..f3e67fd 100644
--- a/DeconvolutionLab2/src/deconvolutionlab/modules/LanguageModule.java
+++ b/DeconvolutionLab2/src/deconvolutionlab/modules/LanguageModule.java
@@ -1,163 +1,213 @@
/*
* DeconvolutionLab2
*
* Conditions of use: You are free to use this software for research or
* educational purposes. In addition, we expect you to include adequate
* citations and acknowledgments whenever you present or publish results that
* are based on it.
*
* Reference: DeconvolutionLab2: An Open-Source Software for Deconvolution
* Microscopy D. Sage, L. Donati, F. Soulez, D. Fortun, G. Schmit, A. Seitz,
* R. Guiet, C. Vonesch, M Unser, Methods of Elsevier, 2017.
*/
/*
* Copyright 2010-2017 Biomedical Imaging Group at the EPFL.
*
* This file is part of DeconvolutionLab2 (DL2).
*
* DL2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* DL2 is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* DL2. If not, see <http://www.gnu.org/licenses/>.
*/
package deconvolutionlab.modules;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import javax.swing.JComboBox;
import javax.swing.JPanel;
+import javax.swing.JTextField;
import deconvolution.Command;
import deconvolution.Token;
import deconvolutionlab.Config;
import lab.component.HTMLPane;
public class LanguageModule extends AbstractModule implements ActionListener {
private HTMLPane language;
private JComboBox<String> cmb;
private JComboBox<String> gui;
+ private JTextField txt;
public LanguageModule(boolean expanded) {
super("Language", "", "", "", expanded);
}
@Override
public JPanel buildExpandedPanel() {
language = new HTMLPane("Monaco", 100, 100);
cmb = new JComboBox<String>(new String[] { "Command line", "ImageJ Macro", "Java", "Matlab" });
gui = new JComboBox<String>(new String[] { "Run (Headless)", "Launch (with control panel)" });
+ txt = new JTextField("Job", 8);
JPanel pn = new JPanel(new FlowLayout());
+ pn.add(txt);
pn.add(cmb);
pn.add(gui);
JPanel panel = new JPanel(new BorderLayout());
panel.add(pn, BorderLayout.NORTH);
panel.add(language.getPane(), BorderLayout.CENTER);
cmb.addActionListener(this);
gui.addActionListener(this);
Config.register(getName(), "language", cmb, cmb.getItemAt(0));
Config.register(getName(), "headless", gui, gui.getItemAt(0));
+ Config.register(getName(), "job", txt, "Job");
language.clear();
return panel;
}
@Override
public void expand() {
super.expand();
update();
}
public void update() {
if (cmb.getSelectedIndex() == 0) {
language.clear();
String mode = "java -jar DeconvolutionLab_2.jar ";
if (gui.getSelectedIndex() == 0)
mode += " Run ";
else
mode += " Launch ";
language.append("p", mode + Command.command());
}
else if (cmb.getSelectedIndex() == 1) {
language.clear();
language.append("p", imagej(gui.getSelectedIndex() == 0));
}
else if (cmb.getSelectedIndex() == 2) {
language.clear();
- String text = "Java code, not yet implemented";
- language.append("p", text);
+ language.append("p", java(gui.getSelectedIndex() == 0));
}
else if (cmb.getSelectedIndex() == 3) {
language.clear();
String text = "Matlab code, not yet implemented";
language.append("p", text);
}
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
if (e.getSource() == cmb)
update();
if (e.getSource() == gui)
update();
}
@Override
public void close() {
}
@Override
public void setCommand(String command) {
update();
}
@Override
public String getCommand() {
return "";
}
private String imagej(boolean headless) {
- String macro = "<p>// Macro generated by DeconvolutionLab2 </p>";
+ String job = txt.getText();
+ String macro = "<p>// Job: " + job + " </p>";
+ macro += "<p>// Macro generated by DeconvolutionLab2 </p>";
macro += "<p>// " + new SimpleDateFormat("dd/MM/yy HH:m:s").format(new Date()) + " </p>";
String param = "<p>parameters = \"\"</p>";
ArrayList<Token> tokens = Command.parse(Command.command());
String image = "image = \" NOT DEFINED \" ";
String psf = "psf = \" NOT DEFINED \" ";
String algo = "algo = \" NOT DEFINED \" ";
for (Token token : tokens) {
if (token.keyword.equals("-image"))
image = "<p>image = \" -image " + token.parameters.trim() + "\" </p>";
else if (token.keyword.equals("-psf"))
psf = "<p>psf = \" -psf " + token.parameters.trim() + "\" </p>";
else if (token.keyword.equals("-algorithm"))
algo = "<p>algorithm = \" -algorithm " + token.parameters.trim() + "\" </p>";
else
param += "<p>parameters += \" " + token.keyword + " " + token.parameters.trim() + "\" </p>";
}
String option = macro + image + psf + algo + param;
String cmd = "";
if (headless)
cmd = "<p>run(\"DeconvolutionLab2 Run\", image + psf + algorithm + parameters)</p>";
else
cmd = "<p>run(\"DeconvolutionLab2 Launch\", image + psf + algorithm + parameters)</p>";
return option + cmd;
}
+
+
+ private String java(boolean headless) {
+ String job = txt.getText();
+ String p = headless ? ".deconvolve(false);" : ".launch(\"" + job + "\", false);";
+ String tab1 = "<p style=\"padding-left:10px\">";
+ String tab2 = "<p style=\"padding-left:20px\">";
+ String code = "";
+ code += "<p>import deconvolution.Deconvolution;</p>";
+ code += "<p>import ij.plugin.PlugIn;</p>";
+ code += "<p></p>";
+
+ code += "<p>public class DeconvolutionLab2_" + job + " implements PlugIn {</p>";
+ code += tab1 + "public DeconvolutionLab2_" + job + "() {</p>";
+
+ String param = tab2 + "String parameters = \"\";</p>";
+ ArrayList<Token> tokens = Command.parse(Command.command());
+ String image = tab2 + "String image = \" NOT DEFINED \";";
+ String psf = tab2 + "String psf = \" NOT DEFINED \";";
+ String algo = tab2 + "String algo = \" NOT DEFINED \";";
+ for (Token token : tokens) {
+ if (token.keyword.equals("-image"))
+ image = tab2 + "String image = \" -image " + token.parameters.trim() + "\";</p>";
+ else if (token.keyword.equals("-psf"))
+ psf = tab2 + "String psf = \" -psf " + token.parameters.trim() + "\";</p>";
+ else if (token.keyword.equals("-algorithm"))
+ algo = tab2 + "String algorithm = \" -algorithm " + token.parameters.trim() + "\";</p>";
+ else
+ param += tab2 + "parameters += \" " + token.keyword + " " + token.parameters.trim() + "\";</p>";
+ }
+ code += image + psf + algo + param;
+ code += tab2 + "new Deconvolution(image + psf + algorithm + parameters)" + p;
+ code += tab1 + "}</p>";
+
+ code += tab1 + "<p></p>";
+
+ code += tab1 + "@Override</p>";
+ code += tab1 + "public void run(String arg0) {</p>";
+ code += tab2 + " new DeconvolutionLab2_" + job + "();</p>";
+
+ code += tab1 + "}</p>";
+ code += "<p>}</p>";
+ return code;
+ }
}
diff --git a/DeconvolutionLab2/src/imagej/IJImager.java b/DeconvolutionLab2/src/imagej/IJImager.java
index ac671b5..f60c2eb 100644
--- a/DeconvolutionLab2/src/imagej/IJImager.java
+++ b/DeconvolutionLab2/src/imagej/IJImager.java
@@ -1,221 +1,218 @@
/*
* 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 imagej;
import java.util.HashMap;
import deconvolutionlab.PlatformImager;
+import deconvolutionlab.PlatformImager.ContainerImage;
import ij.ImagePlus;
import ij.ImageStack;
import ij.WindowManager;
import ij.io.FileSaver;
import ij.io.Opener;
import ij.process.FloatProcessor;
import ij.process.ImageProcessor;
import signal.ComplexComponent;
import signal.ComplexSignal;
import signal.RealSignal;
public class IJImager extends PlatformImager {
- private static HashMap<String, ImagePlus> images = new HashMap<String, ImagePlus>();
- private static HashMap<String, ImageStack> stacks = new HashMap<String, ImageStack>();
-
public static RealSignal create(ImagePlus imp) {
int nx = imp.getWidth();
int ny = imp.getHeight();
int nz = imp.getStackSize();
RealSignal signal = new RealSignal(nx, ny, nz);
for (int k = 0; k < nz; k++) {
ImageProcessor ip = imp.getStack().getProcessor(k + 1).convertToFloat();
signal.setXY(k, (float[]) ip.getPixels());
}
return signal;
}
@Override
public RealSignal create() {
return build(WindowManager.getCurrentImage());
}
@Override
public RealSignal create(String name) {
ImagePlus imp = WindowManager.getImage(name);
if (imp == null)
imp = WindowManager.getCurrentImage();
return build(imp);
}
@Override
public RealSignal open(String filename) {
Opener opener = new Opener();
ImagePlus imp = opener.openImage(filename);
return build(imp);
}
@Override
public void show(RealSignal signal, String title) {
show(signal, title, PlatformImager.Type.FLOAT);
}
@Override
public void show(RealSignal signal, String title, PlatformImager.Type type) {
show(signal, title, type, signal.nz / 2);
}
@Override
public void show(RealSignal signal, String title, PlatformImager.Type type, int z) {
ImagePlus imp = build(signal, type);
if (imp != null) {
imp.setTitle(title);
int nz = imp.getStackSize();
imp.show();
imp.setSlice(Math.max(1, Math.min(nz, z)));
imp.getProcessor().resetMinAndMax();
}
}
+ public ContainerImage createContainer(String title) {
+ return new ContainerImage();
+ }
+
@Override
- public void appendShowLive(String key, RealSignal signal, String title) {
- appendShowLive(key, signal, title, PlatformImager.Type.FLOAT);
+ public void append(ContainerImage container, RealSignal signal, String title) {
+ append(container, signal, title, PlatformImager.Type.FLOAT);
}
@Override
- public void appendShowLive(String key, RealSignal signal, String title, PlatformImager.Type type) {
- ImagePlus imp = build(signal, type);
- ImagePlus image = images.get(key);
- ImageStack stack = stacks.get(key);
- if (image == null || stack == null) {
- stack = new ImageStack(signal.nx, signal.ny);
- stack.addSlice(imp.getProcessor());
- image = new ImagePlus(key, stack);
- image.show();
- images.put(key, image);
- stacks.put(key, stack);
+ public void append(ContainerImage container, RealSignal signal, String title, PlatformImager.Type type) { ImagePlus cont = (ImagePlus) container.object;
+ if (container.object == null) {
+ ImageStack stack = new ImageStack(signal.nx, signal.ny);
+ stack.addSlice(build(signal, type).getProcessor());
+ stack.addSlice(build(signal, type).getProcessor());
+ container.object = new ImagePlus(title, stack);
+ ((ImagePlus)container.object).show();
}
else {
- stack.addSlice(imp.getProcessor());
- image.setStack(stack);
+ cont.getStack().addSlice(build(signal, type).getProcessor());
+ cont.setSlice(cont.getStack().getSize());
+ cont.updateAndDraw();
+ cont.getProcessor().resetMinAndMax();
}
- image.updateAndDraw();
- image.setSlice(image.getStack().getSize());
- image.getProcessor().resetMinAndMax();
}
@Override
public void save(RealSignal signal, String filename) {
save(signal, filename, PlatformImager.Type.FLOAT);
}
@Override
public void save(RealSignal signal, String filename, PlatformImager.Type type) {
ImagePlus imp = build(signal, type);
if (imp != null) {
if (imp.getStackSize() == 1) {
new FileSaver(imp).saveAsTiff(filename);
}
else {
new FileSaver(imp).saveAsTiffStack(filename);
}
}
}
@Override
public void show(ComplexSignal signal, String title) {
show(signal, title, ComplexComponent.MODULE);
}
@Override
public void show(ComplexSignal signal, String title, ComplexComponent complex) {
ImageStack stack = new ImageStack(signal.nx, signal.ny);
for (int k = 0; k < signal.nz; k++) {
float[] plane = null;
switch (complex) {
case REAL:
plane = signal.getRealXY(k);
break;
case IMAGINARY:
plane = signal.getImagXY(k);
break;
case MODULE:
plane = signal.getModuleXY(k);
break;
default:
plane = signal.getModuleXY_dB(k);
}
stack.addSlice(new FloatProcessor(signal.nx, signal.ny, plane));
}
new ImagePlus(title, stack).show();
}
private RealSignal build(ImagePlus imp) {
if (imp == null)
return null;
int nx = imp.getWidth();
int ny = imp.getHeight();
int nz = imp.getStackSize();
RealSignal signal = new RealSignal(nx, ny, nz);
for (int k = 0; k < nz; k++) {
ImageProcessor ip = imp.getStack().getProcessor(k + 1).convertToFloat();
signal.setXY(k, (float[]) ip.getPixels());
}
return signal;
}
private ImagePlus build(RealSignal signal, PlatformImager.Type type) {
if (signal == null)
return null;
ImageStack stack = new ImageStack(signal.nx, signal.ny);
for (int k = 0; k < signal.nz; k++) {
ImageProcessor ip = new FloatProcessor(signal.nx, signal.ny, signal.getXY(k));
switch (type) {
case BYTE:
stack.addSlice(ip.convertToByteProcessor(false));
break;
case SHORT:
stack.addSlice(ip.convertToShortProcessor(false));
break;
case FLOAT:
stack.addSlice(ip);
default:
break;
}
}
return new ImagePlus("", stack);
}
@Override
public String getName() {
return "ImageJ";
}
}
diff --git a/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/IcyImager.java b/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/IcyImager.java
index 90064b6..db2a17c 100644
--- a/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/IcyImager.java
+++ b/DeconvolutionLab2/src/plugins/sage/deconvolutionlab/IcyImager.java
@@ -1,204 +1,210 @@
/*
* 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 icy.file.Saver;
import icy.image.IcyBufferedImage;
import icy.imagej.ImageJUtil;
import icy.main.Icy;
import icy.sequence.Sequence;
import icy.type.DataType;
import icy.type.collection.array.Array1DUtil;
import ij.ImagePlus;
import ij.io.Opener;
import java.io.File;
import java.util.ArrayList;
import signal.ComplexComponent;
import signal.ComplexSignal;
import signal.RealSignal;
import deconvolutionlab.PlatformImager;
import deconvolutionlab.monitor.Monitors;
public class IcyImager extends PlatformImager {
public static RealSignal create(Sequence seq) {
int nx = seq.getSizeX();
int ny = seq.getSizeY();
int nz = seq.getSizeZ();
RealSignal signal = new RealSignal(nx, ny, nz);
for (int k = 0; k < nz; k++) {
float pixels[] = new float[nx * ny];
Array1DUtil.arrayToFloatArray(seq.getDataXY(0, k, 0), pixels, seq.isSignedDataType());
signal.setXY(k, pixels);
}
return signal;
}
@Override
public RealSignal create() {
return build(Icy.getMainInterface().getActiveSequence());
}
@Override
public RealSignal create(String name) {
ArrayList<Sequence> sequences = Icy.getMainInterface().getSequences(name);
for(Sequence sequence : sequences)
if (sequence.getName().equals(name))
return build(sequence);
return null;
}
@Override
public RealSignal open(String filename) {
//File file = new File(filename);
//return build(Loader.loadSequence(file, 0, false));
Opener opener = new Opener();
ImagePlus imp = opener.openImage(filename);
Sequence seq = ImageJUtil.convertToIcySequence(imp, null);
return build(seq);
}
@Override
public void show(RealSignal signal, String title) {
show(signal, title, PlatformImager.Type.FLOAT);
}
@Override
public void show(RealSignal signal, String title, PlatformImager.Type type) {
Sequence sequence = build(signal, type);
Icy.getMainInterface().addSequence(sequence);
}
@Override
public void show(ComplexSignal signal, String title, ComplexComponent complex) {
Sequence sequence = new Sequence();
for (int k = 0; k < signal.nz; k++) {
float[] plane = null;
switch(complex) {
case REAL: plane = signal.getRealXY(k); break;
case IMAGINARY: plane = signal.getImagXY(k); break;
case MODULE: plane = signal.getModuleXY(k); break;
default: plane = signal.getModuleXY_dB(k);
}
IcyBufferedImage image = new IcyBufferedImage(signal.nx, signal.ny, 1, DataType.FLOAT);
Array1DUtil.floatArrayToSafeArray(plane, image.getDataXY(0), image.isSignedDataType());
image.dataChanged();
sequence.setImage(0, k, image);
}
sequence.setName(title);
Icy.getMainInterface().addSequence(sequence);
}
@Override
public void save(RealSignal signal, String filename) {
save(signal, filename, PlatformImager.Type.FLOAT);
}
@Override
public void save(RealSignal signal, String filename, PlatformImager.Type type) {
Sequence sequence = build(signal, type);
File file = new File(filename);
Saver.save(sequence, file, false, true);
}
private RealSignal build(Sequence sequence) {
int nx = sequence.getSizeX();
int ny = sequence.getSizeY();
int nz = sequence.getSizeZ();
RealSignal signal = new RealSignal(nx, ny, nz);
for (int k = 0; k < nz; k++) {
float pixels[] = new float[nx * ny];
Array1DUtil.arrayToFloatArray(sequence.getDataXY(0, k, 0), pixels, sequence.isSignedDataType());
signal.setXY(k, pixels);
}
return signal;
}
private Sequence build(RealSignal signal, PlatformImager.Type type) {
Sequence sequence = new Sequence();
for (int k = 0; k < signal.nz; k++) {
float[] plane = signal.getXY(k);
IcyBufferedImage image = null;
switch(type) {
case BYTE:
byte[] b = Array1DUtil.arrayToByteArray(plane);
image = new IcyBufferedImage(signal.nx, signal.ny, 1, DataType.BYTE);
Array1DUtil.byteArrayToArray(b, image.getDataXY(0), image.isSignedDataType());
break;
case SHORT:
short[] s = Array1DUtil.arrayToShortArray(plane, false);
image = new IcyBufferedImage(signal.nx, signal.ny, 1, DataType.SHORT);
Array1DUtil.shortArrayToArray(s, image.getDataXY(0), image.isSignedDataType());
break;
default:
image = new IcyBufferedImage(signal.nx, signal.ny, 1, DataType.FLOAT);
Array1DUtil.floatArrayToArray(signal.data[k], image.getDataXY(0));
break;
}
image.dataChanged();
sequence.setImage(0, k, image);
}
return sequence;
}
@Override
public String getName() {
return "Icy";
}
@Override
- public void appendShowLive(String key, RealSignal signal, String title) {
- // TODO Auto-generated method stub
-
+ public void show(RealSignal signal, String title, Type type, int z) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void show(ComplexSignal signal, String title) {
+ // TODO Auto-generated method stub
}
@Override
- public void appendShowLive(String key, RealSignal signal, String title, Type type) {
+ public ContainerImage createContainer(String title) {
// TODO Auto-generated method stub
-
+ return null;
}
@Override
- public void show(RealSignal signal, String title, Type type, int z) {
- // TODO Auto-generated method stub
+ public void append(ContainerImage container, RealSignal signal, String title) {
+ // TODO Auto-generated method stub
+
}
-
+
@Override
- public void show(ComplexSignal signal, String title) {
- // TODO Auto-generated method stub
+ public void append(ContainerImage container, RealSignal signal, String title, Type type) {
+ // TODO Auto-generated method stub
+
}
}
diff --git a/DeconvolutionLab2/src/signal/factory/MotionBlur.java b/DeconvolutionLab2/src/signal/factory/MotionBlur.java
new file mode 100644
index 0000000..59a0bbf
--- /dev/null
+++ b/DeconvolutionLab2/src/signal/factory/MotionBlur.java
@@ -0,0 +1,89 @@
+/*
+ * 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.factory;
+
+import signal.RealSignal;
+
+public class MotionBlur extends SignalFactory {
+
+ private double sigma = 3.0;
+ private double direction = 30.0;
+ private double elongation = 3.0;
+
+ public MotionBlur(double sigma, double direction, double elongation) {
+ super(new double[] {sigma, direction, elongation});
+ }
+
+ @Override
+ public String getName() {
+ return "MotionBlur";
+ }
+
+ @Override
+ public String[] getParametersName() {
+ return new String[] {"Sigma", "Direction", "Elongation"};
+ }
+
+ @Override
+ public void setParameters(double[] parameters) {
+ if (parameters.length >= 1)
+ this.sigma = parameters[0];
+ if (parameters.length >= 2)
+ this.direction = parameters[1];
+ if (parameters.length >= 3)
+ this.elongation = parameters[2];
+ }
+
+ @Override
+ public double[] getParameters() {
+ return new double[] {sigma, direction, elongation};
+ }
+
+ @Override
+ public void fill(RealSignal signal) {
+ double K1 = 0.5 / (sigma*sigma);
+ double K2 = 0.5 / (sigma*sigma*elongation*elongation);
+ double cosa = Math.cos(Math.toRadians(direction));
+ double sina = Math.sin(Math.toRadians(direction));
+ for(int x=0; x<nx; x++)
+ for(int y=0; y<ny; y++) {
+ double dx = (x-xc);
+ double dy = (y-yc);
+ //double ps = (1.0 + (dx*cosa + dy*sina)/(dx*dx + dy*dy)) * 0.5;
+ double K = K1 + dx * K2 /(dx*dx + dy*dy);
+ double r2 = (x-xc)*(x-xc) + (y-yc)*(y-yc);
+ for(int z=0; z<nz; z++) {
+ signal.data[z][x+nx*y] = (float)((amplitude-background) * Math.exp(-r2*K) + background);
+ }
+ }
+ }
+}
diff --git a/DeconvolutionLab2/src/signal/factory/SignalFactory.java b/DeconvolutionLab2/src/signal/factory/SignalFactory.java
index 1935fbd..b9aee46 100644
--- a/DeconvolutionLab2/src/signal/factory/SignalFactory.java
+++ b/DeconvolutionLab2/src/signal/factory/SignalFactory.java
@@ -1,211 +1,213 @@
/*
* 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.factory;
import java.util.ArrayList;
import javax.swing.SwingWorker;
import deconvolutionlab.monitor.Monitors;
import signal.RealSignal;
public abstract class SignalFactory {
protected double fractXC = 0.5;
protected double fractYC = 0.5;
protected double fractZC = 0.5;
protected double background = 0.0;
protected double amplitude = 1.0;
protected double xc;
protected double yc;
protected double zc;
protected int nx;
protected int ny;
protected int nz;
public SignalFactory() {
}
public SignalFactory(double[] parameters) {
setParameters(parameters);
}
public static SignalFactory get(String name) {
ArrayList<SignalFactory> list = getAll();
for (SignalFactory factory : list) {
if (factory.getName().equals(name))
return factory;
}
return null;
}
public static ArrayList<String> getAllName() {
ArrayList<String> list = new ArrayList<String>();
for (SignalFactory factory : getAll()) {
list.add(factory.getName());
}
return list;
}
public static ArrayList<SignalFactory> getAll() {
ArrayList<SignalFactory> list = new ArrayList<SignalFactory>();
list.add(new Airy(1));
list.add(new Astigmatism(3, 0.2));
list.add(new Constant());
list.add(new Cross(1, 1, 30));
list.add(new Cube(10 ,1));
list.add(new Defocus(3, 10, 10));
list.add(new DoG(3, 4));
list.add(new DoubleHelix(3, 10, 10));
list.add(new Gaussian(3, 3, 3));
list.add(new GridSpots(3, 1, 10));
list.add(new Impulse());
+ list.add(new MotionBlur(3, 30, 3));
list.add(new Ramp(1, 0, 0));
list.add(new RandomLines(3));
list.add(new Sinc(3, 3, 3));
list.add(new Sphere(10, 1));
list.add(new Torus(10));
return list;
}
public static ArrayList<SignalFactory> getImages() {
ArrayList<SignalFactory> list = new ArrayList<SignalFactory>();
list.add(new Cube(10, 1));
list.add(new Sphere(10, 1));
list.add(new GridSpots(3, 1, 10));
list.add(new Constant());
list.add(new Cross(1, 1, 30));
list.add(new DoG(3, 4));
list.add(new Gaussian(3, 3, 3));
list.add(new Impulse());
list.add(new Ramp(1, 0, 0));
list.add(new RandomLines(3));
list.add(new Torus(10));
return list;
}
public static ArrayList<SignalFactory> getPSF() {
ArrayList<SignalFactory> list = new ArrayList<SignalFactory>();
list.add(new Airy(1));
list.add(new Astigmatism(3, 0.2));
list.add(new Cross(3, 1, 10));
list.add(new Cube(10, 1));
list.add(new Defocus(3, 10, 10));
list.add(new DoG(3, 4));
list.add(new DoubleHelix(3, 10, 10));
list.add(new Gaussian(3, 3, 3));
+ list.add(new MotionBlur(3, 30, 3));
list.add(new Impulse());
list.add(new Sinc(3, 3, 3));
list.add(new Sphere(10, 1));
list.add(new RandomLines(3));
list.add(new Torus(10));
return list;
}
public static SignalFactory getFactoryByName(String name) {
ArrayList<SignalFactory> list = getAll();
for (SignalFactory factory : list)
if (name.toLowerCase().equals(factory.getName().toLowerCase())) {
return factory;
}
return null;
}
public SignalFactory center(double fractXC, double fractYC, double fractZC) {
this.fractXC = fractXC;
this.fractYC = fractYC;
this.fractZC = fractZC;
return this;
}
public SignalFactory intensity(double background, double amplitude) {
this.background = background;
this.amplitude = amplitude;
return this;
}
public String params() {
String name[] = getParametersName();
double params[] = getParameters();
if (params.length == 1)
return name[0] + "=" + params[0];
else if (params.length == 2)
return name[0] + "=" + params[0] + " " + name[1] + "=" + params[1];
else
return name[0] + "=" + params[0] + " " + name[1] + "=" + params[2] + " " + name[2] + "=" + params[2];
}
public RealSignal generate(int nx, int ny, int nz) {
this.nx = nx;
this.ny = ny;
this.nz = nz;
xc = fractXC * nx;
yc = fractYC * ny;
zc = fractZC * nz;
RealSignal signal = new RealSignal(nx, ny, nz);
fill(signal);
return signal;
}
public abstract String getName();
public abstract void setParameters(double[] parameters);
public abstract double[] getParameters();
public abstract String[] getParametersName();
public abstract void fill(RealSignal signal);
public class Worker extends SwingWorker<RealSignal, String> {
private RealSignal signal;
public boolean done=false;
public Worker(RealSignal signal) {
this.signal = signal;
done = false;
}
protected RealSignal doInBackground() throws Exception {
fill(signal);
done = true;
return signal;
}
protected void done() {
System.out.println("Done");
done = true;
}
}
}

Event Timeline