/** Calculate Chi^2 of the a function with all parameters are fixed
    */
  double RefinePowderInstrumentParameters2::calculateFunctionError(IFunction_sptr function,
                                                                   Workspace2D_sptr dataws, int wsindex)
  {
    // 1. Record the fitting information
    vector<string> parnames = function->getParameterNames();
    vector<bool> vecFix(parnames.size(), false);

    for (size_t i = 0; i < parnames.size(); ++i)
    {
      bool fixed = function->isFixed(i);
      vecFix[i] = fixed;
      if (!fixed)
        function->fix(i);
    }

    // 2. Fit with zero iteration
    double chi2;
    string fitstatus;
    doFitFunction(function, dataws, wsindex, "Levenberg-MarquardtMD", 0, chi2, fitstatus);

    // 3. Restore the fit/fix setup
    for (size_t i = 0; i < parnames.size(); ++i)
    {
      if (!vecFix[i])
        function->unfix(i);
    }

    return chi2;
  }
Пример #2
0
  /** Add function's parameter names after peak function name
    */
  std::vector<std::string> GeneratePeaks::addFunctionParameterNames(std::vector<std::string> funcnames)
  {
    std::vector<std::string> vec_funcparnames;

    for (size_t i = 0; i < funcnames.size(); ++i)
    {
      // Add original name in
      vec_funcparnames.push_back(funcnames[i]);

      // Add a full function name and parameter names in
      IFunction_sptr tempfunc = FunctionFactory::Instance().createFunction(funcnames[i]);

      std::stringstream parnamess;
      parnamess << funcnames[i] << " (";
      std::vector<std::string> funcpars = tempfunc->getParameterNames();
      for (size_t j = 0; j < funcpars.size(); ++j)
      {
        parnamess << funcpars[j];
        if (j != funcpars.size()-1)
          parnamess << ", ";
      }
      parnamess << ")";

      vec_funcparnames.push_back(parnamess.str());
    }

    return vec_funcparnames;
  }
  /** Restore function parameter values saved in a (string,double) map to a function object
    * and a (string, Parameter) map
    */
  void restoreFunctionParameterValue(map<string, pair<double, double> > parvaluemap, IFunction_sptr function,
                                     map<string, Parameter>& parammap)
  {
    vector<string> parnames = function->getParameterNames();

    for (size_t i = 0; i < parnames.size(); ++i)
    {
      string& parname = parnames[i];
      map<string, pair<double, double> >::iterator miter;
      miter = parvaluemap.find(parname);

      if (miter != parvaluemap.end())
      {
        double parvalue = miter->second.first;
        double parerror = miter->second.second;

        // 1. Function
        function->setParameter(parname, parvalue);

        // 2. Parameter map
        map<string, Parameter>::iterator pariter = parammap.find(parname);
        if (pariter != parammap.end())
        {
          // Find the entry
          pariter->second.value = parvalue;
          pariter->second.error = parerror;
        }
      }
    }

    return;
  }
  /** 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;
  }
Пример #5
0
/**
 * @brief Returns a string with ties that is passed to Fit
 *
 * This method uses the GlobalParameters property, which may contain a comma-
 * separated list of parameter names that should be the same for all peaks.
 *
 * Parameters that do not exist are silently ignored, but a warning is written
 * to the log so that users have a chance to find typos.
 *
 * @param poldiFn :: Function with some parameters.
 * @return :: String to pass to the Ties-property of Fit.
 */
std::string
PoldiFitPeaks2D::getUserSpecifiedTies(const IFunction_sptr &poldiFn) {
  std::string tieParameterList = getProperty("GlobalParameters");

  if (!tieParameterList.empty()) {
    std::vector<std::string> tieParameters;

    boost::split(tieParameters, tieParameterList, boost::is_any_of(",;"));

    std::vector<std::string> parameters = poldiFn->getParameterNames();

    std::vector<std::string> tieComponents;
    for (auto &tieParameter : tieParameters) {
      if (!tieParameter.empty()) {
        std::vector<std::string> matchedParameters;

        for (auto &parameter : parameters) {
          if (boost::algorithm::ends_with(parameter, tieParameter)) {
            matchedParameters.push_back(parameter);
          }
        }

        switch (matchedParameters.size()) {
        case 0:
          g_log.warning("Function does not have a parameter called '" +
                        tieParameter + "', ignoring.");
          break;
        case 1:
          g_log.warning("There is only one peak, no ties necessary.");
          break;
        default: {
          std::string reference = matchedParameters.front();

          for (auto par = matchedParameters.begin() + 1;
               par != matchedParameters.end(); ++par) {
            tieComponents.push_back(*par + "=" + reference);
          }
          break;
        }
        }
      }
    }

    if (!tieComponents.empty()) {
      return boost::algorithm::join(tieComponents, ",");
    }
  }

  return "";
}
  /** 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;
  }
  /** Set parameter values to function from Parameter map
   */
  void RefinePowderInstrumentParameters2::setFunctionParameterValues(IFunction_sptr function,
                                                                     map<string, Parameter> params)
  {
    // 1. Prepare
    vector<string> funparamnames = function->getParameterNames();

    // 2. Set up
    stringstream msgss;
    msgss << "Set Instrument Function Parameter : " << endl;

    std::map<std::string, Parameter>::iterator paramiter;
    for (size_t i = 0; i < funparamnames.size(); ++i)
    {
      string parname = funparamnames[i];
      paramiter = params.find(parname);

      if (paramiter != params.end())
      {
        // Found, set up the parameter
        Parameter& param = paramiter->second;
        function->setParameter(parname, param.value);

        msgss << setw(10) << parname << " = " << param.value << endl;
      }
      else
      {
        // Not found and thus quit
        stringstream errss;
        errss << "Peak profile parameter " << parname << " is not found in input parameters. ";
        g_log.error(errss.str());
        throw runtime_error(errss.str());
      }
    } // ENDFOR parameter name

    g_log.information(msgss.str());

    return;
  }
Пример #8
0
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 = "";
}