From 8a786d874f2ea21941c692bfc62abe37b5377116 Mon Sep 17 00:00:00 2001 From: Paul Sharp <44529197+DrPaulSharp@users.noreply.github.com> Date: Wed, 6 Aug 2025 00:13:07 +0100 Subject: [PATCH 1/3] Removes controls option "calcSLDDuringFit" --- cpp/RAT | 2 +- cpp/includes/defines.h | 6 ++-- cpp/rat.cpp | 34 +++++++++---------- ratapi/controls.py | 4 --- .../bayes_benchmark/bayes_benchmark.py | 2 +- .../languages/run_custom_file_languages.py | 1 - ratapi/inputs.py | 4 +-- ratapi/utils/enums.py | 8 ++--- setup.py | 6 ++-- tests/test_controls.py | 23 ------------- tests/test_inputs.py | 3 -- 11 files changed, 30 insertions(+), 63 deletions(-) diff --git a/cpp/RAT b/cpp/RAT index 370d46f1..16f3ebef 160000 --- a/cpp/RAT +++ b/cpp/RAT @@ -1 +1 @@ -Subproject commit 370d46f19859eb1ada7b031e6540c7747e328f82 +Subproject commit 16f3ebef737f4c85ca601046f7a30ffabee4eb47 diff --git a/cpp/includes/defines.h b/cpp/includes/defines.h index 9e8a5ff1..587feae9 100644 --- a/cpp/includes/defines.h +++ b/cpp/includes/defines.h @@ -588,8 +588,6 @@ parallel : str How the calculation should be parallelised (This uses the Parallel Computing Toolbox). Can be 'single', 'contrasts' or 'points'. procedure : str Which procedure RAT should execute. Can be 'calculate', 'simplex', 'de', 'ns', or 'dream'. -calcSldDuringFit : bool - Whether SLD will be calculated during fit (for live plotting etc.) numSimulationPoints : int The number of points used for a reflectivity simulation where no data is present. resampleMinAngle : float @@ -644,6 +642,8 @@ boundHandling : str [DREAM] How steps past the space boundaries should be handled. Can be 'off', 'reflect', 'bound', or 'fold'. adaptPCR : bool [DREAM] Whether the crossover probability for differential evolution should be adapted during the run. +calcSLD : bool + Whether SLD will be calculated (for live plotting etc.) )"; struct Control { @@ -664,7 +664,6 @@ struct Control { real_T nMCMC {}; real_T propScale {}; real_T nsTolerance {}; - boolean_T calcSldDuringFit {}; real_T numSimulationPoints {}; real_T resampleMinAngle {}; real_T resampleNPoints {}; @@ -676,6 +675,7 @@ struct Control { real_T pUnitGamma {}; std::string boundHandling {}; boolean_T adaptPCR; + boolean_T calcSLD {}; std::string IPCFilePath {}; }; diff --git a/cpp/rat.cpp b/cpp/rat.cpp index ddec2782..ac31e99e 100644 --- a/cpp/rat.cpp +++ b/cpp/rat.cpp @@ -317,7 +317,6 @@ RAT::Controls createControlsStruct(const Control& control) control_struct.nMCMC = control.nMCMC; control_struct.propScale = control.propScale; control_struct.nsTolerance = control.nsTolerance; - control_struct.calcSldDuringFit = control.calcSldDuringFit; control_struct.numSimulationPoints = control.numSimulationPoints; control_struct.updateFreq = control.updateFreq; control_struct.updatePlotFreq = control.updatePlotFreq; @@ -333,6 +332,7 @@ RAT::Controls createControlsStruct(const Control& control) control_struct.resampleNPoints = control.resampleNPoints; stringToRatBoundedArray(control.boundHandling, control_struct.boundHandling.data, control_struct.boundHandling.size); control_struct.adaptPCR = control.adaptPCR; + control_struct.calcSLD = control.calcSLD; stringToRatBoundedArray(control.IPCFilePath, control_struct.IPCFilePath.data, control_struct.IPCFilePath.size); return control_struct; @@ -910,7 +910,6 @@ PYBIND11_MODULE(rat_core, m) { .def_readwrite("nMCMC", &Control::nMCMC) .def_readwrite("propScale", &Control::propScale) .def_readwrite("nsTolerance", &Control::nsTolerance) - .def_readwrite("calcSldDuringFit", &Control::calcSldDuringFit) .def_readwrite("numSimulationPoints", &Control::numSimulationPoints) .def_readwrite("resampleMinAngle", &Control::resampleMinAngle) .def_readwrite("resampleNPoints", &Control::resampleNPoints) @@ -922,6 +921,7 @@ PYBIND11_MODULE(rat_core, m) { .def_readwrite("pUnitGamma", &Control::pUnitGamma) .def_readwrite("boundHandling", &Control::boundHandling) .def_readwrite("adaptPCR", &Control::adaptPCR) + .def_readwrite("calcSLD", &Control::calcSLD) .def_readwrite("IPCFilePath", &Control::IPCFilePath) .def(py::pickle( [](const Control &ctrl) { // __getstate__ @@ -929,9 +929,9 @@ PYBIND11_MODULE(rat_core, m) { return py::make_tuple(ctrl.parallel, ctrl.procedure, ctrl.display, ctrl.xTolerance, ctrl.funcTolerance, ctrl.maxFuncEvals, ctrl.maxIterations, ctrl.populationSize, ctrl.fWeight, ctrl.crossoverProbability, ctrl.targetValue, ctrl.numGenerations, ctrl.strategy, ctrl.nLive, ctrl.nMCMC, ctrl.propScale, - ctrl.nsTolerance, ctrl.calcSldDuringFit, ctrl.numSimulationPoints, ctrl.resampleMinAngle, ctrl.resampleNPoints, - ctrl.updateFreq, ctrl.updatePlotFreq, ctrl.nSamples, ctrl.nChains, ctrl.jumpProbability, ctrl.pUnitGamma, - ctrl.boundHandling, ctrl.adaptPCR, ctrl.IPCFilePath); + ctrl.nsTolerance, ctrl.numSimulationPoints, ctrl.resampleMinAngle, ctrl.resampleNPoints, + ctrl.updateFreq, ctrl.updatePlotFreq, ctrl.nSamples, ctrl.nChains, ctrl.jumpProbability, + ctrl.pUnitGamma, ctrl.boundHandling, ctrl.adaptPCR, ctrl.calcSLD, ctrl.IPCFilePath); }, [](py::tuple t) { // __setstate__ if (t.size() != 30) @@ -957,18 +957,18 @@ PYBIND11_MODULE(rat_core, m) { ctrl.nMCMC = t[14].cast(); ctrl.propScale = t[15].cast(); ctrl.nsTolerance = t[16].cast(); - ctrl.calcSldDuringFit = t[17].cast(); - ctrl.numSimulationPoints = t[18].cast(); - ctrl.resampleMinAngle = t[19].cast(); - ctrl.resampleNPoints = t[20].cast(); - ctrl.updateFreq = t[21].cast(); - ctrl.updatePlotFreq = t[22].cast(); - ctrl.nSamples = t[23].cast(); - ctrl.nChains = t[24].cast(); - ctrl.jumpProbability = t[25].cast(); - ctrl.pUnitGamma = t[26].cast(); - ctrl.boundHandling = t[27].cast(); - ctrl.adaptPCR = t[28].cast(); + ctrl.numSimulationPoints = t[17].cast(); + ctrl.resampleMinAngle = t[18].cast(); + ctrl.resampleNPoints = t[19].cast(); + ctrl.updateFreq = t[20].cast(); + ctrl.updatePlotFreq = t[21].cast(); + ctrl.nSamples = t[22].cast(); + ctrl.nChains = t[23].cast(); + ctrl.jumpProbability = t[24].cast(); + ctrl.pUnitGamma = t[25].cast(); + ctrl.boundHandling = t[26].cast(); + ctrl.adaptPCR = t[27].cast(); + ctrl.calcSLD = t[28].cast(); ctrl.IPCFilePath = t[29].cast(); return ctrl; diff --git a/ratapi/controls.py b/ratapi/controls.py index 917d78eb..c5408411 100644 --- a/ratapi/controls.py +++ b/ratapi/controls.py @@ -23,7 +23,6 @@ common_fields = [ "procedure", "parallel", - "calcSldDuringFit", "numSimulationPoints", "resampleMinAngle", "resampleNPoints", @@ -58,9 +57,6 @@ class Controls(BaseModel, validate_assignment=True, extra="forbid", use_attribut parallel: Parallel = Parallel.Single """How the calculation should be parallelised. Can be 'single', 'contrasts' or 'points'.""" - calcSldDuringFit: bool = False - """Whether SLD will be calculated during fit (for live plotting etc.)""" - numSimulationPoints: int = Field(500, ge=2) """The number of points used for reflectivity simulations where no data is supplied.""" diff --git a/ratapi/examples/bayes_benchmark/bayes_benchmark.py b/ratapi/examples/bayes_benchmark/bayes_benchmark.py index 9840b002..ee6ea96e 100644 --- a/ratapi/examples/bayes_benchmark/bayes_benchmark.py +++ b/ratapi/examples/bayes_benchmark/bayes_benchmark.py @@ -250,7 +250,7 @@ def bayes_benchmark_3d(grid_size: int) -> (RAT.outputs.BayesResults, Calculation scale_param = problem.scalefactors[0] scalefactor = np.linspace(scale_param.min, scale_param.max, grid_size) - controls = RAT.Controls(procedure="calculate", calcSldDuringFit=True, display="off") + controls = RAT.Controls(procedure="calculate", display="off") def calculate_posterior(roughness_index: int, background_index: int, scalefactor_index: int) -> float: """Calculate the posterior for an item in the roughness, background, and scalefactor vectors. diff --git a/ratapi/examples/languages/run_custom_file_languages.py b/ratapi/examples/languages/run_custom_file_languages.py index 6e69f80e..2f6025ae 100644 --- a/ratapi/examples/languages/run_custom_file_languages.py +++ b/ratapi/examples/languages/run_custom_file_languages.py @@ -11,7 +11,6 @@ project = setup_problem.make_example_problem() controls = RAT.Controls() -controls.calcSldDuringFit = True # Python start = time.time() diff --git a/ratapi/inputs.py b/ratapi/inputs.py index 34b695d3..78a7cf8d 100644 --- a/ratapi/inputs.py +++ b/ratapi/inputs.py @@ -552,7 +552,6 @@ def make_controls(input_controls: ratapi.Controls) -> Control: controls.procedure = input_controls.procedure controls.parallel = input_controls.parallel - controls.calcSldDuringFit = input_controls.calcSldDuringFit controls.numSimulationPoints = input_controls.numSimulationPoints controls.resampleMinAngle = input_controls.resampleMinAngle controls.resampleNPoints = input_controls.resampleNPoints @@ -583,9 +582,8 @@ def make_controls(input_controls: ratapi.Controls) -> Control: controls.pUnitGamma = input_controls.pUnitGamma controls.boundHandling = input_controls.boundHandling controls.adaptPCR = input_controls.adaptPCR - # IPC - controls.IPCFilePath = "" + controls.calcSLD = False controls.IPCFilePath = input_controls._IPCFilePath return controls diff --git a/ratapi/utils/enums.py b/ratapi/utils/enums.py index 43272355..24c50cbc 100644 --- a/ratapi/utils/enums.py +++ b/ratapi/utils/enums.py @@ -73,22 +73,22 @@ class Strategies(RATEnum): """The base vector is random.""" LocalToBest = "local to best" - """The base vector is a combination of one randomly-selected local solution + """The base vector is a combination of one randomly-selected local solution and the best solution of the previous iteration.""" BestWithJitter = "best jitter" """The base vector is the best solution of the previous iteration, with a small random perturbation applied.""" RandomWithPerVectorDither = "vector dither" - """The base vector is random, with a random scaling factor applied to each mutant. + """The base vector is random, with a random scaling factor applied to each mutant. This scaling factor is different for each mutant.""" RandomWithPerGenerationDither = "generation dither" - """The base vector is random, with a random scaling factor applied to each mutant. + """The base vector is random, with a random scaling factor applied to each mutant. This scaling factor is the same for every mutant, and randomised every generation.""" RandomEitherOrAlgorithm = "either or" - """The base vector is randomly chosen from either a pure random mutation, + """The base vector is randomly chosen from either a pure random mutation, or a pure recombination of parent parameter values.""" @classmethod diff --git a/setup.py b/setup.py index 30763b21..bda3a43a 100644 --- a/setup.py +++ b/setup.py @@ -61,8 +61,8 @@ class BuildExt(build_ext): """A custom build extension for adding compiler-specific options.""" c_opts = { - "msvc": ["/EHsc"], - "unix": ["-fopenmp", "-std=c++11"], + "msvc": ["/O2", "/EHsc"], + "unix": ["-O2", "-fopenmp", "-std=c++11"], } l_opts = { "msvc": [], @@ -71,7 +71,7 @@ class BuildExt(build_ext): if sys.platform == "darwin": darwin_opts = ["-stdlib=libc++", "-mmacosx-version-min=10.9"] - c_opts["unix"] = [*darwin_opts, "-fopenmp"] + c_opts["unix"] = [*darwin_opts, "-fopenmp", "-O2"] l_opts["unix"] = [*darwin_opts, "-lomp"] def build_extensions(self): diff --git a/tests/test_controls.py b/tests/test_controls.py index 3e668795..72f0c745 100644 --- a/tests/test_controls.py +++ b/tests/test_controls.py @@ -60,7 +60,6 @@ def table_str(self): "+---------------------+-----------+\n" "| procedure | calculate |\n" "| parallel | single |\n" - "| calcSldDuringFit | False |\n" "| numSimulationPoints | 500 |\n" "| resampleMinAngle | 0.9 |\n" "| resampleNPoints | 50 |\n" @@ -74,7 +73,6 @@ def table_str(self): "control_property, value", [ ("parallel", Parallel.Single), - ("calcSldDuringFit", False), ("numSimulationPoints", 500), ("resampleMinAngle", 0.9), ("resampleNPoints", 50), @@ -90,7 +88,6 @@ def test_calculate_property_values(self, control_property: str, value: Any) -> N "control_property, value", [ ("parallel", Parallel.Points), - ("calcSldDuringFit", True), ("numSimulationPoints", 10), ("resampleMinAngle", 0.2), ("resampleNPoints", 1), @@ -186,14 +183,6 @@ def test_calculate_parallel_validation(self, value: Any) -> None: with pytest.raises(pydantic.ValidationError, match="Input should be 'single', 'points' or 'contrasts'"): self.calculate.parallel = value - @pytest.mark.parametrize("value", [5.0, 12]) - def test_calculate_calcSldDuringFit_validation(self, value: Union[int, float]) -> None: - """Tests the calcSldDuringFit setter validation in Calculate class.""" - with pytest.raises( - pydantic.ValidationError, match="Input should be a valid boolean, unable to interpret input" - ): - self.calculate.calcSldDuringFit = value - @pytest.mark.parametrize("value", ["test", "iterate", True, 1, 3.0]) def test_calculate_display_validation(self, value: Any) -> None: """Tests the display setter validation in Calculate class.""" @@ -220,7 +209,6 @@ def table_str(self): "+---------------------+---------+\n" "| procedure | simplex |\n" "| parallel | single |\n" - "| calcSldDuringFit | False |\n" "| numSimulationPoints | 500 |\n" "| resampleMinAngle | 0.9 |\n" "| resampleNPoints | 50 |\n" @@ -240,7 +228,6 @@ def table_str(self): "control_property, value", [ ("parallel", Parallel.Single), - ("calcSldDuringFit", False), ("numSimulationPoints", 500), ("resampleMinAngle", 0.9), ("resampleNPoints", 50), @@ -262,7 +249,6 @@ def test_simplex_property_values(self, control_property: str, value: Any) -> Non "control_property, value", [ ("parallel", Parallel.Points), - ("calcSldDuringFit", True), ("numSimulationPoints", 10), ("resampleMinAngle", 0.2), ("resampleNPoints", 1), @@ -380,7 +366,6 @@ def table_str(self): "+----------------------+---------------+\n" "| procedure | de |\n" "| parallel | single |\n" - "| calcSldDuringFit | False |\n" "| numSimulationPoints | 500 |\n" "| resampleMinAngle | 0.9 |\n" "| resampleNPoints | 50 |\n" @@ -402,7 +387,6 @@ def table_str(self): "control_property, value", [ ("parallel", Parallel.Single), - ("calcSldDuringFit", False), ("numSimulationPoints", 500), ("resampleMinAngle", 0.9), ("resampleNPoints", 50), @@ -424,7 +408,6 @@ def test_de_property_values(self, control_property: str, value: Any) -> None: "control_property, value", [ ("parallel", Parallel.Points), - ("calcSldDuringFit", True), ("numSimulationPoints", 10), ("resampleMinAngle", 0.2), ("resampleNPoints", 1), @@ -556,7 +539,6 @@ def table_str(self): "+---------------------+--------+\n" "| procedure | ns |\n" "| parallel | single |\n" - "| calcSldDuringFit | False |\n" "| numSimulationPoints | 500 |\n" "| resampleMinAngle | 0.9 |\n" "| resampleNPoints | 50 |\n" @@ -574,7 +556,6 @@ def table_str(self): "control_property, value", [ ("parallel", Parallel.Single), - ("calcSldDuringFit", False), ("numSimulationPoints", 500), ("resampleMinAngle", 0.9), ("resampleNPoints", 50), @@ -594,7 +575,6 @@ def test_ns_property_values(self, control_property: str, value: Any) -> None: "control_property, value", [ ("parallel", Parallel.Points), - ("calcSldDuringFit", True), ("numSimulationPoints", 10), ("resampleMinAngle", 0.2), ("resampleNPoints", 1), @@ -725,7 +705,6 @@ def table_str(self): "+---------------------+---------+\n" "| procedure | dream |\n" "| parallel | single |\n" - "| calcSldDuringFit | False |\n" "| numSimulationPoints | 500 |\n" "| resampleMinAngle | 0.9 |\n" "| resampleNPoints | 50 |\n" @@ -745,7 +724,6 @@ def table_str(self): "control_property, value", [ ("parallel", Parallel.Single), - ("calcSldDuringFit", False), ("numSimulationPoints", 500), ("resampleMinAngle", 0.9), ("resampleNPoints", 50), @@ -767,7 +745,6 @@ def test_dream_property_values(self, control_property: str, value: Any) -> None: "control_property, value", [ ("parallel", Parallel.Points), - ("calcSldDuringFit", True), ("numSimulationPoints", 10), ("resampleMinAngle", 0.2), ("resampleNPoints", 1), diff --git a/tests/test_inputs.py b/tests/test_inputs.py index 2c207928..db5b6646 100644 --- a/tests/test_inputs.py +++ b/tests/test_inputs.py @@ -359,7 +359,6 @@ def standard_layers_controls(): controls = Control() controls.procedure = Procedures.Calculate controls.parallel = Parallel.Single - controls.calcSldDuringFit = False controls.numSimulationPoints = 500 controls.resampleMinAngle = 0.9 controls.resampleNPoints = 50 @@ -398,7 +397,6 @@ def custom_xy_controls(): controls = Control() controls.procedure = Procedures.Calculate controls.parallel = Parallel.Single - controls.calcSldDuringFit = False controls.numSimulationPoints = 500 controls.resampleMinAngle = 0.9 controls.resampleNPoints = 50.0 @@ -757,7 +755,6 @@ def check_controls_equal(actual_controls, expected_controls) -> None: controls_fields = [ "procedure", "parallel", - "calcSldDuringFit", "numSimulationPoints", "resampleMinAngle", "resampleNPoints", From 4242843ef707134113f5dfd0218a3e486dbf5ee2 Mon Sep 17 00:00:00 2001 From: Paul Sharp <44529197+DrPaulSharp@users.noreply.github.com> Date: Wed, 6 Aug 2025 15:53:13 +0100 Subject: [PATCH 2/3] Addresses review comment --- cpp/rat.cpp | 2 +- ratapi/inputs.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cpp/rat.cpp b/cpp/rat.cpp index ac31e99e..7b33da8f 100644 --- a/cpp/rat.cpp +++ b/cpp/rat.cpp @@ -332,7 +332,7 @@ RAT::Controls createControlsStruct(const Control& control) control_struct.resampleNPoints = control.resampleNPoints; stringToRatBoundedArray(control.boundHandling, control_struct.boundHandling.data, control_struct.boundHandling.size); control_struct.adaptPCR = control.adaptPCR; - control_struct.calcSLD = control.calcSLD; + control_struct.calcSLD = false; stringToRatBoundedArray(control.IPCFilePath, control_struct.IPCFilePath.data, control_struct.IPCFilePath.size); return control_struct; diff --git a/ratapi/inputs.py b/ratapi/inputs.py index 78a7cf8d..890066f9 100644 --- a/ratapi/inputs.py +++ b/ratapi/inputs.py @@ -583,7 +583,6 @@ def make_controls(input_controls: ratapi.Controls) -> Control: controls.boundHandling = input_controls.boundHandling controls.adaptPCR = input_controls.adaptPCR - controls.calcSLD = False controls.IPCFilePath = input_controls._IPCFilePath return controls From c31b121ff55ad7a925a4fa406db9571ff7a70913 Mon Sep 17 00:00:00 2001 From: Paul Sharp <44529197+DrPaulSharp@users.noreply.github.com> Date: Thu, 7 Aug 2025 09:48:48 +0100 Subject: [PATCH 3/3] Addresses further review comments --- cpp/includes/defines.h | 3 --- cpp/rat.cpp | 8 +++----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/cpp/includes/defines.h b/cpp/includes/defines.h index 587feae9..097ad0eb 100644 --- a/cpp/includes/defines.h +++ b/cpp/includes/defines.h @@ -642,8 +642,6 @@ boundHandling : str [DREAM] How steps past the space boundaries should be handled. Can be 'off', 'reflect', 'bound', or 'fold'. adaptPCR : bool [DREAM] Whether the crossover probability for differential evolution should be adapted during the run. -calcSLD : bool - Whether SLD will be calculated (for live plotting etc.) )"; struct Control { @@ -675,7 +673,6 @@ struct Control { real_T pUnitGamma {}; std::string boundHandling {}; boolean_T adaptPCR; - boolean_T calcSLD {}; std::string IPCFilePath {}; }; diff --git a/cpp/rat.cpp b/cpp/rat.cpp index 7b33da8f..31bbe144 100644 --- a/cpp/rat.cpp +++ b/cpp/rat.cpp @@ -921,7 +921,6 @@ PYBIND11_MODULE(rat_core, m) { .def_readwrite("pUnitGamma", &Control::pUnitGamma) .def_readwrite("boundHandling", &Control::boundHandling) .def_readwrite("adaptPCR", &Control::adaptPCR) - .def_readwrite("calcSLD", &Control::calcSLD) .def_readwrite("IPCFilePath", &Control::IPCFilePath) .def(py::pickle( [](const Control &ctrl) { // __getstate__ @@ -931,10 +930,10 @@ PYBIND11_MODULE(rat_core, m) { ctrl.targetValue, ctrl.numGenerations, ctrl.strategy, ctrl.nLive, ctrl.nMCMC, ctrl.propScale, ctrl.nsTolerance, ctrl.numSimulationPoints, ctrl.resampleMinAngle, ctrl.resampleNPoints, ctrl.updateFreq, ctrl.updatePlotFreq, ctrl.nSamples, ctrl.nChains, ctrl.jumpProbability, - ctrl.pUnitGamma, ctrl.boundHandling, ctrl.adaptPCR, ctrl.calcSLD, ctrl.IPCFilePath); + ctrl.pUnitGamma, ctrl.boundHandling, ctrl.adaptPCR, ctrl.IPCFilePath); }, [](py::tuple t) { // __setstate__ - if (t.size() != 30) + if (t.size() != 29) throw std::runtime_error("Encountered invalid state unpickling ProblemDefinition object!"); /* Create a new C++ instance */ @@ -968,8 +967,7 @@ PYBIND11_MODULE(rat_core, m) { ctrl.pUnitGamma = t[25].cast(); ctrl.boundHandling = t[26].cast(); ctrl.adaptPCR = t[27].cast(); - ctrl.calcSLD = t[28].cast(); - ctrl.IPCFilePath = t[29].cast(); + ctrl.IPCFilePath = t[28].cast(); return ctrl; }));