Mantid
Loading...
Searching...
No Matches
Sample.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7#include "MantidAPI/Sample.h"
16#include <utility>
17
18namespace Mantid::API {
19using namespace Mantid::Kernel;
25
30 : m_name(), m_shape(ShapeFactory().createShape("")), m_environment(), m_lattice(nullptr), m_crystalStructure(),
31 m_samples(), m_geom_id(0), m_thick(0.0), m_height(0.0), m_width(0.0) {}
32
38 : m_name(copy.m_name), m_shape(copy.m_shape), m_environment(copy.m_environment), m_lattice(nullptr),
39 m_crystalStructure(), m_samples(copy.m_samples), m_geom_id(copy.m_geom_id), m_thick(copy.m_thick),
40 m_height(copy.m_height), m_width(copy.m_width) {
41 if (copy.m_lattice)
42 m_lattice = std::make_unique<OrientedLattice>(copy.getOrientedLattice());
43
44 if (copy.hasCrystalStructure()) {
45 m_crystalStructure = std::make_unique<Geometry::CrystalStructure>(copy.getCrystalStructure());
46 }
47}
48
50Sample::~Sample() = default;
51
58 if (this == &rhs)
59 return *this;
61 m_shape = rhs.m_shape;
62 m_environment = rhs.m_environment;
63 m_geom_id = rhs.m_geom_id;
64 m_samples = std::vector<std::shared_ptr<Sample>>(rhs.m_samples);
65 m_thick = rhs.m_thick;
66 m_height = rhs.m_height;
67 m_width = rhs.m_width;
68 if (rhs.m_lattice)
69 m_lattice = std::make_unique<OrientedLattice>(rhs.getOrientedLattice());
70 else
71 m_lattice.reset(nullptr);
72
73 m_crystalStructure.reset();
74 if (rhs.hasCrystalStructure()) {
75 m_crystalStructure.reset(new Geometry::CrystalStructure(rhs.getCrystalStructure()));
76 }
77
78 return *this;
79}
80
85const std::string &Sample::getName() const { return m_name; }
86
91void Sample::setName(const std::string &name) { m_name = name; }
92
93bool Sample::hasShape() const { return (m_shape != nullptr); }
94
101const IObject &Sample::getShape() const { return *m_shape; }
102
109const IObject_sptr Sample::getShapePtr() const { return m_shape; }
110
115void Sample::setShape(const IObject_sptr &shape) {
116 if (!shape) {
118 } else if (shape != m_shape) {
119 m_shape = shape; // share ownership safely
120 }
121}
122
126const Material &Sample::getMaterial() const { return m_shape->material(); }
127
128bool Sample::hasEnvironment() const { return (m_environment != nullptr); }
129
136 if (!m_environment) {
137 throw std::runtime_error("Sample::getEnvironment - No sample enviroment has been defined.");
138 }
139 return *m_environment;
140}
141
147void Sample::setEnvironment(std::shared_ptr<SampleEnvironment> env) { m_environment = std::move(env); }
148
154 if (!m_lattice) {
155 throw std::runtime_error("Sample::getOrientedLattice - No OrientedLattice has been defined.");
156 }
157 return *m_lattice;
158}
159
165 if (!m_lattice) {
166 throw std::runtime_error("Sample::getOrientedLattice - No OrientedLattice has been defined.");
167 }
168 return *m_lattice;
169}
170
175void Sample::setOrientedLattice(std::unique_ptr<Geometry::OrientedLattice> lattice) { m_lattice = std::move(lattice); }
176
178bool Sample::hasOrientedLattice() const { return (m_lattice != nullptr); }
179
181 if (!hasCrystalStructure()) {
182 throw std::runtime_error("Sample::getCrystalStructure - No CrystalStructure has been defined.");
183 }
184
185 return *m_crystalStructure;
186}
187
190 m_crystalStructure.reset(new Geometry::CrystalStructure(newCrystalStructure));
191}
192
195 // Conversion to bool seems to be a problem in VS2012, so this is a bit more
196 // verbose than it should be.
197 return static_cast<bool>(m_crystalStructure);
198}
199
202
208void Sample::setGeometryFlag(int geom_id) { m_geom_id = geom_id; }
209
215int Sample::getGeometryFlag() const { return m_geom_id; }
216
221void Sample::setThickness(double thick) { m_thick = thick; }
222
227double Sample::getThickness() const { return m_thick; }
228
234
239double Sample::getHeight() const { return m_height; }
240
245void Sample::setWidth(double width) { m_width = width; }
246
251double Sample::getWidth() const { return m_width; }
252
259 if (index == 0) {
260 return *this;
261 } else if ((static_cast<std::size_t>(index) > m_samples.size()) || (index < 0)) {
262 throw std::out_of_range("The index value provided was out of range");
263 } else {
264 return *m_samples[index - 1];
265 }
266}
267
272std::size_t Sample::size() const { return m_samples.size() + 1; }
273
278void Sample::addSample(const std::shared_ptr<Sample> &childSample) { m_samples.emplace_back(childSample); }
279
280//--------------------------------------------------------------------------------------------
285void Sample::saveNexus(Nexus::File *file, const std::string &group) const {
286 file->makeGroup(group, "NXsample", true);
287 file->putAttr("name", m_name);
288 if (m_name.empty()) {
289 file->putAttr("name_empty", 1);
290 }
291 file->putAttr("version", 1);
292 std::string shapeXML("");
293 if (auto csgObject = std::dynamic_pointer_cast<Mantid::Geometry::CSGObject>(m_shape)) {
294 shapeXML = csgObject->getShapeXML();
295 }
296 file->putAttr("shape_xml", shapeXML);
297
298 m_shape->material().saveNexus(file, "material");
299 // Write out the other (indexes 1+) samples
300 file->writeData("num_other_samples", int(m_samples.size()));
301 for (size_t i = 0; i < m_samples.size(); i++)
302 m_samples[i]->saveNexus(file, "sample" + Strings::toString(i + 1));
303 // TODO: SampleEnvironment
304 // OrientedLattice
305 if (hasOrientedLattice()) {
306 file->writeData("num_oriented_lattice", 1);
307 m_lattice->saveNexus(file, "oriented_lattice");
308 } else
309 file->writeData("num_oriented_lattice", 0);
310
311 // Legacy info from RAW file (I think)
312 file->writeData("geom_id", m_geom_id);
313 file->writeData("geom_thickness", m_thick);
314 file->writeData("geom_height", m_height);
315 file->writeData("geom_width", m_width);
316
317 file->closeGroup();
318}
319
320//--------------------------------------------------------------------------------------------
326int Sample::loadNexus(Nexus::File *file, const std::string &group) {
327 file->openGroup(group, "NXsample");
328
329 // Version 0 = saveNexusProcessed before Sep 8, 2011
330 int version = 0;
331 if (file->hasAttr("version")) {
332 file->getAttr("version", version);
333 } else {
334 version = 0;
335 }
336
337 if (version == 0) {
338 // Sample NAME field may/may not be present
339 if (file->hasData("name")) {
340 file->readData("name", m_name);
341 } else {
342 m_name = "";
343 }
344 }
345
346 if (version > 0) {
347 // Name is an attribute
348 file->getAttr("name", m_name);
349 if (file->hasAttr("name_empty")) {
350 int isEmpty;
351 file->getAttr("name_empty", isEmpty);
352 if (isEmpty) {
353 m_name.clear();
354 }
355 }
356
357 // Shape (from XML)
358 std::string shape_xml;
359 file->getAttr("shape_xml", shape_xml);
360 shape_xml = Strings::strip(shape_xml);
361 if (!shape_xml.empty()) {
362 ShapeFactory shapeMaker;
363 m_shape = shapeMaker.createShape(std::move(shape_xml), false /*Don't wrap with <type> tag*/);
364 }
365 Kernel::Material material;
366 material.loadNexus(file, "material");
367 // CSGObject expected, if so, set its material
368 if (auto csgObj = std::dynamic_pointer_cast<Geometry::CSGObject>(m_shape)) {
369 csgObj->setMaterial(material);
370 }
371
372 // Load other samples
373 int num_other_samples;
374 file->readData("num_other_samples", num_other_samples);
375 for (int i = 0; i < num_other_samples; i++) {
376 auto extra = std::make_shared<Sample>();
377 extra->loadNexus(file, "sample" + Strings::toString(i + 1));
378 this->addSample(extra);
379 }
380
381 // OrientedLattice
382 int num_oriented_lattice;
383 file->readData("num_oriented_lattice", num_oriented_lattice);
384 if (num_oriented_lattice > 0) {
385 m_lattice = std::make_unique<OrientedLattice>();
386 m_lattice->loadNexus(file, "oriented_lattice");
387 }
388 }
389
390 try {
391 // Legacy info from RAW file (I think)
392 file->readData("geom_id", m_geom_id);
393 file->readData("geom_thickness", m_thick);
394 file->readData("geom_height", m_height);
395 file->readData("geom_width", m_width);
396 } catch (...) { /* Very old files don't have them. Ignore. */
397 }
398
399 file->closeGroup();
400
401 return version;
402}
403
408 if (m_lattice) {
409 m_lattice.reset(nullptr);
410 }
411}
412
413bool Sample::operator==(const Sample &other) const {
414 if (m_samples.size() != other.m_samples.size())
415 return false;
416 for (size_t i = 0; i < m_samples.size(); ++i) {
417 if (*m_samples[i] != *other.m_samples[i])
418 return false;
419 }
420 auto compare = [](const auto &a, const auto &b, auto call_on) {
421 // both null or both not null
422 if (bool(a) ^ bool(b))
423 return false;
424 if (a)
425 return call_on(a) == call_on(b);
426 else
427 return true;
428 };
429 return *m_lattice == *other.m_lattice && this->m_name == other.m_name && this->m_height == other.m_height &&
430 this->m_width == other.m_width && this->m_thick == other.m_thick && m_geom_id == other.m_geom_id &&
431 compare(m_environment, other.m_environment, [](const auto &x) { return x->name(); }) &&
432 compare(m_shape, other.m_shape, [](const auto &x) { return x->shape(); }) &&
433 compare(m_crystalStructure, other.m_crystalStructure, [](const auto &x) { return *(x->spaceGroup()); });
434}
435
436bool Sample::operator!=(const Sample &other) const { return !this->operator==(other); }
437} // namespace Mantid::API
std::string name
Definition Run.cpp:60
const std::vector< double > & rhs
double height
Definition GetAllEi.cpp:155
std::map< DeltaEMode::Type, std::string > index
This class stores information about the sample used in particular run.
Definition Sample.h:33
void setShape(const Geometry::IObject_sptr &shape)
Update the shape of the object.
Definition Sample.cpp:115
double m_width
The sample width from the SPB_STRUCT in the raw file.
Definition Sample.h:148
double m_thick
The sample thickness from the SPB_STRUCT in the raw file.
Definition Sample.h:144
void clearOrientedLattice()
Delete the oriented lattice.
Definition Sample.cpp:407
const Kernel::Material & getMaterial() const
Return the material (convenience method)
Definition Sample.cpp:126
std::string m_name
The sample name.
Definition Sample.h:127
bool hasEnvironment() const
Definition Sample.cpp:128
int loadNexus(Nexus::File *file, const std::string &group)
Load the object from an open NeXus file.
Definition Sample.cpp:326
void saveNexus(Nexus::File *file, const std::string &group) const
Save the object to an open NeXus file.
Definition Sample.cpp:285
const std::string & getName() const
Returns the name of the sample.
Definition Sample.cpp:85
const Geometry::IObject & getShape() const
Return the sample shape.
Definition Sample.cpp:101
bool operator!=(const Sample &other) const
Definition Sample.cpp:436
void setEnvironment(std::shared_ptr< Geometry::SampleEnvironment > env)
Set the environment used to contain the sample.
Definition Sample.cpp:147
int getGeometryFlag() const
Returns the geometry flag.
Definition Sample.cpp:215
void setOrientedLattice(std::unique_ptr< Geometry::OrientedLattice > lattice)
Set the pointer to OrientedLattice defining the sample's lattice and orientation.
Definition Sample.cpp:175
Sample & operator[](const int index)
index operator for accessing multiple samples
Definition Sample.cpp:258
std::unique_ptr< Geometry::OrientedLattice > m_lattice
Pointer to the OrientedLattice of the sample, NULL if not set.
Definition Sample.h:133
const Geometry::OrientedLattice & getOrientedLattice() const
Get a reference to the sample's OrientedLattice.
Definition Sample.cpp:153
void addSample(const std::shared_ptr< Sample > &childSample)
Adds a sample to the list.
Definition Sample.cpp:278
std::shared_ptr< Geometry::SampleEnvironment > m_environment
An owned pointer to the SampleEnvironment object.
Definition Sample.h:131
void setCrystalStructure(const Geometry::CrystalStructure &newCrystalStructure)
Resets the internal pointer to the new CrystalStructure (it's copied).
Definition Sample.cpp:189
bool hasOrientedLattice() const
Definition Sample.cpp:178
~Sample()
Destructor.
std::unique_ptr< Geometry::CrystalStructure > m_crystalStructure
CrystalStructure of the sample.
Definition Sample.h:136
void setGeometryFlag(int geom_id)
Sets the geometry flag.
Definition Sample.cpp:208
void setName(const std::string &name)
Set the name of the sample.
Definition Sample.cpp:91
Sample()
Default constructor.
Definition Sample.cpp:29
std::size_t size() const
the number of samples
Definition Sample.cpp:272
std::vector< std::shared_ptr< Sample > > m_samples
Vector of child samples.
Definition Sample.h:139
void setWidth(double width)
Sets the width.
Definition Sample.cpp:245
double getWidth() const
Returns the width.
Definition Sample.cpp:251
bool hasCrystalStructure() const
Returns true if the sample actually holds a CrystalStructure.
Definition Sample.cpp:194
void setHeight(double height)
Sets the height.
Definition Sample.cpp:233
int m_geom_id
The sample geometry flag.
Definition Sample.h:142
double getHeight() const
Returns the height.
Definition Sample.cpp:239
void clearCrystalStructure()
Destroys the internally stored CrystalStructure-object.
Definition Sample.cpp:201
double m_height
The sample height from the SPB_STRUCT in the raw file.
Definition Sample.h:146
Geometry::IObject_sptr m_shape
The sample shape object.
Definition Sample.h:129
const Geometry::SampleEnvironment & getEnvironment() const
Get a reference to the sample's environment.
Definition Sample.cpp:135
Sample & operator=(const Sample &rhs)
Assignment operator.
Definition Sample.cpp:57
void setThickness(double thick)
Sets the thickness.
Definition Sample.cpp:221
const Geometry::CrystalStructure & getCrystalStructure() const
Definition Sample.cpp:180
double getThickness() const
Returns the thickness.
Definition Sample.cpp:227
bool operator==(const Sample &other) const
Definition Sample.cpp:413
const Geometry::IObject_sptr getShapePtr() const
Return a pointer to the sample shape.
Definition Sample.cpp:109
bool hasShape() const
Check if sample has a valid shape.
Definition Sample.cpp:93
Three components are required to describe a crystal structure:
IObject : Interface for geometry objects.
Definition IObject.h:42
Class to implement UB matrix.
Defines a single instance of a SampleEnvironment.
Class originally intended to be used with the DataHandling 'LoadInstrument' algorithm.
std::shared_ptr< CSGObject > createShape(Poco::XML::Element *pElem)
Creates a geometric object from a DOM-element-node pointing to an element whose child nodes contain t...
A material is defined as being composed of a given element, defined as a PhysicalConstants::NeutronAt...
Definition Material.h:50
void loadNexus(Nexus::File *file, const std::string &group)
Load the object from an open NeXus file.
Definition Material.cpp:544
bool compare(const mypair &left, const mypair &right)
std::shared_ptr< IObject > IObject_sptr
Typdef for a shared pointer.
Definition IObject.h:93
MANTID_KERNEL_DLL std::string strip(const std::string &A)
strip pre/post spaces
Definition Strings.cpp:419
std::string toString(const T &value)
Convert a number to a string.
Definition Strings.cpp:734