27#include "MantidHistogramData/Histogram.h"
28#include "MantidHistogramData/HistogramBuilder.h"
35#include "boost/algorithm/string.hpp"
36#include "boost/algorithm/string/trim.hpp"
43using Mantid::HistogramData::HistogramX;
54 :
API::
Algorithm(), m_fitMethodSet(false), m_peakRangeSet(false), m_peakWidthSet(false), m_peakWindowSet(false),
55 m_usePeakPositionTolerance(false), m_peakFunc(), m_bkgdFunc(), m_dataWS(), m_wsIndex(0), m_minFitX(0.),
56 m_maxFitX(0.), i_minFitX(0), i_maxFitX(0), m_minPeakX(0.), m_maxPeakX(0.), i_minPeakX(0), i_maxPeakX(0),
57 m_bestPeakFunc(), m_bestBkgdFunc(), m_bkupPeakFunc(), m_bkupBkgdFunc(), m_fitErrorPeakFunc(),
58 m_fitErrorBkgdFunc(), m_minimizer(
"Levenberg-MarquardtMD"),
m_costFunction(), m_vecFWHM(),
59 m_peakPositionTolerance(0.), m_userPeakCentre(0.), m_bestRwp(0.), m_finalGoodnessValue(0.), m_numFitCalls(0),
69 throw runtime_error(
"Input dataws is null. ");
72 if (wsindex < m_dataWS->getNumberHistograms()) {
75 throw runtime_error(
"Input workspace index is out of range.");
131 if (costfunction ==
"Chi-Square") {
133 }
else if (costfunction ==
"Rwp") {
135 }
else if (costfunction ==
"Least squares") {
139 errss <<
"FitOneSinglePeak: cost function " << costfunction <<
" is not supported. ";
140 throw runtime_error(errss.str());
157 bool fitwithsteppedfwhm) {
163 m_sstream <<
"Client inputs user-defined peak width = " << usrwidth <<
"; Automatically reset to 4 as default."
166 if (!fitwithsteppedfwhm) {
167 fitwithsteppedfwhm =
true;
175 if (maxfwhm < minfwhm)
180 m_sstream <<
"Add user defined FWHM = " << usrwidth <<
"\n";
186 if (!fitwithsteppedfwhm) {
188 throw runtime_error(
"Logic error in setup guessed FWHM. ");
189 m_sstream <<
"No FWHM is not guessed by stepped FWHM. "
197 int i_maxindex =
static_cast<int>(vecX.size()) - 1;
199 m_sstream <<
"FWHM to guess. Range = " << minfwhm <<
", " << maxfwhm <<
"; Step = " << stepsize <<
"\n";
200 if (stepsize == 0 || maxfwhm < minfwhm)
201 throw runtime_error(
"FWHM is not given right.");
203 for (
int iwidth = minfwhm; iwidth <= maxfwhm; iwidth += stepsize) {
206 int ileftside = i_centre - iwidth / 2;
210 int irightside = i_centre + iwidth / 2;
211 if (irightside > i_maxindex)
212 irightside = i_maxindex;
214 double in_fwhm = vecX[irightside] - vecX[ileftside];
216 if (in_fwhm < 1.0E-20) {
217 m_sstream <<
"It is impossible to have zero peak width as iCentre = " << i_centre <<
", iWidth = " << iwidth
219 <<
"More information: Spectrum = " <<
m_wsIndex <<
"; Range of X is " << vecX.front() <<
", "
220 << vecX.back() <<
"; Peak centre = " << vecX[i_centre] <<
"\n";
222 m_sstream <<
"Setup: i_width = " << iwidth <<
", i_left = " << ileftside <<
", i_right = " << irightside
223 <<
", FWHM = " << in_fwhm <<
", i_centre = " << i_centre <<
".\n";
241 if (peakpostol < 1.0E-13)
242 g_log.
warning(
"Peak position tolerance is very tight. ");
253 errmsg +=
"Fitting method ";
255 errmsg +=
"Peak range ";
257 errmsg +=
"Peak width ";
259 errmsg +=
"Peak function ";
261 errmsg +=
"Background function ";
263 errmsg +=
"Data workspace ";
265 if (!errmsg.empty()) {
266 errmsg =
"These parameters have not been set for fitting peak: " + errmsg;
286 throw runtime_error(
"Object has not been set up completely to fit peak.");
297 m_sstream <<
"One-Step-Fit Function: " << compfunc->asString() <<
"\n";
308 for (
size_t i = 0; i < numfits; ++i) {
318 if (i != numfits - 1) {
332 m_sstream <<
"One-Step-Fit Best (Chi^2 = " <<
m_bestRwp <<
") Fitted Function: " << compfunc->asString() <<
"\n"
348 if (ishift >= vecY.size())
351 HistogramBuilder builder;
358 auto &dataX = purePeakWS->mutableX(0);
359 auto &dataY = purePeakWS->mutableY(0);
360 auto &dataE = purePeakWS->mutableE(0);
363 if (ishift < vecY.size()) {
367 dataY.assign(vecY.cbegin() +
i_minFitX, vecY.cend());
368 dataE.assign(vecE.cbegin() +
i_minFitX, vecE.cend());
381 double peakcentre = peakfunc->centre();
382 vector<double> svvec(1, peakcentre);
385 peakfunc->function(svdomain, svvalues);
386 double curpeakheight = svvalues[0];
388 const auto &vecX = dataws->x(wsindex);
389 const auto &vecY = dataws->y(wsindex);
390 double ymax = vecY[ixmin + 1];
391 size_t iymax = ixmin + 1;
392 for (
size_t i = ixmin + 2; i < ixmax; ++i) {
393 double tempy = vecY[i];
400 m_sstream <<
"Estimate-Peak-Height: Current peak height = " << curpeakheight
401 <<
". Estimate-Peak-Height: Maximum Y value between " << vecX[ixmin] <<
" and " << vecX[ixmax] <<
" is "
402 << ymax <<
" at X = " << vecX[iymax] <<
".\n";
405 double estheight = ymax / curpeakheight * peakfunc->height();
417 auto &vecX = purePeakWS->x(0);
423 purePeakWS->mutableE(0).assign(purePeakWS->y(0).size(), 1.0);
425 std::transform(purePeakWS->y(0).cbegin(), purePeakWS->y(0).cend(), purePeakWS->mutableY(0).begin(),
426 [=](
const double &
y)
mutable {
427 double newY = y - bkgdvalues[i++];
428 return std::max(0.0, newY);
440 size_t wsindex,
double startx,
double endx) {
443 throw std::runtime_error(
"fitPeakFunction's input peakfunc has not been initialized.");
445 m_sstream <<
"Function (to fit): " << peakfunc->asString() <<
" From " << startx <<
" to " << endx <<
".\n";
447 double goodness =
fitFunctionSD(peakfunc, dataws, wsindex, startx, endx);
466 throw runtime_error(
"Object has not been set up completely to fit peak.");
468 m_sstream <<
"F1158: Well-setup and good to go!\n";
477 outss <<
"User specified peak range cannot be trusted! Because peak range "
478 "overlap fit window. "
480 <<
". A UNRELIABLE algorithm is used to guess peak range. ";
484 auto shift =
static_cast<size_t>(
static_cast<double>(numpts) / 6.);
517 for (
size_t i = 0; i <
m_vecFWHM.size(); ++i) {
529 m_sstream <<
"Fit peak function cost = " << rwp <<
"\n";
555 std::map<std::string, double> funcparammap;
558 vector<string> funcparnames = func->getParameterNames();
559 size_t nParam = funcparnames.size();
560 for (
size_t i = 0; i < nParam; ++i) {
561 double parvalue = func->getParameter(i);
562 funcparammap.emplace(funcparnames[i], parvalue);
576 std::map<std::string, double> paramerrormap;
579 vector<string> funcparnames = func->getParameterNames();
580 size_t nParam = funcparnames.size();
581 for (
size_t i = 0; i < nParam; ++i) {
582 double parerror = func->getError(i);
583 paramerrormap.emplace(funcparnames[i], parerror);
586 return paramerrormap;
593 std::map<std::string, double>::const_iterator miter;
594 for (miter = funcparammap.begin(); miter != funcparammap.end(); ++miter) {
595 string parname = miter->first;
596 double parvalue = miter->second;
597 func->setParameter(parname, parvalue);
612 size_t wsindex,
double xmin,
double xmax) {
618 std::stringstream errss;
619 errss <<
"The FitPeak algorithm requires the CurveFitting library";
621 throw std::runtime_error(errss.str());
625 fit->setProperty(
"Function", fitfunc);
626 fit->setProperty(
"InputWorkspace", dataws);
627 fit->setProperty(
"WorkspaceIndex",
static_cast<int>(wsindex));
628 fit->setProperty(
"StartX", xmin);
629 fit->setProperty(
"EndX", xmax);
631 fit->executeAsChildAlg();
632 if (!fit->isExecuted()) {
633 g_log.
error(
"Fit for background is not executed. ");
634 throw std::runtime_error(
"Fit for background is not executed. ");
638 const double chi2 = fit->getProperty(
"ChiSquaredWeightedDividedByNData");
651 double xmin,
double xmax) {
657 std::stringstream errss;
658 errss <<
"The FitPeak algorithm requires the CurveFitting library";
660 throw std::runtime_error(errss.str());
664 fit->setProperty(
"Function", fitfunc);
665 fit->setProperty(
"InputWorkspace", dataws);
666 fit->setProperty(
"WorkspaceIndex",
static_cast<int>(wsindex));
667 fit->setProperty(
"MaxIterations", 50);
668 fit->setProperty(
"StartX", xmin);
669 fit->setProperty(
"EndX", xmax);
672 fit->setProperty(
"CalcErrors",
true);
675 m_sstream <<
"FitSingleDomain: " << fit->asString() <<
".\n";
677 fit->executeAsChildAlg();
678 if (!fit->isExecuted()) {
679 g_log.
error(
"Fit for background is not executed. ");
680 throw std::runtime_error(
"Fit for background is not executed. ");
685 std::string fitStatus = fit->getProperty(
"OutputStatus");
687 if (fitStatus ==
"success") {
688 chi2 = fit->getProperty(
"OutputChi2overDoF");
689 fitfunc = fit->getProperty(
"Function");
693 m_sstream <<
"[F1201] FitSingleDomain Fitted-Function " << fitfunc->asString() <<
": Fit-status = " << fitStatus
694 <<
", chi^2 = " << chi2 <<
".\n";
708 size_t wsindex, vector<double> vec_xmin, vector<double> vec_xmax) {
710 if (vec_xmin.size() != vec_xmax.size())
711 throw runtime_error(
"Sizes of xmin and xmax (vectors) are not equal. ");
718 std::stringstream errss;
719 errss <<
"The FitPeak algorithm requires the CurveFitting library";
721 throw std::runtime_error(errss.str());
725 std::shared_ptr<MultiDomainFunction> funcmd = std::make_shared<MultiDomainFunction>();
731 funcmd->setAttributeValue(
"NumDeriv",
false);
734 funcmd->addFunction(fitfunc);
737 funcmd->clearDomainIndices();
738 std::vector<size_t> ii(2);
741 funcmd->setDomainIndices(0, ii);
744 fit->setProperty(
"Function", std::dynamic_pointer_cast<IFunction>(funcmd));
745 fit->setProperty(
"InputWorkspace", dataws);
746 fit->setProperty(
"WorkspaceIndex",
static_cast<int>(wsindex));
747 fit->setProperty(
"StartX", vec_xmin[0]);
748 fit->setProperty(
"EndX", vec_xmax[0]);
749 fit->setProperty(
"InputWorkspace_1", dataws);
750 fit->setProperty(
"WorkspaceIndex_1",
static_cast<int>(wsindex));
751 fit->setProperty(
"StartX_1", vec_xmin[1]);
752 fit->setProperty(
"EndX_1", vec_xmax[1]);
753 fit->setProperty(
"MaxIterations", 50);
755 fit->setProperty(
"CostFunction",
"Least squares");
757 m_sstream <<
"FitMultiDomain: Funcion " << funcmd->name() <<
": "
758 <<
"Range: (" << vec_xmin[0] <<
", " << vec_xmax[0] <<
") and (" << vec_xmin[1] <<
", " << vec_xmax[1]
759 <<
"); " << funcmd->asString() <<
"\n";
763 if (!fit->isExecuted()) {
764 throw runtime_error(
"Fit is not executed on multi-domain function/data. ");
769 std::string fitStatus = fit->getProperty(
"OutputStatus");
770 m_sstream <<
"[DB] Multi-domain fit status: " << fitStatus <<
".\n";
773 if (fitStatus ==
"success") {
774 chi2 = fit->getProperty(
"OutputChi2overDoF");
775 m_sstream <<
"FitMultidomain: Successfully-Fitted Function " << fitfunc->asString() <<
", Chi^2 = " << chi2 <<
"\n";
796 std::shared_ptr<CompositeFunction> compfunc = std::make_shared<CompositeFunction>();
797 compfunc->addFunction(peakfunc);
798 compfunc->addFunction(bkgdfunc);
803 double backRwp =
calChiSquareSD(bkgdfunc, dataws, wsindex, startx, endx);
804 m_sstream <<
"Background: Pre-fit Goodness = " << backRwp <<
"\n";
808 auto bkuppeakmap =
backup(peakfunc);
809 auto bkupbkgdmap =
backup(bkgdfunc);
814 double goodness =
fitFunctionSD(compfunc, dataws, wsindex, startx, endx);
820 if (!errorreason.empty())
821 m_sstream <<
"Error reason of fit peak+background composite: " << errorreason <<
"\n";
823 double goodness_final = DBL_MAX;
824 if (goodness <=
m_bestRwp && goodness <= backRwp) {
826 goodness_final = goodness;
830 m_sstream <<
"Fit peak/background composite function FAILS to render a "
832 <<
"Input cost function value = " <<
m_bestRwp <<
", output cost function value = " << goodness <<
"\n";
834 pop(bkuppeakmap, peakfunc);
835 pop(bkupbkgdmap, bkgdfunc);
838 m_sstream <<
"Fit peak-background function fails in all approaches! \n";
841 return goodness_final;
849 std::string &errorreason) {
850 if (costfuncvalue < DBL_MAX) {
852 stringstream errorss;
853 double peakcentre = peakfunc->centre();
854 if (peakcentre < m_minPeakX || peakcentre >
m_maxPeakX) {
855 errorss <<
"Peak centre (at " << peakcentre <<
" ) is out of specified range )" <<
m_minPeakX <<
", "
857 costfuncvalue = DBL_MAX;
860 double peakheight = peakfunc->height();
861 if (peakheight < 0) {
862 errorss <<
"Peak height (" << peakheight <<
") is negative. ";
863 costfuncvalue = DBL_MAX;
865 double peakfwhm = peakfunc->fwhm();
867 errorss <<
"Peak width is unreasonably wide. ";
868 costfuncvalue = DBL_MAX;
870 errorreason = errorss.str();
873 errorreason =
"Fit() on peak function is NOT successful.";
876 return costfuncvalue;
889 vector<double> vec_xmin(2);
890 vector<double> vec_xmax(2);
898 if (chi2 < DBL_MAX - 1) {
916 bool fitsuccess =
true;
924 if (f_height <= 0.) {
926 failreason +=
"Negative peak height. ";
936 failreason =
"Peak centre out of tolerance. ";
939 }
else if (f_centre < m_minPeakX || f_centre >
m_maxPeakX) {
941 failreason +=
"Peak centre out of input peak range ";
948 failreason =
"(Single-step) Fit returns a DBL_MAX.";
953 <<
"Rwp = " << rwp <<
", best Rwp = " <<
m_bestRwp <<
", Fit success = " << fitsuccess <<
". ";
966 }
else if (!fitsuccess) {
967 m_sstream <<
"Reason of fit's failure: " << failreason <<
"\n";
992 :
API::
Algorithm(), m_dataWS(), m_wsIndex(0), m_peakFunc(), m_bkgdFunc(), m_minFitX(0.), m_maxFitX(0.),
993 m_minPeakX(0.), m_maxPeakX(0.), i_minFitX(0), i_maxFitX(0), i_minPeakX(0), i_maxPeakX(0), m_fitBkgdFirst(false),
994 m_outputRawParams(false), m_userGuessedFWHM(0.), m_userPeakCentre(0.), m_minGuessedPeakWidth(0),
995 m_maxGuessedPeakWidth(0), m_fwhmFitStep(0), m_fitWithStepPeakWidth(false), m_usePeakPositionTolerance(false),
996 m_peakPositionTolerance(0.), m_peakParameterTableWS(), m_bkgdParameterTableWS(), m_peakParameterNames(),
997 m_bkgdParameterNames(), m_minimizer("Levenberg-MarquardtMD"), m_bkupBkgdFunc(), m_bkupPeakFunc(),
998 m_bestPeakFunc(), m_bestBkgdFunc(), m_bestRwp(DBL_MAX), m_finalGoodnessValue(0.), m_vecybkup(), m_vecebkup(),
1006 "Name of the input workspace for peak fitting.");
1009 "Name of the output workspace containing fitted peak.");
1012 "Name of the table workspace containing the fitted parameters. ");
1014 std::shared_ptr<BoundedValidator<int>> mustBeNonNegative = std::make_shared<BoundedValidator<int>>();
1015 mustBeNonNegative->setLower(0);
1016 declareProperty(
"WorkspaceIndex", 0, mustBeNonNegative,
"Workspace index ");
1018 std::vector<std::string> peakNames = FunctionFactory::Instance().getFunctionNames<
IPeakFunction>();
1020 declareProperty(
"PeakFunctionType",
"", std::make_shared<StringListValidator>(peakFullNames),
"Peak function type. ");
1025 "List of peak parameter values. They must have a 1-to-1 "
1026 "mapping to PeakParameterNames list. ");
1029 "Fitted peak parameter values. ");
1031 vector<string> bkgdtypes{
"Flat",
"Flat (A0)",
"Linear",
"Linear (A0, A1)",
"Quadratic",
"Quadratic (A0, A1, A2)"};
1032 declareProperty(
"BackgroundType",
"Linear", std::make_shared<StringListValidator>(bkgdtypes),
"Type of Background.");
1035 "List of background parameter names. ");
1038 "List of background parameter values. "
1039 "They must have a 1-to-1 mapping to BackgroundParameterNames list. ");
1042 "Fitted background parameter values. ");
1045 "Enter a comma-separated list of the expected X-position of "
1047 "The number of values must be 2.");
1050 "Enter a comma-separated list of expected x-position as peak range. "
1051 "The number of values must be 2.");
1054 "If true, then the algorithm will fit background first. "
1055 "And then the peak. ");
1058 "If true, then the output table workspace contains the raw "
1059 "profile parameter. "
1060 "Otherwise, the effective parameters will be written. ");
1062 auto mustBePositive = std::make_shared<BoundedValidator<int>>();
1063 mustBePositive->setLower(1);
1065 "Minimum guessed peak width for fit. It is in unit of number of pixels.");
1068 "Maximum guessed peak width for fit. It is in unit of number of pixels.");
1071 "Step of guessed peak width. It is in unit of number of pixels.");
1073 auto mustBePostiveDbl = std::make_shared<BoundedValidator<double>>();
1074 mustBePostiveDbl->setLower(DBL_MIN);
1076 "Peak position tolerance. If fitted peak's position differs "
1077 "from proposed value more than "
1078 "the given value, fit is treated as failure. ");
1080 std::array<string, 2> costFuncOptions = {{
"Chi-Square",
"Rwp"}};
1084 std::vector<std::string> minimizerOptions = API::FuncMinimizerFactory::Instance().getKeys();
1088 "Minimizer to use for fitting. Minimizers available are "
1089 "\"Levenberg-Marquardt\", \"Simplex\","
1090 "\"Conjugate gradient (Fletcher-Reeves imp.)\", \"Conjugate "
1091 "gradient (Polak-Ribiere imp.)\", \"BFGS\", and "
1092 "\"Levenberg-MarquardtMD\"");
1094 declareProperty(
"CostFunctionValue", DBL_MAX,
"Value of cost function of the fitted peak. ",
1143 vector<string> vec_funcparnames;
1145 for (
auto &funcname : funcnames) {
1147 vec_funcparnames.emplace_back(funcname);
1150 IFunction_sptr tempfunc = FunctionFactory::Instance().createFunction(funcname);
1152 stringstream parnamess;
1153 parnamess << funcname <<
" (";
1154 vector<string> funcpars = tempfunc->getParameterNames();
1155 for (
size_t j = 0; j < funcpars.size(); ++j) {
1156 parnamess << funcpars[j];
1157 if (j != funcpars.size() - 1)
1162 vec_funcparnames.emplace_back(parnamess.str());
1165 return vec_funcparnames;
1176 m_wsIndex =
static_cast<size_t>(tempint);
1181 vector<double> fitwindow =
getProperty(
"FitWindow");
1182 if (fitwindow.size() != 2) {
1183 throw runtime_error(
"Must enter 2 and only 2 items in fit window. ");
1194 errss <<
"Minimum X (" <<
m_minFitX <<
") is larger and equal to maximum X (" <<
m_maxFitX
1195 <<
") to fit. It is not allowed. ";
1197 throw runtime_error(errss.str());
1201 vector<double> peakrange =
getProperty(
"PeakRange");
1202 if (peakrange.size() != 2) {
1203 throw runtime_error(
"Must enter 2 and only 2 items for PeakRange in fit window. ");
1209 errss <<
"Minimum peak range (" <<
m_minPeakX <<
") is larger and equal to maximum X (" <<
m_maxPeakX
1210 <<
") of the range of peak. It is not allowed. ";
1212 throw runtime_error(errss.str());
1217 g_log.
warning() <<
"Minimum peak range is out side of the lower boundary "
1222 g_log.
warning() <<
"Maximum peak range is out side of the upper boundary "
1238 std::stringstream errss;
1239 errss <<
"User specified wrong guessed peak width parameters (must be "
1240 "postive and make sense). "
1244 throw std::runtime_error(errss.str());
1257 if (costfunname ==
"Chi-Square") {
1259 }
else if (costfunname ==
"Rwp") {
1262 g_log.
error() <<
"Cost function " << costfunname <<
" is not supported. "
1264 throw runtime_error(
"Cost function is not supported. ");
1283 bool usedefaultbkgdparorder =
false;
1287 if (bkgdtype ==
"Flat" || bkgdtype ==
"Linear")
1288 bkgdtype +=
"Background";
1291 m_bkgdFunc = std::dynamic_pointer_cast<IBackgroundFunction>(FunctionFactory::Instance().createFunction(bkgdtype));
1298 throw runtime_error(
"In the non-default background parameter name mode, "
1299 "user must give out parameter names. ");
1302 vector<double> vec_bkgdparvalues =
getProperty(
"BackgroundParameterValues");
1305 errss <<
"Input background properties' arrays are incorrect: # of "
1306 "parameter names = "
1307 <<
m_bkgdParameterNames.size() <<
", # of parameter values = " << vec_bkgdparvalues.size() <<
"\n";
1309 throw runtime_error(errss.str());
1321 bool defaultparorder =
true;
1323 m_peakFunc = std::dynamic_pointer_cast<IPeakFunction>(FunctionFactory::Instance().createFunction(peaktype));
1328 if (defaultparorder) {
1332 throw runtime_error(
"Peak parameter names' input is not in default mode. "
1333 "It cannot be left empty. ");
1338 vector<double> vec_peakparvalues =
getProperty(
"PeakParameterValues");
1341 errss <<
"Input peak properties' arrays are incorrect: # of parameter "
1343 <<
m_peakParameterNames.size() <<
", # of parameter values = " << vec_peakparvalues.size() <<
"\n";
1344 throw runtime_error(errss.str());
1359 size_t n = std::count(fullstring.begin(), fullstring.end(),
'(');
1361 peaktype = fullstring.substr(0, fullstring.find(
'('));
1362 boost::algorithm::trim(peaktype);
1363 defaultparorder =
true;
1365 peaktype = fullstring;
1366 defaultparorder =
false;
1378 throw runtime_error(
"Either peak function or background function has not been set up.");
1383 throw runtime_error(
"Peak centre is out side of fit window. ");
1395 const std::map<std::string, double> &m_fitErrorBkgdFunc) {
1403 const size_t nspec = 3;
1406 vector<double> vecoutx(indexMaxFitX - indexMinFitX + 1);
1407 for (
size_t i = indexMinFitX; i <=
i_maxFitX; ++i)
1408 vecoutx[i - indexMinFitX] = vecX[i];
1411 const size_t sizex = vecoutx.size();
1412 const auto sizey = sizex;
1413 HistogramBuilder builder;
1414 builder.setX(sizex);
1415 builder.setY(sizey);
1424 compfunc->function(domain, values);
1426 const auto domainVec = domain.
toVector();
1427 outws->mutableX(0).assign(domainVec.cbegin(), domainVec.cend());
1428 outws->setSharedX(1, outws->sharedX(0));
1429 outws->setSharedX(2, outws->sharedX(0));
1432 const auto valvec = values.
toVector();
1433 outws->mutableY(0).assign(vecY.cbegin() + indexMinFitX, vecY.cbegin() + indexMinFitX + sizey);
1434 outws->mutableY(1).assign(valvec.cbegin(), valvec.cbegin() + sizey);
1435 std::transform(outws->y(0).cbegin(), outws->y(0).cbegin() + sizey, outws->y(1).cbegin(), outws->mutableY(2).begin(),
1436 std::minus<double>());
1442 setProperty(
"ParameterTableWorkspace", peaktablews);
1445 vector<double> vec_fitpeak;
1448 [
this](
const auto &peakParameterName) { return m_peakFunc->getParameter(peakParameterName); });
1450 setProperty(
"FittedPeakParameterValues", vec_fitpeak);
1453 vector<double> vec_fitbkgd;
1456 [
this](
const auto &bkgdParameterName) { return m_bkgdFunc->getParameter(bkgdParameterName); });
1458 setProperty(
"FittedBackgroundParameterValues", vec_fitbkgd);
1470 if (
x <= vecx.front()) {
1472 }
else if (
x >= vecx.back()) {
1473 index = vecx.size() - 1;
1475 vector<double>::const_iterator fiter;
1476 fiter = lower_bound(vecx.begin(), vecx.end(),
x);
1477 index =
static_cast<size_t>(fiter - vecx.begin());
1479 throw runtime_error(
"It seems impossible to have this value. ");
1492 map<string, double> bkgderrormap) {
1495 outtablews->addColumn(
"str",
"Name");
1496 outtablews->addColumn(
"double",
"Value");
1497 outtablews->addColumn(
"double",
"Error");
1500 TableRow newrow = outtablews->appendRow();
1504 newrow = outtablews->appendRow();
1505 newrow << peakfunc->name();
1508 vector<string> peakparnames = peakfunc->getParameterNames();
1509 for (
auto &parname : peakparnames) {
1510 double parvalue = peakfunc->getParameter(parname);
1511 double error = peakerrormap[parname];
1512 newrow = outtablews->appendRow();
1513 newrow << parname << parvalue <<
error;
1516 newrow = outtablews->appendRow();
1517 newrow <<
"centre" << peakfunc->centre();
1519 newrow = outtablews->appendRow();
1520 newrow <<
"width" << peakfunc->fwhm();
1522 newrow = outtablews->appendRow();
1523 newrow <<
"height" << peakfunc->height();
1527 newrow = outtablews->appendRow();
1528 newrow << bkgdfunc->name();
1531 vector<string> bkgdparnames = bkgdfunc->getParameterNames();
1532 for (
auto &parname : bkgdparnames) {
1533 double parvalue = bkgdfunc->getParameter(parname);
1534 double error = bkgderrormap[parname];
1535 newrow = outtablews->appendRow();
1536 newrow << parname << parvalue <<
error;
1541 newrow = outtablews->appendRow();
1542 newrow <<
"backgroundintercept" << bkgdfunc->getParameter(
"A0");
1543 if (bkgdtype !=
"Flat") {
1544 newrow = outtablews->appendRow();
1545 newrow <<
"backgroundintercept" << bkgdfunc->getParameter(
"A1");
1547 if (bkgdtype ==
"Quadratic") {
1548 newrow = outtablews->appendRow();
1549 newrow <<
"A2" << bkgdfunc->getParameter(
"A2");
#define DECLARE_ALGORITHM(classname)
CostFunctions::CostFuncFitting & m_costFunction
The cost function.
std::map< DeltaEMode::Type, std::string > index
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.
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.
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
Implements FunctionDomain1D with its own storage in form of a std::vector.
std::vector< double > toVector() const
Convert to a vector.
A class to store values calculated by a function.
const std::vector< double > & toVector() const
Return the calculated values as a vector.
An interface to a peak function, which extend the interface of IFunctionWithLocation by adding method...
Helper class for reporting progress from algorithms.
TableRow represents a row in a TableWorkspace.
A property class for workspaces.
FitOneSinglePeak: a class to perform peak fitting on a single peak.
std::map< std::string, double > m_bestBkgdFunc
Best background parameters.
void setPeakRange(double xpeakleft, double xpeakright)
Set peak range.
double m_finalGoodnessValue
Final goodness value (Rwp/Chi-square)
void setupGuessedFWHM(double usrwidth, int minfwhm, int maxfwhm, int stepsize, bool fitwithsteppedfwhm)
Set peak width to guess.
void processNStoreFitResult(double rwp, bool storebkgd)
Process and store fit result.
double fitPeakFunction(const API::IPeakFunction_sptr &peakfunc, const API::MatrixWorkspace_sptr &dataws, size_t wsindex, double startx, double endx)
Fit peak function (flexible)
size_t m_wsIndex
Input worskpace index.
std::string m_minimizer
Minimzer.
void pop(const std::map< std::string, double > &funcparammap, const API::IFunction_sptr &func)
Restore the parameters value to a function from a string/double map.
std::string getDebugMessage()
Get debug message.
double estimatePeakHeight(const API::IPeakFunction_const_sptr &peakfunc, const API::MatrixWorkspace_sptr &dataws, size_t wsindex, size_t ixmin, size_t ixmax)
Estimate the peak height from a set of data containing pure peaks.
FitOneSinglePeak()
Constructor.
const std::map< std::string, double > & getPeakError() const
Get fitting error for peak function.
double checkFittedPeak(const API::IPeakFunction_sptr &peakfunc, double costfuncvalue, std::string &errorreason)
Check a peak function whether it is valid comparing to user specified criteria.
void setFunctions(const API::IPeakFunction_sptr &peakfunc, const API::IBackgroundFunction_sptr &bkgdfunc)
Set functions.
double m_maxPeakX
peak right boundary (client-defined)
API::IPeakFunction_sptr m_peakFunc
Peak function.
API::IBackgroundFunction_sptr fitBackground(API::IBackgroundFunction_sptr bkgdfunc)
Fit background of a given peak in a given range.
bool m_peakRangeSet
Flag whether the peak range is set.
void init() override
Init.
std::map< std::string, double > m_bkupBkgdFunc
Backed up background function parameters.
void exec() override
Exec.
double fitFunctionSD(API::IFunction_sptr fitfunc, const API::MatrixWorkspace_sptr &dataws, size_t wsindex, double xmin, double xmax)
Fit function in single domain.
double calChiSquareSD(const API::IFunction_sptr &fitfunc, const API::MatrixWorkspace_sptr &dataws, size_t wsindex, double xmin, double xmax)
Calculate chi-square of a single domain function.
API::MatrixWorkspace_sptr m_dataWS
Input data workspace.
std::map< std::string, double > m_bkupPeakFunc
Backed up peak function parameters.
std::map< std::string, double > storeFunctionError(const API::IFunction_const_sptr &func)
Store function fitting error.
double m_peakPositionTolerance
Peak position tolerance.
std::map< std::string, double > m_fitErrorBkgdFunc
Fit error of background function.
bool hasSetupToFitPeak(std::string &errmsg)
Check whether it is ready to fit.
std::map< std::string, double > backup(const API::IFunction_const_sptr &func)
Back up fit result.
const std::map< std::string, double > & getBackgroundError() const
Get fitting error for background function.
std::map< std::string, double > m_fitErrorPeakFunc
Fit error of peak function.
bool m_peakWindowSet
Peak widnow is set up.
API::IBackgroundFunction_sptr m_bkgdFunc
Background function.
size_t i_maxFitX
index of m_maxFitX
std::map< std::string, double > m_bestPeakFunc
Best peak parameters.
std::stringstream m_sstream
String stream.
double m_userPeakCentre
Peak centre provided by user.
void highBkgdFit()
Fit peak first considering high background.
bool simpleFit()
Fit peak and background together.
bool m_usePeakPositionTolerance
Flag to apply peak position tolerance.
void setFittingMethod(std::string minimizer, const std::string &costfunction)
Set fitting method.
void setFitPeakCriteria(bool usepeakpostol, double peakpostol)
Set fitted peak parameters' criterial including (a) peak position tolerance to the given one,...
void setFitWindow(double leftwindow, double rightwindow)
Set fit range.
double m_minFitX
Lower boundary of fitting range.
bool m_peakWidthSet
Flag whether the peak width is set.
std::string m_costFunction
Cost function.
double fitFunctionMD(const API::IFunction_sptr &fitfunc, const API::MatrixWorkspace_sptr &dataws, size_t wsindex, std::vector< double > vec_xmin, std::vector< double > vec_xmax)
Fit function in multiple-domain.
double m_maxFitX
Upper boundary of fitting range.
size_t i_maxPeakX
index of m_maxPeakX
API::MatrixWorkspace_sptr genFitWindowWS()
Generate a partial workspace at fit window.
double m_minPeakX
peak left boundary (client-defined)
std::vector< double > m_vecFWHM
bool m_fitMethodSet
Flag to show whether fitting parameters are set.
double fitCompositeFunction(const API::IPeakFunction_sptr &peakfunc, const API::IBackgroundFunction_sptr &bkgdfunc, const API::MatrixWorkspace_sptr &dataws, size_t wsindex, double startx, double endx)
Fit peak and background composite function.
size_t i_minFitX
index of m_minFitX
size_t i_minPeakX
index of m_minPeakX
void setWorskpace(const API::MatrixWorkspace_sptr &dataws, size_t wsindex)
Set workspaces.
void removeBackground(const API::MatrixWorkspace_sptr &purePeakWS)
remove background
double getFitCostFunctionValue()
Get cost function value from fitting.
FitPeak : Fit a single peak.
size_t i_maxFitX
Vector index of m_maxFitX.
std::string m_minimizer
Minimizer.
bool m_fitBkgdFirst
fitting strategy
double m_minFitX
Minimum fit position.
double m_maxFitX
Maximum fit position.
DataObjects::TableWorkspace_sptr genOutputTableWS(const API::IPeakFunction_sptr &peakfunc, std::map< std::string, double > peakerrormap, const API::IBackgroundFunction_sptr &bkgdfunc, std::map< std::string, double > bkgderrormap)
Generate table workspace.
bool m_usePeakPositionTolerance
Use peak position tolerance as a criterial for peak fit.
bool m_fitWithStepPeakWidth
Flag about guessed FWHM (pixels)
void processProperties()
Process input propeties.
void createFunctions()
Create functions.
API::MatrixWorkspace_sptr m_dataWS
Input data workspace.
double m_maxPeakX
Maximum peak position.
std::vector< std::string > m_bkgdParameterNames
Background.
std::string parseFunctionTypeFull(const std::string &fullstring, bool &defaultparorder)
Parse peak type from full peak type/parameter names string.
std::vector< std::string > addFunctionParameterNames(const std::vector< std::string > &funcnames)
Add function's parameter names after peak function name.
void init() override
Declare properties.
int m_fwhmFitStep
Step width of tried FWHM.
void exec() override
Declare properties.
int m_maxGuessedPeakWidth
Maximum guessed peak width (pixels)
API::IBackgroundFunction_sptr m_bkgdFunc
Background function.
double m_minPeakX
Minimum peak position.
double m_peakPositionTolerance
Tolerance on peak positions as criteria.
double m_finalGoodnessValue
Final.
API::IPeakFunction_sptr m_peakFunc
Peak function.
std::string m_costFunction
bool m_outputRawParams
output option
double m_userGuessedFWHM
User guessed FWHM.
int m_minGuessedPeakWidth
Minimum guessed peak width (pixels)
void setupOutput(const std::map< std::string, double > &m_fitErrorPeakFunc, const std::map< std::string, double > &m_fitErrorBkgdFunc)
Set up the output workspaces.
std::vector< std::string > m_peakParameterNames
Peak.
void prescreenInputData()
Check the input properties and functions.
double m_userPeakCentre
User guessed peak centre.
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.
ListValidator is a validator that requires the value of a property to be one of a defined list of pos...
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
StartsWithValidator is a validator that requires the value of a property to start with one of the str...
std::shared_ptr< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm
std::shared_ptr< IBackgroundFunction > IBackgroundFunction_sptr
std::shared_ptr< IPeakFunction > IPeakFunction_sptr
std::shared_ptr< const IPeakFunction > IPeakFunction_const_sptr
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
std::shared_ptr< const IFunction > IFunction_const_sptr
shared pointer to the function base class (const version)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< CompositeFunction > CompositeFunction_sptr
shared pointer to the composite function base class
size_t getIndex(const HistogramData::HistogramX &vecx, double x)
Get an index of a value in a sorted vector.
std::shared_ptr< TableWorkspace > TableWorkspace_sptr
shared pointer to Mantid::DataObjects::TableWorkspace
MANTID_KERNEL_DLL bool withinAbsoluteDifference(T const x, T const y, S const tolerance)
Test whether x, y are within absolute tolerance tol.
std::shared_ptr< IValidator > IValidator_sptr
A shared_ptr to an IValidator.
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
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
@ Input
An input workspace.
@ Output
An output workspace.