Reputation: 283
I want to run a program, let's say MATLAB or other FEA software from Python, wait for it to run and store results and later use again in Python to process further. I am not able to find a really basic example on how to do so. A simple code or any useful link will be highly appreciated. The help on Subprocess module seems a bit complicated.
Upvotes: 1
Views: 1206
Reputation: 182
I just spent a while trying to work this out from frustratingly vague documentation and examples and finally got it figured out. Here's a really simple demo example:
How to run a MATLAB script from Python (using subprocess.Popen, without having to install the matlab engine)
Step 1: Create the MATLAB script you want to run. In this demo, I have two scripts, saved in the folder C:/Users/User/Documents/MATLABsubprocess :
triangle_area.m
b = 5;
h = 3;
a = 0.5*(b.* h);
save('a.txt','a', '-ASCII')
triangle_area_fun.m
function [a] = triangle_area(b,h)
a = 0.5*(b.* h); %area
save('a.txt','a', '-ASCII')
end
Step 2: Once these two .m files are created, the following Python script runs them using subprocess.Popen():
#Imports:
import subprocess as sp
import pandas as pd
#Set paths and options:
#note: paths need to have forward slashes not backslashes (why?!)
program = 'C:/Program Files/MATLAB/R2017b/bin/matlab.exe' #path to MATLAB exe
folder = 'C:/Users/User/Documents/MATLABsubprocess' #path to MATLAB folder with scripts to run
script = 'triangle_area' #name of script to run
options = '-nosplash -nodesktop -wait' #optional: set run options (nosplash? nodesktop means MATLAB won't open a new desktop window, wait means Python will wait until MATLAB is done beore continuing (needs to be paired with p.wait() after sp.Popen))
has_args = True #set whether the MATLAB script needs arguments (i.e. is it a function?)
#Optional: define arguments to feed to function
if has_args ==True:
script = 'triangle_area_fun' #select script version with arguments
b = 5
h = 3
args = '({},{})'.format(b,h) #put all args into one string
#Set function string:
#Structure: """path_to_exe optional_arguments -r "cd(fullfile('path_to_folder')), script_name, exit" """
#Example: """C:/Program Files/MATLAB/R2017b/bin/matlab.exe -r "cd(fullfile('C:/Users/User/Documents/MATLABsubprocess')), triangle_area, exit" """
#basically, needs to know where the program to use lives, then takes some optional settings, -r runs the program, cd changes to the directory with the script, then needs the name of the script (possibly with arguments), then exits
fun = """{} {} -r "cd(fullfile('{}')), {}, exit" """.format(program, options, folder, script) #create function string that tells subprocess what to do
if has_args==True:
fun = """{} {} -r "cd(fullfile('{}')), {}{}, exit" """.format(program, options, folder, script, args)
print('command:', fun)
#Run MATLAB:
print('running MATLAB script...')
p = sp.Popen(fun) #open the subprocess & run the MATLAB script
p.wait() #wait until MATLAB is done before proceeding (this needs to be paired with -wait in options)
print('done') #if the run is successful, an output file named a.txt should appear in the folder with the MATLAB scripts
#Import MATLAB output files back into Python:
a = pd.read_csv('a.txt', header=None) #read text file using pandas
print(a)
Upvotes: 1