diff --git a/Framework/API/inc/MantidAPI/AlgorithmHistory.h b/Framework/API/inc/MantidAPI/AlgorithmHistory.h
index 78b04c21c1de57618a493758e1ad7931035ea2b3..59f63f111216a0b39aebb39d3384b48d3908dec0 100644
--- a/Framework/API/inc/MantidAPI/AlgorithmHistory.h
+++ b/Framework/API/inc/MantidAPI/AlgorithmHistory.h
@@ -15,8 +15,6 @@
 #include "MantidKernel/PropertyHistory.h"
 #include <nexus/NeXusFile.hpp>
 
-#include <boost/bind.hpp>
-#include <boost/function.hpp>
 #include <ctime>
 #include <set>
 #include <vector>
diff --git a/Framework/API/src/IMDWorkspace.cpp b/Framework/API/src/IMDWorkspace.cpp
index 248fd5c8d146a679d3a461add5e28f3342ef6d39..10f38bf13e560010e83054376d1e331a90f7f327 100644
--- a/Framework/API/src/IMDWorkspace.cpp
+++ b/Framework/API/src/IMDWorkspace.cpp
@@ -135,7 +135,7 @@ const std::string IMDWorkspace::toString() const {
 void IMDWorkspace::makeSinglePointWithNaN(std::vector<coord_t> &x,
                                           std::vector<signal_t> &y,
                                           std::vector<signal_t> &e) const {
-  x.emplace_back(0);
+  x.emplace_back(0.f);
   y.emplace_back(std::numeric_limits<signal_t>::quiet_NaN());
   e.emplace_back(std::numeric_limits<signal_t>::quiet_NaN());
 }
diff --git a/Framework/API/src/IndexProperty.cpp b/Framework/API/src/IndexProperty.cpp
index 3a14b0852a07770cd4c520dd2c601999b6b55d40..977b69f8056ba68787fb6168c491932a0be54a7b 100644
--- a/Framework/API/src/IndexProperty.cpp
+++ b/Framework/API/src/IndexProperty.cpp
@@ -9,6 +9,7 @@
 #include "MantidIndexing/GlobalSpectrumIndex.h"
 #include "MantidIndexing/IndexInfo.h"
 #include "MantidIndexing/SpectrumNumber.h"
+#include "MantidKernel/WarningSuppressions.h"
 
 namespace Mantid {
 namespace API {
@@ -73,6 +74,7 @@ Indexing::SpectrumIndexSet IndexProperty::getIndices() const {
             static_cast<Indexing::SpectrumNumber>(static_cast<int32_t>(max)));
       }
     } else {
+      MSVC_DIAG_OFF(4244);
       switch (type) {
       case IndexType::WorkspaceIndex:
         return indexInfo.makeIndexSet(
@@ -84,6 +86,7 @@ Indexing::SpectrumIndexSet IndexProperty::getIndices() const {
         return indexInfo.makeIndexSet(spectrumNumbers);
       }
       }
+      MSVC_DIAG_ON(4244);
     }
   }
 
diff --git a/Framework/Algorithms/src/ConvertSpectrumAxis.cpp b/Framework/Algorithms/src/ConvertSpectrumAxis.cpp
index 310b43ca6fafb02cc4e5c378e66fd8b4b5ac68ac..28d196f097e56f70f08d1a8b30832e622d616093 100644
--- a/Framework/Algorithms/src/ConvertSpectrumAxis.cpp
+++ b/Framework/Algorithms/src/ConvertSpectrumAxis.cpp
@@ -20,9 +20,6 @@
 #include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitFactory.h"
 
-#include <boost/bind.hpp>
-#include <boost/function.hpp>
-
 #include <cfloat>
 
 namespace Mantid {
@@ -129,13 +126,14 @@ void ConvertSpectrumAxis::exec() {
   } else {
     // Set up binding to memeber funtion. Avoids condition as part of loop over
     // nHistograms.
-    boost::function<double(const IDetector &)> thetaFunction;
+    using namespace std::placeholders;
+    std::function<double(const IDetector &)> thetaFunction;
     if (unitTarget == "signed_theta") {
       thetaFunction =
-          boost::bind(&MatrixWorkspace::detectorSignedTwoTheta, inputWS, _1);
+          std::bind(&MatrixWorkspace::detectorSignedTwoTheta, inputWS, _1);
     } else {
       thetaFunction =
-          boost::bind(&MatrixWorkspace::detectorTwoTheta, inputWS, _1);
+          std::bind(&MatrixWorkspace::detectorTwoTheta, inputWS, _1);
     }
 
     bool warningGiven = false;
diff --git a/Framework/Algorithms/src/ConvertUnitsUsingDetectorTable.cpp b/Framework/Algorithms/src/ConvertUnitsUsingDetectorTable.cpp
index 0861c9b73c47da9f2964ae34321506b742fc5bea..ffbf9b641d7ba3332b2c76eda1dff17fa56af839 100644
--- a/Framework/Algorithms/src/ConvertUnitsUsingDetectorTable.cpp
+++ b/Framework/Algorithms/src/ConvertUnitsUsingDetectorTable.cpp
@@ -18,7 +18,6 @@
 #include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitFactory.h"
 
-#include <boost/bind.hpp>
 #include <boost/function.hpp>
 
 #include <algorithm>
diff --git a/Framework/Algorithms/src/CorrectKiKf.cpp b/Framework/Algorithms/src/CorrectKiKf.cpp
index e4eeb280e902cd704b760b930ffb9ccb9ab0a944..9cc3b2dc48b7a40598a1162f38dda94193f1a6c8 100644
--- a/Framework/Algorithms/src/CorrectKiKf.cpp
+++ b/Framework/Algorithms/src/CorrectKiKf.cpp
@@ -67,9 +67,9 @@ void CorrectKiKf::exec() {
   }
 
   // If input and output workspaces are not the same, create a new workspace for
-  // the output
+  // the output using the clone method to account for different workspace types
   if (outputWS != inputWS) {
-    outputWS = create<MatrixWorkspace>(*inputWS);
+    outputWS = inputWS->clone();
   }
 
   const size_t size = inputWS->blocksize();
diff --git a/Framework/Algorithms/src/Rebin2D.cpp b/Framework/Algorithms/src/Rebin2D.cpp
index 1d0d922a26f74d18dd454224a7d9f0f5a4404ac5..8301c3292612451ade37a55d912988c65bc9c984 100644
--- a/Framework/Algorithms/src/Rebin2D.cpp
+++ b/Framework/Algorithms/src/Rebin2D.cpp
@@ -155,7 +155,8 @@ void Rebin2D::exec() {
   }
   PARALLEL_CHECK_INTERUPT_REGION
   if (useFractionalArea) {
-    outputRB->finalize(true, true);
+    FractionalRebinning::finalizeFractionalRebin(*outputRB);
+    outputRB->finalize(true);
   }
 
   FractionalRebinning::normaliseOutput(outputWS, inputWS, m_progress.get());
diff --git a/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp b/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp
index 56e9482ab0b39815ce80aedac63badc5d77aea32..e18a314c97e1b38a95457d50097c9c14cff13dde 100644
--- a/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp
+++ b/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp
@@ -461,6 +461,7 @@ void SofQWNormalisedPolygon::exec() {
   }
   PARALLEL_CHECK_INTERUPT_REGION
 
+  FractionalRebinning::finalizeFractionalRebin(*outputWS);
   outputWS->finalize();
   FractionalRebinning::normaliseOutput(outputWS, inputWS, m_progress.get());
 
diff --git a/Framework/Algorithms/src/SumSpectra.cpp b/Framework/Algorithms/src/SumSpectra.cpp
index 856e4d87864b6ce0e21a826cae29642cf03dfd28..709247612b0812a9834b8ba8a3ef1cc755b808dc 100644
--- a/Framework/Algorithms/src/SumSpectra.cpp
+++ b/Framework/Algorithms/src/SumSpectra.cpp
@@ -165,6 +165,10 @@ void SumSpectra::init() {
   setPropertySettings(
       "MultiplyBySpectra",
       std::make_unique<EnabledWhenProperty>("WeightedSum", IS_EQUAL_TO, "1"));
+
+  declareProperty("UseFractionalArea", true,
+                  "Normalize the output workspace to the fractional area for "
+                  "RebinnedOutput workspaces.");
 }
 
 /*
@@ -520,6 +524,10 @@ void SumSpectra::doFractionalSum(MatrixWorkspace_sptr outputWorkspace,
   RebinnedOutput_sptr outWS =
       boost::dynamic_pointer_cast<RebinnedOutput>(outputWorkspace);
 
+  // Check finalize state prior to the sum process, at the completion
+  // the output is unfinalized
+  auto isFinalized = inWS->isFinalized();
+
   // Get references to the output workspaces's data vectors
   auto &outSpec = outputWorkspace->getSpectrum(0);
   auto &YSum = outSpec.mutableY();
@@ -548,21 +556,22 @@ void SumSpectra::doFractionalSum(MatrixWorkspace_sptr outputWorkspace,
     if (m_calculateWeightedSum) {
       for (size_t yIndex = 0; yIndex < m_yLength; ++yIndex) {
         const double yErrorsVal = YErrors[yIndex];
+        const double fracVal = (isFinalized ? FracArea[yIndex] : 1.0);
         if (std::isnormal(yErrorsVal)) { // is non-zero, nan, or infinity
-          const double errsq =
-              yErrorsVal * yErrorsVal * FracArea[yIndex] * FracArea[yIndex];
+          const double errsq = yErrorsVal * yErrorsVal * fracVal * fracVal;
           YErrorSum[yIndex] += errsq;
           Weight[yIndex] += 1. / errsq;
-          YSum[yIndex] += YValues[yIndex] * FracArea[yIndex] / errsq;
+          YSum[yIndex] += YValues[yIndex] * fracVal / errsq;
         } else {
           nZeros[yIndex]++;
         }
       }
     } else {
       for (size_t yIndex = 0; yIndex < m_yLength; ++yIndex) {
-        YSum[yIndex] += YValues[yIndex] * FracArea[yIndex];
-        YErrorSum[yIndex] += YErrors[yIndex] * YErrors[yIndex] *
-                             FracArea[yIndex] * FracArea[yIndex];
+        const double fracVal = (isFinalized ? FracArea[yIndex] : 1.0);
+        YSum[yIndex] += YValues[yIndex] * fracVal;
+        YErrorSum[yIndex] +=
+            YErrors[yIndex] * YErrors[yIndex] * fracVal * fracVal;
       }
     }
     // accumulation of fractional weight is the same
@@ -583,8 +592,11 @@ void SumSpectra::doFractionalSum(MatrixWorkspace_sptr outputWorkspace,
     numZeros = 0;
   }
 
-  // Create the correct representation
-  outWS->finalize();
+  // Create the correct representation if using fractional area
+  auto useFractionalArea = getProperty("UseFractionalArea");
+  if (useFractionalArea) {
+    outWS->finalize();
+  }
 }
 
 /** Executes the algorithm
diff --git a/Framework/Algorithms/test/SumSpectraTest.h b/Framework/Algorithms/test/SumSpectraTest.h
index 9b788614fb39d0b4a404da52ca29c360f67f5308..4f6b59606eb21cdea1cc6e2410d79552b32f68fa 100644
--- a/Framework/Algorithms/test/SumSpectraTest.h
+++ b/Framework/Algorithms/test/SumSpectraTest.h
@@ -342,28 +342,52 @@ public:
     RebinnedOutput_sptr output;
     output =
         AnalysisDataService::Instance().retrieveWS<RebinnedOutput>(outName);
-    TS_ASSERT(output);
-    TS_ASSERT_EQUALS(output->getNumberHistograms(), 1);
-    TS_ASSERT_EQUALS(output->blocksize(), 6);
-    // Row with full acceptance
-    TS_ASSERT_EQUALS(output->y(0)[1], 1.);
-    TS_ASSERT_DELTA(output->e(0)[1], 0.40824829046386296, 1.e-5);
-    TS_ASSERT_EQUALS(output->dataF(0)[1], 6.);
-    // Row with limited, but non-zero acceptance, shouldn't have nans!
-    TS_ASSERT_DELTA(output->y(0)[5], 0.66666, 1.e-5);
-    TS_ASSERT_DELTA(output->e(0)[5], 0.47140452079103173, 1.e-5);
-    TS_ASSERT_EQUALS(output->dataF(0)[5], 3.);
 
-    TS_ASSERT(output->run().hasProperty("NumAllSpectra"))
-    TS_ASSERT(output->run().hasProperty("NumMaskSpectra"))
-    TS_ASSERT(output->run().hasProperty("NumZeroSpectra"))
-
-    TS_ASSERT_EQUALS(boost::lexical_cast<std::string>(nHist),
-                     output->run().getLogData("NumAllSpectra")->value())
-    TS_ASSERT_EQUALS(boost::lexical_cast<std::string>(0),
-                     output->run().getLogData("NumMaskSpectra")->value())
-    TS_ASSERT_EQUALS(boost::lexical_cast<std::string>(0),
-                     output->run().getLogData("NumZeroSpectra")->value())
+    auto evaluate = [&, nHist](RebinnedOutput_sptr &output) {
+      TS_ASSERT(output);
+      TS_ASSERT_EQUALS(output->getNumberHistograms(), 1);
+      TS_ASSERT_EQUALS(output->blocksize(), 6);
+      // Row with full acceptance
+      TS_ASSERT_EQUALS(output->y(0)[1], 1.);
+      TS_ASSERT_DELTA(output->e(0)[1], 0.40824829046386296, 1.e-5);
+      TS_ASSERT_EQUALS(output->dataF(0)[1], 6.);
+      // Row with limited, but non-zero acceptance, shouldn't have nans!
+      TS_ASSERT_DELTA(output->y(0)[5], 0.66666, 1.e-5);
+      TS_ASSERT_DELTA(output->e(0)[5], 0.47140452079103173, 1.e-5);
+      TS_ASSERT_EQUALS(output->dataF(0)[5], 3.);
+
+      TS_ASSERT(output->run().hasProperty("NumAllSpectra"))
+      TS_ASSERT(output->run().hasProperty("NumMaskSpectra"))
+      TS_ASSERT(output->run().hasProperty("NumZeroSpectra"))
+
+      TS_ASSERT_EQUALS(boost::lexical_cast<std::string>(nHist),
+                       output->run().getLogData("NumAllSpectra")->value())
+      TS_ASSERT_EQUALS(boost::lexical_cast<std::string>(0),
+                       output->run().getLogData("NumMaskSpectra")->value())
+      TS_ASSERT_EQUALS(boost::lexical_cast<std::string>(0),
+                       output->run().getLogData("NumZeroSpectra")->value())
+    };
+
+    evaluate(output);
+
+    // unfinalize the workspace and confirm it gives the same results
+    // using a clean algorithm
+    ws->unfinalize();
+    AnalysisDataService::Instance().addOrReplace(inName, ws);
+    Mantid::Algorithms::SumSpectra alg3a;
+    if (!alg3a.isInitialized()) {
+      alg3a.initialize();
+    }
+    // Set the properties
+    alg3a.setPropertyValue("InputWorkspace", inName);
+    alg3a.setPropertyValue("OutputWorkspace", outName);
+    alg3a.setProperty("IncludeMonitors", false);
+    alg3a.setProperty("RemoveSpecialValues", true);
+    alg3a.execute();
+    TS_ASSERT(alg3a.isExecuted());
+    output =
+        AnalysisDataService::Instance().retrieveWS<RebinnedOutput>(outName);
+    evaluate(output);
   }
   void testExecNoLimitsWeighted() {
     Mantid::Algorithms::SumSpectra alg2;
diff --git a/Framework/Algorithms/test/WienerSmoothTest.h b/Framework/Algorithms/test/WienerSmoothTest.h
index 2e23642e37ab259b48dfb7aeaaee2913128084b4..eb772bfbdb3df66222ed75313a7000b3ef0dcd95 100644
--- a/Framework/Algorithms/test/WienerSmoothTest.h
+++ b/Framework/Algorithms/test/WienerSmoothTest.h
@@ -647,8 +647,9 @@ private:
       Y.assign(y, y + ny);
       E.assign(e, e + ny);
       using std::placeholders::_1;
-      std::transform(Y.begin(), Y.end(), Y.begin(),
-                     std::bind(std::multiplies<double>(), _1, i + 1));
+      std::transform(
+          Y.begin(), Y.end(), Y.begin(),
+          std::bind(std::multiplies<double>(), _1, static_cast<double>(i + 1)));
     }
 
     return dataWS;
diff --git a/Framework/CMakeLists.txt b/Framework/CMakeLists.txt
index fe0306b6dc98d20734dea40df4d2b182a1915cbd..fe0655675f91b6948921ffcf5e23375d1d1e97a0 100644
--- a/Framework/CMakeLists.txt
+++ b/Framework/CMakeLists.txt
@@ -212,8 +212,13 @@ foreach(_bundle ${BUNDLES})
 
     # Also ship mingw libraries for Inelastic fortran code. We need to do a
     # better job here and build things
-    file(GLOB MINGW_DLLS "${THIRD_PARTY_DIR}/bin/mingw/*.dll")
-    install(FILES ${MINGW_DLLS} DESTINATION ${_bundle}scripts/Inelastic)
+    if(WITH_PYTHON3)
+      install(FILES "${THIRD_PARTY_DIR}/bin/libquadmath-0.dll" "${THIRD_PARTY_DIR}/bin/libgcc_s_seh-1.dll"
+              DESTINATION ${_bundle}scripts/Inelastic)
+    else()
+      file(GLOB MINGW_DLLS "${THIRD_PARTY_DIR}/bin/mingw/*.dll")
+      install(FILES ${MINGW_DLLS} DESTINATION ${_bundle}scripts/Inelastic)
+    endif()
   else()
     install(DIRECTORY ../scripts/
             DESTINATION ${_bundle}scripts
diff --git a/Framework/CurveFitting/src/Functions/ComptonScatteringCountRate.cpp b/Framework/CurveFitting/src/Functions/ComptonScatteringCountRate.cpp
index 9866ce0bfe5e761f3e992b01c85b8f3c1c83a57b..b0e6ce7ceac7568a3e2fb2d13a8233a40083f8d4 100644
--- a/Framework/CurveFitting/src/Functions/ComptonScatteringCountRate.cpp
+++ b/Framework/CurveFitting/src/Functions/ComptonScatteringCountRate.cpp
@@ -10,8 +10,6 @@
 #include "MantidCurveFitting/AugmentedLagrangianOptimizer.h"
 #include "MantidKernel/Math/Optimization/SLSQPMinimizer.h"
 
-#include <boost/bind.hpp>
-
 #include <sstream>
 
 namespace Mantid {
@@ -166,8 +164,9 @@ void ComptonScatteringCountRate::iterationStarting() {
 
   if (m_bkgdPolyN > 0) {
     BkgdNorm2 objf(m_cmatrix, m_dataErrorRatio);
+    using namespace std::placeholders;
     AugmentedLagrangianOptimizer::ObjFunction objfunc =
-        boost::bind(&BkgdNorm2::eval, objf, _1, _2);
+        std::bind(&BkgdNorm2::eval, objf, _1, _2);
     AugmentedLagrangianOptimizer lsqmin(nparams, objfunc, m_eqMatrix,
                                         m_cmatrix);
     lsqmin.minimize(x0);
diff --git a/Framework/CurveFitting/test/AugmentedLagrangianOptimizerTest.h b/Framework/CurveFitting/test/AugmentedLagrangianOptimizerTest.h
index 627d83ab81ea44cab3480af4ae9981e334ff00c2..32ecca97fac0a8edc26b0231be199383a5d46ed2 100644
--- a/Framework/CurveFitting/test/AugmentedLagrangianOptimizerTest.h
+++ b/Framework/CurveFitting/test/AugmentedLagrangianOptimizerTest.h
@@ -12,7 +12,6 @@
 #include "MantidCurveFitting/AugmentedLagrangianOptimizer.h"
 #include "MantidKernel/Matrix.h"
 
-#include <boost/bind.hpp>
 #include <boost/make_shared.hpp>
 
 class AugmentedLagrangianOptimizerTest : public CxxTest::TestSuite {
@@ -78,11 +77,12 @@ public:
 
   void test_minimizer_calls_user_function() {
     using Mantid::CurveFitting::AugmentedLagrangianOptimizer;
+    using namespace std::placeholders;
 
     bool userFuncCalled = false;
     TestUserFuncCall testFunc(userFuncCalled);
     AugmentedLagrangianOptimizer::ObjFunction userFunc =
-        boost::bind(&TestUserFuncCall::eval, testFunc, _1, _2);
+        std::bind(&TestUserFuncCall::eval, testFunc, _1, _2);
     AugmentedLagrangianOptimizer lsqmin(2, userFunc);
 
     std::vector<double> xv(2, 1);
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadAscii2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadAscii2.h
index 561ff25566b17da2ee974d01b3877a4e7bce8288..df4771a4f6a17577b9718e31bbeb5ef7532ae010 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadAscii2.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadAscii2.h
@@ -40,7 +40,7 @@ public:
   /// Summary of algorithms purpose
   const std::string summary() const override {
     return "Loads data from a text file and stores it in a 2D workspace "
-           "(Workspace2D class).";
+           "or Table Workspace.";
   }
 
   /// The version number
@@ -56,6 +56,8 @@ public:
 protected:
   /// Read the data from the file
   virtual API::Workspace_sptr readData(std::ifstream &file);
+  /// Read the data from the file into a table workspace
+  virtual API::Workspace_sptr readTable(std::ifstream &file);
   /// Return true if the line is to be skipped
   bool skipLine(const std::string &line, bool header = false) const;
   /// Return true if the line doesn't start with a valid character
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveAscii2.h b/Framework/DataHandling/inc/MantidDataHandling/SaveAscii2.h
index 9ff03e61e77ad02bbca8b757ba929631d8aae959..4f189859690356d091e1df104ebce941bf1fc99e 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveAscii2.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveAscii2.h
@@ -12,6 +12,7 @@
 //----------------------------------------------------------------------
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/Axis.h"
+#include "MantidAPI/ITableWorkspace_fwd.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
 
 namespace Mantid {
@@ -71,6 +72,10 @@ private:
   void init() override;
   /// Overwrites Algorithm method
   void exec() override;
+  void writeTableWorkspace(API::ITableWorkspace_const_sptr tws,
+                           const std::string &filename, bool appendToFile,
+                           bool writeHeader, int prec, bool scientific,
+                           const std::string &comment);
   /// Writes a spectrum to the file using a workspace index
   void writeSpectrum(const int &wsIndex, std::ofstream &file);
   std::vector<std::string> stringListToVector(std::string &inputString);
diff --git a/Framework/DataHandling/src/EventWorkspaceCollection.cpp b/Framework/DataHandling/src/EventWorkspaceCollection.cpp
index dbe936af1fcb85a392855f991a6bf86947938086..7d570943446221361b908e4cd2307b0f2f15fcea 100644
--- a/Framework/DataHandling/src/EventWorkspaceCollection.cpp
+++ b/Framework/DataHandling/src/EventWorkspaceCollection.cpp
@@ -14,7 +14,6 @@
 #include "MantidIndexing/IndexInfo.h"
 #include "MantidKernel/UnitFactory.h"
 
-#include <boost/bind.hpp>
 #include <memory>
 #include <set>
 #include <unordered_set>
diff --git a/Framework/DataHandling/src/LoadAscii.cpp b/Framework/DataHandling/src/LoadAscii.cpp
index 8b102fc8a0d07d35873b061f4e708b2d85836af4..edbef52288ce83bb3b3b5809059ad6a1af212c83 100644
--- a/Framework/DataHandling/src/LoadAscii.cpp
+++ b/Framework/DataHandling/src/LoadAscii.cpp
@@ -45,9 +45,14 @@ int LoadAscii::confidence(Kernel::FileDescriptor &descriptor) const {
 
   // Avoid some known file types that have different loaders
   int confidence(0);
-  if (filePath.compare(filenameLength - 12, 12, "_runinfo.xml") == 0 ||
-      filePath.compare(filenameLength - 6, 6, ".peaks") == 0 ||
-      filePath.compare(filenameLength - 10, 10, ".integrate") == 0) {
+  if (filenameLength > 12
+          ? (filePath.compare(filenameLength - 12, 12, "_runinfo.xml") == 0)
+          : false || filenameLength > 6
+                ? (filePath.compare(filenameLength - 6, 6, ".peaks") == 0)
+                : false || filenameLength > 10
+                      ? (filePath.compare(filenameLength - 10, 10,
+                                          ".integrate") == 0)
+                      : false) {
     confidence = 0;
   } else if (descriptor.isAscii()) {
     confidence = 9; // Low so that others may try but not stopping version 2
diff --git a/Framework/DataHandling/src/LoadAscii2.cpp b/Framework/DataHandling/src/LoadAscii2.cpp
index 75a208de12569937a509d8b089bca07ec6fbcfcd..9bce357a49ad3f82f0ed9327a97574a1aa91fd58 100644
--- a/Framework/DataHandling/src/LoadAscii2.cpp
+++ b/Framework/DataHandling/src/LoadAscii2.cpp
@@ -10,7 +10,9 @@
 #include "MantidAPI/NumericAxis.h"
 #include "MantidAPI/RegisterFileLoader.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/TableRow.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidDataObjects/TableWorkspace.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidHistogramData/HistogramMath.h"
 #include "MantidKernel/BoundedValidator.h"
@@ -51,9 +53,14 @@ int LoadAscii2::confidence(Kernel::FileDescriptor &descriptor) const {
 
   // Avoid some known file types that have different loaders
   int confidence(0);
-  if (filePath.compare(filenameLength - 12, 12, "_runinfo.xml") == 0 ||
-      filePath.compare(filenameLength - 6, 6, ".peaks") == 0 ||
-      filePath.compare(filenameLength - 10, 10, ".integrate") == 0) {
+  if (filenameLength > 12
+          ? (filePath.compare(filenameLength - 12, 12, "_runinfo.xml") == 0)
+          : false || filenameLength > 6
+                ? (filePath.compare(filenameLength - 6, 6, ".peaks") == 0)
+                : false || filenameLength > 10
+                      ? (filePath.compare(filenameLength - 10, 10,
+                                          ".integrate") == 0)
+                      : false) {
     confidence = 0;
   } else if (descriptor.isAscii()) {
     confidence = 10; // Low so that others may try
@@ -78,6 +85,12 @@ API::Workspace_sptr LoadAscii2::readData(std::ifstream &file) {
   // there is still flexibility, but the format should just make more sense in
   // general
 
+  // if the file appears to be a table workspace then read it as such
+  auto ws = readTable(file);
+  if (ws) {
+    return ws;
+  }
+
   m_baseCols = 0;
   m_specNo = 0;
   m_lastBins = 0;
@@ -134,6 +147,140 @@ API::Workspace_sptr LoadAscii2::readData(std::ifstream &file) {
   return localWorkspace;
 }
 
+/// Attempts to read a table workspace from the file.
+/// Failing early if the format does not match.
+/// @param file the file handle to load from
+/// @returns a populated table workspace or an empty shared pointer
+API::Workspace_sptr LoadAscii2::readTable(std::ifstream &file) {
+
+  DataObjects::TableWorkspace_sptr ws;
+  // We need to see two rows commented out
+  // the first with column names
+  // the second with column types
+  // Then we need data, with the same number of columns as the first two lines
+
+  try {
+    size_t colNames = 0;
+    size_t colTypes = 0;
+    std::string line;
+    std::list<std::string> names;
+    std::list<std::string> types;
+    std::list<std::string> data;
+
+    while (getline(file, line)) {
+      boost::trim(line);
+
+      std::list<std::string> columns;
+
+      if (!line.empty()) {
+        // if line starts with a comment
+        if (line.at(0) == m_comment.at(0)) {
+          // remove the comment character
+          line.erase(0, 1);
+          size_t lineCols = this->splitIntoColumns(columns, line);
+          if (colNames == 0) {
+            colNames = lineCols;
+            names = columns;
+            continue;
+          }
+          if (colTypes == 0) {
+            colTypes = lineCols;
+            types = columns;
+            continue;
+          }
+        }
+
+        if (colTypes != colNames) {
+          // no point going further, the types and names differ in quantity
+          break;
+        }
+
+        size_t colData = this->splitIntoColumns(data, line);
+        if (colNames > 0 && colNames == colTypes && colTypes == colData) {
+          // we seem to have a table workspace
+          // if we have no already created a workspace
+          if (!ws) {
+            ws = boost::make_shared<DataObjects::TableWorkspace>();
+            // create the columns
+            auto itName = names.begin();
+            auto itTypes = types.begin();
+            for (size_t i = 0; i < colNames; i++) {
+              std::string name = *itName;
+              std::string type = *itTypes;
+              // trim the strings
+              boost::trim(name);
+              boost::trim(type);
+              ws->addColumn(std::move(type), std::move(name));
+              itName++;
+              itTypes++;
+            }
+          }
+          // add the data
+          TableRow row = ws->appendRow();
+          auto itTypes = types.begin();
+          for (auto itData = data.begin(); itData != data.end(); itData++) {
+            // direct assignment only works for strings, we ill need to handle
+            // the other data types here
+            std::string type = *itTypes;
+            boost::trim(type);
+            if (type == "str") {
+              row << *itData;
+            } else if (type == "int") {
+              int num = boost::lexical_cast<int>(*itData);
+              row << num;
+            } else if (type == "uint") {
+              uint32_t num = boost::lexical_cast<uint32_t>(*itData);
+              row << num;
+            } else if (type == "long64") {
+              auto num = boost::lexical_cast<int64_t>(*itData);
+              row << num;
+            } else if (type == "size_t") {
+              size_t num = boost::lexical_cast<size_t>(*itData);
+              row << num;
+            } else if (type == "float") {
+              float num = boost::lexical_cast<float>(*itData);
+              row << num;
+            } else if (type == "double") {
+              double num = boost::lexical_cast<double>(*itData);
+              row << num;
+            } else if (type == "bool") {
+              bool val = (itData->at(0) == 't');
+              row << val;
+            } else if (type == "V3D") {
+              V3D val;
+              std::stringstream ss(*itData);
+              val.readPrinted(ss);
+              row << val;
+            } else {
+              throw std::runtime_error("unknown column data type " + type);
+            }
+            itTypes++;
+          }
+        }
+      }
+    }
+    // if the file does not have more than rowsToCheck, it will
+    // stop
+    // and raise the EndOfFile, this may cause problems for small workspaces.
+    // In this case clear the flag
+    if (file.eof()) {
+      file.clear(file.eofbit);
+    }
+  } catch (std::exception &ex) {
+    // log and squash the error, so we can still try to load the file as a
+    // matrix workspace
+    g_log.warning() << "Error while trying to read ascii file as table, "
+                       "continuing to load as matrix workspace.\n"
+                    << ex.what() << "\n";
+    // clear any workspace that we started loading
+    ws.reset();
+  }
+
+  // Seek the file pointer back to the start.
+  file.seekg(0, std::ios::beg);
+  return ws;
+}
+
 /**
  * Check the start of the file for the first data set, then set the number of
  * columns that hsould be expected thereafter
@@ -754,8 +901,10 @@ void LoadAscii2::exec() {
   }
   MatrixWorkspace_sptr outputWS =
       boost::dynamic_pointer_cast<MatrixWorkspace>(rd);
-  outputWS->mutableRun().addProperty("Filename", filename);
-  setProperty("OutputWorkspace", outputWS);
+  if (outputWS) {
+    outputWS->mutableRun().addProperty("Filename", filename);
+  }
+  setProperty("OutputWorkspace", rd);
 }
 } // namespace DataHandling
 } // namespace Mantid
diff --git a/Framework/DataHandling/src/LoadHFIRSANS.cpp b/Framework/DataHandling/src/LoadHFIRSANS.cpp
index fff19d713188c0ba730189b0b288a2024e00f3f8..f1e86e0da34f44707ca679d0953b454b9b961b6d 100644
--- a/Framework/DataHandling/src/LoadHFIRSANS.cpp
+++ b/Framework/DataHandling/src/LoadHFIRSANS.cpp
@@ -538,10 +538,20 @@ void LoadHFIRSANS::storeMetaDataIntoWS() {
       "source-aperture-diameter",
       boost::lexical_cast<double>(m_metadata["Header/source_aperture_size"]),
       "mm");
+  addRunProperty<double>(
+      "source_aperture_diameter",
+      boost::lexical_cast<double>(m_metadata["Header/source_aperture_size"]),
+      "mm");
+
   addRunProperty<double>(
       "sample-aperture-diameter",
       boost::lexical_cast<double>(m_metadata["Header/sample_aperture_size"]),
       "mm");
+  addRunProperty<double>(
+      "sample_aperture_diameter",
+      boost::lexical_cast<double>(m_metadata["Header/sample_aperture_size"]),
+      "mm");
+
   addRunProperty<double>(
       "number-of-guides",
       boost::lexical_cast<double>(m_metadata["Motor_Positions/nguides"]));
@@ -629,6 +639,9 @@ void LoadHFIRSANS::setDetectorDistance() {
                 << " mm." << '\n';
   addRunProperty<double>("sample-detector-distance", m_sampleDetectorDistance,
                          "mm");
+  addRunProperty<double>("sample_detector_distance", m_sampleDetectorDistance,
+                         "mm");
+
   addRunTimeSeriesProperty<double>("sdd", m_sampleDetectorDistance);
 }
 
@@ -736,6 +749,9 @@ void LoadHFIRSANS::setBeamDiameter() {
   double sourceToSampleDistance = getSourceToSampleDistance();
   addRunProperty<double>("source-sample-distance", sourceToSampleDistance,
                          "mm");
+  addRunProperty<double>("source_sample_distance", sourceToSampleDistance,
+                         "mm");
+
   const auto sampleAperture =
       boost::lexical_cast<double>(m_metadata["Header/sample_aperture_size"]);
   const auto sourceAperture =
diff --git a/Framework/DataHandling/src/LoadNexusProcessed.cpp b/Framework/DataHandling/src/LoadNexusProcessed.cpp
index e251aea1bb830fc4d0c679526c2393eebaff14be..f22a90ae90b0b7ea5ded8acc6a8a874032817d2e 100644
--- a/Framework/DataHandling/src/LoadNexusProcessed.cpp
+++ b/Framework/DataHandling/src/LoadNexusProcessed.cpp
@@ -1302,6 +1302,16 @@ API::MatrixWorkspace_sptr LoadNexusProcessed::loadNonEventEntry(
   NXDataSetTyped<double> fracarea = errors;
   if (hasFracArea) {
     fracarea = wksp_cls.openNXDouble("frac_area");
+
+    // Set the fractional area attributes, default values consistent with
+    // previous assumptions: finalized = true, sqrdErrs = false
+    auto rbWS = boost::dynamic_pointer_cast<RebinnedOutput>(local_workspace);
+    auto finalizedValue = fracarea.attributes("finalized");
+    auto finalized = (finalizedValue.empty() ? true : finalizedValue == "1");
+    rbWS->setFinalized(finalized);
+    auto sqrdErrsValue = fracarea.attributes("sqrd_errors");
+    auto sqrdErrs = (sqrdErrsValue.empty() ? false : sqrdErrsValue == "1");
+    rbWS->setSqrdErrors(sqrdErrs);
   }
 
   // Check for x errors; as with fracArea we set it to xbins
diff --git a/Framework/DataHandling/src/LoadPreNexus.cpp b/Framework/DataHandling/src/LoadPreNexus.cpp
index bd0e5c8407fdbb5a577e8e9e5e43575196813ce1..b59b0a213fd2420d645dc461c6501ee6c0c8b759 100644
--- a/Framework/DataHandling/src/LoadPreNexus.cpp
+++ b/Framework/DataHandling/src/LoadPreNexus.cpp
@@ -62,7 +62,9 @@ const std::string LoadPreNexus::category() const {
  */
 int LoadPreNexus::confidence(Kernel::FileDescriptor &descriptor) const {
   const std::string &filename = descriptor.filename();
-  if (filename.compare(filename.size() - 12, 12, "_runinfo.xml") == 0)
+  if (filename.size() > 12
+          ? (filename.compare(filename.size() - 12, 12, "_runinfo.xml") == 0)
+          : false)
     return 80;
   else
     return 0;
diff --git a/Framework/DataHandling/src/LoadTBL.cpp b/Framework/DataHandling/src/LoadTBL.cpp
index 1a13221e1807ea618236cb224b855a3999b4af4c..ba9169b5b1fa1285cce080d3f9ae950cf01e3ee0 100644
--- a/Framework/DataHandling/src/LoadTBL.cpp
+++ b/Framework/DataHandling/src/LoadTBL.cpp
@@ -42,9 +42,14 @@ int LoadTBL::confidence(Kernel::FileDescriptor &descriptor) const {
 
   // Avoid some known file types that have different loaders
   int confidence(0);
-  if (filePath.compare(filenameLength - 12, 12, "_runinfo.xml") == 0 ||
-      filePath.compare(filenameLength - 6, 6, ".peaks") == 0 ||
-      filePath.compare(filenameLength - 10, 10, ".integrate") == 0) {
+  if (filenameLength > 12
+          ? (filePath.compare(filenameLength - 12, 12, "_runinfo.xml") == 0)
+          : false || filenameLength > 6
+                ? (filePath.compare(filenameLength - 6, 6, ".peaks") == 0)
+                : false || filenameLength > 10
+                      ? (filePath.compare(filenameLength - 10, 10,
+                                          ".integrate") == 0)
+                      : false) {
     confidence = 0;
   } else if (descriptor.isAscii()) {
     std::istream &stream = descriptor.data();
diff --git a/Framework/DataHandling/src/SaveAscii2.cpp b/Framework/DataHandling/src/SaveAscii2.cpp
index fab6e66fffee6d0a258b62cd72a2f382b63ab56e..97e0db1dfc76654d38cdd0fe362f4c0ed356840d 100644
--- a/Framework/DataHandling/src/SaveAscii2.cpp
+++ b/Framework/DataHandling/src/SaveAscii2.cpp
@@ -11,6 +11,7 @@
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/SpectrumInfo.h"
+#include "MantidDataObjects/TableWorkspace.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/BoundedValidator.h"
@@ -42,8 +43,8 @@ SaveAscii2::SaveAscii2()
 /// Initialisation method.
 void SaveAscii2::init() {
   declareProperty(
-      std::make_unique<WorkspaceProperty<MatrixWorkspace>>("InputWorkspace", "",
-                                                           Direction::Input),
+      std::make_unique<WorkspaceProperty<Workspace>>("InputWorkspace", "",
+                                                     Direction::Input),
       "The name of the workspace containing the data you want to save to a "
       "Ascii file.");
 
@@ -56,26 +57,29 @@ void SaveAscii2::init() {
   mustBePositive->setLower(1);
   auto mustBeZeroGreater = boost::make_shared<BoundedValidator<int>>();
   mustBeZeroGreater->setLower(0);
-  declareProperty("WorkspaceIndexMin", EMPTY_INT(), mustBeZeroGreater,
-                  "The starting workspace index.");
+  declareProperty(
+      "WorkspaceIndexMin", EMPTY_INT(), mustBeZeroGreater,
+      "The starting workspace index. Ignored for Table Workspaces.");
   declareProperty("WorkspaceIndexMax", EMPTY_INT(), mustBeZeroGreater,
-                  "The ending workspace index.");
-  declareProperty(std::make_unique<ArrayProperty<int>>("SpectrumList"),
-                  "List of workspace indices to save.");
+                  "The ending workspace index. Ignored for Table Workspaces.");
+  declareProperty(
+      std::make_unique<ArrayProperty<int>>("SpectrumList"),
+      "List of workspace indices to save. Ignored for Table Workspaces.");
   declareProperty("Precision", EMPTY_INT(), mustBePositive,
                   "Precision of output double values.");
   declareProperty("ScientificFormat", false,
                   "If true, the values will be "
                   "written to the file in "
                   "scientific notation.");
+  declareProperty("WriteXError", false,
+                  "If true, the error on X will be written as the fourth "
+                  "column. Ignored for Table Workspaces.");
   declareProperty(
-      "WriteXError", false,
-      "If true, the error on X will be written as the fourth column.");
-  declareProperty("WriteSpectrumID", true,
-                  "If false, the spectrum No will not be written for "
-                  "single-spectrum workspaces. "
-                  "It is always written for workspaces with multiple spectra, "
-                  "unless spectrum axis value is written.");
+      "WriteSpectrumID", true,
+      "If false, the spectrum No will not be written for "
+      "single-spectrum workspaces. "
+      "It is always written for workspaces with multiple spectra, "
+      "unless spectrum axis value is written. Ignored for Table Workspaces.");
 
   declareProperty("CommentIndicator", "#",
                   "Character(s) to put in front of comment lines.");
@@ -113,18 +117,19 @@ void SaveAscii2::init() {
   declareProperty("SpectrumMetaData", "",
                   "A comma separated list that defines data that describes "
                   "each spectrum in a workspace. The valid options for this "
-                  "are: SpectrumNumber,Q,Angle");
+                  "are: SpectrumNumber,Q,Angle. Ignored for Table Workspaces.");
 
   declareProperty(
       "AppendToFile", false,
       "If true, don't overwrite the file. Append to the end of it. ");
 
-  declareProperty(
-      "RaggedWorkspace", true,
-      "If true, ensure that more than one xspectra is used. "); // in testing
+  declareProperty("RaggedWorkspace", true,
+                  "If true, ensure that more than one xspectra is used. "
+                  "Ignored for Table Workspaces."); // in testing
 
   declareProperty("WriteSpectrumAxisValue", false,
-                  "Write the spectrum axis value if requested");
+                  "Write the spectrum axis value if requested. Ignored for "
+                  "Table Workspaces.");
 }
 
 /**
@@ -132,10 +137,60 @@ void SaveAscii2::init() {
  */
 void SaveAscii2::exec() {
   // Get the workspace
-  m_ws = getProperty("InputWorkspace");
-  auto nSpectra = static_cast<int>(m_ws->getNumberHistograms());
-  m_nBins = static_cast<int>(m_ws->blocksize());
-  m_isCommonBins = m_ws->isCommonBins(); // checking for ragged workspace
+  Workspace_const_sptr ws = getProperty("InputWorkspace");
+  m_ws = boost::dynamic_pointer_cast<const MatrixWorkspace>(ws);
+  ITableWorkspace_const_sptr tws =
+      boost::dynamic_pointer_cast<const ITableWorkspace>(ws);
+
+  // Get the properties valid for all workspaces
+  const bool writeHeader = getProperty("ColumnHeader");
+  const bool appendToFile = getProperty("AppendToFile");
+  std::string filename = getProperty("Filename");
+  int prec = getProperty("Precision");
+  bool scientific = getProperty("ScientificFormat");
+  std::string comment = getPropertyValue("CommentIndicator");
+
+  const std::string choice = getPropertyValue("Separator");
+  const std::string custom = getPropertyValue("CustomSeparator");
+  // If the custom separator property is not empty, then we use that under
+  // any circumstance.
+  if (!custom.empty()) {
+    m_sep = custom;
+  }
+  // Else if the separator drop down choice is not UserDefined then we use
+  // that.
+  else if (choice != "UserDefined") {
+    auto it = m_separatorIndex.find(choice);
+    m_sep = it->second;
+  }
+  // If we still have nothing, then we are forced to use a default.
+  if (m_sep.empty()) {
+    g_log.notice() << "\"UserDefined\" has been selected, but no custom "
+                      "separator has been entered."
+                      " Using default instead.";
+    m_sep = ",";
+  }
+
+  if (tws) {
+    writeTableWorkspace(tws, filename, appendToFile, writeHeader, prec,
+                        scientific, comment);
+    // return here as the rest of the class is all about matrix workspace saving
+    return;
+  }
+
+  if (!m_ws) {
+    throw std::runtime_error(
+        "SaveAscii does not now how to save this workspace type, " +
+        ws->getName());
+  }
+
+  // Get the properties valid for matrix workspaces
+  std::vector<int> spec_list = getProperty("SpectrumList");
+  const int spec_min = getProperty("WorkspaceIndexMin");
+  const int spec_max = getProperty("WorkspaceIndexMax");
+  m_writeSpectrumAxisValue = getProperty("WriteSpectrumAxisValue");
+  m_writeDX = getProperty("WriteXError");
+
   m_writeID = getProperty("WriteSpectrumID");
   std::string metaDataString = getPropertyValue("SpectrumMetaData");
   if (!metaDataString.empty()) {
@@ -161,14 +216,6 @@ void SaveAscii2::exec() {
     }
   }
 
-  // Get the properties
-  std::vector<int> spec_list = getProperty("SpectrumList");
-  const int spec_min = getProperty("WorkspaceIndexMin");
-  const int spec_max = getProperty("WorkspaceIndexMax");
-  const bool writeHeader = getProperty("ColumnHeader");
-  const bool appendToFile = getProperty("AppendToFile");
-  m_writeSpectrumAxisValue = getProperty("WriteSpectrumAxisValue");
-
   if (m_writeSpectrumAxisValue) {
     auto spectrumAxis = m_ws->getAxis(1);
     if (dynamic_cast<BinEdgeAxis *>(spectrumAxis)) {
@@ -180,30 +227,10 @@ void SaveAscii2::exec() {
   }
 
   // Check whether we need to write the fourth column
-  m_writeDX = getProperty("WriteXError");
   if (!m_ws->hasDx(0) && m_writeDX) {
     throw std::runtime_error(
         "x data errors have been requested but do not exist.");
   }
-  const std::string choice = getPropertyValue("Separator");
-  const std::string custom = getPropertyValue("CustomSeparator");
-  // If the custom separator property is not empty, then we use that under any
-  // circumstance.
-  if (!custom.empty()) {
-    m_sep = custom;
-  }
-  // Else if the separator drop down choice is not UserDefined then we use that.
-  else if (choice != "UserDefined") {
-    auto it = m_separatorIndex.find(choice);
-    m_sep = it->second;
-  }
-  // If we still have nothing, then we are forced to use a default.
-  if (m_sep.empty()) {
-    g_log.notice() << "\"UserDefined\" has been selected, but no custom "
-                      "separator has been entered."
-                      " Using default instead.";
-    m_sep = ",";
-  }
 
   // e + and - are included as they're part of the scientific notation
   if (!boost::regex_match(m_sep.begin(), m_sep.end(),
@@ -212,8 +239,6 @@ void SaveAscii2::exec() {
                                 "plus signs, hyphens or 'e'");
   }
 
-  std::string comment = getPropertyValue("CommentIndicator");
-
   if (comment.at(0) == m_sep.at(0) ||
       !boost::regex_match(
           comment.begin(), comment.end(),
@@ -226,6 +251,10 @@ void SaveAscii2::exec() {
   // Create an spectra index list for output
   std::set<int> idx;
 
+  auto nSpectra = static_cast<int>(m_ws->getNumberHistograms());
+  m_nBins = static_cast<int>(m_ws->blocksize());
+  m_isCommonBins = m_ws->isCommonBins(); // checking for ragged workspace
+
   // Add spectra interval into the index list
   if (spec_max != EMPTY_INT() && spec_min != EMPTY_INT()) {
     if (spec_min >= nSpectra || spec_max >= nSpectra || spec_min < 0 ||
@@ -255,7 +284,6 @@ void SaveAscii2::exec() {
   if (m_nBins == 0 || nSpectra == 0) {
     throw std::runtime_error("Trying to save an empty workspace");
   }
-  std::string filename = getProperty("Filename");
   std::ofstream file(filename.c_str(),
                      (appendToFile ? std::ios::app : std::ios::out));
 
@@ -264,11 +292,9 @@ void SaveAscii2::exec() {
     throw Exception::FileError("Unable to create file: ", filename);
   }
   // Set the number precision
-  int prec = getProperty("Precision");
   if (prec != EMPTY_INT()) {
     file.precision(prec);
   }
-  bool scientific = getProperty("ScientificFormat");
   if (scientific) {
     file << std::scientific;
   }
@@ -448,5 +474,69 @@ bool SaveAscii2::findElementInUnorderedStringVector(
   return std::find(vector.cbegin(), vector.cend(), toFind) != vector.cend();
 }
 
+void SaveAscii2::writeTableWorkspace(ITableWorkspace_const_sptr tws,
+                                     const std::string &filename,
+                                     bool appendToFile, bool writeHeader,
+                                     int prec, bool scientific,
+                                     const std::string &comment) {
+
+  std::ofstream file(filename.c_str(),
+                     (appendToFile ? std::ios::app : std::ios::out));
+
+  if (!file) {
+    g_log.error("Unable to create file: " + filename);
+    throw Exception::FileError("Unable to create file: ", filename);
+  }
+  // Set the number precision
+  if (prec != EMPTY_INT()) {
+    file.precision(prec);
+  }
+  if (scientific) {
+    file << std::scientific;
+  }
+
+  const auto columnCount = tws->columnCount();
+  if (writeHeader) {
+    // write the column names
+    file << comment << " ";
+    for (size_t colIndex = 0; colIndex < columnCount; colIndex++) {
+      file << tws->getColumn(colIndex)->name() << " ";
+      if (colIndex < columnCount - 1) {
+        file << m_sep << " ";
+      }
+    }
+    file << '\n';
+    // write the column types
+    file << comment << " ";
+    for (size_t colIndex = 0; colIndex < columnCount; colIndex++) {
+      file << tws->getColumn(colIndex)->type() << " ";
+      if (colIndex < columnCount - 1) {
+        file << m_sep << " ";
+      }
+    }
+    file << '\n';
+  } else {
+    g_log.warning("Please note that files written without headers cannot be "
+                  "reloaded back into Mantid with LoadAscii.");
+  }
+
+  // write the data
+  const auto rowCount = tws->rowCount();
+  Progress progress(this, 0.0, 1.0, rowCount);
+  for (size_t rowIndex = 0; rowIndex < rowCount; rowIndex++) {
+    for (size_t colIndex = 0; colIndex < columnCount; colIndex++) {
+      tws->getColumn(colIndex)->print(rowIndex, file);
+      if (colIndex < columnCount - 1) {
+        file << m_sep;
+      }
+    }
+    file << "\n";
+    progress.report();
+  }
+
+  file.unsetf(std::ios_base::floatfield);
+  file.close();
+}
+
 } // namespace DataHandling
 } // namespace Mantid
diff --git a/Framework/DataHandling/test/LoadAscii2Test.h b/Framework/DataHandling/test/LoadAscii2Test.h
index 862d32c4f0589a4fedee888962ffb82b45127019..2154b18ca91a01a8d1e6853c5330f7bf0ddf3598 100644
--- a/Framework/DataHandling/test/LoadAscii2Test.h
+++ b/Framework/DataHandling/test/LoadAscii2Test.h
@@ -8,6 +8,7 @@
 #define LOADASCIITEST_H_
 
 #include "MantidDataHandling/LoadAscii2.h"
+#include "SaveAscii2Test.h"
 #include "cxxtest/TestSuite.h"
 
 #include "MantidAPI/AnalysisDataService.h"
@@ -15,6 +16,7 @@
 #include "MantidAPI/Run.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataHandling/SaveAscii2.h"
+#include "MantidDataObjects/TableWorkspace.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidKernel/Unit.h"
 
@@ -154,8 +156,8 @@ public:
 
   void test_fail_five_columns() {
     m_testno++;
-    std::ofstream file(getTestFileName().c_str());
     m_abspath = getAbsPath();
+    std::ofstream file(m_abspath.c_str());
     file << std::scientific;
     file << "# X , Y, E, DX, Z\n";
     for (int i = 0; i < 5; i++) {
@@ -174,8 +176,8 @@ public:
 
   void test_fail_one_column() {
     m_testno++;
-    std::ofstream file(getTestFileName().c_str());
     m_abspath = getAbsPath();
+    std::ofstream file(m_abspath.c_str());
     file << std::scientific;
     file << "# X\n";
     for (int i = 0; i < 5; i++) {
@@ -192,8 +194,8 @@ public:
 
   void test_fail_mismatching_bins() {
     m_testno++;
-    std::ofstream file(getTestFileName().c_str());
     m_abspath = getAbsPath();
+    std::ofstream file(m_abspath.c_str());
     file << std::scientific;
     file << "# X , Y, E, DX\n";
     for (int i = 0; i < 5; i++) {
@@ -213,8 +215,8 @@ public:
 
   void test_fail_mismatching_columns() {
     m_testno++;
-    std::ofstream file(getTestFileName().c_str());
     m_abspath = getAbsPath();
+    std::ofstream file(m_abspath.c_str());
     file << std::scientific;
     file << "# X , Y, E, DX\n";
     for (int i = 0; i < 5; i++) {
@@ -237,8 +239,8 @@ public:
 
   void test_fail_line_start_letter() {
     m_testno++;
-    std::ofstream file(getTestFileName().c_str());
     m_abspath = getAbsPath();
+    std::ofstream file(m_abspath.c_str());
     file << std::scientific;
     file << "# X , Y, E, DX\n";
     for (int i = 0; i < 5; i++) {
@@ -263,8 +265,8 @@ public:
 
   void test_fail_line_start_noncomment_symbol() {
     m_testno++;
-    std::ofstream file(getTestFileName().c_str());
     m_abspath = getAbsPath();
+    std::ofstream file(m_abspath.c_str());
     file << std::scientific;
     file << "# X , Y, E, DX\n";
     for (int i = 0; i < 5; i++) {
@@ -288,8 +290,8 @@ public:
 
   void test_fail_line_mixed_letter_number() {
     m_testno++;
-    std::ofstream file(getTestFileName().c_str());
     m_abspath = getAbsPath();
+    std::ofstream file(m_abspath.c_str());
     file << std::scientific;
     file << "# X , Y, E, DX\n";
     for (int i = 0; i < 5; i++) {
@@ -314,8 +316,8 @@ public:
 
   void test_fail_line_mixed_symbol_number() {
     m_testno++;
-    std::ofstream file(getTestFileName().c_str());
     m_abspath = getAbsPath();
+    std::ofstream file(m_abspath.c_str());
     file << std::scientific;
     file << "# X , Y, E, DX\n";
     for (int i = 0; i < 5; i++) {
@@ -339,8 +341,8 @@ public:
 
   void test_fail_spectra_ID_inclusion_inconisitant() {
     m_testno++;
-    std::ofstream file(getTestFileName().c_str());
     m_abspath = getAbsPath();
+    std::ofstream file(m_abspath.c_str());
 
     file << std::scientific;
     file << "# X , Y, E, DX\n";
@@ -361,6 +363,45 @@ public:
     TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
   }
 
+  void test_tableworkspace() {
+    m_testno++;
+    m_abspath = writeTableTestFile("Tab");
+
+    LoadAscii2 loader;
+    loader.initialize();
+    loader.setRethrows(true);
+
+    const std::string outputName(getTestFileName());
+    TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("Filename", m_abspath));
+    TS_ASSERT_THROWS_NOTHING(
+        loader.setPropertyValue("OutputWorkspace", outputName));
+    TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("Separator", "Tab"));
+    TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("CustomSeparator", ""));
+
+    TS_ASSERT_THROWS_NOTHING(loader.execute());
+
+    TS_ASSERT_EQUALS(loader.isExecuted(), true);
+
+    // Check the workspace
+    AnalysisDataServiceImpl &dataStore = AnalysisDataService::Instance();
+    if (dataStore.doesExist(outputName)) {
+      TS_ASSERT_EQUALS(dataStore.doesExist(outputName), true);
+      Workspace_sptr output;
+      TS_ASSERT_THROWS_NOTHING(output = dataStore.retrieve(outputName));
+      TableWorkspace_sptr outputWS =
+          boost::dynamic_pointer_cast<TableWorkspace>(output);
+      if (outputWS) {
+        checkTableData(outputWS);
+      } else {
+        TS_FAIL("Workspace is not a table workspace");
+      }
+    } else {
+      TS_FAIL(outputName + " does not exist.");
+    }
+    dataStore.remove(outputName);
+    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
+  }
+
 private:
   const std::string getTestFileName() const {
     return m_filename + boost::lexical_cast<std::string>(m_testno) + m_ext;
@@ -371,6 +412,54 @@ private:
     save.setPropertyValue("Filename", getTestFileName());
     return save.getPropertyValue("Filename");
   }
+
+  // Write the test file for a table workspace
+  std::string writeTableTestFile(const std::string &sep = "CSV",
+                                 const std::string &custsep = "") {
+    SaveAscii2 save;
+    save.initialize();
+    save.setPropertyValue("Filename", getTestFileName());
+
+    const std::string name = "SaveTableAsciiWS";
+    auto wsToSave = SaveAscii2Test::writeTableWS(name);
+
+    save.initialize();
+    save.isInitialized();
+    save.setPropertyValue("InputWorkspace", name);
+    save.setPropertyValue("Separator", sep);
+    save.setPropertyValue("CustomSeparator", custsep);
+    save.execute();
+
+    AnalysisDataService::Instance().remove(name);
+
+    return save.getPropertyValue("Filename");
+  }
+
+  void checkTableData(const Mantid::API::ITableWorkspace_sptr outputWS) {
+
+    const std::string name = "Compare_SaveAsciiWS";
+    auto wsToCompare = SaveAscii2Test::writeTableWS(name);
+    TS_ASSERT_EQUALS(outputWS->columnCount(), wsToCompare->columnCount());
+    TS_ASSERT_EQUALS(outputWS->rowCount(), wsToCompare->rowCount());
+
+    for (size_t colIndex = 0; colIndex < outputWS->columnCount(); colIndex++) {
+      auto outputCol = outputWS->getColumn(colIndex);
+      auto compareCol = wsToCompare->getColumn(colIndex);
+      TS_ASSERT_EQUALS(outputCol->name(), compareCol->name());
+      TS_ASSERT_EQUALS(outputCol->type(), compareCol->type());
+      for (size_t rowIndex = 0; rowIndex < outputWS->rowCount(); rowIndex++) {
+
+        std::stringstream ssOutput;
+        std::stringstream ssCompare;
+        outputCol->print(rowIndex, ssOutput);
+        compareCol->print(rowIndex, ssCompare);
+        TS_ASSERT_EQUALS(ssOutput.str(), ssCompare.str());
+      }
+    }
+
+    AnalysisDataService::Instance().remove(name);
+  }
+
   // Write the test file
   std::string writeTestFile(const int cols, const bool header = true,
                             const std::string &comment = "#",
@@ -381,9 +470,10 @@ private:
     SaveAscii2 save;
     save.initialize();
     save.setPropertyValue("Filename", getTestFileName());
+    std::string filePath = save.getPropertyValue("Filename");
     if (cols < 3) {
       // saveascii2 doens't save 2 column files it has to be made manually
-      std::ofstream file(getTestFileName().c_str());
+      std::ofstream file(filePath.c_str());
       if (scientific) {
         file << std::scientific;
       }
@@ -435,10 +525,12 @@ private:
       save.setPropertyValue("Separator", sep);
       save.setPropertyValue("CustomSeparator", custsep);
       save.execute();
-
+      TSM_ASSERT("Failed to save test data using SaveAscii2.",
+                 save.isExecuted());
       AnalysisDataService::Instance().remove(name);
     }
-    return save.getPropertyValue("Filename");
+
+    return filePath;
   }
 
   Mantid::API::MatrixWorkspace_sptr
diff --git a/Framework/DataHandling/test/SaveAscii2Test.h b/Framework/DataHandling/test/SaveAscii2Test.h
index 9d972f7534fd70849e307d194cafa413d0ef1864..7631fce85b1ad5c607e1297a34ec957e60a86724 100644
--- a/Framework/DataHandling/test/SaveAscii2Test.h
+++ b/Framework/DataHandling/test/SaveAscii2Test.h
@@ -9,9 +9,11 @@
 
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/FrameworkManager.h"
+#include "MantidAPI/TableRow.h"
 #include "MantidAPI/TextAxis.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataHandling/SaveAscii2.h"
+#include "MantidDataObjects/TableWorkspace.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include <Poco/File.h>
@@ -863,6 +865,81 @@ public:
     AnalysisDataService::Instance().remove(m_name);
   }
 
+  void test_TableWorkspace() {
+    Workspace_sptr wsToSave = writeTableWS(m_name);
+
+    SaveAscii2 save;
+    std::string filename = initSaveAscii2(save);
+
+    TS_ASSERT_THROWS_NOTHING(save.execute());
+
+    // has the algorithm written a file to disk?
+    TS_ASSERT(Poco::File(filename).exists());
+
+    // Now make some checks on the content of the file
+    std::ifstream in(filename.c_str());
+    std::string header1, header2, header3, header4, header5, header6, header7,
+        header8, header9, separator, comment, type1, type2;
+
+    // Test that the first few column headers, separator and first two types are
+    // as expected
+    in >> comment >> header1 >> separator >> header2 >> separator >> header3 >>
+        separator >> header4 >> separator >> header5 >> separator >> header6 >>
+        separator >> header7 >> separator >> header8 >> separator >> header9 >>
+        separator >> type1 >> separator >> type2;
+
+    TS_ASSERT_EQUALS(comment, "#");
+    TS_ASSERT_EQUALS(separator, ",");
+    TS_ASSERT_EQUALS(header1, "int");
+    TS_ASSERT_EQUALS(header2, "uint");
+    TS_ASSERT_EQUALS(header3, "int64");
+    TS_ASSERT_EQUALS(header4, "size_t");
+    TS_ASSERT_EQUALS(header5, "float");
+    TS_ASSERT_EQUALS(header6, "double");
+    TS_ASSERT_EQUALS(header7, "bool");
+    TS_ASSERT_EQUALS(header8, "string");
+    TS_ASSERT_EQUALS(header9, "V3D");
+    TS_ASSERT_EQUALS(type1, "int");
+    TS_ASSERT_EQUALS(type2, "uint");
+
+    in.close();
+
+    Poco::File(filename).remove();
+    AnalysisDataService::Instance().remove(m_name);
+  }
+
+  // public as it is used in LoadAsciiTest as well.
+  static ITableWorkspace_sptr writeTableWS(const std::string &name) {
+    auto table = WorkspaceFactory::Instance().createTable();
+    // One column of each type
+    table->addColumn("int", "int");
+    table->addColumn("uint", "uint");
+    table->addColumn("long64", "int64");
+    table->addColumn("size_t", "size_t");
+    table->addColumn("float", "float");
+    table->addColumn("double", "double");
+    table->addColumn("bool", "bool");
+    table->addColumn("str", "string");
+    table->addColumn("V3D", "V3D");
+
+    // A few rows
+    TableRow row1 = table->appendRow();
+    row1 << -1 << static_cast<uint32_t>(0) << static_cast<int64_t>(1)
+         << static_cast<size_t>(10) << 5.5f << -9.9 << true << "Hello"
+         << Mantid::Kernel::V3D();
+    TableRow row2 = table->appendRow();
+    row2 << 1 << static_cast<uint32_t>(2) << static_cast<int64_t>(-2)
+         << static_cast<size_t>(100) << 0.0f << 101.0 << false << "World"
+         << Mantid::Kernel::V3D(-1, 3, 4);
+    TableRow row3 = table->appendRow();
+    row3 << 6 << static_cast<uint32_t>(3) << static_cast<int64_t>(0)
+         << static_cast<size_t>(0) << -99.0f << 0.0 << false << "!"
+         << Mantid::Kernel::V3D(1, 6, 10);
+
+    AnalysisDataService::Instance().add(name, table);
+    return table;
+  }
+
 private:
   void writeSampleWS(Mantid::DataObjects::Workspace2D_sptr &wsToSave,
                      const bool &isSpectra = true) {
diff --git a/Framework/DataObjects/inc/MantidDataObjects/FractionalRebinning.h b/Framework/DataObjects/inc/MantidDataObjects/FractionalRebinning.h
index eaa08f04d077365c80a85291dce65708ec6c755f..6bf685879efb01964daafd16d8628848d658894f 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/FractionalRebinning.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/FractionalRebinning.h
@@ -62,6 +62,10 @@ MANTID_DATAOBJECTS_DLL void rebinToFractionalOutput(
     const std::vector<double> &verticalAxis,
     const DataObjects::RebinnedOutput_const_sptr &inputRB = nullptr);
 
+/// Set finalize flag after fractional rebinning loop
+MANTID_DATAOBJECTS_DLL void
+finalizeFractionalRebin(DataObjects::RebinnedOutput &outputWS);
+
 } // namespace FractionalRebinning
 
 } // namespace DataObjects
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.tcc b/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.tcc
index 9e52f7ceabfd04efa842d5aaedf57a34b32dee7a..ba010e243f169a1c8a6d1450eee7da23d257b438 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.tcc
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.tcc
@@ -708,7 +708,7 @@ TMDE(void MDGridBox)::splitContents(size_t index, Kernel::ThreadScheduler *ts) {
   if (ts) {
     // Create a task to split the newly created MDGridBox.
     ts->push(std::make_shared<Kernel::FunctionTask>(
-        boost::bind(&MDGridBox<MDE, nd>::splitAllIfNeeded, &*gridbox, ts)));
+        std::bind(&MDGridBox<MDE, nd>::splitAllIfNeeded, &*gridbox, ts)));
   } else {
     gridbox->splitAllIfNeeded(nullptr);
   }
@@ -761,7 +761,7 @@ TMDE(void MDGridBox)::splitAllIfNeeded(Kernel::ThreadScheduler *ts) {
           // So we create a task to split this MDBox,
           // Task is : this->splitContents(i, ts);
           ts->push(std::make_shared<Kernel::FunctionTask>(
-              boost::bind(&MDGridBox<MDE, nd>::splitContents, &*this, i, ts)));
+              std::bind(&MDGridBox<MDE, nd>::splitContents, &*this, i, ts)));
         }
       } else {
         // This box does NOT have enough events to be worth splitting, if it do
@@ -789,8 +789,8 @@ TMDE(void MDGridBox)::splitAllIfNeeded(Kernel::ThreadScheduler *ts) {
         else
           // Go parallel if this is a big enough gridbox.
           // Task is : gridBox->splitAllIfNeeded(ts);
-          ts->push(std::make_shared<Kernel::FunctionTask>(boost::bind(
-              &MDGridBox<MDE, nd>::splitAllIfNeeded, &*gridBox, ts)));
+          ts->push(std::make_shared<Kernel::FunctionTask>(
+              std::bind(&MDGridBox<MDE, nd>::splitAllIfNeeded, &*gridBox, ts)));
       }
     }
   }
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MortonIndex/WideIntImpl.h b/Framework/DataObjects/inc/MantidDataObjects/MortonIndex/WideIntImpl.h
index 9a24430634ccf7e190222b89033dc66541ea2491..31313e3657c05a51c406255901a4fdd35cc9ead8 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MortonIndex/WideIntImpl.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/MortonIndex/WideIntImpl.h
@@ -512,16 +512,24 @@ public:
     }
   }
 
-  template <size_t Bits2, typename Signed2,
-            class = __need_increase_size<Bits2, Signed2>>
-  constexpr static wide_integer<Bits2, Signed>
-  operator_plus(const wide_integer<Bits, Signed> &lhs,
-                const wide_integer<Bits2, Signed2>
-                    &rhs) noexcept(is_same<Signed, unsigned>::value) {
-    return std::common_type_t<wide_integer<Bits, Signed>,
-                              wide_integer<Bits2, Signed2>>::_impl::
-        operator_plus(wide_integer<Bits2, Signed>(lhs), rhs);
-  }
+  // clang-format off
+  // The __need_increase_size variants are currently disabled due to a suspected bug in the MSVC
+  // compiler producing warnings such as:
+  //   warning C4717: 'operator_amp<128, ?? :: ?? >': recursive on all control paths, function will cause runtime stack overflow
+  // `class = __need_increase_size<Bits2, Signed2>>` should fail substitution when Bits2 == Bits - the arguments have the same width, but it doesn't.  
+  // Mantid only uses a single type of wide integer so these functions are not currently required.
+  // clang-format on
+
+  // template <size_t Bits2, typename Signed2,
+  // class = __need_increase_size<Bits2, Signed2>>
+  // constexpr static typename std::enable_if<Bits2==Bits,wide_integer<Bits2,
+  // Signed>>::type operator_plus(const wide_integer<Bits, Signed> &lhs, const
+  // wide_integer<Bits2, Signed2> &rhs) noexcept(is_same<Signed,
+  // unsigned>::value) {
+  // return std::common_type_t<wide_integer<Bits, Signed>,
+  // wide_integer<Bits2, Signed2>>::_impl::
+  // operator_plus(wide_integer<Bits2, Signed>(lhs), rhs);
+  // }
 
   template <typename T, class = __keep_size<T>>
   constexpr static wide_integer<Bits, Signed>
@@ -535,16 +543,16 @@ public:
     }
   }
 
-  template <size_t Bits2, typename Signed2,
-            class = __need_increase_size<Bits2, Signed2>>
-  constexpr static wide_integer<Bits2, Signed>
-  operator_minus(const wide_integer<Bits, Signed> &lhs,
-                 const wide_integer<Bits2, Signed2>
-                     &rhs) noexcept(is_same<Signed, unsigned>::value) {
-    return std::common_type_t<wide_integer<Bits, Signed>,
-                              wide_integer<Bits2, Signed2>>::_impl::
-        operator_minus(wide_integer<Bits2, Signed>(lhs), rhs);
-  }
+  // template <size_t Bits2, typename Signed2,
+  // class = __need_increase_size<Bits2, Signed2>>
+  // constexpr static typename std::enable_if<Bits2==Bits,wide_integer<Bits2,
+  // Signed>>::type operator_minus(const wide_integer<Bits, Signed> &lhs, const
+  // wide_integer<Bits2, Signed2> &rhs) noexcept(is_same<Signed,
+  // unsigned>::value) {
+  // return std::common_type_t<wide_integer<Bits, Signed>,
+  // wide_integer<Bits2, Signed2>>::_impl::
+  // operator_minus(wide_integer<Bits2, Signed>(lhs), rhs);
+  // }
 
 private:
   constexpr static wide_integer<Bits, Signed> _operator_minus_wide_integer(
@@ -623,15 +631,15 @@ public:
     return res;
   }
 
-  template <size_t Bits2, typename Signed2,
-            class = __need_increase_size<Bits2, Signed2>>
-  constexpr static wide_integer<Bits2, Signed2>
-  operator_star(const wide_integer<Bits, Signed> &lhs,
-                const wide_integer<Bits2, Signed2> &rhs) {
-    return std::common_type_t<wide_integer<Bits, Signed>,
-                              wide_integer<Bits2, Signed2>>::_impl::
-        operator_star(wide_integer<Bits2, Signed2>(lhs), rhs);
-  }
+  // template <size_t Bits2, typename Signed2,
+  // class = __need_increase_size<Bits2, Signed2>>
+  // constexpr static typename std::enable_if<Bits == Bits2, wide_integer<Bits2,
+  // Signed2>>::type operator_star(const wide_integer<Bits, Signed> &lhs, const
+  // wide_integer<Bits2, Signed2> &rhs) {
+  // return std::common_type_t<wide_integer<Bits, Signed>,
+  // wide_integer<Bits2, Signed2>>::_impl::
+  // operator_star(wide_integer<Bits2, Signed2>(lhs), rhs);
+  // }
 
   template <typename T, class = __keep_size<T>>
   constexpr static bool operator_more(const wide_integer<Bits, Signed> &lhs,
@@ -656,14 +664,14 @@ public:
     return false;
   }
 
-  template <size_t Bits2, class = __need_increase_size<Bits2, Signed>>
-  constexpr static bool
-  operator_more(const wide_integer<Bits, Signed> &lhs,
-                const wide_integer<Bits2, Signed> &rhs) noexcept {
-    return std::common_type_t<wide_integer<Bits, Signed>,
-                              wide_integer<Bits2, Signed>>::_impl::
-        operator_more(wide_integer<Bits2, Signed>(lhs), rhs);
-  }
+  // template <size_t Bits2, class = __need_increase_size<Bits2, Signed>>
+  // constexpr static bool
+  // operator_more(const wide_integer<Bits, Signed> &lhs,
+  // const wide_integer<Bits2, Signed> &rhs) noexcept {
+  // return std::common_type_t<wide_integer<Bits, Signed>,
+  // wide_integer<Bits2, Signed>>::_impl::
+  // operator_more(wide_integer<Bits2, Signed>(lhs), rhs);
+  // }
 
   template <typename T, class = __keep_size<T>>
   constexpr static bool operator_less(const wide_integer<Bits, Signed> &lhs,
@@ -688,14 +696,14 @@ public:
     return false;
   }
 
-  template <size_t Bits2, class = __need_increase_size<Bits2, Signed>>
-  constexpr static bool
-  operator_less(const wide_integer<Bits, Signed> &lhs,
-                const wide_integer<Bits2, Signed> &rhs) noexcept {
-    return std::common_type_t<wide_integer<Bits, Signed>,
-                              wide_integer<Bits2, Signed>>::_impl::
-        operator_less(wide_integer<Bits2, Signed>(lhs), rhs);
-  }
+  // template <size_t Bits2, class = __need_increase_size<Bits2, Signed>>
+  // constexpr static bool
+  // operator_less(const wide_integer<Bits, Signed> &lhs,
+  // const wide_integer<Bits2, Signed> &rhs) noexcept {
+  // return std::common_type_t<wide_integer<Bits, Signed>,
+  // wide_integer<Bits2, Signed>>::_impl::
+  // operator_less(wide_integer<Bits2, Signed>(lhs), rhs);
+  // }
 
   template <typename T, class = __keep_size<T>>
   constexpr static bool operator_eq(const wide_integer<Bits, Signed> &lhs,
@@ -711,14 +719,14 @@ public:
     return true;
   }
 
-  template <size_t Bits2, class = __need_increase_size<Bits2, Signed>>
-  constexpr static bool
-  operator_eq(const wide_integer<Bits, Signed> &lhs,
-              const wide_integer<Bits2, Signed> &rhs) noexcept {
-    return std::common_type_t<wide_integer<Bits, Signed>,
-                              wide_integer<Bits2, Signed>>::_impl::
-        operator_eq(wide_integer<Bits2, Signed>(lhs), rhs);
-  }
+  // template <size_t Bits2, class = __need_increase_size<Bits2, Signed>>
+  // constexpr static bool
+  // operator_eq(const wide_integer<Bits, Signed> &lhs,
+  // const wide_integer<Bits2, Signed> &rhs) noexcept {
+  // return std::common_type_t<wide_integer<Bits, Signed>,
+  // wide_integer<Bits2, Signed>>::_impl::
+  // operator_eq(wide_integer<Bits2, Signed>(lhs), rhs);
+  // }
 
   template <typename T, class = __keep_size<T>>
   constexpr static wide_integer<Bits, Signed>
@@ -733,14 +741,16 @@ public:
     return res;
   }
 
-  template <size_t Bits2, class = __need_increase_size<Bits2, Signed>>
-  constexpr static wide_integer<Bits2, Signed>
-  operator_pipe(const wide_integer<Bits, Signed> &lhs,
-                const wide_integer<Bits2, Signed> &rhs) noexcept {
-    return std::common_type_t<wide_integer<Bits, Signed>,
-                              wide_integer<Bits2, Signed>>::_impl::
-        operator_pipe(wide_integer<Bits2, Signed>(lhs), rhs);
-  }
+  // template <size_t Bits2, class = __need_increase_size<Bits2, Signed>>
+  // constexpr static typename std::enable_if<Bits == Bits2, wide_integer<Bits2,
+  // Signed>>::type operator_pipe(const wide_integer<Bits, Signed> &lhs, const
+  // wide_integer<Bits2, Signed> &rhs) noexcept {
+  // static_assert(!std::is_same_v<wide_integer<Bits, Signed>,
+  // std::common_type_t<wide_integer<Bits, Signed>, wide_integer<Bits2,
+  // Signed>>>); return std::common_type_t<wide_integer<Bits, Signed>,
+  // wide_integer<Bits2, Signed>>::_impl::
+  // operator_pipe(wide_integer<Bits2, Signed>(lhs), rhs);
+  // }
 
   template <typename T, class = __keep_size<T>>
   constexpr static wide_integer<Bits, Signed>
@@ -755,14 +765,14 @@ public:
     return res;
   }
 
-  template <size_t Bits2, class = __need_increase_size<Bits2, Signed>>
-  constexpr static wide_integer<Bits2, Signed>
-  operator_amp(const wide_integer<Bits, Signed> &lhs,
-               const wide_integer<Bits2, Signed> &rhs) noexcept {
-    return std::common_type_t<wide_integer<Bits, Signed>,
-                              wide_integer<Bits2, Signed>>::_impl::
-        operator_amp(wide_integer<Bits2, Signed>(lhs), rhs);
-  }
+  // template <size_t Bits2, class = __need_increase_size<Bits2, Signed>>
+  // constexpr static typename std::enable_if<Bits == Bits2, wide_integer<Bits2,
+  // Signed>>::type operator_amp(const wide_integer<Bits, Signed> &lhs, const
+  // wide_integer<Bits2, Signed> &rhs) noexcept {
+  // return std::common_type_t<wide_integer<Bits, Signed>,
+  // wide_integer<Bits2, Signed>>::_impl::
+  // operator_amp(wide_integer<Bits2, Signed>(lhs), rhs);
+  // }
 
 private:
   template <typename T>
@@ -821,15 +831,15 @@ public:
     return quotient;
   }
 
-  template <size_t Bits2, typename Signed2,
-            class = __need_increase_size<Bits2, Signed2>>
-  constexpr static wide_integer<Bits2, Signed2>
-  operator_slash(const wide_integer<Bits, Signed> &lhs,
-                 const wide_integer<Bits2, Signed2> &rhs) {
-    return std::common_type_t<wide_integer<Bits, Signed>,
-                              wide_integer<Bits2, Signed>>::
-        operator_slash(wide_integer<Bits2, Signed2>(lhs), rhs);
-  }
+  // template <size_t Bits2, typename Signed2,
+  // class = __need_increase_size<Bits2, Signed2>>
+  // constexpr static wide_integer<Bits2, Signed2>
+  // operator_slash(const wide_integer<Bits, Signed> &lhs,
+  // const wide_integer<Bits2, Signed2> &rhs) {
+  // return std::common_type_t<wide_integer<Bits, Signed>,
+  // wide_integer<Bits2, Signed>>::
+  // operator_slash(wide_integer<Bits2, Signed2>(lhs), rhs);
+  // }
 
   template <typename T, class = __keep_size<T>>
   constexpr static wide_integer<Bits, Signed>
@@ -843,15 +853,15 @@ public:
     return remainder;
   }
 
-  template <size_t Bits2, typename Signed2,
-            class = __need_increase_size<Bits2, Signed2>>
-  constexpr static wide_integer<Bits2, Signed2>
-  operator_percent(const wide_integer<Bits, Signed> &lhs,
-                   const wide_integer<Bits2, Signed2> &rhs) {
-    return std::common_type_t<wide_integer<Bits, Signed>,
-                              wide_integer<Bits2, Signed>>::
-        operator_percent(wide_integer<Bits2, Signed2>(lhs), rhs);
-  }
+  // template <size_t Bits2, typename Signed2,
+  // class = __need_increase_size<Bits2, Signed2>>
+  // constexpr static wide_integer<Bits2, Signed2>
+  // operator_percent(const wide_integer<Bits, Signed> &lhs,
+  // const wide_integer<Bits2, Signed2> &rhs) {
+  // return std::common_type_t<wide_integer<Bits, Signed>,
+  // wide_integer<Bits2, Signed>>::
+  // operator_percent(wide_integer<Bits2, Signed2>(lhs), rhs);
+  // }
 
   // ^
   template <typename T, class = __keep_size<T>>
@@ -868,14 +878,14 @@ public:
     return res;
   }
 
-  template <size_t Bits2, typename Signed2,
-            class = __need_increase_size<Bits2, Signed2>>
-  constexpr static wide_integer<Bits2, Signed2>
-  operator_circumflex(const wide_integer<Bits, Signed> &lhs,
-                      const wide_integer<Bits2, Signed2> &rhs) noexcept {
-    return wide_integer<Bits2, Signed2>::operator_circumflex(
-        wide_integer<Bits2, Signed2>(lhs), rhs);
-  }
+  // template <size_t Bits2, typename Signed2,
+  // class = __need_increase_size<Bits2, Signed2>>
+  // constexpr static wide_integer<Bits2, Signed2>
+  // operator_circumflex(const wide_integer<Bits, Signed> &lhs,
+  // const wide_integer<Bits2, Signed2> &rhs) noexcept {
+  // return wide_integer<Bits2, Signed2>::operator_circumflex(
+  // wide_integer<Bits2, Signed2>(lhs), rhs);
+  // }
 
   constexpr static wide_integer<Bits, Signed> from_str(const char *c) {
     wide_integer<Bits, Signed> res = 0;
diff --git a/Framework/DataObjects/inc/MantidDataObjects/RebinnedOutput.h b/Framework/DataObjects/inc/MantidDataObjects/RebinnedOutput.h
index 28ba488a3b6aa53a96265beda56ede5a61d307c6..4335a7c7d0fb4a6d9133415e45220b9cf625508e 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/RebinnedOutput.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/RebinnedOutput.h
@@ -25,8 +25,9 @@ namespace DataObjects {
 */
 class DLLExport RebinnedOutput : public Workspace2D {
 public:
-  RebinnedOutput() : m_finalized(false) {}
-  RebinnedOutput(bool finalized) : m_finalized(finalized) {}
+  RebinnedOutput() : m_finalized(false), m_hasSqrdErrs(true) {}
+  RebinnedOutput(bool finalized, bool hasSqrdErrs)
+      : m_finalized(finalized), m_hasSqrdErrs(hasSqrdErrs) {}
   /// Returns a clone of the workspace
   std::unique_ptr<RebinnedOutput> clone() const {
     return std::unique_ptr<RebinnedOutput>(doClone());
@@ -46,18 +47,30 @@ public:
   /// Returns the fractional area
   virtual const MantidVec &dataF(const std::size_t index) const;
 
-  /// Create final representation
-  void finalize(bool hasSqrdErrs = true, bool force = false);
-  void unfinalize(bool hasSqrdErrs = false, bool force = false);
+  /// Finalize to fractional area representation
+  void finalize(bool hasSqrdErrs = true);
+  /// Undo fractional area representation
+  void unfinalize();
 
   /// Returns if finalize has been called
   bool isFinalized() const { return m_finalized; }
+  /// Override the finalized flag
+  void setFinalized(bool value) { m_finalized = value; }
+
+  /// Returns if using squared errors
+  bool hasSqrdErrors() const { return m_hasSqrdErrs; }
+  /// Override the squared errors flag
+  void setSqrdErrors(bool value) { m_hasSqrdErrs = value; }
 
   /// Returns a read-only (i.e. const) reference to the specified F array
   const MantidVec &readF(std::size_t const index) const;
 
   /// Set the fractional area array for a given index.
   void setF(const std::size_t index, const MantidVecPtr &F);
+  /// Multiply the fractional area arrays by a scale factor
+  void scaleF(const double scale);
+  /// Returns if the fractional area is non zero
+  bool nonZeroF() const;
 
 protected:
   /// Protected copy constructor. May be used by childs for cloning.
@@ -74,10 +87,13 @@ protected:
   /// Flag to indicate if finalize has been called, and if errors/variance used
   bool m_finalized;
 
+  /// Flag to indiciate if the finalized data used squared errors
+  bool m_hasSqrdErrs;
+
 private:
   RebinnedOutput *doClone() const override { return new RebinnedOutput(*this); }
   RebinnedOutput *doCloneEmpty() const override {
-    return new RebinnedOutput(m_finalized);
+    return new RebinnedOutput(m_finalized, m_hasSqrdErrs);
   }
 };
 
diff --git a/Framework/DataObjects/src/FractionalRebinning.cpp b/Framework/DataObjects/src/FractionalRebinning.cpp
index a645ace793659e49f68682240bb89a8dbe6b083c..3064644bf89025447f3f597f81f79af207f2ed01 100644
--- a/Framework/DataObjects/src/FractionalRebinning.cpp
+++ b/Framework/DataObjects/src/FractionalRebinning.cpp
@@ -663,6 +663,8 @@ void rebinToFractionalOutput(const Quadrilateral &inputQ,
     if (inputRB->isFinalized()) {
       signal *= inF[j];
       error *= inF[j];
+      if (inputRB->hasSqrdErrors())
+        error *= inF[j];
     }
   }
 
@@ -683,6 +685,16 @@ void rebinToFractionalOutput(const Quadrilateral &inputQ,
   }
 }
 
+/**
+ * Called at the completion of the fractional rebinning loop
+ * to the set the finalize flag in the output workspace.
+ * @param outputWS Reference to the rebinned output workspace
+ */
+void finalizeFractionalRebin(RebinnedOutput &outputWS) {
+  // rebinToFractionalOutput() leaves the data in an unfinalized state
+  outputWS.setFinalized(false);
+}
+
 } // namespace FractionalRebinning
 
 } // namespace DataObjects
diff --git a/Framework/DataObjects/src/RebinnedOutput.cpp b/Framework/DataObjects/src/RebinnedOutput.cpp
index 4c88fd691a336a38acd95ccf677e973a9f715fb3..04570f44d9d606767c997e116cc8c408b5ff73aa 100644
--- a/Framework/DataObjects/src/RebinnedOutput.cpp
+++ b/Framework/DataObjects/src/RebinnedOutput.cpp
@@ -82,7 +82,7 @@ const MantidVec &RebinnedOutput::readF(const std::size_t index) const {
 }
 
 /**
- * Function that sets the fractional area arrat for a given index.
+ * Function that sets the fractional area array for a given index.
  * @param index :: the particular array to set
  * @param F :: the array contained the information
  */
@@ -91,28 +91,73 @@ void RebinnedOutput::setF(const std::size_t index, const MantidVecPtr &F) {
 }
 
 /**
- * This function takes the data/error arrays and divides them by the
- * corresponding fractional area array. This creates a representation that
- * is easily visualized. The Rebin and Integration algorithms will have to
- * undo this in order to properly treat the data.
- * @param hasSqrdErrs :: does the workspace have squared errors?
- * @param force :: ignore finalize flag or not?
+ * Function that scales the fractional area arrays.
+ * @param scale :: the scale factor
  */
-void RebinnedOutput::finalize(bool hasSqrdErrs, bool force) {
-  if (m_finalized && !force)
-    return;
-  auto nHist = static_cast<int>(this->getNumberHistograms());
+void RebinnedOutput::scaleF(const double scale) {
+  std::size_t nHist = this->getNumberHistograms();
+  for (std::size_t i = 0; i < nHist; ++i) {
+    MantidVec &frac = this->dataF(i);
+    std::transform(frac.begin(), frac.end(), frac.begin(),
+                   [scale](double x) { return scale * x; });
+  }
+}
+
+/**
+ * The functions checks if the fractional area data is non zero.
+ */
+bool RebinnedOutput::nonZeroF() const {
+
   // Checks that the fractions are not all zeros.
+  auto nHist = static_cast<int>(this->getNumberHistograms());
   bool frac_all_zeros = true;
   for (int i = 0; i < nHist; ++i) {
-    MantidVec &frac = this->dataF(i);
+    const MantidVec &frac = this->readF(i);
     if (std::accumulate(frac.begin(), frac.end(), 0.) != 0) {
       frac_all_zeros = false;
       break;
     }
   }
-  if (frac_all_zeros)
+  return !frac_all_zeros;
+}
+
+/**
+ * This function takes the data/error arrays and divides them by the
+ * corresponding fractional area array. This creates a representation that
+ * is easily visualized. The Rebin and Integration algorithms will have to
+ * undo this in order to properly treat the data. If the fractional area
+ * is all zero skip the operation as there will be no meaningful data.
+ * @param hasSqrdErrs :: does the workspace have squared errors?
+ */
+void RebinnedOutput::finalize(bool hasSqrdErrs) {
+  if (m_finalized && hasSqrdErrs == m_hasSqrdErrs)
     return;
+
+  // Checks that the fractions are not all zeros.
+  if (!this->nonZeroF())
+    return;
+
+  // Fix the squared error representation before returning
+  auto nHist = static_cast<int>(this->getNumberHistograms());
+  if (m_finalized) {
+    PARALLEL_FOR_IF(Kernel::threadSafe(*this))
+    for (int i = 0; i < nHist; ++i) {
+      MantidVec &err = this->dataE(i);
+      MantidVec &frac = this->dataF(i);
+      if (hasSqrdErrs) {
+        std::transform(err.begin(), err.end(), frac.begin(), err.begin(),
+                       std::divides<double>());
+      } else {
+        std::transform(err.begin(), err.end(), frac.begin(), err.begin(),
+                       std::multiplies<double>());
+      }
+    }
+
+    // Sets flag so subsequent algorithms know to correctly treat data
+    m_hasSqrdErrs = hasSqrdErrs;
+    return;
+  }
+
   PARALLEL_FOR_IF(Kernel::threadSafe(*this))
   for (int i = 0; i < nHist; ++i) {
     MantidVec &data = this->dataY(i);
@@ -127,19 +172,21 @@ void RebinnedOutput::finalize(bool hasSqrdErrs, bool force) {
                      std::divides<double>());
     }
   }
-  // Sets flag so subsequent algorithms know to correctly treat data
+  // Sets flags so subsequent algorithms know to correctly treat data
   m_finalized = true;
+  m_hasSqrdErrs = hasSqrdErrs;
 }
 
 /**
  * This function "unfinalizes" the workspace by taking the data/error arrays
- * and multiplying them by the corresponding fractional area array.
- * @param hasSqrdErrs :: does the workspace have squared errors?
- * @param force :: ignore finalize flag or not?
+ * and multiplying them by the corresponding fractional area array if the array
+ * is non zero. If all the values are zero skip the process as all data will
+ * will be lost.
  */
-void RebinnedOutput::unfinalize(bool hasSqrdErrs, bool force) {
-  if (!m_finalized && !force)
+void RebinnedOutput::unfinalize() {
+  if (!m_finalized || !this->nonZeroF())
     return;
+
   auto nHist = static_cast<int>(this->getNumberHistograms());
   PARALLEL_FOR_IF(Kernel::threadSafe(*this))
   for (int i = 0; i < nHist; ++i) {
@@ -150,7 +197,7 @@ void RebinnedOutput::unfinalize(bool hasSqrdErrs, bool force) {
                    std::multiplies<double>());
     std::transform(err.begin(), err.end(), frac.begin(), err.begin(),
                    std::multiplies<double>());
-    if (hasSqrdErrs) {
+    if (this->m_hasSqrdErrs) {
       std::transform(err.begin(), err.end(), frac.begin(), err.begin(),
                      std::multiplies<double>());
     }
diff --git a/Framework/DataObjects/src/ReflectometryTransform.cpp b/Framework/DataObjects/src/ReflectometryTransform.cpp
index a3231deedb7a1e9f798e555afd6e4eed80886e51..b0a1dd48628308d68db34cff3a4baa6784e52825 100644
--- a/Framework/DataObjects/src/ReflectometryTransform.cpp
+++ b/Framework/DataObjects/src/ReflectometryTransform.cpp
@@ -513,6 +513,7 @@ MatrixWorkspace_sptr ReflectometryTransform::executeNormPoly(
       }
     }
   }
+  FractionalRebinning::finalizeFractionalRebin(*outWS);
   outWS->finalize();
   FractionalRebinning::normaliseOutput(outWS, inputWS);
   // Set the output spectrum-detector mapping
diff --git a/Framework/DataObjects/test/Histogram1DTest.h b/Framework/DataObjects/test/Histogram1DTest.h
index 5ff45b6a1ef48468e829eacd1e15deff057e1114..8509ef2d3769eeb13f035354a3e609ec8ca0b657 100644
--- a/Framework/DataObjects/test/Histogram1DTest.h
+++ b/Framework/DataObjects/test/Histogram1DTest.h
@@ -175,7 +175,7 @@ public:
     // throws so suppress the warning
     MSVC_DIAG_OFF(4834)
     TS_ASSERT_THROWS(h.dataX().at(nel), const std::out_of_range &);
-    MSVC_DIAG_ON()
+    MSVC_DIAG_ON(4834)
   }
   void testrangeexceptionY() {
     h.setCounts(y1);
@@ -183,7 +183,7 @@ public:
     // throws so suppress the warning
     MSVC_DIAG_OFF(4834)
     TS_ASSERT_THROWS(h.dataY().at(nel), const std::out_of_range &);
-    MSVC_DIAG_ON()
+    MSVC_DIAG_ON(4834)
   }
   void testrangeexceptionE() {
     h.setCounts(y1);
@@ -192,7 +192,7 @@ public:
     // throws so suppress the warning
     MSVC_DIAG_OFF(4834)
     TS_ASSERT_THROWS(h.dataE().at(nel), const std::out_of_range &);
-    MSVC_DIAG_ON()
+    MSVC_DIAG_ON(4834)
   }
 
   void test_copy_constructor() {
diff --git a/Framework/DataObjects/test/MDEventWorkspaceTest.h b/Framework/DataObjects/test/MDEventWorkspaceTest.h
index aac5b398a2728f7abc4dbbf6a999a152159268a1..0a152faa94fa28edf7e0f11c8c6a8e83d3914117 100644
--- a/Framework/DataObjects/test/MDEventWorkspaceTest.h
+++ b/Framework/DataObjects/test/MDEventWorkspaceTest.h
@@ -408,12 +408,12 @@ public:
     std::vector<coord_t> min;
     std::vector<coord_t> max;
 
-    min.emplace_back(0);
-    min.emplace_back(0);
-    min.emplace_back(0);
-    max.emplace_back(1.5);
-    max.emplace_back(1.5);
-    max.emplace_back(1.5);
+    min.emplace_back(0.f);
+    min.emplace_back(0.f);
+    min.emplace_back(0.f);
+    max.emplace_back(1.5f);
+    max.emplace_back(1.5f);
+    max.emplace_back(1.5f);
 
     // Create a function to mask some of the workspace.
     auto function = std::make_unique<MDBoxImplicitFunction>(min, max);
@@ -570,12 +570,12 @@ public:
     std::vector<coord_t> min;
     std::vector<coord_t> max;
 
-    min.emplace_back(0);
-    min.emplace_back(0);
-    min.emplace_back(0);
-    max.emplace_back(10);
-    max.emplace_back(10);
-    max.emplace_back(10);
+    min.emplace_back(0.f);
+    min.emplace_back(0.f);
+    min.emplace_back(0.f);
+    max.emplace_back(10.f);
+    max.emplace_back(10.f);
+    max.emplace_back(10.f);
 
     // Create an function that encompases 1/4 of the total bins.
     auto function = std::make_unique<MDBoxImplicitFunction>(min, max);
@@ -593,9 +593,9 @@ public:
     std::vector<coord_t> max;
 
     // Make the box lay over a non-intersecting region of space.
-    min.emplace_back(-1);
-    min.emplace_back(-1);
-    min.emplace_back(-1);
+    min.emplace_back(-1.f);
+    min.emplace_back(-1.f);
+    min.emplace_back(-1.f);
     max.emplace_back(-0.01f);
     max.emplace_back(-0.01f);
     max.emplace_back(-0.01f);
@@ -611,11 +611,11 @@ public:
     std::vector<coord_t> max;
 
     // Make the box that covers half the bins in the workspace.
-    min.emplace_back(0);
-    min.emplace_back(0);
-    min.emplace_back(0);
-    max.emplace_back(10);
-    max.emplace_back(10);
+    min.emplace_back(0.f);
+    min.emplace_back(0.f);
+    min.emplace_back(0.f);
+    max.emplace_back(10.f);
+    max.emplace_back(10.f);
     max.emplace_back(4.99f);
 
     // Create an function that encompases 1/4 of the total bins.
@@ -628,12 +628,12 @@ public:
     // Create a function that masks everything.
     std::vector<coord_t> min;
     std::vector<coord_t> max;
-    min.emplace_back(0);
-    min.emplace_back(0);
-    min.emplace_back(0);
-    max.emplace_back(10);
-    max.emplace_back(10);
-    max.emplace_back(10);
+    min.emplace_back(0.f);
+    min.emplace_back(0.f);
+    min.emplace_back(0.f);
+    max.emplace_back(10.f);
+    max.emplace_back(10.f);
+    max.emplace_back(10.f);
     auto function = std::make_unique<MDBoxImplicitFunction>(min, max);
 
     MDEventWorkspace3Lean::sptr ws =
diff --git a/Framework/DataObjects/test/MDHistoWorkspaceIteratorTest.h b/Framework/DataObjects/test/MDHistoWorkspaceIteratorTest.h
index 89d16b77bb1492be7f94fc018e50483a7def7b9c..8d1e7eefe1755409175621a04fc7348e849b8e5e 100644
--- a/Framework/DataObjects/test/MDHistoWorkspaceIteratorTest.h
+++ b/Framework/DataObjects/test/MDHistoWorkspaceIteratorTest.h
@@ -16,8 +16,6 @@
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/VMD.h"
 #include "MantidTestHelpers/MDEventsTestHelper.h"
-#include <boost/bind.hpp>
-#include <boost/function.hpp>
 #include <boost/scoped_ptr.hpp>
 #include <cmath>
 #include <cxxtest/TestSuite.h>
@@ -106,8 +104,8 @@ public:
 
     std::vector<coord_t> normal_vector;
     std::vector<coord_t> bound_vector;
-    normal_vector.emplace_back(1.);
-    bound_vector.emplace_back(3.);
+    normal_vector.emplace_back(1.f);
+    bound_vector.emplace_back(3.f);
 
     MDImplicitFunction *function = new MDImplicitFunction();
     function->addPlane(MDPlane(normal_vector, bound_vector));
diff --git a/Framework/DataObjects/test/MDHistoWorkspaceTest.h b/Framework/DataObjects/test/MDHistoWorkspaceTest.h
index 88f393ec266d59cc4595f060c088250841d48e99..f51d8d524774535b1f23e47b52374a01bd0f537d 100644
--- a/Framework/DataObjects/test/MDHistoWorkspaceTest.h
+++ b/Framework/DataObjects/test/MDHistoWorkspaceTest.h
@@ -561,10 +561,10 @@ public:
 
     std::vector<coord_t> min;
     std::vector<coord_t> max;
-    min.emplace_back(0);
-    min.emplace_back(0);
-    max.emplace_back(5);
-    max.emplace_back(5);
+    min.emplace_back(0.f);
+    min.emplace_back(0.f);
+    max.emplace_back(5.f);
+    max.emplace_back(5.f);
 
     // Mask part of the workspace
     auto function = std::make_unique<MDBoxImplicitFunction>(min, max);
@@ -982,12 +982,12 @@ public:
     std::vector<coord_t> max;
 
     // Make the box that covers the whole workspace.
-    min.emplace_back(0);
-    min.emplace_back(0);
-    min.emplace_back(0);
-    max.emplace_back(10);
-    max.emplace_back(10);
-    max.emplace_back(10);
+    min.emplace_back(0.f);
+    min.emplace_back(0.f);
+    min.emplace_back(0.f);
+    max.emplace_back(10.f);
+    max.emplace_back(10.f);
+    max.emplace_back(10.f);
 
     // Create an function that encompases ALL of the total bins.
     auto function = std::make_unique<MDBoxImplicitFunction>(min, max);
@@ -1114,12 +1114,12 @@ public:
     std::vector<coord_t> max;
 
     // Make the box that covers half the bins in the workspace.
-    min.emplace_back(0);
-    min.emplace_back(0);
-    min.emplace_back(0);
-    max.emplace_back(10);
-    max.emplace_back(10);
-    max.emplace_back(10);
+    min.emplace_back(0.f);
+    min.emplace_back(0.f);
+    min.emplace_back(0.f);
+    max.emplace_back(10.f);
+    max.emplace_back(10.f);
+    max.emplace_back(10.f);
 
     // Create an function that encompases ALL of the total bins.
     auto function = std::make_unique<MDBoxImplicitFunction>(min, max);
@@ -1131,11 +1131,11 @@ public:
     std::vector<coord_t> max;
 
     // Make the box that covers half the bins in the workspace.
-    min.emplace_back(0);
-    min.emplace_back(0);
-    min.emplace_back(0);
-    max.emplace_back(10);
-    max.emplace_back(10);
+    min.emplace_back(0.f);
+    min.emplace_back(0.f);
+    min.emplace_back(0.f);
+    max.emplace_back(10.f);
+    max.emplace_back(10.f);
     max.emplace_back(4.99f);
 
     // Create an function that encompases 1/2 of the total bins.
@@ -1147,12 +1147,12 @@ public:
     // Create a function that masks everything.
     std::vector<coord_t> min;
     std::vector<coord_t> max;
-    min.emplace_back(0);
-    min.emplace_back(0);
-    min.emplace_back(0);
-    max.emplace_back(10);
-    max.emplace_back(10);
-    max.emplace_back(10);
+    min.emplace_back(0.f);
+    min.emplace_back(0.f);
+    min.emplace_back(0.f);
+    max.emplace_back(10.f);
+    max.emplace_back(10.f);
+    max.emplace_back(10.f);
     auto function = std::make_unique<MDBoxImplicitFunction>(min, max);
 
     MDEventWorkspace3Lean::sptr ws =
diff --git a/Framework/DataObjects/test/WorkspaceIteratorTest.h b/Framework/DataObjects/test/WorkspaceIteratorTest.h
index c78953f3b4fda7f971ec3483b34bb2f815616303..5e065da91af21ec836cf3bdf1a1027bc69fcedc3 100644
--- a/Framework/DataObjects/test/WorkspaceIteratorTest.h
+++ b/Framework/DataObjects/test/WorkspaceIteratorTest.h
@@ -8,7 +8,6 @@
 #define TRIPLEITERATORTEST_
 
 #include <algorithm>
-#include <boost/bind.hpp>
 #include <boost/shared_ptr.hpp>
 #include <cxxtest/TestSuite.h>
 
diff --git a/Framework/Geometry/src/Crystal/CrystalStructure.cpp b/Framework/Geometry/src/Crystal/CrystalStructure.cpp
index 7f2deee0a7bdf68e9fc8f6b26ae18b33ab085778..c1fd3338236677f3e6754a6dfbd0ac9a336506bb 100644
--- a/Framework/Geometry/src/Crystal/CrystalStructure.cpp
+++ b/Framework/Geometry/src/Crystal/CrystalStructure.cpp
@@ -6,7 +6,6 @@
 // SPDX - License - Identifier: GPL - 3.0 +
 #include "MantidGeometry/Crystal/CrystalStructure.h"
 #include <algorithm>
-#include <boost/bind.hpp>
 #include <stdexcept>
 
 #include "MantidGeometry/Crystal/BasicHKLFilters.h"
diff --git a/Framework/Geometry/src/Crystal/StructureFactorCalculator.cpp b/Framework/Geometry/src/Crystal/StructureFactorCalculator.cpp
index 837279174da60aa2b09e11ec4485beebe95463a0..777a4df11da610f880182fc07b1e22b07654279e 100644
--- a/Framework/Geometry/src/Crystal/StructureFactorCalculator.cpp
+++ b/Framework/Geometry/src/Crystal/StructureFactorCalculator.cpp
@@ -6,8 +6,6 @@
 // SPDX - License - Identifier: GPL - 3.0 +
 #include "MantidGeometry/Crystal/StructureFactorCalculator.h"
 
-#include <boost/bind.hpp>
-
 namespace Mantid {
 namespace Geometry {
 
@@ -47,9 +45,9 @@ double StructureFactorCalculator::getFSquared(const Kernel::V3D &hkl) const {
 std::vector<StructureFactor>
 StructureFactorCalculator::getFs(const std::vector<Kernel::V3D> &hkls) const {
   std::vector<StructureFactor> structureFactors(hkls.size());
-
+  using namespace std::placeholders;
   std::transform(hkls.begin(), hkls.end(), structureFactors.begin(),
-                 boost::bind(&StructureFactorCalculator::getF, this, _1));
+                 std::bind(&StructureFactorCalculator::getF, this, _1));
 
   return structureFactors;
 }
@@ -67,10 +65,9 @@ StructureFactorCalculator::getFs(const std::vector<Kernel::V3D> &hkls) const {
 std::vector<double> StructureFactorCalculator::getFsSquared(
     const std::vector<Kernel::V3D> &hkls) const {
   std::vector<double> fSquareds(hkls.size());
-
-  std::transform(
-      hkls.begin(), hkls.end(), fSquareds.begin(),
-      boost::bind(&StructureFactorCalculator::getFSquared, this, _1));
+  using namespace std::placeholders;
+  std::transform(hkls.begin(), hkls.end(), fSquareds.begin(),
+                 std::bind(&StructureFactorCalculator::getFSquared, this, _1));
 
   return fSquareds;
 }
diff --git a/Framework/Geometry/src/Surfaces/LineIntersectVisit.cpp b/Framework/Geometry/src/Surfaces/LineIntersectVisit.cpp
index ad25cc8d4c395f4df138ada5a9f02fa78f7c9d52..16bf817fa13e6f3baa3f196542721d62100809b6 100644
--- a/Framework/Geometry/src/Surfaces/LineIntersectVisit.cpp
+++ b/Framework/Geometry/src/Surfaces/LineIntersectVisit.cpp
@@ -15,7 +15,6 @@
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/Strings.h"
 #include <algorithm>
-#include <boost/bind.hpp>
 
 namespace Mantid {
 
diff --git a/Framework/Geometry/test/CMakeLists.txt b/Framework/Geometry/test/CMakeLists.txt
index ec68a77093eab05529b47876ee807473f99de36f..9c2f5e681b2b6000ccd073e693931904bb946389 100644
--- a/Framework/Geometry/test/CMakeLists.txt
+++ b/Framework/Geometry/test/CMakeLists.txt
@@ -18,6 +18,7 @@ if(CXXTEST_FOUND)
       ../../TestHelpers/src/LoggingCleaner.cpp)
 
   cxxtest_add_test(GeometryTest ${TEST_FILES} ${GMOCK_TEST_FILES})
+  target_compile_definitions(GeometryTest PRIVATE -D_SILENCE_FPOS_SEEKPOS_DEPRECATION_WARNING)
   target_link_libraries(GeometryTest
                         LINK_PRIVATE
                         ${TCMALLOC_LIBRARIES_LINKTIME}
diff --git a/Framework/Kernel/inc/MantidKernel/FunctionTask.h b/Framework/Kernel/inc/MantidKernel/FunctionTask.h
index 69732403625fb2ac8ab6d91815ddd8dde3da5aa0..9b561ac92ab4e2f0a21f184cfba6bfa5a54169bb 100644
--- a/Framework/Kernel/inc/MantidKernel/FunctionTask.h
+++ b/Framework/Kernel/inc/MantidKernel/FunctionTask.h
@@ -9,10 +9,10 @@
 
 #include "MantidKernel/DllConfig.h"
 #include "MantidKernel/Task.h"
+#include <functional>
 #include <stdexcept>
 
 #ifndef Q_MOC_RUN
-#include <boost/bind.hpp>
 #include <boost/function.hpp>
 #endif
 
@@ -35,12 +35,12 @@ public:
   //---------------------------------------------------------------------------------------------
   /** Constructor for a simple void function.
    *
-   * Pro-tip: use boost::bind(f, argument1, argument2) (for example) to turn a
+   * Pro-tip: use std::bind(f, argument1, argument2) (for example) to turn a
    *function that takes
    * an argument into a argument-less function pointer.
    *
-   * Use boost::bind(&ClassName::function, &*this, arg1, arg2) to bind to a
-   *class method of this.
+   * Use std::bind(&ClassName::function, &*this, arg1, arg2) to bind to a
+   * class method of this.
    *
    * @param func :: pointer to a void function()
    * @param cost :: computational cost
@@ -51,17 +51,17 @@ public:
   //---------------------------------------------------------------------------------------------
   /** Constructor for a simple boost bound function.
    *
-   * Pro-tip: use boost::bind(f, argument1, argument2) (for example) to turn a
+   * Pro-tip: use std::bind(f, argument1, argument2) (for example) to turn a
    *function that takes
    * an argument into a argument-less function pointer.
    *
-   * Use boost::bind(&ClassName::function, &*this, arg1, arg2) to bind to a
+   * Use std::bind(&ClassName::function, &*this, arg1, arg2) to bind to a
    *class method of this.
    *
-   * @param func :: boost::function<> returned by boost::bind()
+   * @param func :: std::function<> returned by std::bind()
    * @param cost :: computational cost
    */
-  FunctionTask(boost::function<void()> func, double cost = 1.0)
+  FunctionTask(std::function<void()> func, double cost = 1.0)
       : Task(cost), m_voidFunc(func) {}
 
   //---------------------------------------------------------------------------------------------
@@ -74,7 +74,7 @@ public:
   }
 
 protected:
-  boost::function<void()> m_voidFunc;
+  std::function<void()> m_voidFunc;
 };
 
 } // namespace Kernel
diff --git a/Framework/Kernel/inc/MantidKernel/PropertyWithValueJSON.h b/Framework/Kernel/inc/MantidKernel/PropertyWithValueJSON.h
index 4982aab0b2e50ddf34105d45706153100e3c14b8..bb33edc4ece29e7d35a6f608d8944a4d3be8ef51 100644
--- a/Framework/Kernel/inc/MantidKernel/PropertyWithValueJSON.h
+++ b/Framework/Kernel/inc/MantidKernel/PropertyWithValueJSON.h
@@ -38,11 +38,11 @@ template <> struct ToCpp<int> {
 };
 /// Specialization of ToCpp for long long
 template <> struct ToCpp<long long> {
-  long operator()(const Json::Value &value) { return value.asInt64(); }
+  long long operator()(const Json::Value &value) { return value.asInt64(); }
 };
 /// Specialization of ToCpp for long
 template <> struct ToCpp<long> {
-  Json::Int64 operator()(const Json::Value &value) { return value.asInt64(); }
+  long operator()(const Json::Value &value) { return value.asInt(); }
 };
 /// Specialization of ToCpp for unsigned int
 template <> struct ToCpp<unsigned int> {
diff --git a/Framework/Kernel/inc/MantidKernel/TimeSeriesProperty.h b/Framework/Kernel/inc/MantidKernel/TimeSeriesProperty.h
index 9577b09385a152a2453bebb36129d1deeb1a11b2..91a34719d8cd5647ad769d09efa35ade5a825220 100644
--- a/Framework/Kernel/inc/MantidKernel/TimeSeriesProperty.h
+++ b/Framework/Kernel/inc/MantidKernel/TimeSeriesProperty.h
@@ -159,10 +159,10 @@ public:
                    bool isPeriodic) const override;
 
   /// New split method
-  void
-  splitByTimeVector(std::vector<Types::Core::DateAndTime> &splitter_time_vec,
-                    std::vector<int> &target_vec,
-                    std::vector<TimeSeriesProperty *> outputs);
+  void splitByTimeVector(
+      const std::vector<Types::Core::DateAndTime> &splitter_time_vec,
+      const std::vector<int> &target_vec,
+      const std::vector<TimeSeriesProperty *> &outputs);
 
   /// Fill a TimeSplitterType that will filter the events by matching
   void makeFilterByValue(std::vector<SplittingInterval> &split, double min,
diff --git a/Framework/Kernel/inc/MantidKernel/WarningSuppressions.h b/Framework/Kernel/inc/MantidKernel/WarningSuppressions.h
index 1d9de27ec97d7c72883cd7de67407c7dbbf4b999..1ffd322d9e56c56417e35e304542cadaaa39bd18 100644
--- a/Framework/Kernel/inc/MantidKernel/WarningSuppressions.h
+++ b/Framework/Kernel/inc/MantidKernel/WarningSuppressions.h
@@ -82,7 +82,7 @@
 #define MSVC_DIAG_OFF(id)                                                        \
   __pragma(warning(push))                                                        \
   __pragma(warning(disable : id))
-#define MSVC_DIAG_ON() __pragma(warning(pop))
+#define MSVC_DIAG_ON(id) __pragma(warning(pop))
 // clang-format on
 #else
 #define MSVC_DIAG_OFF(x)
diff --git a/Framework/Kernel/src/MultiFileNameParser.cpp b/Framework/Kernel/src/MultiFileNameParser.cpp
index 413d8dbf446312a63b860a910281b055ca68915d..513a52158fb9c009d76cff3727fd9f23e300e09a 100644
--- a/Framework/Kernel/src/MultiFileNameParser.cpp
+++ b/Framework/Kernel/src/MultiFileNameParser.cpp
@@ -17,7 +17,6 @@
 #include <sstream>
 
 #include <boost/algorithm/string.hpp>
-#include <boost/bind.hpp>
 #include <boost/regex.hpp>
 
 namespace Mantid {
diff --git a/Framework/Kernel/src/NetworkProxyWin.cpp b/Framework/Kernel/src/NetworkProxyWin.cpp
index f7c8c7a6b1267f4e277306d2ce7837732d5ff9f0..b04c02cb17419fe9725476c1c5c4f2ecb4968549 100644
--- a/Framework/Kernel/src/NetworkProxyWin.cpp
+++ b/Framework/Kernel/src/NetworkProxyWin.cpp
@@ -8,6 +8,7 @@
 #if defined(_WIN32) || defined(_WIN64)
 
 #include "MantidKernel/NetworkProxy.h"
+#include "MantidKernel/WarningSuppressions.h"
 // std
 #include <sstream>
 // windows
@@ -117,7 +118,9 @@ bool get_proxy_configuration_win(const std::string &target_url,
   if (fail) {
     err_msg = info.str();
   }
+  MSVC_DIAG_OFF(4244)
   proxy_str = std::string(proxy.begin(), proxy.end());
+  MSVC_DIAG_ON(4244)
   return !fail;
 }
 
diff --git a/Framework/Kernel/src/PropertyWithValue.cpp b/Framework/Kernel/src/PropertyWithValue.cpp
index 47868ff329fe36f42dd34d9964f747eb5f9e6db1..eb1172d7bed782715095f4fccf3d2a4e9c340dad 100644
--- a/Framework/Kernel/src/PropertyWithValue.cpp
+++ b/Framework/Kernel/src/PropertyWithValue.cpp
@@ -21,6 +21,9 @@ namespace Kernel {
   void PropertyWithValue<type>::saveProperty(::NeXus::File *file) {            \
     file->makeGroup(this->name(), "NXlog", true);                              \
     file->writeData("value", m_value);                                         \
+    file->openData("value");                                                   \
+    file->putAttr("units", this->units());                                     \
+    file->closeData();                                                         \
     file->closeGroup();                                                        \
   }
 
diff --git a/Framework/Kernel/src/TimeSeriesProperty.cpp b/Framework/Kernel/src/TimeSeriesProperty.cpp
index de59d2083d617bbba74344fac15952dbf7a5b463..dcd59531bfd0f4e71a480356659bb5c14fbbc869 100644
--- a/Framework/Kernel/src/TimeSeriesProperty.cpp
+++ b/Framework/Kernel/src/TimeSeriesProperty.cpp
@@ -414,12 +414,12 @@ void TimeSeriesProperty<TYPE>::filterByTimes(
  * property according to number of distinct splitters' indexes, such as 0 and 1
  *
  * NOTE: If the input TSP has a single value, it is assumed to be a constant
- *  and so is not split, but simply copied to all outputs.
+ *  and so is not split, but simply copied to all output.
  *
  * @param splitter :: a TimeSplitterType object containing the list of intervals
  *                     and destinations.
- * @param outputs  :: A vector of output TimeSeriesProperty pointers of the same
- *                    type.
+ * @param outputs  :: A vector of output TimeSeriesProperty
+ * pointers of the same type.
  * @param isPeriodic :: whether the log (this TSP) is periodic. For example
  *                    proton-charge is periodic log.
  */
@@ -541,209 +541,118 @@ void TimeSeriesProperty<TYPE>::splitByTime(
 }
 
 /// Split this TimeSeriresProperty by a vector of time with N entries,
-/// and by the target workspace index defined by target_vec
+/// and by the wsIndex workspace index defined by inputWorkspaceIndicies
 /// Requirements:
-/// vector outputs must be defined before this method is called
+/// vector output must be defined before this method is called
 template <typename TYPE>
 void TimeSeriesProperty<TYPE>::splitByTimeVector(
-    std::vector<DateAndTime> &splitter_time_vec, std::vector<int> &target_vec,
-    std::vector<TimeSeriesProperty *> outputs) {
-
-  // check target vector to make it a set
-  std::set<int> target_set;
-  for (auto target : target_vec)
-    target_set.insert(target);
+    const std::vector<DateAndTime> &timeToFilterTo,
+    const std::vector<int> &inputWorkspaceIndicies,
+    const std::vector<TimeSeriesProperty *> &output) {
 
   // check inputs
-  if (splitter_time_vec.size() != target_vec.size() + 1) {
-    std::stringstream errss;
-    errss << "Try to split TSP " << this->m_name
-          << ": Input time vector's size " << splitter_time_vec.size()
-          << " does not match (one more larger than) taget "
-             "workspace index vector's size "
-          << target_vec.size() << "\n";
-    throw std::runtime_error(errss.str());
+  if (timeToFilterTo.size() != inputWorkspaceIndicies.size() + 1) {
+    throw std::runtime_error(
+        "Input time vector's size does not match(one more larger than) target "
+        "workspace index vector's size inputWorkspaceIndicies.size() \n");
   }
+
   // return if the output vector TimeSeriesProperties is not defined
-  if (outputs.empty())
+  if (output.empty())
     return;
 
-  // sort if necessary
   sortIfNecessary();
 
   // work on m_values, m_size, and m_time
-  std::vector<Types::Core::DateAndTime> tsp_time_vec = this->timesAsVector();
-
-  // go over both filter time vector and time series property time vector
+  auto const currentTimes = timesAsVector();
+  auto const currentValues = valuesAsVector();
   size_t index_splitter = 0;
-  size_t index_tsp_time = 0;
-
-  // tsp_time is start time of time series property
-  DateAndTime tsp_time = tsp_time_vec[index_tsp_time];
-  DateAndTime split_start_time = splitter_time_vec[index_splitter];
-  DateAndTime split_stop_time = splitter_time_vec[index_splitter + 1];
 
   // move splitter index such that the first entry of TSP is before the stop
   // time of a splitter
-  bool continue_search = true;
-  bool no_entry_in_range = false;
-
-  std::vector<DateAndTime>::iterator splitter_iter;
-  splitter_iter = std::lower_bound(splitter_time_vec.begin(),
-                                   splitter_time_vec.end(), tsp_time);
-  if (splitter_iter == splitter_time_vec.begin()) {
+  DateAndTime firstPropTime = currentTimes[0];
+  auto firstFilterTime = std::lower_bound(timeToFilterTo.begin(),
+                                          timeToFilterTo.end(), firstPropTime);
+  if (firstFilterTime == timeToFilterTo.end()) {
     // do nothing as the first TimeSeriesProperty entry's time is before any
     // splitters
-    ;
-  } else if (splitter_iter == splitter_time_vec.end()) {
-    // already search to the last splitter which is still earlier than first TSP
-    // entry
-    no_entry_in_range = true;
-  } else {
+    return;
+  } else if (firstFilterTime != timeToFilterTo.begin()) {
     // calculate the splitter's index (now we check the stop time)
-    index_splitter = splitter_iter - splitter_time_vec.begin() - 1;
-    split_start_time = splitter_time_vec[index_splitter];
-    split_stop_time = splitter_time_vec[index_splitter + 1];
+    index_splitter = firstFilterTime - timeToFilterTo.begin() - 1;
   }
 
-  // move along the entries to find the entry inside the current splitter
-  bool first_splitter_after_last_entry(false);
-  if (!no_entry_in_range) {
-    std::vector<DateAndTime>::iterator tsp_time_iter;
-    tsp_time_iter = std::lower_bound(tsp_time_vec.begin(), tsp_time_vec.end(),
-                                     split_start_time);
-    if (tsp_time_iter == tsp_time_vec.end()) {
-      // the first splitter's start time is LATER than the last TSP entry, then
-      // there won't be any
-      // TSP entry to be split into any target splitter.
-      no_entry_in_range = true;
-      first_splitter_after_last_entry = true;
-    } else {
-      // first splitter start time is between tsp_time_iter and the one before
-      // it.
-      // so the index for tsp_time_iter is the first TSP entry in the splitter
-      index_tsp_time = tsp_time_iter - tsp_time_vec.begin();
-      tsp_time = *tsp_time_iter;
-    }
-  } else {
-    // no entry in range is true, which corresponding to the previous case
-    // "already search to the last splitter which is still earlier than first
-    // TSP
-    // entry"
-    ;
-  }
+  DateAndTime filterStartTime = timeToFilterTo[index_splitter];
+  DateAndTime filterEndTime = timeToFilterTo[index_splitter + 1];
 
-  if (no_entry_in_range && first_splitter_after_last_entry) {
-    // initialize all the splitters with the last value
+  // move along the entries to find the entry inside the current splitter
+  auto firstEntryInSplitter = std::lower_bound(
+      currentTimes.begin(), currentTimes.end(), filterStartTime);
+  if (firstEntryInSplitter == currentTimes.end()) {
+    // the first splitter's start time is LATER than the last TSP entry, then
+    // there won't be any
+    // TSP entry to be split into any wsIndex splitter.
     DateAndTime last_entry_time = this->lastTime();
     TYPE last_entry_value = this->lastValue();
-    for (size_t i = 0; i < outputs.size(); ++i)
-      outputs[i]->addValue(last_entry_time, last_entry_value);
+    for (auto &i : output) {
+      i->addValue(last_entry_time, last_entry_value);
+    }
+    return;
   }
 
-  // now it is the time to put TSP's entries to corresponding
-  continue_search = !no_entry_in_range;
-  size_t outer_while_counter = 0;
-  bool partial_target_filled(false);
-  while (continue_search) {
-    // get next target
-    int target = target_vec[index_splitter];
+  // first splitter start time is between firstEntryInSplitter and the one
+  // before it. so the index for firstEntryInSplitter is the first TSP entry
+  // in the splitter
+  size_t timeIndex = firstEntryInSplitter - currentTimes.begin();
+  firstPropTime = *firstEntryInSplitter;
 
-    // get the first entry index (overlap)
-    if (index_tsp_time > 0)
-      --index_tsp_time;
-
-    // add the continous entries to same target time series property
-    const size_t tspTimeVecSize = tsp_time_vec.size();
-    bool continue_add = true;
-    while (continue_add) {
-      size_t inner_while_counter = 0;
-      if (index_tsp_time == tspTimeVecSize) {
-        // last entry. quit all loops
-        continue_add = false;
-        continue_search = false;
-        partial_target_filled = true;
-        break;
-      }
+  for (; index_splitter < timeToFilterTo.size() - 1; ++index_splitter) {
+    int wsIndex = inputWorkspaceIndicies[index_splitter];
 
-      // add current entry
-      if (outputs[target]->size() == 0 ||
-          outputs[target]->lastTime() < tsp_time_vec[index_tsp_time]) {
-        // avoid to add duplicate entry
-        outputs[target]->addValue(m_values[index_tsp_time].time(),
-                                  m_values[index_tsp_time].value());
-      }
+    filterStartTime = timeToFilterTo[index_splitter];
+    filterEndTime = timeToFilterTo[index_splitter + 1];
 
-      const size_t nextTspIndex = index_tsp_time + 1;
-      if (nextTspIndex < tspTimeVecSize) {
-        if (tsp_time_vec[nextTspIndex] > split_stop_time) {
-          // next entry is out of this splitter: add the next one and quit
-          if (outputs[target]->lastTime() < m_values[nextTspIndex].time()) {
-            // avoid the duplicate cases occurred in fast frequency issue
-            outputs[target]->addValue(m_values[nextTspIndex].time(),
-                                      m_values[nextTspIndex].value());
-          }
-          // FIXME - in future, need to find out WHETHER there is way to
-          // skip the
-          // rest without going through the whole sequence
-          continue_add = false;
-        }
+    // get the first entry index (overlap)
+    if (timeIndex > 0)
+      --timeIndex;
+
+    // add the continuous entries to same wsIndex time series property
+    const size_t numEntries = currentTimes.size();
+
+    // Add properties to the current wsIndex.
+    if (timeIndex >= numEntries) {
+      // We have run out of TSP entries, so use the last TSP value
+      // for all remaining outputs
+      auto currentTime = currentTimes.back();
+      if (output[wsIndex]->size() == 0 ||
+          output[wsIndex]->lastTime() != currentTime) {
+        output[wsIndex]->addValue(currentTime, currentValues.back());
       }
-
-      // advance to next entry
-      ++index_tsp_time;
-
-      ++inner_while_counter;
-    } // END-WHILE continue add
-
-    // make splitters to advance to next
-    ++index_splitter;
-    if (index_splitter == splitter_time_vec.size() - 1) {
-      // already last splitters
-      continue_search = false;
     } else {
-      split_start_time = split_stop_time;
-      split_stop_time = splitter_time_vec[index_splitter + 1];
-    }
-
-    ++outer_while_counter;
-  } // END-OF-WHILE
-
-  // Still in 'continue search'-while-loop.  But the TSP runs over before
-  // splitters.
-  // Therefore, the rest of the chopper must have one more entry added!
-  if (partial_target_filled) {
-    // fill the target
-    std::set<int> fill_target_set;
-    for (size_t isplitter = index_splitter;
-         isplitter < splitter_time_vec.size() - 1; ++isplitter) {
-      int target_i = target_vec[isplitter];
-      if (fill_target_set.find(target_i) == fill_target_set.end()) {
-        if (outputs[target_i]->size() == 0 ||
-            outputs[target_i]->lastTime() != m_values.back().time())
-          outputs[target_i]->addValue(m_values.back().time(),
-                                      m_values.back().value());
-        fill_target_set.insert(target_i);
-        // quit loop if it goes over all the targets
-        if (fill_target_set.size() == target_set.size())
+      // Add TSP values until we run out or go past the current filter
+      // end time.
+      for (; timeIndex < numEntries; ++timeIndex) {
+        auto currentTime = currentTimes[timeIndex];
+        if (output[wsIndex]->size() == 0 ||
+            output[wsIndex]->lastTime() < currentTime) {
+          // avoid to add duplicate entry
+          output[wsIndex]->addValue(currentTime, currentValues[timeIndex]);
+        }
+        if (currentTime > filterEndTime)
           break;
       }
     }
   }
 
   // Add a debugging check such that there won't be any time entry with zero log
-  for (size_t i = 0; i < outputs.size(); ++i) {
-    if (outputs[i]->size() == 0) {
+  for (size_t i = 0; i < output.size(); ++i) {
+    if (output[i]->size() == 0) {
       std::stringstream errss;
-      errss << i << "-th split-out term (out of " << outputs.size()
-            << " total output TSP) of '" << m_name << "'' has "
-            << outputs[i]->size() << " size, whose first entry is at "
+      errss << "entry " << m_name << " has 0 size, whose first entry is at "
             << this->firstTime().toSimpleString();
-      g_log.debug(errss.str());
+      g_log.warning(errss.str());
     }
   }
-
-  return;
 }
 
 // The makeFilterByValue & expandFilterToRange methods generate a bunch of
diff --git a/Framework/Kernel/src/UsageService.cpp b/Framework/Kernel/src/UsageService.cpp
index 81a8a3630baeb6e5449e0a71ca655eb128d8ade7..3de84a525e3fdc1aa278b75b03e579f8377c453d 100644
--- a/Framework/Kernel/src/UsageService.cpp
+++ b/Framework/Kernel/src/UsageService.cpp
@@ -19,7 +19,6 @@
 #include <algorithm>
 #include <boost/algorithm/string/join.hpp>
 #include <boost/algorithm/string/trim.hpp>
-#include <boost/bind.hpp>
 
 #include <json/json.h>
 
diff --git a/Framework/Kernel/test/FunctionTaskTest.h b/Framework/Kernel/test/FunctionTaskTest.h
index 01097633b7f5b4c40b55248b1045e9dd131703ba..ea0ceb4b6c98a6f1d90cf7b8aa7ae3611d079cc8 100644
--- a/Framework/Kernel/test/FunctionTaskTest.h
+++ b/Framework/Kernel/test/FunctionTaskTest.h
@@ -42,14 +42,14 @@ public:
   }
 
   void test_Function_using_bind() {
-    FunctionTask mytask(boost::bind<void, int>(my_int_function, 34));
+    FunctionTask mytask(std::bind(my_int_function, 34));
     TS_ASSERT_DIFFERS(my_check_value, 34);
     TS_ASSERT_THROWS_NOTHING(mytask.run());
     TS_ASSERT_EQUALS(my_check_value, 34);
   }
 
   void test_Function_using_bind_complicated() {
-    FunctionTask mytask(boost::bind(my_complicated_function, 56, 12.0));
+    FunctionTask mytask(std::bind(my_complicated_function, 56, 12.0));
     TS_ASSERT_DIFFERS(my_check_value, 68);
     TS_ASSERT_THROWS_NOTHING(mytask.run());
     TS_ASSERT_EQUALS(my_check_value, 68);
diff --git a/Framework/Kernel/test/LoggerTest.h b/Framework/Kernel/test/LoggerTest.h
index eae3879505ea1299cbd9103899157ab09df0dffb..e6babd11b539b8384975481e09fbcc2492fd69e9 100644
--- a/Framework/Kernel/test/LoggerTest.h
+++ b/Framework/Kernel/test/LoggerTest.h
@@ -94,7 +94,7 @@ public:
     ThreadPool tp;
     for (int i = 0; i < 1000; i++)
       tp.schedule(std::make_shared<FunctionTask>(
-          boost::bind(&LoggerTest::doLogInParallel, &*this, i)));
+          std::bind(&LoggerTest::doLogInParallel, &*this, i)));
     tp.joinAll();
   }
 };
diff --git a/Framework/Kernel/test/ThreadPoolTest.h b/Framework/Kernel/test/ThreadPoolTest.h
index 7975ddfbad3baccb7342b9fbf667ac4272146bfe..9ae602e264b4f59eba40ca65a7167378737fea91 100644
--- a/Framework/Kernel/test/ThreadPoolTest.h
+++ b/Framework/Kernel/test/ThreadPoolTest.h
@@ -18,7 +18,6 @@
 
 #include <Poco/Thread.h>
 
-#include <boost/bind.hpp>
 #include <boost/make_shared.hpp>
 #include <cstdlib>
 
@@ -133,7 +132,7 @@ public:
       double cost = i; // time is exactly i
       // Bind to a member function of mywaster
       p.schedule(std::make_shared<FunctionTask>(
-          boost::bind(&TimeWaster::waste_time_with_lock, &mywaster, i), cost));
+          std::bind(&TimeWaster::waste_time_with_lock, &mywaster, i), cost));
     }
 
     Timer overall;
@@ -281,7 +280,7 @@ public:
     for (int i = 0; i < 10; i++) {
       double cost = i;
       p.schedule(std::make_shared<FunctionTask>(
-          boost::bind(threadpooltest_adding_stuff, i), cost));
+          std::bind(threadpooltest_adding_stuff, i), cost));
     }
     TS_ASSERT_THROWS_NOTHING(p.joinAll());
     TS_ASSERT_EQUALS(threadpooltest_vec.size(), 10);
@@ -300,7 +299,7 @@ public:
     for (int i = 0; i < 10; i++) {
       double cost = i;
       p.schedule(std::make_shared<FunctionTask>(
-          boost::bind(threadpooltest_adding_stuff, i), cost));
+          std::bind(threadpooltest_adding_stuff, i), cost));
     }
     TS_ASSERT_THROWS_NOTHING(p.joinAll());
     TS_ASSERT_EQUALS(threadpooltest_vec.size(), 10);
@@ -318,7 +317,7 @@ public:
     for (int i = 0; i < 10; i++) {
       double cost = i;
       p.schedule(std::make_shared<FunctionTask>(
-          boost::bind(threadpooltest_adding_stuff, i), cost));
+          std::bind(threadpooltest_adding_stuff, i), cost));
     }
     TS_ASSERT_THROWS_NOTHING(p.joinAll());
     TS_ASSERT_EQUALS(threadpooltest_vec.size(), 10);
@@ -342,7 +341,7 @@ public:
     boost::shared_ptr<std::mutex> lastMutex;
     for (size_t i = 0; i <= num; i++) {
       auto task = std::make_shared<FunctionTask>(
-          boost::bind(&TimeWaster::add_to_number, &mywaster, i),
+          std::bind(&TimeWaster::add_to_number, &mywaster, i),
           static_cast<double>(i));
       // Create a new mutex every 1000 tasks. This is more relevant to the
       // ThreadSchedulerMutexes; others ignore it.
diff --git a/Framework/LiveData/inc/MantidLiveData/Kafka/IKafkaStreamDecoder.h b/Framework/LiveData/inc/MantidLiveData/Kafka/IKafkaStreamDecoder.h
index 04f89d19eca57def565da2b5e697c0e3d17f37a5..722981f8d7c9a73fffb6f46bc302689cb2714916 100644
--- a/Framework/LiveData/inc/MantidLiveData/Kafka/IKafkaStreamDecoder.h
+++ b/Framework/LiveData/inc/MantidLiveData/Kafka/IKafkaStreamDecoder.h
@@ -205,7 +205,7 @@ protected:
                         const boost::shared_ptr<T> &parent);
 
   template <typename T>
-  void loadInstrument(const std::string &name, boost::shared_ptr<T> workspace,
+  bool loadInstrument(const std::string &name, boost::shared_ptr<T> workspace,
                       const std::string &jsonGeometry = "");
 
   void checkRunMessage(
diff --git a/Framework/LiveData/inc/MantidLiveData/Kafka/IKafkaStreamDecoder.tcc b/Framework/LiveData/inc/MantidLiveData/Kafka/IKafkaStreamDecoder.tcc
index f4d6946980aa48a49c6b7667730f45736dde8348..2b03a36b0867c97bf12d9b832d8517aff68b2572 100644
--- a/Framework/LiveData/inc/MantidLiveData/Kafka/IKafkaStreamDecoder.tcc
+++ b/Framework/LiveData/inc/MantidLiveData/Kafka/IKafkaStreamDecoder.tcc
@@ -102,27 +102,32 @@ void loadFromAlgorithm(const std::string &name,
  * @param parseJSON flag which will extract geometry from
  */
 template <typename T>
-void IKafkaStreamDecoder::loadInstrument(const std::string &name,
+bool IKafkaStreamDecoder::loadInstrument(const std::string &name,
                                          boost::shared_ptr<T> workspace,
                                          const std::string &jsonGeometry) {
-  if (name.empty()) {
-    logger.warning("Empty instrument name found");
-    return;
-  }
-  try {
-    if (jsonGeometry.empty())
-      loadFromAlgorithm<T>(name, workspace);
-    else {
-      NexusGeometry::JSONInstrumentBuilder builder(
-          "{\"nexus_structure\":" + jsonGeometry + "}");
-      workspace->setInstrument(builder.buildGeometry());
+  auto instrument = workspace->getInstrument();
+  if (instrument->getNumberDetectors() != 0) // instrument already loaded.
+    return true;
+
+  if (!name.empty()) {
+    try {
+      if (jsonGeometry.empty())
+        loadFromAlgorithm<T>(name, workspace);
+      else {
+        NexusGeometry::JSONInstrumentBuilder builder(
+            "{\"nexus_structure\":" + jsonGeometry + "}");
+        workspace->setInstrument(builder.buildGeometry());
+      }
+      return true;
+    } catch (std::exception &exc) {
+      logger.warning() << "Error loading instrument '" << name << "': \""
+                       << exc.what()
+                       << "\". The streamed data will have no associated "
+                          "instrument geometry. \n";
     }
-  } catch (std::exception &exc) {
-    logger.warning() << "Error loading instrument '" << name << "': \""
-                     << exc.what()
-                     << "\". The streamed data will have no associated "
-                        "instrument geometry. \n";
   }
+  logger.warning() << "Empty instrument name provided. \n";
+  return false;
 }
 
 /**
diff --git a/Framework/LiveData/src/Kafka/IKafkaStreamDecoder.cpp b/Framework/LiveData/src/Kafka/IKafkaStreamDecoder.cpp
index d2afad3275e9aade9162a7dd89c8b00c4856f350..96cbfb022c6382027a29ef013e27f8abe4dd3ff4 100644
--- a/Framework/LiveData/src/Kafka/IKafkaStreamDecoder.cpp
+++ b/Framework/LiveData/src/Kafka/IKafkaStreamDecoder.cpp
@@ -82,9 +82,9 @@ void IKafkaStreamDecoder::startCapture(bool startNow) {
     auto runStartData = getRunStartMessage(rawMsgBuffer);
     joinStreamAtTime(runStartData);
   } else {
-    m_dataStream =
-        m_broker->subscribe({m_streamTopic, m_runInfoTopic, m_sampleEnvTopic},
-                            SubscribeAtOption::LATEST);
+    m_dataStream = m_broker->subscribe(
+        {m_streamTopic, m_monitorTopic, m_runInfoTopic, m_sampleEnvTopic},
+        SubscribeAtOption::LATEST);
   }
 
   try {
diff --git a/Framework/LiveData/src/Kafka/KafkaEventStreamDecoder.cpp b/Framework/LiveData/src/Kafka/KafkaEventStreamDecoder.cpp
index e78da284402921bc09da0af0c9e11d02cbafb80a..cc947286a85c7c8f244f22721bc3ae48e2c6035c 100644
--- a/Framework/LiveData/src/Kafka/KafkaEventStreamDecoder.cpp
+++ b/Framework/LiveData/src/Kafka/KafkaEventStreamDecoder.cpp
@@ -133,7 +133,26 @@ KafkaEventStreamDecoder::KafkaEventStreamDecoder(
  * Destructor.
  * Stops capturing from the stream
  */
-KafkaEventStreamDecoder::~KafkaEventStreamDecoder() {}
+KafkaEventStreamDecoder::~KafkaEventStreamDecoder() {
+  /*
+   * IKafkaStreamDecoder::stopCapture is called again here as capture must be
+   * terminated before the KafkaEventStreamDecoder is destruced.
+   *
+   * Without this, a race condition occurs (over threads 1 and 2):
+   *  - KafkaEventStreamDecoder::~KafkaEventStreamDecoder is called and members
+   *    immediately destructed [1]
+   *  - IKafkaStreamDecoder::~IKafkaStreamDecoder is called [1]
+   *    - IKafkaStreamDecoder::m_interrupt set [on 1, visible to 2]
+   *    - Capture loop iteration completes and calls
+   *      KafkaEventStreamDecoder::flushIntermediateBuffer [2]
+   *      (this function attempts to access already deleted members of
+   *      KafkaEventStreamDecoder)
+   *
+   * By calling IKafkaStreamDecoder::stopCapture here it ensures that the
+   * capture has fully completed before local state is deleted.
+   */
+  stopCapture();
+}
 
 /**
  * Check if there is data available to extract
@@ -587,16 +606,10 @@ void KafkaEventStreamDecoder::initLocalCaches(
   }
 
   // Load the instrument if possible but continue if we can't
-  if (!instName.empty()) {
-    loadInstrument<DataObjects::EventWorkspace>(instName, eventBuffer,
-                                                jsonGeometry);
-    if (rawMsgBuffer.empty()) {
-      eventBuffer->rebuildSpectraMapping();
-    }
-  } else {
+  if (!loadInstrument<DataObjects::EventWorkspace>(instName, eventBuffer,
+                                                   jsonGeometry))
     g_log.warning(
-        "Empty instrument name received. Continuing without instrument");
-  }
+        "Instrument could not be loaded.Continuing without instrument");
 
   auto &mutableRun = eventBuffer->mutableRun();
   // Run start. Cache locally for computing frame times
@@ -616,11 +629,12 @@ void KafkaEventStreamDecoder::initLocalCaches(
       eventBuffer->getSpectrumToWorkspaceIndexVector(m_specToIdxOffset);
 
   // Buffers for each period
-  const size_t nperiods = runStartData.nPeriods;
+  size_t nperiods = runStartData.nPeriods;
   if (nperiods == 0) {
-    throw std::runtime_error(
-        "KafkaEventStreamDecoder - Message has n_periods==0. This is "
-        "an error by the data producer");
+    g_log.warning(
+        "KafkaEventStreamDecoder - Stream reports 0 periods. This is "
+        "an error by the data producer. Number of periods being set to 1.");
+    nperiods = 1;
   }
   {
     std::lock_guard<std::mutex> workspaceLock(m_mutex);
diff --git a/Framework/LiveData/src/Kafka/KafkaHistoStreamDecoder.cpp b/Framework/LiveData/src/Kafka/KafkaHistoStreamDecoder.cpp
index 5f2faf1cc3c81d079c0870a9e66aedc6eb6b2bbc..cb926855fd8c67ddc3eb7426a908cc3dbce3c628 100644
--- a/Framework/LiveData/src/Kafka/KafkaHistoStreamDecoder.cpp
+++ b/Framework/LiveData/src/Kafka/KafkaHistoStreamDecoder.cpp
@@ -224,6 +224,12 @@ void KafkaHistoStreamDecoder::initLocalCaches(
     histoBuffer->getAxis(0)->unit() =
         Kernel::UnitFactory::Instance().create("TOF");
     histoBuffer->setYUnit("Counts");
+
+    /* Need a mapping with spectra numbers starting at zero */
+    histoBuffer->rebuildSpectraMapping(true, 0);
+    histoBuffer->getAxis(0)->unit() =
+        Kernel::UnitFactory::Instance().create("TOF");
+    histoBuffer->setYUnit("Counts");
   } else {
     auto spDetMsg = GetSpectraDetectorMapping(
         reinterpret_cast<const uint8_t *>(rawMsgBuffer.c_str()));
@@ -245,15 +251,10 @@ void KafkaHistoStreamDecoder::initLocalCaches(
   }
 
   // Load the instrument if possible but continue if we can't
-  if (!instName.empty()) {
-    loadInstrument<DataObjects::Workspace2D>(instName, histoBuffer,
-                                             jsonGeometry);
-    if (rawMsgBuffer.empty()) {
-      histoBuffer->rebuildSpectraMapping();
-    }
-  } else
+  if (!loadInstrument<DataObjects::Workspace2D>(instName, histoBuffer,
+                                                jsonGeometry))
     g_log.warning(
-        "Empty instrument name received. Continuing without instrument");
+        "Instrument could not be loaded. Continuing without instrument");
 
   auto &mutableRun = histoBuffer->mutableRun();
   // Run start. Cache locally for computing frame times
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h
index 8e02f3ff53e98783a48e810c39260548bd904afc..45a1687ada2f33ff87e8cc5aab5fae9533c8f4f0 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h
@@ -51,21 +51,23 @@ struct IntegrationParameters {
 
  */
 
-using EventListMap =
-    std::unordered_map<int64_t,
-                       std::vector<std::pair<double, Mantid::Kernel::V3D>>>;
+using EventListMap = std::unordered_map<
+    int64_t,
+    std::vector<std::pair<std::pair<double, double>, Mantid::Kernel::V3D>>>;
 using PeakQMap = std::unordered_map<int64_t, Mantid::Kernel::V3D>;
 
 class DLLExport Integrate3DEvents {
 public:
   /// Construct object to store events around peaks and integrate peaks
   Integrate3DEvents(
-      const std::vector<std::pair<double, Mantid::Kernel::V3D>> &peak_q_list,
+      const std::vector<std::pair<std::pair<double, double>,
+                                  Mantid::Kernel::V3D>> &peak_q_list,
       Kernel::DblMatrix const &UBinv, double radius,
       const bool useOnePercentBackgroundCorrection = true);
 
   Integrate3DEvents(
-      const std::vector<std::pair<double, Mantid::Kernel::V3D>> &peak_q_list,
+      const std::vector<std::pair<std::pair<double, double>,
+                                  Mantid::Kernel::V3D>> &peak_q_list,
       std::vector<Mantid::Kernel::V3D> const &hkl_list,
       std::vector<Mantid::Kernel::V3D> const &mnp_list,
       Kernel::DblMatrix const &UBinv, Kernel::DblMatrix const &ModHKL,
@@ -73,9 +75,9 @@ public:
       const bool useOnePercentBackgroundCorrection = true);
 
   /// Add event Q's to lists of events near peaks
-  void
-  addEvents(std::vector<std::pair<double, Mantid::Kernel::V3D>> const &event_qs,
-            bool hkl_integ);
+  void addEvents(std::vector<std::pair<std::pair<double, double>,
+                                       Mantid::Kernel::V3D>> const &event_qs,
+                 bool hkl_integ);
 
   /// Find the net integrated intensity of a peak, using ellipsoidal volumes
   boost::shared_ptr<const Mantid::Geometry::PeakShape> ellipseIntegrateEvents(
@@ -114,7 +116,7 @@ public:
 
 private:
   /// Get a list of events for a given Q
-  const std::vector<std::pair<double, Mantid::Kernel::V3D>> *
+  const std::vector<std::pair<std::pair<double, double>, Mantid::Kernel::V3D>> *
   getEvents(const Mantid::Kernel::V3D &peak_q);
 
   bool correctForDetectorEdges(std::tuple<double, double, double> &radii,
@@ -125,21 +127,25 @@ private:
                                const std::vector<double> &bkgOuterRadii);
 
   /// Calculate the number of events in an ellipsoid centered at 0,0,0
-  static double numInEllipsoid(
-      std::vector<std::pair<double, Mantid::Kernel::V3D>> const &events,
-      std::vector<Mantid::Kernel::V3D> const &directions,
-      std::vector<double> const &sizes);
+  static std::pair<double, double>
+  numInEllipsoid(std::vector<std::pair<std::pair<double, double>,
+                                       Mantid::Kernel::V3D>> const &events,
+                 std::vector<Mantid::Kernel::V3D> const &directions,
+                 std::vector<double> const &sizes);
 
   /// Calculate the number of events in an ellipsoid centered at 0,0,0
-  static double numInEllipsoidBkg(
-      std::vector<std::pair<double, Mantid::Kernel::V3D>> const &events,
-      std::vector<Mantid::Kernel::V3D> const &directions,
-      std::vector<double> const &sizes, std::vector<double> const &sizesIn,
-      const bool useOnePercentBackgroundCorrection);
+  static std::pair<double, double>
+  numInEllipsoidBkg(std::vector<std::pair<std::pair<double, double>,
+                                          Mantid::Kernel::V3D>> const &events,
+                    std::vector<Mantid::Kernel::V3D> const &directions,
+                    std::vector<double> const &sizes,
+                    std::vector<double> const &sizesIn,
+                    const bool useOnePercentBackgroundCorrection);
 
   /// Calculate the 3x3 covariance matrix of a list of Q-vectors at 0,0,0
   static void makeCovarianceMatrix(
-      std::vector<std::pair<double, Mantid::Kernel::V3D>> const &events,
+      std::vector<std::pair<std::pair<double, double>,
+                            Mantid::Kernel::V3D>> const &events,
       Kernel::DblMatrix &matrix, double radius);
 
   /// Calculate the eigen vectors of a 3x3 real symmetric matrix
@@ -148,7 +154,8 @@ private:
 
   /// Calculate the standard deviation of 3D events in a specified direction
   static double
-  stdDev(std::vector<std::pair<double, Mantid::Kernel::V3D>> const &events,
+  stdDev(std::vector<std::pair<std::pair<double, double>,
+                               Mantid::Kernel::V3D>> const &events,
          Mantid::Kernel::V3D const &direction, double radius);
 
   /// Form a map key as 10^12*h + 10^6*k + l from the integers h, k, l
@@ -163,15 +170,19 @@ private:
   int64_t getHklMnpKey2(Mantid::Kernel::V3D const &hkl);
 
   /// Add an event to the vector of events for the closest h,k,l
-  void addEvent(std::pair<double, Mantid::Kernel::V3D> event_Q, bool hkl_integ);
-  void addModEvent(std::pair<double, Mantid::Kernel::V3D> event_Q,
-                   bool hkl_integ);
+  void
+  addEvent(std::pair<std::pair<double, double>, Mantid::Kernel::V3D> event_Q,
+           bool hkl_integ);
+  void
+  addModEvent(std::pair<std::pair<double, double>, Mantid::Kernel::V3D> event_Q,
+              bool hkl_integ);
 
   /// Find the net integrated intensity of a list of Q's using ellipsoids
   boost::shared_ptr<const Mantid::DataObjects::PeakShapeEllipsoid>
   ellipseIntegrateEvents(
       std::vector<Kernel::V3D> E1Vec, Kernel::V3D const &peak_q,
-      std::vector<std::pair<double, Mantid::Kernel::V3D>> const &ev_list,
+      std::vector<std::pair<std::pair<double, double>,
+                            Mantid::Kernel::V3D>> const &ev_list,
       std::vector<Mantid::Kernel::V3D> const &directions,
       std::vector<double> const &sigmas, bool specify_size, double peak_radius,
       double back_inner_radius, double back_outer_radius,
diff --git a/Framework/MDAlgorithms/src/AccumulateMD.cpp b/Framework/MDAlgorithms/src/AccumulateMD.cpp
index a631a4299fb5db51b00e608304d0456a4c895f76..84a76dcfcb80c874ae39399c1611c0feefb91f07 100644
--- a/Framework/MDAlgorithms/src/AccumulateMD.cpp
+++ b/Framework/MDAlgorithms/src/AccumulateMD.cpp
@@ -196,9 +196,9 @@ void insertDataSources(
   boost::split(data_split, data_sources, boost::is_any_of(","));
 
   // Trim any whitespace from ends of each data source string
-  std::for_each(
-      data_split.begin(), data_split.end(),
-      boost::bind(boost::algorithm::trim<std::string>, _1, std::locale()));
+  std::for_each(data_split.begin(), data_split.end(),
+                std::bind(boost::algorithm::trim<std::string>,
+                          std::placeholders::_1, std::locale()));
 
   // Insert each data source into our complete set of historical data sources
   historical_data_sources.insert(data_split.begin(), data_split.end());
diff --git a/Framework/MDAlgorithms/src/Integrate3DEvents.cpp b/Framework/MDAlgorithms/src/Integrate3DEvents.cpp
index 582b88eecac4332057ce4dc0a9f712f9d29a19f5..1313c9f7391c8b521afb1b9e8500ca2dbd9d659d 100644
--- a/Framework/MDAlgorithms/src/Integrate3DEvents.cpp
+++ b/Framework/MDAlgorithms/src/Integrate3DEvents.cpp
@@ -45,7 +45,8 @@ using Mantid::Kernel::V3D;
  *                       correction should be used.
  */
 Integrate3DEvents::Integrate3DEvents(
-    const std::vector<std::pair<double, Mantid::Kernel::V3D>> &peak_q_list,
+    const std::vector<std::pair<std::pair<double, double>, Mantid::Kernel::V3D>>
+        &peak_q_list,
     Kernel::DblMatrix const &UBinv, double radius,
     const bool useOnePercentBackgroundCorrection)
     : m_UBinv(UBinv), m_radius(radius), maxOrder(0), crossterm(0),
@@ -80,9 +81,9 @@ Integrate3DEvents::Integrate3DEvents(
  *                       correction should be used.
  */
 Integrate3DEvents::Integrate3DEvents(
-    const std::vector<std::pair<double, Mantid::Kernel::V3D>> &peak_q_list,
-    std::vector<Mantid::Kernel::V3D> const &hkl_list,
-    std::vector<Mantid::Kernel::V3D> const &mnp_list,
+    const std::vector<std::pair<std::pair<double, double>, Mantid::Kernel::V3D>>
+        &peak_q_list,
+    std::vector<V3D> const &hkl_list, std::vector<V3D> const &mnp_list,
     Kernel::DblMatrix const &UBinv, Kernel::DblMatrix const &ModHKL,
     double radius_m, double radius_s, int MaxO, const bool CrossT,
     const bool useOnePercentBackgroundCorrection)
@@ -120,7 +121,8 @@ Integrate3DEvents::Integrate3DEvents(
  * @param hkl_integ
  */
 void Integrate3DEvents::addEvents(
-    std::vector<std::pair<double, V3D>> const &event_qs, bool hkl_integ) {
+    std::vector<std::pair<std::pair<double, double>, V3D>> const &event_qs,
+    bool hkl_integ) {
   if (!maxOrder)
     for (const auto &event_q : event_qs)
       addEvent(event_q, hkl_integ);
@@ -199,17 +201,17 @@ Integrate3DEvents::integrateStrongPeak(const IntegrationParameters &params,
   const auto peak = numInEllipsoid(events, eigen_vectors, peakRadii);
   const auto ratio = pow(r1, 3) / (pow(r3, 3) - pow(r2, 3));
 
-  inti = peak - ratio * backgrd;
-  sigi = sqrt(peak + ratio * ratio * backgrd);
+  inti = peak.first - ratio * backgrd.first;
+  sigi = sqrt(peak.second + ratio * ratio * backgrd.second);
 
   // compute the fraction of peak within the standard core
-  const auto total = (core + peak) - ratio * backgrd;
+  const auto total = (core.first + peak.first) - ratio * backgrd.first;
   const auto frac = std::min(1.0, std::abs(inti / total));
   // compute the uncertainty in the fraction
-  const auto df_ds_core = (1 - frac) / peak;
-  const auto df_ds_peak = frac / peak;
+  const auto df_ds_core = (1 - frac) / peak.first;
+  const auto df_ds_peak = frac / peak.first;
   const auto fracError =
-      sqrt(peak * pow(df_ds_core, 2) + core * pow(df_ds_peak, 2));
+      sqrt(peak.first * pow(df_ds_core, 2) + core.first * pow(df_ds_peak, 2));
 
   // create the peaks shape for the strong peak
   const auto shape = boost::make_shared<const PeakShapeEllipsoid>(
@@ -254,16 +256,17 @@ Integrate3DEvents::integrateWeakPeak(
                r3 = std::get<2>(rValues);
 
   // integrate
-  double backgrd = numInEllipsoidBkg(
+  std::pair<double, double> backgrd = numInEllipsoidBkg(
       events, directions, abcBackgroundOuterRadii, abcBackgroundInnerRadii,
       m_useOnePercentBackgroundCorrection);
-  double peak_w_back = numInEllipsoid(events, directions, abcRadii);
+  std::pair<double, double> peak_w_back =
+      numInEllipsoid(events, directions, abcRadii);
   double ratio = pow(r1, 3) / (pow(r3, 3) - pow(r2, 3));
 
   const auto frac = std::get<0>(libPeak);
   const auto fracError = std::get<1>(libPeak);
 
-  inti = peak_w_back - ratio * backgrd;
+  inti = peak_w_back.first - ratio * backgrd.first;
 
   // correct for fractional intensity
   sigi = sigi / pow(inti, 2);
@@ -324,20 +327,21 @@ double Integrate3DEvents::estimateSignalToNoiseRatio(
   }
 
   // Background / Peak / Background
-  double backgrd = numInEllipsoidBkg(
+  std::pair<double, double> backgrd = numInEllipsoidBkg(
       events, eigen_vectors, abcBackgroundOuterRadii, abcBackgroundInnerRadii,
       m_useOnePercentBackgroundCorrection);
 
-  double peak_w_back = numInEllipsoid(events, eigen_vectors, peakRadii);
+  std::pair<double, double> peak_w_back =
+      numInEllipsoid(events, eigen_vectors, peakRadii);
 
   double ratio = pow(r1, 3) / (pow(r3, 3) - pow(r2, 3));
-  auto inti = peak_w_back - ratio * backgrd;
-  auto sigi = sqrt(peak_w_back + ratio * ratio * backgrd);
+  auto inti = peak_w_back.first - ratio * backgrd.first;
+  auto sigi = sqrt(peak_w_back.second + ratio * ratio * backgrd.second);
 
   return inti / sigi;
 }
 
-const std::vector<std::pair<double, V3D>> *
+const std::vector<std::pair<std::pair<double, double>, V3D>> *
 Integrate3DEvents::getEvents(const V3D &peak_q) {
   auto hkl_key = getHklKey(peak_q);
   if (maxOrder)
@@ -429,7 +433,7 @@ bool Integrate3DEvents::correctForDetectorEdges(
  */
 Mantid::Geometry::PeakShape_const_sptr
 Integrate3DEvents::ellipseIntegrateEvents(
-    std::vector<Kernel::V3D> E1Vec, V3D const &peak_q, bool specify_size,
+    std::vector<V3D> E1Vec, V3D const &peak_q, bool specify_size,
     double peak_radius, double back_inner_radius, double back_outer_radius,
     std::vector<double> &axes_radii, double &inti, double &sigi) {
   inti = 0.0; // default values, in case something
@@ -446,7 +450,8 @@ Integrate3DEvents::ellipseIntegrateEvents(
     return boost::make_shared<NoShape>();
   ;
 
-  std::vector<std::pair<double, V3D>> &some_events = pos->second;
+  std::vector<std::pair<std::pair<double, double>, V3D>> &some_events =
+      pos->second;
 
   if (some_events.size() < 3) // if there are not enough events to
   {                           // find covariance matrix, return
@@ -482,10 +487,10 @@ Integrate3DEvents::ellipseIntegrateEvents(
 
 Mantid::Geometry::PeakShape_const_sptr
 Integrate3DEvents::ellipseIntegrateModEvents(
-    std::vector<Kernel::V3D> E1Vec, V3D const &peak_q, V3D const &hkl,
-    V3D const &mnp, bool specify_size, double peak_radius,
-    double back_inner_radius, double back_outer_radius,
-    std::vector<double> &axes_radii, double &inti, double &sigi) {
+    std::vector<V3D> E1Vec, V3D const &peak_q, V3D const &hkl, V3D const &mnp,
+    bool specify_size, double peak_radius, double back_inner_radius,
+    double back_outer_radius, std::vector<double> &axes_radii, double &inti,
+    double &sigi) {
   inti = 0.0; // default values, in case something
   sigi = 0.0; // is wrong with the peak.
 
@@ -503,7 +508,8 @@ Integrate3DEvents::ellipseIntegrateModEvents(
     return boost::make_shared<NoShape>();
   ;
 
-  std::vector<std::pair<double, V3D>> &some_events = pos->second;
+  std::vector<std::pair<std::pair<double, double>, V3D>> &some_events =
+      pos->second;
 
   if (some_events.size() < 3) // if there are not enough events to
   {                           // find covariance matrix, return
@@ -551,18 +557,21 @@ Integrate3DEvents::ellipseIntegrateModEvents(
  *                     of the three axes of the ellisoid.
  * @return Then number of events that are in or on the specified ellipsoid.
  */
-double Integrate3DEvents::numInEllipsoid(
-    std::vector<std::pair<double, V3D>> const &events,
+std::pair<double, double> Integrate3DEvents::numInEllipsoid(
+    std::vector<std::pair<std::pair<double, double>, V3D>> const &events,
     std::vector<V3D> const &directions, std::vector<double> const &sizes) {
-  double count = 0;
+
+  std::pair<double, double> count(0, 0);
   for (const auto &event : events) {
     double sum = 0;
     for (size_t k = 0; k < 3; k++) {
       double comp = event.second.scalar_prod(directions[k]) / sizes[k];
       sum += comp * comp;
     }
-    if (sum <= 1)
-      count += event.first;
+    if (sum <= 1) {
+      count.first += event.first.first;   // count
+      count.second += event.first.second; // error squared (add in quadrature)
+    }
   }
 
   return count;
@@ -584,13 +593,13 @@ double Integrate3DEvents::numInEllipsoid(
  correction should be used.
  * @return Then number of events that are in or on the specified ellipsoid.
  */
-double Integrate3DEvents::numInEllipsoidBkg(
-    std::vector<std::pair<double, V3D>> const &events,
+std::pair<double, double> Integrate3DEvents::numInEllipsoidBkg(
+    std::vector<std::pair<std::pair<double, double>, V3D>> const &events,
     std::vector<V3D> const &directions, std::vector<double> const &sizes,
     std::vector<double> const &sizesIn,
     const bool useOnePercentBackgroundCorrection) {
-  double count = 0;
-  std::vector<double> eventVec;
+  std::pair<double, double> count(0, 0);
+  std::vector<std::pair<double, double>> eventVec;
   for (const auto &event : events) {
     double sum = 0;
     double sumIn = 0;
@@ -607,12 +616,16 @@ double Integrate3DEvents::numInEllipsoidBkg(
   auto endIndex = eventVec.size();
   if (useOnePercentBackgroundCorrection) {
     // Remove top 1% of background
-    std::sort(eventVec.begin(), eventVec.end());
+    std::sort(
+        eventVec.begin(), eventVec.end(),
+        [](const std::pair<double, double> &a,
+           const std::pair<double, double> &b) { return a.first < b.first; });
     endIndex = static_cast<size_t>(0.99 * static_cast<double>(endIndex));
   }
 
   for (size_t k = 0; k < endIndex; ++k) {
-    count += eventVec[k];
+    count.first += eventVec[k].first;
+    count.second += eventVec[k].second;
   }
 
   return count;
@@ -646,8 +659,8 @@ double Integrate3DEvents::numInEllipsoidBkg(
  */
 
 void Integrate3DEvents::makeCovarianceMatrix(
-    std::vector<std::pair<double, V3D>> const &events, DblMatrix &matrix,
-    double radius) {
+    std::vector<std::pair<std::pair<double, double>, V3D>> const &events,
+    DblMatrix &matrix, double radius) {
   for (int row = 0; row < 3; row++) {
     for (int col = 0; col < 3; col++) {
       double sum = 0;
@@ -713,9 +726,9 @@ void Integrate3DEvents::getEigenVectors(DblMatrix const &cov_matrix,
  *  @param  radius      Maximun size of event vectors that will be used
  *                      in calculating the standard deviation.
  */
-double
-Integrate3DEvents::stdDev(std::vector<std::pair<double, V3D>> const &events,
-                          V3D const &direction, double radius) {
+double Integrate3DEvents::stdDev(
+    std::vector<std::pair<std::pair<double, double>, V3D>> const &events,
+    V3D const &direction, double radius) {
   double sum = 0;
   double sum_sq = 0;
   double stdev = 0;
@@ -1004,8 +1017,8 @@ int64_t Integrate3DEvents::getHklMnpKey(V3D const &q_vector) {
  *                     event_lists map, if it is close enough to some peak
  * @param hkl_integ
  */
-void Integrate3DEvents::addEvent(std::pair<double, V3D> event_Q,
-                                 bool hkl_integ) {
+void Integrate3DEvents::addEvent(
+    std::pair<std::pair<double, double>, V3D> event_Q, bool hkl_integ) {
   int64_t hkl_key;
   if (hkl_integ)
     hkl_key = getHklKey2(event_Q.second);
@@ -1043,8 +1056,8 @@ void Integrate3DEvents::addEvent(std::pair<double, V3D> event_Q,
  *                     event_lists map, if it is close enough to some peak
  * @param hkl_integ
  */
-void Integrate3DEvents::addModEvent(std::pair<double, V3D> event_Q,
-                                    bool hkl_integ) {
+void Integrate3DEvents::addModEvent(
+    std::pair<std::pair<double, double>, V3D> event_Q, bool hkl_integ) {
   int64_t hklmnp_key;
 
   if (hkl_integ)
@@ -1111,12 +1124,13 @@ void Integrate3DEvents::addModEvent(std::pair<double, V3D> event_Q,
  *
  */
 PeakShapeEllipsoid_const_sptr Integrate3DEvents::ellipseIntegrateEvents(
-    std::vector<Kernel::V3D> E1Vec, V3D const &peak_q,
-    std::vector<std::pair<double, Mantid::Kernel::V3D>> const &ev_list,
-    std::vector<Mantid::Kernel::V3D> const &directions,
-    std::vector<double> const &sigmas, bool specify_size, double peak_radius,
-    double back_inner_radius, double back_outer_radius,
-    std::vector<double> &axes_radii, double &inti, double &sigi) {
+    std::vector<V3D> E1Vec, V3D const &peak_q,
+    std::vector<std::pair<std::pair<double, double>, Mantid::Kernel::V3D>> const
+        &ev_list,
+    std::vector<V3D> const &directions, std::vector<double> const &sigmas,
+    bool specify_size, double peak_radius, double back_inner_radius,
+    double back_outer_radius, std::vector<double> &axes_radii, double &inti,
+    double &sigi) {
   // r1, r2 and r3 will give the sizes of the major axis of
   // the peak ellipsoid, and of the inner and outer surface
   // of the background ellipsoidal shell, respectively.
@@ -1187,16 +1201,17 @@ PeakShapeEllipsoid_const_sptr Integrate3DEvents::ellipseIntegrateEvents(
     }
   }
 
-  double backgrd = numInEllipsoidBkg(
+  std::pair<double, double> backgrd = numInEllipsoidBkg(
       ev_list, directions, abcBackgroundOuterRadii, abcBackgroundInnerRadii,
       m_useOnePercentBackgroundCorrection);
 
-  double peak_w_back = numInEllipsoid(ev_list, directions, axes_radii);
+  std::pair<double, double> peak_w_back =
+      numInEllipsoid(ev_list, directions, axes_radii);
 
   double ratio = pow(r1, 3) / (pow(r3, 3) - pow(r2, 3));
 
-  inti = peak_w_back - ratio * backgrd;
-  sigi = sqrt(peak_w_back + ratio * ratio * backgrd);
+  inti = peak_w_back.first - ratio * backgrd.first;
+  sigi = sqrt(peak_w_back.second + ratio * ratio * backgrd.second);
 
   // Make the shape and return it.
   return boost::make_shared<const PeakShapeEllipsoid>(
@@ -1214,8 +1229,7 @@ PeakShapeEllipsoid_const_sptr Integrate3DEvents::ellipseIntegrateEvents(
  * @param QLabFrame: The Peak center.
  * @param r: Peak radius.
  */
-double Integrate3DEvents::detectorQ(std::vector<Kernel::V3D> E1Vec,
-                                    const Mantid::Kernel::V3D QLabFrame,
+double Integrate3DEvents::detectorQ(std::vector<V3D> E1Vec, const V3D QLabFrame,
                                     const std::vector<double> &r) {
   double quot = 1.0;
   for (auto &E1 : E1Vec) {
diff --git a/Framework/MDAlgorithms/src/IntegrateEllipsoids.cpp b/Framework/MDAlgorithms/src/IntegrateEllipsoids.cpp
index e085ec8cb58680b1c9d5344d13f9d008ec773e5b..ed049f7dac573fc625664926908cc37362829daf 100644
--- a/Framework/MDAlgorithms/src/IntegrateEllipsoids.cpp
+++ b/Framework/MDAlgorithms/src/IntegrateEllipsoids.cpp
@@ -101,7 +101,7 @@ void IntegrateEllipsoids::qListFromEventWS(Integrate3DEvents &integrator,
     double errorSq(1.); // ignorable garbage
     const std::vector<WeightedEventNoTime> &raw_events =
         events.getWeightedEventsNoTime();
-    std::vector<std::pair<double, V3D>> qList;
+    std::vector<std::pair<std::pair<double, double>, V3D>> qList;
     for (const auto &raw_event : raw_events) {
       double val = unitConverter.convertUnits(raw_event.tof());
       qConverter.calcMatrixCoord(val, locCoord, signal, errorSq);
@@ -111,7 +111,9 @@ void IntegrateEllipsoids::qListFromEventWS(Integrate3DEvents &integrator,
       V3D qVec(buffer[0], buffer[1], buffer[2]);
       if (hkl_integ)
         qVec = UBinv * qVec;
-      qList.emplace_back(raw_event.m_weight, qVec);
+      qList.emplace_back(std::pair<double, double>(raw_event.m_weight,
+                                                   raw_event.m_errorSquared),
+                         qVec);
     } // end of loop over events in list
     PARALLEL_CRITICAL(addEvents) { integrator.addEvents(qList, hkl_integ); }
 
@@ -155,6 +157,7 @@ void IntegrateEllipsoids::qListFromHistoWS(Integrate3DEvents &integrator,
     // get tof and y values
     const auto &xVals = wksp->points(i);
     const auto &yVals = wksp->y(i);
+    const auto &eVals = wksp->e(i);
 
     // update which pixel is being converted
     std::vector<Mantid::coord_t> locCoord(DIMS, 0.);
@@ -165,10 +168,11 @@ void IntegrateEllipsoids::qListFromHistoWS(Integrate3DEvents &integrator,
     double signal(1.);  // ignorable garbage
     double errorSq(1.); // ignorable garbage
 
-    std::vector<std::pair<double, V3D>> qList;
+    std::vector<std::pair<std::pair<double, double>, V3D>> qList;
 
     for (size_t j = 0; j < yVals.size(); ++j) {
       const double &yVal = yVals[j];
+      const double &esqVal = eVals[j] * eVals[j]; // error squared (variance)
       if (yVal > 0) // TODO, is this condition right?
       {
         double val = unitConverter.convertUnits(xVals[j]);
@@ -186,7 +190,7 @@ void IntegrateEllipsoids::qListFromHistoWS(Integrate3DEvents &integrator,
           continue;
         // Account for counts in histograms by increasing the qList with the
         // same q-point
-        qList.emplace_back(yVal, qVec);
+        qList.emplace_back(std::pair<double, double>(yVal, esqVal), qVec);
       }
     }
     PARALLEL_CRITICAL(addHisto) { integrator.addEvents(qList, hkl_integ); }
@@ -384,7 +388,7 @@ void IntegrateEllipsoids::exec() {
   size_t n_peaks = peak_ws->getNumberPeaks();
   size_t indexed_count = 0;
   std::vector<V3D> peak_q_list;
-  std::vector<std::pair<double, V3D>> qList;
+  std::vector<std::pair<std::pair<double, double>, V3D>> qList;
   std::vector<V3D> hkl_vectors;
   std::vector<V3D> mnp_vectors;
   int ModDim = 0;
@@ -403,7 +407,8 @@ void IntegrateEllipsoids::exec() {
     // use tolerance == 1 to just check for (0,0,0,0,0,0)
     if (Geometry::IndexingUtils::ValidIndex(hkl, 1.0)) {
       peak_q_list.emplace_back(peaks[i].getQLabFrame());
-      qList.emplace_back(1., V3D(peaks[i].getQLabFrame()));
+      qList.emplace_back(std::pair<double, double>(1., 1.),
+                         V3D(peaks[i].getQLabFrame()));
       hkl_vectors.emplace_back(hkl);
       mnp_vectors.emplace_back(mnp);
       indexed_count++;
diff --git a/Framework/MDAlgorithms/src/IntegrateEllipsoidsTwoStep.cpp b/Framework/MDAlgorithms/src/IntegrateEllipsoidsTwoStep.cpp
index 6926b137fc3de5be6ae12b678ef4710bf8e9b54f..88fcf9b563fb2bdfc5f7ca2e1c27f474fb5f21b1 100644
--- a/Framework/MDAlgorithms/src/IntegrateEllipsoidsTwoStep.cpp
+++ b/Framework/MDAlgorithms/src/IntegrateEllipsoidsTwoStep.cpp
@@ -183,9 +183,10 @@ void IntegrateEllipsoidsTwoStep::exec() {
   UBinv.Invert();
   UBinv *= (1.0 / (2.0 * M_PI));
 
-  std::vector<std::pair<double, V3D>> qList;
+  std::vector<std::pair<std::pair<double, double>, V3D>> qList;
   for (size_t i = 0; i < n_peaks; i++) {
-    qList.emplace_back(1., V3D(peaks[i].getQLabFrame()));
+    qList.emplace_back(std::pair<double, double>(1.0, 1.0),
+                       V3D(peaks[i].getQLabFrame()));
   }
 
   const bool integrateEdge = getProperty("IntegrateIfOnEdge");
@@ -410,7 +411,7 @@ void IntegrateEllipsoidsTwoStep::qListFromEventWS(Integrate3DEvents &integrator,
     double errorSq(1.); // ignorable garbage
     const std::vector<WeightedEventNoTime> &raw_events =
         events.getWeightedEventsNoTime();
-    std::vector<std::pair<double, V3D>> qList;
+    std::vector<std::pair<std::pair<double, double>, V3D>> qList;
     for (const auto &raw_event : raw_events) {
       double val = unitConverter.convertUnits(raw_event.tof());
       qConverter.calcMatrixCoord(val, locCoord, signal, errorSq);
@@ -420,7 +421,9 @@ void IntegrateEllipsoidsTwoStep::qListFromEventWS(Integrate3DEvents &integrator,
       V3D qVec(buffer[0], buffer[1], buffer[2]);
       if (hkl_integ)
         qVec = UBinv * qVec;
-      qList.emplace_back(raw_event.m_weight, qVec);
+      qList.emplace_back(std::pair<double, double>(raw_event.m_weight,
+                                                   raw_event.m_errorSquared),
+                         qVec);
     } // end of loop over events in list
     PARALLEL_CRITICAL(addEvents) { integrator.addEvents(qList, hkl_integ); }
 
@@ -488,6 +491,7 @@ void IntegrateEllipsoidsTwoStep::qListFromHistoWS(Integrate3DEvents &integrator,
     // get tof and y values
     const auto &xVals = wksp->points(i);
     const auto &yVals = wksp->y(i);
+    const auto &eVals = wksp->e(i);
 
     // update which pixel is being converted
     std::vector<Mantid::coord_t> locCoord(DIMS, 0.);
@@ -498,10 +502,11 @@ void IntegrateEllipsoidsTwoStep::qListFromHistoWS(Integrate3DEvents &integrator,
     double signal(1.);  // ignorable garbage
     double errorSq(1.); // ignorable garbage
 
-    std::vector<std::pair<double, V3D>> qList;
+    std::vector<std::pair<std::pair<double, double>, V3D>> qList;
 
     for (size_t j = 0; j < yVals.size(); ++j) {
       const double &yVal = yVals[j];
+      const double &esqVal = eVals[j] * eVals[j]; // error squared (variance)
       if (yVal > 0) // TODO, is this condition right?
       {
         double val = unitConverter.convertUnits(xVals[j]);
@@ -514,7 +519,7 @@ void IntegrateEllipsoidsTwoStep::qListFromHistoWS(Integrate3DEvents &integrator,
           continue;
         // Account for counts in histograms by increasing the qList with the
         // same q-point
-        qList.emplace_back(yVal, qVec);
+        qList.emplace_back(std::pair<double, double>(yVal, esqVal), qVec);
       }
     }
     PARALLEL_CRITICAL(addHisto) { integrator.addEvents(qList, hkl_integ); }
diff --git a/Framework/MDAlgorithms/src/MDNorm.cpp b/Framework/MDAlgorithms/src/MDNorm.cpp
index 8522a1c76b7d86d7ac9c78e248287ff4f3107d42..44e17c6971223581b36f3eba4ad4f655be04f2cc 100644
--- a/Framework/MDAlgorithms/src/MDNorm.cpp
+++ b/Framework/MDAlgorithms/src/MDNorm.cpp
@@ -652,10 +652,10 @@ std::map<std::string, std::string> MDNorm::getBinParameters() {
       for (size_t j = 0; j < originalDimensionNames.size(); j++) {
         if (j == static_cast<size_t>(dimIndex)) {
           propertyValue << ",1";
-          transformation.emplace_back(1.);
+          transformation.emplace_back(1.f);
         } else {
           propertyValue << ",0";
-          transformation.emplace_back(0.);
+          transformation.emplace_back(0.f);
         }
       }
       parameters.emplace(property, propertyValue.str());
diff --git a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp
index 48121788de18a066d3ddff530b7610ee09534066..6d589fc3c09784cae697dcc236221c96b18993cb 100644
--- a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp
+++ b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp
@@ -531,7 +531,7 @@ for (int64_t i = 0; i < ndets; i++) {
   // pre-allocate for efficiency and copy non-hkl dim values into place
   pos.resize(vmdDims + otherValues.size() + 1);
   std::copy(otherValues.begin(), otherValues.end(), pos.begin() + vmdDims);
-  pos.emplace_back(1.);
+  pos.emplace_back(1.f);
   auto intersectionsBegin = intersections.begin();
   for (auto it = intersectionsBegin + 1; it != intersections.end(); ++it) {
     const auto &curIntSec = *it;
diff --git a/Framework/MDAlgorithms/src/MDNormSCD.cpp b/Framework/MDAlgorithms/src/MDNormSCD.cpp
index 5f31243d10a167bc4123deabc470d6475fd7bfdb..6472c722160e7f5e2d513d00ec4cda1b1adcfc45 100644
--- a/Framework/MDAlgorithms/src/MDNormSCD.cpp
+++ b/Framework/MDAlgorithms/src/MDNormSCD.cpp
@@ -495,7 +495,7 @@ for (int64_t i = 0; i < ndets; i++) {
   // pre-allocate for efficiency and copy non-hkl dim values into place
   pos.resize(vmdDims + otherValues.size());
   std::copy(otherValues.begin(), otherValues.end(), pos.begin() + vmdDims - 1);
-  pos.emplace_back(1.);
+  pos.emplace_back(1.f);
 
   for (auto it = intersectionsBegin + 1; it != intersections.end(); ++it) {
     const auto &curIntSec = *it;
diff --git a/Framework/MDAlgorithms/src/MDTransfQ3D.cpp b/Framework/MDAlgorithms/src/MDTransfQ3D.cpp
index 521b7b57eb1a967f39d34f7998eb20af1d5296a6..124fb981074c5a5cd3b2419547f0231b831c3562 100644
--- a/Framework/MDAlgorithms/src/MDTransfQ3D.cpp
+++ b/Framework/MDAlgorithms/src/MDTransfQ3D.cpp
@@ -152,26 +152,22 @@ bool MDTransfQ3D::calcMatrixCoord3DElastic(const double &k0,
 
   // Dimension limits have to be converted to coord_t, otherwise floating point
   // error will cause valid events to be discarded.
-  std::vector<coord_t> dim_min;
-  dim_min.reserve(m_DimMin.size());
-  std::copy(m_DimMin.cbegin(), m_DimMin.cend(), std::back_inserter(dim_min));
-  std::vector<coord_t> dim_max;
-  dim_max.reserve(m_DimMax.size());
-  std::copy(m_DimMax.cbegin(), m_DimMax.cend(), std::back_inserter(dim_max));
-
   Coord[0] = static_cast<coord_t>(m_RotMat[0] * qx + m_RotMat[1] * qy +
                                   m_RotMat[2] * qz);
-  if (Coord[0] < dim_min[0] || Coord[0] >= dim_max[0])
+  if (Coord[0] < static_cast<coord_t>(m_DimMin[0]) ||
+      Coord[0] >= static_cast<coord_t>(m_DimMax[0]))
     return false;
 
   Coord[1] = static_cast<coord_t>(m_RotMat[3] * qx + m_RotMat[4] * qy +
                                   m_RotMat[5] * qz);
-  if (Coord[1] < dim_min[1] || Coord[1] >= dim_max[1])
+  if (Coord[1] < static_cast<coord_t>(m_DimMin[1]) ||
+      Coord[1] >= static_cast<coord_t>(m_DimMax[1]))
     return false;
 
   Coord[2] = static_cast<coord_t>(m_RotMat[6] * qx + m_RotMat[7] * qy +
                                   m_RotMat[8] * qz);
-  if (Coord[2] < dim_min[2] || Coord[2] >= dim_max[2])
+  if (Coord[2] < static_cast<coord_t>(m_DimMin[2]) ||
+      Coord[2] >= static_cast<coord_t>(m_DimMax[2]))
     return false;
 
   if (std::sqrt(Coord[0] * Coord[0] + Coord[1] * Coord[1] +
diff --git a/Framework/MDAlgorithms/src/SmoothMD.cpp b/Framework/MDAlgorithms/src/SmoothMD.cpp
index 5fcd208b7eb1d66a74a061df4338deb2f8a73fee..f31fc9b04f891d3bf311500b824666471a38bc78 100644
--- a/Framework/MDAlgorithms/src/SmoothMD.cpp
+++ b/Framework/MDAlgorithms/src/SmoothMD.cpp
@@ -17,8 +17,6 @@
 #include "MantidKernel/MandatoryValidator.h"
 #include "MantidKernel/MultiThreaded.h"
 #include "MantidKernel/PropertyWithValue.h"
-#include <boost/bind.hpp>
-#include <boost/function.hpp>
 #include <boost/make_shared.hpp>
 #include <boost/tuple/tuple.hpp>
 #include <limits>
@@ -45,7 +43,7 @@ using OptionalIMDHistoWorkspace_const_sptr =
     boost::optional<IMDHistoWorkspace_const_sptr>;
 
 // Typedef for a smoothing function
-using SmoothFunction = boost::function<IMDHistoWorkspace_sptr(
+using SmoothFunction = std::function<IMDHistoWorkspace_sptr(
     IMDHistoWorkspace_const_sptr, const WidthVector &,
     OptionalIMDHistoWorkspace_const_sptr)>;
 
@@ -59,11 +57,12 @@ namespace {
  * @return function map
  */
 SmoothFunctionMap makeFunctionMap(Mantid::MDAlgorithms::SmoothMD *instance) {
+  using namespace std::placeholders;
   return {
-      {"Hat", boost::bind(&Mantid::MDAlgorithms::SmoothMD::hatSmooth, instance,
-                          _1, _2, _3)},
-      {"Gaussian", boost::bind(&Mantid::MDAlgorithms::SmoothMD::gaussianSmooth,
-                               instance, _1, _2, _3)}};
+      {"Hat", std::bind(&Mantid::MDAlgorithms::SmoothMD::hatSmooth, instance,
+                        _1, _2, _3)},
+      {"Gaussian", std::bind(&Mantid::MDAlgorithms::SmoothMD::gaussianSmooth,
+                             instance, _1, _2, _3)}};
 }
 } // namespace
 
@@ -227,9 +226,10 @@ SmoothMD::hatSmooth(IMDHistoWorkspace_const_sptr toSmooth,
       // We've already checked in the validator that the doubles we have are odd
       // integer values and well below max int
       std::vector<int> widthVectorInt;
-      widthVectorInt.reserve(widthVector.size());
-      std::copy(widthVector.cbegin(), widthVector.cend(),
-                std::back_inserter(widthVectorInt));
+      widthVectorInt.resize(widthVector.size());
+      std::transform(widthVector.cbegin(), widthVector.cend(),
+                     widthVectorInt.begin(),
+                     [](double w) -> int { return static_cast<int>(w); });
 
       std::vector<size_t> neighbourIndexes =
           iterator->findNeighbourIndexesByWidth(widthVectorInt);
diff --git a/Framework/MDAlgorithms/src/ThresholdMD.cpp b/Framework/MDAlgorithms/src/ThresholdMD.cpp
index 00584f9711b84b0b476a8d79677cdbec10b49fe3..79dae015e69b07575917e189309beb835d83b76a 100644
--- a/Framework/MDAlgorithms/src/ThresholdMD.cpp
+++ b/Framework/MDAlgorithms/src/ThresholdMD.cpp
@@ -11,7 +11,6 @@
 #include "MantidKernel/EnabledWhenProperty.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/MultiThreaded.h"
-#include <boost/bind.hpp>
 #include <boost/function.hpp>
 
 using namespace Mantid::Kernel;
@@ -104,10 +103,11 @@ void ThresholdMD::exec() {
 
   const int64_t nPoints = inputWS->getNPoints();
 
+  using namespace std::placeholders;
   boost::function<bool(double)> comparitor =
-      boost::bind(std::less<double>(), _1, referenceValue);
+      std::bind(std::less<double>(), _1, referenceValue);
   if (condition == GreaterThan()) {
-    comparitor = boost::bind(std::greater<double>(), _1, referenceValue);
+    comparitor = std::bind(std::greater<double>(), _1, referenceValue);
   }
 
   Progress prog(this, 0.0, 1.0, 100);
diff --git a/Framework/MDAlgorithms/test/Integrate3DEventsTest.h b/Framework/MDAlgorithms/test/Integrate3DEventsTest.h
index d74188d3dc3432dba901bf7d83f5ff6da70ba902..ae945d3fb497c83aecff1d60b2d98ec12d5e592b 100644
--- a/Framework/MDAlgorithms/test/Integrate3DEventsTest.h
+++ b/Framework/MDAlgorithms/test/Integrate3DEventsTest.h
@@ -27,7 +27,7 @@ public:
   // expected integration results are obtained using either fixed size
   // ellipsoids, or using ellipsoids with axis half-lengths set to
   // three standard deviations.
-  void test_1() {
+  void test_integrateMainPeaksWithFixedRadiiandDefaultScaledRadii() {
     double inti_all[] = {755, 704, 603};
     double sigi_all[] = {27.4773, 26.533, 24.5561};
 
@@ -39,8 +39,10 @@ public:
     V3D peak_1(10, 0, 0);
     V3D peak_2(0, 5, 0);
     V3D peak_3(0, 0, 4);
-    std::vector<std::pair<double, V3D>> peak_q_list{
-        {1., peak_1}, {1., peak_2}, {1., peak_3}};
+    std::vector<std::pair<std::pair<double, double>, V3D>> peak_q_list{
+        {std::make_pair(1., 1.), peak_1},
+        {std::make_pair(1., 1.), peak_2},
+        {std::make_pair(1., 1.), peak_3}};
 
     // synthesize a UB-inverse to map
     DblMatrix UBinv(3, 3, false); // Q to h,k,l
@@ -54,40 +56,40 @@ public:
     // around peak 1, 704 events around
     // peak 2, and 603 events around
     // peak 3.
-    std::vector<std::pair<double, V3D>> event_Qs;
+    std::vector<std::pair<std::pair<double, double>, V3D>> event_Qs;
     for (int i = -100; i <= 100; i++) {
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_1 + V3D((double)i / 100.0, 0, 0))));
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_2 + V3D((double)i / 100.0, 0, 0))));
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_3 + V3D((double)i / 100.0, 0, 0))));
-
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_1 + V3D(0, (double)i / 200.0, 0))));
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_2 + V3D(0, (double)i / 200.0, 0))));
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_3 + V3D(0, (double)i / 200.0, 0))));
-
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_1 + V3D(0, 0, (double)i / 300.0))));
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_2 + V3D(0, 0, (double)i / 300.0))));
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_3 + V3D(0, 0, (double)i / 300.0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(2., 1.), V3D(peak_1 + V3D((double)i / 100.0, 0, 0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(2., 1.), V3D(peak_2 + V3D((double)i / 100.0, 0, 0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(2., 1.), V3D(peak_3 + V3D((double)i / 100.0, 0, 0))));
+
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(2., 1.), V3D(peak_1 + V3D(0, (double)i / 200.0, 0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(2., 1.), V3D(peak_2 + V3D(0, (double)i / 200.0, 0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(2., 1.), V3D(peak_3 + V3D(0, (double)i / 200.0, 0))));
+
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(2., 1.), V3D(peak_1 + V3D(0, 0, (double)i / 300.0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(2., 1.), V3D(peak_2 + V3D(0, 0, (double)i / 300.0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(2., 1.), V3D(peak_3 + V3D(0, 0, (double)i / 300.0))));
     }
 
     for (int i = -50; i <= 50; i++) {
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_1 + V3D(0, (double)i / 147.0, 0))));
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_2 + V3D(0, (double)i / 147.0, 0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(2., 1.), V3D(peak_1 + V3D(0, (double)i / 147.0, 0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(2., 1.), V3D(peak_2 + V3D(0, (double)i / 147.0, 0))));
     }
 
     for (int i = -25; i <= 25; i++) {
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_1 + V3D(0, 0, (double)i / 61.0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(2., 1.), V3D(peak_1 + V3D(0, 0, (double)i / 61.0))));
     }
 
     double radius = 1.3;
@@ -109,7 +111,7 @@ public:
       auto shape = integrator.ellipseIntegrateEvents(
           E1Vec, peak_q_list[i].second, specify_size, peak_radius,
           back_inner_radius, back_outer_radius, new_sigma, inti, sigi);
-      TS_ASSERT_DELTA(inti, inti_all[i], 0.1);
+      TS_ASSERT_DELTA(inti, 2 * inti_all[i], 0.1);
       TS_ASSERT_DELTA(sigi, sigi_all[i], 0.01);
 
       auto ellipsoid_shape = boost::dynamic_pointer_cast<
@@ -125,7 +127,7 @@ public:
       integrator.ellipseIntegrateEvents(
           E1Vec, peak_q_list[i].second, specify_size, peak_radius,
           back_inner_radius, back_outer_radius, new_sigma, inti, sigi);
-      TS_ASSERT_DELTA(inti, inti_some[i], 0.1);
+      TS_ASSERT_DELTA(inti, 2 * inti_some[i], 0.1);
       TS_ASSERT_DELTA(sigi, sigi_some[i], 0.01);
     }
   }
@@ -142,8 +144,10 @@ public:
     V3D peak_1(6, 0, 0);
     V3D peak_2(0, 5, 0);
     V3D peak_3(0, 0, 4);
-    std::vector<std::pair<double, V3D>> peak_q_list{
-        {1., peak_1}, {1., peak_2}, {1., peak_3}};
+    std::vector<std::pair<std::pair<double, double>, V3D>> peak_q_list{
+        {std::make_pair(1., 1.), peak_1},
+        {std::make_pair(1., 1.), peak_2},
+        {std::make_pair(1., 1.), peak_3}};
 
     // synthesize a UB-inverse to map
     DblMatrix UBinv(3, 3, false); // Q to h,k,l
@@ -167,40 +171,40 @@ public:
     // around peak 1, 704 events around
     // peak 2, and 603 events around
     // peak 3.
-    std::vector<std::pair<double, V3D>> event_Qs;
+    std::vector<std::pair<std::pair<double, double>, V3D>> event_Qs;
     for (int i = -100; i <= 100; i++) {
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_1 + V3D((double)i / 100.0, 0, 0))));
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_2 + V3D((double)i / 100.0, 0, 0))));
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_3 + V3D((double)i / 100.0, 0, 0))));
-
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_1 + V3D(0, (double)i / 200.0, 0))));
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_2 + V3D(0, (double)i / 200.0, 0))));
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_3 + V3D(0, (double)i / 200.0, 0))));
-
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_1 + V3D(0, 0, (double)i / 300.0))));
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_2 + V3D(0, 0, (double)i / 300.0))));
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_3 + V3D(0, 0, (double)i / 300.0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(1., 1.), V3D(peak_1 + V3D((double)i / 100.0, 0, 0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(1., 1.), V3D(peak_2 + V3D((double)i / 100.0, 0, 0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(1., 1.), V3D(peak_3 + V3D((double)i / 100.0, 0, 0))));
+
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(1., 1.), V3D(peak_1 + V3D(0, (double)i / 200.0, 0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(1., 1.), V3D(peak_2 + V3D(0, (double)i / 200.0, 0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(1., 1.), V3D(peak_3 + V3D(0, (double)i / 200.0, 0))));
+
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(1., 1.), V3D(peak_1 + V3D(0, 0, (double)i / 300.0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(1., 1.), V3D(peak_2 + V3D(0, 0, (double)i / 300.0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(1., 1.), V3D(peak_3 + V3D(0, 0, (double)i / 300.0))));
     }
 
     for (int i = -50; i <= 50; i++) {
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_1 + V3D(0, (double)i / 147.0, 0))));
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_2 + V3D(0, (double)i / 147.0, 0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(1., 1.), V3D(peak_1 + V3D(0, (double)i / 147.0, 0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(1., 1.), V3D(peak_2 + V3D(0, (double)i / 147.0, 0))));
     }
 
     for (int i = -25; i <= 25; i++) {
-      event_Qs.emplace_back(
-          std::make_pair(1., V3D(peak_1 + V3D(0, 0, (double)i / 61.0))));
+      event_Qs.emplace_back(std::make_pair(
+          std::make_pair(1., 1.), V3D(peak_1 + V3D(0, 0, (double)i / 61.0))));
     }
 
     double radius = 0.3;
@@ -260,8 +264,10 @@ public:
     V3D peak_1(20, 0, 0);
     V3D peak_2(0, 20, 0);
     V3D peak_3(0, 0, 20);
-    std::vector<std::pair<double, V3D>> peak_q_list{
-        {1., peak_1}, {1., peak_2}, {1., peak_3}};
+    std::vector<std::pair<std::pair<double, double>, V3D>> peak_q_list{
+        {std::make_pair(1., 1.), peak_1},
+        {std::make_pair(1., 1.), peak_2},
+        {std::make_pair(1., 1.), peak_3}};
 
     // synthesize a UB-inverse to map
     DblMatrix UBinv(3, 3, false); // Q to h,k,l
@@ -269,7 +275,7 @@ public:
     UBinv.setRow(1, V3D(0, .2, 0));
     UBinv.setRow(2, V3D(0, 0, .25));
 
-    std::vector<std::pair<double, V3D>> event_Qs;
+    std::vector<std::pair<std::pair<double, double>, V3D>> event_Qs;
     const int numStrongEvents = 10000;
     const int numWeakEvents = 100;
     generatePeak(event_Qs, peak_1, 0.1, numStrongEvents, 1); // strong peak
@@ -336,7 +342,8 @@ public:
     // synthesize two peaks
     V3D peak_1(20, 0, 0);
     V3D peak_2(0, 20, 0);
-    std::vector<std::pair<double, V3D>> peak_q_list{{1., peak_1}, {1., peak_2}};
+    std::vector<std::pair<std::pair<double, double>, V3D>> peak_q_list{
+        {std::make_pair(1., 1.), peak_1}, {std::make_pair(1., 1.), peak_2}};
 
     // synthesize a UB-inverse to map
     DblMatrix UBinv(3, 3, false); // Q to h,k,l
@@ -344,7 +351,7 @@ public:
     UBinv.setRow(1, V3D(0, .2, 0));
     UBinv.setRow(2, V3D(0, 0, .25));
 
-    std::vector<std::pair<double, V3D>> event_Qs;
+    std::vector<std::pair<std::pair<double, double>, V3D>> event_Qs;
     const int numStrongEvents = 10000;
     const int numWeakEvents = 100;
     generatePeak(event_Qs, peak_1, 0.1, numStrongEvents, 1); // strong peak
@@ -394,8 +401,10 @@ public:
     V3D peak_1(20, 0, 0);
     V3D peak_2(0, 20, 0);
     V3D peak_3(0, 0, 20);
-    std::vector<std::pair<double, V3D>> peak_q_list{
-        {1., peak_1}, {1., peak_2}, {1., peak_3}};
+    std::vector<std::pair<std::pair<double, double>, V3D>> peak_q_list{
+        {std::make_pair(1., 1.), peak_1},
+        {std::make_pair(1., 1.), peak_2},
+        {std::make_pair(1., 1.), peak_3}};
 
     // synthesize a UB-inverse to map
     DblMatrix UBinv(3, 3, false); // Q to h,k,l
@@ -403,7 +412,7 @@ public:
     UBinv.setRow(1, V3D(0, .2, 0));
     UBinv.setRow(2, V3D(0, 0, .25));
 
-    std::vector<std::pair<double, V3D>> event_Qs;
+    std::vector<std::pair<std::pair<double, double>, V3D>> event_Qs;
     const int numStrongEvents = 10000;
     const int numWeakEvents = 100;
     generatePeak(event_Qs, peak_1, 0.1, numStrongEvents, 1);   // strong peak
@@ -446,8 +455,10 @@ private:
     V3D peak_1(20, 0, 0);
     V3D peak_2(0, 20, 0);
     V3D peak_3(0, 0, 20);
-    std::vector<std::pair<double, V3D>> peak_q_list{
-        {1., peak_1}, {1., peak_2}, {1., peak_3}};
+    std::vector<std::pair<std::pair<double, double>, V3D>> peak_q_list{
+        {std::make_pair(1., 1.), peak_1},
+        {std::make_pair(1., 1.), peak_2},
+        {std::make_pair(1., 1.), peak_3}};
 
     // synthesize a UB-inverse to map
     DblMatrix UBinv(3, 3, false); // Q to h,k,l
@@ -455,7 +466,7 @@ private:
     UBinv.setRow(1, V3D(0, .2, 0));
     UBinv.setRow(2, V3D(0, 0, .25));
 
-    std::vector<std::pair<double, V3D>> event_Qs;
+    std::vector<std::pair<std::pair<double, double>, V3D>> event_Qs;
     const int numStrongEvents = 10000;
     const int numWeakEvents = 100;
     generatePeak(event_Qs, peak_1, 0.1, numStrongEvents, 1);   // strong peak
@@ -492,8 +503,10 @@ private:
    * @param numSamples :: number of samples to draw
    * @param seed :: the seed to the pseudo-random number generator
    */
-  void generatePeak(std::vector<std::pair<double, V3D>> &event_Qs, V3D center,
-                    double sigma = 5, size_t numSamples = 1000, int seed = 1) {
+  void
+  generatePeak(std::vector<std::pair<std::pair<double, double>, V3D>> &event_Qs,
+               V3D center, double sigma = 5, size_t numSamples = 1000,
+               int seed = 1) {
 
     std::mt19937 gen;
     std::normal_distribution<> d(0, sigma);
@@ -501,7 +514,8 @@ private:
 
     for (size_t i = 0; i < numSamples; ++i) {
       V3D offset(d(gen), d(gen), d(gen));
-      event_Qs.emplace_back(std::make_pair(1., center + offset));
+      event_Qs.emplace_back(
+          std::make_pair(std::make_pair(1., 1.), center + offset));
     }
   }
 
@@ -514,11 +528,10 @@ private:
    * @param countVariation :: how much the average background can vary by
    * @param seed :: the random seed to use (default 1)
    */
-  void generateUniformBackground(std::vector<std::pair<double, V3D>> &event_Qs,
-                                 size_t countsPerQ, const double lower,
-                                 const double upper,
-                                 const int countVariation = 3,
-                                 const double step = 0.5, int seed = 1) {
+  void generateUniformBackground(
+      std::vector<std::pair<std::pair<double, double>, V3D>> &event_Qs,
+      size_t countsPerQ, const double lower, const double upper,
+      const int countVariation = 3, const double step = 0.5, int seed = 1) {
     const auto counts = static_cast<double>(countsPerQ);
     std::mt19937 gen;
     std::uniform_real_distribution<> d(-countVariation, countVariation);
@@ -527,7 +540,8 @@ private:
     for (double i = lower; i < upper; i += step) {
       for (double j = lower; j < upper; j += step) {
         for (double k = lower; k < upper; k += step) {
-          event_Qs.emplace_back(counts + d(gen), V3D(i, j, k));
+          double cts = counts + d(gen);
+          event_Qs.emplace_back(std::make_pair(cts, cts), V3D(i, j, k));
         }
       }
     }
diff --git a/Framework/MDAlgorithms/test/SaveMD2Test.h b/Framework/MDAlgorithms/test/SaveMD2Test.h
index eb43936b5d81ceb03f51e7e618777591b9f54a13..617e3330cdbeec1cb367562100cd961db3507d54 100644
--- a/Framework/MDAlgorithms/test/SaveMD2Test.h
+++ b/Framework/MDAlgorithms/test/SaveMD2Test.h
@@ -217,7 +217,7 @@ public:
     alg.execute();
     TS_ASSERT(alg.isExecuted());
     std::string this_filename = alg.getProperty("Filename");
-    long unsigned int fileSize = Poco::File(this_filename).getSize();
+    const auto fileSize = Poco::File(this_filename).getSize();
     if (Poco::File(this_filename).exists())
       Poco::File(this_filename).remove();
 
@@ -235,7 +235,7 @@ public:
     alg2.execute();
     TS_ASSERT(alg2.isExecuted());
     std::string this_filename2 = alg2.getProperty("Filename");
-    long unsigned int fileSize2 = Poco::File(this_filename2).getSize();
+    const auto fileSize2 = Poco::File(this_filename2).getSize();
     if (Poco::File(this_filename2).exists())
       Poco::File(this_filename2).remove();
 
diff --git a/Framework/Nexus/src/NexusFileIO.cpp b/Framework/Nexus/src/NexusFileIO.cpp
index 33c950ebee21fafba10cf687b1a7e41f2e13e3f1..acad6618507121d287b9ac711c689d78e8e1677e 100644
--- a/Framework/Nexus/src/NexusFileIO.cpp
+++ b/Framework/Nexus/src/NexusFileIO.cpp
@@ -404,6 +404,12 @@ int NexusFileIO::writeNexusProcessedData2D(
         NXputslab(fileID, rebin_workspace->readF(s).data(), start, asize);
         start[0]++;
       }
+
+      std::string finalized = (rebin_workspace->isFinalized()) ? "1" : "0";
+      NXputattr(fileID, "finalized", finalized.c_str(), 2, NX_CHAR);
+      std::string sqrdErrs = (rebin_workspace->hasSqrdErrors()) ? "1" : "0";
+      NXputattr(fileID, "sqrd_errors", sqrdErrs.c_str(), 2, NX_CHAR);
+
       if (m_progress != nullptr)
         m_progress->reportIncrement(1, "Writing data");
     }
diff --git a/Framework/NexusGeometry/src/JSONGeometryParser.cpp b/Framework/NexusGeometry/src/JSONGeometryParser.cpp
index 59724f39f96b101c7c3b5cda657c620dfd2a3a21..5d76f225b13b925f6d382974a66463cd8dbf5ab0 100644
--- a/Framework/NexusGeometry/src/JSONGeometryParser.cpp
+++ b/Framework/NexusGeometry/src/JSONGeometryParser.cpp
@@ -170,7 +170,7 @@ void extractShapeInformation(const Json::Value &shape,
     }
 
     if (windingOrder.size() != verts.size() / 3)
-      throw std::invalid_argument("Invalid off geometry provided in json " +
+      throw std::invalid_argument("Invalid off geometry provided in JSON " +
                                   name + ".");
 
     isOffGeometry = true;
@@ -186,7 +186,7 @@ void extractShapeInformation(const Json::Value &shape,
 
     if (cylinders.size() != verts.size() / 3)
       throw std::invalid_argument(
-          "Invalid cylindrical geometry provided in json " + name + ".");
+          "Invalid cylindrical geometry provided in JSON " + name + ".");
   }
 
   vertices.reserve(vertices.size() + (verts.size() / 3));
@@ -227,7 +227,7 @@ void verifyDependency(const Json::Value &root, const Json::Value &dependency) {
   // Left over values suggests the dependency could not be found
   if (!values.empty())
     throw std::invalid_argument("Could not find dependency " + path +
-                                " in json provided.");
+                                " in JSON provided.");
 }
 
 Eigen::Vector3d getTransformationAxis(const Json::Value &root,
@@ -279,7 +279,7 @@ void extractMonitorWaveformStream(const Json::Value &waveform,
 
 Json::Value getRoot(const std::string &jsonGeometry) {
   if (jsonGeometry.empty())
-    throw std::invalid_argument("Empty geometry json string provided.");
+    throw std::invalid_argument("Empty geometry JSON string provided.");
 
   Json::CharReaderBuilder rbuilder;
   auto reader = std::unique_ptr<Json::CharReader>(rbuilder.newCharReader());
@@ -325,24 +325,24 @@ void JSONGeometryParser::validateAndRetrieveGeometry(
 
   if (nexusStructure.isNull())
     throw std::invalid_argument(
-        "Json geometry does not contain nexus_structure.");
+        "JSON geometry does not contain nexus_structure.");
 
   auto nexusChildren = nexusStructure[CHILDREN];
 
   auto entry = get(nexusChildren, NX_ENTRY); // expect children to be array type
   if (entry.isNull())
     throw std::invalid_argument(
-        "No nexus \"entry\" child found in nexus_structure json.");
+        "No nexus \"entry\" child found in nexus_structure JSON.");
 
   auto entryChildren = entry[CHILDREN];
 
   auto sample = get(entryChildren, NX_SAMPLE);
   if (sample.isNull())
-    throw std::invalid_argument("No sample found in json.");
+    throw std::invalid_argument("No sample found in JSON.");
 
   auto instrument = get(entryChildren, NX_INSTRUMENT);
   if (instrument.isNull())
-    throw std::invalid_argument("No instrument found in json.");
+    throw std::invalid_argument("No instrument found in JSON.");
 
   m_name = extractInstrumentName(instrument);
 
@@ -351,12 +351,12 @@ void JSONGeometryParser::validateAndRetrieveGeometry(
   auto source = get(instrumentChildren, NX_SOURCE);
 
   if (source.isNull())
-    g_log.notice() << "No source information found in json instrument."
+    g_log.notice() << "No source information found in JSON instrument."
                    << std::endl;
 
   auto jsonDetectorBanks = getAllDetectors(instrument);
   if (jsonDetectorBanks.empty())
-    throw std::invalid_argument("No detectors found in json.");
+    throw std::invalid_argument("No detectors found in JSON.");
   ;
   m_jsonDetectorBanks = moveToUniquePtrVec(jsonDetectorBanks);
 
@@ -508,22 +508,29 @@ void JSONGeometryParser::extractMonitorContent() {
   if (m_jsonMonitors.empty())
     return;
 
+  int monitorID = -1;
   for (const auto &monitor : m_jsonMonitors) {
     const auto &children = (*monitor)[CHILDREN];
     auto name = (*monitor)[NAME].asString();
     if (children.empty())
       throw std::invalid_argument("Full monitor definition for " + name +
-                                  " missing in json provided.");
-
+                                  " missing in JSON provided.");
     Monitor mon;
     mon.componentName = name;
+    /* For monitors with no detector ID we create dummy IDs starting from -1 and
+     * decreasing. */
+    mon.detectorID = monitorID--;
+
     for (const auto &child : children) {
       const auto &val = child[VALUES];
       if (child[NAME] == NAME)
         mon.name = val.asString();
-      else if (child[NAME] == DETECTOR_ID || child[NAME] == "detector_number")
+      else if (child[NAME] == DETECTOR_ID || child[NAME] == "detector_number") {
         mon.detectorID = val.asInt();
-      else if (child[NAME] == "events")
+        /* If there is a detector ID for this monitor increment the dummy IDs to
+         * keep them contiguous. */
+        ++monitorID;
+      } else if (child[NAME] == "events")
         extractMonitorEventStream(child, mon);
       else if (child[NAME] == "waveforms")
         extractMonitorWaveformStream(child, mon);
@@ -557,7 +564,7 @@ void JSONGeometryParser::extractChopperContent() {
 
     if (children.empty())
       throw std::invalid_argument(
-          "Full chopper definition missing in json provided.");
+          "Full chopper definition missing in JSON provided.");
     Chopper chop;
     chop.componentName = (*chopper)[NAME].asString();
     for (const auto &child : children) {
@@ -580,7 +587,7 @@ void JSONGeometryParser::extractChopperContent() {
   }
 }
 
-/** Parses instrument geometry which is formated in json corresponding to the
+/** Parses instrument geometry which is formated in JSON corresponding to the
 hdf5 nexus structure.
 @param jsonGeometry - JSON string representing the nexus style instrument
 @throws std::invalid_argument if the geometry string is invalid.
diff --git a/Framework/NexusGeometry/test/JSONGeometryParserTest.h b/Framework/NexusGeometry/test/JSONGeometryParserTest.h
index 77e5b3928bc45cf331362f1d51f563b1442b906d..ecd2c614366637415aeb93e391a843ee4633099d 100644
--- a/Framework/NexusGeometry/test/JSONGeometryParserTest.h
+++ b/Framework/NexusGeometry/test/JSONGeometryParserTest.h
@@ -30,85 +30,85 @@ public:
   }
   static void destroySuite(JSONGeometryParserTest *suite) { delete suite; }
 
-  void test_parse_fail_with_empty_json_string() {
+  void test_parse_fail_with_empty_JSON_string() {
     std::string json;
-    attemptParseInvalidArgument(json, "Empty geometry json string provided.");
+    attemptParseInvalidArgument(json, "Empty geometry JSON string provided.");
   }
 
-  void test_parse_fail_with_no_nexus_structure_in_json() {
+  void test_parse_fail_with_no_nexus_structure_in_JSON() {
     std::string json = "{}";
     attemptParseInvalidArgument(
-        json, "Json geometry does not contain nexus_structure.");
+        json, "JSON geometry does not contain nexus_structure.");
   }
 
-  void test_parse_fail_with_no_child_entry_in_json() {
+  void test_parse_fail_with_no_child_entry_in_JSON() {
     std::string json = "{\"nexus_structure\": { \"children\":[]}}";
     attemptParseInvalidArgument(
-        json, "No nexus \"entry\" child found in nexus_structure json.");
+        json, "No nexus \"entry\" child found in nexus_structure JSON.");
   }
 
-  void test_parse_fail_with_no_sample_in_json() {
+  void test_parse_fail_with_no_sample_in_JSON() {
     std::string json = Mantid::TestHelpers::getJSONGeometryNoSample();
-    attemptParseInvalidArgument(json, "No sample found in json.");
+    attemptParseInvalidArgument(json, "No sample found in JSON.");
   }
 
-  void test_parse_fail_with_no_instrument_in_json() {
+  void test_parse_fail_with_no_instrument_in_JSON() {
     std::string json = Mantid::TestHelpers::getJSONGeometryNoInstrument();
-    attemptParseInvalidArgument(json, "No instrument found in json.");
+    attemptParseInvalidArgument(json, "No instrument found in JSON.");
   }
 
-  void test_parse_fail_with_no_detectors_in_json() {
+  void test_parse_fail_with_no_detectors_in_JSON() {
     std::string json = Mantid::TestHelpers::getJSONGeometryNoDetectors();
-    attemptParseInvalidArgument(json, "No detectors found in json.");
+    attemptParseInvalidArgument(json, "No detectors found in JSON.");
   }
 
-  void test_parse_fail_if_no_detector_ids_in_json() {
+  void test_parse_fail_if_no_detector_ids_in_JSON() {
     std::string json = Mantid::TestHelpers::getJSONGeometryNoDetectorIDs();
     attemptParseInvalidArgument(json, "No detector ids found in detector_1.");
   }
 
-  void test_parse_fail_if_no_x_pixel_offset_in_json() {
+  void test_parse_fail_if_no_x_pixel_offset_in_JSON() {
     std::string json = Mantid::TestHelpers::getJSONGeometryNoXPixelOffset();
     attemptParseInvalidArgument(json,
                                 "No x_pixel_offsets found in detector_1.");
   }
 
-  void test_parse_fail_if_no_y_pixel_offset_in_json() {
+  void test_parse_fail_if_no_y_pixel_offset_in_JSON() {
     std::string json = Mantid::TestHelpers::getJSONGeometryNoYPixelOffset();
     attemptParseInvalidArgument(json,
                                 "No y_pixel_offsets found in detector_1.");
   }
 
-  void test_parse_fail_if_no_pixel_shape_in_json() {
+  void test_parse_fail_if_no_pixel_shape_in_JSON() {
     std::string json = Mantid::TestHelpers::getJSONGeometryNoPixelShape();
     attemptParseInvalidArgument(
         json, "Insufficient pixel shape information found in detector_1.");
   }
 
-  void test_parse_fail_for_empty_off_geometry_in_json() {
+  void test_parse_fail_for_empty_off_geometry_in_JSON() {
     std::string json = Mantid::TestHelpers::getJSONGeometryEmptyOffGeometry();
     attemptParseInvalidArgument(
         json, "Insufficient pixel shape information found in detector_1.");
   }
 
-  void test_parse_fail_for_invalid_off_geometry_in_json() {
+  void test_parse_fail_for_invalid_off_geometry_in_JSON() {
     std::string json = Mantid::TestHelpers::getJSONGeometryInvalidOffGeometry();
     attemptParseInvalidArgument(
-        json, "Invalid off geometry provided in json pixel_shape.");
+        json, "Invalid off geometry provided in JSON pixel_shape.");
   }
 
-  void test_parse_fail_for_empty_cylindrical_geometry_in_json() {
+  void test_parse_fail_for_empty_cylindrical_geometry_in_JSON() {
     std::string json =
         Mantid::TestHelpers::getJSONGeometryEmptyCylindricalGeometry();
     attemptParseInvalidArgument(
         json, "Insufficient pixel shape information found in detector_1.");
   }
 
-  void test_parse_fail_for_invalid_cylindrical_geometry_in_json() {
+  void test_parse_fail_for_invalid_cylindrical_geometry_in_JSON() {
     std::string json =
         Mantid::TestHelpers::getJSONGeometryInvalidCylindricalGeometry();
     attemptParseInvalidArgument(
-        json, "Invalid cylindrical geometry provided in json pixel_shape.");
+        json, "Invalid cylindrical geometry provided in JSON pixel_shape.");
   }
 
   void test_parse_fail_for_missing_transformation_dependency() {
@@ -116,7 +116,7 @@ public:
         Mantid::TestHelpers::getJSONGeometryMissingTransformations();
     attemptParseInvalidArgument(json, "Could not find dependency "
                                       "/entry/instrument/detector_1/"
-                                      "transformations/location in json "
+                                      "transformations/location in JSON "
                                       "provided.");
   }
 
@@ -126,14 +126,14 @@ public:
     attemptParseInvalidArgument(json, "Could not find dependency "
                                       "/entry/instrument/detector_1/"
                                       "transformations/beam_direction_offset "
-                                      "in json provided.");
+                                      "in JSON provided.");
   }
 
   void test_parse_fail_for_missing_transformation_orientation() {
     std::string json = Mantid::TestHelpers::getJSONGeometryMissingOrientation();
     attemptParseInvalidArgument(json, "Could not find dependency "
                                       "/entry/instrument/detector_1/"
-                                      "transformations/orientation in json "
+                                      "transformations/orientation in JSON "
                                       "provided.");
   }
 
@@ -141,7 +141,7 @@ public:
     std::string json =
         Mantid::TestHelpers::getJSONGeometryMissingChopperInformation();
     attemptParseInvalidArgument(
-        json, "Full chopper definition missing in json provided.");
+        json, "Full chopper definition missing in JSON provided.");
   }
 
   void test_parse_fail_for_empty_monitor() {
@@ -149,7 +149,7 @@ public:
         Mantid::TestHelpers::getJSONGeometryMissingMonitorInformation();
     attemptParseInvalidArgument(
         json,
-        "Full monitor definition for monitor_1 missing in json provided.");
+        "Full monitor definition for monitor_1 missing in JSON provided.");
   }
 
   void test_load_full_instrument_simple_off_pixel_shape() {
diff --git a/Framework/Properties/Mantid.properties.template b/Framework/Properties/Mantid.properties.template
index 82755e1a1184a5073066db414e906bb6695ff4e0..841818e17d0b40aa490f78efb1b2473d6b50ca56 100644
--- a/Framework/Properties/Mantid.properties.template
+++ b/Framework/Properties/Mantid.properties.template
@@ -43,6 +43,8 @@ python.plugins.directories = @PYTHONPLUGIN_DIRS@
 
 # Where to load instrument definition files from
 instrumentDefinition.directory = @MANTID_ROOT@/instrument
+# Controls whether Mantid Workbench will use system notifications for important messages (On/Off)
+Notifications.Enabled = On
 
 # Whether to check for updated instrument definitions on startup of Mantid
 UpdateInstrumentDefinitions.OnStartup = @UPDATE_INSTRUMENT_DEFINTITIONS@
@@ -155,11 +157,6 @@ MantidOptions.InstrumentView.UseOpenGL = On
 #   Off: Do not normalize
 graph1d.autodistribution = On
 
-#Uncommenting the line below will enable algorithm chain re-running whenever a
-#workspace is replaced. Uncommenting and setting it to 0 will also turn it off
-#enabling this is currently discouraged as it could cause race conditions with python scripts
-#AlgorithmChaining.SwitchedOn = 1
-
 # logging configuration
 # root level message filter (This sets a minimal level possible for any channel)
 logging.loggers.root.level = notice
@@ -237,4 +234,4 @@ projectRecovery.numberOfCheckpoints = 5
 
 # The size of the project before a warning is given in bytes.
 # 10 GB = 10737418240 bytes
-projectSaving.warningSize = 10737418240
\ No newline at end of file
+projectSaving.warningSize = 10737418240
diff --git a/Framework/PythonInterface/core/src/Converters/DateAndTime.cpp b/Framework/PythonInterface/core/src/Converters/DateAndTime.cpp
index da7c57aa4596d14aec763d7c71700082c2e2d9df..7c7c8a4f37d2cc9329f2d0d022428d9301711cf2 100644
--- a/Framework/PythonInterface/core/src/Converters/DateAndTime.cpp
+++ b/Framework/PythonInterface/core/src/Converters/DateAndTime.cpp
@@ -99,7 +99,8 @@ to_dateandtime(const boost::python::api::object &value) {
 
   boost::python::extract<double> converter_dbl(value);
   if (converter_dbl.check()) {
-    return boost::make_shared<DateAndTime>(converter_dbl());
+    return boost::make_shared<DateAndTime>(
+        static_cast<int64_t>(converter_dbl()));
   }
 
   boost::python::extract<int64_t> converter_int64(value);
diff --git a/Framework/PythonInterface/mantid/BundlePython.cmake b/Framework/PythonInterface/mantid/BundlePython.cmake
index 88b40ede3d6794f851353a96f1fb63640be9a37b..0f0ec08f764d1a82d4198e870a57ccee95bfc073 100644
--- a/Framework/PythonInterface/mantid/BundlePython.cmake
+++ b/Framework/PythonInterface/mantid/BundlePython.cmake
@@ -6,16 +6,6 @@
 ###############################################################################
 
 if( MSVC )
-  #####################################################################
-  # Bundled Python for dev build. Assumes PYTHON_DIR has been set in
-  # MSVCSetup.cmake
-  #####################################################################
-  file(TO_NATIVE_PATH ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR} BIN_NATIVE)
-  add_custom_command( TARGET ${PYBUNDLE_POST_TARGET} POST_BUILD
-                      COMMAND ${CMAKE_COMMAND}
-                      ARGS -E copy_if_different ${PYTHON_DIR}/python27.dll ${BIN_NATIVE}/python27.dll
-                      COMMENT "Copying Python27 dll to bin" )
- 
   #####################################################################
   # Bundle for package
   #####################################################################
@@ -24,5 +14,12 @@ if( MSVC )
   install ( DIRECTORY ${PYTHON_DIR}/Lib DESTINATION bin PATTERN ".svn" EXCLUDE PATTERN ".git" EXCLUDE PATTERN "*_d.pyd" EXCLUDE )
   install ( DIRECTORY ${PYTHON_DIR}/Scripts DESTINATION bin PATTERN ".svn" EXCLUDE PATTERN ".git" EXCLUDE PATTERN "*_d.py" EXCLUDE )
   install ( DIRECTORY ${PYTHON_DIR}/tcl DESTINATION bin PATTERN ".svn" EXCLUDE PATTERN ".git" EXCLUDE )
-  install ( FILES ${PYTHON_DIR}/python27.dll ${PYTHON_EXECUTABLE} ${PYTHONW_EXECUTABLE} DESTINATION bin )
+  install ( FILES ${PYTHON_DIR}/python${PYTHON_MAJOR_VERSION}${PYTHON_MINOR_VERSION}.dll
+            ${PYTHON_EXECUTABLE} ${PYTHONW_EXECUTABLE}
+            DESTINATION bin )
+  # Python >= 3 has an minimal API DLL too
+  if ( EXISTS ${PYTHON_DIR}/python${PYTHON_MAJOR_VERSION}.dll )
+    install ( FILES ${PYTHON_DIR}/python${PYTHON_MAJOR_VERSION}.dll
+              DESTINATION bin )
+  endif()
 endif()
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/Projection.cpp b/Framework/PythonInterface/mantid/api/src/Exports/Projection.cpp
index 765b22c131e50371fafc9b388326e8437169baa7..c2cfa615c3d37cb4fa14a2a36702533377f80e19 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/Projection.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/Projection.cpp
@@ -9,7 +9,6 @@
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidKernel/WarningSuppressions.h"
 #include "MantidPythonInterface/core/Converters/PyObjectToV3D.h"
-#include <boost/bind.hpp>
 #include <boost/python/class.hpp>
 #include <boost/python/copy_non_const_reference.hpp>
 #include <boost/python/exec.hpp>
@@ -103,6 +102,7 @@ Projection_sptr projCtor3(const object &d1, const object &d2,
 } // anonymous namespace
 
 void export_Projection() {
+  using namespace std::placeholders;
   class_<Projection>(
       "Projection",
       init<>("Default constructor creates a two dimensional projection"))
@@ -145,7 +145,7 @@ void export_Projection() {
               &Projection::U, return_internal_reference<>(),
               boost::mpl::vector2<Mantid::Kernel::V3D &, Projection &>()),
           make_function(
-              boost::bind(&Projection::setAxis, _1, 0, _2),
+              std::bind(&Projection::setAxis, _1, 0, _2),
               default_call_policies(),
               boost::mpl::vector3<void, Projection &, Mantid::Kernel::V3D>()))
       .add_property(
@@ -154,7 +154,7 @@ void export_Projection() {
               &Projection::V, return_internal_reference<>(),
               boost::mpl::vector2<Mantid::Kernel::V3D &, Projection &>()),
           make_function(
-              boost::bind(&Projection::setAxis, _1, 1, _2),
+              std::bind(&Projection::setAxis, _1, 1, _2),
               default_call_policies(),
               boost::mpl::vector3<void, Projection &, Mantid::Kernel::V3D>()))
       .add_property(
@@ -163,7 +163,7 @@ void export_Projection() {
               &Projection::W, return_internal_reference<>(),
               boost::mpl::vector2<Mantid::Kernel::V3D &, Projection &>()),
           make_function(
-              boost::bind(&Projection::setAxis, _1, 2, _2),
+              std::bind(&Projection::setAxis, _1, 2, _2),
               default_call_policies(),
               boost::mpl::vector3<void, Projection &, Mantid::Kernel::V3D>()))
       .add_property(
@@ -172,7 +172,7 @@ void export_Projection() {
               &Projection::U, return_internal_reference<>(),
               boost::mpl::vector2<Mantid::Kernel::V3D &, Projection &>()),
           make_function(
-              boost::bind(&projSetAxis, _1, 0, _2), default_call_policies(),
+              std::bind(&projSetAxis, _1, 0, _2), default_call_policies(),
               boost::mpl::vector3<void, Projection &, const object &>()))
       .add_property(
           "v",
@@ -180,7 +180,7 @@ void export_Projection() {
               &Projection::V, return_internal_reference<>(),
               boost::mpl::vector2<Mantid::Kernel::V3D &, Projection &>()),
           make_function(
-              boost::bind(&projSetAxis, _1, 1, _2), default_call_policies(),
+              std::bind(&projSetAxis, _1, 1, _2), default_call_policies(),
               boost::mpl::vector3<void, Projection &, const object &>()))
       .add_property(
           "w",
@@ -188,7 +188,7 @@ void export_Projection() {
               &Projection::W, return_internal_reference<>(),
               boost::mpl::vector2<Mantid::Kernel::V3D &, Projection &>()),
           make_function(
-              boost::bind(&projSetAxis, _1, 2, _2), default_call_policies(),
+              std::bind(&projSetAxis, _1, 2, _2), default_call_policies(),
               boost::mpl::vector3<void, Projection &, const object &>()))
       .def("createWorkspace", createWorkspace(),
            "Create a TableWorkspace representing the projection");
diff --git a/Framework/PythonInterface/mantid/dataobjects/src/Exports/RebinnedOutput.cpp b/Framework/PythonInterface/mantid/dataobjects/src/Exports/RebinnedOutput.cpp
index 422c9239cccf0572896e998ddf1fc5a034866ac1..c241b305e68462d8e917d079fd32eee78b3d86d6 100644
--- a/Framework/PythonInterface/mantid/dataobjects/src/Exports/RebinnedOutput.cpp
+++ b/Framework/PythonInterface/mantid/dataobjects/src/Exports/RebinnedOutput.cpp
@@ -5,22 +5,92 @@
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
 #include "MantidDataObjects/RebinnedOutput.h"
+#include "MantidPythonInterface/core/Converters/NDArrayToVector.h"
+#include "MantidPythonInterface/core/Converters/PySequenceToVector.h"
+#include "MantidPythonInterface/core/Converters/WrapWithNDArray.h"
 #include "MantidPythonInterface/core/GetPointer.h"
+#include "MantidPythonInterface/core/Policies/VectorToNumpy.h"
 #include "MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h"
 
 #include <boost/python/class.hpp>
 
 using Mantid::DataObjects::RebinnedOutput;
 using Mantid::DataObjects::Workspace2D;
+using namespace Mantid::PythonInterface;
+using namespace Mantid::PythonInterface::Converters;
+using namespace Mantid::PythonInterface::Policies;
 using namespace Mantid::PythonInterface::Registry;
 using namespace boost::python;
 
 GET_POINTER_SPECIALIZATION(RebinnedOutput)
 
+namespace {
+/// Typedef for data access, i.e. dataX,Y,E members
+using data_modifier = Mantid::MantidVec &(RebinnedOutput::*)(const std::size_t);
+
+/// return_value_policy for read-only numpy array
+using return_readonly_numpy =
+    return_value_policy<VectorRefToNumpy<WrapReadOnly>>;
+/// return_value_policy for read-write numpy array
+using return_readwrite_numpy =
+    return_value_policy<VectorRefToNumpy<WrapReadWrite>>;
+
+/**
+ * Set the F values from an python array-style object
+ * @param self :: A reference to the calling object
+ * @param wsIndex :: The workspace index for the spectrum to set
+ * @param values :: A numpy array, length must match F array length
+ */
+void setFFromPyObject(RebinnedOutput &self, const size_t wsIndex,
+                      const boost::python::object &values) {
+
+  if (NDArray::check(values)) {
+    NDArrayToVector<double> converter(values);
+    converter.copyTo(self.dataF(wsIndex));
+  } else {
+    PySequenceToVector<double> converter(values);
+    converter.copyTo(self.dataF(wsIndex));
+  }
+}
+} // namespace
+
 void export_RebinnedOutput() {
   class_<RebinnedOutput, bases<Workspace2D>, boost::noncopyable>(
-      "RebinnedOutput", no_init);
-
+      "RebinnedOutput", no_init)
+      .def("readF", &RebinnedOutput::readF,
+           (arg("self"), arg("workspaceIndex")), return_readonly_numpy(),
+           "Creates a read-only numpy wrapper "
+           "around the original F data at the "
+           "given index")
+      .def("dataF", (data_modifier)&RebinnedOutput::dataF,
+           return_readwrite_numpy(), args("self", "workspaceIndex"),
+           "Creates a writable numpy wrapper around the original F data at the "
+           "given index")
+      .def("setF", &setFFromPyObject, args("self", "workspaceIndex", "x"),
+           "Set F values from a python list or numpy array. It performs a "
+           "simple copy into the array")
+      .def("scaleF", &RebinnedOutput::scaleF, (arg("self"), arg("scale")),
+           "Scales the fractional area arrays")
+      .def("nonZeroF", &RebinnedOutput::nonZeroF, (arg("self")),
+           "Returns if the fractional area is non zero")
+      .def("finalize", &RebinnedOutput::finalize,
+           (arg("self"), arg("hasSqrdErrs")),
+           "Divides the data/error arrays by the corresponding fractional area "
+           "array")
+      .def("unfinalize", &RebinnedOutput::unfinalize, (arg("self")),
+           "Multiplies the data/error arrays by the corresponding fractional "
+           "area array")
+      .def("isFinalized", &RebinnedOutput::isFinalized, (arg("self")),
+           "Returns if values are normalized to the fractional area array")
+      .def("hasSqrdErrors", &RebinnedOutput::hasSqrdErrors, (arg("self")),
+           "Returns if squared errors are used with fractional area "
+           "normalization")
+      .def("setFinalized", &RebinnedOutput::setFinalized,
+           (arg("self"), arg("value")),
+           "Sets the value of the is finalized flag")
+      .def("setSqrdErrors", &RebinnedOutput::setSqrdErrors,
+           (arg("self"), arg("value")),
+           "Sets the value of the squared errors flag");
   // register pointers
   RegisterWorkspacePtrToPython<RebinnedOutput>();
 }
diff --git a/Framework/PythonInterface/mantid/fitfunctions.py b/Framework/PythonInterface/mantid/fitfunctions.py
index fd53996acf888f8fbeb16907b8f70db2c4de404b..4ac4bdbb022290036ca5e86a39bd979185e66f97 100644
--- a/Framework/PythonInterface/mantid/fitfunctions.py
+++ b/Framework/PythonInterface/mantid/fitfunctions.py
@@ -370,7 +370,7 @@ class FunctionWrapper(object):
         # to pass InputWorkspace into EvaluateFunction before Function.
         # As a special case has been made for this. This case can be removed
         # with ordered kwargs change in Python 3.6.
-        if name is 'EvaluateFunction':
+        if name == 'EvaluateFunction':
             alg.setProperty('Function', kwargs['Function'])
             del kwargs['Function']
             alg.setProperty('InputWorkspace', kwargs['InputWorkspace'])
diff --git a/Framework/PythonInterface/mantid/kernel/funcinspect.py b/Framework/PythonInterface/mantid/kernel/funcinspect.py
index ff8eac18c91100a0a34c8fe98f670d41fd13f4c1..7232a5e9ea6de8bff7cf4b90e759ee850df24249 100644
--- a/Framework/PythonInterface/mantid/kernel/funcinspect.py
+++ b/Framework/PythonInterface/mantid/kernel/funcinspect.py
@@ -40,11 +40,16 @@ def replace_signature(func, varnames):
     else:
         code_attr = '__code__'
         f = func.__code__
-        c = f.__new__(f.__class__, f.co_argcount, f.co_kwonlyargcount,
-                      f.co_nlocals, f.co_stacksize, f.co_flags, f.co_code, 
-                      f.co_consts, f.co_names, varnames, 
-                      f.co_filename, f.co_name, f.co_firstlineno,
-                      f.co_lnotab, f.co_freevars)
+        new_args = [f.__class__, f.co_argcount, f.co_kwonlyargcount,
+                    f.co_nlocals, f.co_stacksize, f.co_flags, f.co_code, 
+                    f.co_consts, f.co_names, varnames, 
+                    f.co_filename, f.co_name, f.co_firstlineno,
+                    f.co_lnotab, f.co_freevars]
+        # Python 3.8 supports positional-only arguments and has an extra
+        # keyword in the constructor
+        if hasattr(f, 'co_posonlyargcount'):
+            new_args.insert(2, f.co_posonlyargcount)
+        c = f.__new__(*new_args)
     #endif
     setattr(func, code_attr, c)
 
diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/UnitLabel.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/UnitLabel.cpp
index 670d2418574ad1af8d9bf527a3c5303354aebd4a..9330af21762d8c25de0a51457c77062c28c09711 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Exports/UnitLabel.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Exports/UnitLabel.cpp
@@ -24,11 +24,13 @@ boost::shared_ptr<UnitLabel>
 createLabel(const object &ascii, const object &utf8, const object &latex) {
   using Utf8Char = UnitLabel::Utf8String::value_type;
   if (PyUnicode_Check(utf8.ptr())) {
-    auto length = PyUnicode_GetSize(utf8.ptr());
-    boost::scoped_array<Utf8Char> buffer(new Utf8Char[length]);
 #if PY_MAJOR_VERSION >= 3
+    auto length = PyUnicode_GetLength(utf8.ptr());
+    boost::scoped_array<Utf8Char> buffer(new Utf8Char[length]);
     PyUnicode_AsWideChar(utf8.ptr(), buffer.get(), length);
 #else
+    auto length = PyUnicode_GetSize(utf8.ptr());
+    boost::scoped_array<Utf8Char> buffer(new Utf8Char[length]);
     PyUnicode_AsWideChar(reinterpret_cast<PyUnicodeObject *>(utf8.ptr()),
                          buffer.get(), length);
 #endif
diff --git a/Framework/PythonInterface/mantid/plots/__init__.py b/Framework/PythonInterface/mantid/plots/__init__.py
index 86c9847721583276fe74cf9b441691ae020c0bbc..7ce38b4fc87b82bc384a9b413339977fb768d34b 100644
--- a/Framework/PythonInterface/mantid/plots/__init__.py
+++ b/Framework/PythonInterface/mantid/plots/__init__.py
@@ -15,7 +15,11 @@ Functionality for unpacking mantid objects for plotting with matplotlib.
 # of the main package.
 from __future__ import (absolute_import, division, print_function)
 
-from collections import Iterable
+try:
+   from collections.abc import Iterable
+except ImportError:
+   # check Python 2 location
+   from collections import Iterable   
 from matplotlib.axes import Axes
 from matplotlib.collections import Collection
 from matplotlib.colors import Colormap
@@ -34,7 +38,7 @@ from mantid.plots import helperfunctions, plotfunctions, plotfunctions3D
 from mantid.plots.utility import autoscale_on_update
 from mantid.plots.helperfunctions import get_normalize_by_bin_width
 from mantid.plots.scales import PowerScale, SquareScale
-from mantid.plots.utility import artists_hidden, MantidAxType
+from mantid.plots.utility import artists_hidden, MantidAxType, legend_set_draggable
 from mantidqt.widgets.plotconfigdialog.legendtabwidget import LegendProperties
 
 
@@ -268,6 +272,8 @@ class MantidAxes(Axes):
             # If wanting to plot a spectrum
             elif MantidAxes.is_axis_of_type(MantidAxType.SPECTRUM, kwargs):
                 return MantidAxes.get_spec_num_from_wksp_index(workspace, kwargs['wkspIndex'])
+        elif kwargs.get('LogName', None) is not None:
+            return None
         elif getattr(workspace, 'getNumberHistograms', lambda: -1)() == 1:
             # If the workspace has one histogram, just plot that
             kwargs['wkspIndex'] = 0
@@ -495,7 +501,7 @@ class MantidAxes(Axes):
 
     def make_legend(self):
         if self.legend_ is None:
-            self.legend().draggable()
+            legend_set_draggable(self.legend(), True)
         else:
             props = LegendProperties.from_legend(self.legend_)
             LegendProperties.create_legend(props, self)
@@ -617,7 +623,7 @@ class MantidAxes(Axes):
 
                     # also remove the curve from the legend
                     if (not self.is_empty(self)) and self.legend_ is not None:
-                        self.legend().draggable()
+                        legend_set_draggable(self.legend(), True)
 
                 if new_kwargs:
                     _autoscale_on = new_kwargs.pop("autoscale_on_update", self.get_autoscale_on())
@@ -636,7 +642,8 @@ class MantidAxes(Axes):
 
             with autoscale_on_update(self, autoscale_on):
                 artist = self.track_workspace_artist(workspace,
-                                                     plotfunctions.plot(self, *args, **kwargs),
+                                                     plotfunctions.plot(self, normalize_by_bin_width = is_normalized,
+                                                                        *args, **kwargs),
                                                      _data_update, spec_num, is_normalized,
                                                      MantidAxes.is_axis_of_type(MantidAxType.SPECTRUM, kwargs))
             return artist
@@ -741,7 +748,7 @@ class MantidAxes(Axes):
                     container_new = []
                     # also remove the curve from the legend
                     if (not self.is_empty(self)) and self.legend_ is not None:
-                        self.legend().draggable()
+                        legend_set_draggable(self.legend(), True)
 
                 return container_new
 
diff --git a/Framework/PythonInterface/mantid/plots/helperfunctions.py b/Framework/PythonInterface/mantid/plots/helperfunctions.py
index 2cfcdb642634c0f68ea60f8059a24b86e3802aea..0c1f606b8de6a2065babcbc434a821ecfa69c944 100644
--- a/Framework/PythonInterface/mantid/plots/helperfunctions.py
+++ b/Framework/PythonInterface/mantid/plots/helperfunctions.py
@@ -62,11 +62,13 @@ def get_normalize_by_bin_width(workspace, axes, **kwargs):
     :param workspace: :class:`mantid.api.MatrixWorkspace` workspace being plotted
     :param axes: The axes being plotted on
     """
+    normalize_by_bin_width = kwargs.get('normalize_by_bin_width', None)
+    if normalize_by_bin_width is not None:
+        return normalize_by_bin_width, kwargs
     distribution = kwargs.get('distribution', None)
-    aligned, _ = check_resample_to_regular_grid(workspace, **kwargs)
     if distribution or (hasattr(workspace, 'isDistribution') and workspace.isDistribution()):
         return False, kwargs
-    elif distribution is False or aligned:
+    elif distribution is False:
         return True, kwargs
     else:
         try:
@@ -77,11 +79,13 @@ def get_normalize_by_bin_width(workspace, axes, **kwargs):
         if current_artists:
             current_normalization = any(
                 [artist[0].is_normalized for artist in current_artists])
-            normalize_by_bin_width = current_normalization
+            normalization = current_normalization
         else:
-            normalize_by_bin_width = mantid.kernel.config[
-                                         'graph1d.autodistribution'].lower() == 'on'
-    return normalize_by_bin_width, kwargs
+            if mantid.kernel.config['graph1d.autodistribution'].lower() == 'on':
+                normalization = True
+            else:
+                normalization, _ = check_resample_to_regular_grid(workspace, **kwargs)
+    return normalization, kwargs
 
 
 def get_normalization(md_workspace, **kwargs):
@@ -574,12 +578,12 @@ def get_data_uneven_flag(workspace, **kwargs):
 def check_resample_to_regular_grid(ws, **kwargs):
     if isinstance(ws, MatrixWorkspace):
         aligned = kwargs.pop('axisaligned', False)
-        if not ws.isCommonBins() or aligned:
+        if aligned or not ws.isCommonBins():
             return True, kwargs
 
-        x = ws.dataX(0)
+        x = ws.readX(0)
         difference = np.diff(x)
-        if x.size > 1 and not np.all(np.isclose(difference[:-1], difference[0])):
+        if x.size > 1 and not np.allclose(difference[:-1], difference[0]):
             return True, kwargs
     return False, kwargs
 
diff --git a/Framework/PythonInterface/mantid/plots/modest_image/modest_image.py b/Framework/PythonInterface/mantid/plots/modest_image/modest_image.py
index 0d3544ff1f65d9cf829915eca13c02992f23f85b..88631d6fbf890291b5a782fae08bda2923c0e227 100644
--- a/Framework/PythonInterface/mantid/plots/modest_image/modest_image.py
+++ b/Framework/PythonInterface/mantid/plots/modest_image/modest_image.py
@@ -211,8 +211,6 @@ def imshow(axes, X, cmap=None, norm=None, aspect=None,
 
     Unlike matplotlib version, must explicitly specify axes
     """
-    if not axes._hold:
-        axes.cla()
     if norm is not None:
         assert(isinstance(norm, mcolors.Normalize))
     if aspect is None:
diff --git a/Framework/PythonInterface/mantid/plots/plotfunctions.py b/Framework/PythonInterface/mantid/plots/plotfunctions.py
index 248677c96959cf99eb2d14a67d0fdbb09d0bd6ef..a926ebac60386083831049b3b4add6189a5ddcd0 100644
--- a/Framework/PythonInterface/mantid/plots/plotfunctions.py
+++ b/Framework/PythonInterface/mantid/plots/plotfunctions.py
@@ -116,6 +116,7 @@ def _plot_impl(axes, workspace, args, kwargs):
         if kwargs.pop('update_axes_labels', True):
             _setLabels1D(axes, workspace, indices,
                          normalize_by_bin_width=normalize_by_bin_width, axis=axis)
+    kwargs.pop('normalize_by_bin_width', None)
     return x, y, args, kwargs
 
 
@@ -137,6 +138,9 @@ def plot(axes, workspace, *args, **kwargs):
     :param normalization: ``None`` (default) ask the workspace. Applies to MDHisto workspaces. It can override
                           the value from displayNormalizationHisto. It checks only if
                           the normalization is mantid.api.MDNormalization.NumEventsNormalization
+    :param normalize_by_bin_width: ``None`` (default) ask the workspace. It can override
+                          the value from distribution. Is implemented so get_normalize_by_bin_width
+                          only need to be run once.
     :param LogName:   if specified, it will plot the corresponding sample log. The x-axis
                       of the plot is the time difference between the log time and the first
                       value of the `proton_charge` log (if available) or the sample log's
diff --git a/Framework/PythonInterface/mantid/plots/utility.py b/Framework/PythonInterface/mantid/plots/utility.py
index 4e02c746b12961434f6a1d815bab46bf307c7321..2e69e98908026787bb9fc91965b4fe7410910aed 100644
--- a/Framework/PythonInterface/mantid/plots/utility.py
+++ b/Framework/PythonInterface/mantid/plots/utility.py
@@ -11,10 +11,17 @@ from contextlib import contextmanager
 
 from matplotlib import cm
 from matplotlib.container import ErrorbarContainer
+from matplotlib.legend import Legend
 
 from enum import Enum
 
 
+if hasattr(Legend, "set_draggable"):
+    SET_DRAGGABLE_METHOD = "set_draggable"
+else:
+    SET_DRAGGABLE_METHOD = "draggable"
+
+
 # Any changes here must be reflected in the definition in
 # the C++ MplCpp/Plot.h header. See the comment in that file
 # for the reason for duplication.
@@ -117,6 +124,14 @@ def get_autoscale_limits(ax, axis):
         return locator.view_limits(axis_min, axis_max)
 
 
+def legend_set_draggable(legend, state, use_blit=False, update='loc'):
+    """Utility function to support varying Legend api around draggable status across
+    the versions of matplotlib we support. Function arguments match those from matplotlib.
+    See matplotlib documentation for argument descriptions
+    """
+    getattr(legend, SET_DRAGGABLE_METHOD)(state, use_blit, update)
+
+
 def zoom_axis(ax, coord, x_or_y, factor):
     """
     Zoom in around the value 'coord' along the given axis.
diff --git a/Framework/PythonInterface/plugins/algorithms/ConvertWANDSCDtoQ.py b/Framework/PythonInterface/plugins/algorithms/ConvertWANDSCDtoQ.py
index ed5e07670ead025a9bf8ef5cc5e5aa09f4a5ff47..9e5bfc368774507baa6ed6d0330c1ebc82f27c57 100644
--- a/Framework/PythonInterface/plugins/algorithms/ConvertWANDSCDtoQ.py
+++ b/Framework/PythonInterface/plugins/algorithms/ConvertWANDSCDtoQ.py
@@ -86,7 +86,7 @@ class ConvertWANDSCDtoQ(PythonAlgorithm):
         d2 = inWS.getDimension(2)
         number_of_runs = d2.getNBins()
 
-        if (d0.name is not 'y' or d1.name is not 'x' or d2.name != 'scanIndex'):
+        if (d0.name != 'y' or d1.name != 'x' or d2.name != 'scanIndex'):
             issues["InputWorkspace"] = "InputWorkspace has wrong dimensions"
             return issues
 
diff --git a/Framework/PythonInterface/plugins/algorithms/HB2AReduce.py b/Framework/PythonInterface/plugins/algorithms/HB2AReduce.py
index d28ef500fdcab9d5f660162b90255a0e5e1fb20e..817d81c18601df8f9a3da9b9ed49626478374a43 100644
--- a/Framework/PythonInterface/plugins/algorithms/HB2AReduce.py
+++ b/Framework/PythonInterface/plugins/algorithms/HB2AReduce.py
@@ -78,7 +78,7 @@ class HB2AReduce(PythonAlgorithm):
         if not self.getProperty("Filename").value:
             ipts = self.getProperty("IPTS").value
 
-            if ((ipts == Property.EMPTY_INT) or len(self.getProperty("ScanNumbers").value) is 0):
+            if ((ipts == Property.EMPTY_INT) or len(self.getProperty("ScanNumbers").value) == 0):
                 issues["Filename"] = 'Must specify either Filename or IPTS AND ScanNumbers'
 
             if self.getProperty("Exp").value == Property.EMPTY_INT:
diff --git a/Framework/PythonInterface/plugins/algorithms/LoadWANDSCD.py b/Framework/PythonInterface/plugins/algorithms/LoadWANDSCD.py
index 48877bc1139115027314a1b8ef3356129fdae1a2..d5280d8f583b088078c70a194318e1c2d1211e47 100644
--- a/Framework/PythonInterface/plugins/algorithms/LoadWANDSCD.py
+++ b/Framework/PythonInterface/plugins/algorithms/LoadWANDSCD.py
@@ -43,7 +43,7 @@ class LoadWANDSCD(PythonAlgorithm):
         issues = dict()
 
         if not self.getProperty("Filename").value:
-            if (self.getProperty("IPTS").value == Property.EMPTY_INT) or len(self.getProperty("RunNumbers").value) is 0:
+            if (self.getProperty("IPTS").value == Property.EMPTY_INT) or len(self.getProperty("RunNumbers").value) == 0:
                 issues["Filename"] = 'Must specify either Filename or IPTS AND RunNumbers'
 
         return issues
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ISISIndirectDiffractionReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ISISIndirectDiffractionReduction.py
index 9a7fc6d8ea34697f660c80c30edac4ac67805ce5..f26e4a6dc15517e11f4f3160596d43135acc62df 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ISISIndirectDiffractionReduction.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ISISIndirectDiffractionReduction.py
@@ -390,7 +390,7 @@ class ISISIndirectDiffractionReduction(DataProcessorAlgorithm):
         Checks to ensure a calibration file has been given
         and if so performs AlignDetectors and DiffractionFocussing.
         """
-        if self._cal_file is not '':
+        if self._cal_file != '':
             for ws_name in self._workspace_names:
                 AlignDetectors(InputWorkspace=ws_name,
                                OutputWorkspace=ws_name,
diff --git a/Framework/PythonInterface/test/python/mantid/api/MatrixWorkspaceTest.py b/Framework/PythonInterface/test/python/mantid/api/MatrixWorkspaceTest.py
index 5bed2dd3f6475cb1bc735b5915c70af91c728edc..d334cdb21a2dc9d9ea8223a9914fd84ede773205 100644
--- a/Framework/PythonInterface/test/python/mantid/api/MatrixWorkspaceTest.py
+++ b/Framework/PythonInterface/test/python/mantid/api/MatrixWorkspaceTest.py
@@ -458,6 +458,53 @@ class MatrixWorkspaceTest(unittest.TestCase):
         for index in maskedBinsIndices:
             self.assertEqual(1, index)
 
+    def test_rebinnedOutput(self):
+        rebin = WorkspaceFactory.create("RebinnedOutput", 2, 3, 2)
+        self.assertFalse(rebin.nonZeroF())
+        fv = rebin.readF(1)
+        rebin.dataY(1)[:] = 10.0
+        rebin.dataE(1)[:] = 1.0
+        twos = np.ones(len(fv)) * 2.0
+        rebin.setF(1, twos)
+        self.assertTrue(rebin.nonZeroF())
+        rebin.setFinalized(False)
+        rebin.setSqrdErrors(False)
+        rebin.unfinalize()
+        self.assertFalse(rebin.isFinalized())
+        yv = rebin.readY(1)
+        ev = rebin.readE(1)
+        self.assertAlmostEqual(yv[0], 10.0)
+        self.assertAlmostEqual(ev[0], 1.0)
+
+        rebin.finalize(True)
+        self.assertTrue(rebin.isFinalized())
+        self.assertTrue(rebin.hasSqrdErrors())
+        yv = rebin.readY(1)
+        ev = rebin.readE(1)
+        self.assertAlmostEqual(yv[0], 5.0)
+        self.assertAlmostEqual(ev[0], 0.25)
+
+        rebin.finalize(False)
+        self.assertTrue(rebin.isFinalized())
+        self.assertFalse(rebin.hasSqrdErrors())
+        yv = rebin.readY(1)
+        ev = rebin.readE(1)
+        self.assertAlmostEqual(yv[0], 5.0)
+        self.assertAlmostEqual(ev[0], 0.5)
+
+        rebin.unfinalize()
+        self.assertFalse(rebin.isFinalized())
+        yv = rebin.readY(1)
+        ev = rebin.readE(1)
+        self.assertAlmostEqual(yv[0], 10.0)
+        self.assertAlmostEqual(ev[0], 1.0)
+
+        rebin.scaleF(2.0)
+        fv = rebin.readF(1)
+        self.assertAlmostEqual(fv[0], 4.0)
+
+
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/Framework/PythonInterface/test/python/mantid/api/WorkspaceFactoryTest.py b/Framework/PythonInterface/test/python/mantid/api/WorkspaceFactoryTest.py
index 1a8c96c7f2c2a8006f55b59ef75cea703e098e51..9aae031906ca55eab92f740ad840508a7f8b1883 100644
--- a/Framework/PythonInterface/test/python/mantid/api/WorkspaceFactoryTest.py
+++ b/Framework/PythonInterface/test/python/mantid/api/WorkspaceFactoryTest.py
@@ -20,9 +20,9 @@ class WorkspaceFactoryTest(unittest.TestCase):
         return WorkspaceFactory.create("Workspace2D", NVectors=nhist,
                                        XLength=xlength, YLength=ylength)
 
-    def _verify(self, wksp, nhist, xlength, ylength):
+    def _verify(self, wksp, nhist, xlength, ylength, wsId="Workspace2D"):
         self.assertTrue(isinstance(wksp, MatrixWorkspace))
-        self.assertEqual(wksp.id(), "Workspace2D")
+        self.assertEqual(wksp.id(), wsId)
         self.assertEqual(wksp.getNumberHistograms(), nhist)
         self.assertEqual(len(wksp.readX(0)), xlength)
         self.assertEqual(wksp.blocksize(), ylength)
@@ -58,5 +58,12 @@ class WorkspaceFactoryTest(unittest.TestCase):
         peaks = WorkspaceFactory.createPeaks()
         self.assertTrue(isinstance(peaks, IPeaksWorkspace))
 
+    def test_creating_rebinnedoutput(self):
+        rebin = WorkspaceFactory.create("RebinnedOutput", 2, 6, 5)
+        self._verify(rebin, 2, 6, 5, wsId="RebinnedOutput")
+        fv = rebin.readF(1)
+        self.assertEqual(len(fv), 5)
+
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/Framework/PythonInterface/test/python/mantid/plots/CMakeLists.txt b/Framework/PythonInterface/test/python/mantid/plots/CMakeLists.txt
index dfc7e590e48fab793a5be6a9b9fd9423b9ebd128..e62034a5b8d1aa84d48c8f19bc094de220ebbef2 100644
--- a/Framework/PythonInterface/test/python/mantid/plots/CMakeLists.txt
+++ b/Framework/PythonInterface/test/python/mantid/plots/CMakeLists.txt
@@ -3,11 +3,9 @@ add_subdirectory(modest_image)
 # mantid.dataobjects tests
 
 set(TEST_PY_FILES
-  helperfunctionsTest.py
-  plotfunctionsTest.py
-  plotfunctions3DTest.py
-  plots__init__Test.py
-  ScalesTest.py)
+    helperfunctionsTest.py plotfunctionsTest.py plotfunctions3DTest.py
+    plots__init__Test.py ScalesTest.py UtilityTest.py
+)
 
 check_tests_valid(${CMAKE_CURRENT_SOURCE_DIR} ${TEST_PY_FILES})
 
diff --git a/Framework/PythonInterface/test/python/mantid/plots/UtilityTest.py b/Framework/PythonInterface/test/python/mantid/plots/UtilityTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..94d4fd2a3550c3444f8c8e18712c67c786876f0a
--- /dev/null
+++ b/Framework/PythonInterface/test/python/mantid/plots/UtilityTest.py
@@ -0,0 +1,37 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+#  This file is part of the mantid package
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+from __future__ import absolute_import, division
+
+import unittest
+
+from mantid.plots.utility import legend_set_draggable
+from mantid.py3compat.mock import create_autospec
+from matplotlib.legend import Legend
+
+
+class UtilityTest(unittest.TestCase):
+
+    def test_legend_set_draggable(self):
+        legend = create_autospec(Legend)
+        args = (None, False, 'loc')
+        legend_set_draggable(legend, *args)
+
+        if hasattr(Legend, 'set_draggable'):
+            legend.set_draggable.assert_called_with(*args)
+        else:
+            legend.draggable.assert_called_with(*args)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/Framework/SINQ/src/PoldiIndexKnownCompounds.cpp b/Framework/SINQ/src/PoldiIndexKnownCompounds.cpp
index 242f40a4db58c83e47d841b95c2145d2e82bb5f3..894bad112135441a068a5bafcd8031dbb299e446 100644
--- a/Framework/SINQ/src/PoldiIndexKnownCompounds.cpp
+++ b/Framework/SINQ/src/PoldiIndexKnownCompounds.cpp
@@ -14,7 +14,6 @@
 #include "MantidKernel/MandatoryValidator.h"
 #include "MantidSINQ/PoldiUtilities/MillerIndicesIO.h"
 
-#include <boost/bind.hpp>
 #include <numeric>
 
 #include <boost/math/distributions/normal.hpp>
@@ -726,10 +725,9 @@ PoldiPeakCollection_sptr
 PoldiIndexKnownCompounds::getIntensitySortedPeakCollection(
     const PoldiPeakCollection_sptr &peaks) const {
   std::vector<PoldiPeak_sptr> peakVector(peaks->peaks());
-
+  using namespace std::placeholders;
   std::sort(peakVector.begin(), peakVector.end(),
-            boost::bind<bool>(&PoldiPeak::greaterThan, _1, _2,
-                              &PoldiPeak::intensity));
+            std::bind(&PoldiPeak::greaterThan, _1, _2, &PoldiPeak::intensity));
 
   PoldiPeakCollection_sptr sortedPeaks =
       boost::make_shared<PoldiPeakCollection>(peaks->intensityType());
diff --git a/Framework/SINQ/src/PoldiPeakSearch.cpp b/Framework/SINQ/src/PoldiPeakSearch.cpp
index f0a2e6f16dedf29387c966d1455cacce9334112e..abf27d49b0da431b57472010007fc94310eea3d7 100644
--- a/Framework/SINQ/src/PoldiPeakSearch.cpp
+++ b/Framework/SINQ/src/PoldiPeakSearch.cpp
@@ -18,7 +18,6 @@
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidDataObjects/Workspace2D.h"
 
-#include "boost/bind.hpp"
 #include <algorithm>
 #include <list>
 #include <numeric>
@@ -634,10 +633,11 @@ void PoldiPeakSearch::exec() {
   }
 
   std::vector<PoldiPeak_sptr> intensityFilteredPeaks(peakCoordinates.size());
+  using namespace std::placeholders;
   auto newEnd = std::remove_copy_if(
       peakCoordinates.begin(), peakCoordinates.end(),
       intensityFilteredPeaks.begin(),
-      boost::bind(&PoldiPeakSearch::isLessThanMinimum, this, _1));
+      std::bind(&PoldiPeakSearch::isLessThanMinimum, this, _1));
   intensityFilteredPeaks.resize(
       std::distance(intensityFilteredPeaks.begin(), newEnd));
 
@@ -646,8 +646,7 @@ void PoldiPeakSearch::exec() {
                       << "): " << intensityFilteredPeaks.size() << '\n';
 
   std::sort(intensityFilteredPeaks.begin(), intensityFilteredPeaks.end(),
-            boost::bind<bool>(&PoldiPeak::greaterThan, _1, _2,
-                              &PoldiPeak::intensity));
+            std::bind(&PoldiPeak::greaterThan, _1, _2, &PoldiPeak::intensity));
 
   for (std::vector<PoldiPeak_sptr>::const_iterator peak =
            intensityFilteredPeaks.begin();
diff --git a/Framework/SINQ/src/PoldiUtilities/PoldiAutoCorrelationCore.cpp b/Framework/SINQ/src/PoldiUtilities/PoldiAutoCorrelationCore.cpp
index 9bfd8237ff9b6e2295d796e630611ddbc64a552c..8f29752f44fcb2bbebb7ae0b5db9f7df622dd9aa 100644
--- a/Framework/SINQ/src/PoldiUtilities/PoldiAutoCorrelationCore.cpp
+++ b/Framework/SINQ/src/PoldiUtilities/PoldiAutoCorrelationCore.cpp
@@ -10,7 +10,6 @@
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidKernel/Logger.h"
 #include "MantidKernel/MultiThreaded.h"
-#include "boost/bind.hpp"
 #include <algorithm>
 #include <numeric>
 #include <utility>
@@ -25,6 +24,7 @@ namespace Mantid {
 namespace Poldi {
 
 using namespace API;
+using namespace std::placeholders;
 
 PoldiAutoCorrelationCore::PoldiAutoCorrelationCore(Kernel::Logger &g_log)
     : m_detector(), m_chopper(), m_wavelengthRange(), m_deltaT(), m_deltaD(),
@@ -210,11 +210,10 @@ DataObjects::Workspace2D_sptr PoldiAutoCorrelationCore::calculate(
 
     m_logger.information() << "  Correcting intensities...\n";
     std::vector<double> correctedCorrelatedIntensities(dValues.size());
-    std::transform(rawCorrelatedIntensities.begin(),
-                   rawCorrelatedIntensities.end(), m_weightsForD.begin(),
-                   correctedCorrelatedIntensities.rbegin(),
-                   boost::bind(&PoldiAutoCorrelationCore::correctedIntensity,
-                               this, _1, _2));
+    std::transform(
+        rawCorrelatedIntensities.begin(), rawCorrelatedIntensities.end(),
+        m_weightsForD.begin(), correctedCorrelatedIntensities.rbegin(),
+        std::bind(&PoldiAutoCorrelationCore::correctedIntensity, this, _1, _2));
 
     /* The algorithm performs some finalization. In the default case the
      * spectrum is
@@ -315,8 +314,8 @@ PoldiAutoCorrelationCore::getRawCorrelatedIntensity(double dValue,
        */
       std::vector<UncertainValue> cmess(m_detector->elementCount());
       std::transform(m_indices.begin(), m_indices.end(), cmess.begin(),
-                     boost::bind(&PoldiAutoCorrelationCore::getCMessAndCSigma,
-                                 this, dValue, slitOffset, _1));
+                     std::bind(&PoldiAutoCorrelationCore::getCMessAndCSigma,
+                               this, dValue, slitOffset, _1));
 
       UncertainValue sum =
           std::accumulate(cmess.begin(), cmess.end(), UncertainValue(0.0, 0.0),
@@ -594,7 +593,7 @@ std::vector<double> PoldiAutoCorrelationCore::getTofsFor1Angstrom(
   // Map element indices to 2Theta-Values
   std::vector<double> twoThetas(elements.size());
   std::transform(elements.begin(), elements.end(), twoThetas.begin(),
-                 boost::bind(&PoldiAbstractDetector::twoTheta, m_detector, _1));
+                 std::bind(&PoldiAbstractDetector::twoTheta, m_detector, _1));
 
   // We will need sin(Theta) anyway, so we might just calculate those as well
   std::vector<double> sinThetas;
@@ -612,7 +611,7 @@ std::vector<double> PoldiAutoCorrelationCore::getTofsFor1Angstrom(
   std::vector<double> tofFor1Angstrom(elements.size());
   std::transform(distances.begin(), distances.end(), sinThetas.begin(),
                  tofFor1Angstrom.begin(),
-                 boost::bind(&Conversions::dtoTOF, 1.0, _1, _2));
+                 std::bind(&Conversions::dtoTOF, 1.0, _1, _2));
 
   return tofFor1Angstrom;
 }
diff --git a/Framework/SINQ/src/PoldiUtilities/PoldiBasicChopper.cpp b/Framework/SINQ/src/PoldiUtilities/PoldiBasicChopper.cpp
index 82238841208a0396235fa587f8850a2bbacf28bd..0268730416c44e1ba7ec3037c0f3b62f6012b2be 100644
--- a/Framework/SINQ/src/PoldiUtilities/PoldiBasicChopper.cpp
+++ b/Framework/SINQ/src/PoldiUtilities/PoldiBasicChopper.cpp
@@ -7,7 +7,6 @@
 #include "MantidSINQ/PoldiUtilities/PoldiBasicChopper.h"
 
 #include "MantidGeometry/ICompAssembly.h"
-#include "boost/bind.hpp"
 
 namespace Mantid {
 namespace Poldi {
@@ -80,9 +79,10 @@ void PoldiBasicChopper::initializeVariableParameters(double rotationSpeed) {
   m_zeroOffset = m_rawt0 * m_cycleTime + m_rawt0const;
 
   m_slitTimes.resize(m_slitPositions.size());
+  using namespace std::placeholders;
   std::transform(
       m_slitPositions.begin(), m_slitPositions.end(), m_slitTimes.begin(),
-      boost::bind(&PoldiBasicChopper::slitPositionToTimeFraction, this, _1));
+      std::bind(&PoldiBasicChopper::slitPositionToTimeFraction, this, _1));
 }
 
 double PoldiBasicChopper::slitPositionToTimeFraction(double slitPosition) {
diff --git a/Framework/SINQ/src/PoldiUtilities/PoldiDeadWireDecorator.cpp b/Framework/SINQ/src/PoldiUtilities/PoldiDeadWireDecorator.cpp
index 4995383a2fa21a95b9c0774b25466e59adebe3ab..abdcc3da2fb7859a7928974644644391b849f303 100644
--- a/Framework/SINQ/src/PoldiUtilities/PoldiDeadWireDecorator.cpp
+++ b/Framework/SINQ/src/PoldiUtilities/PoldiDeadWireDecorator.cpp
@@ -7,7 +7,6 @@
 #include "MantidSINQ/PoldiUtilities/PoldiDeadWireDecorator.h"
 #include "MantidGeometry/Instrument/DetectorInfo.h"
 
-#include "boost/bind.hpp"
 #include <algorithm>
 
 namespace Mantid {
@@ -74,9 +73,10 @@ PoldiDeadWireDecorator::getGoodElements(std::vector<int> rawElements) {
     size_t newElementCount = rawElements.size() - m_deadWireSet.size();
 
     std::vector<int> goodElements(newElementCount);
+    using namespace std::placeholders;
     std::remove_copy_if(
         rawElements.begin(), rawElements.end(), goodElements.begin(),
-        boost::bind(&PoldiDeadWireDecorator::isDeadElement, this, _1));
+        std::bind(&PoldiDeadWireDecorator::isDeadElement, this, _1));
 
     return goodElements;
   }
diff --git a/Framework/SINQ/src/PoldiUtilities/PoldiPeak.cpp b/Framework/SINQ/src/PoldiUtilities/PoldiPeak.cpp
index 72f914739e5f3d86bacbf4a978e80b19ba5045ee..c65cab3396d38b68b0d3adf514d81dd4a163e194 100644
--- a/Framework/SINQ/src/PoldiUtilities/PoldiPeak.cpp
+++ b/Framework/SINQ/src/PoldiUtilities/PoldiPeak.cpp
@@ -6,7 +6,6 @@
 // SPDX - License - Identifier: GPL - 3.0 +
 #include "MantidSINQ/PoldiUtilities/PoldiPeak.h"
 
-#include "boost/bind.hpp"
 #include <cmath>
 #include <stdexcept>
 
@@ -132,15 +131,15 @@ PoldiPeak_sptr PoldiPeak::create(MillerIndices hkl, UncertainValue dValue,
 bool PoldiPeak::greaterThan(const PoldiPeak_sptr &first,
                             const PoldiPeak_sptr &second,
                             UncertainValue (PoldiPeak::*function)() const) {
-  return static_cast<double>(boost::bind(function, first.get())()) >
-         static_cast<double>(boost::bind(function, second.get())());
+  return static_cast<double>(std::bind(function, first.get())()) >
+         static_cast<double>(std::bind(function, second.get())());
 }
 
 bool PoldiPeak::lessThan(const PoldiPeak_sptr &first,
                          const PoldiPeak_sptr &second,
                          UncertainValue (PoldiPeak::*function)() const) {
-  return static_cast<double>(boost::bind(function, first.get())()) <
-         static_cast<double>(boost::bind(function, second.get())());
+  return static_cast<double>(std::bind(function, first.get())()) <
+         static_cast<double>(std::bind(function, second.get())());
 }
 
 PoldiPeak::PoldiPeak(UncertainValue d, UncertainValue intensity,
diff --git a/Framework/SINQ/test/PoldiPeakCollectionTest.h b/Framework/SINQ/test/PoldiPeakCollectionTest.h
index 2ed9ec100621aa3477275fdaa1341248f2288c3f..3047ea888b90ef65d91ed7280d36e41f0cf621a7 100644
--- a/Framework/SINQ/test/PoldiPeakCollectionTest.h
+++ b/Framework/SINQ/test/PoldiPeakCollectionTest.h
@@ -21,7 +21,6 @@
 #include "MantidGeometry/Crystal/ReflectionGenerator.h"
 #include "MantidGeometry/Crystal/SpaceGroupFactory.h"
 
-#include <boost/bind.hpp>
 #include <stdexcept>
 
 using namespace Mantid::Poldi;
@@ -29,6 +28,7 @@ using namespace Mantid::API;
 using namespace Mantid::DataObjects;
 using namespace Mantid::Kernel;
 using namespace Mantid::Geometry;
+using namespace std::placeholders;
 
 class PoldiPeakCollectionTest;
 
@@ -359,9 +359,8 @@ public:
     std::vector<PoldiPeak_sptr> poldiPeaks = p.peaks();
 
     // sort peak list and check that all peaks are within the limits
-    std::sort(
-        poldiPeaks.begin(), poldiPeaks.end(),
-        boost::bind<bool>(&PoldiPeak::greaterThan, _1, _2, &PoldiPeak::d));
+    std::sort(poldiPeaks.begin(), poldiPeaks.end(),
+              std::bind(&PoldiPeak::greaterThan, _1, _2, &PoldiPeak::d));
 
     TS_ASSERT_LESS_THAN_EQUALS(poldiPeaks[0]->d(), 5.0);
     TS_ASSERT_LESS_THAN_EQUALS(0.55, poldiPeaks[68]->d());
diff --git a/Framework/SINQ/test/PoldiPeakTest.h b/Framework/SINQ/test/PoldiPeakTest.h
index bf58d9a5e7fe3fcd73d4a88140018ee9e5b91cd0..14dc89ba4733d69c1def2c6fca372ddccda2623f 100644
--- a/Framework/SINQ/test/PoldiPeakTest.h
+++ b/Framework/SINQ/test/PoldiPeakTest.h
@@ -9,11 +9,11 @@
 
 #include "MantidSINQ/PoldiUtilities/MillerIndices.h"
 #include "MantidSINQ/PoldiUtilities/PoldiPeak.h"
-#include "boost/bind.hpp"
 #include <cxxtest/TestSuite.h>
 #include <stdexcept>
 
 using namespace Mantid::Poldi;
+using namespace std::placeholders;
 
 class PoldiPeakTest : public CxxTest::TestSuite {
 public:
@@ -143,16 +143,15 @@ public:
     peaks.emplace_back(PoldiPeak::create(2.0, 20.0));
     peaks.emplace_back(PoldiPeak::create(3.0, 800.0));
 
-    std::sort(
-        peaks.begin(), peaks.end(),
-        boost::bind<bool>(&PoldiPeak::greaterThan, _1, _2, &PoldiPeak::q));
+    std::sort(peaks.begin(), peaks.end(),
+              std::bind(&PoldiPeak::greaterThan, _1, _2, &PoldiPeak::q));
     TS_ASSERT_EQUALS(peaks[0]->q(), 3.0);
     TS_ASSERT_EQUALS(peaks[1]->q(), 2.0);
     TS_ASSERT_EQUALS(peaks[2]->q(), 1.0);
 
-    std::sort(peaks.begin(), peaks.end(),
-              boost::bind<bool>(&PoldiPeak::greaterThan, _1, _2,
-                                &PoldiPeak::intensity));
+    std::sort(
+        peaks.begin(), peaks.end(),
+        std::bind(&PoldiPeak::greaterThan, _1, _2, &PoldiPeak::intensity));
     TS_ASSERT_EQUALS(peaks[0]->q(), 3.0);
     TS_ASSERT_EQUALS(peaks[1]->q(), 1.0);
     TS_ASSERT_EQUALS(peaks[2]->q(), 2.0);
@@ -165,14 +164,13 @@ public:
     peaks.emplace_back(PoldiPeak::create(3.0, 800.0));
 
     std::sort(peaks.begin(), peaks.end(),
-              boost::bind<bool>(&PoldiPeak::lessThan, _1, _2, &PoldiPeak::q));
+              std::bind(&PoldiPeak::lessThan, _1, _2, &PoldiPeak::q));
     TS_ASSERT_EQUALS(peaks[0]->q(), 1.0);
     TS_ASSERT_EQUALS(peaks[1]->q(), 2.0);
     TS_ASSERT_EQUALS(peaks[2]->q(), 3.0);
 
-    std::sort(
-        peaks.begin(), peaks.end(),
-        boost::bind<bool>(&PoldiPeak::lessThan, _1, _2, &PoldiPeak::intensity));
+    std::sort(peaks.begin(), peaks.end(),
+              std::bind(&PoldiPeak::lessThan, _1, _2, &PoldiPeak::intensity));
     TS_ASSERT_EQUALS(peaks[0]->q(), 2.0);
     TS_ASSERT_EQUALS(peaks[1]->q(), 1.0);
     TS_ASSERT_EQUALS(peaks[2]->q(), 3.0);
diff --git a/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp b/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp
index 1214b02df26391c7df8834cafd7a71a82819df1c..04a8c90d5ff1b095d7e438e43efa579cff40b4e5 100644
--- a/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp
+++ b/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp
@@ -1278,13 +1278,14 @@ RebinnedOutput_sptr createRebinnedOutputWorkspace() {
   // Set representation
   outputWS->finalize();
 
-  // Make errors squared rooted
+  // Make errors squared rooted and set sqrd err flag
   for (int i = 0; i < numHist; ++i) {
     auto &mutableE = outputWS->mutableE(i);
     for (int j = 0; j < numX - 1; ++j) {
       mutableE[j] = std::sqrt(mutableE[j]);
     }
   }
+  outputWS->setSqrdErrors(false);
 
   return outputWS;
 }
diff --git a/Framework/WorkflowAlgorithms/src/SofTwoThetaTOF.cpp b/Framework/WorkflowAlgorithms/src/SofTwoThetaTOF.cpp
index 4c2a50fc97a7a7c16dfcfce0a3086da90e6e5219..2bccf31cd4a0eff2404d80760aaf2bf8b573b359 100644
--- a/Framework/WorkflowAlgorithms/src/SofTwoThetaTOF.cpp
+++ b/Framework/WorkflowAlgorithms/src/SofTwoThetaTOF.cpp
@@ -198,13 +198,7 @@ SofTwoThetaTOF::groupByTwoTheta(API::MatrixWorkspace_sptr &ws,
     auto tempPath = boost::filesystem::temp_directory_path();
     tempPath /= boost::filesystem::unique_path(
         "detector-grouping-%%%%-%%%%-%%%%-%%%%.xml");
-#ifdef _WIN32
-    // A dirty way to convert a wstring to string.
-    auto const wfilename = tempPath.native();
-    filename = std::string(wfilename.cbegin(), wfilename.cend());
-#else
-    filename = tempPath.native();
-#endif
+    filename = tempPath.string();
     generateGrouping->setProperty("GenerateParFile", false);
     // Make sure the file gets deleted at scope exit.
     // enable cppcheck-suppress unreadVariable if needed
diff --git a/Framework/WorkflowAlgorithms/test/SofTwoThetaTOFTest.h b/Framework/WorkflowAlgorithms/test/SofTwoThetaTOFTest.h
index 2264c1d80563172a5c6d15ff8eb09ecd002f20b7..2b0504e2f579857c03711a8ea47986bcd797db13 100644
--- a/Framework/WorkflowAlgorithms/test/SofTwoThetaTOFTest.h
+++ b/Framework/WorkflowAlgorithms/test/SofTwoThetaTOFTest.h
@@ -98,12 +98,7 @@ public:
     TS_ASSERT_THROWS_NOTHING(alg.setProperty("AngleStep", angleStep))
     auto tempXml = boost::filesystem::temp_directory_path();
     tempXml /= boost::filesystem::unique_path("SofTwoThetaTest-%%%%%%%%.xml");
-#if _WIN32
-    auto const wfilename = tempXml.native();
-    std::string const filename{wfilename.cbegin(), wfilename.cend()};
-#else
-    std::string const filename{tempXml.native()};
-#endif
+    std::string const filename{tempXml.string()};
     TS_ASSERT_THROWS_NOTHING(alg.setProperty("GroupingFilename", filename))
     TS_ASSERT_THROWS_NOTHING(alg.execute())
     TS_ASSERT(alg.isExecuted())
diff --git a/MantidPlot/ipython_widget/mantid_ipython_widget.py b/MantidPlot/ipython_widget/mantid_ipython_widget.py
index 69c4164872225dc0c68980d134ae7c8afa57f93f..1db19db04451d36f6222875d0e3f21346218eff4 100644
--- a/MantidPlot/ipython_widget/mantid_ipython_widget.py
+++ b/MantidPlot/ipython_widget/mantid_ipython_widget.py
@@ -7,6 +7,7 @@
 from __future__ import (absolute_import, division,
                         print_function)
 
+import sys
 import threading
 import types
 import warnings
@@ -36,6 +37,13 @@ except ImportError:
     from IPython.qt.inprocess import QtInProcessKernelManager
 
 
+if sys.version_info.major >= 3 and sys.platform == 'win32':
+    # Tornado requires WindowsSelectorEventLoop
+    # https://www.tornadoweb.org/en/stable/#installation
+    import asyncio
+    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
+
+
 def our_run_code(self, code_obj, result=None, async_=False):
     """ Method with which we replace the run_code method of IPython's InteractiveShell class.
         It calls the original method (renamed to ipython_run_code) on a separate thread
diff --git a/MantidPlot/src/PythonScripting.cpp b/MantidPlot/src/PythonScripting.cpp
index 6daa948f8febaba6135b305e93840b2d5e308d79..b1f4d80d1759d23f657ec161eb968df199be2e14 100644
--- a/MantidPlot/src/PythonScripting.cpp
+++ b/MantidPlot/src/PythonScripting.cpp
@@ -272,14 +272,22 @@ void PythonScripting::setupSip() {
   // Our use of the IPython console requires that we use the v2 api for these
   // PyQt types. This has to be set before the very first import of PyQt
   // which happens on importing _qti
-  PyObject *sipmod = PyImport_ImportModule("sip");
+  // Some environments now have a private sip module inside PyQt itself. Try
+  // this first.
+  PyObject *sipmod = PyImport_ImportModule("PyQt4.sip");
+  if (!sipmod) {
+    PyErr_Clear();
+    sipmod = PyImport_ImportModule("sip");
+  }
   if (sipmod) {
     constexpr std::array<const char *, 7> v2Types = {
         {"QString", "QVariant", "QDate", "QDateTime", "QTextStream", "QTime",
          "QUrl"}};
     for (const auto &className : v2Types) {
-      PyObject_CallMethod(sipmod, STR_LITERAL("setapi"), STR_LITERAL("(si)"),
-                          className, 2);
+      auto result = PyObject_CallMethod(sipmod, STR_LITERAL("setapi"),
+                                        STR_LITERAL("(si)"), className, 2);
+      if (!result)
+        PyErr_Print();
     }
     Py_DECREF(sipmod);
   }
diff --git a/Testing/Data/UnitTest/ILL/D33/001461.nxs.md5 b/Testing/Data/UnitTest/ILL/D33/001461.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..80021c9e2505b690b0ab5e0834c895de7a297b82
--- /dev/null
+++ b/Testing/Data/UnitTest/ILL/D33/001461.nxs.md5
@@ -0,0 +1 @@
+6d3c25f1089e4a4a4695ce06f7712d94
diff --git a/Testing/Data/UnitTest/ILL/D33/001462.nxs.md5 b/Testing/Data/UnitTest/ILL/D33/001462.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..6330f852e1b51bd98727787f0599636ac6d9a683
--- /dev/null
+++ b/Testing/Data/UnitTest/ILL/D33/001462.nxs.md5
@@ -0,0 +1 @@
+a70fb3deb0246a0486ea1e2835aad8ff
diff --git a/Testing/Data/UnitTest/ILL/D33/001463.nxs.md5 b/Testing/Data/UnitTest/ILL/D33/001463.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..988690de860773a1c9563db3f34e86726c77419c
--- /dev/null
+++ b/Testing/Data/UnitTest/ILL/D33/001463.nxs.md5
@@ -0,0 +1 @@
+a927d5ee32d5cf2b37357ec841880e79
diff --git a/Testing/Data/UnitTest/ILL/D33/001464.nxs.md5 b/Testing/Data/UnitTest/ILL/D33/001464.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..bf25fa93c896d99afbb5a945e77ee8d946e52806
--- /dev/null
+++ b/Testing/Data/UnitTest/ILL/D33/001464.nxs.md5
@@ -0,0 +1 @@
+15d724f3c364d0c51e11dd844b414caa
diff --git a/Testing/Data/UnitTest/ILL/D33/002192.nxs.md5 b/Testing/Data/UnitTest/ILL/D33/002192.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..cc91fb049e64ceadd455b0a6223ce5a16a7d7e8a
--- /dev/null
+++ b/Testing/Data/UnitTest/ILL/D33/002192.nxs.md5
@@ -0,0 +1 @@
+399c6d0e14b4e4c306dec30e7e61d924
diff --git a/Testing/Data/UnitTest/ILL/D33/002193.nxs.md5 b/Testing/Data/UnitTest/ILL/D33/002193.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..291f2cf0aff02ca5f2c7d566e9d375d4f79f817a
--- /dev/null
+++ b/Testing/Data/UnitTest/ILL/D33/002193.nxs.md5
@@ -0,0 +1 @@
+30ef0d0c320b13f0cea1b8a58ba74209
diff --git a/Testing/Data/UnitTest/ILL/D33/002194.nxs.md5 b/Testing/Data/UnitTest/ILL/D33/002194.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..2b7173d560c9df6e8fd1f6ba5cb449f61cdb8e0e
--- /dev/null
+++ b/Testing/Data/UnitTest/ILL/D33/002194.nxs.md5
@@ -0,0 +1 @@
+888e1167c70707a1f41cee549497d279
diff --git a/Testing/Data/UnitTest/ILL/D33/002195.nxs.md5 b/Testing/Data/UnitTest/ILL/D33/002195.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..4c733030ed28c61ee05fe37468a51871c3b9616b
--- /dev/null
+++ b/Testing/Data/UnitTest/ILL/D33/002195.nxs.md5
@@ -0,0 +1 @@
+9da522d825f2635e9b2db0e142ffc9b0
diff --git a/Testing/Data/UnitTest/ILL/D33/002196.nxs.md5 b/Testing/Data/UnitTest/ILL/D33/002196.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..3b94d7332c80705eeb053963ce481627bbf7e942
--- /dev/null
+++ b/Testing/Data/UnitTest/ILL/D33/002196.nxs.md5
@@ -0,0 +1 @@
+7cf2136e714921a550ddc7b45893359b
diff --git a/Testing/Data/UnitTest/ILL/D33/002197.nxs.md5 b/Testing/Data/UnitTest/ILL/D33/002197.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..121a275a5f62d1e6d1ec35aafb6fbc2085d13384
--- /dev/null
+++ b/Testing/Data/UnitTest/ILL/D33/002197.nxs.md5
@@ -0,0 +1 @@
+c0e1e220f65add45a92da0c085dd6f99
diff --git a/Testing/Data/UnitTest/ILL/D33/002219.nxs.md5 b/Testing/Data/UnitTest/ILL/D33/002219.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..e34d64d8030c12256ff9147fce6fd453411c1cf4
--- /dev/null
+++ b/Testing/Data/UnitTest/ILL/D33/002219.nxs.md5
@@ -0,0 +1 @@
+3747d9d616291677957e9117ea9f20ff
diff --git a/Testing/Data/UnitTest/ILL/D33/002227.nxs.md5 b/Testing/Data/UnitTest/ILL/D33/002227.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..797325d3b70a6b67f7a4d8b2a6234b34bb07fb95
--- /dev/null
+++ b/Testing/Data/UnitTest/ILL/D33/002227.nxs.md5
@@ -0,0 +1 @@
+a47bd3b799fc84b0c825aba8b97a4b9b
diff --git a/Testing/Data/UnitTest/ILL/D33/002228.nxs.md5 b/Testing/Data/UnitTest/ILL/D33/002228.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..1cdb5358de99c1573cab4cdaaf2b03de99dd30c9
--- /dev/null
+++ b/Testing/Data/UnitTest/ILL/D33/002228.nxs.md5
@@ -0,0 +1 @@
+395afdae589448ebc0e7ce923e3fbf28
diff --git a/Testing/Data/UnitTest/ILL/D33/002229.nxs.md5 b/Testing/Data/UnitTest/ILL/D33/002229.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..1ca4e5ed75e9d74a3d4b66f8b7bd3bc6ecd0c139
--- /dev/null
+++ b/Testing/Data/UnitTest/ILL/D33/002229.nxs.md5
@@ -0,0 +1 @@
+ad565110c454020a6e7ba1022ad72fc4
diff --git a/Testing/Data/UnitTest/ILL/D33/D33Mask2.nxs.md5 b/Testing/Data/UnitTest/ILL/D33/D33Mask2.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..e0a24a53a262dcf629bdec596a2e4f2b822a57c2
--- /dev/null
+++ b/Testing/Data/UnitTest/ILL/D33/D33Mask2.nxs.md5
@@ -0,0 +1 @@
+6b8ba52f6e2fb676efbca0cf63dd12c7
diff --git a/Testing/SystemTests/lib/systemtests/systemtesting.py b/Testing/SystemTests/lib/systemtests/systemtesting.py
index bdc5a0c7cd8bd73da0c72797f3cc818401381660..8f5a5fe5e2e115798df92de6524c69aa430a292a 100644
--- a/Testing/SystemTests/lib/systemtests/systemtesting.py
+++ b/Testing/SystemTests/lib/systemtests/systemtesting.py
@@ -1036,7 +1036,7 @@ class TestManager(object):
                 mod_attrs = dir(mod)
                 for key in mod_attrs:
                     value = getattr(mod, key)
-                    if key is "MantidSystemTest" or not inspect.isclass(value):
+                    if key == "MantidSystemTest" or not inspect.isclass(value):
                         continue
                     if self.isValidTestClass(value):
                         test_name = key
diff --git a/Testing/SystemTests/tests/analysis/ISIS_PowderPolarisTest.py b/Testing/SystemTests/tests/analysis/ISIS_PowderPolarisTest.py
index d9b270d9a4bb3fc0a0726af3a404275ba13411dd..6dd9274baf60471f5f1d76ac3164604c70b22ea8 100644
--- a/Testing/SystemTests/tests/analysis/ISIS_PowderPolarisTest.py
+++ b/Testing/SystemTests/tests/analysis/ISIS_PowderPolarisTest.py
@@ -211,12 +211,31 @@ class TotalScatteringRebinTest(systemtesting.MantidSystemTest):
         self.assertAlmostEqual(self.pdf_output.dataX(0).size, 128, places=3)
 
 
-def run_total_scattering(run_number, merge_banks, q_lims=None, output_binning=None):
+class TotalScatteringPdfTypeTest(systemtesting.MantidSystemTest):
+
+    pdf_output = None
+
+    def runTest(self):
+        setup_mantid_paths()
+        # Load Focused ws
+        mantid.LoadNexus(Filename=total_scattering_input_file, OutputWorkspace='98533-Results-TOF-Grp')
+        q_lims = np.array([2.5, 3, 4, 6, 7, 3.5, 5, 7, 11, 40]).reshape((2, 5))
+        self.pdf_output = run_total_scattering('98533', True, q_lims=q_lims, pdf_type="g(r)")
+
+    def validate(self):
+        # Whilst total scattering is in development, the validation will avoid using reference files as they will have
+        # to be updated very frequently. In the meantime, the expected peak in the PDF at ~3.9 Angstrom will be checked.
+        # After rebin this is at X index 37
+        self.assertAlmostEqual(self.pdf_output.dataY(0)[37], 1.0152123, places=3)
+
+
+def run_total_scattering(run_number, merge_banks, q_lims=None, output_binning=None, pdf_type="G(r)"):
     pdf_inst_obj = setup_inst_object(mode="PDF")
     return pdf_inst_obj.create_total_scattering_pdf(run_number=run_number,
                                                     merge_banks=merge_banks,
                                                     q_lims=q_lims,
-                                                    output_binning=output_binning)
+                                                    output_binning=output_binning,
+                                                    pdf_type=pdf_type)
 
 
 def _gen_required_files():
diff --git a/Testing/SystemTests/tests/analysis/ValidateFacilitiesFile.py b/Testing/SystemTests/tests/analysis/ValidateFacilitiesFile.py
deleted file mode 100644
index df511c193dada8a86ecc32843cacf87d58de6778..0000000000000000000000000000000000000000
--- a/Testing/SystemTests/tests/analysis/ValidateFacilitiesFile.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Mantid Repository : https://github.com/mantidproject/mantid
-#
-# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
-#     NScD Oak Ridge National Laboratory, European Spallation Source
-#     & Institut Laue - Langevin
-# SPDX - License - Identifier: GPL - 3.0 +
-#pylint: disable=no-init,invalid-name
-from __future__ import (absolute_import, division, print_function)
-from mantid import config
-import os
-import systemtesting
-
-
-EXPECTED_EXT = '.expected'
-
-
-class ValidateFacilitiesFile(systemtesting.MantidSystemTest):
-
-    def skipTests(self):
-        try:
-            import minixsv # noqa
-        except ImportError:
-            return True
-        return False
-
-    def runTest(self):
-        """Main entry point for the test suite"""
-        from minixsv import pyxsval
-        direc = config['instrumentDefinition.directory']
-        filename = os.path.join(direc,'Facilities.xml')
-        xsdFile =  os.path.join(direc,'Schema/Facilities/1.0/','FacilitiesSchema.xsd')
-
-        # run the tests
-        failed = []
-        try:
-            print("----------------------------------------")
-            print("Validating Facilities.xml")
-            pyxsval.parseAndValidateXmlInput(filename, xsdFile=xsdFile, validateSchema=0)
-        except Exception as e:
-            print("VALIDATION OF Facilities.xml FAILED WITH ERROR:")
-            print(e)
-            failed.append(filename)
-
-        # final say on whether or not it 'worked'
-        print("----------------------------------------")
-        if len(failed) != 0:
-            print("SUMMARY OF FAILED FILES")
-            raise RuntimeError("Failed Validation of Facilities.xml")
-        else:
-            print("Successfully Validated Facilities.xml")
diff --git a/Testing/SystemTests/tests/analysis/ValidateGroupingFiles.py b/Testing/SystemTests/tests/analysis/ValidateGroupingFiles.py
deleted file mode 100644
index c1e72fc4e27c3891c04fc6d52f3182ad51e889f8..0000000000000000000000000000000000000000
--- a/Testing/SystemTests/tests/analysis/ValidateGroupingFiles.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Mantid Repository : https://github.com/mantidproject/mantid
-#
-# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
-#     NScD Oak Ridge National Laboratory, European Spallation Source
-#     & Institut Laue - Langevin
-# SPDX - License - Identifier: GPL - 3.0 +
-#pylint: disable=no-init
-from __future__ import (absolute_import, division, print_function)
-from mantid import config
-import os
-import systemtesting
-import glob
-
-EXPECTED_EXT = '.expected'
-
-
-class ValidateGroupingFiles(systemtesting.MantidSystemTest):
-
-    xsdFile =''
-
-    def skipTests(self):
-        try:
-            import minixsv # noqa
-        except ImportError:
-            return True
-        return False
-
-    def __getDataFileList__(self):
-        # get a list of directories to look in
-        direc = config['instrumentDefinition.directory']
-        direc =  os.path.join(direc,'Grouping')
-        print("Looking for Grouping files in: %s" % direc)
-        cwd = os.getcwd()
-        os.chdir(direc)
-        myFiles = glob.glob("*Grouping*.xml")
-        os.chdir(cwd)
-        files = []
-        for filename in myFiles:
-            files.append(os.path.join(direc, filename))
-        return files
-
-    def runTest(self):
-        """Main entry point for the test suite"""
-        from minixsv import pyxsval
-        direc = config['instrumentDefinition.directory']
-        self.xsdFile =  os.path.join(direc,'Schema/Grouping/1.0/','GroupingSchema.xsd')
-        files = self.__getDataFileList__()
-
-        # run the tests
-        failed = []
-        for filename in files:
-            try:
-                print("----------------------------------------")
-                print("Validating '%s'" % filename)
-                pyxsval.parseAndValidateXmlInput(filename, xsdFile=self.xsdFile, validateSchema=0)
-            except Exception as err:
-                print("VALIDATION OF '%s' FAILED WITH ERROR:" % filename)
-                print(err)
-                failed.append(filename)
-
-        # final say on whether or not it 'worked'
-        print("----------------------------------------")
-        if len(failed) != 0:
-            print("SUMMARY OF FAILED FILES")
-            for filename in failed:
-                print(filename)
-            raise RuntimeError("Failed Validation for %d of %d files"
-                               % (len(failed), len(files)))
-        else:
-            print("Successfully Validated %d files" % len(files))
diff --git a/Testing/SystemTests/tests/analysis/ValidateInstrumentDefinitionFiles.py b/Testing/SystemTests/tests/analysis/ValidateInstrumentDefinitionFiles.py
deleted file mode 100644
index 0f68e5f18086381b618323d457327c6a7b911992..0000000000000000000000000000000000000000
--- a/Testing/SystemTests/tests/analysis/ValidateInstrumentDefinitionFiles.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# Mantid Repository : https://github.com/mantidproject/mantid
-#
-# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
-#     NScD Oak Ridge National Laboratory, European Spallation Source
-#     & Institut Laue - Langevin
-# SPDX - License - Identifier: GPL - 3.0 +
-#pylint: disable=invalid-name
-#pylint: disable=no-init
-from __future__ import (absolute_import, division, print_function)
-from mantid import config
-import os
-import systemtesting
-import glob
-
-
-EXPECTED_EXT = '.expected'
-
-
-class ValidateInstrumentDefinitionFiles(systemtesting.MantidSystemTest):
-
-    xsdFile=''
-    # Explicitly specify single file to test. If None, test all.
-    theFileToTest=None #"MARI_Definition.xml"
-
-    def skipTests(self):
-        try:
-            from genxmlif import GenXmlIfError # noqa
-            from minixsv import pyxsval # noqa
-        except ImportError:
-            return True
-        return False
-
-    def __getDataFileList__(self):
-        # get a list of directories to look in
-        direc = config['instrumentDefinition.directory']
-        print("Looking for instrument definition files in: %s" % direc)
-        cwd = os.getcwd()
-        os.chdir(direc)
-        myFiles = glob.glob("*Definition*.xml")
-        os.chdir(cwd)
-        files = []
-        for filename in myFiles:
-            files.append(os.path.join(direc, filename))
-        return files
-
-    def runTest(self):
-        """Main entry point for the test suite"""
-        from minixsv import pyxsval
-        # need to extend minixsv library to add method for that forces it to
-        # validate against local schema when the xml file itself has
-        # reference to schema online. The preference is to systemtest against
-        # a local schema file to avoid this systemtest failing is
-        # external url temporariliy not available. Secondary it also avoid
-        # having to worry about proxies.
-
-        #pylint: disable=too-few-public-methods
-        class MyXsValidator(pyxsval.XsValidator):
-            ########################################
-            # force validation of XML input against local file
-            #
-            def validateXmlInputForceReadFile (self, xmlInputFile, inputTreeWrapper, xsdFile):
-                xsdTreeWrapper = self.parse (xsdFile)
-                xsdTreeWrapperList = []
-                xsdTreeWrapperList.append(xsdTreeWrapper)
-                self._validateXmlInput (xmlInputFile, inputTreeWrapper, xsdTreeWrapperList)
-                for xsdTreeWrapper in xsdTreeWrapperList:
-                    xsdTreeWrapper.unlink()
-                return inputTreeWrapper
-
-        def parseAndValidateXmlInputForceReadFile(inputFile, xsdFile=None, **kw):
-            myXsValidator = MyXsValidator(**kw)
-            # parse XML input file
-            inputTreeWrapper = myXsValidator.parse (inputFile)
-            # validate XML input file
-            return myXsValidator.validateXmlInputForceReadFile (inputFile, inputTreeWrapper, xsdFile)
-
-        direc = config['instrumentDefinition.directory']
-        self.xsdFile =  os.path.join(direc,'Schema/IDF/1.0/','IDFSchema.xsd')
-        if self.theFileToTest is None:
-            files = self.__getDataFileList__()
-        else:
-            files = [os.path.join(direc,self.theFileToTest)]
-
-        # run the tests
-        failed = []
-        for filename in files:
-            try:
-                print("----------------------------------------")
-                print("Validating '%s'" % filename)
-                parseAndValidateXmlInputForceReadFile(filename, xsdFile=self.xsdFile)
-            except Exception as e:
-                print("VALIDATION OF '%s' FAILED WITH ERROR:" % filename)
-                print(e)
-                failed.append(filename)
-
-        # final say on whether or not it 'worked'
-        print("----------------------------------------")
-        if len(failed) != 0:
-            print("SUMMARY OF FAILED FILES")
-            for filename in failed:
-                print(filename)
-            raise RuntimeError("Failed Validation for %d of %d files"
-                               % (len(failed), len(files)))
-        else:
-            print("Successfully Validated %d files" % len(files))
-
-
-if __name__ == '__main__':
-
-    valid = ValidateInstrumentDefinitionFiles()
-    # validate specific file
-    #valid.theFileToTest = "MARI_Definition.xml"
-    valid.runTest()
diff --git a/Testing/SystemTests/tests/analysis/ValidateInstrumentDir.py b/Testing/SystemTests/tests/analysis/ValidateInstrumentDir.py
new file mode 100644
index 0000000000000000000000000000000000000000..de86b57a08d5649d5b3fee3d0134587bae298235
--- /dev/null
+++ b/Testing/SystemTests/tests/analysis/ValidateInstrumentDir.py
@@ -0,0 +1,122 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+#pylint: disable=invalid-name
+#pylint: disable=no-init
+from __future__ import (absolute_import, division, print_function)
+
+import glob
+import os
+
+from mantid import config
+import six
+import systemtesting
+
+if six.PY2:
+    from io import open  # noqa
+
+# Constants
+FILE_TO_TEST = None  # "MARI_Definition.xml"
+INSTRUMENT_DIR = config['instrumentDefinition.directory']
+
+
+class ValidateXML(object):
+
+    def skipTests(self):
+        try:
+            import lxml  # noqa
+        except ImportError:
+            return True
+
+        return False
+
+    def runTest(self):
+        """Main entry point for the test suite"""
+        from lxml import etree
+
+        # read local schema
+        xsd_file = open(self.xsdpath(), "r", encoding="utf-8")
+        xsd_doc = etree.parse(xsd_file)
+
+        def validate_definition(filepath):
+            schema = etree.XMLSchema(xsd_doc)
+            with open(filepath, "r", encoding="utf-8") as xml_file:
+                is_valid = schema.validate(etree.XML(xml_file.read().encode("utf-8")))
+            if is_valid:
+                return is_valid, None
+            else:
+                return is_valid, schema.error_log.filter_from_errors()[0]
+
+        if FILE_TO_TEST is None:
+            files = self.filelist()
+        else:
+            files = [os.path.join(INSTRUMENT_DIR, FILE_TO_TEST)]
+
+        # run the tests
+        failed = []
+        for filename in files:
+            print("----------------------------------------")
+            print("Validating '%s'" % filename)
+            valid, errors = validate_definition(filename)
+            if not valid:
+                print("VALIDATION OF '%s' FAILED WITH ERROR:" % filename)
+                print(errors)
+                failed.append(filename)
+
+        # final say on whether or not it 'worked'
+        print("----------------------------------------")
+        if len(failed) != 0:
+            print("SUMMARY OF FAILED FILES")
+            for filename in failed:
+                print(filename)
+            raise RuntimeError("Failed Validation for %d of %d files"
+                               % (len(failed), len(files)))
+        else:
+            print("Successfully Validated %d files" % len(files))
+
+
+class ValidateInstrumentDefinitionFiles(ValidateXML, systemtesting.MantidSystemTest):
+
+    def xsdpath(self):
+        return os.path.join(INSTRUMENT_DIR, "Schema", "IDF", "1.0",
+                            "IDFSchema.xsd")
+
+    def filelist(self):
+        print("Looking for instrument definition files in: %s" % INSTRUMENT_DIR)
+        return glob.glob("{}/*Definition*.xml".format(INSTRUMENT_DIR))
+
+
+class ValidateParameterFiles(ValidateXML, systemtesting.MantidSystemTest):
+
+    def xsdpath(self):
+        return os.path.join(INSTRUMENT_DIR, "Schema", "ParameterFile", "1.0",
+                            "ParameterFileSchema.xsd")
+
+    def filelist(self):
+        print("Looking for instrument definition files in: %s" % INSTRUMENT_DIR)
+        return glob.glob("{}/*Parameters*.xml".format(INSTRUMENT_DIR))
+
+
+class ValidateFacilitiesFile(ValidateXML, systemtesting.MantidSystemTest):
+
+    def xsdpath(self):
+        return os.path.join(INSTRUMENT_DIR, "Schema", "Facilities", "1.0",
+                            "FacilitiesSchema.xsd")
+
+    def filelist(self):
+        return [os.path.join(INSTRUMENT_DIR, 'Facilities.xml')]
+
+
+class ValidateGroupingFiles(ValidateXML, systemtesting.MantidSystemTest):
+
+    def xsdpath(self):
+        return os.path.join(INSTRUMENT_DIR, "Schema", "Grouping", "1.0",
+                            "GroupingSchema.xsd")
+
+    def filelist(self):
+        grouping_dir = os.path.join(INSTRUMENT_DIR, "Grouping")
+        print("Looking for grouping files in: %s" % grouping_dir)
+        return glob.glob("{}/*Grouping*.xml".format(grouping_dir))
diff --git a/Testing/SystemTests/tests/analysis/ValidateParameterFiles.py b/Testing/SystemTests/tests/analysis/ValidateParameterFiles.py
deleted file mode 100644
index 016fb9400aad6fe04f402ace52bf34195c2482a2..0000000000000000000000000000000000000000
--- a/Testing/SystemTests/tests/analysis/ValidateParameterFiles.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Mantid Repository : https://github.com/mantidproject/mantid
-#
-# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
-#     NScD Oak Ridge National Laboratory, European Spallation Source
-#     & Institut Laue - Langevin
-# SPDX - License - Identifier: GPL - 3.0 +
-#pylint: disable=no-init,invalid-name
-from __future__ import (absolute_import, division, print_function)
-from mantid import config
-import os
-import systemtesting
-import glob
-
-EXPECTED_EXT = '.expected'
-
-
-class ValidateParameterFiles(systemtesting.MantidSystemTest):
-
-    xsdFile=''
-
-    def skipTests(self):
-        try:
-            from genxmlif import GenXmlIfError # noqa
-            from minixsv import pyxsval # noqa
-        except ImportError:
-            return True
-        return False
-
-    def __getDataFileList__(self):
-        # get a list of directories to look in
-        direc = config['instrumentDefinition.directory']
-        print("Looking for instrument definition files in: %s" % direc)
-        cwd = os.getcwd()
-        os.chdir(direc)
-        myFiles = glob.glob("*Parameters*.xml")
-        os.chdir(cwd)
-        files = []
-        for filename in myFiles:
-            files.append(os.path.join(direc, filename))
-        return files
-
-    def runTest(self):
-        """Main entry point for the test suite"""
-        from minixsv import pyxsval # noqa
-        direc = config['instrumentDefinition.directory']
-        print(direc)
-        self.xsdFile =  os.path.join(direc,'Schema/ParameterFile/1.0/','ParameterFileSchema.xsd')
-        files = self.__getDataFileList__()
-
-        # run the tests
-        failed = []
-        for filename in files:
-            try:
-                print("----------------------------------------")
-                print("Validating '%s'" % filename)
-                pyxsval.parseAndValidateXmlInput(filename, xsdFile=self.xsdFile, validateSchema=0)
-            except Exception as e:
-                print("VALIDATION OF '%s' FAILED WITH ERROR:" % filename)
-                print(e)
-                failed.append(filename)
-
-        # final say on whether or not it 'worked'
-        print("----------------------------------------")
-        if len(failed) != 0:
-            print("SUMMARY OF FAILED FILES")
-            for filename in failed:
-                print(filename)
-            raise RuntimeError("Failed Validation for %d of %d files"
-                               % (len(failed), len(files)))
-        else:
-            print("Successfully Validated %d files" % len(files))
-
-
-if __name__ == '__main__':
-    valid = ValidateParameterFiles()
-    valid.runTest()
diff --git a/buildconfig/CMake/Bootstrap.cmake b/buildconfig/CMake/Bootstrap.cmake
index 12f00143779c1c881e44b43c3a986c2c9ad36976..d6787dabec28cd6be97f477d678649c7f47d2f4b 100644
--- a/buildconfig/CMake/Bootstrap.cmake
+++ b/buildconfig/CMake/Bootstrap.cmake
@@ -10,7 +10,7 @@ if( MSVC )
   include ( ExternalProject )
   set( EXTERNAL_ROOT ${PROJECT_SOURCE_DIR}/external CACHE PATH "Location to clone third party dependencies to" )
   set( THIRD_PARTY_GIT_URL "https://github.com/mantidproject/thirdparty-msvc2015.git" )
-  set ( THIRD_PARTY_GIT_SHA1 622c6d0aa7d4480cd4d338e153f1f09e52b8fb09 )
+  set ( THIRD_PARTY_GIT_SHA1 a7bd18f35c8d67e68c3a965a07057efa266fc7d7 )
   set ( THIRD_PARTY_DIR ${EXTERNAL_ROOT}/src/ThirdParty )
   # Generates a script to do the clone/update in tmp
   set ( _project_name ThirdParty )
@@ -65,8 +65,14 @@ if( MSVC )
   unset ( _tmp_dir )
 
   # Print out where we are looking for 3rd party stuff
-  set ( PYTHON_MAJOR_VERSION 2 )
-  set ( PYTHON_MINOR_VERSION 7 )
+  option ( WITH_PYTHON3 "If true then build against Python 3.8" OFF )
+  if ( WITH_PYTHON3 )
+    set ( PYTHON_MAJOR_VERSION 3 )
+    set ( PYTHON_MINOR_VERSION 8 )
+  else()
+    set ( PYTHON_MAJOR_VERSION 2 )
+    set ( PYTHON_MINOR_VERSION 7 )
+  endif()
   set ( THIRD_PARTY_BIN "${THIRD_PARTY_DIR}/bin;${THIRD_PARTY_DIR}/lib/qt4/bin;${THIRD_PARTY_DIR}/lib/qt5/bin;${THIRD_PARTY_DIR}/lib/python${PYTHON_MAJOR_VERSION}.${PYTHON_MINOR_VERSION}" )
   message ( STATUS "Third party dependencies are in ${THIRD_PARTY_DIR}" )
   # Add to the path so that cmake can configure correctly without the user having to do it
diff --git a/buildconfig/CMake/FindBoostPython.cmake b/buildconfig/CMake/FindBoostPython.cmake
index 06a4957b06274e94036649a1f24bebb03c73c93d..c8c8686aab11e0773c832cf293ae35470eb76e4c 100644
--- a/buildconfig/CMake/FindBoostPython.cmake
+++ b/buildconfig/CMake/FindBoostPython.cmake
@@ -5,7 +5,7 @@
 #  - windows: boost_python (python2), ????? (python3)
 #  - others?
 if ( MSVC )
-  find_package ( Boost ${BOOST_VERSION_REQUIRED} COMPONENTS python27 REQUIRED )
+  find_package ( Boost ${BOOST_VERSION_REQUIRED} COMPONENTS python${PYTHON_MAJOR_VERSION}${PYTHON_MINOR_VERSION} REQUIRED )
 else ()
   if ( PYTHON_VERSION_MAJOR GREATER 2 )
     # Try a known set of suffixes plus a user-defined set
diff --git a/buildconfig/CMake/PyQtFindImpl.cmake b/buildconfig/CMake/PyQtFindImpl.cmake
index b8d637f0f14fd2da542bbebd08f1763b970ff043..3bfcf7a66f6bd20e4afc438f5f0641c21d347bcd 100644
--- a/buildconfig/CMake/PyQtFindImpl.cmake
+++ b/buildconfig/CMake/PyQtFindImpl.cmake
@@ -29,24 +29,28 @@ function (find_pyqt major_version)
   endif()
   execute_process (COMMAND ${PYTHON_EXECUTABLE} ${_find_pyqt_py} ${major_version}
     OUTPUT_VARIABLE _pyqt_config ERROR_VARIABLE _pyqt_config_err)
+  if(CMAKE_HOST_WIN32 AND major_version EQUAL 4 AND _pyqt_config_err MATCHES "Qt: Untested Windows version 10.0 detected!")
+    # Known warning on Windows 10 with Qt4 and Python 3
+    set(_pyqt_config_err "")
+  endif()
   if (_pyqt_config AND NOT _pyqt_config_err)
     string (REGEX MATCH "^pyqt_version:([^\n]+).*$" _dummy ${_pyqt_config})
-    set (PYQT${major_version}_VERSION "${CMAKE_MATCH_1}" CACHE STRING "PyQt${major_version}'s version as a 6-digit hexadecimal number")
+    set (PYQT${major_version}_VERSION "${CMAKE_MATCH_1}" CACHE STRING "PyQt${major_version}'s version as a 6-digit hexadecimal number" FORCE)
 
     string (REGEX MATCH ".*\npyqt_version_str:([^\n]+).*$" _dummy ${_pyqt_config})
-    set (PYQT${major_version}_VERSION_STR "${CMAKE_MATCH_1}" CACHE STRING "PyQt${major_version}'s version as a human-readable string")
+    set (PYQT${major_version}_VERSION_STR "${CMAKE_MATCH_1}" CACHE STRING "PyQt${major_version}'s version as a human-readable string" FORCE)
 
     string (REGEX MATCH ".*\npyqt_version_tag:([^\n]+).*$" _dummy ${_pyqt_config})
-    set (PYQT${major_version}_VERSION_TAG "${CMAKE_MATCH_1}" CACHE STRING "The Qt version tag used by PyQt${major_version}'s .sip files")
+    set (PYQT${major_version}_VERSION_TAG "${CMAKE_MATCH_1}" CACHE STRING "The Qt version tag used by PyQt${major_version}'s .sip files" FORCE)
 
     string (REGEX MATCH ".*\npyqt_sip_dir:([^\n]+).*$" _dummy ${_pyqt_config})
-    set (PYQT${major_version}_SIP_DIR "${CMAKE_MATCH_1}" CACHE PATH "The base directory where PyQt${major_version}'s .sip files are installed")
+    set (PYQT${major_version}_SIP_DIR "${CMAKE_MATCH_1}" CACHE PATH "The base directory where PyQt${major_version}'s .sip files are installed" FORCE)
 
     string (REGEX MATCH ".*\npyqt_sip_flags:([^\n]+).*$" _dummy ${_pyqt_config})
-    set (PYQT${major_version}_SIP_FLAGS "${CMAKE_MATCH_1}" CACHE STRING "The SIP flags used to build PyQt${major_version}")
+    set (PYQT${major_version}_SIP_FLAGS "${CMAKE_MATCH_1}" CACHE STRING "The SIP flags used to build PyQt${major_version}" FORCE)
 
     string (REGEX MATCH ".*\npyqt_pyuic:([^\n]+).*$" _dummy ${_pyqt_config})
-    set (PYQT${major_version}_PYUIC "${CMAKE_MATCH_1}" CACHE STRING "Location of the pyuic script")
+    set (PYQT${major_version}_PYUIC "${CMAKE_MATCH_1}" CACHE STRING "Location of the pyuic script" FORCE)
 
     if (NOT EXISTS "${PYQT${major_version}_SIP_DIR}/QtCore/QtCoremod.sip")
       message (FATAL_ERROR "Unable to find QtCore/QtCoremod.sip in ${PYQT${major_version}_SIP_DIR}. PyQt sip files are missing."
diff --git a/buildconfig/CMake/WindowsNSIS.cmake b/buildconfig/CMake/WindowsNSIS.cmake
index 9e896bb0cb53039908415d44a62a1152cc3bdf0b..400a70737ad1a937bc1a5eb00157ef4071ec6a4f 100644
--- a/buildconfig/CMake/WindowsNSIS.cmake
+++ b/buildconfig/CMake/WindowsNSIS.cmake
@@ -60,11 +60,16 @@ mark_as_advanced(WINDOWS_DEPLOYMENT_TYPE)
 set ( BOOST_DIST_DLLS
     boost_date_time-mt.dll
     boost_filesystem-mt.dll
-    boost_python27-mt.dll
     boost_regex-mt.dll
     boost_serialization-mt.dll
     boost_system-mt.dll
 )
+if ( WITH_PYTHON3 )
+  list( APPEND BOOST_DIST_DLLS boost_python38-mt.dll )
+else ()
+  list( APPEND BOOST_DIST_DLLS boost_python27-mt.dll )
+endif ()
+
 set ( POCO_DIST_DLLS
     PocoCrypto64.dll
     PocoFoundation64.dll
diff --git a/buildconfig/windows/pycharm.env.in b/buildconfig/windows/pycharm.env.in
index 0c4ff94018fe1dae01de96f7c4ce9b73797f6921..3f27adc4cf49401b9fb8711256654192a1ccbf72 100644
--- a/buildconfig/windows/pycharm.env.in
+++ b/buildconfig/windows/pycharm.env.in
@@ -2,6 +2,6 @@ THIRD_PARTY_DIR=@THIRD_PARTY_DIR@
 QT4_BIN=${THIRD_PARTY_DIR}\lib\qt4\bin;${THIRD_PARTY_DIR}\lib\qt4\lib
 QT5_BIN=${THIRD_PARTY_DIR}\lib\qt5\bin;${THIRD_PARTY_DIR}\lib\qt5\lib
 QT_QPA_PLATFORM_PLUGIN_PATH=${THIRD_PARTY_DIR}\lib\qt5\plugins
-PYTHONHOME=${THIRD_PARTY_DIR}\lib\python2.7
+PYTHONHOME=${THIRD_PARTY_DIR}\lib\python@PYTHON_MAJOR_VERSION@.@PYTHON_MINOR_VERSION@
 MISC_BIN=${THIRD_PARTY_DIR}\bin;${THIRD_PARTY_DIR}\bin\mingw
 PATH=${MISC_BIN};${PYTHONHOME};${QT5_BIN};${QT4_BIN};${PATH}
\ No newline at end of file
diff --git a/dev-docs/source/Python3.rst b/dev-docs/source/Python3.rst
index 85915a6d2ad75e2d9e1a1055742578ff3d79f80b..248ef49e1e69ff5c4b87e102df0115606d63c6dd 100644
--- a/dev-docs/source/Python3.rst
+++ b/dev-docs/source/Python3.rst
@@ -12,13 +12,28 @@ migration strategy for Mantid.
 Building Against Python 3
 #########################
 
-This is currently only possible on a Linux system with a pre-installed version of python 3 and you will need to have
-the latest version of the `mantid-developer` package installed. Once installed run cmake as standard but with the additional option ``-DPYTHON_EXECUTABLE=/usr/bin/python3``. Please note that
-reconfiguring an existing Python 2 build is not supported - a build in a fresh build directory is required.
+This is currently possible on Ubuntu or Windows.
+Please note that reconfiguring an existing Python 2 build is not supported - a build in a fresh build directory is required.
+
+Ubuntu
+^^^^^^
+
+Install the latest version of the `mantid-developer` package. Once installed run cmake as standard but with the additional option ``-DPYTHON_EXECUTABLE=/usr/bin/python3``.
 
 .. warning::
    Do not install python packages via ``pip``. Install packages only from the system repositories.
 
+Windows
+^^^^^^^
+
+All of the required packages are in the third-party bundle that will be fetched for you.
+
+To build from the command line run cmake as standard but with the additional option ``-DWITH_PYTHON3=ON``.
+
+To build from the GUI ensure the previous cache has been deleted, set the source and build directories as usual
+but before clicking configure click "Add Entry" and add an entry with the name ``WITH_PYTHON3`` of type ``BOOL``
+and ensure the Value is checked. Now proceed to configure and generate as usual.
+
 Supporting Python 2 and 3
 #########################
 
diff --git a/dev-docs/source/index.rst b/dev-docs/source/index.rst
index 8c43f6fb93a35abb7ab04da79d05039f1a43131c..1bd00d7980ca5ab63883dee9915a444f07e9565c 100644
--- a/dev-docs/source/index.rst
+++ b/dev-docs/source/index.rst
@@ -47,7 +47,7 @@ Guides
    Configure a doxygen build locally.
 
 :doc:`Python3`
-   Building with Python 3 (Linux only).
+   Building with Python 3 (Ubuntu/Windows).
 
 `C++ Introduction <https://www.mantidproject.org/New_Starter_C%2B%2B_introduction>`_
    Exercises for learning C++.
@@ -207,7 +207,7 @@ GUI Development
 
 :doc:`ISISReflectometryInterface`
    An example of a complex C++ interface that uses MVP.
-   
+
 =========
 Workbench
 =========
diff --git a/docs/source/algorithms/LoadAscii-v2.rst b/docs/source/algorithms/LoadAscii-v2.rst
index 5ec7650188e4269482534ff5ce3d6d54d794af57..263b65da527fe885f0ade4e0e3c24a3af96dbdc4 100644
--- a/docs/source/algorithms/LoadAscii-v2.rst
+++ b/docs/source/algorithms/LoadAscii-v2.rst
@@ -10,14 +10,14 @@ Description
 -----------
 
 The LoadAscii2 algorithm reads in spectra data from a text file and
-stores it in a :ref:`Workspace2D <Workspace2D>` as data points. The data in
+stores it in a :ref:`Workspace2D <Workspace2D>` as data points, or a Table Workspace if it is table data. The data in
 the file must be organized in columns separated by commas, tabs, spaces,
 colons or semicolons. Only one separator type can be used throughout the
 file; use the "Separator" property to tell the algorithm which to use.
 The algorithm :ref:`SaveAscii2 <algm-SaveAscii-v2>` is normally able to produce
 such a file.
 
-The format must be:
+The format must be (Workspace 2D):
 
 -  A single integer or blank line to denote a new spectra
 -  For each bin, between two and four columns of delimited data in the
@@ -39,6 +39,21 @@ no X error::
     2.00000000,3.00000000,1.00000000 4.00000000,0.00000000,0.00000000 4
     2.00000000,0.00000000,0.00000000 4.00000000,0.00000000,0.00000000
 
+The format must be (Table Workspace):
+
+-  Two commented header lines
+-  The first containing the column names
+-  The second containing the column types (str, int, unit, long64, size_t, float, double, bool, V3D)
+-  The number of column names, types and data items must match
+
+
+The following is an example valid file of two columns::
+
+	# Instrument Name , Run Number 
+	# str , int 
+	MUSR,10245
+	IRIS,8465
+	SANS2D,20462
 
 Usage
 -----
diff --git a/docs/source/algorithms/LoadHFIRSANS-v1.rst b/docs/source/algorithms/LoadHFIRSANS-v1.rst
index 6e9754e70e6ecd3da303ca95cdf19a4e2ea6027d..74c0c7f296d9ee1b3c4d3c64885a685ed69ab35e 100644
--- a/docs/source/algorithms/LoadHFIRSANS-v1.rst
+++ b/docs/source/algorithms/LoadHFIRSANS-v1.rst
@@ -24,11 +24,11 @@ Finds and sets the logs:
 * ``monitor``
 * ``timer``
 * ``sample-thicknes``
-* ``source-aperture-diameter``
-* ``sample-aperture-diameter``
+* ``source-aperture-diameter`` and ``source_aperture_diameter``
+* ``sample-aperture-diameter`` and ``sample-aperture-diameter``
 * ``number-of-guides``
-* ``sample-detector-distance`` and ``sdd``
-* ``source-sample-distance``
+* ``sample-detector-distance``, ``sample_detector_distance``, and ``sdd``
+* ``source-sample-distance`` and ``source-sample-distance``
 * ``beam-diameter``
 
 .. categories::
diff --git a/docs/source/algorithms/SANSILLAutoProcess-v1.rst b/docs/source/algorithms/SANSILLAutoProcess-v1.rst
index a2929d0e15b87e95c6b7735bdb67cb5714bf8236..a62851d6755f7cd2f0979d1d1e0dd0eb4600529b 100644
--- a/docs/source/algorithms/SANSILLAutoProcess-v1.rst
+++ b/docs/source/algorithms/SANSILLAutoProcess-v1.rst
@@ -37,11 +37,11 @@ When multiple runs are summed, the run number of the first run is attributed to
 
 .. include:: ../usagedata-note.txt
 
-**Example - full treatment of 3 samples at 3 different distances**
+**Example - full treatment of 3 samples at 3 different distances in D11**
 
 .. testsetup:: ExSANSILLAutoProcess
 
-    config['default.facility'] = 'ILL'
+    config.setFacility('ILL')
     config.appendDataSearchSubDir('ILL/D11/')
 
 .. testcode:: ExSANSILLAutoProcess
@@ -87,6 +87,67 @@ Output:
 
     mtd.clear()
 
+
+**Example 2 - full treatment of 5 samples in D33**
+
+.. plot::
+    :include-source:
+
+    from mantid.simpleapi import *
+    import matplotlib.pyplot as plt
+
+    config.setFacility('ILL')
+    config['default.instrument'] = 'D33'
+    config.appendDataSearchSubDir('ILL/D33/')
+
+    absorber = '002227'
+
+    tr_beam = '002192'
+
+    can_tr = '002193'
+
+    empty_beam = '002219'
+
+    can = '002228'
+
+    mask = 'D33Mask2.nxs'
+
+    sample_names = ['H2O', 'D2O', 'AgBE', 'F127_D2O', 'F127_D2O_Anethol']
+    sample_legends = ['H$_2$O', 'D$_2$O', 'AgBE', 'F127 D$_2$O', 'F127 D$_2$O Anethol']
+
+    samples = ['002229', '001462', '001461', '001463', '001464']
+
+    transmissions = ['002194', '002195', '', '002196', '002197']
+
+    # Autoprocess every sample
+    for i in range(len(samples)):
+        SANSILLAutoProcess(
+            SampleRuns=samples[i],
+            SampleTransmissionRuns=transmissions[i],
+            MaskFiles=mask,
+            AbsorberRuns=absorber,
+            BeamRuns=empty_beam,
+            ContainerRuns=can,
+            ContainerTransmissionRuns=can_tr,
+            TransmissionBeamRuns=tr_beam,
+            CalculateResolution='None',
+            OutputWorkspace=sample_names[i]
+        )
+
+    fig, ax = plt.subplots(subplot_kw={'projection':'mantid'})
+
+    plt.yscale('log')
+    plt.xscale('log')
+
+    # Plot the result of every autoprocess
+    for wName in sample_names:
+        ax.errorbar(mtd[wName][0])
+
+    plt.legend(sample_legends)
+    ax.set_ylabel('d$\sigma$/d$\Omega$ ($cm^{-1}$)')
+
+    #fig.show()
+
 .. categories::
 
 .. sourcelink::
diff --git a/docs/source/algorithms/SaveAscii-v2.rst b/docs/source/algorithms/SaveAscii-v2.rst
index a35e60f03bf289130b86ec3e87ce427584b81e71..0082f962ec3b9767c62fc4c3c3ee0189c3fb6b8d 100644
--- a/docs/source/algorithms/SaveAscii-v2.rst
+++ b/docs/source/algorithms/SaveAscii-v2.rst
@@ -9,7 +9,9 @@
 Description
 -----------
 
-The workspace data are stored in the file in columns: the first column contains
+The format used differs based on the type of workspace being saved.  For a table workspace the data will contain an optional row of column headers, followed by the row values, with each individual column value seperated by the defined seperator.
+
+For a  matrix workspace the data are stored in the file in columns: the first column contains
 the X-values, followed by pairs of Y and E values. Columns are separated by
 commas. The resulting file can normally be loaded into a workspace by the
 :ref:`algm-LoadAscii` algorithm.
diff --git a/docs/source/concepts/PropertiesFile.rst b/docs/source/concepts/PropertiesFile.rst
index aa9c7f758193632c2a6d9574ade2669033ba18b5..7c59e56af91819f03567b9047e213d646328e421 100644
--- a/docs/source/concepts/PropertiesFile.rst
+++ b/docs/source/concepts/PropertiesFile.rst
@@ -149,12 +149,15 @@ The logging priority levels for the file logging and console logging can also be
 
 
 
-MantidPlot Properties
-*********************
+Mantid Graphical User Interface Properties
+******************************************
 
 +--------------------------------------------+---------------------------------------------------+-----------------+
 |Property                                    |Description                                        |Example value    |
 +============================================+===================================================+=================+
+| ``Notifications.Enabled``                  |Should Mantid use System Notifications for         | ``On``, ``Off`` |
+|                                            |important messages?                                |                 |
++--------------------------------------------+---------------------------------------------------+-----------------+
 | ``cluster.submission``                     |Enable cluster submission elements in GUIs         | ``On``, ``Off`` |
 +--------------------------------------------+---------------------------------------------------+-----------------+
 | ``MantidOptions.InstrumentView.UseOpenGL`` |Controls the use of OpenGL in rendering the        | ``On``, ``Off`` |
diff --git a/docs/source/images/Notification_error.png b/docs/source/images/Notification_error.png
new file mode 100644
index 0000000000000000000000000000000000000000..6c687d5a98b092a62d3f9f836db388b5953471b6
Binary files /dev/null and b/docs/source/images/Notification_error.png differ
diff --git a/docs/source/images/Notifications_settings.png b/docs/source/images/Notifications_settings.png
new file mode 100644
index 0000000000000000000000000000000000000000..78a04ffa02c55bf1184e2c27e8a526f2fc201b37
Binary files /dev/null and b/docs/source/images/Notifications_settings.png differ
diff --git a/docs/source/release/v4.3.0/diffraction.rst b/docs/source/release/v4.3.0/diffraction.rst
index e9da75c6bca9a8d07220da593240aebc2d626f81..f315e82ed27f36bdca24ead627dba15bdda810c1 100644
--- a/docs/source/release/v4.3.0/diffraction.rst
+++ b/docs/source/release/v4.3.0/diffraction.rst
@@ -19,6 +19,7 @@ Powder Diffraction
 - The create_total_scattering_pdf merging banks now matches spectra to the spectrum with the largest x range.
 - The create_total_scattering_pdf merging banks no longer matches spectra with scale, it now only matches with offset.
 - The Polaris create_total_scattering_pdf can now be given an parameter `output_binning` that will be used to rebin the output_pdf.
+- The polaris create_total_scattering_pdf function can now accept a `pdf_type` argument to set the pdf_output type.
 - :ref:`HRPDSlabCanAbsorption <algm-HRPDSlabCanAbsorption-v1>` now accepts any thickness parameter and not those in a specified list.
 
 Engineering Diffraction
diff --git a/docs/source/release/v4.3.0/direct_geometry.rst b/docs/source/release/v4.3.0/direct_geometry.rst
index 2a4a9b09cfe3d55ddd8decd3430d8215539703de..2250c429fca2c8f8c403172999cd002a925b9a11 100644
--- a/docs/source/release/v4.3.0/direct_geometry.rst
+++ b/docs/source/release/v4.3.0/direct_geometry.rst
@@ -9,4 +9,6 @@ Direct Geometry Changes
     putting new features at the top of the section, followed by
     improvements, followed by bug fixes.
 
-:ref:`Release 4.3.0 <v4.3.0>`
\ No newline at end of file
+* New ``NOW4`` instrument definition for SNS
+
+:ref:`Release 4.3.0 <v4.3.0>`
diff --git a/docs/source/release/v4.3.0/framework.rst b/docs/source/release/v4.3.0/framework.rst
index 9df25b4238994512a2a77704cc902667db2f9565..2f8d5dff4a12d8aab440dc47ece5f5dd01d4253b 100644
--- a/docs/source/release/v4.3.0/framework.rst
+++ b/docs/source/release/v4.3.0/framework.rst
@@ -20,13 +20,20 @@ Improvements
 
 - Fixed a bug in :ref:`LoadNGEM <algm-LoadNGEM>` where precision was lost due to integer arithmetic.
 - Prevent units that are not suitable for :ref:`ConvertUnits <algm-ConvertUnits>` being entered as the target unit.
+- Fixed an uncaught exception when plotting logs on single spectrum workspaces in mantidworkbench
+- Save the units for single value logs in :ref:`SaveNexusProcessed <algm-SaveNexusProcessed>`
 
 Algorithms
 ----------
 
+Improvements
+############
+
+- :ref:`SaveAscii <algm-SaveAscii>` can now save table workspaces, and :ref:`LoadAscii <algm-LoadAscii>` can load them again.
 - :ref:`TotScatCalculateSelfScattering <algm-TotScatCalculateSelfScattering>` will calculate a normalized self scattering correction for foccues total scattering data.
 - :ref:`MatchAndMergeWorkspaces <algm-MatchAndMergeWorkspaces>` will merge workspaces in a workspace group withing weighting from a set of limits for each workspace and using `MatchSpectra <algm-MatchSpectra>`.
 
+
 Data Objects
 ------------
 
diff --git a/docs/source/release/v4.3.0/mantidplot.rst b/docs/source/release/v4.3.0/mantidplot.rst
index 60c3ca7a50bd5bf376db446cc13ce2a1c0af098d..54265444dbee80a6ff7b8706e9bae5f3f1fa7336 100644
--- a/docs/source/release/v4.3.0/mantidplot.rst
+++ b/docs/source/release/v4.3.0/mantidplot.rst
@@ -10,5 +10,6 @@ Improvements
 
 Bugfixes
 ########
+- The Show Instruments right click menu option is now disabled for workspaces that have had their spectrum axis converted to another axis using :ref:`ConvertSpectrumAxis <algm-ConvertSpectrumAxis>`.  Once this axis has been converetd the workspace loses it's link between the data values and the detectors they were recorded on so we cannot display it in the instrument view.
 
 :ref:`Release 4.3.0 <v4.3.0>`
\ No newline at end of file
diff --git a/docs/source/release/v4.3.0/mantidworkbench.rst b/docs/source/release/v4.3.0/mantidworkbench.rst
index 191efa0a4d127196b2e134c74c8c852ba8b5183d..e377e6eb71dbb9b984932961dff20da70da237f1 100644
--- a/docs/source/release/v4.3.0/mantidworkbench.rst
+++ b/docs/source/release/v4.3.0/mantidworkbench.rst
@@ -8,9 +8,23 @@ MantidWorkbench Changes
 Improvements
 ############
 
+.. figure:: ../../images/Notification_error.png
+   :class: screenshot
+   :width: 600px
+   :align: right
+
+- If you have ever found it hard to spot when errors appear in the Messages window, and perhaps miss them if there are lots of graphs on the screen, then you will like this.  We have added system notifications when Mantid enounters an error, and directs you to look at the Messages window for details.  You can enable or disable these notifications from the File->Settings window.
+
+.. figure:: ../../images/Notifications_settings.png
+   :class: screenshot
+   :width: 500px
+   :align: left
+
+- You can now save Table Workspaces to Ascii using the `SaveAscii <algm-SaveAscii>` algorithm, and the Ascii Save option on the workspaces toolbox.
 - Normalization options have been added to 2d plots and sliceviewer.
 - The images tab in figure options no longer forces the max value to be greater than the min value.
 
+
 Bugfixes
 ########
 
@@ -18,5 +32,6 @@ Bugfixes
 - Figure options no longer causes a crash when using 2d plots created from a script.
 - Running an algorithm that reduces the number of spectra on an active plot (eg SumSpectra) no longer causes an error
 - Fix crash when loading a script with syntax errors
+- The Show Instruments right click menu option is now disabled for workspaces that have had their spectrum axis converted to another axis using :ref:`ConvertSpectrumAxis <algm-ConvertSpectrumAxis>`.  Once this axis has been converetd the workspace loses it's link between the data values and the detectors they were recorded on so we cannot display it in the instrument view.
 
 :ref:`Release 4.3.0 <v4.3.0>`
diff --git a/docs/source/techniques/ISISPowder-Polaris-v1.rst b/docs/source/techniques/ISISPowder-Polaris-v1.rst
index 010dc72edc3444664e35c5dda228fe921d7f08c8..52db29fca0168d4bdc08a1e53bac73291a00ecc6 100644
--- a/docs/source/techniques/ISISPowder-Polaris-v1.rst
+++ b/docs/source/techniques/ISISPowder-Polaris-v1.rst
@@ -168,10 +168,11 @@ The *create_total_scattering_pdf* method allows a user to create a Pair Distribu
 from focused POLARIS data, with a view performing further total scattering analysis.
 
 With no merging criteria specified, *merge_banks=False* a PDF will be generated for each bank within
-the focused_workspace. If run with *merge_banks=True* a PDF will be generated based on the wighted
-sum of the detector banks performed using supplied Q limits *q_lims=q_limits*, Q_limits can be in the
-form of a numpy array with shape (2, x) where x is the number rof detectors, or a string containing the
-directory of an appropriately formatted `.lim` file.
+the focused_workspace. The type of PDF output can be set with the keyword argument `pdf_type`, with the
+option of `G(r)`, `g(r)`, `RDF(r)` (defaults to `G(r)`). If run with *merge_banks=True* a PDF will be
+generated based on the weighted sum of the detector banks performed using supplied Q limits
+*q_lims=q_limits*, Q_limits can be in the form of a numpy array with shape (2, x) where x is the number
+of detectors, or a string containing the directory of an appropriately formatted `.lim` file.
 
 This function can also be called with the argument `output_binning` which will rebin the output PDF as
 with the rebin algorithm.
diff --git a/installers/MacInstaller/make_package.rb b/installers/MacInstaller/make_package.rb
index 0e2744f3f1cf8bda2e795cf0c006706208c923be..30e5acbf1434ea887ae1e5e8c31ac43fb268cf0b 100755
--- a/installers/MacInstaller/make_package.rb
+++ b/installers/MacInstaller/make_package.rb
@@ -16,17 +16,13 @@ require 'pathname'
 AT_EXECUTABLE_TAG = '@executable_path'
 AT_LOADER_TAG = '@loader_path'
 AT_RPATH_TAG = '@rpath'
-BUNDLED_PY_MODULES = [
-  '_posixsubprocess32.so',
-  'backports',
+BUNDLED_PY_MODULES_COMMON = [
   'certifi',
   'chardet',
   'CifFile',
   'cycler.py',
   'dateutil',
   'decorator.py',
-  'enum',
-  'funcsigs',
   'h5py',
   'idna',
   'IPython',
@@ -34,14 +30,12 @@ BUNDLED_PY_MODULES = [
   'ipykernel',
   'jupyter_core',
   'jupyter_client',
-  'kiwisolver.so',
   'markupsafe',
   'matplotlib',
   'mistune.py',
   'mock',
   'mpl_toolkits',
   'numpy',
-  'pathlib2',
   'pexpect',
   'pickleshare.py',
   'pkg_resources',
@@ -54,20 +48,33 @@ BUNDLED_PY_MODULES = [
   'pygments',
   'tornado',
   'requests',
-  'scandir.py',
   'scipy',
-  'simplegeneric.py',
   'sip.so',
   'six.py',
   'sphinx',
   'sphinx_bootstrap_theme',
-  'subprocess32.py',
   'traitlets',
   'urllib3',
   'wcwidth',
   'yaml',
   'zmq'
 ].freeze
+BUNDLED_PY_MODULES_PY2 = [
+  '_posixsubprocess32.so',
+  'backports',
+  'enum',
+  'funcsigs',
+  'kiwisolver.so',
+  'pathlib2',
+  'scandir.py',
+  'simplegeneric.py',
+  'subprocess32.py'
+].freeze
+BUNDLED_PY_MODULES_PY3 = [
+  'appnope',
+  'backcall',
+  'kiwisolver.%s.so'
+].freeze
 BUNDLED_PY_MODULES_MANTIDPLOT = [
   'PyQt4/__init__.py',
   'PyQt4/Qt.so',
@@ -142,6 +149,16 @@ def execute(cmd, ignore_fail = false)
   stdout
 end
 
+# Determine the version of python
+# Return 3-array of major,minor,patch
+def python_version(py_exe)
+  # expects Python X.Y.Z
+  version_info = execute(py_exe + ' --version')
+  version_number_str = version_info.split()[1]
+  # map to 3 integers
+  return version_number_str.split('.').map { |x| x.to_i }
+end
+
 # Deploy the embedded Python bundle
 # Params:
 # +destination+:: Destination directory for bundle
@@ -191,7 +208,7 @@ def deploy_python_framework(destination, host_python_exe,
     end
   end
 
-  # add relative symlink for unversioned paths
+  # add relative symlink for unversioned paths if they don't exist
   Dir.chdir(bundle_py_home + 'bin') do
     FileUtils.ln_s "python#{py_ver}", "python"
     FileUtils.ln_s "2to3-#{py_ver}", "2to3"
@@ -577,11 +594,11 @@ executables = ["#{contents_macos}/MantidNexusParallelLoader"]
 
 # check we have a known bundle
 if bundle_path.to_s.end_with?('MantidWorkbench.app')
-  bundled_packages = BUNDLED_PY_MODULES + BUNDLED_PY_MODULES_WORKBENCH
+  bundled_packages = BUNDLED_PY_MODULES_COMMON + BUNDLED_PY_MODULES_WORKBENCH
   bundled_qt_plugins = QT_PLUGINS_COMMON + ['platforms', 'styles']
   host_qt_plugins_dir = QT5_PLUGINS_DIR
 elsif bundle_path.to_s.end_with?('MantidPlot.app')
-  bundled_packages = BUNDLED_PY_MODULES + BUNDLED_PY_MODULES_MANTIDPLOT
+  bundled_packages = BUNDLED_PY_MODULES_COMMON + BUNDLED_PY_MODULES_MANTIDPLOT
   bundled_qt_plugins = QT_PLUGINS_COMMON
   host_qt_plugins_dir = QT4_PLUGINS_DIR
   executables << "#{contents_macos}/MantidPlot"
@@ -589,6 +606,17 @@ else
   fatal("Unknown bundle type #{bundle_path}. Expected MantidPlot.app or MantidWorkbench.app.")
 end
 
+python_version_full = python_version(host_python_exe.to_s)
+python_version_major = python_version_full[0]
+python_version_minor = python_version_full[1]
+if python_version_major == 2
+  bundled_packages += BUNDLED_PY_MODULES_PY2
+elsif python_version_major == 3
+  bundled_packages += BUNDLED_PY_MODULES_PY3.map { |s| s % "cpython-%d%dm-darwin" % [python_version_major, python_version_minor] }
+else
+  fatal("Unknown Python version: #{python_version_major}. Expected <= 3")
+end
+
 # We start with the assumption CMake has installed all required target libraries/executables
 # into the bundle and the main layout exists.
 bundle_py_site_packages = deploy_python_framework(contents_frameworks, host_python_exe,
diff --git a/instrument/CG2_Definition.xml b/instrument/CG2_Definition.xml
index c0dcffab11ca3ccf7bc7ec38405604a38f517a51..fe4266a41ebe661016f5568dbef0f35fe7db8894 100644
--- a/instrument/CG2_Definition.xml
+++ b/instrument/CG2_Definition.xml
@@ -433,7 +433,7 @@
   <component type="double-flat-panel" idlist="pixel_ids" name="detector1">
     <location>
       <parameter name="x">
-        <logfile id="detector_trans" eq="-0.001*value"/>
+        <logfile id="detector_trans_Readback" eq="-0.001*value"/>
       </parameter>
       <parameter name="z">
         <logfile id="sample_detector_distance" eq="value"/>
diff --git a/instrument/Facilities.xml b/instrument/Facilities.xml
index bb12995ac2ebe0ec0d622f328d6b902355ef5ba9..02d0256f645e89714bb49f2e2695b28f93ce015c 100644
--- a/instrument/Facilities.xml
+++ b/instrument/Facilities.xml
@@ -567,6 +567,11 @@
     </livedata>
   </instrument>
 
+  <instrument name="NOW4" shortname="NOW4" beamline="14Q">
+    <technique>Neutron Spectroscopy</technique>
+    <technique>TOF Direct Geometry Spectroscopy</technique>
+  </instrument>
+
   <instrument name="VISION" shortname="VIS" beamline="16B">
     <technique>Neutron Spectroscopy</technique>
     <technique>TOF Indirect Geometry Spectroscopy</technique>
@@ -902,7 +907,7 @@
 <!-- HZB -->
 <facility name="HZB" FileExtensions=".nxs">
    <timezone>Europe/Berlin</timezone>
-   
+
    <instrument name="TEST" shortname="TEST">
 	<zeropadding size="8" />
     <technique>ESS Test Beamline</technique>
@@ -946,14 +951,14 @@
 <!--  Test Facility to allow example usage of Live listeners against "Fake" instrument sources -->
 <facility name="TEST_LIVE" FileExtensions=".nxs,.raw">
   <timezone>UTC</timezone>
-  
+
   <instrument name="LOKI">
     <technique>SANS Test</technique>
     <livedata>
       <connection name="event" address="hinata:9092" listener="KafkaEventListener" />
     </livedata>
   </instrument>
-  
+
   <instrument name="ISIS_Histogram">
     <technique>Test Listener</technique>
     <livedata>
diff --git a/instrument/GPSANS_Definition.xml b/instrument/GPSANS_Definition.xml
index d36b51947298deeeece84b42b6f2c4af95e8e3a3..2182f730158eaf2ca4692f0dcbace4e8c7655b56 100644
--- a/instrument/GPSANS_Definition.xml
+++ b/instrument/GPSANS_Definition.xml
@@ -433,7 +433,7 @@
   <component type="double-flat-panel" idlist="pixel_ids" name="detector1">
     <location>
       <parameter name="x">
-        <logfile id="detector_trans" eq="-0.001*value"/>
+        <logfile id="detector_trans_Readback" eq="-0.001*value"/>
       </parameter>
       <parameter name="z">
         <logfile id="sample_detector_distance" eq="value"/>
diff --git a/instrument/NOW4_Definition.xml b/instrument/NOW4_Definition.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f5606937349a1241cf47f30ac5fcc97ca6085f50
--- /dev/null
+++ b/instrument/NOW4_Definition.xml
@@ -0,0 +1,351 @@
+<?xml version='1.0' encoding='ASCII'?>
+<instrument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.mantidproject.org/IDF/1.0" last-modified="2019-06-25 14:11:19.918208" name="NOW4" valid-from="2019-06-02 00:00:00" valid-to="2100-01-31 23:59:59" xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd">
+  <!--Created by Andrei Savici-->
+  <defaults>
+    <length unit="metre"/>
+    <angle unit="degree"/>
+    <reference-frame>
+      <along-beam axis="z"/>
+      <pointing-up axis="y"/>
+      <handedness val="right"/>
+      <theta-sign axis="x"/>
+    </reference-frame>
+  </defaults>
+  <!--SOURCE AND SAMPLE POSITION-->
+  <component type="moderator">
+    <location z="-36.262"/>
+  </component>
+  <type is="Source" name="moderator"/>
+  <component type="sample-position">
+    <location x="0.0" y="0.0" z="0.0"/>
+  </component>
+  <type is="SamplePos" name="sample-position"/>
+  <component idlist="detectors" type="detectors">
+    <location/>
+  </component>
+  <type name="detectors">
+    <component type="bank1">
+      <location/>
+    </component>
+  </type>
+  <type name="bank1">
+    <component type="eightpack">
+      <location x="2.64623477185" y="-0.00904297322071" z="-2.3031829704">
+        <rot axis-x="0" axis-y="1" axis-z="0" val="311.035082035"/>
+      </location>
+    </component>
+  </type>
+  <!--STANDARD 8-PACK-->
+  <type name="eightpack">
+    <properties/>
+    <component type="tube">
+      <location name="tube1" x="-0.096012"/>
+      <location name="tube2" x="-0.06858"/>
+      <location name="tube3" x="-0.041148"/>
+      <location name="tube4" x="-0.013716"/>
+      <location name="tube5" x="0.013716"/>
+      <location name="tube6" x="0.041148"/>
+      <location name="tube7" x="0.06858"/>
+      <location name="tube8" x="0.096012"/>
+    </component>
+  </type>
+  <!--STANDARD 2m 128 PIXEL TUBE-->
+  <type name="tube" outline="yes">
+    <properties/>
+    <component type="pixel">
+      <location name="pixel1" y="-0.2"/>
+      <location name="pixel2" y="-0.1984375"/>
+      <location name="pixel3" y="-0.196875"/>
+      <location name="pixel4" y="-0.1953125"/>
+      <location name="pixel5" y="-0.19375"/>
+      <location name="pixel6" y="-0.1921875"/>
+      <location name="pixel7" y="-0.190625"/>
+      <location name="pixel8" y="-0.1890625"/>
+      <location name="pixel9" y="-0.1875"/>
+      <location name="pixel10" y="-0.1859375"/>
+      <location name="pixel11" y="-0.184375"/>
+      <location name="pixel12" y="-0.1828125"/>
+      <location name="pixel13" y="-0.18125"/>
+      <location name="pixel14" y="-0.1796875"/>
+      <location name="pixel15" y="-0.178125"/>
+      <location name="pixel16" y="-0.1765625"/>
+      <location name="pixel17" y="-0.175"/>
+      <location name="pixel18" y="-0.1734375"/>
+      <location name="pixel19" y="-0.171875"/>
+      <location name="pixel20" y="-0.1703125"/>
+      <location name="pixel21" y="-0.16875"/>
+      <location name="pixel22" y="-0.1671875"/>
+      <location name="pixel23" y="-0.165625"/>
+      <location name="pixel24" y="-0.1640625"/>
+      <location name="pixel25" y="-0.1625"/>
+      <location name="pixel26" y="-0.1609375"/>
+      <location name="pixel27" y="-0.159375"/>
+      <location name="pixel28" y="-0.1578125"/>
+      <location name="pixel29" y="-0.15625"/>
+      <location name="pixel30" y="-0.1546875"/>
+      <location name="pixel31" y="-0.153125"/>
+      <location name="pixel32" y="-0.1515625"/>
+      <location name="pixel33" y="-0.15"/>
+      <location name="pixel34" y="-0.1484375"/>
+      <location name="pixel35" y="-0.146875"/>
+      <location name="pixel36" y="-0.1453125"/>
+      <location name="pixel37" y="-0.14375"/>
+      <location name="pixel38" y="-0.1421875"/>
+      <location name="pixel39" y="-0.140625"/>
+      <location name="pixel40" y="-0.1390625"/>
+      <location name="pixel41" y="-0.1375"/>
+      <location name="pixel42" y="-0.1359375"/>
+      <location name="pixel43" y="-0.134375"/>
+      <location name="pixel44" y="-0.1328125"/>
+      <location name="pixel45" y="-0.13125"/>
+      <location name="pixel46" y="-0.1296875"/>
+      <location name="pixel47" y="-0.128125"/>
+      <location name="pixel48" y="-0.1265625"/>
+      <location name="pixel49" y="-0.125"/>
+      <location name="pixel50" y="-0.1234375"/>
+      <location name="pixel51" y="-0.121875"/>
+      <location name="pixel52" y="-0.1203125"/>
+      <location name="pixel53" y="-0.11875"/>
+      <location name="pixel54" y="-0.1171875"/>
+      <location name="pixel55" y="-0.115625"/>
+      <location name="pixel56" y="-0.1140625"/>
+      <location name="pixel57" y="-0.1125"/>
+      <location name="pixel58" y="-0.1109375"/>
+      <location name="pixel59" y="-0.109375"/>
+      <location name="pixel60" y="-0.1078125"/>
+      <location name="pixel61" y="-0.10625"/>
+      <location name="pixel62" y="-0.1046875"/>
+      <location name="pixel63" y="-0.103125"/>
+      <location name="pixel64" y="-0.1015625"/>
+      <location name="pixel65" y="-0.1"/>
+      <location name="pixel66" y="-0.0984375"/>
+      <location name="pixel67" y="-0.096875"/>
+      <location name="pixel68" y="-0.0953125"/>
+      <location name="pixel69" y="-0.09375"/>
+      <location name="pixel70" y="-0.0921875"/>
+      <location name="pixel71" y="-0.090625"/>
+      <location name="pixel72" y="-0.0890625"/>
+      <location name="pixel73" y="-0.0875"/>
+      <location name="pixel74" y="-0.0859375"/>
+      <location name="pixel75" y="-0.084375"/>
+      <location name="pixel76" y="-0.0828125"/>
+      <location name="pixel77" y="-0.08125"/>
+      <location name="pixel78" y="-0.0796875"/>
+      <location name="pixel79" y="-0.078125"/>
+      <location name="pixel80" y="-0.0765625"/>
+      <location name="pixel81" y="-0.075"/>
+      <location name="pixel82" y="-0.0734375"/>
+      <location name="pixel83" y="-0.071875"/>
+      <location name="pixel84" y="-0.0703125"/>
+      <location name="pixel85" y="-0.06875"/>
+      <location name="pixel86" y="-0.0671875"/>
+      <location name="pixel87" y="-0.065625"/>
+      <location name="pixel88" y="-0.0640625"/>
+      <location name="pixel89" y="-0.0625"/>
+      <location name="pixel90" y="-0.0609375"/>
+      <location name="pixel91" y="-0.059375"/>
+      <location name="pixel92" y="-0.0578125"/>
+      <location name="pixel93" y="-0.05625"/>
+      <location name="pixel94" y="-0.0546875"/>
+      <location name="pixel95" y="-0.053125"/>
+      <location name="pixel96" y="-0.0515625"/>
+      <location name="pixel97" y="-0.05"/>
+      <location name="pixel98" y="-0.0484375"/>
+      <location name="pixel99" y="-0.046875"/>
+      <location name="pixel100" y="-0.0453125"/>
+      <location name="pixel101" y="-0.04375"/>
+      <location name="pixel102" y="-0.0421875"/>
+      <location name="pixel103" y="-0.040625"/>
+      <location name="pixel104" y="-0.0390625"/>
+      <location name="pixel105" y="-0.0375"/>
+      <location name="pixel106" y="-0.0359375"/>
+      <location name="pixel107" y="-0.034375"/>
+      <location name="pixel108" y="-0.0328125"/>
+      <location name="pixel109" y="-0.03125"/>
+      <location name="pixel110" y="-0.0296875"/>
+      <location name="pixel111" y="-0.028125"/>
+      <location name="pixel112" y="-0.0265625"/>
+      <location name="pixel113" y="-0.025"/>
+      <location name="pixel114" y="-0.0234375"/>
+      <location name="pixel115" y="-0.021875"/>
+      <location name="pixel116" y="-0.0203125"/>
+      <location name="pixel117" y="-0.01875"/>
+      <location name="pixel118" y="-0.0171875"/>
+      <location name="pixel119" y="-0.015625"/>
+      <location name="pixel120" y="-0.0140625"/>
+      <location name="pixel121" y="-0.0125"/>
+      <location name="pixel122" y="-0.0109375"/>
+      <location name="pixel123" y="-0.009375"/>
+      <location name="pixel124" y="-0.0078125"/>
+      <location name="pixel125" y="-0.00625"/>
+      <location name="pixel126" y="-0.0046875"/>
+      <location name="pixel127" y="-0.003125"/>
+      <location name="pixel128" y="-0.0015625"/>
+      <location name="pixel129" y="0.0"/>
+      <location name="pixel130" y="0.0015625"/>
+      <location name="pixel131" y="0.003125"/>
+      <location name="pixel132" y="0.0046875"/>
+      <location name="pixel133" y="0.00625"/>
+      <location name="pixel134" y="0.0078125"/>
+      <location name="pixel135" y="0.009375"/>
+      <location name="pixel136" y="0.0109375"/>
+      <location name="pixel137" y="0.0125"/>
+      <location name="pixel138" y="0.0140625"/>
+      <location name="pixel139" y="0.015625"/>
+      <location name="pixel140" y="0.0171875"/>
+      <location name="pixel141" y="0.01875"/>
+      <location name="pixel142" y="0.0203125"/>
+      <location name="pixel143" y="0.021875"/>
+      <location name="pixel144" y="0.0234375"/>
+      <location name="pixel145" y="0.025"/>
+      <location name="pixel146" y="0.0265625"/>
+      <location name="pixel147" y="0.028125"/>
+      <location name="pixel148" y="0.0296875"/>
+      <location name="pixel149" y="0.03125"/>
+      <location name="pixel150" y="0.0328125"/>
+      <location name="pixel151" y="0.034375"/>
+      <location name="pixel152" y="0.0359375"/>
+      <location name="pixel153" y="0.0375"/>
+      <location name="pixel154" y="0.0390625"/>
+      <location name="pixel155" y="0.040625"/>
+      <location name="pixel156" y="0.0421875"/>
+      <location name="pixel157" y="0.04375"/>
+      <location name="pixel158" y="0.0453125"/>
+      <location name="pixel159" y="0.046875"/>
+      <location name="pixel160" y="0.0484375"/>
+      <location name="pixel161" y="0.05"/>
+      <location name="pixel162" y="0.0515625"/>
+      <location name="pixel163" y="0.053125"/>
+      <location name="pixel164" y="0.0546875"/>
+      <location name="pixel165" y="0.05625"/>
+      <location name="pixel166" y="0.0578125"/>
+      <location name="pixel167" y="0.059375"/>
+      <location name="pixel168" y="0.0609375"/>
+      <location name="pixel169" y="0.0625"/>
+      <location name="pixel170" y="0.0640625"/>
+      <location name="pixel171" y="0.065625"/>
+      <location name="pixel172" y="0.0671875"/>
+      <location name="pixel173" y="0.06875"/>
+      <location name="pixel174" y="0.0703125"/>
+      <location name="pixel175" y="0.071875"/>
+      <location name="pixel176" y="0.0734375"/>
+      <location name="pixel177" y="0.075"/>
+      <location name="pixel178" y="0.0765625"/>
+      <location name="pixel179" y="0.078125"/>
+      <location name="pixel180" y="0.0796875"/>
+      <location name="pixel181" y="0.08125"/>
+      <location name="pixel182" y="0.0828125"/>
+      <location name="pixel183" y="0.084375"/>
+      <location name="pixel184" y="0.0859375"/>
+      <location name="pixel185" y="0.0875"/>
+      <location name="pixel186" y="0.0890625"/>
+      <location name="pixel187" y="0.090625"/>
+      <location name="pixel188" y="0.0921875"/>
+      <location name="pixel189" y="0.09375"/>
+      <location name="pixel190" y="0.0953125"/>
+      <location name="pixel191" y="0.096875"/>
+      <location name="pixel192" y="0.0984375"/>
+      <location name="pixel193" y="0.1"/>
+      <location name="pixel194" y="0.1015625"/>
+      <location name="pixel195" y="0.103125"/>
+      <location name="pixel196" y="0.1046875"/>
+      <location name="pixel197" y="0.10625"/>
+      <location name="pixel198" y="0.1078125"/>
+      <location name="pixel199" y="0.109375"/>
+      <location name="pixel200" y="0.1109375"/>
+      <location name="pixel201" y="0.1125"/>
+      <location name="pixel202" y="0.1140625"/>
+      <location name="pixel203" y="0.115625"/>
+      <location name="pixel204" y="0.1171875"/>
+      <location name="pixel205" y="0.11875"/>
+      <location name="pixel206" y="0.1203125"/>
+      <location name="pixel207" y="0.121875"/>
+      <location name="pixel208" y="0.1234375"/>
+      <location name="pixel209" y="0.125"/>
+      <location name="pixel210" y="0.1265625"/>
+      <location name="pixel211" y="0.128125"/>
+      <location name="pixel212" y="0.1296875"/>
+      <location name="pixel213" y="0.13125"/>
+      <location name="pixel214" y="0.1328125"/>
+      <location name="pixel215" y="0.134375"/>
+      <location name="pixel216" y="0.1359375"/>
+      <location name="pixel217" y="0.1375"/>
+      <location name="pixel218" y="0.1390625"/>
+      <location name="pixel219" y="0.140625"/>
+      <location name="pixel220" y="0.1421875"/>
+      <location name="pixel221" y="0.14375"/>
+      <location name="pixel222" y="0.1453125"/>
+      <location name="pixel223" y="0.146875"/>
+      <location name="pixel224" y="0.1484375"/>
+      <location name="pixel225" y="0.15"/>
+      <location name="pixel226" y="0.1515625"/>
+      <location name="pixel227" y="0.153125"/>
+      <location name="pixel228" y="0.1546875"/>
+      <location name="pixel229" y="0.15625"/>
+      <location name="pixel230" y="0.1578125"/>
+      <location name="pixel231" y="0.159375"/>
+      <location name="pixel232" y="0.1609375"/>
+      <location name="pixel233" y="0.1625"/>
+      <location name="pixel234" y="0.1640625"/>
+      <location name="pixel235" y="0.165625"/>
+      <location name="pixel236" y="0.1671875"/>
+      <location name="pixel237" y="0.16875"/>
+      <location name="pixel238" y="0.1703125"/>
+      <location name="pixel239" y="0.171875"/>
+      <location name="pixel240" y="0.1734375"/>
+      <location name="pixel241" y="0.175"/>
+      <location name="pixel242" y="0.1765625"/>
+      <location name="pixel243" y="0.178125"/>
+      <location name="pixel244" y="0.1796875"/>
+      <location name="pixel245" y="0.18125"/>
+      <location name="pixel246" y="0.1828125"/>
+      <location name="pixel247" y="0.184375"/>
+      <location name="pixel248" y="0.1859375"/>
+      <location name="pixel249" y="0.1875"/>
+      <location name="pixel250" y="0.1890625"/>
+      <location name="pixel251" y="0.190625"/>
+      <location name="pixel252" y="0.1921875"/>
+      <location name="pixel253" y="0.19375"/>
+      <location name="pixel254" y="0.1953125"/>
+      <location name="pixel255" y="0.196875"/>
+      <location name="pixel256" y="0.1984375"/>
+    </component>
+  </type>
+  <!--PIXEL FOR STANDARD 2m 128 PIXEL TUBE-->
+  <type is="detector" name="pixel">
+    <cylinder id="cyl-approx">
+      <centre-of-bottom-base p="0.0" r="0.0" t="0.0"/>
+      <axis x="0.0" y="1.0" z="0.0"/>
+      <radius val="0.006"/>
+      <height val="0.0015625"/>
+    </cylinder>
+    <algebra val="cyl-approx"/>
+  </type>
+  <!--MONITOR SHAPE-->
+  <!--FIXME: Do something real here.-->
+  <type is="monitor" name="monitor">
+    <cylinder id="cyl-approx">
+      <centre-of-bottom-base p="0.0" r="0.0" t="0.0"/>
+      <axis x="0.0" y="0.0" z="1.0"/>
+      <radius val="0.01"/>
+      <height val="0.03"/>
+    </cylinder>
+    <algebra val="cyl-approx"/>
+  </type>
+  <!--DETECTOR IDs-->
+  <idlist idname="detectors">
+    <id end="2047" start="0"/>
+  </idlist>
+  <!--DETECTOR PARAMETERS-->
+  <component-link name="detectors">
+    <parameter name="tube_pressure">
+      <value units="atm" val="6.0"/>
+    </parameter>
+    <parameter name="tube_thickness">
+      <value units="metre" val="0.0008"/>
+    </parameter>
+    <parameter name="tube_temperature">
+      <value units="K" val="290.0"/>
+    </parameter>
+  </component-link>
+</instrument>
diff --git a/instrument/NOW4_Parameters.xml b/instrument/NOW4_Parameters.xml
new file mode 100644
index 0000000000000000000000000000000000000000..77935f2bfe0b9173a017b941e8ea3a3003de2c27
--- /dev/null
+++ b/instrument/NOW4_Parameters.xml
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<parameter-file instrument="NOW4" valid-from="2011-10-10T00:00:00">
+
+	<component-link name="NOW4">
+
+		<parameter name="deltaE-mode" type="string">
+			<value val="direct" />
+		</parameter>
+
+		<parameter name="ei-mon1-spec">
+			<value val="2" />
+		</parameter>
+
+		<parameter name="ei-mon2-spec">
+			<value val="3" />
+		</parameter>
+
+		<!-- TODO: Update with real vanadium mass -->
+		<parameter name="vanadium-mass">
+			<value val="-1" />
+		</parameter>
+
+		<parameter name="bkgd-range-min">
+			<value val="30000" />
+		</parameter>
+
+		<parameter name="bkgd-range-max">
+			<value val="31500" />
+		</parameter>
+
+		<parameter name="scale-factor">
+			<value val="1.0" />
+		</parameter>
+
+		<parameter name="monovan-integr-min">
+			<value val="-1" />
+		</parameter>
+
+		<parameter name="monovan-integr-max">
+			<value val="1" />
+		</parameter>
+
+		<!-- Diagnostic test defaults -->
+
+		<!-- Absolute lo threshold for vanadium diag (tiny) -->
+		<parameter name="diag_tiny">
+		  <value val="1e-10"/>
+		</parameter>
+
+		<!-- Absolute hi threshold for vanadium diag (huge) -->
+		<parameter name="diag_huge">
+		  <value val="1e10"/>
+		</parameter>
+
+		<!-- Remove zeroes in background (s_zero)-->
+		<parameter name="diag_samp_zero">
+		  <value val="0.0"/>
+		</parameter>
+
+		<!-- Fraction of median to consider counting low for the white beam diag (sv_lo)-->
+		<parameter name="diag_samp_lo">
+		  <value val="0.0"/>
+		</parameter>
+
+		<!-- Fraction of median to consider counting high for the white beam diag (sv_hi)-->
+		<parameter name="diag_samp_hi">
+		  <value val="5.0"/>
+		</parameter>
+
+		<!-- Error criterion as a multiple of error bar for background (sv_sig) -->
+		<parameter name="diag_samp_sig">
+		  <value val="3.3"/>
+		</parameter>
+
+		<!-- Lower bound defining outliers as fraction of median value (v_out_lo)-->
+		<parameter name="diag_van_out_lo">
+		  <value val="0.01"/>
+		</parameter>
+
+		<!-- Upper bound defining outliers as fraction of median value (v_out_hi)-->
+		<parameter name="diag_van_out_hi">
+		  <value val="100."/>
+		</parameter>
+
+		<!-- Fraction of median to consider counting low for the white beam diag (vv_lo)-->
+		<parameter name="diag_van_lo">
+		  <value val="0.1"/>
+		</parameter>
+
+		<!-- Fraction of median to consider counting high for the white beam diag (vv_hi)-->
+		<parameter name="diag_van_hi">
+		  <value val="1.5"/>
+		</parameter>
+
+		<!-- Error criterion as a multiple of error bar for background (vv_sig) -->
+		<parameter name="diag_van_sig">
+		  <value val="3.3"/>
+		</parameter>
+
+		<!-- True if background is to be checked -->
+		<parameter name="check_background">
+		  <value val="0.0"/>
+		</parameter>
+
+		<!-- True if the bleed tests should be run -->
+		<parameter name="diag_bleed_test">
+		  <value val="0.0"/>
+		</parameter>
+
+		<!-- Variation for ratio test with second white beam -->
+		<parameter name="diag_variation">
+		  <value val="1.1"/>
+		</parameter>
+
+		<!-- Absolute units conversion average -->
+
+		<parameter name="monovan_lo_bound">
+			<value val="0.01" />
+		</parameter>
+
+		<parameter name="monovan_hi_bound">
+			<value val="100" />
+		</parameter>
+
+		<parameter name="monovan_lo_frac">
+			<value val="0.8" />
+		</parameter>
+
+		<parameter name="monovan_hi_frac">
+			<value val="1.2" />
+		</parameter>
+
+		<!-- All the following parameters are taken directly from the MARI definition
+			and are WRONG! They are only here for now to get things working -->
+
+		<parameter name="wb-scale-factor">
+			<value val="1.0" />
+		</parameter>
+
+		<parameter name="wb-integr-min">
+			<value val="0.5" />
+		</parameter>
+
+		<parameter name="wb-integr-max">
+			<value val="80" />
+		</parameter>
+
+		<parameter name="norm-mon1-spec">
+			<value val="-3" />
+		</parameter>
+
+		<parameter name="norm-mon1-min">
+			<value val="1000" />
+		</parameter>
+
+		<parameter name="norm-mon1-max">
+			<value val="2000" />
+		</parameter>
+
+		<parameter name="abs-average-min">
+			<value val="1e-10" />
+		</parameter>
+
+		<parameter name="abs-average-max">
+			<value val="1e10" />
+		</parameter>
+
+		<parameter name="abs-median-lbound">
+			<value val="0.01" />
+		</parameter>
+
+		<parameter name="abs-median-ubound">
+			<value val="100" />
+		</parameter>
+
+		<parameter name="abs-median-lo-frac">
+			<value val="0.8" />
+		</parameter>
+
+		<parameter name="abs-median-hi-frac">
+			<value val="1.2" />
+		</parameter>
+
+		<parameter name="abs-median-signif">
+			<value val="3.3" />
+		</parameter>
+
+		<!--   formula for t0 calculation. See http://muparser.sourceforge.net/mup_features.html#idDef2 for available operators-->
+		<parameter name="t0_formula" type="string">
+			<value val="4.0 + (107.0 / (1.0 + (incidentEnergy / 31.0)^3))" />
+		</parameter>
+
+		<parameter name="treat-background-as-events" type="string">
+			<value val="yes" />
+		</parameter>
+
+	</component-link>
+</parameter-file>
diff --git a/instrument/Schema/IDF/1.0/IDFSchema.xsd b/instrument/Schema/IDF/1.0/IDFSchema.xsd
index c4925ed070949d4fcf04c9ac557660c3b84105ba..4764bda76f826fd2ee68eac4498a97e785b87e0b 100644
--- a/instrument/Schema/IDF/1.0/IDFSchema.xsd
+++ b/instrument/Schema/IDF/1.0/IDFSchema.xsd
@@ -194,7 +194,9 @@
         </xs:complexType>
       </xs:element>
       <xs:element name="description">      
-        <xs:attribute name="is"/>
+        <xs:complexType>
+          <xs:attribute name="is"/>
+        </xs:complexType>
       </xs:element>
       <xs:element name="fixed"/>
       <xs:element name="formula">
diff --git a/qt/CMakeLists.txt b/qt/CMakeLists.txt
index 8ba86e753bc4add79a9a12369a6dca7eb3c07205..258bc792fbd5e5881309d718b296bc0b54b1ba06 100644
--- a/qt/CMakeLists.txt
+++ b/qt/CMakeLists.txt
@@ -16,7 +16,7 @@ if(ENABLE_WORKBENCH AND NOT PYRCC5_CMD)
         ${PYTHON_EXECUTABLE}
         -m
         PyQt5.pyrcc_main
-        CACHE string "Command line to use to run the PyQt5 resource compiler")
+        CACHE STRING "Command line to use to run the PyQt5 resource compiler")
   else()
     find_file(PYRCC5_CMD "pyrcc5")
     if(NOT PYRCC5_CMD)
diff --git a/qt/applications/workbench/workbench/app/mainwindow.py b/qt/applications/workbench/workbench/app/mainwindow.py
index b4dc787f43e1ec4255e31ac1dafcda8fcbdf495c..14fa70eb2c0e588ed3c3339cd460e8c0c854b989 100644
--- a/qt/applications/workbench/workbench/app/mainwindow.py
+++ b/qt/applications/workbench/workbench/app/mainwindow.py
@@ -727,11 +727,19 @@ class MainWindow(QMainWindow):
 
 
 def initialize():
-    """Perform an initialization of the application instance. Most notably
-    this patches sys.exit so that it does nothing.
+    """Perform an initialization of the application instance.
+
+        - Patches sys.exit so that it does nothing.
+        - Uses WindowsSelectorEventLoop required by Tornado
 
     :return: A reference to the existing application instance
     """
+    if sys.version_info.major >= 3 and sys.platform == 'win32':
+        # Tornado requires WindowsSelectorEventLoop
+        # https://www.tornadoweb.org/en/stable/#installation
+        import asyncio
+        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
+
     app = qapplication()
 
     # Monkey patching sys.exit so users can't kill
diff --git a/qt/applications/workbench/workbench/plotting/plotscriptgenerator/__init__.py b/qt/applications/workbench/workbench/plotting/plotscriptgenerator/__init__.py
index 2325f12e15c02734ab029346b00bb5013a124301..9744431ef40ba85d2eb51f68d5bd8c24fa990eb4 100644
--- a/qt/applications/workbench/workbench/plotting/plotscriptgenerator/__init__.py
+++ b/qt/applications/workbench/workbench/plotting/plotscriptgenerator/__init__.py
@@ -11,6 +11,7 @@ from __future__ import (absolute_import, unicode_literals)
 from mantid.plots import MantidAxes
 
 from mantidqt.widgets.plotconfigdialog import curve_in_ax
+from matplotlib.legend import Legend
 from workbench.plugins.editor import DEFAULT_CONTENT
 from workbench.plotting.plotscriptgenerator.axes import (generate_axis_limit_commands,
                                                          generate_axis_label_commands,
@@ -22,6 +23,10 @@ from workbench.plotting.plotscriptgenerator.utils import generate_workspace_retr
 
 FIG_VARIABLE = "fig"
 AXES_VARIABLE = "axes"
+if hasattr(Legend, "set_draggable"):
+    SET_DRAGGABLE_METHOD = "set_draggable"
+else:
+    SET_DRAGGABLE_METHOD = "draggable"
 
 
 def generate_script(fig, exclude_headers=False):
@@ -107,7 +112,8 @@ def get_title_cmds(ax, ax_object_var):
 def get_legend_cmds(ax, ax_object_var):
     """Get command axes.set_legend"""
     if ax.legend_:
-        return ["{ax_obj}.legend().draggable()".format(ax_obj=ax_object_var)]
+        return ["{ax_obj}.legend().{draggable_method}()".format(ax_obj=ax_object_var,
+                                                                draggable_method=SET_DRAGGABLE_METHOD)]
     return []
 
 
diff --git a/qt/applications/workbench/workbench/plotting/plotscriptgenerator/test/test_plotscriptgenerator.py b/qt/applications/workbench/workbench/plotting/plotscriptgenerator/test/test_plotscriptgenerator.py
index 7cd871bac2d703572a5e8ae5db936421c05b7fcf..1c44cf2ad473514918066710ebc3083f49d72c8a 100644
--- a/qt/applications/workbench/workbench/plotting/plotscriptgenerator/test/test_plotscriptgenerator.py
+++ b/qt/applications/workbench/workbench/plotting/plotscriptgenerator/test/test_plotscriptgenerator.py
@@ -11,6 +11,7 @@ import unittest
 import matplotlib
 matplotlib.use("Agg")  # noqa
 from matplotlib.axes import Axes
+from matplotlib.legend import Legend
 
 from mantid.plots import MantidAxes
 from mantid.py3compat.mock import Mock, patch
@@ -120,7 +121,10 @@ class PlotScriptGeneratorTest(unittest.TestCase):
 
         mock_ax = self._gen_mock_axes(legend_=True)
         mock_fig = Mock(get_axes=lambda: [mock_ax])
-        self.assertIn('.legend().draggable()', generate_script(mock_fig))
+        if hasattr(Legend, "set_draggable"):
+            self.assertIn('.legend().set_draggable()', generate_script(mock_fig))
+        else:
+            self.assertIn('.legend().draggable()', generate_script(mock_fig))
 
     @patch(GET_AUTOSCALE_LIMITS)
     @patch(GEN_WS_RETRIEVAL_CMDS)
diff --git a/qt/applications/workbench/workbench/plotting/toolbar.py b/qt/applications/workbench/workbench/plotting/toolbar.py
index 53018e5862db88511b1d4bd4b3fbfdcd2f3aaa53..d0b7a5bdd38f2068cd4944f6271beb1f84c22684 100644
--- a/qt/applications/workbench/workbench/plotting/toolbar.py
+++ b/qt/applications/workbench/workbench/plotting/toolbar.py
@@ -76,7 +76,6 @@ class WorkbenchNavigationToolbar(NavigationToolbar2QT):
                 if tooltip_text is not None:
                     a.setToolTip(tooltip_text)
 
-        self.buttons = {}
         # Add the x,y location widget at the right side of the toolbar
         # The stretch factor is 1 which means any resizing of the toolbar
         # will resize this label instead of the buttons.
@@ -88,9 +87,6 @@ class WorkbenchNavigationToolbar(NavigationToolbar2QT):
             labelAction = self.addWidget(self.locLabel)
             labelAction.setVisible(True)
 
-        # reference holder for subplots_adjust window
-        self.adj_window = None
-
         # Adjust icon size or they are too small in PyQt5 by default
         dpi_ratio = QtWidgets.QApplication.instance().desktop().physicalDpiX() / 100
         self.setIconSize(QtCore.QSize(24 * dpi_ratio, 24 * dpi_ratio))
diff --git a/qt/applications/workbench/workbench/plugins/test/test_workspacewidget.py b/qt/applications/workbench/workbench/plugins/test/test_workspacewidget.py
index 1dfe1c0016163f95c804def2d7a1af20f9ff14ec..3d033e6c0ea2657135cd1275a90b57108bd24c53 100644
--- a/qt/applications/workbench/workbench/plugins/test/test_workspacewidget.py
+++ b/qt/applications/workbench/workbench/plugins/test/test_workspacewidget.py
@@ -7,23 +7,27 @@
 #    This file is part of the mantid workbench.
 #
 #
+from __future__ import (absolute_import, division)
 
 import unittest
 
-from qtpy.QtWidgets import QMainWindow, QApplication
+import matplotlib as mpl
+mpl.use('Agg')  # noqa
 
-from mantid.simpleapi import (CreateEmptyTableWorkspace, CreateWorkspace,
-                              GroupWorkspaces)
 from mantid.py3compat import mock
+from mantid.simpleapi import (CreateEmptyTableWorkspace, CreateSampleWorkspace,
+                              GroupWorkspaces)
 from mantidqt.utils.qt.testing import start_qapplication
 from mantidqt.utils.qt.testing.qt_widget_finder import QtWidgetFinder
-import matplotlib as mpl
-mpl.use('Agg')  # noqa
+from qtpy.QtWidgets import QMainWindow, QApplication
 from workbench.plugins.workspacewidget import WorkspaceWidget
 
-
+ALGORITHM_HISTORY_WINDOW_TYPE = "AlgorithmHistoryWindow"
 ALGORITHM_HISTORY_WINDOW = "mantidqt.widgets.workspacewidget." \
-                           "algorithmhistorywindow.AlgorithmHistoryWindow"
+                           "algorithmhistorywindow." + ALGORITHM_HISTORY_WINDOW_TYPE
+MATRIXWORKSPACE_DISPLAY = "mantidqt.widgets.workspacedisplay.matrix." \
+                          "presenter.MatrixWorkspaceDisplay"
+MATRIXWORKSPACE_DISPLAY_TYPE = "StatusBarView"
 
 app = QApplication([])
 
@@ -34,8 +38,7 @@ class WorkspaceWidgetTest(unittest.TestCase, QtWidgetFinder):
     @classmethod
     def setUpClass(cls):
         cls.ws_widget = WorkspaceWidget(QMainWindow())
-        cls.ahw_type_name = 'AlgorithmHistoryWindow'
-        mat_ws = CreateWorkspace([1], [2])
+        mat_ws = CreateSampleWorkspace()
         table_ws = CreateEmptyTableWorkspace()
         group_ws = GroupWorkspaces([mat_ws, table_ws])
         cls.w_spaces = [mat_ws, table_ws, group_ws]
@@ -46,17 +49,22 @@ class WorkspaceWidgetTest(unittest.TestCase, QtWidgetFinder):
     def test_algorithm_history_window_opens_with_workspace(self):
         with mock.patch(ALGORITHM_HISTORY_WINDOW + '.show', lambda x: None):
             self.ws_widget._do_show_algorithm_history([self.ws_names[0]])
-        self.assert_widget_type_exists(self.ahw_type_name)
+        self.assert_widget_type_exists(ALGORITHM_HISTORY_WINDOW_TYPE)
 
     def test_algorithm_history_window_doesnt_open_with_workspace_group(self):
         with mock.patch(ALGORITHM_HISTORY_WINDOW + '.show', lambda x: None):
             self.ws_widget._do_show_algorithm_history([self.ws_names[2]])
-        self.assert_widget_type_doesnt_exist(self.ahw_type_name)
+        self.assert_widget_type_doesnt_exist(ALGORITHM_HISTORY_WINDOW_TYPE)
 
     def test_algorithm_history_window_opens_multiple(self):
         with mock.patch(ALGORITHM_HISTORY_WINDOW + '.show', lambda x: None):
             self.ws_widget._do_show_algorithm_history(self.ws_names)
-        self.assert_number_of_widgets_matching(self.ahw_type_name, 2)
+        self.assert_number_of_widgets_matching(ALGORITHM_HISTORY_WINDOW_TYPE, 2)
+
+    def test_detector_table_shows_with_workspace(self):
+        with mock.patch(MATRIXWORKSPACE_DISPLAY + '.show_view', lambda x: None):
+            self.ws_widget._do_show_detectors([self.ws_names[0]])
+        self.assert_widget_type_exists(MATRIXWORKSPACE_DISPLAY_TYPE)
 
 
 if __name__ == '__main__':
diff --git a/qt/applications/workbench/workbench/plugins/workspacewidget.py b/qt/applications/workbench/workbench/plugins/workspacewidget.py
index 11ea278b3c13b4979b5247d8b2e049cb4b29b892..ce06d4eae68458e58aa5d4b2cfc62ca24691ad48 100644
--- a/qt/applications/workbench/workbench/plugins/workspacewidget.py
+++ b/qt/applications/workbench/workbench/plugins/workspacewidget.py
@@ -9,7 +9,6 @@
 #
 from __future__ import (absolute_import, unicode_literals)
 
-import matplotlib.pyplot
 from functools import partial
 from qtpy.QtWidgets import QApplication, QMessageBox, QVBoxLayout
 
@@ -156,6 +155,8 @@ class WorkspaceWidget(PluginWidget):
                                "".format(ws.name()))
 
     def _do_show_data(self, names):
+        # local import to allow this module to be imported without pyplot being imported
+        import matplotlib.pyplot
         for ws in self._ads.retrieveWorkspaces(names, unrollGroups=True):
             try:
                 MatrixWorkspaceDisplay.supports(ws)
@@ -194,9 +195,9 @@ class WorkspaceWidget(PluginWidget):
             except RuntimeError:
                 continue
             else:
-                successful_workspaces.append(ws.getName())
+                successful_workspaces.append(ws.name())
 
-        self._do_show_data(map(lambda x: x + "-Detectors", successful_workspaces))
+        self._do_show_data(list(map(lambda x: x + "-Detectors", successful_workspaces)))
 
     def _run_create_detector_table(self, ws):
         CreateDetectorTable(InputWorkspace=ws)
diff --git a/qt/applications/workbench/workbench/widgets/settings/general/presenter.py b/qt/applications/workbench/workbench/widgets/settings/general/presenter.py
index 287ded2c54b82afea9684274eaf20c3c0a15b35f..553d1d6c3f9030ae1a4cefa63936353d947a388b 100644
--- a/qt/applications/workbench/workbench/widgets/settings/general/presenter.py
+++ b/qt/applications/workbench/workbench/widgets/settings/general/presenter.py
@@ -30,6 +30,7 @@ class GeneralSettings(object):
     PR_RECOVERY_ENABLED = "projectRecovery.enabled"
     PROMPT_SAVE_EDITOR_MODIFIED = 'project/prompt_save_editor_modified'
     PROMPT_SAVE_ON_CLOSE = 'project/prompt_save_on_close'
+    USE_NOTIFICATIONS = 'Notifications.Enabled'
     USER_LAYOUT = "MainWindow/user_layouts"
 
     def __init__(self, parent, view=None):
@@ -89,6 +90,7 @@ class GeneralSettings(object):
     def setup_confirmations(self):
         self.view.prompt_save_on_close.stateChanged.connect(self.action_prompt_save_on_close)
         self.view.prompt_save_editor_modified.stateChanged.connect(self.action_prompt_save_editor_modified)
+        self.view.use_notifications.stateChanged.connect(self.action_use_notifications_modified)
 
     def action_prompt_save_on_close(self, state):
         CONF.set(self.PROMPT_SAVE_ON_CLOSE, bool(state))
@@ -96,6 +98,9 @@ class GeneralSettings(object):
     def action_prompt_save_editor_modified(self, state):
         CONF.set(self.PROMPT_SAVE_EDITOR_MODIFIED, bool(state))
 
+    def action_use_notifications_modified(self, state):
+        ConfigService.setString(self.USE_NOTIFICATIONS, "On" if bool(state) else "Off")
+
     def load_current_setting_values(self):
         self.view.prompt_save_on_close.setChecked(CONF.get(self.PROMPT_SAVE_ON_CLOSE))
         self.view.prompt_save_editor_modified.setChecked(CONF.get(self.PROMPT_SAVE_EDITOR_MODIFIED))
@@ -105,10 +110,12 @@ class GeneralSettings(object):
         pr_enabled = ("true" == ConfigService.getString(self.PR_RECOVERY_ENABLED).lower())
         pr_time_between_recovery = int(ConfigService.getString(self.PR_TIME_BETWEEN_RECOVERY))
         pr_number_checkpoints = int(ConfigService.getString(self.PR_NUMBER_OF_CHECKPOINTS))
+        use_notifications_setting = ("on" == ConfigService.getString(self.USE_NOTIFICATIONS).lower())
 
         self.view.project_recovery_enabled.setChecked(pr_enabled)
         self.view.time_between_recovery.setValue(pr_time_between_recovery)
         self.view.total_number_checkpoints.setValue(pr_number_checkpoints)
+        self.view.use_notifications.setChecked(use_notifications_setting)
 
     def action_project_recovery_enabled(self, state):
         ConfigService.setString(self.PR_RECOVERY_ENABLED, str(bool(state)))
diff --git a/qt/applications/workbench/workbench/widgets/settings/general/section_general.ui b/qt/applications/workbench/workbench/widgets/settings/general/section_general.ui
index 211ab3a7bddc0924e963db177e6cfb774eb21678..de580f31caa1b53794474cfca9d8115f814e6d16 100644
--- a/qt/applications/workbench/workbench/widgets/settings/general/section_general.ui
+++ b/qt/applications/workbench/workbench/widgets/settings/general/section_general.ui
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>580</width>
-    <height>479</height>
+    <height>541</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -44,9 +44,9 @@
       <property name="geometry">
        <rect>
         <x>0</x>
-        <y>-36</y>
-        <width>547</width>
-        <height>595</height>
+        <y>0</y>
+        <width>568</width>
+        <height>530</height>
        </rect>
       </property>
       <property name="sizePolicy">
@@ -173,7 +173,7 @@
             </sizepolicy>
            </property>
            <property name="title">
-            <string>Confirmations</string>
+            <string>Confirmations and Notifications</string>
            </property>
            <layout class="QVBoxLayout" name="verticalLayout_3">
             <item>
@@ -208,6 +208,22 @@
               </property>
              </widget>
             </item>
+            <item>
+             <widget class="QCheckBox" name="use_notifications">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="text">
+               <string>Use notifications for important events</string>
+              </property>
+              <property name="checked">
+               <bool>true</bool>
+              </property>
+             </widget>
+            </item>
            </layout>
           </widget>
          </item>
diff --git a/qt/python/mantidqt/_common.sip b/qt/python/mantidqt/_common.sip
index 0717cc0acd19d6bfabe76c31f3d64803d6eed19c..ffee4cf80aba2f1a764d0eb4b448f101620e70bc 100644
--- a/qt/python/mantidqt/_common.sip
+++ b/qt/python/mantidqt/_common.sip
@@ -887,6 +887,7 @@ public:
     QString getText();
     QString getFirstFilename() const;
     void isForRunFiles(bool /*mode*/);
+    void isForDirectory(bool /*mode*/);
     bool isSearching() const;
     bool isValid();
     void liveButtonSetChecked(bool);
diff --git a/qt/python/mantidqt/project/plotsloader.py b/qt/python/mantidqt/project/plotsloader.py
index ee19bf7431345972275de710401a2f97fd7f6eb3..309998423ad26e10d528cf38546021858f0e1b0e 100644
--- a/qt/python/mantidqt/project/plotsloader.py
+++ b/qt/python/mantidqt/project/plotsloader.py
@@ -239,19 +239,19 @@ class PlotsLoader(object):
 
     def update_axis(self, axis_, properties):
         if isinstance(axis_, matplotlib.axis.XAxis):
-            if properties["position"] is "top":
+            if properties["position"] == "top":
                 axis_.tick_top()
             else:
                 axis_.tick_bottom()
 
         if isinstance(axis_, matplotlib.axis.YAxis):
-            if properties["position"] is "right":
+            if properties["position"] == "right":
                 axis_.tick_right()
             else:
                 axis_.tick_left()
 
         labels = axis_.get_ticklabels()
-        if properties["fontSize"] is not "":
+        if properties["fontSize"] != "":
             for label in labels:
                 label.set_fontsize(properties["fontSize"])
 
@@ -276,17 +276,17 @@ class PlotsLoader(object):
     @staticmethod
     def update_axis_ticks(axis_, properties):
         # Update Major and Minor Locator
-        if properties["majorTickLocator"] is "FixedLocator":
+        if properties["majorTickLocator"] == "FixedLocator":
             axis_.set_major_locator(ticker.FixedLocator(properties["majorTickLocatorValues"]))
 
-        if properties["minorTickLocator"] is "FixedLocator":
+        if properties["minorTickLocator"] == "FixedLocator":
             axis_.set_minor_locator(ticker.FixedLocator(properties["minorTickLocatorValues"]))
 
         # Update Major and Minor Formatter
-        if properties["majorTickFormatter"] is "FixedFormatter":
+        if properties["majorTickFormatter"] == "FixedFormatter":
             axis_.set_major_formatter(ticker.FixedFormatter(properties["majorTickFormat"]))
 
-        if properties["minorTickFormatter"] is "FixedFormatter":
+        if properties["minorTickFormatter"] == "FixedFormatter":
             axis_.set_major_formatter(ticker.FixedLocator(properties["minorTickFormat"]))
 
     @staticmethod
diff --git a/qt/python/mantidqt/widgets/codeeditor/completion.py b/qt/python/mantidqt/widgets/codeeditor/completion.py
index 3da3608a69e8f901aea1d1ba1e2b86e1365a6303..d5290d19f1ff06ca625b9dd5248965869e04d27c 100644
--- a/qt/python/mantidqt/widgets/codeeditor/completion.py
+++ b/qt/python/mantidqt/widgets/codeeditor/completion.py
@@ -28,11 +28,13 @@ revisiting when we move to Python 3.
 from __future__ import (absolute_import, unicode_literals)
 
 import ast
+from collections import namedtuple
+import contextlib
 import inspect
+from keyword import kwlist as python_keywords
 import re
 import sys
-from keyword import kwlist as python_keywords
-from collections import namedtuple
+import warnings
 
 from lib2to3.pgen2.tokenize import detect_encoding
 from io import BytesIO
@@ -48,6 +50,16 @@ from mantidqt.widgets.codeeditor.editor import CodeEditor
 ArgSpec = namedtuple("ArgSpec", "args varargs keywords defaults")
 
 
+@contextlib.contextmanager
+def _ignore_matplotlib_deprecation_warnings():
+    """Context-manager to disable deprecation warnings from matplotlib while
+    generating the call tips"""
+    from matplotlib.cbook import MatplotlibDeprecationWarning
+    with warnings.catch_warnings():
+        warnings.simplefilter("ignore", MatplotlibDeprecationWarning)
+        yield
+
+
 def get_builtin_argspec(builtin):
     """
     Get the call tips for a builtin function from its docstring
@@ -233,7 +245,8 @@ class CodeCompleter(object):
         if re.search("^#{0}import .*numpy( |,|$)", self.editor.text(), re.MULTILINE):
             self._add_to_completions(self._get_module_call_tips('numpy'))
         if re.search("^#{0}import .*pyplot( |,|$)", self.editor.text(), re.MULTILINE):
-            self._add_to_completions(self._get_module_call_tips('matplotlib.pyplot'))
+            with _ignore_matplotlib_deprecation_warnings():
+                self._add_to_completions(self._get_module_call_tips('matplotlib.pyplot'))
         self._add_to_completions(python_keywords)
 
         self.editor.enableAutoCompletion(CodeEditor.AcsAPIs)
@@ -251,7 +264,8 @@ class CodeCompleter(object):
             self._completions_dict[completion] = True
 
     def update_completion_api(self):
-        self._add_to_completions(self._get_completions_from_globals())
+        with _ignore_matplotlib_deprecation_warnings():
+            self._add_to_completions(self._get_completions_from_globals())
         self.editor.updateCompletionAPI(self.completions)
 
     def _get_module_call_tips(self, module):
diff --git a/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/__init__.py b/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/__init__.py
index 72c00ca55b822bd7a2e3169f8738e04254909735..5e5ffb2aea1f1e66d05ccd6c287e3fe352bb7dba 100644
--- a/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/__init__.py
+++ b/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/__init__.py
@@ -8,6 +8,7 @@
 
 from __future__ import (absolute_import, unicode_literals)
 
+from mantid.plots.utility import legend_set_draggable
 from mantidqt.widgets.plotconfigdialog.colorselector import convert_color_to_hex
 import matplotlib
 from matplotlib.patches import BoxStyle
@@ -157,4 +158,4 @@ class LegendProperties(dict):
 
         legend.set_visible(props['visible'])
 
-        legend.draggable(True)
+        legend_set_draggable(legend, True)
diff --git a/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/presenter.py b/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/presenter.py
index 1628fca82994c54a4c31d6d93fd3443d9e30ebca..d93aac576de27500dffe04ff5d8d227dafe7c4ee 100644
--- a/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/presenter.py
+++ b/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/presenter.py
@@ -56,7 +56,7 @@ class LegendTabWidgetPresenter:
 
         # Converts alpha value (opacity value between 0 and 1) to transparency percentage.
         if int(matplotlib.__version__[0]) >= 2:
-            transparency = 100-(legend_props.transparency*100)
+            transparency = int(100 - (legend_props.transparency*100))
             self.view.set_transparency_spin_box(transparency)
             self.view.set_transparency_slider(transparency)
         self.view.set_entries_font(legend_props.entries_font)
diff --git a/qt/python/mantidqt/widgets/workspacedisplay/table/presenter.py b/qt/python/mantidqt/widgets/workspacedisplay/table/presenter.py
index 00c7401a01149f9a755af4ce33dd8f0eec9951a5..1390419ee2610ca719a289936277695c5e9a7f80 100644
--- a/qt/python/mantidqt/widgets/workspacedisplay/table/presenter.py
+++ b/qt/python/mantidqt/widgets/workspacedisplay/table/presenter.py
@@ -12,6 +12,7 @@ from functools import partial
 from qtpy.QtCore import Qt
 
 from mantid.kernel import logger
+from mantid.plots.utility import legend_set_draggable
 from mantidqt.widgets.observers.ads_observer import WorkspaceDisplayADSObserver
 from mantidqt.widgets.observers.observing_presenter import ObservingPresenter
 from mantidqt.widgets.workspacedisplay.data_copier import DataCopier
@@ -358,7 +359,7 @@ class TableWorkspaceDisplay(ObservingPresenter, DataCopier):
                 return
 
             ax.set_ylabel(column_label)
-        ax.legend().draggable()
+        legend_set_draggable(ax.legend(), True)
         fig.show()
 
     def _get_plot_function_from_type(self, ax, type):
diff --git a/qt/scientific_interfaces/Direct/ALFView_model.cpp b/qt/scientific_interfaces/Direct/ALFCustomInstrumentModel.cpp
similarity index 87%
rename from qt/scientific_interfaces/Direct/ALFView_model.cpp
rename to qt/scientific_interfaces/Direct/ALFCustomInstrumentModel.cpp
index f8bcd2fa4c7e06e39bbfc8886d83856cafa83ae7..f2c58b4ef21f1451801fc795c131c21445b6db8b 100644
--- a/qt/scientific_interfaces/Direct/ALFView_model.cpp
+++ b/qt/scientific_interfaces/Direct/ALFCustomInstrumentModel.cpp
@@ -5,15 +5,13 @@
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
 
-#include "ALFView_model.h"
+#include "ALFCustomInstrumentModel.h"
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/NumericAxis.h"
-
 #include "MantidGeometry/Instrument.h"
-
 #include "MantidKernel/Unit.h"
 
 #include <utility>
@@ -27,7 +25,8 @@ using namespace Mantid::API;
 namespace MantidQt {
 namespace CustomInterfaces {
 
-ALFView_model::ALFView_model() : m_numberOfTubesInAverage(0) {
+ALFCustomInstrumentModel::ALFCustomInstrumentModel()
+    : m_numberOfTubesInAverage(0) {
   m_tmpName = "ALF_tmp";
   m_instrumentName = "ALF";
   m_wsName = "ALFData";
@@ -40,7 +39,8 @@ ALFView_model::ALFView_model() : m_numberOfTubesInAverage(0) {
  * @param name:: string name for ALF data
  * @return std::pair<int,std::string>:: the run number and status
  */
-std::pair<int, std::string> ALFView_model::loadData(const std::string &name) {
+std::pair<int, std::string>
+ALFCustomInstrumentModel::loadData(const std::string &name) {
   auto alg = AlgorithmManager::Instance().create("Load");
   alg->initialize();
   alg->setProperty("Filename", name);
@@ -69,7 +69,7 @@ std::pair<int, std::string> ALFView_model::loadData(const std::string &name) {
  * Loads data, normalise to current and then converts to d spacing
  * @return pair<bool,bool>:: If the instrument is ALF, if it is d-spacing
  */
-std::map<std::string, bool> ALFView_model::isDataValid() {
+std::map<std::string, bool> ALFCustomInstrumentModel::isDataValid() {
   auto ws =
       AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(m_tmpName);
   bool isItALF = false;
@@ -90,7 +90,7 @@ std::map<std::string, bool> ALFView_model::isDataValid() {
  * Transforms ALF data; normalise to current and then converts to d spacing
  * If already d-space does nothing.
  */
-void ALFView_model::transformData() {
+void ALFCustomInstrumentModel::transformData() {
   auto normAlg = AlgorithmManager::Instance().create("NormaliseByCurrent");
   normAlg->initialize();
   normAlg->setProperty("InputWorkspace", m_wsName);
@@ -105,7 +105,7 @@ void ALFView_model::transformData() {
   dSpacingAlg->execute();
 }
 
-void ALFView_model::storeSingleTube(const std::string &name) {
+void ALFCustomInstrumentModel::storeSingleTube(const std::string &name) {
   auto alg = AlgorithmManager::Instance().create("ScaleX");
   alg->initialize();
   alg->setProperty("InputWorkspace", CURVES);
@@ -122,12 +122,12 @@ void ALFView_model::storeSingleTube(const std::string &name) {
   AnalysisDataService::Instance().remove(CURVES);
 }
 
-std::string ALFView_model::WSName() {
+std::string ALFCustomInstrumentModel::WSName() {
   std::string name = m_instrumentName + std::to_string(getCurrentRun());
   return EXTRACTEDWS + name;
 }
 
-void ALFView_model::averageTube() {
+void ALFCustomInstrumentModel::averageTube() {
   const std::string name = m_instrumentName + std::to_string(getCurrentRun());
   const int oldTotalNumber = m_numberOfTubesInAverage;
   // multiply up current average
@@ -160,11 +160,12 @@ void ALFView_model::averageTube() {
   m_numberOfTubesInAverage++;
 }
 
-bool ALFView_model::hasTubeBeenExtracted(const std::string &name) {
+bool ALFCustomInstrumentModel::hasTubeBeenExtracted(const std::string &name) {
   return AnalysisDataService::Instance().doesExist(EXTRACTEDWS + name);
 }
 
-bool ALFView_model::extractTubeConditon(std::map<std::string, bool> tabBools) {
+bool ALFCustomInstrumentModel::extractTubeConditon(
+    std::map<std::string, bool> tabBools) {
   try {
 
     bool ifCurve = (tabBools.find("plotStored")->second ||
@@ -175,7 +176,8 @@ bool ALFView_model::extractTubeConditon(std::map<std::string, bool> tabBools) {
   }
 }
 
-bool ALFView_model::averageTubeConditon(std::map<std::string, bool> tabBools) {
+bool ALFCustomInstrumentModel::averageTubeConditon(
+    std::map<std::string, bool> tabBools) {
   try {
 
     bool ifCurve = (tabBools.find("plotStored")->second ||
@@ -188,12 +190,12 @@ bool ALFView_model::averageTubeConditon(std::map<std::string, bool> tabBools) {
     return false;
   }
 }
-void ALFView_model::extractSingleTube() {
+void ALFCustomInstrumentModel::extractSingleTube() {
   storeSingleTube(m_instrumentName + std::to_string(getCurrentRun()));
   m_numberOfTubesInAverage = 1;
 }
 
-CompositeFunction_sptr ALFView_model::getDefaultFunction() {
+CompositeFunction_sptr ALFCustomInstrumentModel::getDefaultFunction() {
 
   CompositeFunction_sptr composite =
       boost::dynamic_pointer_cast<Mantid::API::CompositeFunction>(
diff --git a/qt/scientific_interfaces/Direct/ALFView_model.h b/qt/scientific_interfaces/Direct/ALFCustomInstrumentModel.h
similarity index 71%
rename from qt/scientific_interfaces/Direct/ALFView_model.h
rename to qt/scientific_interfaces/Direct/ALFCustomInstrumentModel.h
index 63b1f779fd85daf98943adef01ef20a541127ad1..74a357ef1fd0fc32d26d5e709b851884953abf85 100644
--- a/qt/scientific_interfaces/Direct/ALFView_model.h
+++ b/qt/scientific_interfaces/Direct/ALFCustomInstrumentModel.h
@@ -4,12 +4,12 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#ifndef MANTIDQT_CUSTOMINTERFACES_ALFVIEWMODEL_H_
-#define MANTIDQT_CUSTOMINTERFACES_ALFVIEWMODEL_H_
+#ifndef MANTIDQT_CUSTOMINTERFACES_ALFCUSTOMINSTRUMENTMODEL_H_
+#define MANTIDQT_CUSTOMINTERFACES_ALFCUSTOMINSTRUMENTMODEL_H_
 
-#include "BaseInstrumentModel.h"
 #include "MantidAPI/CompositeFunction.h"
 #include "MantidAPI/FunctionFactory.h"
+#include "MantidQtWidgets/InstrumentView/BaseCustomInstrumentModel.h"
 
 #include <map>
 #include <string>
@@ -17,11 +17,12 @@
 namespace MantidQt {
 namespace CustomInterfaces {
 
-class ALFView_model : public BaseInstrumentModel {
+class ALFCustomInstrumentModel
+    : public MantidWidgets::BaseCustomInstrumentModel {
 
 public:
-  ALFView_model();
-  virtual ~ALFView_model(){};
+  ALFCustomInstrumentModel();
+  virtual ~ALFCustomInstrumentModel(){};
   std::pair<int, std::string> loadData(const std::string &name) override;
   std::map<std::string, bool> isDataValid();
   void transformData();
@@ -41,4 +42,4 @@ private:
 } // namespace CustomInterfaces
 } // namespace MantidQt
 
-#endif /* MANTIDQT_CUSTOMINTERFACES_ALFVIEWMODEL_H_ */
+#endif /* MANTIDQT_CUSTOMINTERFACES_ALFCUSTOMINSTRUMENTMODEL_H_ */
diff --git a/qt/scientific_interfaces/Direct/ALFView_presenter.cpp b/qt/scientific_interfaces/Direct/ALFCustomInstrumentPresenter.cpp
similarity index 72%
rename from qt/scientific_interfaces/Direct/ALFView_presenter.cpp
rename to qt/scientific_interfaces/Direct/ALFCustomInstrumentPresenter.cpp
index baf5f8f77816675e5fe072f9e4c0a03d6e2bd5d3..c9f23955d076313a00d7ddb66a27d2ba2446e292 100644
--- a/qt/scientific_interfaces/Direct/ALFView_presenter.cpp
+++ b/qt/scientific_interfaces/Direct/ALFCustomInstrumentPresenter.cpp
@@ -4,11 +4,11 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#include "ALFView_presenter.h"
-#include "ALFView_model.h"
-#include "ALFView_view.h"
-
+#include "ALFCustomInstrumentPresenter.h"
+#include "ALFCustomInstrumentModel.h"
+#include "ALFCustomInstrumentView.h"
 #include "MantidAPI/FileFinder.h"
+#include "MantidQtWidgets/InstrumentView/PlotFitAnalysisPanePresenter.h"
 
 #include <functional>
 #include <tuple>
@@ -16,26 +16,29 @@
 namespace MantidQt {
 namespace CustomInterfaces {
 
-ALFView_presenter::ALFView_presenter(ALFView_view *view, ALFView_model *model,
-                                     PlotFitAnalysisPanePresenter *analysisPane)
-    : BaseInstrumentPresenter(view, model, analysisPane->getView()),
+ALFCustomInstrumentPresenter::ALFCustomInstrumentPresenter(
+    ALFCustomInstrumentView *view, ALFCustomInstrumentModel *model,
+    MantidWidgets::PlotFitAnalysisPanePresenter *analysisPane)
+    : BaseCustomInstrumentPresenter(view, model, analysisPane->getView()),
       m_view(view), m_model(model), m_analysisPane(analysisPane),
       m_extractSingleTubeObserver(nullptr), m_averageTubeObserver(nullptr) {
   addInstrument();
 }
 
-void ALFView_presenter::addInstrument() {
+void ALFCustomInstrumentPresenter::addInstrument() {
   auto setUp = setupALFInstrument();
   initLayout(&setUp);
 }
 
-void ALFView_presenter::setUpInstrumentAnalysisSplitter() {
+void ALFCustomInstrumentPresenter::setUpInstrumentAnalysisSplitter() {
   CompositeFunction_sptr composite = m_model->getDefaultFunction();
   m_analysisPane->addFunction(composite);
   m_view->setupAnalysisPane(m_analysisPane->getView());
 }
 
-void ALFView_presenter::loadSideEffects() { m_analysisPane->clearCurrentWS(); }
+void ALFCustomInstrumentPresenter::loadSideEffects() {
+  m_analysisPane->clearCurrentWS();
+}
 
 typedef std::pair<std::string,
                   std::vector<std::function<bool(std::map<std::string, bool>)>>>
@@ -49,7 +52,7 @@ typedef std::vector<std::tuple<std::string, Observer *>>
     instrumentObserverOptions> : a pair of the conditions and observers
 */
 std::pair<instrumentSetUp, instrumentObserverOptions>
-ALFView_presenter::setupALFInstrument() {
+ALFCustomInstrumentPresenter::setupALFInstrument() {
 
   m_extractSingleTubeObserver = new VoidObserver();
   m_averageTubeObserver = new VoidObserver();
@@ -62,10 +65,10 @@ ALFView_presenter::setupALFInstrument() {
 
   // set up custom context menu conditions
   std::function<bool(std::map<std::string, bool>)> extractConditionBinder =
-      std::bind(&ALFView_model::extractTubeConditon, m_model,
+      std::bind(&ALFCustomInstrumentModel::extractTubeConditon, m_model,
                 std::placeholders::_1);
   std::function<bool(std::map<std::string, bool>)> averageTubeConditonBinder =
-      std::bind(&ALFView_model::averageTubeConditon, m_model,
+      std::bind(&ALFCustomInstrumentModel::averageTubeConditon, m_model,
                 std::placeholders::_1);
 
   binders.emplace_back(extractConditionBinder);
@@ -75,7 +78,8 @@ ALFView_presenter::setupALFInstrument() {
 
   // set up single tube extract
   std::function<void()> extractSingleTubeBinder =
-      std::bind(&ALFView_presenter::extractSingleTube, this); // binder for slot
+      std::bind(&ALFCustomInstrumentPresenter::extractSingleTube,
+                this); // binder for slot
   m_extractSingleTubeObserver->setSlot(
       extractSingleTubeBinder); // add slot to observer
   std::tuple<std::string, Observer *> tmp = std::make_tuple(
@@ -84,7 +88,7 @@ ALFView_presenter::setupALFInstrument() {
 
   // set up average tube
   std::function<void()> averageTubeBinder =
-      std::bind(&ALFView_presenter::averageTube, this);
+      std::bind(&ALFCustomInstrumentPresenter::averageTube, this);
   m_averageTubeObserver->setSlot(averageTubeBinder);
   tmp = std::make_tuple("averageTube", m_averageTubeObserver);
   customInstrumentOptions.emplace_back(tmp);
@@ -92,13 +96,13 @@ ALFView_presenter::setupALFInstrument() {
   return std::make_pair(setUpContextConditions, customInstrumentOptions);
 }
 
-void ALFView_presenter::extractSingleTube() {
+void ALFCustomInstrumentPresenter::extractSingleTube() {
   m_model->extractSingleTube();
   const std::string WSName = m_model->WSName();
   m_analysisPane->addSpectrum(WSName);
 }
 
-void ALFView_presenter::averageTube() {
+void ALFCustomInstrumentPresenter::averageTube() {
   m_model->averageTube();
   const std::string WSName = m_model->WSName();
   m_analysisPane->addSpectrum(WSName);
diff --git a/qt/scientific_interfaces/Direct/ALFView_presenter.h b/qt/scientific_interfaces/Direct/ALFCustomInstrumentPresenter.h
similarity index 53%
rename from qt/scientific_interfaces/Direct/ALFView_presenter.h
rename to qt/scientific_interfaces/Direct/ALFCustomInstrumentPresenter.h
index 0df7153dc00583160557040bfb3b8360e958df58..b32512fdb98b0e309cae39583ae88f731960edb2 100644
--- a/qt/scientific_interfaces/Direct/ALFView_presenter.h
+++ b/qt/scientific_interfaces/Direct/ALFCustomInstrumentPresenter.h
@@ -4,30 +4,31 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#ifndef MANTIDQT_CUSTOMINTERFACES_ALFVIEWPRESENTER_H_
-#define MANTIDQT_CUSTOMINTERFACES_ALFVIEWPRESENTER_H_
+#ifndef MANTIDQT_CUSTOMINTERFACES_ALFCUSTOMINSTRUMENTPRESENTER_H_
+#define MANTIDQT_CUSTOMINTERFACES_ALFCUSTOMINSTRUMENTPRESENTER_H_
 
-#include "BaseInstrumentPresenter.h"
-#include "PlotFitAnalysisPanePresenter.h"
+#include "MantidQtWidgets/InstrumentView/BaseCustomInstrumentPresenter.h"
+#include "MantidQtWidgets/InstrumentView/PlotFitAnalysisPanePresenter.h"
 
-#include "ALFView_model.h"
-#include "ALFView_view.h"
+#include "ALFCustomInstrumentModel.h"
+#include "ALFCustomInstrumentView.h"
 #include "DllConfig.h"
 #include "MantidQtWidgets/Common/ObserverPattern.h"
-#include "MantidQtWidgets/Common/UserSubWindow.h"
 
 #include <string>
 
 namespace MantidQt {
 namespace CustomInterfaces {
 
-class MANTIDQT_DIRECT_DLL ALFView_presenter : public BaseInstrumentPresenter {
+class MANTIDQT_DIRECT_DLL ALFCustomInstrumentPresenter
+    : public MantidWidgets::BaseCustomInstrumentPresenter {
   Q_OBJECT
 
 public:
-  ALFView_presenter(ALFView_view *view, ALFView_model *model,
-                    PlotFitAnalysisPanePresenter *analysisPane);
-  ~ALFView_presenter() {
+  ALFCustomInstrumentPresenter(
+      ALFCustomInstrumentView *view, ALFCustomInstrumentModel *model,
+      MantidWidgets::PlotFitAnalysisPanePresenter *analysisPane);
+  ~ALFCustomInstrumentPresenter() {
     delete m_extractSingleTubeObserver;
     delete m_averageTubeObserver;
     delete m_analysisPane;
@@ -47,13 +48,13 @@ private:
   void extractSingleTube();
   void averageTube();
 
-  ALFView_view *m_view;
-  ALFView_model *m_model;
-  PlotFitAnalysisPanePresenter *m_analysisPane;
+  ALFCustomInstrumentView *m_view;
+  ALFCustomInstrumentModel *m_model;
+  MantidWidgets::PlotFitAnalysisPanePresenter *m_analysisPane;
   VoidObserver *m_extractSingleTubeObserver;
   VoidObserver *m_averageTubeObserver;
 };
 } // namespace CustomInterfaces
 } // namespace MantidQt
 
-#endif /* MANTIDQT_CUSTOMINTERFACES_ALFVIEWPRESENTER_H_ */
+#endif /* MANTIDQT_CUSTOMINTERFACES_ALFCUSTOMINSTRUMENTPRESENTER_H_ */
diff --git a/qt/scientific_interfaces/Direct/ALFView_view.cpp b/qt/scientific_interfaces/Direct/ALFCustomInstrumentView.cpp
similarity index 75%
rename from qt/scientific_interfaces/Direct/ALFView_view.cpp
rename to qt/scientific_interfaces/Direct/ALFCustomInstrumentView.cpp
index 32249d588a5fc244de039e7ccaac165726054eed..5ef3f7d3a3cec1271da1678b396c76b57468190f 100644
--- a/qt/scientific_interfaces/Direct/ALFView_view.cpp
+++ b/qt/scientific_interfaces/Direct/ALFCustomInstrumentView.cpp
@@ -4,7 +4,7 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#include "ALFView_view.h"
+#include "ALFCustomInstrumentView.h"
 #include "MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h"
 
 #include <QMessageBox>
@@ -15,15 +15,16 @@
 namespace MantidQt {
 namespace CustomInterfaces {
 
-ALFView_view::ALFView_view(const std::string &instrument, QWidget *parent)
-    : BaseInstrumentView(instrument, parent),
+ALFCustomInstrumentView::ALFCustomInstrumentView(const std::string &instrument,
+                                                 QWidget *parent)
+    : MantidWidgets::BaseCustomInstrumentView(instrument, parent),
       m_extractSingleTubeObservable(nullptr), m_averageTubeObservable(nullptr),
       m_extractAction(nullptr), m_averageAction(nullptr),
       m_analysisPane(nullptr) {
   m_helpPage = "ALF View";
 }
 
-void ALFView_view::setUpInstrument(
+void ALFCustomInstrumentView::setUpInstrument(
     const std::string &fileName,
     std::vector<std::function<bool(std::map<std::string, bool>)>> &binders) {
 
@@ -52,27 +53,28 @@ void ALFView_view::setUpInstrument(
   setInstrumentWidget(instrumentWidget);
 }
 
-void ALFView_view::extractSingleTube() {
+void ALFCustomInstrumentView::extractSingleTube() {
   MantidWidgets::InstrumentWidget *instrumentView = getInstrumentView();
   instrumentView->getPickTab()->savePlotToWorkspace();
 
   m_extractSingleTubeObservable->notify();
 }
 
-void ALFView_view::averageTube() {
+void ALFCustomInstrumentView::averageTube() {
   MantidWidgets::InstrumentWidget *instrumentView = getInstrumentView();
   instrumentView->getPickTab()->savePlotToWorkspace();
   m_averageTubeObservable->notify();
 }
 
-void ALFView_view::observeExtractSingleTube(Observer *listner) {
+void ALFCustomInstrumentView::observeExtractSingleTube(Observer *listner) {
   m_extractSingleTubeObservable->attach(listner);
 }
-void ALFView_view::observeAverageTube(Observer *listner) {
+void ALFCustomInstrumentView::observeAverageTube(Observer *listner) {
   m_averageTubeObservable->attach(listner);
 }
 
-void ALFView_view::addObserver(std::tuple<std::string, Observer *> &listener) {
+void ALFCustomInstrumentView::addObserver(
+    std::tuple<std::string, Observer *> &listener) {
   if (std::get<0>(listener) == "singleTube") {
     observeExtractSingleTube(std::get<1>(listener));
   } else if (std::get<0>(listener) == "averageTube") {
@@ -80,14 +82,15 @@ void ALFView_view::addObserver(std::tuple<std::string, Observer *> &listener) {
   }
 }
 
-void ALFView_view::setupAnalysisPane(PlotFitAnalysisPaneView *analysis) {
+void ALFCustomInstrumentView::setupAnalysisPane(
+    MantidWidgets::PlotFitAnalysisPaneView *analysis) {
   // keep a copy here so we can use a custom class
   m_analysisPane = analysis;
   // just adds it to the view
-  BaseInstrumentView::setupInstrumentAnalysisSplitters(analysis);
+  BaseCustomInstrumentView::setupInstrumentAnalysisSplitters(analysis);
 }
 
-void ALFView_view::addSpectrum(std::string wsName) {
+void ALFCustomInstrumentView::addSpectrum(std::string wsName) {
   m_analysisPane->addSpectrum(wsName);
 }
 
diff --git a/qt/scientific_interfaces/Direct/ALFView_view.h b/qt/scientific_interfaces/Direct/ALFCustomInstrumentView.h
similarity index 64%
rename from qt/scientific_interfaces/Direct/ALFView_view.h
rename to qt/scientific_interfaces/Direct/ALFCustomInstrumentView.h
index e77c1dc68f4a26110acb0314c73d7e570ed133f8..7b86bc56ca51ce479e1e1629548bc5dc4dcc05aa 100644
--- a/qt/scientific_interfaces/Direct/ALFView_view.h
+++ b/qt/scientific_interfaces/Direct/ALFCustomInstrumentView.h
@@ -4,15 +4,14 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#ifndef MANTIDQT_CUSTOMINTERFACES_ALFVIEW_VIEW_H_
-#define MANTIDQT_CUSTOMINTERFACES_ALFVIEW_VIEW_H_
+#ifndef MANTIDQT_CUSTOMINTERFACES_ALFCustomInstrumentView_H_
+#define MANTIDQT_CUSTOMINTERFACES_ALFCustomInstrumentView_H_
 
-#include "BaseInstrumentView.h"
 #include "DllConfig.h"
 #include "MantidQtWidgets/Common/MWRunFiles.h"
 #include "MantidQtWidgets/Common/ObserverPattern.h"
-#include "MantidQtWidgets/InstrumentView/InstrumentWidget.h"
-#include "PlotFitAnalysisPaneView.h"
+#include "MantidQtWidgets/InstrumentView/BaseCustomInstrumentView.h"
+#include "MantidQtWidgets/InstrumentView/PlotFitAnalysisPaneView.h"
 
 #include <QObject>
 #include <QSplitter>
@@ -22,12 +21,12 @@
 namespace MantidQt {
 namespace CustomInterfaces {
 
-class ALFView_view : public BaseInstrumentView {
+class ALFCustomInstrumentView : public MantidWidgets::BaseCustomInstrumentView {
   Q_OBJECT
 
 public:
-  explicit ALFView_view(const std::string &instrument,
-                        QWidget *parent = nullptr);
+  explicit ALFCustomInstrumentView(const std::string &instrument,
+                                   QWidget *parent = nullptr);
   void observeExtractSingleTube(Observer *listner);
   void observeAverageTube(Observer *listner);
 
@@ -38,7 +37,7 @@ public:
 
   void addObserver(std::tuple<std::string, Observer *> &listener) override;
   void addSpectrum(std::string wsName);
-  void setupAnalysisPane(PlotFitAnalysisPaneView *analysis);
+  void setupAnalysisPane(MantidWidgets::PlotFitAnalysisPaneView *analysis);
 
 public slots:
   void extractSingleTube();
@@ -49,9 +48,9 @@ private:
   Observable *m_averageTubeObservable;
   QAction *m_extractAction;
   QAction *m_averageAction;
-  PlotFitAnalysisPaneView *m_analysisPane;
+  MantidWidgets::PlotFitAnalysisPaneView *m_analysisPane;
 };
 } // namespace CustomInterfaces
 } // namespace MantidQt
 
-#endif /* MANTIDQT_CUSTOMINTERFACES_ALFVIEW_VIEW_H_ */
+#endif /* MANTIDQT_CUSTOMINTERFACES_ALFCustomInstrumentView_H_ */
diff --git a/qt/scientific_interfaces/Direct/ALFView.cpp b/qt/scientific_interfaces/Direct/ALFView.cpp
index 90589ae8d91dd75eab67674124a0416b82c871d5..995675fab20546892f17a037ac155605451712d8 100644
--- a/qt/scientific_interfaces/Direct/ALFView.cpp
+++ b/qt/scientific_interfaces/Direct/ALFView.cpp
@@ -4,20 +4,12 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#include "ALFView_model.h"
-#include "ALFView_presenter.h"
-#include "PlotFitAnalysisPaneModel.h"
-#include "PlotFitAnalysisPaneView.h"
-
-#include "BaseInstrumentModel.h"
-#include "BaseInstrumentView.h"
-// will need these later
-#include "MantidQtWidgets/Common/FunctionBrowser.h"
-#include "MantidQtWidgets/InstrumentView/InstrumentWidget.h"
-#include "MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h"
-#include "MantidQtWidgets/Plotting/PreviewPlot.h"
-
 #include "ALFView.h"
+#include "ALFCustomInstrumentModel.h"
+#include "ALFCustomInstrumentPresenter.h"
+
+#include "MantidQtWidgets/InstrumentView/PlotFitAnalysisPaneModel.h"
+#include "MantidQtWidgets/InstrumentView/PlotFitAnalysisPaneView.h"
 
 #include <tuple>
 
@@ -32,14 +24,16 @@ Mantid::Kernel::Logger g_log("ALFView");
 ALFView::ALFView(QWidget *parent)
     : UserSubWindow(parent), m_view(nullptr), m_presenter(nullptr),
       m_analysisPane(nullptr) {
-  m_model = new ALFView_model();
-  m_view = new ALFView_view(m_model->getInstrument(), this);
-  auto analysisView = new PlotFitAnalysisPaneView(-15.0, 15.0, m_view);
-  auto analysisModel = new PlotFitAnalysisPaneModel();
-  m_analysisPane =
-      new PlotFitAnalysisPanePresenter(analysisView, analysisModel);
-
-  m_presenter = new ALFView_presenter(m_view, m_model, m_analysisPane);
+  m_model = new ALFCustomInstrumentModel();
+  m_view = new ALFCustomInstrumentView(m_model->getInstrument(), this);
+  auto analysisView =
+      new MantidWidgets::PlotFitAnalysisPaneView(-15.0, 15.0, m_view);
+  auto analysisModel = new MantidWidgets::PlotFitAnalysisPaneModel();
+  m_analysisPane = new MantidWidgets::PlotFitAnalysisPanePresenter(
+      analysisView, analysisModel);
+
+  m_presenter =
+      new ALFCustomInstrumentPresenter(m_view, m_model, m_analysisPane);
 }
 void ALFView::initLayout() { this->setCentralWidget(m_view); }
 
diff --git a/qt/scientific_interfaces/Direct/ALFView.h b/qt/scientific_interfaces/Direct/ALFView.h
index 4b21df8b79d66a5e3c514c4e7c6f7ed5f3b98b86..98fc97308ea4395e3d57c919489c1815e5d47b3b 100644
--- a/qt/scientific_interfaces/Direct/ALFView.h
+++ b/qt/scientific_interfaces/Direct/ALFView.h
@@ -7,15 +7,13 @@
 #ifndef MANTIDQT_CUSTOMINTERFACES_ALFVIEW_H_
 #define MANTIDQT_CUSTOMINTERFACES_ALFVIEW_H_
 
-#include "ALFView_model.h"
-#include "ALFView_presenter.h"
-#include "ALFView_view.h"
+#include "ALFCustomInstrumentModel.h"
+#include "ALFCustomInstrumentPresenter.h"
+#include "ALFCustomInstrumentView.h"
 #include "DllConfig.h"
 #include "MantidQtWidgets/Common/ObserverPattern.h"
 #include "MantidQtWidgets/Common/UserSubWindow.h"
-
-#include "PlotFitAnalysisPanePresenter.h"
-#include "PlotFitAnalysisPaneView.h"
+#include "MantidQtWidgets/InstrumentView/PlotFitAnalysisPanePresenter.h"
 
 namespace MantidQt {
 namespace CustomInterfaces {
@@ -34,10 +32,10 @@ protected:
   void initLayout() override;
 
 private:
-  ALFView_view *m_view;
-  ALFView_model *m_model;
-  ALFView_presenter *m_presenter;
-  PlotFitAnalysisPanePresenter *m_analysisPane;
+  ALFCustomInstrumentView *m_view;
+  ALFCustomInstrumentModel *m_model;
+  ALFCustomInstrumentPresenter *m_presenter;
+  MantidWidgets::PlotFitAnalysisPanePresenter *m_analysisPane;
 };
 } // namespace CustomInterfaces
 } // namespace MantidQt
diff --git a/qt/scientific_interfaces/Direct/CMakeLists.txt b/qt/scientific_interfaces/Direct/CMakeLists.txt
index 95b428bc6b408b706f3bce420f375c496963e958..4cc3d153ea8ec7dbc2e253c7cd34b26794c7f552 100644
--- a/qt/scientific_interfaces/Direct/CMakeLists.txt
+++ b/qt/scientific_interfaces/Direct/CMakeLists.txt
@@ -1,24 +1,13 @@
 set(SRC_FILES
     ALFView.cpp
-    ALFView_view.cpp
-    ALFView_presenter.cpp
-    ALFView_model.cpp
-    BaseInstrumentModel.cpp
-    BaseInstrumentView.cpp
-    BaseInstrumentPresenter.cpp
-    PlotFitAnalysisPaneView.cpp
-    PlotFitAnalysisPanePresenter.cpp
-    PlotFitAnalysisPaneModel.cpp)
+    ALFCustomInstrumentView.cpp
+    ALFCustomInstrumentPresenter.cpp
+    ALFCustomInstrumentModel.cpp)
     
 set(MOC_FILES
     ALFView.h
-    ALFView_view.h
-    ALFView_presenter.h
-    BaseInstrumentView.h
-    BaseInstrumentView.h
-    BaseInstrumentPresenter.h
-    PlotFitAnalysisPaneView.h
-    PlotFitAnalysisPanePresenter.h)
+    ALFCustomInstrumentView.h
+    ALFCustomInstrumentPresenter.h)
     
 set(INC_FILES
     DllConfig.h)
@@ -49,8 +38,8 @@ mtd_add_qt_library(TARGET_NAME MantidScientificInterfacesDirect
                      Qwt5
                    MTD_QT_LINK_LIBS
                      MantidQtWidgetsCommon
-                     MantidQtWidgetsPlotting
                      MantidQtWidgetsInstrumentView
+                     MantidQtWidgetsPlotting
                    INSTALL_DIR_BASE
                      ${PLUGINS_DIR}
                    OSX_INSTALL_RPATH
@@ -84,7 +73,7 @@ mtd_add_qt_library(TARGET_NAME MantidScientificInterfacesDirect
                    MTD_QT_LINK_LIBS
                      MantidQtWidgetsCommon
                      MantidQtWidgetsInstrumentView
-					 MantidQtWidgetsPlotting
+                     MantidQtWidgetsPlotting
                      MantidQtWidgetsMplCpp
                    INSTALL_DIR_BASE
                      ${WORKBENCH_PLUGINS_DIR}
diff --git a/qt/scientific_interfaces/Muon/IO_MuonGrouping.cpp b/qt/scientific_interfaces/Muon/IO_MuonGrouping.cpp
index bd085510cecd1cc6e98ffb4912a078ba16d6509e..774ec8026bbce7fb3f86e85eec25780b013edca8 100644
--- a/qt/scientific_interfaces/Muon/IO_MuonGrouping.cpp
+++ b/qt/scientific_interfaces/Muon/IO_MuonGrouping.cpp
@@ -20,7 +20,6 @@
 #include <Poco/DOM/Text.h>
 #include <Poco/XML/XMLWriter.h>
 
-#include <boost/bind.hpp>
 #include <boost/shared_ptr.hpp>
 #include <fstream>
 
diff --git a/qt/scientific_interfaces/test/ISISReflectometry/Common/CoderCommonTester.h b/qt/scientific_interfaces/test/ISISReflectometry/Common/CoderCommonTester.h
index 3db2c579220ead5a2ee87d6f51e059803cab65c5..80cf962c5170f0bff60e2f02200717a686865a8f 100644
--- a/qt/scientific_interfaces/test/ISISReflectometry/Common/CoderCommonTester.h
+++ b/qt/scientific_interfaces/test/ISISReflectometry/Common/CoderCommonTester.h
@@ -295,7 +295,7 @@ private:
     TS_ASSERT_EQUALS(gui->m_ui.tabRadioButton->isChecked(),
                      map[QString("tabRadioButton")].toBool())
     TS_ASSERT_EQUALS(gui->m_ui.fileFormatComboBox->currentIndex(),
-                     map[QString("fileFormatComboBox")].toBool())
+                     map[QString("fileFormatComboBox")].toInt())
     TS_ASSERT_EQUALS(gui->m_ui.filterEdit->text(),
                      map[QString("filterEdit")].toString())
     TS_ASSERT_EQUALS(gui->m_ui.regexCheckBox->isChecked(),
@@ -332,4 +332,4 @@ private:
 } // namespace CustomInterfaces
 } // namespace MantidQt
 
-#endif /* CODER_COMMON_TESTER_H_ */
\ No newline at end of file
+#endif /* CODER_COMMON_TESTER_H_ */
diff --git a/qt/widgets/common/CMakeLists.txt b/qt/widgets/common/CMakeLists.txt
index e73e2df26ad1c6fb2dcc558dde89076d67970ed5..aaae86ccc7e863b6b3156c580612057d5004a89b 100644
--- a/qt/widgets/common/CMakeLists.txt
+++ b/qt/widgets/common/CMakeLists.txt
@@ -57,6 +57,7 @@ set(
   src/MessageDisplay.cpp
   src/MultifitSetupDialog.cpp
   src/MWRunFiles.cpp
+  src/NotificationService.cpp
   src/OptionsPropertyWidget.cpp
   src/ParseKeyValueString.cpp
   src/pixmaps.cpp
@@ -178,6 +179,7 @@ set(
   inc/MantidQtWidgets/Common/MessageDisplay.h
   inc/MantidQtWidgets/Common/MultifitSetupDialog.h
   inc/MantidQtWidgets/Common/MWRunFiles.h
+  inc/MantidQtWidgets/Common/NotificationService.h
   inc/MantidQtWidgets/Common/OptionsPropertyWidget.h
   inc/MantidQtWidgets/Common/pqHelpWindow.h
   inc/MantidQtWidgets/Common/ProcessingAlgoWidget.h
@@ -438,6 +440,7 @@ set(
   src/MuonFitDataSelector.cpp
   src/MuonFitPropertyBrowser.cpp
   src/MuonFunctionBrowser.cpp
+  src/NotificationService.cpp
   src/ProcessingAlgoWidget.cpp
   src/ProgressableView.cpp
   src/ProjectSavePresenter.cpp
@@ -550,6 +553,7 @@ set(
   inc/MantidQtWidgets/Common/MuonFitDataSelector.h
   inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h
   inc/MantidQtWidgets/Common/MuonFunctionBrowser.h
+  inc/MantidQtWidgets/Common/NotificationService.h
   inc/MantidQtWidgets/Common/pqHelpWindow.h
   inc/MantidQtWidgets/Common/PropertyHandler.h
   inc/MantidQtWidgets/Common/ProcessingAlgoWidget.h
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/NotificationService.h b/qt/widgets/common/inc/MantidQtWidgets/Common/NotificationService.h
new file mode 100644
index 0000000000000000000000000000000000000000..7fed1f93a90ad33e8188b4c25132cb9bb883c889
--- /dev/null
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/NotificationService.h
@@ -0,0 +1,49 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef MANTIDQTAPI_NOTIFICATIONSERVICE_H_
+#define MANTIDQTAPI_NOTIFICATIONSERVICE_H_
+
+#include "DllOption.h"
+#include <QObject>
+#include <QSystemTrayIcon>
+
+/** The base class from which mantid custom widgets are derived contains
+ *  some useful functions
+ */
+namespace MantidQt {
+namespace MantidWidgets {
+/**
+This is a singleton providing a notification service for the Mantid Qt based
+applications. This is just a thin simplistic wrapper around QSystemTray
+*/
+class EXPORT_OPT_MANTIDQT_COMMON NotificationService : public QObject {
+  Q_OBJECT
+
+public:
+  // Our Notification icons are the same as Qt's.
+  using MessageIcon = QSystemTrayIcon::MessageIcon;
+
+  /// Default constructor
+  NotificationService() : QObject() {}
+
+  /// Display a notification
+  static void showMessage(const QString &title, const QString &message,
+                          MessageIcon icon = MessageIcon::Information,
+                          int millisecondsTimeoutHint = 10000);
+
+  /// Is the notification service enabled through the config service?
+  static bool isEnabled();
+
+  static const std::string NOTIFICATIONS_ENABLED_KEY;
+
+  /// Are notifications supported by this OS?
+  static bool isSupportedByOS();
+};
+} // namespace MantidWidgets
+} // namespace MantidQt
+
+#endif // MANTIDQTAPI_NOTIFICATIONSERVICE_H_
diff --git a/qt/widgets/common/src/MantidTreeWidget.cpp b/qt/widgets/common/src/MantidTreeWidget.cpp
index 5dce3cd8ed8385c167c7582a21184f336dafed87..2669c6f537d9b7dbce0931f2f98f25f77fb6d037 100644
--- a/qt/widgets/common/src/MantidTreeWidget.cpp
+++ b/qt/widgets/common/src/MantidTreeWidget.cpp
@@ -73,7 +73,7 @@ void MantidTreeWidget::dropEvent(QDropEvent *de) {
   for (int i = 0; i < filenames.size(); ++i) {
     try {
       QFileInfo fi(filenames[i]);
-      QString basename = fi.baseName();
+      QString basename = fi.completeBaseName();
       auto alg = m_mantidUI->createAlgorithm("Load");
       alg->initialize();
       alg->setProperty("Filename", filenames[i].toStdString());
diff --git a/qt/widgets/common/src/MessageDisplay.cpp b/qt/widgets/common/src/MessageDisplay.cpp
index 4cb25ff4153003a7342ffa9a20a01ef21ed181a4..65b6aede2461a2c4c6b39bb1aba3c51d0783a0e3 100644
--- a/qt/widgets/common/src/MessageDisplay.cpp
+++ b/qt/widgets/common/src/MessageDisplay.cpp
@@ -11,6 +11,7 @@
 
 #include "MantidKernel/ConfigService.h"
 #include "MantidKernel/Logger.h"
+#include "MantidQtWidgets/Common/NotificationService.h"
 
 #include <QAction>
 #include <QActionGroup>
@@ -238,8 +239,14 @@ void MessageDisplay::append(const Message &msg) {
     cursor.insertText(msg.text(), format(msg.priority()));
     moveCursorToEnd();
 
-    if (msg.priority() <= Message::Priority::PRIO_ERROR)
+    if (msg.priority() <= Message::Priority::PRIO_ERROR) {
+      NotificationService::showMessage(
+          "Mantid Workbench",
+          "Sorry, there was an error, please look at the message display for "
+          "details.",
+          NotificationService::MessageIcon::Critical);
       emit errorReceived(msg.text());
+    }
     if (msg.priority() <= Message::Priority::PRIO_WARNING)
       emit warningReceived(msg.text());
   }
diff --git a/qt/widgets/common/src/NotificationService.cpp b/qt/widgets/common/src/NotificationService.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3eaf4822fcf900e25351868ffd05d0f63d335987
--- /dev/null
+++ b/qt/widgets/common/src/NotificationService.cpp
@@ -0,0 +1,68 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#include "MantidQtWidgets/Common/NotificationService.h"
+#include "MantidKernel/ConfigService.h"
+#include "MantidKernel/Exception.h"
+#include <QApplication>
+
+namespace MantidQt {
+namespace MantidWidgets {
+
+// Key for the "normalize data to bin width" plot option
+const std::string NotificationService::NOTIFICATIONS_ENABLED_KEY =
+    "Notifications.Enabled";
+
+void NotificationService::showMessage(const QString &title,
+                                      const QString &message, MessageIcon icon,
+                                      int millisecondsTimeoutHint) {
+  if (isEnabled() && isSupportedByOS()) {
+    QSystemTrayIcon sysTrayIcon(qApp);
+    // get the window icon for the app
+    QIcon windowIcon = qApp->windowIcon();
+    // if no icon is set then use the mantid icon
+    if (windowIcon.isNull()) {
+      try {
+        windowIcon = QIcon(":/images/MantidIcon.ico");
+      } catch (std::exception) {
+        // if we cannot use the embedded icon, use a blank one
+        windowIcon = QIcon(QPixmap(32, 32));
+      }
+    }
+    // set this as the window icon otherwise you get a warning on the console
+    sysTrayIcon.setIcon(windowIcon);
+
+    sysTrayIcon.show();
+    sysTrayIcon.showMessage(title, message, icon, millisecondsTimeoutHint);
+
+    sysTrayIcon.hide();
+  }
+}
+
+bool NotificationService::isEnabled() {
+  bool retVal = false;
+  try {
+    retVal = Mantid::Kernel::ConfigService::Instance()
+                 .getValue<bool>(NOTIFICATIONS_ENABLED_KEY)
+                 .get_value_or(true);
+  } catch (Mantid::Kernel::Exception::FileError) {
+    // The Config Service could not find the properties file
+    // Disable notifications
+    retVal = false;
+  } catch (Poco::ExistsException) {
+    // The Config Service could not find the properties file
+    // Disable notifications
+    retVal = false;
+  }
+  return retVal;
+}
+
+bool NotificationService::isSupportedByOS() {
+  return QSystemTrayIcon::supportsMessages();
+}
+
+} // namespace MantidWidgets
+} // namespace MantidQt
diff --git a/qt/widgets/common/src/Python/Sip.cpp b/qt/widgets/common/src/Python/Sip.cpp
index c7a2e42958614cd69b26290653131175d6a2bb9a..3102358e82e2e0424c52a57b66e6834b7bf8c78a 100644
--- a/qt/widgets/common/src/Python/Sip.cpp
+++ b/qt/widgets/common/src/Python/Sip.cpp
@@ -6,6 +6,7 @@
 // SPDX - License - Identifier: GPL - 3.0 +
 
 #include "MantidQtWidgets/Common/Python/Sip.h"
+#include <QtGlobal>
 #include <sip.h>
 
 namespace MantidQt {
@@ -21,30 +22,23 @@ const sipAPIDef *sipAPI() {
   static const sipAPIDef *sip_API = nullptr;
   if (sip_API)
     return sip_API;
-#if defined(SIP_USE_PYCAPSULE)
-  sip_API = (const sipAPIDef *)PyCapsule_Import("sip._C_API", 0);
-#else
-  /* Import the SIP module. */
-  PyObject *sip_module = PyImport_ImportModule("sip");
-  if (sip_module == NULL)
-    throw std::runtime_error("sip_api() - Error importing sip module");
-
-  /* Get the module's dictionary. */
-  PyObject *sip_module_dict = PyModule_GetDict(sip_module);
-
-  /* Get the "_C_API" attribute. */
-  PyObject *c_api = PyDict_GetItemString(sip_module_dict, "_C_API");
-  if (c_api == NULL)
-    throw std::runtime_error(
-        "sip_api() - Unable to find _C_API attribute in sip dictionary");
 
-  /* Sanity check that it is the right type. */
-  if (!PyCObject_Check(c_api))
-    throw std::runtime_error("sip_api() - _C_API type is not a CObject");
-
-  /* Get the actual pointer from the object. */
-  sip_API = (const sipAPIDef *)PyCObject_AsVoidPtr(c_api);
+    // Some configs have a private sip module inside PyQt. Try this first
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+  sip_API = (const sipAPIDef *)PyCapsule_Import("PyQt4.sip._C_API", 0);
+#elif QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) &&                               \
+    QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+  sip_API = (const sipAPIDef *)PyCapsule_Import("PyQt5.sip._C_API", 0);
+#else
+#error "Unknown sip module for Qt >= 6"
 #endif
+  // Try plain sip module
+  if (!sip_API) {
+    PyErr_Clear();
+    sip_API = (const sipAPIDef *)PyCapsule_Import("sip._C_API", 0);
+  }
+
+  assert(sip_API);
   return sip_API;
 }
 } // namespace Detail
@@ -52,4 +46,4 @@ const sipAPIDef *sipAPI() {
 } // namespace Python
 } // namespace Common
 } // namespace Widgets
-} // namespace MantidQt
\ No newline at end of file
+} // namespace MantidQt
diff --git a/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidget.cpp b/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidget.cpp
index 475f767d8a6ba52080fdb032cb0a4cd01867f28e..8153fea4b07baa8252b1ce02381d7026c4d961d0 100644
--- a/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidget.cpp
+++ b/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidget.cpp
@@ -20,6 +20,7 @@
 #include "MantidQtWidgets/Common/WorkspacePresenter/WorkspacePresenter.h"
 #include "MantidQtWidgets/Common/pixmaps.h"
 
+#include "MantidAPI/Axis.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidAPI/IMDWorkspace.h"
@@ -949,9 +950,10 @@ void WorkspaceTreeWidget::addMatrixWorkspaceMenuItems(
   menu->addAction(m_showData);
   menu->addAction(m_showInst);
   // Disable the 'show instrument' option if a workspace doesn't have an
-  // instrument attached
+  // instrument attached or if it does not have a spectra axis
   m_showInst->setEnabled(matrixWS->getInstrument() &&
-                         !matrixWS->getInstrument()->getName().empty());
+                         !matrixWS->getInstrument()->getName().empty() &&
+                         matrixWS->getAxis(1)->isSpectra());
   menu->addSeparator();
   menu->addAction(m_plotSpec);
   menu->addAction(m_plotSpecErr);
diff --git a/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidgetSimple.cpp b/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidgetSimple.cpp
index f57f66290dd0fe3a97d0fce0de4347a2ce46f1c3..eb77a52e852664b9180f0fb88bad6909d1406c2d 100644
--- a/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidgetSimple.cpp
+++ b/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidgetSimple.cpp
@@ -10,6 +10,7 @@
 #include "MantidQtWidgets/Common/MantidTreeWidgetItem.h"
 
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/Axis.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/IPeaksWorkspace.h"
 #include "MantidAPI/ITableWorkspace.h"
@@ -115,7 +116,8 @@ void WorkspaceTreeWidgetSimple::popupContextMenu() {
       menu->addAction(m_showInstrument);
       m_showInstrument->setEnabled(
           matrixWS->getInstrument() &&
-          !matrixWS->getInstrument()->getName().empty());
+          !matrixWS->getInstrument()->getName().empty() &&
+          matrixWS->getAxis(1)->isSpectra());
       menu->addAction(m_sampleLogs);
       menu->addAction(m_sliceViewer);
       menu->addAction(m_showDetectors);
diff --git a/qt/widgets/instrumentview/CMakeLists.txt b/qt/widgets/instrumentview/CMakeLists.txt
index 5140d63e89e4f4505cf7d995a15d27a8b8305d82..806dea6b7d86ab3524c920868d31511cf23b493b 100644
--- a/qt/widgets/instrumentview/CMakeLists.txt
+++ b/qt/widgets/instrumentview/CMakeLists.txt
@@ -6,6 +6,9 @@ set(
   SRC_FILES
   src/BankRenderingHelpers.cpp
   src/BankTextureBuilder.cpp
+  src/BaseCustomInstrumentModel.cpp
+  src/BaseCustomInstrumentView.cpp
+  src/BaseCustomInstrumentPresenter.cpp
   src/BinDialog.cpp
   src/CollapsiblePanel.cpp
   src/DetXMLFile.cpp
@@ -29,6 +32,9 @@ set(
   src/PanelsSurface.cpp
   src/PeakMarker2D.cpp
   src/PeakOverlay.cpp
+  src/PlotFitAnalysisPaneModel.cpp
+  src/PlotFitAnalysisPanePresenter.cpp
+  src/PlotFitAnalysisPaneView.cpp
   src/Projection3D.cpp
   src/ProjectionSurface.cpp
   src/RectF.cpp
@@ -52,6 +58,8 @@ set(QT5_SRC_FILES src/MiniPlotMpl.cpp)
 set(
   MOC_FILES
   inc/MantidQtWidgets/InstrumentView/BinDialog.h
+  inc/MantidQtWidgets/InstrumentView/BaseCustomInstrumentPresenter.h
+  inc/MantidQtWidgets/InstrumentView/BaseCustomInstrumentView.h
   inc/MantidQtWidgets/InstrumentView/CollapsiblePanel.h
   inc/MantidQtWidgets/InstrumentView/InstrumentActor.h
   inc/MantidQtWidgets/InstrumentView/InstrumentTreeModel.h
@@ -65,6 +73,8 @@ set(
   inc/MantidQtWidgets/InstrumentView/InstrumentWidgetTreeTab.h
   inc/MantidQtWidgets/InstrumentView/MantidGLWidget.h
   inc/MantidQtWidgets/InstrumentView/PeakOverlay.h
+  inc/MantidQtWidgets/InstrumentView/PlotFitAnalysisPaneView.h
+  inc/MantidQtWidgets/InstrumentView/PlotFitAnalysisPanePresenter.h
   inc/MantidQtWidgets/InstrumentView/Projection3D.h
   inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h
   inc/MantidQtWidgets/InstrumentView/Shape2DCollection.h
@@ -81,6 +91,9 @@ set(
   INC_FILES
   inc/MantidQtWidgets/InstrumentView/BankRenderingHelpers.h
   inc/MantidQtWidgets/InstrumentView/BankTextureBuilder.h
+  inc/MantidQtWidgets/InstrumentView/BaseCustomInstrumentModel.h
+  inc/MantidQtWidgets/InstrumentView/BaseCustomInstrumentPresenter.h
+  inc/MantidQtWidgets/InstrumentView/BaseCustomInstrumentView.h
   inc/MantidQtWidgets/InstrumentView/BinDialog.h
   inc/MantidQtWidgets/InstrumentView/CollapsiblePanel.h
   inc/MantidQtWidgets/InstrumentView/ColorMap.h
@@ -108,6 +121,9 @@ set(
   inc/MantidQtWidgets/InstrumentView/PanelsSurface.h
   inc/MantidQtWidgets/InstrumentView/PeakMarker2D.h
   inc/MantidQtWidgets/InstrumentView/PeakOverlay.h
+  inc/MantidQtWidgets/InstrumentView/PlotFitAnalysisPaneModel.h
+  inc/MantidQtWidgets/InstrumentView/PlotFitAnalysisPanePresenter.h
+  inc/MantidQtWidgets/InstrumentView/PlotFitAnalysisPaneView.h
   inc/MantidQtWidgets/InstrumentView/Projection3D.h
   inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h
   inc/MantidQtWidgets/InstrumentView/RectF.h
@@ -203,6 +219,7 @@ mtd_add_qt_library(TARGET_NAME MantidQtWidgetsInstrumentView
                      Qt5::OpenGL
                    MTD_QT_LINK_LIBS
                      MantidQtWidgetsCommon
+                     MantidQtWidgetsPlotting
                      MantidQtWidgetsMplCpp
                    INSTALL_DIR
                      ${WORKBENCH_LIB_DIR}
diff --git a/qt/scientific_interfaces/Direct/BaseInstrumentModel.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/BaseCustomInstrumentModel.h
similarity index 69%
rename from qt/scientific_interfaces/Direct/BaseInstrumentModel.h
rename to qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/BaseCustomInstrumentModel.h
index ddf6c6e0a26e2618bbce1c0384aaf947742a1f48..7669ac7266d7e406c2dc2592df89d6cf3d466138 100644
--- a/qt/scientific_interfaces/Direct/BaseInstrumentModel.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/BaseCustomInstrumentModel.h
@@ -4,19 +4,22 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#ifndef MANTIDQT_CUSTOMINTERFACES_BASEINSTRUMENTMODEL_H_
-#define MANTIDQT_CUSTOMINTERFACES_BASEINSTRUMENTMODEL_H_
+#ifndef MANTIDQT_INSTRUMENTVIEW_BASECUSTOMINSTRUMENTMODEL_H_
+#define MANTIDQT_INSTRUMENTVIEW_BASECUSTOMINSTRUMENTMODEL_H_
+
+#include "DllOption.h"
+
 #include <map>
 #include <string>
 
 namespace MantidQt {
-namespace CustomInterfaces {
+namespace MantidWidgets {
 
-class BaseInstrumentModel {
+class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW BaseCustomInstrumentModel {
 
 public:
-  BaseInstrumentModel();
-  ~BaseInstrumentModel(){};
+  BaseCustomInstrumentModel();
+  ~BaseCustomInstrumentModel(){};
   virtual void loadEmptyInstrument();
   virtual std::pair<int, std::string> loadData(const std::string &name);
   void setCurrentRun(int &run) { m_currentRun = run; };
@@ -35,7 +38,7 @@ protected:
   std::string m_wsName;
 };
 
-} // namespace CustomInterfaces
+} // namespace MantidWidgets
 } // namespace MantidQt
 
-#endif /* MANTIDQT_CUSTOMINTERFACES_BASEINSTRUMENTMODEL_H_ */
+#endif /* MANTIDQT_INSTRUMENTVIEW_BASEINSTRUMENTMODEL_H_ */
diff --git a/qt/scientific_interfaces/Direct/BaseInstrumentPresenter.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/BaseCustomInstrumentPresenter.h
similarity index 60%
rename from qt/scientific_interfaces/Direct/BaseInstrumentPresenter.h
rename to qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/BaseCustomInstrumentPresenter.h
index b27ff33805cefb1181fcb707de9e64f78b796588..daad1941f388f94a7d55b634cd1ad24f277520b9 100644
--- a/qt/scientific_interfaces/Direct/BaseInstrumentPresenter.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/BaseCustomInstrumentPresenter.h
@@ -4,30 +4,27 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#ifndef MANTIDQT_CUSTOMINTERFACES_BASEINSTRUMENTPRESENTER_H_
-#define MANTIDQT_CUSTOMINTERFACES_BASEINSTRUMENTPRESENTER_H_
-
-#include "BaseInstrumentModel.h"
-#include "BaseInstrumentView.h"
-#include "PlotFitAnalysisPaneView.h"
-
-#include "ALFView_view.h"
-#include "DllConfig.h"
+#ifndef MANTIDQT_INSTRUMENTVIEW_BASECUSTOMINSTRUMENTPRESENTER_H_
+#define MANTIDQT_INSTRUMENTVIEW_BASECUSTOMINSTRUMENTPRESENTER_H_
+#include "DllOption.h"
 #include "MantidQtWidgets/Common/ObserverPattern.h"
-#include "MantidQtWidgets/Common/UserSubWindow.h"
+#include "MantidQtWidgets/InstrumentView/BaseCustomInstrumentModel.h"
+#include "MantidQtWidgets/InstrumentView/BaseCustomInstrumentView.h"
 
 #include <string>
 
 namespace MantidQt {
-namespace CustomInterfaces {
+namespace MantidWidgets {
 
-class BaseInstrumentPresenter : public QObject {
+class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW BaseCustomInstrumentPresenter
+    : public QObject {
   Q_OBJECT
 
 public:
-  BaseInstrumentPresenter(BaseInstrumentView *view, BaseInstrumentModel *model,
-                          QWidget *analysisView);
-  ~BaseInstrumentPresenter() { delete m_loadRunObserver; };
+  BaseCustomInstrumentPresenter(BaseCustomInstrumentView *view,
+                                BaseCustomInstrumentModel *model,
+                                QWidget *analysisView);
+  ~BaseCustomInstrumentPresenter() { delete m_loadRunObserver; };
 
   typedef std::pair<
       std::string,
@@ -53,14 +50,14 @@ private:
   virtual void setUpInstrumentAnalysisSplitter();
   std::pair<instrumentSetUp, instrumentObserverOptions> setupInstrument();
 
-  BaseInstrumentView *m_view;
-  BaseInstrumentModel *m_model;
+  BaseCustomInstrumentView *m_view;
+  BaseCustomInstrumentModel *m_model;
   int m_currentRun;
   std::string m_currentFile;
   VoidObserver *m_loadRunObserver;
   QWidget *m_analysisPaneView;
 };
-} // namespace CustomInterfaces
+} // namespace MantidWidgets
 } // namespace MantidQt
 
-#endif /* MANTIDQT_CUSTOMINTERFACES_BASEINSTRUMENTPRESENTER_H_ */
+#endif /* MANTIDQT_INSTRUMENTVIEW_BaseCustomInstrumentPresenter_H_ */
diff --git a/qt/scientific_interfaces/Direct/BaseInstrumentView.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/BaseCustomInstrumentView.h
similarity index 76%
rename from qt/scientific_interfaces/Direct/BaseInstrumentView.h
rename to qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/BaseCustomInstrumentView.h
index 6789c6522ac6914537a394e89d7b5b7bdcf1f164..b1ad37f0995c23c9261bd386b2c7ea82f8c3f301 100644
--- a/qt/scientific_interfaces/Direct/BaseInstrumentView.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/BaseCustomInstrumentView.h
@@ -4,15 +4,13 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#ifndef MANTIDQT_CUSTOMINTERFACES_BASEINSTRUMENTVIEW_H_
-#define MANTIDQT_CUSTOMINTERFACES_BASEINSTRUMENTVIEW_H_
+#ifndef MANTIDQT_INSTRUMENTVIEW_BASECUSTOMINSTRUMENTVIEW_H_
+#define MANTIDQT_INSTRUMENTVIEW_BASECUSTOMINSTRUMENTVIEW_H_
 
-#include "DllConfig.h"
-#include "MantidQtWidgets/Common/FunctionBrowser.h"
+#include "DllOption.h"
 #include "MantidQtWidgets/Common/MWRunFiles.h"
 #include "MantidQtWidgets/Common/ObserverPattern.h"
 #include "MantidQtWidgets/InstrumentView/InstrumentWidget.h"
-#include "MantidQtWidgets/Plotting/PreviewPlot.h"
 
 #include <QObject>
 #include <QPushButton>
@@ -21,14 +19,15 @@
 #include <string>
 
 namespace MantidQt {
-namespace CustomInterfaces {
+namespace MantidWidgets {
 
-class BaseInstrumentView : public QSplitter {
+class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW BaseCustomInstrumentView
+    : public QSplitter {
   Q_OBJECT
 
 public:
-  explicit BaseInstrumentView(const std::string &instrument,
-                              QWidget *parent = nullptr);
+  explicit BaseCustomInstrumentView(const std::string &instrument,
+                                    QWidget *parent = nullptr);
   std::string getFile();
   void setRunQuietly(const std::string &runNumber);
   void observeLoadRun(Observer *listener) {
@@ -66,7 +65,7 @@ private:
   MantidWidgets::InstrumentWidget *m_instrumentWidget;
   QPushButton *m_help;
 };
-} // namespace CustomInterfaces
+} // namespace MantidWidgets
 } // namespace MantidQt
 
-#endif /* MANTIDQT_CUSTOMINTERFACES_BASEINSTRUMENTVIEW_H_ */
+#endif /* MANTIDQT_INSTRUMENTVIEW_BASECUSTOMINSTRUMENTVIEW_H_ */
diff --git a/qt/scientific_interfaces/Direct/PlotFitAnalysisPaneModel.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PlotFitAnalysisPaneModel.h
similarity index 71%
rename from qt/scientific_interfaces/Direct/PlotFitAnalysisPaneModel.h
rename to qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PlotFitAnalysisPaneModel.h
index a3befb87039632a2e5d4c9db4aac5f5f2832800d..83f3a03a0f3085a8ee1e6aad7c3fb6f41c50860d 100644
--- a/qt/scientific_interfaces/Direct/PlotFitAnalysisPaneModel.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PlotFitAnalysisPaneModel.h
@@ -4,8 +4,8 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#ifndef MANTIDQT_CUSTOMINTERFACES_PLOTFITANALYSISPANEMODEL_H_
-#define MANTIDQT_CUSTOMINTERFACES_PLOTFITANALYSISPANEMODEL_H_
+#ifndef MANTIDQT_INSTRUMENTVIEW_PLOTFITANALYSISPANEMODEL_H_
+#define MANTIDQT_INSTRUMENTVIEW_PLOTFITANALYSISPANEMODEL_H_
 
 #include "MantidAPI/IFunction.h"
 
@@ -13,7 +13,7 @@
 #include <string>
 using namespace Mantid::API;
 namespace MantidQt {
-namespace CustomInterfaces {
+namespace MantidWidgets {
 
 class PlotFitAnalysisPaneModel {
 
@@ -23,7 +23,7 @@ public:
                        const IFunction_sptr func);
 };
 
-} // namespace CustomInterfaces
+} // namespace MantidWidgets
 } // namespace MantidQt
 
-#endif /* MANTIDQT_CUSTOMINTERFACES_PLOTFITANALYSISPANEMODEL_H_ */
+#endif /* MANTIDQT_INSTRUMENTVIEW_PLOTFITANALYSISPANEMODEL_H_ */
diff --git a/qt/scientific_interfaces/Direct/PlotFitAnalysisPanePresenter.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PlotFitAnalysisPanePresenter.h
similarity index 67%
rename from qt/scientific_interfaces/Direct/PlotFitAnalysisPanePresenter.h
rename to qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PlotFitAnalysisPanePresenter.h
index d50a899f33cdf1c91831472ed656cb475ce43f93..58c0d1ae86922f24941db81e6a09b19bcf21e718 100644
--- a/qt/scientific_interfaces/Direct/PlotFitAnalysisPanePresenter.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PlotFitAnalysisPanePresenter.h
@@ -4,19 +4,20 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#ifndef MANTIDQT_CUSTOMINTERFACES_PLOTFITANALYSISPANEPRESENTER_H_
-#define MANTIDQT_CUSTOMINTERFACES_PLOTFITANALYSISPANEPRESENTER_H_
-
-#include "PlotFitAnalysisPaneModel.h"
-#include "PlotFitAnalysisPaneView.h"
+#ifndef MANTIDQT_INSTRUMENTVIEW_PLOTFITANALYSISPANEPRESENTER_H_
+#define MANTIDQT_INSTRUMENTVIEW_PLOTFITANALYSISPANEPRESENTER_H_
 
+#include "DllOption.h"
 #include "MantidQtWidgets/Common/ObserverPattern.h"
+#include "MantidQtWidgets/InstrumentView/PlotFitAnalysisPaneModel.h"
+#include "MantidQtWidgets/InstrumentView/PlotFitAnalysisPaneView.h"
 #include <string>
 
 namespace MantidQt {
-namespace CustomInterfaces {
+namespace MantidWidgets {
 
-class PlotFitAnalysisPanePresenter : public QObject {
+class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW PlotFitAnalysisPanePresenter
+    : public QObject {
   Q_OBJECT
 
 public:
@@ -39,7 +40,7 @@ private:
   PlotFitAnalysisPaneModel *m_model;
   std::string m_currentName;
 };
-} // namespace CustomInterfaces
+} // namespace MantidWidgets
 } // namespace MantidQt
 
-#endif /* MANTIDQT_CUSTOMINTERFACES_PLOTFITANALYSISPANEPRESENTER_H_ */
+#endif /* MANTIDQT_INSTRUMENTVIEW_PLOTFITANALYSISPANEPRESENTER_H_ */
diff --git a/qt/scientific_interfaces/Direct/PlotFitAnalysisPaneView.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PlotFitAnalysisPaneView.h
similarity index 83%
rename from qt/scientific_interfaces/Direct/PlotFitAnalysisPaneView.h
rename to qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PlotFitAnalysisPaneView.h
index 8962be77d65df0458f2deb648fa5b6ec0104dd1e..24242f33af38302f4b2517e664a4bf04fce60a3a 100644
--- a/qt/scientific_interfaces/Direct/PlotFitAnalysisPaneView.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PlotFitAnalysisPaneView.h
@@ -4,10 +4,10 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#ifndef MANTIDQT_CUSTOMINTERFACES_PLOTFITPANEVIEW_H_
-#define MANTIDQT_CUSTOMINTERFACES_PLOTFITPANEVIEW_H_
+#ifndef MANTIDQT_INSTRUMENTVIEW_PLOTFITPANEVIEW_H_
+#define MANTIDQT_INSTRUMENTVIEW_PLOTFITPANEVIEW_H_
 
-#include "DllConfig.h"
+#include "DllOption.h"
 #include "MantidQtWidgets/Common/FunctionBrowser.h"
 #include "MantidQtWidgets/Common/ObserverPattern.h"
 #include "MantidQtWidgets/Plotting/PreviewPlot.h"
@@ -21,9 +21,10 @@
 #include <string>
 
 namespace MantidQt {
-namespace CustomInterfaces {
+namespace MantidWidgets {
 
-class PlotFitAnalysisPaneView : public QWidget {
+class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW PlotFitAnalysisPaneView
+    : public QWidget {
   Q_OBJECT
 
 public:
@@ -55,7 +56,7 @@ private:
   QPushButton *m_fitButton;
   Observable *m_fitObservable;
 };
-} // namespace CustomInterfaces
+} // namespace MantidWidgets
 } // namespace MantidQt
 
-#endif /* MANTIDQT_CUSTOMINTERFACES_PLOTFITPANEVIEW_H_ */
+#endif /* MANTIDQT_INSTRUMENTVIEW_PLOTFITPANEVIEW_H_ */
diff --git a/qt/scientific_interfaces/Direct/BaseInstrumentModel.cpp b/qt/widgets/instrumentview/src/BaseCustomInstrumentModel.cpp
similarity index 77%
rename from qt/scientific_interfaces/Direct/BaseInstrumentModel.cpp
rename to qt/widgets/instrumentview/src/BaseCustomInstrumentModel.cpp
index 8e3231f9c0fde7ab75fe704ec3d527144f1b127c..9af2790a27671cbc2c6d88fc481a2df31bc5f6ab 100644
--- a/qt/scientific_interfaces/Direct/BaseInstrumentModel.cpp
+++ b/qt/widgets/instrumentview/src/BaseCustomInstrumentModel.cpp
@@ -5,7 +5,7 @@
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
 
-#include "BaseInstrumentModel.h"
+#include "MantidQtWidgets/InstrumentView/BaseCustomInstrumentModel.h"
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/AnalysisDataService.h"
@@ -22,13 +22,13 @@ const int ERRORCODE = -999;
 
 using namespace Mantid::API;
 namespace MantidQt {
-namespace CustomInterfaces {
+namespace MantidWidgets {
 
-BaseInstrumentModel::BaseInstrumentModel()
+BaseCustomInstrumentModel::BaseCustomInstrumentModel()
     : m_currentRun(0), m_tmpName("tmp"), m_instrumentName("MUSR"),
       m_wsName("testData") {}
 
-void BaseInstrumentModel::loadEmptyInstrument() {
+void BaseCustomInstrumentModel::loadEmptyInstrument() {
   auto alg =
       Mantid::API::AlgorithmManager::Instance().create("LoadEmptyInstrument");
   alg->initialize();
@@ -43,7 +43,7 @@ void BaseInstrumentModel::loadEmptyInstrument() {
  * @return std::pair<int,std::string>:: the run number and status
  */
 std::pair<int, std::string>
-BaseInstrumentModel::loadData(const std::string &name) {
+BaseCustomInstrumentModel::loadData(const std::string &name) {
   auto alg = AlgorithmManager::Instance().create("Load");
   alg->initialize();
   alg->setProperty("Filename", name);
@@ -58,16 +58,16 @@ BaseInstrumentModel::loadData(const std::string &name) {
   return std::make_pair(runNumber, message);
 }
 
-void BaseInstrumentModel::rename() {
+void BaseCustomInstrumentModel::rename() {
   AnalysisDataService::Instance().rename(m_tmpName, m_wsName);
 }
-void BaseInstrumentModel::remove() {
+void BaseCustomInstrumentModel::remove() {
   AnalysisDataService::Instance().remove(m_tmpName);
 }
 
-std::string BaseInstrumentModel::dataFileName() { return m_wsName; }
+std::string BaseCustomInstrumentModel::dataFileName() { return m_wsName; }
 
-int BaseInstrumentModel::currentRun() {
+int BaseCustomInstrumentModel::currentRun() {
   try {
 
     auto ws =
@@ -78,9 +78,9 @@ int BaseInstrumentModel::currentRun() {
   }
 }
 
-bool BaseInstrumentModel::isErrorCode(const int run) {
+bool BaseCustomInstrumentModel::isErrorCode(const int run) {
   return (run == ERRORCODE);
 }
 
-} // namespace CustomInterfaces
+} // namespace MantidWidgets
 } // namespace MantidQt
diff --git a/qt/scientific_interfaces/Direct/BaseInstrumentPresenter.cpp b/qt/widgets/instrumentview/src/BaseCustomInstrumentPresenter.cpp
similarity index 75%
rename from qt/scientific_interfaces/Direct/BaseInstrumentPresenter.cpp
rename to qt/widgets/instrumentview/src/BaseCustomInstrumentPresenter.cpp
index b964d8b71d7184efcbaf035f323b2c011b736b07..6d667702346bf2e96bb535da32418a1ca360fa08 100644
--- a/qt/scientific_interfaces/Direct/BaseInstrumentPresenter.cpp
+++ b/qt/widgets/instrumentview/src/BaseCustomInstrumentPresenter.cpp
@@ -4,47 +4,49 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#include "BaseInstrumentPresenter.h"
-#include "BaseInstrumentView.h"
+#include "MantidQtWidgets/InstrumentView/BaseCustomInstrumentPresenter.h"
 #include "MantidAPI/FileFinder.h"
+#include "MantidQtWidgets/InstrumentView/BaseCustomInstrumentModel.h"
+#include "MantidQtWidgets/InstrumentView/BaseCustomInstrumentView.h"
 
 #include <functional>
 #include <tuple>
 
 namespace MantidQt {
-namespace CustomInterfaces {
+namespace MantidWidgets {
 
-BaseInstrumentPresenter::BaseInstrumentPresenter(BaseInstrumentView *view,
-                                                 BaseInstrumentModel *model,
-                                                 QWidget *analysisPaneView)
+BaseCustomInstrumentPresenter::BaseCustomInstrumentPresenter(
+    BaseCustomInstrumentView *view, BaseCustomInstrumentModel *model,
+    QWidget *analysisPaneView)
     : m_view(view), m_model(model), m_currentRun(0), m_currentFile(""),
       m_loadRunObserver(nullptr), m_analysisPaneView(analysisPaneView) {
   m_loadRunObserver = new VoidObserver();
   m_model->loadEmptyInstrument();
 }
 
-void BaseInstrumentPresenter::addInstrument() {
+void BaseCustomInstrumentPresenter::addInstrument() {
   auto setUp = setupInstrument();
   initLayout(&setUp);
 }
 
-void BaseInstrumentPresenter::initLayout(
+void BaseCustomInstrumentPresenter::initLayout(
     std::pair<instrumentSetUp, instrumentObserverOptions> *setUp) {
   // connect to new run
   m_view->observeLoadRun(m_loadRunObserver);
   std::function<void()> loadBinder =
-      std::bind(&BaseInstrumentPresenter::loadRunNumber, this);
+      std::bind(&BaseCustomInstrumentPresenter::loadRunNumber, this);
   m_loadRunObserver->setSlot(loadBinder);
   initInstrument(setUp);
   setUpInstrumentAnalysisSplitter();
   m_view->setupHelp();
 }
 
-void BaseInstrumentPresenter::setUpInstrumentAnalysisSplitter() {
+void BaseCustomInstrumentPresenter::setUpInstrumentAnalysisSplitter() {
   m_view->setupInstrumentAnalysisSplitters(m_analysisPaneView);
 }
 
-void BaseInstrumentPresenter::loadAndAnalysis(const std::string &pathToRun) {
+void BaseCustomInstrumentPresenter::loadAndAnalysis(
+    const std::string &pathToRun) {
   try {
     auto loadedResult = m_model->loadData(pathToRun);
 
@@ -65,7 +67,7 @@ void BaseInstrumentPresenter::loadAndAnalysis(const std::string &pathToRun) {
   }
 }
 
-void BaseInstrumentPresenter::loadRunNumber() {
+void BaseCustomInstrumentPresenter::loadRunNumber() {
   auto pathToRun = m_view->getFile();
   if (pathToRun == "" || m_currentFile == pathToRun) {
     return;
@@ -73,9 +75,7 @@ void BaseInstrumentPresenter::loadRunNumber() {
   loadAndAnalysis(pathToRun);
 }
 
-// All of the below are specific to ALF
-
-void BaseInstrumentPresenter::initInstrument(
+void BaseCustomInstrumentPresenter::initInstrument(
     std::pair<instrumentSetUp, instrumentObserverOptions> *setUp) {
   if (!setUp) {
     return;
@@ -98,7 +98,7 @@ typedef std::vector<std::tuple<std::string, Observer *>>
     instrumentObserverOptions;
 std::pair<instrumentSetUp, instrumentObserverOptions>
 
-BaseInstrumentPresenter::setupInstrument() {
+BaseCustomInstrumentPresenter::setupInstrument() {
   instrumentSetUp setUpContextConditions;
 
   // set up the slots for the custom context menu
@@ -110,5 +110,5 @@ BaseInstrumentPresenter::setupInstrument() {
   return std::make_pair(setUpContextConditions, customInstrumentOptions);
 }
 
-} // namespace CustomInterfaces
+} // namespace MantidWidgets
 } // namespace MantidQt
diff --git a/qt/scientific_interfaces/Direct/BaseInstrumentView.cpp b/qt/widgets/instrumentview/src/BaseCustomInstrumentView.cpp
similarity index 76%
rename from qt/scientific_interfaces/Direct/BaseInstrumentView.cpp
rename to qt/widgets/instrumentview/src/BaseCustomInstrumentView.cpp
index 9f33fb676b92096fa59f855d5b3a36450cfef7ab..b6026356daa4e8e5b81a3b5c7fd8893b1fdc9ce1 100644
--- a/qt/scientific_interfaces/Direct/BaseInstrumentView.cpp
+++ b/qt/widgets/instrumentview/src/BaseCustomInstrumentView.cpp
@@ -4,10 +4,10 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#include "BaseInstrumentView.h"
+#include "MantidQtWidgets/InstrumentView/BaseCustomInstrumentView.h"
 #include "MantidQtWidgets/Common/HelpWindow.h"
 #include "MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h"
-
+// change to BaseCustomInstrumentView etc.
 #include <QMessageBox>
 #include <QSizePolicy>
 #include <QSpacerItem>
@@ -15,10 +15,10 @@
 #include <QVBoxLayout>
 
 namespace MantidQt {
-namespace CustomInterfaces {
+namespace MantidWidgets {
 
-BaseInstrumentView::BaseInstrumentView(const std::string &instrument,
-                                       QWidget *parent)
+BaseCustomInstrumentView::BaseCustomInstrumentView(
+    const std::string &instrument, QWidget *parent)
     : QSplitter(Qt::Vertical, parent), m_helpPage(""),
       m_loadRunObservable(nullptr), m_files(nullptr),
       m_instrument(QString::fromStdString(instrument)),
@@ -27,18 +27,18 @@ BaseInstrumentView::BaseInstrumentView(const std::string &instrument,
   this->addWidget(loadWidget);
 }
 
-void MantidQt::CustomInterfaces::BaseInstrumentView::setUpInstrument(
+void BaseCustomInstrumentView::setUpInstrument(
     const std::string &fileName,
     std::vector<std::function<bool(std::map<std::string, bool>)>> &instrument) {
 
   (void)instrument;
   auto instrumentWidget =
-      new MantidWidgets::InstrumentWidget(QString::fromStdString(fileName));
+      new InstrumentWidget(QString::fromStdString(fileName));
   instrumentWidget->hideHelp();
   setInstrumentWidget(instrumentWidget);
 }
 
-QWidget *BaseInstrumentView::generateLoadWidget() {
+QWidget *BaseCustomInstrumentView::generateLoadWidget() {
   m_loadRunObservable = new Observable();
 
   m_files = new API::MWRunFiles(this);
@@ -60,7 +60,7 @@ QWidget *BaseInstrumentView::generateLoadWidget() {
   return loadWidget;
 }
 
-void BaseInstrumentView::setupInstrumentAnalysisSplitters(
+void BaseCustomInstrumentView::setupInstrumentAnalysisSplitters(
     QWidget *analysisPane) {
   QSplitter *split = new QSplitter(Qt::Horizontal);
   split->addWidget(m_instrumentWidget);
@@ -68,7 +68,7 @@ void BaseInstrumentView::setupInstrumentAnalysisSplitters(
   this->addWidget(split);
 }
 
-void BaseInstrumentView::setupHelp() {
+void BaseCustomInstrumentView::setupHelp() {
   QWidget *helpWidget = new QWidget();
   m_help = new QPushButton("?");
   m_help->setMaximumWidth(25);
@@ -81,7 +81,7 @@ void BaseInstrumentView::setupHelp() {
   connect(m_help, SIGNAL(clicked()), this, SLOT(openHelp()));
 }
 
-void BaseInstrumentView::openHelp() {
+void BaseCustomInstrumentView::openHelp() {
   if (m_helpPage == "") {
     return;
   }
@@ -89,18 +89,18 @@ void BaseInstrumentView::openHelp() {
       nullptr, QString::fromStdString(m_helpPage));
 }
 
-std::string BaseInstrumentView::getFile() {
+std::string BaseCustomInstrumentView::getFile() {
   auto name = m_files->getFilenames();
   if (name.size() > 0)
     return name[0].toStdString();
   return "";
 }
 
-void BaseInstrumentView::setRunQuietly(const std::string &runNumber) {
+void BaseCustomInstrumentView::setRunQuietly(const std::string &runNumber) {
   m_files->setText(QString::fromStdString(runNumber));
 }
 
-void BaseInstrumentView::fileLoaded() {
+void BaseCustomInstrumentView::fileLoaded() {
   if (m_files->getText().isEmpty())
     return;
 
@@ -111,13 +111,13 @@ void BaseInstrumentView::fileLoaded() {
   m_loadRunObservable->notify();
 }
 
-void BaseInstrumentView::warningBox(const std::string &message) {
+void BaseCustomInstrumentView::warningBox(const std::string &message) {
   warningBox(QString::fromStdString(message));
 }
 
-void BaseInstrumentView::warningBox(const QString &message) {
+void BaseCustomInstrumentView::warningBox(const QString &message) {
   QMessageBox::warning(this, m_instrument + " view", message);
 }
 
-} // namespace CustomInterfaces
+} // namespace MantidWidgets
 } // namespace MantidQt
diff --git a/qt/scientific_interfaces/Direct/PlotFitAnalysisPaneModel.cpp b/qt/widgets/instrumentview/src/PlotFitAnalysisPaneModel.cpp
similarity index 88%
rename from qt/scientific_interfaces/Direct/PlotFitAnalysisPaneModel.cpp
rename to qt/widgets/instrumentview/src/PlotFitAnalysisPaneModel.cpp
index c52382b1368cab5e65965ef4be1b8c89a509e460..feb3e076176299796fbe7f41c05e92c8fe8281e4 100644
--- a/qt/scientific_interfaces/Direct/PlotFitAnalysisPaneModel.cpp
+++ b/qt/widgets/instrumentview/src/PlotFitAnalysisPaneModel.cpp
@@ -5,13 +5,13 @@
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
 
-#include "PlotFitAnalysisPaneModel.h"
+#include "MantidQtWidgets/InstrumentView/PlotFitAnalysisPaneModel.h"
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/AlgorithmManager.h"
 
 using namespace Mantid::API;
 namespace MantidQt {
-namespace CustomInterfaces {
+namespace MantidWidgets {
 
 IFunction_sptr
 PlotFitAnalysisPaneModel::doFit(const std::string &wsName,
@@ -29,5 +29,5 @@ PlotFitAnalysisPaneModel::doFit(const std::string &wsName,
   return alg->getProperty("Function");
 }
 
-} // namespace CustomInterfaces
+} // namespace MantidWidgets
 } // namespace MantidQt
diff --git a/qt/scientific_interfaces/Direct/PlotFitAnalysisPanePresenter.cpp b/qt/widgets/instrumentview/src/PlotFitAnalysisPanePresenter.cpp
similarity index 87%
rename from qt/scientific_interfaces/Direct/PlotFitAnalysisPanePresenter.cpp
rename to qt/widgets/instrumentview/src/PlotFitAnalysisPanePresenter.cpp
index f2a32c1a17cd83c7ab7afcc28a030f6d7e4f4918..a14df8b827d236eb6ad5a6b4f52ee6219b4f0b00 100644
--- a/qt/scientific_interfaces/Direct/PlotFitAnalysisPanePresenter.cpp
+++ b/qt/widgets/instrumentview/src/PlotFitAnalysisPanePresenter.cpp
@@ -4,18 +4,14 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#include "PlotFitAnalysisPanePresenter.h"
-
-#include "MantidAPI/CompositeFunction.h"
-#include "MantidAPI/FileFinder.h"
-#include "MantidAPI/FunctionFactory.h"
+#include "MantidQtWidgets/InstrumentView/PlotFitAnalysisPanePresenter.h"
 
 #include <exception>
 #include <functional>
 #include <tuple>
 
 namespace MantidQt {
-namespace CustomInterfaces {
+namespace MantidWidgets {
 
 PlotFitAnalysisPanePresenter::PlotFitAnalysisPanePresenter(
     PlotFitAnalysisPaneView *view, PlotFitAnalysisPaneModel *model)
@@ -54,5 +50,5 @@ void PlotFitAnalysisPanePresenter::addSpectrum(const std::string &wsName) {
   m_view->addSpectrum(wsName);
 }
 
-} // namespace CustomInterfaces
+} // namespace MantidWidgets
 } // namespace MantidQt
diff --git a/qt/scientific_interfaces/Direct/PlotFitAnalysisPaneView.cpp b/qt/widgets/instrumentview/src/PlotFitAnalysisPaneView.cpp
similarity index 96%
rename from qt/scientific_interfaces/Direct/PlotFitAnalysisPaneView.cpp
rename to qt/widgets/instrumentview/src/PlotFitAnalysisPaneView.cpp
index 21ca27a7d4c6e4b5e351965811fb2f8d6b7a4b57..db0ff22fbf2599c56ab7d528a3f5af46650e14d5 100644
--- a/qt/scientific_interfaces/Direct/PlotFitAnalysisPaneView.cpp
+++ b/qt/widgets/instrumentview/src/PlotFitAnalysisPaneView.cpp
@@ -4,7 +4,7 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#include "PlotFitAnalysisPaneView.h"
+#include "MantidQtWidgets/InstrumentView/PlotFitAnalysisPaneView.h"
 #include "MantidAPI/CompositeFunction.h"
 #include "MantidAPI/FunctionFactory.h"
 
@@ -16,7 +16,7 @@
 #include <QSplitter>
 #include <QVBoxLayout>
 namespace MantidQt {
-namespace CustomInterfaces {
+namespace MantidWidgets {
 
 PlotFitAnalysisPaneView::PlotFitAnalysisPaneView(const double &start,
                                                  const double &end,
@@ -115,5 +115,5 @@ void PlotFitAnalysisPaneView::fitWarning(const std::string &message) {
   QMessageBox::warning(this, "Fit error", message.c_str());
 }
 
-} // namespace CustomInterfaces
+} // namespace MantidWidgets
 } // namespace MantidQt
diff --git a/qt/widgets/plotting/inc/MantidQtWidgets/Plotting/Qwt/SafeQwtPlot.h b/qt/widgets/plotting/inc/MantidQtWidgets/Plotting/Qwt/SafeQwtPlot.h
index dd481901f488d0fe2a0a759919b7048fcefa4197..d68c5e69b2106289f9119b6b2ac4c62490808e5c 100644
--- a/qt/widgets/plotting/inc/MantidQtWidgets/Plotting/Qwt/SafeQwtPlot.h
+++ b/qt/widgets/plotting/inc/MantidQtWidgets/Plotting/Qwt/SafeQwtPlot.h
@@ -13,7 +13,7 @@
 #include "qwt_text.h"
 MSVC_DIAG_OFF(4244)
 #include <QPainter>
-MSVC_DIAG_ON()
+MSVC_DIAG_ON(4244)
 #include <qwt_plot.h>
 
 namespace MantidQt {
diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/QPeaksTableModel.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/QPeaksTableModel.h
index cd2c41cde04f0f4b49fdc3a682a52f9173fcbff8..bf71b0cf542471c69840f6d0bc82894d3ac5603b 100644
--- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/QPeaksTableModel.h
+++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/QPeaksTableModel.h
@@ -5,7 +5,6 @@
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
 #include "DllOption.h"
-#include "boost/bind.hpp"
 #include "boost/function.hpp"
 #include "boost/tuple/tuple.hpp"
 #include <QAbstractTableModel>
diff --git a/scripts/Diffraction/isis_powder/polaris.py b/scripts/Diffraction/isis_powder/polaris.py
index f0985a4eb9ebc89fbe9bdc9fc5c54c1bbe78f374..f929a515afff17b168bdbd78ef9e7e0b3a5b2ea6 100644
--- a/scripts/Diffraction/isis_powder/polaris.py
+++ b/scripts/Diffraction/isis_powder/polaris.py
@@ -10,6 +10,7 @@ import os
 from isis_powder.routines import absorb_corrections, common, instrument_settings
 from isis_powder.abstract_inst import AbstractInst
 from isis_powder.polaris_routines import polaris_advanced_config, polaris_algs, polaris_param_mapping
+from mantid.kernel import logger
 
 
 class Polaris(AbstractInst):
@@ -53,6 +54,9 @@ class Polaris(AbstractInst):
             kwargs['q_lims'] = None
         if 'output_binning' not in kwargs:
             kwargs['output_binning'] = None
+        if 'pdf_type' not in kwargs or not kwargs['pdf_type'] in ['G(r)', 'g(r)', 'RDF(r)']:
+            kwargs['pdf_type'] = 'G(r)'
+            logger.warning('PDF type not specified or is invalid, defaulting to G(r)')
         self._inst_settings.update_attributes(kwargs=kwargs)
         # Generate pdf
         run_details = self._get_run_details(self._inst_settings.run_number)
@@ -64,7 +68,8 @@ class Polaris(AbstractInst):
                                                   q_lims=self._inst_settings.q_lims,
                                                   cal_file_name=cal_file_name,
                                                   sample_details=self._sample_details,
-                                                  output_binning=self._inst_settings.output_binning)
+                                                  output_binning=self._inst_settings.output_binning,
+                                                  pdf_type=self._inst_settings.pdf_type)
         return pdf_output
 
     def set_sample_details(self, **kwargs):
diff --git a/scripts/Diffraction/isis_powder/polaris_routines/polaris_algs.py b/scripts/Diffraction/isis_powder/polaris_routines/polaris_algs.py
index 9e022360a541a89b5a902f69628230afc484fb9a..ef0bb81c91786e3fea02aa704eb6f4d38acc0ee2 100644
--- a/scripts/Diffraction/isis_powder/polaris_routines/polaris_algs.py
+++ b/scripts/Diffraction/isis_powder/polaris_routines/polaris_algs.py
@@ -8,6 +8,7 @@ from __future__ import (absolute_import, division, print_function)
 import numpy as np
 
 import mantid.simpleapi as mantid
+from six import string_types
 
 from isis_powder.routines import absorb_corrections, common
 from isis_powder.routines.common_enums import WORKSPACE_UNITS
@@ -80,7 +81,7 @@ def save_unsplined_vanadium(vanadium_ws, output_path):
 
 
 def generate_ts_pdf(run_number, focus_file_path, merge_banks=False, q_lims=None, cal_file_name=None,
-                    sample_details=None, output_binning=None):
+                    sample_details=None, output_binning=None, pdf_type="G(r)"):
     focused_ws = _obtain_focused_run(run_number, focus_file_path)
     focused_ws = mantid.ConvertUnits(InputWorkspace=focused_ws, Target="MomentumTransfer", EMode='Elastic')
 
@@ -107,11 +108,11 @@ def generate_ts_pdf(run_number, focus_file_path, merge_banks=False, q_lims=None,
         q_min, q_max = _load_qlims(q_lims)
         merged_ws = mantid.MatchAndMergeWorkspaces(InputWorkspaces=focused_ws, XMin=q_min, XMax=q_max,
                                                    CalculateScale=False)
-        pdf_output = mantid.PDFFourierTransform(Inputworkspace=merged_ws, InputSofQType="S(Q)-1", PDFType="G(r)",
+        pdf_output = mantid.PDFFourierTransform(Inputworkspace=merged_ws, InputSofQType="S(Q)-1", PDFType=pdf_type,
                                                 Filter=True)
     else:
         pdf_output = mantid.PDFFourierTransform(Inputworkspace='focused_ws', InputSofQType="S(Q)-1",
-                                                PDFType="G(r)", Filter=True)
+                                                PDFType=pdf_type, Filter=True)
         pdf_output = mantid.RebinToWorkspace(WorkspaceToRebin=pdf_output, WorkspaceToMatch=pdf_output[4],
                                              PreserveEvents=True)
     common.remove_intermediate_workspace('self_scattering_correction')
@@ -150,7 +151,7 @@ def _obtain_focused_run(run_number, focus_file_path):
 
 
 def _load_qlims(q_lims):
-    if type(q_lims) == str or type(q_lims) == unicode:
+    if isinstance(q_lims, string_types):
         q_min = []
         q_max = []
         try:
@@ -162,13 +163,13 @@ def _load_qlims(q_lims):
                     q_max.append(float(value_list[3]))
             q_min = np.array(q_min)
             q_max = np.array(q_max)
-        except IOError:
-            raise RuntimeError("q_lims directory is not valid")
-    elif type(q_lims) == list or type(q_lims) == np.ndarray:
+        except IOError as exc:
+            raise RuntimeError("q_lims path is not valid: {}".format(exc))
+    elif isinstance(q_lims, (list, tuple)) or isinstance(q_lims, np.ndarray):
         q_min = q_lims[0, :]
         q_max = q_lims[1, :]
     else:
-        raise RuntimeError("q_lims type is not valid")
+        raise RuntimeError("q_lims type is not valid. Expected a string filename or an array.")
     return q_min, q_max
 
 
diff --git a/scripts/Diffraction/isis_powder/polaris_routines/polaris_param_mapping.py b/scripts/Diffraction/isis_powder/polaris_routines/polaris_param_mapping.py
index 5d5742027d6f70c26009c6c18669e9e0ad7c2ba9..5bb1eb51c5b2ded5bdeaca946c7b0e1bc4e73bb1 100644
--- a/scripts/Diffraction/isis_powder/polaris_routines/polaris_param_mapping.py
+++ b/scripts/Diffraction/isis_powder/polaris_routines/polaris_param_mapping.py
@@ -28,6 +28,7 @@ attr_mapping = [
     ParamMapEntry(ext_name="mode", int_name="mode", enum_class=POLARIS_CHOPPER_MODES,
                   optional=True),
     ParamMapEntry(ext_name="multiple_scattering", int_name="multiple_scattering", optional=True),
+    ParamMapEntry(ext_name="pdf_type", int_name="pdf_type"),
     ParamMapEntry(ext_name="q_lims", int_name="q_lims"),
     ParamMapEntry(ext_name="raw_data_cropping_values", int_name="raw_data_crop_values"),
     ParamMapEntry(ext_name="run_number", int_name="run_number"),
diff --git a/scripts/Diffraction/isis_powder/routines/yaml_parser.py b/scripts/Diffraction/isis_powder/routines/yaml_parser.py
index 0f840d2fd5021ac16ac451f6708bf94080e8509e..f8b54e492c5055c00fc6f5ca77b1950c9a4e0698 100644
--- a/scripts/Diffraction/isis_powder/routines/yaml_parser.py
+++ b/scripts/Diffraction/isis_powder/routines/yaml_parser.py
@@ -42,7 +42,7 @@ def open_yaml_file_as_dictionary(file_path):
 
     with open(file_path, 'r') as input_stream:
         try:
-            read_config = yaml.load(input_stream)
+            read_config = yaml.safe_load(input_stream)
         except yaml.YAMLError as exception:
             print(exception)
             raise RuntimeError("Failed to parse YAML file: " + str(file_path))
diff --git a/scripts/Engineering/gui/CMakeLists.txt b/scripts/Engineering/gui/CMakeLists.txt
index d04e7efbfa29a8b3f80cdfbeacbb2493fa9483a3..62c1f5271a99bb83e2417cbef8c7104fb40003d1 100644
--- a/scripts/Engineering/gui/CMakeLists.txt
+++ b/scripts/Engineering/gui/CMakeLists.txt
@@ -3,6 +3,10 @@
 set(TEST_PY_FILES
     # Common
     engineering_diffraction/tabs/common/test/test_vanadium_corrections.py
+    # Settings
+    engineering_diffraction/settings/test/test_settings_helper.py
+    engineering_diffraction/settings/test/test_settings_model.py
+    engineering_diffraction/settings/test/test_settings_presenter.py
     # Calibration
     engineering_diffraction/tabs/calibration/test/test_calib_model.py
     engineering_diffraction/tabs/calibration/test/test_calib_presenter.py
diff --git a/scripts/Engineering/gui/engineering_diffraction/engineering_diffraction.py b/scripts/Engineering/gui/engineering_diffraction/engineering_diffraction.py
index 3a8dbe99906095ffb77409dd2f222c700fb35310..ba311894e2f91ab1f50a548f22bfb5cef55588a0 100644
--- a/scripts/Engineering/gui/engineering_diffraction/engineering_diffraction.py
+++ b/scripts/Engineering/gui/engineering_diffraction/engineering_diffraction.py
@@ -14,6 +14,10 @@ from .tabs.calibration.presenter import CalibrationPresenter
 from .tabs.focus.model import FocusModel
 from .tabs.focus.view import FocusView
 from .tabs.focus.presenter import FocusPresenter
+from .settings.settings_model import SettingsModel
+from .settings.settings_view import SettingsView
+from .settings.settings_presenter import SettingsPresenter
+from mantidqt.icons import get_icon
 
 from mantidqt.interfacemanager import InterfaceManager
 from mantidqt.utils.qt import load_ui
@@ -35,15 +39,26 @@ class EngineeringDiffractionGui(QtWidgets.QMainWindow, Ui_main_window):
         self.setFocusPolicy(QtCore.Qt.StrongFocus)
         self.calibration_presenter = None
         self.focus_presenter = None
+        self.settings_presenter = None
         self.set_on_help_clicked(self.open_help_window)
 
-        # Setup Tabs
+        self.set_on_settings_clicked(self.open_settings)
+        self.btn_settings.setIcon(get_icon("mdi.settings", "black", 1.2))
+
+        # Setup Elements
+        self.setup_settings()
         self.setup_calibration()
         self.setup_focus()
 
         # Setup notifiers
         self.setup_calibration_notifier()
 
+    def setup_settings(self):
+        model = SettingsModel()
+        view = SettingsView(self)
+        self.settings_presenter = SettingsPresenter(model, view)
+        self.settings_presenter.load_settings_from_file_or_default()
+
     def setup_calibration(self):
         cal_model = CalibrationModel()
         cal_view = CalibrationView(parent=self.tabs)
@@ -67,6 +82,9 @@ class EngineeringDiffractionGui(QtWidgets.QMainWindow, Ui_main_window):
     def set_on_help_clicked(self, slot):
         self.pushButton_help.clicked.connect(slot)
 
+    def set_on_settings_clicked(self, slot):
+        self.btn_settings.clicked.connect(slot)
+
     def set_on_rb_num_changed(self, slot):
         self.lineEdit_RBNumber.textChanged.connect(slot)
 
@@ -76,5 +94,9 @@ class EngineeringDiffractionGui(QtWidgets.QMainWindow, Ui_main_window):
     def open_help_window(self):
         InterfaceManager().showCustomInterfaceHelp(self.doc)
 
+    def open_settings(self):
+        self.settings_presenter.load_existing_settings()
+        self.settings_presenter.show()
+
     def get_rb_no(self):
         return self.lineEdit_RBNumber.text()
diff --git a/scripts/Engineering/gui/engineering_diffraction/main_window.ui b/scripts/Engineering/gui/engineering_diffraction/main_window.ui
index 3f4cac479e962cf435b3197556a061699c45f4d1..6e3565348930ea8a3108e68cb8b0a7d7cafaaa86 100644
--- a/scripts/Engineering/gui/engineering_diffraction/main_window.ui
+++ b/scripts/Engineering/gui/engineering_diffraction/main_window.ui
@@ -91,6 +91,13 @@
         </property>
        </widget>
       </item>
+      <item>
+       <widget class="QToolButton" name="btn_settings">
+        <property name="text">
+         <string/>
+        </property>
+       </widget>
+      </item>
       <item>
        <widget class="QStatusBar" name="statusbar">
         <property name="sizeGripEnabled">
diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/__init__.py b/scripts/Engineering/gui/engineering_diffraction/settings/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/settings_helper.py b/scripts/Engineering/gui/engineering_diffraction/settings/settings_helper.py
new file mode 100644
index 0000000000000000000000000000000000000000..020ad2f3032f2d82b3f6a86b7c7bea913d9ca0b4
--- /dev/null
+++ b/scripts/Engineering/gui/engineering_diffraction/settings/settings_helper.py
@@ -0,0 +1,57 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+
+from __future__ import (absolute_import, division, print_function)
+
+from qtpy.QtCore import QSettings
+
+
+def set_setting(group, prefix, setting_name, value):
+    """
+    Change or add a setting in the mantid .ini file.
+    :param group: Settings group to pull from.
+    :param prefix: Acts like a subgroup.
+    :param setting_name: The key to the setting.
+    :param value: The value of the setting.
+    """
+    settings = QSettings()
+    settings.beginGroup(group)
+    settings.setValue(prefix + setting_name, value)
+    settings.endGroup()
+
+
+def get_setting(group, prefix, setting_name, return_type=str):
+    """
+    Get a setting from the .ini file of mantid settings.
+
+    NOTE: If you specify an int, but the setting contains a bool, you will get 0 for False
+    and 1 for True, without a warning. Specifying bool will raise a TypeError if anything
+    other than a bool or empty string is found in the settings. Not specifying a type will
+    return a string. If nothing is found then an empty string is returned.
+
+    :param group: Settings group to pull from.
+    :param prefix: The prefix of the setting, acts like a subgroup.
+    :param setting_name: Name of the setting.
+    :param return_type: The type of the setting to get.
+    :return: The chosen setting.
+    """
+    settings = QSettings()
+    settings.beginGroup(group)
+    if return_type is bool:
+        setting = settings.value(prefix + setting_name, type=str)
+        if setting == "":
+            pass
+        elif setting == "true":
+            setting = True
+        elif setting == "false":
+            setting = False
+        else:
+            raise TypeError("Unable to convert string into valid bool")
+    else:
+        setting = settings.value(prefix + setting_name, type=return_type)
+    settings.endGroup()
+    return setting
diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/settings_model.py b/scripts/Engineering/gui/engineering_diffraction/settings/settings_model.py
new file mode 100644
index 0000000000000000000000000000000000000000..32edb1a5e53230e984cd6a1d543b36bad393a5e7
--- /dev/null
+++ b/scripts/Engineering/gui/engineering_diffraction/settings/settings_model.py
@@ -0,0 +1,32 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+
+from __future__ import (absolute_import, division, print_function)
+
+from Engineering.gui.engineering_diffraction.settings.settings_helper import get_setting, set_setting
+from Engineering.gui.engineering_diffraction.tabs.common import path_handling
+
+
+class SettingsModel(object):
+    def get_settings_dict(self, names_and_types):
+        settings = {}
+        for setting_name in names_and_types.keys():
+            settings[setting_name] = self.get_setting(setting_name, return_type=names_and_types[setting_name])
+        return settings
+
+    def set_settings_dict(self, settings):
+        for key in settings:
+            self.set_setting(key, settings[key])
+
+    @staticmethod
+    def get_setting(name, return_type=str):
+        return get_setting(path_handling.INTERFACES_SETTINGS_GROUP, path_handling.ENGINEERING_PREFIX, name,
+                           return_type=return_type)
+
+    @staticmethod
+    def set_setting(name, value):
+        set_setting(path_handling.INTERFACES_SETTINGS_GROUP, path_handling.ENGINEERING_PREFIX, name, value)
diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/settings_presenter.py b/scripts/Engineering/gui/engineering_diffraction/settings/settings_presenter.py
new file mode 100644
index 0000000000000000000000000000000000000000..3767e462ccf1f7b08ce43edff8f75c96f2a18936
--- /dev/null
+++ b/scripts/Engineering/gui/engineering_diffraction/settings/settings_presenter.py
@@ -0,0 +1,80 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+# pylint: disable=invalid-name
+from __future__ import (absolute_import, division, print_function)
+
+from os import path
+
+SETTINGS_DICT = {"save_location": str, "full_calibration": str, "recalc_vanadium": bool}
+
+DEFAULT_SETTINGS = {
+    "full_calibration": "",
+    "save_location": path.join(path.expanduser("~"), "Engineering_Mantid"),
+    "recalc_vanadium": False
+}
+
+
+class SettingsPresenter(object):
+    def __init__(self, model, view):
+        self.model = model
+        self.view = view
+        self.settings = {}
+
+        # Connect view signals
+        self.view.set_on_apply_clicked(self.save_new_settings)
+        self.view.set_on_ok_clicked(self.save_and_close_dialog)
+        self.view.set_on_cancel_clicked(self.close_dialog)
+
+    def show(self):
+        self.view.show()
+
+    def load_existing_settings(self):
+        self.load_settings_from_file_or_default()
+        self._show_settings_in_view()
+
+    def close_dialog(self):
+        self.view.close()
+
+    def save_and_close_dialog(self):
+        self.save_new_settings()
+        self.close_dialog()
+
+    def save_new_settings(self):
+        self._collect_new_settings_from_view()
+        self._save_settings_to_file()
+
+    def _collect_new_settings_from_view(self):
+        self.settings["save_location"] = self.view.get_save_location()
+        self.settings["full_calibration"] = self.view.get_full_calibration()
+        self.settings["recalc_vanadium"] = self.view.get_van_recalc()
+
+    def _show_settings_in_view(self):
+        if self._validate_settings(self.settings):
+            self.view.set_save_location(self.settings["save_location"])
+            self.view.set_full_calibration(self.settings["full_calibration"])
+            self.view.set_van_recalc(self.settings["recalc_vanadium"])
+
+    def _save_settings_to_file(self):
+        if self._validate_settings(self.settings):
+            self.model.set_settings_dict(self.settings)
+
+    def load_settings_from_file_or_default(self):
+        self.settings = self.model.get_settings_dict(SETTINGS_DICT)
+        if not self._validate_settings(self.settings):
+            self.settings = DEFAULT_SETTINGS.copy()
+            self._save_settings_to_file()
+
+    @staticmethod
+    def _validate_settings(settings):
+        try:
+            all_keys = settings.keys() == SETTINGS_DICT.keys()
+            save_location = str(settings["save_location"])
+            save_valid = save_location is not "" and save_location is not None
+            recalc_valid = settings["recalc_vanadium"] is not None
+            return all_keys and save_valid and recalc_valid
+        except KeyError:  # Settings contained invalid key.
+            return False
diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/settings_view.py b/scripts/Engineering/gui/engineering_diffraction/settings/settings_view.py
new file mode 100644
index 0000000000000000000000000000000000000000..3d94d776b522c8d6aa5b6f5fa2ae3128932bb901
--- /dev/null
+++ b/scripts/Engineering/gui/engineering_diffraction/settings/settings_view.py
@@ -0,0 +1,69 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+
+from __future__ import (absolute_import, division, print_function)
+from qtpy import QtWidgets
+
+from mantidqt.utils.qt import load_ui
+
+Ui_settings, _ = load_ui(__file__, "settings_widget.ui")
+
+
+class SettingsView(QtWidgets.QDialog, Ui_settings):
+    def __init__(self, parent=None):
+        super(SettingsView, self).__init__(parent)
+        self.setupUi(self)
+        self.setModal(True)
+
+        self.finder_save.setLabelText("Save Location")
+        self.finder_save.isForRunFiles(False)
+        self.finder_save.isForDirectory(True)
+
+        self.finder_fullCalib.setLabelText("Full Calibration")
+        self.finder_fullCalib.isForRunFiles(False)
+        # TODO: Once it becomes possible to load the .csv containing the full calibration into mantid,
+        #  this can be used. Until then, this option is hidden from the user.
+        self.finder_fullCalib.hide()
+
+    # ===============
+    # Slot Connectors
+    # ===============
+
+    def set_on_apply_clicked(self, slot):
+        self.btn_apply.clicked.connect(slot)
+
+    def set_on_ok_clicked(self, slot):
+        self.btn_ok.clicked.connect(slot)
+
+    def set_on_cancel_clicked(self, slot):
+        self.btn_cancel.clicked.connect(slot)
+
+    # =================
+    # Component Getters
+    # =================
+
+    def get_save_location(self):
+        return self.finder_save.getFirstFilename()
+
+    def get_full_calibration(self):
+        return self.finder_fullCalib.getFirstFilename()
+
+    def get_van_recalc(self):
+        return self.check_vanRecalc.isChecked()
+
+    # =================
+    # Component Setters
+    # =================
+
+    def set_save_location(self, text):
+        self.finder_save.setText(text)
+
+    def set_full_calibration(self, text):
+        self.finder_fullCalib.setText(text)
+
+    def set_van_recalc(self, checked):
+        self.check_vanRecalc.setChecked(checked)
diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/settings_widget.ui b/scripts/Engineering/gui/engineering_diffraction/settings/settings_widget.ui
new file mode 100644
index 0000000000000000000000000000000000000000..f2093a42150a686110609cb89b195dc38c8f769b
--- /dev/null
+++ b/scripts/Engineering/gui/engineering_diffraction/settings/settings_widget.ui
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Form</class>
+ <widget class="QWidget" name="Form">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>630</width>
+    <height>184</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Engineering Diffraction Analysis</string>
+  </property>
+  <property name="styleSheet">
+   <string notr="true">QGroupBox {
+border: 1px solid grey;border-radius: 10px;margin-top: 1ex; margin-right: 0ex
+}
+QGroupBox:title {
+                          subcontrol-origin: margin;
+                          subcontrol-position: top center;
+                          padding-top: 0px;
+                          padding-bottom: 0px;
+							  padding-left: 5px;
+                          padding-right: 5px;
+                          color: rgb(56, 56, 56)
+}</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QGroupBox" name="group_general">
+     <property name="title">
+      <string>General</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="0" column="0">
+       <widget class="FileFinder" name="finder_save" native="true"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="group_calib">
+     <property name="title">
+      <string>Calibration</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_2">
+      <item row="0" column="0">
+       <widget class="QCheckBox" name="check_vanRecalc">
+        <property name="text">
+         <string>Force Vanadium Recalculation</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="FileFinder" name="finder_fullCalib" native="true"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>40</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item>
+    <widget class="QFrame" name="frame">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::NoFrame</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Raised</enum>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="btn_apply">
+        <property name="text">
+         <string>Apply</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="btn_ok">
+        <property name="text">
+         <string>OK</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="btn_cancel">
+        <property name="text">
+         <string>Cancel</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>FileFinder</class>
+   <extends>QWidget</extends>
+   <header>mantidqt.widgets.filefinder</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/test/__init__.py b/scripts/Engineering/gui/engineering_diffraction/settings/test/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_helper.py b/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_helper.py
new file mode 100644
index 0000000000000000000000000000000000000000..62a0bf0d145ed963a25d27d06295258523df9bc9
--- /dev/null
+++ b/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_helper.py
@@ -0,0 +1,160 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+
+from __future__ import (absolute_import, division, print_function)
+
+from Engineering.gui.engineering_diffraction.settings.settings_helper import set_setting, get_setting
+
+from qtpy.QtCore import QSettings, QCoreApplication
+
+from shutil import rmtree
+from os.path import dirname
+
+import unittest
+
+GROUP = "CustomInterfaces"
+PREFIX = "EngineeringDiffraction2/"
+
+
+class SettingsHelperTest(unittest.TestCase):
+    def tearDown(self):
+        settings = QSettings()
+        settings.clear()
+        rmtree(dirname(settings.fileName()))
+
+    def setUp(self):
+        settings = QSettings()
+        settings.clear()
+
+    @classmethod
+    def setUpClass(cls):
+        QCoreApplication.setApplicationName("test1")
+        QCoreApplication.setOrganizationName("org1")
+        QSettings.setDefaultFormat(QSettings.IniFormat)
+
+    def test_set_setting_with_string(self):
+        set_setting(GROUP, PREFIX, "something", "value")
+
+        settings = QSettings()
+        settings.beginGroup(GROUP)
+        returned = settings.value(PREFIX + "something")
+        settings.endGroup()
+        self.assertEqual(returned, "value")
+
+    def test_set_setting_with_bool_false(self):
+        set_setting(GROUP, PREFIX, "something", False)
+
+        settings = QSettings()
+        settings.beginGroup("CustomInterfaces")
+        returned = settings.value("EngineeringDiffraction2/" + "something", type=bool)
+        settings.endGroup()
+        self.assertEqual(returned, False)
+
+    def test_set_setting_with_bool_true(self):
+        set_setting(GROUP, PREFIX, "something", True)
+
+        settings = QSettings()
+        settings.beginGroup("CustomInterfaces")
+        returned = settings.value("EngineeringDiffraction2/" + "something", type=bool)
+        settings.endGroup()
+        self.assertEqual(returned, True)
+
+    def test_set_setting_with_int(self):
+        set_setting(GROUP, PREFIX, "something", 10)
+
+        settings = QSettings()
+        settings.beginGroup(GROUP)
+        returned = settings.value(PREFIX + "something", type=int)
+        settings.endGroup()
+        self.assertEqual(returned, 10)
+
+    def test_get_setting_with_string(self):
+        settings = QSettings()
+        settings.beginGroup(GROUP)
+        settings.setValue(PREFIX + "something", "value")
+        settings.endGroup()
+
+        self.assertEqual(get_setting(GROUP, PREFIX, "something"), "value")
+
+    def test_get_setting_with_bool_false(self):
+        settings = QSettings()
+        settings.beginGroup(GROUP)
+        settings.setValue(PREFIX + "something", False)
+        settings.endGroup()
+
+        self.assertEqual(get_setting(GROUP, PREFIX, "something", return_type=bool), False)
+
+    def test_get_setting_with_bool_true(self):
+        settings = QSettings()
+        settings.beginGroup(GROUP)
+        settings.setValue(PREFIX + "something", True)
+        settings.endGroup()
+
+        self.assertEqual(get_setting(GROUP, PREFIX, "something", return_type=bool), True)
+
+    def test_get_setting_with_int(self):
+        settings = QSettings()
+        settings.beginGroup(GROUP)
+        settings.setValue(PREFIX + "something", 10)
+        settings.endGroup()
+
+        self.assertEqual(get_setting(GROUP, PREFIX, "something", return_type=int), 10)
+
+    def test_get_setting_with_invalid(self):
+        self.assertEqual(get_setting(GROUP, PREFIX, "something"), "")
+
+    def test_get_setting_int_without_specifying_type(self):
+        settings = QSettings()
+        settings.beginGroup(GROUP)
+        settings.setValue(PREFIX + "something", 10)
+        settings.endGroup()
+
+        self.assertEqual(get_setting(GROUP, PREFIX, "something"), "10")
+
+    def test_get_setting_bool_without_specifying_type(self):
+        settings = QSettings()
+        settings.beginGroup(GROUP)
+        settings.setValue(PREFIX + "something", True)
+        settings.endGroup()
+
+        self.assertEqual(get_setting(GROUP, PREFIX, "something"), "true")
+
+    def test_get_setting_bool_specifying_int(self):
+        settings = QSettings()
+        settings.beginGroup(GROUP)
+        settings.setValue(PREFIX + "something", True)
+        settings.endGroup()
+
+        self.assertEqual(get_setting(GROUP, PREFIX, "something", return_type=int), 1)
+
+    def test_get_setting_int_specifying_bool(self):
+        settings = QSettings()
+        settings.beginGroup(GROUP)
+        settings.setValue(PREFIX + "something", 10)
+        settings.endGroup()
+
+        self.assertRaises(TypeError, get_setting, GROUP, PREFIX, "something", return_type=bool)
+
+    def test_get_setting_string_specifying_int(self):
+        settings = QSettings()
+        settings.beginGroup(GROUP)
+        settings.setValue(PREFIX + "something", "some setting")
+        settings.endGroup()
+
+        self.assertRaises(TypeError, get_setting, GROUP, PREFIX, "something", return_type=int)
+
+    def test_get_setting_string_specifying_bool(self):
+        settings = QSettings()
+        settings.beginGroup(GROUP)
+        settings.setValue(PREFIX + "something", "a")
+        settings.endGroup()
+
+        self.assertRaises(TypeError, get_setting, GROUP, PREFIX, "something", return_type=bool)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_model.py b/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_model.py
new file mode 100644
index 0000000000000000000000000000000000000000..3acd388e063e79e16cf256551c8b8aa144ff587e
--- /dev/null
+++ b/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_model.py
@@ -0,0 +1,51 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+
+from __future__ import (absolute_import, division, print_function)
+
+import unittest
+
+from mantid.py3compat.mock import patch
+from Engineering.gui.engineering_diffraction.settings.settings_model import SettingsModel
+
+dir_path = "Engineering.gui.engineering_diffraction.settings."
+
+
+class SettingsModelTest(unittest.TestCase):
+    def setUp(self):
+        self.model = SettingsModel()
+
+    @patch(dir_path + "settings_model.set_setting")
+    def test_set_setting(self, set_setting_mock):
+        self.model.set_setting("name", "value")
+        set_setting_mock.assert_called_with("CustomInterfaces", "EngineeringDiffraction2/", "name", "value")
+
+    @patch(dir_path + "settings_model.get_setting")
+    def test_get_setting(self, get_setting_mock):
+        self.model.get_setting("name")
+        get_setting_mock.assert_called_with("CustomInterfaces", "EngineeringDiffraction2/", "name", return_type=str)
+
+    @patch(dir_path + "settings_model.set_setting")
+    def test_set_settings_dict(self, set_setting_mock):
+        self.model.set_settings_dict({"name": "value", "namebool": False, "namenum": 10})
+        self.assertEqual(set_setting_mock.call_count, 3)
+        set_setting_mock.assert_any_call("CustomInterfaces", "EngineeringDiffraction2/", "name", "value")
+        set_setting_mock.assert_any_call("CustomInterfaces", "EngineeringDiffraction2/", "namebool", False)
+        set_setting_mock.assert_any_call("CustomInterfaces", "EngineeringDiffraction2/", "namenum", 10)
+
+    @patch(dir_path + "settings_model.get_setting")
+    def test_get_settings_dict(self, get_setting_mock):
+        get_setting_mock.return_value = "value"
+        self.assertEqual(self.model.get_settings_dict({"name1": str, "name2": str}),
+                         {'name1': 'value', 'name2': 'value'})
+        self.assertEqual(get_setting_mock.call_count, 2)
+        get_setting_mock.assert_any_call("CustomInterfaces", "EngineeringDiffraction2/", "name1", return_type=str)
+        get_setting_mock.assert_any_call("CustomInterfaces", "EngineeringDiffraction2/", "name2", return_type=str)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_presenter.py b/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_presenter.py
new file mode 100644
index 0000000000000000000000000000000000000000..f08c8d6a901214837dc9c98dbc964b76997075ba
--- /dev/null
+++ b/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_presenter.py
@@ -0,0 +1,95 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+# pylint: disable=invalid-name
+from __future__ import (absolute_import, division, print_function)
+
+import unittest
+
+from mantid.py3compat import mock
+
+from Engineering.gui.engineering_diffraction.settings import settings_model, settings_view, settings_presenter
+
+dir_path = "Engineering.gui.engineering_diffraction.settings."
+
+
+class SettingsPresenterTest(unittest.TestCase):
+    def setUp(self):
+        self.model = mock.create_autospec(settings_model.SettingsModel)
+        self.view = mock.create_autospec(settings_view.SettingsView)
+        self.presenter = settings_presenter.SettingsPresenter(self.model, self.view)
+        self.presenter.settings = {}
+
+    def test_load_existing_settings(self):
+        self.model.get_settings_dict.return_value = {
+            "save_location": "result",
+            "full_calibration": "value",
+            "recalc_vanadium": False
+        }
+
+        self.presenter.load_existing_settings()
+
+        self.assertEqual(self.presenter.settings, {
+            "full_calibration": "value",
+            "save_location": "result",
+            "recalc_vanadium": False
+        })
+        self.assertEqual(self.view.set_save_location.call_count, 1)
+        self.assertEqual(self.view.set_full_calibration.call_count, 1)
+        self.assertEqual(self.view.set_van_recalc.call_count, 1)
+
+    def test_load_invalid_settings(self):
+        self.model.get_settings_dict.return_value = {
+            "foo": "dud",
+            "bar": "result"
+        }
+        self.presenter.load_existing_settings()
+
+        self.view.set_save_location.assert_called_with(settings_presenter.DEFAULT_SETTINGS["save_location"])
+        self.view.set_full_calibration.assert_called_with(settings_presenter.DEFAULT_SETTINGS["full_calibration"])
+        self.view.set_van_recalc.assert_called_with(settings_presenter.DEFAULT_SETTINGS["recalc_vanadium"])
+
+    def test_save_new_settings(self):
+        self.view.get_save_location.return_value = "save"
+        self.view.get_full_calibration.return_value = "cal"
+        self.view.get_van_recalc.return_value = False
+
+        self.presenter.save_new_settings()
+
+        self.assertEqual(self.presenter.settings, {
+            "full_calibration": "cal",
+            "save_location": "save",
+            "recalc_vanadium": False
+        })
+        self.model.set_settings_dict.assert_called_with({
+            "full_calibration": "cal",
+            "save_location": "save",
+            "recalc_vanadium": False
+        })
+        self.assertEqual(self.view.close.call_count, 0)
+
+    def test_save_settings_and_close(self):
+        self.view.get_save_location.return_value = "save"
+        self.view.get_full_calibration.return_value = "cal"
+        self.view.get_van_recalc.return_value = False
+
+        self.presenter.save_and_close_dialog()
+
+        self.assertEqual(self.presenter.settings, {
+            "full_calibration": "cal",
+            "save_location": "save",
+            "recalc_vanadium": False
+        })
+        self.model.set_settings_dict.assert_called_with({
+            "full_calibration": "cal",
+            "save_location": "save",
+            "recalc_vanadium": False
+        })
+        self.assertEqual(self.view.close.call_count, 1)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/model.py b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/model.py
index 6616e2367296727778d173acfd411e730fc61424..24357c27e2aae6f9594e6d75e3eb6cf146cdae74 100644
--- a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/model.py
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/model.py
@@ -13,19 +13,18 @@ import matplotlib.pyplot as plt
 
 from mantid.api import AnalysisDataService as Ads
 from mantid.kernel import logger
-from mantid.simpleapi import Load, EnggCalibrate, DeleteWorkspace, CloneWorkspace, \
+from mantid.simpleapi import EnggCalibrate, DeleteWorkspace, CloneWorkspace, \
     CreateWorkspace, AppendSpectra, CreateEmptyTableWorkspace
 from Engineering.EnggUtils import write_ENGINX_GSAS_iparam_file
 from Engineering.gui.engineering_diffraction.tabs.common import vanadium_corrections
 from Engineering.gui.engineering_diffraction.tabs.common import path_handling
+from Engineering.gui.engineering_diffraction.settings.settings_helper import get_setting
 
 VANADIUM_INPUT_WORKSPACE_NAME = "engggui_vanadium_ws"
 CURVES_WORKSPACE_NAME = "engggui_vanadium_curves"
 INTEGRATED_WORKSPACE_NAME = "engggui_vanadium_integration"
 CALIB_PARAMS_WORKSPACE_NAME = "engggui_calibration_banks_parameters"
 
-CALIBRATION_DIR = path.join(path_handling.OUT_FILES_ROOT_DIR, "Calibration", "")
-
 NORTH_BANK_TEMPLATE_FILE = "template_ENGINX_241391_236516_North_bank.prm"
 SOUTH_BANK_TEMPLATE_FILE = "template_ENGINX_241391_236516_South_bank.prm"
 
@@ -47,8 +46,14 @@ class CalibrationModel(object):
         """
         van_integration, van_curves = vanadium_corrections.fetch_correction_workspaces(
             vanadium_path, instrument, rb_num=rb_num)
-        sample_workspace = self.load_sample(sample_path)
-        output = self.run_calibration(sample_workspace, van_integration, van_curves)
+        sample_workspace = path_handling.load_workspace(sample_path)
+        full_calib_path = get_setting(path_handling.INTERFACES_SETTINGS_GROUP,
+                                      path_handling.ENGINEERING_PREFIX, "full_calibration")
+        if full_calib_path is not None and path.exists(full_calib_path):
+            full_calib = path_handling.load_workspace(full_calib_path)
+            output = self.run_calibration(sample_workspace, van_integration, van_curves, full_calib_ws=full_calib)
+        else:
+            output = self.run_calibration(sample_workspace, van_integration, van_curves)
         if plot_output:
             self._plot_vanadium_curves()
             for i in range(2):
@@ -64,10 +69,10 @@ class CalibrationModel(object):
             params_table.append([i, difc[i], 0.0, tzero[i]])
         self.update_calibration_params_table(params_table)
 
-        self.create_output_files(CALIBRATION_DIR, difc, tzero, sample_path, vanadium_path,
-                                 instrument)
+        calib_dir = path.join(path_handling.get_output_path(), "Calibration", "")
+        self.create_output_files(calib_dir, difc, tzero, sample_path, vanadium_path, instrument)
         if rb_num:
-            user_calib_dir = path.join(path_handling.OUT_FILES_ROOT_DIR, "User", rb_num,
+            user_calib_dir = path.join(path_handling.get_output_path(), "User", rb_num,
                                        "Calibration", "")
             self.create_output_files(user_calib_dir, difc, tzero, sample_path, vanadium_path,
                                      instrument)
@@ -180,33 +185,31 @@ class CalibrationModel(object):
             ax.set_xlabel("Expected Peaks Centre(dSpacing, A)")
         fig.show()
 
-    @staticmethod
-    def load_sample(sample_run_no):
-        try:
-            return Load(Filename=sample_run_no, OutputWorkspace="engggui_calibration_sample_ws")
-        except Exception as e:
-            logger.error("Error while loading calibration sample data. "
-                         "Could not run the algorithm Load successfully for the calibration sample "
-                         "(run number: " + str(sample_run_no) + "). Error description: " + str(e) +
-                         " Please check also the previous log messages for details.")
-            raise RuntimeError
-
-    def run_calibration(self, sample_ws, van_integration, van_curves):
+    def run_calibration(self, sample_ws, van_integration, van_curves, full_calib_ws=None):
         """
         Runs the main Engineering calibration algorithm.
         :param sample_ws: The workspace with the sample data.
         :param van_integration: The integration values from the vanadium corrections
         :param van_curves: The curves from the vanadium corrections.
+        :param full_calib_ws: Full pixel calibration of the detector (optional)
         :return: The output of the algorithm.
         """
         output = [None] * 2
         for i in range(2):
             table_name = self._generate_table_workspace_name(i)
-            output[i] = EnggCalibrate(InputWorkspace=sample_ws,
-                                      VanIntegrationWorkspace=van_integration,
-                                      VanCurvesWorkspace=van_curves,
-                                      Bank=str(i + 1),
-                                      FittedPeaks=table_name)
+            if full_calib_ws is not None:
+                output[i] = EnggCalibrate(InputWorkspace=sample_ws,
+                                          VanIntegrationWorkspace=van_integration,
+                                          VanCurvesWorkspace=van_curves,
+                                          Bank=str(i + 1),
+                                          FittedPeaks=table_name)
+            else:
+                output[i] = EnggCalibrate(InputWorkspace=sample_ws,
+                                          VanIntegrationWorkspace=van_integration,
+                                          VanCurvesWorkspace=van_curves,
+                                          Bank=str(i + 1),
+                                          FittedPeaks=table_name,
+                                          DetectorPositions=full_calib_ws)
         return output
 
     def create_output_files(self, calibration_dir, difc, tzero, sample_path, vanadium_path,
diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/test_calib_model.py b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/test_calib_model.py
index 60e8d530feb89353e116cd204610f5244169e85b..e5ea4fde9e1c83df09746247076e47c28e0698f1 100644
--- a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/test_calib_model.py
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/test_calib_model.py
@@ -34,7 +34,7 @@ class CalibrationModelTest(unittest.TestCase):
     @patch(class_path + '.update_calibration_params_table')
     @patch(class_path + '.create_output_files')
     @patch(class_path + '.run_calibration')
-    @patch(class_path + '.load_sample')
+    @patch(file_path + ".path_handling.load_workspace")
     @patch(file_path + '.vanadium_corrections.fetch_correction_workspaces')
     def test_EnggVanadiumCorrections_algorithm_is_called(self, van, load_sample, calib,
                                                          output_files, update_table):
@@ -44,7 +44,7 @@ class CalibrationModelTest(unittest.TestCase):
 
     @patch(class_path + '.update_calibration_params_table')
     @patch(class_path + '.create_output_files')
-    @patch(class_path + '.load_sample')
+    @patch(file_path + ".path_handling.load_workspace")
     @patch(class_path + '.run_calibration')
     @patch(file_path + '.vanadium_corrections.fetch_correction_workspaces')
     def test_fetch_vanadium_is_called(self, van_corr, calibrate_alg, load_sample, output_files,
@@ -53,9 +53,26 @@ class CalibrationModelTest(unittest.TestCase):
         self.model.create_new_calibration(VANADIUM_NUMBER, CERIUM_NUMBER, False, "ENGINX")
         self.assertEqual(van_corr.call_count, 1)
 
+    @patch(file_path + '.path.exists')
+    @patch(file_path + '.get_setting')
     @patch(class_path + '.update_calibration_params_table')
     @patch(class_path + '.create_output_files')
-    @patch(class_path + '.load_sample')
+    @patch(file_path + ".path_handling.load_workspace")
+    @patch(class_path + '.run_calibration')
+    @patch(file_path + '.vanadium_corrections.fetch_correction_workspaces')
+    def test_having_full_calib_set_uses_file(self, van_corr, calibrate_alg, load_workspace, output_files,
+                                             update_table, setting, path):
+        path.return_value = True
+        setting.return_value = "mocked/out/path"
+        van_corr.return_value = ("mocked_integration", "mocked_curves")
+        load_workspace.return_value = "mocked_workspace"
+        self.model.create_new_calibration(VANADIUM_NUMBER, CERIUM_NUMBER, False, "ENGINX")
+        calibrate_alg.assert_called_with("mocked_workspace", "mocked_integration", "mocked_curves",
+                                         full_calib_ws="mocked_workspace")
+
+    @patch(class_path + '.update_calibration_params_table')
+    @patch(class_path + '.create_output_files')
+    @patch(file_path + ".path_handling.load_workspace")
     @patch(file_path + '.vanadium_corrections.fetch_correction_workspaces')
     @patch(class_path + '._plot_vanadium_curves')
     @patch(class_path + '._generate_difc_tzero_workspace')
@@ -75,7 +92,7 @@ class CalibrationModelTest(unittest.TestCase):
 
     @patch(class_path + '.update_calibration_params_table')
     @patch(class_path + '.create_output_files')
-    @patch(class_path + '.load_sample')
+    @patch(file_path + ".path_handling.load_workspace")
     @patch(file_path + '.vanadium_corrections.fetch_correction_workspaces')
     @patch(class_path + '._plot_vanadium_curves')
     @patch(class_path + '._plot_difc_tzero')
@@ -93,7 +110,7 @@ class CalibrationModelTest(unittest.TestCase):
 
     @patch(class_path + '.update_calibration_params_table')
     @patch(class_path + '.create_output_files')
-    @patch(class_path + '.load_sample')
+    @patch(file_path + ".path_handling.load_workspace")
     @patch(file_path + '.vanadium_corrections.fetch_correction_workspaces')
     @patch(class_path + '._plot_vanadium_curves')
     @patch(class_path + '._plot_difc_tzero')
@@ -107,7 +124,7 @@ class CalibrationModelTest(unittest.TestCase):
 
     @patch(class_path + '.update_calibration_params_table')
     @patch(class_path + '.create_output_files')
-    @patch(class_path + '.load_sample')
+    @patch(file_path + ".path_handling.load_workspace")
     @patch(file_path + '.vanadium_corrections.fetch_correction_workspaces')
     @patch(class_path + '.run_calibration')
     def test_calibration_params_table_is_updated(self, calibrate_alg, vanadium_alg, load_sample,
diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/common/path_handling.py b/scripts/Engineering/gui/engineering_diffraction/tabs/common/path_handling.py
index 35da5482bfb72effedfcd22855f0363533fd28c5..ca37e6d9d6ef57218cba4d7db6bba44b5ae3bb7a 100644
--- a/scripts/Engineering/gui/engineering_diffraction/tabs/common/path_handling.py
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/common/path_handling.py
@@ -8,9 +8,29 @@
 from __future__ import (absolute_import, division, print_function)
 
 from os import path
+from mantid.kernel import logger
+from mantid.simpleapi import Load
+from Engineering.gui.engineering_diffraction.settings.settings_helper import get_setting
 
-OUT_FILES_ROOT_DIR = path.join(path.expanduser("~"), "Engineering_Mantid")
+INTERFACES_SETTINGS_GROUP = "CustomInterfaces"
+ENGINEERING_PREFIX = "EngineeringDiffraction2/"
 
 
 def get_run_number_from_path(run_path, instrument):
     return path.splitext(path.basename(run_path))[0].replace(instrument, '').lstrip('0')
+
+
+def get_output_path():
+    location = get_setting(INTERFACES_SETTINGS_GROUP, ENGINEERING_PREFIX, "save_location")
+    return location if location is not None else ""
+
+
+def load_workspace(file_path):
+    try:
+        return Load(Filename=file_path, OutputWorkspace="engggui_calibration_sample_ws")
+    except Exception as e:
+        logger.error("Error while loading workspace. "
+                     "Could not run the algorithm Load successfully for the data file "
+                     "(path: " + str(file_path) + "). Error description: " + str(e) +
+                     " Please check also the previous log messages for details.")
+        raise RuntimeError
diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/common/test/test_vanadium_corrections.py b/scripts/Engineering/gui/engineering_diffraction/tabs/common/test/test_vanadium_corrections.py
index 9fa9503123401c3611d891c5a1816bc513030851..9468b3183a861f4f355a5410f145b36717f7fd2e 100644
--- a/scripts/Engineering/gui/engineering_diffraction/tabs/common/test/test_vanadium_corrections.py
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/common/test/test_vanadium_corrections.py
@@ -59,17 +59,19 @@ class VanadiumCorrectionsTest(unittest.TestCase):
         self.assertEqual(0, van_correction.call_count)
         self.assertEqual(0, save.call_count)
 
+    @patch(dir_path + ".vanadium_corrections.path_handling.get_output_path")
     @patch(dir_path + ".vanadium_corrections.makedirs")
-    def test_file_path_generation(self, makedirs):
+    def test_file_path_generation(self, makedirs, out_path):
+        out_path.return_value = path.join(path.expanduser("~"), "Test_Directory")
         vanadium_run_number = "1234"
-        engineering_path = path.join(path.expanduser("~"), "Engineering_Mantid")
+        engineering_path = path.join(path.expanduser("~"), "Test_Directory")
         if path.exists(engineering_path):
             rmtree(engineering_path)
         output = vanadium_corrections._generate_saved_workspace_file_paths(vanadium_run_number)
         self.assertEqual(output,
-                         (path.join(path.expanduser("~"), "Engineering_Mantid", "Vanadium_Runs",
+                         (path.join(path.expanduser("~"), "Test_Directory", "Vanadium_Runs",
                                     "1234_precalculated_vanadium_run_integration.nxs"),
-                          path.join(path.expanduser("~"), "Engineering_Mantid", "Vanadium_Runs",
+                          path.join(path.expanduser("~"), "Test_Directory", "Vanadium_Runs",
                                     "1234_precalculated_vanadium_run_bank_curves.nxs")))
         self.assertEqual(1, makedirs.call_count)
 
diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/common/vanadium_corrections.py b/scripts/Engineering/gui/engineering_diffraction/tabs/common/vanadium_corrections.py
index 2f79c91c4990f585815bb7e6186540be7c01085a..0fa938deb76c981da0d00947a391b6b2882a6e1b 100644
--- a/scripts/Engineering/gui/engineering_diffraction/tabs/common/vanadium_corrections.py
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/common/vanadium_corrections.py
@@ -14,6 +14,7 @@ from mantid.simpleapi import logger, Load, EnggVanadiumCorrections, SaveNexus
 from mantid.simpleapi import AnalysisDataService as Ads
 
 from Engineering.gui.engineering_diffraction.tabs.common import path_handling
+from Engineering.gui.engineering_diffraction.settings.settings_helper import get_setting
 
 VANADIUM_INPUT_WORKSPACE_NAME = "engggui_vanadium_ws"
 CURVES_WORKSPACE_NAME = "engggui_vanadium_curves"
@@ -35,7 +36,9 @@ def fetch_correction_workspaces(vanadium_path, instrument, rb_num=""):
     """
     vanadium_number = path_handling.get_run_number_from_path(vanadium_path, instrument)
     integ_path, curves_path = _generate_saved_workspace_file_paths(vanadium_number)
-    if path.exists(curves_path) and path.exists(integ_path):  # Check if the cached files exist.
+    force_recalc = get_setting(path_handling.INTERFACES_SETTINGS_GROUP,
+                               path_handling.ENGINEERING_PREFIX, "recalc_vanadium", return_type=bool)
+    if path.exists(curves_path) and path.exists(integ_path) and not force_recalc:  # Check if the cached files exist.
         try:
             integ_workspace = Load(Filename=integ_path, OutputWorkspace=INTEGRATED_WORKSPACE_NAME)
             curves_workspace = Load(Filename=curves_path, OutputWorkspace=CURVES_WORKSPACE_NAME)
@@ -48,7 +51,7 @@ def fetch_correction_workspaces(vanadium_path, instrument, rb_num=""):
             return integ_workspace, curves_workspace
         except RuntimeError as e:
             logger.error(
-                "Problem loading existing vanadium calculations. Creating new cached files. Description: "
+                "Problem loading existing vanadium calculations. Creating new files. Description: "
                 + str(e))
     integ_workspace, curves_workspace = _calculate_vanadium_correction(vanadium_path)
     _save_correction_files(integ_workspace, integ_path, curves_workspace, curves_path)
@@ -113,10 +116,10 @@ def _generate_saved_workspace_file_paths(vanadium_number, rb_num=""):
     integrated_filename = vanadium_number + SAVED_FILE_INTEG_SUFFIX
     curves_filename = vanadium_number + SAVED_FILE_CURVE_SUFFIX
     if rb_num:
-        vanadium_dir = path.join(path_handling.OUT_FILES_ROOT_DIR, "User", rb_num,
+        vanadium_dir = path.join(path_handling.get_output_path(), "User", rb_num,
                                  VANADIUM_DIRECTORY_NAME)
     else:
-        vanadium_dir = path.join(path_handling.OUT_FILES_ROOT_DIR, VANADIUM_DIRECTORY_NAME)
+        vanadium_dir = path.join(path_handling.get_output_path(), VANADIUM_DIRECTORY_NAME)
     if not path.exists(vanadium_dir):
         makedirs(vanadium_dir)
     return path.join(vanadium_dir, integrated_filename), path.join(vanadium_dir, curves_filename)
diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/model.py b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/model.py
index 9b67f260aba5d3b9110b2f22c71bc8c6509d1b0a..d4cd2e5f713959ab55c51151c63c049c16522bfd 100644
--- a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/model.py
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/model.py
@@ -12,7 +12,8 @@ from matplotlib import gridspec
 import matplotlib.pyplot as plt
 
 from Engineering.gui.engineering_diffraction.tabs.common import vanadium_corrections, path_handling
-from mantid.simpleapi import EnggFocus, Load, logger, AnalysisDataService as Ads, SaveNexus, SaveGSS, SaveFocusedXYE
+from Engineering.gui.engineering_diffraction.settings.settings_helper import get_setting
+from mantid.simpleapi import EnggFocus, logger, AnalysisDataService as Ads, SaveNexus, SaveGSS, SaveFocusedXYE
 
 SAMPLE_RUN_WORKSPACE_NAME = "engggui_focusing_input_ws"
 FOCUSED_OUTPUT_WORKSPACE_NAME = "engggui_focusing_output_ws_bank_"
@@ -33,12 +34,18 @@ class FocusModel(object):
             return
         integration_workspace = Ads.retrieve(vanadium_corrections.INTEGRATED_WORKSPACE_NAME)
         curves_workspace = Ads.retrieve(vanadium_corrections.CURVES_WORKSPACE_NAME)
-        sample_workspace = self._load_focus_sample_run(sample_path)
+        sample_workspace = path_handling.load_workspace(sample_path)
         output_workspaces = []
+        full_calib_path = get_setting(path_handling.INTERFACES_SETTINGS_GROUP,
+                                      path_handling.ENGINEERING_PREFIX, "full_calibration")
+        if full_calib_path is not None and path.exists(full_calib_path):
+            full_calib_workspace = path_handling.load_workspace(full_calib_path)
+        else:
+            full_calib_workspace = None
         for name in banks:
             output_workspace_name = FOCUSED_OUTPUT_WORKSPACE_NAME + str(name)
             self._run_focus(sample_workspace, output_workspace_name, integration_workspace,
-                            curves_workspace, name)
+                            curves_workspace, name, full_calib_workspace)
             output_workspaces.append(output_workspace_name)
             # Save the output to the file system.
             self._save_output(instrument, sample_path, name, output_workspace_name, rb_num)
@@ -47,30 +54,32 @@ class FocusModel(object):
             self._plot_focused_workspaces(output_workspaces)
 
     @staticmethod
-    def _run_focus(input_workspace, output_workspace, vanadium_integration_ws, vanadium_curves_ws,
-                   bank):
+    def _run_focus(input_workspace,
+                   output_workspace,
+                   vanadium_integration_ws,
+                   vanadium_curves_ws,
+                   bank,
+                   full_calib_ws=None):
         try:
-            return EnggFocus(InputWorkspace=input_workspace,
-                             OutputWorkspace=output_workspace,
-                             VanIntegrationWorkspace=vanadium_integration_ws,
-                             VanCurvesWorkspace=vanadium_curves_ws,
-                             Bank=bank)
+            if full_calib_ws is not None:
+                return EnggFocus(InputWorkspace=input_workspace,
+                                 OutputWorkspace=output_workspace,
+                                 VanIntegrationWorkspace=vanadium_integration_ws,
+                                 VanCurvesWorkspace=vanadium_curves_ws,
+                                 Bank=bank,
+                                 DetectorPositions=full_calib_ws)
+            else:
+                return EnggFocus(InputWorkspace=input_workspace,
+                                 OutputWorkspace=output_workspace,
+                                 VanIntegrationWorkspace=vanadium_integration_ws,
+                                 VanCurvesWorkspace=vanadium_curves_ws,
+                                 Bank=bank)
         except RuntimeError as e:
             logger.error(
                 "Error in focusing, Could not run the EnggFocus algorithm successfully for bank " +
                 str(bank) + ". Error Description: " + str(e))
             raise RuntimeError()
 
-    @staticmethod
-    def _load_focus_sample_run(sample_path):
-        try:
-            return Load(Filename=sample_path, OutputWorkspace=SAMPLE_RUN_WORKSPACE_NAME)
-        except RuntimeError as e:
-            logger.error(
-                "Error while loading sample data for focusing. Could not load the sample with filename: "
-                + sample_path + ". Error Description: " + str(e))
-            raise RuntimeError
-
     @staticmethod
     def _plot_focused_workspaces(focused_workspaces):
         fig = plt.figure()
@@ -104,36 +113,36 @@ class FocusModel(object):
     def _save_focused_output_files_as_gss(self, instrument, sample_path, bank, sample_workspace,
                                           rb_num):
         gss_output_path = path.join(
-            path_handling.OUT_FILES_ROOT_DIR, "Focus",
+            path_handling.get_output_path(), "Focus",
             self._generate_output_file_name(instrument, sample_path, bank, ".gss"))
         SaveGSS(InputWorkspace=sample_workspace, Filename=gss_output_path)
         if rb_num is not None:
             gss_output_path = path.join(
-                path_handling.OUT_FILES_ROOT_DIR, "User", rb_num, "Focus",
+                path_handling.get_output_path(), "User", rb_num, "Focus",
                 self._generate_output_file_name(instrument, sample_path, bank, ".gss"))
             SaveGSS(InputWorkspace=sample_workspace, Filename=gss_output_path)
 
     def _save_focused_output_files_as_nexus(self, instrument, sample_path, bank, sample_workspace,
                                             rb_num):
         nexus_output_path = path.join(
-            path_handling.OUT_FILES_ROOT_DIR, "Focus",
+            path_handling.get_output_path(), "Focus",
             self._generate_output_file_name(instrument, sample_path, bank, ".nxs"))
         SaveNexus(InputWorkspace=sample_workspace, Filename=nexus_output_path)
         if rb_num is not None:
             nexus_output_path = path.join(
-                path_handling.OUT_FILES_ROOT_DIR, "User", rb_num, "Focus",
+                path_handling.get_output_path(), "User", rb_num, "Focus",
                 self._generate_output_file_name(instrument, sample_path, bank, ".nxs"))
             SaveNexus(InputWorkspace=sample_workspace, Filename=nexus_output_path)
 
     def _save_focused_output_files_as_xye(self, instrument, sample_path, bank, sample_workspace,
                                           rb_num):
         xye_output_path = path.join(
-            path_handling.OUT_FILES_ROOT_DIR, "Focus",
+            path_handling.get_output_path(), "Focus",
             self._generate_output_file_name(instrument, sample_path, bank, ".dat"))
         SaveFocusedXYE(InputWorkspace=sample_workspace, Filename=xye_output_path, SplitFiles=False)
         if rb_num is not None:
             xye_output_path = path.join(
-                path_handling.OUT_FILES_ROOT_DIR, "User", rb_num, "Focus",
+                path_handling.get_output_path(), "User", rb_num, "Focus",
                 self._generate_output_file_name(instrument, sample_path, bank, ".dat"))
             SaveFocusedXYE(InputWorkspace=sample_workspace,
                            Filename=xye_output_path,
diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/test/test_focus_model.py b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/test/test_focus_model.py
index 53b8456052a5e0b8d271ec15a95631b49e75e377..bf476ed3a1ed7958cef5c0fb8f38e0f0aafaf309 100644
--- a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/test/test_focus_model.py
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/test/test_focus_model.py
@@ -25,7 +25,7 @@ class FocusModelTest(unittest.TestCase):
                                                    sample_path="this_is_mocked_out_too",
                                                    instrument="ENGINX")
 
-    @patch(file_path + ".FocusModel._load_focus_sample_run")
+    @patch(file_path + ".path_handling.load_workspace")
     @patch(file_path + ".vanadium_corrections.Ads.doesExist")
     def test_focus_cancelled_if_van_wsp_missing(self, ads_exist, load):
         ads_exist.return_value = False
@@ -35,7 +35,7 @@ class FocusModelTest(unittest.TestCase):
     @patch(file_path + ".Ads")
     @patch(file_path + ".FocusModel._save_output")
     @patch(file_path + ".FocusModel._run_focus")
-    @patch(file_path + ".FocusModel._load_focus_sample_run")
+    @patch(file_path + ".path_handling.load_workspace")
     def test_focus_run_for_each_bank(self, load_focus, run_focus, output, ads):
         ads.retrieve.return_value = "test_wsp"
         banks = ["1", "2"]
@@ -45,13 +45,13 @@ class FocusModelTest(unittest.TestCase):
         self.assertEqual(len(banks), run_focus.call_count)
         run_focus.assert_called_with("mocked_sample",
                                      model.FOCUSED_OUTPUT_WORKSPACE_NAME + banks[-1], "test_wsp",
-                                     "test_wsp", banks[-1])
+                                     "test_wsp", banks[-1], None)
 
     @patch(file_path + ".Ads")
     @patch(file_path + ".FocusModel._save_output")
     @patch(file_path + ".FocusModel._plot_focused_workspaces")
     @patch(file_path + ".FocusModel._run_focus")
-    @patch(file_path + ".FocusModel._load_focus_sample_run")
+    @patch(file_path + ".path_handling.load_workspace")
     @patch(file_path + ".vanadium_corrections.fetch_correction_workspaces")
     def test_focus_plotted_when_checked(self, fetch_van, load_focus, run_focus, plot_focus, output,
                                         ads):
@@ -67,7 +67,7 @@ class FocusModelTest(unittest.TestCase):
     @patch(file_path + ".FocusModel._save_output")
     @patch(file_path + ".FocusModel._plot_focused_workspaces")
     @patch(file_path + ".FocusModel._run_focus")
-    @patch(file_path + ".FocusModel._load_focus_sample_run")
+    @patch(file_path + ".path_handling.load_workspace")
     @patch(file_path + ".vanadium_corrections.fetch_correction_workspaces")
     def test_focus_not_plotted_when_not_checked(self, fetch_van, load_focus, run_focus, plot_focus,
                                                 output, ads):
@@ -83,7 +83,7 @@ class FocusModelTest(unittest.TestCase):
     @patch(file_path + ".SaveNexus")
     def test_save_output_files_with_no_RB_number(self, nexus, gss, xye):
         mocked_workspace = "mocked-workspace"
-        output_file = path.join(path_handling.OUT_FILES_ROOT_DIR, "Focus",
+        output_file = path.join(path_handling.get_output_path(), "Focus",
                                 "ENGINX_123_bank_North.nxs")
 
         self.model._save_output("ENGINX", "Path/To/ENGINX000123.whatever", "North",
diff --git a/scripts/Inelastic/CrystalField/normalisation.py b/scripts/Inelastic/CrystalField/normalisation.py
index 42c101bb894ab0c3809972101c702926e325ccff..89d9e25c9ff0d062b099976c792348c019164e3b 100644
--- a/scripts/Inelastic/CrystalField/normalisation.py
+++ b/scripts/Inelastic/CrystalField/normalisation.py
@@ -212,7 +212,7 @@ def split2range(*args, **kwargs):
         Nlm[bname] = splitting_factor
     ranges = norm2stev(IonNum=nre, **Nlm)
 
-    if argin['Output'].lower() is 'constraints':
+    if argin['Output'].lower() == 'constraints':
         constr = ''
         for bname in ranges.keys():
             constr += '%.4g<%s<%.4g,' % (-ranges[bname], bname, ranges[bname])
diff --git a/scripts/Inelastic/Direct/PropertiesDescriptors.py b/scripts/Inelastic/Direct/PropertiesDescriptors.py
index 23d18c73955d65f1909f5d938871b7241e947bc4..a22e2e03799c278d05e22420da64287e54218433 100644
--- a/scripts/Inelastic/Direct/PropertiesDescriptors.py
+++ b/scripts/Inelastic/Direct/PropertiesDescriptors.py
@@ -1201,7 +1201,7 @@ class SpectraToMonitorsList(PropDescriptor):
             return None
 
         if isinstance(spectra_list, string_types):
-            if spectra_list.lower() is 'none':
+            if spectra_list.lower() == 'none':
                 result = None
             else:
                 spectra = spectra_list.split(',')
diff --git a/scripts/Inelastic/IndirectImport.py b/scripts/Inelastic/IndirectImport.py
index d3a20fd4b4ddf998ff29c7c1156d5a4e83fb0766..a7bb64a857ba805c5d9c87d4c95c36b10fad1d86 100644
--- a/scripts/Inelastic/IndirectImport.py
+++ b/scripts/Inelastic/IndirectImport.py
@@ -10,9 +10,11 @@ the Indirect scripts depending on platform and numpy package version.
 
 We also deal with importing the mantidplot module outside of MantidPlot here.
 """
-
 from __future__ import (absolute_import, division, print_function)
+
+from contextlib import contextmanager
 import numpy.core.setup_common as numpy_cfg
+import os
 import platform
 import sys
 from mantid import logger
@@ -106,9 +108,23 @@ def import_f2py(lib_base_name):
     # Only proceed if we are indeed on one of the supported platforms.
     assert is_supported_f2py_platform()
 
-    lib_name = lib_base_name + _lib_suffix()
+    @contextmanager
+    def in_syspath(directory):
+        sys.path.insert(0, directory)
+        yield
+        sys.path.pop(0)
 
-    return __import__(lib_name)
+    lib_name = lib_base_name + _lib_suffix()
+    # In Python 3 f2py produces a filename properly tagged with the ABI compatability
+    # information and Python can import this without issue but it will take an untagged
+    # filename in preference so we cannot keep the Python2/Python3 ones in the same
+    # directory. We manipulate the sys.path temporarily to get the correct library.
+    version = sys.version_info
+    if version.major >= 3:
+        return __import__(lib_name)
+    else:
+        with in_syspath(os.path.join(os.path.dirname(__file__), 'cp27')):
+            return __import__(lib_name)
 
 
 def run_f2py_compatibility_test():
diff --git a/scripts/Inelastic/QLdata_win64.cp38-win_amd64.pyd b/scripts/Inelastic/QLdata_win64.cp38-win_amd64.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..68170025432c02fcf2e4375c7e8b808d121c18c0
Binary files /dev/null and b/scripts/Inelastic/QLdata_win64.cp38-win_amd64.pyd differ
diff --git a/scripts/Inelastic/QLres_win64.cp38-win_amd64.pyd b/scripts/Inelastic/QLres_win64.cp38-win_amd64.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..a05effad32b68e5f8337836553e1ff9aea0ad4c7
Binary files /dev/null and b/scripts/Inelastic/QLres_win64.cp38-win_amd64.pyd differ
diff --git a/scripts/Inelastic/QLse_win64.cp38-win_amd64.pyd b/scripts/Inelastic/QLse_win64.cp38-win_amd64.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..f26afeee8cf8c299bfdf934b0bc2a3a597c56b55
Binary files /dev/null and b/scripts/Inelastic/QLse_win64.cp38-win_amd64.pyd differ
diff --git a/scripts/Inelastic/Quest_win64.cp38-win_amd64.pyd b/scripts/Inelastic/Quest_win64.cp38-win_amd64.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..7c02c7a842f4911c3279a8e0dbb9c929e4071d92
Binary files /dev/null and b/scripts/Inelastic/Quest_win64.cp38-win_amd64.pyd differ
diff --git a/scripts/Inelastic/ResNorm_win64.cp38-win_amd64.pyd b/scripts/Inelastic/ResNorm_win64.cp38-win_amd64.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..7daae32de8642e428ca5deecee245a8632d1e4b4
Binary files /dev/null and b/scripts/Inelastic/ResNorm_win64.cp38-win_amd64.pyd differ
diff --git a/scripts/Inelastic/QLdata_win64.pyd b/scripts/Inelastic/cp27/QLdata_win64.pyd
similarity index 100%
rename from scripts/Inelastic/QLdata_win64.pyd
rename to scripts/Inelastic/cp27/QLdata_win64.pyd
diff --git a/scripts/Inelastic/QLres_win64.pyd b/scripts/Inelastic/cp27/QLres_win64.pyd
similarity index 100%
rename from scripts/Inelastic/QLres_win64.pyd
rename to scripts/Inelastic/cp27/QLres_win64.pyd
diff --git a/scripts/Inelastic/QLse_win64.pyd b/scripts/Inelastic/cp27/QLse_win64.pyd
similarity index 100%
rename from scripts/Inelastic/QLse_win64.pyd
rename to scripts/Inelastic/cp27/QLse_win64.pyd
diff --git a/scripts/Inelastic/Quest_win64.pyd b/scripts/Inelastic/cp27/Quest_win64.pyd
similarity index 100%
rename from scripts/Inelastic/Quest_win64.pyd
rename to scripts/Inelastic/cp27/Quest_win64.pyd
diff --git a/scripts/Inelastic/ResNorm_win64.pyd b/scripts/Inelastic/cp27/ResNorm_win64.pyd
similarity index 100%
rename from scripts/Inelastic/ResNorm_win64.pyd
rename to scripts/Inelastic/cp27/ResNorm_win64.pyd
diff --git a/scripts/Inelastic/cylabs_win64.pyd b/scripts/Inelastic/cp27/cylabs_win64.pyd
similarity index 100%
rename from scripts/Inelastic/cylabs_win64.pyd
rename to scripts/Inelastic/cp27/cylabs_win64.pyd
diff --git a/scripts/Inelastic/muscat_win64.pyd b/scripts/Inelastic/cp27/muscat_win64.pyd
similarity index 100%
rename from scripts/Inelastic/muscat_win64.pyd
rename to scripts/Inelastic/cp27/muscat_win64.pyd
diff --git a/scripts/Inelastic/cylabs_win64.cp38-win_amd64.pyd b/scripts/Inelastic/cylabs_win64.cp38-win_amd64.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..49f51382e30f7c123199b4f0509278381c81834a
Binary files /dev/null and b/scripts/Inelastic/cylabs_win64.cp38-win_amd64.pyd differ
diff --git a/scripts/Inelastic/muscat_win64.cp38-win_amd64.pyd b/scripts/Inelastic/muscat_win64.cp38-win_amd64.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..7eeaf0122037daccf6b6212635df82bb91306d58
Binary files /dev/null and b/scripts/Inelastic/muscat_win64.cp38-win_amd64.pyd differ
diff --git a/scripts/LargeScaleStructures/geometry_writer.py b/scripts/LargeScaleStructures/geometry_writer.py
index 031bf1bda74447cf0d0cfdd370e1aaef54aeee40..a74d8f854d200f7c969e88aef6e4a8c578e3ca66 100644
--- a/scripts/LargeScaleStructures/geometry_writer.py
+++ b/scripts/LargeScaleStructures/geometry_writer.py
@@ -105,12 +105,12 @@ class MantidGeom(object):
         if location is None:
             self._append_child("location", sample, x="0.0", y="0.0", z="0.0")
         else:
-            if coord_type is "cartesian":
+            if coord_type == "cartesian":
                 self._append_child("location", sample,
                                    x=location[0],
                                    y=location[1],
                                    z=location[2])
-            if coord_type is "spherical":
+            if coord_type == "spherical":
                 self._append_child("location", sample,
                                    r=location[0],
                                    t=location[1],
diff --git a/scripts/Muon/GUI/FrequencyDomainAnalysis/MaxEnt/maxent_presenter.py b/scripts/Muon/GUI/FrequencyDomainAnalysis/MaxEnt/maxent_presenter.py
index 4429ca99e33c78d1e09569b30eda5b252e6336fe..e7a06d561adcfae05d702a5d3728d362726ada3f 100644
--- a/scripts/Muon/GUI/FrequencyDomainAnalysis/MaxEnt/maxent_presenter.py
+++ b/scripts/Muon/GUI/FrequencyDomainAnalysis/MaxEnt/maxent_presenter.py
@@ -54,7 +54,7 @@ class MaxEntPresenter(object):
         else:
             self.view.setRun("")
 
-        if run is not "None":
+        if run != "None":
             final_options.append(run)
         self.view.addItems(final_options)
         start = int(
diff --git a/scripts/PyChop/PyChopGui.py b/scripts/PyChop/PyChopGui.py
index 5cfe88870ddd7fc7a87a134e9beeb9adc377ff6f..1e052cfadf6c110124342438008993a44788acdd 100755
--- a/scripts/PyChop/PyChopGui.py
+++ b/scripts/PyChop/PyChopGui.py
@@ -27,6 +27,7 @@ from qtpy.QtCore import (QEventLoop, Qt)  # noqa
 from qtpy.QtWidgets import (QAction, QCheckBox, QComboBox, QDialog, QFileDialog, QGridLayout, QHBoxLayout, QMenu, QLabel,
                             QLineEdit, QMainWindow, QMessageBox, QPushButton, QSizePolicy, QSpacerItem, QTabWidget,
                             QTextEdit, QVBoxLayout, QWidget)  # noqa
+from mantid.plots.utility import legend_set_draggable
 from mantidqt.MPLwidgets import FigureCanvasQTAgg as FigureCanvas
 from mantidqt.MPLwidgets import NavigationToolbar2QT as NavigationToolbar
 import matplotlib
@@ -280,7 +281,7 @@ class PyChopGui(QMainWindow):
                 self.plot_qe(ei, label_text, overplot)
             self.resaxes_xlim = max(ei, self.resaxes_xlim)
         self.resaxes.set_xlim([0, self.resaxes_xlim])
-        self.resaxes.legend().draggable()
+        legend_set_draggable(self.resaxes.legend(), True)
         self.resaxes.set_xlabel('Energy Transfer (meV)')
         self.resaxes.set_ylabel(r'$\Delta$E (meV FWHM)')
         self.rescanvas.draw()
@@ -299,7 +300,7 @@ class PyChopGui(QMainWindow):
         line, = self.qeaxes.plot(np.hstack(q2), np.concatenate((np.flipud(en), en)).tolist() * len(self.engine.detector.tthlims))
         line.set_label(label_text)
         self.qeaxes.set_xlim([0, self.qeaxes_xlim])
-        self.qeaxes.legend().draggable()
+        legend_set_draggable(self.qesaxes.legend(), True)
         self.qeaxes.set_xlabel(r'$|Q| (\mathrm{\AA}^{-1})$')
         self.qeaxes.set_ylabel('Energy Transfer (meV)')
         self.qecanvas.draw()
@@ -371,7 +372,7 @@ class PyChopGui(QMainWindow):
         self.flxaxes1.set_xlabel('Incident Energy (meV)')
         self.flxaxes2.set_ylabel('Elastic Resolution FWHM (meV)')
         lg = self.flxaxes2.legend()
-        lg.draggable()
+        legend_set_draggable(lg, True)
         self.flxcanvas.draw()
 
     def update_slider(self, val=None):
@@ -438,7 +439,7 @@ class PyChopGui(QMainWindow):
         line, = self.frqaxes2.plot(freqs, elres, 'o-')
         line.set_label('%s "%s" Ei = %5.3f meV' % (inst, chop, ei))
         lg = self.frqaxes2.legend()
-        lg.draggable()
+        legend_set_draggable(lg, True)
         self.frqaxes2.set_xlim([0, np.max(freqs)])
         self.frqcanvas.draw()
 
diff --git a/scripts/directtools/__init__.py b/scripts/directtools/__init__.py
index 90547109c7656f958c95ba59bda0fe23dbff08bf..f4e22c5825043ba2e8a5efa4d365ee711700d101 100644
--- a/scripts/directtools/__init__.py
+++ b/scripts/directtools/__init__.py
@@ -234,7 +234,8 @@ def _plotsinglehistogram(workspaces, labels, style, xscale, yscale):
     for ws, label in zip(workspaces, labels):
         if 'm' in style:
             markerStyle, markerIndex = _choosemarker(markers, markerIndex)
-        axes.errorbar(ws, wkspIndex=0, linestyle=lineStyle, marker=markerStyle, label=label, distribution=True)
+        axes.errorbar(ws, wkspIndex=0, linestyle=lineStyle, marker=markerStyle, label=label, distribution=True,
+                      capsize=4, linewidth=1)
     axes.set_xscale(xscale)
     axes.set_yscale(yscale)
     if axes.get_yscale() == 'linear':
@@ -554,8 +555,8 @@ def plotconstQ(workspaces, Q, dQ, style='l', keepCutWorkspaces=True, xscale='lin
     for ws in workspaces:
         if ws.getAxis(axisIndex).getUnit().unitID() != qID:
             raise RuntimeError("Cannot cut in const Q. The workspace '{}' is not in units of momentum transfer.".format(str(ws)))
-    figure, axes, cutWSList = plotcuts(direction, workspaces, Q, dQ, r'$Q$', r'$\mathrm{\AA}^{-1}$', style, keepCutWorkspaces,
-                                       xscale, yscale)
+    figure, axes, cutWSList = plotcuts(direction, workspaces, Q, dQ, r'$Q$', r'$\mathrm{\AA}^{-1}$', style,
+                                       keepCutWorkspaces, xscale, yscale)
     _profiletitle(workspaces, cutWSList, _singlecutinfo(Q, dQ), r'$Q$', r'$\mathrm{\AA}^{-1}$', axes)
     if len(cutWSList) > 1:
         axes.legend()
@@ -625,8 +626,10 @@ def plotcuts(direction, workspaces, cuts, widths, quantity, unit, style='l', kee
                 if 'm' in style:
                     markerStyle, markerIndex = _choosemarker(markers, markerIndex)
                 realCutCentre, realCutWidth = _cutcentreandwidth(line)
-                label = _label(ws, realCutCentre, realCutWidth, len(workspaces) == 1, len(cuts) == 1, len(widths) == 1, quantity, unit)
-                axes.errorbar(line, wkspIndex=0, linestyle=lineStyle, marker=markerStyle, label=label, distribution=True)
+                label = _label(ws, realCutCentre, realCutWidth, len(workspaces) == 1, len(cuts) == 1, len(widths) == 1,
+                               quantity, unit)
+                axes.errorbar(line, wkspIndex=0, linestyle=lineStyle, marker=markerStyle, label=label,
+                              distribution=True, capsize=4, linewidth=1)
     axes.set_xscale(xscale)
     axes.set_yscale(yscale)
     if axes.get_yscale() == 'linear':
@@ -796,6 +799,7 @@ def subplots(**kwargs):
     """
     figure, axes = pyplot.subplots(subplot_kw=_mantidsubplotsetup(), **kwargs)
     figure.set_tight_layout(True)
+    axes.tick_params(direction='in', top=True, right=True)
     return figure, axes
 
 
diff --git a/scripts/test/DirectReductionHelpersTest.py b/scripts/test/DirectReductionHelpersTest.py
index 6ab18eb09f38426d8b2412cbc614ab0954ec4a7f..13fa61a6b0c6e228d9682987dcbc68f7b1e58cdd 100644
--- a/scripts/test/DirectReductionHelpersTest.py
+++ b/scripts/test/DirectReductionHelpersTest.py
@@ -290,7 +290,7 @@ class DirectReductionHelpersTest(unittest.TestCase):
                     return attr
                 else:
                     attr_dic = object.__getattribute__(self,'__dict__')
-                    if name is '__dict__':
+                    if name == '__dict__':
                         return attr_dic
                     else:
                         return helpers.gen_getter(attr_dic,name)
@@ -346,7 +346,7 @@ class DirectReductionHelpersTest(unittest.TestCase):
             some_descriptor = SomeDescriptor()
 
             def __setattr__(self,name,val):
-                if name is 'special':
+                if name == 'special':
                     return
                 elif name in self.__class__.__dict__:
                     fp = self.__class__.__dict__[name]
@@ -356,7 +356,7 @@ class DirectReductionHelpersTest(unittest.TestCase):
 
 
             def __getattr__(self,name):
-                if name is 'special':
+                if name == 'special':
                     return self.__special
                 else:
                     tDict = object.__getattribute__(self,'__dict__')
diff --git a/tools/DAEserv/DAEserv.sln b/tools/DAEserv/DAEserv.sln
deleted file mode 100644
index 18790d93e2ff66b2c40731fff2043b212e054f5c..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv.sln
+++ /dev/null
@@ -1,20 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DAEserv", "DAEserv\DAEserv.vcxproj", "{60C9EAAB-AE44-468B-9F18-17C9724DE716}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Release|Win32 = Release|Win32
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{60C9EAAB-AE44-468B-9F18-17C9724DE716}.Debug|Win32.ActiveCfg = Debug|Win32
-		{60C9EAAB-AE44-468B-9F18-17C9724DE716}.Debug|Win32.Build.0 = Debug|Win32
-		{60C9EAAB-AE44-468B-9F18-17C9724DE716}.Release|Win32.ActiveCfg = Release|Win32
-		{60C9EAAB-AE44-468B-9F18-17C9724DE716}.Release|Win32.Build.0 = Release|Win32
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
diff --git a/tools/DAEserv/DAEserv/AssemblyInfo.cpp b/tools/DAEserv/DAEserv/AssemblyInfo.cpp
deleted file mode 100644
index 1a77e0140c6dc9d270d8094d0153d89047ba9ed8..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv/AssemblyInfo.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "stdafx.h"
-
-using namespace System;
-using namespace System::Reflection;
-using namespace System::Runtime::CompilerServices;
-using namespace System::Runtime::InteropServices;
-using namespace System::Security::Permissions;
-
-//
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-//
-[assembly:AssemblyTitleAttribute("DAEserv")];
-[assembly:AssemblyDescriptionAttribute("")];
-[assembly:AssemblyConfigurationAttribute("")];
-[assembly:AssemblyCompanyAttribute("")];
-[assembly:AssemblyProductAttribute("DAEserv")];
-[assembly:AssemblyCopyrightAttribute("Copyright (c)  2008")];
-[assembly:AssemblyTrademarkAttribute("")];
-[assembly:AssemblyCultureAttribute("")];
-
-//
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version
-//      Build Number
-//      Revision
-//
-// You can specify all the value or you can default the Revision and Build Numbers
-// by using the '*' as shown below:
-
-[assembly:AssemblyVersionAttribute("1.0.*")];
-
-[assembly:ComVisible(false)];
-
-[assembly:CLSCompliantAttribute(true)];
-
-[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
-
diff --git a/tools/DAEserv/DAEserv/DAEserv.vcproj b/tools/DAEserv/DAEserv/DAEserv.vcproj
deleted file mode 100644
index ec5f7a8acfa699eea35cf98108eb938b00bc9325..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv/DAEserv.vcproj
+++ /dev/null
@@ -1,300 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="DAEserv"
-	ProjectGUID="{60C9EAAB-AE44-468B-9F18-17C9724DE716}"
-	RootNamespace="DAEserv"
-	Keyword="ManagedCProj"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
-			IntermediateDirectory="$(ConfigurationName)"
-			ConfigurationType="1"
-			CharacterSet="1"
-			ManagedExtensions="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				PreprocessorDefinitions="WIN32;_DEBUG;_WIN32_WINNT=0x0400"
-				RuntimeLibrary="3"
-				UsePrecompiledHeader="2"
-				WarningLevel="3"
-				DebugInformationFormat="3"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(NoInherit)"
-				LinkIncremental="2"
-				GenerateDebugInformation="true"
-				AssemblyDebug="1"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCWebDeploymentTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
-			IntermediateDirectory="$(ConfigurationName)"
-			ConfigurationType="1"
-			CharacterSet="1"
-			ManagedExtensions="1"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="C:\Mantid\Code\Third_Party\include"
-				PreprocessorDefinitions="WIN32;NDEBUG;_WIN32_WINNT=0x0400;_CRT_SECURE_NO_DEPRECATE"
-				RuntimeLibrary="2"
-				UsePrecompiledHeader="2"
-				WarningLevel="3"
-				DebugInformationFormat="3"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(NoInherit) WS2_32.lib"
-				LinkIncremental="1"
-				GenerateDebugInformation="true"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCWebDeploymentTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-		<AssemblyReference
-			RelativePath="System.dll"
-			AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
-		/>
-		<AssemblyReference
-			RelativePath="System.Data.dll"
-			AssemblyName="System.Data, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86"
-		/>
-		<AssemblyReference
-			RelativePath="System.ServiceProcess.dll"
-			AssemblyName="System.ServiceProcess, Version=2.0.0.0, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
-		/>
-		<AssemblyReference
-			RelativePath="System.Configuration.Install.dll"
-			AssemblyName="System.Configuration.Install, Version=2.0.0.0, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
-		/>
-		<AssemblyReference
-			RelativePath="System.XML.dll"
-			AssemblyName="System.Xml, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
-		/>
-		<AssemblyReference
-			RelativePath="System.Management.dll"
-			AssemblyName="System.Management, Version=2.0.0.0, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
-		/>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
-			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
-			>
-			<File
-				RelativePath=".\AssemblyInfo.cpp"
-				>
-			</File>
-			<File
-				RelativePath=".\DAEservWinService.cpp"
-				>
-			</File>
-			<File
-				RelativePath=".\isisds_command.cpp"
-				>
-			</File>
-			<File
-				RelativePath=".\ProjectInstaller.cpp"
-				>
-			</File>
-			<File
-				RelativePath=".\stdafx.cpp"
-				>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						UsePrecompiledHeader="1"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						UsePrecompiledHeader="1"
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath=".\work.cpp"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl;inc;xsd"
-			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
-			>
-			<File
-				RelativePath=".\DAEservWinService.h"
-				FileType="1"
-				>
-				<File
-					RelativePath=".\DAEservWinService.resX"
-					SubType="Designer"
-					>
-				</File>
-			</File>
-			<File
-				RelativePath=".\isisds_command.h"
-				>
-			</File>
-			<File
-				RelativePath=".\ProjectInstaller.h"
-				FileType="1"
-				SubType="Component"
-				>
-				<File
-					RelativePath=".\ProjectInstaller.resx"
-					SubType="Designer"
-					>
-				</File>
-			</File>
-			<File
-				RelativePath=".\resource.h"
-				>
-			</File>
-			<File
-				RelativePath=".\stdafx.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Resource Files"
-			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
-			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
-			>
-			<File
-				RelativePath=".\app.ico"
-				>
-			</File>
-			<File
-				RelativePath=".\app.rc"
-				>
-			</File>
-		</Filter>
-		<File
-			RelativePath=".\ReadMe.txt"
-			>
-		</File>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/tools/DAEserv/DAEserv/DAEserv.vcproj.CLRC.hqs74821.user b/tools/DAEserv/DAEserv/DAEserv.vcproj.CLRC.hqs74821.user
deleted file mode 100644
index 6635a408da53e1ddbad83ac04e0650bcf0885992..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv/DAEserv.vcproj.CLRC.hqs74821.user
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioUserFile
-	ProjectType="Visual C++"
-	Version="8.00"
-	ShowAllFiles="false"
-	>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			>
-			<DebugSettings
-				Command="$(TargetPath)"
-				WorkingDirectory=""
-				CommandArguments=""
-				Attach="false"
-				DebuggerType="3"
-				Remote="1"
-				RemoteMachine="NDW675"
-				RemoteCommand=""
-				HttpUrl=""
-				PDBPath=""
-				SQLDebugging=""
-				Environment=""
-				EnvironmentMerge="true"
-				DebuggerFlavor=""
-				MPIRunCommand=""
-				MPIRunArguments=""
-				MPIRunWorkingDirectory=""
-				ApplicationCommand=""
-				ApplicationArguments=""
-				ShimCommand=""
-				MPIAcceptMode=""
-				MPIAcceptFilter=""
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			>
-			<DebugSettings
-				Command="$(TargetPath)"
-				WorkingDirectory=""
-				CommandArguments=""
-				Attach="false"
-				DebuggerType="3"
-				Remote="1"
-				RemoteMachine="NDW675"
-				RemoteCommand=""
-				HttpUrl=""
-				PDBPath=""
-				SQLDebugging=""
-				Environment=""
-				EnvironmentMerge="true"
-				DebuggerFlavor=""
-				MPIRunCommand=""
-				MPIRunArguments=""
-				MPIRunWorkingDirectory=""
-				ApplicationCommand=""
-				ApplicationArguments=""
-				ShimCommand=""
-				MPIAcceptMode=""
-				MPIAcceptFilter=""
-			/>
-		</Configuration>
-	</Configurations>
-</VisualStudioUserFile>
diff --git a/tools/DAEserv/DAEserv/DAEservWinService.cpp b/tools/DAEserv/DAEserv/DAEservWinService.cpp
deleted file mode 100644
index 02a76cb6bac899966145b381163d0a254bcc8355..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv/DAEservWinService.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-// Mantid Repository : https://github.com/mantidproject/mantid
-//
-// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
-//     NScD Oak Ridge National Laboratory, European Spallation Source
-//     & Institut Laue - Langevin
-// SPDX - License - Identifier: GPL - 3.0 +
-// DAEserv.cpp : main Windows Service project file.
-
-#include "stdafx.h"
-#include <string.h>
-#include "DAEservWinService.h"
-#include <windows.h>
-
-using namespace DAEserv;
-using namespace System::Text;
-using namespace System::Security::Policy;
-using namespace System::Reflection;
-
-DWORD WINAPI startService(LPVOID p);
-
-//To install/uninstall the service, type: "DAEserv.exe -Install [-u]"
-int _tmain(int argc, _TCHAR* argv[])
-{
-	if (argc >= 2)
-	{
-		if (argv[1][0] == _T('/'))
-		{
-			argv[1][0] = _T('-');
-		}
-
-		if (_tcsicmp(argv[1], _T("-Install")) == 0)
-		{
-			array<String^>^ myargs = System::Environment::GetCommandLineArgs();
-			array<String^>^ args = gcnew array<String^>(myargs->Length - 1);
-
-			// Set args[0] with the full path to the assembly,
-			Assembly^ assem = Assembly::GetExecutingAssembly();
-			args[0] = assem->Location;
-
-			Array::Copy(myargs, 2, args, 1, args->Length - 1);
-			AppDomain^ dom = AppDomain::CreateDomain(L"execDom");
-			Type^ type = System::Object::typeid;
-			String^ path = type->Assembly->Location;
-			StringBuilder^ sb = gcnew StringBuilder(path->Substring(0, path->LastIndexOf(L"\\")));
-			sb->Append(L"\\InstallUtil.exe");
-			Evidence^ evidence = gcnew Evidence();
-			dom->ExecuteAssembly(sb->ToString(), evidence, args);
-		}
-	}
-	else
-	{
-		ServiceBase::Run(gcnew DAEservWinService());
-	}
-}
-
diff --git a/tools/DAEserv/DAEserv/DAEservWinService.h b/tools/DAEserv/DAEserv/DAEservWinService.h
deleted file mode 100644
index 986ba810a99bdf2f37e4f1cf0cdec3ff4a08857f..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv/DAEservWinService.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Mantid Repository : https://github.com/mantidproject/mantid
-//
-// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
-//     NScD Oak Ridge National Laboratory, European Spallation Source
-//     & Institut Laue - Langevin
-// SPDX - License - Identifier: GPL - 3.0 +
-#pragma once
-
-#include <windows.h>
-
-using namespace System;
-using namespace System::Collections;
-using namespace System::ServiceProcess;
-using namespace System::ComponentModel;
-
-DWORD WINAPI startService(LPVOID p);
-
-namespace DAEserv {
-
-	/// <summary>
-	/// Summary for DAEservWinService
-	/// </summary>
-	///
-	/// WARNING: If you change the name of this class, you will need to change the
-	///          'Resource File Name' property for the managed resource compiler tool
-	///          associated with all .resx files this class depends on.  Otherwise,
-	///          the designers will not be able to interact properly with localized
-	///          resources associated with this form.
-	public ref class DAEservWinService : public System::ServiceProcess::ServiceBase
-	{
-	public:
-		DAEservWinService()
-		{
-			InitializeComponent();
-			//
-			//TODO: Add the constructor code here
-			//
-		}
-	protected:
-		/// <summary>
-		/// Clean up any resources being used.
-		/// </summary>
-		~DAEservWinService()
-		{
-			if (components)
-			{
-				delete components;
-			}
-		}
-
-		/// <summary>
-		/// Set things in motion so your service can do its work.
-		/// </summary>
-		virtual void OnStart(array<String^>^ args) override
-		{
-			// TODO: Add code here to start your service.
-            DWORD ID;
-            HANDLE thread = CreateThread(NULL,0,&startService,0,0,&ID);
-		}
-
-		/// <summary>
-		/// Stop this service.
-		/// </summary>
-		virtual void OnStop() override
-		{
-			// TODO: Add code here to perform any tear-down necessary to stop your service.
-		}
-
-	private:
-		/// <summary>
-		/// Required designer variable.
-		/// </summary>
-		System::ComponentModel::Container ^components;
-
-#pragma region Windows Form Designer generated code
-		/// <summary>
-		/// Required method for Designer support - do not modify
-		/// the contents of this method with the code editor.
-		/// </summary>
-		void InitializeComponent(void)
-		{
-			this->components = gcnew System::ComponentModel::Container();
-			this->CanStop = true;
-			this->CanPauseAndContinue = true;
-			this->AutoLog = true;
-			this->ServiceName = L"DAEservWinService";
-		}
-#pragma endregion
-	};
-}
diff --git a/tools/DAEserv/DAEserv/DAEservWinService.resX b/tools/DAEserv/DAEserv/DAEservWinService.resX
deleted file mode 100644
index de824e1eebee2baf2ca6b6748d8c7fb2713ed739..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv/DAEservWinService.resX
+++ /dev/null
@@ -1,110 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1">this is my long string</data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        [base64 mime encoded serialized CLR Framework object]
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        [base64 mime encoded string representing a byte array form of the CLR Framework object]
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a CLR class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-</root>
\ No newline at end of file
diff --git a/tools/DAEserv/DAEserv/ProjectInstaller.cpp b/tools/DAEserv/DAEserv/ProjectInstaller.cpp
deleted file mode 100644
index 43ef2da539192dbe73a7e18ef520ee352252252e..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv/ProjectInstaller.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-// Mantid Repository : https://github.com/mantidproject/mantid
-//
-// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
-//     NScD Oak Ridge National Laboratory, European Spallation Source
-//     & Institut Laue - Langevin
-// SPDX - License - Identifier: GPL - 3.0 +
-#include "StdAfx.h"
-#include "ProjectInstaller.h"
diff --git a/tools/DAEserv/DAEserv/ProjectInstaller.h b/tools/DAEserv/DAEserv/ProjectInstaller.h
deleted file mode 100644
index 9018b6da32008102261d125f6641268983c217fd..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv/ProjectInstaller.h
+++ /dev/null
@@ -1,86 +0,0 @@
-// Mantid Repository : https://github.com/mantidproject/mantid
-//
-// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
-//     NScD Oak Ridge National Laboratory, European Spallation Source
-//     & Institut Laue - Langevin
-// SPDX - License - Identifier: GPL - 3.0 +
-#pragma once
-
-using namespace System;
-using namespace System::ComponentModel;
-using namespace System::Collections;
-using namespace System::Configuration::Install;
-
-
-namespace DAEserv {
-
-	[RunInstaller(true)]
-
-	/// <summary>
-	/// Summary for ProjectInstaller
-	/// </summary>
-	public ref class ProjectInstaller : public System::Configuration::Install::Installer
-	{
-	public:
-		ProjectInstaller(void)
-		{
-			InitializeComponent();
-			//
-			//TODO: Add the constructor code here
-			//
-		}
-
-	protected:
-		/// <summary>
-		/// Clean up any resources being used.
-		/// </summary>
-		~ProjectInstaller()
-		{
-			if (components)
-			{
-				delete components;
-			}
-		}
-    private: System::ServiceProcess::ServiceProcessInstaller^  serviceProcessInstaller1;
-    protected: 
-    private: System::ServiceProcess::ServiceInstaller^  serviceInstaller1;
-
-	private:
-		/// <summary>
-		/// Required designer variable.
-		/// </summary>
-		System::ComponentModel::Container ^components;
-
-#pragma region Windows Form Designer generated code
-		/// <summary>
-		/// Required method for Designer support - do not modify
-		/// the contents of this method with the code editor.
-		/// </summary>
-		void InitializeComponent(void)
-		{
-            this->serviceProcessInstaller1 = (gcnew System::ServiceProcess::ServiceProcessInstaller());
-            this->serviceInstaller1 = (gcnew System::ServiceProcess::ServiceInstaller());
-            // 
-            // serviceProcessInstaller1
-            // 
-            this->serviceProcessInstaller1->Account = System::ServiceProcess::ServiceAccount::LocalSystem;
-            this->serviceProcessInstaller1->Password = nullptr;
-            this->serviceProcessInstaller1->Username = nullptr;
-            // 
-            // serviceInstaller1
-            // 
-            this->serviceInstaller1->ServiceName = L"DAEservWinService";
-            this->serviceInstaller1->StartType = System::ServiceProcess::ServiceStartMode::Automatic;
-            this->serviceInstaller1->AfterInstall += gcnew System::Configuration::Install::InstallEventHandler(this, &ProjectInstaller::serviceInstaller1_AfterInstall);
-            // 
-            // ProjectInstaller
-            // 
-            this->Installers->AddRange(gcnew cli::array< System::Configuration::Install::Installer^  >(2) {this->serviceProcessInstaller1, 
-                this->serviceInstaller1});
-
-        }
-#pragma endregion
-    private: System::Void serviceInstaller1_AfterInstall(System::Object^  sender, System::Configuration::Install::InstallEventArgs^  e) {
-             }
-    };
-}
diff --git a/tools/DAEserv/DAEserv/ProjectInstaller.resx b/tools/DAEserv/DAEserv/ProjectInstaller.resx
deleted file mode 100644
index 58601895865326ce6a3c8bcf407f07b116abcc9a..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv/ProjectInstaller.resx
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a .NET class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <metadata name="serviceProcessInstaller1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>17, 54</value>
-  </metadata>
-  <metadata name="serviceInstaller1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>187, 17</value>
-  </metadata>
-  <metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
-    <value>False</value>
-  </metadata>
-</root>
\ No newline at end of file
diff --git a/tools/DAEserv/DAEserv/ReadMe.txt b/tools/DAEserv/DAEserv/ReadMe.txt
deleted file mode 100644
index 936ef5f94488297862d856c4f7b9359ed4df4857..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv/ReadMe.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-========================================================================
-    APPLICATION : DAEserv Project Overview
-========================================================================
-
-Windows Service Wizard has created this DAEserv Application for you.  
-
-This file contains a summary of what you will find in each of the files that
-make up your DAEserv application.
-
-DAEserv.vcproj
-    This is the main project file for VC++ projects generated using a Windows Service Wizard. 
-    It contains information about the version of Visual C++ that generated the file, and 
-    information about the platforms, configurations.
-
-DAEservWinService.cpp
-    This is the main application source file.
-
-AssemblyInfo.cpp
-	Contains custom attributes for modifying assembly metadata.
-
-
-/////////////////////////////////////////////////////////////////////////////
-Other notes:
-
-Windows Service Wizard uses "TODO:" to indicate parts of the source code you
-should add to or customize.
-
-/////////////////////////////////////////////////////////////////////////////
-
-To run your service:
-	1. Build the project
-	2. From the command line, run:
-		DAEserv.exe -Install
diff --git a/tools/DAEserv/DAEserv/app.ico b/tools/DAEserv/DAEserv/app.ico
deleted file mode 100644
index 3a5525fd794f7a7c5c8e6187f470ea3af38cd2b6..0000000000000000000000000000000000000000
Binary files a/tools/DAEserv/DAEserv/app.ico and /dev/null differ
diff --git a/tools/DAEserv/DAEserv/app.rc b/tools/DAEserv/DAEserv/app.rc
deleted file mode 100644
index 807aa89666df8ea82369bdbdfefb8294bf5a19b1..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv/app.rc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Microsoft Visual C++ generated resource script.
-//
-#include "resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (U.S.) resources
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Icon
-//
-
-// Icon placed first or with lowest ID value becomes application icon
-
-LANGUAGE 9, 1
-#pragma code_page(1252)
-1           ICON         "app.ico"
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE  
-BEGIN
-    "resource.h\0"
-    "\0"
-END
-
-2 TEXTINCLUDE  
-BEGIN
-    "#include ""afxres.h""\r\n"
-    "\0"
-END
-
-3 TEXTINCLUDE  
-BEGIN
-    "\0"
-END
-
-#endif    // APSTUDIO_INVOKED
-
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-
-/////////////////////////////////////////////////////////////////////////////
-#endif    // not APSTUDIO_INVOKED
-
diff --git a/tools/DAEserv/DAEserv/isisds_command.cpp b/tools/DAEserv/DAEserv/isisds_command.cpp
deleted file mode 100644
index b354735c73272a643e4cd6d5e4e83a4756458797..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv/isisds_command.cpp
+++ /dev/null
@@ -1,383 +0,0 @@
-/** 
-
-    @file isisds_command.cpp
-    
-    IDC interface - minimal socket interface to the DAE
-    
-    @author Freddie Akeroyd, STFC ISIS Facility
-    @date 31/07/2008
-
-    Copyright &copy; 2007-8 STFC Rutherford Appleton Laboratory
-
-    This file is part of ISIS Instrument control program.
-    you can redistribute it and/or modify it under the terms of the 
-    GNU General Public License
-*/
-
-
-#include "stdafx.h"
-
-#include <stdio.h>
-#include "isisds_command.h"
-
-using namespace std;
-
-/* 
- * versions of these structures
- * increment major for incompatible changes
- * increment minor for backward compatible changes on server
- */
-#define ISISDS_MAJOR_VER 1
-#define ISISDS_MINOR_VER 1
-
-#ifndef _WIN32
-#define closesocket	close
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/select.h>
-#endif
-
-/* wait until read len bytes, return <=0 on error */
-static int recv_all(SOCKET s, void* buffer, int len, int flags)
-{
-	char* cbuffer = (char*)buffer;
-	int n, ntot;
-	ntot = 0;
-	while(len > 0)
-	{
-		n = recv(s, cbuffer, len, flags);
-		if (n <= 0)
-		{
-			return n; /* error */
-		}
-		len -= n;
-		cbuffer += n;
-		ntot += n;
-	}
-	return ntot;
-}
-
-/* clear out old data from a socket */
-static void clear_replies(SOCKET s)
-{
-	static char buffer[100000];
-	struct timeval timeout = { 0, 0 };
-    fd_set fds;
-	int done = 0;
-	while(!done)
-	{
-		FD_ZERO(&fds);
-		FD_SET(s, &fds);
-		if ( (select(FD_SETSIZE, &fds, NULL, NULL, &timeout) > 0) && FD_ISSET(s, &fds) )
-		{
-			recv(s, buffer, sizeof(buffer), 0);
-		}
-		else
-		{
-			done = 1;
-		}
-	}
-}
-
-/*
- * client: open a socket and perform initial negotiation
- * return connected socket or INVALID_SOCKET on error
- */
-SOCKET isisds_send_open(const char* host, ISISDSAccessMode access_type)
-{
-	SOCKET s;
-	int setkeepalive = 1;
-	struct hostent *hostp;
-	struct sockaddr_in address;
-	int n;
-	char *comm, *comm_data;
-/*	int len_comm_data; */
-	isisds_open_t op;
-	ISISDSDataType data_type;
-	int dims_array[10], ndims;
-
-	if ( (hostp = gethostbyname(host)) == NULL )
-	{
-		return INVALID_SOCKET;
-	}
-	memset(&address, 0, sizeof(address));
-	memcpy(&(address.sin_addr.s_addr), hostp->h_addr_list[0], hostp->h_length);
-	address.sin_family = AF_INET;
-	address.sin_port = htons(ISISDS_PORT);
-	s = socket(PF_INET, SOCK_STREAM, 0);
-	if (s == INVALID_SOCKET)
-	{
-		return INVALID_SOCKET;
-	}
-	setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char*)&setkeepalive, sizeof(setkeepalive));
-	if (connect(s, (struct sockaddr*)&address, sizeof(address)) == -1)
-	{
-		closesocket(s);
-		return INVALID_SOCKET;
-	}
-/* socket connected */
-	op.ver_major = ISISDS_MAJOR_VER;
-	op.ver_minor = ISISDS_MINOR_VER;
-	op.pid = 0;
-	op.access_type = access_type;
-	strncpy(op.user, "faa", sizeof(op.user));
-	strncpy(op.host, "localhost", sizeof(op.host));
-	op.len = sizeof(op);
-	if ( (n = send(s, (char*)&op, sizeof(op), 0)) != sizeof(op) )
-	{
-		closesocket(s);
-		return INVALID_SOCKET;
-	}
-	if (isisds_recv_command_alloc(s, &comm, (void**)&comm_data, &data_type, dims_array, &ndims) <= 0)
-	{
-		closesocket(s);
-		return INVALID_SOCKET;
-	}
-	if (comm_data != NULL)
-	{
-		free(comm_data);
-	}
-	if (!strcmp(comm, "OK"))
-	{
-		free(comm);
-		return s;
-	}
-	else
-	{
-		free(comm);
-		closesocket(s);
-		return INVALID_SOCKET;
-	}
-}
-
-/*
- * server
- * client minor ver <= server minor ver
- */
-int isisds_recv_open(SOCKET s, ISISDSAccessMode* access_type)
-{
-	int n;
-	isisds_open_t op;
-	if ( (n = recv_all(s, (char*)&op, sizeof(op), 0)) != sizeof(op) )
-	{
-		return -1;
-	}
-	if ( op.len != sizeof(op) )
-	{
-		return -1;
-	}
-	if ( (op.ver_major != ISISDS_MAJOR_VER) || (op.ver_minor > ISISDS_MINOR_VER) )
-	{
-		return -1;
-	}
-    //cout<<"op.len="<<op.len<<'\n';
-    //cout<<"host=  "<<op.host<<'\n';
-    //cout<<"user=  "<<op.user<<'\n';
-
-	*access_type = (ISISDSAccessMode)op.access_type;
-	return isisds_send_command(s, "OK", NULL, ISISDSUnknown, NULL, 0);
-}
-/*
- * return > 0 on success
- * if dims_array == NULL, ndims is length
- * on graceful termination should get an FD_CLOSE from client, should then send any data
- * shutdown(s, SD_SEND) and then closesocket()
- */
-int isisds_send_command(SOCKET s, const char* command, const void* data, ISISDSDataType type, const int dims_array[], int ndims)
-{
-	int i, n, len_data;
-	isisds_command_header_t comm;
-	memset(&comm, 0, sizeof(comm));
-	if (dims_array == NULL)
-	{
-		comm.ndims = 1;
-		comm.dims_array[0] = ndims;
-		len_data = ndims * isisds_type_size[type];
-	}
-	else
-	{
-		len_data = 1;
-		comm.ndims = ndims;
-		for(i=0; i<ndims; i++)
-		{
-			len_data *= dims_array[i];
-			comm.dims_array[i] = dims_array[i];
-		}
-		len_data *= isisds_type_size[type];
-	}
-	comm.len = sizeof(comm) + len_data;
-	comm.type = type;
-	strncpy(comm.command, command, sizeof(comm.command));
-	clear_replies(s);
-	n = send(s, (char*)&comm, sizeof(comm), 0);
-	if ( (n == sizeof(comm)) && (data != NULL) && (len_data > 0) )
-	{
-		n = send(s, (const char*)data, len_data, 0);
-	}
-	return n;
-}
-
-/* if not do_alloc, then type and dims_array are checked */
-static int isisds_recv_command_helper(SOCKET s, char** command, void** data, ISISDSDataType* type, int dims_array[], int* ndims, int do_alloc)
-{ 
-	int n, len_data, size_in, i;
-	isisds_command_header_t comm;
-	n = recv_all(s, (char*)&comm, sizeof(comm), 0);
-	if (n != sizeof(comm))
-	{
-		return -1;
-	}
-	*command = (char*)malloc(sizeof(comm.command) + 1);
-	strncpy(*command, comm.command, sizeof(comm.command));
-	(*command)[sizeof(comm.command)] = '\0';
-	len_data = comm.len - sizeof(comm); /* in bytes */
-	if (len_data < 0)
-	{
-		return -1; /* error */
-	}
-	else if (len_data == 0)
-	{
-		dims_array[0] = 0;
-/*		*ndims = 0; */
-		*type = ISISDSUnknown;
-		return n; /* all ok, just no extra data */
-	}
-/*	isisds_report(0, 0, "Received data Type = \"%s\", ndims = %d\n", isisds_type_name[comm.type], comm.ndims); */
-	if (do_alloc)
-	{
-		*data = malloc(len_data + 1);
-		((char*)(*data))[len_data] = '\0';
-	}
-	else
-	{
-		size_in = 1;
-		for(i=0; i < *ndims; i++)
-		{
-			size_in *= dims_array[i];
-		}
-		size_in *= isisds_type_size[*type];
-		if (size_in < len_data)
-		{
-			isisds_report(0,0,"data array too small %d < %d\n", size_in, len_data);
-			return -1;
-		}
-		if (size_in > len_data) /* only NULL terminate if space */
-		{
-			((char*)(*data))[len_data] = '\0';
-		}
-	}
-	n = recv_all(s, *data, len_data, 0);
-	if (n != len_data)
-	{
-		free(*data);
-		*data = NULL;
-		len_data = 0;
-		return -1;
-	}
-	/* only update values if changed ... allows Read only parameters to be passed */
-	if ( do_alloc || (*ndims != comm.ndims) )
-	{
-		*ndims = comm.ndims;
-	}
-	if ( do_alloc || (*type != comm.type) )
-	{
-		*type = (ISISDSDataType)comm.type;
-	}
-	for(i=0; i < comm.ndims; i++)
-	{
-		dims_array[i] = comm.dims_array[i];
-	}
-	return n;
-}
-
-/* return > 0 on success */
-int isisds_recv_command(SOCKET s, char* command, int* len_command, void* data, ISISDSDataType* type, int dims_array[], int* ndims)
-{
-    int t_dims[8] = { 1, 0, 0, 0, 0, 0, 0, 0 };
-	int t_ndims = 1;
-	int istat;
-	char* command_temp = NULL;
-	if (type == NULL)
-	{
-		return -1;
-	}
-	if ( dims_array == NULL || ndims == NULL || (*ndims <= 1 && dims_array[0] <= 1) )
-	{
-		/* assume single simple value */
-		istat = isisds_recv_command_helper(s, &command_temp, &data, type, t_dims, &t_ndims, 0);
-		if ( (t_ndims != 1) || (t_dims[0] != 1) )
-		{
-			istat = -1;
-		}
-	}
-	else
-	{
-		istat = isisds_recv_command_helper(s, &command_temp, &data, type, dims_array, ndims, 0);
-	}
-	strncpy(command, command_temp, *len_command);
-	*len_command = strlen(command_temp);
-	free(command_temp);
-	return istat;
-}
-
-/* return > 0 on success */
-int isisds_recv_command_alloc(SOCKET s, char** command, void** data, ISISDSDataType* type, int dims_array[], int* ndims)
-{
-	if (ndims == NULL || dims_array == NULL || type == NULL)
-	{
-		return -1;
-	}
-	if (data == NULL || command == NULL)
-	{
-		return -1;
-	}
-	*data = NULL;
-	*command = NULL;
-	/* *ndims = 0; */
-	dims_array[0] = 0;
-	*type = ISISDSUnknown;
-	return isisds_recv_command_helper(s, command, data, type, dims_array, ndims, 1);
-}
-
-int isisds_send_close(SOCKET s)
-{
-	/*	shutdown((*pfh)->s, SD_SEND);   indicate no more data to send SHUT_WR
-	 * check for FD_READ and recv any other stuff from server 
-     * check for FD_CLOSE and closesocket()
-     */
-    closesocket(s);
-	return 0;
-}
-
-static void default_status_reporter(int status, int code, const char* message)
-{
-	printf("ISISDS: %d %d %s\n", status, code, message);
-}
-
-static isisds_error_report_t status_reporter = default_status_reporter;
-
-int isisds_report(int status, int code, const char* format, ... )
-{
-	va_list ap;
-	char* message = (char*)malloc(1024);
-	va_start(ap, format);
-	vsprintf(message, format, ap);
-	va_end(ap);
-    (*status_reporter)(status, code, message);
-	free(message);
-	return 0;
-}
-
-int isisds_set_report_func(isisds_error_report_t report_func)
-{
-	status_reporter = report_func;
-	return 0;
-}
diff --git a/tools/DAEserv/DAEserv/isisds_command.h b/tools/DAEserv/DAEserv/isisds_command.h
deleted file mode 100644
index f3cb5caa356676bec8ff1e5270f41fa7ace7d810..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv/isisds_command.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/** 
-
-    @file isisds_command.h 
-    
-    IDC interface - minimal socket interface to the DAE
-    
-    @author Freddie Akeroyd, STFC ISIS Facility
-    @date 31/07/2008
-
-    Copyright &copy; 2007-8 STFC Rutherford Appleton Laboratory
-
-    This file is part of ISIS Instrument control program.
-    you can redistribute it and/or modify it under the terms of the 
-    GNU General Public License
-*/
-
-
-#ifndef ISISDS_COMMAND_H
-#define ISISDS_COMMAND_H
-
-typedef void (*isisds_error_report_t)(int status, int code, const char* messsage);
-
-#define ISISDS_PORT 6789
-
-#ifdef _WIN32
-#include <winsock2.h>
-#else
-#define SOCKET	int
-#define INVALID_SOCKET	-1
-#endif /* _WIN32 */
-
-typedef enum { ISISDSDAEAccess = 0, ISISDSCRPTAccess = 1} ISISDSAccessMode;
-
-typedef enum { ISISDSUnknown = 0, ISISDSInt32 = 1, ISISDSReal32 = 2, ISISDSReal64 = 3, ISISDSChar = 4 } ISISDSDataType;
-static int isisds_type_size[] = { 0, 4, 4, 8, 1 };
-static const char* isisds_type_name[] = { "Unknown", "Int32", "Real32", "Real64", "Char" };
-static const char* isisds_type_code[] = { "U00", "I32", "R32", "R64", "C08" }; /* 3 char in length */
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-SOCKET isisds_send_open(const char* host, ISISDSAccessMode access_type);
-int isisds_recv_open(SOCKET s, ISISDSAccessMode* access_type);
-int isisds_send_command(SOCKET s, const char* command, const void* data, ISISDSDataType type, const int dims_array[], int ndims);
-int isisds_recv_command_alloc(SOCKET s, char** command, void** data, ISISDSDataType* type, int dims_array[], int* ndims);
-int isisds_recv_command(SOCKET s, char* command, int* len_command, void* data, ISISDSDataType* type, int dims_array[], int* ndims);
-int isisds_send_close(SOCKET s);
-
-int isisds_set_report_func(isisds_error_report_t report_func);
-int isisds_report(int status, int code, const char* format, ... );
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-/* 
- * try to align to 64 bit (8 bytes) boundaries
- */
-typedef struct
-{
-	int len;
-	int ver_major;
-	int ver_minor;
-	int pid;
-	int access_type; /* 0 =dae, 1 = crpt */
-	int pad[1];
-	char user[32];
-	char host[64];
-}  isisds_open_t;
-
-/*
- * used for sends and replies once a connection open
- * try to align to 64 bits (8 bytes) boundaries 
- */
-typedef struct 
-{
-	int len;  /* of this structure plus any additional data (in bytes) */
- 	int type; /* ISISDSDataType */
-	int ndims;
-	int dims_array[11];
-	char command[32];
-	/* additional data (if any) will follow this */
-} isisds_command_header_t;
-
-#endif /* ISISDS_COMMAND_H */
diff --git a/tools/DAEserv/DAEserv/resource.h b/tools/DAEserv/DAEserv/resource.h
deleted file mode 100644
index 913236fb45b2a3d7fe618ff32acdf9fe0444ceb5..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv/resource.h
+++ /dev/null
@@ -1,9 +0,0 @@
-// Mantid Repository : https://github.com/mantidproject/mantid
-//
-// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
-//     NScD Oak Ridge National Laboratory, European Spallation Source
-//     & Institut Laue - Langevin
-// SPDX - License - Identifier: GPL - 3.0 +
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by app.rc
diff --git a/tools/DAEserv/DAEserv/stdafx.cpp b/tools/DAEserv/DAEserv/stdafx.cpp
deleted file mode 100644
index c71bf0e14efdb820d1574f308bc7d38a821cdd53..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv/stdafx.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-// Mantid Repository : https://github.com/mantidproject/mantid
-//
-// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
-//     NScD Oak Ridge National Laboratory, European Spallation Source
-//     & Institut Laue - Langevin
-// SPDX - License - Identifier: GPL - 3.0 +
-// stdafx.cpp : source file that includes just the standard includes
-// DAEserv.pch will be the pre-compiled header
-// stdafx.obj will contain the pre-compiled type information
-
-#include "stdafx.h"
\ No newline at end of file
diff --git a/tools/DAEserv/DAEserv/stdafx.h b/tools/DAEserv/DAEserv/stdafx.h
deleted file mode 100644
index 24b4845280a0f6371860c3f37465420c395c00b2..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv/stdafx.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Mantid Repository : https://github.com/mantidproject/mantid
-//
-// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
-//     NScD Oak Ridge National Laboratory, European Spallation Source
-//     & Institut Laue - Langevin
-// SPDX - License - Identifier: GPL - 3.0 +
-// stdafx.h : include file for standard system include files,
-// or project specific include files that are used frequently, but
-// are changed infrequently
-#pragma once
-
-#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
-#include <stdio.h>
-#include <tchar.h>
-
-// TODO: reference additional headers your program requires here
-
diff --git a/tools/DAEserv/DAEserv/work.cpp b/tools/DAEserv/DAEserv/work.cpp
deleted file mode 100644
index acce5e24e21e00a3172696680f3fb1b34238d504..0000000000000000000000000000000000000000
--- a/tools/DAEserv/DAEserv/work.cpp
+++ /dev/null
@@ -1,464 +0,0 @@
-// Mantid Repository : https://github.com/mantidproject/mantid
-//
-// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
-//     NScD Oak Ridge National Laboratory, European Spallation Source
-//     & Institut Laue - Langevin
-// SPDX - License - Identifier: GPL - 3.0 +
-#include "stdafx.h"
-
-#include "isisds_command.h"
-
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <iostream>
-#include <string>
-#include <vector>
-#include <valarray>
-#include <ctime>
-#include <fstream>
-#include <boost/math/special_functions/erf.hpp>
-
-using namespace std;
-// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
-
-#define DEFAULT_BUFLEN 512
-#define DEFAULT_PORT "6789"
-
-#define FINISH( s ) cout<<s<<"\n"; \
-                    closesocket(ClientSocket); \
-                    WSACleanup(); \
-                    return 1; \
-
-bool read_command(SOCKET s);
-int peakFun(int i,float x, int t, float dc);
-
-//ofstream ofil("C:\\Mantid\\Code\\DAEserv\\release\\tmp.txt");
-
-struct Workspace
-{
-    typedef float real_t;
-    Workspace()
-    {
-
-        ifstream fil("configDAE.txt");
-        if (!fil)
-        {
-            numberOfSpectra = 3;
-            numberOfBins = 100;
-            x_start = 0.01;
-            x_end = 2000;
-        }
-        else
-        {
-            fil>>numberOfSpectra
-                >>numberOfBins
-                >>x_start
-                >>x_end;
-        }
-        numberOfPeriods = 1;
-        alpha = (x_end-x_start)/(numberOfBins+1);
-        peakStep = (x_end-x_start)/(numberOfSpectra);
-
-        y.resize(numberOfSpectra);
-        x.resize(numberOfBins+1);
-        float dx = alpha;
-        x[0] = x_start;
-        for(size_t i=1;i<x.size();i++)
-        {
-            if (alpha < 0) dx = -x[i-1]*alpha;
-            x[i] = x[i-1] + dx;
-        }
-        for(int i=0;i<numberOfSpectra;i++)
-        {
-            y[i].resize(numberOfBins+1);
-            for(size_t j=0;j<y[i].size();j++)
-            {
-                y[i][j] = peakFun(i,x[j],0,peakStep);
-            }
-        }
-        ndet = numberOfSpectra;
-        udet.resize(ndet);
-        spec.resize(ndet);
-        for(int i=0;i<ndet;i++)
-        {
-            udet[i] = 1000 + i + 1;
-            spec[i] = i+1;
-        }
-    }
-    valarray< real_t > x;
-    vector< valarray<int> > y; 
-    int numberOfSpectra;
-    int numberOfPeriods;
-    int numberOfBins;
-    int ndet;
-    valarray<int> udet,spec;
-    float x_start;
-    float x_end;
-    float alpha;
-    float peakStep;
-};
-
-
-struct ThreadData
-{
-    SOCKET s;
-    DWORD ID;
-    HANDLE thread;
-    time_t start_time;
-    bool done;
-};
-
-// Thread functions
-DWORD WINAPI workingThread(LPVOID p);
-DWORD WINAPI updatingThread(LPVOID p);
-
-// Global variables
-Workspace workspace;
-vector<ThreadData*> thData;
-bool updatingData = false;
-bool readingData = false;
-HANDLE updatingThreadHandle = NULL;
-
-DWORD WINAPI startService(LPVOID p)
-{
-
-    WSADATA wsaData;
-    SOCKET ListenSocket = INVALID_SOCKET,
-           ClientSocket = INVALID_SOCKET;
-    struct addrinfo *result = NULL,
-                    hints;
-//    char recvbuf[DEFAULT_BUFLEN];
-    int iResult;//, iSendResult;
-    int recvbuflen = DEFAULT_BUFLEN;
-    
-
-    // Initialize Winsock
-    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
-    if (iResult != 0) {
-        printf("WSAStartup failed: %d\n", iResult);
-        return 1;
-    }
-
-    ZeroMemory(&hints, sizeof(hints));
-    hints.ai_family = AF_INET;
-    hints.ai_socktype = SOCK_STREAM;
-    hints.ai_protocol = IPPROTO_TCP;
-    hints.ai_flags = AI_PASSIVE;
-
-    // Resolve the server address and port
-    iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
-    if ( iResult != 0 ) {
-        printf("getaddrinfo failed: %d\n", iResult);
-        WSACleanup();
-        return 1;
-    }
-
-    updatingThreadHandle = CreateThread(NULL,0,&updatingThread,NULL,0,NULL);
-
-    for(;;)
-    {
-        // Create a SOCKET for connecting to server
-        ListenSocket = socket(result->ai_family, result->ai_socktype, 0);
-        if (ListenSocket == INVALID_SOCKET) {
-            printf("socket failed: %ld\n", WSAGetLastError());
-            freeaddrinfo(result);
-            WSACleanup();
-            return 1;
-        }
-
-        // Setup the TCP listening socket
-        iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
-        if (iResult == SOCKET_ERROR) {
-            printf("bind failed: %d\n", WSAGetLastError());
-            freeaddrinfo(result);
-            closesocket(ListenSocket);
-            WSACleanup();
-            return 1;
-        }
-
-//        freeaddrinfo(result);
-
-        iResult = listen(ListenSocket, SOMAXCONN);
-        if (iResult == SOCKET_ERROR) {
-            printf("listen failed: %d\n", WSAGetLastError());
-            closesocket(ListenSocket);
-            WSACleanup();
-            return 1;
-        }
-
-        // Accept a client socket
-        ClientSocket = accept(ListenSocket, NULL, NULL);
-        if (ClientSocket == INVALID_SOCKET) {
-            printf("accept failed: %d\n", WSAGetLastError());
-            closesocket(ListenSocket);
-            WSACleanup();
-            return 1;
-        }
-
-        // No longer need server socket
-        closesocket(ListenSocket);
-
-        //ofil<<"Number of running threads "<<thData.size()<<'\n';
-        ThreadData *td = new ThreadData;
-        td->s = ClientSocket;
-        td->done = false;
-        time_t curr_time = time(NULL);
-        td->start_time = curr_time;
-        thData.push_back(td);
-        td->thread = CreateThread(NULL,0,&workingThread,td,0,&td->ID);
-        for(vector<ThreadData*>::iterator t=thData.begin();t!=thData.end();t++)
-        {
-            if ((**t).done)
-            {
-                delete *t;
-                t = thData.erase(t);
-            }
-            double diff = difftime(curr_time,(**t).start_time);
-            //ofil<<(**t).ID<<" diff="<<diff<<endl;
-            // thread unfinished after 60 seconds is treated as failed and terminated
-            if(diff > 2. && !(**t).done)
-            {
-                cerr<<"Terminate "<<(**t).ID<<endl;
-                TerminateThread((**t).thread,0);
-                closesocket((**t).s);
-                delete *t;
-                t = thData.erase(t);
-            }
-        }
-
-    }
-
-
-    WSACleanup();
-    for(vector<ThreadData*>::iterator t=thData.begin();t!=thData.end();t++)
-        delete *t;
-   return 0;
-}
-
-bool read_command(SOCKET s)
-{
-    char comm_buffer[256];
-    int comm_buff_size = sizeof(comm_buffer);
-//    ISISDSDataType ret_type;
-    int sv_dims_array[1] = { 1 }, sv_ndims = 1;   // used for rading single values with IDC routines
-//    int dims_array[2];
-
-    isisds_command_header_t comm;
-    ZeroMemory(&comm,sizeof(comm));
-    int stat = recv(s, (char*)&comm, sizeof(comm), 0);
-    if (stat < 0) return false;
-    if (comm.len < 0) return false;
-    //ofil<<" Command "<<comm.command<<' '<<comm.len<<'\n';
-    //ofil<<" Type "<<comm.type<<' '<<isisds_type_name[comm.type]<<'\n';
-    //ofil<<" NDims "<<comm.ndims<<'\n';
-    //for(int i=0;i<comm.ndims;i++)
-    //    ofil<<"    dim_"<<i<<"= "<<comm.dims_array[i]<<endl;//*/
-    stat = recv(s, comm_buffer, comm_buff_size, 0);
-    //ofil<<"Data size="<<stat<<endl;
-    if (stat < 0) return false;
-    if (comm.type == ISISDSChar)
-    {
-        comm_buffer[stat] = '\0';
-        string name(comm_buffer);
-        //ofil<<name<<endl;
-        if (name == "NSP1")
-        {
-            isisds_send_command(s, "OK", &workspace.numberOfSpectra, ISISDSInt32, sv_dims_array, sv_ndims);
-            return true;
-        }
-
-        if (name == "NPER")
-        {
-            isisds_send_command(s, "OK", &workspace.numberOfPeriods, ISISDSInt32, sv_dims_array, sv_ndims);
-            return true;
-        }
-        
-        if (name == "NTC1")
-        {
-            isisds_send_command(s, "OK", &workspace.numberOfBins, ISISDSInt32, sv_dims_array, sv_ndims);
-            return true;
-        }
-        
-        if (name == "RTCB1")
-        {
-            int dim = (int)workspace.x.size();
-            int n = isisds_send_command(s, "OK", &workspace.x[0], ISISDSReal32, &dim, sv_ndims);
-            return true;
-        }
-
-        if (name == "NAME")
-        {
-            int dim = 7;
-            char instr[] = "DAESERV";
-            int n = isisds_send_command(s, "OK", instr, ISISDSChar, &dim, sv_ndims);
-            return true;
-        }
-
-        if (name == "CNT1")
-        {
-            int dim = (int)workspace.x.size()*workspace.y.size();
-            int *data = new int[dim];
-            int mv_dims_array[1], mv_ndims = 1;
-            mv_dims_array[0] = dim;
-            int k = 0;
-            for(size_t i=0;i<workspace.y.size();i++)
-                for(size_t j=0;j<workspace.y[i].size();j++)
-                    data[k++] = workspace.y[i][j];
-            isisds_send_command(s, "OK", data, ISISDSInt32, mv_dims_array, mv_ndims);
-            delete[] data;
-            return true;
-        }
-        
-        if (name == "RRPB")
-        {
-            int dim = 32;
-            float rpb[32];
-            rpb[8] = 0.1;
-            int n = isisds_send_command(s, "OK", rpb, ISISDSReal32, &dim, sv_ndims);
-            return true;
-        }
-
-        if (name == "NDET")
-        {
-            isisds_send_command(s, "OK", &workspace.ndet, ISISDSInt32, sv_dims_array, sv_ndims);
-            return true;
-        }
-
-        if (name == "UDET")
-        {
-            int dim = workspace.ndet;
-            isisds_send_command(s, "OK", &workspace.udet[0], ISISDSInt32,&dim, sv_ndims);
-            return true;
-        }
-        
-        if (name == "SPEC")
-        {
-            int dim = workspace.ndet;
-            isisds_send_command(s, "OK", &workspace.spec[0], ISISDSInt32, &dim, sv_ndims);
-            return true;
-        }
-        
-    }
-    else if (comm.type == ISISDSInt32)
-    {
-        //ofil<<"Reading data\n";
-        int *idat = (int*)comm_buffer;
-        int n = comm.dims_array[0];
-        //for(int i=0;i<n;i++)
-        //    ofil<<"int("<<i<<")="<<idat[i]<<'\n';
-       int dim = workspace.numberOfBins+1;
-       int i = idat[0]-1;
-       if (i < 0 || i >= dim)
-       {
-           cerr<<"Spectrum number out of range\n";
-           return false;
-       }
-       int res = isisds_send_command(s, "OK", &workspace.y[i][0], ISISDSInt32, &dim, sv_ndims);
-       return true;
-    }
-    return false;
-}
-
-DWORD WINAPI workingThread(LPVOID p){
-
-    if (updatingData) WaitForSingleObject(updatingThreadHandle,10000);
-    readingData = true;
-
-    ThreadData& data = *(ThreadData*)p;
-    SOCKET ClientSocket = data.s;
-
-        ISISDSAccessMode access_type;
-        int stat = isisds_recv_open(ClientSocket, &access_type);
-        if (stat <= 0)
-        {
-            readingData = false;
-            FINISH("Couldnt connect")
-        }
-
-
-        // Receive until the peer shuts down the connection
-        bool ok = true;
-        do {
-
-            //ofil<<"Running\n";
-            ok = read_command(ClientSocket);
-
-        } while (ok);
-
-        // shutdown the connection since we're done
-        int iResult = shutdown(ClientSocket, SD_SEND);
-        if (iResult == SOCKET_ERROR) {
-            printf("shutdown failed: %d\n", WSAGetLastError());
-            closesocket(ClientSocket);
-            WSACleanup();
-            readingData = false;
-            return 1;
-        }//*/
-
-        // cleanup
-        closesocket(ClientSocket);
-
-        //ofil<<"Stopping "<<data.ID<<endl;
-
-        data.done = true;
-        readingData = false;
-  return 0;
-}
-
-
-int peakFun(int i,float xx, int t, float dc)
-{
-   double x = double(xx);
-   double I=10*t;
-   double a=2.;
-   double b=0.03;
-   double c=100 + double(dc)*i;
-   double s=8;
-   double bk=8;
-   double s2 = s*s;
-   double p1 = a/2*(a*s2+2*(x-c));
-   double p2 = (a*s2+(x-c))/sqrt(2*s2);
-   double p3 = b/2*(b*s2-2*(x-c));
-   double p4 = (b*s2-(x-c))/sqrt(s*s2);
-   if (p1 > 400) p1 = 400;
-   if (p1 > 400) p1 = 400;
-   if (p1 < -400) p1 = -400;
-   if (p3 > 400) p3 = 400;
-   if (p3 < -400) p3 = -400;
-   double res = I*(exp(p1)*boost::math::erfc(p2)+ exp(p3)*boost::math::erfc(p4))+bk;
-   return int(res);
-}
-
-DWORD WINAPI updatingThread(LPVOID p){
-
-    HANDLE timer = CreateWaitableTimerA(NULL,FALSE,"tim");
-    if (timer == NULL)
-        return -1;
-
-    LARGE_INTEGER tstart = {0,0};
-    if (!SetWaitableTimer(timer,&tstart,10000,NULL,NULL,TRUE))
-        return -1;
-
-    for(int t=0;;t++)
-    {
-        if (t > 300) t = 0;
-        if (WaitForSingleObject(timer,20000) == WAIT_FAILED)
-            return -1;
-
-        if (readingData) continue;
-        updatingData = true;
-        int length = workspace.numberOfBins+1;
-        for(int i=0;i<workspace.numberOfSpectra;i++)
-        {
-            for(size_t j=0;j<length;j++)
-            {
-                workspace.y[i][j] = peakFun(i,workspace.x[j],t,workspace.peakStep);
-            }
-        }
-        updatingData = false;
-
-    }
-    return 0;
-}
diff --git a/tools/sip/sipwrapper.py b/tools/sip/sipwrapper.py
index 1ae794a8dcebdad1fd262e09fe97d617018b5c6c..fd72b1202f2f8468ca0328915523ce81eb5c7b61 100755
--- a/tools/sip/sipwrapper.py
+++ b/tools/sip/sipwrapper.py
@@ -66,7 +66,7 @@ def parse_arguments(argv):
     known_args, _ = parser.parse_known_args(argv)
     sip_cmd_line = argv[1:]
     if sys.platform == 'win32':
-        sip_cmd_line = map(lambda s: s.replace('\\', '\\\\'), sip_cmd_line)
+        sip_cmd_line = list(map(lambda s: s.replace('\\', '\\\\'), sip_cmd_line))
         # the executable may need .exe appending to be run with the cmd
         # processor
         sip_exe = sip_cmd_line[0] + '.exe'