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#include "MantidKernel/Unit.h"
16
17#include <iterator>
18#include <optional>
19#include <vector>
20
21namespace Mantid {
22namespace Kernel {
23class ProgressBase;
24}
25} // namespace Mantid
26
27namespace Mantid {
28namespace Crystal {
29namespace FindSXPeaksHelper {
30
32enum class XAxisUnit { TOF, DSPACING };
33
34/* ------------------------------------------------------------------------------------------
35 * Single Crystal peak representation
36 * ------------------------------------------------------------------------------------------
37 */
38struct MANTID_CRYSTAL_DLL SXPeak {
39public:
40 SXPeak(double t, double phi, double intensity, const std::vector<int> &spectral, const size_t wsIndex,
41 const Mantid::API::SpectrumInfo &spectrumInfo);
42
45 bool compare(const SXPeak &rhs, double tolerance) const;
46
49 bool compare(const SXPeak &rhs, const double xTolerance, const double phiTolerance, const double thetaTolerance,
50 const XAxisUnit tofUnits = XAxisUnit::TOF) const;
51
53 Mantid::Kernel::V3D getQ() const;
54
56 SXPeak &operator+=(const SXPeak &rhs);
57
59 void reduce();
60
61 friend std::ostream &operator<<(std::ostream &os, const SXPeak &rhs) {
62 os << rhs.m_tof << "," << rhs.m_twoTheta << "," << rhs.m_phi << "," << rhs.m_intensity << "\n";
63 os << " Spectra";
64 std::copy(rhs.m_spectra.begin(), rhs.m_spectra.end(), std::ostream_iterator<int>(os, ","));
65 return os;
66 }
67
68 const double &getIntensity() const;
69
70 detid_t getDetectorId() const;
71
72 const std::vector<int> &getPeakSpectras() const;
73
74private:
76 double m_tof;
78 double m_dSpacing;
80 double m_twoTheta;
82 double m_phi;
86 std::vector<int> m_spectra;
88 double m_LTotal;
90 size_t m_wsIndex;
98 std::string m_qConvention;
99};
100
101using yIt = Mantid::HistogramData::HistogramY::const_iterator;
102using Bound = HistogramData::HistogramX::const_iterator;
103using BoundsIterator = std::pair<Bound, Bound>;
104using PeakList = std::optional<std::vector<SXPeak>>;
105
107public:
108 PeakContainer(const HistogramData::HistogramY &y);
109 void startRecord(yIt item);
110 void stopRecord(yIt item);
111 void record(yIt item);
112 size_t getNumberOfPointsInPeak() const;
113 yIt getMaxIterator() const;
114 double getStartingSignal() const;
115
116private:
117 const HistogramData::HistogramY &m_y;
121 double m_maxSignal = -1.;
122};
123
124/* ------------------------------------------------------------------------------------------
125 * Background strategy
126 * ------------------------------------------------------------------------------------------
127 */
128struct MANTID_CRYSTAL_DLL BackgroundStrategy {
129 virtual ~BackgroundStrategy() = default;
130 virtual bool isBelowBackground(const double intensity, const HistogramData::HistogramY &y) const = 0;
131};
132
133struct MANTID_CRYSTAL_DLL AbsoluteBackgroundStrategy : public BackgroundStrategy {
134 AbsoluteBackgroundStrategy(const double background);
135 bool isBelowBackground(const double intensity, const HistogramData::HistogramY &) const override;
136
137private:
138 double m_background = 0.;
139};
140
141struct MANTID_CRYSTAL_DLL PerSpectrumBackgroundStrategy : public BackgroundStrategy {
142 PerSpectrumBackgroundStrategy(const double backgroundMultiplier);
143 bool isBelowBackground(const double intensity, const HistogramData::HistogramY &y) const override;
144
145private:
146 double m_backgroundMultiplier = 1.;
147};
148
149/* ------------------------------------------------------------------------------------------
150 * Peak Finding Strategy
151 * ------------------------------------------------------------------------------------------
152 */
153class MANTID_CRYSTAL_DLL PeakFindingStrategy {
154public:
155 PeakFindingStrategy(const BackgroundStrategy *backgroundStrategy, const API::SpectrumInfo &spectrumInfo,
156 const double minValue = EMPTY_DBL(), const double maxValue = EMPTY_DBL(),
157 const XAxisUnit units = XAxisUnit::TOF);
158 virtual ~PeakFindingStrategy() = default;
159 PeakList findSXPeaks(const HistogramData::HistogramX &x, const HistogramData::HistogramY &y,
160 const HistogramData::HistogramE &e, const int workspaceIndex) const;
161 void setMinNBinsPerPeak(int minBinsPerPeak);
162
163protected:
164 void filterPeaksForMinBins(std::vector<std::unique_ptr<PeakContainer>> &inputPeakList) const;
165
166 BoundsIterator getBounds(const HistogramData::HistogramX &x) const;
167 double calculatePhi(size_t workspaceIndex) const;
168 double getXValue(const HistogramData::HistogramX &x, const size_t peakLocation) const;
169 double convertToTOF(const double xValue, const size_t workspaceIndex) const;
170 virtual PeakList dofindSXPeaks(const HistogramData::HistogramX &x, const HistogramData::HistogramY &y,
171 const HistogramData::HistogramE &e, Bound low, Bound high,
172 const int workspaceIndex) const = 0;
173 PeakList convertToSXPeaks(const HistogramData::HistogramX &x, const HistogramData::HistogramY &y,
174 const std::vector<std::unique_ptr<PeakContainer>> &peaks, const int workspaceIndex) const;
175
177 const double m_minValue = EMPTY_DBL();
178 const double m_maxValue = EMPTY_DBL();
181 int m_minNBinsPerPeak = EMPTY_INT();
182};
183
184class MANTID_CRYSTAL_DLL StrongestPeaksStrategy : public PeakFindingStrategy {
185public:
186 StrongestPeaksStrategy(const BackgroundStrategy *backgroundStrategy, const API::SpectrumInfo &spectrumInfo,
187 const double minValue = EMPTY_DBL(), const double maxValue = EMPTY_DBL(),
188 const XAxisUnit units = XAxisUnit::TOF);
189 PeakList dofindSXPeaks(const HistogramData::HistogramX &x, const HistogramData::HistogramY &y,
190 [[maybe_unused]] const HistogramData::HistogramE &e, Bound low, Bound high,
191 const int workspaceIndex) const override;
192};
193
194class MANTID_CRYSTAL_DLL AllPeaksStrategy : public PeakFindingStrategy {
195public:
196 AllPeaksStrategy(const BackgroundStrategy *backgroundStrategy, const API::SpectrumInfo &spectrumInfo,
197 const double minValue = EMPTY_DBL(), const double maxValue = EMPTY_DBL(),
198 const XAxisUnit units = XAxisUnit::TOF);
199 PeakList dofindSXPeaks(const HistogramData::HistogramX &x, const HistogramData::HistogramY &y,
200 [[maybe_unused]] const HistogramData::HistogramE &e, Bound low, Bound high,
201 const int workspaceIndex) const override;
202
203private:
204 std::vector<std::unique_ptr<PeakContainer>>
205 getAllPeaks(const HistogramData::HistogramX &x, const HistogramData::HistogramY &y, Bound low, Bound high,
206 const Mantid::Crystal::FindSXPeaksHelper::BackgroundStrategy *backgroundStrategy) const;
207};
208
209#define NSIGMA_COMPARISON_THRESHOLD 1e-10
210
211class MANTID_CRYSTAL_DLL NSigmaPeaksStrategy : public PeakFindingStrategy {
212public:
213 NSigmaPeaksStrategy(const API::SpectrumInfo &spectrumInfo, const double nsigma = EMPTY_DBL(),
214 const double minValue = EMPTY_DBL(), const double maxValue = EMPTY_DBL(),
215 const XAxisUnit units = XAxisUnit::TOF);
216 PeakList dofindSXPeaks(const HistogramData::HistogramX &x, const HistogramData::HistogramY &y,
217 const HistogramData::HistogramE &e, Bound low, Bound high,
218 const int workspaceIndex) const override;
219
220private:
221 std::vector<std::unique_ptr<PeakContainer>> getAllNSigmaPeaks(const HistogramData::HistogramX &x,
222 const HistogramData::HistogramY &y,
223 const HistogramData::HistogramE &e, Bound low,
224 Bound high) const;
225 const double m_nsigma;
226};
227
228/* ------------------------------------------------------------------------------------------
229 * Comparison Strategy
230 * ------------------------------------------------------------------------------------------
231 */
232class MANTID_CRYSTAL_DLL CompareStrategy {
233public:
234 virtual ~CompareStrategy() = default;
235 virtual bool compare(const SXPeak &lhs, const SXPeak &rhs) const = 0;
236};
237
238class MANTID_CRYSTAL_DLL RelativeCompareStrategy : public CompareStrategy {
239public:
240 RelativeCompareStrategy(const double resolution);
241 bool compare(const SXPeak &lhs, const SXPeak &rhs) const override;
242
243private:
244 const double m_resolution;
245};
246
247class MANTID_CRYSTAL_DLL AbsoluteCompareStrategy : public CompareStrategy {
248public:
249 AbsoluteCompareStrategy(const double tofResolution, const double phiResolution, const double twoThetaResolution,
250 const XAxisUnit units = XAxisUnit::TOF);
251 bool compare(const SXPeak &lhs, const SXPeak &rhs) const override;
252
253private:
254 const double m_xUnitResolution;
258};
259
260/* ------------------------------------------------------------------------------------------
261 * PeakListReduction Strategy
262 * ------------------------------------------------------------------------------------------
263 */
264class MANTID_CRYSTAL_DLL ReducePeakListStrategy {
265public:
266 ReducePeakListStrategy(const CompareStrategy *compareStrategy);
267 virtual ~ReducePeakListStrategy() = default;
268 virtual std::vector<SXPeak> reduce(const std::vector<SXPeak> &peaks,
269 Mantid::Kernel::ProgressBase &progress) const = 0;
270
271 void setMinNSpectraPerPeak(int minSpectrasForPeak);
272 void setMaxNSpectraPerPeak(int maxSpectrasForPeak);
273
274protected:
276 int m_minNSpectraPerPeak = EMPTY_INT();
277 int m_maxNSpectraPerPeak = EMPTY_INT();
278};
279
280class MANTID_CRYSTAL_DLL SimpleReduceStrategy : public ReducePeakListStrategy {
281public:
282 SimpleReduceStrategy(const CompareStrategy *compareStrategy);
283 std::vector<SXPeak> reduce(const std::vector<SXPeak> &peaks, Mantid::Kernel::ProgressBase &progress) const override;
284
285private:
286 void reducePeaksFromNumberOfSpectras(std::vector<SXPeak> &inputPeaks) const;
287};
288
289class MANTID_CRYSTAL_DLL FindMaxReduceStrategy : public ReducePeakListStrategy {
290public:
291 FindMaxReduceStrategy(const CompareStrategy *compareStrategy);
292 std::vector<SXPeak> reduce(const std::vector<SXPeak> &peaks, Mantid::Kernel::ProgressBase &progress) const override;
293
294private:
295 std::vector<std::vector<SXPeak *>> getPeakGroups(const std::vector<SXPeak> &peakList,
296 Mantid::Kernel::ProgressBase &progress) const;
297 std::vector<SXPeak> getFinalPeaks(const std::vector<std::vector<SXPeak *>> &peakGroups) const;
298};
299
300} // namespace FindSXPeaksHelper
301} // namespace Crystal
302} // namespace Mantid
const std::vector< double > & rhs
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:34
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.