diff --git a/CMakeLists.txt b/CMakeLists.txt
index 14839c35ece36ec8f9541f65b4a36f2dfa599862..22a52df7805fe911efee14cb0a47b910b09de88b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -39,6 +39,11 @@ set ( CPACK_PACKAGE_NAME "mantid${CPACK_PACKAGE_SUFFIX}" )
 ###########################################################################
 include ( Eigen )
 
+###########################################################################
+# Bootstrap any dependencies
+###########################################################################
+include ( Bootstrap )
+
 ###########################################################################
 # Set ParaView information since later items depend on it
 ###########################################################################
@@ -56,11 +61,6 @@ if ( ENABLE_MANTIDPLOT )
   include ( ParaViewSetup )
 endif ()
 
-###########################################################################
-# Bootstrap any dependencies
-###########################################################################
-include ( Bootstrap )
-
 ###########################################################################
 # Set expected variables for OS X
 ###########################################################################
diff --git a/Framework/API/inc/MantidAPI/MuParserUtils.h b/Framework/API/inc/MantidAPI/MuParserUtils.h
index 1af5ab3a5ac3247778a4d05c7c8b9d9be82c8954..dd075d7598bb4a2094bd73bec01a7d2145204bf1 100644
--- a/Framework/API/inc/MantidAPI/MuParserUtils.h
+++ b/Framework/API/inc/MantidAPI/MuParserUtils.h
@@ -42,6 +42,12 @@ extern const MANTID_API_DLL std::map<double, std::string> MUPARSER_CONSTANTS;
 /// Add a set of default constants to a muParser.
 void MANTID_API_DLL addDefaultConstants(mu::Parser &parser);
 
+typedef double (*oneVarFun)(double); // pointer to a function of one variable
+extern const MANTID_API_DLL std::map<std::string, oneVarFun>
+    MUPARSER_ONEVAR_FUNCTIONS;
+
+void MANTID_API_DLL extraOneVarFunctions(mu::Parser &parser);
+
 } // namespace MuParserUtils
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/src/ExperimentInfo.cpp b/Framework/API/src/ExperimentInfo.cpp
index 44133915a71497ae18e51250061b8a813be978be..bc121da3a3757d43c7ac82c16a46e9edc480715c 100644
--- a/Framework/API/src/ExperimentInfo.cpp
+++ b/Framework/API/src/ExperimentInfo.cpp
@@ -58,7 +58,9 @@ ExperimentInfo::ExperimentInfo()
     : m_moderatorModel(), m_choppers(), m_sample(new Sample()),
       m_run(new Run()), m_parmap(new ParameterMap()),
       sptr_instrument(new Instrument()),
