Skip to content

Commit

Permalink
refs #10904. IntegratePeaksMD algorithms done.
Browse files Browse the repository at this point in the history
IntegratePeaksMD v1 and v2 write out integrated peak info in the form of PeakShape

PeakShapeSpherical adapted to write out background outer radius and background inner radius as well as the peak radius. Factories also updated for this, unit tests added to and updated for this.

I got a little worried that someone may change the integer values agaist the enum entries of SpecialCoordinateSystem. So I put in place a unit test to sanity check those.
  • Loading branch information
OwenArnold committed Feb 5, 2015
1 parent 44f167b commit 4427109
Show file tree
Hide file tree
Showing 13 changed files with 367 additions and 32 deletions.
1 change: 1 addition & 0 deletions Code/Mantid/Framework/API/CMakeLists.txt
Expand Up @@ -361,6 +361,7 @@ set ( TEST_FILES
SampleTest.h
ScopedWorkspaceTest.h
ScriptBuilderTest.h
SpecialCoordinateSystemTest.h
SpectraAxisTest.h
SpectrumDetectorMappingTest.h
TextAxisTest.h
Expand Down
Expand Up @@ -6,7 +6,7 @@ namespace API {
/**
* Special coordinate systems for Q3D.
*/
enum SpecialCoordinateSystem { None = 0, QLab = 1, QSample = 2, HKL = 3 };
enum SpecialCoordinateSystem { None = 0, QLab = 1, QSample = 2, HKL = 3 }; // Do NOT alter existing values
}
}

Expand Down
55 changes: 55 additions & 0 deletions Code/Mantid/Framework/API/test/SpecialCoordinateSystemTest.h
@@ -0,0 +1,55 @@
#ifndef MANTID_API_SPECIALCOORDINATESYSTEMTEST
#define MANTID_API_SPECIALCOORDINATESYSTEMTEST

#include <cxxtest/TestSuite.h>
#include "MantidAPI/SpecialCoordinateSystem.h"

using namespace Mantid::API;

/*
* We are testing the enum because the order of the elements in the enum is critical. There are various places in the codebase where the
* enum integer values are assumed to be constant. A proper fix for this would be a type replacment enum->object, but while that has not been done,
* a santiy check (these tests) on the enum ordering will prevent unintentional reordering.
*/
class SpecialCoordinateSystemTest : public CxxTest::TestSuite
{
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor (& destructor) isn't called when running other tests
static SpecialCoordinateSystemTest *createSuite() { return new SpecialCoordinateSystemTest(); }
static void destroySuite( SpecialCoordinateSystemTest *suite ) { delete suite; }

void test_none()
{
// Do not change
SpecialCoordinateSystem none = None;
TS_ASSERT_EQUALS(0, none);
}

void test_qLab()
{
// Do not change
SpecialCoordinateSystem qlab = QLab;
TS_ASSERT_EQUALS(1, qlab);
}

void test_qSample()
{
// Do not change
SpecialCoordinateSystem qSample = QSample;
TS_ASSERT_EQUALS(2, qSample);
}

void test_HKL()
{
// Do not change
SpecialCoordinateSystem hkl = HKL;
TS_ASSERT_EQUALS(3, hkl);
}


};

#endif


Expand Up @@ -4,6 +4,7 @@
#include "MantidKernel/System.h"
#include "MantidDataObjects/PeakShapeBase.h"
#include "MantidAPI/SpecialCoordinateSystem.h"
#include <boost/optional.hpp>
#include <string>

