20#include <boost/iterator/counting_iterator.hpp>
48 "Name of the integrated detector vanadium (white beam) workspace.");
51 "A hard mask to apply to the inputworkspace");
53 "A MaskWorkspace containing the masked spectra as zeroes and ones.");
54 auto mustBePosInt = std::make_shared<BoundedValidator<int>>();
55 mustBePosInt->setLower(0);
57 "The index number of the first spectrum to include in the calculation\n"
60 "The index number of the last spectrum to include in the calculation\n"
61 "(default the last histogram)");
63 "No bin with a boundary at an x value less than this will be used\n"
64 "in the summation that decides if a detector is 'bad' (default: the\n"
65 "start of each histogram)");
67 "No bin with a boundary at an x value higher than this value will\n"
68 "be used in the summation that decides if a detector is 'bad'\n"
69 "(default: the end of each histogram)");
71 string findDetOutLimGrp(
"Find Detectors Outside Limits");
73 "Spectra whose total number of counts are equal to or below this value\n"
74 "will be marked bad (default 0)");
77 "Spectra whose total number of counts are equal to or above this value\n"
78 "will be marked bad (default off)");
81 string medianDetTestGrp(
"Median Detector Test");
82 auto mustBePositiveDbl = std::make_shared<BoundedValidator<double>>();
83 mustBePositiveDbl->setLower(0);
85 "Levels above pixel that will be used to compute the median.\n"
86 "If no level is specified, or 0, the median is over the whole "
90 "Error criterion as a multiple of error bar i.e. to "
91 "fail the test, the magnitude of the\n"
92 "difference with respect to the median value must also "
93 "exceed this number of error bars");
95 this->
declareProperty(
"LowThresholdFraction", 0.1,
"Lower acceptable bound as fraction of median value");
97 this->
declareProperty(
"HighThresholdFraction", 1.5,
"Upper acceptable bound as fraction of median value");
99 this->
declareProperty(
"LowOutlier", 0.01,
"Lower bound defining outliers as fraction of median value");
101 this->
declareProperty(
"HighOutlier", 100.,
"Upper bound defining outliers as fraction of median value");
103 this->
declareProperty(
"CorrectForSolidAngle",
false,
"Flag to correct for solid angle efficiency. False by default.");
106 "If false (default) zeroes will be included in "
107 "the median calculation, otherwise they will not be "
108 "included but they will be left unmasked");
111 string detEffVarGrp(
"Detector Efficiency Variation");
114 "Name of a matching second detector vanadium run from the same\n"
115 "instrument. It must be treated in the same manner as the input detector "
119 "Identify spectra whose total number of counts has changed by more\n"
120 "than this factor of the median change between the two input workspaces");
123 std::make_unique<EnabledWhenProperty>(
"DetVanCompare",
IS_NOT_DEFAULT));
125 string countsCheck(
"Check Sample Counts");
128 "A sample workspace integrated over the full axis range.");
131 string backgroundCheck(
"Check Sample Background");
134 "A sample workspace integrated over the background region.");
136 this->
declareProperty(
"SampleBkgLowAcceptanceFactor", 0.0, mustBePositiveDbl,
137 "Low threshold for the background check MedianDetectorTest.");
139 this->
declareProperty(
"SampleBkgHighAcceptanceFactor", 5.0, mustBePositiveDbl,
140 "High threshold for the background check MedianDetectorTest.");
142 this->
declareProperty(
"SampleBkgSignificanceTest", 3.3, mustBePositiveDbl,
143 "Error criterion as a multiple of error bar i.e. to "
144 "fail the test, the magnitude of the\n"
145 "difference with respect to the median value must also "
146 "exceed this number of error bars");
149 "Flag to correct for solid angle efficiency for "
150 "background check MedianDetectorTest. False by "
154 string psdBleedMaskGrp(
"Create PSD Bleed Mask");
157 "A sample workspace. This is used in the PSD Bleed calculation.");
160 "The maximum rate allowed for a tube in counts/us/frame.");
162 this->
declareProperty(
"NIgnoredCentralPixels", 80, mustBePosInt,
"The number of pixels about the centre to ignore.");
165 std::make_unique<EnabledWhenProperty>(
"MaxTubeFramerate",
IS_NOT_DEFAULT));
210 md->setProperty(
"Workspace", inputWS);
211 md->setProperty(
"MaskedWorkspace", hardMaskWS);
212 md->executeAsChildAlg();
227 double variation = this->
getProperty(
"DetVanRatioVariation");
232 alg->setProperty(
"WhiteBeamBase", inputWS);
233 alg->setProperty(
"WhiteBeamCompare", input2WS);
234 alg->setProperty(
"StartWorkspaceIndex",
m_minIndex);
235 alg->setProperty(
"EndWorkspaceIndex",
m_maxIndex);
238 alg->setProperty(
"Variation", variation);
239 alg->executeAsChildAlg();
243 int localFails = alg->getProperty(
"NumberOfFailures");
244 numFailed += localFails;
254 zeroChk->setProperty(
"InputWorkspace", totalCountsWS);
255 zeroChk->setProperty(
"StartWorkspaceIndex",
m_minIndex);
256 zeroChk->setProperty(
"EndWorkspaceIndex",
m_maxIndex);
257 zeroChk->setProperty(
"LowThreshold", 1.0e-10);
258 zeroChk->setProperty(
"HighThreshold", 1.0e100);
259 zeroChk->executeAsChildAlg();
262 int localFails = zeroChk->getProperty(
"NumberOfFailures");
263 numFailed += localFails;
271 double significanceTest = this->
getProperty(
"SampleBkgSignificanceTest");
272 double lowThreshold = this->
getProperty(
"SampleBkgLowAcceptanceFactor");
273 double highThreshold = this->
getProperty(
"SampleBkgHighAcceptanceFactor");
274 bool correctSA = this->
getProperty(
"SampleCorrectForSolidAngle");
279 alg->setProperty(
"InputWorkspace", bkgWS);
280 alg->setProperty(
"StartWorkspaceIndex",
m_minIndex);
281 alg->setProperty(
"EndWorkspaceIndex",
m_maxIndex);
282 alg->setProperty(
"SignificanceTest", significanceTest);
283 alg->setProperty(
"LowThreshold", lowThreshold);
284 alg->setProperty(
"HighThreshold", highThreshold);
285 alg->setProperty(
"LowOutlier", 0.0);
286 alg->setProperty(
"HighOutlier", 1.0e100);
287 alg->setProperty(
"ExcludeZeroesFromMedian",
true);
288 alg->setProperty(
"CorrectForSolidAngle", correctSA);
289 alg->executeAsChildAlg();
292 int localFails = alg->getProperty(
"NumberOfFailures");
293 numFailed += localFails;
299 double maxTubeFrameRate = this->
getProperty(
"MaxTubeFramerate");
300 int numIgnore = this->
getProperty(
"NIgnoredCentralPixels");
305 alg->setProperty(
"InputWorkspace", sampleWS);
306 alg->setProperty(
"MaxTubeFramerate", maxTubeFrameRate);
307 alg->setProperty(
"NIgnoredCentralPixels", numIgnore);
308 alg->executeAsChildAlg();
311 int localFails = alg->getProperty(
"NumberOfFailures");
312 numFailed += localFails;
319 std::vector<int> detList;
321 extract->setProperty(
"InputWorkspace", inputWS);
322 extract->setProperty(
"OutputWorkspace",
"final_mask");
323 extract->setProperty(
"DetectorList", detList);
324 extract->executeAsChildAlg();
325 maskWS = extract->getProperty(
"OutputWorkspace");
337 maskAlg->setProperty(
"Workspace", inputWS);
338 maskAlg->setProperty(
"MaskedWorkspace", maskWS);
339 maskAlg->setProperty(
"StartWorkspaceIndex",
m_minIndex);
340 maskAlg->setProperty(
"EndWorkspaceIndex",
m_maxIndex);
341 maskAlg->executeAsChildAlg();
355 double lowThreshold = this->
getProperty(
"LowThreshold");
356 double highThreshold = this->
getProperty(
"HighThreshold");
360 fdol->setProperty(
"InputWorkspace", inputWS);
361 fdol->setProperty(
"OutputWorkspace", localMask);
362 fdol->setProperty(
"StartWorkspaceIndex",
m_minIndex);
363 fdol->setProperty(
"EndWorkspaceIndex",
m_maxIndex);
366 fdol->setProperty(
"LowThreshold", lowThreshold);
367 fdol->setProperty(
"HighThreshold", highThreshold);
368 fdol->executeAsChildAlg();
369 localMask = fdol->getProperty(
"OutputWorkspace");
370 int localFails = fdol->getProperty(
"NumberOfFailures");
371 nFails += localFails;
375 double significanceTest = this->
getProperty(
"SignificanceTest");
376 double lowThresholdFrac = this->
getProperty(
"LowThresholdFraction");
377 double highThresholdFrac = this->
getProperty(
"HighThresholdFraction");
378 double lowOutlier = this->
getProperty(
"LowOutlier");
379 double highOutlier = this->
getProperty(
"HighOutlier");
380 bool excludeZeroes = this->
getProperty(
"ExcludeZeroesFromMedian");
381 bool correctforSA = this->
getProperty(
"CorrectForSolidAngle");
390 mdt->setProperty(
"InputWorkspace", inputWS);
391 mdt->setProperty(
"StartWorkspaceIndex",
m_minIndex);
392 mdt->setProperty(
"EndWorkspaceIndex",
m_maxIndex);
395 mdt->setProperty(
"LevelsUp", parents);
396 mdt->setProperty(
"SignificanceTest", significanceTest);
397 mdt->setProperty(
"LowThreshold", lowThresholdFrac);
398 mdt->setProperty(
"HighThreshold", highThresholdFrac);
399 mdt->setProperty(
"LowOutlier", lowOutlier);
400 mdt->setProperty(
"HighOutlier", highOutlier);
401 mdt->setProperty(
"ExcludeZeroesFromMedian", excludeZeroes);
402 mdt->setProperty(
"CorrectForSolidAngle", correctforSA);
403 mdt->executeAsChildAlg();
404 localMask = mdt->getProperty(
"OutputWorkspace");
405 localFails = mdt->getProperty(
"NumberOfFailures");
406 nFails += localFails;
416 :
API::
Algorithm(), m_fracDone(0.0), m_TotalTime(RTTotal), m_parents(0), m_progStepWidth(0.0), m_minIndex(0),
435 const int indexMax,
const double lower,
const double upper,
436 const bool outputWorkspace2D) {
437 g_log.
debug() <<
"Integrating input spectra.\n";
446 childAlg->setProperty(
"InputWorkspace", inputWS);
447 childAlg->setProperty(
"StartWorkspaceIndex", indexMin);
448 childAlg->setProperty(
"EndWorkspaceIndex", indexMax);
451 childAlg->setProperty(
"RangeLower",
lower);
452 childAlg->setProperty(
"RangeUpper",
upper);
453 childAlg->setPropertyValue(
"IncludePartialBins",
"1");
454 childAlg->executeAsChildAlg();
459 if (outputWorkspace2D && std::dynamic_pointer_cast<EventWorkspace>(outputW)) {
460 g_log.
debug() <<
"Converting output Event Workspace into a Workspace2D.\n";
462 childAlg->setProperty(
"InputWorkspace", outputW);
463 childAlg->executeAsChildAlg();
464 finalOutputW = childAlg->getProperty(
"OutputWorkspace");
479 auto maskWS = create<DataObjects::MaskWorkspace>(*inputWS, HistogramData::Points(1));
480 maskWS->setTitle(inputWS->getTitle());
486 return {{boost::counting_iterator<std::size_t>(0),
494 std::multimap<size_t, size_t> mymap;
501 if (countsWS->hasGroupedDetectors()) {
502 throw std::runtime_error(
"Median detector test: not able to create "
503 "detector to spectra map. Try with LevelUp=0.");
506 const SpectrumInfo &spectrumInfo = countsWS->spectrumInfo();
507 const auto &componentInfo = countsWS->componentInfo();
509 for (
size_t i = 0; i < countsWS->getNumberHistograms(); ++i) {
513 for (
int level = 0; level <
m_parents; ++level) {
514 if (!componentInfo.hasParent(ancestor)) {
515 g_log.
warning(
"Too many levels up. Will ignore LevelsUp");
519 ancestor = componentInfo.parent(ancestor);
521 mymap.emplace(ancestor, i);
524 std::vector<std::vector<size_t>> speclist;
526 std::multimap<size_t, size_t>::iterator m_it, s_it;
527 for (m_it = mymap.begin(); m_it != mymap.end(); m_it = s_it) {
528 auto const theKey = m_it->first;
529 auto keyRange = mymap.equal_range(theKey);
531 std::vector<size_t> speclistsingle;
532 for (s_it = keyRange.first; s_it != keyRange.second; ++s_it) {
533 speclistsingle.emplace_back(s_it->second);
535 speclist.emplace_back(std::move(speclistsingle));
555 const std::vector<std::vector<size_t>> &indexmap) {
556 std::vector<double> medianvec;
557 g_log.
debug(
"Calculating the median count rate of the spectra");
559 bool checkForMask =
false;
561 if (instrument !=
nullptr) {
562 checkForMask = ((instrument->getSource() !=
nullptr) && (instrument->getSample() !=
nullptr));
566 for (
const auto &hists : indexmap) {
567 std::vector<double> medianInput;
568 const auto nhists =
static_cast<int>(hists.size());
570 medianInput.reserve(nhists);
573 for (
int i = 0; i < nhists; ++i) {
576 if (checkForMask && spectrumInfo.hasDetectors(hists[i])) {
577 if (spectrumInfo.isMasked(hists[i]) || spectrumInfo.isMonitor(hists[i]))
581 const double yValue = input.
y(hists[i])[0];
583 throw std::out_of_range(
"Negative number of counts found, could be "
584 "corrupted raw counts or solid angle data");
586 if (!std::isfinite(yValue) || (excludeZeroes && yValue < DBL_EPSILON))
591 PARALLEL_CRITICAL(DetectorDiagnostic_median_d) { medianInput.emplace_back(yValue); }
597 if (medianInput.empty()) {
598 g_log.
information(
"some group has no valid histograms. Will use 0 for median.");
599 medianInput.emplace_back(0.);
603 double median = stats.
median;
605 if (median < 0 || median > DBL_MAX / 10.0) {
606 throw std::out_of_range(
"The calculated value for the median was either "
607 "negative or unreliably large");
609 medianvec.emplace_back(median);
621 g_log.
information() <<
"Workspace already contains a count rate, nothing to do.\n";
632 return childAlg->getProperty(
"Workspace");
#define DECLARE_ALGORITHM(classname)
IPeaksWorkspace_sptr workspace
#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.
double lower
lower and upper bounds on the multiplier, if known
Base class from which all concrete algorithm classes should be derived.
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 interruption_point()
This is called during long-running operations, and check if the algorithm has requested that it be ca...
const SpectrumInfo & spectrumInfo() const
Return a reference to the SpectrumInfo object.
Geometry::Instrument_const_sptr getInstrument() const
Returns the parameterized instrument.
Base MatrixWorkspace Abstract Class.
virtual std::size_t getNumberHistograms() const =0
Returns the number of histograms in the workspace.
const HistogramData::HistogramY & y(const size_t index) const
API::SpectrumInfo is an intermediate step towards a SpectrumInfo that is part of Instrument-2....
bool hasDetectors(const size_t index) const
Returns true if the spectrum is associated with detectors in the instrument.
const SpectrumDefinition & spectrumDefinition(const size_t index) const
Returns a const reference to the SpectrumDefinition of the spectrum.
A property class for workspaces.
const std::string name() const override
Algorithm's name for identification overriding a virtual method.
int version() const override
Algorithm's version for identification overriding a virtual method.
void init() override
Virtual method - must be overridden by concrete algorithm.
double m_rangeUpper
Ending x-axis value for integrations.
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.
int m_TotalTime
An estimate total number of additions or equilivent required to compute a spectrum.
std::vector< std::vector< size_t > > makeMap(const API::MatrixWorkspace_sptr &countsWS)
method to check which spectra should be grouped when calculating the median
std::vector< std::vector< size_t > > makeInstrumentMap(const API::MatrixWorkspace &countsWS)
method to create the map with all spectra
double m_fracDone
An estimate of the percentage of the algorithm runtimes that has been completed.
RunTime
For the progress bar, estimates of how many additions, or equivalent, member functions will do for ea...
@ RTGetTotalCounts
Estimate of the work required from Integrate for each spectrum.
@ RTGetRate
Work required by the ConvertToDistribution algorithm.
int m_maxIndex
Ending workspace index to run tests on.
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.
DetectorDiagnostic()
Default constructor.
API::MatrixWorkspace_sptr convertToRate(API::MatrixWorkspace_sptr workspace)
Convert to a distribution.
double m_progStepWidth
The number of tests to be run.
DataObjects::MaskWorkspace_sptr generateEmptyMask(const API::MatrixWorkspace_const_sptr &inputWS)
Create a masking workspace to return.
void applyMask(const API::MatrixWorkspace_sptr &inputWS, const API::MatrixWorkspace_sptr &maskWS)
Apply a given mask.
void exec() override
Virtual method - must be overridden by concrete algorithm.
API::MatrixWorkspace_sptr doDetVanTest(const API::MatrixWorkspace_sptr &inputWS, int &nFails)
Perform checks on detector vanadium.
double m_rangeLower
Starting x-axis value for integrations.
int m_minIndex
Starting workspace index to run tests on.
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...
const std::string category() const override
Algorithm's category for identification.
Exception for when an item is not found in a collection.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void setPropertySettings(const std::string &name, std::unique_ptr< IPropertySettings const > settings)
Add a PropertySettings instance to the chain of settings for a given property.
void setPropertyGroup(const std::string &name, const std::string &group)
Set the group for a given property.
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< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm
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
std::shared_ptr< MaskWorkspace > MaskWorkspace_sptr
shared pointer to the MaskWorkspace class
std::shared_ptr< const Mantid::Geometry::IDetector > IDetector_const_sptr
Shared pointer to IDetector (const version)
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
Statistics getStatistics(const std::vector< TYPE > &data, const unsigned int flags=StatOptions::AllStats)
Return a statistics object for the given data set.
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.
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Input
An input workspace.
@ Output
An output workspace.
Simple struct to store statistics.
double median
Median value.