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 {
35
36 constexpr bool operator()(const T &value, const T &ignored) const {
37 UNUSED_ARG(ignored);
38 return !std::isfinite(value);
39 };
40};
41} // namespace
42
46 using namespace Mantid::Kernel;
47 declareProperty(std::make_unique<API::WorkspaceProperty<>>("InputWorkspace", "", Direction::Input),
48 "A 1D Workspace that contains values to select against");
49 const std::vector<std::string> select_mode{"SelectIf", "DeselectIf"};
50 declareProperty("Mode", "SelectIf", std::make_shared<StringListValidator>(select_mode),
51 "Mode to select or deselect detectors based on comparison with values.");
52 const std::vector<std::string> select_operator{"Equal", "NotEqual", "Greater", "GreaterEqual",
53 "Less", "LessEqual", "NotFinite"};
54 declareProperty("Operator", "Equal", std::make_shared<StringListValidator>(select_operator),
55 "Operator to compare to given values.");
56 declareProperty("Value", 0.0);
57 declareProperty(std::make_unique<API::FileProperty>("InputCalFile", "", API::FileProperty::OptionalLoad, ".cal"),
58 "The name of the CalFile with grouping data.");
59 declareProperty(std::make_unique<API::FileProperty>("OutputCalFile", "", API::FileProperty::OptionalSave, ".cal"),
60 "The name of the CalFile with grouping data.");
62 std::make_unique<API::WorkspaceProperty<>>("OutputWorkspace", "", Direction::Output, API::PropertyMode::Optional),
63 "The masked workspace.");
64}
65
70std::map<std::string, std::string> MaskDetectorsIf::validateInputs() {
71 std::map<std::string, std::string> issues;
72 const auto noInputFile = isDefault("InputCalFile");
73 const auto noOutputFile = isDefault("OutputCalFile");
74 if (!noInputFile && noOutputFile) {
75 issues["OutputCalFile"] = "Output file name is missing.";
76 } else if (noInputFile && !noOutputFile) {
77 issues["InputCalFile"] = "Input file name is missing.";
78 }
79 return issues;
80}
81
86
87 if (isDefault("InputCalFile") && isDefault("OutputWorkspace")) {
88 g_log.error() << "No InputCalFle or OutputWorkspace specified; " << this->name() << " will do nothing.\n";
89 return;
90 }
91 const size_t nspec = m_inputW->getNumberHistograms();
92 for (size_t i = 0; i < nspec; ++i) {
93 // Get the list of udets contributing to this spectra
94 const auto &dets = m_inputW->getSpectrum(i).getDetectorIDs();
95
96 if (dets.empty())
97 continue;
98 else {
99 const size_t num_bins = m_inputW->y(i).size();
100 for (size_t j = 0; j < num_bins; ++j) {
101 const double val = m_inputW->y(i)[j];
102 if (m_compar_f(val, m_value)) {
103 for (const auto det : dets) {
104 m_umap.emplace(det, m_select_on);
105 }
106 // stop after the first bin matches the criteria
107 break;
108 }
109 }
110 }
111 const double p = static_cast<double>(i) / static_cast<double>(nspec);
112 progress(p, "Generating detector map");
113 }
114
115 if (!isDefault("InputCalFile")) {
117 }
118 if (!isDefault("OutputWorkspace")) {
120 }
121}
122
127 API::MatrixWorkspace_sptr outputW = getProperty("OutputWorkspace");
128 if (outputW != m_inputW)
129 outputW = m_inputW->clone();
130 auto &detectorInfo = outputW->mutableDetectorInfo();
131 for (const auto &selection : m_umap) {
132 detectorInfo.setMasked(detectorInfo.indexOf(selection.first), selection.second);
133 }
134
135 const auto &spectrumInfo = outputW->spectrumInfo();
136 for (size_t i = 0; i < spectrumInfo.size(); ++i) {
137 if (spectrumInfo.hasDetectors(i) && spectrumInfo.isMasked(i))
138 outputW->getSpectrum(i).clearData();
139 }
140
141 if (auto event = dynamic_cast<DataObjects::EventWorkspace *>(outputW.get()))
142 event->clearMRU();
143
144 setProperty("OutputWorkspace", outputW);
145}
150 m_inputW = getProperty("InputWorkspace");
151 m_value = getProperty("Value");
152
153 // Get the selction mode (select if or deselect if)
154 std::string select_mode = getProperty("Mode");
155 if (select_mode == "SelectIf")
156 m_select_on = true;
157 else
158 m_select_on = false;
159
160 // Select function object based on the type of comparison operator
161 std::string select_operator = getProperty("Operator");
162
163 if (select_operator == "LessEqual")
164 m_compar_f = std::less_equal<double>();
165 else if (select_operator == "Less")
166 m_compar_f = std::less<double>();
167 else if (select_operator == "GreaterEqual")
168 m_compar_f = std::greater_equal<double>();
169 else if (select_operator == "Greater")
170 m_compar_f = std::greater<double>();
171 else if (select_operator == "Equal")
172 m_compar_f = std::equal_to<double>();
173 else if (select_operator == "NotEqual")
174 m_compar_f = std::not_equal_to<double>();
175 else if (select_operator == "NotFinite")
176 m_compar_f = not_finite<double>();
177}
178
185 const std::string oldfile = getProperty("InputCalFile");
186 const std::string newfile = getProperty("OutputCalFile");
187 progress(0.99, "Creating new cal file");
188 std::ifstream oldf(oldfile.c_str());
189 if (!oldf.is_open()) {
190 g_log.error() << "Unable to open grouping file " << oldfile << '\n';
191 throw Exception::FileError("Error reading .cal file", oldfile);
192 }
193 std::ofstream newf(newfile.c_str());
194 if (!newf.is_open()) {
195 g_log.error() << "Unable to open grouping file " << newfile << '\n';
196 throw Exception::FileError("Error reading .cal file", newfile);
197 }
198 std::string str;
199 while (getline(oldf, str)) {
200 // Comment or empty lines get copied into the new cal file
201 if (str.empty() || str[0] == '#') {
202 newf << str << '\n';
203 continue;
204 }
205 std::istringstream istr(str);
206 int n, udet, sel, group;
207 double offset;
208 istr >> n >> udet >> offset >> sel >> group;
209 const auto it = m_umap.find(udet);
210 bool selection;
211
212 if (it == m_umap.end())
213 selection = sel != 0;
214 else
215 selection = (*it).second;
216
217 newf << std::fixed << std::setw(9) << n << std::fixed << std::setw(15) << udet << std::fixed << std::setprecision(7)
218 << std::setw(15) << offset << std::fixed << std::setw(8) << selection << std::fixed << std::setw(8) << group
219 << '\n';
220 }
221 oldf.close();
222 newf.close();
223}
224} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
double value
The value of the point.
Definition: FitMW.cpp:51
T first_argument_type
T second_argument_type
bool result_type
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition: System.h:64
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Definition: Algorithm.cpp:1913
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
Kernel::Logger & g_log
Definition: Algorithm.h:451
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
Definition: Algorithm.cpp:231
bool isDefault(const std::string &name) const
Definition: Algorithm.cpp:2084
@ OptionalSave
to specify a file to write to but an empty string is
Definition: FileProperty.h:50
@ OptionalLoad
to specify a file to read but the file doesn't have to exist
Definition: FileProperty.h:53
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:77
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