namespace Mantid {
Expand Down Expand Up @@ -39,6 +40,11 @@ class DLLExport PeakShapeSpherical : public PeakShapeBase {
API::SpecialCoordinateSystem frame,
std::string algorithmName = std::string(),
int algorithmVersion = -1);
/// Constructor
PeakShapeSpherical(const double &peakRadius, const double& peakInnerRadius, const double& peakOuterRadius,
API::SpecialCoordinateSystem frame,
std::string algorithmName = std::string(),
int algorithmVersion = -1);
/// Destructor
virtual ~PeakShapeSpherical();
/// Copy constructor
Expand All @@ -55,10 +61,18 @@ class DLLExport PeakShapeSpherical : public PeakShapeBase {
bool operator==(const PeakShapeSpherical &other) const;
/// Peak radius
double radius() const;
/// Peak outer background radius
boost::optional<double> backgroundOuterRadius() const;
/// Peak inner background radius
boost::optional<double> backgroundInnerRadius() const;

private:
/// Peak radius
double m_radius;
/// Background outer radius
boost::optional<double> m_backgroundOuterRadius;
/// Background inner radius;
boost::optional<double> m_backgroundInnerRadius;
};

} // namespace DataObjects
Expand Down
73 changes: 70 additions & 3 deletions Code/Mantid/Framework/DataObjects/src/PeakShapeSpherical.cpp
Expand Up @@ -5,13 +5,46 @@
namespace Mantid {
namespace DataObjects {

/**
* @brief Constructor
* @param peakRadius : Peak radius
* @param frame : Coordinate frame used for the integration
* @param algorithmName : Algorithm name used for the integration
* @param algorithmVersion : Algorithm version used for the integration
*/
PeakShapeSpherical::PeakShapeSpherical(const double &peakRadius,
API::SpecialCoordinateSystem frame,
std::string algorithmName,
int algorithmVersion)
: PeakShapeBase(frame, algorithmName, algorithmVersion),
m_radius(peakRadius) {}

/**
* @brief PeakShapeSpherical::PeakShapeSpherical
* @param peakRadius : Peak radius
* @param peakInnerRadius : Peak inner radius
* @param peakOuterRadius : Peak outer radius
* @param frame : Coordinate frame used for the integration
* @param algorithmName : Algorithm name
* @param algorithmVersion : Algorithm version
*/
PeakShapeSpherical::PeakShapeSpherical(const double &peakRadius,
const double &peakInnerRadius,
const double &peakOuterRadius,
API::SpecialCoordinateSystem frame,
std::string algorithmName,
int algorithmVersion)
: PeakShapeBase(frame, algorithmName, algorithmVersion),
m_radius(peakRadius), m_backgroundInnerRadius(peakInnerRadius),
m_backgroundOuterRadius(peakOuterRadius) {
if (peakRadius == m_backgroundInnerRadius) {
m_backgroundInnerRadius.reset();
}
if (peakRadius == m_backgroundOuterRadius) {
m_backgroundOuterRadius.reset();
}
}

//----------------------------------------------------------------------------------------------
/** Destructor
*/
Expand All @@ -22,7 +55,9 @@ PeakShapeSpherical::~PeakShapeSpherical() {}
* @param other : source of the copy
*/
PeakShapeSpherical::PeakShapeSpherical(const PeakShapeSpherical &other)
: PeakShapeBase(other), m_radius(other.radius()) {}
: PeakShapeBase(other), m_radius(other.radius()),
m_backgroundOuterRadius(other.backgroundOuterRadius()),
m_backgroundInnerRadius(other.backgroundInnerRadius()) {}

/**
* @brief Assignment operator
Expand All @@ -34,6 +69,8 @@ operator=(const PeakShapeSpherical &other) {
if (this != &other) {
PeakShapeBase::operator=(other);
m_radius = other.radius();
m_backgroundOuterRadius = other.backgroundOuterRadius();
m_backgroundInnerRadius = other.backgroundInnerRadius();
}
return *this;
}
Expand All @@ -45,7 +82,17 @@ operator=(const PeakShapeSpherical &other) {
std::string PeakShapeSpherical::toJSON() const {
Json::Value root;
PeakShapeBase::buildCommon(root);
root["radius"] = Json::Value(radius());
root["radius"] = Json::Value(m_radius);
// Check that there is an inner radius before writing
if (m_backgroundInnerRadius.is_initialized()) {
root["background_outer_radius"] =
Json::Value(m_backgroundOuterRadius.get());
}
// Check that there is an outer radius before writing
if (m_backgroundOuterRadius.is_initialized()) {
root["background_inner_radius"] =
Json::Value(m_backgroundInnerRadius.get());
}

Json::StyledWriter writer;
return writer.write(root);
Expand All @@ -62,7 +109,9 @@ PeakShapeSpherical *PeakShapeSpherical::clone() const {
std::string PeakShapeSpherical::shapeName() const { return "spherical"; }

bool PeakShapeSpherical::operator==(const PeakShapeSpherical &other) const {
return PeakShapeBase::operator==(other) && other.radius() == this->radius();
return PeakShapeBase::operator==(other) && other.radius() == this->radius() &&
other.backgroundInnerRadius() == this->backgroundInnerRadius() &&
other.backgroundOuterRadius() == this->backgroundOuterRadius();
}

/**
Expand All @@ -71,5 +120,23 @@ bool PeakShapeSpherical::operator==(const PeakShapeSpherical &other) const {
*/
double PeakShapeSpherical::radius() const { return m_radius; }

/**
* @brief Get the background outer radius. The outer radius may not be set, so
* this is optional.
* @return boost optional outer radius
*/
boost::optional<double> PeakShapeSpherical::backgroundOuterRadius() const {
return m_backgroundOuterRadius;
}

/**
* @brief Get the background inner radius. The inner radius may not be set, so
* this is optional.
* @return boost optional inner radius.
*/
boost::optional<double> PeakShapeSpherical::backgroundInnerRadius() const {
return m_backgroundInnerRadius;
}

} // namespace DataObjects
} // namespace Mantid
Expand Up @@ -38,8 +38,21 @@ PeakShape *PeakShapeSphericalFactory::create(const std::string &source) const {
static_cast<SpecialCoordinateSystem>(root["frame"].asInt()));
const double radius(root["radius"].asDouble());

