Skip to content

Commit

Permalink
Refs #11043. Adding actual PawleyFunction
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Wedel committed Mar 11, 2015
1 parent 1428773 commit 9558185
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 22 deletions.
Expand Up @@ -2,6 +2,8 @@
#define MANTID_CURVEFITTING_PAWLEYFUNCTION_H_

#include "MantidKernel/System.h"
#include "MantidAPI/CompositeFunction.h"
#include "MantidAPI/FunctionParameterDecorator.h"
#include "MantidAPI/IFunction1D.h"
#include "MantidAPI/ParamFunction.h"

Expand All @@ -11,6 +13,37 @@
namespace Mantid {
namespace CurveFitting {

class DLLExport PawleyParameterFunction : virtual public API::IFunction,
virtual public API::ParamFunction {
public:
PawleyParameterFunction();
virtual ~PawleyParameterFunction() {}

std::string name() const { return "PawleyParameterFunction"; }

void setAttribute(const std::string &attName, const Attribute &attValue);

Geometry::PointGroup::CrystalSystem getCrystalSystem() const;
Geometry::UnitCell getUnitCellFromParameters() const;

void function(const API::FunctionDomain &domain,
API::FunctionValues &values) const;
void functionDeriv(const API::FunctionDomain &domain,
API::Jacobian &jacobian);

protected:
void init();

void setCrystalSystem(const std::string &crystalSystem);

void createCrystalSystemParameters(
Geometry::PointGroup::CrystalSystem crystalSystem);

Geometry::PointGroup::CrystalSystem m_crystalSystem;
};

typedef boost::shared_ptr<PawleyParameterFunction> PawleyParameterFunction_sptr;

/** PawleyFunction
The Pawley approach to obtain lattice parameters from a powder diffractogram
Expand Down Expand Up @@ -46,35 +79,34 @@ namespace CurveFitting {
File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport PawleyParameterFunction : virtual public API::IFunction,
virtual public API::ParamFunction {
class PawleyFunction : public API::IFunction1D,
public API::FunctionParameterDecorator {
public:
PawleyParameterFunction();
virtual ~PawleyParameterFunction() {}

std::string name() const { return "PawleyParameterFunction"; }
virtual ~PawleyFunction() {}

void setAttribute(const std::string &attName, const Attribute &attValue);
std::string name() const { return "PawleyFunction"; }

Geometry::PointGroup::CrystalSystem getCrystalSystem() const;
Geometry::UnitCell getUnitCellFromParameters() const;
void setCrystalSystem(const std::string &crystalSystem);
void setProfileFunction(const std::string &profileFunction);

void function(const API::FunctionDomain &domain,
API::FunctionValues &values) const;
void function1D(double *out, const double *xValues, const size_t nData) const;
void functionDeriv1D(API::Jacobian *out, const double *xValues,
const size_t nData);
void functionDeriv(const API::FunctionDomain &domain,
API::Jacobian &jacobian);
API::Jacobian &jacobian) {
calNumericalDeriv(domain, jacobian);
}

void addPeak();

protected:
void init();
void beforeDecoratedFunctionSet(const API::IFunction_sptr &fn);

void setCrystalSystem(const std::string &crystalSystem);

void createCrystalSystemParameters(
Geometry::PointGroup::CrystalSystem crystalSystem);

Geometry::PointGroup::CrystalSystem m_crystalSystem;
API::CompositeFunction_sptr m_compositeFunction;
PawleyParameterFunction_sptr m_pawleyParameterFunction;
API::CompositeFunction_sptr m_peakProfileComposite;
};

} // namespace CurveFitting
} // namespace Mantid

Expand Down
77 changes: 77 additions & 0 deletions Code/Mantid/Framework/CurveFitting/src/PawleyFunction.cpp
@@ -1,9 +1,15 @@
#include "MantidCurveFitting/PawleyFunction.h"

#include "MantidAPI/FunctionFactory.h"

#include <boost/algorithm/string.hpp>
#include <boost/make_shared.hpp>

namespace Mantid {
namespace CurveFitting {

DECLARE_FUNCTION(PawleyParameterFunction)

using namespace API;
using namespace Geometry;

Expand Down Expand Up @@ -160,5 +166,76 @@ void PawleyParameterFunction::createCrystalSystemParameters(
declareParameter("ZeroShift", 0.0);
}

void PawleyFunction::setCrystalSystem(const std::string &crystalSystem) {
m_pawleyParameterFunction->setAttributeValue("CrystalSystem", crystalSystem);
m_compositeFunction->checkFunction();
}

void PawleyFunction::setProfileFunction(const std::string &profileFunction) {
m_pawleyParameterFunction->setAttributeValue("ProfileFunction",
profileFunction);
m_compositeFunction->checkFunction();
}

void PawleyFunction::function1D(double *out, const double *xValues,
const size_t nData) const {
UNUSED_ARG(out);
UNUSED_ARG(xValues);
UNUSED_ARG(nData);
}

void PawleyFunction::functionDeriv1D(API::Jacobian *out, const double *xValues,
const size_t nData) {
UNUSED_ARG(out);
UNUSED_ARG(xValues);
UNUSED_ARG(nData);
}

void PawleyFunction::addPeak() {
m_peakProfileComposite->addFunction(
FunctionFactory::Instance().createFunction("Gaussian"));
}

void PawleyFunction::init() {
setDecoratedFunction("CompositeFunction");

if (!m_compositeFunction) {
throw std::runtime_error(
"PawleyFunction could not construct internal CompositeFunction.");
}
}

void PawleyFunction::beforeDecoratedFunctionSet(const API::IFunction_sptr &fn) {
CompositeFunction_sptr composite =
boost::dynamic_pointer_cast<CompositeFunction>(fn);

if (!composite) {
throw std::invalid_argument("PawleyFunction only works with "
"CompositeFunction. Selecting another "
"decorated function is not possible.");
}

m_compositeFunction = composite;

if (m_compositeFunction->nFunctions() == 0) {
m_peakProfileComposite = boost::dynamic_pointer_cast<CompositeFunction>(
FunctionFactory::Instance().createFunction("CompositeFunction"));

m_pawleyParameterFunction =
boost::dynamic_pointer_cast<PawleyParameterFunction>(
FunctionFactory::Instance().createFunction(
"PawleyParameterFunction"));

m_compositeFunction->addFunction(m_pawleyParameterFunction);
m_compositeFunction->addFunction(m_peakProfileComposite);
} else {
m_pawleyParameterFunction =
boost::dynamic_pointer_cast<PawleyParameterFunction>(
m_compositeFunction->getFunction(0));
m_peakProfileComposite = boost::dynamic_pointer_cast<CompositeFunction>(
m_compositeFunction->getFunction(1));
}
}

} // namespace CurveFitting
} // namespace Mantid
28 changes: 25 additions & 3 deletions Code/Mantid/Framework/CurveFitting/test/PawleyFunctionTest.h
Expand Up @@ -6,7 +6,7 @@
#include "MantidCurveFitting/PawleyFunction.h"
#include "MantidGeometry/Crystal/PointGroup.h"

using Mantid::CurveFitting::PawleyParameterFunction;
using namespace Mantid::CurveFitting;
using namespace Mantid::API;
using namespace Mantid::Geometry;
using namespace Mantid::Kernel;
Expand Down Expand Up @@ -251,9 +251,31 @@ class PawleyFunctionTest : public CxxTest::TestSuite {
cellParametersAre(cell, 3.0, 4.0, 5.0, 101.0, 111.0, 103.0);
}

void testPawleyFunctionInitialization() {
PawleyFunction fn;
fn.initialize();

TS_ASSERT(boost::dynamic_pointer_cast<CompositeFunction>(
fn.getDecoratedFunction()));

// The base parameters of PawleyParameterFunction
TS_ASSERT_EQUALS(fn.nParams(), 7);
}

void testPawleyFunctionSetCrystalSystem() {
PawleyFunction fn;
fn.initialize();

TS_ASSERT_EQUALS(fn.nParams(), 7);

fn.setCrystalSystem("Cubic");

TS_ASSERT_EQUALS(fn.nParams(), 2);
}

private:
void cellParametersAre(const UnitCell &cell, double a, double b, double c, double alpha,
double beta, double gamma) {
void cellParametersAre(const UnitCell &cell, double a, double b, double c,
double alpha, double beta, double gamma) {
TS_ASSERT_DELTA(cell.a(), a, 1e-9);
TS_ASSERT_DELTA(cell.b(), b, 1e-9);
TS_ASSERT_DELTA(cell.c(), c, 1e-9);
Expand Down

0 comments on commit 9558185

Please sign in to comment.