From 4fff3320642b1a83137e804887559b8ec277df8d Mon Sep 17 00:00:00 2001 From: Stephen Nneji Date: Fri, 11 Sep 2026 14:41:11 +0100 Subject: [PATCH] Ignore unused custom files --- pyproject.toml | 2 +- ratapi/inputs.py | 41 +++++++++++++++++++++++++++++++++++++---- ratapi/wrappers.py | 2 +- tests/test_inputs.py | 19 ++++++++++++++++++- 4 files changed, 57 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 94d7f768..d3315c51 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ build-backend = 'setuptools.build_meta' [project] name = "ratapi" -version = "0.0.0.dev16" +version = "0.0.0.dev17" description = "Python extension for the Reflectivity Analysis Toolbox (RAT)" readme = "README.md" requires-python = ">=3.10" diff --git a/ratapi/inputs.py b/ratapi/inputs.py index 026a54ec..cf140f42 100644 --- a/ratapi/inputs.py +++ b/ratapi/inputs.py @@ -49,6 +49,38 @@ def get_python_handle(file_name: str, function_name: str, path: str | pathlib.Pa return handle +def get_used_custom_files(project): + """Get custom files referenced in the project. + + Parameters + ---------- + project : RAT.Project + The project model, which defines the physical system under study. + + Returns + ------- + files : ClassList[CustomFile] + A list of custom file models used in the project. + + """ + used_custom_files = {} + files = {file.name: file for file in project.custom_files} + if project.model != "standard layers": + for contrast in project.contrasts: + if contrast.model: + used_custom_files[contrast.model[0]] = files[contrast.model[0]] + + for background in project.backgrounds: + if background.type == "function": + used_custom_files[background.source] = files[background.source] + + for resolution in project.resolutions: + if resolution.type == "function": + used_custom_files[resolution.source] = files[resolution.source] + + return ratapi.ClassList(list(used_custom_files.values())) + + class FileHandles: """Class to defer creation of custom file handles. @@ -206,10 +238,11 @@ def make_problem(project: ratapi.Project, validate_range: bool = False) -> Probl contrast_models = [[]] * len(project.contrasts) # Set contrast parameters according to model type + used_custom_files = get_used_custom_files(project) if project.model == LayerModels.StandardLayers: contrast_custom_files = [float("NaN")] * len(project.contrasts) else: - contrast_custom_files = [project.custom_files.index(contrast.model[0], True) for contrast in project.contrasts] + contrast_custom_files = [used_custom_files.index(contrast.model[0], True) for contrast in project.contrasts] # Get details of defined layers layer_details = get_layer_details(project) @@ -253,7 +286,7 @@ def make_problem(project: ratapi.Project, validate_range: bool = False) -> Probl data = append_data_background(data, project.data[background.source].data) elif background.type == TypeOptions.Function: - contrast_background_param.append(project.custom_files.index(background.source, True)) + contrast_background_param.append(used_custom_files.index(background.source, True)) contrast_background_param.extend( [ project.background_parameters.index(value, True) @@ -278,7 +311,7 @@ def make_problem(project: ratapi.Project, validate_range: bool = False) -> Probl contrast_resolution_types.append(resolution.type) contrast_resolution_param = [] if resolution.type == TypeOptions.Function: - contrast_resolution_param.append(project.custom_files.index(resolution.source, True)) + contrast_resolution_param.append(used_custom_files.index(resolution.source, True)) contrast_resolution_param.extend( [ project.resolution_parameters.index(value, True) @@ -334,7 +367,7 @@ def make_problem(project: ratapi.Project, validate_range: bool = False) -> Probl problem.numberOfLayers = len(project.layers) problem.contrastLayers = [contrast_model if contrast_model else [] for contrast_model in contrast_models] problem.layersDetails = layer_details if project.model == LayerModels.StandardLayers else [] - problem.customFiles = FileHandles(project.custom_files) + problem.customFiles = FileHandles(used_custom_files) problem.modelType = project.model problem.contrastCustomFiles = contrast_custom_files diff --git a/ratapi/wrappers.py b/ratapi/wrappers.py index 38f276ac..841517a3 100644 --- a/ratapi/wrappers.py +++ b/ratapi/wrappers.py @@ -51,7 +51,7 @@ def __init__(self, filename: str) -> None: raise ImportError(self.loader_error_message) from None self.engine = self.loader.result() - path = pathlib.Path(filename) + path = pathlib.Path(filename).resolve() self.engine.cd(str(path.parent), nargout=0) self.function_name = path.stem diff --git a/tests/test_inputs.py b/tests/test_inputs.py index 7d497f7e..6a230c56 100644 --- a/tests/test_inputs.py +++ b/tests/test_inputs.py @@ -10,7 +10,7 @@ import ratapi import ratapi.wrappers -from ratapi.inputs import FileHandles, check_indices, make_controls, make_input, make_problem +from ratapi.inputs import FileHandles, check_indices, get_used_custom_files, make_controls, make_input, make_problem from ratapi.rat_core import Checks, Control, NameStore, ProblemDefinition from ratapi.utils.enums import ( BackgroundActions, @@ -466,6 +466,23 @@ def test_make_input(test_project, test_problem, test_controls, request) -> None: check_controls_equal(controls, test_controls) +def test_get_used_custom_files(custom_xy_project): + """Test unused custom files are removed.""" + + used_custom_files = get_used_custom_files(custom_xy_project) + assert len(used_custom_files) == len(custom_xy_project.custom_files) + assert used_custom_files[0] == custom_xy_project.custom_files[0] + + custom_xy_project.custom_files.append(name="Test Custom File2", filename="matlab_test.m", language="matlab") + used_custom_files = get_used_custom_files(custom_xy_project) + assert len(used_custom_files) == 1 + assert used_custom_files[0].name == custom_xy_project.custom_files[0].name + + custom_xy_project.backgrounds.append(name="b2", type="function", source="Test Custom File2") + used_custom_files = get_used_custom_files(custom_xy_project) + assert len(used_custom_files) == len(custom_xy_project.custom_files) + + @pytest.mark.parametrize( ["test_project", "test_problem"], [