Skip to content

Commit

Permalink
Refs #11043. Correcting parameter behavior, adding peaks.
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Wedel committed Mar 11, 2015
1 parent 9558185 commit 492aff6
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 18 deletions.
Expand Up @@ -5,6 +5,7 @@
#include "MantidAPI/CompositeFunction.h"
#include "MantidAPI/FunctionParameterDecorator.h"
#include "MantidAPI/IFunction1D.h"
#include "MantidAPI/IPeakFunction.h"
#include "MantidAPI/ParamFunction.h"

#include "MantidGeometry/Crystal/PointGroup.h"
Expand All @@ -26,6 +27,14 @@ class DLLExport PawleyParameterFunction : virtual public API::IFunction,
Geometry::PointGroup::CrystalSystem getCrystalSystem() const;
Geometry::UnitCell getUnitCellFromParameters() const;

std::string getProfileFunctionName() const {
return getAttribute("ProfileFunction").asString();
}

std::string getProfileFunctionCenterParameterName() const {
return m_profileFunctionCenterParameterName;
}

void function(const API::FunctionDomain &domain,
API::FunctionValues &values) const;
void functionDeriv(const API::FunctionDomain &domain,
Expand All @@ -34,12 +43,16 @@ class DLLExport PawleyParameterFunction : virtual public API::IFunction,
protected:
void init();

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

void createCrystalSystemParameters(
Geometry::PointGroup::CrystalSystem crystalSystem);
void setCenterParameterNameFromFunction(
const API::IPeakFunction_sptr &profileFunction);

Geometry::PointGroup::CrystalSystem m_crystalSystem;
std::string m_profileFunctionCenterParameterName;
};

typedef boost::shared_ptr<PawleyParameterFunction> PawleyParameterFunction_sptr;
Expand Down Expand Up @@ -82,6 +95,7 @@ typedef boost::shared_ptr<PawleyParameterFunction> PawleyParameterFunction_sptr;
class PawleyFunction : public API::IFunction1D,
public API::FunctionParameterDecorator {
public:
PawleyFunction();
virtual ~PawleyFunction() {}

std::string name() const { return "PawleyFunction"; }
Expand All @@ -94,10 +108,12 @@ class PawleyFunction : public API::IFunction1D,
const size_t nData);
void functionDeriv(const API::FunctionDomain &domain,
API::Jacobian &jacobian) {
calNumericalDeriv(domain, jacobian);
calNumericalDeriv(domain, jacobian);
}

void addPeak();
void addPeak(const Kernel::V3D &hkl, double centre, double fwhm,
double height);
API::IPeakFunction_sptr getPeak(size_t i) const;

protected:
void init();
Expand All @@ -106,6 +122,8 @@ class PawleyFunction : public API::IFunction1D,
API::CompositeFunction_sptr m_compositeFunction;
PawleyParameterFunction_sptr m_pawleyParameterFunction;
API::CompositeFunction_sptr m_peakProfileComposite;

std::vector<Kernel::V3D> m_hkls;
};
} // namespace CurveFitting
} // namespace Mantid
Expand Down
78 changes: 67 additions & 11 deletions Code/Mantid/Framework/CurveFitting/src/PawleyFunction.cpp
Expand Up @@ -14,12 +14,15 @@ using namespace API;
using namespace Geometry;

PawleyParameterFunction::PawleyParameterFunction()
: ParamFunction(), m_crystalSystem(PointGroup::Triclinic) {}
: ParamFunction(), m_crystalSystem(PointGroup::Triclinic),
m_profileFunctionCenterParameterName() {}

