Skip to content
Snippets Groups Projects
Commit 643a36a5 authored by Karl Palmen's avatar Karl Palmen
Browse files

Add new fitting function and unit test re #4957


Signed-off-by: default avatarKarl Palmen <karl.palmen@stfc.ac.uk>
parent 5e0bbb66
No related branches found
No related tags found
No related merge requests found
......@@ -32,6 +32,7 @@ set ( SRC_FILES
src/LogNormal.cpp
src/Lorentzian.cpp
src/Lorentzian1D.cpp
src/MuonFInteraction.cpp
src/MultiBG.cpp
src/PRConjugateGradientMinimizer.cpp
src/PlotPeakByLogValue.cpp
......@@ -86,6 +87,7 @@ set ( INC_FILES
inc/MantidCurveFitting/LogNormal.h
inc/MantidCurveFitting/Lorentzian.h
inc/MantidCurveFitting/Lorentzian1D.h
inc/MantidCurveFitting/MuonFInteraction.h
inc/MantidCurveFitting/MultiBG.h
inc/MantidCurveFitting/PRConjugateGradientMinimizer.h
inc/MantidCurveFitting/PlotPeakByLogValue.h
......@@ -129,6 +131,7 @@ set ( TEST_FILES
test/LogNormalTest.h
test/Lorentzian1DTest.h
test/LorentzianTest.h
test/MuonFInteractionTest.h
test/MultiBGTest.h
test/PlotPeakByLogValueTest.h
test/ProductFunctionMWTest.h
......
#ifndef MANTID_CURVEFITTING_MUONFINTERACTION_H_
#define MANTID_CURVEFITTING_MUONFINTERACTION_H_
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/ParamFunction.h"
#include "MantidAPI/IFunctionMW.h"
namespace Mantid
{
namespace CurveFitting
{
/**
Provide Muon F Interaction fitting function
@author Karl Palmen, ISIS, RAL
@date 16/03/2012
Copyright &copy; 2007-2012 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://svn.mantidproject.org/mantid/trunk/Code/Mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport MuonFInteraction : public API::ParamFunction, public API::IFunctionMW
{
public:
/// Destructor
virtual ~MuonFInteraction() {}
/// overwrite IFunction base class methods
std::string name()const{return "MuonFInteraction";}
/// overwrite IFunction base class methods
virtual const std::string category() const { return "Muon";}
protected:
virtual void functionMW(double* out, const double* xValues, const size_t nData)const;
virtual void functionDerivMW(API::Jacobian* out, const double* xValues, const size_t nData);
/// overwrite IFunction base class method that declares function parameters
virtual void init();
};
} // namespace CurveFitting
} // namespace Mantid
#endif /*MANTID_CURVEFITTING_MUONFINTERACTION_H_*/
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidCurveFitting/MuonFInteraction.h"
#include <cmath>
namespace Mantid
{
namespace CurveFitting
{
using namespace Kernel;
using namespace API;
DECLARE_FUNCTION(MuonFInteraction)
void MuonFInteraction::init()
{
declareParameter("Lambda", 0.2);
declareParameter("Omega", 0.5);
declareParameter("Beta", 1);
declareParameter("A", 1);
}
void MuonFInteraction::functionMW(double* out, const double* xValues, const size_t nData)const
{
const double& lambda = getParameter("Lambda");
const double& omega = getParameter("Omega");
const double& beta = getParameter("Beta");
const double& A = getParameter("A");
const double& sqrt3 = sqrt(3.0);
for (int i = 0; i < nData; i++) {
double A1=exp(-pow(lambda*xValues[i],beta))*A/6;
double A2=cos(sqrt3*omega*xValues[i]);
double A3=(1.0-1.0/sqrt3)*cos(((3.0-sqrt3)/2.0)*omega*xValues[i]);
double A4=(1.0+1.0/sqrt3)*cos(((3.0+sqrt3)/2.0)*omega*xValues[i]);
out[i] = A1*(3+A2+A3+A4);
}
}
void MuonFInteraction::functionDerivMW(Jacobian* out, const double* xValues, const size_t nData)
{
calNumericalDeriv(out, xValues, nData);
}
} // namespace CurveFitting
} // namespace Mantid
#ifndef MUONFINTERACTIONTEST_H_
#define MUONFINTERACTIONTEST_H_
#include <cxxtest/TestSuite.h>
#include "MantidCurveFitting/MuonFInteraction.h"
#include "MantidAPI/CompositeFunction.h"
#include "MantidCurveFitting/LinearBackground.h"
#include "MantidCurveFitting/BoundaryConstraint.h"
#include "MantidCurveFitting/Fit.h"
#include "MantidKernel/UnitFactory.h"
#include "MantidAPI/AnalysisDataService.h"
#include "MantidAPI/WorkspaceFactory.h"
#include "MantidAPI/Algorithm.h"
#include "MantidDataObjects/Workspace2D.h"
#include "MantidDataHandling/LoadRaw.h"
#include "MantidKernel/Exception.h"
#include "MantidAPI/FunctionFactory.h"
using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace Mantid::CurveFitting;
using namespace Mantid::DataObjects;
using namespace Mantid::DataHandling;
class MuonFInteractionTest : public CxxTest::TestSuite
{
public:
void getMockData(Mantid::MantidVec& y, Mantid::MantidVec& e)
{
// Mock data got from an Excel spreadsheet with
// Lambda = 0.16, Omega = 0.4, Beta = 1.2 & A = 1.5
y[0] = 1.5;
y[1] = 1.141313628;
y[2] = 0.591838582;
y[3] = 0.217069719;
y[4] = 0.143355934;
y[5] = 0.256915274;
y[6] = 0.365739273;
y[7] = 0.360727646;
y[8] = 0.260023319;
y[9] = 0.146136639;
y[10] = 0.080853314;
y[11] = 0.068393706;
y[12] = 0.075537727;
y[13] = 0.071800717;
y[14] = 0.051659705;
y[15] = 0.028746883;
y[16] = 0.017073081;
y[17] = 0.018710399;
y[18] = 0.025298535;
y[19] = 0.027436201;
for (int i = 0; i <=20; i++)
{
e[i] = 0.01;
}
}
void testAgainstMockData()
{
Fit alg2;
TS_ASSERT_THROWS_NOTHING(alg2.initialize());
TS_ASSERT( alg2.isInitialized() );
// create mock data to test against
std::string wsName = "MuonFInteractionMockData";
int histogramNumber = 1;
int timechannels = 21;
Workspace_sptr ws = WorkspaceFactory::Instance().create("Workspace2D",histogramNumber,timechannels,timechannels);
Workspace2D_sptr ws2D = boost::dynamic_pointer_cast<Workspace2D>(ws);
for (int i = 0; i < 21; i++) ws2D->dataX(0)[i] = i;
Mantid::MantidVec& y = ws2D->dataY(0); // y-values (counts)
Mantid::MantidVec& e = ws2D->dataE(0); // error values of counts
getMockData(y, e);
//put this workspace in the data service
TS_ASSERT_THROWS_NOTHING(AnalysisDataService::Instance().addOrReplace(wsName, ws2D));
// set up Lorentzian fitting function
MuonFInteraction fn;
fn.initialize();
//alg2.setFunction(fn);
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","19");
// execute fit
TS_ASSERT_THROWS_NOTHING(
TS_ASSERT( alg2.execute() )
)
TS_ASSERT( alg2.isExecuted() );
// test the output from fit is what you expect
double dummy = alg2.getProperty("OutputChi2overDoF");
TS_ASSERT_DELTA( dummy, 0.0001,0.0001);
IFitFunction *out = FunctionFactory::Instance().createInitialized(alg2.getPropertyValue("Function"));
TS_ASSERT_DELTA( out->getParameter("Lambda"), 0.16 ,0.001);
TS_ASSERT_DELTA( out->getParameter("Omega"), 0.4 ,0.001);
TS_ASSERT_DELTA( out->getParameter("Beta"), 1.2 ,0.01);
TS_ASSERT_DELTA( out->getParameter("A"), 1.5 ,0.01);
// check it categories
const std::vector<std::string> categories = out->categories();
TS_ASSERT( categories.size() == 1 );
TS_ASSERT( categories[0] == "Muon" );
AnalysisDataService::Instance().remove(wsName);
}
};
#endif /*MUONFINTERACTONTEST_H_*/
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment