diff --git a/Code/Mantid/Framework/CurveFitting/src/PlotPeakByLogValue.cpp b/Code/Mantid/Framework/CurveFitting/src/PlotPeakByLogValue.cpp index df9a871cbe20fc7c6bfab3a222764e518d2247a6..05b17fd5f03428109e06e17e297083c451869098 100644 --- a/Code/Mantid/Framework/CurveFitting/src/PlotPeakByLogValue.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/PlotPeakByLogValue.cpp @@ -34,6 +34,7 @@ In this example a group of three Matrix workspaces were fitted with a [[Gaussian #include <boost/lexical_cast.hpp> #include "MantidCurveFitting/PlotPeakByLogValue.h" +#include "MantidAPI/AlgorithmManager.h" #include "MantidAPI/FuncMinimizerFactory.h" #include "MantidAPI/CostFunctionFactory.h" #include "MantidDataObjects/Workspace2D.h" @@ -114,6 +115,8 @@ namespace Mantid std::vector<std::string> costFuncOptions = CostFunctionFactory::Instance().getKeys(); declareProperty("CostFunction","Least squares",boost::make_shared<StringListValidator>(costFuncOptions), "Cost functions to use for fitting. Cost functions available are 'Least squares' and 'Ignore positive peaks'", Direction::InOut); + + declareProperty("CreateOutput", false, "Set to true to create output workspaces with the results of the fit(default is false)."); } /** @@ -130,6 +133,8 @@ namespace Mantid std::string logName = getProperty("LogValue"); bool individual = getPropertyValue("FitType") == "Individual"; bool passWSIndexToFunction = getProperty("PassWSIndexToFunction"); + bool createFitOutput = getProperty("CreateOutput"); + std::string baseName = getPropertyValue("OutputWorkspace"); bool isDataName = false; // if true first output column is of type string and is the data source name ITableWorkspace_sptr result = WorkspaceFactory::Instance().createTable("TableWorkspace"); @@ -163,7 +168,6 @@ namespace Mantid } } - for(size_t iPar=0;iPar<ifun->nParams();++iPar) { result->addColumn("double",ifun->parameterName(iPar)); @@ -173,6 +177,10 @@ namespace Mantid setProperty("OutputWorkspace",result); + std::vector<std::string> covariance_workspaces; + std::vector<std::string> fit_workspaces; + std::vector<std::string> parameter_workspaces; + double dProg = 1./static_cast<double>(wsNames.size()); double Prog = 0.; for(int i=0;i<static_cast<int>(wsNames.size());++i) @@ -203,6 +211,13 @@ namespace Mantid jend = data.indx.back() + 1; } + if (createFitOutput) + { + covariance_workspaces.reserve(covariance_workspaces.size()+jend); + fit_workspaces.reserve(fit_workspaces.size()+jend); + parameter_workspaces.reserve(parameter_workspaces.size()+jend); + } + dProg /= abs(jend - j); for(;j < jend;++j) { @@ -238,8 +253,14 @@ namespace Mantid g_log.debug() << "Fitting " << data.ws->name() << " index " << j << " with " << std::endl; g_log.debug() << ifun->asString() << std::endl; + std::string spectrum_index = boost::lexical_cast<std::string>(j); + std::string wsBaseName = ""; + + if(createFitOutput) + wsBaseName = wsNames[i].name + "_" + spectrum_index; + // Fit the function - API::IAlgorithm_sptr fit = createChildAlgorithm("Fit"); + API::IAlgorithm_sptr fit = AlgorithmManager::Instance().createUnmanaged("Fit"); fit->initialize(); fit->setProperty("Function",ifun); fit->setProperty("InputWorkspace",data.ws); @@ -249,6 +270,8 @@ namespace Mantid fit->setPropertyValue("Minimizer",getPropertyValue("Minimizer")); fit->setPropertyValue("CostFunction",getPropertyValue("CostFunction")); fit->setProperty("CalcErrors",true); + fit->setProperty("CreateOutput",createFitOutput); + fit->setProperty("Output", wsBaseName); fit->execute(); if (!fit->isExecuted()) @@ -259,6 +282,13 @@ namespace Mantid ifun = fit->getProperty("Function"); chi2 = fit->getProperty("OutputChi2overDoF"); + if (createFitOutput) + { + covariance_workspaces.push_back(wsBaseName + "_NormalisedCovarianceMatrix"); + parameter_workspaces.push_back(wsBaseName + "_Parameters"); + fit_workspaces.push_back(wsBaseName + "_Workspace"); + } + g_log.debug() << "Fit result " << fit->getPropertyValue("OutputStatus") << ' ' << chi2 << std::endl; } @@ -299,6 +329,28 @@ namespace Mantid } // for(;j < jend;++j) } + + if(createFitOutput) + { + //collect output of fit for each spectrum into workspace groups + API::IAlgorithm_sptr groupAlg = AlgorithmManager::Instance().createUnmanaged("GroupWorkspaces"); + groupAlg->initialize(); + groupAlg->setProperty("InputWorkspaces", covariance_workspaces); + groupAlg->setProperty("OutputWorkspace", baseName + "_NormalisedCovarianceMatrices"); + groupAlg->execute(); + + groupAlg = AlgorithmManager::Instance().createUnmanaged("GroupWorkspaces"); + groupAlg->initialize(); + groupAlg->setProperty("InputWorkspaces", parameter_workspaces); + groupAlg->setProperty("OutputWorkspace", baseName + "_Parameters"); + groupAlg->execute(); + + groupAlg = AlgorithmManager::Instance().createUnmanaged("GroupWorkspaces"); + groupAlg->initialize(); + groupAlg->setProperty("InputWorkspaces", fit_workspaces); + groupAlg->setProperty("OutputWorkspace", baseName + "_Workspaces"); + groupAlg->execute(); + } } /** Get a workspace identified by an InputData structure. diff --git a/Code/Mantid/Framework/CurveFitting/test/PlotPeakByLogValueTest.h b/Code/Mantid/Framework/CurveFitting/test/PlotPeakByLogValueTest.h index 078f6a76c5621bf3fa657d7fe7ae69f01f354548..a4b8a125c48756e9a205023ef29ceeb30ca9e3a1 100644 --- a/Code/Mantid/Framework/CurveFitting/test/PlotPeakByLogValueTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/PlotPeakByLogValueTest.h @@ -13,6 +13,7 @@ #include "MantidAPI/IFunction1D.h" #include "MantidAPI/ParamFunction.h" #include "MantidAPI/FunctionFactory.h" +#include "MantidAPI/WorkspaceGroup.h" #include "MantidKernel/TimeSeriesProperty.h" #include "MantidTestHelpers/WorkspaceCreationHelper.h" @@ -318,6 +319,76 @@ public: AnalysisDataService::Instance().clear(); } + void test_createOutputOption() + { + auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(Fun(),3,-5.0,5.0,0.1,false); + AnalysisDataService::Instance().add( "PLOTPEAKBYLOGVALUETEST_WS", ws ); + PlotPeakByLogValue alg; + alg.initialize(); + alg.setPropertyValue("Input","PLOTPEAKBYLOGVALUETEST_WS,v1:3"); + alg.setPropertyValue("OutputWorkspace","PlotPeakResult"); + alg.setProperty("PassWSIndexToFunction",true); + alg.setProperty("CreateOutput", true); + alg.setPropertyValue("Function","name=FlatBackground,ties=(A0=0.5);name=PLOTPEAKBYLOGVALUETEST_Fun"); + alg.execute(); + + TS_ASSERT( alg.isExecuted() ); + + TWS_type result = WorkspaceCreationHelper::getWS<TableWorkspace>("PlotPeakResult"); + TS_ASSERT( result ); + + // each spectrum contains values equal to its spectrum number (from 1 to 3) + TableRow row = result->getFirstRow(); + do{ + TS_ASSERT_DELTA( row.Double(1), 0.5, 1e-15 ); + } + while( row.next() ); + + auto matrices = AnalysisDataService::Instance().retrieveWS<const WorkspaceGroup>("PlotPeakResult_NormalisedCovarianceMatrices"); + auto params = AnalysisDataService::Instance().retrieveWS<const WorkspaceGroup>("PlotPeakResult_Parameters"); + auto fits = AnalysisDataService::Instance().retrieveWS<const WorkspaceGroup>("PlotPeakResult_Workspaces"); + + TS_ASSERT( matrices ); + TS_ASSERT( params ); + TS_ASSERT( fits ); + + TS_ASSERT( matrices->getNames().size() == 3 ); + TS_ASSERT( params->getNames().size() == 3 ); + TS_ASSERT( fits->getNames().size() == 3 ); + + AnalysisDataService::Instance().clear(); + } + + void test_createOutputOptionMultipleWorkspaces() + { + createData(); + + PlotPeakByLogValue alg; + alg.initialize(); + alg.setPropertyValue("Input","PlotPeakGroup_0;PlotPeakGroup_1;PlotPeakGroup_2"); + alg.setPropertyValue("OutputWorkspace","PlotPeakResult"); + alg.setPropertyValue("WorkspaceIndex","1"); + alg.setPropertyValue("LogValue","var"); + alg.setProperty("CreateOutput", true); + alg.setPropertyValue("Function","name=LinearBackground,A0=1,A1=0.3;name=Gaussian,PeakCentre=5,Height=2,Sigma=0.1"); + TS_ASSERT( alg.execute() ); + + TWS_type result = WorkspaceCreationHelper::getWS<TableWorkspace>("PlotPeakResult"); + TS_ASSERT_EQUALS(result->columnCount(),12); + + auto matrices = AnalysisDataService::Instance().retrieveWS<const WorkspaceGroup>("PlotPeakResult_NormalisedCovarianceMatrices"); + auto params = AnalysisDataService::Instance().retrieveWS<const WorkspaceGroup>("PlotPeakResult_Parameters"); + auto fits = AnalysisDataService::Instance().retrieveWS<const WorkspaceGroup>("PlotPeakResult_Workspaces"); + + TS_ASSERT( matrices ); + TS_ASSERT( params ); + TS_ASSERT( fits ); + + TS_ASSERT( matrices->getNames().size() == 3 ); + TS_ASSERT( params->getNames().size() == 3 ); + TS_ASSERT( fits->getNames().size() == 3 ); + } + private: WorkspaceGroup_sptr m_wsg; diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SequentialFitDialog.ui b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SequentialFitDialog.ui index abcb5bb00f67b4d647c142dacacdb6114cf7575c..9be27de7c522c9f5919a0fd959ff2a7d6b39d2c9 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SequentialFitDialog.ui +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SequentialFitDialog.ui @@ -128,6 +128,16 @@ </property> </widget> </item> + <item> + <widget class="QCheckBox" name="ckCreateOutput"> + <property name="toolTip"> + <string>If check, the output of the fitting will be created for each spectrum.</string> + </property> + <property name="text"> + <string>Create Output</string> + </property> + </widget> + </item> <item> <spacer name="horizontalSpacer_4"> <property name="orientation"> diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/SequentialFitDialog.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/SequentialFitDialog.cpp index 34eead5e24f772f845071e9043e349df2bfebe24..16bc8d602418a660d247be74d58a8831e1cbf078 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/SequentialFitDialog.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/SequentialFitDialog.cpp @@ -336,6 +336,7 @@ void SequentialFitDialog::accept() alg->setProperty("EndX",m_fitBrowser->endX()); alg->setPropertyValue("OutputWorkspace",m_fitBrowser->outputName()); alg->setPropertyValue("Function",funStr); + alg->setProperty("CreateOutput", ui.ckCreateOutput->isChecked()); if (ui.ckbLogPlot->isChecked()) { std::string logName = ui.cbLogValue->currentText().toStdString();