Clear Filters
Clear Filters

Matlab -> Python -> xfoil: Code works differently when called from Python versus called from Matlab to Python

9 views (last 30 days)
I have a Python 3 class that creates input to send to a fortran program (xfoil). I am using subprocess.run to launch the fortran binary and send the command inputs to it, and this works just fine if I do it from within Python. Commands are sent to the fortran program, output is captured, all is well.
Unfortunately, I am trying to make the Python code available from Matlab and it seems to work differently when launched that way. I have been able to load the python module and link to the class from Matlab (and I'm able to use properties and methods of the Python class that don't call xfoil - so I have the Matlab environment set up correctly to be able to use Python).
I have also checked that the absolute path is being used to call xfoil and load inputs from the correct working directory (verified with debug print statements for what the current directory is). And I also have checked that the error is being thrown from Fortran, indicating it is reaching the end of file (stream in this case) when prompting for user input. Again, this does not happen if I call the Python routine that initiates the xfoil analysis from another Python component. Something is different when it is being launched from Matlab.
So as for code, here is what my Python call looks like:
binfile = '../../airfoils/xfoil'
if not posix:
binfile += '.exe'
# get the whole absolute path to xfoil
binfile = os.path.realpath(binfile)
print(f' xfoil pathname={binfile}')
# get the commands to send to xfoil
with open(file=f'{filename}.inp', encoding='utf8', mode='r') as fin:
cmds = fin.read()
# connect the subprocess for xfoil
p = subprocess.run(binfile, input=cmds,
shell=True, encoding='utf8',
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
print(f' stderr={p.stderr}')
print(f' stdout={p.stdout}')
The Matlab code:
% check that the python path contains the folder with airfoil_section.py
P = py.sys.path;
[fpath, ~, ~] = fileparts(which('MatlabTests'));
if count(P, fpath) == 0
insert(P, int32(0), fpath);
end
sect = py.airfoil_section.Section2d('../../folder/file.dat', ... % <- This works fine from Matlab
'other info', 1.0);
sect.analyze_base_polar() % Xfoil call happens from this target Python code, and for some reason is not passing inputs to xfoil
The error message it produces is as follows (Italics are necessary obfuscations):
>> MatlabTests
current dir = [Verified correct path]
Running [airfoil name] with XFOIL
xfoil pathname= [Verified correct path]
stderr=At line 135 of file ../src/userio.f
Fortran runtime error: End of file
stdout=
Error using XFOIL_Toolbox>generateXFOILPolar (line XXXX)
Python Error: FileNotFoundError: [Errno 2] No such file or directory: 'name.out'
Error in airfoil_section>_run_xfoil_polar (line XXXX)
Error in airfoil_section>analyze_base_polar (line XXXX)
I am running on:
  • Mac OS 11.6.5
  • Matlab R2021a (64-bit)
  • Python 3.8.10
Thanks in advance!
Jason

Answers (1)

arushi
arushi on 17 Jan 2024
Hi Jason,
I understand that you want face the end of line error while trying to make the Python code available from MATLAB. This issue may be related to how MATLAB handles the standard input and output streams when calling a subprocess from Python, which is itself being called from MATLAB. When running the Python script directly, the subprocess.runfunction can properly interact with the standard input of the xfoilprogram. However, when running from MATLAB, the standard input might not be correctly connected, leading to the Fortran runtime error you're seeing.
Here are some suggestions to troubleshoot and potentially resolve this issue:
  1. Ensure that the input is being sent correctly: You may want to explicitly specify stdin = subprocess.PIPE in your subprocess.run call to ensure that the input is being piped correctly.
  2. Use subprocess.Popen instead of subprocess.run: The subprocess.Popen class provides more control over the input/output/error pipes and may work better when called from MATLAB.
  3. Check for file path issues: Ensure that all file paths are absolute and correctly formatted, as relative paths may not be resolved the same way when called from MATLAB.
  4. Check the environment: MATLAB may run Python scripts in a different environment. You can print out the environment variables in your Python script to check for differences:
  5. Use a script file instead of piping input: As an alternative to piping commands directly to xfoil, you might consider writing the commands to a script file and then executing xfoil with that script file as an argument.
  6. Check MATLAB's Python configuration: Use pyenv in MATLAB to check that it is configured to use the correct Python interpreter and that all necessary environment variables are set.
Please refer to the documentation given below of subprocess and all its functions –
Hope this helps.

Products


Release

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!