Skip to content

Commit

Permalink
Refs #11551. Adding better unit cell access to ILatticeFunction
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Wedel committed Apr 17, 2015
1 parent 511df42 commit c78b7a5
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 53 deletions.
9 changes: 8 additions & 1 deletion Code/Mantid/Framework/API/inc/MantidAPI/ILatticeFunction.h
Expand Up @@ -11,7 +11,9 @@ namespace API {

/** ILatticeFunction
This abstract class defines the interface for a function that
This abstract class defines the interface for a function that calculates
values based on HKL-values and a lattice. Currently the only implementation
is CurveFitting::LatticeFunction.
@author Michael Wedel, Paul Scherrer Institut - SINQ
@date 15/04/2015
Expand Down Expand Up @@ -57,6 +59,11 @@ class MANTID_API_DLL ILatticeFunction : public FunctionParameterDecorator {

/// Set the function parameters according to the supplied unit cell.
virtual void setUnitCell(const std::string &unitCellString) = 0;
/// Overload to set unit cell directly from UnitCell object.
virtual void setUnitCell(const Geometry::UnitCell &unitCell) = 0;

/// Returns a unit cell object created from the function parameters
virtual Geometry::UnitCell getUnitCell() const = 0;
};

typedef boost::shared_ptr<ILatticeFunction> ILatticeFunction_sptr;
Expand Down
Expand Up @@ -53,6 +53,8 @@ class DLLExport LatticeFunction : public API::ILatticeFunction {

void setCrystalSystem(const std::string &crystalSystem);
void setUnitCell(const std::string &unitCellString);
void setUnitCell(const Geometry::UnitCell &unitCell);
Geometry::UnitCell getUnitCell() const;

protected:
void init();
Expand Down
14 changes: 14 additions & 0 deletions Code/Mantid/Framework/CurveFitting/src/LatticeFunction.cpp
Expand Up @@ -41,6 +41,20 @@ void LatticeFunction::setUnitCell(const std::string &unitCellString) {
m_cellParameters->setParametersFromUnitCell(strToUnitCell(unitCellString));
}

/// Sets the unit cell parameters from a UnitCell object.
void LatticeFunction::setUnitCell(const UnitCell &unitCell) {
throwIfNoFunctionSet();

m_cellParameters->setParametersFromUnitCell(unitCell);
}

/// Returns a UnitCell object constructed from the function parameters.
UnitCell LatticeFunction::getUnitCell() const {
throwIfNoFunctionSet();

return m_cellParameters->getUnitCellFromParameters();
}

/// Sets the decorated function to expose parameters
void LatticeFunction::init() {
setDecoratedFunction("PawleyParameterFunction");
Expand Down
131 changes: 79 additions & 52 deletions Code/Mantid/Framework/CurveFitting/test/LatticeFunctionTest.h
Expand Up @@ -8,9 +8,12 @@
#include "MantidAPI/FunctionFactory.h"
#include "MantidAPI/LatticeDomain.h"
#include "MantidAPI/TableRow.h"
#include "MantidGeometry/Crystal/UnitCell.h"

using Mantid::CurveFitting::LatticeFunction;
using Mantid::Kernel::V3D;
using Mantid::Geometry::UnitCell;
using Mantid::Geometry::unitCellToStr;

using namespace Mantid::API;

Expand Down Expand Up @@ -47,7 +50,7 @@ class LatticeFunctionTest : public CxxTest::TestSuite {
*/
}

