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";
1003 :
API::
Algorithm(), m_dataWS(), m_wsIndex(0), m_peakFunc(), m_bkgdFunc(), m_minFitX(0.), m_maxFitX(0.),
1004 m_minPeakX(0.), m_maxPeakX(0.), i_minFitX(0), i_maxFitX(0), i_minPeakX(0), i_maxPeakX(0), m_fitBkgdFirst(false),
1005 m_outputRawParams(false), m_userGuessedFWHM(0.), m_userPeakCentre(0.), m_minGuessedPeakWidth(0),
1006 m_maxGuessedPeakWidth(0), m_fwhmFitStep(0), m_fitWithStepPeakWidth(false), m_usePeakPositionTolerance(false),
1007 m_peakPositionTolerance(0.), m_peakParameterTableWS(), m_bkgdParameterTableWS(), m_peakParameterNames(),
1008 m_bkgdParameterNames(), m_minimizer("Levenberg-MarquardtMD"), m_bkupBkgdFunc(), m_bkupPeakFunc(),
1009 m_bestPeakFunc(), m_bestBkgdFunc(), m_bestRwp(DBL_MAX), m_finalGoodnessValue(0.), m_vecybkup(), m_vecebkup(),
1017 "Name of the input workspace for peak fitting.");
1020 "Name of the output workspace containing fitted peak.");
1023 "Name of the table workspace containing the fitted parameters. ");
1025 std::shared_ptr<BoundedValidator<int>> mustBeNonNegative = std::make_shared<BoundedValidator<int>>();
1026 mustBeNonNegative->setLower(0);
1027 declareProperty(
"WorkspaceIndex", 0, mustBeNonNegative,
"Workspace index ");
1031 declareProperty(
"PeakFunctionType",
"", std::make_shared<StringListValidator>(peakFullNames),
"Peak function type. ");
1036 "List of peak parameter values. They must have a 1-to-1 "
1037 "mapping to PeakParameterNames list. ");
1040 "Fitted peak parameter values. ");
1042 vector<string> bkgdtypes{
"Flat",
"Flat (A0)",
"Linear",
"Linear (A0, A1)",
"Quadratic",
"Quadratic (A0, A1, A2)"};
1043 declareProperty(
"BackgroundType",
"Linear", std::make_shared<StringListValidator>(bkgdtypes),
"Type of Background.");
1046 "List of background parameter names. ");
1049 "List of background parameter values. "
1050 "They must have a 1-to-1 mapping to BackgroundParameterNames list. ");
1053 "Fitted background parameter values. ");
1056 "Enter a comma-separated list of the expected X-position of "
1058 "The number of values must be 2.");
1061 "Enter a comma-separated list of expected x-position as peak range. "
1062 "The number of values must be 2.");
1065 "If true, then the algorithm will fit background first. "
1066 "And then the peak. ");
1069 "If true, then the output table workspace contains the raw "
1070 "profile parameter. "
1071 "Otherwise, the effective parameters will be written. ");
1073 auto mustBePositive = std::make_shared<BoundedValidator<int>>();
1074 mustBePositive->setLower(1);
1076 "Minimum guessed peak width for fit. It is in unit of number of pixels.");
1079 "Maximum guessed peak width for fit. It is in unit of number of pixels.");
1082 "Step of guessed peak width. It is in unit of number of pixels.");
1084 auto mustBePostiveDbl = std::make_shared<BoundedValidator<double>>();
1085 mustBePostiveDbl->setLower(DBL_MIN);
1087 "Peak position tolerance. If fitted peak's position differs "
1088 "from proposed value more than "
1089 "the given value, fit is treated as failure. ");
1091 std::array<string, 2> costFuncOptions = {{
"Chi-Square",
"Rwp"}};
1099 "Minimizer to use for fitting. Minimizers available are "
1100 "\"Levenberg-Marquardt\", \"Simplex\","
1101 "\"Conjugate gradient (Fletcher-Reeves imp.)\", \"Conjugate "
1102 "gradient (Polak-Ribiere imp.)\", \"BFGS\", and "
1103 "\"Levenberg-MarquardtMD\"");
1105 declareProperty(
"CostFunctionValue", DBL_MAX,
"Value of cost function of the fitted peak. ",
1154 vector<string> vec_funcparnames;
1156 for (
auto &funcname : funcnames) {
1158 vec_funcparnames.emplace_back(funcname);
1163 stringstream parnamess;
1164 parnamess << funcname <<
" (";
1165 vector<string> funcpars = tempfunc->getParameterNames();
1166 for (
size_t j = 0; j < funcpars.size(); ++j) {
1167 parnamess << funcpars[j];
1168 if (j != funcpars.size() - 1)
1173 vec_funcparnames.emplace_back(parnamess.str());
1176 return vec_funcparnames;
1187 m_wsIndex =
static_cast<size_t>(tempint);
1192 vector<double> fitwindow =
getProperty(
"FitWindow");
1193 if (fitwindow.size() != 2) {
1194 throw runtime_error(
"Must enter 2 and only 2 items in fit window. ");
1205 errss <<
"Minimum X (" <<
m_minFitX <<
") is larger and equal to maximum X (" <<
m_maxFitX
1206 <<
") to fit. It is not allowed. ";
1208 throw runtime_error(errss.str());
1212 vector<double> peakrange =
getProperty(
"PeakRange");
1213 if (peakrange.size() != 2) {
1214 throw runtime_error(
"Must enter 2 and only 2 items for PeakRange in fit window. ");
1220 errss <<
"Minimum peak range (" <<
m_minPeakX <<
") is larger and equal to maximum X (" <<
m_maxPeakX
1221 <<
") of the range of peak. It is not allowed. ";
1223 throw runtime_error(errss.str());
1228 g_log.
warning() <<
"Minimum peak range is out side of the lower boundary "
1233 g_log.
warning() <<
"Maximum peak range is out side of the upper boundary "
1249 std::stringstream errss;
1250 errss <<
"User specified wrong guessed peak width parameters (must be "
1251 "postive and make sense). "
1255 throw std::runtime_error(errss.str());
1268 if (costfunname ==
"Chi-Square") {
1270 }
else if (costfunname ==
"Rwp") {
1273 g_log.
error() <<
"Cost function " << costfunname <<
" is not supported. "
1275 throw runtime_error(
"Cost function is not supported. ");
1294 bool usedefaultbkgdparorder =
false;
1298 if (bkgdtype ==
"Flat" || bkgdtype ==
"Linear")
1299 bkgdtype +=
"Background";
1309 throw runtime_error(
"In the non-default background parameter name mode, "
1310 "user must give out parameter names. ");
1313 vector<double> vec_bkgdparvalues =
getProperty(
"BackgroundParameterValues");
1316 errss <<
"Input background properties' arrays are incorrect: # of "
1317 "parameter names = "
1318 <<
m_bkgdParameterNames.size() <<
", # of parameter values = " << vec_bkgdparvalues.size() <<
"\n";
1320 throw runtime_error(errss.str());
1332 bool defaultparorder =
true;
1339 if (defaultparorder) {
1343 throw runtime_error(
"Peak parameter names' input is not in default mode. "
1344 "It cannot be left empty. ");
1349 vector<double> vec_peakparvalues =
getProperty(
"PeakParameterValues");
1352 errss <<
"Input peak properties' arrays are incorrect: # of parameter "
1354 <<
m_peakParameterNames.size() <<
", # of parameter values = " << vec_peakparvalues.size() <<
"\n";
1355 throw runtime_error(errss.str());
1370 size_t n = std::count(fullstring.begin(), fullstring.end(),
'(');
1372 peaktype = fullstring.substr(0, fullstring.find(
'('));
1373 boost::algorithm::trim(peaktype);
1374 defaultparorder =
true;
1376 peaktype = fullstring;
1377 defaultparorder =
false;
1389 throw runtime_error(
"Either peak function or background function has not been set up.");
1394 throw runtime_error(
"Peak centre is out side of fit window. ");
1406 const std::map<std::string, double> &m_fitErrorBkgdFunc) {
1414 const size_t nspec = 3;
1422 const size_t sizex = vecoutx.size();
1423 const auto sizey = sizex;
1424 HistogramBuilder builder;
1425 builder.setX(sizex);
1426 builder.setY(sizey);
1435 compfunc->function(domain, values);
1437 const auto domainVec = domain.
toVector();
1438 outws->mutableX(0).assign(domainVec.cbegin(), domainVec.cend());
1439 outws->setSharedX(1, outws->sharedX(0));
1440 outws->setSharedX(2, outws->sharedX(0));
1443 const auto valvec = values.
toVector();
1444 outws->mutableY(0).assign(vecY.cbegin() +
i_minFitX, vecY.cbegin() +
i_minFitX + sizey);
1445 outws->mutableY(1).assign(valvec.cbegin(), valvec.cbegin() + sizey);
1446 std::transform(outws->y(0).cbegin(), outws->y(0).cbegin() + sizey, outws->y(1).cbegin(), outws->mutableY(2).begin(),
1447 std::minus<double>());
1453 setProperty(
"ParameterTableWorkspace", peaktablews);
1456 vector<double> vec_fitpeak;
1459 [
this](
const auto &peakParameterName) { return m_peakFunc->getParameter(peakParameterName); });
1461 setProperty(
"FittedPeakParameterValues", vec_fitpeak);
1464 vector<double> vec_fitbkgd;
1467 [
this](
const auto &bkgdParameterName) { return m_bkgdFunc->getParameter(bkgdParameterName); });
1469 setProperty(
"FittedBackgroundParameterValues", vec_fitbkgd);
1481 if (
x <= vecx.front()) {
1483 }
else if (
x >= vecx.back()) {
1484 index = vecx.size() - 1;
1486 vector<double>::const_iterator fiter;
1487 fiter = lower_bound(vecx.begin(), vecx.end(),
x);
1488 index =
static_cast<size_t>(fiter - vecx.begin());
1490 throw runtime_error(
"It seems impossible to have this value. ");
1503 map<string, double> bkgderrormap) {
1506 outtablews->addColumn(
"str",
"Name");
1507 outtablews->addColumn(
"double",
"Value");
1508 outtablews->addColumn(
"double",
"Error");
1511 TableRow newrow = outtablews->appendRow();
1515 newrow = outtablews->appendRow();
1516 newrow << peakfunc->name();
1519 vector<string> peakparnames = peakfunc->getParameterNames();
1520 for (
auto &parname : peakparnames) {
1521 double parvalue = peakfunc->getParameter(parname);
1522 double error = peakerrormap[parname];
1523 newrow = outtablews->appendRow();
1524 newrow << parname << parvalue <<
error;
1527 newrow = outtablews->appendRow();
1528 newrow <<
"centre" << peakfunc->centre();
1530 newrow = outtablews->appendRow();
1531 newrow <<
"width" << peakfunc->fwhm();
1533 newrow = outtablews->appendRow();
1534 newrow <<
"height" << peakfunc->height();
1538 newrow = outtablews->appendRow();
1539 newrow << bkgdfunc->name();
1542 vector<string> bkgdparnames = bkgdfunc->getParameterNames();
1543 for (
auto &parname : bkgdparnames) {
1544 double parvalue = bkgdfunc->getParameter(parname);
1545 double error = bkgderrormap[parname];
1546 newrow = outtablews->appendRow();
1547 newrow << parname << parvalue <<
error;
1552 newrow = outtablews->appendRow();
1553 newrow <<
"backgroundintercept" << bkgdfunc->getParameter(
"A0");
1554 if (bkgdtype !=
"Flat") {
1555 newrow = outtablews->appendRow();
1556 newrow <<
"backgroundintercept" << bkgdfunc->getParameter(
"A1");
1558 if (bkgdtype ==
"Quadratic") {
1559 newrow = outtablews->appendRow();
1560 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.
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.
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.
std::map< std::string, double > getPeakError()
Get fitting error for 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 > getBackgroundError()
Get fitting error for background function.
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.
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)
size_t i_minFitX
Vector index of m_minFitX.
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.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
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
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.