Mantid
Loading...
Searching...
No Matches
QTransform.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2024 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
13
14using namespace Mantid::DataObjects;
15
16namespace Mantid {
17namespace MDAlgorithms {
22
23//----------------------------------------------------------------------------------------------
24namespace { // anonymous
25size_t getNumQDimensions(const IMDEventWorkspace_sptr ws) {
26 // Check that the input workspace has units in Q_sample or Q_lab or |Q| frame
27 // Check the assumption that the Q dimensions are the first
28 if (ws->getSpecialCoordinateSystem() == Mantid::Kernel::SpecialCoordinateSystem::QSample ||
29 ws->getSpecialCoordinateSystem() == Mantid::Kernel::SpecialCoordinateSystem::QLab) {
30 // check that the first 3 dimensions are in Q
31 if (ws->getNumDims() < 3)
32 return 0;
33
34 for (size_t i = 0; i < 3; ++i)
35 if (!ws->getDimension(i)->getMDFrame().isQ())
36 return 0;
37
38 return 3;
39 } else if (ws->getDimension(0)->getName() == "|Q|") {
40 return 1;
41 }
42
43 return 0;
44}
45} // namespace
46//----------------------------------------------------------------------------------------------
50 declareProperty(std::make_unique<WorkspaceProperty<IMDEventWorkspace>>("InputWorkspace", "", Direction::Input),
51 "An input MDEventWorkspace. Must be in Q.");
52 declareProperty(std::make_unique<WorkspaceProperty<IMDEventWorkspace>>("OutputWorkspace", "", Direction::Output),
53 "The output MDEventWorkspace with correction applied.");
54}
55
56std::map<std::string, std::string> QTransform::validateInputs() {
57 std::map<std::string, std::string> result;
58 // check that the input workspace has units in Q_sample or Q_lab frame
59 API::IMDEventWorkspace_sptr input_ws = getProperty("InputWorkspace");
60 if (getNumQDimensions(input_ws) == 0)
61 result["InputWorkspace"] = "Input workspace must be in Q_sample or Q_lab frame. Either Q3D or Q1D with |Q|.";
62
63 return result;
64}
65//----------------------------------------------------------------------------------------------
69 IMDEventWorkspace_sptr input_ws = getProperty("InputWorkspace");
70 IMDEventWorkspace_sptr output_ws = getProperty("OutputWorkspace");
71
72 if (output_ws != input_ws)
73 output_ws = input_ws->clone();
74
75 m_numQDims = getNumQDimensions(output_ws);
76
78
79 // refresh cache for MDBoxes: set correct Box signal
80 output_ws->refreshCache();
81
82 setProperty("OutputWorkspace", output_ws);
83}
84
85template <typename MDE, size_t nd>
87 // Get Box from MDEventWorkspace
88 MDBoxBase<MDE, nd> *box1 = ws->getBox();
89 std::vector<API::IMDNode *> boxes;
90 box1->getBoxes(boxes, 1000, true);
91 auto numBoxes = int(boxes.size());
92
93 PRAGMA_OMP(parallel for if (!ws->isFileBacked()))
94 for (int i = 0; i < numBoxes; ++i) {
96 auto *box = dynamic_cast<MDBox<MDE, nd> *>(boxes[i]);
97 if (box && !box->getIsMasked()) {
98 std::vector<MDE> &events = box->getEvents();
99 for (auto it = events.begin(); it != events.end(); ++it) {
100
101 double qsqr{0};
102 for (size_t d = 0; d < m_numQDims; ++d)
103 qsqr += it->getCenter(d) * it->getCenter(d);
104
105 const auto correction = this->correction(qsqr);
106
107 // apply the correction
108 const auto intensity = it->getSignal() * correction;
109 it->setSignal(static_cast<float>(intensity));
110 const auto error2 = it->getErrorSquared() * correction * correction;
111 it->setErrorSquared(static_cast<float>(error2));
112 }
113 }
114 if (box) {
115 box->releaseEvents();
116 }
118 }
119
120 return;
121}
122
123} // namespace MDAlgorithms
124} // namespace Mantid
#define CALL_MDEVENT_FUNCTION(funcname, workspace)
Macro that makes it possible to call a templated method for a MDEventWorkspace using a IMDEventWorksp...
#define PARALLEL_START_INTERRUPT_REGION
Begins a block to skip processing is the algorithm has been interupted Note the end of the block if n...
#define PARALLEL_END_INTERRUPT_REGION
Ends a block to skip processing is the algorithm has been interupted Note the start of the block if n...
#define PRAGMA_OMP(expression)
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.
Abstract base class for multi-dimension event workspaces (MDEventWorkspace).
virtual void getBoxes(std::vector< IMDNode * > &boxes, size_t maxDepth, bool leafOnly)=0
Fill a vector with all the boxes who are the childred of this one up to a certain depth.
A property class for workspaces.
Templated super-class of a multi-dimensional event "box".
Definition MDBoxBase.h:50
Templated class for a multi-dimensional event "box".
Definition MDBox.h:45
std::vector< MDE > & getEvents()
Get vector of events to change.
Definition MDBox.hxx:243
std::shared_ptr< MDEventWorkspace< MDE, nd > > sptr
Typedef for a shared pointer of this kind of event workspace.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
std::map< std::string, std::string > validateInputs() override
Perform validation of ALL the input properties of the algorithm.
void init() override
Initialize the algorithm's properties.
void applyCorrection(typename Mantid::DataObjects::MDEventWorkspace< MDE, nd >::sptr)
void exec() override
Execute the algorithm.
virtual double correction(const double) const =0
std::shared_ptr< IMDEventWorkspace > IMDEventWorkspace_sptr
Shared pointer to Mantid::API::IMDEventWorkspace.
Helper class which provides the Collimation Length for SANS instruments.
Describes the direction (within an algorithm) of a Property.
Definition Property.h:50
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54