Mantid
Loading...
Searching...
No Matches
IdentifyNoisyDetectors.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 +
13#include "MantidHistogramData/Histogram.h"
15#include <numeric>
16
17namespace Mantid::Algorithms {
18using namespace Kernel;
19using namespace API;
20using namespace HistogramData;
21using namespace DataObjects;
22
23DECLARE_ALGORITHM(IdentifyNoisyDetectors)
24
26 auto wsVal = std::make_shared<CompositeValidator>();
27 wsVal->add<WorkspaceUnitValidator>("TOF");
28 wsVal->add<HistogramValidator>();
29 wsVal->add<SpectraAxisValidator>();
30 wsVal->add<InstrumentValidator>();
31 declareProperty(
32 std::make_unique<WorkspaceProperty<MatrixWorkspace>>("InputWorkspace", "", Direction::Input /*,wsVal*/));
33 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("OutputWorkspace", "", Direction::Output));
34 declareProperty("RangeLower", 2000.0, "The lower integration range");
35 declareProperty("RangeUpper", 19000.0, "The upper integration range");
36}
37
39 // Get the input workspace
40 MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace");
41 MatrixWorkspace_sptr inputWs = getProperty("InputWorkspace");
42 const auto nHist = static_cast<int>(inputWS->getNumberHistograms());
43
44 const double rangeLower = getProperty("RangeLower");
45 const double rangeUpper = getProperty("RangeUpper");
46 const double steps = rangeUpper - rangeLower;
47
48 if (0 == nHist)
49 throw std::runtime_error("Cannot run this algorithm on an input workspace without any spectra. "
50 "It does not seem to make sense and the calculations done here will "
51 "will cause a division by zero.");
52
53 Progress progress(this, 0.0, 1.0, (nHist * 7) + 6);
54
55 // Create the output workspace a single value for each spectra.
56 MatrixWorkspace_sptr outputWs;
57 outputWs = create<MatrixWorkspace>(*inputWS, Points(1));
58
59 MatrixWorkspace_sptr stdDevWs;
60 stdDevWs = create<MatrixWorkspace>(*outputWs);
61
62 progress.report("Integrating...");
63
64 auto integ = createChildAlgorithm("Integration");
65 integ->initialize();
66 integ->setProperty<MatrixWorkspace_sptr>("InputWorkspace", inputWs);
67 integ->setProperty<double>("RangeLower", rangeLower);
68 integ->setProperty<double>("RangeUpper", rangeUpper);
69 integ->execute();
70
71 MatrixWorkspace_sptr int1 = integ->getProperty("OutputWorkspace");
72
73 progress.report("Power...");
74
75 auto power = createChildAlgorithm("Power");
76 power->initialize();
77 power->setProperty<MatrixWorkspace_sptr>("InputWorkspace", inputWs);
78 power->setProperty<double>("Exponent", 2.0);
79 power->execute();
80
81 MatrixWorkspace_sptr power_tmp = power->getProperty("OutputWorkspace");
82
83 progress.report("Integrating...");
84
85 // integrate again
86 integ = createChildAlgorithm("Integration");
87 integ->initialize();
88 integ->setProperty<MatrixWorkspace_sptr>("InputWorkspace", power_tmp);
89 integ->setProperty<double>("RangeLower", rangeLower);
90 integ->setProperty<double>("RangeUpper", rangeUpper);
91 integ->execute();
92
93 MatrixWorkspace_sptr int2 = integ->getProperty("OutputWorkspace");
94
95 progress.report("Dividing...");
96 auto algScale = createChildAlgorithm("Scale");
97 algScale->initialize();
98 algScale->setProperty("InputWorkspace", int1);
99 algScale->setProperty("OutputWorkspace", int1);
100 algScale->setProperty("Factor", 1.0 / steps);
101 algScale->execute();
102 int1 = algScale->getProperty("OutputWorkspace");
103
104 progress.report("Dividing...");
105
106 algScale = createChildAlgorithm("Scale");
107 algScale->setProperty("InputWorkspace", int2);
108 algScale->setProperty("OutputWorkspace", int2);
109 algScale->setProperty("Factor", 1.0 / steps);
110 algScale->execute();
111 int2 = algScale->getProperty("OutputWorkspace");
112
113 for (int i = 0; i < nHist; i++) {
114 outputWs->setHistogram(i, Points{0.0}, Counts{1.0});
115 stdDevWs->setSharedX(i, outputWs->sharedX(i));
116 stdDevWs->mutableY(i)[0] = sqrt(int2->y(i)[0] - std::pow(int1->y(i)[0], 2));
117
118 progress.report();
119 }
120
121 getStdDev(progress, outputWs, stdDevWs);
122 getStdDev(progress, outputWs, stdDevWs);
123 getStdDev(progress, outputWs, stdDevWs);
124
125 setProperty("OutputWorkspace", outputWs);
126}
127
138 const MatrixWorkspace_sptr &values) {
139 const auto nhist = static_cast<int>(valid->getNumberHistograms());
140 int count = 0;
141 double mean = 0.0;
142 double mean2 = 0.0;
143
144 for (int i = 0; i < nhist; i++) {
145 if (valid->y(i)[0] > 0) {
146 mean += values->y(i)[0];
147 mean2 += std::pow(values->y(i)[0], 2);
148 count++;
149 }
150
151 progress.report();
152 }
153
154 if (0 == count) {
155 // all values are zero, no need to loop
156 return;
157 }
158
159 mean = mean / count;
160 double stddev = sqrt((mean2 / count) - std::pow(mean, 2));
161
162 double upper = mean + 3 * stddev;
163 double lower = mean - 3 * stddev;
164 double min = mean * 0.0001;
165
166 Counts counts{0.0};
167 for (int i = 0; i < nhist; i++) {
168 double value = values->y(i)[0];
169 if (value > upper) {
170 valid->setCounts(i, counts);
171 } else if (value < lower) {
172 valid->setCounts(i, counts);
173 } else if (value < min) {
174 valid->setCounts(i, counts);
175 }
176
177 progress.report("Calculating StdDev...");
178 }
179}
180
181} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
double value
The value of the point.
Definition: FitMW.cpp:51
int count
counter
Definition: Matrix.cpp:37
double lower
lower and upper bounds on the multiplier, if known
double upper
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
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.
Definition: Algorithm.cpp:842
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
Definition: Algorithm.cpp:231
A validator which checks that a workspace contains histogram data (the default) or point data as requ...
A validator which checks that a workspace has a valid instrument.
Helper class for reporting progress from algorithms.
Definition: Progress.h:25
A validator which checks whether the input workspace has the Spectra number in the axis.
A property class for workspaces.
A validator which checks that the unit of the workspace referred to by a WorkspaceProperty is the exp...
Identifies "bad" detectors based on their standard deviation, and how this differs from the standard ...
void getStdDev(API::Progress &progress, const Mantid::API::MatrixWorkspace_sptr &valid, const Mantid::API::MatrixWorkspace_sptr &values)
Main work portion of algorithm.
void exec() override
Executes the algorithm.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
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