diff --git a/Framework/API/inc/MantidAPI/Sample.h b/Framework/API/inc/MantidAPI/Sample.h index a64532cd7e97dbef4e04d3d4ff2e5a2d5d5250fc..c921348c9fb3b773881edbc6024074a1d8f55d66 100644 --- a/Framework/API/inc/MantidAPI/Sample.h +++ b/Framework/API/inc/MantidAPI/Sample.h @@ -15,6 +15,7 @@ namespace Mantid { //------------------------------------------------------------------------------ namespace Geometry { class OrientedLattice; +class CrystalStructure; } namespace API { @@ -103,6 +104,14 @@ public: bool hasOrientedLattice() const; //@} + /** @name Access the sample's crystal structure */ + //@{ + const Geometry::CrystalStructure &getCrystalStructure() const; + void setCrystalStructure(const Geometry::CrystalStructure &newCrystalStructure); + bool hasCrystalStructure() const; + void clearCrystalStructure(); + //@} + // Required for SANS work until we define a proper // sample object from the raw file information /**@name Legacy functions */ @@ -137,6 +146,9 @@ private: /// Pointer to the OrientedLattice of the sample, NULL if not set. Geometry::OrientedLattice *m_lattice; + /// CrystalStructure of the sample + std::unique_ptr<Geometry::CrystalStructure> m_crystalStructure; + /// Vector of child samples std::vector<boost::shared_ptr<Sample>> m_samples; diff --git a/Framework/API/src/Sample.cpp b/Framework/API/src/Sample.cpp index b472d32a98ffbdc69f43152c13b2c43a5c8e5342..dc6137e704235f5f6e5580b7e400310e068c97c7 100644 --- a/Framework/API/src/Sample.cpp +++ b/Framework/API/src/Sample.cpp @@ -4,6 +4,7 @@ #include "MantidAPI/Sample.h" #include "MantidAPI/SampleEnvironment.h" #include "MantidGeometry/IComponent.h" +#include "MantidGeometry/Crystal/CrystalStructure.h" #include "MantidGeometry/Crystal/OrientedLattice.h" #include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidKernel/Strings.h" @@ -22,8 +23,9 @@ using Geometry::ShapeFactory; * Default constructor. Required for cow_ptr. */ Sample::Sample() - : m_name(), m_shape(), m_environment(), m_lattice(NULL), m_samples(), - m_geom_id(0), m_thick(0.0), m_height(0.0), m_width(0.0) {} + : m_name(), m_shape(), m_environment(), m_lattice(NULL), + m_crystalStructure(), m_samples(), m_geom_id(0), m_thick(0.0), + m_height(0.0), m_width(0.0) {} /** * Copy constructor @@ -31,11 +33,16 @@ Sample::Sample() */ Sample::Sample(const Sample ©) : m_name(copy.m_name), m_shape(copy.m_shape), - m_environment(copy.m_environment), m_lattice(NULL), + m_environment(copy.m_environment), m_lattice(NULL), m_crystalStructure(), m_samples(copy.m_samples), m_geom_id(copy.m_geom_id), m_thick(copy.m_thick), m_height(copy.m_height), m_width(copy.m_width) { if (copy.m_lattice) m_lattice = new OrientedLattice(copy.getOrientedLattice()); + + if (copy.hasCrystalStructure()) { + m_crystalStructure.reset( + new Geometry::CrystalStructure(copy.getCrystalStructure())); + } } /// Destructor @@ -64,6 +71,12 @@ Sample &Sample::operator=(const Sample &rhs) { else m_lattice = NULL; + m_crystalStructure.reset(); + if (rhs.hasCrystalStructure()) { + m_crystalStructure.reset( + new Geometry::CrystalStructure(rhs.getCrystalStructure())); + } + return *this; } @@ -161,6 +174,29 @@ void Sample::setOrientedLattice(OrientedLattice *latt) { /** @return true if the sample has an OrientedLattice */ bool Sample::hasOrientedLattice() const { return (m_lattice != NULL); } +const Geometry::CrystalStructure &Sample::getCrystalStructure() const { + if (!hasCrystalStructure()) { + throw std::runtime_error( + "Sample::getCrystalStructure - No CrystalStructure has been defined."); + } + + return *m_crystalStructure; +} + +/// Resets the internal pointer to the new CrystalStructure (it's copied). +void Sample::setCrystalStructure( + const Geometry::CrystalStructure &newCrystalStructure) { + m_crystalStructure.reset(new Geometry::CrystalStructure(newCrystalStructure)); +} + +/// Returns true if the sample actually holds a CrystalStructure. +bool Sample::hasCrystalStructure() const { + return m_crystalStructure.operator bool(); +} + +/// Destroys the internally stored CrystalStructure-object. +void Sample::clearCrystalStructure() { m_crystalStructure.reset(); } + /** * Set the geometry flag that is specfied in the raw file within the SPB_STRUCT * 1 = cylinder, 2 = flat plate, 3 = disc, 4 = single crystal diff --git a/Framework/API/test/SampleTest.h b/Framework/API/test/SampleTest.h index ba20d5cf7b0e0db6ce23d31c7b4d9e06c046c47d..6e90959ee3d8faa92803c1062adedc31a5643535 100644 --- a/Framework/API/test/SampleTest.h +++ b/Framework/API/test/SampleTest.h @@ -3,6 +3,7 @@ #include "MantidAPI/Sample.h" #include "MantidAPI/SampleEnvironment.h" +#include "MantidGeometry/Crystal/CrystalStructure.h" #include "MantidGeometry/Crystal/OrientedLattice.h" #include "MantidKernel/Exception.h" #include "MantidTestHelpers/ComponentCreationHelper.h" @@ -199,6 +200,57 @@ public: delete latticeA; } + void test_setCrystalStructure() { + Sample sample; + TS_ASSERT(!sample.hasCrystalStructure()); + TS_ASSERT_THROWS(sample.getCrystalStructure(), std::runtime_error); + + CrystalStructure structure("3 4 5 90 90 90", "C m m m", + "Fe 0.12 0.23 0.121"); + + TS_ASSERT_THROWS_NOTHING(sample.setCrystalStructure(structure)); + TS_ASSERT(sample.hasCrystalStructure()); + CrystalStructure fromSample = sample.getCrystalStructure(); + + TS_ASSERT(fromSample.spaceGroup()); + TS_ASSERT_EQUALS(fromSample.spaceGroup()->hmSymbol(), "C m m m"); + } + + void test_clearCrystalStructure() { + Sample sample; + TS_ASSERT(!sample.hasCrystalStructure()); + TS_ASSERT_THROWS(sample.getCrystalStructure(), std::runtime_error); + + CrystalStructure structure("3 4 5 90 90 90", "C m m m", + "Fe 0.12 0.23 0.121"); + sample.setCrystalStructure(structure); + TS_ASSERT(sample.hasCrystalStructure()); + + TS_ASSERT_THROWS_NOTHING(sample.clearCrystalStructure()); + TS_ASSERT(!sample.hasCrystalStructure()); + } + + void test_crystalStructureCopyConstructorAndAssignment() { + Sample sampleA; + + CrystalStructure structure("3 4 5 90 90 90", "C m m m", + "Fe 0.12 0.23 0.121"); + sampleA.setCrystalStructure(structure); + TS_ASSERT(sampleA.hasCrystalStructure()); + + Sample sampleB = sampleA; + TS_ASSERT(sampleB.hasCrystalStructure()); + + CrystalStructure fromA = sampleA.getCrystalStructure(); + CrystalStructure fromB = sampleB.getCrystalStructure(); + TS_ASSERT_EQUALS(fromA.spaceGroup()->hmSymbol(), fromB.spaceGroup()->hmSymbol()); + + Sample sampleC(sampleA); + + CrystalStructure fromC = sampleC.getCrystalStructure(); + TS_ASSERT_EQUALS(fromA.spaceGroup()->hmSymbol(), fromC.spaceGroup()->hmSymbol()); + } + void test_Material_Returns_The_Correct_Value() { Material vanBlock("vanBlock", Mantid::PhysicalConstants::getNeutronAtom(23, 0), 0.072);