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