Mantid
Loading...
Searching...
No Matches
MaskDetectorsIf.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
15#include <fstream>
16#include <iomanip>
17#include <numeric>
18
19namespace Mantid::Algorithms {
20
21// Register the class into the algorithm factory
22DECLARE_ALGORITHM(MaskDetectorsIf)
23
24using namespace Kernel;
25
26// anonymous namespace
27namespace {
31template <class T> struct not_finite {
34
35 constexpr bool operator()(const T &value, const T &ignored) const {
36 UNUSED_ARG(ignored);
37 return !std::isfinite(value);
38 };
39};
40} // namespace
41
45 using namespace Mantid::Kernel;
46 declareProperty(std::make_unique<API::WorkspaceProperty<>>("InputWorkspace", "", Direction::Input),
47 "A 1D Workspace that contains values to select against");
48 const std::vector<std::string> select_mode{"SelectIf", "DeselectIf"};
49 declareProperty("Mode", "SelectIf", std::make_shared<StringListValidator>(select_mode),
50 "Mode to select or deselect detectors based on comparison with values.");
51 const std::vector<std::string> select_operator{"Equal", "NotEqual", "Greater", "GreaterEqual",
52 "Less", "LessEqual", "NotFinite"};
53 declareProperty("Operator", "Equal", std::make_shared<StringListValidator>(select_operator),
54 "Operator to compare to given values.");
55 declareProperty("Value", 0.0);
56 declareProperty(std::make_unique<API::FileProperty>("InputCalFile", "", API::FileProperty::OptionalLoad, ".cal"),
57 "The name of the CalFile with grouping data.");
58 declareProperty(std::make_unique<API::FileProperty>("OutputCalFile", "", API::FileProperty::OptionalSave, ".cal"),
59 "The name of the CalFile with grouping data.");
61 std::make_unique<API::WorkspaceProperty<>>("OutputWorkspace", "", Direction::Output, API::PropertyMode::Optional),
62 "The masked workspace.");
63}
64
69std::map<std::string, std::string> MaskDetectorsIf::validateInputs() {
70 std::map<std::string, std::string> issues;
71 const auto noInputFile = isDefault("InputCalFile");
72 const auto noOutputFile = isDefault("OutputCalFile");
73 if (!noInputFile && noOutputFile) {
74 issues["OutputCalFile"] = "Output file name is missing.";
75 } else if (noInputFile && !noOutputFile) {
76 issues["InputCalFile"] = "Input file name is missing.";
77 }
78 return issues;
79}
80
85
86 if (isDefault("InputCalFile") && isDefault("OutputWorkspace")) {
87 g_log.error() << "No InputCalFle or OutputWorkspace specified; " << this->name() << " will do nothing.\n";
88 return;
89 }
90 const size_t nspec = m_inputW->getNumberHistograms();
91 for (size_t i = 0; i < nspec; ++i) {
92 // Get the list of udets contributing to this spectra
93 const auto &dets = m_inputW->getSpectrum(i).getDetectorIDs();
94
95 if (dets.empty())
96 continue;
97 else {
98 const size_t num_bins = m_inputW->y(i).size();
99 for (size_t j = 0; j < num_bins; ++j) {
100 const double val = m_inputW->y(i)[j];
101 if (m_compar_f(val, m_value)) {
102 for (const auto det : dets) {
103 m_umap.emplace(det, m_select_on);
104 }
105 // stop after the first bin matches the criteria
106 break;
107 }
108 }
109 }
110 const double p = static_cast<double>(i) / static_cast<double>(nspec);
111 progress(p, "Generating detector map");
112 }
113
114 if (!isDefault("InputCalFile")) {
116 }
117 if (!isDefault("OutputWorkspace")) {
119 }
120}
121
126 API::MatrixWorkspace_sptr outputW = getProperty("OutputWorkspace");
127 if (outputW != m_inputW)
128 outputW = m_inputW->clone();
129 auto &detectorInfo = outputW->mutableDetectorInfo();
130 for (const auto &selection : m_umap) {
131 detectorInfo.setMasked(detectorInfo.indexOf(selection.first), selection.second);
132 }
133
134 const auto &spectrumInfo = outputW->spectrumInfo();
135 for (size_t i = 0; i < spectrumInfo.size(); ++i) {
136 if (spectrumInfo.hasDetectors(i) && spectrumInfo.isMasked(i))
137 outputW->getSpectrum(i).clearData();
138 }
139
140 if (const auto *event = dynamic_cast<DataObjects::EventWorkspace *>(outputW.get()))
141 event->clearMRU();
142
143 setProperty("OutputWorkspace", outputW);
144}
149 m_inputW = getProperty("InputWorkspace");
150 m_value = getProperty("Value");
151
152 // Get the selction mode (select if or deselect if)
153 std::string select_mode = getProperty("Mode");
154 if (select_mode == "SelectIf")
155 m_select_on = true;
156 else
157 m_select_on = false;
158
159 // Select function object based on the type of comparison operator
160 std::string select_operator = getProperty("Operator");
161
162 if (select_operator == "LessEqual")
163 m_compar_f = std::less_equal<double>();
164 else if (select_operator == "Less")
165 m_compar_f = std::less<double>();
166 else if (select_operator == "GreaterEqual")
167 m_compar_f = std::greater_equal<double>();
168 else if (select_operator == "Greater")
169 m_compar_f = std::greater<double>();
170 else if (select_operator == "Equal")
171 m_compar_f = std::equal_to<double>();
172 else if (select_operator == "NotEqual")
173 m_compar_f = std::not_equal_to<double>();
174 else if (select_operator == "NotFinite")
175 m_compar_f = not_finite<double>();
176}
177
184 const std::string oldfile = getProperty("InputCalFile");
185 const std::string newfile = getProperty("OutputCalFile");
186 progress(0.99, "Creating new cal file");
187 std::ifstream oldf(oldfile.c_str());
188 if (!oldf.is_open()) {
189 g_log.error() << "Unable to open grouping file " << oldfile << '\n';
190 throw Exception::FileError("Error reading .cal file", oldfile);
191 }
192 std::ofstream newf(newfile.c_str());
193 if (!newf.is_open()) {
194 g_log.error() << "Unable to open grouping file " << newfile << '\n';
195 throw Exception::FileError("Error reading .cal file", newfile);
196 }
197 std::string str;
198 while (getline(oldf, str)) {
199 // Comment or empty lines get copied into the new cal file
200 if (str.empty() || str[0] == '#') {
201 newf << str << '\n';
202 continue;
203 }
204 std::istringstream istr(str);
205 int n, udet, sel, group;
206 double offset;
207 istr >> n >> udet >> offset >> sel >> group;
208 const auto it = m_umap.find(udet);
209 bool selection;
210
211 if (it == m_umap.end())
212 selection = sel != 0;
213 else
214 selection = (*it).second;
215
216 newf << std::fixed << std::setw(9) << n << std::fixed << std::setw(15) << udet << std::fixed << std::setprecision(7)
217 << std::setw(15) << offset << std::fixed << std::setw(8) << selection << std::fixed << std::setw(8) << group
218 << '\n';
219 }
220 oldf.close();
221 newf.close();
222}
223} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
double value
The value of the point.
Definition FitMW.cpp:51
T first_argument_type
T second_argument_type
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition System.h:48
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.
Kernel::Logger & g_log
Definition Algorithm.h:422
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
bool isDefault(const std::string &name) const
@ OptionalSave
to specify a file to write to but an empty string is
@ OptionalLoad
to specify a file to read but the file doesn't have to exist
A property class for workspaces.
const std::string name() const override
Algorithm's name for identification overriding a virtual method.
std::map< std::string, std::string > validateInputs() override
Validates the algorithm's input properties.
boost::function< bool(double, double)> m_compar_f
A comparator function.
void init() override
Initialisation method.
API::MatrixWorkspace_const_sptr m_inputW
The input workspace.
void retrieveProperties()
Get the input properties and store them in the object variables.
void createNewCalFile()
Create a new cal file based on the old file.
bool m_select_on
Whether select is on or off.
void outputToWorkspace()
Create an output workspace masking/unmasking the selected/deselected spectra.
udet2valuem m_umap
A map from detid to selection.
void exec() override
Executes the algorithm.
double m_value
The Value parameter.
This class is intended to fulfill the design specified in <https://github.com/mantidproject/documents...
Records the filename and the description of failure.
Definition Exception.h:98
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void error(const std::string &msg)
Logs at error level.
Definition Logger.cpp:108
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54