product = new PeakShapeSpherical(radius, frame, algorithmName,
algorithmVersion);
if (!root["background_outer_radius"].empty() &&
!root["background_inner_radius"].empty()) {
const double backgroundOuterRadius(
root["background_outer_radius"].asDouble());
const double backgroundInnerRadius(
root["background_inner_radius"].asDouble());
product = new PeakShapeSpherical(radius, backgroundInnerRadius, backgroundOuterRadius, frame, algorithmName,
algorithmVersion);
}

else {

product = new PeakShapeSpherical(radius, frame, algorithmName,
algorithmVersion);
}
} else {
if (m_successor) {
product = m_successor->create(source);
Expand Down
Expand Up @@ -93,6 +93,30 @@ class PeakShapeSphericalFactoryTest : public CxxTest::TestSuite {
TS_ASSERT_EQUALS(sourceShape, *sphericalShapeProduct);
delete productShape;
}

void test_create_with_multiple_radii()
{
const double radius = 2;
const double backgroundInnerRadius = 3;
const double backgroundOuterRadius = 4;
const SpecialCoordinateSystem frame = HKL;
const std::string algorithmName = "foo";
const int algorithmVersion = 3;

// Make a source shape with background outer and inner radius
PeakShapeSpherical sourceShape(radius, backgroundInnerRadius, backgroundOuterRadius, frame, algorithmName,
algorithmVersion);

PeakShapeSphericalFactory factory;
PeakShape *productShape = factory.create(sourceShape.toJSON());

PeakShapeSpherical *sphericalShapeProduct =
dynamic_cast<PeakShapeSpherical *>(productShape);
TS_ASSERT(sphericalShapeProduct);

TS_ASSERT_EQUALS(sourceShape, *sphericalShapeProduct);
delete productShape;
}
};

#endif /* MANTID_DATAOBJECTS_PEAKSHAPESPHERICALFACTORYTEST_H_ */

0 comments on commit 4427109

Please sign in to comment.