27using namespace Kernel;
29using namespace Geometry;
30using namespace DataObjects;
37 "The workspace containing the flood data");
39 "The name of the workspace to be created as the output of the algorithm");
41 auto positiveDouble = std::make_shared<BoundedValidator<double>>();
42 positiveDouble->setLower(0);
44 "Minimum efficiency for a pixel to be considered (default: no minimum).");
46 "Maximum efficiency for a pixel to be considered (default: no maximum).");
47 declareProperty(
"MaskedFullComponent",
"",
"Component Name to fully mask according to the IDF file.");
49 "Number of pixels to mask on the edges: X-low, X-high, Y-low, Y-high");
50 declareProperty(
"MaskedComponent",
"",
"Component Name to mask the edges according to the IDF file.");
69 const std::string maskedFullComponent =
getPropertyValue(
"MaskedFullComponent");
70 if (!maskedFullComponent.empty()) {
71 g_log.
debug() <<
"CalculateEfficiency: Masking Full Component: " << maskedFullComponent <<
"\n";
77 std::vector<int> maskedEdges =
getProperty(
"MaskedEdges");
78 if (!maskedEdges.empty() && (maskedEdges[0] > 0 || maskedEdges[1] > 0 || maskedEdges[2] > 0 || maskedEdges[3] > 0)) {
79 g_log.
debug() <<
"CalculateEfficiency: Masking edges length = " << maskedEdges.size() <<
")"
80 <<
" of the component " << maskedFullComponent <<
"\n";
82 maskEdges(inputWS, maskedEdges[0], maskedEdges[1], maskedEdges[2], maskedEdges[3], maskedComponent);
93 childAlg->executeAsChildAlg();
94 rebinnedWS = childAlg->getProperty(
"OutputWorkspace");
98 for (
int i = 0; i < static_cast<int>(rebinnedWS->getNumberHistograms()); i++) {
99 outputWS->setSharedX(i, rebinnedWS->sharedX(i));
145 const auto numberOfSpectra =
static_cast<int>(rebinnedWS->getNumberHistograms());
150 const auto &spectrumInfo = rebinnedWS->spectrumInfo();
151 for (
int i = 0; i < numberOfSpectra; i++) {
152 progress(0.2 + 0.2 * i / numberOfSpectra,
"Computing sensitivity");
154 if (spectrumInfo.isMonitor(i) || spectrumInfo.isMasked(i))
158 auto &YValues = rebinnedWS->y(i);
159 auto &YErrors = rebinnedWS->e(i);
162 error += YErrors[0] * YErrors[0];
166 g_log.
debug() <<
"sumUnmaskedDetectors: unmasked pixels = " << nPixels <<
" from a total of " << numberOfSpectra
186 int nPixels,
double min_eff,
double max_eff) {
188 const size_t numberOfSpectra = rebinnedWS->getNumberHistograms();
192 std::vector<size_t> dets_to_mask;
194 const auto &spectrumInfo = rebinnedWS->spectrumInfo();
195 for (
size_t i = 0; i < numberOfSpectra; i++) {
196 const double currProgress = 0.4 + 0.2 * (
static_cast<double>(i) /
static_cast<double>(numberOfSpectra));
197 progress(currProgress,
"Computing sensitivity");
199 if (spectrumInfo.isMasked(i))
203 auto &YIn = rebinnedWS->y(i);
204 auto &EIn = rebinnedWS->e(i);
205 auto &YOut = outputWS->mutableY(i);
206 auto &EOut = outputWS->mutableE(i);
208 if (spectrumInfo.isMonitor(i)) {
215 YOut[0] = nPixels / sum * YIn[0];
216 const double err_sum = YIn[0] / sum *
error;
217 EOut[0] = nPixels / std::abs(sum) * std::sqrt(EIn[0] * EIn[0] + err_sum * err_sum);
220 if (!
isEmpty(min_eff) && YOut[0] < min_eff)
221 dets_to_mask.emplace_back(i);
222 if (!
isEmpty(max_eff) && YOut[0] > max_eff)
223 dets_to_mask.emplace_back(i);
226 g_log.
debug() <<
"normalizeDetectors: Masked pixels outside the acceptable "
228 << min_eff <<
"," << max_eff <<
"] = " << dets_to_mask.size()
229 <<
" from a total of non masked = " << nPixels
230 <<
" (from a total number of spectra in the ws = " << numberOfSpectra <<
")\n";
233 if (!dets_to_mask.empty()) {
240 mask->setProperty<std::vector<size_t>>(
"WorkspaceIndexList", dets_to_mask);
246 mask->setProperty<std::vector<size_t>>(
"WorkspaceIndexList", dets_to_mask);
248 }
catch (std::invalid_argument &err) {
250 e <<
"Invalid argument to MaskDetectors Child Algorithm: " << err.what();
252 }
catch (std::runtime_error &err) {
254 e <<
"Unable to successfully run MaskDetectors Child Algorithm: " << err.what();
268 std::shared_ptr<const Geometry::ICompAssembly> component =
269 std::dynamic_pointer_cast<const Geometry::ICompAssembly>(instrument->getComponentByName(componentName));
271 g_log.
warning(
"Component " + componentName +
" expected to be a CompAssembly, e.g., a bank. Component " +
272 componentName +
" not masked!");
276 for (
int x = 0;
x < component->nelements();
x++) {
277 std::shared_ptr<Geometry::ICompAssembly> xColumn =
278 std::dynamic_pointer_cast<Geometry::ICompAssembly>((*component)[
x]);
279 for (
int y = 0;
y < xColumn->nelements();
y++) {
280 std::shared_ptr<Geometry::Detector> detector = std::dynamic_pointer_cast<Geometry::Detector>((*xColumn)[
y]);
282 auto detID = detector->getID();
289 for (
const auto &idx : indexList) {
291 spectrumInfo.setMasked(idx,
true);
293 }
catch (std::exception &) {
294 g_log.
warning(
"Expecting the component " + componentName +
295 " to be a CompAssembly, e.g., a bank. Component not masked!");
309 const std::string &componentName) {
311 auto instrument = ws->getInstrument();
313 std::shared_ptr<Mantid::Geometry::RectangularDetector> component;
315 component = std::const_pointer_cast<Mantid::Geometry::RectangularDetector>(
316 std::dynamic_pointer_cast<const Mantid::Geometry::RectangularDetector>(
317 instrument->getComponentByName(componentName)));
318 }
catch (std::exception &) {
319 g_log.
warning(
"Expecting the component " + componentName +
" to be a RectangularDetector. maskEdges not executed.");
323 g_log.
warning(
"Component " + componentName +
" is not a RectangularDetector. MaskEdges not executed.");
327 std::vector<int> IDs;
330 while (i < left * component->idstep()) {
331 IDs.emplace_back(component->idstart() + i);
335 i = component->maxDetectorID() -
right * component->idstep();
336 while (i < component->maxDetectorID()) {
341 for (
int row = 0; row < low; row++) {
342 i = row + component->idstart();
343 while (i < component->nelements() * component->idstep() - component->idstep() + low + component->idstart()) {
345 i += component->idstep();
349 for (
int row = 0; row < high; row++) {
350 i = component->idstep() + component->idstart() - row - 1;
351 while (i < component->nelements() * component->idstep() + component->idstart()) {
353 i += component->idstep();
357 g_log.
debug() <<
"CalculateEfficiency::maskEdges Detector Ids to Mask:" << std::endl;
358 for (
auto id : IDs) {
364 maskAlg->setChild(
true);
365 maskAlg->setProperty(
"Workspace", ws);
366 maskAlg->setProperty(
"DetectorList", IDs);
#define DECLARE_ALGORITHM(classname)
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
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.
Geometry::Instrument_const_sptr getInstrument() const
Returns the parameterized instrument.
SpectrumInfo & mutableSpectrumInfo()
Return a non-const reference to the SpectrumInfo object.
virtual void clearData()=0
Base MatrixWorkspace Abstract Class.
virtual ISpectrum & getSpectrum(const size_t index)=0
Return the underlying ISpectrum ptr at the given workspace index.
std::vector< size_t > getIndicesFromDetectorIDs(const std::vector< detid_t > &detIdList) const
Converts a list of detector IDs to the corresponding workspace indices.
A property class for workspaces.
void exec() override
Executes the algorithm.
void normalizeDetectors(const API::MatrixWorkspace_sptr &rebinnedWS, const API::MatrixWorkspace_sptr &outputWS, double sum, double error, int nPixels, double min_eff, double max_eff)
Normalize all detectors to get the relative efficiency.
void sumUnmaskedDetectors(const API::MatrixWorkspace_sptr &rebinnedWS, double &sum, double &error, int &nPixels)
Sum all detectors, excluding monitors and masked detectors.
void maskComponent(API::MatrixWorkspace &ws, const std::string &componentName)
Fully masks one component named componentName.
void init() override
Initialization method.
void maskEdges(const API::MatrixWorkspace_sptr &ws, int left, int right, int high, int low, const std::string &componentName)
Mask edges of a RectangularDetector.
Support for a property that holds an array of values.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
@ Input
An input workspace.
@ Output
An output workspace.