void testSetUnitCell() {
void testSetUnitCellString() {
LatticeFunction fn;
fn.initialize();

Expand All @@ -68,61 +71,85 @@ class LatticeFunctionTest : public CxxTest::TestSuite {
TS_ASSERT_EQUALS(fn.getParameter("Gamma"), 90.0);
}

void testSetUnitCellUnitCell() {
LatticeFunction fn;
fn.initialize();

TS_ASSERT_THROWS_NOTHING(fn.setUnitCell(UnitCell(1, 2, 3, 90, 100, 110)));
TS_ASSERT_EQUALS(fn.getParameter("a"), 1.0);
TS_ASSERT_EQUALS(fn.getParameter("b"), 2.0);
TS_ASSERT_EQUALS(fn.getParameter("c"), 3.0);
TS_ASSERT_EQUALS(fn.getParameter("Alpha"), 90.0);
TS_ASSERT_EQUALS(fn.getParameter("Beta"), 100.0);
TS_ASSERT_EQUALS(fn.getParameter("Gamma"), 110.0);
}

void testGetUnitCell() {
LatticeFunction fn;
fn.initialize();

UnitCell cell(1, 2, 3, 90, 100, 110);
TS_ASSERT_THROWS_NOTHING(fn.setUnitCell(cell));

TS_ASSERT_EQUALS(unitCellToStr(fn.getUnitCell()), unitCellToStr(cell));
}

void testFunctionValues() {
LatticeFunction fn;
fn.initialize();

// Al2O3, from PoldiCreatePeaksFromCell system test.
fn.setCrystalSystem("Hexagonal");
fn.setParameter("a", 4.7605);
fn.setParameter("c", 12.9956);

std::vector<V3D> hkls;
hkls.push_back(V3D(1, 0, -2));
hkls.push_back(V3D(1, 0, 4));
hkls.push_back(V3D(0, 0, 6));
hkls.push_back(V3D(5, -2, -5));

LatticeDomain domain(hkls);
FunctionValues values(domain);

// Calculate d-values
TS_ASSERT_THROWS_NOTHING(fn.function(domain, values));

// Check values.
TS_ASSERT_DELTA(values[0], 3.481144, 1e-6);
TS_ASSERT_DELTA(values[1], 2.551773, 1e-6);
TS_ASSERT_DELTA(values[2], 2.165933, 1e-6);
TS_ASSERT_DELTA(values[3], 0.88880, 1e-5);
LatticeFunction fn;
fn.initialize();

// Al2O3, from PoldiCreatePeaksFromCell system test.
fn.setCrystalSystem("Hexagonal");
fn.setParameter("a", 4.7605);
fn.setParameter("c", 12.9956);

std::vector<V3D> hkls;
hkls.push_back(V3D(1, 0, -2));
hkls.push_back(V3D(1, 0, 4));
hkls.push_back(V3D(0, 0, 6));
hkls.push_back(V3D(5, -2, -5));

LatticeDomain domain(hkls);
FunctionValues values(domain);

// Calculate d-values
TS_ASSERT_THROWS_NOTHING(fn.function(domain, values));

// Check values.
TS_ASSERT_DELTA(values[0], 3.481144, 1e-6);
TS_ASSERT_DELTA(values[1], 2.551773, 1e-6);
TS_ASSERT_DELTA(values[2], 2.165933, 1e-6);
TS_ASSERT_DELTA(values[3], 0.88880, 1e-5);
}

void testFitExampleTable() {
// Fit Silicon lattice with three peaks.
ITableWorkspace_sptr table = WorkspaceFactory::Instance().createTable();
table->addColumn("V3D", "HKL");
table->addColumn("double", "d");

TableRow newRow = table->appendRow();
newRow << V3D(1, 1, 1) << 3.135702;
newRow = table->appendRow();
newRow << V3D(2, 2, 0) << 1.920217;
newRow = table->appendRow();
newRow << V3D(3, 1, 1) << 1.637567;

IFunction_sptr fn = FunctionFactory::Instance().createFunction("LatticeFunction");
fn->setAttributeValue("CrystalSystem", "Cubic");
fn->addTies("ZeroShift=0.0");
fn->setParameter("a", 5);

IAlgorithm_sptr fit = AlgorithmManager::Instance().create("Fit");
fit->setProperty("Function", fn);
fit->setProperty("InputWorkspace", table);
fit->setProperty("CostFunction", "Unweighted least squares");
fit->setProperty("CreateOutput", true);
fit->execute();

TS_ASSERT_DELTA(fn->getParameter("a"), 5.4311946, 1e-6);
TS_ASSERT_LESS_THAN(fn->getError(0), 1e-6);
// Fit Silicon lattice with three peaks.
ITableWorkspace_sptr table = WorkspaceFactory::Instance().createTable();
table->addColumn("V3D", "HKL");
table->addColumn("double", "d");

TableRow newRow = table->appendRow();
newRow << V3D(1, 1, 1) << 3.135702;
newRow = table->appendRow();
newRow << V3D(2, 2, 0) << 1.920217;
newRow = table->appendRow();
newRow << V3D(3, 1, 1) << 1.637567;

IFunction_sptr fn =
FunctionFactory::Instance().createFunction("LatticeFunction");
fn->setAttributeValue("CrystalSystem", "Cubic");
fn->addTies("ZeroShift=0.0");
fn->setParameter("a", 5);

IAlgorithm_sptr fit = AlgorithmManager::Instance().create("Fit");
fit->setProperty("Function", fn);
fit->setProperty("InputWorkspace", table);
fit->setProperty("CostFunction", "Unweighted least squares");
fit->setProperty("CreateOutput", true);
fit->execute();

TS_ASSERT_DELTA(fn->getParameter("a"), 5.4311946, 1e-6);
TS_ASSERT_LESS_THAN(fn->getError(0), 1e-6);
}
};

Expand Down

0 comments on commit c78b7a5

Please sign in to comment.