Calling a Python Script from within experiment

Hi,

Scenario: I have a work flow doing image texture analysis using ImageGLCM and then feeding those values into a random forest model in python to do a classification analysis.  I then take the results of the classification model and create a mask layer image for the user.  All well and good but manual intervention is required.

The client would would like a single interface and is ok with either python or IP.  Two things put IP as a preferred solution: 1. The grey level co-occurance parameters are much faster calculated in IP due to multithreading (15 sec versus 90-120sec) and the creation of a user interface and visualization is much better or at least easier.

The idea I am toying with is to do the ImageGLCM within IP and then save the data to a defined location.

Call the python script to load the random forest model and run the classification prediction and save the data to file at defined location.

Then have IP read that file and finish processing and do visualization.

Questions

1. how do I call a python script to execute from within IP?

2. How do I handle waiting for the script to complete? One thought was after the script is called to look for its output file, though I have concerns of collisions between IP and python with that file.  Are there best practices?

Andy

I am copying an Exchange comment I made in 2008, in case the link below is no longer accessible:

"I had a somewhat similar situation making Igor and FORTRAN work together. The "proper" (and difficult) way is probably to make an XOP from your FORTRAN code. The simple, brute force method I took was to use Igor as a front-end, have it write an input file (with parameters used by the FORTRAN application), and launch the FORTRAN app from Igor by executing a BAT file. The FORTRAN app reads its input data, executes its computation, writes its output in IGOR-friendly format to another data file, and terminates. When Igor detects that this output file is ready to open, it loads the data, and plots and analyzes it."

Contact me if you think similar Procedure methods may apply to a Python executable..

https://www.wavemetrics.com/forum/general/loading-multiple-simulation-d…

 

> Questions
> 1. how do I call a python script to execute from within IP?

As noted above, one approach is to use ExecuteScriptText to call out to the OS.

> 2. How do I handle waiting for the script to complete? One thought was after the script is called to look for its output file, though I have concerns of collisions between IP and python with that file.  Are there best practices?

I would not know "best" practices. I can think of three possible options to avoid collisions with the output file.

- You might use SetBackground to look for a semaphore file from the python script *after the file has been written*. You can have foreground tasks running and alert the user with a dialog when the next steps in processing are ready to initiate.
- You might have the python script write a semaphore file to a specific location *after the file has been written*. You may likely need to "freeze out" the UI for the next processing steps until IgorPro completes its do...enddo loop certifying the appearance of the semaphore file from the python script.
- You might have the python script write a semaphore variable into the current IgorPro experiment itself *after the file has been written*. Again, you may likely need to freeze out the UI as above.

I don't have any experience doing this in macOS, but in Windows the batch file method works very well.  I've even used it to call Python from within a Windows Subsystem for Linux environment, as well as pass user arguments to the Python script.  I've attached a simple Python script and an ipf that creates a batch file to run the script via Anaconda.  You'll have to change the extension of the Python file back to .py and then change two paths in the ipf to make it work.  I added a couple of waits to the Python script to simulate computation time, and while the Python script was running, the execution of the Igor script was paused until Python was done, so you might not need to do anything special to check if Python is done.

If you prefer an asynchronous approach, you can use subprocess on the python side to hand control back to Igor.

Hi,

I am trying to get the syntax for this initially on a Mac, though I will need to move it to a Windows based system for the client.

Struggling with executescripttext and the required format.

What I have is a script file, untitled_text.sh

#!/bin/zsh
python3 /Users/andreashegedus/Desktop/test.py

I have set the chmod so it runs from in terminal.

and test.py

print('Hello World')

 Pushing the frontiers here.

 

Within IP9, what would the command script string be to run this?

I have tried these two without success and the error message is not helpful

fred = "do shell script /Applications/Terminal /Users/andreashegedus/Desktop/untitled_text.sh"
•fred = "do shell script /Users/andreashegedus/Desktop/untitled_text.sh"

 

Any help?

Andy

Perhaps this more exhaustive approach could be useful.

// code example from LaTex To Picture package

    string theTempFolderU =  SpecialDirPath("Temporary",0,1,0)
    string theTempFile, theCmd, theSys, iname
    theTempFile = theTempFolderU + theFileName
    theTempFolderU = RemoveEnding(theTempFolderU)
    theSys = IgorInfo(2)   
    StrSwitch(theSys)
        case "Macintosh":
            theCmd = generateMacCmd(theTempFolderU, theTempFile)
            ExecuteScriptText/UNQ/Z theCmd
            string/G COMPILEREPORT = S_value
            if (V_flag==0)
...
            else
                iname = ""
                switch(prterr)
                    case 0:
                        break
                    case 1:
                        print "Error on compilation. See COMPILEREPORT string in root folder and log at " + theTempFolderU
                        break
                    case 2:
                        print S_value
                        break
                endswitch
            endif
            break

// generate the macintosh command string
Static Function/S generateMacCmd(string theTFU, string theTF)

    string theCmd
    sprintf theCmd, "/Library/TeX/texbin/pdflatex -output-directory='%s' '%s'", theTFU, theTF
    sprintf theCmd, "do shell script \"%s\"", theCmd
    return theCmd
end