From cd47b6b12c4b06413f713d7f91f090cf88f87f3b Mon Sep 17 00:00:00 2001 From: Matthias Puchner <github@mpuchner.de> Date: Fri, 30 Apr 2021 16:01:36 +0200 Subject: [PATCH] refactor fitting tests to latest samplebuilder paradigm A sample builder shall get the parameter values already at construction time, not afterwards. This also eliminates the usage of registered parameters --- Sample/StandardSamples/CylindersBuilder.cpp | 3 +- Sample/StandardSamples/CylindersBuilder.h | 2 +- .../PlainMultiLayerBySLDBuilder.cpp | 4 +- .../PlainMultiLayerBySLDBuilder.h | 2 +- Sample/StandardSamples/ResonatorBuilder.cpp | 3 +- Sample/StandardSamples/ResonatorBuilder.h | 2 +- .../Core/Fitting/AdjustMinimizerPlan.cpp | 11 ++- .../Core/Fitting/AdjustMinimizerPlan.h | 4 + Tests/Functional/Core/Fitting/Plan.cpp | 18 ----- Tests/Functional/Core/Fitting/Plan.h | 7 +- Tests/Functional/Core/Fitting/PlanCases.cpp | 76 +++++++++++++++++-- Tests/Functional/Core/Fitting/PlanCases.h | 29 +++++++ 12 files changed, 124 insertions(+), 37 deletions(-) diff --git a/Sample/StandardSamples/CylindersBuilder.cpp b/Sample/StandardSamples/CylindersBuilder.cpp index bef842f6d59..17758944682 100644 --- a/Sample/StandardSamples/CylindersBuilder.cpp +++ b/Sample/StandardSamples/CylindersBuilder.cpp @@ -50,7 +50,8 @@ MultiLayer* CylindersInDWBABuilder::buildSample() const // ----------------------------------------------------------------------------- // Cylinders in BA // ----------------------------------------------------------------------------- -CylindersInBABuilder::CylindersInBABuilder() : m_height(5 * Units::nm), m_radius(5 * Units::nm) +CylindersInBABuilder::CylindersInBABuilder(double height, double radius) + : m_height(height * Units::nm), m_radius(radius * Units::nm) { registerParameter("height", &m_height); registerParameter("radius", &m_radius); diff --git a/Sample/StandardSamples/CylindersBuilder.h b/Sample/StandardSamples/CylindersBuilder.h index 280fa725be6..6f85f664567 100644 --- a/Sample/StandardSamples/CylindersBuilder.h +++ b/Sample/StandardSamples/CylindersBuilder.h @@ -40,7 +40,7 @@ private: class CylindersInBABuilder : public ISampleBuilder { public: - CylindersInBABuilder(); + CylindersInBABuilder(double height = 5, double radius = 5); MultiLayer* buildSample() const; private: diff --git a/Sample/StandardSamples/PlainMultiLayerBySLDBuilder.cpp b/Sample/StandardSamples/PlainMultiLayerBySLDBuilder.cpp index 477ecd52cf6..b3d0edf3761 100644 --- a/Sample/StandardSamples/PlainMultiLayerBySLDBuilder.cpp +++ b/Sample/StandardSamples/PlainMultiLayerBySLDBuilder.cpp @@ -18,12 +18,12 @@ #include "Sample/Multilayer/Layer.h" #include "Sample/Multilayer/MultiLayer.h" -PlainMultiLayerBySLDBuilder::PlainMultiLayerBySLDBuilder(int n_layers) +PlainMultiLayerBySLDBuilder::PlainMultiLayerBySLDBuilder(int n_layers, double thick_ti) : m_number_of_layers(n_layers) , m_si{2.0704e-06, 2.3726e-11} , m_ti{-1.9493e-06, 9.6013e-10} , m_ni{9.4245e-06, 1.1423e-09} - , m_thick_ti(3.0) + , m_thick_ti(thick_ti) , m_thick_ni(7.0) { registerParameter("ti_thickness", &m_thick_ti); diff --git a/Sample/StandardSamples/PlainMultiLayerBySLDBuilder.h b/Sample/StandardSamples/PlainMultiLayerBySLDBuilder.h index 22e136d2f8b..640208ac5e3 100644 --- a/Sample/StandardSamples/PlainMultiLayerBySLDBuilder.h +++ b/Sample/StandardSamples/PlainMultiLayerBySLDBuilder.h @@ -28,7 +28,7 @@ class PlainMultiLayerBySLDBuilder : public ISampleBuilder { public: - PlainMultiLayerBySLDBuilder(int n_layers = 10); + PlainMultiLayerBySLDBuilder(int n_layers = 10, double thick_ti = 3.0); MultiLayer* buildSample() const override; // passes ownership protected: diff --git a/Sample/StandardSamples/ResonatorBuilder.cpp b/Sample/StandardSamples/ResonatorBuilder.cpp index 073083a76bc..d0bb6fa3ee0 100644 --- a/Sample/StandardSamples/ResonatorBuilder.cpp +++ b/Sample/StandardSamples/ResonatorBuilder.cpp @@ -20,7 +20,8 @@ #include "Sample/Slice/LayerRoughness.h" #include <memory> -ResonatorBuilder::ResonatorBuilder() : ISampleBuilder(), m_l_ti(13.0 * Units::nm) +ResonatorBuilder::ResonatorBuilder(double ti_thickness) + : ISampleBuilder(), m_l_ti(ti_thickness * Units::nm) { registerParameter("ti_thickness", &m_l_ti); } diff --git a/Sample/StandardSamples/ResonatorBuilder.h b/Sample/StandardSamples/ResonatorBuilder.h index a5b936ff744..387b2dd4536 100644 --- a/Sample/StandardSamples/ResonatorBuilder.h +++ b/Sample/StandardSamples/ResonatorBuilder.h @@ -27,7 +27,7 @@ class ResonatorBuilder : public ISampleBuilder { public: - ResonatorBuilder(); + ResonatorBuilder(double ti_thickness = 13.0); MultiLayer* buildSample() const; private: diff --git a/Tests/Functional/Core/Fitting/AdjustMinimizerPlan.cpp b/Tests/Functional/Core/Fitting/AdjustMinimizerPlan.cpp index 6f0483bbba9..06d97529a08 100644 --- a/Tests/Functional/Core/Fitting/AdjustMinimizerPlan.cpp +++ b/Tests/Functional/Core/Fitting/AdjustMinimizerPlan.cpp @@ -16,6 +16,8 @@ #include "Base/Const/Units.h" #include "Core/Fitting/FitObjective.h" #include "Fit/Kernel/Minimizer.h" +#include "Sample/Multilayer/MultiLayer.h" +#include "Sample/StandardSamples/CylindersBuilder.h" #include <iostream> namespace { @@ -26,7 +28,6 @@ using namespace mumufit; AdjustMinimizerPlan::AdjustMinimizerPlan() : Plan("AdjustMinimizerPlan") { - setBuilderName("CylindersInBABuilder"); setSimulationName("MiniGISASFit"); addParameter(Parameter("height", 2.0 * nm, AttLimits::limited(0.01, 30.0), 0.05), 5.0 * nm); addParameter(Parameter("radius", 10.0 * nm, AttLimits::limited(0.01, 30.0), 0.05), 5.0 * nm); @@ -59,3 +60,11 @@ bool AdjustMinimizerPlan::checkMinimizer(mumufit::Minimizer& minimizer) return success; } + +std::unique_ptr<MultiLayer> +AdjustMinimizerPlan::createMultiLayer(const mumufit::Parameters& params) const +{ + CylindersInBABuilder sampleBuilder(params["height"].value(), params["radius"].value()); + + return std::unique_ptr<MultiLayer>(sampleBuilder.buildSample()); +} diff --git a/Tests/Functional/Core/Fitting/AdjustMinimizerPlan.h b/Tests/Functional/Core/Fitting/AdjustMinimizerPlan.h index 9ab90761286..0639b60ea9a 100644 --- a/Tests/Functional/Core/Fitting/AdjustMinimizerPlan.h +++ b/Tests/Functional/Core/Fitting/AdjustMinimizerPlan.h @@ -25,6 +25,10 @@ public: AdjustMinimizerPlan(); bool checkMinimizer(mumufit::Minimizer& minimizer); + +protected: + virtual std::unique_ptr<MultiLayer> + createMultiLayer(const mumufit::Parameters& params) const override; }; #endif // BORNAGAIN_TESTS_FUNCTIONAL_CORE_FITTING_ADJUSTMINIMIZERPLAN_H diff --git a/Tests/Functional/Core/Fitting/Plan.cpp b/Tests/Functional/Core/Fitting/Plan.cpp index ae888bebfe8..822cb482b7a 100644 --- a/Tests/Functional/Core/Fitting/Plan.cpp +++ b/Tests/Functional/Core/Fitting/Plan.cpp @@ -55,11 +55,6 @@ bool Plan::checkMinimizer(mumufit::Minimizer& minimizer) return success; } -void Plan::setBuilderName(const std::string& name) -{ - m_sample_builder_name = name; -} - void Plan::setSimulationName(const std::string& name) { m_simulation_name = name; @@ -96,19 +91,6 @@ std::unique_ptr<ISimulation> Plan::createSimulation(const mumufit::Parameters&) return SimulationFactory().createItemPtr(m_simulation_name); } -//! Creates sample for given set of fit parameters. - -std::unique_ptr<MultiLayer> Plan::createMultiLayer(const mumufit::Parameters& params) const -{ - auto sample_builder = SampleBuilderFactory().createItemPtr(m_sample_builder_name); - - // propagating current values of fit parameters to sample builder before building the sample - for (const auto& par : params) - sample_builder->registeredParameter(par.name())->setValue(par.value()); - - return std::unique_ptr<MultiLayer>(sample_builder->buildSample()); -} - //! Creates "experimental" data for fitting. std::unique_ptr<OutputData<double>> Plan::createOutputData() const diff --git a/Tests/Functional/Core/Fitting/Plan.h b/Tests/Functional/Core/Fitting/Plan.h index a39e2a37aec..621a1c85dca 100644 --- a/Tests/Functional/Core/Fitting/Plan.h +++ b/Tests/Functional/Core/Fitting/Plan.h @@ -36,18 +36,19 @@ public: virtual bool checkMinimizer(mumufit::Minimizer& minimizer); - void setBuilderName(const std::string& name); void setSimulationName(const std::string& name); protected: virtual std::unique_ptr<FitObjective> createFitObjective() const; virtual std::unique_ptr<ISimulation> buildSimulation(const mumufit::Parameters& params) const; virtual std::unique_ptr<ISimulation> createSimulation(const mumufit::Parameters& params) const; - virtual std::unique_ptr<MultiLayer> createMultiLayer(const mumufit::Parameters& params) const; + + //! Creates sample for given set of fit parameters. + virtual std::unique_ptr<MultiLayer> + createMultiLayer(const mumufit::Parameters& params) const = 0; virtual std::unique_ptr<OutputData<double>> createOutputData() const; std::string m_simulation_name; - std::string m_sample_builder_name; bool m_residual_based; }; diff --git a/Tests/Functional/Core/Fitting/PlanCases.cpp b/Tests/Functional/Core/Fitting/PlanCases.cpp index cac0eb79f7d..46b1e63df26 100644 --- a/Tests/Functional/Core/Fitting/PlanCases.cpp +++ b/Tests/Functional/Core/Fitting/PlanCases.cpp @@ -25,6 +25,9 @@ #include "Sample/Multilayer/Layer.h" #include "Sample/Multilayer/MultiLayer.h" #include "Sample/Particle/Particle.h" +#include "Sample/StandardSamples/CylindersBuilder.h" +#include "Sample/StandardSamples/PlainMultiLayerBySLDBuilder.h" +#include "Sample/StandardSamples/ResonatorBuilder.h" using namespace mumufit; @@ -34,15 +37,23 @@ const double nm = Units::nm; CylindersInBAPlan::CylindersInBAPlan() : Plan("CylindersInBAPlan") { - setBuilderName("CylindersInBABuilder"); setSimulationName("MiniGISAS"); addParameter(Parameter("height", 4.5 * nm, AttLimits::lowerLimited(0.01), 0.01), 5.0 * nm); addParameter(Parameter("radius", 5.5 * nm, AttLimits::lowerLimited(0.01), 0.01), 5.0 * nm); } +std::unique_ptr<MultiLayer> +CylindersInBAPlan::createMultiLayer(const mumufit::Parameters& params) const +{ + CylindersInBABuilder sampleBuilder(params["height"].value(), params["radius"].value()); + + return std::unique_ptr<MultiLayer>(sampleBuilder.buildSample()); +} + +// ---------------------------------------------------------------------------- + CylindersInBAEasyPlan::CylindersInBAEasyPlan() : Plan("CylindersInBAEasyPlan") { - setBuilderName("CylindersInBABuilder"); setSimulationName("MiniGISASFit"); const double tolerance = 0.1; addParameter(Parameter("height", 4.5 * nm, AttLimits::limited(4.0, 6.0), 0.1), 5.0 * nm, @@ -51,20 +62,36 @@ CylindersInBAEasyPlan::CylindersInBAEasyPlan() : Plan("CylindersInBAEasyPlan") tolerance); } +std::unique_ptr<MultiLayer> +CylindersInBAEasyPlan::createMultiLayer(const mumufit::Parameters& params) const +{ + CylindersInBABuilder sampleBuilder(params["height"].value(), params["radius"].value()); + + return std::unique_ptr<MultiLayer>(sampleBuilder.buildSample()); +} + +// ---------------------------------------------------------------------------- + CylindersInBAResidualPlan::CylindersInBAResidualPlan() : Plan("CylindersInBAResidualPlan", /*residual_based*/ true) { - setBuilderName("CylindersInBABuilder"); setSimulationName("MiniGISAS"); addParameter(Parameter("height", 4.5 * nm, AttLimits::limitless(), 0.01), 5.0 * nm); addParameter(Parameter("radius", 5.5 * nm, AttLimits::limitless(), 0.01), 5.0 * nm); } +std::unique_ptr<MultiLayer> +CylindersInBAResidualPlan::createMultiLayer(const mumufit::Parameters& params) const +{ + CylindersInBABuilder sampleBuilder(params["height"].value(), params["radius"].value()); + + return std::unique_ptr<MultiLayer>(sampleBuilder.buildSample()); +} + // ---------------------------------------------------------------------------- RectDetPlan::RectDetPlan() : Plan("RectDetPlan") { - setBuilderName("CylindersInBABuilder"); addParameter(Parameter("height", 4.5 * nm, AttLimits::limited(4.0, 6.0), 0.01), 5.0 * nm); addParameter(Parameter("radius", 5.5 * nm, AttLimits::limited(4.0, 6.0), 0.01), 5.0 * nm); } @@ -87,32 +114,50 @@ std::unique_ptr<ISimulation> RectDetPlan::createSimulation(const Parameters&) co return std::unique_ptr<ISimulation>(result.release()); } +std::unique_ptr<MultiLayer> RectDetPlan::createMultiLayer(const mumufit::Parameters& params) const +{ + CylindersInBABuilder sampleBuilder(params["height"].value(), params["radius"].value()); + + return std::unique_ptr<MultiLayer>(sampleBuilder.buildSample()); +} + // ---------------------------------------------------------------------------- SpecularPlan::SpecularPlan() : Plan("SpecularPlan") { setSimulationName("BasicSpecular"); - setBuilderName("PlainMultiLayerBySLDBuilder"); addParameter(Parameter("ti_thickness", 5.0 * nm, AttLimits::limited(1.0 * nm, 7.0 * nm), 0.1), 3.0 * nm); } +std::unique_ptr<MultiLayer> SpecularPlan::createMultiLayer(const mumufit::Parameters& params) const +{ + PlainMultiLayerBySLDBuilder sampleBuilder(10, params["ti_thickness"].value()); + + return std::unique_ptr<MultiLayer>(sampleBuilder.buildSample()); +} + // ---------------------------------------------------------------------------- SpecularPlanQ::SpecularPlanQ() : Plan("SpecularPlanQ") { setSimulationName("BasicSpecularQ"); - setBuilderName("PlainMultiLayerBySLDBuilder"); addParameter(Parameter("ti_thickness", 5.0 * nm, AttLimits::limited(1.0 * nm, 7.0 * nm), 0.1), 3.0 * nm); } +std::unique_ptr<MultiLayer> SpecularPlanQ::createMultiLayer(const mumufit::Parameters& params) const +{ + PlainMultiLayerBySLDBuilder sampleBuilder(10, params["ti_thickness"].value()); + + return std::unique_ptr<MultiLayer>(sampleBuilder.buildSample()); +} + // ---------------------------------------------------------------------------- MultipleSpecPlan::MultipleSpecPlan() : Plan("MultipleSpecPlan") { setSimulationName("BasicSpecular"); - setBuilderName("PlainMultiLayerBySLDBuilder"); addParameter(Parameter("ti_thickness", 5.0 * nm, AttLimits::limited(1.0 * nm, 7.0 * nm), 0.1), 3.0 * nm); } @@ -134,13 +179,28 @@ std::unique_ptr<FitObjective> MultipleSpecPlan::createFitObjective() const return result; } +std::unique_ptr<MultiLayer> +MultipleSpecPlan::createMultiLayer(const mumufit::Parameters& params) const +{ + PlainMultiLayerBySLDBuilder sampleBuilder(10, params["ti_thickness"].value()); + + return std::unique_ptr<MultiLayer>(sampleBuilder.buildSample()); +} + // ---------------------------------------------------------------------------- OffSpecularPlan::OffSpecularPlan() : Plan("OffSpecularPlan") { - setBuilderName("ResonatorBuilder"); setSimulationName("OffSpecularMini"); addParameter( Parameter("ti_thickness", 12.0 * nm, AttLimits::limited(11.5 * nm, 14.0 * nm), 0.1 * nm), 13.0 * nm); } + +std::unique_ptr<MultiLayer> +OffSpecularPlan::createMultiLayer(const mumufit::Parameters& params) const +{ + ResonatorBuilder sampleBuilder(params["ti_thickness"].value()); + + return std::unique_ptr<MultiLayer>(sampleBuilder.buildSample()); +} diff --git a/Tests/Functional/Core/Fitting/PlanCases.h b/Tests/Functional/Core/Fitting/PlanCases.h index 6d44ae542b4..c05ab6ba737 100644 --- a/Tests/Functional/Core/Fitting/PlanCases.h +++ b/Tests/Functional/Core/Fitting/PlanCases.h @@ -22,6 +22,10 @@ class CylindersInBAPlan : public Plan { public: CylindersInBAPlan(); + +protected: + virtual std::unique_ptr<MultiLayer> + createMultiLayer(const mumufit::Parameters& params) const override; }; //! Two parameter fit: cylinders in BA with mini GISAS simulation. @@ -30,6 +34,10 @@ public: class CylindersInBAEasyPlan : public Plan { public: CylindersInBAEasyPlan(); + +protected: + virtual std::unique_ptr<MultiLayer> + createMultiLayer(const mumufit::Parameters& params) const override; }; //! Two parameter fit: cylinders in BA with mini GISAS simulation. @@ -38,6 +46,10 @@ public: class CylindersInBAResidualPlan : public Plan { public: CylindersInBAResidualPlan(); + +protected: + virtual std::unique_ptr<MultiLayer> + createMultiLayer(const mumufit::Parameters& params) const override; }; //! Two parameter fit: cylinders in BA with mini GISAS simulation. @@ -50,6 +62,8 @@ public: protected: std::unique_ptr<ISimulation> createSimulation(const mumufit::Parameters&) const; + virtual std::unique_ptr<MultiLayer> + createMultiLayer(const mumufit::Parameters& params) const override; }; //! Plan for fitting reflectometry curve on Ti/Ni multilayer @@ -57,6 +71,10 @@ protected: class SpecularPlan : public Plan { public: SpecularPlan(); + +protected: + virtual std::unique_ptr<MultiLayer> + createMultiLayer(const mumufit::Parameters& params) const override; }; //! Plan for fitting reflectometry curve on Ti/Ni multilayer (q-defined beam) @@ -64,6 +82,10 @@ public: class SpecularPlanQ : public Plan { public: SpecularPlanQ(); + +protected: + virtual std::unique_ptr<MultiLayer> + createMultiLayer(const mumufit::Parameters& params) const override; }; //! The same as SpecularPlan, but with two (identical) datasets @@ -75,6 +97,9 @@ public: protected: std::unique_ptr<FitObjective> createFitObjective() const override; + + virtual std::unique_ptr<MultiLayer> + createMultiLayer(const mumufit::Parameters& params) const override; }; //! Fit for off-specular experiment @@ -83,6 +108,10 @@ class OffSpecularPlan : public Plan { public: OffSpecularPlan(); ~OffSpecularPlan() override = default; + +protected: + virtual std::unique_ptr<MultiLayer> + createMultiLayer(const mumufit::Parameters& params) const override; }; #endif // BORNAGAIN_TESTS_FUNCTIONAL_CORE_FITTING_PLANCASES_H -- GitLab