From 23132caa06fc443e4bbe2b09cdca18e98c230703 Mon Sep 17 00:00:00 2001
From: Antti Soininen <soininen@ill.fr>
Date: Fri, 8 Sep 2017 16:04:00 +0200
Subject: [PATCH] Add CalculatePolynomialBackground, move Jacobian.h.

Jacobian.h moved from CurveFitting to API and renamed to BasicJacobian
since a Jacobian implementation is needed by
CalculatePolynomialBackground.

Re #20404
---
 Framework/API/CMakeLists.txt                  |   1 +
 .../inc/MantidAPI/BasicJacobian.h}            |  17 +-
 Framework/Algorithms/CMakeLists.txt           |  17 +-
 .../CalculatePolynomialBackground.h           |  50 +++++
 .../src/CalculatePolynomialBackground.cpp     | 199 ++++++++++++++++++
 .../test/CalculatePolynomialBackgroundTest.h  |  57 +++++
 Framework/CurveFitting/CMakeLists.txt         |   1 -
 .../CostFunctions/CostFuncLeastSquares.cpp    |   6 +-
 .../src/CostFunctions/CostFuncRwp.cpp         |   1 -
 .../src/SeqDomainSpectrumCreator.cpp          |   1 -
 .../test/Functions/LorentzianTest.h           |   4 +-
 .../Functions/PeakParameterFunctionTest.h     |   8 +-
 .../test/Functions/ProductFunctionTest.h      |   9 +-
 .../test/Functions/ProductLinearExpTest.h     |  17 +-
 .../test/Functions/ProductQuadraticExpTest.h  |  10 +-
 .../test/Functions/PseudoVoigtTest.h          |  12 +-
 .../test/Functions/TabulatedFunctionTest.h    |   8 +-
 .../CurveFitting/test/Functions/VoigtTest.h   |   4 +-
 .../test/PoldiSpectrumDomainFunctionTest.h    |   6 +-
 .../test/PoldiSpectrumLinearBackgroundTest.h  |   6 +-
 20 files changed, 369 insertions(+), 65 deletions(-)
 rename Framework/{CurveFitting/inc/MantidCurveFitting/Jacobian.h => API/inc/MantidAPI/BasicJacobian.h} (87%)
 create mode 100644 Framework/Algorithms/inc/MantidAlgorithms/CalculatePolynomialBackground.h
 create mode 100644 Framework/Algorithms/src/CalculatePolynomialBackground.cpp
 create mode 100644 Framework/Algorithms/test/CalculatePolynomialBackgroundTest.h

