Mantid
Loading...
Searching...
No Matches
CentroidPeaksMD.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 +
13#include "MantidKernel/System.h"
15
17
18namespace Mantid::MDAlgorithms {
19
20// Register the algorithm into the AlgorithmFactory
21DECLARE_ALGORITHM(CentroidPeaksMD)
22
23using namespace Mantid::API;
24using namespace Mantid::DataObjects;
25using namespace Mantid::Geometry;
26using namespace Mantid::Kernel;
27using namespace Mantid::DataObjects;
28
29CentroidPeaksMD::CentroidPeaksMD() { this->useAlgorithm("CentroidPeaksMD", 2); }
30
31//----------------------------------------------------------------------------------------------
35 declareProperty(std::make_unique<WorkspaceProperty<IMDEventWorkspace>>("InputWorkspace", "", Direction::Input),
36 "An input MDEventWorkspace.");
37
38 std::vector<std::string> propOptions{"Q (lab frame)", "Q (sample frame)", "HKL"};
39 declareProperty("CoordinatesToUse", "HKL", std::make_shared<StringListValidator>(propOptions),
40 "Ignored: algorithm uses the InputWorkspace's coordinates.");
41
42 declareProperty(std::make_unique<PropertyWithValue<double>>("PeakRadius", 1.0, Direction::Input),
43 "Fixed radius around each peak position in which to calculate the "
44 "centroid.");
45
46 declareProperty(std::make_unique<WorkspaceProperty<PeaksWorkspace>>("PeaksWorkspace", "", Direction::Input),
47 "A PeaksWorkspace containing the peaks to centroid.");
48
49 declareProperty(std::make_unique<WorkspaceProperty<PeaksWorkspace>>("OutputWorkspace", "", Direction::Output),
50 "The output PeaksWorkspace will be a copy of the input PeaksWorkspace "
51 "with the peaks' positions modified by the new found centroids.");
52}
53
54//----------------------------------------------------------------------------------------------
59template <typename MDE, size_t nd> void CentroidPeaksMD::integrate(typename MDEventWorkspace<MDE, nd>::sptr ws) {
60 if (nd != 3)
61 throw std::invalid_argument("For now, we expect the input MDEventWorkspace "
62 "to have 3 dimensions only.");
63
65 Mantid::DataObjects::PeaksWorkspace_sptr inPeakWS = getProperty("PeaksWorkspace");
66
68 Mantid::DataObjects::PeaksWorkspace_sptr peakWS = getProperty("OutputWorkspace");
69 if (peakWS != inPeakWS)
70 peakWS = inPeakWS->clone();
71
72 std::string CoordinatesToUseStr = getPropertyValue("CoordinatesToUse");
73 int CoordinatesToUse = ws->getSpecialCoordinateSystem();
74 if (CoordinatesToUse == 1 && CoordinatesToUseStr != "Q (lab frame)")
75 g_log.warning() << "Warning: used Q (lab frame) coordinates for MD "
76 "workspace, not CoordinatesToUse from input \n";
77 else if (CoordinatesToUse == 2 && CoordinatesToUseStr != "Q (sample frame)")
78 g_log.warning() << "Warning: used Q (sample frame) coordinates for MD "
79 "workspace, not CoordinatesToUse from input \n";
80 else if (CoordinatesToUse == 3 && CoordinatesToUseStr != "HKL")
81 g_log.warning() << "Warning: used HKL coordinates for MD workspace, not "
82 "CoordinatesToUse from input \n";
83
85 double PeakRadius = getProperty("PeakRadius");
86
87 PRAGMA_OMP(parallel for schedule(dynamic, 10) )
88 for (int i = 0; i < int(peakWS->getNumberPeaks()); ++i) {
89 Peak &p = peakWS->getPeak(i);
90 double detectorDistance = p.getL2();
91
92 // Get the peak center as a position in the dimensions of the workspace
93 V3D pos;
94 if (CoordinatesToUse == 1) //"Q (lab frame)"
95 pos = p.getQLabFrame();
96 else if (CoordinatesToUse == 2) //"Q (sample frame)"
97 pos = p.getQSampleFrame();
98 else if (CoordinatesToUse == 3) //"HKL"
99 pos = p.getHKL();
100
101 // Build the sphere transformation
102 bool dimensionsUsed[nd];
103 coord_t center[nd];
104 for (size_t d = 0; d < nd; ++d) {
105 dimensionsUsed[d] = true; // Use all dimensions
106 center[d] = static_cast<coord_t>(pos[d]);
107 }
108 CoordTransformDistance sphere(nd, center, dimensionsUsed);
109
110 // Initialize the centroid to 0.0
111 signal_t signal = 0;
112 coord_t centroid[nd];
113 for (size_t d = 0; d < nd; d++)
114 centroid[d] = 0.0;
115
116 // Perform centroid
117 ws->getBox()->centroidSphere(sphere, static_cast<coord_t>(PeakRadius * PeakRadius), centroid, signal);
118
119 // Normalize by signal
120 if (signal != 0.0) {
121 for (size_t d = 0; d < nd; d++)
122 centroid[d] /= static_cast<coord_t>(signal);
123
124 V3D vecCentroid(centroid[0], centroid[1], centroid[2]);
125
126 // Save it back in the peak object, in the dimension specified.
127 if (CoordinatesToUse == 1) //"Q (lab frame)"
128 {
129 p.setQLabFrame(vecCentroid, detectorDistance);
130 p.findDetector();
131 } else if (CoordinatesToUse == 2) //"Q (sample frame)"
132 {
133 p.setQSampleFrame(vecCentroid, detectorDistance);
134 p.findDetector();
135 } else if (CoordinatesToUse == 3) //"HKL"
136 {
137 p.setHKL(vecCentroid);
138 }
139
140 g_log.information() << "Peak " << i << " at " << pos << ": signal " << signal << ", centroid " << vecCentroid
141 << " in " << CoordinatesToUse << '\n';
142 } else {
143 g_log.information() << "Peak " << i << " at " << pos << " had no signal, and could not be centroided.\n";
144 }
145 }
146
147 // Save the output
148 setProperty("OutputWorkspace", peakWS);
149}
150
151//----------------------------------------------------------------------------------------------
155 inWS = getProperty("InputWorkspace");
156
158}
159
160} // namespace Mantid::MDAlgorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
#define CALL_MDEVENT_FUNCTION3(funcname, workspace)
Macro that makes it possible to call a templated method for a MDEventWorkspace using a IMDEventWorksp...
#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.
Definition: Algorithm.cpp:1913
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
Definition: Algorithm.cpp:2026
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
void useAlgorithm(const std::string &, const int version=-1)
The algorithm to use instead of this one.
A property class for workspaces.
void setHKL(double H, double K, double L) override
Set all three H,K,L indices of the peak.
Definition: BasePeak.cpp:132
Mantid::Kernel::V3D getHKL() const override
Return the HKL vector.
Definition: BasePeak.cpp:103
Unique CoordCenterVectorParam type declaration for ndimensional coordinate centers.
void centroidSphere(Mantid::API::CoordTransform &radiusTransform, const coord_t radiusSquared, coord_t *centroid, signal_t &signal) const override=0
Find the centroid around a sphere.
std::shared_ptr< MDEventWorkspace< MDE, nd > > sptr
Typedef for a shared pointer of this kind of event workspace.
Kernel::SpecialCoordinateSystem getSpecialCoordinateSystem() const override
Get the coordinate system.
Structure describing a single-crystal peak.
Definition: Peak.h:34
Mantid::Kernel::V3D getQLabFrame() const override
Return the Q change (of the lattice, k_i - k_f) for this peak.
Definition: Peak.cpp:441
void setQSampleFrame(const Mantid::Kernel::V3D &QSampleFrame, boost::optional< double > detectorDistance=boost::none) override
Set the peak using the peak's position in reciprocal space, in the sample frame.
Definition: Peak.cpp:492
void setQLabFrame(const Mantid::Kernel::V3D &qLab, boost::optional< double > detectorDistance=boost::none) override
Set the peak using the peak's position in reciprocal space, in the lab frame.
Definition: Peak.cpp:513
bool findDetector()
After creating a peak using the Q in the lab frame, the detPos is set to the direction of the detecto...
Definition: Peak.cpp:613
Mantid::Kernel::V3D getQSampleFrame() const override
Return the Q change (of the lattice, k_i - k_f) for this peak.
Definition: Peak.cpp:472
double getL2() const override
Return the L2 flight path length (sample to detector), in meters.
Definition: Peak.cpp:718
The class PeaksWorkspace stores information about a set of SCD peaks.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
void information(const std::string &msg)
Logs at information level.
Definition: Logger.cpp:105
The concrete, templated class for properties.
Class for 3D vectors.
Definition: V3D.h:34
Mantid::API::IMDEventWorkspace_sptr inWS
Input MDEventWorkspace.
void integrate(typename DataObjects::MDEventWorkspace< MDE, nd >::sptr ws)
Integrate the peaks of the workspace using parameters saved in the algorithm class.
void exec() override
Run the algorithm.
void init() override
Initialise the properties.
std::shared_ptr< PeaksWorkspace > PeaksWorkspace_sptr
Typedef for a shared pointer to a peaks workspace.
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
Definition: MDTypes.h:27
double signal_t
Typedef for the signal recorded in a MDBox, etc.
Definition: MDTypes.h:36
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54