Mantid
Loading...
Searching...
No Matches
FindSXPeaksHelper.h
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 +
7#pragma once
8
10#include "MantidCrystal/DllConfig.h"
11#include "MantidHistogramData/HistogramE.h"
12#include "MantidHistogramData/HistogramX.h"
13#include "MantidHistogramData/HistogramY.h"
15
16#include <iterator>
17#include <optional>
18#include <vector>
19
20namespace Mantid {
21namespace Kernel {
22class ProgressBase;
23}
24} // namespace Mantid
25
26namespace Mantid {
27namespace Crystal {
28namespace FindSXPeaksHelper {
29
31enum class XAxisUnit { TOF, DSPACING };
32
33/* ------------------------------------------------------------------------------------------
34 * Single Crystal peak representation
35 * ------------------------------------------------------------------------------------------
36 */
37struct MANTID_CRYSTAL_DLL SXPeak {
38public:
39 SXPeak(double t, double phi, double intensity, const std::vector<int> &spectral, const size_t wsIndex,
40 const Mantid::API::SpectrumInfo &spectrumInfo);
41
44 bool compare(const SXPeak &rhs, double tolerance) const;
45
48 bool compare(const SXPeak &rhs, const double xTolerance, const double phiTolerance, const double thetaTolerance,
49 const XAxisUnit tofUnits = XAxisUnit::TOF) const;
50
52 Mantid::Kernel::V3D getQ() const;
53
55 SXPeak &operator+=(const SXPeak &rhs);
56
58 void reduce();
59
60 friend std::ostream &operator<<(std::ostream &os, const SXPeak &rhs) {
61 os << rhs.m_tof << "," << rhs.m_twoTheta << "," << rhs.m_phi << "," << rhs.m_intensity << "\n";
62 os << " Spectra";
63 std::copy(rhs.m_spectra.begin(), rhs.m_spectra.end(), std::ostream_iterator<int>(os, ","));
64 return os;
65 }
66
67 const double &getIntensity() const;
68
69 detid_t getDetectorId() const;
70
71 const std::vector<int> &getPeakSpectras() const;
72
73private:
75 double m_tof;
77 double m_dSpacing;
79 double m_twoTheta;
81 double m_phi;
85 std::vector<int> m_spectra;
87 double m_LTotal;
89 size_t m_wsIndex;
97 std::string m_qConvention;
98};
99
100using yIt = Mantid::HistogramData::HistogramY::const_iterator;
101using Bound = HistogramData::HistogramX::const_iterator;
102using BoundsIterator = std::pair<Bound, Bound>;
103using PeakList = std::optional<std::vector<SXPeak>>;
104
106public:
107 PeakContainer(const HistogramData::HistogramY &y);
108 void startRecord(yIt item);
109 void stopRecord(yIt item);
110 void record(yIt item);
111 size_t getNumberOfPointsInPeak() const;
112 yIt getMaxIterator() const;
113 double getStartingSignal() const;
114
115private:
116 const HistogramData::HistogramY &m_y;
120 double m_maxSignal = -1.;
121};
122
123/* ------------------------------------------------------------------------------------------
124 * Background strategy
125 * ------------------------------------------------------------------------------------------
126 */
127struct MANTID_CRYSTAL_DLL BackgroundStrategy {
128 virtual ~BackgroundStrategy() = default;
129 virtual bool isBelowBackground(const double intensity, const HistogramData::HistogramY &y) const = 0;
130};
131
132struct MANTID_CRYSTAL_DLL AbsoluteBackgroundStrategy : public BackgroundStrategy {
134 bool isBelowBackground(const double intensity, const HistogramData::HistogramY &) const override;
135
136private:
137 double m_background = 0.;
138};
139
140struct MANTID_CRYSTAL_DLL PerSpectrumBackgroundStrategy : public BackgroundStrategy {
141 PerSpectrumBackgroundStrategy(const double backgroundMultiplier);
142 bool isBelowBackground(const double intensity, const HistogramData::HistogramY &y) const override;
143
144private:
145 double m_backgroundMultiplier = 1.;
146};
147
148/* ------------------------------------------------------------------------------------------
149 * Peak Finding Strategy
150 * ------------------------------------------------------------------------------------------
151 */
152class MANTID_CRYSTAL_DLL PeakFindingStrategy {
153public:
154 PeakFindingStrategy(const BackgroundStrategy *backgroundStrategy, const API::SpectrumInfo &spectrumInfo,
155 const double minValue = EMPTY_DBL(), const double maxValue = EMPTY_DBL(),
156 const XAxisUnit units = XAxisUnit::TOF);
157 virtual ~PeakFindingStrategy() = default;
158 PeakList findSXPeaks(const HistogramData::HistogramX &x, const HistogramData::HistogramY &y,
159 const HistogramData::HistogramE &e, const int workspaceIndex) const;
160 void setMinNBinsPerPeak(int minBinsPerPeak);
161
162protected:
163 void filterPeaksForMinBins(std::vector<std::unique_ptr<PeakContainer>> &inputPeakList) const;
164
165 BoundsIterator getBounds(const HistogramData::HistogramX &x) const;
166 double calculatePhi(size_t workspaceIndex) const;
167 double getXValue(const HistogramData::HistogramX &x, const size_t peakLocation) const;
168 double convertToTOF(const double xValue, const size_t workspaceIndex) const;
169 virtual PeakList dofindSXPeaks(const HistogramData::HistogramX &x, const HistogramData::HistogramY &y,
170 const HistogramData::HistogramE &e, Bound low, Bound high,
171 const int workspaceIndex) const = 0;
172 PeakList convertToSXPeaks(const HistogramData::HistogramX &x, const HistogramData::HistogramY &y,
173 const std::vector<std::unique_ptr<PeakContainer>> &peaks, const int workspaceIndex) const;
174
176 const double m_minValue = EMPTY_DBL();
177 const double m_maxValue = EMPTY_DBL();
180 int m_minNBinsPerPeak = EMPTY_INT();
181};
182
183class MANTID_CRYSTAL_DLL StrongestPeaksStrategy : public PeakFindingStrategy {
184public:
185 StrongestPeaksStrategy(const BackgroundStrategy *backgroundStrategy, const API::SpectrumInfo &spectrumInfo,
186 const double minValue = EMPTY_DBL(), const double maxValue = EMPTY_DBL(),
187 const XAxisUnit units = XAxisUnit::TOF);
188 PeakList dofindSXPeaks(const HistogramData::HistogramX &x, const HistogramData::HistogramY &y,
189 [[maybe_unused]] const HistogramData::HistogramE &e, Bound low, Bound high,
190 const int workspaceIndex) const override;
191};
192
193class MANTID_CRYSTAL_DLL AllPeaksStrategy : public PeakFindingStrategy {
194public:
195 AllPeaksStrategy(const BackgroundStrategy *backgroundStrategy, const API::SpectrumInfo &spectrumInfo,
196 const double minValue = EMPTY_DBL(), const double maxValue = EMPTY_DBL(),
197 const XAxisUnit units = XAxisUnit::TOF);
198 PeakList dofindSXPeaks(const HistogramData::HistogramX &x, const HistogramData::HistogramY &y,
199 [[maybe_unused]] const HistogramData::HistogramE &e, Bound low, Bound high,
200 const int workspaceIndex) const override;
201
202private:
203 std::vector<std::unique_ptr<PeakContainer>>
204 getAllPeaks(const HistogramData::HistogramX &x, const HistogramData::HistogramY &y, Bound low, Bound high,
205 const Mantid::Crystal::FindSXPeaksHelper::BackgroundStrategy *backgroundStrategy) const;
206};
207
208#define NSIGMA_COMPARISON_THRESHOLD 1e-10
209
210class MANTID_CRYSTAL_DLL NSigmaPeaksStrategy : public PeakFindingStrategy {
211public:
212 NSigmaPeaksStrategy(const API::SpectrumInfo &spectrumInfo, const double nsigma = EMPTY_DBL(),
213 const double minValue = EMPTY_DBL(), const double maxValue = EMPTY_DBL(),
214 const XAxisUnit units = XAxisUnit::TOF);
215 PeakList dofindSXPeaks(const HistogramData::HistogramX &x, const HistogramData::HistogramY &y,
216 const HistogramData::HistogramE &e, Bound low, Bound high,
217 const int workspaceIndex) const override;
218
219private:
220 std::vector<std::unique_ptr<PeakContainer>> getAllNSigmaPeaks(const HistogramData::HistogramX &x,
221 const HistogramData::HistogramY &y,
222 const HistogramData::HistogramE &e, Bound low,
223 Bound high) const;
224 const double m_nsigma;
225};
226
227/* ------------------------------------------------------------------------------------------
228 * Comparison Strategy
229 * ------------------------------------------------------------------------------------------
230 */
231class MANTID_CRYSTAL_DLL CompareStrategy {
232public:
233 virtual ~CompareStrategy() = default;
234 virtual bool compare(const SXPeak &lhs, const SXPeak &rhs) const = 0;
235};
236
237class MANTID_CRYSTAL_DLL RelativeCompareStrategy : public CompareStrategy {
238public:
239 RelativeCompareStrategy(const double resolution);
240 bool compare(const SXPeak &lhs, const SXPeak &rhs) const override;
241
242private:
243 const double m_resolution;
244};
245
246class MANTID_CRYSTAL_DLL AbsoluteCompareStrategy : public CompareStrategy {
247public:
248 AbsoluteCompareStrategy(const double tofResolution, const double phiResolution, const double twoThetaResolution,
249 const XAxisUnit units = XAxisUnit::TOF);
250 bool compare(const SXPeak &lhs, const SXPeak &rhs) const override;
251
252private:
253 const double m_xUnitResolution;
257};
258
259/* ------------------------------------------------------------------------------------------
260 * PeakListReduction Strategy
261 * ------------------------------------------------------------------------------------------
262 */
263class MANTID_CRYSTAL_DLL ReducePeakListStrategy {
264public:
265 ReducePeakListStrategy(const CompareStrategy *compareStrategy);
266 virtual ~ReducePeakListStrategy() = default;
267 virtual std::vector<SXPeak> reduce(const std::vector<SXPeak> &peaks,
268 Mantid::Kernel::ProgressBase &progress) const = 0;
269
270 void setMinNSpectraPerPeak(int minSpectrasForPeak);
271 void setMaxNSpectraPerPeak(int maxSpectrasForPeak);
272
273protected:
275 int m_minNSpectraPerPeak = EMPTY_INT();
276 int m_maxNSpectraPerPeak = EMPTY_INT();
277};
278
279class MANTID_CRYSTAL_DLL SimpleReduceStrategy : public ReducePeakListStrategy {
280public:
281 SimpleReduceStrategy(const CompareStrategy *compareStrategy);
282 std::vector<SXPeak> reduce(const std::vector<SXPeak> &peaks, Mantid::Kernel::ProgressBase &progress) const override;
283
284private:
285 void reducePeaksFromNumberOfSpectras(std::vector<SXPeak> &inputPeaks) const;
286};
287
288class MANTID_CRYSTAL_DLL FindMaxReduceStrategy : public ReducePeakListStrategy {
289public:
290 FindMaxReduceStrategy(const CompareStrategy *compareStrategy);
291 std::vector<SXPeak> reduce(const std::vector<SXPeak> &peaks, Mantid::Kernel::ProgressBase &progress) const override;
292
293private:
294 std::vector<std::vector<SXPeak *>> getPeakGroups(const std::vector<SXPeak> &peakList,
295 Mantid::Kernel::ProgressBase &progress) const;
296 std::vector<SXPeak> getFinalPeaks(const std::vector<std::vector<SXPeak *>> &peakGroups) const;
297};
298
299} // namespace FindSXPeaksHelper
300} // namespace Crystal
301} // namespace Mantid
const std::vector< double > & rhs
double intensity
double background
double tolerance
API::SpectrumInfo is an intermediate step towards a SpectrumInfo that is part of Instrument-2....
virtual bool compare(const SXPeak &lhs, const SXPeak &rhs) const =0
virtual PeakList dofindSXPeaks(const HistogramData::HistogramX &x, const HistogramData::HistogramY &y, const HistogramData::HistogramE &e, Bound low, Bound high, const int workspaceIndex) const =0
virtual std::vector< SXPeak > reduce(const std::vector< SXPeak > &peaks, Mantid::Kernel::ProgressBase &progress) const =0
Class for 3D vectors.
Definition V3D.h:35
MatrixWorkspace_sptr MANTID_API_DLL operator+=(const MatrixWorkspace_sptr &lhs, const MatrixWorkspace_sptr &rhs)
Adds two workspaces.
Mantid::HistogramData::HistogramY::const_iterator yIt
HistogramData::HistogramX::const_iterator Bound
XAxisUnit
enum to determine the units of the workspaces X axis we are searching in
std::optional< std::vector< SXPeak > > PeakList
std::pair< Bound, Bound > BoundsIterator
bool compare(const mypair &left, const mypair &right)
Helper class which provides the Collimation Length for SANS instruments.
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
Definition EmptyValues.h:24
int32_t detid_t
Typedef for a detector ID.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition EmptyValues.h:42
virtual bool isBelowBackground(const double intensity, const HistogramData::HistogramY &y) const =0
friend std::ostream & operator<<(std::ostream &os, const SXPeak &rhs)
int m_nPixels
Number of contributing pixels.
double m_phi
Phi angle for the centre detector of the peak.
std::vector< int > m_spectra
Contributing spectra to this peak.
Kernel::V3D m_unitWaveVector
Unit vector in the direction of the wavevector.
double m_LTotal
Detector-sample distance.
double m_intensity
Measured intensity of centre of the peak.
double m_dSpacing
d-spacing at the peak centre
double m_twoTheta
2 * theta angle for then centre detector of the peak
size_t m_wsIndex
Detector workspace index.