Mantid
Loading...
Searching...
No Matches
RotateInstrumentComponent.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 +
12
13namespace Mantid::DataHandling {
14
15// Register the algorithm into the algorithm factory
16DECLARE_ALGORITHM(RotateInstrumentComponent)
17
18using namespace Kernel;
19using namespace Geometry;
20using namespace API;
21
24
27 // When used as a Child Algorithm the workspace name is not used - hence the
28 // "Anonymous" to satisfy the validator
29 declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("Workspace", "Anonymous", Direction::InOut),
30 "The name of the workspace for which the new instrument "
31 "configuration will have an effect. Any other workspaces "
32 "stored in the analysis data service will be unaffected.");
33 declareProperty("ComponentName", "",
34 "The name of the component to rotate. "
35 "Component names are defined in the "
36 "instrument definition files.");
37 declareProperty("DetectorID", -1,
38 "The ID of the detector to rotate. If both "
39 "the component name and the detector ID "
40 "are set the latter will be used.");
41 declareProperty("X", 0.0, "The x-part of the rotation axis.");
42 declareProperty("Y", 0.0, "The y-part of the rotation axis.");
43 declareProperty("Z", 0.0, "The z-part of the rotation axis.");
44 declareProperty("Angle", 0.0, "The angle of rotation in degrees.");
45 declareProperty("RelativeRotation", true,
46 "The property defining how the rotation should be "
47 "interpreted. If true it is a relative rotation. Otherwise "
48 "it is an absolute rotation.");
49}
50
56 // Get the input workspace
57 Workspace_sptr ws = getProperty("Workspace");
58 MatrixWorkspace_sptr inputW = std::dynamic_pointer_cast<MatrixWorkspace>(ws);
59 DataObjects::PeaksWorkspace_sptr inputP = std::dynamic_pointer_cast<DataObjects::PeaksWorkspace>(ws);
60
61 // Get some stuff from the input workspace
62 Instrument_sptr inst;
63 if (inputW) {
64 inst = std::const_pointer_cast<Instrument>(inputW->getInstrument());
65 if (!inst)
66 throw std::runtime_error("Could not get a valid instrument from the "
67 "MatrixWorkspace provided as input");
68 } else if (inputP) {
69 inst = std::const_pointer_cast<Instrument>(inputP->getInstrument());
70 if (!inst)
71 throw std::runtime_error("Could not get a valid instrument from the "
72 "PeaksWorkspace provided as input");
73 } else {
74 if (!inst)
75 throw std::runtime_error("Could not get a valid instrument from the "
76 "workspace and it does not seem to be valid as "
77 "input (must be either MatrixWorkspace or "
78 "PeaksWorkspace");
79 }
80
81 const std::string ComponentName = getProperty("ComponentName");
82 const int DetID = getProperty("DetectorID");
83 const double X = getProperty("X");
84 const double Y = getProperty("Y");
85 const double Z = getProperty("Z");
86 const double angle = getProperty("Angle");
87 const bool relativeRotation = getProperty("RelativeRotation");
88
89 if (X + Y + Z == 0.0)
90 throw std::invalid_argument("The rotation axis must not be a zero vector");
91
93
94 // Find the component to move
95 if (DetID != -1) {
96 comp = inst->getDetector(DetID);
97 if (comp == nullptr) {
98 std::ostringstream mess;
99 mess << "Detector with ID " << DetID << " was not found.";
100 g_log.error(mess.str());
101 throw std::runtime_error(mess.str());
102 }
103 } else if (!ComponentName.empty()) {
104 comp = inst->getComponentByName(ComponentName);
105 if (comp == nullptr) {
106 std::ostringstream mess;
107 mess << "Component with name " << ComponentName << " was not found.";
108 g_log.error(mess.str());
109 throw std::runtime_error(mess.str());
110 }
111 } else {
112 g_log.error("DetectorID or ComponentName must be given.");
113 throw std::invalid_argument("DetectorID or ComponentName must be given.");
114 }
115
116 // Do the rotation
117 Quat rotation(angle, V3D(X, Y, Z));
118 if (relativeRotation)
119 // Note the unusual order. This is as in Component::getRotation().
120 rotation = comp->getRotation() * rotation;
121
122 const auto componentId = comp->getComponentID();
123 if (inputW) {
124 auto &componentInfo = inputW->mutableComponentInfo();
125 componentInfo.setRotation(componentInfo.indexOf(componentId), rotation);
126 } else if (inputP) {
127 auto &componentInfo = inputP->mutableComponentInfo();
128 componentInfo.setRotation(componentInfo.indexOf(componentId), rotation);
129 }
130}
131
132} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
Mantid::Kernel::Quat(ComponentInfo::* rotation)(const size_t) const
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
A property class for workspaces.
void exec() override
Overwrites Algorithm method.
void init() override
Overwrites Algorithm method.
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
Class for quaternions.
Definition: Quat.h:39
std::vector< double > getRotation(bool check_normalisation=false, bool throw_on_errors=false) const
returns the rotation matrix defined by this quaternion as an 9-point
Definition: Quat.cpp:453
void setRotation(const double deg)
Set the rotation (both don't change rotation axis)
Definition: Quat.cpp:158
Class for 3D vectors.
Definition: V3D.h:34
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
Definition: Workspace_fwd.h:20
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< PeaksWorkspace > PeaksWorkspace_sptr
Typedef for a shared pointer to a peaks workspace.
std::shared_ptr< const IComponent > IComponent_const_sptr
Typdef of a shared pointer to a const IComponent.
Definition: IComponent.h:161
std::shared_ptr< Instrument > Instrument_sptr
Shared pointer to an instrument object.
@ InOut
Both an input & output workspace.
Definition: Property.h:55