From 678e28dccd29f3067f9252420568ecdb1c938857 Mon Sep 17 00:00:00 2001
From: Jan Hansen <27991883+hansenjn@users.noreply.github.com>
Date: Tue, 30 Jul 2024 15:29:21 -0700
Subject: [PATCH] Improving headless mode - 3D Analyzer - #3 - avoid
ProgressDialog
Avoid ProgressDialog entirely in noGUIs (headless) macro mode.
---
3D Analyzer/pom.xml | 2 +-
.../src/main/java/motiQ3D/MotiQ_3D.java | 75 +++++++++++--------
.../main/java/motiQ3D/TimelapseParticle.java | 48 ++++++------
3D Analyzer/src/main/resources/plugins.config | 4 +-
4 files changed, 70 insertions(+), 59 deletions(-)
diff --git a/3D Analyzer/pom.xml b/3D Analyzer/pom.xml
index 68002a1..0297182 100644
--- a/3D Analyzer/pom.xml
+++ b/3D Analyzer/pom.xml
@@ -11,7 +11,7 @@
MotiQ_3D
JNH
- 0.3.2-SNAPSHOT
+ 0.3.3-SNAPSHOT
MotiQ 3D Analyzer
diff --git a/3D Analyzer/src/main/java/motiQ3D/MotiQ_3D.java b/3D Analyzer/src/main/java/motiQ3D/MotiQ_3D.java
index e7e8f07..d9f6185 100644
--- a/3D Analyzer/src/main/java/motiQ3D/MotiQ_3D.java
+++ b/3D Analyzer/src/main/java/motiQ3D/MotiQ_3D.java
@@ -4,7 +4,7 @@
*
* Copyright (C) 2014-2024 Jan N. Hansen
* First version: July 28, 2014
- * This Version: July 29, 2024
+ * This Version: July 30, 2024
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -43,7 +43,7 @@
public class MotiQ_3D implements PlugIn, Measurements{
//Name variables
static final String PLUGINNAME = "MotiQ 3D Analyzer";
- static final String PLUGINVERSION = "v0.3.2";
+ static final String PLUGINVERSION = "v0.3.3";
DecimalFormat dformat6 = new DecimalFormat("#0.000000");
DecimalFormat dformat3 = new DecimalFormat("#0.000");
@@ -313,6 +313,7 @@ record = true;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
GenericDialog gd = new GenericDialog(PLUGINNAME + " - settings");
+ gd.addHelp("https://github.com/hansenjn/MotiQ/wiki");
//show Dialog-----------------------------------------------------------------
// gd.setInsets(0,0,0); (top, left, bottom)
gd.setInsets(0,0,0); gd.addMessage(PLUGINNAME + ", version " + PLUGINVERSION
@@ -534,8 +535,8 @@ public void windowClosing(WindowEvent winEvt) {
}
//add progressDialog
- progress = new ProgressDialog(name, tasks, noGUIs);
if(!noGUIs) {
+ progress = new ProgressDialog(name, tasks, noGUIs);
progress.setLocation(0,0);
progress.setVisible(true);
progress.addWindowListener(new java.awt.event.WindowAdapter() {
@@ -565,17 +566,21 @@ public void windowClosing(WindowEvent winEvt) {
break continueAll;
}
Date startDate = new Date();
- progress.updateBarText(" in progress...");
+ if(!noGUIs) progress.updateBarText(" in progress...");
running: while(true){
//Check for problems with image file
if(name[task].substring(name[task].lastIndexOf("."),name[task].length()).equals(".txt")){
- progress.notifyMessage("Task " + (task+1) + "/" + tasks + ": File is no image! Could not be processed!",ProgressDialog.ERROR);
- progress.moveTask(task);
+ if(!noGUIs) {
+ progress.notifyMessage("Task " + (task+1) + "/" + tasks + ": File is no image! Could not be processed!",ProgressDialog.ERROR);
+ progress.moveTask(task);
+ }
break running;
}
if(name[task].substring(name[task].lastIndexOf("."),name[task].length()).equals(".zip")){
- progress.notifyMessage("Task " + (task+1) + "/" + tasks + ": File is no image! Could not be processed!",ProgressDialog.ERROR);
- progress.moveTask(task);
+ if(!noGUIs) {
+ progress.notifyMessage("Task " + (task+1) + "/" + tasks + ": File is no image! Could not be processed!",ProgressDialog.ERROR);
+ progress.moveTask(task);
+ }
break running;
}
//Check for problems with image file
@@ -594,8 +599,10 @@ public void windowClosing(WindowEvent winEvt) {
imp.deleteRoi();
}
}catch (Exception e) {
- progress.notifyMessage("Task " + (task+1) + "/" + tasks + ": file is no image - could not be processed!",ProgressDialog.ERROR);
- progress.moveTask(task);
+ if(!noGUIs) {
+ progress.notifyMessage("Task " + (task+1) + "/" + tasks + ": file is no image - could not be processed!",ProgressDialog.ERROR);
+ progress.moveTask(task);
+ }
break running;
}
@@ -678,7 +685,7 @@ public void windowClosing(WindowEvent winEvt) {
cal.fps = fps;
timeUnit = calTimeUnit;
}else{
- progress.notifyMessage("Task " + (task+1) + "/" + tasks + ": recalibration failed! Metadata calibration is used instead!!",ProgressDialog.ERROR);
+ if(!noGUIs) progress.notifyMessage("Task " + (task+1) + "/" + tasks + ": recalibration failed! Metadata calibration is used instead!!",ProgressDialog.ERROR);
}
}
//Calibrate
@@ -845,8 +852,10 @@ public void windowClosing(WindowEvent winEvt) {
floodNodes[index][3] = floodNodeT;
}
if(processedPxCount%(pxCount100) points, Calibration cal, double projectedFrames, boolean skeletonize,
- //double gaussSigmaXY, double gaussSigmaZ, int orWidth, int orHeight, int orSlices, int orTimes, boolean minimizeImages,
- //boolean binarizeBeforeSkeletonization, ProgressDialog progress)
particleCollection.add(new TimelapseParticle(pointCollection, cal, totalGroupSize, skeletonize,
gSigmaXY, gSigmaZ, width, height, slices, frames, true,
- binarizeBeforeSkl, progress));
+ binarizeBeforeSkl, progress, noGUIs));
}
}
}
@@ -1112,7 +1121,7 @@ public void windowClosing(WindowEvent winEvt) {
}
//Filter particles
- progress.setBar(0.8);
+ if(!noGUIs) progress.setBar(0.8);
/***************************************************************************
*#########################################################################*
@@ -1135,7 +1144,7 @@ public void windowClosing(WindowEvent winEvt) {
try{
new File(dir [task] + filePrefix).mkdirs();
}catch(Exception e){
- progress.notifyMessage("failed to create subfolder to save additional plots! Will save plots into origianl folder!",ProgressDialog.NOTIFICATION);
+ if(!noGUIs) progress.notifyMessage("failed to create subfolder to save additional plots! Will save plots into origianl folder!",ProgressDialog.NOTIFICATION);
}
String RPSuffix = "_RP" + dformat0.format(minParticleVolume);
@@ -1602,7 +1611,7 @@ public void windowClosing(WindowEvent winEvt) {
}
}
}catch(Exception e){
- progress.notifyMessage("Task " + task + "/" + tasks + ": error - could not correctly write results...",ProgressDialog.ERROR);
+ if(!noGUIs) progress.notifyMessage("Task " + task + "/" + tasks + ": error - could not correctly write results...",ProgressDialog.ERROR);
}
tw1.append("");
}
@@ -1640,7 +1649,7 @@ public void windowClosing(WindowEvent winEvt) {
v3D = new Visualizer3D(imp, 3.0f);
v3D.setAngle(10.0f, -10.0f, 0.0f);
- progress.updateBarText("generating visualizations...");
+ if(!noGUIs) progress.updateBarText("generating visualizations...");
if(mergeSelection.equals(mergeOrNotMerge[0])){
IJ.saveAs(allParticles.particleImp, "tif", subfolderPrefix + RPSuffix + ".tif");
IJ.saveAs(allParticles.convexHullImp, "tif", subfolderPrefix + "_H.tif");
@@ -1654,7 +1663,7 @@ public void windowClosing(WindowEvent winEvt) {
for(int err = 0; err < e.getStackTrace().length; err++){
out += " \n " + e.getStackTrace()[err].toString();
}
- progress.notifyMessage("Task " + (task+1) + "/" + tasks + ": No 3D visualization generated - an error occured: " + out,ProgressDialog.NOTIFICATION);
+ if(!noGUIs) progress.notifyMessage("Task " + (task+1) + "/" + tasks + ": No 3D visualization generated - an error occured: " + out,ProgressDialog.NOTIFICATION);
}
allParticles.closeImps();
}else if(mergeSelection.equals(mergeOrNotMerge[1])){
@@ -1671,21 +1680,23 @@ public void windowClosing(WindowEvent winEvt) {
for(int err = 0; err < e.getStackTrace().length; err++){
out += " \n " + e.getStackTrace()[err].toString();
}
- progress.notifyMessage("Task " + (task+1) + "/" + tasks + ": An error occured when generating a 3D visualization - the analysis and all other output files than the missing 3D file are however unaffected and valid!"
+ if(!noGUIs) progress.notifyMessage("Task " + (task+1) + "/" + tasks + ": An error occured when generating a 3D visualization - the analysis and all other output files than the missing 3D file are however unaffected and valid!"
+ " Debuggin information: " + out + "",ProgressDialog.NOTIFICATION);
}
particleCollection.get(i).closeImps();
}
}
- progress.setBar(0.9);
+ if(!noGUIs) progress.setBar(0.9);
//Save Images
//Save results text files
//Update Multi-Task-Manager
- progress.setBar(1.0);
- progress.moveTask(task);
+ if(!noGUIs) {
+ progress.setBar(1.0);
+ progress.moveTask(task);
+ }
break running;
}
}
diff --git a/3D Analyzer/src/main/java/motiQ3D/TimelapseParticle.java b/3D Analyzer/src/main/java/motiQ3D/TimelapseParticle.java
index 43a2a47..d76ff1c 100644
--- a/3D Analyzer/src/main/java/motiQ3D/TimelapseParticle.java
+++ b/3D Analyzer/src/main/java/motiQ3D/TimelapseParticle.java
@@ -4,7 +4,7 @@
*
* Copyright (C) 2014-2023 Jan N. Hansen
* First version: July 28, 2014
- * This Version: April 15, 2019
+ * This Version: July 30, 2024
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -191,9 +191,9 @@ public class TimelapseParticle{
public TimelapseParticle(){}
public TimelapseParticle(ArrayList points, Calibration cal, double projectedFrames, boolean skeletonize, double gaussSigmaXY, double gaussSigmaZ,
- int orWidth, int orHeight, int orSlices, int orTimes, boolean minimizeImages, boolean binarizeBeforeSkeletonization, ProgressDialog progressDialog){
+ int orWidth, int orHeight, int orSlices, int orTimes, boolean minimizeImages, boolean binarizeBeforeSkeletonization, ProgressDialog progressDialog, boolean noGUIs){
// SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
-// progressDialog.notifyMessage("Started particle generation " + df.format(new Date()),ProgressDialog.NOTIFICATION);
+// if(!noGUIs) progressDialog.notifyMessage("Started particle generation " + df.format(new Date()),ProgressDialog.NOTIFICATION);
final double calibration = cal.pixelWidth;
final double voxelDepth = cal.pixelDepth;
@@ -237,7 +237,7 @@ public TimelapseParticle(ArrayList points, Calibration cal, double proj
height = 1+yMax-yMin;
data = new double [width][height][slices][times];
-// progressDialog.notifyMessage("Step 1 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
+// if(!noGUIs) progressDialog.notifyMessage("Step 1 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
//Determine static variables
double maxIntensity = 0.0, maxPossibIntensity = 0.0;
@@ -308,7 +308,7 @@ public TimelapseParticle(ArrayList points, Calibration cal, double proj
}
}
-// progressDialog.notifyMessage("Step static 1 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
+// if(!noGUIs) progressDialog.notifyMessage("Step static 1 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
int xCal, yCal, zCal, tCal;
for(int i = 0; i < nPoints; i++){
@@ -345,7 +345,7 @@ public TimelapseParticle(ArrayList points, Calibration cal, double proj
volume [tCal] += vxVolume;
}
-// progressDialog.notifyMessage("Step static 2 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
+// if(!noGUIs) progressDialog.notifyMessage("Step static 2 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
for(int t = 0; t < times; t++){
averageIntensity [t] /= (volume [t] / vxVolume);
@@ -384,7 +384,7 @@ public TimelapseParticle(ArrayList points, Calibration cal, double proj
surface [tCal] += transientSurface;
}
-// progressDialog.notifyMessage("Step static 3 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
+// if(!noGUIs) progressDialog.notifyMessage("Step static 3 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
double transientRadius;
for(int t = 0; t < times; t++){
@@ -410,7 +410,7 @@ public TimelapseParticle(ArrayList points, Calibration cal, double proj
RI [t] = surface [t] / (Math.PI * Math.pow(transientRadius,2) * 4); //RI
}
-// progressDialog.notifyMessage("Step static 4 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
+// if(!noGUIs) progressDialog.notifyMessage("Step static 4 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
{
//convex hull calculation
@@ -431,7 +431,7 @@ public TimelapseParticle(ArrayList points, Calibration cal, double proj
}
//calculate hull
- transHullData = getConv3DHull(transHullData, progressDialog);
+ transHullData = getConv3DHull(transHullData, progressDialog, noGUIs);
for(int z = 0; z < slices; z++){
for(int x = 0; x < width; x++){
@@ -443,7 +443,7 @@ public TimelapseParticle(ArrayList points, Calibration cal, double proj
}
}
-// progressDialog.notifyMessage("Step static 5 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
+// if(!noGUIs) progressDialog.notifyMessage("Step static 5 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
{
String bitDepth = "8-bit"; maxPossibIntensity = 255.0;
@@ -580,7 +580,7 @@ public TimelapseParticle(ArrayList points, Calibration cal, double proj
convexHullImp.setCalibration(cal);
}
-// progressDialog.notifyMessage("Step static 6 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
+// if(!noGUIs) progressDialog.notifyMessage("Step static 6 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
for(int t = 0; t < times; t++){
convexHullxC [t] /= (convexHullVolume [t]/vxVolume);
@@ -607,7 +607,7 @@ public TimelapseParticle(ArrayList points, Calibration cal, double proj
}
}
-// progressDialog.notifyMessage("Step 2 SKL " + df.format(new Date()),ProgressDialog.NOTIFICATION);
+// if(!noGUIs) progressDialog.notifyMessage("Step 2 SKL " + df.format(new Date()),ProgressDialog.NOTIFICATION);
// SKELETON PARAMETERS
if(skeletonize){
@@ -804,7 +804,7 @@ public TimelapseParticle(ArrayList points, Calibration cal, double proj
particleImpGaussed.close();
}
-// progressDialog.notifyMessage("Step 3 TIMEDEP " + df.format(new Date()),ProgressDialog.NOTIFICATION);
+// if(!noGUIs) progressDialog.notifyMessage("Step 3 TIMEDEP " + df.format(new Date()),ProgressDialog.NOTIFICATION);
//TIME DEPENDENT VARIABLES
if(times>1){
@@ -866,7 +866,7 @@ public TimelapseParticle(ArrayList points, Calibration cal, double proj
motility [t] = occupVolume [t] + lostVolume [t];
}
-// progressDialog.notifyMessage("Step 3.1 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
+// if(!noGUIs) progressDialog.notifyMessage("Step 3.1 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
//FloodFiller to find #extensions and #retractions
int floodNodeX, floodNodeY, floodNodeZ, floodNodeT, index, maxExtRetr = 0;
@@ -1067,7 +1067,7 @@ public TimelapseParticle(ArrayList points, Calibration cal, double proj
}
}
-// progressDialog.notifyMessage("Step 4 LTPs " + df.format(new Date()),ProgressDialog.NOTIFICATION);
+// if(!noGUIs) progressDialog.notifyMessage("Step 4 LTPs " + df.format(new Date()),ProgressDialog.NOTIFICATION);
//timegroup variables
projectedTimes = (int)((double)times/(double)projectedFrames);
@@ -1137,7 +1137,7 @@ public TimelapseParticle(ArrayList points, Calibration cal, double proj
}
}
-// progressDialog.notifyMessage("Step 4 LTPs 1 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
+// if(!noGUIs) progressDialog.notifyMessage("Step 4 LTPs 1 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
for(int i = 0; i < projectedTimes; i++){
projectedDynamicFraction [i] = (projectedVolume [i] - projectedStaticVolume [i]) / projectedVolume [i];
@@ -1192,7 +1192,7 @@ public TimelapseParticle(ArrayList points, Calibration cal, double proj
}
}
-// progressDialog.notifyMessage("Step 4 LTPs 2 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
+// if(!noGUIs) progressDialog.notifyMessage("Step 4 LTPs 2 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
//LONG TERM AVERAGES OF PARAMETERS
if(times>=projectedFrames&&projectedFrames!=1){
@@ -1375,7 +1375,7 @@ public TimelapseParticle(ArrayList points, Calibration cal, double proj
}
}
-// progressDialog.notifyMessage("Step 4 LTPs 3 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
+// if(!noGUIs) progressDialog.notifyMessage("Step 4 LTPs 3 " + df.format(new Date()),ProgressDialog.NOTIFICATION);
//Dynamic parameters
if(times>1){
@@ -1431,7 +1431,7 @@ public TimelapseParticle(ArrayList points, Calibration cal, double proj
}
}
initialized = true;
-// progressDialog.notifyMessage("Done " + df.format(new Date()),ProgressDialog.NOTIFICATION);
+// if(!noGUIs) progressDialog.notifyMessage("Done " + df.format(new Date()),ProgressDialog.NOTIFICATION);
}
/** Closes all ImagePlus belonging to the particle*/
@@ -1452,12 +1452,12 @@ public void closeImps (){
* @param image
* @param progressDialog should reference to the current progressDialog that visualises analysis progress
* */
- private boolean [][][] getConv3DHull(boolean[][][] image, ProgressDialog progressDialog){ //TODO IMPROVE!
+ private boolean [][][] getConv3DHull(boolean[][][] image, ProgressDialog progressDialog, boolean noGUIs){ //TODO IMPROVE!
int width = image.length;
int height = image[0].length;
int slices = image[0][0].length;
- progressDialog.addToBar(0.01);
+ if(!noGUIs) progressDialog.addToBar(0.01);
//initialize
ArrayList pList = new ArrayList ();
@@ -1708,7 +1708,7 @@ public void closeImps (){
}
if((int)Math.round(100.0*doneConnectionsCount/(double)connectionsCount) % 10 == 0){
- progressDialog.updateBarText("Get convex hull ... " + (int)Math.round(100.0*doneConnectionsCount/(double)connectionsCount) + "%");
+ if(!noGUIs) progressDialog.updateBarText("Get convex hull ... " + (int)Math.round(100.0*doneConnectionsCount/(double)connectionsCount) + "%");
}
}
}
@@ -1716,7 +1716,7 @@ public void closeImps (){
}
}
}
- progressDialog.updateBarText("Get convex hull ... 100%");
+ if(!noGUIs) progressDialog.updateBarText("Get convex hull ... 100%");
//get 2D hull
{
@@ -1795,7 +1795,7 @@ public void closeImps (){
pList2.clear();
oldPList2.clear();
}
- progressDialog.updateBarText("convex hull determined");
+ if(!noGUIs) progressDialog.updateBarText("convex hull determined");
oldPList.clear();
pList.clear();
return image;
diff --git a/3D Analyzer/src/main/resources/plugins.config b/3D Analyzer/src/main/resources/plugins.config
index acde514..6e03ccd 100644
--- a/3D Analyzer/src/main/resources/plugins.config
+++ b/3D Analyzer/src/main/resources/plugins.config
@@ -24,8 +24,8 @@
# Belongs to the MotiQ toolbox for analyzing cellular morphology, dynamics, and signaling. MotiQ 3D analyzer analyzes segmented images that are either background-removed (in which intensity information in foreground pixels is preserved while the intensity of background pixels is set to zero) or binary images. After analysis, MotiQ 3D analyzer outputs a text-file containing many different parameter results and a set of images visualizing the results.
# Author: Jan N. Hansen
-# Version: 0.3.2
+# Version: 0.3.3
# Date: 2017/12/01
# Requires: ImageJ
-Plugins>MotiQ, "MotiQ 3D Analyzer (v0.3.2)", motiQ3D.MotiQ_3D
\ No newline at end of file
+Plugins>MotiQ, "MotiQ 3D Analyzer (v0.3.3)", motiQ3D.MotiQ_3D
\ No newline at end of file