/**
* Uses linear algorithm to do the fitting.
* @param histogram the histogram to fit
* @param background an output variable for the calculated background
* @param variance an output variable for background's variance, currently always
* zero.
* @param startX an X value in the first bin to be included in the fit
* @param endX an X value in the last bin to be included in the fit
*/
void CalculateFlatBackground::LinearFit(
    const HistogramData::Histogram &histogram, double &background,
    double &variance, const double startX, const double endX) {
  MatrixWorkspace_sptr WS = WorkspaceFactory::Instance().create(
      "Workspace2D", 1, histogram.x().size(), histogram.y().size());
  WS->setHistogram(0, histogram);
  IAlgorithm_sptr childAlg = createChildAlgorithm("Fit");

  IFunction_sptr func =
      API::FunctionFactory::Instance().createFunction("LinearBackground");
  childAlg->setProperty<IFunction_sptr>("Function", func);

  childAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", WS);
  childAlg->setProperty<bool>("CreateOutput", true);
  childAlg->setProperty<int>("WorkspaceIndex", 0);
  childAlg->setProperty<double>("StartX", startX);
  childAlg->setProperty<double>("EndX", endX);
  // Default minimizer doesn't work properly even on the easiest cases,
  // so Levenberg-MarquardtMD is used instead
  childAlg->setProperty<std::string>("Minimizer", "Levenberg-MarquardtMD");

  childAlg->executeAsChildAlg();

  std::string outputStatus = childAlg->getProperty("OutputStatus");
  if (outputStatus != "success") {
    g_log.warning("Unable to successfully fit the data: " + outputStatus);
    background = -1;
    return;
  }

  Mantid::API::ITableWorkspace_sptr output =
      childAlg->getProperty("OutputParameters");

  // Find rows with parameters we are after
  size_t rowA0, rowA1;
  output->find(static_cast<std::string>("A0"), rowA0, 0);
  output->find(static_cast<std::string>("A1"), rowA1, 0);

  // Linear function is defined as A0 + A1*x
  const double intercept = output->cell<double>(rowA0, 1);
  const double slope = output->cell<double>(rowA1, 1);

  const double centre = (startX + endX) / 2.0;

  // Calculate the value of the flat background by taking the value at the
  // centre point of the fit
  background = slope * centre + intercept;
  // ATM we don't calculate the error here.
  variance = 0;
}