diff --git a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt index 69b0c484232455ee84c81973921de8b9e1f1e112..ffdc03127aa01e7ab7ac7c0709dc18702b974170 100644 --- a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt +++ b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt @@ -75,6 +75,7 @@ set ( SRC_FILES src/SplineSmoothing.cpp src/StaticKuboToyabe.cpp src/StaticKuboToyabeTimesExpDecay.cpp + src/StaticKuboToyabeTimesGausDecay.cpp src/SteepestDescentMinimizer.cpp src/StretchExp.cpp src/StretchExpMuon.cpp @@ -174,6 +175,7 @@ set ( INC_FILES inc/MantidCurveFitting/SplineSmoothing.h inc/MantidCurveFitting/StaticKuboToyabe.h inc/MantidCurveFitting/StaticKuboToyabeTimesExpDecay.h + inc/MantidCurveFitting/StaticKuboToyabeTimesGausDecay.h inc/MantidCurveFitting/SteepestDescentMinimizer.h inc/MantidCurveFitting/StretchExp.h inc/MantidCurveFitting/StretchExpMuon.h @@ -256,6 +258,7 @@ set ( TEST_FILES SplineSmoothingTest.h StaticKuboToyabeTest.h StaticKuboToyabeTimesExpDecayTest.h + StaticKuboToyabeTimesGausDecayTest.h StretchExpMuonTest.h StretchExpTest.h TabulatedFunctionTest.h diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/StaticKuboToyabeTimesGausDecay.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/StaticKuboToyabeTimesGausDecay.h new file mode 100644 index 0000000000000000000000000000000000000000..44fcd87dff9467751c9d261bb24f93275531bb0c --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/StaticKuboToyabeTimesGausDecay.h @@ -0,0 +1,58 @@ +#ifndef MANTID_CURVEFITTING_STATICKUBOTOYABETIMESGAUSDECAY_H_ +#define MANTID_CURVEFITTING_STATICKUBOTOYABETIMESGAUSDECAY_H_ + +#include "MantidAPI/ParamFunction.h" +#include "MantidAPI/IFunction1D.h" + +namespace Mantid +{ +namespace CurveFitting +{ + + /** + StaticKuboToyabeTimesGausDecay fitting function. + + Represents multiplication of two other fitting functions: StaticKuboToyabe and GausDecay. + + @author Arturs Bekasovs + @date 27/09/2013 + + Copyright © 2013 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + class DLLExport StaticKuboToyabeTimesGausDecay : public API::ParamFunction, public API::IFunction1D + { + public: + std::string name()const {return "StaticKuboToyabeTimesGausDecay";} + + virtual const std::string category() const { return "Muon";} + + protected: + virtual void function1D(double* out, const double* xValues, const size_t nData)const; + + virtual void init(); + + }; + + +} // namespace CurveFitting +} // namespace Mantid + +#endif /* MANTID_CURVEFITTING_STATICKUBOTOYABETIMESGAUSDECAY_H_ */ \ No newline at end of file diff --git a/Code/Mantid/Framework/CurveFitting/src/StaticKuboToyabeTimesGausDecay.cpp b/Code/Mantid/Framework/CurveFitting/src/StaticKuboToyabeTimesGausDecay.cpp new file mode 100644 index 0000000000000000000000000000000000000000..060704ddf83a35a2c8bd7f1261a971f6062cd857 --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/src/StaticKuboToyabeTimesGausDecay.cpp @@ -0,0 +1,47 @@ +/*WIKI* +Fitting function for use by Muon scientists defined by: + +<math> \mbox{A}\times ( \exp(-{Delta}^2 \times {x}^2 / 2 ) \times ( 1 - ( {Delta}^2 \times {x}^2 ) ) \times \frac 2 3 + \frac 1 3 ) \times \exp(-{Sigma}^2 \times {x}^2 ) </math> + *WIKI*/ +#include "MantidCurveFitting/StaticKuboToyabeTimesGausDecay.h" +#include "MantidAPI/FunctionFactory.h" +#include <cmath> + +namespace Mantid +{ +namespace CurveFitting +{ + using namespace Kernel; + using namespace API; + + DECLARE_FUNCTION(StaticKuboToyabeTimesGausDecay) + + void StaticKuboToyabeTimesGausDecay::init() + { + declareParameter("A", 1.0, "Amplitude at time 0"); + declareParameter("Delta", 0.2, "StaticKuboToyabe decay rate"); + declareParameter("Sigma", 0.2, "Gaus decay rate"); + } + + void StaticKuboToyabeTimesGausDecay::function1D(double* out, const double* xValues, const size_t nData) const + { + const double A = getParameter("A"); + const double D = getParameter("Delta"); + const double S = getParameter("Sigma"); + + // Precalculate squares + const double D2 = pow(D, 2); + const double S2 = pow(S, 2); + + // Precalculate constants + const double C1 = 2.0/3; + const double C2 = 1.0/3; + + for (size_t i = 0; i < nData; i++) { + double x2 = pow(xValues[i], 2); + out[i] = A*(exp(-(x2*D2)/2)*(1-x2*D2)*C1 + C2)*exp(-S2*x2); + } + +} +} // namespace CurveFitting +} // namespace Mantid \ No newline at end of file diff --git a/Code/Mantid/Framework/CurveFitting/test/StaticKuboToyabeTimesGausDecayTest.h b/Code/Mantid/Framework/CurveFitting/test/StaticKuboToyabeTimesGausDecayTest.h new file mode 100644 index 0000000000000000000000000000000000000000..8176745069405e3a1f30e0ed5b96431d6ef7784f --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/test/StaticKuboToyabeTimesGausDecayTest.h @@ -0,0 +1,124 @@ +#ifndef MANTID_CURVEFITTING_STATICKUBOTOYABETIMESGAUSDECAYTEST_H_ +#define MANTID_CURVEFITTING_STATICKUBOTOYABETIMESGAUSDECAYTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidCurveFitting/StaticKuboToyabeTimesGausDecay.h" +#include "MantidAPI/FunctionFactory.h" +#include "MantidCurveFitting/Fit.h" +#include "MantidDataObjects/Workspace2D.h" + +using Mantid::CurveFitting::StaticKuboToyabeTimesGausDecay; +using namespace Mantid::Kernel; +using namespace Mantid::API; +using namespace Mantid::CurveFitting; +using namespace Mantid::DataObjects; + +class StaticKuboToyabeTimesGausDecayTest : public CxxTest::TestSuite +{ +public: + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static StaticKuboToyabeTimesGausDecayTest *createSuite() { return new StaticKuboToyabeTimesGausDecayTest(); } + static void destroySuite( StaticKuboToyabeTimesGausDecayTest *suite ) { delete suite; } + + void getMockData(Mantid::MantidVec& y, Mantid::MantidVec& e) + { + // A = 0.24, Delta = 0.16, Sigma = 0.1 + y[0] = 0.24; + y[1] = 0.231594; + y[2] = 0.207961; + y[3] = 0.173407; + y[4] = 0.133761; + y[5] = 0.0948783; + y[6] = 0.0613345; + y[7] = 0.035692; + y[8] = 0.0184429; + y[9] = 0.0084925; + y[10] = 0.00390022; + y[11] = 0.00258855; + y[12] = 0.00283237; + y[13] = 0.00347216; + y[14] = 0.00390132; + + for (int i = 0; i < 15; i++) + e[i] = 1.0; + } + + StaticKuboToyabeTimesGausDecayTest() + : fn() + {} + + void test_Initialize() + { + TS_ASSERT_THROWS_NOTHING(fn.initialize()); + } + + void test_Name() + { + TS_ASSERT_EQUALS(fn.name(), "StaticKuboToyabeTimesGausDecay"); + } + + void test_Params() + { + TS_ASSERT_DELTA(fn.getParameter("A"), 1.0, 0.0001); + TS_ASSERT_DELTA(fn.getParameter("Delta"), 0.2, 0.0001); + TS_ASSERT_DELTA(fn.getParameter("Sigma"), 0.2, 0.0001); + } + + void test_Category() + { + const std::vector<std::string> categories = fn.categories(); + TS_ASSERT( categories.size() == 1 ); + TS_ASSERT( categories[0] == "Muon" ); + } + + void test_AgainstMockData() + { + Fit alg2; + TS_ASSERT_THROWS_NOTHING(alg2.initialize()); + TS_ASSERT( alg2.isInitialized() ); + + // create mock data to test against + std::string wsName = "SKTTimesGausDecayMockData"; + Workspace_sptr ws = WorkspaceFactory::Instance().create("Workspace2D", 1, 15, 15); + Workspace2D_sptr ws2D = boost::dynamic_pointer_cast<Workspace2D>(ws); + + for (int i = 0; i < 15; i++) + ws2D->dataX(0)[i] = i; + + getMockData(ws2D->dataY(0), ws2D->dataE(0)); + + //put this workspace in the data service + TS_ASSERT_THROWS_NOTHING(AnalysisDataService::Instance().addOrReplace(wsName, ws2D)); + + alg2.setPropertyValue("Function",fn.asString()); + + // Set which spectrum to fit against and initial starting values + alg2.setPropertyValue("InputWorkspace", wsName); + alg2.setPropertyValue("WorkspaceIndex", "0"); + alg2.setPropertyValue("StartX", "0"); + alg2.setPropertyValue("EndX", "14"); + + TS_ASSERT_THROWS_NOTHING( + TS_ASSERT( alg2.execute() ) + ) + + TS_ASSERT( alg2.isExecuted() ); + + double dummy = alg2.getProperty("OutputChi2overDoF"); + TS_ASSERT_DELTA( dummy, 0.0001,0.0001); + + IFunction_sptr out = alg2.getProperty("Function"); + TS_ASSERT_DELTA( out->getParameter("A"), 0.24 ,0.0001); + TS_ASSERT_DELTA( out->getParameter("Delta"), 0.16 ,0.001); + TS_ASSERT_DELTA( out->getParameter("Sigma"), 0.1 ,0.001); + + AnalysisDataService::Instance().remove(wsName); + } + + StaticKuboToyabeTimesGausDecay fn; +}; + + +#endif /* MANTID_CURVEFITTING_STATICKUBOTOYABETIMESGAUSDECAYTEST_H_ */ \ No newline at end of file