Skip to content

Commit e9454fa

Browse files
committed
as
1 parent 1add187 commit e9454fa

File tree

5 files changed

+84
-58
lines changed

5 files changed

+84
-58
lines changed

.github/workflows/run_tests.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
name: Run Unit Tests
23

34
on:
@@ -11,8 +12,11 @@ concurrency:
1112
cancel-in-progress: true
1213

1314
jobs:
15+
run_ruff:
16+
uses: ./.github/workflows/run_ruff.yml
1417

1518
test:
19+
needs: [run_ruff]
1620
strategy:
1721
fail-fast: false
1822
matrix:
@@ -47,12 +51,8 @@ jobs:
4751
run: |
4852
sudo apt-get update
4953
sudo apt install libomp-dev
50-
- name: Set up MATLAB
51-
uses: matlab-actions/setup-matlab@v2
52-
with:
53-
release: R2024a
5454
- name: Install and Test with pytest
5555
run: |
5656
export PATH="$pythonLocation:$PATH"
5757
python -m pip install -e .[Dev,Orso]
58-
python RATapi/examples/normal_reflectivity/DSPC_custom_layers.py
58+
pytest tests/ --cov=RATapi --cov-report=term

RATapi/inputs.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import numpy as np
99

1010
import RATapi
11-
import RATapi.controls
1211
import RATapi.wrappers
1312
from RATapi.rat_core import Checks, Control, NameStore, ProblemDefinition
1413
from RATapi.utils.enums import Calculations, Languages, LayerModels, TypeOptions

RATapi/wrappers.py

Lines changed: 68 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,107 @@
11
"""Wrappers for the interface between RATapi and MATLAB custom files."""
2-
from contextlib import contextmanager
2+
33
import os
44
import pathlib
55
import platform
66
import shutil
77
import subprocess
8+
from contextlib import contextmanager
89
from typing import Callable
910

10-
import numpy as np
1111
from numpy.typing import ArrayLike
1212

1313
import RATapi.rat_core
1414

15-
1615
MATLAB_PATH_FILE = os.path.join(os.path.dirname(os.path.realpath(__file__)), "matlab.txt")
1716

1817

1918
@contextmanager
20-
def cd(newdir):
19+
def cd(new_dir):
20+
"""Context manager to change to a given directory and return to current directory on exit.
21+
22+
Parameters
23+
----------
24+
new_dir : string
25+
The path to change to
26+
"""
2127
prev_dir = os.getcwd()
22-
os.chdir(os.path.expanduser(newdir))
28+
os.chdir(os.path.expanduser(new_dir))
2329
try:
2430
yield
2531
finally:
2632
os.chdir(prev_dir)
2733

2834

29-
def set_matlab_path(matlab_path):
30-
if not matlab_path:
31-
return
32-
33-
if platform.system() == "Windows":
34-
process = subprocess.Popen(f'"{matlab_path}" -batch "comserver(\'register\')"')
35+
def set_matlab_path(matlab_exe_path):
36+
"""Set the path of MATLAB to use for custom functions.
37+
38+
This will also register the MATLAB COM server on Windows OS which could be slow.
39+
40+
Parameters
41+
----------
42+
matlab_path : string
43+
The full path of the MATLAB executable
44+
"""
45+
if not matlab_exe_path:
46+
return
47+
48+
if platform.system() == "Windows":
49+
process = subprocess.Popen(f'"{matlab_exe_path}" -batch "comserver(\'register\')"')
3550
process.wait()
36-
3751

3852
with open(MATLAB_PATH_FILE, "w") as path_file:
39-
path_file.write(matlab_path)
53+
path_file.write(matlab_exe_path)
54+
4055

56+
def get_matlab_paths(matlab_exe_path):
57+
"""Return paths for loading MATLAB engine C interface dynamic libraries.
4158
42-
def get_matlab_paths(exe_path):
43-
if not exe_path:
59+
Parameters
60+
----------
61+
matlab_exe_path : string
62+
The full path of the MATLAB executable
63+
64+
Returns
65+
-------
66+
paths : Tuple[string, string]
67+
The path of the MATLAB bin and the DLL location
68+
"""
69+
if not matlab_exe_path:
4470
raise FileNotFoundError()
45-
46-
bin_path = pathlib.Path(exe_path).parent
47-
if bin_path.stem != 'bin':
71+
72+
bin_path = pathlib.Path(matlab_exe_path).parent
73+
if bin_path.stem != "bin":
4874
raise FileNotFoundError()
49-
50-
if platform.system() == "Windows":
51-
arch = "win64"
52-
elif platform.system() == "Darwin":
53-
arch = "maca64" if platform.mac_ver()[-1] == 'arm64' else "maci64"
54-
else:
75+
76+
if platform.system() == "Windows":
77+
arch = "win64"
78+
elif platform.system() == "Darwin":
79+
arch = "maca64" if platform.mac_ver()[-1] == "arm64" else "maci64"
80+
else:
5581
arch = "glnxa64"
56-
82+
5783
dll_path = bin_path / arch
5884
if not dll_path.exists():
5985
raise FileNotFoundError(f"The expected MATLAB folders were in found at the path: {dll_path}")
60-
61-
return f'{bin_path.as_posix()}/' , f'{dll_path.as_posix()}/'
86+
87+
return f"{bin_path.as_posix()}/", f"{dll_path.as_posix()}/"
88+
6289

