General Approach to Start an External Application

Everything OAD-related that won't fit in the other categories: share general aspects of macro programming and discuss the OAD environment
user-8
Posts: 63
Joined: Thu Jan 01, 1970 1:00 am

General Approach to Start an External Application

Post by user-8 »

Hi,

here I present a collection of (hopefully) useful example on how to start various external applications from a ZEN OAD macro directly using different ways.

  • Start (normal) Python Script directly to plot a CSV data file (saved ZEN data table)
  • Start (normal) Python Script using a little tool script to plot the same CSV data file
  • Open an CZI File, Start Fiji, Analyse the image data in Fiji and import the results back into ZEN
  • Open an CZI File and open the image data in ICY

All those example illustrate the general approaches that can be used to start various external application from with a OAD macro. For plotting the data using matplotlib one must have the required python modules installed --> see PythonXY, WinPython, .... (this is outside the ZEN world and not possible in IronPython).

All the scripts (only the CZI for the cell count is attached) are attached. It contains also an image analysis pipeline that can be used to create the CSV table and the required Fiji macro for counting cells.

So please replace 3CH_Z-Stack.czi inside the macro with a similar CZI (please do not try Gigabyte-sized multiposition files right away :) .

Good luck!

Code: Select all

"""
Author: SRh
Date: 2013_12_02
Version: 1.0

This macro illustrates the possibility to start an external application directly from a Zen OAD Python script.

1) Load CZI File (or Execute a Zen Experiment) or Data File
2) Define parameters to hand over to the file location
3) Use .NET power inside IronPython... --> start external process = Python Script, Fiji or ICY

Remark: With this method one can start any external application from with an Zen Macro.
It works for Fiji, ImageJ, ICY, Python Scripts, ...

"""

import clr
from System.Diagnostics import Process
from System.IO import Directory, Path, File
import sys

# place all the example files and scripts here ...
scriptfolder = r'MyFolder\Start_External_Application_Example'
sys.path.append(scriptfolder)
# import tools scripts
import FijiTableTools as ft
import StartExternal as stext

# please set to True if one wants the example to be executed
start_PlotData = True
start_Simple_Plot = False
start_Fiji = False
start_Icy = False

# Remove all open images
Zen.Application.Documents.RemoveAll()
# example csv table created from Zen table
csvfile = r'MyFolder\Start_External_Application_Example\96well_all_objects.csv'
# example - Time Series CZI file
imagefile1 = r'MyFolder\\Count_Cells_DAPI_96frames.czi'
# example - 2 Channel Z-Stack
imagefile2 = r'MyFolder\\Start_External_Application_Example\3CH_Z-Stack.czi'

######## Example 1  - Start Python Script and pass command line parameters #######

# check if set to run
if (start_PlotData == True):

    # this is the location of the script use to plot the data
    # use this version for a general approach --> pass filename, X-column, Y-column and rows2skip to plot directly from the OAD macro
    script1 = r'MyFolder\\Start_External_Application_Example\PlotData_Example.py'
    # define the parameters --> the respective python script must be configure to be able to read command line parameters
    # requires PythonXY, WinPython or required Python modules to be installed
    params1 = ' -f ' + csvfile + ' -x 2 -y 0 -r 2'
    # start the data display script as an external application
    app1 = Process();
    app1.StartInfo.FileName = script1
    app1.StartInfo.Arguments = params1
    app1.Start()

######## Example 2 - Start Python Script using a little tool function and pass parameters #######

# check if set to run
if (start_Simple_Plot == True):
    
    # this is easy version, where one has define the columns manually inside the data display script
    script2 = r'MyFolder\\simple_plot.py'
    # this one for the easy version --> only the filename is passed as an argument
    params2 = ' -f ' + csvfile
    # start the data display script as an external application using a tool script
    stext.StartApp(script2, params2)

######## Example 3 - Start Fiji, Open the CZI file, Run an analysis macros inside Fiji and re-import the results into Zen #######

