From 3a4b9222ceef28290431ca0197d31e35d8165fdd Mon Sep 17 00:00:00 2001 From: Stephen Nneji Date: Tue, 12 May 2026 14:47:50 +0100 Subject: [PATCH 1/2] Add function to run directly from MATLAB API --- ratapi/__init__.py | 3 +- ratapi/utils/matlab.py | 67 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 ratapi/utils/matlab.py diff --git a/ratapi/__init__.py b/ratapi/__init__.py index 98683c7e..8f441f44 100644 --- a/ratapi/__init__.py +++ b/ratapi/__init__.py @@ -9,7 +9,7 @@ from ratapi.outputs import BayesResults, Results from ratapi.project import Project from ratapi.run import run -from ratapi.utils import convert, plotting +from ratapi.utils import convert, matlab, plotting with suppress(ImportError): # orsopy is an optional dependency from ratapi.utils import orso as orso @@ -26,4 +26,5 @@ "run", "plotting", "convert", + "matlab", ] diff --git a/ratapi/utils/matlab.py b/ratapi/utils/matlab.py new file mode 100644 index 00000000..dad8921b --- /dev/null +++ b/ratapi/utils/matlab.py @@ -0,0 +1,67 @@ +"""Runs RAT from the MATLAB API.""" + +import os +import tempfile +import warnings +from pathlib import Path + +from ..outputs import Results +from ..project import Project +from ..wrappers import MatlabWrapper + +RUNNER = """function executeRAT() +project = jsonToProject('{project}'); +controls = jsonToControls('{control}'); +[project, results] = RAT(project, controls); + +projectToJson(project, '{project}'); +resultsToJson(results, '{result}'); +end +""" + + +def run_matlab_directly(project, controls, matlab_rat_path): + """Run User provided MATLAB RAT for the given project and controls inputs. + + Parameters + ---------- + project : RAT.Project + The project model, which defines the physical system under study. + controls : RAT.Controls + The controls model, which defines algorithmic properties. + matlab_rat_path : str + The path to MATLAB RAT folder. + """ + if MatlabWrapper.loader is None: + raise ImportError(MatlabWrapper.loader_error_message) from None + + engine = MatlabWrapper.loader.result() + cur_dir = os.getcwd() + + with tempfile.TemporaryDirectory() as tmp: + project_file = Path(tmp, "project.json") + control_file = Path(tmp, "controls.json") + result_file = Path(tmp, "results.json") + runner_file = Path(tmp, "executeRAT.m") + + with open(runner_file, "w") as f: + f.write(RUNNER.format(project=project_file, control=control_file, result=result_file)) + + with warnings.catch_warnings(): # Avoid warning about relative paths + warnings.simplefilter("ignore") + project.save(project_file) + controls.save(control_file) + + engine.cd(matlab_rat_path, nargout=0) + engine.eval("addPaths", nargout=0) + engine.cd(cur_dir, nargout=0) + + engine.addpath(tmp, nargout=0) + for file in project.custom_files: + engine.addpath(str(file.path), nargout=0) + + engine.executeRAT(nargout=0) + + project = Project.load(project_file) + results = Results.load(result_file) + return project, results From f7e3a0c73d3a601638b577c64695ca3ceaeedfe1 Mon Sep 17 00:00:00 2001 From: Stephen Nneji Date: Fri, 15 May 2026 09:26:04 +0100 Subject: [PATCH 2/2] refactor matlab.py --- ratapi/utils/matlab.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/ratapi/utils/matlab.py b/ratapi/utils/matlab.py index dad8921b..9784c4a5 100644 --- a/ratapi/utils/matlab.py +++ b/ratapi/utils/matlab.py @@ -10,8 +10,17 @@ from ..wrappers import MatlabWrapper RUNNER = """function executeRAT() + +cur_dir = pwd; +cd('{rat_path}'); +addPaths; +cd(cur_dir); + project = jsonToProject('{project}'); controls = jsonToControls('{control}'); +for i=1:project.customFile.rowCount + addpath(project.customFile.varTable{{i, 5}}); +end [project, results] = RAT(project, controls); projectToJson(project, '{project}'); @@ -36,7 +45,6 @@ def run_matlab_directly(project, controls, matlab_rat_path): raise ImportError(MatlabWrapper.loader_error_message) from None engine = MatlabWrapper.loader.result() - cur_dir = os.getcwd() with tempfile.TemporaryDirectory() as tmp: project_file = Path(tmp, "project.json") @@ -45,22 +53,17 @@ def run_matlab_directly(project, controls, matlab_rat_path): runner_file = Path(tmp, "executeRAT.m") with open(runner_file, "w") as f: - f.write(RUNNER.format(project=project_file, control=control_file, result=result_file)) + f.write(RUNNER.format(project=project_file, control=control_file, result=result_file, + rat_path=matlab_rat_path)) with warnings.catch_warnings(): # Avoid warning about relative paths warnings.simplefilter("ignore") project.save(project_file) controls.save(control_file) - - engine.cd(matlab_rat_path, nargout=0) - engine.eval("addPaths", nargout=0) - engine.cd(cur_dir, nargout=0) - + engine.addpath(tmp, nargout=0) - for file in project.custom_files: - engine.addpath(str(file.path), nargout=0) - engine.executeRAT(nargout=0) + engine.rmpath(tmp, nargout=0) project = Project.load(project_file) results = Results.load(result_file)