6390
def start_matlab():
64-
"""Start MATLAB asynchronously and returns a future to retrieve the engine later.
91+
"""Load MATLAB engine dynamic libraries and creates wrapper object.
6592
6693
Returns
6794
-------
68-
future : RATapi.rat_core.MatlabEngine
69-
A custom matlab engine wrapper.
95+
engine : Optional[RATapi.rat_core.MatlabEngine]
96+
A matlab engine object
7097
7198
"""
7299
try:
73100
with open(MATLAB_PATH_FILE) as path_file:
74101
matlab_path = path_file.read()
75102
except FileNotFoundError:
76103
matlab_path = ""
77-
104+
78105
if not matlab_path:
79106
matlab_path = shutil.which("matlab")
80107
if matlab_path is None:
@@ -85,17 +112,16 @@ def start_matlab():
85112
if temp.is_symlink():
86113
matlab_path = temp.readlink().as_posix()
87114
set_matlab_path(matlab_path)
88-
115+
89116
if matlab_path:
90117
bin_path, dll_path = get_matlab_paths(matlab_path)
91118
os.environ["MATLAB_DLL_PATH"] = dll_path
92-
print(bin_path, dll_path)
93-
if platform.system() == "Windows":
119+
if platform.system() == "Windows":
94120
os.environ["PATH"] = dll_path + os.pathsep + os.environ["PATH"]
95-
121+
96122
with cd(bin_path):
97123
engine = RATapi.rat_core.MatlabEngine()
98-
124+
99125
return engine
100126

101127

@@ -107,12 +133,15 @@ class MatlabWrapper:
107133
filename : string
108134
The path of the file containing MATLAB function
109135
"""
136+
110137
engine = start_matlab()
111-
138+
112139
def __init__(self, filename) -> None:
113140
if self.engine is None:
114-
raise ValueError("MATLAB is not found. Please use `set_matlab_path` to set the location of your MATLAB installation") from None
115-
141+
raise ValueError(
142+
"MATLAB is not found. Please use `set_matlab_path` to set the location of your MATLAB installation"
143+
) from None
144+
116145
path = pathlib.Path(filename)
117146
self.engine.cd(str(path.parent))
118147
self.engine.setFunction(path.stem)
@@ -133,7 +162,6 @@ def handle(*args):
133162
return handle
134163

135164

136-
137165
class DylibWrapper:
138166
"""Creates a python callback for a function in dynamic library.
139167

cpp/rat.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ class MatlabEngine
5454
std::function<int(Engine *, const char *)> engEvalString;
5555

5656
std::function<double(const mxArray *)> mxGetScalar;
57-
// std::function<const mwSize *(const mxArray *)> mxGetDimensions;
5857
std::function<void *(const mxArray *)> mxGetData;
5958
std::function<mxArray *(double)> mxCreateDoubleScalar;
6059
std::function<mxArray *(mwSize, mwSize, mxComplexity)> mxCreateDoubleMatrix;

setup.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
import os
21
import platform
3-
import shutil
42
import sys
5-
import warnings
63
from glob import glob
74
from pathlib import Path
85

@@ -105,13 +102,15 @@ def run(self):
105102

106103
if self.inplace:
107104
obj_name = get_shared_object_name(libevent[0])
108-
build_py.copy_file(f"{build_py.build_lib}/{PACKAGE_NAME}/{obj_name}",
109-
f"{build_py.get_package_dir(PACKAGE_NAME)}/{obj_name}")
110-
111-
open(f"{build_py.get_package_dir(PACKAGE_NAME)}/matlab.txt", 'w').close()
112-
105+
build_py.copy_file(
106+
f"{build_py.build_lib}/{PACKAGE_NAME}/{obj_name}",
107+
f"{build_py.get_package_dir(PACKAGE_NAME)}/{obj_name}",
108+
)
109+
110+
open(f"{build_py.get_package_dir(PACKAGE_NAME)}/matlab.txt", "w").close()
113111

114-
class BuildClib(build_clib):
112+
113+
class BuildClib(build_clib):
115114
def initialize_options(self):
116115
super().initialize_options()
117116
build_py = self.get_finalized_command("build_py")
@@ -153,6 +152,7 @@ def build_libraries(self, libraries):
153152

154153
super().build_libraries(libraries)
155154

155+
156156
setup(
157157
name=PACKAGE_NAME,
158158
version=__version__,
@@ -165,8 +165,8 @@ def build_libraries(self, libraries):
165165
packages=find_packages(),
166166
include_package_data=True,
167167
package_data={"": ["matlab.txt", get_shared_object_name(libevent[0])], "RATapi.examples": ["data/*.dat"]},
168-
cmdclass={"build_clib": BuildClib, "build_ext": BuildExt},
169-
libraries=[libevent],
168+
cmdclass={"build_clib": BuildClib, "build_ext": BuildExt},
169+
libraries=[libevent],
170170
ext_modules=ext_modules,
171171
python_requires=">=3.10",
172172
install_requires=[

0 commit comments

Comments
 (0)