13#include "MantidIndexing/IndexInfo.h"
39using namespace Kernel;
44 :
API::
Algorithm(), m_MinRange(DBL_MAX), m_MaxRange(-DBL_MAX), m_MinWsIndex(0), m_MaxWsIndex(0) {}
50 auto wsValidation = std::make_shared<CompositeValidator>();
53 auto unitValidation = std::make_shared<CompositeValidator>(CompositeRelation::OR);
57 wsValidation->add(unitValidation);
60 "The name of the Workspace2D to take as input");
63 auto mustBePositive = std::make_shared<BoundedValidator<int>>();
64 mustBePositive->setLower(0);
65 declareProperty(
"StartWorkspaceIndex", 0, mustBePositive,
"Start workspace index (default 0)");
67 "End workspace index (default to total number of histograms)");
72 auto mustBePositiveDouble = std::make_shared<BoundedValidator<double>>();
73 mustBePositiveDouble->setLower(0.0);
77 std::make_shared<StringListValidator>(peakFindingStrategy),
78 "Different options for peak finding."
79 "1. StrongestPeakOnly: Looks only for the strongest peak in each "
80 "spectrum (provided there is "
81 "one). This options is more performant than the AllPeaks option.\n"
82 "2. AllPeaks: This strategy will find all peaks in each "
83 "spectrum. This is slower than StrongestPeakOnly. Note that the "
84 "recommended ResolutionStrategy in this mode is AbsoluteResolution.\n"
85 "3. AllPeaksNSigma: This stratergy will look for peaks by bins that are"
86 " more than nsigma different in intensity. Note that the "
87 "recommended ResolutionStrategy in this mode is AbsoluteResolution.\n");
91 "Multiplication factor for the signal background. Peaks which are"
92 " below the estimated background are discarded. The background is "
94 " to be an average of the first and the last signal and multiplied"
95 " by the SignalBackground property.\n");
98 "Peaks which are below the specified absolute background are discarded."
99 " The background is gloabally specified for all spectra. Inspect your "
100 "data in the InstrumentView to get a good feeling for the background "
102 "Background thresholds which are too low will mistake noise for peaks.");
105 "NSigma", 5.0, mustBePositiveDouble,
106 "Multiplication factor on error used to compare the difference in intensity between consecutive bins.");
114 std::make_unique<EnabledWhenProperty>(
122 const std::string peakGroup =
"Peak Finding Settings";
134 std::make_shared<StringListValidator>(resolutionStrategy),
135 "Different options for the resolution."
136 "1. RelativeResolution: This defines a relative tolerance "
137 "needed to avoid peak duplication in number of pixels. "
138 "This selection will enable the Resolution property and "
139 "disable the XResolution, PhiResolution, ThetaResolution.\n"
140 "1. AbsoluteResolution: This defines an absolute tolerance "
141 "needed to avoid peak duplication in number of pixels. "
142 "This selection will disable the Resolution property and "
143 "enable the XResolution, PhiResolution, "
144 "ThetaResolution.\n");
147 "Tolerance needed to avoid peak duplication in number of pixels");
150 "Absolute tolerance in time-of-flight or d-spacing needed to avoid peak "
151 "duplication in number of pixels. The values are specified "
152 "in either microseconds or angstroms.");
155 "Absolute tolerance in the phi "
156 "coordinate needed to avoid peak "
157 "duplication in number of pixels. The "
158 "values are specified in degrees.");
161 "Absolute tolerance of two theta value needed to avoid peak "
162 "duplication in number of pixels. The values are specified "
183 const std::string resolutionGroup =
"Resolution Settings";
192 "Minimum number of bins contributing to a peak in an individual spectrum");
195 "Minimum number of spectra contributing to a peak after they are grouped");
198 "Maximum number of spectra contributing to a peak after they are grouped");
201 const std::string peakValidationGroup =
"Peak Validation Settings";
207 "The name of the PeaksWorkspace in which to store the list "
221 std::map<std::string, std::string> validationOutput;
222 const std::string resolutionStrategy =
getProperty(
"ResolutionStrategy");
228 validationOutput[
"XResolution"] =
"XResolution must be set to a value greater than 0";
231 const int minNSpectraPerPeak =
getProperty(
"MinNSpectraPerPeak");
232 const int maxNSpectraPerPeak =
getProperty(
"MaxNSpectraPerPeak");
233 if (!
isEmpty(minNSpectraPerPeak) && !
isEmpty(maxNSpectraPerPeak)) {
234 if (maxNSpectraPerPeak < minNSpectraPerPeak) {
235 validationOutput[
"MaxNSpectraPerPeak"] =
"MaxNSpectraPerPeak must be greater than MinNSpectraPerPeak";
236 validationOutput[
"MinNSpectraPerPeak"] =
"MinNSpectraPerPeak must be lower than MaxNSpectraPerPeak";
241 if (inputWorkspace) {
242 const int minWsIndex =
getProperty(
"StartWorkspaceIndex");
243 const int maxWsIndex =
getProperty(
"EndWorkspaceIndex");
244 size_t numberOfSpectraToConsider =
245 !
isEmpty(minWsIndex) ? (!
isEmpty(maxWsIndex) ? (maxWsIndex - minWsIndex + 1)
246 : (inputWorkspace->getNumberHistograms() - minWsIndex))
247 : (!
isEmpty(maxWsIndex) ? (maxWsIndex + 1) : (inputWorkspace->getNumberHistograms()));
249 if (!
isEmpty(minNSpectraPerPeak)) {
250 if (
static_cast<int>(numberOfSpectraToConsider) < minNSpectraPerPeak) {
251 validationOutput[
"MinNSpectraPerPeak"] =
252 "MinNSpectraPerPeak must be less than the number of spectrums considered in InputWorkspace";
256 if (!
isEmpty(maxNSpectraPerPeak)) {
257 if (
static_cast<int>(numberOfSpectraToConsider) < maxNSpectraPerPeak) {
258 validationOutput[
"MaxNSpectraPerPeak"] =
259 "MaxNSpectraPerPeak must be less than the number of spectrums considered in InputWorkspace";
263 const int minNBinsPerPeak =
getProperty(
"MinNBinsPerPeak");
264 if (!
isEmpty(minNBinsPerPeak)) {
265 if (minNBinsPerPeak >
static_cast<int>(inputWorkspace->getMaxNumberBins())) {
266 validationOutput[
"MinNBinsPerPeak"] =
267 "MinNBinsPerPeak must be less than the number of bins in the InputWorkspace";
272 return validationOutput;
293 m_peaks->setInstrument(localworkspace->getInstrument());
295 size_t numberOfSpectra = localworkspace->getNumberHistograms();
303 throw std::invalid_argument(
"Cannot have StartWorkspaceIndex > EndWorkspaceIndex");
308 g_log.
warning(
"EndSpectrum out of range! Set to max detector number");
312 g_log.
warning(
"Range_upper is less than Range_lower. Will integrate up to "
320 const auto &spectrumInfo = localworkspace->spectrumInfo();
327 auto peakFindingStrategy =
330 const int minNBinsPerPeak =
getProperty(
"MinNBinsPerPeak");
331 if (!
isEmpty(minNBinsPerPeak)) {
332 peakFindingStrategy->setMinNBinsPerPeak(minNBinsPerPeak);
344 const auto wsIndexSize_t =
static_cast<size_t>(wsIndex);
345 if (!spectrumInfo.hasDetectors(wsIndexSize_t) || spectrumInfo.isMonitor(wsIndexSize_t)) {
350 const auto &
x = localworkspace->x(wsIndex);
351 const auto &
y = localworkspace->y(wsIndex);
352 const auto &e = localworkspace->e(wsIndex);
355 auto foundPeaks = peakFindingStrategy->findSXPeaks(
x,
y, e, wsIndex);
360 PARALLEL_CRITICAL(entries) { std::copy(foundPeaks->cbegin(), foundPeaks->cend(), std::back_inserter(entries)); }
381 auto &goniometerMatrix = localworkspace->run().getGoniometer().getR();
385 const int minNSpectraPerPeak =
getProperty(
"MinNSpectraPerPeak");
386 if (!
isEmpty(minNSpectraPerPeak)) {
387 reductionStrategy->setMinNSpectraPerPeak(minNSpectraPerPeak);
390 const int maxNSpectraPerPeak =
getProperty(
"MaxNSpectraPerPeak");
391 if (!
isEmpty(maxNSpectraPerPeak)) {
392 reductionStrategy->setMaxNSpectraPerPeak(maxNSpectraPerPeak);
395 auto finalv = reductionStrategy->reduce(pcv,
progress);
397 for (
auto &finalPeak : finalv) {
403 peak->setIntensity(finalPeak.getIntensity());
404 peak->setDetectorID(finalPeak.getDetectorId());
405 peak->setGoniometerMatrix(goniometerMatrix);
406 peak->setRunNumber(localworkspace->getRunNumber());
409 }
catch (std::exception &e) {
424 const auto xAxis =
workspace->getAxis(0);
425 const auto unitID = xAxis->unit()->unitID();
427 if (unitID ==
"TOF") {
428 return XAxisUnit::TOF;
430 return XAxisUnit::DSPACING;
435 const std::string peakFindingStrategy =
getProperty(
"PeakFindingStrategy");
437 const double signalBackground =
getProperty(
"SignalBackground");
438 return std::make_unique<PerSpectrumBackgroundStrategy>(signalBackground);
440 const double background =
getProperty(
"AbsoluteBackground");
441 return std::make_unique<AbsoluteBackgroundStrategy>(background);
445 throw std::invalid_argument(
"The selected background strategy has not been implemented yet.");
449std::unique_ptr<FindSXPeaksHelper::PeakFindingStrategy>
451 const double minValue,
const double maxValue,
const XAxisUnit tofUnits)
const {
453 std::string peakFindingStrategy =
getProperty(
"PeakFindingStrategy");
455 return std::make_unique<StrongestPeaksStrategy>(backgroundStrategy, spectrumInfo, minValue, maxValue, tofUnits);
457 return std::make_unique<AllPeaksStrategy>(backgroundStrategy, spectrumInfo, minValue, maxValue, tofUnits);
460 return std::make_unique<NSigmaPeaksStrategy>(spectrumInfo, nsigma, minValue, maxValue, tofUnits);
462 throw std::invalid_argument(
"The selected peak finding strategy has not been implemented yet.");
466std::unique_ptr<FindSXPeaksHelper::ReducePeakListStrategy>
468 const std::string peakFindingStrategy =
getProperty(
"PeakFindingStrategy");
470 if (useSimpleReduceStrategy) {
471 return std::make_unique<FindSXPeaksHelper::SimpleReduceStrategy>(compareStrategy);
473 return std::make_unique<FindSXPeaksHelper::FindMaxReduceStrategy>(compareStrategy);
478 const std::string resolutionStrategy =
getProperty(
"ResolutionStrategy");
480 if (useRelativeResolutionStrategy) {
482 return std::make_unique<FindSXPeaksHelper::RelativeCompareStrategy>(resolution);
484 double xUnitResolution =
getProperty(
"XResolution");
485 double phiResolution =
getProperty(
"PhiResolution");
486 double twoThetaResolution =
getProperty(
"TwoThetaResolution");
488 return std::make_unique<FindSXPeaksHelper::AbsoluteCompareStrategy>(xUnitResolution, phiResolution,
489 twoThetaResolution, tofUnits);
#define DECLARE_ALGORITHM(classname)
IPeaksWorkspace_sptr workspace
#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...
#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.
Base class from which all concrete algorithm classes should be derived.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Kernel::Property * getPointerToProperty(const std::string &name) const override
Get a property by name.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
A validator which checks that a workspace contains histogram data (the default) or point data as requ...
Helper class for reporting progress from algorithms.
API::SpectrumInfo is an intermediate step towards a SpectrumInfo that is part of Instrument-2....
A property class for workspaces.
A validator which checks that the unit of the workspace referred to by a WorkspaceProperty is the exp...
BackgroundStrategy : Abstract class used for identifying elements of a IMDWorkspace that are not cons...
Search detector space for single crystal peaks.
FindSXPeaksHelper::XAxisUnit getWorkspaceXAxisUnit(const Mantid::API::MatrixWorkspace_const_sptr &workspace) const
Check what x units this workspace has.
static const std::string absoluteResolutionPeaksStrategy
static const std::string allPeaksNSigmaStrategy
Mantid::DataObjects::PeaksWorkspace_sptr m_peaks
size_t m_MaxWsIndex
The spectrum to finish the integration at.
void exec() override
Executes the algorithm.
std::unique_ptr< FindSXPeaksHelper::BackgroundStrategy > getBackgroundStrategy() const
Selects a background strategy.
FindSXPeaks()
Default constructor.
std::unique_ptr< FindSXPeaksHelper::CompareStrategy > getCompareStrategy() const
Selects a comparison strategy.
std::map< std::string, std::string > validateInputs() override
Perform validation of ALL the input properties of the algorithm.
double m_MinRange
The value in X to start the search from.
double m_MaxRange
The value in X to finish the search at.
static const std::string strongestPeakStrategy
static const std::string relativeResolutionStrategy
static const std::string allPeaksStrategy
void init() override
Initialisation method.
void reducePeakList(const peakvector &, Mantid::API::Progress &progress)
Reduce the peak list by removing duplicates then convert SXPeaks objects to PeakObjects and add them ...
size_t m_MinWsIndex
The spectrum to start the integration from.
std::unique_ptr< FindSXPeaksHelper::PeakFindingStrategy > getPeakFindingStrategy(const FindSXPeaksHelper::BackgroundStrategy *backgroundStrategy, const API::SpectrumInfo &spectrumInfo, const double minValue, const double maxValue, const FindSXPeaksHelper::XAxisUnit tofUnits=FindSXPeaksHelper::XAxisUnit::TOF) const
Selects a peak finding strategy.
std::unique_ptr< FindSXPeaksHelper::ReducePeakListStrategy > getReducePeakListStrategy(const FindSXPeaksHelper::CompareStrategy *compareStrategy) const
Selects a peak finding strategy.
Structure describing a single-crystal peak.
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 setPropertySettings(const std::string &name, std::unique_ptr< IPropertySettings > settings)
void setPropertyGroup(const std::string &name, const std::string &group)
Set the group for a given property.
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
XAxisUnit
enum to determine the units of the workspaces X axis we are searching in
std::vector< FindSXPeaksHelper::SXPeak > peakvector
std::unique_ptr< Peak > Peak_uptr
std::unique_ptr< IPeak > IPeak_uptr
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.
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
@ Input
An input workspace.
@ Output
An output workspace.