Mantid
Loading...
Searching...
No Matches
CentroidPeaksMD2.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 +
16
17namespace Mantid::MDAlgorithms {
18
19// Register the algorithm into the AlgorithmFactory
20DECLARE_ALGORITHM(CentroidPeaksMD2)
21
22using namespace Mantid::API;
23using namespace Mantid::DataObjects;
24using namespace Mantid::Geometry;
25using namespace Mantid::Kernel;
26using namespace Mantid::DataObjects;
27
28//----------------------------------------------------------------------------------------------
32 declareProperty(std::make_unique<WorkspaceProperty<IMDEventWorkspace>>("InputWorkspace", "", Direction::Input),
33 "An input MDEventWorkspace.");
34
35 declareProperty(std::make_unique<PropertyWithValue<double>>("PeakRadius", 1.0, Direction::Input),
36 "Fixed radius around each peak position in which to calculate the "
37 "centroid.");
38
39 declareProperty(std::make_unique<WorkspaceProperty<IPeaksWorkspace>>("PeaksWorkspace", "", Direction::Input),
40 "A PeaksWorkspace containing the peaks to centroid.");
41
42 declareProperty(std::make_unique<WorkspaceProperty<IPeaksWorkspace>>("OutputWorkspace", "", Direction::Output),
43 "The output PeaksWorkspace will be a copy of the input PeaksWorkspace "
44 "with the peaks' positions modified by the new found centroids.");
45}
46
47//----------------------------------------------------------------------------------------------
52template <typename MDE, size_t nd> void CentroidPeaksMD2::integrate(typename MDEventWorkspace<MDE, nd>::sptr ws) {
53 if (nd != 3)
54 throw std::invalid_argument("For now, we expect the input MDEventWorkspace "
55 "to have 3 dimensions only.");
56
58 IPeaksWorkspace_sptr inPeakWS = getProperty("PeaksWorkspace");
59
61 IPeaksWorkspace_sptr peakWS = getProperty("OutputWorkspace");
62
63 if (peakWS != inPeakWS)
64 peakWS = inPeakWS->clone();
65
66 int CoordinatesToUse = ws->getSpecialCoordinateSystem();
67
69 double PeakRadius = getProperty("PeakRadius");
70
71 PRAGMA_OMP(parallel for schedule(dynamic, 10) )
72 for (int i = 0; i < int(peakWS->getNumberPeaks()); ++i) {
73 // Get a direct ref to that peak.
74 IPeak &p = peakWS->getPeak(i);
75 Peak *peak = dynamic_cast<Peak *>(&p);
76 double detectorDistance = 0.;
77 if (peak)
78 detectorDistance = p.getL2();
79
80 // Get the peak center as a position in the dimensions of the workspace
81 V3D pos;
82 if (CoordinatesToUse == 1) //"Q (lab frame)"
83 pos = p.getQLabFrame();
84 else if (CoordinatesToUse == 2) //"Q (sample frame)"
85 pos = p.getQSampleFrame();
86 else if (CoordinatesToUse == 3) //"HKL"
87 pos = p.getHKL();
88
89 // Build the sphere transformation
90 bool dimensionsUsed[nd];
91 coord_t center[nd];
92 for (size_t d = 0; d < nd; ++d) {
93 dimensionsUsed[d] = true; // Use all dimensions
94 center[d] = static_cast<coord_t>(pos[d]);
95 }
96 CoordTransformDistance sphere(nd, center, dimensionsUsed);
97
98 // Initialize the centroid to 0.0
99 signal_t signal = 0;
100 coord_t centroid[nd];
101 for (size_t d = 0; d < nd; d++)
102 centroid[d] = 0.0;
103
104 // Perform centroid
105 ws->getBox()->centroidSphere(sphere, static_cast<coord_t>(PeakRadius * PeakRadius), centroid, signal);
106
107 // Normalize by signal
108 if (signal != 0.0) {
109 for (size_t d = 0; d < nd; d++)
110 centroid[d] /= static_cast<coord_t>(signal);
111
112 V3D vecCentroid(centroid[0], centroid[1], centroid[2]);
113 p.setBinCount(static_cast<double>(signal));
114
115 // Save it back in the peak object, in the dimension specified.
116 try {
117 if (CoordinatesToUse == 1) //"Q (lab frame)"
118 {
119 p.setQLabFrame(vecCentroid, detectorDistance);
120 if (peak)
121 peak->findDetector();
122 } else if (CoordinatesToUse == 2) //"Q (sample frame)"
123 {
124 p.setQSampleFrame(vecCentroid, detectorDistance);
125 if (peak)
126 peak->findDetector();
127 } else if (CoordinatesToUse == 3) //"HKL"
128 {
129 p.setHKL(vecCentroid);
130 }
131 } catch (std::exception &e) {
132 g_log.warning() << "Error setting Q or HKL\n";
133 g_log.warning() << e.what() << '\n';
134 }
135
136 g_log.information() << "Peak " << i << " at " << pos << ": signal " << signal << ", centroid " << vecCentroid
137 << " in " << CoordinatesToUse << '\n';
138 } else {
139 g_log.information() << "Peak " << i << " at " << pos << " had no signal, and could not be centroided.\n";
140 }
141 }
142
143 // Save the output
144 setProperty("OutputWorkspace", peakWS);
145}
146
147//----------------------------------------------------------------------------------------------
151 inWS = getProperty("InputWorkspace");
152
154}
155
156} // namespace Mantid::MDAlgorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
#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.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Kernel::Logger & g_log
Definition Algorithm.h:422
A property class for workspaces.
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
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:623
Structure describing a single-crystal peak.
Definition IPeak.h:26
virtual void setHKL(double H, double K, double L)=0
virtual void setBinCount(double m_BinCount)=0
virtual void setQLabFrame(const Mantid::Kernel::V3D &QLabFrame, std::optional< double > detectorDistance)=0
virtual double getL2() const =0
virtual Mantid::Kernel::V3D getQSampleFrame() const =0
virtual Mantid::Kernel::V3D getQLabFrame() const =0
virtual Mantid::Kernel::V3D getHKL() const =0
virtual void setQSampleFrame(const Mantid::Kernel::V3D &QSampleFrame, std::optional< double > detectorDistance)=0
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:117
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
The concrete, templated class for properties.
Class for 3D vectors.
Definition V3D.h:34
void exec() override
Run the algorithm.
void init() override
Initialise the properties.
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.
std::shared_ptr< IPeaksWorkspace > IPeaksWorkspace_sptr
shared pointer to Mantid::API::IPeaksWorkspace
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