Skip to content
Snippets Groups Projects
Commit 492aff6d authored by Michael Wedel's avatar Michael Wedel
Browse files

Refs #11043. Correcting parameter behavior, adding peaks.

parent 95581851
No related branches found
No related tags found
No related merge requests found
......@@ -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"
......@@ -26,6 +27,14 @@ public:
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,
......@@ -34,12 +43,16 @@ public:
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;
......@@ -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"; }
......@@ -94,10 +108,12 @@ public:
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();
......@@ -106,6 +122,8 @@ protected:
API::CompositeFunction_sptr m_compositeFunction;
PawleyParameterFunction_sptr m_pawleyParameterFunction;
API::CompositeFunction_sptr m_peakProfileComposite;
std::vector<Kernel::V3D> m_hkls;
};
} // namespace CurveFitting
} // namespace Mantid
......
......@@ -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);
......@@ -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
......@@ -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();
......@@ -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();
}
......@@ -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() {
......
......@@ -263,14 +263,40 @@ public:
}
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:
......
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