# check if set to run
if (start_Fiji == True):
    
    # load the time series example CZI file
    image1 = Zen.Application.LoadImage(imagefile1)
    Zen.Application.Documents.Add(image1)
    
    # define Fiji analysis macro
    filename = image1.FileName # get the name of the current image data set
    exeloc = 'C:\Users\Public\Documents\Fiji\ImageJ-win64.exe' # use the absolute path --> this works always
    macro = '-macro Zen_Test\Count_Cells_EXP2.ijm' # specify the Fiji macro one wants to use
    option =  macro + ' ' + filename # 'glue' together the options
    
    # define status of Fiji
    Fiji_Finished = False
    
    ## start Fiji and execute the macro
    app = Process();
    app.StartInfo.FileName = exeloc
    app.StartInfo.Arguments = option
    app.Start()
    
    # check if Fiji already saved the data tables
    while (Fiji_Finished == False):
        Fiji_Finished = File.Exists(filename + '_Summary_Fiji.txt')
        #print Fiji_Finished
    
    # read the data tables and convert them into Zen tables
    rowoffset = 1 # skip ... lines
    filename_R = filename + '_Results_Fiji.txt'
    filename_S = filename + '_Summary_Fiji.txt'
    
    # Results Table
    [ValuesArray_R, Legends_R, numvar_R, entries_R, coltypelist] = ft.Conv2Array(filename_R, rowoffset, '\t')
    table_R = ft.CreateTable(ValuesArray_R, numvar_R, entries_R, Legends_R, 1, 'Result Table',coltypelist)
    # read the sliceor frame lables separately since those are strings
    labels = ft.Conv2List(filename_R, rowoffset, '\t', 1)
    # add them to the Zen table to replace the NaNs
    ft.AddLabels(table_R, labels, entries_R, 0)
    Zen.Application.Documents.Add(table_R)
    
    # Summary Table
    [ValuesArray_S, Legends_S, numvar_S, entries_S,coltypelist] = ft.Conv2Array(filename_S, rowoffset, '\t')
    table_S = ft.CreateTable(ValuesArray_S, numvar_S, entries_S, Legends_S, 0, 'Summary Table',coltypelist)
    Zen.Application.Documents.Add(table_S)

######## Example 4  - Start ICY and open the CZI file inside ICY #######

# check if set to run
if (start_Icy == True):

    icylocation = r'C:\Users\Public\Documents\Icy\icy.exe'
    
    ## start application as an external process
    app = Process();
    app.StartInfo.FileName = icylocation
    app.StartInfo.Arguments = imagefile2
    app.Start()
Attachments
Start_External_Application_Example2.zip
(13.99 MiB) Downloaded 251 times
user-4296
Posts: 3
Joined: Thu Jan 01, 1970 1:00 am

Passing in Variables

Post by user-4296 »

Thank you your post was very helpful. Is there a way to pass in integer variables from Zen to a macro in Fiji for the Fiji macro to utilize? In your example you pass the argument as the name of the macro but I also want to include 2 integers that were generated in the Zen macro. Thanks!
user-8
Posts: 63
Joined: Thu Jan 01, 1970 1:00 am

Post by user-8 »

Hi,

yes this is possible. See the example below.

OAD Macro in ZEN:

Code: Select all