-      m_detectorInfo(boost::make_shared<Beamline::DetectorInfo>(0)) {}
+      m_detectorInfo(boost::make_shared<Beamline::DetectorInfo>(0)) {
+  m_parmap->setDetectorInfo(m_detectorInfo);
+}
 
 /**
  * Constructs the object from a copy if the input. This leaves the new mutex
@@ -208,12 +210,13 @@ void ExperimentInfo::setInstrument(const Instrument_const_sptr &instr) {
   m_detectorInfoWrapper = nullptr;
   if (instr->isParametrized()) {
     sptr_instrument = instr->baseInstrument();
-    m_parmap = instr->getParameterMap();
+    m_parmap = boost::make_shared<ParameterMap>(*instr->getParameterMap());
   } else {
     sptr_instrument = instr;
     m_parmap = boost::make_shared<ParameterMap>();
   }
   m_detectorInfo = makeDetectorInfo(*sptr_instrument, *instr);
+  m_parmap->setDetectorInfo(m_detectorInfo);
   // Detector IDs that were previously dropped because they were not part of the
   // instrument may now suddenly be valid, so we have to reinitialize the
   // detector grouping. Also the index corresponding to specific IDs may have
@@ -404,6 +407,7 @@ void ExperimentInfo::replaceInstrumentParameters(
   m_spectrumInfoWrapper = nullptr;
   m_detectorInfoWrapper = nullptr;
   this->m_parmap.reset(new ParameterMap(pmap));
+  m_parmap->setDetectorInfo(m_detectorInfo);
 }
 
 /**
@@ -418,6 +422,7 @@ void ExperimentInfo::swapInstrumentParameters(Geometry::ParameterMap &pmap) {
   m_spectrumInfoWrapper = nullptr;
   m_detectorInfoWrapper = nullptr;
   this->m_parmap->swap(pmap);
+  m_parmap->setDetectorInfo(m_detectorInfo);
 }
 
 /**
diff --git a/Framework/API/src/MatrixWorkspace.cpp b/Framework/API/src/MatrixWorkspace.cpp
index bc1615fb4835496f3d7d37690a83c2d589b8be18..c329ac01f3116b05c4dee0a9e0c0f1ad8419dc52 100644
--- a/Framework/API/src/MatrixWorkspace.cpp
+++ b/Framework/API/src/MatrixWorkspace.cpp
@@ -72,11 +72,6 @@ MatrixWorkspace::MatrixWorkspace(const MatrixWorkspace &other)
   m_isCommonBinsFlag = other.m_isCommonBinsFlag;
   m_masks = other.m_masks;
   // TODO: Do we need to init m_monitorWorkspace?
-
-  // This call causes copying of m_parmap (ParameterMap). The constructor of
-  // ExperimentInfo just kept a shared_ptr to the same map as in other, which
-  // is not enough as soon as the maps in one of the workspaces it edited.
-  instrumentParameters();
 }
 
 /// Destructor
diff --git a/Framework/API/src/MuParserUtils.cpp b/Framework/API/src/MuParserUtils.cpp
index 623130f6e811b1042cd45d341be9ffe2116121a3..fe56575992421f521b0fd38357350a72b00ceb3d 100644
--- a/Framework/API/src/MuParserUtils.cpp
+++ b/Framework/API/src/MuParserUtils.cpp
@@ -2,12 +2,14 @@
 
 #include "MantidKernel/make_unique.h"
 #include "MantidKernel/PhysicalConstants.h"
+#include <gsl/gsl_sf.h>
 
 using namespace Mantid::PhysicalConstants;
 
 namespace Mantid {
 namespace API {
 namespace MuParserUtils {
+
 // The constant names below try to follow the naming scheme of the
 // scipy.constants Python module.
 // In addition to these, muParser defines "_e" for the Euler's number and
@@ -39,6 +41,16 @@ void DLLExport addDefaultConstants(mu::Parser &parser) {
   }
 }
 
+typedef double (*oneVarFun)(double); // pointer to a function of one variable
+const std::map<std::string, oneVarFun> MUPARSER_ONEVAR_FUNCTIONS = {
+    {"erf", gsl_sf_erf}, {"erfc", gsl_sf_erfc}};
+
+void DLLExport extraOneVarFunctions(mu::Parser &parser) {
+  for (const auto function : MUPARSER_ONEVAR_FUNCTIONS) {
+    parser.DefineFun(function.first, function.second);
+  }
+}
+
 } // namespace MuParserUtils
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/test/MuParserUtilsTest.h b/Framework/API/test/MuParserUtilsTest.h
index 46d142cb57bba143b7a8bc0a24c200b68ff4dff8..5d1bd8900c6dde45ea4665dbf338dfa811226524 100644
--- a/Framework/API/test/MuParserUtilsTest.h
+++ b/Framework/API/test/MuParserUtilsTest.h
@@ -14,11 +14,27 @@ public:
   void test_addDefaultConstants_Only_MUPARSER_CONSTANTS_IsAdded() {
     mu::Parser parser;
     MuParserUtils::addDefaultConstants(parser);
+    MuParserUtils::extraOneVarFunctions(parser);
     TS_ASSERT(defaultConstantsDefined(parser));
+    TS_ASSERT(extraOneVarFunctionsDefined(parser));
     TS_ASSERT(noVariablesDefined(parser));
   }
 
 private:
+  static bool extraOneVarFunctionsDefined(const mu::Parser &parser) {
+    const auto functionMap = parser.GetFunDef();
+    for (const auto pair : MuParserUtils::MUPARSER_ONEVAR_FUNCTIONS) {
+      const auto iterator = functionMap.find(pair.first);
+      if (iterator == functionMap.end()) {
+        return false;
+      }
+      if (iterator->first != pair.first) {
+        return false;
+      }
+    }
+    return true;
+  }
+
   static bool defaultConstantsDefined(const mu::Parser &parser) {
     const auto constantMap = parser.GetConst();
     // muParser defines two extra constants: "_e" and "_pi".
diff --git a/Framework/Algorithms/src/Q1D2.cpp b/Framework/Algorithms/src/Q1D2.cpp
index 1181c1779028dfc9f23241205be853377be9ec72..ad6410b78c2164c1b51d706d79b1f2e7ef62bbbd 100644
--- a/Framework/Algorithms/src/Q1D2.cpp
+++ b/Framework/Algorithms/src/Q1D2.cpp
@@ -76,14 +76,23 @@ void Q1D2::init() {
                   Direction::Input);
   auto mustBePositive = boost::make_shared<BoundedValidator<double>>();
   mustBePositive->setLower(0.0);
-  declareProperty("RadiusCut", 0.0, mustBePositive,
-                  "To increase resolution some wavelengths are excluded within "
-                  "this distance from\n"
-                  "the beam center (mm)");
+
+  declareProperty(
+      "RadiusCut", 0.0, mustBePositive,
+      "To increase resolution some wavelengths are excluded within "
+      "this distance from the beam center (mm). Note that RadiusCut\n"
+      " and WaveCut both need to be larger than 0 to affect \n"
+      "the effective cutoff. See the algorithm description for\n"
+      " a detailed explanation of the cutoff.");
+
   declareProperty(
       "WaveCut", 0.0, mustBePositive,
       "To increase resolution by starting to remove some wavelengths below this"
-      "freshold (angstrom)");
+      " threshold (angstrom).  Note that WaveCut\n"
+      " and RadiusCut both need to be larger than 0 to affect \n"
+      "on the effective cutoff. See the algorithm description for\n"
+      " a detailed explanation of the cutoff.");
+
   declareProperty("OutputParts", false,
                   "Set to true to output two additional workspaces which will "
                   "have the names OutputWorkspace_sumOfCounts "
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineBackground.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineBackground.h
index b428bacc2da5ccfabc6aa30cc8e0b76d65a2aed6..c154c4c35aad3f442946f3028571ef836935538c 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineBackground.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineBackground.h
@@ -7,6 +7,10 @@
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/Workspace_fwd.h"
 
+#include <gsl/gsl_bspline.h>
+#include <gsl/gsl_multifit.h>
+#include <gsl/gsl_statistics.h>
+
 namespace Mantid {
 namespace CurveFitting {
 namespace Algorithms {
@@ -56,6 +60,42 @@ private:
   // Overridden Algorithm methods
   void init() override;
   void exec() override;
+
+  /// Adds data from the workspace to the GSL vectors for later processing
+  void addWsDataToSpline(const API::MatrixWorkspace *ws, const size_t specNum,
+                         int expectedNumBins);
+
+  /// Allocates various pointers used within GSL
+  void allocateBSplinePointers(int numBins, int ncoeffs);
+
+  /// Calculates the bin weight using the error values in the WS
+  double calculateBinWeight(double errValue);
+
+  /// Deallocates various pointers within GSL
+  void freeBSplinePointers();
+
+  /// Calculates the number on unmasked bins to process
+  size_t calculateNumBinsToProcess(const API::MatrixWorkspace *ws);
+
+  /// Gets the values from the fitted GSL, and creates a clone of input
+  /// workspace with new values
+  API::MatrixWorkspace_sptr saveSplineOutput(const API::MatrixWorkspace_sptr ws,
+                                             const size_t spec);
+
+  /// Sets up the splines for later fitting
+  void setupSpline(double xMin, double xMax, int numBins, int ncoeff);
+
+  /// Struct holding various pointers required by GSL
+  struct bSplinePointers {
+    gsl_bspline_workspace *splineToProcess{nullptr};
+    gsl_vector *inputSplineWs{nullptr};
+    gsl_vector *xData{nullptr}, *yData{nullptr};
+    gsl_vector *coefficients{nullptr}, *binWeights{nullptr};
+    gsl_matrix *fittedWs{nullptr}, *covariance{nullptr};
+    gsl_multifit_linear_workspace *weightedLinearFitWs{nullptr};
+  };
+
+  bSplinePointers m_splinePointers{};
 };
 
 } // namespace Algorithms
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/UserFunction.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/UserFunction.h
index d042653957f6e328b1431c6c886336a871a988b4..e4438d0374c080b0286385abf71eaf7d6d68fa2f 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/UserFunction.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/UserFunction.h
@@ -83,7 +83,7 @@ public:
 private:
   /// The formula
   std::string m_formula;
-  /// muParser instance
+  /// extended muParser instance
   mu::Parser *m_parser;
   /// Used as 'x' variable in m_parser.
   mutable double m_x;
diff --git a/Framework/CurveFitting/src/Algorithms/SplineBackground.cpp b/Framework/CurveFitting/src/Algorithms/SplineBackground.cpp
index 79de451f6780d1bb4c9568f4b766f6fbbf81ddf4..1755ef1b715aee8976fe6ca3d675f3cd0a278a51 100644
--- a/Framework/CurveFitting/src/Algorithms/SplineBackground.cpp
+++ b/Framework/CurveFitting/src/Algorithms/SplineBackground.cpp
@@ -2,10 +2,10 @@
 // Includes
 //----------------------------------------------------------------------
 #include "MantidCurveFitting/Algorithms/SplineBackground.h"
-#include "MantidKernel/cow_ptr.h"
-#include "MantidKernel/BoundedValidator.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidKernel/cow_ptr.h"
+#include "MantidKernel/BoundedValidator.h"
 
 #include <gsl/gsl_bspline.h>
 #include <gsl/gsl_multifit.h>
@@ -39,142 +39,263 @@ void SplineBackground::init() {
  *
  */
 void SplineBackground::exec() {
-
   API::MatrixWorkspace_sptr inWS = getProperty("InputWorkspace");
-  int spec = getProperty("WorkspaceIndex");
+  const int ncoeffs = getProperty("NCoeff");
+  const int spec = getProperty("WorkspaceIndex");
 
+  // Check if the user specified a spectrum number its valid
   if (spec > static_cast<int>(inWS->getNumberHistograms()))
     throw std::out_of_range("WorkspaceIndex is out of range.");
 
-  const auto &yInputVals = inWS->y(spec);
-  const int ncoeffs = getProperty("NCoeff");
-  const int k = 4; // order of the spline + 1 (cubic)
-  const int nbreak = ncoeffs - (k - 2);
+  /* this is the data to be fitted */
+  const int numBins = static_cast<int>(calculateNumBinsToProcess(inWS.get()));
 
-  if (nbreak <= 0)
-    throw std::out_of_range("Too low NCoeff");
+  if (numBins < ncoeffs) {
+    throw std::out_of_range("Too many basis functions (NCoeff)");
+  }
 
-  gsl_bspline_workspace *bw;
-  gsl_vector *B;
+  allocateBSplinePointers(numBins, ncoeffs);
+  addWsDataToSpline(inWS.get(), spec, numBins);
 
-  gsl_vector *c, *w, *x, *y;
-  gsl_matrix *Z, *cov;
-  gsl_multifit_linear_workspace *mw;
-  double chisq;
+  const auto &xVals = inWS->x(spec);
+  setupSpline(xVals.front(), xVals.back(), numBins, ncoeffs);
 
-  int n = static_cast<int>(yInputVals.size());
-  bool isMasked = inWS->hasMaskedBins(spec);
-  std::vector<int> masked(yInputVals.size());
-  if (isMasked) {
-    auto maskedBins = inWS->maskedBins(spec);
-    for (auto &maskedBin : maskedBins)
-      masked[maskedBin.first] = 1;
-    n -= static_cast<int>(inWS->maskedBins(spec).size());
+  // Wrap this in its own block so we can alias the member variable
+  // to a shorter name for the duration of this call
+  {
+    // Have to pass a pointer so it can write chi ^ 2 even though we don't
+    // use this value
+    double chisq;
+    // Create temporary alias to reduce the size of the call
+    bSplinePointers &sp = m_splinePointers;
+    // do the fit
+    gsl_multifit_wlinear(sp.fittedWs, sp.binWeights, sp.yData, sp.coefficients,
+                         sp.covariance, &chisq, sp.weightedLinearFitWs);
   }
 
-  if (n < ncoeffs) {
-    g_log.error("Too many basis functions (NCoeff)");
-    throw std::out_of_range("Too many basis functions (NCoeff)");
-  }
+  auto outWS = saveSplineOutput(inWS, spec);
+  freeBSplinePointers();
+  setProperty("OutputWorkspace", outWS);
+}
 
-  /* allocate a cubic bspline workspace (k = 4) */
-  bw = gsl_bspline_alloc(k, nbreak);
-  B = gsl_vector_alloc(ncoeffs);
+/**
+ * Calculates the number of unmasked bins to process within spline background
+ *
+ * @param ws:: The input workspace to calculate the number of unmasked bins of
+*/
+size_t
+SplineBackground::calculateNumBinsToProcess(const API::MatrixWorkspace *ws) {
+  const int spec = getProperty("WorkspaceIndex");
+  const auto &yInputVals = ws->y(spec);
+  size_t ySize = yInputVals.size();
+
+  // Check and subtract masked bins from the count
+  bool isMasked = ws->hasMaskedBins(spec);
+  if (isMasked) {
+    ySize -= static_cast<int>(ws->maskedBins(spec).size());
+  }
+  return ySize;
+}
 
-  x = gsl_vector_alloc(n);
-  y = gsl_vector_alloc(n);
-  Z = gsl_matrix_alloc(n, ncoeffs);
-  c = gsl_vector_alloc(ncoeffs);
-  w = gsl_vector_alloc(n);
-  cov = gsl_matrix_alloc(ncoeffs, ncoeffs);
-  mw = gsl_multifit_linear_alloc(n, ncoeffs);
+/**
+ * Adds the data from the workspace into various GSL vectors
+ * for the spline later
+ *
+ * @param ws:: The workspace containing data to process
+ * @param specNum:: The spectrum number to process from the input WS
+ * @param expectedNumBins:: The expected number of unmasked bins to add
+ */
+void SplineBackground::addWsDataToSpline(const API::MatrixWorkspace *ws,
+                                         const size_t specNum,
+                                         int expectedNumBins) {
+  const auto xPointData = ws->points(specNum);
+  const auto yInputVals = ws->y(specNum);
+  const auto eInputVals = ws->e(specNum);
+  const bool hasMaskedBins = ws->hasMaskedBins(specNum);
+
+  // Mark masked bins to skip them later
+  std::vector<bool> masked(yInputVals.size(), false);
+  if (hasMaskedBins) {
+    const auto maskedBinsMap = ws->maskedBins(specNum);
+    for (const auto &maskedBin : maskedBinsMap) {
+      masked[maskedBin.first] = true;
+    }
+  }
 
-  /* this is the data to be fitted */
-  const auto &eInputVals = inWS->e(spec);
-  const auto &xInputPoints = inWS->points(spec);
-  int j = 0;
-  for (MantidVec::size_type i = 0; i < yInputVals.size(); ++i) {
-    if (isMasked && masked[i])
+  int numUnmaskedBins = 0;
+  for (size_t i = 0; i < yInputVals.size(); ++i) {
+    if (hasMaskedBins && masked[i])
       continue;
-    gsl_vector_set(x, j, xInputPoints[i]);
-    gsl_vector_set(y, j, yInputVals[i]);
-    gsl_vector_set(
-        w, j, eInputVals[i] > 0. ? 1. / (eInputVals[i] * eInputVals[i]) : 0.);
+    gsl_vector_set(m_splinePointers.xData, numUnmaskedBins, xPointData[i]);
+    gsl_vector_set(m_splinePointers.yData, numUnmaskedBins, yInputVals[i]);
+    gsl_vector_set(m_splinePointers.binWeights, numUnmaskedBins,
+                   calculateBinWeight(eInputVals[i]));
 
-    ++j;
+    ++numUnmaskedBins;
   }
 
-  if (n != j) {
-    gsl_bspline_free(bw);
-    gsl_vector_free(B);
-    gsl_vector_free(x);
-    gsl_vector_free(y);
-    gsl_matrix_free(Z);
-    gsl_vector_free(c);
-    gsl_vector_free(w);
-    gsl_matrix_free(cov);
-    gsl_multifit_linear_free(mw);
-
-    throw std::runtime_error("Assertion failed: n != j");
+  if (expectedNumBins != numUnmaskedBins) {
+    freeBSplinePointers();
+    throw std::runtime_error(
+        "Assertion failed: number of unmasked bins found was"
+        " not equal to the number that was calculated");
   }
+}
 
-  const auto &xInputVals = inWS->x(spec);
-
-  double xStart = xInputVals.front();
-  double xEnd = xInputVals.back();
-
-  /* use uniform breakpoints */
-  gsl_bspline_knots_uniform(xStart, xEnd, bw);
+/**
+  * Allocates the various vectors and workspaces within the GSL
+  *
+  * @param numBins:: The number of unmasked bins in the input workspaces to
+  *process
+  * @param ncoeffs:: The user specified number of coefficients to process
+  */
+void SplineBackground::allocateBSplinePointers(int numBins, int ncoeffs) {
+  const int k = 4; // order of the spline + 1 (cubic)
+  const int nbreak = ncoeffs - (k - 2);
 
-  /* construct the fit matrix X */
-  for (int i = 0; i < n; ++i) {
-    double xi = gsl_vector_get(x, i);
+  if (nbreak <= 0)
+    throw std::out_of_range("Too low NCoeff");
 
-    /* compute B_j(xi) for all j */
-    gsl_bspline_eval(xi, B, bw);
+  // Create an alias to tidy it up
+  bSplinePointers &sp = m_splinePointers;
+  // allocate a cubic bspline workspace (k = 4)
+  sp.splineToProcess = gsl_bspline_alloc(k, nbreak);
+  sp.inputSplineWs = gsl_vector_alloc(ncoeffs);
+
+  sp.xData = gsl_vector_alloc(numBins);
+  sp.yData = gsl_vector_alloc(numBins);
+  sp.fittedWs = gsl_matrix_alloc(numBins, ncoeffs);
+  sp.coefficients = gsl_vector_alloc(ncoeffs);
+  sp.binWeights = gsl_vector_alloc(numBins);
+  sp.covariance = gsl_matrix_alloc(ncoeffs, ncoeffs);
+  sp.weightedLinearFitWs = gsl_multifit_linear_alloc(numBins, ncoeffs);
+}
 
-    /* fill in row i of X */
-    for (j = 0; j < ncoeffs; ++j) {
-      double Bj = gsl_vector_get(B, j);
-      gsl_matrix_set(Z, i, j, Bj);
+/**
+  * Calculates the bin weight from the error value passed
+  * logs a warning if the value is less than or equal to 0
+  * or a special floating point value
+  *
+  * @param errValue:: The error value to use within the calculation
+  *
+  * @return:: The bin weight to use within the GSL allocation
+  */
+double SplineBackground::calculateBinWeight(double errValue) {
+  double outBinWeight = -1;
+  if (errValue <= 0 || !std::isfinite(errValue)) {
+    // Regardless of which warning we print we should
+    // set the bin weight
+    outBinWeight = 0;
+    if (errValue <= 0) {
+      g_log.warning(
+          "Spline background found an error value of 0 or less on an unmasked"
+          " bin. This bin will have no weight during the fitting process");
+    } else {
+      // nan / inf
+      g_log.warning(
+          "Spline background found an error value of nan or inf on an"
+          " unmasked bin. This bin will have no weight during the fitting"
+          " process");
     }
+  } else {
+    // Value is perfectly normal in every way
+    outBinWeight = 1. / (errValue * errValue);
   }
+  return outBinWeight;
+}
 
-  /* do the fit */
-  gsl_multifit_wlinear(Z, w, y, c, cov, &chisq, mw);
+/**
+ * Frees various vectors and workspaces within the GSL
+ */
+void SplineBackground::freeBSplinePointers() {
+  // Create an alias to tidy it up
+  bSplinePointers &sp = m_splinePointers;
+
+  gsl_bspline_free(sp.splineToProcess);
+  sp.splineToProcess = nullptr;
+  gsl_vector_free(sp.inputSplineWs);
+  sp.inputSplineWs = nullptr;
+  gsl_vector_free(sp.xData);
+  sp.xData = nullptr;
+  gsl_vector_free(sp.yData);
+  sp.yData = nullptr;
+  gsl_matrix_free(sp.fittedWs);
+  sp.fittedWs = nullptr;
+  gsl_vector_free(sp.coefficients);
+  sp.coefficients = nullptr;
+  gsl_vector_free(sp.binWeights);
+  sp.binWeights = nullptr;
+  gsl_matrix_free(sp.covariance);
+  sp.covariance = nullptr;
+  gsl_multifit_linear_free(sp.weightedLinearFitWs);
+  sp.weightedLinearFitWs = nullptr;
+}
 
+/**
+ * Makes a clone of the input workspace and retrieves fitted values
+ * and stores them in the output workspace with the user specified name
+ *
+ * @param ws:: The input workspace to clone
+ * @param spec:: The user specified spectrum number in the input ws to process
+ *
+ * @return:: A shared pointer to the output workspace
+ */
+MatrixWorkspace_sptr
+SplineBackground::saveSplineOutput(const API::MatrixWorkspace_sptr ws,
+                                   const size_t spec) {
+  const auto &xInputVals = ws->x(spec);
+  const auto &yInputVals = ws->y(spec);
   /* output the smoothed curve */
   API::MatrixWorkspace_sptr outWS = WorkspaceFactory::Instance().create(
-      inWS, 1, xInputVals.size(), yInputVals.size());
-  {
-    outWS->getSpectrum(0)
-        .setSpectrumNo(inWS->getSpectrum(spec).getSpectrumNo());
-    double yi, yerr;
-
-    auto &yVals = outWS->mutableY(0);
-    auto &eVals = outWS->mutableE(0);
-
-    for (MantidVec::size_type i = 0; i < yInputVals.size(); i++) {
-      double xi = xInputVals[i];
-      gsl_bspline_eval(xi, B, bw);
-      gsl_multifit_linear_est(B, c, cov, &yi, &yerr);
-      yVals[i] = yi;
-      eVals[i] = yerr;
-    }
-    outWS->setSharedX(0, inWS->sharedX(0));
+      ws, 1, xInputVals.size(), yInputVals.size());
+
+  outWS->getSpectrum(0).setSpectrumNo(ws->getSpectrum(spec).getSpectrumNo());
+
+  double yi, yerr;
+  auto &yVals = outWS->mutableY(0);
+  auto &eVals = outWS->mutableE(0);
+
+  for (size_t i = 0; i < yInputVals.size(); i++) {
+    double xi = xInputVals[i];
+    gsl_bspline_eval(xi, m_splinePointers.inputSplineWs,
+                     m_splinePointers.splineToProcess);
+    gsl_multifit_linear_est(m_splinePointers.inputSplineWs,
+                            m_splinePointers.coefficients,
+                            m_splinePointers.covariance, &yi, &yerr);
+    yVals[i] = yi;
+    eVals[i] = yerr;
   }
+  outWS->setSharedX(0, ws->sharedX(0));
+  return outWS;
+}
 
-  gsl_bspline_free(bw);
-  gsl_vector_free(B);
-  gsl_vector_free(x);
-  gsl_vector_free(y);
-  gsl_matrix_free(Z);
-  gsl_vector_free(c);
-  gsl_vector_free(w);
-  gsl_matrix_free(cov);
-  gsl_multifit_linear_free(mw);
+/**
+ * Sets up GSL with various parameters needed for subsequent fitting
+ *
+ * @param xMin:: The minimum x value in the input workspace
+ * @param xMax:: The maximum x value in the input workspace
+ * @param numBins:: The number of unmasked bins in the input workspace
+ * @param ncoeff:: The user specified coefficient to use
+ */
+void SplineBackground::setupSpline(double xMin, double xMax, int numBins,
+                                   int ncoeff) {
+  /* use uniform breakpoints */
+  gsl_bspline_knots_uniform(xMin, xMax, m_splinePointers.splineToProcess);
 
-  setProperty("OutputWorkspace", outWS);
+  /* construct the fit matrix X */
+  for (int i = 0; i < numBins; ++i) {
+    double xi = gsl_vector_get(m_splinePointers.xData, i);
+
+    /* compute B_j(xi) for all j */
+    gsl_bspline_eval(xi, m_splinePointers.inputSplineWs,
+                     m_splinePointers.splineToProcess);
+
+    /* fill in row i of X */
+    for (int j = 0; j < ncoeff; ++j) {
+      double Bj = gsl_vector_get(m_splinePointers.inputSplineWs, j);
+      gsl_matrix_set(m_splinePointers.fittedWs, i, j, Bj);
+    }
+  }
 }
 
 } // namespace Algorithms
diff --git a/Framework/CurveFitting/src/Functions/UserFunction.cpp b/Framework/CurveFitting/src/Functions/UserFunction.cpp
index ede884290521d14691a103f85d03592b09b7b3ca..179c1ab7317e2eecdebd97be494ab4bebf0ab543 100644
--- a/Framework/CurveFitting/src/Functions/UserFunction.cpp
+++ b/Framework/CurveFitting/src/Functions/UserFunction.cpp
@@ -3,6 +3,7 @@
 //----------------------------------------------------------------------
 #include "MantidCurveFitting/Functions/UserFunction.h"
 #include "MantidAPI/FunctionFactory.h"
+#include "MantidAPI/MuParserUtils.h"
 #include <boost/tokenizer.hpp>
 #include "MantidGeometry/muParser_Silent.h"
 
@@ -15,13 +16,15 @@ using namespace CurveFitting;
 // Register the class into the function factory
 DECLARE_FUNCTION(UserFunction)
 
+using Mantid::API::MuParserUtils::extraOneVarFunctions;
 using namespace Kernel;
-
 using namespace API;
 
 /// Constructor
 UserFunction::UserFunction()
-    : m_parser(new mu::Parser()), m_x(0.), m_x_set(false) {}
+    : m_parser(new mu::Parser()), m_x(0.), m_x_set(false) {
+  extraOneVarFunctions(*m_parser);
+}
 
 /// Destructor
 UserFunction::~UserFunction() { delete m_parser; }
@@ -64,6 +67,7 @@ void UserFunction::setAttribute(const std::string &attName,
 
   try {
     mu::Parser tmp_parser;
+    extraOneVarFunctions(tmp_parser);
     tmp_parser.SetVarFactory(AddVariable, this);
 
     m_formula = value.asString();
diff --git a/Framework/DataHandling/CMakeLists.txt b/Framework/DataHandling/CMakeLists.txt
index 053860b3eb504fa900c89b3e08e68c7e11db3acc..bc8273cd7bba374ff322f8180d2144bc8b24cd23 100644
--- a/Framework/DataHandling/CMakeLists.txt
+++ b/Framework/DataHandling/CMakeLists.txt
@@ -438,6 +438,7 @@ set ( TEST_FILES
 	LoadTBLTest.h
 	LoadSINQFocusTest.h
 	LoadSNSspecTest.h
+        LoadSpecTest.h
 	LoadSPETest.h
         LoadSampleDetailsFromRawTest.h
 	LoadSassenaTest.h
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadRKH.h b/Framework/DataHandling/inc/MantidDataHandling/LoadRKH.h
index cbac1544e293dcdf1dd1e7718f5c0450ffaca5b8..1c2e33f2bf92d61f34da5d077ec2ed93d19d482c 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadRKH.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadRKH.h
@@ -5,6 +5,7 @@
 // Includes
 //---------------------------------------------------
 #include "MantidAPI/IFileLoader.h"
+#include "MantidHistogramData/Histogram.h"
 #include "MantidKernel/cow_ptr.h"
 
 #include <fstream>
@@ -92,6 +93,13 @@ private:
 
   /// Check if we the data set stores an X-Error values
   bool hasXerror(std::ifstream &stream);
+
+  /// Read data from the RKH file
+  void readLinesForRKH1D(std::istream &stream, int readStart, int readEnd,
+                         HistogramData::Points &x, HistogramData::Counts &y,
+                         HistogramData::CountStandardDeviations &ye,
+                         HistogramData::PointStandardDeviations &xe,
+                         API::Progress &prog, bool readXError = false);
 };
 }
 }
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h
index f0389efa692337c1a87a3f2d80ea09d9a8eee316..75c104fc42cd0297aeb67e19acee3d2a87221e40 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h
@@ -4,6 +4,7 @@
 //----------------------------------------------------------------------
 // Includes
 //----------------------------------------------------------------------
+#include "MantidAPI/DeprecatedAlgorithm.h"
 #include "MantidAPI/IFileLoader.h"
 
 namespace Mantid {
@@ -45,7 +46,8 @@ 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 DLLExport LoadSNSspec : public API::IFileLoader<Kernel::FileDescriptor> {
+class DLLExport LoadSNSspec : public API::IFileLoader<Kernel::FileDescriptor>,
+                              API::DeprecatedAlgorithm {
 public:
   LoadSNSspec();
   const std::string name() const override { return "LoadSNSspec"; }
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSassena.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSassena.h
index 79437a014556f09a0706c6f8385a61ae4bc375fd..0a28d434867e407864418f840c074795e4f3af32 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadSassena.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSassena.h
@@ -83,15 +83,16 @@ protected:
   herr_t dataSetDouble(const hid_t &h5file, const std::string setName,
                        std::vector<double> &buf);
   /// Load qvectors dataset, calculate modulus of vectors
-  MantidVec loadQvectors(const hid_t &h5file, API::WorkspaceGroup_sptr gws,
-                         std::vector<int> &sorting_indexes);
+  HistogramData::Points loadQvectors(const hid_t &h5file,
+                                     API::WorkspaceGroup_sptr gws,
+                                     std::vector<int> &sorting_indexes);
   /// Load structure factor asa function of q-vector modulus
   void loadFQ(const hid_t &h5file, API::WorkspaceGroup_sptr gws,
-              const std::string setName, const MantidVec &qvmod,
+              const std::string setName, const HistogramData::Points &qvmod,
               const std::vector<int> &sorting_indexes);
   /// Load time-dependent structure factor
   void loadFQT(const hid_t &h5file, API::WorkspaceGroup_sptr gws,
-               const std::string setName, const MantidVec &qvmod,
+               const std::string setName, const HistogramData::Points &qvmod,
                const std::vector<int> &sorting_indexes);
 
 private:
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSpec.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSpec.h
index 8a6411464b042bc518ffd236ccbd6acc75df339e..8fb12e9d81d24a0db34dad460d3ddfc0b479ae3d 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadSpec.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSpec.h
@@ -5,6 +5,7 @@
 // Includes
 //----------------------------------------------------------------------
 #include "MantidAPI/Algorithm.h"
+#include "MantidHistogramData/Histogram.h"
 
 namespace Mantid {
 namespace DataHandling {
@@ -62,6 +63,14 @@ private:
   void init() override;
   void exec() override;
 
+  /// Helper method for reading the number of spectra from the file
+  size_t readNumberOfSpectra(std::ifstream &file) const;
+  /// Helper method for reading a line from the file
+  void readLine(const std::string &line, std::vector<double> &buffer) const;
+  /// Helper method for reading a single histogram
+  void readHistogram(const std::vector<double> &input,
+                     HistogramData::Histogram &histogram) const;
+
   /// Allowed values for the cache property
   std::vector<std::string> m_seperator_options;
   std::map<std::string, const char *> m_separatormap; ///<a map of seperators
diff --git a/Framework/DataHandling/src/LoadQKK.cpp b/Framework/DataHandling/src/LoadQKK.cpp
index 7463ec3de93cec7ba96fe7566593e4d3923e599a..ade598c50e682538cb162d41117638db746634fa 100644
--- a/Framework/DataHandling/src/LoadQKK.cpp
+++ b/Framework/DataHandling/src/LoadQKK.cpp
@@ -113,18 +113,21 @@ void LoadQKK::exec() {
   // Set the units of the data as Counts
   outputWorkspace->setYUnitLabel("Counts");
 
-  //  Put the data into outputWorkspace
-  size_t count = 0;
-  for (size_t i = 0; i < ny; ++i)
-    for (size_t j = 0; j < nx; ++j) {
-      // Move data across
-      double c = hmm(0, int(i), int(j));
-      outputWorkspace->dataX(count)[0] = wavelength0;
-      outputWorkspace->dataX(count)[1] = wavelength1;
-      outputWorkspace->dataY(count)[0] = c;
-      outputWorkspace->dataE(count)[0] = sqrt(c);
-      ++count;
-    }
+  using namespace HistogramData;
+  const BinEdges binEdges = {wavelength0, wavelength1};
+  for (size_t index = 0; index < nHist; ++index) {
+    auto x = static_cast<int>(index % nx);
+    auto y = static_cast<int>(index / nx);
+    auto c = hmm(0, x, y);
+
+    Counts yValue = {static_cast<double>(c)};
+    CountStandardDeviations errors = {sqrt(c)};
+
+    auto histogram = outputWorkspace->histogram(index);
+    histogram.setBinEdges(binEdges);
+    histogram.setCounts(yValue);
+    histogram.setCountStandardDeviations(errors);
+  }
 
   // Build instrument geometry
 
diff --git a/Framework/DataHandling/src/LoadRKH.cpp b/Framework/DataHandling/src/LoadRKH.cpp
index 8ee788fae7ce9b94f93acf3704b3ab4f1d4ef44a..802343028c301c360873ff9c350f862b0d3d7525 100644
--- a/Framework/DataHandling/src/LoadRKH.cpp
+++ b/Framework/DataHandling/src/LoadRKH.cpp
@@ -47,46 +47,64 @@ using namespace Mantid::Kernel;
 
 DECLARE_FILELOADER_ALGORITHM(LoadRKH)
 
-namespace {
-void readLinesForRKH1D(std::istream &stream, int readStart, int readEnd,
-                       std::vector<double> &columnOne,
-                       std::vector<double> &ydata, std::vector<double> &errdata,
-                       Progress &prog) {
-  std::string fileline;
-  for (int index = 1; index <= readEnd; ++index) {
-    getline(stream, fileline);
-    if (index < readStart)
-      continue;
-    double x(0.), y(0.), yerr(0.);
-    std::istringstream datastr(fileline);
-    datastr >> x >> y >> yerr;
-    columnOne.push_back(x);
-    ydata.push_back(y);
-    errdata.push_back(yerr);
-    prog.report();
-  }
-}
+/**
+ * Read data from a RKH1D file
+ *
+ * @param stream :: the input stream to read from
+ * @param readStart :: the line to start reading from
+ * @param readEnd :: the line to stop reading at
+ * @param x :: histogram data points to fill
+ * @param y :: histogram data counts to fill
+ * @param ye :: histogram data count standard deviations to fill
+ * @param xe :: histogram data point standard deviations to fill
+ * @param prog :: handle to progress bar
+ * @param readXError :: whether to read x errors (optional, default: false)
+ */
+void LoadRKH::readLinesForRKH1D(std::istream &stream, int readStart,
+                                int readEnd, HistogramData::Points &x,
+                                HistogramData::Counts &y,
+                                HistogramData::CountStandardDeviations &ye,
+                                HistogramData::PointStandardDeviations &xe,
+                                Progress &prog, bool readXError) {
+
+  std::vector<double> xData;
+  std::vector<double> yData;
+  std::vector<double> xError;
+  std::vector<double> yError;
+
+  xData.reserve(readEnd);
+  yData.reserve(readEnd);
+  xError.reserve(readEnd);
+  yError.reserve(readEnd);
 
-void readLinesWithXErrorForRKH1D(std::istream &stream, int readStart,
-                                 int readEnd, std::vector<double> &columnOne,
-                                 std::vector<double> &ydata,
-                                 std::vector<double> &errdata,
-                                 std::vector<double> &xError, Progress &prog) {
   std::string fileline;
   for (int index = 1; index <= readEnd; ++index) {
     getline(stream, fileline);
     if (index < readStart)
       continue;
-    double x(0.), y(0.), yerr(0.), xerr(0.);
+
+    double xValue(0.), yValue(0.), yErrorValue(0.);
     std::istringstream datastr(fileline);
-    datastr >> x >> y >> yerr >> xerr;
-    columnOne.push_back(x);
-    ydata.push_back(y);
-    errdata.push_back(yerr);
-    xError.push_back(xerr);
+    datastr >> xValue >> yValue >> yErrorValue;
+
+    xData.push_back(xValue);
+    yData.push_back(yValue);
+    yError.push_back(yErrorValue);
+
+    // check if we need to read in x error values
+    if (readXError) {
+      double xErrorValue(0.);
+      datastr >> xErrorValue;
+      xError.push_back(xErrorValue);
+    }
+
     prog.report();
   }
-}
+
+  x = xData;
+  y = yData;
+  ye = yError;
+  xe = xError;
 }
 
 /**
@@ -286,23 +304,18 @@ const API::MatrixWorkspace_sptr LoadRKH::read1D() {
 
   int pointsToRead = readEnd - readStart + 1;
   // Now stream sits at the first line of data
-  std::vector<double> columnOne, ydata, errdata, xError;
-  columnOne.reserve(readEnd);
-  ydata.reserve(readEnd);
-  errdata.reserve(readEnd);
+  HistogramData::Points columnOne;
+  HistogramData::Counts ydata;
+  HistogramData::PointStandardDeviations xError;
+  HistogramData::CountStandardDeviations errdata;
 
   auto hasXError = hasXerror(m_fileIn);
 
   Progress prog(this, 0.0, 1.0, readEnd);
 
-  if (hasXError) {
-    xError.reserve(readEnd);
-    readLinesWithXErrorForRKH1D(m_fileIn, readStart, readEnd, columnOne, ydata,
-                                errdata, xError, prog);
-  } else {
-    readLinesForRKH1D(m_fileIn, readStart, readEnd, columnOne, ydata, errdata,
-                      prog);
-  }
+  readLinesForRKH1D(m_fileIn, readStart, readEnd, columnOne, ydata, errdata,
+                    xError, prog, hasXError);
+
   m_fileIn.close();
 
   assert(pointsToRead == static_cast<int>(columnOne.size()));
@@ -318,9 +331,9 @@ const API::MatrixWorkspace_sptr LoadRKH::read1D() {
         "Workspace2D", 1, pointsToRead, pointsToRead);
     localworkspace->getAxis(0)->unit() =
         UnitFactory::Instance().create(firstColVal);
-    localworkspace->dataX(0) = columnOne;
-    localworkspace->dataY(0) = ydata;
-    localworkspace->dataE(0) = errdata;
+    localworkspace->setPoints(0, columnOne);
+    localworkspace->setCounts(0, ydata);
+    localworkspace->setCountStandardDeviations(0, errdata);
     if (hasXError) {
       localworkspace->setPointStandardDeviations(0, xError);
     }
diff --git a/Framework/DataHandling/src/LoadRawHelper.cpp b/Framework/DataHandling/src/LoadRawHelper.cpp
index f5e0720dc93bbae210db32e7d8bc8bef929943d4..3215c382b24a3c20c7cf9874279a50fa6884cc30 100644
--- a/Framework/DataHandling/src/LoadRawHelper.cpp
+++ b/Framework/DataHandling/src/LoadRawHelper.cpp
@@ -382,14 +382,12 @@ void LoadRawHelper::setWorkspaceData(
     int64_t lengthIn, int64_t binStart) {
   if (!newWorkspace)
     return;
-  typedef double (*uf)(double);
-  uf dblSqrt = std::sqrt;
+
   // But note that the last (overflow) bin is kept
-  MantidVec &Y = newWorkspace->dataY(wsIndex);
+  auto &Y = newWorkspace->mutableY(wsIndex);
   Y.assign(isisRaw->dat1 + binStart, isisRaw->dat1 + lengthIn);
   // Fill the vector for the errors, containing sqrt(count)
-  MantidVec &E = newWorkspace->dataE(wsIndex);
-  std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt);
+  newWorkspace->setCountVariances(wsIndex, Y.rawData());
 
   newWorkspace->getSpectrum(wsIndex).setSpectrumNo(nspecNum);
   // for loadrawbin0
diff --git a/Framework/DataHandling/src/LoadSINQFocus.cpp b/Framework/DataHandling/src/LoadSINQFocus.cpp
index a81719d9784549ee7159ffb93e38cf57935e3b8a..91f2b88bbd4bc232123f34a943c743b3d83588d1 100644
--- a/Framework/DataHandling/src/LoadSINQFocus.cpp
+++ b/Framework/DataHandling/src/LoadSINQFocus.cpp
@@ -161,7 +161,8 @@ void LoadSINQFocus::loadDataIntoTheWorkSpace(NeXus::NXEntry &entry) {
 
   std::vector<double> timeBinning =
       m_loader.getTimeBinningFromNexusPath(entry, "merged/time_binning");
-  m_localWorkspace->dataX(0).assign(timeBinning.begin(), timeBinning.end());
+  auto &x = m_localWorkspace->mutableX(0);
+  x.assign(timeBinning.begin(), timeBinning.end());
 
   Progress progress(this, 0, 1, m_numberOfTubes * m_numberOfPixelsPerTube);
   size_t spec = 0;
@@ -169,13 +170,14 @@ void LoadSINQFocus::loadDataIntoTheWorkSpace(NeXus::NXEntry &entry) {
     for (size_t j = 0; j < m_numberOfPixelsPerTube; ++j) {
       if (spec > 0) {
         // just copy the time binning axis to every spectra
-        m_localWorkspace->dataX(spec) = m_localWorkspace->readX(0);
+        m_localWorkspace->setSharedX(spec, m_localWorkspace->sharedX(0));
       }
       // Assign Y
       int *data_p = &data(static_cast<int>(i), static_cast<int>(j));
-      m_localWorkspace->dataY(spec).assign(data_p, data_p + m_numberOfChannels);
+      m_localWorkspace->mutableY(spec)
+          .assign(data_p, data_p + m_numberOfChannels);
       // Assign Error
-      MantidVec &E = m_localWorkspace->dataE(spec);
+      auto &E = m_localWorkspace->mutableE(spec);
       std::transform(data_p, data_p + m_numberOfChannels, E.begin(),
                      LoadSINQFocus::calculateError);
       ++spec;
diff --git a/Framework/DataHandling/src/LoadSNSspec.cpp b/Framework/DataHandling/src/LoadSNSspec.cpp
index bfad9dbf9b793dbb6b45e4249cc4e720026a73d3..77e13b54b1023f8dcad3e31e831daee3db5871c7 100644
--- a/Framework/DataHandling/src/LoadSNSspec.cpp
+++ b/Framework/DataHandling/src/LoadSNSspec.cpp
@@ -75,7 +75,10 @@ using namespace Kernel;
 using namespace API;
 
 /// Empty constructor
-LoadSNSspec::LoadSNSspec() {}
+LoadSNSspec::LoadSNSspec() : API::DeprecatedAlgorithm() {
+  useAlgorithm("LoadSpec");
+  deprecatedDate("2017-01-30");
+}
 
 /// Initialisation method.
 void LoadSNSspec::init() {
@@ -97,116 +100,16 @@ void LoadSNSspec::init() {
                   "[[Unit Factory]] or \"Dimensionless\") (default: Energy)");
 }
 
-/**
-*   Executes the algorithm.
-*/
 void LoadSNSspec::exec() {
-  std::string filename = getProperty("Filename");
-  std::ifstream file(filename.c_str());
-
-  file.seekg(0, std::ios::end);
-  Progress progress(this, 0, 1, static_cast<int>(file.tellg()));
-  file.seekg(0, std::ios::beg);
-
-  std::string str;
-
-  std::vector<DataObjects::Histogram1D> spectra;
-
-  int nBins = 0; // number of rows
-
-  // bool numeric = true;
-  std::vector<double> input;
-
-  // determine the number of lines starting by #L
-  // as there is one per set of data
-  int spectra_nbr = 0;
-  while (getline(file, str)) {
-    if (str.empty())
-      continue;
-    if (str[0] == '#' && str[1] == 'L') {
-      spectra_nbr++;
-    }
-  }
-
-  spectra.resize(spectra_nbr, DataObjects::Histogram1D(
-                                  HistogramData::Histogram::XMode::BinEdges,
-                                  HistogramData::Histogram::YMode::Counts));
-  file.clear(); // end of file has been reached so we need to clear file state
-  file.seekg(0, std::ios::beg); // go back to beginning of file
-
-  int working_with_spectrum_nbr = -1; // spectrum number
-  while (getline(file, str)) {
-    progress.report(static_cast<int>(file.tellg()));
-
-    // line with data, need to be parsed by white spaces
-    if (!str.empty() && str[0] != '#') {
-      typedef Mantid::Kernel::StringTokenizer tokenizer;
-      const std::string sep = " ";
-      tokenizer tok(str, sep,
-                    Mantid::Kernel::StringTokenizer::TOK_IGNORE_EMPTY);
-      for (const auto &beg : tok) {
-        input.push_back(std::stod(beg));
-      }
-    }
-
-    if (str.empty()) {
-      if (working_with_spectrum_nbr != -1) {
-        for (int j = 0; j < static_cast<int>(input.size() - 1); j++) {
-          spectra[working_with_spectrum_nbr].dataX().push_back(input[j]);
-          j++;
-          spectra[working_with_spectrum_nbr].dataY().push_back(input[j]);
-          j++;
-          spectra[working_with_spectrum_nbr].dataE().push_back(input[j]);
-          nBins = j / 3;
-        }
-        spectra[working_with_spectrum_nbr].dataX().push_back(input.back());
-      }
-      working_with_spectrum_nbr++;
-      input.clear();
-    }
-
-  } // end of read file
-
-  try {
-    if (spectra_nbr == 0)
-      throw "Undefined number of spectra";
-
-    if (working_with_spectrum_nbr == (spectra_nbr - 1)) {
-      for (int j = 0; j < static_cast<int>(input.size() - 1); j++) {
-        spectra[working_with_spectrum_nbr].dataX().push_back(input[j]);
-        j++;
-        spectra[working_with_spectrum_nbr].dataY().push_back(input[j]);
-        j++;
-        spectra[working_with_spectrum_nbr].dataE().push_back(input[j]);
-        nBins = j / 3;
-      }
-      spectra[working_with_spectrum_nbr].dataX().push_back(input.back());
-    }
-  } catch (...) {
-  }
-
-  try {
-    int nSpectra = spectra_nbr;
-    MatrixWorkspace_sptr localWorkspace =
-        boost::dynamic_pointer_cast<MatrixWorkspace>(
-            WorkspaceFactory::Instance().create("Workspace2D", nSpectra,
-                                                nBins + 1, nBins));
-
-    localWorkspace->getAxis(0)->unit() =
-        UnitFactory::Instance().create(getProperty("Unit"));
-
-    for (int i = 0; i < nSpectra; i++) {
-      localWorkspace->dataX(i) = spectra[i].dataX();
-      localWorkspace->dataY(i) = spectra[i].dataY();
-      localWorkspace->dataE(i) = spectra[i].dataE();
-      // Just have spectrum number start at 1 and count up
-      localWorkspace->getSpectrum(i).setSpectrumNo(i + 1);
-    }
-
-    setProperty("OutputWorkspace", localWorkspace);
-  } catch (Exception::NotFoundError &) {
-    // Asked for dimensionless workspace (obviously not in unit factory)
-  }
+  auto alg = createChildAlgorithm("LoadSpec");
+  alg->setPropertyValue("Filename", getPropertyValue("Filename"));
+  alg->setPropertyValue("OutputWorkspace", getPropertyValue("OutputWorkspace"));
+  alg->setPropertyValue("unit", getPropertyValue("unit"));
+  alg->execute();
+
+  MatrixWorkspace_sptr ws = alg->getProperty("OutputWorkspace");
+  setProperty("OutputWorkspace", ws);
 }
+
 } // namespace DataHandling
 } // namespace Mantid
diff --git a/Framework/DataHandling/src/LoadSPE.cpp b/Framework/DataHandling/src/LoadSPE.cpp
index 071f39346cb938bb1e579f593a7a3cf5210a1907..f24599c499a7379013df44c5854c8b723ed845ff 100644
--- a/Framework/DataHandling/src/LoadSPE.cpp
+++ b/Framework/DataHandling/src/LoadSPE.cpp
@@ -188,12 +188,11 @@ void LoadSPE::readHistogram(FILE *speFile, API::MatrixWorkspace_sptr workspace,
     reportFormatError(std::string(comment));
 
   // Then it's the Y values
-  MantidVec &Y = workspace->dataY(index);
+  auto &Y = workspace->mutableY(index);
   const size_t nbins = workspace->blocksize();
   int retval;
   for (size_t i = 0; i < nbins; ++i) {
     retval = fscanf(speFile, "%10le", &Y[i]);
-    // g_log.error() << Y[i] << '\n';
     if (retval != 1) {
       std::stringstream ss;
       ss << "Reading data value" << i << " of histogram " << index;
@@ -214,7 +213,7 @@ void LoadSPE::readHistogram(FILE *speFile, API::MatrixWorkspace_sptr workspace,
     reportFormatError(std::string(comment));
 
   // And then the error values
-  MantidVec &E = workspace->dataE(index);
+  auto &E = workspace->mutableE(index);
   for (size_t i = 0; i < nbins; ++i) {
     retval = fscanf(speFile, "%10le", &E[i]);
     if (retval != 1) {
diff --git a/Framework/DataHandling/src/LoadSassena.cpp b/Framework/DataHandling/src/LoadSassena.cpp
index c2a4f2c2315452fa606fd068621a789816b37db8..6cd16bf1fb05b8f97fcfe1b18c6728ab01879871 100644
--- a/Framework/DataHandling/src/LoadSassena.cpp
+++ b/Framework/DataHandling/src/LoadSassena.cpp
@@ -103,11 +103,12 @@ bool compare(const mypair &left, const mypair &right) {
  * @param sorting_indexes permutation of qvmod indexes to render it in
  * increasing order of momemtum transfer
  */
-MantidVec LoadSassena::loadQvectors(const hid_t &h5file,
-                                    API::WorkspaceGroup_sptr gws,
-                                    std::vector<int> &sorting_indexes) {
+HistogramData::Points
+LoadSassena::loadQvectors(const hid_t &h5file, API::WorkspaceGroup_sptr gws,
+                          std::vector<int> &sorting_indexes) {
 
-  MantidVec qvmod; // store the modulus of the vector
+  // store the modulus of the vector
+  std::vector<double> qvmod;
 
   const std::string gwsName = this->getPropertyValue("OutputWorkspace");
   const std::string setName("qvectors");
@@ -124,7 +125,7 @@ MantidVec LoadSassena::loadQvectors(const hid_t &h5file,
   if (errorcode < 0) {
     this->g_log.error("LoadSassena::loadQvectors cannot proceed");
     qvmod.resize(0);
-    return qvmod;
+    return HistogramData::Points(std::move(qvmod));
   }
 
   qvmod.reserve(nq);
@@ -154,7 +155,7 @@ MantidVec LoadSassena::loadQvectors(const hid_t &h5file,
   ws->setTitle(wsName);
 
   for (int iq = 0; iq < nq; iq++) {
-    MantidVec &Y = ws->dataY(iq);
+    auto &Y = ws->mutableY(iq);
     curr = std::next(buf.cbegin(), 3 * sorting_indexes[iq]);
     Y.assign(curr, std::next(curr, 3));
   }
@@ -164,7 +165,7 @@ MantidVec LoadSassena::loadQvectors(const hid_t &h5file,
 
   this->registerWorkspace(
       gws, wsName, ws, "X-axis: origin of Q-vectors; Y-axis: tip of Q-vectors");
-  return qvmod;
+  return HistogramData::Points(std::move(qvmod));
 }
 
 /**
@@ -179,7 +180,8 @@ MantidVec LoadSassena::loadQvectors(const hid_t &h5file,
  * increasing order of momemtum transfer
  */
 void LoadSassena::loadFQ(const hid_t &h5file, API::WorkspaceGroup_sptr gws,
-                         const std::string setName, const MantidVec &qvmod,
+                         const std::string setName,
+                         const HistogramData::Points &qvmod,
                          const std::vector<int> &sorting_indexes) {
 
   int nq = static_cast<int>(qvmod.size()); // number of q-vectors
@@ -198,10 +200,10 @@ void LoadSassena::loadFQ(const hid_t &h5file, API::WorkspaceGroup_sptr gws,
   const std::string wsName = gwsName + std::string("_") + setName;
   ws->setTitle(wsName);
 
-  MantidVec &re = ws->dataY(0); // store the real part
-  ws->dataX(0) = qvmod;         // X-axis values are the modulus of the q vector
-  MantidVec &im = ws->dataY(1); // store the imaginary part
-  ws->dataX(1) = qvmod;
+  auto &re = ws->mutableY(0); // store the real part
+  ws->setPoints(0, qvmod);    // X-axis values are the modulus of the q vector
+  auto &im = ws->mutableY(1); // store the imaginary part
+  ws->setPoints(1, qvmod);
 
   for (int iq = 0; iq < nq; ++iq) {
     auto curr = std::next(buf.cbegin(), 2 * sorting_indexes[iq]);
@@ -232,7 +234,8 @@ void LoadSassena::loadFQ(const hid_t &h5file, API::WorkspaceGroup_sptr gws,
 * order of momemtum transfer
 */
 void LoadSassena::loadFQT(const hid_t &h5file, API::WorkspaceGroup_sptr gws,
-                          const std::string setName, const MantidVec &qvmod,
+                          const std::string setName,
+                          const HistogramData::Points &qvmod,
                           const std::vector<int> &sorting_indexes) {
 
   hsize_t dims[3];
@@ -271,10 +274,10 @@ void LoadSassena::loadFQT(const hid_t &h5file, API::WorkspaceGroup_sptr gws,
 
   int origin = nnt - 1;
   for (int iq = 0; iq < nq; iq++) {
-    MantidVec &reX = wsRe->dataX(iq);
-    MantidVec &imX = wsIm->dataX(iq);
-    MantidVec &reY = wsRe->dataY(iq);
-    MantidVec &imY = wsIm->dataY(iq);
+    auto &reX = wsRe->mutableX(iq);
+    auto &imX = wsIm->mutableX(iq);
+    auto &reY = wsRe->mutableY(iq);
+    auto &imY = wsIm->mutableY(iq);
     const int index = sorting_indexes[iq];
     auto curr = std::next(buf.cbegin(), index * nnt * 2);
     for (int it = 0; it < nnt; it++) {
@@ -407,7 +410,7 @@ void LoadSassena::exec() {
 
   // Block to read the Q-vectors
   std::vector<int> sorting_indexes;
-  const MantidVec qvmod = this->loadQvectors(h5file, gws, sorting_indexes);
+  const auto qvmod = this->loadQvectors(h5file, gws, sorting_indexes);
   if (qvmod.empty()) {
     this->g_log.error("No Q-vectors read. Unable to proceed");
     H5Fclose(h5file);
diff --git a/Framework/DataHandling/src/LoadSpec.cpp b/Framework/DataHandling/src/LoadSpec.cpp
index 212bbec31d59559184f17234f7f93cb8f4cd2e5e..b49509f4bb7191e1fd0e19344d4a9886faefa42c 100644
--- a/Framework/DataHandling/src/LoadSpec.cpp
+++ b/Framework/DataHandling/src/LoadSpec.cpp
@@ -50,7 +50,6 @@ void LoadSpec::init() {
 */
 void LoadSpec::exec() {
   std::string filename = getProperty("Filename");
-  // separator can be 1 or more spaces
   std::ifstream file(filename.c_str());
 
   file.seekg(0, std::ios::end);
@@ -58,101 +57,131 @@ void LoadSpec::exec() {
   file.seekg(0, std::ios::beg);
 
   std::string str;
-
-  std::vector<DataObjects::Histogram1D> spectra;
-
-  int nBins = 0; // number of rows
-
-  // bool numeric = true;
   std::vector<double> input;
 
-  // determine the number of lines starting by #L
-  // as there is one per set of data
-  int spectra_nbr = 0;
-  while (getline(file, str)) {
-    if (str[0] == '#' && str[1] == 'L') {
-      spectra_nbr++;
-    }
-  }
+  const size_t nSpectra = readNumberOfSpectra(file);
+  auto localWorkspace = boost::dynamic_pointer_cast<MatrixWorkspace>(
+      WorkspaceFactory::Instance().create("Workspace2D", nSpectra, 2, 1));
+
+  localWorkspace->getAxis(0)->unit() =
+      UnitFactory::Instance().create(getProperty("Unit"));
 
-  spectra.resize(spectra_nbr, DataObjects::Histogram1D(
-                                  HistogramData::Histogram::XMode::Points,
-                                  HistogramData::Histogram::YMode::Counts));
   file.clear(); // end of file has been reached so we need to clear file state
   file.seekg(0, std::ios::beg); // go back to beginning of file
 
-  int working_with_spectrum_nbr = -1; // spectrum number
+  int specNum = -1; // spectrum number
   while (getline(file, str)) {
     progress.report(static_cast<int>(file.tellg()));
 
     // line with data, need to be parsed by white spaces
-    if (!str.empty() && str[0] != '#') {
-      typedef Mantid::Kernel::StringTokenizer tokenizer;
-      const std::string sep = " ";
-      tokenizer tok(str, sep,
-                    Mantid::Kernel::StringTokenizer::TOK_IGNORE_EMPTY);
-      for (const auto &beg : tok) {
-        input.push_back(std::stod(beg));
-      }
+    readLine(str, input);
+
+    if (str.empty() && specNum != -1) {
+      auto histogram = localWorkspace->histogram(specNum);
+      readHistogram(input, histogram);
+      localWorkspace->setHistogram(specNum, histogram);
     }
 
     if (str.empty()) {
-      if (working_with_spectrum_nbr != -1) {
-        for (int j = 0; j < static_cast<int>(input.size() - 1); j++) {
-          spectra[working_with_spectrum_nbr].dataX().push_back(input[j]);
-          j++;
-          spectra[working_with_spectrum_nbr].dataY().push_back(input[j]);
-          j++;
-          spectra[working_with_spectrum_nbr].dataE().push_back(input[j]);
-          nBins = j / 3;
-        }
-      }
-      working_with_spectrum_nbr++;
+      specNum++;
       input.clear();
     }
 
   } // end of read file
 
   try {
-    if (spectra_nbr == 0)
+    if (nSpectra == 0)
       throw "Undefined number of spectra";
 
-    if (working_with_spectrum_nbr == (spectra_nbr - 1)) {
-      for (int j = 0; j < static_cast<int>(input.size() - 1); j++) {
-        spectra[working_with_spectrum_nbr].dataX().push_back(input[j]);
-        j++;
-        spectra[working_with_spectrum_nbr].dataY().push_back(input[j]);
-        j++;
-        spectra[working_with_spectrum_nbr].dataE().push_back(input[j]);
-        nBins = j / 3;
-      }
+    if (static_cast<size_t>(specNum) == (nSpectra - 1)) {
+      auto histogram = localWorkspace->histogram(specNum);
+      readHistogram(input, histogram);
+      localWorkspace->setHistogram(specNum, histogram);
     }
   } catch (...) {
   }
 
-  try {
-    int nSpectra = spectra_nbr;
-    MatrixWorkspace_sptr localWorkspace =
-        boost::dynamic_pointer_cast<MatrixWorkspace>(
-            WorkspaceFactory::Instance().create("Workspace2D", nSpectra, nBins,
-                                                nBins));
-
-    localWorkspace->getAxis(0)->unit() =
-        UnitFactory::Instance().create(getProperty("Unit"));
-
-    for (int i = 0; i < nSpectra; i++) {
-      localWorkspace->dataX(i) = spectra[i].dataX();
-      localWorkspace->dataY(i) = spectra[i].dataY();
-      localWorkspace->dataE(i) = spectra[i].dataE();
-      // Just have spectrum number start at 1 and count up
-      localWorkspace->getSpectrum(i).setSpectrumNo(i + 1);
+  setProperty("OutputWorkspace", localWorkspace);
+}
+
+/**
+ * Read the total number of specrta contained in the file
+ *
+ * @param file :: file stream to read from
+ * @return a size_t representing the number of spectra
+ */
+size_t LoadSpec::readNumberOfSpectra(std::ifstream &file) const {
+  // determine the number of lines starting by #L
+  // as there is one per set of data
+  size_t spectra_nbr = 0;
+  std::string str;
+  while (getline(file, str)) {
+    if (str.empty())
+      continue;
+    if (str[0] == '#' && str[1] == 'L') {
+      spectra_nbr++;
     }
+  }
+  return spectra_nbr;
+}
 
-    setProperty("OutputWorkspace", localWorkspace);
-  } catch (Exception::NotFoundError &) {
-    // Asked for dimensionless workspace (obviously not in unit factory)
+/**
+ * Read a single line from the file into the data buffer
+ *
+ * @param line :: the current line in the file to process
+ * @param buffer :: the buffer to store loaded data in
+ */
+void LoadSpec::readLine(const std::string &line,
+                        std::vector<double> &buffer) const {
+  if (!line.empty() && line[0] != '#') {
+    typedef Mantid::Kernel::StringTokenizer tokenizer;
+    const std::string sep = " ";
+    tokenizer tok(line, sep, Mantid::Kernel::StringTokenizer::TOK_IGNORE_EMPTY);
+    for (const auto &beg : tok) {
+      buffer.push_back(std::stod(beg));
+    }
   }
 }
 
+/**
+ * Convert the data from the input buffer to a histogram object
+ *
+ * @param input :: the input buffer containing the raw data
+ * @param histogram :: the histogram object to fill with values
+ * */
+void LoadSpec::readHistogram(const std::vector<double> &input,
+                             HistogramData::Histogram &histogram) const {
+  std::vector<double> x, y, e;
+
+  auto isHist = input.size() % 3 > 0;
+  auto nElements = (isHist) ? input.size() - 1 : input.size() - 2;
+
+  x.reserve(nElements);
+  y.reserve(nElements);
+  e.reserve(nElements);
+
+  for (size_t index = 0; index < nElements; index++) {
+    x.push_back(input[index]);
+    index++;
+    y.push_back(input[index]);
+    index++;
+    e.push_back(input[index]);
+  }
+
+  histogram.resize(y.size());
+
+  if (isHist) {
+    // we're loading binned data
+    // last value is final x bin
+    x.push_back(input.back());
+    histogram.setBinEdges(x);
+  } else {
+    histogram.setPoints(x);
+  }
+
+  histogram.setCounts(y);
+  histogram.setCountStandardDeviations(e);
+}
+
 } // namespace DataHandling
 } // namespace Mantid
diff --git a/Framework/DataHandling/src/LoadSpice2D.cpp b/Framework/DataHandling/src/LoadSpice2D.cpp
index be29746f24a4f4ddcc95dc8d0ca0bc573a4f9b6c..17540beb5995aa34e3eabb4cc78c480979af40c5 100644
--- a/Framework/DataHandling/src/LoadSpice2D.cpp
+++ b/Framework/DataHandling/src/LoadSpice2D.cpp
@@ -79,9 +79,9 @@ bool from_string(T &t, const std::string &s,
  */
 void store_value(DataObjects::Workspace2D_sptr ws, int specID, double value,
                  double error, double wavelength, double dwavelength) {
-  MantidVec &X = ws->dataX(specID);
-  MantidVec &Y = ws->dataY(specID);
-  MantidVec &E = ws->dataE(specID);
+  auto &X = ws->mutableX(specID);
+  auto &Y = ws->mutableY(specID);
+  auto &E = ws->mutableE(specID);
   // The following is mostly to make Mantid happy by defining a histogram with
   // a single bin around the neutron wavelength
   X[0] = wavelength - dwavelength / 2.0;
diff --git a/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp b/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp
index a0381cf324144ee9596c980b18c3d9858f528fe9..be6ffb3b60bb64b361ac6aef5195a866693fa87d 100644
--- a/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp
+++ b/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp
@@ -521,28 +521,26 @@ MatrixWorkspace_sptr LoadSpiceXML2DDet::createMatrixWorkspace(
         // scan per column
         for (size_t j_row = 0; j_row < veccounts.size(); ++j_row) {
           double counts = atof(veccounts[j_row].c_str());
+          size_t rowIndex, columnIndex;
 
           if (loadinstrument) {
             // the detector ID and ws index are set up in column-major too!
-            size_t wsindex = i_col * numpixelx + j_row;
-            //  size_t wsindex = j_row * numpixely + icol;
-            // size_t wsindex = icol * numpixelx + j_row;
-            outws->dataX(wsindex)[0] = static_cast<double>(wsindex);
-            outws->dataY(wsindex)[0] = counts;
-            if (counts > 0)
-              outws->dataE(wsindex)[0] = sqrt(counts);
-            else
-              outws->dataE(wsindex)[0] = 1.0;
-
+            rowIndex = i_col * numpixelx + j_row;
+            columnIndex = 0;
           } else {
-            outws->dataX(j_row)[i_col] = static_cast<double>(j_row);
-            outws->dataY(j_row)[i_col] = counts;
-            if (counts > 0)
-              outws->dataE(j_row)[i_col] = sqrt(counts);
-            else
-              outws->dataE(j_row)[i_col] = 1.0;
+            rowIndex = j_row;
+            columnIndex = i_col;
           }
 
+          outws->mutableX(rowIndex)[columnIndex] =
+              static_cast<double>(columnIndex);
+          outws->mutableY(rowIndex)[columnIndex] = counts;
+
+          if (counts > 0)
+            outws->mutableE(rowIndex)[columnIndex] = sqrt(counts);
+          else
+            outws->mutableE(rowIndex)[columnIndex] = 1.0;
+
           // record max count
           if (counts > max_counts) {
             max_counts = counts;
@@ -713,8 +711,9 @@ void LoadSpiceXML2DDet::setXtoLabQ(API::MatrixWorkspace_sptr dataws,
   size_t numspec = dataws->getNumberHistograms();
   for (size_t iws = 0; iws < numspec; ++iws) {
     double ki = 2. * M_PI / wavelength;
-    dataws->dataX(iws)[0] = ki;
-    dataws->dataX(iws)[1] = ki + 0.00001;
+    auto &x = dataws->mutableX(iws);
+    x[0] = ki;
+    x[1] = ki + 0.00001;
   }
 
   dataws->getAxis(0)->setUnit("Momentum");
diff --git a/Framework/DataHandling/test/LoadQKKTest.h b/Framework/DataHandling/test/LoadQKKTest.h
index f324b8e555262ab74c602eaf88b4f5718709b331..2584f5ebd9851d4439acd993dfd8ae34985555db 100644
--- a/Framework/DataHandling/test/LoadQKKTest.h
+++ b/Framework/DataHandling/test/LoadQKKTest.h
@@ -54,6 +54,17 @@ public:
     const auto &spectrumInfo = data->spectrumInfo();
     for (size_t i = 0; i < data->getNumberHistograms(); ++i) {
       TS_ASSERT_THROWS_NOTHING(spectrumInfo.detector(i));
+
+      auto x = data->x(i);
+      TS_ASSERT_EQUALS(x.size(), 2);
+      TS_ASSERT_EQUALS(x[0], 1);
+      TS_ASSERT_EQUALS(x[1], 2);
+
+      auto y = data->y(i);
+      TS_ASSERT_EQUALS(y[0], 0.0);
+
+      auto e = data->e(i);
+      TS_ASSERT_EQUALS(e[0], 0.0);
     }
   }
 };
diff --git a/Framework/DataHandling/test/LoadSNSspecTest.h b/Framework/DataHandling/test/LoadSNSspecTest.h
index 45e1c54cc773a1cd19e11aaba43ca012afb221df..473d840b9f62af76cb4f73dc2b868c3774f2f503 100644
--- a/Framework/DataHandling/test/LoadSNSspecTest.h
+++ b/Framework/DataHandling/test/LoadSNSspecTest.h
@@ -49,19 +49,58 @@ public:
 
     TS_ASSERT_EQUALS(ws->getNumberHistograms(), 4); // number of spectrum
     TS_ASSERT_EQUALS(ws->blocksize(), 39);
-    // TS_ASSERT( ws->isDistribution() )
+    TS_ASSERT(!ws->isDistribution())
+    TS_ASSERT(ws->isHistogramData())
 
-    TS_ASSERT_EQUALS(ws->readX(0)[1], 148.294676917);
-    TS_ASSERT_EQUALS(ws->readX(2)[38], 314.564466187);
-    TS_ASSERT_EQUALS(ws->readX(3)[10], 188.738679712);
+    TS_ASSERT_EQUALS(ws->x(0)[1], 148.294676917);
+    TS_ASSERT_EQUALS(ws->x(2)[38], 314.564466187);
+    TS_ASSERT_EQUALS(ws->x(3)[10], 188.738679712);
 
-    TS_ASSERT_EQUALS(ws->readY(0)[4], 2.63040177974e-5);
-    TS_ASSERT_EQUALS(ws->readY(2)[10], 8.80816679672e-5);
-    TS_ASSERT_EQUALS(ws->readY(3)[38], 1.85253847513e-5);
+    TS_ASSERT_EQUALS(ws->y(0)[4], 2.63040177974e-5);
+    TS_ASSERT_EQUALS(ws->y(2)[10], 8.80816679672e-5);
+    TS_ASSERT_EQUALS(ws->y(3)[38], 1.85253847513e-5);
 
-    TS_ASSERT_EQUALS(ws->readE(0)[14], 8.03084255786e-6);
-    TS_ASSERT_EQUALS(ws->readE(1)[5], 1.42117480748e-5);
-    TS_ASSERT_EQUALS(ws->readE(3)[36], 5.76084468445e-5);
+    TS_ASSERT_EQUALS(ws->e(0)[14], 8.03084255786e-6);
+    TS_ASSERT_EQUALS(ws->e(1)[5], 1.42117480748e-5);
+    TS_ASSERT_EQUALS(ws->e(3)[36], 5.76084468445e-5);
+
+    AnalysisDataService::Instance().remove(outWS);
+  }
+
+  void testExecPoint() {
+    if (!loader.isInitialized())
+      loader.initialize();
+
+    std::string outWS("outWS");
+
+    TS_ASSERT_THROWS_NOTHING(
+        loader.setPropertyValue("Filename", "LoadSpecPoint.txt"));
+    TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("OutputWorkspace", outWS));
+
+    TS_ASSERT_THROWS_NOTHING(loader.execute());
+    TS_ASSERT(loader.isExecuted());
+
+    MatrixWorkspace_const_sptr ws;
+    TS_ASSERT_THROWS_NOTHING(
+        ws = boost::dynamic_pointer_cast<MatrixWorkspace>(
+            AnalysisDataService::Instance().retrieve(outWS)));
+
+    TS_ASSERT_EQUALS(ws->getNumberHistograms(), 4); // number of spectrum
+    TS_ASSERT_EQUALS(ws->blocksize(), 39);
+    TS_ASSERT(!ws->isDistribution())
+    TS_ASSERT(!ws->isHistogramData())
+
+    TS_ASSERT_EQUALS(ws->x(0)[1], 148.294676917);
+    TS_ASSERT_EQUALS(ws->x(2)[38], 314.564466187);
+    TS_ASSERT_EQUALS(ws->x(3)[10], 188.738679712);
+
+    TS_ASSERT_EQUALS(ws->y(0)[4], 2.63040177974e-5);
+    TS_ASSERT_EQUALS(ws->y(2)[10], 8.80816679672e-5);
+    TS_ASSERT_EQUALS(ws->y(3)[38], 1.85253847513e-5);
+
+    TS_ASSERT_EQUALS(ws->e(0)[14], 8.03084255786e-6);
+    TS_ASSERT_EQUALS(ws->e(1)[5], 1.42117480748e-5);
+    TS_ASSERT_EQUALS(ws->e(3)[36], 5.76084468445e-5);
 
     AnalysisDataService::Instance().remove(outWS);
   }
diff --git a/Framework/DataHandling/test/LoadSPETest.h b/Framework/DataHandling/test/LoadSPETest.h
index 2143a174defa2ba605e5f562583834457486e662..39f74af8935c01456171e4389aaff734c674bba1 100644
--- a/Framework/DataHandling/test/LoadSPETest.h
+++ b/Framework/DataHandling/test/LoadSPETest.h
@@ -62,21 +62,21 @@ public:
     TS_ASSERT_EQUALS((*(ws->getAxis(1)))(12), 12.5);
     TS_ASSERT_EQUALS((*(ws->getAxis(1)))(32), 32.5);
 
-    TS_ASSERT_EQUALS(ws->readX(0)[0], -20.0);
-    TS_ASSERT_EQUALS(ws->readX(22)[86], -2.8);
-    TS_ASSERT_EQUALS(ws->readX(31)[195], 19.0);
+    TS_ASSERT_EQUALS(ws->x(0)[0], -20.0);
+    TS_ASSERT_EQUALS(ws->x(22)[86], -2.8);
+    TS_ASSERT_EQUALS(ws->x(31)[195], 19.0);
     // verify result is NaN
-    TS_ASSERT_DIFFERS(ws->readY(4)[99], ws->readY(4)[99]);
-    TS_ASSERT_EQUALS(ws->readY(5)[0], 0.0);
-    TS_ASSERT_EQUALS(ws->readY(9)[48], -3.911);
-    TS_ASSERT_EQUALS(ws->readY(13)[137], 4.313);
-    TS_ASSERT_EQUALS(ws->readY(31)[194], 158.9);
-
-    TS_ASSERT_EQUALS(ws->readE(4)[173], 0.0);
-    TS_ASSERT_EQUALS(ws->readE(9)[111], 16.48);
-    TS_ASSERT_EQUALS(ws->readE(18)[0], 0.0);
-    TS_ASSERT_EQUALS(ws->readE(26)[35], 4.908);
-    TS_ASSERT_EQUALS(ws->readE(31)[194], 60.38);
+    TS_ASSERT_DIFFERS(ws->y(4)[99], ws->y(4)[99]);
+    TS_ASSERT_EQUALS(ws->y(5)[0], 0.0);
+    TS_ASSERT_EQUALS(ws->y(9)[48], -3.911);
+    TS_ASSERT_EQUALS(ws->y(13)[137], 4.313);
+    TS_ASSERT_EQUALS(ws->y(31)[194], 158.9);
+
+    TS_ASSERT_EQUALS(ws->e(4)[173], 0.0);
+    TS_ASSERT_EQUALS(ws->e(9)[111], 16.48);
+    TS_ASSERT_EQUALS(ws->e(18)[0], 0.0);
+    TS_ASSERT_EQUALS(ws->e(26)[35], 4.908);
+    TS_ASSERT_EQUALS(ws->e(31)[194], 60.38);
 
     AnalysisDataService::Instance().remove(outWS);
   }
diff --git a/Framework/DataHandling/test/LoadSassenaTest.h b/Framework/DataHandling/test/LoadSassenaTest.h
index 235e583c912c2526263399850920027904d49dae..7390eba20c7feb403633f834136119ac5af21759 100644
--- a/Framework/DataHandling/test/LoadSassenaTest.h
+++ b/Framework/DataHandling/test/LoadSassenaTest.h
@@ -52,37 +52,37 @@ public:
     DataObjects::Workspace2D_sptr ws =
         boost::dynamic_pointer_cast<DataObjects::Workspace2D>(
             gws->getItem("outGWS_qvectors"));
-    TS_ASSERT_DELTA(ws->readY(4)[0], 0.02402402, 1e-08);
+    TS_ASSERT_DELTA(ws->y(4)[0], 0.02402402, 1e-08);
 
     // Test fq
     ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(
         gws->getItem("outGWS_fq"));
-    TS_ASSERT_DELTA(ws->readY(0)[4], 1070.7009, 1e-04);
-    TS_ASSERT_DELTA(ws->readY(1)[4], 674.67703, 1e-05);
+    TS_ASSERT_DELTA(ws->y(0)[4], 1070.7009, 1e-04);
+    TS_ASSERT_DELTA(ws->y(1)[4], 674.67703, 1e-05);
 
     // Test fq0
     ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(
         gws->getItem("outGWS_fq0"));
-    TS_ASSERT_DELTA(ws->readY(0)[4], 1094.1314, 1e-04);
-    TS_ASSERT_DELTA(ws->readY(1)[4], 652.75902, 1e-05);
+    TS_ASSERT_DELTA(ws->y(0)[4], 1094.1314, 1e-04);
+    TS_ASSERT_DELTA(ws->y(1)[4], 652.75902, 1e-05);
 
     // Test fq2
     ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(
         gws->getItem("outGWS_fq2"));
-    TS_ASSERT_DELTA(ws->readY(0)[4], 358926.16, 1e-02);
-    TS_ASSERT_EQUALS(ws->readY(1)[4], 0.0);
+    TS_ASSERT_DELTA(ws->y(0)[4], 358926.16, 1e-02);
+    TS_ASSERT_EQUALS(ws->y(1)[4], 0.0);
 
     // Test fq Real part
     ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(
         gws->getItem("outGWS_fqt.Re"));
-    TS_ASSERT_DELTA(ws->readY(4)[0], 1918.2156, 1e-04);
-    TS_ASSERT_DELTA(ws->readY(4)[14], 1918.2156, 1e-04);
+    TS_ASSERT_DELTA(ws->y(4)[0], 1918.2156, 1e-04);
+    TS_ASSERT_DELTA(ws->y(4)[14], 1918.2156, 1e-04);
 
     // Test fq Imaginary part
     ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(
         gws->getItem("outGWS_fqt.Im"));
-    TS_ASSERT_DELTA(ws->readY(4)[0], -656.82368, 1e-05);
-    TS_ASSERT_DELTA(ws->readY(4)[14], 656.82368, 1e-05);
+    TS_ASSERT_DELTA(ws->y(4)[0], -656.82368, 1e-05);
+    TS_ASSERT_DELTA(ws->y(4)[14], 656.82368, 1e-05);
 
   } // end of testExec
 
diff --git a/Framework/DataHandling/test/LoadSpecTest.h b/Framework/DataHandling/test/LoadSpecTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..f53292751e308ed5b018bea96d200f6c40a0fb7c
--- /dev/null
+++ b/Framework/DataHandling/test/LoadSpecTest.h
@@ -0,0 +1,102 @@
+#ifndef LOADSNSSPECTEST_H_
+#define LOADSNSSPECTEST_H_
+
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidDataHandling/LoadSpec.h"
+#include <cxxtest/TestSuite.h>
+
+using namespace Mantid::API;
+
+class LoadSpecTest : public CxxTest::TestSuite {
+public:
+  void testName() { TS_ASSERT_EQUALS(loader.name(), "LoadSpec"); }
+
+  void testVersion() { TS_ASSERT_EQUALS(loader.version(), 1); }
+
+  void testInit() {
+    TS_ASSERT_THROWS_NOTHING(loader.initialize());
+    TS_ASSERT(loader.isInitialized());
+  }
+
+  void testExec() {
+    if (!loader.isInitialized())
+      loader.initialize();
+
+    std::string outWS("outWS");
+
+    TS_ASSERT_THROWS_NOTHING(
+        loader.setPropertyValue("Filename", "LoadSNSspec.txt"));
+    TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("OutputWorkspace", outWS));
+
+    TS_ASSERT_THROWS_NOTHING(loader.execute());
+    TS_ASSERT(loader.isExecuted());
+
+    MatrixWorkspace_const_sptr ws;
+    TS_ASSERT_THROWS_NOTHING(
+        ws = boost::dynamic_pointer_cast<MatrixWorkspace>(
+            AnalysisDataService::Instance().retrieve(outWS)));
+
+    TS_ASSERT_EQUALS(ws->getNumberHistograms(), 4); // number of spectrum
+    TS_ASSERT_EQUALS(ws->blocksize(), 39);
+    TS_ASSERT(!ws->isDistribution())
+    TS_ASSERT(ws->isHistogramData())
+
+    TS_ASSERT_EQUALS(ws->x(0)[1], 148.294676917);
+    TS_ASSERT_EQUALS(ws->x(2)[38], 314.564466187);
+    TS_ASSERT_EQUALS(ws->x(3)[10], 188.738679712);
+
+    TS_ASSERT_EQUALS(ws->y(0)[4], 2.63040177974e-5);
+    TS_ASSERT_EQUALS(ws->y(2)[10], 8.80816679672e-5);
+    TS_ASSERT_EQUALS(ws->y(3)[38], 1.85253847513e-5);
+
+    TS_ASSERT_EQUALS(ws->e(0)[14], 8.03084255786e-6);
+    TS_ASSERT_EQUALS(ws->e(1)[5], 1.42117480748e-5);
+    TS_ASSERT_EQUALS(ws->e(3)[36], 5.76084468445e-5);
+
+    AnalysisDataService::Instance().remove(outWS);
+  }
+
+  void testExecPoint() {
+    if (!loader.isInitialized())
+      loader.initialize();
+
+    std::string outWS("outWS");
+
+    TS_ASSERT_THROWS_NOTHING(
+        loader.setPropertyValue("Filename", "LoadSpecPoint.txt"));
+    TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("OutputWorkspace", outWS));
+
+    TS_ASSERT_THROWS_NOTHING(loader.execute());
+    TS_ASSERT(loader.isExecuted());
+
+    MatrixWorkspace_const_sptr ws;
+    TS_ASSERT_THROWS_NOTHING(
+        ws = boost::dynamic_pointer_cast<MatrixWorkspace>(
+            AnalysisDataService::Instance().retrieve(outWS)));
+
+    TS_ASSERT_EQUALS(ws->getNumberHistograms(), 4); // number of spectrum
+    TS_ASSERT_EQUALS(ws->blocksize(), 39);
+    TS_ASSERT(!ws->isDistribution())
+    TS_ASSERT(!ws->isHistogramData())
+
+    TS_ASSERT_EQUALS(ws->x(0)[1], 148.294676917);
+    TS_ASSERT_EQUALS(ws->x(2)[38], 314.564466187);
+    TS_ASSERT_EQUALS(ws->x(3)[10], 188.738679712);
+
+    TS_ASSERT_EQUALS(ws->y(0)[4], 2.63040177974e-5);
+    TS_ASSERT_EQUALS(ws->y(2)[10], 8.80816679672e-5);
+    TS_ASSERT_EQUALS(ws->y(3)[38], 1.85253847513e-5);
+
+    TS_ASSERT_EQUALS(ws->e(0)[14], 8.03084255786e-6);
+    TS_ASSERT_EQUALS(ws->e(1)[5], 1.42117480748e-5);
+    TS_ASSERT_EQUALS(ws->e(3)[36], 5.76084468445e-5);
+
+    AnalysisDataService::Instance().remove(outWS);
+  }
+
+private:
+  Mantid::DataHandling::LoadSpec loader;
+};
+
+#endif /*LoadSNSSPECTEST_H_*/
diff --git a/Framework/DataHandling/test/LoadSpice2dTest.h b/Framework/DataHandling/test/LoadSpice2dTest.h
index 1ebec15ccb8588e71f2383673c8c31cd4e143948..8523c7f619a9b23ece6a14a0496f30fe78613ab4 100644
--- a/Framework/DataHandling/test/LoadSpice2dTest.h
+++ b/Framework/DataHandling/test/LoadSpice2dTest.h
@@ -78,31 +78,31 @@ public:
                      36864 + Mantid::DataHandling::LoadSpice2D::nMonitors);
 
     // Test the size of the data vectors
-    TS_ASSERT_EQUALS((ws2d->dataX(0).size()), 2);
-    TS_ASSERT_EQUALS((ws2d->dataY(0).size()), 1);
-    TS_ASSERT_EQUALS((ws2d->dataE(0).size()), 1);
+    TS_ASSERT_EQUALS((ws2d->x(0).size()), 2);
+    TS_ASSERT_EQUALS((ws2d->y(0).size()), 1);
+    TS_ASSERT_EQUALS((ws2d->e(0).size()), 1);
 
     double tolerance(1e-04);
     int nmon = Mantid::DataHandling::LoadSpice2D::nMonitors;
-    TS_ASSERT_DELTA(ws2d->dataX(0 + nmon)[0], 5.93, tolerance);
-    TS_ASSERT_DELTA(ws2d->dataX(2 + nmon)[0], 5.93, tolerance);
-    TS_ASSERT_DELTA(ws2d->dataX(192 + nmon)[0], 5.93, tolerance);
+    TS_ASSERT_DELTA(ws2d->x(0 + nmon)[0], 5.93, tolerance);
+    TS_ASSERT_DELTA(ws2d->x(2 + nmon)[0], 5.93, tolerance);
+    TS_ASSERT_DELTA(ws2d->x(192 + nmon)[0], 5.93, tolerance);
 
-    TS_ASSERT_DELTA(ws2d->dataY(0 + nmon)[0], 318.0, tolerance);
-    TS_ASSERT_DELTA(ws2d->dataY(2 + nmon)[0], 109.0, tolerance);
-    TS_ASSERT_DELTA(ws2d->dataY(192 + nmon)[0], 390.0, tolerance);
+    TS_ASSERT_DELTA(ws2d->y(0 + nmon)[0], 318.0, tolerance);
+    TS_ASSERT_DELTA(ws2d->y(2 + nmon)[0], 109.0, tolerance);
+    TS_ASSERT_DELTA(ws2d->y(192 + nmon)[0], 390.0, tolerance);
 
-    TS_ASSERT_DELTA(ws2d->dataE(0 + nmon)[0], 17.8325, tolerance);
-    TS_ASSERT_DELTA(ws2d->dataE(2 + nmon)[0], 10.4403, tolerance);
-    TS_ASSERT_DELTA(ws2d->dataE(192 + nmon)[0], 19.7484, tolerance);
+    TS_ASSERT_DELTA(ws2d->e(0 + nmon)[0], 17.8325, tolerance);
+    TS_ASSERT_DELTA(ws2d->e(2 + nmon)[0], 10.4403, tolerance);
+    TS_ASSERT_DELTA(ws2d->e(192 + nmon)[0], 19.7484, tolerance);
 
     // check monitor
-    TS_ASSERT_DELTA(ws2d->dataY(0)[0], 29205906.0, tolerance);
-    TS_ASSERT_DELTA(ws2d->dataE(0)[0], 5404.2488, tolerance);
+    TS_ASSERT_DELTA(ws2d->y(0)[0], 29205906.0, tolerance);
+    TS_ASSERT_DELTA(ws2d->e(0)[0], 5404.2488, tolerance);
 
     // check timer
-    TS_ASSERT_DELTA(ws2d->dataY(1)[0], 3600.0, tolerance);
-    TS_ASSERT_DELTA(ws2d->dataE(1)[0], 0.0, tolerance);
+    TS_ASSERT_DELTA(ws2d->y(1)[0], 3600.0, tolerance);
+    TS_ASSERT_DELTA(ws2d->e(1)[0], 0.0, tolerance);
 
     // Check instrument
     //----------------------------------------------------------------------
@@ -206,15 +206,15 @@ public:
         boost::dynamic_pointer_cast<Mantid::DataObjects::Workspace2D>(ws);
 
     // Test the size of the data vectors
-    TS_ASSERT_EQUALS((ws2d->dataX(0).size()), 2);
-    TS_ASSERT_EQUALS((ws2d->dataY(0).size()), 1);
-    TS_ASSERT_EQUALS((ws2d->dataE(0).size()), 1);
+    TS_ASSERT_EQUALS((ws2d->x(0).size()), 2);
+    TS_ASSERT_EQUALS((ws2d->y(0).size()), 1);
+    TS_ASSERT_EQUALS((ws2d->e(0).size()), 1);
 
     double tolerance(1e-04);
     int nmon = Mantid::DataHandling::LoadSpice2D::nMonitors;
-    TS_ASSERT_DELTA(ws2d->dataX(0 + nmon)[0], 4.5, tolerance);
-    TS_ASSERT_DELTA(ws2d->dataX(2 + nmon)[0], 4.5, tolerance);
-    TS_ASSERT_DELTA(ws2d->dataX(192 + nmon)[0], 4.5, tolerance);
+    TS_ASSERT_DELTA(ws2d->x(0 + nmon)[0], 4.5, tolerance);
+    TS_ASSERT_DELTA(ws2d->x(2 + nmon)[0], 4.5, tolerance);
+    TS_ASSERT_DELTA(ws2d->x(192 + nmon)[0], 4.5, tolerance);
   }
 
   void assertDetectorDistances(Mantid::DataObjects::Workspace2D_sptr ws2d) {
diff --git a/Framework/Geometry/src/Instrument.cpp b/Framework/Geometry/src/Instrument.cpp
index 23a82264143154560c45b8b80696c217544ba4d4..395e369265863a02778433cdd4f0ffd242844caa 100644
--- a/Framework/Geometry/src/Instrument.cpp
+++ b/Framework/Geometry/src/Instrument.cpp
@@ -1235,8 +1235,6 @@ const Beamline::DetectorInfo &Instrument::detectorInfo() const {
 /// Only for use by ExperimentInfo. Sets the pointer to the DetectorInfo.
 void Instrument::setDetectorInfo(
     boost::shared_ptr<const Beamline::DetectorInfo> detectorInfo) {
-  if (m_map_nonconst)
-    m_map_nonconst->setDetectorInfo(detectorInfo);
   m_detectorInfo = std::move(detectorInfo);
 }
 namespace Conversion {
diff --git a/Framework/Geometry/src/Instrument/ParameterMap.cpp b/Framework/Geometry/src/Instrument/ParameterMap.cpp
index 0d7916d7a88c33fdf04c3c66bd6dedeebc74f9ef..85cde7251f732d6f06371e0ce5441ab8e77f785d 100644
--- a/Framework/Geometry/src/Instrument/ParameterMap.cpp
+++ b/Framework/Geometry/src/Instrument/ParameterMap.cpp
@@ -1165,10 +1165,7 @@ const Beamline::DetectorInfo &ParameterMap::detectorInfo() const {
 /// Only for use by ExperimentInfo. Sets the pointer to the DetectorInfo.
 void ParameterMap::setDetectorInfo(
     boost::shared_ptr<const Beamline::DetectorInfo> detectorInfo) {
-  if (detectorInfo != m_detectorInfo) {
-    PARALLEL_CRITICAL(ParameterMap_setDetectorInfo)
-    m_detectorInfo = std::move(detectorInfo);
-  }
+  m_detectorInfo = std::move(detectorInfo);
 }
 
 } // Namespace Geometry
diff --git a/Framework/PythonInterface/plugins/algorithms/SortXAxis.py b/Framework/PythonInterface/plugins/algorithms/SortXAxis.py
index e0d6eead820df25133e18978f2ffdb68ed739a13..ee803cb59e1246ccd5785d922c4efe1626ebf173 100644
--- a/Framework/PythonInterface/plugins/algorithms/SortXAxis.py
+++ b/Framework/PythonInterface/plugins/algorithms/SortXAxis.py
@@ -1,6 +1,5 @@
 #pylint: disable=no-init,invalid-name
 from __future__ import (absolute_import, division, print_function)
-import mantid.simpleapi as api
 
 from mantid.api import *
 from mantid.kernel import *
@@ -29,7 +28,12 @@ class SortXAxis(PythonAlgorithm):
         output_ws = self.getPropertyValue('OutputWorkspace')
 
         num_specs = input_ws.getNumberHistograms()
-        api.CloneWorkspace(InputWorkspace=input_ws, OutputWorkspace=output_ws)
+
+        clone_alg = self.createChildAlgorithm("CloneWorkspace", enableLogging=False)
+        clone_alg.setProperty("InputWorkspace", input_ws)
+        clone_alg.setProperty("OutputWorkspace", output_ws)
+        clone_alg.execute()
+        output_ws = clone_alg.getProperty("OutputWorkspace").value
 
         for i in range(0, num_specs):
             x_data = input_ws.readX(i)
@@ -46,9 +50,9 @@ class SortXAxis(PythonAlgorithm):
             y_ordered = y_data[indexes]
             e_ordered = e_data[indexes]
 
-            mtd[output_ws].setX(i, x_ordered)
-            mtd[output_ws].setY(i, y_ordered)
-            mtd[output_ws].setE(i, e_ordered)
+            output_ws.setX(i, x_ordered)
+            output_ws.setY(i, y_ordered)
+            output_ws.setE(i, e_ordered)
 
         self.setProperty('OutputWorkspace', output_ws)
 
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ElasticWindowMultiple.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ElasticWindowMultiple.py
index a911f07c447a7982591a8e4aa66e70b42113204c..5b3e08a10443166106c25258b9288b940292cb8f 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ElasticWindowMultiple.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ElasticWindowMultiple.py
@@ -216,7 +216,6 @@ class ElasticWindowMultiple(DataProcessorAlgorithm):
 
         progress.report('Creating ELF workspaces')
         transpose_alg = self.createChildAlgorithm("Transpose", enableLogging=False)
-        transpose_alg.setAlwaysStoreInADS(True)
         sort_alg = self.createChildAlgorithm("SortXAxis", enableLogging=False)
         # Process the ELF workspace
         if self._elf_workspace != '':
@@ -225,7 +224,7 @@ class ElasticWindowMultiple(DataProcessorAlgorithm):
             transpose_alg.setProperty("OutputWorkspace", self._elf_workspace)
             transpose_alg.execute()
 
-            sort_alg.setProperty("InputWorkspace", self._elf_workspace)
+            sort_alg.setProperty("InputWorkspace", transpose_alg.getProperty("OutputWorkspace").value)
             sort_alg.setProperty("OutputWorkspace", self._elf_workspace)
             sort_alg.execute()
 
@@ -247,7 +246,7 @@ class ElasticWindowMultiple(DataProcessorAlgorithm):
                 self._elt_workspace = sort_alg.getProperty("OutputWorkspace").value
             else:
                 clone_alg = self.createChildAlgorithm("CloneWorkspace", enableLogging=False)
-                clone_alg.setProperty("InputWorkspace", self._elf_workspace)
+                clone_alg.setProperty("InputWorkspace", self.getProperty("OutputELF").value)
                 clone_alg.setProperty("OutputWorkspace", self._elt_workspace)
                 clone_alg.execute()
                 self._elt_workspace = clone_alg.getProperty("OutputWorkspace").value
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/SortXAxisTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/SortXAxisTest.py
index 5efe3cf23d14f0f575211432d3d9dae0f8f41d72..211ba767192a7a7e8d38e4611af7d7b84ccf2736 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/SortXAxisTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/SortXAxisTest.py
@@ -109,7 +109,33 @@ class SortXAxisTest(unittest.TestCase):
         DeleteWorkspace(unsortedws)
         DeleteWorkspace(sortedws)
 
-
+    def test_sort_x_works_child(self):
+        # Create unsorted workspace
+        parent = AlgorithmManager.createUnmanaged('Load')
+        create_ws_alg = parent.createChildAlgorithm("CreateWorkspace")
+        dataX = [4, 3, 2, 1]
+        dataY = [1, 2, 3]
+        dataE = [1, 2, 3]
+        create_ws_alg.setProperty("DataX", dataX)
+        create_ws_alg.setProperty("DataY", dataY)
+        create_ws_alg.setProperty("DataE", dataE)
+        create_ws_alg.setProperty("UnitX",'TOF')
+        create_ws_alg.setProperty("Distribution", False)
+        create_ws_alg.execute()
+        # Run the algorithm
+        sort_alg = parent.createChildAlgorithm("SortXAxis")
+        sort_alg.setProperty("InputWorkspace", create_ws_alg.getProperty("OutputWorkspace").value)
+        sort_alg.execute()
+        # Check the resulting data values. Sorting operation should have resulted in no changes
+        sortedws = sort_alg.getProperty("OutputWorkspace").value
+        sortedX = sortedws.readX(0)
+        sortedY = sortedws.readY(0)
+        sortedE = sortedws.readE(0)
+        self.assertEqual(sorted(dataX), sortedX.tolist())
+        dataY.reverse()
+        dataE.reverse()
+        self.assertEqual(dataY, sortedY.tolist())
+        self.assertEqual(dataE, sortedE.tolist())
 
 if __name__ == '__main__':
     unittest.main()
\ No newline at end of file
diff --git a/MantidPlot/pymantidplot/__init__.py b/MantidPlot/pymantidplot/__init__.py
index 85ea6f3ba4e87d92054c87e572f5ab0b7a2eb475..1a0079aa6be7909ba97b6a01e6cb22d1e0453f1f 100644
--- a/MantidPlot/pymantidplot/__init__.py
+++ b/MantidPlot/pymantidplot/__init__.py
@@ -801,14 +801,13 @@ def plotSlice(source, label="", xydim=None, slicepoint=None,
 
     Optional Keyword Args:
         label :: label for the window title
-        xydim :: indexes or names of the dimensions to plot, as an (X,Y) list or tuple. See SliceViewer::setXYDim()
-        slicepoint :: list with the slice point in each dimension.
-                      Must be the same length as the number of dimensions of the workspace.
-                      See SliceViewer::setSlicePoint()
-        colormin :: value of the minimum color in the scale. See SliceViewer::setColorScaleMin()
-        colormax :: value of the maximum color in the scale. See SliceViewer::setColorScaleMax()
-        colorscalelog :: value of the maximum color in the scale. See SliceViewer::setColorScaleLog()
-        limits :: list with the (xleft, xright, ybottom, ytop) limits to the view to show. See SliceViewer::setXYLimits()
+        xydim :: indexes or names of the dimensions to plot, as an (X,Y) list or tuple. See `SliceViewer::setXYDim()`
+        slicepoint :: list with the slice point in each dimension.Must be the same length as the number of \
+dimensions of the workspace. See SliceViewer::setSlicePoint()
+        colormin :: value of the minimum color in the scale. See `SliceViewer::setColorScaleMin()`
+        colormax :: value of the maximum color in the scale. See `SliceViewer::setColorScaleMax()`
+        colorscalelog :: value of the maximum color in the scale. See `SliceViewer::setColorScaleLog()`
+        limits :: list with the (xleft, xright, ybottom, ytop) limits to the view to show. See `SliceViewer::setXYLimits()`
         normalization :: 0=none; 1=volume (default); 2=# of events.
 
     Returns:
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflRunsTabWidget.ui b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflRunsTabWidget.ui
index 0b93c3bb4b7974d0fd459cf4dc0a6b74b26bab4d..c82cfb0a83ace92ef289033dc03bfa36e1a29fb1 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflRunsTabWidget.ui
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflRunsTabWidget.ui
@@ -248,6 +248,12 @@
            </property>
            <item>
              <widget class="QToolBox" name="toolbox">
+               <property name="font">
+                 <font>
+                   <pointsize>11</pointsize>
+                   <bold>true</bold>
+                 </font>
+               </property>
              </widget>
            </item>
          </layout>
diff --git a/MantidQt/CustomInterfaces/src/Indirect/IndirectDiffractionReduction.cpp b/MantidQt/CustomInterfaces/src/Indirect/IndirectDiffractionReduction.cpp
index 26f5dce2addab27d0a8d50cb456476190fd0919d..aaf4cd9ae8692303fc7cd3c7ed81cff24987d055 100644
--- a/MantidQt/CustomInterfaces/src/Indirect/IndirectDiffractionReduction.cpp
+++ b/MantidQt/CustomInterfaces/src/Indirect/IndirectDiffractionReduction.cpp
@@ -115,7 +115,7 @@ void IndirectDiffractionReduction::run() {
   if (instName == "OSIRIS") {
     if (mode == "diffonly") {
       if (!validateVanCal()) {
-        showInformationBox("Vaniduium and Calibration input is invalid.");
+        showInformationBox("Vanadium and Calibration input is invalid.");
         return;
       }
       runOSIRISdiffonlyReduction();
@@ -131,8 +131,8 @@ void IndirectDiffractionReduction::run() {
       showInformationBox("Rebinning parameters are incorrect.");
       return;
     }
+    runGenericReduction(instName, mode);
   }
-  runGenericReduction(instName, mode);
 }
 
 /**
@@ -364,7 +364,7 @@ void IndirectDiffractionReduction::runGenericReduction(QString instName,
                                     m_uiForm.spCanScale->value());
   }
 
-  // Add the pproperty for grouping policy if needed
+  // Add the property for grouping policy if needed
   if (m_uiForm.ckIndividualGrouping->isChecked())
     msgDiffReduction->setProperty("GroupingPolicy", "Individual");
 
@@ -470,7 +470,7 @@ void IndirectDiffractionReduction::runOSIRISdiffonlyReduction() {
  *
  * Optionally loads an IPF if a reflection was provided.
  *
- * @param instrumentName Name of an inelastic indiretc instrument (IRIS, OSIRIN,
+ * @param instrumentName Name of an inelastic indirect instrument (IRIS, OSIRIS,
  *TOSCA, VESUVIO)
  * @param reflection Reflection mode to load parameters for (diffspec or
  *diffonly)
@@ -645,7 +645,7 @@ void IndirectDiffractionReduction::saveSettings() {
 /**
  * Validates the rebinning fields and updates invalid markers.
  *
- * @returns True if reinning options are valid, flase otherwise
+ * @returns True if reining options are valid, false otherwise
  */
 bool IndirectDiffractionReduction::validateRebin() {
   QString rebStartTxt = m_uiForm.leRebinStart->text();
@@ -736,7 +736,7 @@ bool IndirectDiffractionReduction::validateCalOnly() {
 }
 
 /**
- * Disables and shows message on run button indicating that run files have benn
+ * Disables and shows message on run button indicating that run files have been
  * changed.
  */
 void IndirectDiffractionReduction::runFilesChanged() {
diff --git a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/RotationSurface.h b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/RotationSurface.h
index 5e21f753185e7748e35c8ea7a7aa57867a25f2d6..0896d16f8005669ec61f4b5d371aa46942ce6177 100644
--- a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/RotationSurface.h
+++ b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/RotationSurface.h
@@ -46,6 +46,11 @@ protected:
   /// UnwrappedSurface::project().
   double applyUCorrection(double u) const;
 
+  /// Update the view rect to offset for the U correction
+  void updateViewRectForUCorrection();
+  /// Calculate UV offsets from the view rect
+  std::pair<double, double> calculateViewRectOffsets();
+
   const Mantid::Kernel::V3D m_pos; ///< Origin (sample position)
   const Mantid::Kernel::V3D
       m_zaxis; ///< The z axis of the surface specific coord system
diff --git a/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp b/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp
index 802c20883ea99d7e2c1b003cc808e921249c13b9..8a7b13c3c011c40554d6d4faaf7fbf51ee0bb0ad 100644
--- a/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp
+++ b/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp
@@ -3,6 +3,7 @@
 #include "MantidQtMantidWidgets/SequentialFitDialog.h"
 #include "MantidQtMantidWidgets/MultifitSetupDialog.h"
 #include "MantidQtAPI/MantidDesktopServices.h"
+#include "MantidQtAPI/HelpWindow.h"
 
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/IPeakFunction.h"
@@ -3063,11 +3064,8 @@ QStringList FitPropertyBrowser::getParameterNames() const {
 void FitPropertyBrowser::functionHelp() {
   PropertyHandler *handler = currentHandler();
   if (handler) {
-    // Create and open the URL of the help page
-    QString url =
-        QString::fromStdString("http://docs.mantidproject.org/fitfunctions/" +
-                               handler->ifun()->name());
-    MantidDesktopServices::openUrl(QUrl(url));
+    MantidQt::API::HelpWindow::showFitFunction(this->nativeParentWidget(),
+                                               handler->ifun()->name());
   }
 }
 
diff --git a/MantidQt/MantidWidgets/src/InstrumentView/RotationSurface.cpp b/MantidQt/MantidWidgets/src/InstrumentView/RotationSurface.cpp
index 65b053cb448e923448c40e046a63fb98f019597a..a1cd14e0cc1c60c5f0fda43f4bc669fc563f44cf 100644
--- a/MantidQt/MantidWidgets/src/InstrumentView/RotationSurface.cpp
+++ b/MantidQt/MantidWidgets/src/InstrumentView/RotationSurface.cpp
@@ -162,26 +162,42 @@ void RotationSurface::init() {
                             udet.u = applyUCorrection(udet.u);
                           }
                         }
+}
 
-                        double dU = fabs(m_u_max - m_u_min);
-                        double dV = fabs(m_v_max - m_v_min);
-                        double du = dU * 0.05;
-                        double dv = dV * 0.05;
-                        if (m_width_max > du && std::isfinite(m_width_max)) {
-                          if (du > 0 && !(dU >= m_width_max)) {
-                            m_width_max = dU;
-                          }
-                          du = m_width_max;
-                        }
-                        if (m_height_max > dv && std::isfinite(m_height_max)) {
-                          if (dv > 0 && !(dV >= m_height_max)) {
-                            m_height_max = dV;
-                          }
-                          dv = m_height_max;
-                        }
+/** Update the view rect to account for the U correction
+ */
+void RotationSurface::updateViewRectForUCorrection() {
+  const auto offsets = calculateViewRectOffsets();
+  const auto min = QPointF(m_u_min - offsets.first, m_v_min - offsets.second);
+  const auto max = QPointF(m_u_max + offsets.first, m_v_max + offsets.second);
+  m_viewRect = RectF(min, max);
+}
+
+/** Calculate UV offsets to the view rect
+ *
+ * @return a std::pair containing the u & v offsets for the view rect
+ */
+std::pair<double, double> RotationSurface::calculateViewRectOffsets() {
+  const auto dU = fabs(m_u_max - m_u_min);
+  const auto dV = fabs(m_v_max - m_v_min);
+  auto du = dU * 0.05;
+  auto dv = dV * 0.05;
+
+  if (m_width_max > du && std::isfinite(m_width_max)) {
+    if (du > 0 && !(dU >= m_width_max)) {
+      m_width_max = dU;
+    }
+    du = m_width_max;
+  }
+
+  if (m_height_max > dv && std::isfinite(m_height_max)) {
+    if (dv > 0 && !(dV >= m_height_max)) {
+      m_height_max = dV;
+    }
+    dv = m_height_max;
+  }
 
-                        m_viewRect = RectF(QPointF(m_u_min - du, m_v_min - dv),
-                                           QPointF(m_u_max + du, m_v_max + dv));
+  return std::make_pair(du, dv);
 }
 
 void RotationSurface::findUVBounds() {
@@ -308,6 +324,7 @@ void RotationSurface::setUCorrection(double umin, double umax) {
   }
   m_manual_u_correction = true;
   updateDetectors();
+  updateViewRectForUCorrection();
 }
 
 /**
@@ -316,6 +333,7 @@ void RotationSurface::setUCorrection(double umin, double umax) {
 void RotationSurface::setAutomaticUCorrection() {
   m_manual_u_correction = false;
   updateDetectors();
+  updateViewRectForUCorrection();
 }
 
 } // MantidWidgets
diff --git a/MantidQt/MantidWidgets/src/MantidHelpWindow.cpp b/MantidQt/MantidWidgets/src/MantidHelpWindow.cpp
index e84f06684128141a81d1d558e71fd03c7b9096cd..c8613668120d3695ad8d108a03516bd3427093d8 100644
--- a/MantidQt/MantidWidgets/src/MantidHelpWindow.cpp
+++ b/MantidQt/MantidWidgets/src/MantidHelpWindow.cpp
@@ -260,7 +260,7 @@ void MantidHelpWindow::showConcept(const QString &name) {
 void MantidHelpWindow::showFitFunction(const std::string &name) {
   if (bool(g_helpWindow)) {
     QString url(BASE_URL);
-    url += "functions/";
+    url += "fitfunctions/";
     if (name.empty())
       url += "index.html";
     else
diff --git a/MantidQt/MantidWidgets/src/UserFunctionDialog.cpp b/MantidQt/MantidWidgets/src/UserFunctionDialog.cpp
index cef8dcddcc316912917309e341a25dce83f8c7fc..ceadf692863289dcba6e3a61405da0fa9afb0357 100644
--- a/MantidQt/MantidWidgets/src/UserFunctionDialog.cpp
+++ b/MantidQt/MantidWidgets/src/UserFunctionDialog.cpp
@@ -80,6 +80,9 @@ void UserFunctionDialog::loadFunctions() {
   setFunction("Base", "sqrt", "sqrt(x)", "Sqare root of x");
   setFunction("Base", "sign", "sign(x)", "Sign of x");
   setFunction("Base", "rint", "rint(x)", "Round to nearest integer");
+  setFunction("Base", "erf", "erf(x)", "error function of x");
+  setFunction("Base", "erfc", "erfc(x)",
+              "Complementary error function erfc(x) = 1 - erf(x)");
   setFunction("Built-in", "Gauss", "h*exp(-s*(x-c)^2)");
   setFunction("Built-in", "ExpDecay", "h*exp(-x/t)");
   QFile funFile(
diff --git a/Testing/Data/UnitTest/LoadSpecPoint.txt.md5 b/Testing/Data/UnitTest/LoadSpecPoint.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..653ab265b516777be5760d20ffe519f63bf89035
--- /dev/null
+++ b/Testing/Data/UnitTest/LoadSpecPoint.txt.md5
@@ -0,0 +1 @@
+07e390fb339d5608a54f2e02aeb378a1
diff --git a/buildconfig/Jenkins/buildscript b/buildconfig/Jenkins/buildscript
index 1fbd8652525e583cce842c9dadb926b0a5c3ebfb..8115027e3736563ff42564f460c8fa57b039f734 100755
--- a/buildconfig/Jenkins/buildscript
+++ b/buildconfig/Jenkins/buildscript
@@ -28,9 +28,9 @@ if [[ ${NODE_LABELS} == *osx* ]]; then
 fi
 
 ###############################################################################
-# All nodes currently have PARAVIEW_DIR=5.2.0 and PARAVIEW_NEXT_DIR=5.1.2
+# All nodes currently have PARAVIEW_DIR=5.2.0 and PARAVIEW_NEXT_DIR=5.3.0-RC1
 ###############################################################################
-export PARAVIEW_DIR=${PARAVIEW_DIR}
+export PARAVIEW_DIR=${PARAVIEW_NEXT_DIR}
 
 ###############################################################################
 # Print out the versions of things we are using
diff --git a/buildconfig/Jenkins/buildscript.bat b/buildconfig/Jenkins/buildscript.bat
index e7f9c2b39f165387fb56f38b222acc7d6b8aef4f..e8eb0d1a3ba758f72b7da8ecef329630f617e30b 100755
--- a/buildconfig/Jenkins/buildscript.bat
+++ b/buildconfig/Jenkins/buildscript.bat
@@ -8,8 +8,7 @@ setlocal enableextensions enabledelayedexpansion
 :: BUILD_THREADS & PARAVIEW_DIR should be set in the configuration of each slave.
 :: CMake, git & git-lfs should be on the PATH
 ::
-:: All nodes currently have PARAVIEW_DIR=5.1.0, PARAVIEW_NEXT_DIR=5.0.0
-:: and PARAVIEW_MSVC2015_DIR=4.3.b40280-msvc2015
+:: All nodes currently have PARAVIEW_DIR=5.2.0 and PARAVIEW_NEXT_DIR=5.3.0-RC1
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 call cmake.exe --version
 set VS_VERSION=14
@@ -28,7 +27,7 @@ echo %sha1%
 set VS_VERSION=14
 call "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" amd64
 set CM_GENERATOR=Visual Studio 14 2015 Win64
-set PARAVIEW_DIR=%PARAVIEW_DIR%
+set PARAVIEW_DIR=%PARAVIEW_NEXT_DIR%
 
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 :: Set up the location for local object store outside of the build and source
diff --git a/docs/source/algorithms/BayesQuasi-v1.rst b/docs/source/algorithms/BayesQuasi-v1.rst
index f723456b9e835577632a1d94eb9657bb4b8a76ef..055473ed18806b3e8c378e3cd5ea94baa1465df2 100644
--- a/docs/source/algorithms/BayesQuasi-v1.rst
+++ b/docs/source/algorithms/BayesQuasi-v1.rst
@@ -19,7 +19,7 @@ so that the amplitudes represent their integrated areas.
 
 For a Lorentzian, the Fourier transform does the conversion:
 :math:`1/(x^{2}+\delta^{2}) \Leftrightarrow exp[-2\pi(\delta k)]`.
-If x is identified with energy E and :math:`2\pi k with t/\hbar` where t is time then:
+If x is identified with energy E and :math:`2\pi k` with :math:`t/\hbar` where t is time then:
 :math:`1/[E^{2}+(\hbar / \tau)^{2}] \Leftrightarrow exp[-t/\tau]` and :math:`\sigma` is identified with :math:`\hbar / \tau.`
 The program estimates the quasielastic components of each of the groups of spectra and requires the resolution
 file and optionally the normalisation file created by ResNorm.
@@ -52,4 +52,4 @@ Usage
 
 .. categories::
 
-.. sourcelink::
\ No newline at end of file
+.. sourcelink::
diff --git a/docs/source/algorithms/Q1D-v2.rst b/docs/source/algorithms/Q1D-v2.rst
index ec3b8e6f4ec149b736afdfd7d296d37a6dfcf6e9..58211b2be981940a13afbccc5a7cbe9441093831 100644
--- a/docs/source/algorithms/Q1D-v2.rst
+++ b/docs/source/algorithms/Q1D-v2.rst
@@ -139,7 +139,7 @@ From the equation it is possible to see that for pixels in
 substituting :math:`WaveCut = W_{low}` we have that :math:`R = 0` and
 hence all detectors contribute at wavelengths above :math:`WaveCut`.
 
-*Practically, it is more likely to be necessary to implement
+Practically, it is more likely to be necessary to implement
 :math:`RadiusCut` and :math:`WaveCut` in situations where the scattering
 near to the beamstop is weak and 'contaminated' by short wavelength
 scatter. This might arise, for example, when running at long
@@ -147,7 +147,7 @@ sample-detector distances, or at short sample-detector distances with
 large diameter beams, or where the sample generates Bragg peaks at
 low-Q. The best recourse is to check the wavelength overlap. If it is
 not too bad it may be possible to improve the data presentation simply
-by altering :math:`Q{min}` and the binning scheme.*
+by altering :math:`Q{min}` and the binning scheme.
 
 Examples
 ######################
diff --git a/docs/source/api/python/changes.rst b/docs/source/api/python/changes.rst
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/docs/source/api/python/index.rst b/docs/source/api/python/index.rst
index 18e44ea86b65e6f8bd0aad25756ffff38c738c0d..c65db0cf43c895db369382c2e7dda74a85424b11 100644
--- a/docs/source/api/python/index.rst
+++ b/docs/source/api/python/index.rst
@@ -20,7 +20,7 @@ Reference
 .. toctree::
    :hidden:
 
-   changes
+   changes <changes>
 
 Matplotlib-like plotting interface
 ----------------------------------
diff --git a/docs/source/release/v3.10.0/framework.rst b/docs/source/release/v3.10.0/framework.rst
index c1512caa458491911d5a44060196649164196e7d..d21aff7887b6a7bce3104735ee3971b06f63be2f 100644
--- a/docs/source/release/v3.10.0/framework.rst
+++ b/docs/source/release/v3.10.0/framework.rst
@@ -31,6 +31,8 @@ CurveFitting
 Improved
 ########
 
+- :ref:`UserFunction <func-UserFunction>` now supports :math:`erf` and :math:`erfc`.
+
 Python
 ------
 
diff --git a/docs/source/release/v3.10.0/index.rst b/docs/source/release/v3.10.0/index.rst
index 0863236dc1a57b24c1ea847044212d5f6949117d..a856a7fa0f5f2315cd445d408dd96feda96584d9 100644
--- a/docs/source/release/v3.10.0/index.rst
+++ b/docs/source/release/v3.10.0/index.rst
@@ -1,6 +1,6 @@
-==========================
+===========================
 Mantid 3.10.0 Release Notes
-==========================
+===========================
 
 .. figure:: ../../images/ReleaseUnderConstruction.jpg
    :class: screenshot
diff --git a/docs/source/release/v3.10.0/indirect_inelastic.rst b/docs/source/release/v3.10.0/indirect_inelastic.rst
index e45f25b1b5f7e65e83a60b09444b3b6741034d16..a1733c6061c57e67bf7d35bde1ddc802ade4b627 100644
--- a/docs/source/release/v3.10.0/indirect_inelastic.rst
+++ b/docs/source/release/v3.10.0/indirect_inelastic.rst
@@ -31,4 +31,6 @@ Improvements
 Bugfixes
 --------
 
+- The *Diffraction* Interface no longer crashes when in OSIRIS diffonly mode
+
 `Full list of changes on GitHub <http://github.com/mantidproject/mantid/pulls?q=is%3Apr+milestone%3A%22Release+3.10%22+is%3Amerged+label%3A%22Component%3A+Indirect+Inelastic%22>`_
diff --git a/docs/source/release/v3.10.0/sans.rst b/docs/source/release/v3.10.0/sans.rst
index b745605f557ec6f77ecf14a0671e51d027287acb..e7c21f51ea58d9e634361e06df6672c44ca08614 100644
--- a/docs/source/release/v3.10.0/sans.rst
+++ b/docs/source/release/v3.10.0/sans.rst
@@ -7,6 +7,7 @@ SANS Changes
 
 Bug Fixes
 ---------
+- Fixed wrong first spectrum number for LARMOR. The first non-monitor spectrum number is 11, but it had been set to 10.
 
 |
 
diff --git a/docs/source/release/v3.10.0/ui.rst b/docs/source/release/v3.10.0/ui.rst
index 16708099c14d90c883bdd4f08f5a891459082c33..ec933e261200fca3c7146c2f7d343a4e22612a69 100644
--- a/docs/source/release/v3.10.0/ui.rst
+++ b/docs/source/release/v3.10.0/ui.rst
@@ -19,6 +19,7 @@ User Interface
 
 Instrument View
 ###############
+ - Fixed a bug preventing the some of the banks from being visible when using a U correction.
 
 Plotting Improvements
 #####################
@@ -38,6 +39,10 @@ Bugs Resolved
 SliceViewer Improvements
 ------------------------
 
+VSI Improvments
+---------------
+Update ParaView to v5.3.0-RC1
+
 |
 
 Full list of
diff --git a/docs/source/release/v3.9.0/index.rst b/docs/source/release/v3.9.0/index.rst
index cd9519e34e99acee0e64c015ddc1fbfa68643730..4dcdf24c70a30ced732803d06cc0889e7b44a24f 100644
--- a/docs/source/release/v3.9.0/index.rst
+++ b/docs/source/release/v3.9.0/index.rst
@@ -30,6 +30,8 @@ Installation packages can be found on our `download page`_
 which now links to sourceforge to mirror our download files around the world, you can also
 access the source code on `GitHub release page`_.
 
+This is the last version to support RedHat Enterprise Linux 6 (RHEL6).
+
 Citation
 --------
 
diff --git a/scripts/CompareFitMinimizers/post_processing.py b/scripts/CompareFitMinimizers/post_processing.py
index ec92a02cc384d6c58a922c1b82f9492e88e664ea..863f9a63ed27b6257ed18401f6b0092a78aa5d4f 100644
--- a/scripts/CompareFitMinimizers/post_processing.py
+++ b/scripts/CompareFitMinimizers/post_processing.py
@@ -20,7 +20,14 @@
 
 from __future__ import (absolute_import, division, print_function)
 import numpy as np
-from scipy import stats  # older version of numpy does not support nanmean and nanmedian
+
+# older version of numpy does not support nanmean and nanmedian
+# and nanmean and nanmedian was removed in scipy 0.18 in favor of numpy
+# so try numpy first then scipy.stats
+try:
+    from numpy import nanmean, nanmedian
+except ImportError:
+    from scipy.stats import nanmean, nanmedian
 
 
 def calc_summary_table(minimizers, group_results):
@@ -60,8 +67,8 @@ def calc_summary_table(minimizers, group_results):
         norm_acc_rankings = accuracy_tbl / min_sum_err_sq[:, None]
         norm_runtime_rankings = time_tbl / min_runtime[:, None]
 
-        groups_norm_acc[group_idx, :] = stats.nanmedian(norm_acc_rankings, 0)
-        groups_norm_runtime[group_idx, :] = stats.nanmedian(norm_runtime_rankings, 0)
+        groups_norm_acc[group_idx, :] = nanmedian(norm_acc_rankings, 0)
+        groups_norm_runtime[group_idx, :] = nanmedian(norm_runtime_rankings, 0)
 
     return groups_norm_acc, groups_norm_runtime
 
@@ -103,14 +110,14 @@ def calc_norm_summary_tables(accuracy_tbl, time_tbl):
 
     summary_cells_acc = np.array([np.nanmin(norm_acc_rankings, 0),
                                   np.nanmax(norm_acc_rankings, 0),
-                                  stats.nanmean(norm_acc_rankings, 0),
-                                  stats.nanmedian(norm_acc_rankings, 0)
+                                  nanmean(norm_acc_rankings, 0),
+                                  nanmedian(norm_acc_rankings, 0)
                                   ])
 
     summary_cells_runtime = np.array([np.nanmin(norm_runtimes, 0),
                                       np.nanmax(norm_runtimes, 0),
-                                      stats.nanmean(norm_runtimes, 0),
-                                      stats.nanmedian(norm_runtimes, 0)
+                                      nanmean(norm_runtimes, 0),
+                                      nanmedian(norm_runtimes, 0)
                                       ])
 
     return norm_acc_rankings, norm_runtimes, summary_cells_acc, summary_cells_runtime
diff --git a/scripts/CompareFitMinimizers/results_output.py b/scripts/CompareFitMinimizers/results_output.py
index 57d28e5c23af2b95e2ca6723f5c3b07b132b5130..9ed41095057d5fc7bfdd30cac551c58a4411e99b 100644
--- a/scripts/CompareFitMinimizers/results_output.py
+++ b/scripts/CompareFitMinimizers/results_output.py
@@ -25,9 +25,16 @@ formats such as RST and plain text.
 from __future__ import (absolute_import, division, print_function)
 
 import numpy as np
-from scipy import stats  # older version of numpy does not support nanmean and nanmedian
 import post_processing as postproc
 
+# older version of numpy does not support nanmean and nanmedian
+# and nanmean and nanmedian was removed in scipy 0.18 in favor of numpy
+# so try numpy first then scipy.stats
+try:
+    from numpy import nanmean, nanmedian
+except ImportError:
+    from scipy.stats import nanmean, nanmedian
+
 # Some naming conventions for the output files
 BENCHMARK_VERSION_STR = 'v3.8'
 FILENAME_SUFFIX_ACCURACY = 'acc'
@@ -448,8 +455,8 @@ def print_tables_simple_text(minimizers, results_per_test, accuracy_tbl, time_tb
     results_text += '---------------- Summary (accuracy): -------- \n'
     results_text += 'Best ranking: {0}\n'.format(np.nanmin(norm_acc_rankings, 0))
     results_text += 'Worst ranking: {0}\n'.format(np.nanmax(norm_acc_rankings, 0))
-    results_text += 'Mean: {0}\n'.format(stats.nanmean(norm_acc_rankings, 0))
-    results_text += 'Median: {0}\n'.format(stats.nanmedian(norm_acc_rankings, 0))
+    results_text += 'Mean: {0}\n'.format(nanmean(norm_acc_rankings, 0))
+    results_text += 'Median: {0}\n'.format(nanmedian(norm_acc_rankings, 0))
     results_text += '\n'
 
     print(results_text)
@@ -467,8 +474,8 @@ def print_tables_simple_text(minimizers, results_per_test, accuracy_tbl, time_tb
     time_text += '---------------- Summary (run time): -------- \n'
     time_text += 'Best ranking: {0}\n'.format(np.nanmin(norm_runtimes, 0))
     time_text += 'Worst ranking: {0}\n'.format(np.nanmax(norm_runtimes, 0))
-    time_text += 'Mean: {0}\n'.format(stats.nanmean(norm_runtimes, 0))
-    time_text += 'Median: {0}\n'.format(stats.nanmedian(norm_runtimes, 0))
+    time_text += 'Mean: {0}\n'.format(nanmean(norm_runtimes, 0))
+    time_text += 'Median: {0}\n'.format(nanmedian(norm_runtimes, 0))
     time_text += '\n'
 
     print(time_text)
diff --git a/scripts/FilterEvents.py b/scripts/FilterEvents.py
index 5301cc40b27e06e7effc58b872368c7bad5e95ca..a63fb834d1a2f5a2b96a916417d18166de60aeea 100644
--- a/scripts/FilterEvents.py
+++ b/scripts/FilterEvents.py
@@ -1,4 +1,5 @@
 #pylint: disable=invalid-name
+from __future__ import (absolute_import, division, print_function)
 from FilterEvents import eventFilterGUI
 from PyQt4 import QtGui
 import sys
diff --git a/scripts/FilterEvents/MplFigureCanvas.py b/scripts/FilterEvents/MplFigureCanvas.py
index 29e109f5510e68adc56ffcba34b8bb406f9650d7..41176d1e840bbeb0e842a26caf3899a005341d3c 100644
--- a/scripts/FilterEvents/MplFigureCanvas.py
+++ b/scripts/FilterEvents/MplFigureCanvas.py
@@ -1,4 +1,5 @@
 #pylint: disable=invalid-name
+from __future__ import (absolute_import, division, print_function)
 from PyQt4 import QtGui
 
 from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
diff --git a/scripts/FilterEvents/__init__.py b/scripts/FilterEvents/__init__.py
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..af8a08144d8dd2724a1f5d04e707f5108f8e3dc7 100644
--- a/scripts/FilterEvents/__init__.py
+++ b/scripts/FilterEvents/__init__.py
@@ -0,0 +1,14 @@
+# Note that this a workaround
+# When introduced? During the Python2 to Python3 conversion
+# Why introduced? The autogenerated file ui_MainWindow.py contains a line
+#                 from MplFigureCancas import MplFigureCanvas
+#                 which should be
+#                 from .MpsFigureCanvas import MplFigureCanvas
+#                 for Python3, but since it is autogenerated we cannot change
+#                 this easily.
+import mantid
+import os
+import sys
+path = mantid.config["pythonscripts.directories"].split(";")[0]
+path = os.path.join(path[:path.index("scripts")], "scripts", "FilterEvents")
+sys.path.append(path)
diff --git a/scripts/FilterEvents/eventFilterGUI.py b/scripts/FilterEvents/eventFilterGUI.py
index 89b57105b65e2caead38e0e2bb518c53aaae5c7e..5464002a4cb29b63a7c5d3843832158560fcc382 100644
--- a/scripts/FilterEvents/eventFilterGUI.py
+++ b/scripts/FilterEvents/eventFilterGUI.py
@@ -1,4 +1,5 @@
 #pylint: disable=invalid-name, too-many-lines, too-many-instance-attributes
+from __future__ import (absolute_import, division, print_function)
 import numpy
 
 from FilterEvents.ui_MainWindow import Ui_MainWindow #import line for the UI python class
diff --git a/scripts/Interface/ui/reflectometer/refl_gui.py b/scripts/Interface/ui/reflectometer/refl_gui.py
index fc808e9a7dc1bbb520ce11b302c17420b87c7d9d..6d275c51f9a88da8c5ffa5d46b7383d7af68b9e8 100644
--- a/scripts/Interface/ui/reflectometer/refl_gui.py
+++ b/scripts/Interface/ui/reflectometer/refl_gui.py
@@ -1042,7 +1042,8 @@ class ReflGui(QtGui.QMainWindow, ui_refl_window.Ui_windowRefl):
                     alg = AlgorithmManager.create("ReflectometryReductionOneAuto")
                     alg.initialize()
                     alg.setProperty("InputWorkspace", ws[i])
-                    alg.setProperty("FirstTransmissionRun", group_trans_ws)
+                    if group_trans_ws:
+                        alg.setProperty("FirstTransmissionRun", group_trans_ws)
                     if angle is not None:
                         alg.setProperty("ThetaIn", angle)
                     alg.setProperty("OutputWorkspaceBinned", runno+'_IvsQ_binned_'+str(i+1))
@@ -1066,7 +1067,7 @@ class ReflGui(QtGui.QMainWindow, ui_refl_window.Ui_windowRefl):
                     wlamGroup.append(wlam)
                     thetaGroup.append(th)
 
-                wqBinned = GroupWorkspaces(InputWorkspaces=wqGroup, OutputWorkspace=runno+'_IvsQ_binned')
+                wqBinned = GroupWorkspaces(InputWorkspaces=wqGroupBinned, OutputWorkspace=runno+'_IvsQ_binned')
                 wq = GroupWorkspaces(InputWorkspaces=wqGroup, OutputWorkspace=runno+'_IvsQ')
                 wlam = GroupWorkspaces(InputWorkspaces=wlamGroup, OutputWorkspace=runno+'_IvsLam')
                 th = thetaGroup[0]
@@ -1074,7 +1075,8 @@ class ReflGui(QtGui.QMainWindow, ui_refl_window.Ui_windowRefl):
                 alg = AlgorithmManager.create("ReflectometryReductionOneAuto")
                 alg.initialize()
                 alg.setProperty("InputWorkspace", ws)
-                alg.setProperty("FirstTransmissionRun", transmission_ws)
+                if transmission_ws:
+                    alg.setProperty("FirstTransmissionRun", transmission_ws)
                 if angle is not None:
                     alg.setProperty("ThetaIn", angle)
                 alg.setProperty("OutputWorkspaceBinned", runno+'_IvsQ_binned')
diff --git a/scripts/QECoverage.py b/scripts/QECoverage.py
index 41336738b16e1f100b9df5d92dde5b7ff6c44c48..0906172dfc84ed7257e3c6a9e895e77c59452c4a 100644
--- a/scripts/QECoverage.py
+++ b/scripts/QECoverage.py
@@ -1,5 +1,6 @@
 # pylint: disable=line-too-long, too-many-instance-attributes, invalid-name, missing-docstring, too-many-statements
 # pylint: disable= too-many-branches, no-self-use
+from __future__ import (absolute_import, division, print_function)
 import sys
 
 import numpy as np
diff --git a/scripts/SANS/isis_instrument.py b/scripts/SANS/isis_instrument.py
index ba9fedfc628c9fee7a2feaec7d8dc543b4d74706..2bb0f0788c2cddc98c388f90b30dd198c486b7bd 100644
--- a/scripts/SANS/isis_instrument.py
+++ b/scripts/SANS/isis_instrument.py
@@ -1454,7 +1454,7 @@ class LARMOR(ISISInstrument):
         second = self.DETECTORS['high-angle']
 
         first.set_orien('Horizontal')
-        first.set_first_spec_num(10)
+        first.set_first_spec_num(11)
         second.set_orien('Horizontal')
         second.place_after(first)
 
diff --git a/scripts/TofConverter.py b/scripts/TofConverter.py
index b662651eea559ed4415f143859318f229f057e54..7c0a68b30bdf31cdd1e1049cedcc1a0e99dbb38a 100644
--- a/scripts/TofConverter.py
+++ b/scripts/TofConverter.py
@@ -1,4 +1,5 @@
 #pylint: disable=invalid-name
+from __future__ import (absolute_import, division, print_function)
 from TofConverter import converterGUI
 from PyQt4 import QtGui
 import sys
diff --git a/scripts/TofConverter/convertUnits.py b/scripts/TofConverter/convertUnits.py
index 89c14fcc0ff828eb431d13e4987f36ca0ad87cd8..cb788145fdd15101128826d5deb3295da6755f3b 100644
--- a/scripts/TofConverter/convertUnits.py
+++ b/scripts/TofConverter/convertUnits.py
@@ -1,4 +1,5 @@
 #pylint: disable=invalid-name,too-many-branches
+from __future__ import (absolute_import, division, print_function)
 import math
 # Used by converter GUI to do unit conversions
 
diff --git a/scripts/TofConverter/converterGUI.py b/scripts/TofConverter/converterGUI.py
index 1d3d19f21905064565e80c4a70fe762605893694..e29fd10951539797f4b03075cc8b8b4361933c26 100644
--- a/scripts/TofConverter/converterGUI.py
+++ b/scripts/TofConverter/converterGUI.py
@@ -1,5 +1,6 @@
 #pylint: disable=invalid-name
-from ui_converter import Ui_MainWindow #import line for the UI python class
+from __future__ import (absolute_import, division, print_function)
+from .ui_converter import Ui_MainWindow #import line for the UI python class
 from PyQt4 import QtCore, QtGui
 import math
 import TofConverter.convertUnits
@@ -96,12 +97,12 @@ class MainWindow(QtGui.QMainWindow):
 
             self.ui.convertedVal.clear()
             self.ui.convertedVal.insert(str(self.output))
-        except UnboundLocalError, ule:
+        except UnboundLocalError as ule:
             QtGui.QMessageBox.warning(self, "TofConverter", str(ule))
             return
-        except ArithmeticError, ae:
+        except ArithmeticError as ae:
             QtGui.QMessageBox.warning(self, "TofConverter", str(ae))
             return
-        except RuntimeError, re:
+        except RuntimeError as re:
             QtGui.QMessageBox.warning(self, "TofConverter", str(re))
             return
diff --git a/tools/skipped_systemtests.py b/tools/skipped_systemtests.py
index 80be8a9a65821f4ef78622e8b89b136d82043786..5634804ac173c34450198ab817da3b4a29086a68 100755
--- a/tools/skipped_systemtests.py
+++ b/tools/skipped_systemtests.py
@@ -5,7 +5,7 @@ import datetime
 import requests # python-requests
 
 URL = "http://builds.mantidproject.org/job/master_systemtests"
-PLATFORMS=['rhel7','rhel6', 'osx', 'win7', 'ubuntu']
+PLATFORMS=['rhel7', 'osx', 'win7', 'ubuntu', 'ubuntu-16.04']
 
 
 class TestCase(object):