diff --git a/Code/Mantid/Framework/API/CMakeLists.txt b/Code/Mantid/Framework/API/CMakeLists.txt index 63b186613846..e5c265295913 100644 --- a/Code/Mantid/Framework/API/CMakeLists.txt +++ b/Code/Mantid/Framework/API/CMakeLists.txt @@ -361,6 +361,7 @@ set ( TEST_FILES SampleTest.h ScopedWorkspaceTest.h ScriptBuilderTest.h + SpecialCoordinateSystemTest.h SpectraAxisTest.h SpectrumDetectorMappingTest.h TextAxisTest.h diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/SpecialCoordinateSystem.h b/Code/Mantid/Framework/API/inc/MantidAPI/SpecialCoordinateSystem.h index 470b3f3014ee..ec7d1c9b83c6 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/SpecialCoordinateSystem.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/SpecialCoordinateSystem.h @@ -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 } } diff --git a/Code/Mantid/Framework/API/test/SpecialCoordinateSystemTest.h b/Code/Mantid/Framework/API/test/SpecialCoordinateSystemTest.h new file mode 100644 index 000000000000..d6f315645392 --- /dev/null +++ b/Code/Mantid/Framework/API/test/SpecialCoordinateSystemTest.h @@ -0,0 +1,55 @@ +#ifndef MANTID_API_SPECIALCOORDINATESYSTEMTEST +#define MANTID_API_SPECIALCOORDINATESYSTEMTEST + +#include +#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 + + diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeSpherical.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeSpherical.h index 2c488761a442..18e63d3c3ade 100644 --- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeSpherical.h +++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeSpherical.h @@ -4,6 +4,7 @@ #include "MantidKernel/System.h" #include "MantidDataObjects/PeakShapeBase.h" #include "MantidAPI/SpecialCoordinateSystem.h" +#include #include namespace Mantid { @@ -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 @@ -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 backgroundOuterRadius() const; + /// Peak inner background radius + boost::optional backgroundInnerRadius() const; private: /// Peak radius double m_radius; + /// Background outer radius + boost::optional m_backgroundOuterRadius; + /// Background inner radius; + boost::optional m_backgroundInnerRadius; }; } // namespace DataObjects diff --git a/Code/Mantid/Framework/DataObjects/src/PeakShapeSpherical.cpp b/Code/Mantid/Framework/DataObjects/src/PeakShapeSpherical.cpp index 81d1f4d07ad9..2680933a1d61 100644 --- a/Code/Mantid/Framework/DataObjects/src/PeakShapeSpherical.cpp +++ b/Code/Mantid/Framework/DataObjects/src/PeakShapeSpherical.cpp @@ -5,6 +5,13 @@ 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, @@ -12,6 +19,32 @@ PeakShapeSpherical::PeakShapeSpherical(const double &peakRadius, : 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 */ @@ -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 @@ -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; } @@ -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); @@ -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(); } /** @@ -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 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 PeakShapeSpherical::backgroundInnerRadius() const { + return m_backgroundInnerRadius; +} + } // namespace DataObjects } // namespace Mantid diff --git a/Code/Mantid/Framework/DataObjects/src/PeakShapeSphericalFactory.cpp b/Code/Mantid/Framework/DataObjects/src/PeakShapeSphericalFactory.cpp index b12a265843ad..e0c287fb7282 100644 --- a/Code/Mantid/Framework/DataObjects/src/PeakShapeSphericalFactory.cpp +++ b/Code/Mantid/Framework/DataObjects/src/PeakShapeSphericalFactory.cpp @@ -38,8 +38,21 @@ PeakShape *PeakShapeSphericalFactory::create(const std::string &source) const { static_cast(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); diff --git a/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalFactoryTest.h b/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalFactoryTest.h index ddc245f2a0e0..9b3aaf9944ce 100644 --- a/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalFactoryTest.h +++ b/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalFactoryTest.h @@ -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(productShape); + TS_ASSERT(sphericalShapeProduct); + + TS_ASSERT_EQUALS(sourceShape, *sphericalShapeProduct); + delete productShape; + } }; #endif /* MANTID_DATAOBJECTS_PEAKSHAPESPHERICALFACTORYTEST_H_ */ diff --git a/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalTest.h b/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalTest.h index 98385ae84954..cf2ea54759d6 100644 --- a/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalTest.h +++ b/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalTest.h @@ -39,16 +39,47 @@ class PeakShapeSphericalTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(frame, shape.frame()); TS_ASSERT_EQUALS(algorithmName, shape.algorithmName()); TS_ASSERT_EQUALS(algorithmVersion, shape.algorithmVersion()); + TS_ASSERT(!shape.backgroundInnerRadius().is_initialized()); + TS_ASSERT(!shape.backgroundOuterRadius().is_initialized()); + } + + void test_multiple_radii_constructor() + { + 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; + + // Construct it. + PeakShapeSpherical shape(radius, backgroundInnerRadius, backgroundOuterRadius, frame, algorithmName, + algorithmVersion); + + TS_ASSERT_EQUALS(radius, shape.radius()); + TS_ASSERT_EQUALS(frame, shape.frame()); + TS_ASSERT_EQUALS(algorithmName, shape.algorithmName()); + TS_ASSERT_EQUALS(algorithmVersion, shape.algorithmVersion()); + TS_ASSERT_EQUALS(backgroundInnerRadius, shape.backgroundInnerRadius().get()); + TS_ASSERT_EQUALS(backgroundOuterRadius, shape.backgroundOuterRadius().get()); + + PeakShapeSpherical badShape(radius, radius, radius, frame, algorithmName, + algorithmVersion); + + TSM_ASSERT("Background inner radius should be unset since is same as radius", !badShape.backgroundInnerRadius().is_initialized()); + TSM_ASSERT("Background outer radius should be unset since is same as radius", !badShape.backgroundOuterRadius().is_initialized()); } void test_copy_constructor() { 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; // Construct it. - PeakShapeSpherical a(radius, frame, algorithmName, + PeakShapeSpherical a(radius, backgroundInnerRadius, backgroundOuterRadius, frame, algorithmName, algorithmVersion); // Copy construct it PeakShapeSpherical b(a); @@ -57,16 +88,20 @@ class PeakShapeSphericalTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(frame, b.frame()); TS_ASSERT_EQUALS(algorithmName, b.algorithmName()); TS_ASSERT_EQUALS(algorithmVersion, b.algorithmVersion()); + TS_ASSERT_EQUALS(backgroundInnerRadius, b.backgroundInnerRadius().get()); + TS_ASSERT_EQUALS(backgroundOuterRadius, b.backgroundOuterRadius().get()); } void test_assignment() { 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; // Construct it. - PeakShapeSpherical a(radius, frame, algorithmName, + PeakShapeSpherical a(radius, backgroundInnerRadius, backgroundOuterRadius, frame, algorithmName, algorithmVersion); PeakShapeSpherical b(1.0, QSample, "bar", -2); @@ -78,16 +113,20 @@ class PeakShapeSphericalTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(a.frame(), b.frame()); TS_ASSERT_EQUALS(a.algorithmName(), b.algorithmName()); TS_ASSERT_EQUALS(a.algorithmVersion(), b.algorithmVersion()); + TS_ASSERT_EQUALS(a.backgroundInnerRadius(), b.backgroundInnerRadius().get()); + TS_ASSERT_EQUALS(a.backgroundOuterRadius(), b.backgroundOuterRadius().get()); } void test_clone() { 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; // Construct it. - PeakShapeSpherical a(radius, frame, algorithmName, + PeakShapeSpherical a(radius, backgroundInnerRadius, backgroundOuterRadius, frame, algorithmName, algorithmVersion); PeakShapeSpherical *clone = a.clone(); @@ -95,6 +134,8 @@ class PeakShapeSphericalTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(a.frame(), clone->frame()); TS_ASSERT_EQUALS(a.algorithmName(), clone->algorithmName()); TS_ASSERT_EQUALS(a.algorithmVersion(), clone->algorithmVersion()); + TS_ASSERT_EQUALS(a.backgroundInnerRadius(), clone->backgroundInnerRadius().get()); + TS_ASSERT_EQUALS(a.backgroundOuterRadius(), clone->backgroundOuterRadius().get()); TS_ASSERT_DIFFERS(clone, &a); } @@ -113,17 +154,45 @@ class PeakShapeSphericalTest : public CxxTest::TestSuite { Json::Value output; TSM_ASSERT("Should parse as JSON", reader.parse(json, output)); - 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(radius, output["radius"].asDouble()); } + void test_toJSON_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; + + // Construct it. + PeakShapeSpherical shape(radius, backgroundInnerRadius, backgroundOuterRadius, 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(algorithmName, output["algorithm_name"].asString()); + TS_ASSERT_EQUALS(algorithmVersion, output["algorithm_version"].asInt()); + TS_ASSERT_EQUALS(frame, output["frame"].asInt()); + TS_ASSERT_EQUALS(radius, output["radius"].asDouble()); + TS_ASSERT_EQUALS(backgroundInnerRadius, output["background_inner_radius"].asDouble()); + TS_ASSERT_EQUALS(backgroundOuterRadius, output["background_outer_radius"].asDouble()); + } + void test_equals() { TS_ASSERT_EQUALS(PeakShapeSpherical(1.0, QSample), PeakShapeSpherical(1.0, QSample)); + TS_ASSERT_EQUALS(PeakShapeSpherical(1.0,2.0,3.0, QSample), + PeakShapeSpherical(1.0,2.0,3.0, QSample)); + TSM_ASSERT_DIFFERS("Different radius", PeakShapeSpherical(1.0, QSample), PeakShapeSpherical(2.0, QSample)); @@ -131,6 +200,14 @@ class PeakShapeSphericalTest : public CxxTest::TestSuite { TSM_ASSERT_DIFFERS("Different frame", PeakShapeSpherical(1.0, QSample), PeakShapeSpherical(1.0, QLab)); + + TSM_ASSERT_DIFFERS("Different background inner", + PeakShapeSpherical(1.0, 1.0, 3.0, QSample), + PeakShapeSpherical(1.0, 2.0, 3.0, QSample)); + + TSM_ASSERT_DIFFERS("Different background outer", + PeakShapeSpherical(1.0, 2.0, 2.0, QSample), + PeakShapeSpherical(1.0, 2.0, 3.0, QSample)); } void test_shape_name() { diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h index 104fc7d70a3a..1bd10f52c63d 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h @@ -56,7 +56,7 @@ class DLLExport IntegratePeaksMD2 : public API::Algorithm { /// Check if peaks overlap void checkOverlap(int i, Mantid::DataObjects::PeaksWorkspace_sptr peakWS, - int CoordinatesToUse, double radius); + Mantid::API::SpecialCoordinateSystem CoordinatesToUse, double radius); }; } // namespace Mantid diff --git a/Code/Mantid/Framework/MDAlgorithms/src/IntegratePeaksMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/IntegratePeaksMD.cpp index 30bbc961e5fa..be6af459f453 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/IntegratePeaksMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/IntegratePeaksMD.cpp @@ -1,6 +1,7 @@ #include "MantidAPI/IMDEventWorkspace.h" #include "MantidMDAlgorithms/GSLFunctions.h" #include "MantidDataObjects/PeaksWorkspace.h" +#include "MantidDataObjects/PeakShapeSpherical.h" #include "MantidKernel/System.h" #include "MantidMDEvents/MDEventFactory.h" #include "MantidMDAlgorithms/IntegratePeaksMD.h" @@ -167,17 +168,17 @@ void IntegratePeaksMD::integrate(typename MDEventWorkspace::sptr ws) { /// Value of the CoordinatesToUse property. std::string CoordinatesToUseStr = getPropertyValue("CoordinatesToUse"); - int CoordinatesToUse = ws->getSpecialCoordinateSystem(); + API::SpecialCoordinateSystem CoordinatesToUse = ws->getSpecialCoordinateSystem(); g_log.warning() << " Warning" << CoordinatesToUse << std::endl; - if (CoordinatesToUse == 1 && CoordinatesToUseStr != "Q (lab frame)") + if (CoordinatesToUse == API::QLab && CoordinatesToUseStr != "Q (lab frame)") g_log.warning() << "Warning: used Q (lab frame) coordinates for MD " "workspace, not CoordinatesToUse from input " << std::endl; - else if (CoordinatesToUse == 2 && CoordinatesToUseStr != "Q (sample frame)") + else if (CoordinatesToUse == API::QSample && CoordinatesToUseStr != "Q (sample frame)") g_log.warning() << "Warning: used Q (sample frame) coordinates for MD " "workspace, not CoordinatesToUse from input " << std::endl; - else if (CoordinatesToUse == 3 && CoordinatesToUseStr != "HKL") + else if (CoordinatesToUse == API::HKL && CoordinatesToUseStr != "HKL") g_log.warning() << "Warning: used HKL coordinates for MD workspace, not " "CoordinatesToUse from input " << std::endl; @@ -276,11 +277,11 @@ void IntegratePeaksMD::integrate(typename MDEventWorkspace::sptr ws) { // Get the peak center as a position in the dimensions of the workspace V3D pos; - if (CoordinatesToUse == 1) //"Q (lab frame)" + if (CoordinatesToUse == API::QLab) //"Q (lab frame)" pos = p.getQLabFrame(); - else if (CoordinatesToUse == 2) //"Q (sample frame)" + else if (CoordinatesToUse == API::QSample) //"Q (sample frame)" pos = p.getQSampleFrame(); - else if (CoordinatesToUse == 3) //"HKL" + else if (CoordinatesToUse == API::HKL) //"HKL" pos = p.getHKL(); // Get the instrument and its detectors @@ -329,6 +330,13 @@ void IntegratePeaksMD::integrate(typename MDEventWorkspace::sptr ws) { BackgroundOuterRadiusVector[i] = lenQpeak * BackgroundOuterRadius; CoordTransformDistance sphere(nd, center, dimensionsUsed); + if(Peak* shapeablePeak = dynamic_cast(&p)){ + + PeakShape* sphere = new PeakShapeSpherical(PeakRadiusVector[i], BackgroundInnerRadiusVector[i], + BackgroundOuterRadiusVector[i], CoordinatesToUse, this->name(), this->version()); + shapeablePeak->setPeakShape(sphere); + } + // Perform the integration into whatever box is contained within. ws->getBox()->integrateSphere( sphere, diff --git a/Code/Mantid/Framework/MDAlgorithms/src/IntegratePeaksMD2.cpp b/Code/Mantid/Framework/MDAlgorithms/src/IntegratePeaksMD2.cpp index 7fa493bc29c0..dd963ded0e7c 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/IntegratePeaksMD2.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/IntegratePeaksMD2.cpp @@ -1,6 +1,8 @@ #include "MantidAPI/IMDEventWorkspace.h" #include "MantidMDAlgorithms/GSLFunctions.h" #include "MantidDataObjects/PeaksWorkspace.h" +#include "MantidDataObjects/Peak.h" +#include "MantidDataObjects/PeakShapeSpherical.h" #include "MantidKernel/System.h" #include "MantidMDEvents/MDEventFactory.h" #include "MantidMDAlgorithms/IntegratePeaksMD2.h" @@ -172,7 +174,7 @@ void IntegratePeaksMD2::integrate(typename MDEventWorkspace::sptr ws) { // Get the instrument and its detectors inst = peakWS->getInstrument(); - int CoordinatesToUse = ws->getSpecialCoordinateSystem(); + Mantid::API::SpecialCoordinateSystem CoordinatesToUse = ws->getSpecialCoordinateSystem(); /// Radius to use around peaks double PeakRadius = getProperty("PeakRadius"); @@ -269,11 +271,11 @@ void IntegratePeaksMD2::integrate(typename MDEventWorkspace::sptr ws) { // Get the peak center as a position in the dimensions of the workspace V3D pos; - if (CoordinatesToUse == 1) //"Q (lab frame)" + if (CoordinatesToUse == Mantid::API::QLab) //"Q (lab frame)" pos = p.getQLabFrame(); - else if (CoordinatesToUse == 2) //"Q (sample frame)" + else if (CoordinatesToUse == Mantid::API::QSample) //"Q (sample frame)" pos = p.getQSampleFrame(); - else if (CoordinatesToUse == 3) //"HKL" + else if (CoordinatesToUse == Mantid::API::HKL) //"HKL" pos = p.getHKL(); // Do not integrate if sphere is off edge of detector @@ -313,11 +315,19 @@ void IntegratePeaksMD2::integrate(typename MDEventWorkspace::sptr ws) { } lenQpeak = std::sqrt(lenQpeak); } + PeakRadiusVector[i] = lenQpeak * PeakRadius; BackgroundInnerRadiusVector[i] = lenQpeak * BackgroundInnerRadius; BackgroundOuterRadiusVector[i] = lenQpeak * BackgroundOuterRadius; CoordTransformDistance sphere(nd, center, dimensionsUsed); + if(Peak* shapeablePeak = dynamic_cast(&p)){ + + PeakShape* sphere = new PeakShapeSpherical(PeakRadiusVector[i], BackgroundInnerRadiusVector[i], + BackgroundOuterRadiusVector[i], CoordinatesToUse, this->name(), this->version()); + shapeablePeak->setPeakShape(sphere); + } + // Perform the integration into whatever box is contained within. ws->getBox()->integrateSphere( sphere, @@ -676,25 +686,25 @@ void IntegratePeaksMD2::runMaskDetectors( void IntegratePeaksMD2::checkOverlap(int i, Mantid::DataObjects::PeaksWorkspace_sptr peakWS, - int CoordinatesToUse, double radius) { + Mantid::API::SpecialCoordinateSystem CoordinatesToUse, double radius) { // Get a direct ref to that peak. IPeak &p1 = peakWS->getPeak(i); V3D pos1; - if (CoordinatesToUse == 1) //"Q (lab frame)" + if (CoordinatesToUse == API::QLab) //"Q (lab frame)" pos1 = p1.getQLabFrame(); - else if (CoordinatesToUse == 2) //"Q (sample frame)" + else if (CoordinatesToUse == API::QSample) //"Q (sample frame)" pos1 = p1.getQSampleFrame(); - else if (CoordinatesToUse == 3) //"HKL" + else if (CoordinatesToUse == API::HKL) //"HKL" pos1 = p1.getHKL(); for (int j = i + 1; j < peakWS->getNumberPeaks(); ++j) { // Get a direct ref to rest of peaks peak. IPeak &p2 = peakWS->getPeak(j); V3D pos2; - if (CoordinatesToUse == 1) //"Q (lab frame)" + if (CoordinatesToUse == API::QLab) //"Q (lab frame)" pos2 = p2.getQLabFrame(); - else if (CoordinatesToUse == 2) //"Q (sample frame)" + else if (CoordinatesToUse == API::QSample) //"Q (sample frame)" pos2 = p2.getQSampleFrame(); - else if (CoordinatesToUse == 3) //"HKL" + else if (CoordinatesToUse == API::HKL) //"HKL" pos2 = p2.getHKL(); if (pos1.distance(pos2) < radius) { g_log.warning() << " Warning: Peak integration spheres for peaks " << i diff --git a/Code/Mantid/Framework/MDAlgorithms/test/IntegratePeaksMD2Test.h b/Code/Mantid/Framework/MDAlgorithms/test/IntegratePeaksMD2Test.h index 1dad0714373f..5f4dd4555d5a 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/IntegratePeaksMD2Test.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/IntegratePeaksMD2Test.h @@ -5,6 +5,7 @@ #include "MantidAPI/IMDEventWorkspace.h" #include "MantidAPI/FrameworkManager.h" #include "MantidDataObjects/PeaksWorkspace.h" +#include "MantidDataObjects/PeakShapeSpherical.h" #include "MantidGeometry/MDGeometry/MDHistoDimension.h" #include "MantidKernel/System.h" #include "MantidKernel/Timer.h" @@ -26,6 +27,7 @@ #include #include + using Mantid::API::AnalysisDataService; using Mantid::Geometry::MDHistoDimension; using namespace Mantid::API; @@ -339,10 +341,10 @@ class IntegratePeaksMD2Test : public CxxTest::TestSuite { createMDEW(); const double peakRadius = 2; - const double backgroundOutterRadius = 3; + const double backgroundOuterRadius = 3; const double backgroundInnerRadius = 2.5; - doRun(peakRadius, backgroundOutterRadius, "OutWS", backgroundInnerRadius); + doRun(peakRadius, backgroundOuterRadius, "OutWS", backgroundInnerRadius); auto outWS = AnalysisDataService::Instance().retrieveWS("OutWS"); @@ -351,9 +353,46 @@ class IntegratePeaksMD2Test : public CxxTest::TestSuite double actualBackgroundInnerRadius = atof(outWS->mutableRun().getProperty("BackgroundInnerRadius")->value().c_str()); TS_ASSERT_EQUALS(peakRadius, actualPeakRadius); - TS_ASSERT_EQUALS(backgroundOutterRadius, actualBackgroundOutterRadius); + TS_ASSERT_EQUALS(backgroundOuterRadius, actualBackgroundOutterRadius); TS_ASSERT_EQUALS(backgroundInnerRadius, actualBackgroundInnerRadius); TS_ASSERT(outWS->hasIntegratedPeaks()); + + // TODO. the methods above will be obsolete soon. + IPeak& iPeak = outWS->getPeak(0); + Peak * const peak = dynamic_cast(&iPeak); + TS_ASSERT(peak); + const PeakShape& shape = peak->getPeakShape(); + PeakShapeSpherical const * const sphericalShape = dynamic_cast(const_cast(&shape)); + TS_ASSERT(sphericalShape); + TS_ASSERT_EQUALS(peakRadius, sphericalShape->radius()); + TS_ASSERT_EQUALS(backgroundOuterRadius, sphericalShape->backgroundOuterRadius().get()); + TS_ASSERT_EQUALS(backgroundInnerRadius, sphericalShape->backgroundInnerRadius().get()); + } + + void test_writes_out_peak_shape() + { + createMDEW(); + const double peakRadius = 2; + const double backgroundOuterRadius = 3; + const double backgroundInnerRadius = 2.5; + + doRun(peakRadius, backgroundOuterRadius, "OutWS", backgroundInnerRadius); + + PeaksWorkspace_sptr outWS = AnalysisDataService::Instance().retrieveWS("OutWS"); + + // Get a peak. + IPeak& iPeak = outWS->getPeak(0); + Peak * const peak = dynamic_cast(&iPeak); + TS_ASSERT(peak); + // Get the peak's shape + const PeakShape& shape = peak->getPeakShape(); + PeakShapeSpherical const * const sphericalShape = dynamic_cast(const_cast(&shape)); + TSM_ASSERT("Wrong sort of peak", sphericalShape); + + // Check the shape is what we expect + TS_ASSERT_EQUALS(peakRadius, sphericalShape->radius()); + TS_ASSERT_EQUALS(backgroundOuterRadius, sphericalShape->backgroundOuterRadius().get()); + TS_ASSERT_EQUALS(backgroundInnerRadius, sphericalShape->backgroundInnerRadius().get()); } }; diff --git a/Code/Mantid/Framework/MDAlgorithms/test/IntegratePeaksMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/IntegratePeaksMDTest.h index 0881d7800c7f..ff7c903353fc 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/IntegratePeaksMDTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/IntegratePeaksMDTest.h @@ -5,6 +5,7 @@ #include "MantidAPI/IMDEventWorkspace.h" #include "MantidAPI/FrameworkManager.h" #include "MantidDataObjects/PeaksWorkspace.h" +#include "MantidDataObjects/PeakShapeSpherical.h" #include "MantidGeometry/MDGeometry/MDHistoDimension.h" #include "MantidKernel/System.h" #include "MantidKernel/Timer.h" @@ -356,6 +357,32 @@ class IntegratePeaksMDTest : public CxxTest::TestSuite TS_ASSERT(outWS->hasIntegratedPeaks()); } + void test_writes_out_peak_shape() + { + createMDEW(); + const double peakRadius = 2; + const double backgroundOuterRadius = 3; + const double backgroundInnerRadius = 2.5; + + doRun(peakRadius, backgroundOuterRadius, "OutWS", backgroundInnerRadius); + + PeaksWorkspace_sptr outWS = AnalysisDataService::Instance().retrieveWS("OutWS"); + + // Get a peak. + IPeak& iPeak = outWS->getPeak(0); + Peak * const peak = dynamic_cast(&iPeak); + TS_ASSERT(peak); + // Get the peak's shape + const PeakShape& shape = peak->getPeakShape(); + PeakShapeSpherical const * const sphericalShape = dynamic_cast(const_cast(&shape)); + TSM_ASSERT("Wrong sort of peak", sphericalShape); + + // Check the shape is what we expect + TS_ASSERT_EQUALS(peakRadius, sphericalShape->radius()); + TS_ASSERT_EQUALS(backgroundOuterRadius, sphericalShape->backgroundOuterRadius().get()); + TS_ASSERT_EQUALS(backgroundInnerRadius, sphericalShape->backgroundInnerRadius().get()); + } + };