bgrd1 = [color=#ff00ff]'20'[/color]
clip1 = [color=#ff00ff]'10'[/color]
bgrd2 = [color=#ff00ff]'10'[/color]
clip2 = [color=#ff00ff]'5'[/color]
multi = [color=#ff00ff]'3'[/color]

filename = image.FileName [color=#008000]# get the name of the current image data set[/color]
params = filename+[color=#ff00ff]';'[/color]+[color=#191970][B]str[/B][/color](bgrd1)+[color=#ff00ff]';'[/color]+[color=#191970][B]str[/B][/color](clip1)+[color=#ff00ff]';'[/color]+[color=#191970][B]str[/B][/color](bgrd2)+[color=#ff00ff]';'[/color]+[color=#191970][B]str[/B][/color](clip2)+[color=#ff00ff]';'[/color]+[color=#191970][B]str[/B][/color](multi)
exeloc = r[color=#ff00ff]'C:\Users\Public\Documents\Fiji\ImageJ-win64.exe'[/color]

[color=#008000]## define Fiji analysis script[/color]
macro = [color=#ff00ff]'-macro Zen_Test\Open_CZI_Physiology.ijm'[/color] [color=#008000]# specify the Fiji macro one wants to use[/color]
option =  macro + [color=#ff00ff]' '[/color] + params [color=#008000]# 'glue' together the options[/color] 

[color=#008000]## start Fiji and execute the macro[/color]
app = [color=#191970][B]Process[/B][/color]();
app.StartInfo.FileName = exeloc
app.StartInfo.Arguments = option
app.[color=#191970][B]Start[/B][/color]()
So the idea is to pass string with defined separator and split it inside a Fiij macro. This is not the most elegant way, but it works fine. Here is the relevant Fiji stuff (just an example):

Code: Select all

// Author:    Sebastian Rhode
// Date:    04.10.2012

paramstr = getArgument;
if (paramstr=="") exit("No argument!");

params = split(paramstr,";");

imagedir = File.getParent(params[0]);
filename = File.getName(params[0]);
print("Directory :", imagedir);
print("File Name :", filename);


print("Image File   : ",params[0]);
print("Background 1 : ",params[1]);
print("Threshold 1  : ",params[2]);
print("Background 2 : ",params[3]);
print("Threshold 2  : ",params[4]);
print("Scale Factor : ",params[5]);


run("Bio-Formats Importer", "open=["+ params[0] + "] autoscale color_mode=Default open_all_series view=Hyperstack stack_order=XYCZT");
run("Split Channels");
run("Ratio Plus", "image1=C1-" + filename + " image2=C2-" + filename + " background1="+params[1]+" clipping_value1="+params[2]+" background2="+params[3]+" clipping_value2="+params[4]+" multiplication="+params[5]);
run("Rainbow RGB");
Anand Ranjan
Posts: 14
Joined: Wed Dec 02, 2020 7:53 pm

Re: General Approach to Start an External Application

Post by Anand Ranjan »

Hi,
I need help with modifying the script for calling Fiji from within Zen OAD (Author: SRh Date: 2013_12_02 Version: 1.0). In the original script, the image file and fiji macro are both specified in Zen OAD.

Is it possible to make the following two modifications in the script?

1) Our Fiji macro runs in batch mode and already has the information of the image files to analyze. It would be great if Zen script could run the Fiji macro without specifying image files.

2) Though Fiji is open on the computer, Zen starts a new Fiji everytime and delays the excution of the script. Would it be possible to have Fiji analyze in background (no visible open program) or atleast a new Fiji is not opened everytime? Any thoughts would be helpful.

Here's the Fiji Macro named 'get_mininal_variance_bathc_mode_PC' that we want Zen OAD to run.
----------------------------------------
//dir=getDirectory("Choose a Directory");
//dir="Z:/Anand/Testing_Zen_image_acquisition_12Nov2020/DIC_Z_stack_analysis/DIC/"

//dir="/Users/ranjan9/Desktop/DIC/"
//From my local desktop on home imac. Suer fast!

//dir="/Volumes/DarwinShare/Anand/Testing_Zen_image_acquisition_12Nov2020/2021-02-11/Cluster1/DIC/"
//Runs from the darwinshare folder. It takes a little longer to connect, but works fine.

dir="Z:/Xiaona/Zen_Automation_AR/2021-02-11/DIC/"

//Run from remote desktop
//dir="Z:/Anand/Testing_Zen_image_acquisition_12Nov2020/2021-02-11/Cluster1/DIC/"

lst=getFileList(dir);

setBatchMode(true);
for ( i=0; i<lst.length; i++ ) {
open(dir+lst);
}

run("Images to Stack", "name=Stack title=[] use");

sliceName = newArray(nSlices);
normVar = newArray(nSlices);

for (s=1; s<nSlices+1;s++) {
// iterate through slices
Stack.setSlice(s);
run("Clear Results");
run("Set Measurements...", " mean redirect=None decimal=5");
run("Measure");
mean = getResult("Mean");
//selectWindow("Results");
//run("Close");
W = getWidth();
H = getHeight();
b = 0;

for (j=0; j<H; j++) {
for (i=0; i<W; i++) {
p = getPixel(i,j);
t = (p-mean)*(p-mean);
b += t;
}
}
normVar[s-1] = b/(H*W*mean);
sliceName[s-1] = getInfo("slice.label");
}
//print(nSlices)
//print(s)
Array.print(sliceName);
Array.print(normVar);
minVar = Array.findMinima(normVar, 0);
//Array.print(minVar);
file = File.open(dir+"minVar.txt");
print(file, sliceName[minVar[0]]);
print(sliceName[minVar[0]]);

close("Results");
close("ROI Manager");
close("Stack");

----------------------------------------
Thank you very much for your attention.
Best,
Anand
CarlZeissMicroscopy3
Posts: 180
Joined: Wed May 20, 2020 10:10 am

Re: General Approach to Start an External Application

Post by CarlZeissMicroscopy3 »

Hello Anand Ranjan,

the 'core' of starting an other application from a Zen macro is

Code: Select all

import clr
from System.Diagnostics import Process

def StartApp(exeloc, option):
    app = Process();
    app.StartInfo.FileName = exeloc
    app.StartInfo.Arguments = option
    app.Start()
where exeloc is the location of the exe file (application) you want to start and option represents the options corresponding to the options offered by the application.

In other words: It depends on the options/possibilities offered by an application what you can do with it when you start it programmatically.
The same is true for 'starts a new application everytime' which cannot be influenced by Zen (or any other application). As far as I can remember ImageJ or Fiji (?once?) had an option in its setting so that the application is only run once on a computer.
As we cannot influence these themes, please get information about these features from the corresponding software support.

Please, also have a look at the Process class of .Net Framework, because it offers some additional features like starting applications with minimized window etc. In addition there are lots of examples in the internet on how to use the Process class.

Code: Select all

import clr
from System.Diagnostics import Process


def Fiji(macroname, FileOrFolder):
    ## define Fiji analysis script
    exeloc = 'C:\Users\Public\Documents\Fiji\ImageJ-win64.exe' # use the absolute path --> this works always 
    macro = '-macro ' + macroname # specify the Fiji macro one wants to use
    option =  macro + ' ' +  FileOrFolder # 'glue' together the options
    StartApp(exeloc, option)
    
def Fiji(macroname):
    ## define Fiji analysis script
    exeloc = 'C:\Users\Public\Documents\Fiji\ImageJ-win64.exe' # use the absolute path --> this works always 
    option = '-macro ' + macroname # specify the Fiji macro one wants to use
    StartApp(exeloc, option)

def StartApp(exeloc, option):
    app = Process();
    app.StartInfo.FileName = exeloc
    app.StartInfo.Arguments = option
    app.Start()
  
I hope this helps.
Anand Ranjan
Posts: 14
Joined: Wed Dec 02, 2020 7:53 pm

Re: General Approach to Start an External Application

Post by Anand Ranjan »

Thank you very much for your quick response.

If I understand correctly, you have provided the two different methods for adding information of Fiji macro in the Zen script-

------------------------------------------------------------------------------
def Fiji(macroname, FileOrFolder):
## define Fiji analysis script
exeloc = 'C:\Users\Public\Documents\Fiji\ImageJ-win64.exe' # use the absolute path --> this works always
macro = '-macro ' + macroname # specify the Fiji macro one wants to use
option = macro + ' ' + FileOrFolder # 'glue' together the options
StartApp(exeloc, option)
--------------------------------------------------------------------------------------
def Fiji(macroname):
## define Fiji analysis script
exeloc = 'C:\Users\Public\Documents\Fiji\ImageJ-win64.exe' # use the absolute path --> this works always
option = '-macro ' + macroname # specify the Fiji macro one wants to use
StartApp(exeloc, option)
-------------------------------------------------------------------------------------------------

If my Fiji macro is named 'get_minimal_variance_batch_mode_PC' and its path is -
'Z:\Anand\Zen_Automation_AR\get_minimal_variance_batch_mode_PC.ijm'
Would the following Zen script be fine and if not can you please suggest changes.

def Fiji(get_minimal_variance_batch_mode_PC):
## define Fiji analysis script
exeloc = 'D:\Fiji.app\ImageJ-win64.exe' # use the absolute path --> this works always
option = '-macro ' + 'Z:\Anand\Zen_Automation_AR\get_minimal_variance_batch_mode_PC.ijm' # specify the Fiji macro one wants to use
StartApp(exeloc, option)

Sorry about the naivete of my queries. I'm a little stuck at effectively calling Fiji from Zen OAD.

Many thanks,
Anand
CarlZeissMicroscopy3
Posts: 180
Joined: Wed May 20, 2020 10:10 am

Re: General Approach to Start an External Application

Post by CarlZeissMicroscopy3 »

Hello Anand Ranjan,

yes, something like

Code: Select all

import clr
from System.Diagnostics import Process

def StartApp(exeloc, option):
    app = Process();
    app.StartInfo.FileName = exeloc
    app.StartInfo.Arguments = option
    app.Start()
    
exeloc = 'D:\Fiji.app\ImageJ-win64.exe'
option = '-macro ' + 'Z:\Anand\Zen_Automation_AR\get_minimal_variance_batch_mode_PC.ijm'
StartApp(exeloc, option)
should work.

By the way: You can test your call in a very simple way, which means without any Python.
Click on the windows Start button, then type cmd followed by a return.
You are now in the command line editor.
Copy
D:\Fiji.app\ImageJ-win64.exe -macro Z:\Anand\Zen_Automation_AR\get_minimal_variance_batch_mode_PC.ijm
(to the clipboard) and paste it via 'right mouse click' into the command line editor.
Type return and it shoud work.

If it does not work it will not work with StartApp either and you need assistance from a Fiji forum etc.

Good luck!
Anand Ranjan
Posts: 14
Joined: Wed Dec 02, 2020 7:53 pm

Re: General Approach to Start an External Application

Post by Anand Ranjan »

The Zen script worked great and the macro in Fiji was called ran very well.
Thank you very much.
Best,
Anand
Anand Ranjan
Posts: 14
Joined: Wed Dec 02, 2020 7:53 pm

Re: General Approach to Start an External Application

Post by Anand Ranjan »

Hi,
I recently learned about running Fiji from PC's console in Headless mode without opening the program. In my current script, it takes about 11 seconds for Fiji to analyze Z-stack and return results to OAD. I was wondering if OAD supports opening Fiji in Headless mode. Hopefully, Fiji analysis without opening the program will make it a little faster.

Here's the command for running Fiji in headless mode from PC's console-

ImageJ-win64 --ij2 --headless --console --run Z:\Anand\Zen_Automation_AR\get_minimal_variance_Zstack_newFileEachTime_PC_filename_minvar.ijm

And here's my current script to call Fiji from OAD
-------------------------------------------------------------------------------------------------------------------
import clr
from System.Diagnostics import Process

def StartApp(exeloc, option):
app = Process();
app.StartInfo.FileName = exeloc
app.StartInfo.Arguments = option
app.Start()

# define status of Fiji
Fiji_Finished = False

exeloc = 'D:\Fiji.app\ImageJ-win64.exe'
filename = outputexperiment1.FileName
option = '-macro ' + 'Z:\Anand\Zen_Automation_AR\get_minimal_variance_Zstack_newFileEachTime_PC_filename_minvar.ijm' +' ' + filename
StartApp(exeloc, option)
-----------------------------------------------------------------------------------------------------------------------------------
Any guidance will be very helpful.
Thank you,
Anand
CarlZeissMicroscopy3
Posts: 180
Joined: Wed May 20, 2020 10:10 am

Re: General Approach to Start an External Application

Post by CarlZeissMicroscopy3 »

Hello Anand Ranjan,
I was wondering if OAD supports opening Fiji in Headless mode.
Please keep in mind that with

Code: Select all

import clr
from System.Diagnostics import Process

app = Process();
you import a library from the .Net Framework in OAD and therefore no direct 'OAD support opening Fiji' exists.
So, if you use a library please have a look at the internet, because it is documented and discussed there in many ways.

Simply search on the internet for something like '.net process start fiji' or more general '.net process' to get contributions.

One contribution that seems to point in your direction is
https://stackoverflow.com/questions/212 ... ine-from-c

I hope this helps.
Post Reply