void PawleyParameterFunction::setAttribute(const std::string &attName,
const Attribute &attValue) {
if (attName == "CrystalSystem") {
setCrystalSystem(attValue.asString());
} else if (attName == "ProfileFunction") {
setProfileFunction(attValue.asString());
}

ParamFunction::setAttribute(attName, attValue);
Expand Down Expand Up @@ -81,15 +84,21 @@ void PawleyParameterFunction::init() {
declareAttribute("CrystalSystem", IFunction::Attribute("Triclinic"));
declareAttribute("ProfileFunction", IFunction::Attribute("Gaussian"));

declareParameter("a", 1.0);
declareParameter("b", 1.0);
declareParameter("c", 1.0);
setCrystalSystem("Triclinic");
setProfileFunction("Gaussian");
}

declareParameter("Alpha", 90.0);
declareParameter("Beta", 90.0);
declareParameter("Gamma", 90.0);
void PawleyParameterFunction::setProfileFunction(
const std::string &profileFunction) {
IPeakFunction_sptr peakFunction = boost::dynamic_pointer_cast<IPeakFunction>(
FunctionFactory::Instance().createFunction(profileFunction));

declareParameter("ZeroShift", 0.0);
if (!peakFunction) {
throw std::invalid_argument("PawleyFunction can only use IPeakFunctions to "
"calculate peak profiles.");
}

setCenterParameterNameFromFunction(peakFunction);
}

void
Expand Down Expand Up @@ -166,6 +175,19 @@ void PawleyParameterFunction::createCrystalSystemParameters(
declareParameter("ZeroShift", 0.0);
}

void PawleyParameterFunction::setCenterParameterNameFromFunction(
const IPeakFunction_sptr &profileFunction) {
m_profileFunctionCenterParameterName.clear();
if (profileFunction) {
m_profileFunctionCenterParameterName =
profileFunction->getCentreParameterName();
}
}

PawleyFunction::PawleyFunction()
: FunctionParameterDecorator(), m_compositeFunction(),
m_pawleyParameterFunction(), m_peakProfileComposite(), m_hkls() {}

void PawleyFunction::setCrystalSystem(const std::string &crystalSystem) {
m_pawleyParameterFunction->setAttributeValue("CrystalSystem", crystalSystem);
m_compositeFunction->checkFunction();
Expand All @@ -174,6 +196,23 @@ void PawleyFunction::setCrystalSystem(const std::string &crystalSystem) {
void PawleyFunction::setProfileFunction(const std::string &profileFunction) {
m_pawleyParameterFunction->setAttributeValue("ProfileFunction",
profileFunction);

// At this point PawleyParameterFunction guarantees that it's an IPeakFunction
for (size_t i = 0; i < m_peakProfileComposite->nFunctions(); ++i) {
IPeakFunction_sptr oldFunction = boost::dynamic_pointer_cast<IPeakFunction>(
m_peakProfileComposite->getFunction(i));

IPeakFunction_sptr newFunction = boost::dynamic_pointer_cast<IPeakFunction>(
FunctionFactory::Instance().createFunction(
m_pawleyParameterFunction->getProfileFunctionName()));

newFunction->setCentre(oldFunction->centre());
newFunction->setFwhm(oldFunction->fwhm());
newFunction->setHeight(oldFunction->height());

m_peakProfileComposite->replaceFunction(i, newFunction);
}

m_compositeFunction->checkFunction();
}

Expand All @@ -191,9 +230,26 @@ void PawleyFunction::functionDeriv1D(API::Jacobian *out, const double *xValues,
UNUSED_ARG(nData);
}

void PawleyFunction::addPeak() {
m_peakProfileComposite->addFunction(
FunctionFactory::Instance().createFunction("Gaussian"));
void PawleyFunction::addPeak(const Kernel::V3D &hkl, double centre, double fwhm,
double height) {
m_hkls.push_back(hkl);

IPeakFunction_sptr peak = boost::dynamic_pointer_cast<IPeakFunction>(
FunctionFactory::Instance().createFunction(
m_pawleyParameterFunction->getProfileFunctionName()));

peak->setCentre(centre);
peak->setFwhm(fwhm);
peak->setHeight(height);

m_peakProfileComposite->addFunction(peak);

m_compositeFunction->checkFunction();
}

IPeakFunction_sptr PawleyFunction::getPeak(size_t i) const {
return boost::dynamic_pointer_cast<IPeakFunction>(
m_peakProfileComposite->getFunction(i));
}

void PawleyFunction::init() {
Expand Down
36 changes: 31 additions & 5 deletions Code/Mantid/Framework/CurveFitting/test/PawleyFunctionTest.h
Expand Up @@ -263,14 +263,40 @@ class PawleyFunctionTest : public CxxTest::TestSuite {
}

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

TS_ASSERT_EQUALS(fn.nParams(), 7);

fn.setCrystalSystem("Cubic");

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

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

TS_ASSERT_EQUALS(fn.nParams(), 7);

fn.addPeak(V3D(), 2.0, 3.0, 4.0);

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

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

TS_ASSERT_EQUALS(fn.nParams(), 7);

fn.addPeak(V3D(), 2.0, 3.0, 4.0);

TS_ASSERT_EQUALS(fn.nParams(), 7);
TS_ASSERT_EQUALS(fn.nParams(), 10);

fn.setCrystalSystem("Cubic");
fn.setProfileFunction("PseudoVoigt");

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

private:
Expand Down

0 comments on commit 492aff6

Please sign in to comment.