Skip to content

Commit

Permalink
Added Abragam Fit Function and Unit Test re #4956
Browse files Browse the repository at this point in the history
also corrected comment in StaticKuboToyabe.h

Signed-off-by: Karl Palmen <karl.palmen@stfc.ac.uk>
  • Loading branch information
KarlPalmen committed Mar 22, 2012
1 parent 48fbbdf commit 994c699
Show file tree
Hide file tree
Showing 5 changed files with 270 additions and 1 deletion.
3 changes: 3 additions & 0 deletions Code/Mantid/Framework/CurveFitting/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
set ( SRC_FILES
src/Abragam.cpp
src/BFGS_Minimizer.cpp
src/BackToBackExponential.cpp
src/BackgroundFunction.cpp
Expand Down Expand Up @@ -54,6 +55,7 @@ set ( SRC_FILES
set ( SRC_UNITY_IGNORE_FILES src/Fit1D.cpp src/GSLFunctions.cpp )

set ( INC_FILES
inc/MantidCurveFitting/Abragam.h
inc/MantidCurveFitting/BFGS_Minimizer.h
inc/MantidCurveFitting/BackToBackExponential.h
inc/MantidCurveFitting/BackgroundFunction.h
Expand Down Expand Up @@ -109,6 +111,7 @@ set ( INC_FILES
)

set ( TEST_FILES
test/AbragamTest.h
test/BackToBackExponentialTest.h
test/BivariateNormalTest.h
test/BoundaryConstraintTest.h
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#ifndef MANTID_CURVEFITTING_ABRAGAM_H_
#define MANTID_CURVEFITTING_ABRAGAM_H_

//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/ParamFunction.h"
//#include "MantidAPI/IPeakFunction.h"

#include "MantidAPI/IFunctionMW.h"

namespace Mantid
{
namespace CurveFitting
{
/**
Provide Abragam fitting function for muon scientists
@author Karl Palmen, ISIS, RAL
@date 21/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 Abragam : public API::ParamFunction, public API::IFunctionMW
{
public:

/// Destructor
virtual ~Abragam() {}

/// overwrite IFunction base class methods
std::string name()const{return "Abragam";}

/// 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);
virtual void setActiveParameter(size_t i,double value);

/// overwrite IFunction base class method that declares function parameters
virtual void init();

};

} // namespace CurveFitting
} // namespace Mantid

#endif /*MANTID_CURVEFITTING_ABRAGAM_H_*/
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace Mantid
Provide static Kubo Toyabe fitting function
@author Karl Palmen, ISIS, RAL
@date 20/01/2012
@date 20/03/2012
Copyright &copy; 2007-2012 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
Expand Down
69 changes: 69 additions & 0 deletions Code/Mantid/Framework/CurveFitting/src/Abragam.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidCurveFitting/Abragam.h"
#include <cmath>


namespace Mantid
{
namespace CurveFitting
{

using namespace Kernel;
using namespace API;

DECLARE_FUNCTION(Abragam)

void Abragam::init()
{
declareParameter("A", 0.2);
declareParameter("Omega", 0.5);
declareParameter("Phi", 0);
declareParameter("Sigma", 1);
declareParameter("Tau",1);
}


void Abragam::functionMW(double* out, const double* xValues, const size_t nData)const
{
const double& A = getParameter("A");
const double& w = getParameter("Omega");
const double& phi = getParameter("Phi");
const double& sig = getParameter("Sigma");
const double& t = getParameter("Tau");

for (int i = 0; i < nData; i++) {
double A1=A*cos(w*xValues[i]+phi);
double A2=-(sig*sig*t*t)*(exp(-xValues[i]/t)-1+(xValues[i]/t));
double A3=exp(A2);

out[i] = A1*A3;
}

}

void Abragam::functionDerivMW(Jacobian* out, const double* xValues, const size_t nData)
{
calNumericalDeriv(out, xValues, nData);
}

void Abragam::setActiveParameter(size_t i,double value)
{
size_t j = indexOfActive(i);

if (parameterName(j) == "Sigma" )
setParameter(j,fabs(value),false); // Make sigma positive
else if (parameterName(j) == "Phi")
{
double a = fmod(value, 2*M_PI); // Put angle in range of 0 to 360 degrees
if( a<0 ) a += 2*M_PI;
setParameter(j,a,false);
}
else
setParameter(j,value,false);
}


} // namespace CurveFitting
} // namespace Mantid
129 changes: 129 additions & 0 deletions Code/Mantid/Framework/CurveFitting/test/AbragamTest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#ifndef ABRAGAMTEST_H_
#define ABRAGAMTEST_H_

#include <cxxtest/TestSuite.h>

#include "MantidCurveFitting/Abragam.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 AbragamTest : public CxxTest::TestSuite
{
public:

void getMockData(Mantid::MantidVec& y, Mantid::MantidVec& e)
{
// Data got from the Abragam function on Excel spreadsheet with
// A = 0.3, Omega = 0.4, Phi = PI/4, Sigma = 0.2, Tau = 2.0
y[0] = 0.212132034;
y[1] = 0.110872429;
y[2] = -0.004130004;
y[3] = -0.107644046;
y[4] = -0.181984622;
y[5] = -0.218289678;
y[6] = -0.215908947;
y[7] = -0.180739307;
y[8] = -0.123016506;
y[9] = -0.054943061;
y[10] = 0.011526466;
y[11] = 0.066481012;
y[12] = 0.103250678;
y[13] = 0.118929645;
y[14] = 0.114251678;
y[15] = 0.092934753;
y[16] = 0.060672555;
y[17] = 0.023977227;
y[18] = -0.010929869;
y[19] = -0.039018774;
y[20] = -0.057037526;

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 = "AbragamMockData";
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
Abragam 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","20");

// 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.000001,0.000001);

// test the output from fit is what you expect
IFitFunction *out = FunctionFactory::Instance().createInitialized(alg2.getPropertyValue("Function"));
TS_ASSERT_DELTA( out->getParameter("A"), 0.3 ,0.001);
TS_ASSERT_DELTA( out->getParameter("Omega"), 0.4 ,0.001);
TS_ASSERT_DELTA( out->getParameter("Phi"), M_PI/4.0 ,0.01); // 45 degrees
TS_ASSERT_DELTA( out->getParameter("Sigma"), 0.2 ,0.001);
TS_ASSERT_DELTA( out->getParameter("Tau"), 2.0 ,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 /*ABRAGAMTEST_H_*/

0 comments on commit 994c699

Please sign in to comment.