Mantid
Loading...
Searching...
No Matches
RotateSource.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 +
11#include "MantidKernel/Quat.h"
12#include "MantidKernel/V3D.h"
13
14namespace Mantid::DataHandling {
15
19
20// Register the algorithm into the AlgorithmFactory
21DECLARE_ALGORITHM(RotateSource)
22
23using namespace Geometry;
24using namespace API;
25
26//----------------------------------------------------------------------------------------------
30
31 // When used as a Child Algorithm the workspace name is not used - hence the
32 // "Anonymous" to satisfy the validator
33 declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("Workspace", "Anonymous", Direction::InOut),
34 "The name of the workspace for which the new instrument "
35 "configuration will have an effect. Any other workspaces "
36 "stored in the analysis data service will be unaffected.");
37 declareProperty("Angle", 0.0,
38 "The angle of rotation in degrees (according "
39 "to the handedness of the coordinate system.");
40}
41
42//----------------------------------------------------------------------------------------------
46
47 // Get the input workspace
48 Workspace_sptr ws = getProperty("Workspace");
49
50 MatrixWorkspace_sptr inputW = std::dynamic_pointer_cast<MatrixWorkspace>(ws);
51 DataObjects::PeaksWorkspace_sptr inputP = std::dynamic_pointer_cast<DataObjects::PeaksWorkspace>(ws);
52
53 // Get some stuff from the input workspace
55 if (inputW) {
56 inst = inputW->getInstrument();
57 if (!inst)
58 throw std::runtime_error("Could not get a valid instrument from the "
59 "MatrixWorkspace provided as input");
60 } else if (inputP) {
61 inst = inputP->getInstrument();
62 if (!inst)
63 throw std::runtime_error("Could not get a valid instrument from the "
64 "PeaksWorkspace provided as input");
65 } else {
66 throw std::runtime_error("Input workspaces does not seem to be valid (must "
67 "be either MatrixWorkspace or PeaksWorkspace)");
68 }
69
70 double angle = getProperty("Angle");
71
72 if (angle != 0.) {
73
74 // Need the reference frame to decide around which axis to rotate
75 auto refFrame = inst->getReferenceFrame();
76 if (!refFrame) {
77 throw std::runtime_error("Could not get a valid reference frame");
78 }
79
80 // Axis of rotation
81 auto beam = refFrame->vecPointingAlongBeam();
82 auto up = refFrame->vecPointingUp();
83 auto rotationAxis = up.cross_prod(beam);
84
85 // The handedness
86 auto handedness = refFrame->getHandedness();
87 if (handedness == Left) {
88 angle *= -1.;
89 }
90
91 // Get the source's position
92 auto source = inst->getSource();
93 if (!source) {
94 throw std::runtime_error("Could not get the source's position");
95 }
96 // Get the sample's position
97 auto sample = inst->getSample();
98 if (!sample) {
99 throw std::runtime_error("Could not get the sample's position");
100 }
101 auto samplePos = sample->getPos();
102 // The vector we want to rotate
103 auto sourcePos = source->getPos() - samplePos;
104
105 // The new position
106 Quat quat(angle, rotationAxis);
107 quat.rotate(sourcePos);
108 sourcePos += samplePos;
109
110 // The source's name
111 std::string sourceName = source->getName();
112
113 // Move the source to the new location
114 auto move = this->createChildAlgorithm("MoveInstrumentComponent");
115 move->initialize();
116 move->setProperty("Workspace", ws);
117 move->setProperty("ComponentName", sourceName);
118 move->setProperty("X", sourcePos.X());
119 move->setProperty("Y", sourcePos.Y());
120 move->setProperty("Z", sourcePos.Z());
121 move->setProperty("RelativePosition", false);
122 move->execute();
123 }
124}
125
126} // namespace Mantid::DataHandling
#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
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
Definition: Algorithm.cpp:842
A property class for workspaces.
void init() override
Initialize the algorithm's properties.
void exec() override
Execute the algorithm.
Class for quaternions.
Definition: Quat.h:39
void rotate(V3D &) const
Rotate a vector.
Definition: Quat.cpp:397
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 Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
Describes the direction (within an algorithm) of a Property.
Definition: Property.h:50
@ InOut
Both an input & output workspace.
Definition: Property.h:55