18using namespace Kernel;
21using namespace Geometry;
26 m_rangeLower(0.0), m_rangeUpper(0.0), m_solidAngle(false) {}
33 std::make_shared<HistogramValidator>()),
34 "Name of the input workspace");
36 "A MaskWorkspace where 0 denotes a masked spectra. Any spectra containing"
37 "a zero is also masked on the output");
39 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
40 mustBePositive->setLower(0);
41 auto mustBePosInt = std::make_shared<BoundedValidator<int>>();
42 mustBePosInt->setLower(0);
44 "Levels above pixel that will be used to compute the median.\n"
45 "If no level is specified, or 0, the median is over the whole "
48 "Error criterion as a multiple of error bar i.e. to fail the "
49 "test, the magnitude of the\n"
50 "difference with respect to the median value must also "
51 "exceed this number of error bars");
52 declareProperty(
"LowThreshold", 0.1,
"Lower acceptable bound as fraction of median value");
53 declareProperty(
"HighThreshold", 1.5,
"Upper acceptable bound as fraction of median value");
54 declareProperty(
"LowOutlier", 0.01,
"Lower bound defining outliers as fraction of median value");
55 declareProperty(
"HighOutlier", 100.,
"Upper bound defining outliers as fraction of median value");
57 "If false (default) zeroes will be included in "
58 "the median calculation, otherwise they will not be included "
59 "but they will be left unmasked");
62 "The index number of the first spectrum to include in the calculation\n"
65 "The index number of the last spectrum to include in the calculation\n"
66 "(default the last histogram)");
68 "No bin with a boundary at an x value less than this will be included\n"
69 "in the summation used to decide if a detector is 'bad' (default: the\n"
70 "start of each histogram)");
72 "No bin with a boundary at an x value higher than this value will\n"
73 "be included in the summation used to decide if a detector is 'bad'\n"
74 "(default: the end of each histogram)");
75 declareProperty(
"CorrectForSolidAngle",
false,
"Flag to correct for solid angle efficiency. False by default.");
96 if (solidAngle !=
nullptr) {
97 countsWS = countsWS / solidAngle;
103 std::vector<std::vector<size_t>> specmap =
makeMap(countsWS);
104 const bool excludeZeroes =
getProperty(
"ExcludeZeroesFromMedian");
108 std::vector<double> median =
calculateMedian(*countsWS, excludeZeroes, specmap);
109 std::vector<double>::iterator medit;
110 for (medit = median.begin(); medit != median.end(); ++medit) {
111 g_log.
debug() <<
"Median value = " << (*medit) <<
"\n";
114 int numFailed =
maskOutliers(median, countsWS, specmap);
118 for (medit = median.begin(); medit != median.end(); ++medit) {
119 g_log.
information() <<
"Median value with outliers removed = " << (*medit) <<
"\n";
125 <<
"\tNumber of failures - " << numFailed <<
"\n";
138 int maxWsIndex =
static_cast<int>(
m_inputWS->getNumberHistograms()) - 1;
143 g_log.
warning(
"StartSpectrum out of range, changed to 0");
150 g_log.
warning(
"EndSpectrum out of range, changed to max spectrum number");
154 g_log.
warning(
"EndSpectrum can not be less than the StartSpectrum, changed "
155 "to max spectrum number");
162 throw std::invalid_argument(
"The threshold for reading high must be "
163 "greater than the low threshold");
187 childAlg->setProperty(
"InputWorkspace",
m_inputWS);
188 childAlg->setProperty(
"StartWorkspaceIndex", firstSpec);
189 childAlg->setProperty(
"EndWorkspaceIndex", lastSpec);
194 if (!childAlg->isExecuted()) {
195 throw std::runtime_error(
"Unexpected problem calculating solid angles");
199 catch (std::exception &) {
201 " will continue with the solid angles of all spectra set to "
210 return childAlg->getProperty(
"OutputWorkspace");
221 std::vector<std::vector<size_t>> indexmap) {
229 bool checkForMask =
false;
231 if (instrument !=
nullptr) {
232 checkForMask = ((instrument->getSource() !=
nullptr) && (instrument->getSample() !=
nullptr));
234 auto &spectrumInfo = countsWS->mutableSpectrumInfo();
236 for (
size_t i = 0; i < indexmap.size(); ++i) {
237 std::vector<size_t> &hists = indexmap[i];
238 double median = medianvec[i];
241 for (
int j = 0; j < static_cast<int>(hists.size()); ++j) {
242 const double value = countsWS->y(hists[j])[0];
243 if ((
value == 0.) && checkForMask) {
244 if (spectrumInfo.hasDetectors(hists[j]) && spectrumInfo.isMasked(hists[j])) {
248 if ((
value < out_lo * median) && (
value > 0.0)) {
249 countsWS->getSpectrum(hists[j]).clearData();
251 spectrumInfo.setMasked(hists[j],
true);
254 }
else if (
value > out_hi * median) {
255 countsWS->getSpectrum(hists[j]).clearData();
257 spectrumInfo.setMasked(hists[j],
true);
280 std::vector<std::vector<size_t>> indexmap,
282 g_log.
debug(
"Applying the criteria to find failing detectors");
287 const double minSigma =
getProperty(
"SignificanceTest");
291 const auto progStep =
static_cast<int>(ceil(numSpec / 30.0));
294 const double deadValue(1.0);
297 bool checkForMask =
false;
299 if (instrument !=
nullptr) {
300 checkForMask = ((instrument->getSource() !=
nullptr) && (instrument->getSample() !=
nullptr));
302 const auto &spectrumInfo = countsWS->spectrumInfo();
305 for (
int j = 0; j < static_cast<int>(indexmap.size()); ++j) {
306 std::vector<size_t> hists = indexmap.at(j);
307 double median = medianvec.at(j);
308 const size_t nhist = hists.size();
309 g_log.
debug() <<
"new component with " << nhist <<
" spectra.\n";
310 for (
size_t i = 0; i < nhist; ++i) {
311 g_log.
debug() <<
"Counts workspace index=" << i <<
", Mask workspace index=" << hists.at(i) <<
'\n';
315 if (steps % progStep == 0) {
319 if (checkForMask && spectrumInfo.hasDetectors(hists.at(i))) {
320 if (spectrumInfo.isMasked(hists.at(i))) {
321 maskWS->mutableY(hists.at(i))[0] = deadValue;
324 if (spectrumInfo.isMonitor(hists.at(i))) {
330 const double signal = countsWS->y(hists.at(i))[0];
333 if (!std::isfinite(signal)) {
334 maskWS->mutableY(hists.at(i))[0] = deadValue;
340 const double error = minSigma * countsWS->e(hists.at(i))[0];
342 if ((signal < median *
m_loFrac && (signal - median < -
error)) ||
344 maskWS->mutableY(hists.at(i))[0] = deadValue;
#define DECLARE_ALGORITHM(classname)
double value
The value of the point.
#define PARALLEL_START_INTERRUPT_REGION
Begins a block to skip processing is the algorithm has been interupted Note the end of the block if n...
#define PARALLEL_CRITICAL(name)
#define PARALLEL_END_INTERRUPT_REGION
Ends a block to skip processing is the algorithm has been interupted Note the start of the block if n...
#define PARALLEL_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
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.
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.
A property class for workspaces.
A base class for a detector diagnostic algorithm.
std::vector< double > calculateMedian(const API::MatrixWorkspace &input, bool excludeZeroes, const std::vector< std::vector< size_t > > &indexmap)
Calculate the median of the given workspace.
std::vector< std::vector< size_t > > makeMap(const API::MatrixWorkspace_sptr &countsWS)
method to check which spectra should be grouped when calculating the median
double m_fracDone
An estimate of the percentage of the algorithm runtimes that has been completed.
@ RTGetSolidAngle
An estimate of how much work SolidAngle will do for each spectrum.
@ RTMarkDetects
Time taken to find failing detectors.
API::MatrixWorkspace_sptr integrateSpectra(const API::MatrixWorkspace_sptr &inputWS, const int indexMin, const int indexMax, const double lower, const double upper, const bool outputWorkspace2D=false)
Get the total counts for each spectra.
DataObjects::MaskWorkspace_sptr generateEmptyMask(const API::MatrixWorkspace_const_sptr &inputWS)
Create a masking workspace to return.
double advanceProgress(double toAdd)
Update the fraction complete estimate assuming that the algorithm has completed a task with estimated...
int m_parents
number of parents up, 0 go to instrument
void failProgress(RunTime aborted)
Update the fraction complete estimate assuming that the algorithm aborted a task with estimated RunTi...
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 warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< MaskWorkspace > MaskWorkspace_sptr
shared pointer to the MaskWorkspace class
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
std::enable_if< std::is_pointer< Arg >::value, bool >::type threadSafe(Arg workspace)
Thread-safety check Checks the workspace to ensure it is suitable for multithreaded access.
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
@ Input
An input workspace.
@ Output
An output workspace.