/** * Add a new entry to the diagnosis table. * @param runTitle :: Title of the run fitted * @param fitQuality :: Number representing a goodness of the fit * @param fittedFunction :: Function containing fitted parameters */ void MuonSequentialFitDialog::addDiagnosisEntry(const std::string& runTitle, double fitQuality, IFunction_sptr fittedFunction) { int newRow = m_ui.diagnosisTable->rowCount(); m_ui.diagnosisTable->insertRow(newRow); QString runTitleDisplay = QString::fromStdString(runTitle); m_ui.diagnosisTable->setItem( newRow, 0, createTableWidgetItem(runTitleDisplay) ); QString fitQualityDisplay = QString::number(fitQuality); m_ui.diagnosisTable->setItem( newRow, 1, createTableWidgetItem(fitQualityDisplay) ); for(int i = 2; i < m_ui.diagnosisTable->columnCount(); i += 2) { std::string paramName = m_ui.diagnosisTable->horizontalHeaderItem(i)->text().toStdString(); size_t paramIndex = fittedFunction->parameterIndex(paramName); QString value = QString::number( fittedFunction->getParameter(paramIndex) ); QString error = QString::number( fittedFunction->getError(paramIndex) ); m_ui.diagnosisTable->setItem(newRow, i, createTableWidgetItem(value) ); m_ui.diagnosisTable->setItem(newRow, i + 1, createTableWidgetItem(error) ); } m_ui.diagnosisTable->scrollToBottom(); }
TEST(FunctionFactoryTest, CreateFitFunctionTest) { IFunction_sptr fun = FunctionFactory::instance().createFitFunction("FunctionFactoryTestFunction(A=10,B=20)"); EXPECT_TRUE( fun.get() != nullptr ); EXPECT_EQ(fun->getParameter("A"),10); EXPECT_EQ(fun->getParameter("B"),20); //std::cerr << fun->asString() << std::endl; }
/** Fit function * Minimizer: "Levenberg-MarquardtMD"/"Simplex" */ bool RefinePowderInstrumentParameters2::doFitFunction(IFunction_sptr function, Workspace2D_sptr dataws, int wsindex, string minimizer, int numiters, double& chi2, string& fitstatus) { // 0. Debug output stringstream outss; outss << "Fit function: " << m_positionFunc->asString() << endl << "Data To Fit: \n"; for (size_t i = 0; i < dataws->readX(0).size(); ++i) outss << dataws->readX(wsindex)[i] << "\t\t" << dataws->readY(wsindex)[i] << "\t\t" << dataws->readE(wsindex)[i] << "\n"; g_log.information() << outss.str(); // 1. Create and setup fit algorithm API::IAlgorithm_sptr fitalg = createChildAlgorithm("Fit", 0.0, 0.2, true); fitalg->initialize(); fitalg->setProperty("Function", function); fitalg->setProperty("InputWorkspace", dataws); fitalg->setProperty("WorkspaceIndex", wsindex); fitalg->setProperty("Minimizer", minimizer); fitalg->setProperty("CostFunction", "Least squares"); fitalg->setProperty("MaxIterations", numiters); fitalg->setProperty("CalcErrors", true); // 2. Fit bool successfulfit = fitalg->execute(); if (!fitalg->isExecuted() || ! successfulfit) { // Early return due to bad fit g_log.warning("Fitting to instrument geometry function failed. "); chi2 = DBL_MAX; fitstatus = "Minimizer throws exception."; return false; } // 3. Understand solution chi2 = fitalg->getProperty("OutputChi2overDoF"); string tempfitstatus = fitalg->getProperty("OutputStatus"); fitstatus = tempfitstatus; bool goodfit = fitstatus.compare("success") == 0; stringstream dbss; dbss << "Fit Result (GSL): Chi^2 = " << chi2 << "; Fit Status = " << fitstatus << ", Return Bool = " << goodfit << std::endl; vector<string> funcparnames = function->getParameterNames(); for (size_t i = 0; i < funcparnames.size(); ++i) dbss << funcparnames[i] << " = " << setw(20) << function->getParameter(funcparnames[i]) << " +/- " << function->getError(i) << "\n"; g_log.debug() << dbss.str(); return goodfit; }
/// Returns a TableWorkspace with refined cell parameters and error. ITableWorkspace_sptr PoldiFitPeaks2D::getRefinedCellParameters( const IFunction_sptr &fitFunction) const { Poldi2DFunction_sptr poldi2DFunction = boost::dynamic_pointer_cast<Poldi2DFunction>(fitFunction); if (!poldi2DFunction || poldi2DFunction->nFunctions() < 1) { throw std::invalid_argument( "Cannot process function that is not a Poldi2DFunction."); } // Create a new table for lattice parameters ITableWorkspace_sptr latticeParameterTable = WorkspaceFactory::Instance().createTable(); latticeParameterTable->addColumn("str", "Parameter"); latticeParameterTable->addColumn("double", "Value"); latticeParameterTable->addColumn("double", "Error"); // The first function should be PoldiSpectrumPawleyFunction boost::shared_ptr<PoldiSpectrumPawleyFunction> poldiPawleyFunction = boost::dynamic_pointer_cast<PoldiSpectrumPawleyFunction>( poldi2DFunction->getFunction(0)); if (!poldiPawleyFunction) { throw std::invalid_argument("First function in Poldi2DFunction is not " "PoldiSpectrumPawleyFunction."); } // Get the actual PawleyFunction to extract parameters. IPawleyFunction_sptr pawleyFunction = boost::dynamic_pointer_cast<IPawleyFunction>( poldiPawleyFunction->getDecoratedFunction()); if (pawleyFunction) { CompositeFunction_sptr pawleyParts = boost::dynamic_pointer_cast<CompositeFunction>( pawleyFunction->getDecoratedFunction()); // The first function in PawleyFunction contains the parameters IFunction_sptr pawleyParameters = pawleyParts->getFunction(0); for (size_t i = 0; i < pawleyParameters->nParams(); ++i) { TableRow newRow = latticeParameterTable->appendRow(); newRow << pawleyParameters->parameterName(i) << pawleyParameters->getParameter(i) << pawleyParameters->getError(i); } } return latticeParameterTable; }
/** Store function parameter values to a map */ void storeFunctionParameterValue(IFunction_sptr function, map<string, pair<double, double> >& parvaluemap) { parvaluemap.clear(); vector<string> parnames = function->getParameterNames(); for (size_t i = 0; i < parnames.size(); ++i) { string& parname = parnames[i]; double parvalue = function->getParameter(i); double parerror = function->getError(i); parvaluemap.insert(make_pair(parname, make_pair(parvalue, parerror))); } return; }
API::MatrixWorkspace_sptr CreateFloodWorkspace::removeBackground(API::MatrixWorkspace_sptr ws) { g_log.information() << "Remove background " << getPropertyValue(Prop::BACKGROUND) << '\n'; auto fitWS = transpose(ws); auto const &x = fitWS->x(0); // Define the fitting interval double startX = getProperty(Prop::START_X); double endX = getProperty(Prop::END_X); std::vector<double> excludeFromFit; if (isDefault(Prop::START_X)) { startX = x.front(); } else { excludeFromFit.push_back(x.front()); excludeFromFit.push_back(startX); } if (isDefault(Prop::END_X)) { endX = x.back(); } else { excludeFromFit.push_back(endX); excludeFromFit.push_back(x.back()); } // Exclude any bad detectors. for (auto i : m_excludedSpectra) { excludeFromFit.push_back(i); excludeFromFit.push_back(i); } std::string const function = getBackgroundFunction(); // Fit the data to determine unwanted background auto alg = createChildAlgorithm("Fit", 0.9, 0.99); alg->setProperty("Function", function); alg->setProperty("InputWorkspace", fitWS); alg->setProperty("WorkspaceIndex", 0); if (!excludeFromFit.empty()) { alg->setProperty("Exclude", excludeFromFit); } alg->setProperty("Output", "fit"); alg->execute(); IFunction_sptr func = alg->getProperty("Function"); g_log.information() << "Background function parameters:\n"; for (size_t i = 0; i < func->nParams(); ++i) { g_log.information() << " " << func->parameterName(i) << ": " << func->getParameter(i) << '\n'; } // Divide the workspace by the fitted curve to remove the background // and scale to values around 1 MatrixWorkspace_sptr bkgWS = alg->getProperty("OutputWorkspace"); auto const &bkg = bkgWS->y(1); auto const nHisto = static_cast<int>(ws->getNumberHistograms()); PARALLEL_FOR_IF(Kernel::threadSafe(*ws, *bkgWS)) for (int i = 0; i < nHisto; ++i) { PARALLEL_START_INTERUPT_REGION auto const xVal = x[i]; if (isExcludedSpectrum(xVal)) { ws->mutableY(i)[0] = VERY_BIG_VALUE; ws->mutableE(i)[0] = 0.0; } else if (xVal >= startX && xVal <= endX) { auto const background = bkg[i]; if (background <= 0.0) { throw std::runtime_error( "Background is expected to be positive, found value " + std::to_string(background) + " at spectrum with workspace index " + std::to_string(i)); } ws->mutableY(i)[0] /= background; ws->mutableE(i)[0] /= background; } else { ws->mutableY(i)[0] = 1.0; ws->mutableE(i)[0] = 0.0; } PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // Remove the logs ws->setSharedRun(make_cow<Run>()); return ws; }
void IqtFit::singleFitComplete(bool error) { disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(singleFitComplete(bool))); if (error) { QString msg = "There was an error executing the fitting algorithm. Please see the " "Results Log pane for more details."; showMessageBox(msg); return; } IFunction_sptr outputFunc = m_singleFitAlg->getProperty("Function"); // Get params. QMap<QString, double> parameters; std::vector<std::string> parNames = outputFunc->getParameterNames(); std::vector<double> parVals; for (size_t i = 0; i < parNames.size(); ++i) parVals.push_back(outputFunc->getParameter(parNames[i])); for (size_t i = 0; i < parNames.size(); ++i) parameters[QString(parNames[i].c_str())] = parVals[i]; m_ffRangeManager->setValue(m_properties["BackgroundA0"], parameters["f0.A0"]); const int fitType = m_uiForm.cbFitType->currentIndex(); if (fitType != 2) { // Exp 1 m_dblManager->setValue(m_properties["Exponential1.Intensity"], parameters["f1.Intensity"]); m_dblManager->setValue(m_properties["Exponential1.Tau"], parameters["f1.Tau"]); if (fitType == 1) { // Exp 2 m_dblManager->setValue(m_properties["Exponential2.Intensity"], parameters["f2.Intensity"]); m_dblManager->setValue(m_properties["Exponential2.Tau"], parameters["f2.Tau"]); } } if (fitType > 1) { // Str QString fval; if (fitType == 2) { fval = "f1."; } else { fval = "f2."; } m_dblManager->setValue(m_properties["StretchedExp.Intensity"], parameters[fval + "Intensity"]); m_dblManager->setValue(m_properties["StretchedExp.Tau"], parameters[fval + "Tau"]); m_dblManager->setValue(m_properties["StretchedExp.Beta"], parameters[fval + "Beta"]); } // Can start upddating the guess curve again connect(m_dblManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(plotGuess(QtProperty *))); // Plot the guess first so that it is under the fit plotGuess(NULL); // Now show the fitted curve of the mini plot m_uiForm.ppPlot->addSpectrum("Fit", m_singleFitOutputName + "_Workspace", 1, Qt::red); m_pythonExportWsName = ""; }