14#include "MantidHistogramData/EstimatePolynomial.h"
36 "Name of input MatrixWorkspace that contains peaks.");
38 declareProperty(
"WorkspaceIndex",
EMPTY_INT(),
39 "workspace indices to have peak and background separated. "
40 "No default is taken. ");
42 declareProperty(
"SigmaConstant", 1.0,
43 "Multiplier of standard deviations of the variance for convergence of "
44 "peak elimination. Default is 1.0. ");
47 "Optional: enter a comma-separated list of the minimum and "
48 "maximum X-positions of window to fit. "
49 "The window is the same for all indices in workspace. The "
50 "length must be exactly two.");
52 std::vector<std::string> bkgdtypes{
"Flat",
"Linear",
"Quadratic"};
53 declareProperty(
"BackgroundType",
"Linear", std::make_shared<StringListValidator>(bkgdtypes),
"Type of Background.");
57 "The name of the TableWorkspace in which to store the background found "
59 "Table contains the indices of the beginning and ending of peak "
60 "and the estimated background coefficients for the constant, linear, and "
65 const auto &inpX = histogram.x();
66 const auto &inpY = histogram.y();
67 const size_t sizey = inpY.size();
100 std::vector<size_t> peak_min_max_indexes;
101 std::vector<double> bkgd3;
102 int goodfit =
findBackground(histogram, l0,
n, peak_min_max_indexes, bkgd3);
105 size_t min_peak = peak_min_max_indexes[0];
106 size_t max_peak = peak_min_max_indexes[1];
107 double a0 = bkgd3[0];
108 double a1 = bkgd3[1];
109 double a2 = bkgd3[2];
111 t << static_cast<int>(
m_inputWSIndex) <<
static_cast<int>(min_peak) <<
static_cast<int>(max_peak) << a0 << a1 << a2
132 std::vector<size_t> &peak_min_max_indexes, std::vector<double> &bkgd3) {
133 const size_t sizex = histogram.x().size();
134 const auto &inpY = histogram.y();
135 const size_t sizey = inpY.size();
140 double Ymean, Yvariance, Ysigma;
142 auto in = std::min_element(inpY.cbegin(), inpY.cend());
143 double bkg0 = inpY[in - inpY.begin()];
144 for (
size_t l = l0; l <
n; ++l) {
145 maskedY.emplace_back(inpY[l] - bkg0);
148 auto xn =
static_cast<double>(
n - l0);
149 if ((0. == xn) || (0. == xn - 1.0))
150 throw std::runtime_error(
"The number of Y values in the input workspace for the "
151 "workspace index given, minus 'l0' or minus 'l0' minus 1, is 0. This "
158 Ysigma = std::sqrt((
moment4(maskedY,
static_cast<size_t>(xn), Ymean) - (xn - 3.0) / (xn - 1.0) * Yvariance) / xn);
159 MantidVec::const_iterator it = std::max_element(maskedY.begin(), maskedY.end());
160 const size_t pos = it - maskedY.begin();
167 if (mask[1] == mask[2] && mask[2] == mask[3])
169 if (mask[0] == mask[2] && mask[2] == mask[3])
171 for (
size_t l = 2; l <
n - l0 - 3; ++l) {
172 if (mask[l - 1] == mask[l + 1] && (mask[l - 1] == mask[l - 2] || mask[l + 1] == mask[l + 2])) {
173 mask[l] = mask[l + 1];
176 if (mask[
n - l0 - 2] == mask[
n - l0 - 3] && mask[
n - l0 - 3] == mask[
n - l0 - 4])
177 mask[
n - l0 - 1] = mask[
n - l0 - 2];
178 if (mask[
n - l0 - 1] == mask[
n - l0 - 3] && mask[
n - l0 - 3] == mask[
n - l0 - 4])
179 mask[
n - l0 - 2] = mask[
n - l0 - 1];
183 vector<cont_peak> peaks;
185 peaks.emplace_back();
186 peaks.back().start = l0;
188 for (
size_t l = 1; l <
n - l0; ++l) {
189 if (mask[l] != mask[l - 1] && mask[l] == 1) {
190 peaks.emplace_back();
191 peaks.back().start = l + l0;
192 }
else if (!peaks.empty()) {
193 size_t ipeak = peaks.size() - 1;
194 if (mask[l] != mask[l - 1] && mask[l] == 0) {
195 peaks[ipeak].stop = l + l0;
197 if (inpY[l + l0] > peaks[ipeak].maxY)
198 peaks[ipeak].maxY = inpY[l + l0];
201 size_t min_peak, max_peak;
202 if (!peaks.empty()) {
203 g_log.
debug() <<
"Peaks' size = " << peaks.size() <<
" -> esitmate background. \n";
204 if (peaks.back().stop == 0)
205 peaks.back().stop =
n - 1;
206 std::sort(peaks.begin(), peaks.end(),
by_len());
209 min_peak = peaks[0].start;
211 max_peak = peaks[0].stop + sizex - sizey;
215 g_log.
debug(
"Peaks' size = 0 -> whole region assumed background");
222 double a0 = 0., a1 = 0., a2 = 0.;
226 peak_min_max_indexes.resize(2);
227 peak_min_max_indexes[0] = min_peak;
228 peak_min_max_indexes[1] = max_peak;
252 const size_t i_max,
const size_t p_min,
const size_t p_max,
253 const bool hasPeak,
double &out_bg0,
double &out_bg1,
double &out_bg2) {
256 HistogramData::estimateBackground(
m_backgroundOrder, histogram, i_min, i_max, p_min, p_max, out_bg0, out_bg1,
257 out_bg2, redux_chisq);
259 HistogramData::estimatePolynomial(
m_backgroundOrder, histogram, i_min, i_max, out_bg0, out_bg1, out_bg2,
263 g_log.
information() <<
"Estimated background: A0 = " << out_bg0 <<
", A1 = " << out_bg1 <<
", A2 = " << out_bg2
274 for (
size_t i = 0; i <
n; ++i) {
275 sum += (
X[i] - mean) * (
X[i] - mean) * (
X[i] - mean) * (
X[i] - mean);
277 sum /=
static_cast<double>(
n);
289 if (
m_inputWS->getNumberHistograms() == 1) {
292 throw runtime_error(
"WorkspaceIndex must be given. ");
294 }
else if (inpwsindex < 0 || inpwsindex >=
static_cast<int>(
m_inputWS->getNumberHistograms())) {
296 errss <<
"Input workspace " <<
m_inputWS->getName() <<
" has " <<
m_inputWS->getNumberHistograms()
297 <<
" spectra. Input workspace index " << inpwsindex <<
" is out of boundary. ";
298 throw runtime_error(errss.str());
302 std::vector<double> fitwindow =
getProperty(
"FitWindow");
307 size_t bkgdorder = 0;
332 if ((fitwindow.size() == 2) && fitwindow[0] >= fitwindow[1]) {
333 throw std::invalid_argument(
"Fit window has either wrong item number or "
334 "window value is not in ascending order.");
#define DECLARE_ALGORITHM(classname)
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.
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
Helper class for reporting progress from algorithms.
TableRow represents a row in a TableWorkspace.
A property class for workspaces.
FindPeakBackground : Calculate Zscore for a Matrix Workspace.
void estimateBackground(const HistogramData::Histogram &histogram, const size_t i_min, const size_t i_max, const size_t p_min, const size_t p_max, const bool hasPeak, double &out_bg0, double &out_bg1, double &out_bg2)
Estimate background.
void processInputProperties()
process inputs
API::MatrixWorkspace_const_sptr m_inputWS
Input workspace.
void exec() override
Implement abstract Algorithm methods.
std::vector< double > m_vecFitWindows
fit window
void setFitWindow(const std::vector< double > &window)
set fit window
double m_sigmaConstant
constant sigma
void findWindowIndex(const HistogramData::Histogram &histogram, size_t &l0, size_t &n)
find fit window's data point index
double moment4(MantidVec &X, size_t n, double mean)
Calculate 4th moment.
std::string m_backgroundType
size_t m_backgroundOrder
background order: 0 for flat, 1 for linear, 2 for quadratic
void setBackgroundOrder(size_t order)
set background order
size_t m_inputWSIndex
workspace index
API::ITableWorkspace_sptr m_outPeakTableWS
output workspace (table of result)
int findBackground(const HistogramData::Histogram &histogram, const size_t &l0, const size_t &n, std::vector< size_t > &peak_min_max_indexes, std::vector< double > &bkgd3)
main method to calculate background
void setSigma(const double &sigma)
set sigma constant
void createOutputWorkspaces()
create output workspace
This algorithm searches for peaks in a dataset.
int getIndex(const HistogramData::HistogramX &vecX, double x)
needed by FindPeaksBackground
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 information(const std::string &msg)
Logs at information level.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
Statistics getStatistics(const std::vector< TYPE > &data, const unsigned int flags=StatOptions::AllStats)
Return a statistics object for the given data set.
Helper class which provides the Collimation Length for SANS instruments.
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
std::vector< double > MantidVec
typedef for the data storage used in Mantid matrix workspaces
@ Input
An input workspace.
@ Output
An output workspace.
Simple struct to store statistics.
double standard_deviation
standard_deviation of the values