diff --git a/Framework/API/CMakeLists.txt b/Framework/API/CMakeLists.txt
index eb1053e0d9e..ef9e727d3f2 100644
--- a/Framework/API/CMakeLists.txt
+++ b/Framework/API/CMakeLists.txt
@@ -170,6 +170,7 @@ set ( INC_FILES
 	inc/MantidAPI/AnalysisDataService.h
 	inc/MantidAPI/ArchiveSearchFactory.h
 	inc/MantidAPI/Axis.h
+	inc/MantidAPI/BasicJacobian.h
 	inc/MantidAPI/BinEdgeAxis.h
 	inc/MantidAPI/BoxController.h
 	inc/MantidAPI/CatalogFactory.h
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Jacobian.h b/Framework/API/inc/MantidAPI/BasicJacobian.h
similarity index 87%
rename from Framework/CurveFitting/inc/MantidCurveFitting/Jacobian.h
rename to Framework/API/inc/MantidAPI/BasicJacobian.h
index 09730cd87e0..49ed61594c3 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Jacobian.h
+++ b/Framework/API/inc/MantidAPI/BasicJacobian.h
@@ -1,22 +1,19 @@
-#ifndef MANTID_CURVEFITTING_GSLFUNCTIONS_H_
-#define MANTID_CURVEFITTING_GSLFUNCTIONS_H_
+#ifndef MANTID_API_BASICJACOBIAN_H_
+#define MANTID_API_BASICJACOBIAN_H_
 
 #include "MantidAPI/Jacobian.h"
-#include "MantidKernel/Exception.h"
-#include <gsl/gsl_matrix.h>
 
 #include <vector>
-#include <stdexcept>
 
 namespace Mantid {
-namespace CurveFitting {
+namespace API {
 /**
 An implementation of Jacobian using std::vector.
 
 @author Roman Tolchenov
 @date 17/02/2012
 
-Copyright &copy; 2010 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
+Copyright &copy; 2010-2017 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
 National Laboratory & European Spallation Source
 
 This file is part of Mantid.
@@ -37,7 +34,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 File change history is stored at: <https://github.com/mantidproject/mantid>
 Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
-class Jacobian : public API::Jacobian {
+class BasicJacobian : public API::Jacobian {
   /// Number of data points
   size_t m_ny;
   /// Number of parameters in a function (== IFunction::nParams())
@@ -49,7 +46,7 @@ public:
   /// Constructor.
   /// @param ny :: Number of data points
   /// @param np :: Number of parameters
-  Jacobian(size_t ny, size_t np) : m_ny(ny), m_np(np) {
+  BasicJacobian(size_t ny, size_t np) : m_ny(ny), m_np(np) {
     m_data.resize(ny * np, 0.0);
   }
   /// overwrite base method
@@ -96,4 +93,4 @@ public:
 } // namespace CurveFitting
 } // namespace Mantid
 
-#endif /*MANTID_CURVEFITTING_GSLFUNCTIONS_H_*/
+#endif /*MANTID_API_BASICJACOBIAN_H_*/
diff --git a/Framework/Algorithms/CMakeLists.txt b/Framework/Algorithms/CMakeLists.txt
index ff0aed40894..08ea4c0c912 100644
--- a/Framework/Algorithms/CMakeLists.txt
+++ b/Framework/Algorithms/CMakeLists.txt
@@ -25,6 +25,7 @@ set ( SRC_FILES
 	src/CalculateEfficiency.cpp
 	src/CalculateFlatBackground.cpp
 	src/CalculateMuonAsymmetry.cpp
+	src/CalculatePolynomialBackground.cpp
 	src/CalculateResolution.cpp
 	src/CalculateSlits.cpp
 	src/CalculateTransmission.cpp
@@ -44,8 +45,8 @@ set ( SRC_FILES
 	src/Comment.cpp
 	src/CommutativeBinaryOperation.cpp
 	src/CompareWorkspaces.cpp
-        src/ConjoinXRuns.cpp
 	src/ConjoinWorkspaces.cpp
+	src/ConjoinXRuns.cpp
 	src/ConvertAxesToRealSpace.cpp
 	src/ConvertAxisByFormula.cpp
 	src/ConvertDiffCal.cpp
@@ -162,7 +163,7 @@ set ( SRC_FILES
 	src/Integration.cpp
 	src/InterpolatingRebin.cpp
 	src/InterpolationOption.cpp
-        src/InvertMask.cpp
+	src/InvertMask.cpp
 	src/LineProfile.cpp
 	src/Logarithm.cpp
 	src/LorentzCorrection.cpp
@@ -344,6 +345,7 @@ set ( INC_FILES
 	inc/MantidAlgorithms/CalculateEfficiency.h
 	inc/MantidAlgorithms/CalculateFlatBackground.h
 	inc/MantidAlgorithms/CalculateMuonAsymmetry.h
+	inc/MantidAlgorithms/CalculatePolynomialBackground.h
 	inc/MantidAlgorithms/CalculateResolution.h
 	inc/MantidAlgorithms/CalculateSlits.h
 	inc/MantidAlgorithms/CalculateTransmission.h
@@ -364,7 +366,7 @@ set ( INC_FILES
 	inc/MantidAlgorithms/CommutativeBinaryOperation.h
 	inc/MantidAlgorithms/CompareWorkspaces.h
 	inc/MantidAlgorithms/ConjoinWorkspaces.h
-        inc/MantidAlgorithms/ConjoinXRuns.h
+	inc/MantidAlgorithms/ConjoinXRuns.h
 	inc/MantidAlgorithms/ConvertAxesToRealSpace.h
 	inc/MantidAlgorithms/ConvertAxisByFormula.h
 	inc/MantidAlgorithms/ConvertDiffCal.h
@@ -482,7 +484,7 @@ set ( INC_FILES
 	inc/MantidAlgorithms/Integration.h
 	inc/MantidAlgorithms/InterpolatingRebin.h
 	inc/MantidAlgorithms/InterpolationOption.h
-        inc/MantidAlgorithms/InvertMask.h
+	inc/MantidAlgorithms/InvertMask.h
 	inc/MantidAlgorithms/LineProfile.h
 	inc/MantidAlgorithms/Logarithm.h
 	inc/MantidAlgorithms/LorentzCorrection.h
@@ -679,6 +681,7 @@ set ( TEST_FILES
 	CalculateEfficiencyTest.h
 	CalculateFlatBackgroundTest.h
 	CalculateMuonAsymmetryTest.h
+	CalculatePolynomialBackgroundTest.h
 	CalculateResolutionTest.h
 	CalculateSlitsTest.h
 	CalculateTransmissionBeamSpreaderTest.h
@@ -687,8 +690,8 @@ set ( TEST_FILES
 	ChainedOperatorTest.h
 	ChangeBinOffsetTest.h
 	ChangeLogTimeTest.h
-	ChangePulsetimeTest.h
 	ChangePulsetime2Test.h
+	ChangePulsetimeTest.h
 	ChangeTimeZeroTest.h
 	CheckWorkspacesMatchTest.h
 	ChopDataTest.h
@@ -700,7 +703,7 @@ set ( TEST_FILES
 	CommutativeBinaryOperationTest.h
 	CompareWorkspacesTest.h
 	ConjoinWorkspacesTest.h
-        ConjoinXRunsTest.h
+	ConjoinXRunsTest.h
 	ConvertAxesToRealSpaceTest.h
 	ConvertAxisByFormulaTest.h
 	ConvertDiffCalTest.h
@@ -812,7 +815,7 @@ set ( TEST_FILES
 	IntegrationTest.h
 	InterpolatingRebinTest.h
 	InterpolationOptionTest.h
-        InvertMaskTest.h
+	InvertMaskTest.h
 	LineProfileTest.h
 	LogarithmTest.h
 	LorentzCorrectionTest.h
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalculatePolynomialBackground.h b/Framework/Algorithms/inc/MantidAlgorithms/CalculatePolynomialBackground.h
new file mode 100644
index 00000000000..93e04fa8f40
--- /dev/null
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CalculatePolynomialBackground.h
@@ -0,0 +1,50 @@
+#ifndef MANTID_ALGORITHMS_CALCULATEPOLYNOMIALBACKGROUND_H_
+#define MANTID_ALGORITHMS_CALCULATEPOLYNOMIALBACKGROUND_H_
+
+#include "MantidAlgorithms/DllConfig.h"
+#include "MantidAPI/Algorithm.h"
+
+namespace Mantid {
+namespace Algorithms {
+
+/** CalculatePolynomialBackground : TODO: DESCRIPTION
+
+  Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
+  National Laboratory & European Spallation Source
+
+  This file is part of Mantid.
+
+  Mantid is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  Mantid is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+  File change history is stored at: <https://github.com/mantidproject/mantid>
+  Code Documentation is available at: <http://doxygen.mantidproject.org>
+*/
+class MANTID_ALGORITHMS_DLL CalculatePolynomialBackground : public API::Algorithm {
+public:
+  const std::string name() const override;
+  int version() const override;
+  const std::string category() const override;
+  const std::string summary() const override;
+
+private:
+  void init() override;
+  void exec() override;
+  std::vector<double> includedRanges(const std::pair<double, double> &totalRange) const;
+  std::pair<double, double> totalRange(API::MatrixWorkspace &ws, const size_t wsIndex) const;
+};
+
+} // namespace Algorithms
+} // namespace Mantid
+
+#endif /* MANTID_ALGORITHMS_CALCULATEPOLYNOMIALBACKGROUND_H_ */
diff --git a/Framework/Algorithms/src/CalculatePolynomialBackground.cpp b/Framework/Algorithms/src/CalculatePolynomialBackground.cpp
new file mode 100644
index 00000000000..cdc67f56dc4
--- /dev/null
+++ b/Framework/Algorithms/src/CalculatePolynomialBackground.cpp
@@ -0,0 +1,199 @@
+#include "MantidAlgorithms/CalculatePolynomialBackground.h"
+
+#include "MantidAPI/BasicJacobian.h"
+#include "MantidAPI/FunctionFactory.h"
+#include "MantidAPI/IFunction1D.h"
+#include "MantidAPI/IncreasingAxisValidator.h"
+#include "MantidAPI/ITableWorkspace.h"
+#include "MantidDataObjects/Workspace2D.h"
+#include "MantidDataObjects/WorkspaceCreation.h"
+#include "MantidKernel/ArrayOrderedPairsValidator.h"
+#include "MantidKernel/ArrayProperty.h"
+#include "MantidKernel/BoundedValidator.h"
+
+#include <utility>
+
+namespace {
+namespace Prop {
+constexpr char *INPUT_WS = "InputWorkspace";
+constexpr char *OUTPUT_WS = "OutputWorkspace";
+constexpr char *POLY_ORDER = "PolynomeOrder";
+constexpr char *XRANGES = "XRanges";
+}
+
+std::vector<double> invertRanges(const std::vector<double> &ranges) {
+  std::vector<double> inversion(ranges.size() - 2);
+  for (size_t i = 1; i < ranges.size() - 1; ++i) {
+    inversion[i - 1] = ranges[i];
+  }
+  return inversion;
+}
+
+std::string makeFunctionString(const std::vector<double> &parameters) {
+  const auto order = parameters.size() - 1;
+  std::ostringstream s;
+  switch (order) {
+  case 0:
+    s << "name=FlatBackground";
+    break;
+  case 1:
+    s << "name=LinearBackground";
+    break;
+  case 2:
+    s << "name=Quadratic";
+    break;
+  default:
+    s << "name=Polynomial,n=" << order;
+  }
+  for (size_t o = 0; o <= order; ++o) {
+    s << ',' << 'A' << o << '=' << parameters[o];
+  }
+  return s.str();
+}
+}
+
+namespace Mantid {
+namespace Algorithms {
+
+// Register the algorithm into the AlgorithmFactory
+DECLARE_ALGORITHM(CalculatePolynomialBackground)
+
+//----------------------------------------------------------------------------------------------
+
+/// Algorithms name for identification. @see Algorithm::name
+const std::string CalculatePolynomialBackground::name() const { return "CalculatePolynomialBackground"; }
+
+/// Algorithm's version for identification. @see Algorithm::version
+int CalculatePolynomialBackground::version() const { return 1; }
+
+/// Algorithm's category for identification. @see Algorithm::category
+const std::string CalculatePolynomialBackground::category() const {
+  return "CorrectionFunctions\\BackgroundCorrections";
+}
+
+/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
+const std::string CalculatePolynomialBackground::summary() const {
+  return "Fits a polynomial background to a workspace.";
+}
+
+//----------------------------------------------------------------------------------------------
+/** Initialize the algorithm's properties.
+ */
+void CalculatePolynomialBackground::init() {
+  auto increasingAxis = boost::make_shared<API::IncreasingAxisValidator>();
+  auto nonnegativeInt = boost::make_shared<Kernel::BoundedValidator<int>>();
+  nonnegativeInt->setLower(0);
+  auto orderedPairs = boost::make_shared<Kernel::ArrayOrderedPairsValidator<double>>();
+  declareProperty(
+      Kernel::make_unique<API::WorkspaceProperty<API::MatrixWorkspace>>(Prop::INPUT_WS, "",
+                                                             Kernel::Direction::Input, increasingAxis),
+      "An input workspace.");
+  declareProperty(
+      Kernel::make_unique<API::WorkspaceProperty<API::MatrixWorkspace>>(Prop::OUTPUT_WS, "",
+                                                             Kernel::Direction::Output),
+      "A workspace containing the fitted background.");
+  declareProperty(Prop::POLY_ORDER, 0, nonnegativeInt, "Order of the polynome to fit to the input workspace.");
+  declareProperty(Kernel::make_unique<Kernel::ArrayProperty<double>>(Prop::XRANGES, std::vector<double>(), orderedPairs), "A list of fitting ranges given as pairs of X values.");
+}
+
+//----------------------------------------------------------------------------------------------
+/** Execute the algorithm.
+ */
+void CalculatePolynomialBackground::exec() {
+  API::MatrixWorkspace_sptr inWS = getProperty(Prop::INPUT_WS);
+
+  API::MatrixWorkspace_sptr outWS{DataObjects::create<DataObjects::Workspace2D>(*inWS)};
+  const auto polyOrder = static_cast<size_t>(static_cast<int>(getProperty(Prop::POLY_ORDER)));
+  const std::vector<double> initialParams(polyOrder + 1, 0.1);
+  const auto fitFunction = makeFunctionString(initialParams);
+  const auto nHistograms = static_cast<int64_t>(inWS->getNumberHistograms());
+  const auto nBins = inWS->blocksize();
+  for (int64_t i = 0; i < nHistograms; ++i) {
+    const auto includedR = includedRanges(totalRange(*inWS, i));
+    const bool logging{false};
+    auto fit = createChildAlgorithm("Fit", 0, 0, logging);
+    fit->setProperty("Function", fitFunction);
+    fit->setProperty("InputWorkspace", inWS);
+    fit->setProperty("WorkspaceIndex", static_cast<int>(i));
+    fit->setProperty("StartX", includedR.front());
+    fit->setProperty("EndX", includedR.back());
+    fit->setProperty("Exclude", invertRanges(includedR));
+    fit->setProperty("CreateOutput", true);
+    fit->executeAsChildAlg();
+    API::ITableWorkspace_sptr fitResult = fit->getProperty("OutputParameters");
+    std::vector<double> parameters(polyOrder + 1);
+    std::vector<double> paramErrors(polyOrder + 1);
+    for (size_t row = 0; row < parameters.size(); ++row) {
+      parameters[row] = fitResult->cell<double>(row, 1);
+      paramErrors[row] = fitResult->cell<double>(row, 2);
+    }
+    const auto bkgFunction = makeFunctionString(parameters);
+    auto bkg = boost::dynamic_pointer_cast<API::IFunction1D>(API::FunctionFactory::Instance().createInitialized(bkgFunction));
+    // We want bkg to directly write to the output workspace.
+    double *bkgY = const_cast<double *>(outWS->mutableY(i).rawData().data());
+    bkg->function1D(bkgY, outWS->points(i).rawData().data(), nBins);
+    API::BasicJacobian jacobian{nBins, polyOrder + 1};
+    bkg->functionDeriv1D(&jacobian, outWS->points(i).rawData().data(), nBins);
+    for (size_t j = 0; j < nBins; ++j) {
+      double uncertainty{0.0};
+      for (size_t k = 0; k < paramErrors.size(); ++k) {
+        uncertainty += std::abs(jacobian.get(j, k)) * paramErrors[k];
+      }
+      outWS->mutableE(i)[j] = uncertainty;
+    }
+  }
+
+  setProperty(Prop::OUTPUT_WS, outWS);
+}
+
+std::pair<double, double> CalculatePolynomialBackground::totalRange(API::MatrixWorkspace &ws, const size_t wsIndex) const {
+  const std::vector<double> ranges = getProperty(Prop::XRANGES);
+  const auto minmaxIt = std::minmax_element(ranges.cbegin(), ranges.cend());
+  const auto minEdge = *minmaxIt.first;
+  const auto maxEdge = *minmaxIt.second;
+  const auto minX = ws.x(wsIndex).front();
+  const auto maxX = ws.x(wsIndex).back();
+  return std::pair<double, double>(std::min(minEdge, minX), std::max(maxEdge, maxX));
+}
+
+std::vector<double> CalculatePolynomialBackground::includedRanges(const std::pair<double, double> &totalRange) const {
+  std::vector<double> ranges = getProperty(Prop::XRANGES);
+  // Sort the range edges keeping the information whether the edge
+  // 'starts' or 'ends' a range.
+  enum class Edge { start, end };
+  std::vector<std::pair<double, Edge>> edges(ranges.size());
+  for (size_t i = 0; i < ranges.size(); ++i) {
+    edges[i].first = ranges[i];
+    edges[i].second = i % 2 == 0 ? Edge::start : Edge::end;
+  }
+  std::sort(edges.begin(), edges.end(), [](const std::pair<double, Edge> &p1, const std::pair<double, Edge> &p2) {
+    if (p1.first == p2.first)
+      return p1.second == Edge::start;
+    return p1.first < p2.first;
+  });
+  // If an 'end' edge is followed by a 'start', we have a new range. Everything else
+  // can be merged.
+  std::vector<double> mergedRanges;
+  mergedRanges.reserve(ranges.size());
+  auto edgeIt = edges.begin();
+  mergedRanges.emplace_back(std::max(edges.front().first, totalRange.first));
+  while (edgeIt != edges.end()) {
+    auto endEdgeIt = edgeIt + 1;
+    while (endEdgeIt != edges.end()) {
+      const auto val = *endEdgeIt;
+      const auto prevVal = *(endEdgeIt - 1);
+      if (val.second == Edge::start && prevVal.second == Edge::end) {
+        mergedRanges.emplace_back(prevVal.first);
+        mergedRanges.emplace_back(val.first);
+        edgeIt = endEdgeIt;
+        break;
+      }
+      ++endEdgeIt;
+    }
+    ++edgeIt;
+  }
+  mergedRanges.emplace_back(std::min(edges.back().first, totalRange.second));
+  return mergedRanges;
+}
+} // namespace Algorithms
+} // namespace Mantid
diff --git a/Framework/Algorithms/test/CalculatePolynomialBackgroundTest.h b/Framework/Algorithms/test/CalculatePolynomialBackgroundTest.h
new file mode 100644
index 00000000000..4fb51472fbf
--- /dev/null
+++ b/Framework/Algorithms/test/CalculatePolynomialBackgroundTest.h
@@ -0,0 +1,57 @@
+#ifndef MANTID_ALGORITHMS_CALCULATEPOLYNOMIALBACKGROUNDTEST_H_
+#define MANTID_ALGORITHMS_CALCULATEPOLYNOMIALBACKGROUNDTEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidAlgorithms/CalculatePolynomialBackground.h"
+
+using Mantid::Algorithms::CalculatePolynomialBackground;
+
+class CalculatePolynomialBackgroundTest : public CxxTest::TestSuite {
+public:
+  // This pair of boilerplate methods prevent the suite being created statically
+  // This means the constructor isn't called when running other tests
+  static CalculatePolynomialBackgroundTest *createSuite() { return new CalculatePolynomialBackgroundTest(); }
+  static void destroySuite( CalculatePolynomialBackgroundTest *suite ) { delete suite; }
+
+
+  void test_Init()
+  {
+    CalculatePolynomialBackground alg;
+    TS_ASSERT_THROWS_NOTHING( alg.initialize() )
+    TS_ASSERT( alg.isInitialized() )
+  }
+
+  void test_exec()
+  {
+    /*// Create test input if necessary
+    MatrixWorkspace_sptr inputWS = //-- Fill in appropriate code. Consider using TestHelpers/WorkspaceCreationHelpers.h --
+
+    CalculatePolynomialBackground alg;
+    // Don't put output in ADS by default
+    alg.setChild(true);
+    TS_ASSERT_THROWS_NOTHING( alg.initialize() )
+    TS_ASSERT( alg.isInitialized() )
+    TS_ASSERT_THROWS_NOTHING( alg.setProperty("InputWorkspace", inputWS) );
+    TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", "_unused_for_child") );
+    TS_ASSERT_THROWS_NOTHING( alg.execute(); );
+    TS_ASSERT( alg.isExecuted() );
+
+    // Retrieve the workspace from the algorithm. The type here will probably need to change. It should
+    // be the type using in declareProperty for the "OutputWorkspace" type.
+    // We can't use auto as it's an implicit conversion.
+    Workspace_sptr outputWS = alg.getProperty("OutputWorkspace");
+    TS_ASSERT(outputWS);
+    TS_FAIL("TODO: Check the results and remove this line");*/
+  }
+  
+  void test_Something()
+  {
+    TS_FAIL( "You forgot to write a test!");
+  }
+
+
+};
+
+
+#endif /* MANTID_ALGORITHMS_CALCULATEPOLYNOMIALBACKGROUNDTEST_H_ */
diff --git a/Framework/CurveFitting/CMakeLists.txt b/Framework/CurveFitting/CMakeLists.txt
index 5211b133292..4c164076905 100644
--- a/Framework/CurveFitting/CMakeLists.txt
+++ b/Framework/CurveFitting/CMakeLists.txt
@@ -295,7 +295,6 @@ set ( INC_FILES
 	inc/MantidCurveFitting/HistogramDomainCreator.h
 	inc/MantidCurveFitting/IFittingAlgorithm.h
 	inc/MantidCurveFitting/IMWDomainCreator.h
-	inc/MantidCurveFitting/Jacobian.h
 	inc/MantidCurveFitting/LatticeDomainCreator.h
 	inc/MantidCurveFitting/LatticeFunction.h
 	inc/MantidCurveFitting/MSVesuvioHelpers.h
diff --git a/Framework/CurveFitting/src/CostFunctions/CostFuncLeastSquares.cpp b/Framework/CurveFitting/src/CostFunctions/CostFuncLeastSquares.cpp
index fa152b12012..264fb77af79 100644
--- a/Framework/CurveFitting/src/CostFunctions/CostFuncLeastSquares.cpp
+++ b/Framework/CurveFitting/src/CostFunctions/CostFuncLeastSquares.cpp
@@ -1,11 +1,11 @@
 //----------------------------------------------------------------------
 // Includes
 //----------------------------------------------------------------------
-#include "MantidCurveFitting/CostFunctions/CostFuncLeastSquares.h"
+#include "MantidAPI/BasicJacobian.h"
 #include "MantidAPI/CompositeDomain.h"
 #include "MantidAPI/FunctionValues.h"
 #include "MantidAPI/IConstraint.h"
-#include "MantidCurveFitting/Jacobian.h"
+#include "MantidCurveFitting/CostFunctions/CostFuncLeastSquares.h"
 #include "MantidCurveFitting/SeqDomain.h"
 #include "MantidKernel/Logger.h"
 #include "MantidKernel/MultiThreaded.h"
@@ -230,7 +230,7 @@ void CostFuncLeastSquares::addValDerivHessian(API::IFunction_sptr function,
   function->function(*domain, *values);
   size_t np = function->nParams(); // number of parameters
   size_t ny = values->size();      // number of data points
-  Jacobian jacobian(ny, np);
+  API::BasicJacobian jacobian(ny, np);
   function->functionDeriv(*domain, jacobian);
 
   size_t iActiveP = 0;
diff --git a/Framework/CurveFitting/src/CostFunctions/CostFuncRwp.cpp b/Framework/CurveFitting/src/CostFunctions/CostFuncRwp.cpp
index 17e783d9f7e..0fb89e7ce91 100644
--- a/Framework/CurveFitting/src/CostFunctions/CostFuncRwp.cpp
+++ b/Framework/CurveFitting/src/CostFunctions/CostFuncRwp.cpp
@@ -2,7 +2,6 @@
 // Includes
 //----------------------------------------------------------------------
 #include "MantidCurveFitting/CostFunctions/CostFuncRwp.h"
-#include "MantidCurveFitting/Jacobian.h"
 #include "MantidCurveFitting/SeqDomain.h"
 #include "MantidAPI/IConstraint.h"
 #include "MantidAPI/CompositeDomain.h"
diff --git a/Framework/CurveFitting/src/SeqDomainSpectrumCreator.cpp b/Framework/CurveFitting/src/SeqDomainSpectrumCreator.cpp
index 8b42f51d7bf..0a6b4d4fa0d 100644
--- a/Framework/CurveFitting/src/SeqDomainSpectrumCreator.cpp
+++ b/Framework/CurveFitting/src/SeqDomainSpectrumCreator.cpp
@@ -1,6 +1,5 @@
 #include "MantidCurveFitting/SeqDomainSpectrumCreator.h"
 #include "MantidCurveFitting/FunctionDomain1DSpectrumCreator.h"
-#include "MantidCurveFitting/Jacobian.h"
 #include "MantidCurveFitting/SeqDomain.h"
 #include "MantidAPI/IEventWorkspace.h"
 #include "MantidAPI/SpectrumInfo.h"
diff --git a/Framework/CurveFitting/test/Functions/LorentzianTest.h b/Framework/CurveFitting/test/Functions/LorentzianTest.h
index 91504fc455a..765568a15e7 100644
--- a/Framework/CurveFitting/test/Functions/LorentzianTest.h
+++ b/Framework/CurveFitting/test/Functions/LorentzianTest.h
@@ -4,7 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidCurveFitting/Functions/Lorentzian.h"
-#include "MantidCurveFitting/Jacobian.h"
+#include "MantidAPI/BasicJacobian.h"
 #include "MantidAPI/FunctionDomain1D.h"
 #include "MantidAPI/FunctionValues.h"
 
@@ -29,7 +29,7 @@ public:
     const size_t nData(1);
     std::vector<double> xValues(nData, 2.5);
 
-    Mantid::CurveFitting::Jacobian jacobian(nData, 3);
+    Mantid::API::BasicJacobian jacobian(nData, 3);
     func->functionDerivLocal(&jacobian, xValues.data(), nData);
 
     double dfda = jacobian.get(0, 0);
diff --git a/Framework/CurveFitting/test/Functions/PeakParameterFunctionTest.h b/Framework/CurveFitting/test/Functions/PeakParameterFunctionTest.h
index fc8679e79b8..d5a444c0ba0 100644
--- a/Framework/CurveFitting/test/Functions/PeakParameterFunctionTest.h
+++ b/Framework/CurveFitting/test/Functions/PeakParameterFunctionTest.h
@@ -4,11 +4,11 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidCurveFitting/Functions/PeakParameterFunction.h"
+#include "MantidAPI/BasicJacobian.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/FunctionFactory.h"
 #include "MantidAPI/FunctionParameterDecorator.h"
 #include "MantidAPI/IPeakFunction.h"
-#include "MantidCurveFitting/Jacobian.h"
 
 using namespace Mantid::CurveFitting;
 using namespace Mantid::CurveFitting::Functions;
@@ -62,7 +62,7 @@ public:
     fn->setParameter("Height", 4.0);
 
     FunctionDomain1DVector domain(std::vector<double>(4, 0.0));
-    Mantid::CurveFitting::Jacobian jacobian(4, 3);
+    Mantid::API::BasicJacobian jacobian(4, 3);
 
     TS_ASSERT_THROWS_NOTHING(fn->functionDeriv(domain, jacobian));
 
@@ -93,7 +93,7 @@ public:
 
     FunctionDomain1DVector domain(std::vector<double>(3, 0.0));
     FunctionValues values(domain);
-    Mantid::CurveFitting::Jacobian jacobian(domain.size(), 3);
+    Mantid::API::BasicJacobian jacobian(domain.size(), 3);
 
     TS_ASSERT_THROWS(fn->function(domain, values), std::invalid_argument);
     TS_ASSERT_THROWS(fn->functionDeriv(domain, jacobian),
@@ -110,7 +110,7 @@ public:
 
     FunctionDomain1DVector domain(std::vector<double>(4, 0.0));
     FunctionValues values(domain);
-    Mantid::CurveFitting::Jacobian jacobian(domain.size(), 3);
+    Mantid::API::BasicJacobian jacobian(domain.size(), 3);
 
     TS_ASSERT_THROWS(fn->function(domain, values), std::runtime_error);
     TS_ASSERT_THROWS(fn->functionDeriv(domain, jacobian), std::runtime_error);
diff --git a/Framework/CurveFitting/test/Functions/ProductFunctionTest.h b/Framework/CurveFitting/test/Functions/ProductFunctionTest.h
index d3a20f073d2..89734c9fdc3 100644
--- a/Framework/CurveFitting/test/Functions/ProductFunctionTest.h
+++ b/Framework/CurveFitting/test/Functions/ProductFunctionTest.h
@@ -4,13 +4,12 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidCurveFitting/Functions/ProductFunction.h"
+#include "MantidAPI/BasicJacobian.h"
+#include "MantidAPI/FunctionFactory.h"
+#include "MantidAPI/IPeakFunction.h"
 #include "MantidCurveFitting/Functions/Gaussian.h"
-#include "MantidCurveFitting/Jacobian.h"
-
 #include "MantidDataObjects/Workspace2D.h"
 
-#include "MantidAPI/IPeakFunction.h"
-#include "MantidAPI/FunctionFactory.h"
 
 typedef Mantid::DataObjects::Workspace2D_sptr WS_type;
 using Mantid::CurveFitting::Functions::ProductFunction;
@@ -252,7 +251,7 @@ public:
 
     TS_ASSERT_EQUALS(out.getCalculated(0), 105.0);
 
-    Mantid::CurveFitting::Jacobian jacobian(1, 4);
+    Mantid::API::BasicJacobian jacobian(1, 4);
     prodF.functionDeriv(domain, jacobian);
 
     TS_ASSERT_DELTA(jacobian.get(0, 0), 15, 1e-9);
diff --git a/Framework/CurveFitting/test/Functions/ProductLinearExpTest.h b/Framework/CurveFitting/test/Functions/ProductLinearExpTest.h
index a198b826c7a..5789b8f5ac5 100644
--- a/Framework/CurveFitting/test/Functions/ProductLinearExpTest.h
+++ b/Framework/CurveFitting/test/Functions/ProductLinearExpTest.h
@@ -4,13 +4,14 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidCurveFitting/Functions/ProductLinearExp.h"
-#include "MantidCurveFitting/Functions/ExpDecay.h"
-#include "MantidCurveFitting/Functions/LinearBackground.h"
-#include "MantidCurveFitting/Functions/ProductFunction.h"
-#include "MantidCurveFitting/Jacobian.h"
+
+#include "MantidAPI/BasicJacobian.h"
 #include "MantidAPI/FunctionDomain1D.h"
 #include "MantidAPI/FunctionValues.h"
 #include "MantidAPI/FunctionFactory.h"
+#include "MantidCurveFitting/Functions/ExpDecay.h"
+#include "MantidCurveFitting/Functions/LinearBackground.h"
+#include "MantidCurveFitting/Functions/ProductFunction.h"
 #include <algorithm>
 #include <boost/shared_ptr.hpp>
 #include <boost/make_shared.hpp>
@@ -80,8 +81,8 @@ to check that the results are equal.
     FunctionDomain1DVector domain(xValues);
     FunctionValues valuesBenchmark(domain);
     FunctionValues valuesLinExpDecay(domain);
-    Mantid::CurveFitting::Jacobian jacobianNumerical(nResults, 4);
-    Mantid::CurveFitting::Jacobian jacobianLinExpDecay(nResults, 4);
+    Mantid::API::BasicJacobian jacobianNumerical(nResults, 4);
+    Mantid::API::BasicJacobian jacobianLinExpDecay(nResults, 4);
     // Peform function evaluations.
     benchmark.function(domain, valuesBenchmark);
     func.function(domain, valuesLinExpDecay);
@@ -201,7 +202,7 @@ public:
                   LinearIncrementingAssignment(0, 0.1));
     FunctionDomain1DVector domain(xValues);
 
-    Mantid::CurveFitting::Jacobian jacobian(nResults, 4);
+    Mantid::API::BasicJacobian jacobian(nResults, 4);
 
     ProductLinearExp func;
     TS_ASSERT_THROWS_NOTHING(func.functionDeriv(domain, jacobian));
@@ -229,4 +230,4 @@ public:
   }
 };
 
-#endif /* MANTID_CURVEFITTING_PRODUCTLINEAREXPTEST_H_ */
\ No newline at end of file
+#endif /* MANTID_CURVEFITTING_PRODUCTLINEAREXPTEST_H_ */
diff --git a/Framework/CurveFitting/test/Functions/ProductQuadraticExpTest.h b/Framework/CurveFitting/test/Functions/ProductQuadraticExpTest.h
index c6c4385de3e..ec297680105 100644
--- a/Framework/CurveFitting/test/Functions/ProductQuadraticExpTest.h
+++ b/Framework/CurveFitting/test/Functions/ProductQuadraticExpTest.h
@@ -4,13 +4,13 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidCurveFitting/Functions/ProductQuadraticExp.h"
+#include "MantidAPI/BasicJacobian.h"
+#include "MantidAPI/FunctionDomain1D.h"
+#include "MantidAPI/FunctionFactory.h"
+#include "MantidAPI/FunctionValues.h"
 #include "MantidCurveFitting/Functions/ExpDecay.h"
 #include "MantidCurveFitting/Functions/Quadratic.h"
 #include "MantidCurveFitting/Functions/ProductFunction.h"
-#include "MantidCurveFitting/Jacobian.h"
-#include "MantidAPI/FunctionDomain1D.h"
-#include "MantidAPI/FunctionValues.h"
-#include "MantidAPI/FunctionFactory.h"
 #include <algorithm>
 #include <boost/shared_ptr.hpp>
 #include <boost/make_shared.hpp>
@@ -199,7 +199,7 @@ public:
                   LinearIncrementingAssignment(0, 0.1));
     FunctionDomain1DVector domain(xValues);
 
-    Mantid::CurveFitting::Jacobian jacobian(nResults, 5);
+    Mantid::API::BasicJacobian jacobian(nResults, 5);
 
     ProductQuadraticExp func;
     TS_ASSERT_THROWS_NOTHING(func.functionDeriv(domain, jacobian));
diff --git a/Framework/CurveFitting/test/Functions/PseudoVoigtTest.h b/Framework/CurveFitting/test/Functions/PseudoVoigtTest.h
index 0b8c7ede140..914969cc99d 100644
--- a/Framework/CurveFitting/test/Functions/PseudoVoigtTest.h
+++ b/Framework/CurveFitting/test/Functions/PseudoVoigtTest.h
@@ -3,15 +3,15 @@
 
 #include <cxxtest/TestSuite.h>
 
-#include "MantidAPI/FunctionDomain1D.h"
 #include "MantidCurveFitting/Functions/PseudoVoigt.h"
-#include "MantidCurveFitting/Jacobian.h"
-#include <boost/make_shared.hpp>
-
+#include "MantidAPI/BasicJacobian.h"
+#include "MantidAPI/FunctionDomain1D.h"
 #include "MantidCurveFitting/Functions/Gaussian.h"
 #include "MantidCurveFitting/Functions/Lorentzian.h"
 #include "MantidKernel/MersenneTwister.h"
 
+#include <boost/make_shared.hpp>
+
 using namespace Mantid::CurveFitting;
 using namespace Mantid::CurveFitting::Functions;
 using namespace Mantid::API;
@@ -180,7 +180,7 @@ public:
     IFunction_sptr pv = getInitializedPV(1.0, 4.78, 0.05, 0.7);
 
     FunctionDomain1DVector domain(m_xValues);
-    Mantid::CurveFitting::Jacobian jacobian(domain.size(), 4);
+    Mantid::API::BasicJacobian jacobian(domain.size(), 4);
 
     pv->functionDeriv(domain, jacobian);
 
@@ -255,4 +255,4 @@ private:
   std::vector<double> m_dfdf;
 };
 
-#endif /* MANTID_CURVEFITTING_PSEUDOVOIGTTEST_H_ */
\ No newline at end of file
+#endif /* MANTID_CURVEFITTING_PSEUDOVOIGTTEST_H_ */
diff --git a/Framework/CurveFitting/test/Functions/TabulatedFunctionTest.h b/Framework/CurveFitting/test/Functions/TabulatedFunctionTest.h
index cf922d0ec92..23c819e67ad 100644
--- a/Framework/CurveFitting/test/Functions/TabulatedFunctionTest.h
+++ b/Framework/CurveFitting/test/Functions/TabulatedFunctionTest.h
@@ -4,13 +4,13 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidCurveFitting/Functions/TabulatedFunction.h"
-#include "MantidCurveFitting/Functions/UserFunction.h"
-#include "MantidCurveFitting/Jacobian.h"
-#include "MantidAPI/FunctionDomain.h"
 #include "MantidAPI/AlgorithmFactory.h"
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/BasicJacobian.h"
 #include "MantidAPI/FileFinder.h"
+#include "MantidAPI/FunctionDomain.h"
 #include "MantidAPI/FunctionFactory.h"
+#include "MantidCurveFitting/Functions/UserFunction.h"
 
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
@@ -207,7 +207,7 @@ public:
     FunctionValues y(x);
     fun.function(x, y);
 
-    Mantid::CurveFitting::Jacobian jac(x.size(), 3);
+    Mantid::API::BasicJacobian jac(x.size(), 3);
     fun.functionDeriv(x, jac);
 
     for (size_t i = 0; i < x.size(); ++i) {
diff --git a/Framework/CurveFitting/test/Functions/VoigtTest.h b/Framework/CurveFitting/test/Functions/VoigtTest.h
index 34d940fac85..d2aa4543d23 100644
--- a/Framework/CurveFitting/test/Functions/VoigtTest.h
+++ b/Framework/CurveFitting/test/Functions/VoigtTest.h
@@ -5,9 +5,9 @@
 
 #include "MantidCurveFitting/Functions/Voigt.h"
 
+#include "MantidAPI/BasicJacobian.h"
 #include "MantidAPI/FunctionDomain1D.h"
 #include "MantidAPI/FunctionValues.h"
-#include "MantidCurveFitting/Jacobian.h"
 
 #include <boost/scoped_ptr.hpp>
 #include <boost/make_shared.hpp>
@@ -79,7 +79,7 @@ public:
     const double a_L(5), pos(-1), gamma_L(0.9), gamma_G(0.1);
     auto voigtFn = createFunction(a_L, pos, gamma_L, gamma_G);
 
-    Mantid::CurveFitting::Jacobian jacobian(g_domainSize, 4);
+    Mantid::API::BasicJacobian jacobian(g_domainSize, 4);
     voigtFn->functionDeriv(*m_domain, jacobian);
     const size_t nValues(g_domainSize);
     for (size_t i = 0; i < nValues; ++i) {
diff --git a/Framework/SINQ/test/PoldiSpectrumDomainFunctionTest.h b/Framework/SINQ/test/PoldiSpectrumDomainFunctionTest.h
index 7e4467f8c89..93e6abdea64 100644
--- a/Framework/SINQ/test/PoldiSpectrumDomainFunctionTest.h
+++ b/Framework/SINQ/test/PoldiSpectrumDomainFunctionTest.h
@@ -1,12 +1,12 @@
 #ifndef MANTID_SINQ_POLDISPECTRUMDOMAINFUNCTIONTEST_H_
 #define MANTID_SINQ_POLDISPECTRUMDOMAINFUNCTIONTEST_H_
 
+#include "MantidSINQ/PoldiUtilities/PoldiSpectrumDomainFunction.h"
+#include "MantidAPI/BasicJacobian.h"
 #include "MantidAPI/FunctionFactory.h"
 #include "MantidAPI/MultiDomainFunction.h"
-#include "MantidCurveFitting/Jacobian.h"
 #include "MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h"
 #include "MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h"
-#include "MantidSINQ/PoldiUtilities/PoldiSpectrumDomainFunction.h"
 
 #include <cxxtest/TestSuite.h>
 #include <gtest/gtest.h>
@@ -144,7 +144,7 @@ public:
     std::vector<double> xvalues(500, 1.0);
     FunctionDomain1DSpectrum domain(342, xvalues);
     TS_ASSERT_EQUALS(domain.getWorkspaceIndex(), 342);
-    Mantid::CurveFitting::Jacobian jacobian(500, 3);
+    Mantid::API::BasicJacobian jacobian(500, 3);
 
     function.functionDeriv(domain, jacobian);
 
diff --git a/Framework/SINQ/test/PoldiSpectrumLinearBackgroundTest.h b/Framework/SINQ/test/PoldiSpectrumLinearBackgroundTest.h
index a0a8cc3c8b0..296768632d7 100644
--- a/Framework/SINQ/test/PoldiSpectrumLinearBackgroundTest.h
+++ b/Framework/SINQ/test/PoldiSpectrumLinearBackgroundTest.h
@@ -3,10 +3,10 @@
 
 #include "MantidSINQ/PoldiUtilities/PoldiSpectrumLinearBackground.h"
 
+#include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/BasicJacobian.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/FunctionFactory.h"
-#include "MantidAPI/AlgorithmManager.h"
-#include "MantidCurveFitting/Jacobian.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
 #include <cxxtest/TestSuite.h>
@@ -95,7 +95,7 @@ public:
     function->setParameter("A1", 2.0);
 
     FunctionDomain1DSpectrum domainOne(1, m_xValues);
-    Mantid::CurveFitting::Jacobian jacobian(domainOne.size(),
+    Mantid::API::BasicJacobian jacobian(domainOne.size(),
                                             function->nParams());
     function->functionDeriv(domainOne, jacobian);
 
-- 
GitLab