15#include "MantidHistogramData/HistogramIterator.h"
16#include "MantidHistogramData/LinearGenerator.h"
23const std::string COMPONENTS{
"Components"};
24const std::string DIAGNOSTICS_WS{
"DiagnosticsWorkspace"};
25const std::string EPP_WS{
"EPPWorkspace"};
26const std::string INPUT_WS{
"InputWorkspace"};
27const std::string OUTPUT_WS{
"OutputWorkspace"};
28const std::string POLYNOMIAL_DEGREE{
"Degree"};
29const std::string SIGMA_MULTIPLIER{
"NonBkgRegionInSigmas"};
30const std::string IGNORE_INVALID_DATA{
"IgnoreInvalidData"};
41 size_t const firstColumnIndex) {
42 std::vector<double> ranges;
44 bool needsRangeStart{
true};
45 bool needsRangeEnd{
false};
47 if (spectrumInfo.isMasked(i) || statuses.
cell<std::string>(i + firstColumnIndex) !=
"success") {
49 needsRangeStart =
true;
50 needsRangeEnd =
false;
52 ranges.emplace_back(
static_cast<double>(i) - 0.5);
56 if (needsRangeStart) {
57 needsRangeStart =
false;
59 ranges.emplace_back(
static_cast<double>(i) - 0.5);
71 std::vector<double> peakStarts;
73 std::vector<double> peakEnds;
86PeakBounds peakBounds(
size_t const firstIndex,
size_t const lastIndex,
double const sigmaMultiplier,
90 size_t const boundsSize = lastIndex - firstIndex + 1;
91 bounds.peakStarts.resize(boundsSize);
92 bounds.peakEnds.resize(boundsSize);
93 for (
size_t i = firstIndex; i <= lastIndex; ++i) {
94 auto const boundsIndex = i - firstIndex;
95 if (fitStatusColumn.
cell<std::string>(i) ==
"success") {
96 auto const peakCentre = peakCentreColumn.
cell<
double>(i);
97 auto const peakWidth = sigmaMultiplier * sigmaColumn.
cell<
double>(i);
98 bounds.peakStarts[boundsIndex] = peakCentre - peakWidth;
99 bounds.peakEnds[boundsIndex] = peakCentre + peakWidth;
101 bounds.peakStarts[boundsIndex] = std::numeric_limits<double>::lowest();
102 bounds.peakEnds[boundsIndex] = std::numeric_limits<double>::max();
119 throw NotFoundError(
"EPPWorkspace does not contain 'PeakCentre' column.",
"PeakCentre");
122 throw NotFoundError(
"EPPWorkspace does not contain 'Sigma' column",
"Sigma");
125 throw NotFoundError(
"EPPWorkspace does not contain 'FitStatus' column.",
"FitStatus");
139 throw NotFoundError(
"Component not found in InputWorkspace's instrument.", componentName);
176 auto const &ys = componentBkgWS.
y(0);
177 auto const &es = componentBkgWS.
e(0);
178 for (
size_t i = 0; i < ys.size(); ++i) {
179 targetWS.
mutableY(firstTargetWSIndex + i) = ys[i];
180 targetWS.
mutableE(firstTargetWSIndex + i) = es[i];
199 return "CorrectionFunctions\\BackgroundCorrections;ILL\\Direct";
204 return {
"CalculateFlatBackground",
"CalculatePolynomialBackground",
"CreateUserDefinedBackground",
"RemoveBackground",
210 return "Fits polynomial backgrounds over the pixels of position sensitive "
219 "A workspace to fit the backgrounds to.");
222 "The fitted backgrounds.");
224 "A list of component names for which to calculate the backgrounds.");
227 "A table workspace containing results from the FindEPP algorithm.");
228 auto positiveDouble = std::make_shared<Kernel::BoundedValidator<double>>();
229 positiveDouble->setLowerExclusive(0.);
231 "Half width of the range excluded from background around "
232 "the elastic peaks in multiplies of 'Sigma' in the EPP table.'.");
233 auto nonnegativeInt = std::make_shared<Kernel::BoundedValidator<int>>();
234 nonnegativeInt->setLower(0);
235 declareProperty(Prop::POLYNOMIAL_DEGREE, 0, nonnegativeInt,
"The degree of the background polynomial.");
238 "Detector diagnostics workspace for masking.");
239 declareProperty(Prop::IGNORE_INVALID_DATA,
false,
"Flag to ignore infinities, NaNs and data with zero errors.");
244 std::map<std::string, std::string> issues;
247 if (inWS->getNumberHistograms() != eppWS->rowCount()) {
248 issues[Prop::EPP_WS] =
"Wrong EPP workspace? The number of the table rows "
249 "does not match the number of histograms in InputWorkspace.";
253 if (inWS->getNumberHistograms() != maskWS->getNumberHistograms()) {
254 issues[Prop::EPP_WS] =
"Wrong diagnostics workspace? The number of histograms "
255 "does not match with InputWorkspace.";
267 for (
size_t i = 0; i < bkgWS->getNumberHistograms(); ++i) {
268 bkgWS->convertToFrequencies(i);
271 double const sigmaMultiplier =
getProperty(Prop::SIGMA_MULTIPLIER);
272 auto peakCentreColumn = eppWS->getColumn(
"PeakCentre");
273 auto sigmaColumn = eppWS->getColumn(
"Sigma");
274 auto fitStatusColumn = eppWS->getColumn(
"FitStatus");
275 checkEPPColumnsExist(peakCentreColumn, sigmaColumn, fitStatusColumn);
277 std::vector<std::string>
const componentNames =
components(*instrument);
280 for (int64_t i = 0; i < static_cast<int64_t>(componentNames.size()); ++i) {
282 auto const &componentName = componentNames[
static_cast<size_t>(i)];
283 progress.report(
"Processing " + componentName);
284 checkComponentExists(componentName, *instrument);
286 auto const wsIndexRange = componentWSIndexRange(*componentWS, *ws);
287 auto const bkgRanges = bkgFittingRanges(*componentWS, *fitStatusColumn, wsIndexRange.first);
288 if (bkgRanges.empty()) {
291 auto const bounds = peakBounds(wsIndexRange.first, wsIndexRange.last, sigmaMultiplier, *peakCentreColumn,
292 *sigmaColumn, *fitStatusColumn);
295 writeComponentBackgroundToOutput(*fittedComponentBkg, *bkgWS, wsIndexRange.first);
300 for (
size_t i = 0; i < bkgWS->getNumberHistograms(); ++i) {
301 bkgWS->convertToCounts(i);
318 mask->setProperty(
"Workspace", ws);
319 mask->setProperty(
"MaskedWorkspace", diagnosticsWS);
332 std::string
const COMPONENTS_PARAMETER{
"components-for-backgrounds"};
334 throw std::runtime_error(
"Could not find '" + COMPONENTS_PARAMETER +
335 "' in instrument parameters file. Component "
336 "names must be given using the '" +
337 Prop::COMPONENTS +
"' property.");
339 auto const componentList = instrument.
getStringParameter(COMPONENTS_PARAMETER).front();
352 std::string
const &componentName) {
354 crop->setProperty(
"InputWorkspace", ws);
355 crop->setProperty(
"OutputWorkspace",
"_unused");
356 crop->setProperty(
"ComponentNames", std::vector<std::string>{componentName});
358 return crop->getProperty(
"OutputWorkspace");
368 std::vector<double>
const &xRanges) {
369 int const degree =
getProperty(Prop::POLYNOMIAL_DEGREE);
371 calculateBkg->setProperty(
"InputWorkspace", ws);
372 calculateBkg->setProperty(
"OutputWorkspace",
"_unused");
373 calculateBkg->setProperty(
"Degree", degree);
374 calculateBkg->setProperty(
"XRanges", xRanges);
375 calculateBkg->setProperty(
"CostFunction",
"Unweighted least squares");
376 calculateBkg->setProperty(
"IgnoreInvalidData",
getPropertyValue(Prop::IGNORE_INVALID_DATA));
378 calculateBkg->execute();
379 return calculateBkg->getProperty(
"OutputWorkspace");
390 std::vector<double>
const &peakStarts,
391 std::vector<double>
const &peakEnds) {
392 HistogramData::Points wsIndices{ws.
getNumberHistograms(), HistogramData::LinearGenerator(0., 1.)};
396 HistogramData::Histogram modelHistogram{wsIndices, zeroCounts};
399 auto const peakStart = peakStarts[i];
400 auto const peakEnd = peakEnds[i];
403 double &sum = averageWS->mutableY(0)[i];
404 double &
error = averageWS->mutableE(0)[i];
405 for (
auto &histogramItem : ws.
histogram(i)) {
406 auto const center = histogramItem.center();
407 if (peakStart <= center && center <= peakEnd) {
410 sum += histogramItem.frequency();
411 auto const stdDev = histogramItem.frequencyStandardDeviation();
415 if (itemCount != 0) {
416 sum /=
static_cast<double>(itemCount);
417 error /=
static_cast<double>(itemCount);
#define DECLARE_ALGORITHM(classname)
#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_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.
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.
bool isDefault(const std::string &name) const
void setPropertyValue(const std::string &name, const std::string &value) override
Set the value of a property by string N.B.
Column is the base class for columns of TableWorkspace.
T & cell(size_t index)
Templated method for returning a value. No type checks are done.
const SpectrumInfo & spectrumInfo() const
Return a reference to the SpectrumInfo object.
Geometry::Instrument_const_sptr getInstrument() const
Returns the parameterized instrument.
specnum_t getSpectrumNo() const
Base MatrixWorkspace Abstract Class.
virtual ISpectrum & getSpectrum(const size_t index)=0
Return the underlying ISpectrum ptr at the given workspace index.
const HistogramData::HistogramE & e(const size_t index) const
virtual std::size_t getNumberHistograms() const =0
Returns the number of histograms in the workspace.
bool isDistribution() const
Are the Y-values dimensioned?
HistogramData::Histogram histogram(const size_t index) const
Returns the Histogram at the given workspace index.
HistogramData::HistogramE & mutableE(const size_t index) &
size_t getIndexFromSpectrumNumber(const specnum_t specNo) const
Given a spectrum number, find the corresponding workspace index.
HistogramData::HistogramY & mutableY(const size_t index) &
const HistogramData::HistogramY & y(const size_t index) const
Helper class for reporting progress from algorithms.
A property class for workspaces.
DirectILLTubeBackground : Fits polynomial backgrounds over the pixels of position sensitive tubes.
API::MatrixWorkspace_sptr fitComponentBackground(API::MatrixWorkspace_sptr const &ws, std::vector< double > const &xRanges)
Fits a polynomial background.
API::MatrixWorkspace_sptr applyDiagnostics(API::MatrixWorkspace_sptr ws)
Apply a mask workspace (if given) to ws.
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
int version() const override
Algorithm's version for identification.
std::map< std::string, std::string > validateInputs() override
Validate input properties.
void exec() override
Execute the algorithm.
void init() override
Initialize the algorithm's properties.
API::MatrixWorkspace_sptr cropToComponent(API::MatrixWorkspace_sptr const &ws, std::string const &componentName)
Crop a component workspace out of ws.
std::vector< std::string > components(Geometry::Instrument const &instrument)
Return a list of component names for the algorithm to process.
API::MatrixWorkspace_sptr peakExcludingAverage(const API::MatrixWorkspace &ws, std::vector< double > const &peakStarts, std::vector< double > const &peakEnds)
Average the histograms of a workspace.
const std::string category() const override
Algorithm's category for identification.
const std::vector< std::string > seeAlso() const override
Return a vector of related algorithms.
std::shared_ptr< const IComponent > getComponentByName(const std::string &cname, int nlevels=0) const override
Returns a pointer to the first component of assembly encountered with the given name.
std::vector< std::string > getStringParameter(const std::string &pname, bool recursive=true) const override
Get a parameter defined as a string.
bool hasParameter(const std::string &name, bool recursive=true) const override
Returns a boolean indicating if the component has the named parameter.
Support for a property that holds an array of values.
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.
std::shared_ptr< Column > Column_sptr
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
The exception classes used by Mantid.
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.
String constants for algorithm's properties.
@ Input
An input workspace.
@ Output
An output workspace.