Mantid
Loading...
Searching...
No Matches
IntegratePeaksUsingClusters.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 +
20#include "MantidKernel/Utils.h"
21
22#include <cmath>
23
24using namespace Mantid::API;
25using namespace Mantid::Kernel;
26using namespace Mantid::DataObjects;
28
29namespace Mantid::Crystal {
30
31// Register the algorithm into the AlgorithmFactory
33
34//----------------------------------------------------------------------------------------------
36const std::string IntegratePeaksUsingClusters::name() const { return "IntegratePeaksUsingClusters"; }
37
39int IntegratePeaksUsingClusters::version() const { return 1; }
40
42const std::string IntegratePeaksUsingClusters::category() const { return "MDAlgorithms\\Peaks;Crystal\\Integration"; }
43
44//----------------------------------------------------------------------------------------------
45
46//----------------------------------------------------------------------------------------------
50 declareProperty(std::make_unique<WorkspaceProperty<IMDHistoWorkspace>>("InputWorkspace", "", Direction::Input),
51 "Input md workspace.");
52 declareProperty(std::make_unique<WorkspaceProperty<PeaksWorkspace>>("PeaksWorkspace", "", Direction::Input),
53 "A PeaksWorkspace containing the peaks to integrate.");
54
55 auto positiveValidator = std::make_shared<BoundedValidator<double>>();
56 positiveValidator->setExclusive(true);
57 positiveValidator->setLower(0);
58
59 auto compositeValidator = std::make_shared<CompositeValidator>();
60 compositeValidator->add(positiveValidator);
61 compositeValidator->add(std::make_shared<MandatoryValidator<double>>());
62
63 declareProperty(std::make_unique<PropertyWithValue<double>>("Threshold", 0, compositeValidator, Direction::Input),
64 "Threshold signal above which to consider peaks");
65
66 std::array<std::string, 3> normalizations = {{"NoNormalization", "VolumeNormalization", "NumEventsNormalization"}};
67
68 declareProperty("Normalization", normalizations[1],
70 "Normalization to use with Threshold. Defaults to "
71 "VolumeNormalization to account for different binning.");
72
73 declareProperty(std::make_unique<WorkspaceProperty<PeaksWorkspace>>("OutputWorkspace", "", Direction::Output),
74 "An output integrated peaks workspace.");
75 declareProperty(std::make_unique<WorkspaceProperty<IMDHistoWorkspace>>("OutputWorkspaceMD", "", Direction::Output),
76 "MDHistoWorkspace containing the labeled clusters used by "
77 "the algorithm.");
78}
79
85 std::string normProp = getPropertyValue("Normalization");
86 Mantid::API::MDNormalization normalization;
87 if (normProp == "NoNormalization") {
88 normalization = NoNormalization;
89 } else if (normProp == "VolumeNormalization") {
90 normalization = VolumeNormalization;
91 } else {
92 normalization = NumEventsNormalization;
93 }
94 return normalization;
95}
96
97//----------------------------------------------------------------------------------------------
101 IMDHistoWorkspace_sptr mdWS = getProperty("InputWorkspace");
102 PeaksWorkspace_sptr inPeakWS = getProperty("PeaksWorkspace");
103 PeaksWorkspace_sptr peakWS = getProperty("OutputWorkspace");
104 if (peakWS != inPeakWS) {
105 peakWS = inPeakWS->clone();
106 }
107
108 {
109 const SpecialCoordinateSystem mdCoordinates = mdWS->getSpecialCoordinateSystem();
110 if (mdCoordinates == None) {
111 throw std::invalid_argument("The coordinate system of the input "
112 "MDWorkspace cannot be established. Create "
113 "your workspace with an MDFrame which is "
114 "not a General Frame or Unknown Frame.");
115 }
116 }
117
118 const double threshold = getProperty("Threshold");
119 // Make a background strategy for the CCL analysis to use.
120 HardThresholdBackground backgroundStrategy(threshold, this->getNormalization());
121 // CCL. Multi-processor version.
123
124 Progress progress(this, 0.0, 1.0, 1);
125 // Perform CCL.
126 ClusterTuple clusters = analysis.executeAndFetchClusters(mdWS, &backgroundStrategy, progress);
127 // Extract the clusters
128 ConnectedComponentMappingTypes::ClusterMap &clusterMap = clusters.get<1>();
129 // Extract the labeled image
130 IMDHistoWorkspace_sptr outHistoWS = clusters.get<0>();
131 // Labels taken by peaks.
132 std::map<size_t, size_t> labelsTakenByPeaks;
133 // Make a peak transform so that we can understand a peak in the context of
134 // the mdworkspace coordinate setup.
135 PeakClusterProjection projection(outHistoWS); // Projection of PeaksWorkspace
136 // over labelled cluster
137 // workspace.
138
139 progress.doReport("Performing Peak Integration");
140 g_log.information("Starting Integration");
141 progress.resetNumSteps(peakWS->getNumberPeaks(), 0.9, 1);
143 for (int i = 0; i < peakWS->getNumberPeaks(); ++i) {
145 Geometry::IPeak &peak = peakWS->getPeak(i);
146 const Mantid::signal_t signalValue =
147 projection.signalAtPeakCenter(peak); // No normalization when extracting label ids!
148 if (std::isnan(signalValue)) {
149 g_log.warning() << "Warning: image for integration is off edge of detector for peak " << i << '\n';
150 } else if (signalValue < static_cast<Mantid::signal_t>(analysis.getStartLabelId())) {
151 g_log.information() << "Peak: " << i
152 << " Has no corresponding cluster/blob detected on "
153 "the image. This could be down to your Threshold "
154 "settings.\n";
155 } else {
156 const auto labelIdAtPeak = static_cast<size_t>(signalValue);
157 ICluster *const cluster = clusterMap[labelIdAtPeak].get();
158 ICluster::ClusterIntegratedValues integratedValues = cluster->integrate(mdWS);
159 peak.setIntensity(integratedValues.get<0>());
160 peak.setSigmaIntensity(std::sqrt(integratedValues.get<1>()));
161
163 auto it = labelsTakenByPeaks.find(labelIdAtPeak);
164 if (it != labelsTakenByPeaks.end()) {
165 g_log.warning() << "Overlapping Peaks. Peak: " << i << " overlaps with another Peak: " << it->second
166 << " and shares label id: " << it->first << '\n';
167 }
168 labelsTakenByPeaks.emplace(labelIdAtPeak, i);
169 }
170 progress.report();
171 }
173 }
175
176 setProperty("OutputWorkspace", peakWS);
177 setProperty("OutputWorkspaceMD", outHistoWS);
178}
179
180} // namespace Mantid::Crystal
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
#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...
Definition: MultiThreaded.h:94
#define PARALLEL_CRITICAL(name)
#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 PARALLEL_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
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 progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
Definition: Algorithm.cpp:231
Helper class for reporting progress from algorithms.
Definition: Progress.h:25
A property class for workspaces.
ConnectedComponentLabelling : Implements connected component labeling on MDHistoWorkspaces.
size_t getStartLabelId() const
Getter for the start label id.
ConnectedComponentMappingTypes::ClusterTuple executeAndFetchClusters(Mantid::API::IMDHistoWorkspace_sptr ws, BackgroundStrategy *const strategy, Mantid::API::Progress &progress) const
Execute and return clusters, as well as maps to integratable clusters.
HardThresholdBackground : Implementation of BackgroundStrategy using a fixed background signal value ...
ICluster : Abstract cluster.
Definition: ICluster.h:25
boost::tuple< double, double > ClusterIntegratedValues
Definition: ICluster.h:27
virtual ClusterIntegratedValues integrate(std::shared_ptr< const Mantid::API::IMDHistoWorkspace > ws) const =0
integrate the cluster
IntegratePeaksUsingClusters : Uses clustering to integrate peaks.
void init() override
Initialize the algorithm's properties.
const std::string category() const override
Algorithm's category for identification.
Mantid::API::MDNormalization getNormalization()
Get the normalization.
int version() const override
Algorithm's version for identification.
PeakClusterProjection : Maps peaks onto IMDHistoWorkspaces and returns the signal value at the peak c...
Mantid::signal_t signalAtPeakCenter(const Mantid::Geometry::IPeak &peak, Mantid::API::MDNormalization normalization=Mantid::API::NoNormalization) const
Get the signal value at the peak center.
Structure describing a single-crystal peak.
Definition: IPeak.h:26
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
ListValidator is a validator that requires the value of a property to be one of a defined list of pos...
Definition: ListValidator.h:29
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
Validator to check that a property is not left empty.
The concrete, templated class for properties.
std::shared_ptr< IMDHistoWorkspace > IMDHistoWorkspace_sptr
shared pointer to Mantid::API::IMDHistoWorkspace
MDNormalization
Enum describing different ways to normalize the signal in a MDWorkspace.
Definition: IMDIterator.h:25
@ VolumeNormalization
Divide the signal by the volume of the box/bin.
Definition: IMDIterator.h:29
@ NumEventsNormalization
Divide the signal by the number of events that contributed to it.
Definition: IMDIterator.h:31
@ NoNormalization
Don't normalize = return raw counts.
Definition: IMDIterator.h:27
std::map< size_t, std::shared_ptr< Mantid::Crystal::ICluster > > ClusterMap
boost::tuple< Mantid::API::IMDHistoWorkspace_sptr, ClusterMap > ClusterTuple
std::shared_ptr< PeaksWorkspace > PeaksWorkspace_sptr
Typedef for a shared pointer to a peaks workspace.
SpecialCoordinateSystem
Special coordinate systems for Q3D.
std::shared_ptr< IValidator > IValidator_sptr
A shared_ptr to an IValidator.
Definition: IValidator.h:26
std::enable_if< std::is_pointer< Arg >::value, bool >::type threadSafe(Arg workspace)
Thread-safety check Checks the workspace to ensure it is suitable for multithreaded access.
Definition: MultiThreaded.h:22
double signal_t
Typedef for the signal recorded in a MDBox, etc.
Definition: MDTypes.h:36
STL namespace.
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54