Note: I tried this with Octave, since I don't have a MATLAB license.
As already hinted at in the comments, your communication between your MATLAB script and your Python script is missing two essential aspects:
- The handling of the inputs to the Python script within the Python script.
- The handling of the results from the Python script within the MATLAB script.
Handling the inputs to the Python script
This is the easier part:
- Calling
system('python script.py argA argB')
from MATLAB results in calling the Python script script.py
with command line arguments argA
and argB
.
- From within the called Python script
script.py
, the command line arguments are available via sys.argv
, which is a list of strings.
Let's assume you have a Python script script.py
with the following contents:
### Contents of 'script.py' ###
import sys
print(sys.argv)
Call this script from the command line via the following call:
$ python script.py argA argB
Then your output will look as follows:
['script.py', 'argA', 'argB']
As you can see, all command line arguments are available as strings, prepended by the name (or path) of the called script itself. You can now actually make use of them from within your script; for example, convert them to numbers for calculations or, as in your case, use them as a name for a file to be loaded.
Handling the outputs of the Python script
This is the more tricky part, and I am not sure if mine is the best solution:
Once you have done all the data processing in your Python script, you somehow need to get the results back to MATLAB. A very straightforward approach would be printing the results within the Python script and then capturing the outputs as part of the return value of the system()
call in your MATLAB script.
Let's assume you still have the Python script script.py
, with the same contents as above. Additionally now, let's assume we have a MATLAB script script.m
with the following contents:
%%% Contents of 'script.m' %%%
[status, output] = system('python script.py argA argB');
sprintf('From python: %s', output)
Call this script from the command line via the following call (again, I am using Octave here):
$ octave script.m
Then your output will look as follows:
ans = From python: ['script.py', 'argA', 'argB']
As you can see, we got the same output, but this time from the MATLAB script (and only from the MATLAB script). The MATLAB script captured the Python output in the output
variable, then processed it (by prepending 'From python: '
), and printed it again.
Putting it all together into a (somewhat) more useful example
We can use the same approach to pass not only strings but actual data. For this case we might want to write raw bytes to the output from within our Python script, then parse them from within our MATLAB script and convert them to a corresponding MATLAB object.
The following example …
- (in MATLAB) sends a number
n
to Python as a command line argument;
- (in Python) creates an
n×n
square matrix containing the values 0,1,…,n²-2,n²-1
as a 2D Numpy array, then prints the raw bytes of the corresponding float64
values;
- (in MATLAB) captures the raw bytes and converts them to the corresponding 2D MATLAB array of
double
values.
Python script script.py
:
### Contents of 'script.py' ###
import sys
import numpy as np
# Convert 1st argument to integer, then create square matrix of doubles with it
num = int(sys.argv[1])
data = np.arange(num*num, dtype=np.float64).reshape(num, num)
# Write resulting bytes to stdout
sys.stdout.buffer.write(data.tobytes())
MATLAB script script.m
:
%%% Contents of 'script.m' %%%
rows_cols = 3;
[status, res] = system(sprintf('python script.py %d', rows_cols));
numpy_data = reshape(typecast(uint8(res), 'double'), [rows_cols, rows_cols])'
Command line call of Octave and corresponding output:
$ octave script.m
numpy_data =
0 1 2
3 4 5
6 7 8
As you can see, the 2D array was successfully reinstantiated as the MATLAB array numpy_data
.
In reality, this might be trickier, of course: For example, if the Python script produces more outputs other than only the raw data that we are actually interested in, we need to filter out the parts that we are interested in (on the MATLAB side) or suppress all unrelated outputs (on the Python side). Also, getting the numbers of bytes, shapes, and orders of dimensions correct might not always be as straightforward as in the given example (note, for example, that here we needed to transpose the final MATLAB result).
target
andoriginalPatient
have not been defined in the Python script. Where should they come from?system()
. Python does not "magically" assign them to appropriate variables, but instead provides them via thesys.argv
list. Tryimport sys
andprint(sys.argv)
in your Python script to see if that gets you any further. Also see here for more doc onsys.argv
.