Mantid
Loading...
Searching...
No Matches
CopySample.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 +
9#include "MantidAPI/Run.h"
18
19namespace Mantid::Algorithms {
20
21// Register the algorithm into the AlgorithmFactory
22DECLARE_ALGORITHM(CopySample)
23
24using namespace Mantid::API;
25using namespace Mantid::Kernel;
29
30//----------------------------------------------------------------------------------------------
34 declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("InputWorkspace", "", Direction::Input),
35 "An input workspace from wich to copy sample information.");
36 declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("OutputWorkspace", "", Direction::InOut),
37 "An output workspace to wich to copy sample information..");
38 declareProperty(std::make_unique<PropertyWithValue<bool>>("CopyName", true, Direction::Input),
39 "Copy the name of the sample");
40 declareProperty(std::make_unique<PropertyWithValue<bool>>("CopyMaterial", true, Direction::Input),
41 "Copy the material of the sample");
42 declareProperty(std::make_unique<PropertyWithValue<bool>>("CopyEnvironment", true, Direction::Input),
43 "Copy the sample environment");
44 declareProperty(std::make_unique<PropertyWithValue<bool>>("CopyShape", true, Direction::Input),
45 "Copy the sample shape");
46 declareProperty(std::make_unique<PropertyWithValue<bool>>("CopyLattice", true, Direction::Input),
47 "Copy the sample oriented lattice");
48 declareProperty(std::make_unique<PropertyWithValue<bool>>("CopyOrientationOnly", false, Direction::Input),
49 "Copy the U matrix only, if both origin and destination have "
50 "oriented lattices");
51 setPropertySettings("CopyOrientationOnly",
52 std::make_unique<Kernel::EnabledWhenProperty>("CopyLattice", IS_EQUAL_TO, "1"));
53 declareProperty(std::make_unique<PropertyWithValue<int>>("MDInputSampleNumber", 0, Direction::Input),
54 "The number of the sample to be copied from, for an MD workspace "
55 "(starting from 0)");
56 declareProperty(std::make_unique<PropertyWithValue<int>>("MDOutputSampleNumber", EMPTY_INT(), Direction::Input),
57 "The number of the sample to be copied to for an MD "
58 "workspace (starting from 0). No number, or negative number, "
59 "means that it will copy to all samples");
60}
61
62std::map<std::string, std::string> CopySample::validateInputs() {
63 std::map<std::string, std::string> result;
64 const bool copyLattice = getProperty("CopyLattice");
65 const bool copyOrientationOnly = getProperty("CopyOrientationOnly");
66 if (copyOrientationOnly && !copyLattice) {
67 result["CopyLattice"] = "Need to check CopyLattice if CopyOrientationOnly is checked";
68 }
69 return result;
70}
71
72//----------------------------------------------------------------------------------------------
76 Workspace_sptr inWS = this->getProperty("InputWorkspace");
77 Workspace_sptr outWS = this->getProperty("OutputWorkspace");
78
79 Sample sample;
80 // get input sample
81 MultipleExperimentInfos_sptr inMDWS = std::dynamic_pointer_cast<MultipleExperimentInfos>(inWS);
82 if (inMDWS != nullptr) // it is an MD workspace
83 {
84 int inputSampleNumber = getProperty("MDInputSampleNumber");
85 if (inputSampleNumber < 0) {
86 g_log.warning() << "Number less then 0. Will use sample number 0 instead\n";
87 inputSampleNumber = 0;
88 }
89 if (static_cast<uint16_t>(inputSampleNumber) > (inMDWS->getNumExperimentInfo() - 1)) {
90 g_log.warning() << "Number greater than the number of last sample in the workspace ("
91 << (inMDWS->getNumExperimentInfo() - 1) << "). Will use sample number 0 instead\n";
92 inputSampleNumber = 0;
93 }
94 sample = inMDWS->getExperimentInfo(static_cast<uint16_t>(inputSampleNumber))->sample();
95 } else // peaks workspace or matrix workspace
96 {
97 ExperimentInfo_sptr ei = std::dynamic_pointer_cast<ExperimentInfo>(inWS);
98 if (!ei)
99 throw std::invalid_argument("Wrong type of input workspace");
100 sample = ei->sample();
101 }
102
103 bool copyName = getProperty("CopyName");
104 bool copyMaterial = getProperty("CopyMaterial");
105 bool copyEnvironment = getProperty("CopyEnvironment");
106 bool copyShape = getProperty("CopyShape");
107 bool copyLattice = getProperty("CopyLattice");
108 bool copyOrientation = getProperty("CopyOrientationOnly");
109
110 // Sample copy;
111 MultipleExperimentInfos_sptr outMDWS = std::dynamic_pointer_cast<MultipleExperimentInfos>(outWS);
112 if (outMDWS != nullptr) {
113 int outputSampleNumber = getProperty("MDOutputSampleNumber");
114 if ((outputSampleNumber == EMPTY_INT()) || (outputSampleNumber < 0)) // copy to all samples
115 {
116 for (uint16_t i = 0; i < outMDWS->getNumExperimentInfo(); i++) {
117 auto ei = outMDWS->getExperimentInfo(i);
118 copyParameters(sample, ei->mutableSample(), copyName, copyMaterial, copyEnvironment, copyShape, copyLattice,
119 copyOrientation, ei->run().getGoniometer().getR());
120 }
121 } else // copy to a single sample
122 {
123 if (static_cast<uint16_t>(outputSampleNumber) > (outMDWS->getNumExperimentInfo() - 1)) {
124 g_log.warning() << "Number greater than the number of last sample in "
125 "the workspace ("
126 << (outMDWS->getNumExperimentInfo() - 1) << "). Will use sample number 0 instead\n";
127 outputSampleNumber = 0;
128 }
129 auto ei = outMDWS->getExperimentInfo(static_cast<uint16_t>(outputSampleNumber));
130 copyParameters(sample, ei->mutableSample(), copyName, copyMaterial, copyEnvironment, copyShape, copyLattice,
131 copyOrientation, ei->run().getGoniometer().getR());
132 }
133 } else // peaks workspace or matrix workspace
134 {
135 ExperimentInfo_sptr ei = std::dynamic_pointer_cast<ExperimentInfo>(outWS);
136 if (!ei)
137 throw std::invalid_argument("Wrong type of output workspace");
138 copyParameters(sample, ei->mutableSample(), copyName, copyMaterial, copyEnvironment, copyShape, copyLattice,
139 copyOrientation, ei->run().getGoniometer().getR());
140 }
141 this->setProperty("OutputWorkspace", outWS);
142}
143
144void CopySample::copyParameters(Sample &from, Sample &to, bool nameFlag, bool materialFlag, bool environmentFlag,
145 bool shapeFlag, bool latticeFlag, bool orientationOnlyFlag,
146 const Kernel::Matrix<double> &rotationMatrix) {
147 if (nameFlag)
148 to.setName(from.getName());
149 if (environmentFlag) {
150 to.setEnvironment(std::make_unique<SampleEnvironment>(from.getEnvironment()));
151 }
152 if (shapeFlag) {
153 Material rhsMaterial;
154 if (materialFlag) {
155 rhsMaterial = from.getMaterial();
156 } else {
157 // Reset to lhs material
158 rhsMaterial = to.getMaterial();
159 }
160 auto rhsObject = std::shared_ptr<IObject>(from.getShape().cloneWithMaterial(rhsMaterial));
161
162 if (auto csgObj = std::dynamic_pointer_cast<Geometry::CSGObject>(rhsObject)) {
163 // Rotate CSGObject by goniometer by editing XML, if possible for that shape
164 std::string xml = csgObj->getShapeXML();
165 xml = Geometry::ShapeFactory().addGoniometerTag(rotationMatrix, xml);
166 rhsObject = Geometry::ShapeFactory().createShape(xml, false);
167 rhsObject->setMaterial(rhsMaterial); // add back in Material
168 }
169 if (auto meshObj = std::dynamic_pointer_cast<Geometry::MeshObject>(rhsObject)) {
170 // Rotate MeshObject by goniometer
171 meshObj->rotate(rotationMatrix);
172 }
173
174 to.setShape(rhsObject);
176 to.setHeight(from.getHeight());
177 to.setThickness(from.getThickness());
178 to.setWidth(from.getWidth());
179 } else if (materialFlag) {
180 auto lhsObject = std::shared_ptr<IObject>(to.getShape().cloneWithMaterial(from.getMaterial()));
181 to.setShape(lhsObject);
182 }
183
184 if ((latticeFlag) && from.hasOrientedLattice()) {
185 if (to.hasOrientedLattice() && orientationOnlyFlag) {
187 } else {
188 // copy over
189 to.setOrientedLattice(std::make_unique<OrientedLattice>(from.getOrientedLattice()));
190 }
191 }
192}
193
194} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Kernel::Logger & g_log
Definition Algorithm.h:422
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
const Kernel::Material & getMaterial() const
Return the material (convenience method)
Definition Sample.cpp:126
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
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
const Geometry::OrientedLattice & getOrientedLattice() const
Get a reference to the sample's OrientedLattice.
Definition Sample.cpp:153
bool hasOrientedLattice() const
Definition Sample.cpp:178
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
void setWidth(double width)
Sets the width.
Definition Sample.cpp:245
double getWidth() const
Returns the width.
Definition Sample.cpp:251
void setHeight(double height)
Sets the height.
Definition Sample.cpp:233
double getHeight() const
Returns the height.
Definition Sample.cpp:239
const Geometry::SampleEnvironment & getEnvironment() const
Get a reference to the sample's environment.
Definition Sample.cpp:135
void setThickness(double thick)
Sets the thickness.
Definition Sample.cpp:221
double getThickness() const
Returns the thickness.
Definition Sample.cpp:227
A property class for workspaces.
void init() override
Initialise the properties.
std::map< std::string, std::string > validateInputs() override
Method checking errors on ALL the inputs, before execution.
void copyParameters(API::Sample &from, API::Sample &to, bool nameFlag, bool materialFlag, bool environmentFlag, bool shapeFlag, bool latticeFlag, bool orientationOnlyFlag, const Kernel::Matrix< double > &rotationMatrix)
Function to copy information from one sample to another.
void exec() override
Run the algorithm.
IObject : Interface for geometry objects.
Definition IObject.h:42
virtual IObject * cloneWithMaterial(const Kernel::Material &material) const =0
Class to implement UB matrix.
void setU(const Kernel::DblMatrix &newU, const bool force=true)
Sets the U matrix.
const Kernel::DblMatrix & getU() const
Get the U 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...
std::string addGoniometerTag(const Kernel::Matrix< double > &rotateMatrix, std::string xml)
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void setPropertySettings(const std::string &name, std::unique_ptr< IPropertySettings > settings)
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
A material is defined as being composed of a given element, defined as a PhysicalConstants::NeutronAt...
Definition Material.h:50
Numerical Matrix class.
Definition Matrix.h:42
The concrete, templated class for properties.
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< ExperimentInfo > ExperimentInfo_sptr
Shared pointer to ExperimentInfo.
std::shared_ptr< MultipleExperimentInfos > MultipleExperimentInfos_sptr
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
Definition EmptyValues.h:24
@ InOut
Both an input & output workspace.
Definition Property.h:55
@ Input
An input workspace.
Definition Property.h:53