Mantid
Loading...
Searching...
No Matches
FilterPeaks.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 +
14
16
17namespace {
18
19// Filter functions
20double intensity(const Mantid::Geometry::IPeak &p) { return p.getIntensity(); }
21
22double wavelength(const Mantid::Geometry::IPeak &p) { return p.getWavelength(); }
23
24double dspacing(const Mantid::Geometry::IPeak &p) { return p.getDSpacing(); }
25
26double tof(const Mantid::Geometry::IPeak &p) { return p.getTOF(); }
27
28double HKLSum(const Mantid::Geometry::IPeak &p) { return p.getH() + p.getK() + p.getL(); }
29
30double HKL2(const Mantid::Geometry::IPeak &p) { return p.getIntHKL().norm2(); }
31
32double MNP2(const Mantid::Geometry::IPeak &p) { return p.getIntMNP().norm2(); }
33
34double QMOD(const Mantid::Geometry::IPeak &p) { return p.getQSampleFrame().norm(); }
35
36double SN(const Mantid::Geometry::IPeak &p) {
37 return (p.getSigmaIntensity() > 0) ? (p.getIntensity() / p.getSigmaIntensity()) : (0.0);
38}
39
40double RUN(const Mantid::Geometry::IPeak &p) { return p.getRunNumber(); }
41
42std::string BANKNAME(const Mantid::Geometry::IPeak &p) {
43 const Peak &fullPeak = dynamic_cast<const Peak &>(p);
44 return fullPeak.getBankName();
45}
46
47} // namespace
48
49// namespace
50namespace Mantid::Crystal {
51// Register the algorithm into the AlgorithmFactory
52DECLARE_ALGORITHM(FilterPeaks)
53
54using namespace Kernel;
55using namespace API;
56using API::IPeaksWorkspace;
59
61const std::string FilterPeaks::name() const { return "FilterPeaks"; }
63int FilterPeaks::version() const { return 1; }
65const std::string FilterPeaks::category() const { return "Crystal\\Peaks"; }
66
70 declareProperty(std::make_unique<WorkspaceProperty<IPeaksWorkspace>>("InputWorkspace", "", Direction::Input),
71 "The input workspace");
72 declareProperty(std::make_unique<WorkspaceProperty<IPeaksWorkspace>>("OutputWorkspace", "", Direction::Output),
73 "The filtered workspace");
74
75 // filter by property
76 const std::string FILTER("Filter Options");
77 std::vector<std::string> filters{"h+k+l", "h^2+k^2+l^2", "m^2+n^2+p^2", "Intensity", "Signal/Noise",
78 "QMod", "Wavelength", "DSpacing", "TOF", "RunNumber"};
79 declareProperty("FilterVariable", "h+k+l", std::make_shared<StringListValidator>(filters),
80 "The variable on which to filter the peaks");
81
82 declareProperty("FilterValue", EMPTY_DBL(), "The value of the FilterVariable to compare each peak to");
83
84 std::vector<std::string> operation{"<", ">", "=", "!=", "<=", ">="};
85 declareProperty("Operator", "<", std::make_shared<StringListValidator>(operation), "");
86 setPropertyGroup("FilterVariable", FILTER);
87 setPropertyGroup("FilterValue", FILTER);
88 setPropertyGroup("Operator", FILTER);
89
90 // select by bankname
91 const std::string SELECT("Select Bank by Name");
92 std::vector<std::string> action{"=", "!="};
93 declareProperty("Criterion", "=", std::make_shared<StringListValidator>(action), "");
94 declareProperty("BankName", "", "Selected bank name, empty means skip selection. Applicable only to PeaksWorkspace");
95 setPropertyGroup("Criterion", SELECT);
96 setPropertyGroup("BankName", SELECT);
97}
98
102 IPeaksWorkspace_const_sptr inputWS = getProperty("InputWorkspace");
103 IPeaksWorkspace_sptr filteredWS =
104 std::dynamic_pointer_cast<IPeaksWorkspace>(WorkspaceFactory::Instance().createPeaks(inputWS->id()));
105
106 // Copy over ExperimentInfo from input workspace
107 filteredWS->copyExperimentInfoFrom(inputWS.get());
108
109 const double filterValue = getProperty("FilterValue");
110 const std::string Operator = getProperty("Operator");
111 const std::string filterVariable = getProperty("FilterVariable");
112
113 const std::string bankname = getProperty("BankName");
114 const std::string criterion = getProperty("Criterion");
115
116 if (!bankname.empty() && (inputWS->id() == "PeaksWorkspace")) {
117 FilterFunctionStr filterFunction = &BANKNAME;
118 IPeaksWorkspace_sptr selectedWS = filteredWS->clone();
119
120 if (criterion == "=")
121 filterPeaksStr<std::equal_to<std::string>>(*inputWS, *selectedWS, filterFunction, bankname);
122 else if (criterion == "!=")
123 filterPeaksStr<std::not_equal_to<std::string>>(*inputWS, *selectedWS, filterFunction, bankname);
124 else
125 throw std::invalid_argument("Unsupported operator " + criterion + " for BankName filter");
126
127 inputWS = selectedWS;
128 setProperty("OutputWorkspace", selectedWS);
129 }
130
131 if (!isDefault("FilterValue")) {
132 const auto filterFunction = getFilterVariableFunction(filterVariable);
133 // Choose which version of the function to u.se based on the operator
134 if (Operator == "<")
135 filterPeaks<std::less<double>>(*inputWS, *filteredWS, filterFunction, filterValue);
136 else if (Operator == ">")
137 filterPeaks<std::greater<double>>(*inputWS, *filteredWS, filterFunction, filterValue);
138 else if (Operator == "=")
139 filterPeaks<std::equal_to<double>>(*inputWS, *filteredWS, filterFunction, filterValue);
140 else if (Operator == "!=")
141 filterPeaks<std::not_equal_to<double>>(*inputWS, *filteredWS, filterFunction, filterValue);
142 else if (Operator == "<=")
143 filterPeaks<std::less_equal<double>>(*inputWS, *filteredWS, filterFunction, filterValue);
144 else if (Operator == ">=")
145 filterPeaks<std::greater_equal<double>>(*inputWS, *filteredWS, filterFunction, filterValue);
146 else
147 throw std::invalid_argument("Unknown Operator " + Operator);
148
149 setProperty("OutputWorkspace", filteredWS);
150 }
151}
152
164 FilterFunction filterFunction;
165 if (filterVariable == "h+k+l")
166 filterFunction = &HKLSum;
167 else if (filterVariable == "h^2+k^2+l^2")
168 filterFunction = &HKL2;
169 else if (filterVariable == "m^2+n^2+p^2")
170 filterFunction = &MNP2;
171 else if (filterVariable == "Intensity")
172 filterFunction = &intensity;
173 else if (filterVariable == "Wavelength")
174 filterFunction = &wavelength;
175 else if (filterVariable == "DSpacing")
176 filterFunction = &dspacing;
177 else if (filterVariable == "TOF")
178 filterFunction = &tof;
179 else if (filterVariable == "Signal/Noise")
180 filterFunction = &SN;
181 else if (filterVariable == "QMod")
182 filterFunction = &QMOD;
183 else if (filterVariable == "RunNumber")
184 filterFunction = &RUN;
185 else
186 throw std::invalid_argument("Unknown FilterVariable: " + filterVariable);
187 return filterFunction;
188}
189
190} // namespace Mantid::Crystal
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
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.
bool isDefault(const std::string &name) const
A property class for workspaces.
void init() override
Override for algorithm init.
const std::string name() const override
Algorithm's name for identification.
FilterFunction getFilterVariableFunction(const std::string &filterVariable) const
Get a function to filter peaks by.
void exec() override
Override for algorithm exec.
const std::string category() const override
Algorithm's category for identification.
std::function< double(const Geometry::IPeak &)> FilterFunction
Typedef for the function to get the variable we're filtering against.
Definition FilterPeaks.h:34
std::function< std::string(const Geometry::IPeak &)> FilterFunctionStr
Definition FilterPeaks.h:35
int version() const override
Algorithm's version for identification.
Structure describing a single-crystal peak.
Definition Peak.h:34
const std::string & getBankName() const
Find the name of the bank that is the parent of the detector.
Definition Peak.cpp:347
Structure describing a single-crystal peak.
Definition IPeak.h:26
virtual double getH() const =0
virtual double getTOF() const =0
virtual double getSigmaIntensity() const =0
virtual double getWavelength() const =0
virtual double getDSpacing() const =0
virtual Mantid::Kernel::V3D getIntHKL() const =0
virtual double getK() const =0
virtual int getRunNumber() const =0
virtual Mantid::Kernel::V3D getQSampleFrame() const =0
virtual double getIntensity() const =0
virtual double getL() const =0
virtual Mantid::Kernel::V3D getIntMNP() const =0
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void setPropertyGroup(const std::string &name, const std::string &group)
Set the group for a given property.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
double norm() const noexcept
Definition V3D.h:269
constexpr double norm2() const noexcept
Vector length squared.
Definition V3D.h:271
std::shared_ptr< IPeaksWorkspace > IPeaksWorkspace_sptr
shared pointer to Mantid::API::IPeaksWorkspace
std::shared_ptr< const IPeaksWorkspace > IPeaksWorkspace_const_sptr
shared pointer to Mantid::API::IPeaksWorkspace (const version)
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition EmptyValues.h:42
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54