diff --git a/Code/Mantid/Framework/DataObjects/CMakeLists.txt b/Code/Mantid/Framework/DataObjects/CMakeLists.txt
index 5ddf645329ed..0e165cd0107d 100644
--- a/Code/Mantid/Framework/DataObjects/CMakeLists.txt
+++ b/Code/Mantid/Framework/DataObjects/CMakeLists.txt
@@ -14,6 +14,7 @@ set ( SRC_FILES
src/PeakColumn.cpp
src/PeakNoShapeFactory.cpp
src/PeakShapeBase.cpp
+ src/PeakShapeEllipsoid.cpp
src/PeakShapeSpherical.cpp
src/PeakShapeSphericalFactory.cpp
src/PeaksWorkspace.cpp
@@ -51,6 +52,7 @@ set ( INC_FILES
inc/MantidDataObjects/PeakNoShapeFactory.h
inc/MantidDataObjects/PeakShape.h
inc/MantidDataObjects/PeakShapeBase.h
+ inc/MantidDataObjects/PeakShapeEllipsoid.h
inc/MantidDataObjects/PeakShapeFactory.h
inc/MantidDataObjects/PeakShapeSpherical.h
inc/MantidDataObjects/PeakShapeSphericalFactory.h
@@ -79,6 +81,7 @@ set ( TEST_FILES
OffsetsWorkspaceTest.h
PeakColumnTest.h
PeakNoShapeFactoryTest.h
+ PeakShapeEllipsoidTest.h
PeakShapeSphericalFactoryTest.h
PeakShapeSphericalTest.h
PeakTest.h
diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h
new file mode 100644
index 000000000000..3c187ac2da62
--- /dev/null
+++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h
@@ -0,0 +1,84 @@
+#ifndef MANTID_DATAOBJECTS_PEAKSHAPEELLIPSOID_H_
+#define MANTID_DATAOBJECTS_PEAKSHAPEELLIPSOID_H_
+
+#include "MantidKernel/System.h"
+#include "MantidKernel/V3D.h"
+#include "MantidDataObjects/PeakShapeBase.h"
+
+
+namespace Mantid
+{
+namespace DataObjects
+{
+
+ /** PeakShapeEllipsoid : PeakShape representing a 3D ellipsoid
+
+ Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source
+
+ This file is part of Mantid.
+
+ Mantid is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ Mantid is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ File change history is stored at:
+ Code Documentation is available at:
+ */
+ class DLLExport PeakShapeEllipsoid : public PeakShapeBase
+ {
+ public:
+ /// Constructor
+ PeakShapeEllipsoid(std::vector directions, std::vector abcRadius, std::vector abcBackgroundInnerRadius, std::vector abcBackgroundOuterRadius, API::SpecialCoordinateSystem frame,
+ std::string algorithmName = std::string(),
+ int algorithmVersion = -1);
+ /// Copy constructor
+ PeakShapeEllipsoid(const PeakShapeEllipsoid& other);
+ /// Assignment operator
+ PeakShapeEllipsoid& operator=(const PeakShapeEllipsoid& other);
+ /// Equals operator
+ bool operator==(const PeakShapeEllipsoid& other) const;
+ /// Destructor
+ virtual ~PeakShapeEllipsoid();
+ /// Get radii
+ std::vector abcRadii() const;
+ /// Get background inner radii
+ std::vector abcRadiiBackgroundInner() const;
+ /// Get background outer radii
+ std::vector abcRadiiBackgroundOuter() const;
+ /// Get ellipsoid directions
+ std::vector directions() const;
+
+ /// PeakShape interface
+ std::string toJSON() const;
+ /// Clone ellipsoid
+ PeakShape *clone() const;
+ /// Get the peak shape
+ std::string shapeName() const;
+
+ private:
+ /// principle axis
+ std::vector m_directions;
+ /// radii
+ std::vector m_abc_radii;
+ /// inner radii
+ std::vector m_abc_radiiBackgroundInner;
+ /// outer radii
+ std::vector m_abc_radiiBackgroundOuter;
+
+
+ };
+
+
+} // namespace DataObjects
+} // namespace Mantid
+
+#endif /* MANTID_DATAOBJECTS_PEAKSHAPEELLIPSOID_H_ */
diff --git a/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoid.cpp b/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoid.cpp
new file mode 100644
index 000000000000..d33a19cadf3a
--- /dev/null
+++ b/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoid.cpp
@@ -0,0 +1,105 @@
+#include "MantidDataObjects/PeakShapeEllipsoid.h"
+#include "MantidKernel/cow_ptr.h"
+#include
+
+namespace Mantid {
+namespace DataObjects {
+
+PeakShapeEllipsoid::PeakShapeEllipsoid(
+ std::vector directions, std::vector abcRadii,
+ std::vector abcRadiiBackgroundInner,
+ std::vector abcRadiiBackgroundOuter,
+ API::SpecialCoordinateSystem frame, std::string algorithmName,
+ int algorithmVersion)
+ : PeakShapeBase(frame, algorithmName, algorithmVersion),
+ m_directions(directions), m_abc_radii(abcRadii),
+ m_abc_radiiBackgroundInner(abcRadiiBackgroundInner),
+ m_abc_radiiBackgroundOuter(abcRadiiBackgroundOuter) {
+
+ if (directions.size() != 3) {
+ throw std::invalid_argument("directions must be of size 3");
+ }
+ if (abcRadii.size() != 3) {
+ throw std::invalid_argument("radii must be of size 3");
+ }
+ if (abcRadiiBackgroundInner.size() != 3) {
+ throw std::invalid_argument("radii inner must be of size 3");
+ }
+ if (abcRadiiBackgroundOuter.size() != 3) {
+ throw std::invalid_argument("radii outer must be of size 3");
+ }
+}
+
+PeakShapeEllipsoid::PeakShapeEllipsoid(const PeakShapeEllipsoid &other)
+ : PeakShapeBase(other), m_directions(other.directions()),
+ m_abc_radii(other.abcRadii()),
+ m_abc_radiiBackgroundInner(other.abcRadiiBackgroundInner()),
+ m_abc_radiiBackgroundOuter(other.abcRadiiBackgroundOuter()) {}
+
+PeakShapeEllipsoid &PeakShapeEllipsoid::
+operator=(const PeakShapeEllipsoid &other) {
+ if (&other != this) {
+ PeakShapeBase::operator=(other);
+ m_directions = other.directions();
+ m_abc_radii = other.abcRadii();
+ m_abc_radiiBackgroundInner = other.abcRadiiBackgroundInner();
+ m_abc_radiiBackgroundOuter = other.abcRadiiBackgroundOuter();
+ }
+ return *this;
+}
+
+bool PeakShapeEllipsoid::operator==(const PeakShapeEllipsoid &other) const {
+ return PeakShapeBase::operator==(other) &&
+ other.directions() == this->directions() &&
+ other.abcRadii() == this->abcRadii() &&
+ other.abcRadiiBackgroundInner() == this->abcRadiiBackgroundInner() &&
+ other.abcRadiiBackgroundOuter() == this->abcRadiiBackgroundOuter();
+}
+
+PeakShapeEllipsoid::~PeakShapeEllipsoid() {}
+
+std::vector PeakShapeEllipsoid::abcRadii() const { return m_abc_radii; }
+
+std::vector PeakShapeEllipsoid::abcRadiiBackgroundInner() const {
+ return m_abc_radiiBackgroundInner;
+}
+
+std::vector PeakShapeEllipsoid::abcRadiiBackgroundOuter() const {
+ return m_abc_radiiBackgroundOuter;
+}
+
+std::vector PeakShapeEllipsoid::directions() const {
+ return m_directions;
+}
+
+std::string PeakShapeEllipsoid::toJSON() const {
+ Json::Value root;
+ PeakShapeBase::buildCommon(root);
+ root["radius0"] = Json::Value(m_abc_radii[0]);
+ root["radius1"] = Json::Value(m_abc_radii[1]);
+ root["radius2"] = Json::Value(m_abc_radii[2]);
+
+ root["background_inner_radius0"] = Json::Value(m_abc_radiiBackgroundInner[0]);
+ root["background_inner_radius1"] = Json::Value(m_abc_radiiBackgroundInner[1]);
+ root["background_inner_radius2"] = Json::Value(m_abc_radiiBackgroundInner[2]);
+
+ root["background_outer_radius0"] = Json::Value(m_abc_radiiBackgroundOuter[0]);
+ root["background_outer_radius1"] = Json::Value(m_abc_radiiBackgroundOuter[1]);
+ root["background_outer_radius2"] = Json::Value(m_abc_radiiBackgroundOuter[2]);
+
+ root["direction0"] = m_directions[0].toString();
+ root["direction1"] = m_directions[1].toString();
+ root["direction2"] = m_directions[2].toString();
+
+ Json::StyledWriter writer;
+ return writer.write(root);
+}
+
+PeakShape *PeakShapeEllipsoid::clone() const {
+ return new PeakShapeEllipsoid(*this);
+}
+
+std::string PeakShapeEllipsoid::shapeName() const { return "ellipsoid"; }
+
+} // namespace DataObjects
+} // namespace Mantid
diff --git a/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidTest.h b/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidTest.h
new file mode 100644
index 000000000000..101a674bd40a
--- /dev/null
+++ b/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidTest.h
@@ -0,0 +1,185 @@
+#ifndef MANTID_DATAOBJECTS_PEAKSHAPEELLIPSOIDTEST_H_
+#define MANTID_DATAOBJECTS_PEAKSHAPEELLIPSOIDTEST_H_
+
+#include
+
+#include "MantidDataObjects/PeakShapeEllipsoid.h"
+#include "MantidKernel/cow_ptr.h"
+#include "MantidKernel/V3D.h"
+#include
+#include
+#include
+
+using Mantid::DataObjects::PeakShapeEllipsoid;
+using namespace Mantid;
+using namespace Mantid::Kernel;
+using namespace Mantid::API;
+using namespace boost::assign;
+
+class PeakShapeEllipsoidTest : public CxxTest::TestSuite {
+public:
+ // This pair of boilerplate methods prevent the suite being created statically
+ // This means the constructor isn't called when running other tests
+ static PeakShapeEllipsoidTest *createSuite() {
+ return new PeakShapeEllipsoidTest();
+ }
+ static void destroySuite(PeakShapeEllipsoidTest *suite) { delete suite; }
+
+ void test_constructor() {
+ auto directions = list_of(V3D(1, 0, 0))(V3D(0, 1, 0))(V3D(0, 0, 1))
+ .convert_to_container>();
+ const MantidVec abcRadii = list_of(2)(3)(4);
+ const MantidVec abcInnerRadii = list_of(5)(6)(7);
+ const MantidVec abcOuterRadii = list_of(8)(9)(10);
+ const SpecialCoordinateSystem frame = HKL;
+ const std::string algorithmName = "foo";
+ const int algorithmVersion = 3;
+
+ // Construct it.
+ PeakShapeEllipsoid shape(directions, abcRadii, abcInnerRadii, abcOuterRadii,
+ frame, algorithmName, algorithmVersion);
+
+ TS_ASSERT_EQUALS(abcRadii, shape.abcRadii());
+ TS_ASSERT_EQUALS(abcInnerRadii, shape.abcRadiiBackgroundInner());
+ TS_ASSERT_EQUALS(abcOuterRadii, shape.abcRadiiBackgroundOuter());
+
+ TS_ASSERT_EQUALS(frame, shape.frame());
+ TS_ASSERT_EQUALS(algorithmName, shape.algorithmName());
+ TS_ASSERT_EQUALS(algorithmVersion, shape.algorithmVersion());
+ }
+
+ void test_constructor_throws() {
+ auto directions = list_of(V3D(1, 0, 0))(V3D(0, 1, 0))(V3D(0, 0, 1))
+ .convert_to_container>();
+ auto bad_directions =
+ list_of(V3D(1, 0, 0)).convert_to_container>();
+ const MantidVec abcRadii = list_of(2)(3)(4);
+ const MantidVec bad_abcRadii = list_of(2)(3)(4)(5);
+ const MantidVec abcInnerRadii = list_of(5)(6)(7);
+ const MantidVec bad_abcInnerRadii = list_of(5)(6);
+ const MantidVec abcOuterRadii = list_of(8)(9)(10);
+ const MantidVec bad_abcOuterRadii = list_of(8)(9)(10)(11);
+ const SpecialCoordinateSystem frame = HKL;
+ const std::string algorithmName = "foo";
+ const int algorithmVersion = 3;
+
+ TSM_ASSERT_THROWS("Should throw, bad directions",
+ PeakShapeEllipsoid(bad_directions, abcRadii,
+ abcInnerRadii, abcOuterRadii, frame),
+ std::invalid_argument &);
+ TSM_ASSERT_THROWS("Should throw, bad radii",
+ PeakShapeEllipsoid(directions, bad_abcRadii,
+ abcInnerRadii, abcOuterRadii, frame),
+ std::invalid_argument &);
+ TSM_ASSERT_THROWS("Should throw, bad inner radii",
+ PeakShapeEllipsoid(directions, abcRadii,
+ bad_abcInnerRadii, abcOuterRadii,
+ frame),
+ std::invalid_argument &);
+ TSM_ASSERT_THROWS("Should throw, bad outer radii",
+ PeakShapeEllipsoid(directions, abcRadii, abcInnerRadii,
+ bad_abcOuterRadii, frame),
+ std::invalid_argument &);
+ }
+
+ void test_copy_constructor() {
+ auto directions = list_of(V3D(1, 0, 0))(V3D(0, 1, 0))(V3D(0, 0, 1))
+ .convert_to_container>();
+ const MantidVec abcRadii = list_of(2)(3)(4);
+ const MantidVec abcInnerRadii = list_of(5)(6)(7);
+ const MantidVec abcOuterRadii = list_of(8)(9)(10);
+ const SpecialCoordinateSystem frame = HKL;
+ const std::string algorithmName = "foo";
+ const int algorithmVersion = 3;
+
+ // Construct it.
+ PeakShapeEllipsoid a(directions, abcRadii, abcInnerRadii, abcOuterRadii,
+ frame, algorithmName, algorithmVersion);
+
+ PeakShapeEllipsoid b(a);
+ TS_ASSERT_EQUALS(abcRadii, b.abcRadii());
+ TS_ASSERT_EQUALS(abcInnerRadii, b.abcRadiiBackgroundInner());
+ TS_ASSERT_EQUALS(abcOuterRadii, b.abcRadiiBackgroundOuter());
+
+ TS_ASSERT_EQUALS(frame, b.frame());
+ TS_ASSERT_EQUALS(algorithmName, b.algorithmName());
+ TS_ASSERT_EQUALS(algorithmVersion, b.algorithmVersion());
+ }
+
+ void test_assignment() {
+ PeakShapeEllipsoid a(list_of(V3D(1, 0, 0))(V3D(0, 1, 0))(V3D(0, 0, 1))
+ .convert_to_container>(),
+ list_of(2)(3)(4), list_of(5)(6)(7), list_of(8)(9)(10),
+ HKL, "foo", 1);
+
+ PeakShapeEllipsoid b(list_of(V3D(0, 0, 0))(V3D(0, 1, 0))(V3D(0, 0, 1))
+ .convert_to_container>(),
+ list_of(1)(3)(4), list_of(1)(6)(7), list_of(8)(9)(10),
+ QLab, "bar", 2);
+
+ b = a;
+
+ TS_ASSERT_EQUALS(a.abcRadii(), b.abcRadii());
+ TS_ASSERT_EQUALS(a.abcRadiiBackgroundInner(), b.abcRadiiBackgroundInner());
+ TS_ASSERT_EQUALS(a.abcRadiiBackgroundOuter(), b.abcRadiiBackgroundOuter());
+
+ TS_ASSERT_EQUALS(a.frame(), b.frame());
+ TS_ASSERT_EQUALS(a.algorithmName(), b.algorithmName());
+ TS_ASSERT_EQUALS(a.algorithmVersion(), b.algorithmVersion());
+ }
+
+ void test_shape_name() {
+
+ const double radius = 1;
+ const SpecialCoordinateSystem frame = HKL;
+
+ // Construct it.
+ PeakShapeEllipsoid shape(list_of(V3D(1, 0, 0))(V3D(0, 1, 0))(V3D(0, 0, 1))
+ .convert_to_container>(),
+ list_of(2)(3)(4), list_of(5)(6)(7),
+ list_of(8)(9)(10), HKL, "foo", 1);
+
+ TS_ASSERT_EQUALS("ellipsoid", shape.shapeName());
+ }
+
+ void test_toJSON() {
+
+ auto directions = list_of(V3D(1, 0, 0))(V3D(0, 1, 0))(V3D(0, 0, 1))
+ .convert_to_container>();
+ const MantidVec abcRadii = list_of(2)(3)(4);
+ const MantidVec abcInnerRadii = list_of(5)(6)(7);
+ const MantidVec abcOuterRadii = list_of(8)(9)(10);
+ const SpecialCoordinateSystem frame = HKL;
+ const std::string algorithmName = "foo";
+ const int algorithmVersion = 3;
+
+ // Construct it.
+ PeakShapeEllipsoid shape(directions, abcRadii, abcInnerRadii, abcOuterRadii,
+ frame, algorithmName, algorithmVersion);
+
+ const std::string json = shape.toJSON();
+
+ Json::Reader reader;
+ Json::Value output;
+ TSM_ASSERT("Should parse as JSON", reader.parse(json, output));
+
+ TS_ASSERT_EQUALS(directions[0].toString(), output["direction0"].asString());
+ TS_ASSERT_EQUALS(directions[1].toString(), output["direction1"].asString());
+ TS_ASSERT_EQUALS(directions[2].toString(), output["direction2"].asString());
+ TS_ASSERT_EQUALS(algorithmName, output["algorithm_name"].asString());
+ TS_ASSERT_EQUALS(algorithmVersion, output["algorithm_version"].asInt());
+ TS_ASSERT_EQUALS(frame, output["frame"].asInt());
+ TS_ASSERT_EQUALS(abcRadii[0], output["radius0"].asDouble());
+ TS_ASSERT_EQUALS(abcRadii[1], output["radius1"].asDouble());
+ TS_ASSERT_EQUALS(abcRadii[2], output["radius2"].asDouble());
+ TS_ASSERT_EQUALS(abcOuterRadii[0], output["background_outer_radius0"].asDouble());
+ TS_ASSERT_EQUALS(abcOuterRadii[1], output["background_outer_radius1"].asDouble());
+ TS_ASSERT_EQUALS(abcOuterRadii[2], output["background_outer_radius2"].asDouble());
+
+ }
+
+
+
+};
+
+#endif /* MANTID_DATAOBJECTS_PEAKSHAPEELLIPSOIDTEST_H_ */