From 8cec977d3323f7fdb2f7c84992a34e8328e42be0 Mon Sep 17 00:00:00 2001 From: Robert Applin <40830825+robertapplin@users.noreply.github.com> Date: Tue, 9 Oct 2018 14:44:44 +0100 Subject: [PATCH] Refs #23463. More unit tests --- .../Indirect/test/IndirectFittingModelTest.h | 225 ++++++++++++++---- 1 file changed, 181 insertions(+), 44 deletions(-) diff --git a/qt/scientific_interfaces/Indirect/test/IndirectFittingModelTest.h b/qt/scientific_interfaces/Indirect/test/IndirectFittingModelTest.h index b36a44b8d4d..0d512d6482e 100644 --- a/qt/scientific_interfaces/Indirect/test/IndirectFittingModelTest.h +++ b/qt/scientific_interfaces/Indirect/test/IndirectFittingModelTest.h @@ -59,6 +59,20 @@ struct SetUpADSWithWorkspace { AnalysisDataService::Instance().addOrReplace(inputWSName, workspace); }; + template <typename T> + void addOrReplace(std::string const &workspaceName, T const &workspace) { + AnalysisDataService::Instance().addOrReplace(workspaceName, workspace); + } + + bool doesExist(std::string const &workspaceName) { + return AnalysisDataService::Instance().doesExist(workspaceName); + } + + MatrixWorkspace_sptr retrieveWorkspace(std::string const &workspaceName) { + return boost::dynamic_pointer_cast<MatrixWorkspace>( + AnalysisDataService::Instance().retrieve(workspaceName)); + } + ~SetUpADSWithWorkspace() { AnalysisDataService::Instance().clear(); }; }; @@ -92,15 +106,6 @@ std::unique_ptr<DummyModel> getEmptyModel() { return std::make_unique<DummyModel>(); } -std::unique_ptr<DummyModel> createModelWithSingleInstrumentWorkspace( - std::string const &workspaceName, int const &xLength, int const &yLength) { - auto model = getEmptyModel(); - SetUpADSWithWorkspace ads(workspaceName, - createWorkspaceWithInstrument(xLength, yLength)); - model->addWorkspace(workspaceName); - return model; -} - std::unique_ptr<DummyModel> createModelWithSingleWorkspace(std::string const &workspaceName, int const &numberOfSpectra) { @@ -132,11 +137,20 @@ createModelWithMultipleWorkspaces(int const &numberOfSpectra, return model; } +std::unique_ptr<DummyModel> createModelWithSingleInstrumentWorkspace( + std::string const &workspaceName, int const &xLength, int const &yLength) { + auto model = getEmptyModel(); + SetUpADSWithWorkspace ads(workspaceName, + createWorkspaceWithInstrument(xLength, yLength)); + model->addWorkspace(workspaceName); + return model; +} + } // namespace class IndirectFittingModelTest : public CxxTest::TestSuite { public: - // WorkflowAlgorithms do not appear in the FrameworkManager without this line + /// WorkflowAlgorithms do not appear in the FrameworkManager without this line IndirectFittingModelTest() { FrameworkManager::Instance(); } static IndirectFittingModelTest *createSuite() { @@ -156,10 +170,8 @@ public: void test_that_a_workspace_is_stored_correctly_in_the_ADS() { SetUpADSWithWorkspace ads("WorkspaceName", createWorkspace(3)); - TS_ASSERT(AnalysisDataService::Instance().doesExist("WorkspaceName")); - MatrixWorkspace_sptr storedWorkspace = - boost::dynamic_pointer_cast<MatrixWorkspace>( - AnalysisDataService::Instance().retrieve("WorkspaceName")); + TS_ASSERT(ads.doesExist("WorkspaceName")); + auto const storedWorkspace = ads.retrieveWorkspace("WorkspaceName"); TS_ASSERT_EQUALS(storedWorkspace->getNumberHistograms(), 3); } @@ -197,8 +209,8 @@ public: auto model = getEmptyModel(); auto const workspace1 = createWorkspace(3); auto const workspace2 = createWorkspace(3); - SetUpADSWithWorkspace ads1("WorkspaceName1", workspace1); - SetUpADSWithWorkspace ads2("WorkspaceName2", workspace2); + SetUpADSWithWorkspace ads("WorkspaceName1", workspace1); + ads.addOrReplace("WorkspaceName2", workspace2); model->addWorkspace("WorkspaceName1"); model->addWorkspace("WorkspaceName2"); @@ -389,8 +401,7 @@ public: auto const modelWorkspace = model->getWorkspace(0); SetUpADSWithWorkspace ads("Name", modelWorkspace); - auto alg = - setupConvolutionSequentialFitAlgorithm(model, modelWorkspace, "Name"); + auto const alg = getSetupFitAlgorithm(model, modelWorkspace, "Name"); TS_ASSERT(alg->isInitialized()); } @@ -400,23 +411,28 @@ public: auto const modelWorkspace = model->getWorkspace(0); SetUpADSWithWorkspace ads("Name", modelWorkspace); - auto alg = - setupConvolutionSequentialFitAlgorithm(model, modelWorkspace, "Name"); + auto const alg = getSetupFitAlgorithm(model, modelWorkspace, "Name"); TS_ASSERT_THROWS_NOTHING(alg->execute()); TS_ASSERT(alg->isExecuted()); } - void - test_that_isPreviouslyFit_returns_true_if_the_spectrum_has_been_fitted_previously() { + void test_that_addOutput_adds_the_output_of_a_fit_into_the_model() { auto model = createModelWithSingleInstrumentWorkspace("__ConvFit", 6, 5); auto const modelWorkspace = model->getWorkspace(0); SetUpADSWithWorkspace ads("__ConvFit", modelWorkspace); - auto const alg = executeConvolutionSequentialFitAlgorithm( - model, modelWorkspace, "__ConvFit"); + auto const alg = + getExecutedFitAlgorithm(model, modelWorkspace, "__ConvFit"); model->addOutput(alg); + TS_ASSERT(model->getResultWorkspace()); + TS_ASSERT(model->getResultGroup()); + } + + void + test_that_isPreviouslyFit_returns_true_if_the_spectrum_has_been_fitted_previously() { + auto const model = getModelWithOutputFitData(); TS_ASSERT(model->isPreviouslyFit(0, 0)); } @@ -464,8 +480,7 @@ public: auto const modelWorkspace = model->getWorkspace(0); SetUpADSWithWorkspace ads("Name", modelWorkspace); - auto alg = - setupConvolutionSequentialFitAlgorithm(model, modelWorkspace, "Name"); + (void)getSetupFitAlgorithm(model, modelWorkspace, "Name"); TS_ASSERT(!model->isInvalidFunction()); } @@ -501,8 +516,8 @@ public: auto const modelWorkspace = model->getWorkspace(0); SetUpADSWithWorkspace ads("__ConvFit", modelWorkspace); - auto const alg = executeConvolutionSequentialFitAlgorithm( - model, modelWorkspace, "__ConvFit"); + auto const alg = + getExecutedFitAlgorithm(model, modelWorkspace, "__ConvFit"); model->addOutput(alg); TS_ASSERT(!model->getFitParameterNames().empty()); @@ -607,26 +622,139 @@ public: auto const modelWorkspace = model->getWorkspace(0); SetUpADSWithWorkspace ads("Name", modelWorkspace); - auto const alg = - setupConvolutionSequentialFitAlgorithm(model, modelWorkspace, "Name"); + (void)getSetupFitAlgorithm(model, modelWorkspace, "Name"); model->setDefaultParameterValue("Amplitude", 1.5, 0); auto const parameters = model->getDefaultParameters(0); TS_ASSERT_EQUALS(parameters.at("f1.f1.f0.Amplitude").value, 1.5); } + void + test_that_getParameterValues_returns_an_empty_map_if_the_dataIndex_is_out_of_range() { + auto const model = getModelWithOutputFitData(); + TS_ASSERT(model->getParameterValues(1, 0).empty()); + } + + void + test_that_getParameterValues_returns_the_default_parameters_if_there_are_no_fit_parameters() { + auto model = createModelWithSingleInstrumentWorkspace("__ConvFit", 6, 5); + auto const modelWorkspace = model->getWorkspace(0); + SetUpADSWithWorkspace ads("__ConvFit", modelWorkspace); + + (void)getSetupFitAlgorithm(model, modelWorkspace, "__ConvFit"); + model->setDefaultParameterValue("Amplitude", 1.5, 0); + + auto const parameters = model->getParameterValues(0, 0); + TS_ASSERT_EQUALS(parameters.at("f1.f1.f0.Amplitude").value, 1.5); + } + + void + test_that_getParameterValues_returns_the_fit_parameters_after_a_fit_has_been_executed() { + auto const model = getModelWithOutputFitData(); + + auto const parameters = model->getParameterValues(0, 0); + TS_ASSERT_EQUALS(parameters.at("f1.f1.f0.Amplitude").value, 1.0, 0.0001); + TS_ASSERT_EQUALS(parameters.at("f1.f1.f0.FWHM").value, 0.0175, 0.0001); + TS_ASSERT(!parameters.empty()); + } + + void test_getFitParameters_returns_an_empty_map_when_there_is_no_fitOutput() { + auto model = createModelWithSingleInstrumentWorkspace("__ConvFit", 6, 5); + auto const modelWorkspace = model->getWorkspace(0); + SetUpADSWithWorkspace ads("__ConvFit", modelWorkspace); + + (void)getSetupFitAlgorithm(model, modelWorkspace, "__ConvFit"); + + TS_ASSERT(model->getFitParameters(0, 0).empty()); + } + + void test_getFitParameters_returns_the_fitParameters_after_a_fit() { + auto const model = getModelWithOutputFitData(); + + auto const parameters = model->getFitParameters(0, 0); + TS_ASSERT_EQUALS(parameters.at("f1.f1.f0.Amplitude").value, 1.0, 0.0001); + TS_ASSERT_EQUALS(parameters.at("f1.f1.f0.FWHM").value, 0.0175, 0.0001); + TS_ASSERT(!parameters.empty()); + } + + void + test_getDefaultParameters_returns_an_empty_map_when_the_dataIndex_is_out_of_range() { + auto const model = getModelWithOutputFitData(); + TS_ASSERT(model->getDefaultParameters(1).empty()); + } + + void + test_getDefaultParameters_returns_the_default_parameters_which_have_been_set() { + auto const model = getModelWithOutputFitData(); + + model->setDefaultParameterValue("Amplitude", 1.5, 0); + + auto const parameters = model->getDefaultParameters(0); + TS_ASSERT(!parameters.empty()); + TS_ASSERT_EQUALS(parameters.at("f1.f1.f0.Amplitude").value, 1.5, 0.0001); + } + + void test_that_getResultLocation_returns_a_location_for_the_output_data() { + auto const model = getModelWithOutputFitData(); + TS_ASSERT(model->getResultLocation(0, 0)); + } + + void test_that_saveResult_does_not_throw_when_saving_data_from_a_fit() { + auto const model = getModelWithOutputFitData(); + TS_ASSERT_THROWS_NOTHING(model->saveResult()); + } + + void + test_that_cleanFailedRun_removes_the_temporary_workspace_from_the_ADS_when_a_fit_fails() { + /// Fails the fit algorithm on purpose by providing an invalid function + auto model = + createModelWithSingleInstrumentWorkspace("__ConvFitResolution", 6, 5); + auto const modelWorkspace = model->getWorkspace(0); + SetUpADSWithWorkspace ads("__ConvFitResolution", modelWorkspace); + + std::string const functionString = + "name=Convolution;name=Resolution,Workspace=__ConvFit" + "Resolution,WorkspaceIndex=0;"; + auto alg = setupConvolutionSequentialFitAlgorithm( + modelWorkspace, "__ConvFit", functionString); + alg->execute(); + + TS_ASSERT(ads.doesExist("__ConvolutionFitSequential_ws1")); + model->cleanFailedRun(alg); + TS_ASSERT(!ads.doesExist("__ConvolutionFitSequential_ws1")); + } + + void + test_that_cleanFailedSingleRun_removes_the_temporary_workspace_from_the_ADS_when_a_fit_fails_for_a_specific_workspaceIndex() { + /// Fails the fit algorithm on purpose by providing an invalid function + auto model = + createModelWithSingleInstrumentWorkspace("__ConvFitResolution", 6, 5); + auto const modelWorkspace = model->getWorkspace(0); + SetUpADSWithWorkspace ads("__ConvFitResolution", modelWorkspace); + + std::string const functionString = + "name=Convolution;name=Resolution,Workspace=__ConvFit" + "Resolution,WorkspaceIndex=0;"; + auto alg = setupConvolutionSequentialFitAlgorithm( + modelWorkspace, "__ConvFit", functionString); + alg->execute(); + + TS_ASSERT(ads.doesExist("__ConvolutionFitSequential_ws1")); + model->cleanFailedSingleRun(alg, 0); + TS_ASSERT(!ads.doesExist("__ConvolutionFitSequential_ws1")); + } + private: void setFittingFunction(std::unique_ptr<DummyModel> &model, - std::string const &functionString) { + std::string const &functionString) const { auto const function = FunctionFactory::Instance().createInitialized(functionString); model->setFitFunction(function); } - IAlgorithm_sptr - setupConvolutionSequentialFitAlgorithm(MatrixWorkspace_sptr workspace, - std::string const &workspaceName, - std::string const &functionString) { + IAlgorithm_sptr setupConvolutionSequentialFitAlgorithm( + MatrixWorkspace_sptr workspace, std::string const &workspaceName, + std::string const &functionString) const { auto alg = boost::make_shared<ConvolutionFitSequential>(); TS_ASSERT_THROWS_NOTHING(alg->initialize()); alg->setProperty("InputWorkspace", workspace); @@ -644,10 +772,9 @@ private: return alg; } - IAlgorithm_sptr - setupConvolutionSequentialFitAlgorithm(std::unique_ptr<DummyModel> &model, - MatrixWorkspace_sptr workspace, - std::string const &workspaceName) { + IAlgorithm_sptr getSetupFitAlgorithm(std::unique_ptr<DummyModel> &model, + MatrixWorkspace_sptr workspace, + std::string const &workspaceName) const { std::string const function = "name=LinearBackground,A0=0,A1=0,ties=(A0=0.000000,A1=0.0);" "(composite=Convolution,FixResolution=true,NumDeriv=true;" @@ -663,14 +790,24 @@ private: } IAlgorithm_sptr - executeConvolutionSequentialFitAlgorithm(std::unique_ptr<DummyModel> &model, - MatrixWorkspace_sptr workspace, - std::string const &workspaceName) { - auto const alg = - setupConvolutionSequentialFitAlgorithm(model, workspace, workspaceName); + getExecutedFitAlgorithm(std::unique_ptr<DummyModel> &model, + MatrixWorkspace_sptr workspace, + std::string const &workspaceName) const { + auto const alg = getSetupFitAlgorithm(model, workspace, workspaceName); alg->execute(); return alg; } + + std::unique_ptr<DummyModel> getModelWithOutputFitData() { + auto model = createModelWithSingleInstrumentWorkspace("__ConvFit", 6, 5); + auto const modelWorkspace = model->getWorkspace(0); + SetUpADSWithWorkspace ads("__ConvFit", modelWorkspace); + + auto const alg = + getExecutedFitAlgorithm(model, modelWorkspace, "__ConvFit"); + model->addOutput(alg); + return model; + } }; #endif -- GitLab