diff --git a/Framework/API/inc/MantidAPI/ExperimentInfo.h b/Framework/API/inc/MantidAPI/ExperimentInfo.h
index f31cba3a94c58fd2c9fc117d937d649ae31e7486..04a28cd65fee13843f52eb0dcf894653c7a0673b 100644
--- a/Framework/API/inc/MantidAPI/ExperimentInfo.h
+++ b/Framework/API/inc/MantidAPI/ExperimentInfo.h
@@ -104,6 +104,8 @@ public:
   const Run &run() const;
   /// Writable version of the run object
   Run &mutableRun();
+  void setSharedRun(Kernel::cow_ptr<Run> run);
+
   /// Access a log for this experiment.
   Kernel::Property *getLog(const std::string &log) const;
   /// Access a single value from a log for this experiment.
@@ -187,10 +189,6 @@ protected:
   boost::shared_ptr<ModeratorModel> m_moderatorModel;
   /// Description of the choppers for this experiment.
   std::list<boost::shared_ptr<ChopperModel>> m_choppers;
-  /// The information on the sample environment
-  boost::shared_ptr<Sample> m_sample;
-  /// The run information
-  boost::shared_ptr<Run> m_run;
   /// Parameters modifying the base instrument
   boost::shared_ptr<Geometry::ParameterMap> m_parmap;
   /// The base (unparametrized) instrument
@@ -218,15 +216,18 @@ private:
 
   // Loads the xml from an instrument file with some basic error handling
   std::string loadInstrumentXML(const std::string &filename);
+
+  /// The information on the sample environment
+  Kernel::cow_ptr<Sample> m_sample;
+  /// The run information
+  Kernel::cow_ptr<Run> m_run;
+
   /// Detector grouping information
   mutable std::unordered_map<detid_t, size_t> m_det2group;
   void cacheDefaultDetectorGrouping() const; // Not thread-safe
   void invalidateAllSpectrumDefinitions();
   mutable std::once_flag m_defaultDetectorGroupingCached;
 
-  /// Mutex to protect against cow_ptr copying
-  mutable std::recursive_mutex m_mutex;
-
   mutable std::unique_ptr<Beamline::SpectrumInfo> m_spectrumInfo;
   mutable std::unique_ptr<SpectrumInfo> m_spectrumInfoWrapper;
   mutable std::mutex m_spectrumInfoMutex;
diff --git a/Framework/API/inc/MantidAPI/WorkspaceFactory.h b/Framework/API/inc/MantidAPI/WorkspaceFactory.h
index 4afc17aa358bb398ec64bb7098878ca9c4b18550..75d1b95df77630b56343a5b79360b1677fa5e8b6 100644
--- a/Framework/API/inc/MantidAPI/WorkspaceFactory.h
+++ b/Framework/API/inc/MantidAPI/WorkspaceFactory.h
@@ -82,10 +82,6 @@ public:
                             MatrixWorkspace &child,
                             const bool differentSize) const;
 
-  void initializeFromParentWithoutLogs(const MatrixWorkspace &parent,
-                                       MatrixWorkspace &child,
-                                       const bool differentSize) const;
-
   /// Create a ITableWorkspace
   boost::shared_ptr<ITableWorkspace>
   createTable(const std::string &className = "TableWorkspace") const;
diff --git a/Framework/API/src/ExperimentInfo.cpp b/Framework/API/src/ExperimentInfo.cpp
index aad114140a74c02c5f3d0f3b7556509f6e6f6b48..3eb512910b36fe4eb1418b035d51e54ae03edf13 100644
--- a/Framework/API/src/ExperimentInfo.cpp
+++ b/Framework/API/src/ExperimentInfo.cpp
@@ -66,8 +66,7 @@ Kernel::Logger g_log("ExperimentInfo");
 /** Constructor
  */
 ExperimentInfo::ExperimentInfo()
-    : m_moderatorModel(), m_choppers(), m_sample(new Sample()),
-      m_run(new Run()), m_parmap(new ParameterMap()),
+    : m_moderatorModel(), m_choppers(), m_parmap(new ParameterMap()),
       sptr_instrument(new Instrument()) {
   m_parmap->setInstrument(sptr_instrument.get());
 }
@@ -91,7 +90,7 @@ ExperimentInfo::~ExperimentInfo() = default;
  */
 void ExperimentInfo::copyExperimentInfoFrom(const ExperimentInfo *other) {
   m_sample = other->m_sample;
-  m_run = other->m_run->clone();
+  m_run = other->m_run;
   this->setInstrument(other->getInstrument());
   if (other->m_moderatorModel)
     m_moderatorModel = other->m_moderatorModel->clone();
@@ -602,30 +601,17 @@ ChopperModel &ExperimentInfo::chopperModel(const size_t index) const {
 */
 const Sample &ExperimentInfo::sample() const {
   populateIfNotLoaded();
-  std::lock_guard<std::recursive_mutex> lock(m_mutex);
   return *m_sample;
 }
 
 /** Get a reference to the Sample associated with this workspace.
 *  This non-const method will copy the sample if it is shared between
 *  more than one workspace, and the reference returned will be to the copy.
-*  Can ONLY be taken by reference!
 * @return reference to sample object
 */
 Sample &ExperimentInfo::mutableSample() {
   populateIfNotLoaded();
-  // Use a double-check for sharing so that we only
-  // enter the critical region if absolutely necessary
-  if (!m_sample.unique()) {
-    std::lock_guard<std::recursive_mutex> lock(m_mutex);
-    // Check again because another thread may have taken copy
-    // and dropped reference count since previous check
-    if (!m_sample.unique()) {
-      boost::shared_ptr<Sample> oldData = m_sample;
-      m_sample = boost::make_shared<Sample>(*oldData);
-    }
-  }
-  return *m_sample;
+  return m_sample.access();
 }
 
 /** Get a constant reference to the Run object associated with this workspace.
@@ -633,30 +619,22 @@ Sample &ExperimentInfo::mutableSample() {
 */
 const Run &ExperimentInfo::run() const {
   populateIfNotLoaded();
-  std::lock_guard<std::recursive_mutex> lock(m_mutex);
   return *m_run;
 }
 
 /** Get a reference to the Run object associated with this workspace.
 *  This non-const method will copy the Run object if it is shared between
 *  more than one workspace, and the reference returned will be to the copy.
-*  Can ONLY be taken by reference!
 * @return reference to Run object
 */
 Run &ExperimentInfo::mutableRun() {
   populateIfNotLoaded();
-  // Use a double-check for sharing so that we only
-  // enter the critical region if absolutely necessary
-  if (!m_run.unique()) {
-    std::lock_guard<std::recursive_mutex> lock(m_mutex);
-    // Check again because another thread may have taken copy
-    // and dropped reference count since previous check
-    if (!m_run.unique()) {
-      boost::shared_ptr<Run> oldData = m_run;
-      m_run = boost::make_shared<Run>(*oldData);
-    }
-  }
-  return *m_run;
+  return m_run.access();
+}
+
+/// Set the run object. Use in particular to clear run without copying old run.
+void ExperimentInfo::setSharedRun(Kernel::cow_ptr<Run> run) {
+  m_run = std::move(run);
 }
 
 /**
diff --git a/Framework/API/src/WorkspaceFactory.cpp b/Framework/API/src/WorkspaceFactory.cpp
index 3f29b9c437032a8e04ffd6246cd999831e9bc021..88525dfa5d5b01926b840b8c6e748effe8e890b0 100644
--- a/Framework/API/src/WorkspaceFactory.cpp
+++ b/Framework/API/src/WorkspaceFactory.cpp
@@ -78,29 +78,20 @@ WorkspaceFactoryImpl::create(const MatrixWorkspace_const_sptr &parent,
 }
 
 /** Initialize a workspace from its parent
- * This sets values such as instrument, units, sample, spectramap.
+ * This sets values such as title, instrument, units, sample, spectramap.
  * This does NOT copy any data.
- * This does NOT copy any sample logs, i.e., Run object of the workspace won't
- * be copied
- * from its parent.
- * @brief WorkspaceFactoryImpl::initializeFromParentWithoutLogs
- * @param parent
- * @param child
- * @param differentSize
+ *
+ * @param parent :: the parent workspace
+ * @param child :: the child workspace
+ * @param differentSize :: A flag to indicate if the two workspace will be
+ *different sizes
  */
-void WorkspaceFactoryImpl::initializeFromParentWithoutLogs(
+void WorkspaceFactoryImpl::initializeFromParent(
     const MatrixWorkspace &parent, MatrixWorkspace &child,
     const bool differentSize) const {
   child.setTitle(parent.getTitle());
   child.setComment(parent.getComment());
-  child.setInstrument(parent.getInstrument()); // This call also copies the
-                                               // SHARED POINTER to the
-                                               // parameter map
-
-  // This call will (should) perform a COPY of the parameter map.
-  child.instrumentParameters();
-  child.m_sample = parent.m_sample;
-  child.m_run = boost::make_shared<API::Run>();
+  child.copyExperimentInfoFrom(&parent);
   child.setYUnit(parent.m_YUnit);
   child.setYUnitLabel(parent.m_YUnitLabel);
   child.setDistribution(parent.isDistribution());
@@ -144,22 +135,6 @@ void WorkspaceFactoryImpl::initializeFromParentWithoutLogs(
   }
 }
 
-/** Initialize a workspace from its parent
- * This sets values such as title, instrument, units, sample, spectramap.
- * This does NOT copy any data.
- *
- * @param parent :: the parent workspace
- * @param child :: the child workspace
- * @param differentSize :: A flag to indicate if the two workspace will be
- *different sizes
- */
-void WorkspaceFactoryImpl::initializeFromParent(
-    const MatrixWorkspace &parent, MatrixWorkspace &child,
-    const bool differentSize) const {
-  initializeFromParentWithoutLogs(parent, child, differentSize);
-  child.m_run = parent.m_run;
-}
-
 /** Creates a new instance of the class with the given name, and allocates
  * memory for the arrays
  *  @param  className The name of the class you wish to create
diff --git a/Framework/Algorithms/src/CropToComponent.cpp b/Framework/Algorithms/src/CropToComponent.cpp
index 239cb9e95d8181babd577311dacbe786b7da90a9..42d0b5b62483a5d7a7bf11c9fcf29f5364435095 100644
--- a/Framework/Algorithms/src/CropToComponent.cpp
+++ b/Framework/Algorithms/src/CropToComponent.cpp
@@ -1,45 +1,27 @@
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAlgorithms/CropToComponent.h"
-#include "MantidGeometry/IDetector.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Instrument/ComponentInfo.h"
 #include "MantidKernel/ArrayProperty.h"
+#include "MantidIndexing/Conversion.h"
+#include "MantidIndexing/GlobalSpectrumIndex.h"
+#include "MantidIndexing/IndexInfo.h"
 
 namespace {
-
-void getDetectors(
-    Mantid::API::MatrixWorkspace_sptr workspace,
-    const std::vector<std::string> &componentNames,
-    std::vector<Mantid::Geometry::IDetector_const_sptr> &detectors) {
-  auto instrument = workspace->getInstrument();
+std::vector<size_t>
+getDetectorIndices(const Mantid::API::MatrixWorkspace &workspace,
+                   const std::vector<std::string> &componentNames) {
+  const auto &compInfo = workspace.componentInfo();
+  const auto instrument = workspace.getInstrument();
+  std::vector<size_t> detIndices;
   for (const auto &componentName : componentNames) {
-    instrument->getDetectorsInBank(detectors, componentName);
-  }
-}
-
-void getWorkspaceIndices(
-    Mantid::API::MatrixWorkspace_sptr workspace,
-    std::vector<Mantid::Geometry::IDetector_const_sptr> &detectors,
-    std::vector<size_t> &workspaceIndices) {
-  const auto numberOfDetectors = static_cast<int>(detectors.size());
-  std::vector<Mantid::detid_t> detectorIds(numberOfDetectors);
-
-  PARALLEL_FOR_NO_WSP_CHECK()
-  for (int index = 0; index < numberOfDetectors; ++index) {
-    auto det = detectors[index];
-    detectorIds[index] = det->getID();
+    const auto comp = instrument->getComponentByName(componentName);
+    const auto compIndex = compInfo.indexOf(comp->getComponentID());
+    const auto indices = compInfo.detectorsInSubtree(compIndex);
+    detIndices.insert(detIndices.end(), indices.begin(), indices.end());
   }
-
-  // Get the corresponding workspace indices
-  auto detIdToWorkspaceIndexMap =
-      workspace->getDetectorIDToWorkspaceIndexMap(true);
-  PARALLEL_FOR_NO_WSP_CHECK()
-  for (int index = 0; index < numberOfDetectors; ++index) {
-    workspaceIndices[index] = detIdToWorkspaceIndexMap[detectorIds[index]];
-  }
-
-  // Sort the workspace indices
-  std::sort(workspaceIndices.begin(), workspaceIndices.end());
+  return detIndices;
 }
 }
 
@@ -99,12 +81,13 @@ void CropToComponent::exec() {
       getProperty("InputWorkspace");
 
   // Get all detectors
-  std::vector<Mantid::Geometry::IDetector_const_sptr> detectors;
-  getDetectors(inputWorkspace, componentNames, detectors);
+  const auto &detectorIndices =
+      getDetectorIndices(*inputWorkspace, componentNames);
 
   // Get the corresponding workspace indices from the detectors
-  std::vector<size_t> workspaceIndices(detectors.size());
-  getWorkspaceIndices(inputWorkspace, detectors, workspaceIndices);
+  const auto &workspaceIndices =
+      inputWorkspace->indexInfo().globalSpectrumIndicesFromDetectorIndices(
+          detectorIndices);
 
   // Run ExtractSpectra in order to obtain the cropped workspace
   auto extract_alg = Mantid::API::AlgorithmManager::Instance().createUnmanaged(
@@ -113,7 +96,8 @@ void CropToComponent::exec() {
   extract_alg->initialize();
   extract_alg->setProperty("InputWorkspace", inputWorkspace);
   extract_alg->setProperty("OutputWorkspace", "dummy");
-  extract_alg->setProperty("WorkspaceIndexList", workspaceIndices);
+  extract_alg->setProperty("WorkspaceIndexList",
+                           Indexing::castVector<size_t>(workspaceIndices));
   extract_alg->execute();
   Mantid::API::MatrixWorkspace_sptr outputWorkspace =
       extract_alg->getProperty("OutputWorkspace");
diff --git a/Framework/Algorithms/src/FilterEvents.cpp b/Framework/Algorithms/src/FilterEvents.cpp
index 936759f7cd0cd4699be40d6da404bf941cc301b1..d92c13eaeaac35f67096b5c0968f56bfc1083a58 100644
--- a/Framework/Algorithms/src/FilterEvents.cpp
+++ b/Framework/Algorithms/src/FilterEvents.cpp
@@ -1092,7 +1092,9 @@ void FilterEvents::createOutputWorkspaces() {
     }
 
     boost::shared_ptr<EventWorkspace> optws =
-        createWithoutLogs<DataObjects::EventWorkspace>(*m_eventWS);
+        create<EventWorkspace>(*m_eventWS);
+    // Clear Run without copying first.
+    optws->setSharedRun(Kernel::make_cow<Run>());
     m_outputWorkspacesMap.emplace(wsgroup, optws);
 
     // Add information, including title and comment, to output workspace
@@ -1202,7 +1204,9 @@ void FilterEvents::createOutputWorkspacesMatrixCase() {
     // create new workspace from input EventWorkspace and all the sample logs
     // are copied to the new one
     boost::shared_ptr<EventWorkspace> optws =
-        createWithoutLogs<DataObjects::EventWorkspace>(*m_eventWS);
+        create<EventWorkspace>(*m_eventWS);
+    // Clear Run without copying first.
+    optws->setSharedRun(Kernel::make_cow<Run>());
     m_outputWorkspacesMap.emplace(wsgroup, optws);
 
     // TODO/ISSUE/NOW - How about comment and info similar to
@@ -1292,7 +1296,9 @@ void FilterEvents::createOutputWorkspacesTableSplitterCase() {
 
     // create new workspace
     boost::shared_ptr<EventWorkspace> optws =
-        createWithoutLogs<DataObjects::EventWorkspace>(*m_eventWS);
+        create<EventWorkspace>(*m_eventWS);
+    // Clear Run without copying first.
+    optws->setSharedRun(Kernel::make_cow<Run>());
     m_outputWorkspacesMap.emplace(wsgroup, optws);
 
     // TODO/NOW/ISSUE -- How about comment and info?
diff --git a/Framework/Algorithms/test/CropToComponentTest.h b/Framework/Algorithms/test/CropToComponentTest.h
index 7fe5592e554f0ca84fba0bbaf88ba2239366a945..7f3f1d58e7d5d457cbb8857c466499963f11aa01 100644
--- a/Framework/Algorithms/test/CropToComponentTest.h
+++ b/Framework/Algorithms/test/CropToComponentTest.h
@@ -91,6 +91,9 @@ public:
     auto inputWorkspace =
         getSampleWorkspace(numberOfBanks, numberOfPixelsPerBank);
     std::vector<std::string> componentNames = {"bank3"};
+    // Clearing some IDs in bank2 should not cause issues, compare
+    // test_throws_if_no_spectrum_for_detector.
+    inputWorkspace->getSpectrum(9).clearDetectorIDs();
 
     // Act
     Mantid::Algorithms::CropToComponent crop;
@@ -110,6 +113,29 @@ public:
     std::iota(expectedIDs.begin(), expectedIDs.end(), 27);
   }
 
+  void test_throws_if_no_spectrum_for_detector() {
+    // Arrange
+    int numberOfBanks = 4;
+    int numberOfPixelsPerBank = 3;
+
+    auto inputWorkspace =
+        getSampleWorkspace(numberOfBanks, numberOfPixelsPerBank);
+    std::vector<std::string> componentNames = {"bank3"};
+    // Clear some IDs in bank3.
+    inputWorkspace->getSpectrum(18).clearDetectorIDs();
+
+    // Act
+    Mantid::Algorithms::CropToComponent crop;
+    crop.setChild(true);
+    crop.initialize();
+    crop.setProperty("InputWorkspace", inputWorkspace);
+    crop.setProperty("OutputWorkspace", "dummy");
+    crop.setProperty("ComponentNames", componentNames);
+    TS_ASSERT_THROWS_EQUALS(
+        crop.execute(), const std::runtime_error &e, std::string(e.what()),
+        "Some of the requested detectors do not have a corresponding spectrum");
+  }
+
   void test_that_incorrect_component_name_is_not_accepeted() {
     // Arrange
     int numberOfBanks = 4;
diff --git a/Framework/CurveFitting/CMakeLists.txt b/Framework/CurveFitting/CMakeLists.txt
index 154f38ab4e310a0482a1541e4fd09ac1d4e0020c..18aa84dbcfa919e253f8369bb664e7b6643adedf 100644
--- a/Framework/CurveFitting/CMakeLists.txt
+++ b/Framework/CurveFitting/CMakeLists.txt
@@ -32,14 +32,12 @@ set ( SRC_FILES
 	src/CostFunctions/CostFuncUnweightedLeastSquares.cpp
 	src/FitMW.cpp
 	src/FuncMinimizers/BFGS_Minimizer.cpp
-	src/FuncMinimizers/DTRSMinimizer.cpp
 	src/FuncMinimizers/DampedGaussNewtonMinimizer.cpp
 	src/FuncMinimizers/DerivMinimizer.cpp
 	src/FuncMinimizers/FABADAMinimizer.cpp
 	src/FuncMinimizers/FRConjugateGradientMinimizer.cpp
 	src/FuncMinimizers/LevenbergMarquardtMDMinimizer.cpp
 	src/FuncMinimizers/LevenbergMarquardtMinimizer.cpp
-	src/FuncMinimizers/MoreSorensenMinimizer.cpp
 	src/FuncMinimizers/PRConjugateGradientMinimizer.cpp
 	src/FuncMinimizers/SimplexMinimizer.cpp
 	src/FuncMinimizers/SteepestDescentMinimizer.cpp
@@ -196,14 +194,12 @@ set ( INC_FILES
 	inc/MantidCurveFitting/FortranMatrix.h
 	inc/MantidCurveFitting/FortranVector.h
 	inc/MantidCurveFitting/FuncMinimizers/BFGS_Minimizer.h
-	inc/MantidCurveFitting/FuncMinimizers/DTRSMinimizer.h
 	inc/MantidCurveFitting/FuncMinimizers/DampedGaussNewtonMinimizer.h
 	inc/MantidCurveFitting/FuncMinimizers/DerivMinimizer.h
 	inc/MantidCurveFitting/FuncMinimizers/FABADAMinimizer.h
 	inc/MantidCurveFitting/FuncMinimizers/FRConjugateGradientMinimizer.h
 	inc/MantidCurveFitting/FuncMinimizers/LevenbergMarquardtMDMinimizer.h
 	inc/MantidCurveFitting/FuncMinimizers/LevenbergMarquardtMinimizer.h
-	inc/MantidCurveFitting/FuncMinimizers/MoreSorensenMinimizer.h
 	inc/MantidCurveFitting/FuncMinimizers/PRConjugateGradientMinimizer.h
 	inc/MantidCurveFitting/FuncMinimizers/SimplexMinimizer.h
 	inc/MantidCurveFitting/FuncMinimizers/SteepestDescentMinimizer.h
@@ -356,16 +352,15 @@ set ( TEST_FILES
 	FortranMatrixTest.h
 	FortranVectorTest.h
 	FuncMinimizers/BFGSTest.h
-        FuncMinimizers/DTRSMinimizerTest.h
 	FuncMinimizers/DampedGaussNewtonMinimizerTest.h
 	FuncMinimizers/ErrorMessagesTest.h
 	FuncMinimizers/FABADAMinimizerTest.h
 	FuncMinimizers/FRConjugateGradientTest.h
 	FuncMinimizers/LevenbergMarquardtMDTest.h
 	FuncMinimizers/LevenbergMarquardtTest.h
-        FuncMinimizers/MoreSorensenTest.h
 	FuncMinimizers/PRConjugateGradientTest.h
 	FuncMinimizers/SimplexTest.h
+	FuncMinimizers/TrustRegionMinimizerTest.h
 	FunctionDomain1DSpectrumCreatorTest.h
 	FunctionFactoryConstraintTest.h
 	FunctionParameterDecoratorFitTest.h
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/DTRSMinimizer.h b/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/DTRSMinimizer.h
deleted file mode 100644
index d0e9051cc3f5ce461583ce896a2de9ed42e67d8e..0000000000000000000000000000000000000000
--- a/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/DTRSMinimizer.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef MANTID_CURVEFITTING_DTRSMINIMIZER_H_
-#define MANTID_CURVEFITTING_DTRSMINIMIZER_H_
-
-#include "MantidCurveFitting/FuncMinimizers/TrustRegionMinimizer.h"
-
-namespace Mantid {
-namespace CurveFitting {
-namespace FuncMinimisers {
-
-/** A GALAHAD trust region minimizer.
-
-    Copyright &copy; 2009 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-    National Laboratory & European Spallation Source
-
-    This file is part of Mantid.
-
-    Mantid is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 3 of the License, or
-    (at your option) any later version.
-
-    Mantid is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-    File change history is stored at: <https://github.com/mantidproject/mantid>.
-    Code Documentation is available at: <http://doxygen.mantidproject.org>
-*/
-class DLLExport DTRSMinimizer : public TrustRegionMinimizer {
-public:
-  /// constructor and destructor
-  DTRSMinimizer();
-  /// Name of the minimizer.
-  std::string name() const override;
-
-private:
-  void calculateStep(const DoubleFortranMatrix &J, const DoubleFortranVector &f,
-                     const DoubleFortranMatrix &hf,
-                     const DoubleFortranVector &g, double Delta,
-                     DoubleFortranVector &d, double &normd,
-                     const NLLS::nlls_options &options) override;
-
-  void solveDtrs(const DoubleFortranMatrix &J, const DoubleFortranVector &f,
-                 const DoubleFortranMatrix &hf, double Delta,
-                 DoubleFortranVector &d, double &normd,
-                 const NLLS::nlls_options &options);
-
-  // Used for calculating step
-  DoubleFortranMatrix m_A, m_ev;
-  DoubleFortranVector m_ew, m_v, m_v_trans, m_d_trans;
-  NLLS::all_eig_symm_work m_all_eig_symm_ws;
-  DoubleFortranVector m_scale;
-};
-
-} // namespace FuncMinimisers
-} // namespace CurveFitting
-} // namespace Mantid
-
-#endif /*MANTID_CURVEFITTING_DTRSMINIMIZER_H_*/
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/MoreSorensenMinimizer.h b/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/MoreSorensenMinimizer.h
deleted file mode 100644
index 63bddd5fea8f084195d37795b35779ed2b4f4615..0000000000000000000000000000000000000000
--- a/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/MoreSorensenMinimizer.h
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef MANTID_CURVEFITTING_MORESORENSENMINIMIZER_H_
-#define MANTID_CURVEFITTING_MORESORENSENMINIMIZER_H_
-
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
-#include "MantidCurveFitting/FuncMinimizers/TrustRegionMinimizer.h"
-
-namespace Mantid {
-namespace CurveFitting {
-namespace FuncMinimisers {
-
-/** A More-Sorensen trust region minimizer.
-
-    Copyright &copy; 2009 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-    National Laboratory & European Spallation Source
-
-    This file is part of Mantid.
-
-    Mantid is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 3 of the License, or
-    (at your option) any later version.
-
-    Mantid is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-    File change history is stored at: <https://github.com/mantidproject/mantid>.
-    Code Documentation is available at: <http://doxygen.mantidproject.org>
-*/
-class DLLExport MoreSorensenMinimizer : public TrustRegionMinimizer {
-public:
-  /// constructor and destructor
-  MoreSorensenMinimizer();
-  /// Name of the minimizer.
-  std::string name() const override;
-
-private:
-  void calculateStep(const DoubleFortranMatrix &J, const DoubleFortranVector &f,
-                     const DoubleFortranMatrix &hf,
-                     const DoubleFortranVector &g, double Delta,
-                     DoubleFortranVector &d, double &normd,
-                     const NLLS::nlls_options &options) override;
-
-  void solveSubproblem(const DoubleFortranMatrix &J,
-                       const DoubleFortranVector &f,
-                       const DoubleFortranMatrix &hf, double Delta,
-                       DoubleFortranVector &d, double &nd,
-                       const NLLS::nlls_options &options);
-
-  bool getPdShift(double &sigma, DoubleFortranVector &d,
-                  const NLLS::nlls_options &options);
-
-  // Used for calculating step
-  DoubleFortranMatrix m_A, m_LtL, m_AplusSigma;
-  DoubleFortranVector m_v, m_q, m_y1;
-  NLLS::min_eig_symm_work m_min_eig_symm_ws;
-  DoubleFortranVector m_scale;
-};
-
-} // namespace FuncMinimisers
-} // namespace CurveFitting
-} // namespace Mantid
-
-#endif /*MANTID_CURVEFITTING_MORESORENSENMINIMIZER_H_*/
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/TrustRegionMinimizer.h b/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/TrustRegionMinimizer.h
index 753bd294192d6f29fdf85aba9ba54219b1077f20..f971fe2e1b7a2ebe11d374b1556ad5e602bc3ac3 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/TrustRegionMinimizer.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/TrustRegionMinimizer.h
@@ -14,7 +14,7 @@
 namespace Mantid {
 namespace CurveFitting {
 namespace FuncMinimisers {
-/** A base class for least squares trust region minimizers.
+/** Trust Region minimizer class using the DTRS method of GALAHAD.
 
     Copyright &copy; 2009 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
     National Laboratory & European Spallation Source
@@ -48,6 +48,8 @@ public:
   bool iterate(size_t) override;
   /// Return current value of the cost function
   double costFunctionVal() override;
+  /// Name of the minimizer.
+  std::string name() const override;
 
 private:
   /// Evaluate the fitting function and calculate the residuals.
@@ -58,12 +60,10 @@ private:
   void evalHF(const DoubleFortranVector &x, const DoubleFortranVector &f,
               DoubleFortranMatrix &h) const;
   /// Find a correction vector to the parameters.
-  virtual void calculateStep(const DoubleFortranMatrix &J,
-                             const DoubleFortranVector &f,
-                             const DoubleFortranMatrix &hf,
-                             const DoubleFortranVector &g, double Delta,
-                             DoubleFortranVector &d, double &normd,
-                             const NLLS::nlls_options &options) = 0;
+  void calculateStep(const DoubleFortranMatrix &J, const DoubleFortranVector &f,
+                     const DoubleFortranMatrix &hf, double Delta,
+                     DoubleFortranVector &d, double &normd,
+                     const NLLS::nlls_options &options);
 
   /// Stored cost function
   boost::shared_ptr<CostFunctions::CostFuncLeastSquares> m_leastSquares;
@@ -81,6 +81,12 @@ private:
   NLLS::nlls_inform m_inform;
   /// Temporary and helper objects
   NLLS::NLLS_workspace m_workspace;
+
+  // Used for calculating step in DTRS method
+  DoubleFortranMatrix m_A, m_ev;
+  DoubleFortranVector m_ew, m_v, m_v_trans, m_d_trans;
+  NLLS::all_eig_symm_work m_all_eig_symm_ws;
+  DoubleFortranVector m_scale;
 };
 
 } // namespace FuncMinimisers
diff --git a/Framework/CurveFitting/src/FuncMinimizers/DTRSMinimizer.cpp b/Framework/CurveFitting/src/FuncMinimizers/DTRSMinimizer.cpp
deleted file mode 100644
index b2841bb337973c2bda5d657f514f6cd5ebe998c6..0000000000000000000000000000000000000000
--- a/Framework/CurveFitting/src/FuncMinimizers/DTRSMinimizer.cpp
+++ /dev/null
@@ -1,1005 +0,0 @@
-// This code was originally translated from Fortran code on
-// https://ccpforge.cse.rl.ac.uk/gf/project/ral_nlls June 2016
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
-#include "MantidCurveFitting/FuncMinimizers/DTRSMinimizer.h"
-#include "MantidCurveFitting/RalNlls/TrustRegion.h"
-#include "MantidAPI/FuncMinimizerFactory.h"
-
-#include <algorithm>
-#include <limits>
-
-namespace Mantid {
-namespace CurveFitting {
-namespace FuncMinimisers {
-
-// clang-format off
-///@cond nodoc
-DECLARE_FUNCMINIMIZER(DTRSMinimizer, Trust Region)
-///@endcond
-// clang-format on
-
-DTRSMinimizer::DTRSMinimizer() : TrustRegionMinimizer() {}
-
-/** Name of the minimizer.
- */
-std::string DTRSMinimizer::name() const { return "Trust Region"; }
-
-namespace {
-
-const double HUGEST = std::numeric_limits<double>::max();
-const double EPSILON_MCH = std::numeric_limits<double>::epsilon();
-const double LARGEST = HUGEST;
-const double LOWER_DEFAULT = -0.5 * LARGEST;
-const double UPPER_DEFAULT = LARGEST;
-const double POINT4 = 0.4;
-const double ZERO = 0.0;
-const double ONE = 1.0;
-const double TWO = 2.0;
-const double THREE = 3.0;
-const double FOUR = 4.0;
-const double SIX = 6.0;
-const double HALF = 0.5;
-const double ONESIXTH = ONE / SIX;
-const double SIXTH = ONESIXTH;
-const double ONE_THIRD = ONE / THREE;
-const double TWO_THIRDS = TWO / THREE;
-const double THREE_QUARTERS = 0.75;
-const double TWENTY_FOUR = 24.0;
-const int MAX_DEGREE = 3;
-const int HISTORY_MAX = 100;
-const double TEN_EPSILON_MCH = 10.0 * EPSILON_MCH;
-const double ROOTS_TOL = TEN_EPSILON_MCH;
-const double INFINITE_NUMBER = HUGEST;
-
-/** Replacement for FORTRAN's SIGN intrinsic function
- */
-inline double sign(double x, double y) { return y >= 0.0 ? fabs(x) : -fabs(x); }
-
-//!  - - - - - - - - - - - - - - - - - - - - - - -
-//!   control derived type with component defaults
-//!  - - - - - - - - - - - - - - - - - - - - - - -
-struct dtrs_control_type {
-  //!  maximum degree of Taylor approximant allowed
-  int taylor_max_degree = 3;
-
-  //!  any entry of H that is smaller than h_min * MAXVAL( H ) we be treated as
-  // zero
-  double h_min = EPSILON_MCH;
-
-  //!  lower and upper bounds on the multiplier, if known
-  double lower = LOWER_DEFAULT;
-  double upper = UPPER_DEFAULT;
-
-  //!  stop when | ||x|| - radius | <=
-  //!     max( stop_normal * radius, stop_absolute_normal )
-  double stop_normal = EPSILON_MCH;
-  double stop_absolute_normal = EPSILON_MCH;
-
-  //!  is the solution is REQUIRED to lie on the boundary (i.e., is the
-  // constraint
-  //!  an equality)?
-  bool equality_problem = false;
-};
-
-//!  - - - - - - - - - - - - - - - - - - - - - - - -
-//!   history derived type with component defaults
-//!  - - - - - - - - - - - - - - - - - - - - - - - -
-struct dtrs_history_type {
-  //
-  //!  value of lambda
-  double lambda = 0.0;
-
-  //!  corresponding value of ||x(lambda)||_M
-  double x_norm = 0.0;
-};
-
-//!  - - - - - - - - - - - - - - - - - - - - - - -
-//!   inform derived type with component defaults
-//!  - - - - - - - - - - - - - - - - - - - - - - -
-struct dtrs_inform_type {
-  //
-
-  //!  the number of (||x||_M,lambda) pairs in the history
-  int len_history = 0;
-
-  //!  the value of the quadratic function
-  double obj = HUGEST;
-
-  //!  the M-norm of x, ||x||_M
-  double x_norm = 0.0;
-
-  //!  the Lagrange multiplier corresponding to the trust-region constraint
-  double multiplier = 0.0;
-
-  //!  a lower bound max(0,-lambda_1), where lambda_1 is the left-most
-  //!  eigenvalue of (H,M)
-  double pole = 0.0;
-
-  //!  has the hard case occurred?
-  bool hard_case = false;
-
-  //!  history information
-  std::vector<dtrs_history_type> history;
-};
-
-/** Get the largest of the four values.
- *  @param a :: Value number 1.
- *  @param b :: Value number 2.
- *  @param c :: Value number 3.
- *  @param d :: Value number 4.
- */
-double biggest(double a, double b, double c, double d) {
-  return std::max(std::max(a, b), std::max(c, d));
-}
-
-/** Get the largest of the three values.
- *  @param a :: Value number 1.
- *  @param b :: Value number 2.
- *  @param c :: Value number 3.
- */
-double biggest(double a, double b, double c) {
-  return std::max(std::max(a, b), c);
-}
-
-/** Find the largest by absolute value element of a vector.
- *  @param v :: The searched vector.
- */
-double maxAbsVal(const DoubleFortranVector &v) {
-  auto p = v.indicesOfMinMaxElements();
-  return std::max(fabs(v.get(p.first)), fabs(v.get(p.second)));
-}
-
-/** Find the minimum and maximum elements of a vector.
- *  @param v :: The searched vector.
- *  @returns :: A pair of doubles where the first is the minimum and
- *      the second is the maxumum.
- */
-std::pair<double, double> minMaxValues(const DoubleFortranVector &v) {
-  auto p = v.indicesOfMinMaxElements();
-  return std::make_pair(v.get(p.first), v.get(p.second));
-}
-
-/** Compute the 2-norm of a vector which is a square root of the
- *  sum of squares of its elements.
- *  @param v :: The vector.
- */
-double twoNorm(const DoubleFortranVector &v) {
-  if (v.size() == 0)
-    return 0.0;
-  return gsl_blas_dnrm2(v.gsl());
-}
-
-/** Get the dot-product of two vectors of the same size.
- *  @param v1 :: The first vector.
- *  @param v2 :: The second vector.
- */
-double dotProduct(const DoubleFortranVector &v1,
-                  const DoubleFortranVector &v2) {
-  return v1.dot(v2);
-}
-
-/** Find the maximum element in the first n elements of a vector.
- *  @param v :: The vector.
- *  @param n :: The number of elements to examine.
- */
-double maxVal(const DoubleFortranVector &v, int n) {
-  double res = std::numeric_limits<double>::lowest();
-  for (int i = 1; i <= n; ++i) {
-    auto val = v(i);
-    if (val > res) {
-      res = val;
-    }
-  }
-  return res;
-}
-
-/**  Find the number and values of real roots of the quadratic equation
- *
- *                    a2 * x**2 + a1 * x + a0 = 0
- *
- *   where a0, a1 and a2 are real
- *  @param a0 :: The free coefficient.
- *  @param a1 :: The coefficient at the linear term.
- *  @param a2 :: The coefficient at the quadratic term.
- *  @param tol :: A tolerance for comparing doubles.
- *  @param nroots :: The output number of real roots.
- *  @param root1 :: The first real root if nroots > 0.
- *  @param root2 :: The second real root if nroots = 2.
- */
-void rootsQuadratic(double a0, double a1, double a2, double tol, int &nroots,
-                    double &root1, double &root2) {
-
-  auto rhs = tol * a1 * a1;
-  if (fabs(a0 * a2) > rhs) { // really is quadratic
-    root2 = a1 * a1 - FOUR * a2 * a0;
-    if (fabs(root2) <= pow(EPSILON_MCH * a1, 2)) { // numerical double root
-      nroots = 2;
-      root1 = -HALF * a1 / a2;
-      root2 = root1;
-    } else if (root2 < ZERO) { // complex not real roots
-      nroots = 0;
-      root1 = ZERO;
-      root2 = ZERO;
-    } else { // distint real roots
-      auto d = -HALF * (a1 + sign(sqrt(root2), a1));
-      nroots = 2;
-      root1 = d / a2;
-      root2 = a0 / d;
-      if (root1 > root2) {
-        d = root1;
-        root1 = root2;
-        root2 = d;
-      }
-    }
-  } else if (a2 == ZERO) {
-    if (a1 == ZERO) {
-      if (a0 == ZERO) { // the function is zero
-        nroots = 1;
-        root1 = ZERO;
-        root2 = ZERO;
-      } else { // the function is constant
-        nroots = 0;
-        root1 = ZERO;
-        root2 = ZERO;
-      }
-    } else { // the function is linear
-      nroots = 1;
-      root1 = -a0 / a1;
-      root2 = ZERO;
-    }
-  } else { // very ill-conditioned quadratic
-    nroots = 2;
-    if (-a1 / a2 > ZERO) {
-      root1 = ZERO;
-      root2 = -a1 / a2;
-    } else {
-      root1 = -a1 / a2;
-      root2 = ZERO;
-    }
-  }
-
-  //  perfom a Newton iteration to ensure that the roots are accurate
-
-  if (nroots >= 1) {
-    auto p = (a2 * root1 + a1) * root1 + a0;
-    auto pprime = TWO * a2 * root1 + a1;
-    if (pprime != ZERO) {
-      root1 = root1 - p / pprime;
-    }
-    if (nroots == 2) {
-      p = (a2 * root2 + a1) * root2 + a0;
-      pprime = TWO * a2 * root2 + a1;
-      if (pprime != ZERO) {
-        root2 = root2 - p / pprime;
-      }
-    }
-  }
-}
-
-/**  Find the number and values of real roots of the cubic equation
- *
- *                 a3 * x**3 + a2 * x**2 + a1 * x + a0 = 0
- *
- *   where a0, a1, a2 and a3 are real
- *  @param a0 :: The free coefficient.
- *  @param a1 :: The coefficient at the linear term.
- *  @param a2 :: The coefficient at the quadratic term.
- *  @param a3 :: The coefficient at the cubic term.
- *  @param tol :: A tolerance for comparing doubles.
- *  @param nroots :: The output number of real roots.
- *  @param root1 :: The first real root.
- *  @param root2 :: The second real root if nroots > 1.
- *  @param root3 :: The third real root if nroots == 3.
- */
-void rootsCubic(double a0, double a1, double a2, double a3, double tol,
-                int &nroots, double &root1, double &root2, double &root3) {
-
-  //  Check to see if the cubic is actually a quadratic
-  if (a3 == ZERO) {
-    rootsQuadratic(a0, a1, a2, tol, nroots, root1, root2);
-    root3 = INFINITE_NUMBER;
-    return;
-  }
-
-  //  Deflate the polnomial if the trailing coefficient is zero
-  if (a0 == ZERO) {
-    root1 = ZERO;
-    rootsQuadratic(a1, a2, a3, tol, nroots, root2, root3);
-    nroots = nroots + 1;
-    return;
-  }
-
-  //  1. Use Nonweiler's method (CACM 11:4, 1968, pp269)
-
-  double c0 = a0 / a3;
-  double c1 = a1 / a3;
-  double c2 = a2 / a3;
-
-  double s = c2 / THREE;
-  double t = s * c2;
-  double b = 0.5 * (s * (TWO_THIRDS * t - c1) + c0);
-  t = (t - c1) / THREE;
-  double c = t * t * t;
-  double d = b * b - c;
-
-  // 1 real + 2 equal real or 2 complex roots
-  if (d >= ZERO) {
-    d = pow(sqrt(d) + fabs(b), ONE_THIRD);
-    if (d != ZERO) {
-      if (b > ZERO) {
-        b = -d;
-      } else {
-        b = d;
-      }
-      c = t / b;
-    }
-    d = sqrt(THREE_QUARTERS) * (b - c);
-    b = b + c;
-    c = -0.5 * b - s;
-    root1 = b - s;
-    if (d == ZERO) {
-      nroots = 3;
-      root2 = c;
-      root3 = c;
-    } else {
-      nroots = 1;
-    }
-  } else { // 3 real roots
-    if (b == ZERO) {
-      d = TWO_THIRDS * atan(ONE);
-    } else {
-      d = atan(sqrt(-d) / fabs(b)) / THREE;
-    }
-    if (b < ZERO) {
-      b = TWO * sqrt(t);
-    } else {
-      b = -TWO * sqrt(t);
-    }
-    c = cos(d) * b;
-    t = -sqrt(THREE_QUARTERS) * sin(d) * b - HALF * c;
-    d = -t - c - s;
-    c = c - s;
-    t = t - s;
-    if (fabs(c) > fabs(t)) {
-      root3 = c;
-    } else {
-      root3 = t;
-      t = c;
-    }
-    if (fabs(d) > fabs(t)) {
-      root2 = d;
-    } else {
-      root2 = t;
-      t = d;
-    }
-    root1 = t;
-    nroots = 3;
-  }
-
-  //  reorder the roots
-
-  if (nroots == 3) {
-    if (root1 > root2) {
-      double a = root2;
-      root2 = root1;
-      root1 = a;
-    }
-    if (root2 > root3) {
-      double a = root3;
-      if (root1 > root3) {
-        a = root1;
-        root1 = root3;
-      }
-      root3 = root2;
-      root2 = a;
-    }
-  }
-
-  //  perfom a Newton iteration to ensure that the roots are accurate
-  double p = ((a3 * root1 + a2) * root1 + a1) * root1 + a0;
-  double pprime = (THREE * a3 * root1 + TWO * a2) * root1 + a1;
-  if (pprime != ZERO) {
-    root1 = root1 - p / pprime;
-    // p = ((a3 * root1 + a2) * root1 + a1) * root1 + a0; // never used
-  }
-
-  if (nroots == 3) {
-    p = ((a3 * root2 + a2) * root2 + a1) * root2 + a0;
-    pprime = (THREE * a3 * root2 + TWO * a2) * root2 + a1;
-    if (pprime != ZERO) {
-      root2 = root2 - p / pprime;
-      // p = ((a3 * root2 + a2) * root2 + a1) * root2 + a0; // never used
-    }
-
-    p = ((a3 * root3 + a2) * root3 + a1) * root3 + a0;
-    pprime = (THREE * a3 * root3 + TWO * a2) * root3 + a1;
-    if (pprime != ZERO) {
-      root3 = root3 - p / pprime;
-      // p = ((a3 * root3 + a2) * root3 + a1) * root3 + a0; // never used
-    }
-  }
-}
-
-/**  Compute pi_beta = ||x||^beta and its derivatives
- *   Extracted wholesale from module RAL_NLLS_RQS
- *
- *  @param max_order :: Maximum order of derivative.
- *  @param beta :: Power.
- *  @param x_norm2 :: (0) value of ||x||^2,
- *                    (i) ith derivative of ||x||^2, i = 1, max_order
- *  @param pi_beta :: (0) value of ||x||^beta,
- *                    (i) ith derivative of ||x||^beta, i = 1, max_order
- */
-void dtrsPiDerivs(int max_order, double beta,
-                  const DoubleFortranVector &x_norm2,
-                  DoubleFortranVector &pi_beta) {
-  double hbeta = HALF * beta;
-  pi_beta(0) = pow(x_norm2(0), hbeta);
-  pi_beta(1) = hbeta * (pow(x_norm2(0), (hbeta - ONE))) * x_norm2(1);
-  if (max_order == 1)
-    return;
-  pi_beta(2) = hbeta * (pow(x_norm2(0), (hbeta - TWO))) *
-               ((hbeta - ONE) * pow(x_norm2(1), 2) + x_norm2(0) * x_norm2(2));
-  if (max_order == 2)
-    return;
-  pi_beta(3) = hbeta * (pow(x_norm2(0), (hbeta - THREE))) *
-               (x_norm2(3) * pow(x_norm2(0), 2) +
-                (hbeta - ONE) * (THREE * x_norm2(0) * x_norm2(1) * x_norm2(2) +
-                                 (hbeta - TWO) * pow(x_norm2(1), 3)));
-}
-
-/**  Set initial values for the TRS control parameters
- *
- *  @param control :: A structure containing control information.
- */
-void dtrsInitialize(dtrs_control_type &control) {
-  control.stop_normal = pow(EPSILON_MCH, 0.75);
-  control.stop_absolute_normal = pow(EPSILON_MCH, 0.75);
-}
-
-/**  Solve the trust-region subproblem
- *
- *       minimize     1/2 <x, H x> + <c, x> + f
- *       subject to    ||x||_2 <= radius  or ||x||_2 = radius
- *
- *   where H is diagonal, using a secular iteration
- *
- *  @param n :: The number of unknowns.
- *  @param radius :: The trust-region radius.
- *  @param f :: The value of constant term for the quadratic function
- *  @param c :: A vector of values for the linear term c.
- *  @param h :: A vector of values for the diagonal matrix H.
- *  @param x :: The required solution vector x.
- *  @param control :: A structure containing control information.
- *  @param inform :: A structure containing information.
- */
-void dtrsSolveMain(int n, double radius, double f, const DoubleFortranVector &c,
-                   const DoubleFortranVector &h, DoubleFortranVector &x,
-                   const dtrs_control_type &control, dtrs_inform_type &inform) {
-
-  //  set initial values
-
-  if (x.len() != n) {
-    x.allocate(n);
-  }
-  x.zero();
-  inform.x_norm = ZERO;
-  inform.obj = f;
-  inform.hard_case = false;
-  double delta_lambda = ZERO;
-
-  //  Check that arguments are OK
-  if (n < 0) {
-    throw std::runtime_error(
-        "Number of unknowns for trust-region subproblem is negative.");
-  }
-  if (radius < 0) {
-    throw std::runtime_error(
-        "Trust-region radius for trust-region subproblem is negative");
-  }
-
-  DoubleFortranVector x_norm2(0, MAX_DEGREE), pi_beta(0, MAX_DEGREE);
-
-  //  compute the two-norm of c and the extreme eigenvalues of H
-
-  double c_norm = twoNorm(c);
-  double lambda_min = 0.0;
-  double lambda_max = 0.0;
-  std::tie(lambda_min, lambda_max) = minMaxValues(h);
-
-  double lambda = 0.0;
-  //!  check for the trivial case
-  if (c_norm == ZERO && lambda_min >= ZERO) {
-    if (control.equality_problem) {
-      int i_hard = 1;                // TODO: is init value of 1 correct?
-      for (int i = 1; i <= n; ++i) { // do i = 1, n
-        if (h(i) == lambda_min) {
-          i_hard = i;
-          break;
-        }
-      }
-      x(i_hard) = ONE / radius;
-      inform.x_norm = radius;
-      inform.obj = f + lambda_min * radius * radius;
-    }
-    return;
-  }
-
-  //  construct values lambda_l and lambda_u for which lambda_l <=
-  //  lambda_optimal
-  //   <= lambda_u, and ensure that all iterates satisfy lambda_l <= lambda
-  //   <= lambda_u
-
-  double c_norm_over_radius = c_norm / radius;
-  double lambda_l = 0.0, lambda_u = 0.0;
-  if (control.equality_problem) {
-    lambda_l =
-        biggest(control.lower, -lambda_min, c_norm_over_radius - lambda_max);
-    lambda_u = std::min(control.upper, c_norm_over_radius - lambda_min);
-  } else {
-    lambda_l = biggest(control.lower, ZERO, -lambda_min,
-                       c_norm_over_radius - lambda_max);
-    lambda_u = std::min(control.upper,
-                        std::max(ZERO, c_norm_over_radius - lambda_min));
-  }
-  lambda = lambda_l;
-
-  //  check for the "hard case"
-  if (lambda == -lambda_min) {
-    int i_hard = 1; // TODO: is init value of 1 correct?
-    double c2 = ZERO;
-    inform.hard_case = true;
-    for (int i = 1; i <= n; ++i) { // for_do(i, 1, n)
-      if (h(i) == lambda_min) {
-        if (fabs(c(i)) > EPSILON_MCH * c_norm) {
-          inform.hard_case = false;
-          c2 = c2 + pow(c(i), 2);
-        } else {
-          i_hard = i;
-        }
-      }
-    }
-
-    //  the hard case may occur
-    if (inform.hard_case) {
-      for (int i = 1; i <= n; ++i) { // for_do(i, 1, n)
-        if (h(i) != lambda_min) {
-          x(i) = -c(i) / (h(i) + lambda);
-        } else {
-          x(i) = ZERO;
-        }
-      }
-      inform.x_norm = twoNorm(x);
-
-      //  the hard case does occur
-
-      if (inform.x_norm <= radius) {
-        if (inform.x_norm < radius) {
-
-          //  compute the step alpha so that x + alpha e_i_hard lies on the
-          //  trust-region
-          //  boundary and gives the smaller value of q
-
-          auto utx = x(i_hard) / radius;
-          auto distx =
-              (radius - inform.x_norm) * ((radius + inform.x_norm) / radius);
-          auto alpha = sign(
-              distx / (fabs(utx) + sqrt(pow(utx, 2) + distx / radius)), utx);
-
-          //  record the optimal values
-
-          x(i_hard) = x(i_hard) + alpha;
-        }
-        inform.x_norm = twoNorm(x);
-        inform.obj = f + HALF * (dotProduct(c, x) - lambda * pow(radius, 2));
-        return;
-
-        //  the hard case didn't occur after all
-      } else {
-        inform.hard_case = false;
-
-        //  compute the first derivative of ||x|(lambda)||^2 - radius^2
-        auto w_norm2 = ZERO;
-        for (int i = 1; i <= n; ++i) { // for_do(i, 1, n)
-          if (h(i) != lambda_min)
-            w_norm2 = w_norm2 + pow(c(i), 2) / pow((h(i) + lambda), 3);
-        }
-        x_norm2(1) = -TWO * w_norm2;
-
-        //  compute the newton correction
-
-        lambda = lambda + (pow(inform.x_norm, 2) - pow(radius, 2)) / x_norm2(1);
-        lambda_l = std::max(lambda_l, lambda);
-      }
-
-      //  there is a singularity at lambda. compute the point for which the
-      //  sum of squares of the singular terms is equal to radius^2
-    } else {
-      lambda = lambda + std::max(sqrt(c2) / radius, lambda * EPSILON_MCH);
-      lambda_l = std::max(lambda_l, lambda);
-    }
-  }
-
-  //  the iterates will all be in the L region. Prepare for the main loop
-  auto max_order = std::max(1, std::min(MAX_DEGREE, control.taylor_max_degree));
-
-  //  start the main loop
-  for (;;) {
-
-    //  if h(lambda) is positive definite, solve  h(lambda) x = - c
-
-    for (int i = 1; i <= n; ++i) { // for_do(i, 1, n)
-      x(i) = -c(i) / (h(i) + lambda);
-    }
-
-    //  compute the two-norm of x
-    inform.x_norm = twoNorm(x);
-    x_norm2(0) = pow(inform.x_norm, 2);
-
-    //  if the newton step lies within the trust region, exit
-
-    if (lambda == ZERO && inform.x_norm <= radius) {
-      inform.obj = f + HALF * dotProduct(c, x);
-      return;
-    }
-
-    //!  the current estimate gives a good approximation to the required
-    //!  root
-
-    if (fabs(inform.x_norm - radius) <=
-        std::max(control.stop_normal * radius, control.stop_absolute_normal)) {
-      break;
-    }
-
-    lambda_l = std::max(lambda_l, lambda);
-
-    //  record, for the future, values of lambda which give small ||x||
-    if (inform.len_history < HISTORY_MAX) {
-      dtrs_history_type history_item;
-      history_item.lambda = lambda;
-      history_item.x_norm = inform.x_norm;
-      inform.history.push_back(history_item);
-      inform.len_history = inform.len_history + 1;
-    }
-
-    //  a lambda in L has been found. It is now simply a matter of applying
-    //  a variety of Taylor-series-based methods starting from this lambda
-
-    //  precaution against rounding producing lambda outside L
-
-    if (lambda > lambda_u) {
-      throw std::runtime_error(
-          "Lambda for trust-region subproblem is ill conditioned");
-    }
-
-    //  compute first derivatives of x^T M x
-
-    //  form ||w||^2 = x^T H^-1(lambda) x
-
-    double w_norm2 = ZERO;
-    for (int i = 1; i <= n; ++i) { // for_do(i, 1, n)
-      w_norm2 = w_norm2 + pow(c(i), 2) / pow(h(i) + lambda, 3);
-    }
-
-    //  compute the first derivative of x_norm2 = x^T M x
-    x_norm2(1) = -TWO * w_norm2;
-
-    //  compute pi_beta = ||x||^beta and its first derivative when beta = - 1
-    double beta = -ONE;
-    dtrsPiDerivs(1, beta, x_norm2, pi_beta);
-
-    //  compute the Newton correction (for beta = - 1)
-
-    delta_lambda = -(pi_beta(0) - pow((radius), beta)) / pi_beta(1);
-
-    DoubleFortranVector lambda_new(3);
-    int n_lambda = 1;
-    lambda_new(n_lambda) = lambda + delta_lambda;
-
-    if (max_order >= 3) {
-
-      //  compute the second derivative of x^T x
-
-      double z_norm2 = ZERO;
-      for (int i = 1; i <= n; ++i) { // for_do(i, 1, n)
-        z_norm2 = z_norm2 + pow(c(i), 2) / pow((h(i) + lambda), 4);
-      }
-      x_norm2(2) = SIX * z_norm2;
-
-      //  compute the third derivatives of x^T x
-
-      double v_norm2 = ZERO;
-      for (int i = 1; i <= n; ++i) { // for_do(i, 1, n)
-        v_norm2 = v_norm2 + pow(c(i), 2) / pow((h(i) + lambda), 5);
-      }
-      x_norm2(3) = -TWENTY_FOUR * v_norm2;
-
-      //  compute pi_beta = ||x||^beta and its derivatives when beta = 2
-
-      beta = TWO;
-      dtrsPiDerivs(max_order, beta, x_norm2, pi_beta);
-
-      //  compute the "cubic Taylor approximaton" step (beta = 2)
-
-      auto a_0 = pi_beta(0) - pow((radius), beta);
-      auto a_1 = pi_beta(1);
-      auto a_2 = HALF * pi_beta(2);
-      auto a_3 = SIXTH * pi_beta(3);
-      auto a_max = biggest(fabs(a_0), fabs(a_1), fabs(a_2), fabs(a_3));
-      if (a_max > ZERO) {
-        a_0 = a_0 / a_max;
-        a_1 = a_1 / a_max;
-        a_2 = a_2 / a_max;
-        a_3 = a_3 / a_max;
-      }
-      int nroots = 0;
-      double root1 = 0, root2 = 0, root3 = 0;
-
-      rootsCubic(a_0, a_1, a_2, a_3, ROOTS_TOL, nroots, root1, root2, root3);
-      n_lambda = n_lambda + 1;
-      if (nroots == 3) {
-        lambda_new(n_lambda) = lambda + root3;
-      } else {
-        lambda_new(n_lambda) = lambda + root1;
-      }
-
-      //  compute pi_beta = ||x||^beta and its derivatives when beta = - 0.4
-
-      beta = -POINT4;
-      dtrsPiDerivs(max_order, beta, x_norm2, pi_beta);
-
-      //  compute the "cubic Taylor approximaton" step (beta = - 0.4)
-
-      a_0 = pi_beta(0) - pow((radius), beta);
-      a_1 = pi_beta(1);
-      a_2 = HALF * pi_beta(2);
-      a_3 = SIXTH * pi_beta(3);
-      a_max = biggest(fabs(a_0), fabs(a_1), fabs(a_2), fabs(a_3));
-      if (a_max > ZERO) {
-        a_0 = a_0 / a_max;
-        a_1 = a_1 / a_max;
-        a_2 = a_2 / a_max;
-        a_3 = a_3 / a_max;
-      }
-      rootsCubic(a_0, a_1, a_2, a_3, ROOTS_TOL, nroots, root1, root2, root3);
-      n_lambda = n_lambda + 1;
-      if (nroots == 3) {
-        lambda_new(n_lambda) = lambda + root3;
-      } else {
-        lambda_new(n_lambda) = lambda + root1;
-      }
-    }
-
-    //  compute the best Taylor improvement
-
-    auto lambda_plus = maxVal(lambda_new, n_lambda);
-    delta_lambda = lambda_plus - lambda;
-    lambda = lambda_plus;
-
-    //  improve the lower bound if possible
-
-    lambda_l = std::max(lambda_l, lambda_plus);
-
-    //  check that the best Taylor improvement is significant
-
-    if (fabs(delta_lambda) < EPSILON_MCH * std::max(ONE, fabs(lambda))) {
-      break;
-    }
-
-  } // for(;;)
-}
-
-/**  Solve the trust-region subproblem
- *
- *       minimize     q(x) = 1/2 <x, H x> + <c, x> + f
- *       subject to   ||x||_2 <= radius  or ||x||_2 = radius
- *
- *   where H is diagonal, using a secular iteration
- *
- *  @param n :: The number of unknowns.
- *  @param radius :: The trust-region radius.
- *  @param f :: The value of constant term for the quadratic function.
- *  @param c :: A vector of values for the linear term c.
- *  @param h ::  A vector of values for the diagonal matrix H.
- *  @param x :: The required solution vector x.
- *  @param control :: A structure containing control information.
- *  @param inform :: A structure containing information.
- */
-void dtrsSolve(int n, double radius, double f, const DoubleFortranVector &c,
-               const DoubleFortranVector &h, DoubleFortranVector &x,
-               const dtrs_control_type &control, dtrs_inform_type &inform) {
-  //  scale the problem to solve instead
-  //      minimize    q_s(x_s) = 1/2 <x_s, H_s x_s> + <c_s, x_s> + f_s
-  //      subject to    ||x_s||_2 <= radius_s  or ||x_s||_2 = radius_s
-
-  //  where H_s = H / s_h and c_s = c / s_c for scale factors s_h and s_c
-
-  //  This corresponds to
-  //    radius_s = ( s_h / s_c ) radius,
-  //    f_s = ( s_h / s_c^2 ) f
-  //  and the solution may be recovered as
-  //    x = ( s_c / s_h ) x_s
-  //    lambda = s_h lambda_s
-  //    q(x) = ( s_c^2 / s_ h ) q_s(x_s)
-
-  //  scale H by the largest H and remove relatively tiny H
-
-  DoubleFortranVector h_scale(n);
-  auto scale_h = maxAbsVal(h); // MAXVAL( ABS( H ) )
-  if (scale_h > ZERO) {
-    for (int i = 1; i <= n; ++i) { // do i = 1, n
-      if (fabs(h(i)) >= control.h_min * scale_h) {
-        h_scale(i) = h(i) / scale_h;
-      } else {
-        h_scale(i) = ZERO;
-      }
-    }
-  } else {
-    scale_h = ONE;
-    h_scale.zero();
-  }
-
-  //  scale c by the largest c and remove relatively tiny c
-
-  DoubleFortranVector c_scale(n);
-  auto scale_c = maxAbsVal(c); // maxval( abs( c ) )
-  if (scale_c > ZERO) {
-    for (int i = 1; i <= n; ++i) { // do i = 1, n
-      if (fabs(c(i)) >= control.h_min * scale_c) {
-        c_scale(i) = c(i) / scale_c;
-      } else {
-        c_scale(i) = ZERO;
-      }
-    }
-  } else {
-    scale_c = ONE;
-    c_scale.zero();
-  }
-
-  double radius_scale = (scale_h / scale_c) * radius;
-  double f_scale = (scale_h / pow(scale_c, 2)) * f;
-
-  auto control_scale = control;
-  if (control_scale.lower != LOWER_DEFAULT) {
-    control_scale.lower = control_scale.lower / scale_h;
-  }
-  if (control_scale.upper != UPPER_DEFAULT) {
-    control_scale.upper = control_scale.upper / scale_h;
-  }
-
-  //  solve the scaled problem
-
-  dtrsSolveMain(n, radius_scale, f_scale, c_scale, h_scale, x, control_scale,
-                inform);
-
-  //  unscale the solution, function value, multiplier and related values
-
-  //  x = ( scale_c / scale_h ) * x
-  x *= scale_c / scale_h;
-  inform.obj *= pow(scale_c, 2) / scale_h;
-  inform.multiplier *= scale_h;
-  inform.pole *= scale_h;
-  for (size_t i = 0; i < inform.history.size();
-       ++i) { //      do i = 1, inform.len_history
-    inform.history[i].lambda *= scale_h;
-    inform.history[i].x_norm *= scale_c / scale_h;
-  }
-}
-
-} // namespace
-
-/**   Solve the trust-region subproblem using
- *    the DTRS method from Galahad
- *
- *    This method needs H to be diagonal, so we need to
- *    pre-process
- *
- *    main output  d, the soln to the TR subproblem
- *  @param J :: The Jacobian.
- *  @param f :: The residuals.
- *  @param hf :: The Hessian (sort of).
- *  @param Delta :: The raduis of the trust region.
- *  @param d :: The output vector of corrections to the parameters giving the
- *        solution to the TR subproblem.
- *  @param normd :: The 2-norm of d.
- *  @param options :: The options.
- */
-void DTRSMinimizer::solveDtrs(const DoubleFortranMatrix &J,
-                              const DoubleFortranVector &f,
-                              const DoubleFortranMatrix &hf, double Delta,
-                              DoubleFortranVector &d, double &normd,
-                              const NLLS::nlls_options &options) {
-
-  dtrs_control_type dtrs_options;
-  dtrs_inform_type dtrs_inform;
-
-  //  The code finds
-  //   d = arg min_p   w^T p + 0.5 * p^T D p
-  //        s.t. ||p|| \leq Delta
-  //
-  //  where D is diagonal
-  //
-  //  our probem in naturally in the form
-  //
-  //  d = arg min_p   v^T p + 0.5 * p^T H p
-  //        s.t. ||p|| \leq Delta
-  //
-  //  first, find the matrix H and vector v
-  //  Set A = J^T J
-  NLLS::matmultInner(J, m_A);
-  // add any second order information...
-  // so A = J^T J + HF
-  m_A += hf;
-
-  // now form v = J^T f
-  NLLS::multJt(J, f, m_v);
-
-  // if scaling needed, do it
-  if (options.scale != 0) {
-    applyScaling(J, m_A, m_v, m_scale, options);
-  }
-
-  // Now that we have the unprocessed matrices, we need to get an
-  // eigendecomposition to make A diagonal
-  //
-  NLLS::allEigSymm(m_A, m_ew, m_ev);
-
-  // We can now change variables, setting y = Vp, getting
-  // Vd = arg min_(Vx) v^T p + 0.5 * (Vp)^T D (Vp)
-  //       s.t.  ||x|| \leq Delta
-  // <=>
-  // Vd = arg min_(Vx) V^Tv^T (Vp) + 0.5 * (Vp)^T D (Vp)
-  //       s.t.  ||x|| \leq Delta
-  // <=>
-  // we need to get the transformed vector v
-  NLLS::multJt(m_ev, m_v, m_v_trans);
-
-  // we've now got the vectors we need, pass to dtrsSolve
-  dtrsInitialize(dtrs_options);
-
-  auto n = J.len2();
-  if (m_v_trans.len() != n) {
-    m_v_trans.allocate(n);
-  }
-
-  for (int ii = 1; ii <= n; ++ii) { // for_do(ii, 1,n)
-    if (fabs(m_v_trans(ii)) < EPSILON_MCH) {
-      m_v_trans(ii) = ZERO;
-    }
-    if (fabs(m_ew(ii)) < EPSILON_MCH) {
-      m_ew(ii) = ZERO;
-    }
-  }
-
-  dtrsSolve(n, Delta, ZERO, m_v_trans, m_ew, m_d_trans, dtrs_options,
-            dtrs_inform);
-
-  // and return the un-transformed vector
-  NLLS::multJ(m_ev, m_d_trans, d);
-
-  normd = NLLS::norm2(d); // ! ||d||_D
-
-  if (options.scale != 0) {
-    for (int ii = 1; ii <= n; ++ii) { // for_do(ii, 1, n)
-      d(ii) = d(ii) / m_scale(ii);
-    }
-  }
-
-} // solveDtrs
-
-/** Implements the abstarct method of TrustRegionMinimizer.
- */
-void DTRSMinimizer::calculateStep(const DoubleFortranMatrix &J,
-                                  const DoubleFortranVector &f,
-                                  const DoubleFortranMatrix &hf,
-                                  const DoubleFortranVector &, double Delta,
-                                  DoubleFortranVector &d, double &normd,
-                                  const NLLS::nlls_options &options) {
-  solveDtrs(J, f, hf, Delta, d, normd, options);
-}
-
-} // namespace FuncMinimisers
-} // namespace CurveFitting
-} // namespace Mantid
diff --git a/Framework/CurveFitting/src/FuncMinimizers/MoreSorensenMinimizer.cpp b/Framework/CurveFitting/src/FuncMinimizers/MoreSorensenMinimizer.cpp
deleted file mode 100644
index 8f74fef1df4fe243710fa92746e98c6f6d632ef1..0000000000000000000000000000000000000000
--- a/Framework/CurveFitting/src/FuncMinimizers/MoreSorensenMinimizer.cpp
+++ /dev/null
@@ -1,320 +0,0 @@
-// This code was originally translated from Fortran code on
-// https://ccpforge.cse.rl.ac.uk/gf/project/ral_nlls June 2016
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
-#include "MantidCurveFitting/FuncMinimizers/MoreSorensenMinimizer.h"
-#include "MantidAPI/FuncMinimizerFactory.h"
-#include "MantidCurveFitting/RalNlls/TrustRegion.h"
-#include <cmath>
-
-namespace Mantid {
-namespace CurveFitting {
-namespace FuncMinimisers {
-
-// clang-format off
-///@cond nodoc
-DECLARE_FUNCMINIMIZER(MoreSorensenMinimizer,More-Sorensen)
-///@endcond
-// clang-format on
-
-MoreSorensenMinimizer::MoreSorensenMinimizer() : TrustRegionMinimizer() {}
-
-/// Name of the minimizer.
-std::string MoreSorensenMinimizer::name() const { return "More-Sorensen"; }
-
-namespace {
-
-/** Solve a system of linear equations. The system's matrix must be
- *  positive-definite.
- *  @param A :: A matrix of a system of equations.
- *     Must be positive-definite for success.
- *  @param b :: A vector of the right-hand side.
- *  @param LtL :: A work matrix.
- *  @param x :: A vector that receives the solution.
- *  @return true if successful
- */
-bool solveSpd(const DoubleFortranMatrix &A, const DoubleFortranVector &b,
-              DoubleFortranMatrix &LtL, DoubleFortranVector &x) {
-  // Fortran code uses this:
-  // dposv('L', n, 1, LtL, n, x, n, inform.external_return)
-  // This is the GSL replacement:
-  LtL = A;
-  auto res = gsl_linalg_cholesky_decomp(LtL.gsl());
-  if (res == GSL_EDOM) {
-    // Matrix is not positive definite, return for retry.
-    return false;
-  }
-  gsl_linalg_cholesky_solve(LtL.gsl(), b.gsl(), x.gsl());
-  return true;
-}
-
-/** Calculate the leftmost eigenvalue of a matrix.
- *  @param A :: A matrix to analyse.
- *  @param sigma :: A variable to receive the value of the smallest
- *        eigenvalue.
- *  @param y :: A vector that receives the corresponding eigenvector.
- */
-void minEigSymm(const DoubleFortranMatrix &A, double &sigma,
-                DoubleFortranVector &y) {
-  auto M = A;
-  DoubleFortranVector ew;
-  DoubleFortranMatrix ev;
-  M.eigenSystem(ew, ev);
-  auto ind = ew.sortIndices();
-  int imin = static_cast<int>(ind[0]) + 1;
-  sigma = ew(imin);
-  int n = static_cast<int>(A.size1());
-  y.allocate(n);
-  for (int i = 1; i <= n; ++i) {
-    y(i) = ev(i, imin);
-  }
-}
-
-/** Calculate AplusSigma = A + sigma * I
- *  @param sigma :: The value of the diagonal shift.
- *  @param AplusSigma :: The resulting matrix.
- */
-void shiftMatrix(const DoubleFortranMatrix &A, double sigma,
-                 DoubleFortranMatrix &AplusSigma) {
-  AplusSigma = A;
-  auto n = A.len1();
-  for (int i = 1; i <= n; ++i) { // for_do(i,1,n)
-    AplusSigma(i, i) = AplusSigma(i, i) + sigma;
-  }
-}
-
-/** Negate a vector
- *  @param v :: A vector.
- */
-DoubleFortranVector negative(const DoubleFortranVector &v) {
-  DoubleFortranVector neg = v;
-  neg *= -1.0;
-  return neg;
-}
-
-/**  A subroutine to find the optimal beta such that
- *    || d || = Delta, where d = a + beta * b
- *
- *    uses the approach from equation (3.20b),
- *     "Methods for non-linear least squares problems" (2nd edition, 2004)
- *     by Madsen, Nielsen and Tingleff
- *  @param a :: The first vector.
- *  @param b :: The second vector.
- *  @param Delta :: The Delta.
- *  @param beta :: The beta.
- *  @return true if successful
- */
-bool findBeta(const DoubleFortranVector &a, const DoubleFortranVector &b,
-              double Delta, double &beta) {
-
-  auto c = a.dot(b);
-
-  auto norma2 = pow(NLLS::norm2(a), 2);
-  auto normb2 = pow(NLLS::norm2(b), 2);
-
-  double discrim = pow(c, 2) + (normb2) * (pow(Delta, 2) - norma2);
-  if (discrim < NLLS::ZERO) {
-    return false;
-  }
-
-  if (c <= 0) {
-    beta = (-c + sqrt(discrim)) / normb2;
-  } else {
-    beta = (pow(Delta, 2) - norma2) / (c + sqrt(discrim));
-  }
-  return true;
-}
-
-} // namespace
-
-/** Given an indefinite matrix m_A, find a shift sigma
-*  such that (A + sigma I) is positive definite.
-*  @param sigma :: The result (shift).
-*  @param d :: A solution vector to the system of linear equations
-*     with the found positive defimnite matrix. The RHS vector is -m_v.
-*  @param options :: The options.
-*  @return true if successful
-*/
-bool MoreSorensenMinimizer::getPdShift(double &sigma, DoubleFortranVector &d,
-                                       const NLLS::nlls_options &options) {
-  int no_shifts = 0;
-  bool successful_shift = false;
-  while (!successful_shift) {
-    shiftMatrix(m_A, sigma, m_AplusSigma);
-    successful_shift = solveSpd(m_AplusSigma, negative(m_v), m_LtL, d);
-    if (!successful_shift) {
-      // We try again with a shifted sigma, but no too many times.
-      no_shifts = no_shifts + 1;
-      if (no_shifts == 10) {
-        return false;
-      }
-      sigma = sigma + (pow(10.0, no_shifts)) * options.more_sorensen_shift;
-    }
-  }
-  return true;
-}
-
-/** Solve the trust-region subproblem using
- *  the method of More and Sorensen
- *
- *  Using the implementation as in Algorithm 7.3.6
- *  of Trust Region Methods
- *
- *  main output  d, the soln to the TR subproblem
- *  @param J :: The Jacobian.
- *  @param f :: The residuals.
- *  @param hf :: The Hessian (sort of).
- *  @param Delta :: The raduis of the trust region.
- *  @param d :: The output vector of corrections to the parameters giving the
- *        solution to the TR subproblem.
- *  @param nd :: The 2-norm of d.
- *  @param options :: The options.
- */
-void MoreSorensenMinimizer::solveSubproblem(const DoubleFortranMatrix &J,
-                                            const DoubleFortranVector &f,
-                                            const DoubleFortranMatrix &hf,
-                                            double Delta,
-                                            DoubleFortranVector &d, double &nd,
-                                            const NLLS::nlls_options &options) {
-
-  // The code finds
-  //  d = arg min_p   v^T p + 0.5 * p^T A p
-  //       s.t. ||p|| \leq Delta
-  //
-  // set A and v for the model being considered here...
-
-  // Set A = J^T J
-  NLLS::matmultInner(J, m_A);
-  // add any second order information...
-  // so A = J^T J + HF
-  m_A += hf;
-  // now form v = J^T f
-  NLLS::multJt(J, f, m_v);
-
-  // if scaling needed, do it
-  if (options.scale != 0) {
-    applyScaling(J, m_A, m_v, m_scale, options);
-  }
-
-  auto n = J.len2();
-  auto scaleBack = [n, &d, &options, this]() {
-    if (options.scale != 0) {
-      for (int i = 1; i <= n; ++i) {
-        d(i) = d(i) / m_scale(i);
-      }
-    }
-  };
-
-  auto local_ms_shift = options.more_sorensen_shift;
-  // d = -A\v
-  DoubleFortranVector negv = m_v;
-  negv *= -1.0;
-  bool matrix_ok = solveSpd(m_A, negv, m_LtL, d);
-  double sigma = 0.0;
-  if (matrix_ok) {
-    // A is symmetric positive definite....
-    sigma = NLLS::ZERO;
-  } else {
-    // shift and try again
-    minEigSymm(m_A, sigma, m_y1);
-    sigma = -(sigma - local_ms_shift);
-    // find a shift that makes (A + sigma I) positive definite
-    bool ok = getPdShift(sigma, d, options);
-    if (!ok) {
-      scaleBack();
-      return;
-    }
-  }
-
-  nd = NLLS::norm2(d);
-  if (!std::isfinite(nd)) {
-    throw std::runtime_error("Step is NaN or infinite.");
-  }
-
-  // now, we're not in the trust region initally, so iterate....
-  auto sigma_shift = NLLS::ZERO;
-  int no_restarts = 0;
-  // set 'small' in the context of the algorithm
-  double epsilon =
-      std::max(options.more_sorensen_tol * Delta, options.more_sorensen_tiny);
-  int it = 1;
-  for (; it <= options.more_sorensen_maxits; ++it) {
-
-    if (nd <= Delta + epsilon) {
-      // we're within the tr radius
-      if (fabs(sigma) < options.more_sorensen_tiny ||
-          fabs(nd - Delta) < epsilon) {
-        // we're good....exit
-        break;
-      }
-      if (m_y1.len() == n) {
-        double alpha = 0.0;
-        if (findBeta(d, m_y1, Delta, alpha)) {
-          DoubleFortranVector tmp = m_y1;
-          tmp *= alpha;
-          d += tmp;
-        }
-      }
-      // also good....exit
-      break;
-    }
-
-    // m_q = R'\d
-    // DTRSM( "Left", "Lower", "No Transpose", "Non-unit", n, 1, one, m_LtL, n,
-    // m_q, n );
-    for (int j = 1; j <= m_LtL.len1(); ++j) {
-      for (int k = j + 1; k <= m_LtL.len1(); ++k) {
-        m_LtL(j, k) = 0.0;
-      }
-    }
-    m_LtL.solve(d, m_q);
-
-    auto nq = NLLS::norm2(m_q);
-    sigma_shift = (pow((nd / nq), 2)) * ((nd - Delta) / Delta);
-    if (fabs(sigma_shift) < options.more_sorensen_tiny * fabs(sigma)) {
-      if (no_restarts < 1) {
-        // find a shift that makes (A + sigma I) positive definite
-        bool ok = getPdShift(sigma, d, options);
-        if (!ok) {
-          break;
-        }
-        no_restarts = no_restarts + 1;
-      } else {
-        // we're not going to make progress...jump out
-        throw std::runtime_error("Not making progress.");
-      }
-    } else {
-      sigma = sigma + sigma_shift;
-    }
-
-    shiftMatrix(m_A, sigma, m_AplusSigma);
-    DoubleFortranVector negv = m_v;
-    negv *= -1.0;
-    bool matrix_ok = solveSpd(m_AplusSigma, negv, m_LtL, d);
-    if (!matrix_ok) {
-      break;
-    }
-
-    nd = NLLS::norm2(d);
-  }
-
-  if (it == options.more_sorensen_maxits) {
-    // maxits reached, not converged
-    throw std::runtime_error("No convergence in maximum number of iterations.");
-  }
-  scaleBack();
-}
-
-/** Implements the abstract method of TrustRegionMinimizer.
- */
-void MoreSorensenMinimizer::calculateStep(
-    const DoubleFortranMatrix &J, const DoubleFortranVector &f,
-    const DoubleFortranMatrix &hf, const DoubleFortranVector &, double Delta,
-    DoubleFortranVector &d, double &normd, const NLLS::nlls_options &options) {
-  solveSubproblem(J, f, hf, Delta, d, normd, options);
-}
-
-} // namespace FuncMinimisers
-} // namespace CurveFitting
-} // namespace Mantid
diff --git a/Framework/CurveFitting/src/FuncMinimizers/TrustRegionMinimizer.cpp b/Framework/CurveFitting/src/FuncMinimizers/TrustRegionMinimizer.cpp
index 4cde25729569d2e769c9369f1fc427a4777460c3..2b4c732e7120eec05e4b92c7c63ccbf038b4e4d0 100644
--- a/Framework/CurveFitting/src/FuncMinimizers/TrustRegionMinimizer.cpp
+++ b/Framework/CurveFitting/src/FuncMinimizers/TrustRegionMinimizer.cpp
@@ -5,6 +5,7 @@
 //----------------------------------------------------------------------
 #include "MantidCurveFitting/FuncMinimizers/TrustRegionMinimizer.h"
 #include "MantidCurveFitting/RalNlls/TrustRegion.h"
+#include "MantidAPI/FuncMinimizerFactory.h"
 
 #include <cmath>
 
@@ -12,11 +13,21 @@ namespace Mantid {
 namespace CurveFitting {
 namespace FuncMinimisers {
 
+// clang-format off
+///@cond nodoc
+DECLARE_FUNCMINIMIZER(TrustRegionMinimizer, Trust Region)
+///@endcond
+// clang-format on
+
 TrustRegionMinimizer::TrustRegionMinimizer() : m_function() {
   declareProperty("InitialRadius", 100.0,
                   "Initial radius of the trust region.");
 }
 
+/** Name of the minimizer.
+*/
+std::string TrustRegionMinimizer::name() const { return "Trust Region"; }
+
 /** Initialise the minimizer.
  *  @param costFunction :: The cost function to minimize. Must be the least
  *  squares.
@@ -241,7 +252,7 @@ bool TrustRegionMinimizer::iterate(size_t) {
       return true;
     }
     // Calculate the step d that the model thinks we should take next
-    calculateStep(w.J, w.f, w.hf, w.g, w.Delta, w.d, w.normd, options);
+    calculateStep(w.J, w.f, w.hf, w.Delta, w.d, w.normd, options);
 
     // Accept the step?
     w.Xnew = X;
@@ -405,6 +416,973 @@ bool TrustRegionMinimizer::iterate(size_t) {
   return true;
 }
 
+/** DTRS method **/
+namespace {
+
+const double HUGEST = std::numeric_limits<double>::max();
+const double EPSILON_MCH = std::numeric_limits<double>::epsilon();
+const double LARGEST = HUGEST;
+const double LOWER_DEFAULT = -0.5 * LARGEST;
+const double UPPER_DEFAULT = LARGEST;
+const double POINT4 = 0.4;
+const double ZERO = 0.0;
+const double ONE = 1.0;
+const double TWO = 2.0;
+const double THREE = 3.0;
+const double FOUR = 4.0;
+const double SIX = 6.0;
+const double HALF = 0.5;
+const double ONESIXTH = ONE / SIX;
+const double SIXTH = ONESIXTH;
+const double ONE_THIRD = ONE / THREE;
+const double TWO_THIRDS = TWO / THREE;
+const double THREE_QUARTERS = 0.75;
+const double TWENTY_FOUR = 24.0;
+const int MAX_DEGREE = 3;
+const int HISTORY_MAX = 100;
+const double TEN_EPSILON_MCH = 10.0 * EPSILON_MCH;
+const double ROOTS_TOL = TEN_EPSILON_MCH;
+const double INFINITE_NUMBER = HUGEST;
+
+/** Replacement for FORTRAN's SIGN intrinsic function
+*/
+inline double sign(double x, double y) { return y >= 0.0 ? fabs(x) : -fabs(x); }
+
+//!  - - - - - - - - - - - - - - - - - - - - - - -
+//!   control derived type with component defaults
+//!  - - - - - - - - - - - - - - - - - - - - - - -
+struct control_type {
+  //!  maximum degree of Taylor approximant allowed
+  int taylor_max_degree = 3;
+
+  //!  any entry of H that is smaller than h_min * MAXVAL( H ) we be treated as
+  // zero
+  double h_min = EPSILON_MCH;
+
+  //!  lower and upper bounds on the multiplier, if known
+  double lower = LOWER_DEFAULT;
+  double upper = UPPER_DEFAULT;
+
+  //!  stop when | ||x|| - radius | <=
+  //!     max( stop_normal * radius, stop_absolute_normal )
+  double stop_normal = EPSILON_MCH;
+  double stop_absolute_normal = EPSILON_MCH;
+
+  //!  is the solution is REQUIRED to lie on the boundary (i.e., is the
+  // constraint
+  //!  an equality)?
+  bool equality_problem = false;
+};
+
+//!  - - - - - - - - - - - - - - - - - - - - - - - -
+//!   history derived type with component defaults
+//!  - - - - - - - - - - - - - - - - - - - - - - - -
+struct history_type {
+  //
+  //!  value of lambda
+  double lambda = 0.0;
+
+  //!  corresponding value of ||x(lambda)||_M
+  double x_norm = 0.0;
+};
+
+//!  - - - - - - - - - - - - - - - - - - - - - - -
+//!   inform derived type with component defaults
+//!  - - - - - - - - - - - - - - - - - - - - - - -
+struct inform_type {
+  //
+
+  //!  the number of (||x||_M,lambda) pairs in the history
+  int len_history = 0;
+
+  //!  the value of the quadratic function
+  double obj = HUGEST;
+
+  //!  the M-norm of x, ||x||_M
+  double x_norm = 0.0;
+
+  //!  the Lagrange multiplier corresponding to the trust-region constraint
+  double multiplier = 0.0;
+
+  //!  a lower bound max(0,-lambda_1), where lambda_1 is the left-most
+  //!  eigenvalue of (H,M)
+  double pole = 0.0;
+
+  //!  has the hard case occurred?
+  bool hard_case = false;
+
+  //!  history information
+  std::vector<history_type> history;
+};
+
+/** Get the largest of the four values.
+*  @param a :: Value number 1.
+*  @param b :: Value number 2.
+*  @param c :: Value number 3.
+*  @param d :: Value number 4.
+*/
+double biggest(double a, double b, double c, double d) {
+  return std::max(std::max(a, b), std::max(c, d));
+}
+
+/** Get the largest of the three values.
+*  @param a :: Value number 1.
+*  @param b :: Value number 2.
+*  @param c :: Value number 3.
+*/
+double biggest(double a, double b, double c) {
+  return std::max(std::max(a, b), c);
+}
+
+/** Find the largest by absolute value element of a vector.
+*  @param v :: The searched vector.
+*/
+double maxAbsVal(const DoubleFortranVector &v) {
+  auto p = v.indicesOfMinMaxElements();
+  return std::max(fabs(v.get(p.first)), fabs(v.get(p.second)));
+}
+
+/** Find the minimum and maximum elements of a vector.
+*  @param v :: The searched vector.
+*  @returns :: A pair of doubles where the first is the minimum and
+*      the second is the maxumum.
+*/
+std::pair<double, double> minMaxValues(const DoubleFortranVector &v) {
+  auto p = v.indicesOfMinMaxElements();
+  return std::make_pair(v.get(p.first), v.get(p.second));
+}
+
+/** Compute the 2-norm of a vector which is a square root of the
+*  sum of squares of its elements.
+*  @param v :: The vector.
+*/
+double twoNorm(const DoubleFortranVector &v) {
+  if (v.size() == 0)
+    return 0.0;
+  return gsl_blas_dnrm2(v.gsl());
+}
+
+/** Get the dot-product of two vectors of the same size.
+*  @param v1 :: The first vector.
+*  @param v2 :: The second vector.
+*/
+double dotProduct(const DoubleFortranVector &v1,
+                  const DoubleFortranVector &v2) {
+  return v1.dot(v2);
+}
+
+/** Find the maximum element in the first n elements of a vector.
+*  @param v :: The vector.
+*  @param n :: The number of elements to examine.
+*/
+double maxVal(const DoubleFortranVector &v, int n) {
+  double res = std::numeric_limits<double>::lowest();
+  for (int i = 1; i <= n; ++i) {
+    auto val = v(i);
+    if (val > res) {
+      res = val;
+    }
+  }
+  return res;
+}
+
+/**  Find the number and values of real roots of the quadratic equation
+*
+*                    a2 * x**2 + a1 * x + a0 = 0
+*
+*   where a0, a1 and a2 are real
+*  @param a0 :: The free coefficient.
+*  @param a1 :: The coefficient at the linear term.
+*  @param a2 :: The coefficient at the quadratic term.
+*  @param tol :: A tolerance for comparing doubles.
+*  @param nroots :: The output number of real roots.
+*  @param root1 :: The first real root if nroots > 0.
+*  @param root2 :: The second real root if nroots = 2.
+*/
+void rootsQuadratic(double a0, double a1, double a2, double tol, int &nroots,
+                    double &root1, double &root2) {
+
+  auto rhs = tol * a1 * a1;
+  if (fabs(a0 * a2) > rhs) { // really is quadratic
+    root2 = a1 * a1 - FOUR * a2 * a0;
+    if (fabs(root2) <= pow(EPSILON_MCH * a1, 2)) { // numerical double root
+      nroots = 2;
+      root1 = -HALF * a1 / a2;
+      root2 = root1;
+    } else if (root2 < ZERO) { // complex not real roots
+      nroots = 0;
+      root1 = ZERO;
+      root2 = ZERO;
+    } else { // distint real roots
+      auto d = -HALF * (a1 + sign(sqrt(root2), a1));
+      nroots = 2;
+      root1 = d / a2;
+      root2 = a0 / d;
+      if (root1 > root2) {
+        d = root1;
+        root1 = root2;
+        root2 = d;
+      }
+    }
+  } else if (a2 == ZERO) {
+    if (a1 == ZERO) {
+      if (a0 == ZERO) { // the function is zero
+        nroots = 1;
+        root1 = ZERO;
+        root2 = ZERO;
+      } else { // the function is constant
+        nroots = 0;
+        root1 = ZERO;
+        root2 = ZERO;
+      }
+    } else { // the function is linear
+      nroots = 1;
+      root1 = -a0 / a1;
+      root2 = ZERO;
+    }
+  } else { // very ill-conditioned quadratic
+    nroots = 2;
+    if (-a1 / a2 > ZERO) {
+      root1 = ZERO;
+      root2 = -a1 / a2;
+    } else {
+      root1 = -a1 / a2;
+      root2 = ZERO;
+    }
+  }
+
+  //  perfom a Newton iteration to ensure that the roots are accurate
+
+  if (nroots >= 1) {
+    auto p = (a2 * root1 + a1) * root1 + a0;
+    auto pprime = TWO * a2 * root1 + a1;
+    if (pprime != ZERO) {
+      root1 = root1 - p / pprime;
+    }
+    if (nroots == 2) {
+      p = (a2 * root2 + a1) * root2 + a0;
+      pprime = TWO * a2 * root2 + a1;
+      if (pprime != ZERO) {
+        root2 = root2 - p / pprime;
+      }
+    }
+  }
+}
+
+/**  Find the number and values of real roots of the cubic equation
+*
+*                 a3 * x**3 + a2 * x**2 + a1 * x + a0 = 0
+*
+*   where a0, a1, a2 and a3 are real
+*  @param a0 :: The free coefficient.
+*  @param a1 :: The coefficient at the linear term.
+*  @param a2 :: The coefficient at the quadratic term.
+*  @param a3 :: The coefficient at the cubic term.
+*  @param tol :: A tolerance for comparing doubles.
+*  @param nroots :: The output number of real roots.
+*  @param root1 :: The first real root.
+*  @param root2 :: The second real root if nroots > 1.
+*  @param root3 :: The third real root if nroots == 3.
+*/
+void rootsCubic(double a0, double a1, double a2, double a3, double tol,
+                int &nroots, double &root1, double &root2, double &root3) {
+
+  //  Check to see if the cubic is actually a quadratic
+  if (a3 == ZERO) {
+    rootsQuadratic(a0, a1, a2, tol, nroots, root1, root2);
+    root3 = INFINITE_NUMBER;
+    return;
+  }
+
+  //  Deflate the polnomial if the trailing coefficient is zero
+  if (a0 == ZERO) {
+    root1 = ZERO;
+    rootsQuadratic(a1, a2, a3, tol, nroots, root2, root3);
+    nroots = nroots + 1;
+    return;
+  }
+
+  //  1. Use Nonweiler's method (CACM 11:4, 1968, pp269)
+
+  double c0 = a0 / a3;
+  double c1 = a1 / a3;
+  double c2 = a2 / a3;
+
+  double s = c2 / THREE;
+  double t = s * c2;
+  double b = 0.5 * (s * (TWO_THIRDS * t - c1) + c0);
+  t = (t - c1) / THREE;
+  double c = t * t * t;
+  double d = b * b - c;
+
+  // 1 real + 2 equal real or 2 complex roots
+  if (d >= ZERO) {
+    d = pow(sqrt(d) + fabs(b), ONE_THIRD);
+    if (d != ZERO) {
+      if (b > ZERO) {
+        b = -d;
+      } else {
+        b = d;
+      }
+      c = t / b;
+    }
+    d = sqrt(THREE_QUARTERS) * (b - c);
+    b = b + c;
+    c = -0.5 * b - s;
+    root1 = b - s;
+    if (d == ZERO) {
+      nroots = 3;
+      root2 = c;
+      root3 = c;
+    } else {
+      nroots = 1;
+    }
+  } else { // 3 real roots
+    if (b == ZERO) {
+      d = TWO_THIRDS * atan(ONE);
+    } else {
+      d = atan(sqrt(-d) / fabs(b)) / THREE;
+    }
+    if (b < ZERO) {
+      b = TWO * sqrt(t);
+    } else {
+      b = -TWO * sqrt(t);
+    }
+    c = cos(d) * b;
+    t = -sqrt(THREE_QUARTERS) * sin(d) * b - HALF * c;
+    d = -t - c - s;
+    c = c - s;
+    t = t - s;
+    if (fabs(c) > fabs(t)) {
+      root3 = c;
+    } else {
+      root3 = t;
+      t = c;
+    }
+    if (fabs(d) > fabs(t)) {
+      root2 = d;
+    } else {
+      root2 = t;
+      t = d;
+    }
+    root1 = t;
+    nroots = 3;
+  }
+
+  //  reorder the roots
+
+  if (nroots == 3) {
+    if (root1 > root2) {
+      double a = root2;
+      root2 = root1;
+      root1 = a;
+    }
+    if (root2 > root3) {
+      double a = root3;
+      if (root1 > root3) {
+        a = root1;
+        root1 = root3;
+      }
+      root3 = root2;
+      root2 = a;
+    }
+  }
+
+  //  perfom a Newton iteration to ensure that the roots are accurate
+  double p = ((a3 * root1 + a2) * root1 + a1) * root1 + a0;
+  double pprime = (THREE * a3 * root1 + TWO * a2) * root1 + a1;
+  if (pprime != ZERO) {
+    root1 = root1 - p / pprime;
+    // p = ((a3 * root1 + a2) * root1 + a1) * root1 + a0; // never used
+  }
+
+  if (nroots == 3) {
+    p = ((a3 * root2 + a2) * root2 + a1) * root2 + a0;
+    pprime = (THREE * a3 * root2 + TWO * a2) * root2 + a1;
+    if (pprime != ZERO) {
+      root2 = root2 - p / pprime;
+      // p = ((a3 * root2 + a2) * root2 + a1) * root2 + a0; // never used
+    }
+
+    p = ((a3 * root3 + a2) * root3 + a1) * root3 + a0;
+    pprime = (THREE * a3 * root3 + TWO * a2) * root3 + a1;
+    if (pprime != ZERO) {
+      root3 = root3 - p / pprime;
+      // p = ((a3 * root3 + a2) * root3 + a1) * root3 + a0; // never used
+    }
+  }
+}
+
+/**  Compute pi_beta = ||x||^beta and its derivatives
+*   Extracted wholesale from module RAL_NLLS_RQS
+*
+*  @param max_order :: Maximum order of derivative.
+*  @param beta :: Power.
+*  @param x_norm2 :: (0) value of ||x||^2,
+*                    (i) ith derivative of ||x||^2, i = 1, max_order
+*  @param pi_beta :: (0) value of ||x||^beta,
+*                    (i) ith derivative of ||x||^beta, i = 1, max_order
+*/
+void PiBetaDerivs(int max_order, double beta,
+                  const DoubleFortranVector &x_norm2,
+                  DoubleFortranVector &pi_beta) {
+  double hbeta = HALF * beta;
+  pi_beta(0) = pow(x_norm2(0), hbeta);
+  pi_beta(1) = hbeta * (pow(x_norm2(0), (hbeta - ONE))) * x_norm2(1);
+  if (max_order == 1)
+    return;
+  pi_beta(2) = hbeta * (pow(x_norm2(0), (hbeta - TWO))) *
+               ((hbeta - ONE) * pow(x_norm2(1), 2) + x_norm2(0) * x_norm2(2));
+  if (max_order == 2)
+    return;
+  pi_beta(3) = hbeta * (pow(x_norm2(0), (hbeta - THREE))) *
+               (x_norm2(3) * pow(x_norm2(0), 2) +
+                (hbeta - ONE) * (THREE * x_norm2(0) * x_norm2(1) * x_norm2(2) +
+                                 (hbeta - TWO) * pow(x_norm2(1), 3)));
+}
+
+/**  Set initial values for the TRS control parameters
+*
+*  @param control :: A structure containing control information.
+*/
+void intitializeControl(control_type &control) {
+  control.stop_normal = pow(EPSILON_MCH, 0.75);
+  control.stop_absolute_normal = pow(EPSILON_MCH, 0.75);
+}
+
+/**  Solve the trust-region subproblem
+*
+*       minimize     1/2 <x, H x> + <c, x> + f
+*       subject to    ||x||_2 <= radius  or ||x||_2 = radius
+*
+*   where H is diagonal, using a secular iteration
+*
+*  @param n :: The number of unknowns.
+*  @param radius :: The trust-region radius.
+*  @param f :: The value of constant term for the quadratic function
+*  @param c :: A vector of values for the linear term c.
+*  @param h :: A vector of values for the diagonal matrix H.
+*  @param x :: The required solution vector x.
+*  @param control :: A structure containing control information.
+*  @param inform :: A structure containing information.
+*/
+void solveSubproblemMain(int n, double radius, double f,
+                         const DoubleFortranVector &c,
+                         const DoubleFortranVector &h, DoubleFortranVector &x,
+                         const control_type &control, inform_type &inform) {
+
+  //  set initial values
+
+  if (x.len() != n) {
+    x.allocate(n);
+  }
+  x.zero();
+  inform.x_norm = ZERO;
+  inform.obj = f;
+  inform.hard_case = false;
+  double delta_lambda = ZERO;
+
+  //  Check that arguments are OK
+  if (n < 0) {
+    throw std::runtime_error(
+        "Number of unknowns for trust-region subproblem is negative.");
+  }
+  if (radius < 0) {
+    throw std::runtime_error(
+        "Trust-region radius for trust-region subproblem is negative");
+  }
+
+  DoubleFortranVector x_norm2(0, MAX_DEGREE), pi_beta(0, MAX_DEGREE);
+
+  //  compute the two-norm of c and the extreme eigenvalues of H
+
+  double c_norm = twoNorm(c);
+  double lambda_min = 0.0;
+  double lambda_max = 0.0;
+  std::tie(lambda_min, lambda_max) = minMaxValues(h);
+
+  double lambda = 0.0;
+  //!  check for the trivial case
+  if (c_norm == ZERO && lambda_min >= ZERO) {
+    if (control.equality_problem) {
+      int i_hard = 1;                // TODO: is init value of 1 correct?
+      for (int i = 1; i <= n; ++i) { // do i = 1, n
+        if (h(i) == lambda_min) {
+          i_hard = i;
+          break;
+        }
+      }
+      x(i_hard) = ONE / radius;
+      inform.x_norm = radius;
+      inform.obj = f + lambda_min * radius * radius;
+    }
+    return;
+  }
+
+  //  construct values lambda_l and lambda_u for which lambda_l <=
+  //  lambda_optimal
+  //   <= lambda_u, and ensure that all iterates satisfy lambda_l <= lambda
+  //   <= lambda_u
+
+  double c_norm_over_radius = c_norm / radius;
+  double lambda_l = 0.0, lambda_u = 0.0;
+  if (control.equality_problem) {
+    lambda_l =
+        biggest(control.lower, -lambda_min, c_norm_over_radius - lambda_max);
+    lambda_u = std::min(control.upper, c_norm_over_radius - lambda_min);
+  } else {
+    lambda_l = biggest(control.lower, ZERO, -lambda_min,
+                       c_norm_over_radius - lambda_max);
+    lambda_u = std::min(control.upper,
+                        std::max(ZERO, c_norm_over_radius - lambda_min));
+  }
+  lambda = lambda_l;
+
+  //  check for the "hard case"
+  if (lambda == -lambda_min) {
+    int i_hard = 1; // TODO: is init value of 1 correct?
+    double c2 = ZERO;
+    inform.hard_case = true;
+    for (int i = 1; i <= n; ++i) { // for_do(i, 1, n)
+      if (h(i) == lambda_min) {
+        if (fabs(c(i)) > EPSILON_MCH * c_norm) {
+          inform.hard_case = false;
+          c2 = c2 + pow(c(i), 2);
+        } else {
+          i_hard = i;
+        }
+      }
+    }
+
+    //  the hard case may occur
+    if (inform.hard_case) {
+      for (int i = 1; i <= n; ++i) { // for_do(i, 1, n)
+        if (h(i) != lambda_min) {
+          x(i) = -c(i) / (h(i) + lambda);
+        } else {
+          x(i) = ZERO;
+        }
+      }
+      inform.x_norm = twoNorm(x);
+
+      //  the hard case does occur
+
+      if (inform.x_norm <= radius) {
+        if (inform.x_norm < radius) {
+
+          //  compute the step alpha so that x + alpha e_i_hard lies on the
+          //  trust-region
+          //  boundary and gives the smaller value of q
+
+          auto utx = x(i_hard) / radius;
+          auto distx =
+              (radius - inform.x_norm) * ((radius + inform.x_norm) / radius);
+          auto alpha = sign(
+              distx / (fabs(utx) + sqrt(pow(utx, 2) + distx / radius)), utx);
+
+          //  record the optimal values
+
+          x(i_hard) = x(i_hard) + alpha;
+        }
+        inform.x_norm = twoNorm(x);
+        inform.obj = f + HALF * (dotProduct(c, x) - lambda * pow(radius, 2));
+        return;
+
+        //  the hard case didn't occur after all
+      } else {
+        inform.hard_case = false;
+
+        //  compute the first derivative of ||x|(lambda)||^2 - radius^2
+        auto w_norm2 = ZERO;
+        for (int i = 1; i <= n; ++i) { // for_do(i, 1, n)
+          if (h(i) != lambda_min)
+            w_norm2 = w_norm2 + pow(c(i), 2) / pow((h(i) + lambda), 3);
+        }
+        x_norm2(1) = -TWO * w_norm2;
+
+        //  compute the newton correction
+
+        lambda = lambda + (pow(inform.x_norm, 2) - pow(radius, 2)) / x_norm2(1);
+        lambda_l = std::max(lambda_l, lambda);
+      }
+
+      //  there is a singularity at lambda. compute the point for which the
+      //  sum of squares of the singular terms is equal to radius^2
+    } else {
+      lambda = lambda + std::max(sqrt(c2) / radius, lambda * EPSILON_MCH);
+      lambda_l = std::max(lambda_l, lambda);
+    }
+  }
+
+  //  the iterates will all be in the L region. Prepare for the main loop
+  auto max_order = std::max(1, std::min(MAX_DEGREE, control.taylor_max_degree));
+
+  //  start the main loop
+  for (;;) {
+
+    //  if h(lambda) is positive definite, solve  h(lambda) x = - c
+
+    for (int i = 1; i <= n; ++i) { // for_do(i, 1, n)
+      x(i) = -c(i) / (h(i) + lambda);
+    }
+
+    //  compute the two-norm of x
+    inform.x_norm = twoNorm(x);
+    x_norm2(0) = pow(inform.x_norm, 2);
+
+    //  if the newton step lies within the trust region, exit
+
+    if (lambda == ZERO && inform.x_norm <= radius) {
+      inform.obj = f + HALF * dotProduct(c, x);
+      return;
+    }
+
+    //!  the current estimate gives a good approximation to the required
+    //!  root
+
+    if (fabs(inform.x_norm - radius) <=
+        std::max(control.stop_normal * radius, control.stop_absolute_normal)) {
+      break;
+    }
+
+    lambda_l = std::max(lambda_l, lambda);
+
+    //  record, for the future, values of lambda which give small ||x||
+    if (inform.len_history < HISTORY_MAX) {
+      history_type history_item;
+      history_item.lambda = lambda;
+      history_item.x_norm = inform.x_norm;
+      inform.history.push_back(history_item);
+      inform.len_history = inform.len_history + 1;
+    }
+
+    //  a lambda in L has been found. It is now simply a matter of applying
+    //  a variety of Taylor-series-based methods starting from this lambda
+
+    //  precaution against rounding producing lambda outside L
+
+    if (lambda > lambda_u) {
+      throw std::runtime_error(
+          "Lambda for trust-region subproblem is ill conditioned");
+    }
+
+    //  compute first derivatives of x^T M x
+
+    //  form ||w||^2 = x^T H^-1(lambda) x
+
+    double w_norm2 = ZERO;
+    for (int i = 1; i <= n; ++i) { // for_do(i, 1, n)
+      w_norm2 = w_norm2 + pow(c(i), 2) / pow(h(i) + lambda, 3);
+    }
+
+    //  compute the first derivative of x_norm2 = x^T M x
+    x_norm2(1) = -TWO * w_norm2;
+
+    //  compute pi_beta = ||x||^beta and its first derivative when beta = - 1
+    double beta = -ONE;
+    PiBetaDerivs(1, beta, x_norm2, pi_beta);
+
+    //  compute the Newton correction (for beta = - 1)
+
+    delta_lambda = -(pi_beta(0) - pow((radius), beta)) / pi_beta(1);
+
+    DoubleFortranVector lambda_new(3);
+    int n_lambda = 1;
+    lambda_new(n_lambda) = lambda + delta_lambda;
+
+    if (max_order >= 3) {
+
+      //  compute the second derivative of x^T x
+
+      double z_norm2 = ZERO;
+      for (int i = 1; i <= n; ++i) { // for_do(i, 1, n)
+        z_norm2 = z_norm2 + pow(c(i), 2) / pow((h(i) + lambda), 4);
+      }
+      x_norm2(2) = SIX * z_norm2;
+
+      //  compute the third derivatives of x^T x
+
+      double v_norm2 = ZERO;
+      for (int i = 1; i <= n; ++i) { // for_do(i, 1, n)
+        v_norm2 = v_norm2 + pow(c(i), 2) / pow((h(i) + lambda), 5);
+      }
+      x_norm2(3) = -TWENTY_FOUR * v_norm2;
+
+      //  compute pi_beta = ||x||^beta and its derivatives when beta = 2
+
+      beta = TWO;
+      PiBetaDerivs(max_order, beta, x_norm2, pi_beta);
+
+      //  compute the "cubic Taylor approximaton" step (beta = 2)
+
+      auto a_0 = pi_beta(0) - pow((radius), beta);
+      auto a_1 = pi_beta(1);
+      auto a_2 = HALF * pi_beta(2);
+      auto a_3 = SIXTH * pi_beta(3);
+      auto a_max = biggest(fabs(a_0), fabs(a_1), fabs(a_2), fabs(a_3));
+      if (a_max > ZERO) {
+        a_0 = a_0 / a_max;
+        a_1 = a_1 / a_max;
+        a_2 = a_2 / a_max;
+        a_3 = a_3 / a_max;
+      }
+      int nroots = 0;
+      double root1 = 0, root2 = 0, root3 = 0;
+
+      rootsCubic(a_0, a_1, a_2, a_3, ROOTS_TOL, nroots, root1, root2, root3);
+      n_lambda = n_lambda + 1;
+      if (nroots == 3) {
+        lambda_new(n_lambda) = lambda + root3;
+      } else {
+        lambda_new(n_lambda) = lambda + root1;
+      }
+
+      //  compute pi_beta = ||x||^beta and its derivatives when beta = - 0.4
+
+      beta = -POINT4;
+      PiBetaDerivs(max_order, beta, x_norm2, pi_beta);
+
+      //  compute the "cubic Taylor approximaton" step (beta = - 0.4)
+
+      a_0 = pi_beta(0) - pow((radius), beta);
+      a_1 = pi_beta(1);
+      a_2 = HALF * pi_beta(2);
+      a_3 = SIXTH * pi_beta(3);
+      a_max = biggest(fabs(a_0), fabs(a_1), fabs(a_2), fabs(a_3));
+      if (a_max > ZERO) {
+        a_0 = a_0 / a_max;
+        a_1 = a_1 / a_max;
+        a_2 = a_2 / a_max;
+        a_3 = a_3 / a_max;
+      }
+      rootsCubic(a_0, a_1, a_2, a_3, ROOTS_TOL, nroots, root1, root2, root3);
+      n_lambda = n_lambda + 1;
+      if (nroots == 3) {
+        lambda_new(n_lambda) = lambda + root3;
+      } else {
+        lambda_new(n_lambda) = lambda + root1;
+      }
+    }
+
+    //  compute the best Taylor improvement
+
+    auto lambda_plus = maxVal(lambda_new, n_lambda);
+    delta_lambda = lambda_plus - lambda;
+    lambda = lambda_plus;
+
+    //  improve the lower bound if possible
+
+    lambda_l = std::max(lambda_l, lambda_plus);
+
+    //  check that the best Taylor improvement is significant
+
+    if (fabs(delta_lambda) < EPSILON_MCH * std::max(ONE, fabs(lambda))) {
+      break;
+    }
+
+  } // for(;;)
+}
+
+/**  Solve the trust-region subproblem
+*
+*       minimize     q(x) = 1/2 <x, H x> + <c, x> + f
+*       subject to   ||x||_2 <= radius  or ||x||_2 = radius
+*
+*   where H is diagonal, using a secular iteration
+*
+*  @param n :: The number of unknowns.
+*  @param radius :: The trust-region radius.
+*  @param f :: The value of constant term for the quadratic function.
+*  @param c :: A vector of values for the linear term c.
+*  @param h ::  A vector of values for the diagonal matrix H.
+*  @param x :: The required solution vector x.
+*  @param control :: A structure containing control information.
+*  @param inform :: A structure containing information.
+*/
+void solveSubproblem(int n, double radius, double f,
+                     const DoubleFortranVector &c, const DoubleFortranVector &h,
+                     DoubleFortranVector &x, const control_type &control,
+                     inform_type &inform) {
+  //  scale the problem to solve instead
+  //      minimize    q_s(x_s) = 1/2 <x_s, H_s x_s> + <c_s, x_s> + f_s
+  //      subject to    ||x_s||_2 <= radius_s  or ||x_s||_2 = radius_s
+
+  //  where H_s = H / s_h and c_s = c / s_c for scale factors s_h and s_c
+
+  //  This corresponds to
+  //    radius_s = ( s_h / s_c ) radius,
+  //    f_s = ( s_h / s_c^2 ) f
+  //  and the solution may be recovered as
+  //    x = ( s_c / s_h ) x_s
+  //    lambda = s_h lambda_s
+  //    q(x) = ( s_c^2 / s_ h ) q_s(x_s)
+
+  //  scale H by the largest H and remove relatively tiny H
+
+  DoubleFortranVector h_scale(n);
+  auto scale_h = maxAbsVal(h); // MAXVAL( ABS( H ) )
+  if (scale_h > ZERO) {
+    for (int i = 1; i <= n; ++i) { // do i = 1, n
+      if (fabs(h(i)) >= control.h_min * scale_h) {
+        h_scale(i) = h(i) / scale_h;
+      } else {
+        h_scale(i) = ZERO;
+      }
+    }
+  } else {
+    scale_h = ONE;
+    h_scale.zero();
+  }
+
+  //  scale c by the largest c and remove relatively tiny c
+
+  DoubleFortranVector c_scale(n);
+  auto scale_c = maxAbsVal(c); // maxval( abs( c ) )
+  if (scale_c > ZERO) {
+    for (int i = 1; i <= n; ++i) { // do i = 1, n
+      if (fabs(c(i)) >= control.h_min * scale_c) {
+        c_scale(i) = c(i) / scale_c;
+      } else {
+        c_scale(i) = ZERO;
+      }
+    }
+  } else {
+    scale_c = ONE;
+    c_scale.zero();
+  }
+
+  double radius_scale = (scale_h / scale_c) * radius;
+  double f_scale = (scale_h / pow(scale_c, 2)) * f;
+
+  auto control_scale = control;
+  if (control_scale.lower != LOWER_DEFAULT) {
+    control_scale.lower = control_scale.lower / scale_h;
+  }
+  if (control_scale.upper != UPPER_DEFAULT) {
+    control_scale.upper = control_scale.upper / scale_h;
+  }
+
+  //  solve the scaled problem
+
+  solveSubproblemMain(n, radius_scale, f_scale, c_scale, h_scale, x,
+                      control_scale, inform);
+
+  //  unscale the solution, function value, multiplier and related values
+
+  //  x = ( scale_c / scale_h ) * x
+  x *= scale_c / scale_h;
+  inform.obj *= pow(scale_c, 2) / scale_h;
+  inform.multiplier *= scale_h;
+  inform.pole *= scale_h;
+  for (size_t i = 0; i < inform.history.size();
+       ++i) { //      do i = 1, inform.len_history
+    inform.history[i].lambda *= scale_h;
+    inform.history[i].x_norm *= scale_c / scale_h;
+  }
+}
+
+} // namespace
+
+/**   Solve the trust-region subproblem using
+*    the DTRS method from Galahad
+*
+*    This method needs H to be diagonal, so we need to
+*    pre-process
+*
+*    main output  d, the soln to the TR subproblem
+*  @param J :: The Jacobian.
+*  @param f :: The residuals.
+*  @param hf :: The Hessian (sort of).
+*  @param Delta :: The raduis of the trust region.
+*  @param d :: The output vector of corrections to the parameters giving the
+*        solution to the TR subproblem.
+*  @param normd :: The 2-norm of d.
+*  @param options :: The options.
+*/
+void TrustRegionMinimizer::calculateStep(const DoubleFortranMatrix &J,
+                                         const DoubleFortranVector &f,
+                                         const DoubleFortranMatrix &hf,
+                                         double Delta, DoubleFortranVector &d,
+                                         double &normd,
+                                         const NLLS::nlls_options &options) {
+
+  control_type controlOptions;
+  inform_type inform;
+
+  //  The code finds
+  //   d = arg min_p   w^T p + 0.5 * p^T D p
+  //        s.t. ||p|| \leq Delta
+  //
+  //  where D is diagonal
+  //
+  //  our probem in naturally in the form
+  //
+  //  d = arg min_p   v^T p + 0.5 * p^T H p
+  //        s.t. ||p|| \leq Delta
+  //
+  //  first, find the matrix H and vector v
+  //  Set A = J^T J
+  NLLS::matmultInner(J, m_A);
+  // add any second order information...
+  // so A = J^T J + HF
+  m_A += hf;
+
+  // now form v = J^T f
+  NLLS::multJt(J, f, m_v);
+
+  // if scaling needed, do it
+  if (options.scale != 0) {
+    applyScaling(J, m_A, m_v, m_scale, options);
+  }
+
+  // Now that we have the unprocessed matrices, we need to get an
+  // eigendecomposition to make A diagonal
+  //
+  NLLS::allEigSymm(m_A, m_ew, m_ev);
+
+  // We can now change variables, setting y = Vp, getting
+  // Vd = arg min_(Vx) v^T p + 0.5 * (Vp)^T D (Vp)
+  //       s.t.  ||x|| \leq Delta
+  // <=>
+  // Vd = arg min_(Vx) V^Tv^T (Vp) + 0.5 * (Vp)^T D (Vp)
+  //       s.t.  ||x|| \leq Delta
+  // <=>
+  // we need to get the transformed vector v
+  NLLS::multJt(m_ev, m_v, m_v_trans);
+
+  // we've now got the vectors we need, pass to solveSubproblem
+  intitializeControl(controlOptions);
+
+  auto n = J.len2();
+  if (m_v_trans.len() != n) {
+    m_v_trans.allocate(n);
+  }
+
+  for (int ii = 1; ii <= n; ++ii) { // for_do(ii, 1,n)
+    if (fabs(m_v_trans(ii)) < EPSILON_MCH) {
+      m_v_trans(ii) = ZERO;
+    }
+    if (fabs(m_ew(ii)) < EPSILON_MCH) {
+      m_ew(ii) = ZERO;
+    }
+  }
+
+  solveSubproblem(n, Delta, ZERO, m_v_trans, m_ew, m_d_trans, controlOptions,
+                  inform);
+
+  // and return the un-transformed vector
+  NLLS::multJ(m_ev, m_d_trans, d);
+
+  normd = NLLS::norm2(d); // ! ||d||_D
+
+  if (options.scale != 0) {
+    for (int ii = 1; ii <= n; ++ii) { // for_do(ii, 1, n)
+      d(ii) = d(ii) / m_scale(ii);
+    }
+  }
+
+} // calculateStep
+
 /** Return the current value of the cost function.
  */
 double TrustRegionMinimizer::costFunctionVal() { return m_leastSquares->val(); }
diff --git a/Framework/CurveFitting/test/FuncMinimizers/MoreSorensenTest.h b/Framework/CurveFitting/test/FuncMinimizers/MoreSorensenTest.h
deleted file mode 100644
index 5d4265a6da5b158951c5137a3083972abe210cc5..0000000000000000000000000000000000000000
--- a/Framework/CurveFitting/test/FuncMinimizers/MoreSorensenTest.h
+++ /dev/null
@@ -1,329 +0,0 @@
-#ifndef CURVEFITTING_MORESORNSENTTEST_H_
-#define CURVEFITTING_MORESORNSENTTEST_H_
-
-#include <cxxtest/TestSuite.h>
-
-#include "MantidCurveFitting/CostFunctions/CostFuncLeastSquares.h"
-#include "MantidCurveFitting/FuncMinimizers/MoreSorensenMinimizer.h"
-#include "MantidCurveFitting/Functions/UserFunction.h"
-#include "MantidAPI/FunctionDomain1D.h"
-#include "MantidAPI/FunctionValues.h"
-#include "MantidCurveFitting/Constraints/BoundaryConstraint.h"
-
-#include <sstream>
-
-using namespace Mantid;
-using namespace Mantid::CurveFitting;
-using namespace Mantid::CurveFitting::FuncMinimisers;
-using namespace Mantid::CurveFitting::CostFunctions;
-using namespace Mantid::CurveFitting::Constraints;
-using namespace Mantid::CurveFitting::Functions;
-using namespace Mantid::API;
-
-class MoreSorensenTest : public CxxTest::TestSuite {
-public:
-  // This pair of boilerplate methods prevent the suite being created statically
-  // This means the constructor isn't called when running other tests
-  static MoreSorensenTest *createSuite() { return new MoreSorensenTest(); }
-  static void destroySuite(MoreSorensenTest *suite) { delete suite; }
-
-  void test_Linear() {
-    API::FunctionDomain1D_sptr domain(
-        new API::FunctionDomain1DVector(0.0, 10.0, 20));
-    API::FunctionValues mockData(*domain);
-    UserFunction dataMaker;
-    dataMaker.setAttributeValue("Formula", "a*x+b");
-    dataMaker.setParameter("a", 1.1);
-    dataMaker.setParameter("b", 2.2);
-    dataMaker.function(*domain, mockData);
-
-    API::FunctionValues_sptr values(new API::FunctionValues(*domain));
-    values->setFitDataFromCalculated(mockData);
-    values->setFitWeights(1.0);
-
-    boost::shared_ptr<UserFunction> fun = boost::make_shared<UserFunction>();
-    fun->setAttributeValue("Formula", "a*x+b");
-    fun->setParameter("a", 1.);
-    fun->setParameter("b", 2.);
-
-    boost::shared_ptr<CostFuncLeastSquares> costFun =
-        boost::make_shared<CostFuncLeastSquares>();
-    costFun->setFittingFunction(fun, domain, values);
-    TS_ASSERT_EQUALS(costFun->nParams(), 2);
-
-    MoreSorensenMinimizer s;
-    s.initialize(costFun);
-    TS_ASSERT(s.minimize());
-
-    TS_ASSERT_DELTA(fun->getParameter("a"), 1.1, 0.01);
-    TS_ASSERT_DELTA(fun->getParameter("b"), 2.2, 0.01);
-    TS_ASSERT_EQUALS(s.getError(), "success");
-  }
-
-  void test_Gaussian() {
-    API::FunctionDomain1D_sptr domain(
-        new API::FunctionDomain1DVector(0.0, 10.0, 20));
-    API::FunctionValues mockData(*domain);
-    UserFunction dataMaker;
-    dataMaker.setAttributeValue("Formula", "a*x+b+h*exp(-s*x^2)");
-    dataMaker.setParameter("a", 1.1);
-    dataMaker.setParameter("b", 2.2);
-    dataMaker.setParameter("h", 3.3);
-    dataMaker.setParameter("s", 0.2);
-    dataMaker.function(*domain, mockData);
-
-    API::FunctionValues_sptr values(new API::FunctionValues(*domain));
-    values->setFitDataFromCalculated(mockData);
-    values->setFitWeights(1.0);
-
-    boost::shared_ptr<UserFunction> fun = boost::make_shared<UserFunction>();
-    fun->setAttributeValue("Formula", "a*x+b+h*exp(-s*x^2)");
-    fun->setParameter("a", 1.);
-    fun->setParameter("b", 2.);
-    fun->setParameter("h", 3.);
-    fun->setParameter("s", 0.1);
-
-    boost::shared_ptr<CostFuncLeastSquares> costFun =
-        boost::make_shared<CostFuncLeastSquares>();
-    costFun->setFittingFunction(fun, domain, values);
-
-    MoreSorensenMinimizer s;
-    s.initialize(costFun);
-    TS_ASSERT(s.minimize());
-    TS_ASSERT_DELTA(costFun->val(), 0.0, 0.0001);
-    TS_ASSERT_DELTA(fun->getParameter("a"), 1.1, 0.001);
-    TS_ASSERT_DELTA(fun->getParameter("b"), 2.2, 0.001);
-    TS_ASSERT_DELTA(fun->getParameter("h"), 3.3, 0.001);
-    TS_ASSERT_DELTA(fun->getParameter("s"), 0.2, 0.001);
-    TS_ASSERT_EQUALS(s.getError(), "success");
-  }
-
-  void test_Gaussian_fixed() {
-    API::FunctionDomain1D_sptr domain(
-        new API::FunctionDomain1DVector(0.0, 10.0, 20));
-    API::FunctionValues mockData(*domain);
-    UserFunction dataMaker;
-    dataMaker.setAttributeValue("Formula", "a*x+b+h*exp(-s*x^2)");
-    dataMaker.setParameter("a", 1.1);
-    dataMaker.setParameter("b", 2.2);
-    dataMaker.setParameter("h", 3.3);
-    dataMaker.setParameter("s", 0.2);
-    dataMaker.function(*domain, mockData);
-
-    API::FunctionValues_sptr values(new API::FunctionValues(*domain));
-    values->setFitDataFromCalculated(mockData);
-    values->setFitWeights(1.0);
-
-    boost::shared_ptr<UserFunction> fun = boost::make_shared<UserFunction>();
-    fun->setAttributeValue("Formula", "a*x+b+h*exp(-s*x^2)");
-    fun->setParameter("a", 1.);
-    fun->setParameter("b", 2.5);
-    fun->setParameter("h", 3.);
-    fun->setParameter("s", 0.1);
-    fun->fix(0);
-
-    boost::shared_ptr<CostFuncLeastSquares> costFun =
-        boost::make_shared<CostFuncLeastSquares>();
-    costFun->setFittingFunction(fun, domain, values);
-    TS_ASSERT_EQUALS(costFun->nParams(), 3);
-
-    MoreSorensenMinimizer s;
-    s.initialize(costFun);
-    TS_ASSERT(s.minimize());
-    TS_ASSERT_DELTA(costFun->val(), 0.2, 0.01);
-    TS_ASSERT_DELTA(fun->getParameter("a"), 1., 0.000001);
-    TS_ASSERT_DELTA(fun->getParameter("b"), 2.90, 0.01);
-    TS_ASSERT_DELTA(fun->getParameter("h"), 2.67, 0.01);
-    TS_ASSERT_DELTA(fun->getParameter("s"), 0.27, 0.01);
-    TS_ASSERT_EQUALS(s.getError(), "success");
-  }
-
-  void test_Gaussian_tied() {
-    API::FunctionDomain1D_sptr domain(
-        new API::FunctionDomain1DVector(0.0, 10.0, 20));
-    API::FunctionValues mockData(*domain);
-    UserFunction dataMaker;
-    dataMaker.setAttributeValue("Formula", "a*x+b+h*exp(-s*x^2)");
-    dataMaker.setParameter("a", 1.1);
-    dataMaker.setParameter("b", 2.2);
-    dataMaker.setParameter("h", 3.3);
-    dataMaker.setParameter("s", 0.2);
-    dataMaker.function(*domain, mockData);
-
-    API::FunctionValues_sptr values(new API::FunctionValues(*domain));
-    values->setFitDataFromCalculated(mockData);
-    values->setFitWeights(1.0);
-
-    boost::shared_ptr<UserFunction> fun = boost::make_shared<UserFunction>();
-    fun->setAttributeValue("Formula", "a*x+b+h*exp(-s*x^2)");
-    fun->setParameter("a", 1.);
-    fun->setParameter("b", 2.5);
-    fun->setParameter("h", 3.);
-    fun->setParameter("s", 0.1);
-    fun->tie("a", "1");
-
-    boost::shared_ptr<CostFuncLeastSquares> costFun =
-        boost::make_shared<CostFuncLeastSquares>();
-    costFun->setFittingFunction(fun, domain, values);
-    TS_ASSERT_EQUALS(costFun->nParams(), 3);
-
-    MoreSorensenMinimizer s;
-    s.initialize(costFun);
-    TS_ASSERT(s.minimize());
-    TS_ASSERT_DELTA(costFun->val(), 0.2, 0.01);
-    TS_ASSERT_DELTA(fun->getParameter("a"), 1., 0.000001);
-    TS_ASSERT_DELTA(fun->getParameter("b"), 2.90, 0.01);
-    TS_ASSERT_DELTA(fun->getParameter("h"), 2.67, 0.01);
-    TS_ASSERT_DELTA(fun->getParameter("s"), 0.27, 0.01);
-    TS_ASSERT_EQUALS(s.getError(), "success");
-  }
-
-  void xtest_Gaussian_tied_with_formula() {
-    API::FunctionDomain1D_sptr domain(
-        new API::FunctionDomain1DVector(0.0, 10.0, 20));
-    API::FunctionValues mockData(*domain);
-    UserFunction dataMaker;
-    dataMaker.setAttributeValue("Formula", "a*x+b+h*exp(-s*x^2)");
-    dataMaker.setParameter("a", 1.1);
-    dataMaker.setParameter("b", 2.2);
-    dataMaker.setParameter("h", 3.3);
-    dataMaker.setParameter("s", 0.2);
-    dataMaker.function(*domain, mockData);
-
-    API::FunctionValues_sptr values(new API::FunctionValues(*domain));
-    values->setFitDataFromCalculated(mockData);
-    values->setFitWeights(1.0);
-
-    boost::shared_ptr<UserFunction> fun = boost::make_shared<UserFunction>();
-    fun->setAttributeValue("Formula", "a*x+b+h*exp(-s*x^2)");
-    fun->setParameter("a", 1.);
-    fun->setParameter("b", 2.);
-    fun->setParameter("h", 3.);
-    fun->setParameter("s", 0.1);
-    fun->tie("b", "2*a+0.1");
-
-    boost::shared_ptr<CostFuncLeastSquares> costFun =
-        boost::make_shared<CostFuncLeastSquares>();
-    costFun->setFittingFunction(fun, domain, values);
-    TS_ASSERT_EQUALS(costFun->nParams(), 3);
-
-    MoreSorensenMinimizer s;
-    s.initialize(costFun);
-    TS_ASSERT(s.minimize());
-    TS_ASSERT_DELTA(costFun->val(), 0.002, 0.01);
-
-    double a = fun->getParameter("a");
-    TS_ASSERT_DELTA(a, 1.0895, 0.01);
-    TS_ASSERT_DELTA(fun->getParameter("b"), 2 * a + 0.1, 0.0001);
-    TS_ASSERT_DELTA(fun->getParameter("h"), 3.23, 0.01);
-    TS_ASSERT_DELTA(fun->getParameter("s"), 0.207, 0.001);
-    TS_ASSERT_EQUALS(s.getError(), "success");
-  }
-
-  void xtest_Linear_constrained() {
-    API::FunctionDomain1D_sptr domain(
-        new API::FunctionDomain1DVector(0.0, 10.0, 20));
-    API::FunctionValues mockData(*domain);
-    UserFunction dataMaker;
-    dataMaker.setAttributeValue("Formula", "a*x+b");
-    dataMaker.setParameter("a", 1.1);
-    dataMaker.setParameter("b", 2.2);
-    dataMaker.function(*domain, mockData);
-
-    API::FunctionValues_sptr values(new API::FunctionValues(*domain));
-    values->setFitDataFromCalculated(mockData);
-    values->setFitWeights(1.0);
-
-    boost::shared_ptr<UserFunction> fun = boost::make_shared<UserFunction>();
-    fun->setAttributeValue("Formula", "a*x+b");
-    fun->setParameter("a", 1.);
-    fun->setParameter("b", 2.);
-
-    fun->addConstraint(
-        Kernel::make_unique<BoundaryConstraint>(fun.get(), "a", 0, 0.5));
-
-    boost::shared_ptr<CostFuncLeastSquares> costFun =
-        boost::make_shared<CostFuncLeastSquares>();
-    costFun->setFittingFunction(fun, domain, values);
-    TS_ASSERT_EQUALS(costFun->nParams(), 2);
-
-    MoreSorensenMinimizer s;
-    s.initialize(costFun);
-    TS_ASSERT(s.minimize());
-
-    TS_ASSERT_DELTA(fun->getParameter("a"), 0.5, 0.1);
-    TS_ASSERT_DELTA(fun->getParameter("b"), 5.2, 0.2);
-    TS_ASSERT_EQUALS(s.getError(), "success");
-  }
-
-  void xtest_Linear_constrained1() {
-    API::FunctionDomain1D_sptr domain(
-        new API::FunctionDomain1DVector(0.0, 10.0, 20));
-    API::FunctionValues mockData(*domain);
-    UserFunction dataMaker;
-    dataMaker.setAttributeValue("Formula", "a^2*x+b");
-    dataMaker.setParameter("a", 1);
-    dataMaker.setParameter("b", 2);
-    dataMaker.function(*domain, mockData);
-
-    API::FunctionValues_sptr values(new API::FunctionValues(*domain));
-    values->setFitDataFromCalculated(mockData);
-    values->setFitWeights(1.0);
-
-    boost::shared_ptr<UserFunction> fun = boost::make_shared<UserFunction>();
-    fun->setAttributeValue("Formula", "a^2*x+b");
-    fun->setParameter("a", -0.5);
-    fun->setParameter("b", 2.2);
-
-    // lower bound is made > 0 because function's derivative over "a" at a=0 is
-    // 0
-    fun->addConstraint(
-        Kernel::make_unique<BoundaryConstraint>(fun.get(), "a", 0.001, 2.0));
-
-    boost::shared_ptr<CostFuncLeastSquares> costFun =
-        boost::make_shared<CostFuncLeastSquares>();
-    costFun->setFittingFunction(fun, domain, values);
-    TS_ASSERT_EQUALS(costFun->nParams(), 2);
-
-    MoreSorensenMinimizer s;
-    s.initialize(costFun);
-    TS_ASSERT(s.minimize());
-
-    // std::cerr << "a=" << fun->getParameter("a") << '\n';
-    // std::cerr << "b=" << fun->getParameter("b") << '\n';
-
-    TS_ASSERT_DELTA(costFun->val(), 0.00, 0.0001);
-    TS_ASSERT_DELTA(fun->getParameter("a"), 1.0, 0.01);
-    TS_ASSERT_DELTA(fun->getParameter("b"), 2.0, 0.01);
-    TS_ASSERT_EQUALS(s.getError(), "success");
-  }
-
-  void xtest_cannot_reach_tolerance() {
-    API::FunctionDomain1D_sptr domain(
-        new API::FunctionDomain1DVector(0.0, 1.0, 10));
-    API::FunctionValues mockData(*domain);
-    UserFunction dataMaker;
-    dataMaker.setAttributeValue("Formula", "a*x");
-    dataMaker.setParameter("a", 1.0);
-    dataMaker.function(*domain, mockData);
-
-    API::FunctionValues_sptr values(new API::FunctionValues(*domain));
-    values->setFitDataFromCalculated(mockData);
-    values->setFitWeights(1.0);
-
-    boost::shared_ptr<UserFunction> fun = boost::make_shared<UserFunction>();
-    fun->setAttributeValue("Formula", "a+b+0*x");
-
-    boost::shared_ptr<CostFuncLeastSquares> costFun =
-        boost::make_shared<CostFuncLeastSquares>();
-    costFun->setFittingFunction(fun, domain, values);
-
-    MoreSorensenMinimizer s;
-    s.initialize(costFun);
-    TS_ASSERT(!s.minimize());
-
-    TS_ASSERT_EQUALS(s.getError(), "cannot reach the specified tolerance in F");
-  }
-};
-
-#endif /*CURVEFITTING_MORESORNSENTTEST_H_*/
diff --git a/Framework/CurveFitting/test/FuncMinimizers/DTRSMinimizerTest.h b/Framework/CurveFitting/test/FuncMinimizers/TrustRegionMinimizerTest.h
similarity index 93%
rename from Framework/CurveFitting/test/FuncMinimizers/DTRSMinimizerTest.h
rename to Framework/CurveFitting/test/FuncMinimizers/TrustRegionMinimizerTest.h
index 7712495c097799f9350ff12651c135d3776e6cc3..84dc5edc84b21210b4aeabdff0cc76e45d3f986d 100644
--- a/Framework/CurveFitting/test/FuncMinimizers/DTRSMinimizerTest.h
+++ b/Framework/CurveFitting/test/FuncMinimizers/TrustRegionMinimizerTest.h
@@ -1,10 +1,10 @@
-#ifndef CURVEFITTING_DTRSMINIMIZERTTEST_H_
-#define CURVEFITTING_DTRSMINIMIZERTTEST_H_
+#ifndef CURVEFITTING_TRUSTREGIONMINIMIZERTTEST_H_
+#define CURVEFITTING_TRUSTREGIONMINIMIZERTTEST_H_
 
 #include <cxxtest/TestSuite.h>
 
 #include "MantidCurveFitting/CostFunctions/CostFuncLeastSquares.h"
-#include "MantidCurveFitting/FuncMinimizers/DTRSMinimizer.h"
+#include "MantidCurveFitting/FuncMinimizers/TrustRegionMinimizer.h"
 #include "MantidCurveFitting/Functions/UserFunction.h"
 #include "MantidAPI/FunctionDomain1D.h"
 #include "MantidAPI/FunctionValues.h"
@@ -20,12 +20,14 @@ using namespace Mantid::CurveFitting::Constraints;
 using namespace Mantid::CurveFitting::Functions;
 using namespace Mantid::API;
 
-class DTRSMinimizerTest : public CxxTest::TestSuite {
+class TrustRegionMinimizerTest : public CxxTest::TestSuite {
 public:
   // This pair of boilerplate methods prevent the suite being created statically
   // This means the constructor isn't called when running other tests
-  static DTRSMinimizerTest *createSuite() { return new DTRSMinimizerTest(); }
-  static void destroySuite(DTRSMinimizerTest *suite) { delete suite; }
+  static TrustRegionMinimizerTest *createSuite() {
+    return new TrustRegionMinimizerTest();
+  }
+  static void destroySuite(TrustRegionMinimizerTest *suite) { delete suite; }
 
   void test_Linear() {
     API::FunctionDomain1D_sptr domain(
@@ -51,7 +53,7 @@ public:
     costFun->setFittingFunction(fun, domain, values);
     TS_ASSERT_EQUALS(costFun->nParams(), 2);
 
-    DTRSMinimizer s;
+    TrustRegionMinimizer s;
     s.initialize(costFun);
     TS_ASSERT(s.minimize());
 
@@ -87,7 +89,7 @@ public:
         boost::make_shared<CostFuncLeastSquares>();
     costFun->setFittingFunction(fun, domain, values);
 
-    DTRSMinimizer s;
+    TrustRegionMinimizer s;
     s.initialize(costFun);
     TS_ASSERT(s.minimize());
     TS_ASSERT_DELTA(costFun->val(), 0.0, 0.0001);
@@ -127,7 +129,7 @@ public:
     costFun->setFittingFunction(fun, domain, values);
     TS_ASSERT_EQUALS(costFun->nParams(), 3);
 
-    DTRSMinimizer s;
+    TrustRegionMinimizer s;
     s.initialize(costFun);
     TS_ASSERT(s.minimize()); //
     TS_ASSERT_DELTA(costFun->val(), 0.2, 0.01);
@@ -167,7 +169,7 @@ public:
     costFun->setFittingFunction(fun, domain, values);
     TS_ASSERT_EQUALS(costFun->nParams(), 3);
 
-    DTRSMinimizer s;
+    TrustRegionMinimizer s;
     s.initialize(costFun);
     TS_ASSERT(s.minimize()); //
     TS_ASSERT_DELTA(costFun->val(), 0.2, 0.01);
@@ -205,7 +207,7 @@ public:
     costFun->setFittingFunction(fun, domain, values);
     TS_ASSERT_EQUALS(costFun->nParams(), 2);
 
-    DTRSMinimizer s;
+    TrustRegionMinimizer s;
     s.initialize(costFun);
     TS_ASSERT(s.minimize());
 
@@ -243,7 +245,7 @@ public:
     costFun->setFittingFunction(fun, domain, values);
     TS_ASSERT_EQUALS(costFun->nParams(), 2);
 
-    DTRSMinimizer s;
+    TrustRegionMinimizer s;
     s.initialize(costFun);
     TS_ASSERT(s.minimize());
 
@@ -254,4 +256,4 @@ public:
   }
 };
 
-#endif /*CURVEFITTING_DTRSMINIMIZERTTEST_H_*/
+#endif /*CURVEFITTING_TRUSTREGIONMINIMIZERTTEST_H_*/
diff --git a/Framework/CurveFitting/test/RalNlls/NLLSTest.h b/Framework/CurveFitting/test/RalNlls/NLLSTest.h
index 94337fb13bf1564c746c5be59f78579c007ca852..ae6dc165970b3004d3af2cbe5efd2ea14a01010e 100644
--- a/Framework/CurveFitting/test/RalNlls/NLLSTest.h
+++ b/Framework/CurveFitting/test/RalNlls/NLLSTest.h
@@ -16,19 +16,6 @@ using namespace Mantid::API;
 
 class NLLSTest : public CxxTest::TestSuite {
 public:
-  void test_More_Sorensen_ExpDecay() {
-    auto ws = make_exp_decay_workspace();
-    Fit fit;
-    fit.initialize();
-    fit.setPropertyValue("Function", "name=ExpDecay");
-    fit.setProperty("InputWorkspace", ws);
-    fit.setProperty("Minimizer", "More-Sorensen");
-    fit.execute();
-    IFunction_sptr fun = fit.getProperty("Function");
-    TS_ASSERT_DELTA(fun->getParameter(0), 60.195, 0.001);
-    TS_ASSERT_DELTA(fun->getParameter(1), 2.16815, 0.00001);
-  }
-
   void test_Galahad_ExpDecay() {
     auto ws = make_exp_decay_workspace();
     Fit fit;
diff --git a/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h
index 9d122261e5cbac7c2551c1ab99ab934c88b1c919..2bdbd533ff90e4c116fa85a5fb295ed050095792 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h
@@ -283,11 +283,6 @@ private:
 
   /// Coordinates
   Kernel::SpecialCoordinateSystem m_coordSystem;
-
-  // adapter for logs() function, which create reference to this class itself
-  // and does not allow to delete the shared pointers,
-  // returned by logs() function when they go out of scope
-  API::LogManager_sptr m_logCash;
 };
 
 /// Typedef for a shared pointer to a peaks workspace.
diff --git a/Framework/DataObjects/inc/MantidDataObjects/WorkspaceCreation.h b/Framework/DataObjects/inc/MantidDataObjects/WorkspaceCreation.h
index 572cc2c8032cc9cbc1b8e48234faf1c4fb0d9c5c..7a3d895a65962c561b7996c1fcbf5202b00bcabf 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/WorkspaceCreation.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/WorkspaceCreation.h
@@ -145,10 +145,6 @@ fixDistributionFlag(API::MatrixWorkspace &workspace,
 MANTID_DATAOBJECTS_DLL void
 initializeFromParent(const API::MatrixWorkspace &parent,
                      API::MatrixWorkspace &ws);
-
-MANTID_DATAOBJECTS_DLL void
-initializeFromParentWithoutLogs(const API::MatrixWorkspace &parent,
-                                API::MatrixWorkspace &ws);
 }
 
 /** This is the create() method that all the other create() methods call.
@@ -193,46 +189,6 @@ std::unique_ptr<T> create(const P &parent, const IndexArg &indexArg,
   return ws;
 }
 
-/** create a new workspace with empty run, i.e., without logs
- *  this is for initializeFromParentWithoutLogs
- */
-template <class T, class P, class IndexArg, class HistArg,
-          class = typename std::enable_if<
-              std::is_base_of<API::MatrixWorkspace, P>::value>::type>
-std::unique_ptr<T> createWithoutLogs(const P &parent, const IndexArg &indexArg,
-                                     const HistArg &histArg) {
-  // Figure out (dynamic) target type:
-  // - Type is same as parent if T is base of parent
-  // - If T is not base of parent, conversion may occur. Currently only
-  //   supported for EventWorkspace
-  std::unique_ptr<T> ws;
-  if (std::is_base_of<API::HistoWorkspace, T>::value &&
-      parent.id() == "EventWorkspace") {
-    // Drop events, create Workspace2D or T whichever is more derived.
-    ws = detail::createHelper<T>();
-  } else {
-    try {
-      // If parent is more derived than T: create type(parent)
-      ws = dynamic_cast<const T &>(parent).cloneEmpty();
-    } catch (std::bad_cast &) {
-      // If T is more derived than parent: create T
-      ws = detail::createConcreteHelper<T>();
-    }
-  }
-
-  // The instrument is also copied by initializeFromParentWithoutLogs,
-  // but if indexArg is
-  // IndexInfo and contains non-empty spectrum definitions the initialize call
-  // will fail due to invalid indices in the spectrum definitions. Therefore, we
-  // copy the instrument first. This should be cleaned up once we figure out the
-  // future of WorkspaceFactory.
-  ws->setInstrument(parent.getInstrument());
-  ws->initialize(indexArg, HistogramData::Histogram(histArg));
-  detail::initializeFromParentWithoutLogs(parent, *ws);
-  detail::fixDistributionFlag(*ws, histArg);
-  return ws;
-}
-
 template <class T, class IndexArg, class HistArg,
           typename std::enable_if<
               !std::is_base_of<API::MatrixWorkspace, IndexArg>::value>::type * =
@@ -269,19 +225,6 @@ std::unique_ptr<T> create(const P &parent) {
   return ws;
 }
 
-template <class T, class P,
-          typename std::enable_if<std::is_base_of<API::MatrixWorkspace,
-                                                  P>::value>::type * = nullptr>
-std::unique_ptr<T> createWithoutLogs(const P &parent) {
-  const auto numHistograms = parent.getNumberHistograms();
-  auto ws = createWithoutLogs<T>(parent, numHistograms,
-                                 detail::stripData(parent.histogram(0)));
-  for (size_t i = 0; i < numHistograms; ++i) {
-    ws->setSharedX(i, parent.sharedX(i));
-  }
-  return ws;
-}
-
 // Templating with HistArg clashes with the IndexArg template above. Could be
 // fixed with many enable_if cases, but for now we simply provide 3 variants
 // (Histogram, BinEdges, Points) by hand.
diff --git a/Framework/DataObjects/src/PeaksWorkspace.cpp b/Framework/DataObjects/src/PeaksWorkspace.cpp
index d38c71e134721f311ab3efe3b8022464955b96ca..301c714e2c6f5a474e161fe5bc73a93c2e900315 100644
--- a/Framework/DataObjects/src/PeaksWorkspace.cpp
+++ b/Framework/DataObjects/src/PeaksWorkspace.cpp
@@ -877,15 +877,9 @@ PeaksWorkspace::getSpecialCoordinateSystem() const {
 struct NullDeleter {
   template <typename T> void operator()(T *) {}
 };
-/**Get access to shared pointer containing workspace porperties, cashes the
- shared pointer
- into internal class variable to not allow shared pointer being deleted */
+/**Get access to shared pointer containing workspace porperties */
 API::LogManager_sptr PeaksWorkspace::logs() {
-  if (m_logCash)
-    return m_logCash;
-
-  m_logCash = API::LogManager_sptr(&(this->mutableRun()), NullDeleter());
-  return m_logCash;
+  return API::LogManager_sptr(&(this->mutableRun()), NullDeleter());
 }
 
 /** Get constant access to shared pointer containing workspace porperties;
diff --git a/Framework/DataObjects/src/WorkspaceCreation.cpp b/Framework/DataObjects/src/WorkspaceCreation.cpp
index ee7eec6e4da2548fd14374624570d646ea2e19f1..92ecff01b8353a8025e330d6a02b29052576f128 100644
--- a/Framework/DataObjects/src/WorkspaceCreation.cpp
+++ b/Framework/DataObjects/src/WorkspaceCreation.cpp
@@ -52,24 +52,6 @@ void initializeFromParent(const API::MatrixWorkspace &parent,
   static_cast<void>(ws.mutableX(0));
 }
 
-/** Initialize a MatrixWorkspace from its parent including instrument, unit,
- * number of spectra but without Run (i.e., logs)
- * @brief initializeFromParentWithoutLogs
- * @param parent
- * @param ws
- */
-void initializeFromParentWithoutLogs(const API::MatrixWorkspace &parent,
-                                     API::MatrixWorkspace &ws) {
-  bool differentSize = (parent.x(0).size() != ws.x(0).size()) ||
-                       (parent.y(0).size() != ws.y(0).size());
-  API::WorkspaceFactory::Instance().initializeFromParentWithoutLogs(
-      parent, ws, differentSize);
-  // For EventWorkspace, `ws.y(0)` put entry 0 in the MRU. However, clients
-  // would typically expect an empty MRU and fail to clear it. This dummy call
-  // removes the entry from the MRU.
-  static_cast<void>(ws.mutableX(0));
-}
-
 template <>
 void fixDistributionFlag(API::MatrixWorkspace &workspace,
                          const HistogramData::Histogram &histArg) {
diff --git a/Framework/DataObjects/test/WorkspaceCreationTest.h b/Framework/DataObjects/test/WorkspaceCreationTest.h
index 7aba97e764b0e0ff9746a0ec22625d3d908b95ba..dccc28d59ee2daf4cd37e614521de4aaf4094033 100644
--- a/Framework/DataObjects/test/WorkspaceCreationTest.h
+++ b/Framework/DataObjects/test/WorkspaceCreationTest.h
@@ -265,7 +265,9 @@ public:
     const std::string &name1 = "Log4";
     const std::string &value1 = "6.4a";
     parent->mutableRun().addProperty(name1, value1);
-    const auto ws = createWithoutLogs<Workspace2D>(*parent);
+    const auto ws = create<Workspace2D>(*parent);
+    TS_ASSERT_EQUALS(&parent->run(), &ws->run());
+    ws->setSharedRun(Kernel::make_cow<Run>());
     check_indices(*ws);
     check_zeroed_data(*ws);
     check_instrument(*ws);
diff --git a/Framework/Indexing/CMakeLists.txt b/Framework/Indexing/CMakeLists.txt
index b3d274a33d63b6a6b30f0c1f0f9e465b38956e95..e5b69e1a9de4cb53c493f6632026201e14b6fb41 100644
--- a/Framework/Indexing/CMakeLists.txt
+++ b/Framework/Indexing/CMakeLists.txt
@@ -9,6 +9,7 @@ set ( SRC_FILES
 )
 
 set ( INC_FILES
+	inc/MantidIndexing/Conversion.h
 	inc/MantidIndexing/DetectorID.h
 	inc/MantidIndexing/DllConfig.h
 	inc/MantidIndexing/Extract.h
@@ -27,6 +28,7 @@ set ( INC_FILES
 )
 
 set ( TEST_FILES
+	ConversionTest.h
 	DetectorIDTest.h
 	ExtractTest.h
 	GlobalSpectrumIndexTest.h
diff --git a/Framework/Indexing/inc/MantidIndexing/Conversion.h b/Framework/Indexing/inc/MantidIndexing/Conversion.h
new file mode 100644
index 0000000000000000000000000000000000000000..01a24ac96ee6b30db13af350acf4eb613a3058ca
--- /dev/null
+++ b/Framework/Indexing/inc/MantidIndexing/Conversion.h
@@ -0,0 +1,79 @@
+#ifndef MANTID_INDEXING_CONVERSION_H_
+#define MANTID_INDEXING_CONVERSION_H_
+
+#include "MantidIndexing/DllConfig.h"
+#include "MantidIndexing/GlobalSpectrumIndex.h"
+#include "MantidIndexing/SpectrumNumber.h"
+
+namespace Mantid {
+namespace Indexing {
+
+/** Conversion helpers from and to (vectors of) integer types such as
+  SpectrumNumber and GlobalSpectrumIndex.
+
+  @author Simon Heybrock
+  @date 2017
+
+  Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
+  National Laboratory & European Spallation Source
+
+  This file is part of Mantid.
+
+  Mantid is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  Mantid is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+  File change history is stored at: <https://github.com/mantidproject/mantid>
+  Code Documentation is available at: <http://doxygen.mantidproject.org>
+*/
+
+/** Convert std::vector<In> to std::vector<Out> by static-casting all elements.
+ *
+ * `In` must be an integral type and `Out` can be any type inheriting
+ * Indexing::IndexType, such as SpectrumNumber or GlobalSpectrumIndex. The
+ * conversion is done using static_cast without any range check. It is the
+ * responsibility of the caller to not pass any vectors containing elements that
+ * suffer from loss of data in a static_cast. */
+template <
+    class Out, class In,
+    typename std::enable_if<std::is_integral<In>::value>::type * = nullptr>
+std::vector<Out> castVector(const std::vector<In> &indices) {
+  std::vector<Out> converted;
+  converted.reserve(indices.size());
+  for (const auto index : indices)
+    converted.push_back(static_cast<typename Out::underlying_type>(index));
+  return converted;
+}
+
+/** Convert std::vector<In> to std::vector<Out> by static-casting all elements.
+ *
+ * `Out` must be an integral type and `In` can be any type inheriting
+ * Indexing::IndexType, such as SpectrumNumber or GlobalSpectrumIndex. The
+ * conversion is done using static_cast without any range check. It is the
+ * responsibility of the caller to not pass any vectors containing elements that
+ * suffer from loss of data in a static_cast. */
+template <
+    class Out, class In,
+    typename std::enable_if<!std::is_integral<In>::value>::type * = nullptr>
+std::vector<Out> castVector(const std::vector<In> &indices) {
+  std::vector<Out> converted;
+  converted.reserve(indices.size());
+  for (const auto index : indices)
+    converted.push_back(
+        static_cast<Out>(static_cast<typename In::underlying_type>(index)));
+  return converted;
+}
+
+} // namespace Indexing
+} // namespace Mantid
+
+#endif /* MANTID_INDEXING_CONVERSION_H_ */
diff --git a/Framework/Indexing/inc/MantidIndexing/IndexInfo.h b/Framework/Indexing/inc/MantidIndexing/IndexInfo.h
index a9e3267c6cf46d4e2c80e344ae3814dea4b905b3..ded7d80947676efd3964bfb915c3ced210242a57 100644
--- a/Framework/Indexing/inc/MantidIndexing/IndexInfo.h
+++ b/Framework/Indexing/inc/MantidIndexing/IndexInfo.h
@@ -114,6 +114,9 @@ public:
   SpectrumIndexSet
   makeIndexSet(const std::vector<GlobalSpectrumIndex> &globalIndices) const;
 
+  std::vector<GlobalSpectrumIndex> globalSpectrumIndicesFromDetectorIndices(
+      const std::vector<size_t> &detectorIndices) const;
+
   bool isOnThisPartition(GlobalSpectrumIndex globalIndex) const;
 
   Parallel::StorageMode storageMode() const;
diff --git a/Framework/Indexing/inc/MantidIndexing/IndexType.h b/Framework/Indexing/inc/MantidIndexing/IndexType.h
index 0920f29b6b2c3cb7a2d681b364268db96e07bd35..3778d2036e468801181bc85327e8bd4223ad1ae6 100644
--- a/Framework/Indexing/inc/MantidIndexing/IndexType.h
+++ b/Framework/Indexing/inc/MantidIndexing/IndexType.h
@@ -37,6 +37,7 @@ template <class Derived, class Int,
           class = typename std::enable_if<std::is_integral<Int>::value>::type>
 class IndexType {
 public:
+  using underlying_type = Int;
   IndexType() noexcept : m_data(0) {}
   IndexType(Int data) noexcept : m_data(data) {}
   explicit operator Int() const noexcept { return m_data; }
diff --git a/Framework/Indexing/src/IndexInfo.cpp b/Framework/Indexing/src/IndexInfo.cpp
index ed94a21c0f3ea752281ea0bb409c97a9d6f27f84..0f27f32d743d749a200521fbba012f08cbba6cee 100644
--- a/Framework/Indexing/src/IndexInfo.cpp
+++ b/Framework/Indexing/src/IndexInfo.cpp
@@ -193,6 +193,55 @@ SpectrumIndexSet IndexInfo::makeIndexSet(
   return m_spectrumNumberTranslator->makeIndexSet(globalIndices);
 }
 
+/** Map a vector of detector indices to a vector of global spectrum indices.
+ *
+ * The mapping is based on the held spectrum definitions. Throws if any spectrum
+ * maps to more than one detectors. Throws if there is no 1:1 mapping from
+ * detectors to spectra, such as when some of the detectors have no matching
+ * spectrum. */
+std::vector<GlobalSpectrumIndex>
+IndexInfo::globalSpectrumIndicesFromDetectorIndices(
+    const std::vector<size_t> &detectorIndices) const {
+  if (!m_spectrumDefinitions)
+    throw std::runtime_error("IndexInfo::"
+                             "globalSpectrumIndicesFromDetectorIndices -- no "
+                             "spectrum definitions available");
+  std::vector<char> detectorMap;
+  for (const auto &index : detectorIndices) {
+    // IndexInfo has no knowledge of the maximum detector index so we workaround
+    // this knowledge gap by assuming below that any index beyond the end of the
+    // map is 0.
+    if (index >= detectorMap.size())
+      detectorMap.resize(index + 1, 0);
+    detectorMap[index] = 1;
+  }
+
+  std::vector<GlobalSpectrumIndex> spectrumIndices;
+  for (size_t i = 0; i < size(); ++i) {
+    const auto &spectrumDefinition = m_spectrumDefinitions->operator[](i);
+    if (spectrumDefinition.size() == 1) {
+      const auto detectorIndex = spectrumDefinition[0].first;
+      if (detectorMap.size() > detectorIndex &&
+          detectorMap[detectorIndex] != 0) {
+        if (detectorMap[detectorIndex] > 1)
+          throw std::runtime_error(
+              "Multiple spectra correspond to the same detector");
+        // Increment flag to catch two spectra mapping to same detector.
+        ++detectorMap[detectorIndex];
+        spectrumIndices.push_back(i);
+      }
+    }
+    if (spectrumDefinition.size() > 1)
+      throw std::runtime_error("SpectrumDefinition contains multiple entries. "
+                               "No unique mapping from detector to spectrum "
+                               "possible");
+  }
+  if (detectorIndices.size() != spectrumIndices.size())
+    throw std::runtime_error(
+        "Some of the requested detectors do not have a corresponding spectrum");
+  return spectrumIndices;
+}
+
 /// Returns true if the given global index is on this partition.
 bool IndexInfo::isOnThisPartition(GlobalSpectrumIndex globalIndex) const {
   // A map from global index to partition might be faster, consider adding this
diff --git a/Framework/Indexing/test/ConversionTest.h b/Framework/Indexing/test/ConversionTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..c84c095f2aa21c32769426aed290e8f13d01750f
--- /dev/null
+++ b/Framework/Indexing/test/ConversionTest.h
@@ -0,0 +1,57 @@
+#ifndef MANTID_INDEXING_CONVERSIONTEST_H_
+#define MANTID_INDEXING_CONVERSIONTEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidIndexing/Conversion.h"
+#include "MantidIndexing/GlobalSpectrumIndex.h"
+#include "MantidIndexing/SpectrumNumber.h"
+
+using namespace Mantid::Indexing;
+
+class ConversionTest : public CxxTest::TestSuite {
+public:
+  // This pair of boilerplate methods prevent the suite being created statically
+  // This means the constructor isn't called when running other tests
+  static ConversionTest *createSuite() { return new ConversionTest(); }
+  static void destroySuite(ConversionTest *suite) { delete suite; }
+
+  void test_just_a_static_cast() {
+    std::vector<SpectrumNumber> in{-1};
+    TS_ASSERT_EQUALS(castVector<size_t>(in),
+                     (std::vector<size_t>{18446744073709551615ul}));
+  }
+
+  void test_GlobalSpectrumIndex() {
+    std::vector<GlobalSpectrumIndex> in{0, 1, 2};
+    TS_ASSERT_EQUALS(castVector<size_t>(in), (std::vector<size_t>{0, 1, 2}));
+    TS_ASSERT_EQUALS(castVector<int64_t>(in), (std::vector<int64_t>{0, 1, 2}));
+    TS_ASSERT_EQUALS(castVector<int32_t>(in), (std::vector<int32_t>{0, 1, 2}));
+  }
+
+  void test_to_GlobalSpectrumIndex() {
+    std::vector<int64_t> in{0, 1, 2};
+    TS_ASSERT_EQUALS(castVector<GlobalSpectrumIndex>(in),
+                     (std::vector<GlobalSpectrumIndex>{0, 1, 2}));
+    std::vector<size_t> in2{0, 1, 2};
+    TS_ASSERT_EQUALS(castVector<GlobalSpectrumIndex>(in2),
+                     (std::vector<GlobalSpectrumIndex>{0, 1, 2}));
+  }
+
+  void test_SpectrumNumber() {
+    std::vector<SpectrumNumber> in{-1, 1, 2};
+    TS_ASSERT_EQUALS(castVector<int64_t>(in), (std::vector<int64_t>{-1, 1, 2}));
+    TS_ASSERT_EQUALS(castVector<int32_t>(in), (std::vector<int32_t>{-1, 1, 2}));
+  }
+
+  void test_to_SpectrumNumber() {
+    std::vector<int32_t> in{-1, 1, 2};
+    TS_ASSERT_EQUALS(castVector<SpectrumNumber>(in),
+                     (std::vector<SpectrumNumber>{-1, 1, 2}));
+    std::vector<int64_t> in2{-1, 1, 2};
+    TS_ASSERT_EQUALS(castVector<SpectrumNumber>(in2),
+                     (std::vector<SpectrumNumber>{-1, 1, 2}));
+  }
+};
+
+#endif /* MANTID_INDEXING_CONVERSIONTEST_H_ */
diff --git a/Framework/Indexing/test/IndexInfoTest.h b/Framework/Indexing/test/IndexInfoTest.h
index 0b5434423faf6cf5f578e5259c938497ca2cee88..7e16ef641f317550f9d78c9cb4fc31629f3c6ae8 100644
--- a/Framework/Indexing/test/IndexInfoTest.h
+++ b/Framework/Indexing/test/IndexInfoTest.h
@@ -187,6 +187,90 @@ public:
     TS_ASSERT_EQUALS(info.spectrumDefinitions().get(), defs.get());
   }
 
+  void test_globalSpectrumIndicesFromDetectorIndices_fails_without_spec_defs() {
+    IndexInfo info(3);
+    std::vector<size_t> detectorIndices{6, 8};
+    TS_ASSERT_THROWS_EQUALS(
+        info.globalSpectrumIndicesFromDetectorIndices(detectorIndices),
+        const std::runtime_error &e, std::string(e.what()),
+        "IndexInfo::globalSpectrumIndicesFromDetectorIndices -- no spectrum "
+        "definitions available");
+  }
+
+  void test_globalSpectrumIndicesFromDetectorIndices_fails_multiple() {
+    IndexInfo info(3);
+    std::vector<size_t> detectorIndices{6, 8};
+    std::vector<SpectrumDefinition> specDefs(3);
+    specDefs[0].add(6);
+    specDefs[1].add(7);
+    specDefs[1].add(77);
+    specDefs[2].add(8);
+    info.setSpectrumDefinitions(specDefs);
+    TS_ASSERT_THROWS_EQUALS(
+        info.globalSpectrumIndicesFromDetectorIndices(detectorIndices),
+        const std::runtime_error &e, std::string(e.what()),
+        "SpectrumDefinition contains multiple entries. No unique mapping from "
+        "detector to spectrum possible");
+  }
+
+  void test_globalSpectrumIndicesFromDetectorIndices_fails_missing() {
+    IndexInfo info(3);
+    std::vector<size_t> detectorIndices{6, 8};
+    std::vector<SpectrumDefinition> specDefs(3);
+    // Nothing maps to 8
+    specDefs[0].add(6);
+    specDefs[1].add(7);
+    info.setSpectrumDefinitions(specDefs);
+    TS_ASSERT_THROWS_EQUALS(
+        info.globalSpectrumIndicesFromDetectorIndices(detectorIndices),
+        const std::runtime_error &e, std::string(e.what()),
+        "Some of the requested detectors do not have a corresponding spectrum");
+  }
+
+  void test_globalSpectrumIndicesFromDetectorIndices_fails_conflict() {
+    IndexInfo info(3);
+    std::vector<size_t> detectorIndices{6, 8};
+    std::vector<SpectrumDefinition> specDefs(3);
+    // Two indices map to same detector.
+    specDefs[0].add(6);
+    specDefs[1].add(6);
+    specDefs[2].add(8);
+    info.setSpectrumDefinitions(specDefs);
+    TS_ASSERT_THROWS_EQUALS(
+        info.globalSpectrumIndicesFromDetectorIndices(detectorIndices),
+        const std::runtime_error &e, std::string(e.what()),
+        "Multiple spectra correspond to the same detector");
+  }
+
+  void test_globalSpectrumIndicesFromDetectorIndices_fails_conflict_miss() {
+    IndexInfo info(3);
+    std::vector<size_t> detectorIndices{6, 8};
+    std::vector<SpectrumDefinition> specDefs(3);
+    // Two indices map to same detector, but additionally one is missing.
+    specDefs[0].add(6);
+    specDefs[1].add(6);
+    info.setSpectrumDefinitions(specDefs);
+    TS_ASSERT_THROWS_EQUALS(
+        info.globalSpectrumIndicesFromDetectorIndices(detectorIndices),
+        const std::runtime_error &e, std::string(e.what()),
+        "Multiple spectra correspond to the same detector");
+  }
+
+  void test_globalSpectrumIndicesFromDetectorIndices() {
+    IndexInfo info(3);
+    std::vector<size_t> detectorIndices{6, 8};
+    std::vector<SpectrumDefinition> specDefs(3);
+    specDefs[0].add(6);
+    specDefs[1].add(7);
+    specDefs[2].add(8);
+    info.setSpectrumDefinitions(specDefs);
+    const auto &indices =
+        info.globalSpectrumIndicesFromDetectorIndices(detectorIndices);
+    TS_ASSERT_EQUALS(indices.size(), detectorIndices.size());
+    TS_ASSERT_EQUALS(indices[0], 0);
+    TS_ASSERT_EQUALS(indices[1], 2);
+  }
+
   void test_StorageMode_Cloned() {
     runParallel(run_StorageMode_Cloned);
     // Trivial: Run with one partition.
diff --git a/Framework/PythonInterface/plugins/algorithms/EnggFocus.py b/Framework/PythonInterface/plugins/algorithms/EnggFocus.py
index 7e658088f19150698b68417007aa4537b38f98ac..28ecf993a48d5403c04f3ac7fa2bba021ee4fa61 100644
--- a/Framework/PythonInterface/plugins/algorithms/EnggFocus.py
+++ b/Framework/PythonInterface/plugins/algorithms/EnggFocus.py
@@ -62,7 +62,7 @@ class EnggFocus(PythonAlgorithm):
 
         self.declareProperty(self.INDICES_PROP_NAME, '', direction=Direction.Input,
                              doc='Sets the spectrum numbers for the detectors '
-                             'that should be considered in the focussing operation (all others will be '
+                             'that should be considered in the focusing operation (all others will be '
                              'ignored). This option cannot be used together with Bank, as they overlap. '
                              'You can give multiple ranges, for example: "0-99", or "0-9, 50-59, 100-109".')
 
@@ -160,8 +160,28 @@ class EnggFocus(PythonAlgorithm):
         # converting units), so I guess that's what users will expect
         self._convert_to_distribution(input_ws)
 
+        if bank:
+            self._add_bank_number(input_ws, bank)
+
         self.setProperty("OutputWorkspace", input_ws)
 
+    def _bank_to_int(self, bank):
+        if bank == "North":
+            return "1"
+        if bank == "South":
+            return "2"
+        if bank in ("1", "2"):
+            return bank
+        raise RuntimeError("Invalid value for bank: \"{}\" of type {}".format(bank, type(bank)))
+
+    def _add_bank_number(self, ws, bank):
+        alg = self.createChildAlgorithm("AddSampleLog")
+        alg.setProperty("Workspace", ws)
+        alg.setProperty("LogName", "bankid")
+        alg.setProperty("LogText", self._bank_to_int(bank))
+        alg.setProperty("LogType", "Number")
+        alg.execute()
+
     def _mask_bins(self, wks, min_bins, max_bins):
         """
         Mask multiple ranges of bins, given multiple pairs min-max
diff --git a/Testing/Data/SystemTest/ISIS_Powder/input/PEARL00098494.nxs.md5 b/Testing/Data/SystemTest/ISIS_Powder/input/PEARL00098494.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..bb209053d4c2864afe53af5a6f21b89dd8721439
--- /dev/null
+++ b/Testing/Data/SystemTest/ISIS_Powder/input/PEARL00098494.nxs.md5
@@ -0,0 +1 @@
+c13f59f8155dc56e59d0412511b80b5d
\ No newline at end of file
diff --git a/Testing/SystemTests/tests/analysis/ISIS_PowderPearlTest.py b/Testing/SystemTests/tests/analysis/ISIS_PowderPearlTest.py
index 12eba9b03a1fccf20ec220cd46884c632d8a35b0..1b3731a5357d07a680ea3bad2742901ab1ce33df 100644
--- a/Testing/SystemTests/tests/analysis/ISIS_PowderPearlTest.py
+++ b/Testing/SystemTests/tests/analysis/ISIS_PowderPearlTest.py
@@ -122,9 +122,34 @@ class FocusTest(stresstesting.MantidStressTest):
             mantid.mtd.clear()
 
 
+class CreateCalTest(stresstesting.MantidStressTest):
+
+    calibration_results = None
+    existing_config = config["datasearch.directories"]
+
+    def requiredFiles(self):
+        return _gen_required_files()
+
+    def runTest(self):
+        setup_mantid_paths()
+        self.calibration_results = run_create_cal()
+
+    def valid(self):
+        return ceria_validator(self.calibration_results)
+
+    def cleanup(self):
+        try:
+            _try_delete(spline_path)
+            _try_delete(output_dir)
+        finally:
+            config['datasearch.directories'] = self.existing_config
+            mantid.mtd.clear()
+
+
 def _gen_required_files():
     required_run_numbers = ["98472", "98485",  # create_van
-                            "98507", "98472_splined"]  # Focus (Si)
+                            "98507", "98472_splined",  # Focus (Si)
+                            "98494"]  # create_cal (Ce)
 
     # Generate file names of form "INSTxxxxx.nxs" - PEARL requires 000 padding
     input_files = [os.path.join(input_dir, (inst_name + "000" + number + ".nxs")) for number in required_run_numbers]
@@ -132,6 +157,12 @@ def _gen_required_files():
     return input_files
 
 
+def run_create_cal():
+    ceria_run = 98494
+    inst_obj = setup_inst_object(tt_mode="tt88", focus_mode="all")
+    return inst_obj.create_cal(run_number=ceria_run)
+
+
 def run_vanadium_calibration(focus_mode):
     vanadium_run = 98507  # Choose arbitrary run in the cycle 17_1
 
@@ -162,6 +193,11 @@ def focus_validation(results):
     return _compare_ws(reference_file_name=reference_file_name, results=results)
 
 
+def ceria_validator(results):
+    reference_file_name = "ISIS_Powder-PEARL00098494_grouped.nxs"
+    return _compare_ws(reference_file_name=reference_file_name, results=results)
+
+
 def _compare_ws(reference_file_name, results):
     ref_ws = mantid.Load(Filename=reference_file_name)
 
diff --git a/Testing/SystemTests/tests/analysis/reference/ISIS_Powder-PEARL98494_grouped.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/ISIS_Powder-PEARL98494_grouped.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..85159fd3ae5819d82f207365d911baf49b3d05a1
--- /dev/null
+++ b/Testing/SystemTests/tests/analysis/reference/ISIS_Powder-PEARL98494_grouped.nxs.md5
@@ -0,0 +1 @@
+b957a6b0928e12a8c86284ea010df429
\ No newline at end of file
diff --git a/docs/source/release/v3.12.0/diffraction.rst b/docs/source/release/v3.12.0/diffraction.rst
index 5de79b4872045e64e6092cf0a641cb8a82d6aced..79174ecb3939e6ada94c7ff15821a054b6fecc3b 100644
--- a/docs/source/release/v3.12.0/diffraction.rst
+++ b/docs/source/release/v3.12.0/diffraction.rst
@@ -13,6 +13,7 @@ Powder Diffraction
 ------------------
 
 - Some new functionality for POLARIS in the ISIS Powder scripts. Adjusted some default parameters and output unsplined vanadium workspace by default
+- ISIS_Powder scripts for PEARL now support creation of grouping .cal files from ceria run(s)
 - The ``CalibrationFile`` is now optional in :ref:`SNSPowderReduction <algm-SNSPowderReduction>`. In this case time focussing will use :ref:`ConvertUnits <algm-ConvertUnits>` and the instrument geometry. Care must be taken to supply a ``GroupingFile`` otherwise all of the spectra will be kept separate.
 - New algorithm :ref:`algm-EstimateDivergence` estimates the beam divergence due to finite slit size
 - :ref:`PDCalibration <algm-PDCalibration>` returns three more diagnostic workspaces: one for the fitted peak heights, one for the fitted peak widths, and one for observed resolution.
diff --git a/docs/source/release/v3.12.0/framework.rst b/docs/source/release/v3.12.0/framework.rst
index b6bc937cb3b1db9a97698e9d71c8b81c05f267b7..6b6eed76cd9adb64b0492a33f27d810a460cab79 100644
--- a/docs/source/release/v3.12.0/framework.rst
+++ b/docs/source/release/v3.12.0/framework.rst
@@ -38,6 +38,7 @@ Performance
 -----------
 
 - Improved performance for second and consecutive loads of instrument geometry, particularly for instruments with many detector pixels. This affects :ref:`LoadEmptyInstrument <algm-LoadEmptyInstrument>` and load algorithms that are using it.
+- Up to 30% performance improvement for :ref:`CropToComponent <algm-CropToComponent>` based on ongoing work on Instrument-2.0.
 
 Python
 ------
diff --git a/docs/source/release/v3.12.0/indirect_inelastic.rst b/docs/source/release/v3.12.0/indirect_inelastic.rst
index e4d374817645fff48b81eb22fd105102e3e38583..6759792bee11b44c4a2c2cfa8e89ca33c6649c2c 100644
--- a/docs/source/release/v3.12.0/indirect_inelastic.rst
+++ b/docs/source/release/v3.12.0/indirect_inelastic.rst
@@ -37,6 +37,7 @@ New
 Improved
 ########
 - The Plot Guess Feature in the ConvFit Interface is now enabled for the diffusion functions.
+- The Plot Guess Feature in the MSDFit Interface is now implemented for the three models introduced in release v3.11 (MsdGauss, MsdPeters and MsdYi).
 
 Bugfixes
 ########
diff --git a/docs/source/techniques/ISISPowder-Pearl-v1.rst b/docs/source/techniques/ISISPowder-Pearl-v1.rst
index 76d56a89537ef4ddf6eaafc95f80d397b6f512fb..404a1e8f8328e79ee45d53439a66c5d8b45118b7 100644
--- a/docs/source/techniques/ISISPowder-Pearl-v1.rst
+++ b/docs/source/techniques/ISISPowder-Pearl-v1.rst
@@ -55,6 +55,7 @@ The following methods can be executed on a PEARL object:
 
 - :ref:`create_vanadium_pearl_isis-powder-diffraction-ref`
 - :ref:`focus_pearl_isis-powder-diffraction-ref`
+- :ref:`create_cal_pearl_isis-powder-diffraction-ref`
 
 For information on creating a PEARL object see:
 :ref:`creating_pearl_object-isis-powder-diffraction-ref`
@@ -113,7 +114,7 @@ The following parameter is required if
 The following parameter may also be optionally set:
 
 - :ref:`file_ext_pearl_isis-powder-diffraction-ref`
-
+  
 Example
 =======
 
@@ -131,6 +132,32 @@ Example
                       run_number="100-110", tt_mode="tt88",
                       vanadium_normalisation=True)
 
+.. _create_cal_pearl_isis-powder-diffraction-ref:
+
+create_cal
+^^^^^^^^^^
+The *create_cal* method creates the offset calibration file for PEARL
+scripts. The following parameters are required:
+
+- :ref:`calibration_mapping_file_pearl_isis-powder-diffraction-ref`
+- :ref:`focus_mode_pearl_isis-powder-diffraction-ref`
+- :ref:`long_mode_pearl_isis-powder-diffraction-ref`
+- :ref:`run_number_pearl_isis-powder-diffraction-ref`
+
+Example
+=======
+
+.. code-block:: python
+
+  # Notice how the filename ends with .yaml
+  cal_mapping_file = r"C:\path\to\cal_mapping.yaml"
+  
+  pearl_example.create_cal(run_number=95671, 
+                           tt_mode="tt70",
+                           long_mode=True,
+                           calibration_mapping_file=cal_mapping_file)
+
+
 .. _calibration_mapping_pearl_isis-powder-diffraction-ref:
 
 Calibration Mapping File
@@ -462,7 +489,8 @@ Example Input:
 run_number
 ^^^^^^^^^^
 Specifies the run number(s) to process when calling the
-:ref:`focus_pearl_isis-powder-diffraction-ref` method.
+:ref:`focus_pearl_isis-powder-diffraction-ref` and
+:ref:`create_cal_isis-powder-diffraction-ref` methods.
 
 This parameter accepts a single value or a range
 of values with the following syntax:
@@ -573,6 +601,104 @@ requires the user to restart Mantid for the new values to take effect.
 Please read :ref:`instrument_advanced_properties_isis-powder-diffraction-ref`
 before proceeding to change values within the advanced configuration file.
 
+.. _create_cal_rebin_1_params_pearl_isis-powder-diffraction-ref:
+
+create_cal_rebin_1_params
+^^^^^^^^^^^^^^^^^^^^^^^^^
+The rebin parameters to use in the first rebin operation in
+:ref:`create_cal_pearl_isis-powder-diffraction-ref`. On PEARL this is
+set to the following:
+
+.. code-block:: python
+
+  # Long mode OFF:
+        create_cal_rebin_1_params: "100,-0.0006,19950"
+	
+  # Long mode ON:
+        create_cal_rebin_1_params: "20300,-0.0006,39990"
+
+	
+.. _create_cal_rebin_2_params_pearl_isis-powder-diffraction-ref:
+
+create_cal_rebin_2_params
+^^^^^^^^^^^^^^^^^^^^^^^^^
+The rebin parameters to use in the second rebin operation in
+:ref:`create_cal_pearl_isis-powder-diffraction-ref`. On PEARL this is
+set to the following:
+
+.. code-block:: python
+
+  create_cal_rebin_2_params: "1.8,0.002,2.1"
+
+
+.. _cross_corr_reference_spectra_pearl_isis-powder-diffraction-ref:
+
+cross_corr_reference_spectra
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The Workspace Index of the spectra to correlate all other spectra
+against in the cross-correlation step of
+:ref:`create_cal_pearl_isis-powder-diffraction-ref`. On PEARL this is
+set to the following:
+
+.. code-block:: python
+
+  cross_corr_reference_spectra: 20
+
+  
+.. _cross_corr_ws_index_max_pearl_isis-powder-diffraction-ref:
+
+cross_corr_ws_index_max
+^^^^^^^^^^^^^^^^^^^^^^^
+The workspace index of the last member of the range of spectra to
+cross-correlate against in
+:ref:`create_cal_pearl_isis-powder-diffraction-ref`. On PEARL this is
+set to the following:
+
+.. code-block:: python
+
+  cross_corr_ws_index_max: 1063
+
+  
+.. _cross_corr_ws_index_min_pearl_isis-powder-diffraction-ref:
+
+cross_corr_ws_index_min
+^^^^^^^^^^^^^^^^^^^^^^^
+The workspace index of the first member of the range of spectra to
+cross-correlate against in
+:ref:`create_cal_pearl_isis-powder-diffraction-ref`. On PEARL this is
+set to the following:
+
+.. code-block:: python
+
+  cross_corr_ws_index_min: 9
+
+  
+.. _cros_cor_x_max_pearl_isis-powder-diffraction-ref:
+
+cross_cor_x_max
+^^^^^^^^^^^^^^^
+The ending point of the region to be cross correlated in
+:ref:`create_cal_pearl_isis-powder-diffraction-ref`. On PEARL this is
+set to the following:
+
+.. code-block:: python
+
+  cross_corr_x_max: 2.1
+
+
+.. _cros_corr_x_min_pearl_isis-powder-diffraction-ref:
+
+cross_cor_x_min
+^^^^^^^^^^^^^^^
+The starting point of the region to be cross correlated in
+:ref:`create_cal_pearl_isis-powder-diffraction-ref`. On PEARL this is
+set to the following:
+
+.. code-block:: python
+
+  cross_corr_x_min: 1.8
+
+
 .. _focused_cropping_values_pearl_isis-powder-diffraction-ref:
 
 focused_cropping_values
@@ -630,6 +756,58 @@ On PEARL this is set to the following TOF windows:
       ]
 
 
+.. _get_det_offsets_d_ref_pearl_isis-powder-diffraction-ref:
+
+get_det_offsets_d_ref
+^^^^^^^^^^^^^^^^^^^^^
+Center of reference peak in d-space for GetDetectorOffsets in
+:ref:`create_cal_pearl_isis-powder-diffraction-ref`. On PEARL this is
+set to the following:
+
+.. code-block:: python
+
+  get_det_offsets_d_ref: 1.912795
+
+
+.. _get_det_offsets_step_pearl_isis-powder-diffraction-ref:
+
+get_det_offsets_step
+^^^^^^^^^^^^^^^^^^^^
+Step size used to bin d-spacing data in GetDetectorOffsets when
+running :ref:`create_cal_pearl_isis-powder-diffraction-ref`. On PEARL
+this is set to the following:
+
+.. code-block:: python
+
+  get_det_offsets_step: 0.002
+
+
+.. _get_det_offsets_x_max_pearl_isis-powder-diffraction-ref:
+
+get_det_offsets_x_max
+^^^^^^^^^^^^^^^^^^^^^
+Maximum of CrossCorrelation data to search for peak, usually negative,
+in :ref:`create_cal_pearl_isis-powder-diffraction-ref`. On PEARL this
+is set to the following:
+
+.. code-block:: python
+
+  get_det_offsets_x_max: -200
+
+  
+.. _get_det_offsets_x_min_pearl_isis-powder-diffraction-ref:
+
+get_det_offsets_x_min
+^^^^^^^^^^^^^^^^^^^^^
+Minimum of CrossCorrelation data to search for peak, usually negative,
+in :ref:`create_cal_pearl_isis-powder-diffraction-ref`. On PEARL this
+is set to the following:
+
+.. code-block:: python
+
+  get_det_offsets_x_min: -200
+		
+
 .. _monitor_lambda_crop_range_pearl_isis-powder-diffraction-ref:
 
 monitor_lambda_crop_range
diff --git a/instrument/Facilities.xml b/instrument/Facilities.xml
index b218298efb24d2994ad442ec7f41235c8731dfab..061fd364bd169b7259d6a12d23059867425af0ab 100644
--- a/instrument/Facilities.xml
+++ b/instrument/Facilities.xml
@@ -799,14 +799,14 @@
   <instrument name="ISIS_Histogram">
     <technique>Test Listener</technique>
     <livedata>
-      <connection name="histo" address="localhost:56789" listener="ISISHistoDataListener" />
+      <connection name="histo" address="127.0.0.1:56789" listener="ISISHistoDataListener" />
     </livedata>
   </instrument>
 
   <instrument name="ISIS_Event">
     <technique>Test Listener</technique>
     <livedata>
-      <connection name="event" address="localhost:59876" listener="ISISLiveEventDataListener" />
+      <connection name="event" address="127.0.0.1:59876" listener="ISISLiveEventDataListener" />
     </livedata>
   </instrument>
 
diff --git a/instrument/SEQUOIA_Definition-20120404-20171113.xml b/instrument/SEQUOIA_Definition-20120404-20171113.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c2e6b15bc303f5afc3df1adc4cc0f067899bb3f0
--- /dev/null
+++ b/instrument/SEQUOIA_Definition-20120404-20171113.xml
@@ -0,0 +1,1826 @@
+<?xml version='1.0' encoding='ASCII'?>
+<!-- For help on the notation used to specify an Instrument Definition File 
+     see http://www.mantidproject.org/IDF -->
+<instrument xmlns="http://www.mantidproject.org/IDF/1.0" 
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd"
+ valid-to="2017-11-13 23:59:59" name="SEQUOIA" valid-from="2012-04-04 14:15:46.929098">
+  <!--For runs after 19889 -->
+  <defaults>
+    <length unit="metre"/>
+    <angle unit="degree"/>
+    <reference-frame>
+      <along-beam axis="z"/>
+      <pointing-up axis="y"/>
+      <handedness val="right"/>
+    </reference-frame>
+  </defaults>
+  <!--SOURCE AND SAMPLE POSITION-->
+  <component type="moderator">
+    <location z="-20.0114"/>
+  </component>
+  <type is="Source" name="moderator"/>
+  <component type="sample-position">
+    <location y="0.0" x="0.0" z="0.0"/>
+  </component>
+  <type is="SamplePos" name="sample-position"/>
+  <!--MONITORS-->
+  <component type="monitors" idlist="monitors">
+    <location/>
+  </component>
+  <type name="monitors">
+    <component type="monitor">
+      <location z="-1.77808" name="monitor1"/>
+      <location z="8.99184" name="monitor2"/>
+    </component>
+  </type>
+  <component type="B row" idlist="B row">
+    <location/>
+  </component>
+  <type name="B row">
+    <component type="B1">
+      <location/>
+    </component>
+    <component type="B2">
+      <location/>
+    </component>
+    <component type="B3">
+      <location/>
+    </component>
+    <component type="B4">
+      <location/>
+    </component>
+    <component type="B5">
+      <location/>
+    </component>
+    <component type="B6">
+      <location/>
+    </component>
+    <component type="B7">
+      <location/>
+    </component>
+    <component type="B8">
+      <location/>
+    </component>
+    <component type="B9">
+      <location/>
+    </component>
+    <component type="B10">
+      <location/>
+    </component>
+    <component type="B11">
+      <location/>
+    </component>
+    <component type="B12">
+      <location/>
+    </component>
+    <component type="B13">
+      <location/>
+    </component>
+    <component type="B14">
+      <location/>
+    </component>
+    <component type="B15">
+      <location/>
+    </component>
+    <component type="B16">
+      <location/>
+    </component>
+    <component type="B17">
+      <location/>
+    </component>
+    <component type="B18">
+      <location/>
+    </component>
+    <component type="B19">
+      <location/>
+    </component>
+    <component type="B20">
+      <location/>
+    </component>
+    <component type="B21">
+      <location/>
+    </component>
+    <component type="B22">
+      <location/>
+    </component>
+    <component type="B23">
+      <location/>
+    </component>
+    <component type="B24">
+      <location/>
+    </component>
+    <component type="B25">
+      <location/>
+    </component>
+    <component type="B26">
+      <location/>
+    </component>
+    <component type="B27">
+      <location/>
+    </component>
+    <component type="B28">
+      <location/>
+    </component>
+    <component type="B29">
+      <location/>
+    </component>
+    <component type="B30">
+      <location/>
+    </component>
+    <component type="B31">
+      <location/>
+    </component>
+    <component type="B32">
+      <location/>
+    </component>
+    <component type="B33">
+      <location/>
+    </component>
+    <component type="B34">
+      <location/>
+    </component>
+    <component type="B35">
+      <location/>
+    </component>
+    <component type="B36">
+      <location/>
+    </component>
+    <component type="B37">
+      <location/>
+    </component>
+  </type>
+  <type name="B1">
+    <component type="eightpack">
+      <location y="-1.30353562" x="4.60563316108" z="2.76377527">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="239.032627"/>
+      </location>
+    </component>
+  </type>
+  <type name="B2">
+    <component type="eightpack">
+      <location y="-1.303534985" x="4.5367332938" z="2.8754758848">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="236.732627"/>
+      </location>
+    </component>
+  </type>
+  <type name="B3">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="4.31906484166" z="3.19313298634">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="233.52406849"/>
+      </location>
+    </component>
+  </type>
+  <type name="B4">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="4.18256210476" z="3.36996307718">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="231.14100232"/>
+      </location>
+    </component>
+  </type>
+  <type name="B5">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="4.0394219694" z="3.54026506322">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="228.76774758"/>
+      </location>
+    </component>
+  </type>
+  <type name="B6">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="3.88900961084" z="3.70488877512">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="226.38891513"/>
+      </location>
+    </component>
+  </type>
+  <type name="B7">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="3.71577988364" z="3.87745665452">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="223.78023066"/>
+      </location>
+    </component>
+  </type>
+  <type name="B8">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="3.55275443372" z="4.0273746986">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="221.41717399"/>
+      </location>
+    </component>
+  </type>
+  <type name="B9">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="3.38385871106" z="4.17028409782">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="219.05662215"/>
+      </location>
+    </component>
+  </type>
+  <type name="B10">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="3.20998708014" z="4.30555569164">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="216.70619963"/>
+      </location>
+    </component>
+  </type>
+  <type name="B11">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="3.02996424486" z="4.43407703226">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="214.34619963"/>
+      </location>
+    </component>
+  </type>
+  <type name="B12">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="2.84480731774" z="4.5550843874">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="211.98619963"/>
+      </location>
+    </component>
+  </type>
+  <type name="B13">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="2.65482458366" z="4.6683646917">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="209.62619963"/>
+      </location>
+    </component>
+  </type>
+  <type name="B14">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="2.4603383163" z="4.77372578146">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="207.26619963"/>
+      </location>
+    </component>
+  </type>
+  <type name="B15">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="2.22317726585" z="4.88876471826">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="204.45377863"/>
+      </location>
+    </component>
+  </type>
+  <type name="B16">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="2.01893382776" z="4.97651229486">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="202.08202669"/>
+      </location>
+    </component>
+  </type>
+  <type name="B17">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="1.81182191864" z="5.05564016048">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="199.71647921"/>
+      </location>
+    </component>
+  </type>
+  <type name="B18">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="1.60068188829" z="5.12639931284">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="197.3406045"/>
+      </location>
+    </component>
+  </type>
+  <type name="B19">
+    <component type="eightpack">
+      <location y="-1.29479999993" x="1.38823150065" z="5.18797469134">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="194.9806045"/>
+      </location>
+    </component>
+  </type>
+  <type name="B20">
+    <component type="eightpack">
+      <location y="-1.29479999993" x="1.17342296557" z="5.24073913242">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="192.6206045"/>
+      </location>
+    </component>
+  </type>
+  <type name="B21">
+    <component type="eightpack">
+      <location y="-1.29479999993" x="0.92524769992" z="5.29019704722">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="189.9206045"/>
+      </location>
+    </component>
+  </type>
+  <type name="B22">
+    <component type="eightpack">
+      <location y="-1.29479999993" x="0.706622533158" z="5.32380997974">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="187.5606045"/>
+      </location>
+    </component>
+  </type>
+  <type name="B23">
+    <component type="eightpack">
+      <location y="-1.29479999993" x="0.48679868223" z="5.34839182796">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="185.2006045"/>
+      </location>
+    </component>
+  </type>
+  <type name="B24">
+    <component type="eightpack">
+      <location y="-1.29479999993" x="0.266149046568" z="5.3639008927">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="182.8406045"/>
+      </location>
+    </component>
+  </type>
+  <type name="B25">
+    <component type="eightpack">
+      <location y="-1.29479999993" x="0.045047927176" z="5.37031086464">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="180.4806045"/>
+      </location>
+    </component>
+  </type>
+  <type name="B26">
+    <component type="eightpack">
+      <location y="-1.29479999993" x="-0.207962706248" z="5.36647180196">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="177.78077169"/>
+      </location>
+    </component>
+  </type>
+  <type name="B27">
+    <component type="eightpack">
+      <location y="-1.29479999993" x="-0.428767559532" z="5.35335656276">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="175.42077169"/>
+      </location>
+    </component>
+  </type>
+  <type name="B28">
+    <component type="eightpack">
+      <location y="-1.29479999993" x="-0.648845069592" z="5.3311601149">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="173.06077169"/>
+      </location>
+    </component>
+  </type>
+  <type name="B29">
+    <component type="eightpack">
+      <location y="-1.29479999993" x="-0.867821906974" z="5.29992011642">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="170.70077169"/>
+      </location>
+    </component>
+  </type>
+  <type name="B30">
+    <component type="eightpack">
+      <location y="-1.29479999993" x="-1.08532660785" z="5.25968955934">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="168.34077169"/>
+      </location>
+    </component>
+  </type>
+  <type name="B31">
+    <component type="eightpack">
+      <location y="-1.29479999993" x="-1.30099020726" z="5.21053668838">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="165.98077169"/>
+      </location>
+    </component>
+  </type>
+  <type name="B32">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="-1.51446642013" z="5.15261142704">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="163.62077169"/>
+      </location>
+    </component>
+  </type>
+  <type name="B33">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="-1.72664610677" z="5.08615521502">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="161.24869638"/>
+      </location>
+    </component>
+  </type>
+  <type name="B34">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="-1.95342748836" z="5.00448226686">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="158.67752934"/>
+      </location>
+    </component>
+  </type>
+  <type name="B35">
+    <component type="eightpack">
+      <location y="-1.29479999993" x="-2.15779859854" z="4.91969141536">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="156.31752934"/>
+      </location>
+    </component>
+  </type>
+  <type name="B36">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="-2.35202492205" z="4.83001371308">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="154.03575652"/>
+      </location>
+    </component>
+  </type>
+  <type name="B37">
+    <component type="eightpack">
+      <location y="-1.29480004006" x="-2.54885044204" z="4.72893432164">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="151.67575652"/>
+      </location>
+    </component>
+  </type>
+  <component type="C row" idlist="C row">
+    <location/>
+  </component>
+  <type name="C row">
+    <component type="C1">
+      <location/>
+    </component>
+    <component type="C2">
+      <location/>
+    </component>
+    <component type="C3">
+      <location/>
+    </component>
+    <component type="C4">
+      <location/>
+    </component>
+    <component type="C5">
+      <location/>
+    </component>
+    <component type="C6">
+      <location/>
+    </component>
+    <component type="C7">
+      <location/>
+    </component>
+    <component type="C8">
+      <location/>
+    </component>
+    <component type="C9">
+      <location/>
+    </component>
+    <component type="C10">
+      <location/>
+    </component>
+    <component type="C11">
+      <location/>
+    </component>
+    <component type="C12">
+      <location/>
+    </component>
+    <component type="C13">
+      <location/>
+    </component>
+    <component type="C14">
+      <location/>
+    </component>
+    <component type="C15">
+      <location/>
+    </component>
+    <component type="C16">
+      <location/>
+    </component>
+    <component type="C17">
+      <location/>
+    </component>
+    <component type="C18">
+      <location/>
+    </component>
+    <component type="C19">
+      <location/>
+    </component>
+    <component type="C20">
+      <location/>
+    </component>
+    <component type="C21">
+      <location/>
+    </component>
+    <component type="C22">
+      <location/>
+    </component>
+    <component type="C23">
+      <location/>
+    </component>
+    <component type="C24">
+      <location/>
+    </component>
+    <component type="C25T">
+      <location/>
+    </component>
+    <component type="C26T">
+      <location/>
+    </component>
+    <component type="C25B">
+      <location/>
+    </component>
+    <component type="C26B">
+      <location/>
+    </component>
+    <component type="C27">
+      <location/>
+    </component>
+    <component type="C28">
+      <location/>
+    </component>
+    <component type="C29">
+      <location/>
+    </component>
+    <component type="C30">
+      <location/>
+    </component>
+    <component type="C31">
+      <location/>
+    </component>
+    <component type="C32">
+      <location/>
+    </component>
+    <component type="C33">
+      <location/>
+    </component>
+    <component type="C34">
+      <location/>
+    </component>
+    <component type="C35">
+      <location/>
+    </component>
+    <component type="C36">
+      <location/>
+    </component>
+    <component type="C37">
+      <location/>
+    </component>
+  </type>
+  <type name="C1">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="4.6875281408" z="2.89948601712">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="238.261"/>
+      </location>
+    </component>
+  </type>
+  <type name="C2">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="4.56415688386" z="3.09005035024">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="235.901"/>
+      </location>
+    </component>
+  </type>
+  <type name="C3">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="4.43304318622" z="3.27537285488">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="233.541"/>
+      </location>
+    </component>
+  </type>
+  <type name="C4">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="4.29500585244" z="3.45438429518">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="231.191"/>
+      </location>
+    </component>
+  </type>
+  <type name="C5">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="4.14967007504" z="3.62768575198">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="228.8397"/>
+      </location>
+    </component>
+  </type>
+  <type name="C6">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="3.99533264178" z="3.7969858655">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="226.4581"/>
+      </location>
+    </component>
+  </type>
+  <type name="C7">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="3.81281980386" z="3.97800034472">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="223.7854"/>
+      </location>
+    </component>
+  </type>
+  <type name="C8">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="3.64602183672" z="4.13139723376">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="221.4289"/>
+      </location>
+    </component>
+  </type>
+  <type name="C9">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="3.47173969862" z="4.27892822902">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="219.0544"/>
+      </location>
+    </component>
+  </type>
+  <type name="C10">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="3.29203392138" z="4.41864602934">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="216.6873"/>
+      </location>
+    </component>
+  </type>
+  <type name="C11">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="3.1075271606" z="4.55031056154">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="214.3302"/>
+      </location>
+    </component>
+  </type>
+  <type name="C12">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="2.9161672309" z="4.67522753548">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="211.9538"/>
+      </location>
+    </component>
+  </type>
+  <type name="C13">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="2.71943750244" z="4.79241055994">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="209.5726"/>
+      </location>
+    </component>
+  </type>
+  <type name="C14">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="2.49170903842" z="4.91467906064">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="206.8847"/>
+      </location>
+    </component>
+  </type>
+  <type name="C15">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="2.28458593857" z="5.01427223712">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="204.4948"/>
+      </location>
+    </component>
+  </type>
+  <type name="C16">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="2.07474382485" z="5.10464666648">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="202.1189"/>
+      </location>
+    </component>
+  </type>
+  <type name="C17">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="1.86274311677" z="5.18575022284">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="199.7585"/>
+      </location>
+    </component>
+  </type>
+  <type name="C18">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="1.64894478364" z="5.25773702578">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="197.4126"/>
+      </location>
+    </component>
+  </type>
+  <type name="C19">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="1.43260531538" z="5.3206941592">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="195.0696"/>
+      </location>
+    </component>
+  </type>
+  <type name="C20">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="1.21326640912" z="5.37493873956">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="192.72"/>
+      </location>
+    </component>
+  </type>
+  <type name="C21">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="0.955168885442" z="5.42691364704">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="189.98215784"/>
+      </location>
+    </component>
+  </type>
+  <type name="C22">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="0.73405361952" z="5.46121787104">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="187.65536244"/>
+      </location>
+    </component>
+  </type>
+  <type name="C23">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="0.511432623056" z="5.48666909522">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="185.32536244"/>
+      </location>
+    </component>
+  </type>
+  <type name="C24">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="0.287949459406" z="5.50292524">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="182.99536244"/>
+      </location>
+    </component>
+  </type>
+  <type name="C25T">
+    <component type="eightpack-top">
+      <location y="0.431673" x="0.17600619612" z="5.50764222828">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="181.83036244"/>
+      </location>
+    </component>
+  </type>
+  <type name="C26T">
+    <component type="eightpack-top">
+      <location y="0.431673" x="-0.0480523141568" z="5.51024428302">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="179.50036244"/>
+      </location>
+    </component>
+  </type>
+  <type name="C25B">
+    <component type="eightpack-bottom">
+      <location y="-0.468884" x="0.17600619612" z="5.50764222828">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="181.83036244"/>
+      </location>
+    </component>
+  </type>
+  <type name="C26B">
+    <component type="eightpack-bottom">
+      <location y="-0.468884" x="-0.0480523141568" z="5.51024428302">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="179.50036244"/>
+      </location>
+    </component>
+  </type>
+  <type name="C27">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="-0.42281525673" z="5.4947435952">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="175.5998157"/>
+      </location>
+    </component>
+  </type>
+  <type name="C28">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="-0.658224241588" z="5.47153733224">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="173.1403"/>
+      </location>
+    </component>
+  </type>
+  <type name="C29">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="-0.882973593968" z="5.43979205156">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="170.7803"/>
+      </location>
+    </component>
+  </type>
+  <type name="C30">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="-1.10621978349" z="5.39879295398">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="168.4203"/>
+      </location>
+    </component>
+  </type>
+  <type name="C31">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="-1.32781484906" z="5.34867441312">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="166.0581"/>
+      </location>
+    </component>
+  </type>
+  <type name="C32">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="-1.55303519339" z="5.28766236598">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="163.632"/>
+      </location>
+    </component>
+  </type>
+  <type name="C33">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="-1.77201739703" z="5.21830976402">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="161.2437"/>
+      </location>
+    </component>
+  </type>
+  <type name="C34">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="-1.99960889486" z="5.13516569612">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="158.7243"/>
+      </location>
+    </component>
+  </type>
+  <type name="C35">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="-2.21150431485" z="5.04742302172">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="156.3396"/>
+      </location>
+    </component>
+  </type>
+  <type name="C36">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="-2.41598945122" z="4.95276649526">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="153.9966"/>
+      </location>
+    </component>
+  </type>
+  <type name="C37">
+    <component type="eightpack">
+      <location y="-0.0389000000002" x="-2.61672177696" z="4.8497781084">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="151.6507"/>
+      </location>
+    </component>
+  </type>
+  <component type="D row" idlist="D row">
+    <location/>
+  </component>
+  <type name="D row">
+    <component type="D1">
+      <location/>
+    </component>
+    <component type="D2">
+      <location/>
+    </component>
+    <component type="D3">
+      <location/>
+    </component>
+    <component type="D4">
+      <location/>
+    </component>
+    <component type="D5">
+      <location/>
+    </component>
+    <component type="D6">
+      <location/>
+    </component>
+    <component type="D7">
+      <location/>
+    </component>
+    <component type="D8">
+      <location/>
+    </component>
+    <component type="D9">
+      <location/>
+    </component>
+    <component type="D10">
+      <location/>
+    </component>
+    <component type="D11">
+      <location/>
+    </component>
+    <component type="D12">
+      <location/>
+    </component>
+    <component type="D13">
+      <location/>
+    </component>
+    <component type="D14">
+      <location/>
+    </component>
+    <component type="D15">
+      <location/>
+    </component>
+    <component type="D16">
+      <location/>
+    </component>
+    <component type="D17">
+      <location/>
+    </component>
+    <component type="D18">
+      <location/>
+    </component>
+    <component type="D19">
+      <location/>
+    </component>
+    <component type="D20">
+      <location/>
+    </component>
+    <component type="D21">
+      <location/>
+    </component>
+    <component type="D22">
+      <location/>
+    </component>
+    <component type="D23">
+      <location/>
+    </component>
+    <component type="D24">
+      <location/>
+    </component>
+    <component type="D25">
+      <location/>
+    </component>
+    <component type="D26">
+      <location/>
+    </component>
+    <component type="D27">
+      <location/>
+    </component>
+    <component type="D28">
+      <location/>
+    </component>
+    <component type="D29">
+      <location/>
+    </component>
+    <component type="D30">
+      <location/>
+    </component>
+    <component type="D31">
+      <location/>
+    </component>
+    <component type="D32">
+      <location/>
+    </component>
+    <component type="D33">
+      <location/>
+    </component>
+    <component type="D34">
+      <location/>
+    </component>
+    <component type="D35">
+      <location/>
+    </component>
+    <component type="D36">
+      <location/>
+    </component>
+    <component type="D37">
+      <location/>
+    </component>
+  </type>
+  <type name="D1">
+    <component type="eightpack">
+      <location y="1.22910000001" x="4.57110507672" z="2.8206377674">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="238.323"/>
+      </location>
+    </component>
+  </type>
+  <type name="D2">
+    <component type="eightpack">
+      <location y="1.22910000001" x="4.45107939094" z="3.00647489636">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="235.963"/>
+      </location>
+    </component>
+  </type>
+  <type name="D3">
+    <component type="eightpack">
+      <location y="1.22910000001" x="4.3234927881" z="3.18720437996">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="233.603"/>
+      </location>
+    </component>
+  </type>
+  <type name="D4">
+    <component type="eightpack">
+      <location y="1.22909999011" x="4.18920230992" z="3.36178283446">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="231.25338983"/>
+      </location>
+    </component>
+  </type>
+  <type name="D5">
+    <component type="eightpack">
+      <location y="1.22909999011" x="4.046441869" z="3.53235379888">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="228.88056701"/>
+      </location>
+    </component>
+  </type>
+  <type name="D6">
+    <component type="eightpack">
+      <location y="1.22909999011" x="3.89757971054" z="3.69601869888">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="226.52047601"/>
+      </location>
+    </component>
+  </type>
+  <type name="D7">
+    <component type="eightpack">
+      <location y="1.22909999011" x="3.72157876206" z="3.87194811842">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="223.86555961"/>
+      </location>
+    </component>
+  </type>
+  <type name="D8">
+    <component type="eightpack">
+      <location y="1.22909999011" x="3.5583230586" z="4.02249205914">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="221.49618627"/>
+      </location>
+    </component>
+  </type>
+  <type name="D9">
+    <component type="eightpack">
+      <location y="1.22909999011" x="3.39320041704" z="4.16270439492">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="219.18496575"/>
+      </location>
+    </component>
+  </type>
+  <type name="D10">
+    <component type="eightpack">
+      <location y="1.22909999011" x="3.21560850146" z="4.30135873788">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="216.78104403"/>
+      </location>
+    </component>
+  </type>
+  <type name="D11">
+    <component type="eightpack">
+      <location y="1.22909999011" x="3.03576816772" z="4.43013621718">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="214.42104403"/>
+      </location>
+    </component>
+  </type>
+  <type name="D12">
+    <component type="eightpack">
+      <location y="1.22909999011" x="2.8507685936" z="4.55138591118">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="212.06104403"/>
+      </location>
+    </component>
+  </type>
+  <type name="D13">
+    <component type="eightpack">
+      <location y="1.22909999011" x="2.66093309824" z="4.6649148256">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="209.70104403"/>
+      </location>
+    </component>
+  </type>
+  <type name="D14">
+    <component type="eightpack">
+      <location y="1.22909999011" x="2.43095921681" z="4.7887819515">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="206.914"/>
+      </location>
+    </component>
+  </type>
+  <type name="D15">
+    <component type="eightpack">
+      <location y="1.22910000001" x="2.23344308175" z="4.88411720152">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="204.574"/>
+      </location>
+    </component>
+  </type>
+  <type name="D16">
+    <component type="eightpack">
+      <location y="1.22910000001" x="2.03256714746" z="4.97097887692">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="202.239"/>
+      </location>
+    </component>
+  </type>
+  <type name="D17">
+    <component type="eightpack">
+      <location y="1.22910000001" x="1.82756698926" z="5.04997495972">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="199.895"/>
+      </location>
+    </component>
+  </type>
+  <type name="D18">
+    <component type="eightpack">
+      <location y="1.22910000001" x="1.61940384297" z="5.12050738406">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="197.55"/>
+      </location>
+    </component>
+  </type>
+  <type name="D19">
+    <component type="eightpack">
+      <location y="1.22910000001" x="1.40898478401" z="5.1823505446">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="195.21"/>
+      </location>
+    </component>
+  </type>
+  <type name="D20">
+    <component type="eightpack">
+      <location y="1.22910000001" x="1.19621786562" z="5.23555709554">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="192.87"/>
+      </location>
+    </component>
+  </type>
+  <type name="D21">
+    <component type="eightpack">
+      <location y="1.22910000001" x="0.985335317362" z="5.28028000076">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="190.5702"/>
+      </location>
+    </component>
+  </type>
+  <type name="D22">
+    <component type="eightpack">
+      <location y="1.22910000001" x="0.78360224407" z="5.3139241067">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="188.3885"/>
+      </location>
+    </component>
+  </type>
+  <type name="D23">
+    <component type="eightpack">
+      <location y="1.22910000001" x="0.565047087836" z="5.3415347703">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="186.0385"/>
+      </location>
+    </component>
+  </type>
+  <type name="D24">
+    <component type="eightpack">
+      <location y="1.22910000001" x="0.345548983018" z="5.36021154524">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="183.6885"/>
+      </location>
+    </component>
+  </type>
+  <type name="D25">
+    <component type="eightpack">
+      <location y="1.22910000001" x="0.125469660185" z="5.3698723692">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="181.3385"/>
+      </location>
+    </component>
+  </type>
+  <type name="D26">
+    <component type="eightpack">
+      <location y="1.22910000001" x="-0.0948207044146" z="5.37050099634">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="178.9885"/>
+      </location>
+    </component>
+  </type>
+  <type name="D27">
+    <component type="eightpack">
+      <location y="1.22910000001" x="-0.45265876194" z="5.35136387434">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="175.165"/>
+      </location>
+    </component>
+  </type>
+  <type name="D28">
+    <component type="eightpack">
+      <location y="1.22910000001" x="-0.671703998982" z="5.3283026403">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="172.815"/>
+      </location>
+    </component>
+  </type>
+  <type name="D29">
+    <component type="eightpack">
+      <location y="1.22910000001" x="-0.889619420656" z="5.29627912548">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="170.465"/>
+      </location>
+    </component>
+  </type>
+  <type name="D30">
+    <component type="eightpack">
+      <location y="1.22910000001" x="-1.10603848998" z="5.25534719566">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="168.115"/>
+      </location>
+    </component>
+  </type>
+  <type name="D31">
+    <component type="eightpack">
+      <location y="1.22910000001" x="-1.32059718735" z="5.20557569754">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="165.765"/>
+      </location>
+    </component>
+  </type>
+  <type name="D32">
+    <component type="eightpack">
+      <location y="1.22910000001" x="-1.53293721022" z="5.1470570414">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="163.415"/>
+      </location>
+    </component>
+  </type>
+  <type name="D33">
+    <component type="eightpack">
+      <location y="1.22910000001" x="-1.74030639162" z="5.0807040372">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="161.092"/>
+      </location>
+    </component>
+  </type>
+  <type name="D34">
+    <component type="eightpack">
+      <location y="1.22910000001" x="-1.96180272434" z="5.0013049707">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="158.582"/>
+      </location>
+    </component>
+  </type>
+  <type name="D35">
+    <component type="eightpack">
+      <location y="1.22910000001" x="-2.16506783826" z="4.91676592972">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="156.234"/>
+      </location>
+    </component>
+  </type>
+  <type name="D36">
+    <component type="eightpack">
+      <location y="1.22910000001" x="-2.36510173842" z="4.8237238044">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="153.881"/>
+      </location>
+    </component>
+  </type>
+  <type name="D37">
+    <component type="eightpack">
+      <location y="1.22910000001" x="-2.56172303758" z="4.7222335451">
+        <rot axis-z="0" axis-x="0" axis-y="1" val="151.521"/>
+      </location>
+    </component>
+  </type>
+  <!--STANDARD 8-PACK-->
+  <type name="eightpack">
+    <properties/>
+    <component type="tube">
+      <location x="-0.096012" name="tube1"/>
+      <location x="-0.06858" name="tube2"/>
+      <location x="-0.041148" name="tube3"/>
+      <location x="-0.013716" name="tube4"/>
+      <location x="0.013716" name="tube5"/>
+      <location x="0.041148" name="tube6"/>
+      <location x="0.06858" name="tube7"/>
+      <location x="0.096012" name="tube8"/>
+    </component>
+  </type>
+  <!--8-PACK ABOVE BEAMSTOP-->
+  <type name="eightpack-top">
+    <properties/>
+    <component type="tube-top">
+      <location x="-0.096012" name="tube1"/>
+      <location x="-0.06858" name="tube2"/>
+      <location x="-0.041148" name="tube3"/>
+      <location x="-0.013716" name="tube4"/>
+      <location x="0.013716" name="tube5"/>
+      <location x="0.041148" name="tube6"/>
+      <location x="0.06858" name="tube7"/>
+      <location x="0.096012" name="tube8"/>
+    </component>
+  </type>
+  <!--8-PACK BELOW BEAMSTOP-->
+  <type name="eightpack-bottom">
+    <properties/>
+    <component type="tube-bottom">
+      <location x="-0.096012" name="tube1"/>
+      <location x="-0.06858" name="tube2"/>
+      <location x="-0.041148" name="tube3"/>
+      <location x="-0.013716" name="tube4"/>
+      <location x="0.013716" name="tube5"/>
+      <location x="0.041148" name="tube6"/>
+      <location x="0.06858" name="tube7"/>
+      <location x="0.096012" name="tube8"/>
+    </component>
+  </type>
+  <!--STANDARD 128 PIXEL TUBE-->
+  <type name="tube" outline="yes">
+    <properties/>
+    <component type="pixel">
+      <location y="-0.5953125" name="pixel1"/>
+      <location y="-0.5859375" name="pixel2"/>
+      <location y="-0.5765625" name="pixel3"/>
+      <location y="-0.5671875" name="pixel4"/>
+      <location y="-0.5578125" name="pixel5"/>
+      <location y="-0.5484375" name="pixel6"/>
+      <location y="-0.5390625" name="pixel7"/>
+      <location y="-0.5296875" name="pixel8"/>
+      <location y="-0.5203125" name="pixel9"/>
+      <location y="-0.5109375" name="pixel10"/>
+      <location y="-0.5015625" name="pixel11"/>
+      <location y="-0.4921875" name="pixel12"/>
+      <location y="-0.4828125" name="pixel13"/>
+      <location y="-0.4734375" name="pixel14"/>
+      <location y="-0.4640625" name="pixel15"/>
+      <location y="-0.4546875" name="pixel16"/>
+      <location y="-0.4453125" name="pixel17"/>
+      <location y="-0.4359375" name="pixel18"/>
+      <location y="-0.4265625" name="pixel19"/>
+      <location y="-0.4171875" name="pixel20"/>
+      <location y="-0.4078125" name="pixel21"/>
+      <location y="-0.3984375" name="pixel22"/>
+      <location y="-0.3890625" name="pixel23"/>
+      <location y="-0.3796875" name="pixel24"/>
+      <location y="-0.3703125" name="pixel25"/>
+      <location y="-0.3609375" name="pixel26"/>
+      <location y="-0.3515625" name="pixel27"/>
+      <location y="-0.3421875" name="pixel28"/>
+      <location y="-0.3328125" name="pixel29"/>
+      <location y="-0.3234375" name="pixel30"/>
+      <location y="-0.3140625" name="pixel31"/>
+      <location y="-0.3046875" name="pixel32"/>
+      <location y="-0.2953125" name="pixel33"/>
+      <location y="-0.2859375" name="pixel34"/>
+      <location y="-0.2765625" name="pixel35"/>
+      <location y="-0.2671875" name="pixel36"/>
+      <location y="-0.2578125" name="pixel37"/>
+      <location y="-0.2484375" name="pixel38"/>
+      <location y="-0.2390625" name="pixel39"/>
+      <location y="-0.2296875" name="pixel40"/>
+      <location y="-0.2203125" name="pixel41"/>
+      <location y="-0.2109375" name="pixel42"/>
+      <location y="-0.2015625" name="pixel43"/>
+      <location y="-0.1921875" name="pixel44"/>
+      <location y="-0.1828125" name="pixel45"/>
+      <location y="-0.1734375" name="pixel46"/>
+      <location y="-0.1640625" name="pixel47"/>
+      <location y="-0.1546875" name="pixel48"/>
+      <location y="-0.1453125" name="pixel49"/>
+      <location y="-0.1359375" name="pixel50"/>
+      <location y="-0.1265625" name="pixel51"/>
+      <location y="-0.1171875" name="pixel52"/>
+      <location y="-0.1078125" name="pixel53"/>
+      <location y="-0.0984375" name="pixel54"/>
+      <location y="-0.0890625" name="pixel55"/>
+      <location y="-0.0796875" name="pixel56"/>
+      <location y="-0.0703125" name="pixel57"/>
+      <location y="-0.0609375" name="pixel58"/>
+      <location y="-0.0515625" name="pixel59"/>
+      <location y="-0.0421875" name="pixel60"/>
+      <location y="-0.0328125" name="pixel61"/>
+      <location y="-0.0234375" name="pixel62"/>
+      <location y="-0.0140625" name="pixel63"/>
+      <location y="-0.0046875" name="pixel64"/>
+      <location y="0.0046875" name="pixel65"/>
+      <location y="0.0140625" name="pixel66"/>
+      <location y="0.0234375" name="pixel67"/>
+      <location y="0.0328125" name="pixel68"/>
+      <location y="0.0421875" name="pixel69"/>
+      <location y="0.0515625" name="pixel70"/>
+      <location y="0.0609375" name="pixel71"/>
+      <location y="0.0703125" name="pixel72"/>
+      <location y="0.0796875" name="pixel73"/>
+      <location y="0.0890625" name="pixel74"/>
+      <location y="0.0984375" name="pixel75"/>
+      <location y="0.1078125" name="pixel76"/>
+      <location y="0.1171875" name="pixel77"/>
+      <location y="0.1265625" name="pixel78"/>
+      <location y="0.1359375" name="pixel79"/>
+      <location y="0.1453125" name="pixel80"/>
+      <location y="0.1546875" name="pixel81"/>
+      <location y="0.1640625" name="pixel82"/>
+      <location y="0.1734375" name="pixel83"/>
+      <location y="0.1828125" name="pixel84"/>
+      <location y="0.1921875" name="pixel85"/>
+      <location y="0.2015625" name="pixel86"/>
+      <location y="0.2109375" name="pixel87"/>
+      <location y="0.2203125" name="pixel88"/>
+      <location y="0.2296875" name="pixel89"/>
+      <location y="0.2390625" name="pixel90"/>
+      <location y="0.2484375" name="pixel91"/>
+      <location y="0.2578125" name="pixel92"/>
+      <location y="0.2671875" name="pixel93"/>
+      <location y="0.2765625" name="pixel94"/>
+      <location y="0.2859375" name="pixel95"/>
+      <location y="0.2953125" name="pixel96"/>
+      <location y="0.3046875" name="pixel97"/>
+      <location y="0.3140625" name="pixel98"/>
+      <location y="0.3234375" name="pixel99"/>
+      <location y="0.3328125" name="pixel100"/>
+      <location y="0.3421875" name="pixel101"/>
+      <location y="0.3515625" name="pixel102"/>
+      <location y="0.3609375" name="pixel103"/>
+      <location y="0.3703125" name="pixel104"/>
+      <location y="0.3796875" name="pixel105"/>
+      <location y="0.3890625" name="pixel106"/>
+      <location y="0.3984375" name="pixel107"/>
+      <location y="0.4078125" name="pixel108"/>
+      <location y="0.4171875" name="pixel109"/>
+      <location y="0.4265625" name="pixel110"/>
+      <location y="0.4359375" name="pixel111"/>
+      <location y="0.4453125" name="pixel112"/>
+      <location y="0.4546875" name="pixel113"/>
+      <location y="0.4640625" name="pixel114"/>
+      <location y="0.4734375" name="pixel115"/>
+      <location y="0.4828125" name="pixel116"/>
+      <location y="0.4921875" name="pixel117"/>
+      <location y="0.5015625" name="pixel118"/>
+      <location y="0.5109375" name="pixel119"/>
+      <location y="0.5203125" name="pixel120"/>
+      <location y="0.5296875" name="pixel121"/>
+      <location y="0.5390625" name="pixel122"/>
+      <location y="0.5484375" name="pixel123"/>
+      <location y="0.5578125" name="pixel124"/>
+      <location y="0.5671875" name="pixel125"/>
+      <location y="0.5765625" name="pixel126"/>
+      <location y="0.5859375" name="pixel127"/>
+      <location y="0.5953125" name="pixel128"/>
+    </component>
+  </type>
+  <!--SMALL TOP 128 PIXEL TUBE-->
+  <type name="tube-top" outline="yes">
+    <properties/>
+    <component type="pixel-top">
+      <location y="-0.12852796875" name="pixel1"/>
+      <location y="-0.12650390625" name="pixel2"/>
+      <location y="-0.12447984375" name="pixel3"/>
+      <location y="-0.12245578125" name="pixel4"/>
+      <location y="-0.12043171875" name="pixel5"/>
+      <location y="-0.11840765625" name="pixel6"/>
+      <location y="-0.11638359375" name="pixel7"/>
+      <location y="-0.11435953125" name="pixel8"/>
+      <location y="-0.11233546875" name="pixel9"/>
+      <location y="-0.11031140625" name="pixel10"/>
+      <location y="-0.10828734375" name="pixel11"/>
+      <location y="-0.10626328125" name="pixel12"/>
+      <location y="-0.10423921875" name="pixel13"/>
+      <location y="-0.10221515625" name="pixel14"/>
+      <location y="-0.10019109375" name="pixel15"/>
+      <location y="-0.09816703125" name="pixel16"/>
+      <location y="-0.09614296875" name="pixel17"/>
+      <location y="-0.09411890625" name="pixel18"/>
+      <location y="-0.09209484375" name="pixel19"/>
+      <location y="-0.09007078125" name="pixel20"/>
+      <location y="-0.08804671875" name="pixel21"/>
+      <location y="-0.08602265625" name="pixel22"/>
+      <location y="-0.08399859375" name="pixel23"/>
+      <location y="-0.08197453125" name="pixel24"/>
+      <location y="-0.07995046875" name="pixel25"/>
+      <location y="-0.07792640625" name="pixel26"/>
+      <location y="-0.07590234375" name="pixel27"/>
+      <location y="-0.07387828125" name="pixel28"/>
+      <location y="-0.07185421875" name="pixel29"/>
+      <location y="-0.06983015625" name="pixel30"/>
+      <location y="-0.06780609375" name="pixel31"/>
+      <location y="-0.06578203125" name="pixel32"/>
+      <location y="-0.06375796875" name="pixel33"/>
+      <location y="-0.06173390625" name="pixel34"/>
+      <location y="-0.05970984375" name="pixel35"/>
+      <location y="-0.05768578125" name="pixel36"/>
+      <location y="-0.05566171875" name="pixel37"/>
+      <location y="-0.05363765625" name="pixel38"/>
+      <location y="-0.05161359375" name="pixel39"/>
+      <location y="-0.04958953125" name="pixel40"/>
+      <location y="-0.04756546875" name="pixel41"/>
+      <location y="-0.04554140625" name="pixel42"/>
+      <location y="-0.04351734375" name="pixel43"/>
+      <location y="-0.04149328125" name="pixel44"/>
+      <location y="-0.03946921875" name="pixel45"/>
+      <location y="-0.03744515625" name="pixel46"/>
+      <location y="-0.03542109375" name="pixel47"/>
+      <location y="-0.03339703125" name="pixel48"/>
+      <location y="-0.03137296875" name="pixel49"/>
+      <location y="-0.02934890625" name="pixel50"/>
+      <location y="-0.02732484375" name="pixel51"/>
+      <location y="-0.02530078125" name="pixel52"/>
+      <location y="-0.02327671875" name="pixel53"/>
+      <location y="-0.02125265625" name="pixel54"/>
+      <location y="-0.01922859375" name="pixel55"/>
+      <location y="-0.01720453125" name="pixel56"/>
+      <location y="-0.01518046875" name="pixel57"/>
+      <location y="-0.01315640625" name="pixel58"/>
+      <location y="-0.01113234375" name="pixel59"/>
+      <location y="-0.00910828125" name="pixel60"/>
+      <location y="-0.00708421875" name="pixel61"/>
+      <location y="-0.00506015625" name="pixel62"/>
+      <location y="-0.00303609375" name="pixel63"/>
+      <location y="-0.00101203125" name="pixel64"/>
+      <location y="0.00101203125" name="pixel65"/>
+      <location y="0.00303609375" name="pixel66"/>
+      <location y="0.00506015625" name="pixel67"/>
+      <location y="0.00708421875" name="pixel68"/>
+      <location y="0.00910828125" name="pixel69"/>
+      <location y="0.01113234375" name="pixel70"/>
+      <location y="0.01315640625" name="pixel71"/>
+      <location y="0.01518046875" name="pixel72"/>
+      <location y="0.01720453125" name="pixel73"/>
+      <location y="0.01922859375" name="pixel74"/>
+      <location y="0.02125265625" name="pixel75"/>
+      <location y="0.02327671875" name="pixel76"/>
+      <location y="0.02530078125" name="pixel77"/>
+      <location y="0.02732484375" name="pixel78"/>
+      <location y="0.02934890625" name="pixel79"/>
+      <location y="0.03137296875" name="pixel80"/>
+      <location y="0.03339703125" name="pixel81"/>
+      <location y="0.03542109375" name="pixel82"/>
+      <location y="0.03744515625" name="pixel83"/>
+      <location y="0.03946921875" name="pixel84"/>
+      <location y="0.04149328125" name="pixel85"/>
+      <location y="0.04351734375" name="pixel86"/>
+      <location y="0.04554140625" name="pixel87"/>
+      <location y="0.04756546875" name="pixel88"/>
+      <location y="0.04958953125" name="pixel89"/>
+      <location y="0.05161359375" name="pixel90"/>
+      <location y="0.05363765625" name="pixel91"/>
+      <location y="0.05566171875" name="pixel92"/>
+      <location y="0.05768578125" name="pixel93"/>
+      <location y="0.05970984375" name="pixel94"/>
+      <location y="0.06173390625" name="pixel95"/>
+      <location y="0.06375796875" name="pixel96"/>
+      <location y="0.06578203125" name="pixel97"/>
+      <location y="0.06780609375" name="pixel98"/>
+      <location y="0.06983015625" name="pixel99"/>
+      <location y="0.07185421875" name="pixel100"/>
+      <location y="0.07387828125" name="pixel101"/>
+      <location y="0.07590234375" name="pixel102"/>
+      <location y="0.07792640625" name="pixel103"/>
+      <location y="0.07995046875" name="pixel104"/>
+      <location y="0.08197453125" name="pixel105"/>
+      <location y="0.08399859375" name="pixel106"/>
+      <location y="0.08602265625" name="pixel107"/>
+      <location y="0.08804671875" name="pixel108"/>
+      <location y="0.09007078125" name="pixel109"/>
+      <location y="0.09209484375" name="pixel110"/>
+      <location y="0.09411890625" name="pixel111"/>
+      <location y="0.09614296875" name="pixel112"/>
+      <location y="0.09816703125" name="pixel113"/>
+      <location y="0.10019109375" name="pixel114"/>
+      <location y="0.10221515625" name="pixel115"/>
+      <location y="0.10423921875" name="pixel116"/>
+      <location y="0.10626328125" name="pixel117"/>
+      <location y="0.10828734375" name="pixel118"/>
+      <location y="0.11031140625" name="pixel119"/>
+      <location y="0.11233546875" name="pixel120"/>
+      <location y="0.11435953125" name="pixel121"/>
+      <location y="0.11638359375" name="pixel122"/>
+      <location y="0.11840765625" name="pixel123"/>
+      <location y="0.12043171875" name="pixel124"/>
+      <location y="0.12245578125" name="pixel125"/>
+      <location y="0.12447984375" name="pixel126"/>
+      <location y="0.12650390625" name="pixel127"/>
+      <location y="0.12852796875" name="pixel128"/>
+    </component>
+  </type>
+  <!--SMALL BOTTOM 128 PIXEL TUBE-->
+  <type name="tube-bottom" outline="yes">
+    <properties/>
+    <component type="pixel-bottom">
+      <location y="-0.165448257812" name="pixel1"/>
+      <location y="-0.162842773438" name="pixel2"/>
+      <location y="-0.160237289063" name="pixel3"/>
+      <location y="-0.157631804687" name="pixel4"/>
+      <location y="-0.155026320312" name="pixel5"/>
+      <location y="-0.152420835937" name="pixel6"/>
+      <location y="-0.149815351563" name="pixel7"/>
+      <location y="-0.147209867188" name="pixel8"/>
+      <location y="-0.144604382812" name="pixel9"/>
+      <location y="-0.141998898437" name="pixel10"/>
+      <location y="-0.139393414062" name="pixel11"/>
+      <location y="-0.136787929688" name="pixel12"/>
+      <location y="-0.134182445313" name="pixel13"/>
+      <location y="-0.131576960937" name="pixel14"/>
+      <location y="-0.128971476562" name="pixel15"/>
+      <location y="-0.126365992187" name="pixel16"/>
+      <location y="-0.123760507813" name="pixel17"/>
+      <location y="-0.121155023437" name="pixel18"/>
+      <location y="-0.118549539062" name="pixel19"/>
+      <location y="-0.115944054687" name="pixel20"/>
+      <location y="-0.113338570312" name="pixel21"/>
+      <location y="-0.110733085938" name="pixel22"/>
+      <location y="-0.108127601562" name="pixel23"/>
+      <location y="-0.105522117187" name="pixel24"/>
+      <location y="-0.102916632812" name="pixel25"/>
+      <location y="-0.100311148437" name="pixel26"/>
+      <location y="-0.0977056640625" name="pixel27"/>
+      <location y="-0.0951001796875" name="pixel28"/>
+      <location y="-0.0924946953125" name="pixel29"/>
+      <location y="-0.0898892109375" name="pixel30"/>
+      <location y="-0.0872837265625" name="pixel31"/>
+      <location y="-0.0846782421875" name="pixel32"/>
+      <location y="-0.0820727578125" name="pixel33"/>
+      <location y="-0.0794672734375" name="pixel34"/>
+      <location y="-0.0768617890625" name="pixel35"/>
+      <location y="-0.0742563046875" name="pixel36"/>
+      <location y="-0.0716508203125" name="pixel37"/>
+      <location y="-0.0690453359375" name="pixel38"/>
+      <location y="-0.0664398515625" name="pixel39"/>
+      <location y="-0.0638343671875" name="pixel40"/>
+      <location y="-0.0612288828125" name="pixel41"/>
+      <location y="-0.0586233984375" name="pixel42"/>
+      <location y="-0.0560179140625" name="pixel43"/>
+      <location y="-0.0534124296875" name="pixel44"/>
+      <location y="-0.0508069453125" name="pixel45"/>
+      <location y="-0.0482014609375" name="pixel46"/>
+      <location y="-0.0455959765625" name="pixel47"/>
+      <location y="-0.0429904921875" name="pixel48"/>
+      <location y="-0.0403850078125" name="pixel49"/>
+      <location y="-0.0377795234375" name="pixel50"/>
+      <location y="-0.0351740390625" name="pixel51"/>
+      <location y="-0.0325685546875" name="pixel52"/>
+      <location y="-0.0299630703125" name="pixel53"/>
+      <location y="-0.0273575859375" name="pixel54"/>
+      <location y="-0.0247521015625" name="pixel55"/>
+      <location y="-0.0221466171875" name="pixel56"/>
+      <location y="-0.0195411328125" name="pixel57"/>
+      <location y="-0.0169356484375" name="pixel58"/>
+      <location y="-0.0143301640625" name="pixel59"/>
+      <location y="-0.0117246796875" name="pixel60"/>
+      <location y="-0.0091191953125" name="pixel61"/>
+      <location y="-0.0065137109375" name="pixel62"/>
+      <location y="-0.0039082265625" name="pixel63"/>
+      <location y="-0.0013027421875" name="pixel64"/>
+      <location y="0.0013027421875" name="pixel65"/>
+      <location y="0.0039082265625" name="pixel66"/>
+      <location y="0.0065137109375" name="pixel67"/>
+      <location y="0.0091191953125" name="pixel68"/>
+      <location y="0.0117246796875" name="pixel69"/>
+      <location y="0.0143301640625" name="pixel70"/>
+      <location y="0.0169356484375" name="pixel71"/>
+      <location y="0.0195411328125" name="pixel72"/>
+      <location y="0.0221466171875" name="pixel73"/>
+      <location y="0.0247521015625" name="pixel74"/>
+      <location y="0.0273575859375" name="pixel75"/>
+      <location y="0.0299630703125" name="pixel76"/>
+      <location y="0.0325685546875" name="pixel77"/>
+      <location y="0.0351740390625" name="pixel78"/>
+      <location y="0.0377795234375" name="pixel79"/>
+      <location y="0.0403850078125" name="pixel80"/>
+      <location y="0.0429904921875" name="pixel81"/>
+      <location y="0.0455959765625" name="pixel82"/>
+      <location y="0.0482014609375" name="pixel83"/>
+      <location y="0.0508069453125" name="pixel84"/>
+      <location y="0.0534124296875" name="pixel85"/>
+      <location y="0.0560179140625" name="pixel86"/>
+      <location y="0.0586233984375" name="pixel87"/>
+      <location y="0.0612288828125" name="pixel88"/>
+      <location y="0.0638343671875" name="pixel89"/>
+      <location y="0.0664398515625" name="pixel90"/>
+      <location y="0.0690453359375" name="pixel91"/>
+      <location y="0.0716508203125" name="pixel92"/>
+      <location y="0.0742563046875" name="pixel93"/>
+      <location y="0.0768617890625" name="pixel94"/>
+      <location y="0.0794672734375" name="pixel95"/>
+      <location y="0.0820727578125" name="pixel96"/>
+      <location y="0.0846782421875" name="pixel97"/>
+      <location y="0.0872837265625" name="pixel98"/>
+      <location y="0.0898892109375" name="pixel99"/>
+      <location y="0.0924946953125" name="pixel100"/>
+      <location y="0.0951001796875" name="pixel101"/>
+      <location y="0.0977056640625" name="pixel102"/>
+      <location y="0.100311148437" name="pixel103"/>
+      <location y="0.102916632813" name="pixel104"/>
+      <location y="0.105522117188" name="pixel105"/>
+      <location y="0.108127601563" name="pixel106"/>
+      <location y="0.110733085938" name="pixel107"/>
+      <location y="0.113338570312" name="pixel108"/>
+      <location y="0.115944054688" name="pixel109"/>
+      <location y="0.118549539063" name="pixel110"/>
+      <location y="0.121155023438" name="pixel111"/>
+      <location y="0.123760507813" name="pixel112"/>
+      <location y="0.126365992187" name="pixel113"/>
+      <location y="0.128971476563" name="pixel114"/>
+      <location y="0.131576960938" name="pixel115"/>
+      <location y="0.134182445313" name="pixel116"/>
+      <location y="0.136787929688" name="pixel117"/>
+      <location y="0.139393414062" name="pixel118"/>
+      <location y="0.141998898438" name="pixel119"/>
+      <location y="0.144604382813" name="pixel120"/>
+      <location y="0.147209867188" name="pixel121"/>
+      <location y="0.149815351563" name="pixel122"/>
+      <location y="0.152420835937" name="pixel123"/>
+      <location y="0.155026320313" name="pixel124"/>
+      <location y="0.157631804688" name="pixel125"/>
+      <location y="0.160237289063" name="pixel126"/>
+      <location y="0.162842773438" name="pixel127"/>
+      <location y="0.165448257812" name="pixel128"/>
+    </component>
+  </type>
+  <!--PIXEL FOR STANDARD 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 y="1.0" x="0.0" z="0.0"/>
+      <radius val="0.0127"/>
+      <height val="0.009375"/>
+    </cylinder>
+    <algebra val="cyl-approx"/>
+  </type>
+  <!--PIXEL FOR SMALL TOP 128 PIXEL TUBE-->
+  <type is="detector" name="pixel-top">
+    <cylinder id="cyl-approx">
+      <centre-of-bottom-base p="0.0" r="0.0" t="0.0"/>
+      <axis y="1.0" x="0.0" z="0.0"/>
+      <radius val="0.0127"/>
+      <height val="0.0020240625"/>
+    </cylinder>
+    <algebra val="cyl-approx"/>
+  </type>
+  <!--PIXEL FOR SMALL BOTTOM 128 PIXEL TUBE-->
+  <type is="detector" name="pixel-bottom">
+    <cylinder id="cyl-approx">
+      <centre-of-bottom-base p="0.0" r="0.0" t="0.0"/>
+      <axis y="1.0" x="0.0" z="0.0"/>
+      <radius val="0.0127"/>
+      <height val="0.002605484375"/>
+    </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 y="0.0" x="0.0" z="0.0"/>
+      <axis y="0.0" x="0.0" z="1.0"/>
+      <radius val="0.01"/>
+      <height val="0.03"/>
+    </cylinder>
+    <algebra val="cyl-approx"/>
+  </type>
+  <!--DETECTOR IDs-->
+  <idlist idname="B row">
+    <id start="37888" end="38911"/>
+    <id start="38912" end="39935"/>
+    <id start="39936" end="40959"/>
+    <id start="40960" end="41983"/>
+    <id start="41984" end="43007"/>
+    <id start="43008" end="44031"/>
+    <id start="44032" end="45055"/>
+    <id start="45056" end="46079"/>
+    <id start="46080" end="47103"/>
+    <id start="47104" end="48127"/>
+    <id start="48128" end="49151"/>
+    <id start="49152" end="50175"/>
+    <id start="50176" end="51199"/>
+    <id start="51200" end="52223"/>
+    <id start="52224" end="53247"/>
+    <id start="53248" end="54271"/>
+    <id start="54272" end="55295"/>
+    <id start="55296" end="56319"/>
+    <id start="56320" end="57343"/>
+    <id start="57344" end="58367"/>
+    <id start="58368" end="59391"/>
+    <id start="59392" end="60415"/>
+    <id start="60416" end="61439"/>
+    <id start="61440" end="62463"/>
+    <id start="62464" end="63487"/>
+    <id start="63488" end="64511"/>
+    <id start="64512" end="65535"/>
+    <id start="65536" end="66559"/>
+    <id start="66560" end="67583"/>
+    <id start="67584" end="68607"/>
+    <id start="68608" end="69631"/>
+    <id start="69632" end="70655"/>
+    <id start="70656" end="71679"/>
+    <id start="71680" end="72703"/>
+    <id start="72704" end="73727"/>
+    <id start="73728" end="74751"/>
+    <id start="74752" end="75775"/>
+  </idlist>
+  <idlist idname="C row">
+    <id start="75776" end="76799"/>
+    <id start="76800" end="77823"/>
+    <id start="77824" end="78847"/>
+    <id start="78848" end="79871"/>
+    <id start="79872" end="80895"/>
+    <id start="80896" end="81919"/>
+    <id start="81920" end="82943"/>
+    <id start="82944" end="83967"/>
+    <id start="83968" end="84991"/>
+    <id start="84992" end="86015"/>
+    <id start="86016" end="87039"/>
+    <id start="87040" end="88063"/>
+    <id start="88064" end="89087"/>
+    <id start="89088" end="90111"/>
+    <id start="90112" end="91135"/>
+    <id start="91136" end="92159"/>
+    <id start="92160" end="93183"/>
+    <id start="93184" end="94207"/>
+    <id start="94208" end="95231"/>
+    <id start="95232" end="96255"/>
+    <id start="96256" end="97279"/>
+    <id start="97280" end="98303"/>
+    <id start="98304" end="99327"/>
+    <id start="99328" end="100351"/>
+    <id start="100352" end="101375"/>
+    <id start="101376" end="102399"/>
+    <id start="102400" end="103423"/>
+    <id start="103424" end="104447"/>
+    <id start="104448" end="105471"/>
+    <id start="105472" end="106495"/>
+    <id start="106496" end="107519"/>
+    <id start="107520" end="108543"/>
+    <id start="108544" end="109567"/>
+    <id start="109568" end="110591"/>
+    <id start="110592" end="111615"/>
+    <id start="111616" end="112639"/>
+    <id start="112640" end="113663"/>
+    <id start="113664" end="114687"/>
+    <id start="114688" end="115711"/>
+  </idlist>
+  <idlist idname="D row">
+    <id start="115712" end="116735"/>
+    <id start="116736" end="117759"/>
+    <id start="117760" end="118783"/>
+    <id start="118784" end="119807"/>
+    <id start="119808" end="120831"/>
+    <id start="120832" end="121855"/>
+    <id start="121856" end="122879"/>
+    <id start="122880" end="123903"/>
+    <id start="123904" end="124927"/>
+    <id start="124928" end="125951"/>
+    <id start="125952" end="126975"/>
+    <id start="126976" end="127999"/>
+    <id start="128000" end="129023"/>
+    <id start="129024" end="130047"/>
+    <id start="130048" end="131071"/>
+    <id start="131072" end="132095"/>
+    <id start="132096" end="133119"/>
+    <id start="133120" end="134143"/>
+    <id start="134144" end="135167"/>
+    <id start="135168" end="136191"/>
+    <id start="136192" end="137215"/>
+    <id start="137216" end="138239"/>
+    <id start="138240" end="139263"/>
+    <id start="139264" end="140287"/>
+    <id start="140288" end="141311"/>
+    <id start="141312" end="142335"/>
+    <id start="142336" end="143359"/>
+    <id start="143360" end="144383"/>
+    <id start="144384" end="145407"/>
+    <id start="145408" end="146431"/>
+    <id start="146432" end="147455"/>
+    <id start="147456" end="148479"/>
+    <id start="148480" end="149503"/>
+    <id start="149504" end="150527"/>
+    <id start="150528" end="151551"/>
+    <id start="151552" end="152575"/>
+    <id start="152576" end="153599"/>
+  </idlist>
+  <!--MONITOR IDs-->
+  <idlist idname="monitors">
+    <id val="-1"/>
+    <id val="-2"/>
+  </idlist>
+  <!--DETECTOR PARAMETERS-->
+  <component-link name="B row">
+    <parameter name="tube_pressure">
+      <value units="atm" val="10.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>
+  <component-link name="C row">
+    <parameter name="tube_pressure">
+      <value units="atm" val="10.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>
+  <component-link name="D row">
+    <parameter name="tube_pressure">
+      <value units="atm" val="10.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/SEQUOIA_Definition.xml b/instrument/SEQUOIA_Definition.xml
index ae0a7cf3160892b2a4e763b9bc8bb9dfe66fe886..bfc60dbcf2292a9c39c90b8c10c9d06a05964ce6 100644
--- a/instrument/SEQUOIA_Definition.xml
+++ b/instrument/SEQUOIA_Definition.xml
@@ -4,7 +4,7 @@
 <instrument xmlns="http://www.mantidproject.org/IDF/1.0" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd"
- valid-to="2100-01-31 23:59:59" name="SEQUOIA" valid-from="2012-04-04 14:15:46.929098">
+ valid-to="2100-01-31 23:59:59" name="SEQUOIA" valid-from="2017-11-14 00:00:00">
   <!--For runs after 19889 -->
   <defaults>
     <length unit="metre"/>
@@ -150,265 +150,305 @@
       <location/>
     </component>
   </type>
+
+
+
   <type name="B1">
     <component type="eightpack">
-      <location y="-1.30353562" x="4.60563316108" z="2.76377527">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="239.032627"/>
+      <location x="4.60563316" y="-1.30353562" z="2.76377527">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-120.96737300"/>
       </location>
     </component>
   </type>
+
   <type name="B2">
     <component type="eightpack">
-      <location y="-1.303534985" x="4.5367332938" z="2.8754758848">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="236.732627"/>
+      <location x="4.53673329" y="-1.30353498" z="2.87547588">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-123.26737300"/>
       </location>
     </component>
   </type>
+
   <type name="B3">
     <component type="eightpack">
-      <location y="-1.29480004006" x="4.31906484166" z="3.19313298634">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="233.52406849"/>
+      <location x="4.32508796" y="-1.29480004" z="3.17838441">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-126.03975949"/>
       </location>
     </component>
   </type>
+
   <type name="B4">
     <component type="eightpack">
-      <location y="-1.29480004006" x="4.18256210476" z="3.36996307718">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="231.14100232"/>
+      <location x="4.18866859" y="-1.29480004" z="3.35768576">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-130.73635071"/>
       </location>
     </component>
   </type>
+
   <type name="B5">
     <component type="eightpack">
-      <location y="-1.29480004006" x="4.0394219694" z="3.54026506322">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="228.76774758"/>
+      <location x="4.03408387" y="-1.29480004" z="3.52380664">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-133.23225242"/>
       </location>
     </component>
   </type>
+
   <type name="B6">
     <component type="eightpack">
-      <location y="-1.29480004006" x="3.88900961084" z="3.70488877512">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="226.38891513"/>
+      <location x="3.89604104" y="-1.29480004" z="3.69605380">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-133.59755814"/>
       </location>
     </component>
   </type>
+
   <type name="B7">
     <component type="eightpack">
-      <location y="-1.29480004006" x="3.71577988364" z="3.87745665452">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="223.78023066"/>
+      <location x="3.71929890" y="-1.29480004" z="3.86302362">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-134.43907120"/>
       </location>
     </component>
   </type>
+
   <type name="B8">
     <component type="eightpack">
-      <location y="-1.29480004006" x="3.55275443372" z="4.0273746986">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="221.41717399"/>
+      <location x="3.55198594" y="-1.29480004" z="4.01116995">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-140.58282601"/>
       </location>
     </component>
   </type>
+
   <type name="B9">
     <component type="eightpack">
-      <location y="-1.29480004006" x="3.38385871106" z="4.17028409782">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="219.05662215"/>
+      <location x="3.38288547" y="-1.29480004" z="4.15489954">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-138.94337785"/>
       </location>
     </component>
   </type>
+
   <type name="B10">
     <component type="eightpack">
-      <location y="-1.29480004006" x="3.20998708014" z="4.30555569164">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="216.70619963"/>
+      <location x="3.20856785" y="-1.29480004" z="4.28814601">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-145.29380037"/>
       </location>
     </component>
   </type>
+
   <type name="B11">
     <component type="eightpack">
-      <location y="-1.29480004006" x="3.02996424486" z="4.43407703226">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="214.34619963"/>
+      <location x="3.02000290" y="-1.29480004" z="4.41187658">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-145.65316791"/>
       </location>
     </component>
   </type>
+
   <type name="B12">
     <component type="eightpack">
-      <location y="-1.29480004006" x="2.84480731774" z="4.5550843874">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="211.98619963"/>
+      <location x="2.83477748" y="-1.29480004" z="4.53219306">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-150.01380037"/>
       </location>
     </component>
   </type>
+
   <type name="B13">
     <component type="eightpack">
-      <location y="-1.29480004006" x="2.65482458366" z="4.6683646917">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="209.62619963"/>
+      <location x="2.64110812" y="-1.29480004" z="4.64038880">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-150.37571272"/>
       </location>
     </component>
   </type>
+
   <type name="B14">
     <component type="eightpack">
-      <location y="-1.29480004006" x="2.4603383163" z="4.77372578146">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="207.26619963"/>
+      <location x="2.42016459" y="-1.29480004" z="4.75766497">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-154.20290073"/>
       </location>
     </component>
   </type>
+
   <type name="B15">
     <component type="eightpack">
-      <location y="-1.29480004006" x="2.22317726585" z="4.88876471826">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="204.45377863"/>
+      <location x="2.21521234" y="-1.29480004" z="4.84460733">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-155.53900705"/>
       </location>
     </component>
   </type>
+
   <type name="B16">
     <component type="eightpack">
-      <location y="-1.29480004006" x="2.01893382776" z="4.97651229486">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="202.08202669"/>
+      <location x="2.00923259" y="-1.29480004" z="4.93196737">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-157.91138643"/>
       </location>
     </component>
   </type>
+
   <type name="B17">
     <component type="eightpack">
-      <location y="-1.29480004006" x="1.81182191864" z="5.05564016048">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="199.71647921"/>
+      <location x="1.79989540" y="-1.29480004" z="5.00713336">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-162.28352079"/>
       </location>
     </component>
   </type>
+
   <type name="B18">
     <component type="eightpack">
-      <location y="-1.29480004006" x="1.60068188829" z="5.12639931284">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="197.3406045"/>
+      <location x="1.58897659" y="-1.29480004" z="5.07332939">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-160.76312018"/>
       </location>
     </component>
   </type>
+
   <type name="B19">
     <component type="eightpack">
-      <location y="-1.29479999993" x="1.38823150065" z="5.18797469134">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="194.9806045"/>
+      <location x="1.38823150" y="-1.29480000" z="5.18797469">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-165.01939550"/>
       </location>
     </component>
   </type>
+
   <type name="B20">
     <component type="eightpack">
-      <location y="-1.29479999993" x="1.17342296557" z="5.24073913242">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="192.6206045"/>
+      <location x="1.15312896" y="-1.29480000" z="5.17106157">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-165.74312465"/>
       </location>
     </component>
   </type>
+
   <type name="B21">
     <component type="eightpack">
-      <location y="-1.29479999993" x="0.92524769992" z="5.29019704722">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="189.9206045"/>
+      <location x="0.90484069" y="-1.29480000" z="5.21640688">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-168.07939550"/>
       </location>
     </component>
   </type>
+
   <type name="B22">
     <component type="eightpack">
-      <location y="-1.29479999993" x="0.706622533158" z="5.32380997974">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="187.5606045"/>
+      <location x="0.67538331" y="-1.29480000" z="5.22415270">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-170.43939550"/>
       </location>
     </component>
   </type>
+
   <type name="B23">
     <component type="eightpack">
-      <location y="-1.29479999993" x="0.48679868223" z="5.34839182796">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="185.2006045"/>
+      <location x="0.44007592" y="-1.29480000" z="5.26821910">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-172.79939550"/>
       </location>
     </component>
   </type>
+
   <type name="B24">
     <component type="eightpack">
-      <location y="-1.29479999993" x="0.266149046568" z="5.3639008927">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="182.8406045"/>
+      <location x="0.18960402" y="-1.29480000" z="5.28024042">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-175.15939550"/>
       </location>
     </component>
   </type>
+
   <type name="B25">
     <component type="eightpack">
-      <location y="-1.29479999993" x="0.045047927176" z="5.37031086464">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="180.4806045"/>
+      <location x="0.01466154" y="-1.29480000" z="5.33357573">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-177.51939550"/>
       </location>
     </component>
   </type>
+
   <type name="B26">
     <component type="eightpack">
-      <location y="-1.29479999993" x="-0.207962706248" z="5.36647180196">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="177.78077169"/>
+      <location x="-0.09080780" y="-1.29480000" z="5.31769720">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="175.78077169"/>
       </location>
     </component>
   </type>
+
   <type name="B27">
     <component type="eightpack">
-      <location y="-1.29479999993" x="-0.428767559532" z="5.35335656276">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="175.42077169"/>
+      <location x="-0.35773309" y="-1.29480000" z="5.26980698">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="173.42077169"/>
       </location>
     </component>
   </type>
+
   <type name="B28">
     <component type="eightpack">
-      <location y="-1.29479999993" x="-0.648845069592" z="5.3311601149">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="173.06077169"/>
+      <location x="-0.59159503" y="-1.29480000" z="5.24629441">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="171.06077169"/>
       </location>
     </component>
   </type>
+
   <type name="B29">
     <component type="eightpack">
-      <location y="-1.29479999993" x="-0.867821906974" z="5.29992011642">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="170.70077169"/>
+      <location x="-0.83175778" y="-1.29480000" z="5.22538666">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="172.70077169"/>
       </location>
     </component>
   </type>
+
   <type name="B30">
     <component type="eightpack">
-      <location y="-1.29479999993" x="-1.08532660785" z="5.25968955934">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="168.34077169"/>
+      <location x="-1.04781390" y="-1.29480000" z="5.18902672">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="170.34077169"/>
       </location>
     </component>
   </type>
+
   <type name="B31">
     <component type="eightpack">
-      <location y="-1.29479999993" x="-1.30099020726" z="5.21053668838">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="165.98077169"/>
+      <location x="-1.27165523" y="-1.29480000" z="5.15219040">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="165.97471636"/>
       </location>
     </component>
   </type>
+
   <type name="B32">
     <component type="eightpack">
-      <location y="-1.29480004006" x="-1.51446642013" z="5.15261142704">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="163.62077169"/>
+      <location x="-1.48889791" y="-1.29480004" z="5.10215436">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="163.61590264"/>
       </location>
     </component>
   </type>
+
   <type name="B33">
     <component type="eightpack">
-      <location y="-1.29480004006" x="-1.72664610677" z="5.08615521502">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="161.24869638"/>
+      <location x="-1.69931559" y="-1.29480004" z="5.03778769">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="163.24869638"/>
       </location>
     </component>
   </type>
+
   <type name="B34">
     <component type="eightpack">
-      <location y="-1.29480004006" x="-1.95342748836" z="5.00448226686">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="158.67752934"/>
+      <location x="-1.93536281" y="-1.29480004" z="4.96546377">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="158.67455058"/>
       </location>
     </component>
   </type>
+
   <type name="B35">
     <component type="eightpack">
-      <location y="-1.29479999993" x="-2.15779859854" z="4.91969141536">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="156.31752934"/>
+      <location x="-2.13714329" y="-1.29480000" z="4.88845537">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="156.31649375"/>
       </location>
     </component>
   </type>
+
   <type name="B36">
     <component type="eightpack">
-      <location y="-1.29480004006" x="-2.35202492205" z="4.83001371308">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="154.03575652"/>
+      <location x="-2.33740510" y="-1.29480004" z="4.79624681">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="156.03575652"/>
       </location>
     </component>
   </type>
+
   <type name="B37">
     <component type="eightpack">
-      <location y="-1.29480004006" x="-2.54885044204" z="4.72893432164">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="151.67575652"/>
+      <location x="-2.53854557" y="-1.29480004" z="4.70435809">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="153.67575652"/>
       </location>
     </component>
   </type>
+
   <component type="C row" idlist="C row">
     <location/>
   </component>
@@ -531,279 +571,322 @@
       <location/>
     </component>
   </type>
+
+
   <type name="C1">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="4.6875281408" z="2.89948601712">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="238.261"/>
+      <location x="4.68752814" y="-0.03890000" z="2.89948602">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-121.73900000"/>
       </location>
     </component>
   </type>
+
   <type name="C2">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="4.56415688386" z="3.09005035024">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="235.901"/>
+      <location x="4.56415688" y="-0.03890000" z="3.09005035">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-124.09900000"/>
       </location>
     </component>
   </type>
+
   <type name="C3">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="4.43304318622" z="3.27537285488">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="233.541"/>
+      <location x="4.44152039" y="-0.03890000" z="3.26875643">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-128.43191466"/>
       </location>
     </component>
   </type>
+
   <type name="C4">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="4.29500585244" z="3.45438429518">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="231.191"/>
+      <location x="4.30245611" y="-0.03890000" z="3.44722278">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-129.54935813"/>
       </location>
     </component>
   </type>
+
   <type name="C5">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="4.14967007504" z="3.62768575198">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="228.8397"/>
+      <location x="4.15046910" y="-0.03890000" z="3.62726009">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-131.16090642"/>
       </location>
     </component>
   </type>
+
   <type name="C6">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="3.99533264178" z="3.7969858655">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="226.4581"/>
+      <location x="4.00043213" y="-0.03890000" z="3.79150338">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-134.87781995"/>
       </location>
     </component>
   </type>
+
   <type name="C7">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="3.81281980386" z="3.97800034472">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="223.7854"/>
+      <location x="3.81887648" y="-0.03890000" z="3.96989553">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-136.21201782"/>
       </location>
     </component>
   </type>
+
   <type name="C8">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="3.64602183672" z="4.13139723376">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="221.4289"/>
+      <location x="3.65103853" y="-0.03890000" z="4.12467528">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-138.57202879"/>
       </location>
     </component>
   </type>
+
   <type name="C9">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="3.47173969862" z="4.27892822902">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="219.0544"/>
+      <location x="3.47772803" y="-0.03890000" z="4.27168431">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-142.94560000"/>
       </location>
     </component>
   </type>
+
   <type name="C10">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="3.29203392138" z="4.41864602934">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="216.6873"/>
+      <location x="3.29697500" y="-0.03890000" z="4.41286144">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-144.49150348"/>
       </location>
     </component>
   </type>
+
   <type name="C11">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="3.1075271606" z="4.55031056154">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="214.3302"/>
+      <location x="3.11095084" y="-0.03890000" z="4.54489513">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-147.37791861"/>
       </location>
     </component>
   </type>
+
   <type name="C12">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="2.9161672309" z="4.67522753548">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="211.9538"/>
+      <location x="2.91972054" y="-0.03890000" z="4.67012515">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-148.04570659"/>
       </location>
     </component>
   </type>
+
   <type name="C13">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="2.71943750244" z="4.79241055994">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="209.5726"/>
+      <location x="2.72318215" y="-0.03890000" z="4.78720431">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-150.42728504"/>
       </location>
     </component>
   </type>
+
   <type name="C14">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="2.49170903842" z="4.91467906064">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="206.8847"/>
+      <location x="2.49518898" y="-0.03890000" z="4.91013204">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-153.11550665"/>
       </location>
     </component>
   </type>
+
   <type name="C15">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="2.28458593857" z="5.01427223712">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="204.4948"/>
+      <location x="2.29085022" y="-0.03890000" z="5.00755538">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-157.50520000"/>
       </location>
     </component>
   </type>
+
   <type name="C16">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="2.07474382485" z="5.10464666648">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="202.1189"/>
+      <location x="2.07971832" y="-0.03890000" z="5.09933415">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-159.67747624"/>
       </location>
     </component>
   </type>
+
   <type name="C17">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="1.86274311677" z="5.18575022284">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="199.7585"/>
+      <location x="1.86823359" y="-0.03890000" z="5.17927085">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-159.31237483"/>
       </location>
     </component>
   </type>
+
   <type name="C18">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="1.64894478364" z="5.25773702578">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="197.4126"/>
+      <location x="1.65373656" y="-0.03890000" z="5.25175170">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-162.58521231"/>
       </location>
     </component>
   </type>
+
   <type name="C19">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="1.43260531538" z="5.3206941592">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="195.0696"/>
+      <location x="1.43601246" y="-0.03890000" z="5.31531240">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-164.92911667"/>
       </location>
     </component>
   </type>
+
   <type name="C20">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="1.21326640912" z="5.37493873956">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="192.72"/>
+      <location x="1.21525847" y="-0.03890000" z="5.36844336">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-167.27933073"/>
       </location>
     </component>
   </type>
+
   <type name="C21">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="0.955168885442" z="5.42691364704">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="189.98215784"/>
+      <location x="0.96734789" y="-0.03890000" z="5.41757004">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-170.01252792"/>
       </location>
     </component>
   </type>
+
   <type name="C22">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="0.73405361952" z="5.46121787104">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="187.65536244"/>
+      <location x="0.74310975" y="-0.03890000" z="5.44833626">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-172.34084747"/>
       </location>
     </component>
   </type>
+
   <type name="C23">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="0.511432623056" z="5.48666909522">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="185.32536244"/>
+      <location x="0.51611317" y="-0.03890000" z="5.46889453">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-174.67333539"/>
       </location>
     </component>
   </type>
+
   <type name="C24">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="0.287949459406" z="5.50292524">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="182.99536244"/>
+      <location x="0.28602580" y="-0.03890000" z="5.49485310">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-177.00407517"/>
       </location>
     </component>
   </type>
+
+
   <type name="C25T">
     <component type="eightpack-top">
-      <location y="0.431673" x="0.17600619612" z="5.50764222828">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="181.83036244"/>
+      <location x="0.09212690" y="0.43167300" z="5.46198943">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="179.83036244"/>
       </location>
     </component>
   </type>
+
   <type name="C26T">
     <component type="eightpack-top">
-      <location y="0.431673" x="-0.0480523141568" z="5.51024428302">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="179.50036244"/>
+      <location x="-0.19589577" y="0.43167300" z="5.48742613">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-178.49963756"/>
       </location>
     </component>
   </type>
+
   <type name="C25B">
     <component type="eightpack-bottom">
-      <location y="-0.468884" x="0.17600619612" z="5.50764222828">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="181.83036244"/>
+      <location x="0.03848187" y="-0.46888400" z="5.51449283">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-176.16963756"/>
       </location>
     </component>
   </type>
+
   <type name="C26B">
     <component type="eightpack-bottom">
-      <location y="-0.468884" x="-0.0480523141568" z="5.51024428302">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="179.50036244"/>
+      <location x="-0.16610316" y="-0.46888400" z="5.50534429">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="177.50036244"/>
       </location>
     </component>
   </type>
+
+
   <type name="C27">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="-0.42281525673" z="5.4947435952">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="175.5998157"/>
+      <location x="-0.43450969" y="-0.03890000" z="5.47475185">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="175.59410540"/>
       </location>
     </component>
   </type>
+
   <type name="C28">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="-0.658224241588" z="5.47153733224">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="173.1403"/>
+      <location x="-0.66081582" y="-0.03890000" z="5.45973585">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="173.13995799"/>
       </location>
     </component>
   </type>
+
   <type name="C29">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="-0.882973593968" z="5.43979205156">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="170.7803"/>
+      <location x="-0.88535518" y="-0.03890000" z="5.43136348">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="170.77959045"/>
       </location>
     </component>
   </type>
+
   <type name="C30">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="-1.10621978349" z="5.39879295398">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="168.4203"/>
+      <location x="-1.10847049" y="-0.03890000" z="5.39200274">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="168.41988227"/>
       </location>
     </component>
   </type>
+
   <type name="C31">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="-1.32781484906" z="5.34867441312">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="166.0581"/>
+      <location x="-1.33021840" y="-0.03890000" z="5.34243710">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="166.05724233"/>
       </location>
     </component>
   </type>
+
   <type name="C32">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="-1.55303519339" z="5.28766236598">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="163.632"/>
+      <location x="-1.54970752" y="-0.03890000" z="5.28566674">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="163.63206010"/>
       </location>
     </component>
   </type>
+
   <type name="C33">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="-1.77201739703" z="5.21830976402">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="161.2437"/>
+      <location x="-1.76631632" y="-0.03890000" z="5.21922266">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="161.24445453"/>
       </location>
     </component>
   </type>
+
   <type name="C34">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="-1.99960889486" z="5.13516569612">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="158.7243"/>
+      <location x="-1.99821145" y="-0.03890000" z="5.13779260">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="158.72507943"/>
       </location>
     </component>
   </type>
+
   <type name="C35">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="-2.21150431485" z="5.04742302172">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="156.3396"/>
+      <location x="-2.20688155" y="-0.03890000" z="5.05127937">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="156.34197478"/>
       </location>
     </component>
   </type>
+
   <type name="C36">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="-2.41598945122" z="4.95276649526">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="153.9966"/>
+      <location x="-2.41521494" y="-0.03890000" z="4.95518370">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="153.99717971"/>
       </location>
     </component>
   </type>
+
   <type name="C37">
     <component type="eightpack">
-      <location y="-0.0389000000002" x="-2.61672177696" z="4.8497781084">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="151.6507"/>
+      <location x="-2.61905356" y="-0.03890000" z="4.85174310">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="151.65074678"/>
       </location>
     </component>
   </type>
+
   <component type="D row" idlist="D row">
     <location/>
   </component>
@@ -920,265 +1003,303 @@
       <location/>
     </component>
   </type>
+
   <type name="D1">
     <component type="eightpack">
-      <location y="1.22910000001" x="4.57110507672" z="2.8206377674">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="238.323"/>
+      <location x="4.57110508" y="1.22910000" z="2.82063777">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-121.67700000"/>
       </location>
     </component>
   </type>
+
   <type name="D2">
     <component type="eightpack">
-      <location y="1.22910000001" x="4.45107939094" z="3.00647489636">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="235.963"/>
+      <location x="4.45107939" y="1.22910000" z="3.00647490">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-124.03700000"/>
       </location>
     </component>
   </type>
+
   <type name="D3">
     <component type="eightpack">
-      <location y="1.22910000001" x="4.3234927881" z="3.18720437996">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="233.603"/>
+      <location x="4.32562254" y="1.22910000" z="3.17527848">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-126.39481562"/>
       </location>
     </component>
   </type>
+
   <type name="D4">
     <component type="eightpack">
-      <location y="1.22909999011" x="4.18920230992" z="3.36178283446">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="231.25338983"/>
+      <location x="4.19024547" y="1.22909999" z="3.34888797">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-130.16527786"/>
       </location>
     </component>
   </type>
+
   <type name="D5">
     <component type="eightpack">
-      <location y="1.22909999011" x="4.046441869" z="3.53235379888">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="228.88056701"/>
+      <location x="4.04057606" y="1.22909999" z="3.51400427">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-133.11943299"/>
       </location>
     </component>
   </type>
+
   <type name="D6">
     <component type="eightpack">
-      <location y="1.22909999011" x="3.89757971054" z="3.69601869888">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="226.52047601"/>
+      <location x="3.89992629" y="1.22909999" z="3.68747804">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-133.47127159"/>
       </location>
     </component>
   </type>
+
   <type name="D7">
     <component type="eightpack">
-      <location y="1.22909999011" x="3.72157876206" z="3.87194811842">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="223.86555961"/>
+      <location x="3.71712561" y="1.22909999" z="3.85067850">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-138.09352040"/>
       </location>
     </component>
   </type>
+
   <type name="D8">
     <component type="eightpack">
-      <location y="1.22909999011" x="3.5583230586" z="4.02249205914">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="221.49618627"/>
+      <location x="3.55149251" y="1.22909999" z="4.00021060">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-140.18327205"/>
       </location>
     </component>
   </type>
+
   <type name="D9">
     <component type="eightpack">
-      <location y="1.22909999011" x="3.39320041704" z="4.16270439492">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="219.18496575"/>
+      <location x="3.38537409" y="1.22909999" z="4.14327501">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-142.81503425"/>
       </location>
     </component>
   </type>
+
   <type name="D10">
     <component type="eightpack">
-      <location y="1.22909999011" x="3.21560850146" z="4.30135873788">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="216.78104403"/>
+      <location x="3.20567983" y="1.22909999" z="4.27410397">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-143.21838586"/>
       </location>
     </component>
   </type>
+
   <type name="D11">
     <component type="eightpack">
-      <location y="1.22909999011" x="3.03576816772" z="4.43013621718">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="214.42104403"/>
+      <location x="3.02514131" y="1.22909999" z="4.40098907">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-145.57869146"/>
       </location>
     </component>
   </type>
+
   <type name="D12">
     <component type="eightpack">
-      <location y="1.22909999011" x="2.8507685936" z="4.55138591118">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="212.06104403"/>
+      <location x="2.83822852" y="1.22909999" z="4.51862094">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-147.93482291"/>
       </location>
     </component>
   </type>
+
   <type name="D13">
     <component type="eightpack">
-      <location y="1.22909999011" x="2.66093309824" z="4.6649148256">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="209.70104403"/>
+      <location x="2.64462431" y="1.22909999" z="4.62399219">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-150.30161665"/>
       </location>
     </component>
   </type>
+
   <type name="D14">
     <component type="eightpack">
-      <location y="1.22909999011" x="2.43095921681" z="4.7887819515">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="206.914"/>
+      <location x="2.42209904" y="1.22909999" z="4.74028095">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-153.06925621"/>
       </location>
     </component>
   </type>
+
   <type name="D15">
     <component type="eightpack">
-      <location y="1.22910000001" x="2.23344308175" z="4.88411720152">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="204.574"/>
+      <location x="2.22069737" y="1.22910000" z="4.83068516">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-155.42172481"/>
       </location>
     </component>
   </type>
+
   <type name="D16">
     <component type="eightpack">
-      <location y="1.22910000001" x="2.03256714746" z="4.97097887692">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="202.239"/>
+      <location x="2.02116273" y="1.22910000" z="4.91162670">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-157.76440699"/>
       </location>
     </component>
   </type>
+
   <type name="D17">
     <component type="eightpack">
-      <location y="1.22910000001" x="1.82756698926" z="5.04997495972">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="199.895"/>
+      <location x="1.80807003" y="1.22910000" z="4.98762876">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-162.10500000"/>
       </location>
     </component>
   </type>
+
   <type name="D18">
     <component type="eightpack">
-      <location y="1.22910000001" x="1.61940384297" z="5.12050738406">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="197.55"/>
+      <location x="1.59732827" y="1.22910000" z="5.05348200">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-162.44065504"/>
       </location>
     </component>
   </type>
+
   <type name="D19">
     <component type="eightpack">
-      <location y="1.22910000001" x="1.40898478401" z="5.1823505446">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="195.21"/>
+      <location x="1.38212538" y="1.22910000" z="5.09666056">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-162.79000000"/>
       </location>
     </component>
   </type>
+
   <type name="D20">
     <component type="eightpack">
-      <location y="1.22910000001" x="1.19621786562" z="5.23555709554">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="192.87"/>
+      <location x="1.16544269" y="1.22910000" z="5.14003543">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-169.13000000"/>
       </location>
     </component>
   </type>
+
   <type name="D21">
     <component type="eightpack">
-      <location y="1.22910000001" x="0.985335317362" z="5.28028000076">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="190.5702"/>
+      <location x="0.92532593" y="1.22910000" z="5.17057445">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-167.42980000"/>
       </location>
     </component>
   </type>
+
   <type name="D22">
     <component type="eightpack">
-      <location y="1.22910000001" x="0.78360224407" z="5.3139241067">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="188.3885"/>
+      <location x="0.71060011" y="1.22910000" z="5.18736890">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-173.61150000"/>
       </location>
     </component>
   </type>
+
   <type name="D23">
     <component type="eightpack">
-      <location y="1.22910000001" x="0.565047087836" z="5.3415347703">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="186.0385"/>
+      <location x="0.48164236" y="1.22910000" z="5.20368182">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-175.96150000"/>
       </location>
     </component>
   </type>
+
   <type name="D24">
     <component type="eightpack">
-      <location y="1.22910000001" x="0.345548983018" z="5.36021154524">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="183.6885"/>
+      <location x="0.26369605" y="1.22910000" z="5.21159572">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-174.31150000"/>
       </location>
     </component>
   </type>
+
   <type name="D25">
     <component type="eightpack">
-      <location y="1.22910000001" x="0.125469660185" z="5.3698723692">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="181.3385"/>
+      <location x="0.06617699" y="1.22910000" z="5.21734046">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="-178.84091257"/>
       </location>
     </component>
   </type>
+
   <type name="D26">
     <component type="eightpack">
-      <location y="1.22910000001" x="-0.0948207044146" z="5.37050099634">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="178.9885"/>
+      <location x="-0.16676294" y="1.22910000" z="5.22006198">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="176.98850000"/>
       </location>
     </component>
   </type>
+
   <type name="D27">
     <component type="eightpack">
-      <location y="1.22910000001" x="-0.45265876194" z="5.35136387434">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="175.165"/>
+      <location x="-0.40194500" y="1.22910000" z="5.21464587">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="173.16500000"/>
       </location>
     </component>
   </type>
+
   <type name="D28">
     <component type="eightpack">
-      <location y="1.22910000001" x="-0.671703998982" z="5.3283026403">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="172.815"/>
+      <location x="-0.62471030" y="1.22910000" z="5.20497816">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="172.86287063"/>
       </location>
     </component>
   </type>
+
   <type name="D29">
     <component type="eightpack">
-      <location y="1.22910000001" x="-0.889619420656" z="5.29627912548">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="170.465"/>
+      <location x="-0.84698897" y="1.22910000" z="5.18880218">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="170.54161119"/>
       </location>
     </component>
   </type>
+
   <type name="D30">
     <component type="eightpack">
-      <location y="1.22910000001" x="-1.10603848998" z="5.25534719566">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="168.115"/>
+      <location x="-1.06502357" y="1.22910000" z="5.15994415">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="168.09928742"/>
       </location>
     </component>
   </type>
+
   <type name="D31">
     <component type="eightpack">
-      <location y="1.22910000001" x="-1.32059718735" z="5.20557569754">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="165.765"/>
+      <location x="-1.27963336" y="1.22910000" z="5.12817396">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="163.76500000"/>
       </location>
     </component>
   </type>
+
   <type name="D32">
     <component type="eightpack">
-      <location y="1.22910000001" x="-1.53293721022" z="5.1470570414">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="163.415"/>
+      <location x="-1.49766720" y="1.22910000" z="5.08217793">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="165.41500000"/>
       </location>
     </component>
   </type>
+
   <type name="D33">
     <component type="eightpack">
-      <location y="1.22910000001" x="-1.74030639162" z="5.0807040372">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="161.092"/>
+      <location x="-1.70438263" y="1.22910000" z="5.01426999">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="161.08460684"/>
       </location>
     </component>
   </type>
+
   <type name="D34">
     <component type="eightpack">
-      <location y="1.22910000001" x="-1.96180272434" z="5.0013049707">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="158.582"/>
+      <location x="-1.93321328" y="1.22910000" z="4.94302276">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="160.58200000"/>
       </location>
     </component>
   </type>
+
   <type name="D35">
     <component type="eightpack">
-      <location y="1.22910000001" x="-2.16506783826" z="4.91676592972">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="156.234"/>
+      <location x="-2.14240965" y="1.22910000" z="4.86983735">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="157.56952266"/>
       </location>
     </component>
   </type>
+
   <type name="D36">
     <component type="eightpack">
-      <location y="1.22910000001" x="-2.36510173842" z="4.8237238044">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="153.881"/>
+      <location x="-2.34599340" y="1.22910000" z="4.78604450">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="153.87709788"/>
       </location>
     </component>
   </type>
+
   <type name="D37">
     <component type="eightpack">
-      <location y="1.22910000001" x="-2.56172303758" z="4.7222335451">
-        <rot axis-z="0" axis-x="0" axis-y="1" val="151.521"/>
+      <location x="-2.54477954" y="1.22910000" z="4.69529234">
+         <rot axis-z="0" axis-x="0" axis-y="1" val="151.52119987"/>
       </location>
     </component>
   </type>
+
   <!--STANDARD 8-PACK-->
   <type name="eightpack">
     <properties/>
diff --git a/qt/scientific_interfaces/CMakeLists.txt b/qt/scientific_interfaces/CMakeLists.txt
index e979e681458c44050ef2a469c5abd13d92cd78ac..25a9fa612bf0b3eab71e068b2ce4bf437bbb6835 100644
--- a/qt/scientific_interfaces/CMakeLists.txt
+++ b/qt/scientific_interfaces/CMakeLists.txt
@@ -30,6 +30,7 @@ set ( TEST_FILES
   test/ALCLatestFileFinderTest.h
   test/ALCPeakFittingModelTest.h
   test/ALCPeakFittingPresenterTest.h
+  test/EnggDiffFittingModelTest.h
   test/EnggDiffFittingPresenterTest.h
   test/EnggDiffractionPresenterTest.h
   test/IO_MuonGroupingTest.h
diff --git a/qt/scientific_interfaces/EnggDiffraction/CMakeLists.txt b/qt/scientific_interfaces/EnggDiffraction/CMakeLists.txt
index 985648af0074a208841bb5256b44c65d0f60990f..e5e0b3be88254d266056ec745716c1e6405d0117 100644
--- a/qt/scientific_interfaces/EnggDiffraction/CMakeLists.txt
+++ b/qt/scientific_interfaces/EnggDiffraction/CMakeLists.txt
@@ -1,4 +1,5 @@
 set ( SRC_FILES
+    EnggDiffFittingModel.cpp
 	EnggDiffFittingPresenter.cpp
 	EnggDiffFittingViewQtWidget.cpp
 	EnggDiffractionPresenter.cpp
@@ -9,6 +10,7 @@ set ( SRC_FILES
 # IMPORTANT: Include files are required in the MOC_FILES set. Scroll down to find it.
 set ( INC_FILES
 	EnggDiffCalibSettings.h
+	EnggDiffFittingModel.h
 	EnggDiffFittingPresWorker.h
 	EnggDiffFittingPresenter.h
 	EnggDiffFittingViewQtWidget.h
@@ -21,6 +23,7 @@ set ( INC_FILES
 )
 
 set ( MOC_FILES
+    EnggDiffFittingModel.h
     EnggDiffFittingPresenter.h
     EnggDiffFittingPresWorker.h
     EnggDiffFittingViewQtWidget.h
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingModel.cpp b/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingModel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6c9cd5cedc9430afbbe35531f3efaf034bc8f7be
--- /dev/null
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingModel.cpp
@@ -0,0 +1,133 @@
+#include "EnggDiffFittingModel.h"
+
+#include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/MatrixWorkspace_fwd.h"
+#include "MantidAPI/Run.h"
+#include "MantidAPI/WorkspaceGroup.h"
+#include "MantidKernel/PropertyWithValue.h"
+
+#include <algorithm>
+#include <numeric>
+
+using namespace Mantid;
+
+namespace {
+
+template <typename T> void insertInOrder(const T &item, std::vector<T> &vec) {
+  vec.insert(std::upper_bound(vec.begin(), vec.end(), item), item);
+}
+
+bool isDigit(const std::string &text) {
+  return std::all_of(text.cbegin(), text.cend(), ::isdigit);
+}
+
+} // anonymous namespace
+
+namespace MantidQT {
+namespace CustomInterfaces {
+
+void EnggDiffFittingModel::addWorkspace(const int runNumber, const size_t bank,
+                                        const API::MatrixWorkspace_sptr ws) {
+  m_wsMap[bank - 1][runNumber] = ws;
+}
+
+API::MatrixWorkspace_sptr
+EnggDiffFittingModel::getWorkspace(const int runNumber, const size_t bank) {
+  if (bank < 1 || bank > m_wsMap.size()) {
+    return nullptr;
+  }
+  if (m_wsMap[bank - 1].find(runNumber) == m_wsMap[bank - 1].end()) {
+    return nullptr;
+  }
+  return m_wsMap[bank - 1][runNumber];
+}
+
+std::vector<int> EnggDiffFittingModel::getAllRunNumbers() const {
+  std::vector<int> runNumbers;
+
+  for (const auto &workspaces : m_wsMap) {
+    for (const auto &kvPair : workspaces) {
+      const auto runNumber = kvPair.first;
+      if (std::find(runNumbers.begin(), runNumbers.end(), runNumber) ==
+          runNumbers.end()) {
+        insertInOrder(runNumber, runNumbers);
+      }
+    }
+  }
+
+  return runNumbers;
+}
+
+void EnggDiffFittingModel::loadWorkspaces(const std::string &filename) {
+  auto loadAlg = API::AlgorithmManager::Instance().create("Load");
+  loadAlg->initialize();
+
+  loadAlg->setPropertyValue("Filename", filename);
+  loadAlg->setPropertyValue("OutputWorkspace", FOCUSED_WS_NAME);
+  loadAlg->execute();
+
+  API::AnalysisDataServiceImpl &ADS = API::AnalysisDataService::Instance();
+  if (filename.find(",") == std::string::npos) { // Only 1 run loaded
+    const auto ws = ADS.retrieveWS<API::MatrixWorkspace>(FOCUSED_WS_NAME);
+    addWorkspace(ws->getRunNumber(), guessBankID(ws), ws);
+  } else {
+    const auto group_ws = ADS.retrieveWS<API::WorkspaceGroup>(FOCUSED_WS_NAME);
+    for (auto iter = group_ws->begin(); iter != group_ws->end(); ++iter) {
+      const auto ws = boost::dynamic_pointer_cast<API::MatrixWorkspace>(*iter);
+      addWorkspace(ws->getRunNumber(), guessBankID(ws), ws);
+    }
+  }
+}
+
+std::vector<std::pair<int, size_t>>
+EnggDiffFittingModel::getRunNumbersAndBanksIDs() {
+  std::vector<std::pair<int, size_t>> pairs;
+
+  const auto runNumbers = getAllRunNumbers();
+  for (const auto runNumber : runNumbers) {
+    for (size_t i = 0; i < m_wsMap.size(); ++i) {
+      if (m_wsMap[i].find(runNumber) != m_wsMap[i].end()) {
+        pairs.push_back(std::pair<int, size_t>(runNumber, i + 1));
+      }
+    }
+  }
+  return pairs;
+}
+
+size_t
+EnggDiffFittingModel::guessBankID(API::MatrixWorkspace_const_sptr ws) const {
+  if (ws->run().hasProperty("bankid")) {
+    const auto log = dynamic_cast<Kernel::PropertyWithValue<int> *>(
+        ws->run().getLogData("bankid"));
+    return boost::lexical_cast<size_t>(log->value());
+  }
+
+  // couldn't get it from sample logs - try using the old naming convention
+  auto name = ws->getName();
+  std::vector<std::string> chunks;
+  boost::split(chunks, name, boost::is_any_of("_"));
+  bool isNum = isDigit(chunks.back());
+  if (!chunks.empty() && isNum) {
+    try {
+      return boost::lexical_cast<size_t>(chunks.back());
+    } catch (boost::exception &) {
+      // If we get a bad cast or something goes wrong then
+      // the file is probably not what we were expecting
+      // so throw a runtime error
+      throw std::runtime_error(
+          "Failed to fit file: The data was not what is expected. "
+          "Does the file contain a focused workspace?");
+    }
+  }
+
+  throw std::runtime_error("Could not guess run number from input workspace. "
+                           "Are you sure it has been focused correctly?");
+}
+
+const std::string EnggDiffFittingModel::FOCUSED_WS_NAME =
+    "engggui_fitting_focused_ws";
+
+} // namespace CustomInterfaces
+} // namespace MantidQT
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingModel.h b/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingModel.h
new file mode 100644
index 0000000000000000000000000000000000000000..9993fa1315b0b009a8e8ff0a20f0847a5cb082e6
--- /dev/null
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingModel.h
@@ -0,0 +1,38 @@
+#ifndef MANTIDQTCUSTOMINTERFACES_ENGGDIFFRACTION_ENGGDIFFFITTINGMODEL_H_
+#define MANTIDQTCUSTOMINTERFACES_ENGGDIFFRACTION_ENGGDIFFFITTINGMODEL_H_
+
+#include "DllConfig.h"
+#include "MantidAPI/MatrixWorkspace_fwd.h"
+
+#include <array>
+#include <unordered_map>
+#include <vector>
+
+using namespace Mantid;
+
+namespace MantidQT {
+namespace CustomInterfaces {
+
+class MANTIDQT_ENGGDIFFRACTION_DLL EnggDiffFittingModel {
+public:
+  API::MatrixWorkspace_sptr getWorkspace(const int runNumber,
+                                         const size_t bank);
+  std::vector<int> getAllRunNumbers() const;
+  void loadWorkspaces(const std::string &filename);
+  std::vector<std::pair<int, size_t>> getRunNumbersAndBanksIDs();
+  void addWorkspace(const int runNumber, const size_t bank,
+                    const API::MatrixWorkspace_sptr ws);
+
+private:
+  static const size_t MAX_BANKS = 2;
+  static const std::string FOCUSED_WS_NAME;
+  std::array<std::unordered_map<int, API::MatrixWorkspace_sptr>, MAX_BANKS>
+      m_wsMap;
+
+  size_t guessBankID(API::MatrixWorkspace_const_sptr) const;
+};
+
+} // namespace CustomInterfaces
+} // namespace MantidQT
+
+#endif // MANTIDQTCUSTOMINTERFACES_ENGGDIFFRACTION_ENGGDIFFFITTINGMODEL_H_
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingPresenter.cpp b/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingPresenter.cpp
index 09808dcdff316a764bf5b3de387bdfb1784ce812..385f141bdac433f4b9e83598548e44aad63f594a 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingPresenter.cpp
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingPresenter.cpp
@@ -1,6 +1,7 @@
 #include "EnggDiffFittingPresenter.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
@@ -9,6 +10,7 @@
 #include "MantidQtWidgets/LegacyQwt/QwtHelper.h"
 #include "EnggDiffFittingPresWorker.h"
 
+#include <boost/algorithm/string.hpp>
 #include <boost/lexical_cast.hpp>
 #include <cctype>
 #include <fstream>
@@ -29,6 +31,7 @@ Mantid::Kernel::Logger g_log("EngineeringDiffractionGUI");
 
 const bool EnggDiffFittingPresenter::g_useAlignDetectors = true;
 
+// MOVE THIS TO THE MODEL
 const std::string EnggDiffFittingPresenter::g_focusedFittingWSName =
     "engggui_fitting_focused_ws";
 
@@ -124,6 +127,10 @@ void EnggDiffFittingPresenter::notify(
   case IEnggDiffFittingPresenter::LogMsg:
     processLogMsg();
     break;
+
+  case IEnggDiffFittingPresenter::selectRun:
+    processSelectRun();
+    break;
   }
 }
 
@@ -345,6 +352,16 @@ std::vector<std::string> EnggDiffFittingPresenter::processFullPathInput(
   return foundFullFilePaths;
 }
 
+void EnggDiffFittingPresenter::processSelectRun() {
+  const auto workspaceID = m_view->getFittingListWidgetCurrentValue();
+  std::vector<std::string> tokens;
+
+  boost::split(tokens, workspaceID, boost::is_any_of("_"));
+  const auto ws =
+      m_model.getWorkspace(std::stoi(tokens[0]), std::stoi(tokens[1]));
+  plotFocusedFile(false, ws);
+}
+
 /**
   * Takes the full path of a file which has been selected through
   * browse, the run number the user has input and stores the
@@ -703,40 +720,60 @@ EnggDiffFittingPresenter::enableMultiRun(const std::string &firstRun,
 
 void EnggDiffFittingPresenter::processStart() {}
 
-void EnggDiffFittingPresenter::processLoad() {
-  // while file text-area is not empty
-  // while directory vector is not empty
-  // if loaded here set a global variable true so doesnt load again?
-
-  try {
-    MatrixWorkspace_sptr focusedWS;
-    const std::string focusedFile = m_view->getFittingRunNo();
-    Poco::Path selectedfPath(focusedFile);
+size_t EnggDiffFittingPresenter::findBankID(
+    Mantid::API::MatrixWorkspace_sptr ws) const {
+  // MOVE THIS TO THE MODEL
+  size_t bankID = 1;
 
-    if (!focusedFile.empty() && selectedfPath.isFile()) {
-      runLoadAlg(focusedFile, focusedWS);
-      setDifcTzero(focusedWS);
-      convertUnits(g_focusedFittingWSName);
-      plotFocusedFile(false);
+  auto name = ws->getName();
+  std::vector<std::string> chunks;
+  boost::split(chunks, name, boost::is_any_of("_"));
+  bool isNum = isDigit(chunks.back());
+  if (!chunks.empty() && isNum) {
+    try {
+      bankID = boost::lexical_cast<size_t>(chunks.back());
+    } catch (boost::exception &) {
+      // If we get a bad cast or something goes wrong then
+      // the file is probably not what we were expecting
+      // so throw a runtime error
+      throw std::runtime_error(
+          "Failed to fit file: The data was not what is expected. "
+          "Does the file contain focused " +
+          m_view->getCurrentInstrument() + " workspace?");
+    }
+  }
+  return bankID;
+}
 
-      m_view->showStatus(
-          "Focused file loaded! (Click 'Select "
-          "Peak' to activate peak picker tool, hold Shift + Click "
-          "Peak, Click 'Add Peak')");
+void EnggDiffFittingPresenter::processLoad() {
+  const std::string filenames = m_view->getFittingRunNo();
 
-    } else {
-      m_view->userWarning("No File Found",
-                          "Please select a focused file to load");
-      m_view->showStatus("Error while plotting the focused workspace");
-    }
-  } catch (std::invalid_argument &ia) {
-    m_view->userWarning(
-        "Failed to load the selected focus file",
-        "The focus file failed to load, please check the logger for more"
-        " information.");
-    g_log.error("Failed to load file. Error message: ");
-    g_log.error(ia.what());
+  try {
+    m_model.loadWorkspaces(filenames);
+  } catch (Poco::PathSyntaxException &ex) {
+    warnFileNotFound(ex);
+    return;
+  } catch (std::invalid_argument &ex) {
+    warnFileNotFound(ex);
+    return;
+  } catch (Mantid::Kernel::Exception::NotFoundError &ex) {
+    warnFileNotFound(ex);
+    return;
   }
+
+  const auto runNoBankPairs = m_model.getRunNumbersAndBanksIDs();
+  std::vector<std::string> workspaceIDs;
+  std::transform(
+      runNoBankPairs.begin(), runNoBankPairs.end(),
+      std::back_inserter(workspaceIDs), [](const std::pair<int, size_t> &pair) {
+        return std::to_string(pair.first) + "_" + std::to_string(pair.second);
+      });
+  m_view->enableFittingListWidget(true);
+  m_view->clearFittingListWidget();
+  std::for_each(workspaceIDs.begin(), workspaceIDs.end(),
+                [&](const std::string &workspaceID) {
+                  m_view->addRunNoItem(workspaceID);
+                });
 }
 
 void EnggDiffFittingPresenter::processShutDown() {
@@ -921,31 +958,7 @@ std::string EnggDiffFittingPresenter::validateFittingexpectedPeaks(
 }
 
 void EnggDiffFittingPresenter::setDifcTzero(MatrixWorkspace_sptr wks) const {
-  size_t bankID = 1;
-  // attempt to guess bankID - this should be done in code that is currently
-  // in the view
-  auto fittingFilename = m_view->getFittingRunNo();
-  Poco::File fittingFile(fittingFilename);
-  if (fittingFile.exists()) {
-    Poco::Path path(fittingFile.path());
-    auto name = path.getBaseName();
-    std::vector<std::string> chunks;
-    boost::split(chunks, name, boost::is_any_of("_"));
-    bool isNum = isDigit(chunks.back());
-    if (!chunks.empty() && isNum) {
-      try {
-        bankID = boost::lexical_cast<size_t>(chunks.back());
-      } catch (boost::exception &) {
-        // If we get a bad cast or something goes wrong then
-        // the file is probably not what we were expecting
-        // so throw a runtime error
-        throw std::runtime_error(
-            "Failed to fit file: The data was not what is expected. "
-            "Does the file contain focused " +
-            m_view->getCurrentInstrument() + " workspace?");
-      }
-    }
-  }
+  const auto bankID = findBankID(wks);
 
   const std::string units = "none";
   auto &run = wks->mutableRun();
@@ -1714,19 +1727,20 @@ bool EnggDiffFittingPresenter::isDigit(const std::string &text) const {
   return std::all_of(text.cbegin(), text.cend(), ::isdigit);
 }
 
-void EnggDiffFittingPresenter::plotFocusedFile(bool plotSinglePeaks) {
-  AnalysisDataServiceImpl &ADS = Mantid::API::AnalysisDataService::Instance();
+void EnggDiffFittingPresenter::warnFileNotFound(const std::exception &ex) {
+  m_view->showStatus("Error while loading focused run");
+  m_view->userWarning("Invalid file selected",
+                      "Mantid could not load the selected file. "
+                      "Are you sure it exists? "
+                      "See the logger for more information");
+  g_log.error("Failed to load file. Error message: ");
+  g_log.error(ex.what());
+}
 
-  if (!ADS.doesExist(g_focusedFittingWSName)) {
-    g_log.error() << "Focused workspace could not be plotted as there is no " +
-                         g_focusedFittingWSName + " workspace found.\n";
-    m_view->showStatus("Error while plotting focused workspace");
-    return;
-  }
+void EnggDiffFittingPresenter::plotFocusedFile(
+    bool plotSinglePeaks, MatrixWorkspace_sptr focusedPeaksWS) {
 
   try {
-    auto focusedPeaksWS =
-        ADS.retrieveWS<MatrixWorkspace>(g_focusedFittingWSName);
     auto focusedData = QwtHelper::curveDataFromWs(focusedPeaksWS);
 
     // Check that the number of curves to plot isn't excessive
@@ -1774,7 +1788,9 @@ void EnggDiffFittingPresenter::plotFitPeaksCurves() {
     m_view->resetCanvas();
 
     // plots focused workspace
-    plotFocusedFile(m_fittingFinishedOK);
+    throw new std::runtime_error("Plotting fit not yet implemented");
+    // TODO: sort out what to do here
+    // plotFocusedFile(m_fittingFinishedOK);
 
     if (m_fittingFinishedOK) {
       g_log.debug() << "single peaks fitting being plotted now.\n";
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingPresenter.h b/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingPresenter.h
index 16a27d250fd3b5584acff3ed512af6568b773d33..a0736a7ff9c3ad763c8f6214084b5b7935e8e6cb 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingPresenter.h
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingPresenter.h
@@ -4,6 +4,7 @@
 #include "MantidAPI/ITableWorkspace_fwd.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
 #include "DllConfig.h"
+#include "EnggDiffFittingModel.h"
 #include "IEnggDiffFittingPresenter.h"
 #include "IEnggDiffFittingView.h"
 #include "IEnggDiffractionCalibration.h"
@@ -87,7 +88,8 @@ public:
                      std::string tableName, size_t row, std::string &startX,
                      std::string &endX);
 
-  void plotFocusedFile(bool plotSinglePeaks);
+  void plotFocusedFile(bool plotSinglePeaks,
+                       Mantid::API::MatrixWorkspace_sptr focusedPeaksWS);
 
   void plotFitPeaksCurves();
 
@@ -145,8 +147,12 @@ protected slots:
   void fittingRunNoChanged();
 
 private:
+  size_t findBankID(Mantid::API::MatrixWorkspace_sptr ws) const;
+
   bool isDigit(const std::string &text) const;
 
+  void warnFileNotFound(const std::exception &ex);
+
   // Methods related single peak fits
   virtual void
   startAsyncFittingWorker(const std::vector<std::string> &focusedRunNo,
@@ -225,8 +231,14 @@ private:
   /// Associated view for this presenter (MVP pattern)
   IEnggDiffFittingView *const m_view;
 
+  /// Associated model for this presenter
+  MantidQT::CustomInterfaces::EnggDiffFittingModel m_model;
+
   /// Holds if the view is in the process of being closed
   bool m_viewHasClosed;
+
+  /// Handle the user selecting a different run to plot
+  void processSelectRun();
 };
 
 } // namespace CustomInterfaces
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingViewQtWidget.cpp b/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingViewQtWidget.cpp
index a24d6a2e1ce8424d48f94a57ced94c48f010caba..cc00e278ccb5ce34fd2ebd59f4a8ae533ba2e82b 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingViewQtWidget.cpp
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingViewQtWidget.cpp
@@ -86,11 +86,8 @@ void EnggDiffFittingViewQtWidget::doSetup() {
   connect(m_ui.lineEdit_pushButton_run_num, SIGNAL(textEdited(const QString &)),
           this, SLOT(resetFittingMode()));
 
-  connect(m_ui.lineEdit_pushButton_run_num, SIGNAL(editingFinished()), this,
-          SLOT(FittingRunNo()));
-
   connect(m_ui.lineEdit_pushButton_run_num, SIGNAL(returnPressed()), this,
-          SLOT(FittingRunNo()));
+          SLOT(loadClicked()));
 
   connect(this, SIGNAL(getBanks()), this, SLOT(FittingRunNo()));
 
@@ -126,6 +123,10 @@ void EnggDiffFittingViewQtWidget::doSetup() {
   connect(m_ui.pushButton_plot_separate_window, SIGNAL(released()),
           SLOT(plotSeparateWindow()));
 
+  connect(m_ui.listWidget_fitting_run_num,
+          SIGNAL(itemClicked(QListWidgetItem *)), this,
+          SLOT(listWidget_fitting_run_num_clicked(QListWidgetItem *)));
+
   // Tool-tip button
   connect(m_ui.pushButton_tooltip, SIGNAL(released()), SLOT(showToolTipHelp()));
 
@@ -276,6 +277,12 @@ void EnggDiffFittingViewQtWidget::listViewFittingRun() {
   }
 }
 
+void EnggDiffFittingViewQtWidget::listWidget_fitting_run_num_clicked(
+    QListWidgetItem *clickedItem) {
+  const auto label = clickedItem->text();
+  m_presenter->notify(IEnggDiffFittingPresenter::selectRun);
+}
+
 void EnggDiffFittingViewQtWidget::resetFittingMode() {
   // resets the global variable so the list view widgets
   // adds the run number to for single runs too
@@ -459,17 +466,17 @@ void EnggDiffFittingViewQtWidget::browseFitFocusedRun() {
   std::string nexusFormat = "Nexus file with calibration table: NXS, NEXUS"
                             "(*.nxs *.nexus);;";
 
-  QString path(
-      QFileDialog::getOpenFileName(this, tr("Open Focused File "), prevPath,
-                                   QString::fromStdString(nexusFormat)));
+  QStringList paths(
+      QFileDialog::getOpenFileNames(this, tr("Open Focused File "), prevPath,
+                                    QString::fromStdString(nexusFormat)));
 
-  if (path.isEmpty()) {
+  if (paths.isEmpty()) {
     return;
   }
 
-  MantidQt::API::AlgorithmInputHistory::Instance().setPreviousDirectory(path);
-  setFittingRunNo(path.toStdString());
-  getBanks();
+  // MantidQt::API::AlgorithmInputHistory::Instance().setPreviousDirectory(paths[0]);
+  setFittingRunNo(paths.join(",").toStdString());
+  // getBanks();
 }
 
 void EnggDiffFittingViewQtWidget::setFittingRunNo(const std::string &path) {
@@ -504,6 +511,11 @@ int EnggDiffFittingViewQtWidget::getFittingListWidgetCurrentRow() const {
   return m_ui.listWidget_fitting_run_num->currentRow();
 }
 
+std::string
+EnggDiffFittingViewQtWidget::getFittingListWidgetCurrentValue() const {
+  return m_ui.listWidget_fitting_run_num->currentItem()->text().toStdString();
+}
+
 void EnggDiffFittingViewQtWidget::setFittingListWidgetCurrentRow(
     int idx) const {
   m_ui.listWidget_fitting_run_num->setCurrentRow(idx);
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingViewQtWidget.h b/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingViewQtWidget.h
index 10c6c31e17dda70ac1e9017f930301e5cd783d00..3cfeef3885e8f1ec32f39b41fac008790c330d2a 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingViewQtWidget.h
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingViewQtWidget.h
@@ -107,6 +107,8 @@ public:
 
   int getFittingListWidgetCurrentRow() const override;
 
+  std::string getFittingListWidgetCurrentValue() const override;
+
   void setFittingListWidgetCurrentRow(int idx) const override;
 
   std::string fittingPeaksData() const override;
@@ -190,6 +192,7 @@ private slots:
   void showToolTipHelp();
   void setBankDir(int idx);
   void listViewFittingRun();
+  void listWidget_fitting_run_num_clicked(QListWidgetItem *listWidget);
 
 private:
   /// Setup the interface (tab UI)
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffractionQtTabFitting.ui b/qt/scientific_interfaces/EnggDiffraction/EnggDiffractionQtTabFitting.ui
index 6ed8a033782e74f7c3703f23581ba38e5c86d190..7c50ba5e7e6a7d6f0dfc577b33d0a77bd92943df 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffractionQtTabFitting.ui
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffractionQtTabFitting.ui
@@ -373,7 +373,7 @@
           </property>
           <property name="maximumSize">
            <size>
-            <width>50</width>
+            <width>60</width>
             <height>16777215</height>
            </size>
           </property>
diff --git a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffFittingPresenter.h b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffFittingPresenter.h
index 11f2a885682c810a1d456d34545755602453017a..8c5d25fd1c42f84a9168994e56e7faf43188ea6b 100644
--- a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffFittingPresenter.h
+++ b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffFittingPresenter.h
@@ -52,6 +52,7 @@ public:
     savePeaks,    ///< Save the peaks list
     ShutDown,     ///< closing the interface
     LogMsg,       ///< need to send a message to the Mantid log system
+    selectRun,    ///< update plot with new run selected from list widget
   };
 
   /**
diff --git a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffFittingView.h b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffFittingView.h
index c1638eaeae7dda02b3dc830d457db61081f731d0..8fe38b27bc9a9a06f2deb04a59e78a1c6d96d857 100644
--- a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffFittingView.h
+++ b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffFittingView.h
@@ -191,6 +191,11 @@ public:
    */
   virtual int getFittingListWidgetCurrentRow() const = 0;
 
+  /**
+  * @return The text on the current selected row of the list widget
+  */
+  virtual std::string getFittingListWidgetCurrentValue() const = 0;
+
   /**
    * Sets the current row of the fitting list widget
    *
diff --git a/qt/scientific_interfaces/Indirect/ConvFit.cpp b/qt/scientific_interfaces/Indirect/ConvFit.cpp
index 457726a04c4205336eaa3bdfd79ab5737fa535a2..f87f091e91fec1da7f2d7e65f97e7fe6ba72eaec 100644
--- a/qt/scientific_interfaces/Indirect/ConvFit.cpp
+++ b/qt/scientific_interfaces/Indirect/ConvFit.cpp
@@ -481,7 +481,7 @@ void ConvFit::algorithmComplete(bool error, const QString &outputWSName) {
   updatePlot();
   updatePlotRange();
 
-  std::string paramWsName = outputPrefix + "_Parameters";
+  const std::string paramWsName = outputPrefix + "_Parameters";
 
   if (AnalysisDataService::Instance().doesExist(paramWsName)) {
     QString prefixPrefix = "f1.f1.";
@@ -828,8 +828,8 @@ CompositeFunction_sptr ConvFit::createFunction(bool tieCentres,
     func = FunctionFactory::Instance().createFunction("DeltaFunction");
     index = model->addFunction(func);
     std::string parName = createParName(index);
-    populateFunction(func, model, m_properties["Delta Function"], parName,
-                     false);
+    populateFunction(func, model, m_properties["Delta Function"], false,
+                     parName);
   }
 
   // ------------------------------------------------------------
@@ -880,7 +880,7 @@ CompositeFunction_sptr ConvFit::createFunction(bool tieCentres,
     index = model->addFunction(product);
     prefix1 = createParName(index, subIndex);
 
-    populateFunction(func, model, m_properties["FitFunction1"], prefix1, false);
+    populateFunction(func, model, m_properties["FitFunction1"], false, prefix1);
 
     // Add 2nd Lorentzian
     if (fitTypeIndex == 2) {
@@ -898,8 +898,8 @@ CompositeFunction_sptr ConvFit::createFunction(bool tieCentres,
       index = model->addFunction(product);
       prefix2 = createParName(index, subIndex);
 
-      populateFunction(func, model, m_properties["FitFunction2"], prefix2,
-                       false);
+      populateFunction(func, model, m_properties["FitFunction2"], false,
+                       prefix2);
     }
   }
 
@@ -1033,39 +1033,6 @@ QtProperty *ConvFit::createFitType(QtProperty *fitTypeGroup,
   return fitTypeGroup;
 }
 
-/**
- * Populates the properties of a function with given values
- * @param func The function currently being added to the composite
- * @param comp A composite function of the previously called functions
- * @param group The QtProperty representing the fit type
- * @param pref The index of the functions eg. (f0.f1)
- * @param tie Bool to state if parameters are to be tied together
- */
-void ConvFit::populateFunction(IFunction_sptr func, IFunction_sptr comp,
-                               QtProperty *group, const std::string &pref,
-                               bool tie) {
-  // Get sub-properties of group and apply them as parameters on the function
-  // object
-  QList<QtProperty *> props = group->subProperties();
-
-  for (int i = 0; i < props.size(); i++) {
-    if (tie || !props[i]->subProperties().isEmpty()) {
-      std::string name = pref + props[i]->propertyName().toStdString();
-      std::string value = props[i]->valueText().toStdString();
-      comp->tie(name, value);
-    } else {
-      std::string propName = props[i]->propertyName().toStdString();
-      double propValue = props[i]->valueText().toDouble();
-      if (propValue != 0.0) {
-        if (func->hasAttribute(propName))
-          func->setAttributeValue(propName, propValue);
-        else
-          func->setParameter(propName, propValue);
-      }
-    }
-  }
-}
-
 /**
  * Generate a string to describe the fit type selected by the user.
  * Used when naming the resultant workspaces.
@@ -1237,8 +1204,8 @@ void ConvFit::updateProperties(int specNo) {
 }
 
 void ConvFit::updateProperties(int specNo, const QString &fitFunction) {
-  bool isTwoLorentzian = fitFunction == "Lorentzian 2";
-  bool specOutOfBounds =
+  const bool isTwoLorentzian = fitFunction == "Lorentzian 2";
+  const bool specOutOfBounds =
       specNo < minimumSpectrum() || maximumSpectrum() < specNo;
 
   for (auto &param : getFunctionParameters(fitFunction)) {
@@ -1294,7 +1261,7 @@ void ConvFit::plotGuess() {
   // Do nothing if there is not a sample and resolution
   if (m_uiForm.dsResInput->isValid() && m_uiForm.ckPlotGuess->isChecked()) {
     extendResolutionWorkspace();
-    bool tieCentres = (m_uiForm.cbFitType->currentIndex() == 2);
+    const bool tieCentres = (m_uiForm.cbFitType->currentIndex() == 2);
     IndirectDataAnalysisTab::plotGuess(m_uiForm.ppPlotTop,
                                        createFunction(tieCentres, true));
   } else {
diff --git a/qt/scientific_interfaces/Indirect/ConvFit.h b/qt/scientific_interfaces/Indirect/ConvFit.h
index ec0880e97a052fb1be26c5b948aa63271b9e5f2a..5997d389e80ef443dcc9114fdac067b428d9cfd3 100644
--- a/qt/scientific_interfaces/Indirect/ConvFit.h
+++ b/qt/scientific_interfaces/Indirect/ConvFit.h
@@ -60,9 +60,6 @@ private:
   QtProperty *createFitType(QtProperty *, const bool & = true);
 
   void createTemperatureCorrection(Mantid::API::CompositeFunction_sptr product);
-  void populateFunction(Mantid::API::IFunction_sptr func,
-                        Mantid::API::IFunction_sptr comp, QtProperty *group,
-                        const std::string &pref, bool tie);
   QString fitTypeString() const;
   QString backgroundString() const;
   QString minimizerString(QString outputName) const;
diff --git a/qt/scientific_interfaces/Indirect/IndirectDataAnalysisTab.cpp b/qt/scientific_interfaces/Indirect/IndirectDataAnalysisTab.cpp
index fa7d733233e80703d9df0379cbd45245a5bba92b..5fb5de2db6395b103e62d1f3b0517e929a611aae 100644
--- a/qt/scientific_interfaces/Indirect/IndirectDataAnalysisTab.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectDataAnalysisTab.cpp
@@ -2,7 +2,9 @@
 
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FunctionDomain1D.h"
+#include "MantidAPI/FunctionFactory.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/WorkspaceGroup.h"
 #include "boost/shared_ptr.hpp"
 
@@ -167,6 +169,9 @@ void IndirectDataAnalysisTab::plotCurrentPreview() {
 /**
  * Plots the selected spectrum of the input workspace in this indirect data
  * analysis tab.
+ *
+ * @param previewPlot The preview plot widget in which to plot the input
+ *                    input workspace.
  */
 void IndirectDataAnalysisTab::plotInput(
     MantidQt::MantidWidgets::PreviewPlot *previewPlot) {
@@ -204,6 +209,15 @@ void IndirectDataAnalysisTab::updatePlot(
   }
 }
 
+/**
+ * Plots the data in the workspace with the specified name. Plots the
+ * sample and fit  spectrum in the specified top preview plot. Plots
+ * the diff spectra in the specified difference preview plot.
+ *
+ * @param workspaceName     The name of the workspace to plot.
+ * @param fitPreviewPlot    The fit preview plot.
+ * @param diffPreviewPlot   The difference preview plot.
+ */
 void IndirectDataAnalysisTab::updatePlot(
     const std::string &workspaceName,
     MantidQt::MantidWidgets::PreviewPlot *fitPreviewPlot,
@@ -228,6 +242,17 @@ void IndirectDataAnalysisTab::updatePlot(
   }
 }
 
+/**
+ * Plots the workspace at the index specified by the selected
+ * spectrum, in the specified workspace group. Plots the sample
+ * and fit  spectrum in the specified top preview plot. Plots
+ * the diff spectra in the specified difference preview plot.
+ *
+ * @param outputWS          The group workspace containing the
+ *                          workspaced to plot.
+ * @param fitPreviewPlot    The fit preview plot.
+ * @param diffPreviewPlot   The difference preview plot.
+ */
 void IndirectDataAnalysisTab::updatePlot(
     WorkspaceGroup_sptr outputWS,
     MantidQt::MantidWidgets::PreviewPlot *fitPreviewPlot,
@@ -241,6 +266,15 @@ void IndirectDataAnalysisTab::updatePlot(
   }
 }
 
+/**
+ * Plots the data in the specified workspace. Plots the sample
+ * and fit  spectrum in the specified top preview plot. Plots
+ * the diff spectra in the specified difference preview plot.
+ *
+ * @param outputWS          The workspace to plot.
+ * @param fitPreviewPlot    The fit preview plot.
+ * @param diffPreviewPlot   The difference preview plot.
+ */
 void IndirectDataAnalysisTab::updatePlot(
     MatrixWorkspace_sptr outputWS,
     MantidQt::MantidWidgets::PreviewPlot *fitPreviewPlot,
@@ -259,6 +293,18 @@ void IndirectDataAnalysisTab::updatePlot(
   }
 }
 
+/*
+ * Updates the plot range with the specified name, to match the range of
+ * the sample curve.
+ *
+ * @param rangeName           The name of the range to update.
+ * @param previewPlot         The preview plot widget, in which the range
+ *                            is specified.
+ * @param startRangePropName  The name of the property specifying the start
+ *                            value for the range.
+ * @parma endRangePropName    The name of the property specifying the end
+ *                            value for the range.
+ */
 void IndirectDataAnalysisTab::updatePlotRange(
     const QString &rangeName, MantidQt::MantidWidgets::PreviewPlot *previewPlot,
     const QString &startRangePropName, const QString &endRangePropName) {
@@ -273,6 +319,14 @@ void IndirectDataAnalysisTab::updatePlotRange(
   }
 }
 
+/*
+ * Plots a guess of the fit for the specified function, in the
+ * specified preview plot widget.
+ *
+ * @param previewPlot The preview plot widget in which to plot
+ *                    the guess.
+ * @param function    The function to fit.
+ */
 void IndirectDataAnalysisTab::plotGuess(
     MantidQt::MantidWidgets::PreviewPlot *previewPlot,
     IFunction_sptr function) {
@@ -280,25 +334,40 @@ void IndirectDataAnalysisTab::plotGuess(
 
   if (inputWorkspace()) {
     auto guessWs = createGuessWorkspace(function);
-    previewPlot->addSpectrum("Guess", guessWs, 0, Qt::green);
+
+    // Check whether the guess workspace has enough data points
+    // to plot
+    if (guessWs->x(0).size() >= 2) {
+      previewPlot->addSpectrum("Guess", guessWs, 0, Qt::green);
+    }
   }
 }
 
+/*
+ * Creates a guess workspace, for approximating a fit with the specified
+ * function on the input workspace.
+ *
+ * @param func  The function to fit.
+ * @return      A guess workspace containing the guess data for the fit.
+ */
 MatrixWorkspace_sptr
 IndirectDataAnalysisTab::createGuessWorkspace(IFunction_sptr func) {
   const auto inputWS = inputWorkspace();
   const auto startX = m_dblManager->value(m_properties["StartX"]);
   const auto endX = m_dblManager->value(m_properties["EndX"]);
-  const size_t binIndexLow = inputWS->binIndexOf(startX);
-  const size_t binIndexHigh = inputWS->binIndexOf(endX);
-  const size_t nData = binIndexHigh - binIndexLow;
+  const auto binIndexLow = inputWS->binIndexOf(startX);
+  const auto binIndexHigh = inputWS->binIndexOf(endX);
+  const auto nData = binIndexHigh - binIndexLow;
 
   const auto &xPoints = inputWS->points(0);
 
   std::vector<double> dataX(nData);
   std::copy(&xPoints[binIndexLow], &xPoints[binIndexLow + nData],
             dataX.begin());
-  std::vector<double> dataY = computeOutput(func, dataX);
+  const auto dataY = computeOutput(func, dataX);
+
+  if (dataY.empty())
+    return WorkspaceFactory::Instance().create("Workspace2D", 1, 1, 1);
 
   IAlgorithm_sptr createWsAlg =
       createWorkspaceAlgorithm("__GuessAnon", 1, dataX, dataY);
@@ -306,9 +375,21 @@ IndirectDataAnalysisTab::createGuessWorkspace(IFunction_sptr func) {
   return createWsAlg->getProperty("OutputWorkspace");
 }
 
+/*
+ * Computes the output vector of applying the specified function to
+ * the specified input vector.
+ *
+ * @param func    The function to apply.
+ * @param dataX   Vector of input data.
+ * @return        Vector containing values calculated from applying
+ *                the specified function to the input data.
+ */
 std::vector<double>
 IndirectDataAnalysisTab::computeOutput(IFunction_sptr func,
                                        const std::vector<double> &dataX) {
+  if (dataX.empty())
+    return std::vector<double>();
+
   FunctionDomain1DVector domain(dataX);
   FunctionValues outputData(domain);
   func->function(domain, outputData);
@@ -320,6 +401,17 @@ IndirectDataAnalysisTab::computeOutput(IFunction_sptr func,
   return dataY;
 }
 
+/*
+ * Generates and returns an algorithm for creating a workspace, with
+ * the specified name, number of spectra and containing the specified
+ * x data and y data.
+ *
+ * @param workspaceName The name of the workspace to create.
+ * @param numSpec       The number of spectra in the workspace to create.
+ * @param dataX         The x data to add to the created workspace.
+ * @param dataY         The y data to add to the created workspace.
+ * @return              An algorithm for creating the workspace.
+ */
 IAlgorithm_sptr IndirectDataAnalysisTab::createWorkspaceAlgorithm(
     const std::string &workspaceName, int numSpec,
     const std::vector<double> &dataX, const std::vector<double> &dataY) {
@@ -335,6 +427,86 @@ IAlgorithm_sptr IndirectDataAnalysisTab::createWorkspaceAlgorithm(
   return createWsAlg;
 }
 
+/**
+ * Create and populates a function with given values
+ * @param funcName  The name of the function to create and populate populate
+ * @param group     The QtProperty representing the fit type
+ * @param comp      A composite function of the previously called functions to
+ *                  be used in tie
+ * @param tie       Bool to state if parameters are to be tied together
+ * @param pref      The index of the functions eg. (f0.f1)
+ */
+IFunction_sptr IndirectDataAnalysisTab::createPopulatedFunction(
+    const std::string &funcName, IFunction_sptr comp, QtProperty *group,
+    bool tie, const std::string &pref) {
+  IFunction_sptr func = FunctionFactory::Instance().createFunction(funcName);
+  populateFunction(func, comp, group, tie, pref);
+  return func;
+}
+
+/**
+ * Create and populates a function with given values
+ * @param func  The function to populate
+ * @param group The QtProperty representing the fit type
+ * @param tie   Bool to state if parameters are to be tied together
+ * @param pref  The index of the functions eg. (f0.f1)
+ */
+IFunction_sptr
+IndirectDataAnalysisTab::createPopulatedFunction(const std::string &funcName,
+                                                 QtProperty *group, bool tie,
+                                                 const std::string &pref) {
+  IFunction_sptr func = FunctionFactory::Instance().createFunction(funcName);
+  populateFunction(func, group, tie, pref);
+  return func;
+}
+
+/**
+ * Populates the properties of a function with given values
+ * @param func  The function to populate
+ * @param group The QtProperty representing the fit type
+ * @param tie   Bool to state if parameters are to be tied together
+ * @param pref  The index of the functions eg. (f0.f1)
+ */
+void IndirectDataAnalysisTab::populateFunction(IFunction_sptr func,
+                                               QtProperty *group, bool tie,
+                                               const std::string &pref) {
+  populateFunction(func, func, group, tie, pref);
+}
+
+/**
+ * Populates the properties of a function with given values
+ * @param func  The function currently being added to the composite
+ * @param comp  A composite function of the previously called functions
+ * @param group The QtProperty representing the fit type
+ * @param pref  The index of the functions eg. (f0.f1)
+ * @param tie   Bool to state if parameters are to be tied together
+ */
+void IndirectDataAnalysisTab::populateFunction(IFunction_sptr func,
+                                               IFunction_sptr comp,
+                                               QtProperty *group, bool tie,
+                                               const std::string &pref) {
+  // Get sub-properties of group and apply them as parameters on the function
+  // object
+  QList<QtProperty *> props = group->subProperties();
+
+  for (const auto &prop : props) {
+    if (tie || !prop->subProperties().isEmpty()) {
+      std::string name = pref + prop->propertyName().toStdString();
+      std::string value = prop->valueText().toStdString();
+      comp->tie(name, value);
+    } else {
+      std::string propName = prop->propertyName().toStdString();
+      double propValue = prop->valueText().toDouble();
+      if (propValue != 0.0) {
+        if (func->hasAttribute(propName))
+          func->setAttributeValue(propName, propValue);
+        else
+          func->setParameter(propName, propValue);
+      }
+    }
+  }
+}
+
 } // namespace IDA
 } // namespace CustomInterfaces
 } // namespace MantidQt
diff --git a/qt/scientific_interfaces/Indirect/IndirectDataAnalysisTab.h b/qt/scientific_interfaces/Indirect/IndirectDataAnalysisTab.h
index a29dd0d2f9fc83b110a28cd76c6f9002e7921225..ccfa93c5b9dd6b33f759bfbb9e49d68a6b2c1771 100644
--- a/qt/scientific_interfaces/Indirect/IndirectDataAnalysisTab.h
+++ b/qt/scientific_interfaces/Indirect/IndirectDataAnalysisTab.h
@@ -118,6 +118,22 @@ protected:
                            const std::vector<double> &dataX,
                            const std::vector<double> &dataY);
 
+  Mantid::API::IFunction_sptr
+  createPopulatedFunction(const std::string &funcName,
+                          Mantid::API::IFunction_sptr comp, QtProperty *group,
+                          bool tie = false, const std::string &pref = "");
+
+  Mantid::API::IFunction_sptr
+  createPopulatedFunction(const std::string &funcName, QtProperty *group,
+                          bool tie = false, const std::string &pref = "");
+
+  void populateFunction(Mantid::API::IFunction_sptr func, QtProperty *group,
+                        bool tie = false, const std::string &pref = "");
+
+  void populateFunction(Mantid::API::IFunction_sptr func,
+                        Mantid::API::IFunction_sptr comp, QtProperty *group,
+                        bool tie = false, const std::string &pref = "");
+
   /// DoubleEditorFactory
   DoubleEditorFactory *m_dblEdFac;
   /// QtCheckBoxFactory
diff --git a/qt/scientific_interfaces/Indirect/IqtFit.cpp b/qt/scientific_interfaces/Indirect/IqtFit.cpp
index 0b5607670ead1534dc13da5f91bf7ae4102af387..0925d7b60de9672e9cc1485c3e18c42cf4472cb8 100644
--- a/qt/scientific_interfaces/Indirect/IqtFit.cpp
+++ b/qt/scientific_interfaces/Indirect/IqtFit.cpp
@@ -426,20 +426,21 @@ CompositeFunction_sptr IqtFit::createFunction(bool tie) {
   }
 
   if (fitType == 2) {
-    fname = "StretchedExp";
+    result->addFunction(createPopulatedFunction(
+        "StretchExp", m_properties["StretchedExp"], tie));
   } else {
-    fname = "Exponential1";
+    result->addFunction(
+        createPopulatedFunction("ExpDecay", m_properties["Exponential1"], tie));
   }
 
-  result->addFunction(createExponentialFunction(fname, tie));
-
   if (fitType == 1 || fitType == 3) {
     if (fitType == 1) {
-      fname = "Exponential2";
+      result->addFunction(createPopulatedFunction(
+          "ExpDecay", m_properties["Exponential2"], tie));
     } else {
-      fname = "StretchedExp";
+      result->addFunction(createPopulatedFunction(
+          "StretchExp", m_properties["StretchedExp"], tie));
     }
-    result->addFunction(createExponentialFunction(fname, tie));
   }
 
   // Return CompositeFunction object to caller.
@@ -447,51 +448,11 @@ CompositeFunction_sptr IqtFit::createFunction(bool tie) {
   return result;
 }
 
-IFunction_sptr IqtFit::createExponentialFunction(const QString &name,
-                                                 bool tie) {
-  IFunction_sptr result;
-  if (name.startsWith("Exp")) {
-    IFunction_sptr result =
-        FunctionFactory::Instance().createFunction("ExpDecay");
-    result->setParameter(
-        "Height", m_dblManager->value(m_properties[name + ".Intensity"]));
-    result->setParameter("Lifetime",
-                         m_dblManager->value(m_properties[name + ".Tau"]));
-    if (tie) {
-      result->tie("Height",
-                  m_properties[name + ".Intensity"]->valueText().toStdString());
-      result->tie("Lifetime",
-                  m_properties[name + ".Tau"]->valueText().toStdString());
-    }
-    result->applyTies();
-    return result;
-  } else {
-    IFunction_sptr result =
-        FunctionFactory::Instance().createFunction("StretchExp");
-    result->setParameter(
-        "Height", m_dblManager->value(m_properties[name + ".Intensity"]));
-    result->setParameter("Lifetime",
-                         m_dblManager->value(m_properties[name + ".Tau"]));
-    result->setParameter("Stretching",
-                         m_dblManager->value(m_properties[name + ".Beta"]));
-    if (tie) {
-      result->tie("Height",
-                  m_properties[name + ".Intensity"]->valueText().toStdString());
-      result->tie("Lifetime",
-                  m_properties[name + ".Tau"]->valueText().toStdString());
-      result->tie("Stretching",
-                  m_properties[name + ".Beta"]->valueText().toStdString());
-    }
-    result->applyTies();
-    return result;
-  }
-}
-
 QtProperty *IqtFit::createExponential(const QString &name) {
   QtProperty *expGroup = m_grpManager->addProperty(name);
-  m_properties[name + ".Intensity"] = m_dblManager->addProperty("Intensity");
+  m_properties[name + ".Intensity"] = m_dblManager->addProperty("Height");
   m_dblManager->setDecimals(m_properties[name + ".Intensity"], NUM_DECIMALS);
-  m_properties[name + ".Tau"] = m_dblManager->addProperty("Tau");
+  m_properties[name + ".Tau"] = m_dblManager->addProperty("Lifetime");
   m_dblManager->setDecimals(m_properties[name + ".Tau"], NUM_DECIMALS);
   expGroup->addSubProperty(m_properties[name + ".Intensity"]);
   expGroup->addSubProperty(m_properties[name + ".Tau"]);
@@ -500,9 +461,9 @@ QtProperty *IqtFit::createExponential(const QString &name) {
 
 QtProperty *IqtFit::createStretchedExp(const QString &name) {
   QtProperty *prop = m_grpManager->addProperty(name);
-  m_properties[name + ".Intensity"] = m_dblManager->addProperty("Intensity");
-  m_properties[name + ".Tau"] = m_dblManager->addProperty("Tau");
-  m_properties[name + ".Beta"] = m_dblManager->addProperty("Beta");
+  m_properties[name + ".Intensity"] = m_dblManager->addProperty("Height");
+  m_properties[name + ".Tau"] = m_dblManager->addProperty("Lifetime");
+  m_properties[name + ".Beta"] = m_dblManager->addProperty("Stretching");
   m_dblManager->setRange(m_properties[name + ".Beta"], 0, 1);
   m_dblManager->setDecimals(m_properties[name + ".Intensity"], NUM_DECIMALS);
   m_dblManager->setDecimals(m_properties[name + ".Tau"], NUM_DECIMALS);
diff --git a/qt/scientific_interfaces/Indirect/IqtFit.h b/qt/scientific_interfaces/Indirect/IqtFit.h
index e1eb02576977c002ff9da68be9ef28efb53e63bc..86275cde486f8478458c582ce2527d84f795f754 100644
--- a/qt/scientific_interfaces/Indirect/IqtFit.h
+++ b/qt/scientific_interfaces/Indirect/IqtFit.h
@@ -59,8 +59,6 @@ private slots:
 private:
   boost::shared_ptr<Mantid::API::CompositeFunction>
   createFunction(bool tie = false);
-  boost::shared_ptr<Mantid::API::IFunction>
-  createExponentialFunction(const QString &name, bool tie = false);
   QtProperty *createExponential(const QString &);
   QtProperty *createStretchedExp(const QString &);
   void setDefaultParameters(const QString &name);
diff --git a/qt/scientific_interfaces/Indirect/MSDFit.cpp b/qt/scientific_interfaces/Indirect/MSDFit.cpp
index 3a8abd797cb8ab2eb57b8c204795ab10f1e34e0e..1289fd3a2d748a23b1a56d606750feabfa399fce 100644
--- a/qt/scientific_interfaces/Indirect/MSDFit.cpp
+++ b/qt/scientific_interfaces/Indirect/MSDFit.cpp
@@ -1,6 +1,7 @@
 #include "MSDFit.h"
 #include "../General/UserInputValidator.h"
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/FunctionFactory.h"
 #include "MantidAPI/WorkspaceGroup.h"
 #include "MantidQtWidgets/LegacyQwt/RangeSelector.h"
 
@@ -36,11 +37,14 @@ void MSDFit::setup() {
   m_properties["EndX"] = m_dblManager->addProperty("EndX");
   m_dblManager->setDecimals(m_properties["EndX"], NUM_DECIMALS);
 
-  m_properties["Gaussian"] = createModel("Gaussian", {"Intensity", "MSD"});
-  m_properties["Peters"] = createModel("Peters", {"Intensity", "MSD", "Beta"});
-  m_properties["Yi"] = createModel("Yi", {"Intensity", "MSD", "Sigma"});
+  m_properties["Gaussian"] = createModel("MsdGauss", {"Height", "MSD"});
+  m_properties["Peters"] = createModel("MsdPeters", {"Height", "MSD", "Beta"});
+  m_properties["Yi"] = createModel("MsdYi", {"Height", "MSD", "Sigma"});
 
   auto fitRangeSelector = m_uiForm.ppPlotTop->addRangeSelector("MSDRange");
+  m_dblManager->setValue(m_properties["StartX"],
+                         fitRangeSelector->getMinimum());
+  m_dblManager->setValue(m_properties["EndX"], fitRangeSelector->getMaximum());
 
   modelSelection(m_uiForm.cbModelInput->currentIndex());
 
@@ -64,6 +68,13 @@ void MSDFit::setup() {
   connect(m_uiForm.spPlotSpectrum, SIGNAL(valueChanged(int)), this,
           SLOT(updatePlot()));
 
+  connect(m_dblManager, SIGNAL(propertyChanged(QtProperty *)), this,
+          SLOT(plotGuess()));
+  connect(m_uiForm.ckPlotGuess, SIGNAL(stateChanged(int)), this,
+          SLOT(plotGuess()));
+  connect(m_uiForm.cbModelInput, SIGNAL(currentIndexChanged(int)), this,
+          SLOT(plotGuess()));
+
   connect(m_uiForm.spSpectraMin, SIGNAL(valueChanged(int)), this,
           SLOT(specMinChanged(int)));
   connect(m_uiForm.spSpectraMax, SIGNAL(valueChanged(int)), this,
@@ -90,7 +101,8 @@ void MSDFit::run() {
       dataName.left(dataName.lastIndexOf("_")).toStdString() + "_s" +
       std::to_string(specMin) + "_to_s" + std::to_string(specMax) + "_" +
       model.toStdString() + "_msd";
-  m_parameterToProperty = createParameterToPropertyMap(model);
+  m_parameterToProperty =
+      createParameterToPropertyMap(m_properties[model]->propertyName());
 
   IAlgorithm_sptr msdAlg =
       msdFitAlgorithm(modelToAlgorithmProperty(model), specMin, specMax);
@@ -113,7 +125,8 @@ void MSDFit::singleFit() {
   m_pythonExportWsName =
       dataName.left(dataName.lastIndexOf("_")).toStdString() + "_s" +
       std::to_string(fitSpec) + "_" + model.toStdString() + "_msd";
-  m_parameterToProperty = createParameterToPropertyMap(model);
+  m_parameterToProperty =
+      createParameterToPropertyMap(m_properties[model]->propertyName());
 
   IAlgorithm_sptr msdAlg =
       msdFitAlgorithm(modelToAlgorithmProperty(model), fitSpec, fitSpec);
@@ -212,6 +225,23 @@ void MSDFit::updatePlot() {
   IndirectDataAnalysisTab::updatePlotRange("MSDRange", m_uiForm.ppPlotTop);
 }
 
+void MSDFit::plotGuess() {
+
+  if (m_uiForm.ckPlotGuess->isChecked()) {
+    QString modelName = m_uiForm.cbModelInput->currentText();
+    IndirectDataAnalysisTab::plotGuess(m_uiForm.ppPlotTop,
+                                       createFunction(modelName));
+  } else {
+    m_uiForm.ppPlotTop->removeSpectrum("Guess");
+  }
+}
+
+IFunction_sptr MSDFit::createFunction(const QString &modelName) {
+  return createPopulatedFunction(
+      m_properties[modelName]->propertyName().toStdString(),
+      m_properties[modelName]);
+}
+
 /**
  * Called when new data has been loaded by the data selector.
  *
@@ -313,12 +343,23 @@ QtProperty *MSDFit::createModel(const QString &modelName,
 }
 
 void MSDFit::modelSelection(int selected) {
-  QString model = m_uiForm.cbModelInput->itemText(selected);
+  auto model = m_uiForm.cbModelInput->itemText(selected);
   m_msdTree->clear();
 
   m_msdTree->addProperty(m_properties["StartX"]);
   m_msdTree->addProperty(m_properties["EndX"]);
   m_msdTree->addProperty(m_properties[model]);
+
+  if (!m_pythonExportWsName.empty()) {
+    auto idx = m_pythonExportWsName.rfind("_");
+    m_pythonExportWsName = m_pythonExportWsName.substr(0, idx);
+    idx = m_pythonExportWsName.rfind("_");
+    m_pythonExportWsName = m_pythonExportWsName.substr(0, idx);
+    m_pythonExportWsName += "_" + model.toStdString() + "_msd";
+  }
+
+  m_uiForm.ckPlotGuess->setChecked(false);
+  updatePlot();
 }
 
 /*
@@ -333,7 +374,7 @@ void MSDFit::modelSelection(int selected) {
 QHash<QString, QString>
 MSDFit::createParameterToPropertyMap(const QString &model) {
   QHash<QString, QString> parameterToProperty;
-  parameterToProperty["Height"] = model + ".Intensity";
+  parameterToProperty["Height"] = model + ".Height";
   parameterToProperty["MSD"] = model + ".MSD";
 
   if (model == "Peters")
diff --git a/qt/scientific_interfaces/Indirect/MSDFit.h b/qt/scientific_interfaces/Indirect/MSDFit.h
index e9d58afaa3e8e1ba13b211d5180a2dbdadeb2390..d329bec176d3c27167bb71c85efcd37c5b6fc6e8 100644
--- a/qt/scientific_interfaces/Indirect/MSDFit.h
+++ b/qt/scientific_interfaces/Indirect/MSDFit.h
@@ -4,6 +4,8 @@
 #include "IndirectDataAnalysisTab.h"
 #include "ui_MSDFit.h"
 
+#include "MantidAPI/IFunction.h"
+
 namespace MantidQt {
 namespace CustomInterfaces {
 namespace IDA {
@@ -33,6 +35,7 @@ private slots:
   void modelSelection(int selected);
   void updatePlot();
   void updateProperties(int specNo);
+  void plotGuess();
 
 private:
   Mantid::API::IAlgorithm_sptr msdFitAlgorithm(const std::string &model,
@@ -41,6 +44,7 @@ private:
                           const std::vector<QString> &modelParameters);
   QHash<QString, QString> createParameterToPropertyMap(const QString &model);
   std::string modelToAlgorithmProperty(const QString &model);
+  Mantid::API::IFunction_sptr createFunction(const QString &modelName);
 
   Ui::MSDFit m_uiForm;
   QtTreePropertyBrowser *m_msdTree;
diff --git a/qt/scientific_interfaces/Indirect/MSDFit.ui b/qt/scientific_interfaces/Indirect/MSDFit.ui
index 20d0a5a06ddc59f4c30fe2d486b2fc4dd424f07c..dfc78073f9d7549b9e2633ad2912a9cfede37194 100644
--- a/qt/scientific_interfaces/Indirect/MSDFit.ui
+++ b/qt/scientific_interfaces/Indirect/MSDFit.ui
@@ -56,9 +56,6 @@
    </item>
    <item>
     <layout class="QHBoxLayout" name="loMSDFit">
-     <item>
-      <layout class="QVBoxLayout" name="properties"/>
-     </item>
      <item>
       <layout class="QVBoxLayout" name="loMSDPlot">
        <item>
diff --git a/qt/scientific_interfaces/test/EnggDiffFittingModelTest.h b/qt/scientific_interfaces/test/EnggDiffFittingModelTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..c9c4837854e491533172322acffa59099f8c24b4
--- /dev/null
+++ b/qt/scientific_interfaces/test/EnggDiffFittingModelTest.h
@@ -0,0 +1,86 @@
+#ifndef MANTID_CUSTOMINTERFACES_ENGGDIFFFITTINGMODELTEST_H_
+#define MANTID_CUSTOMINTERFACES_ENGGDIFFFITTINGMODELTEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceFactory.h"
+
+#include "../EnggDiffraction/EnggDiffFittingModel.h"
+
+#include <vector>
+
+// Lets us have pairs inside assertion macros
+typedef std::pair<int, size_t> RunBankPair;
+
+using namespace Mantid;
+using namespace MantidQT::CustomInterfaces;
+
+namespace {
+
+void addSampleWorkspaceToModel(const int runNumber, const int bank,
+                               EnggDiffFittingModel &model) {
+  API::MatrixWorkspace_sptr ws =
+      API::WorkspaceFactory::Instance().create("Workspace2D", 1, 10, 10);
+  model.addWorkspace(runNumber, bank, ws);
+}
+
+} // anonymous namespace
+
+class EnggDiffFittingModelTest : public CxxTest::TestSuite {
+public:
+  // This pair of boilerplate methods prevent the suite being created statically
+  // This means the constructor isn't called when running other tests
+  static EnggDiffFittingModelTest *createSuite() {
+    return new EnggDiffFittingModelTest();
+  }
+  static void destroySuite(EnggDiffFittingModelTest *suite) { delete suite; }
+
+  void test_addAndGetWorkspace() {
+    auto model = EnggDiffFittingModel();
+    API::MatrixWorkspace_sptr ws =
+        API::WorkspaceFactory::Instance().create("Workspace2D", 1, 10, 10);
+    const int runNumber = 100;
+    const int bank = 1;
+    TS_ASSERT_THROWS_NOTHING(model.addWorkspace(runNumber, bank, ws));
+    const auto retrievedWS = model.getWorkspace(runNumber, bank);
+
+    TS_ASSERT(retrievedWS != nullptr);
+    TS_ASSERT_EQUALS(ws, retrievedWS);
+  }
+
+  void test_getAllRunNumbers() {
+    auto model = EnggDiffFittingModel();
+
+    addSampleWorkspaceToModel(123, 1, model);
+    addSampleWorkspaceToModel(456, 2, model);
+    addSampleWorkspaceToModel(789, 1, model);
+    addSampleWorkspaceToModel(123, 2, model);
+
+    const auto runNumbers = model.getAllRunNumbers();
+
+    TS_ASSERT_EQUALS(runNumbers.size(), 3);
+    TS_ASSERT_EQUALS(runNumbers[0], 123);
+    TS_ASSERT_EQUALS(runNumbers[1], 456);
+    TS_ASSERT_EQUALS(runNumbers[2], 789);
+  }
+
+  void test_getRunNumbersAndBankIDs() {
+    auto model = EnggDiffFittingModel();
+
+    addSampleWorkspaceToModel(123, 1, model);
+    addSampleWorkspaceToModel(456, 2, model);
+    addSampleWorkspaceToModel(789, 1, model);
+    addSampleWorkspaceToModel(123, 2, model);
+
+    const auto runNoBankPairs = model.getRunNumbersAndBanksIDs();
+
+    TS_ASSERT_EQUALS(runNoBankPairs.size(), 4);
+    TS_ASSERT_EQUALS(runNoBankPairs[0], RunBankPair(123, 1));
+    TS_ASSERT_EQUALS(runNoBankPairs[1], RunBankPair(123, 2));
+    TS_ASSERT_EQUALS(runNoBankPairs[2], RunBankPair(456, 2));
+    TS_ASSERT_EQUALS(runNoBankPairs[3], RunBankPair(789, 1));
+  }
+};
+
+#endif
\ No newline at end of file
diff --git a/qt/scientific_interfaces/test/EnggDiffFittingViewMock.h b/qt/scientific_interfaces/test/EnggDiffFittingViewMock.h
index c244b4d9bfa2af4b9a52918c54cebe1e0aa398db..5356e30ee18b5aa36be7ecd517adf151fc3ddbc5 100644
--- a/qt/scientific_interfaces/test/EnggDiffFittingViewMock.h
+++ b/qt/scientific_interfaces/test/EnggDiffFittingViewMock.h
@@ -99,6 +99,9 @@ public:
   // sets the current row of the fitting list widget
   MOCK_CONST_METHOD1(setFittingListWidgetCurrentRow, void(int idx));
 
+  // gets current value of the fitting list widget
+  MOCK_CONST_METHOD0(getFittingListWidgetCurrentValue, std::string());
+
   // sets the peak list according to the QString given
   MOCK_CONST_METHOD1(setPeakList, void(const std::string &peakList));
 
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/HintingLineEdit.h b/qt/widgets/common/inc/MantidQtWidgets/Common/HintingLineEdit.h
index 9f36d636a57b76d7375a3c5994780e198db33dc5..41904b5de4d32db7f000e781c05272c20d17ef06 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/HintingLineEdit.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/HintingLineEdit.h
@@ -64,6 +64,9 @@ protected:
 protected slots:
   void updateHints(const QString &text);
   void hideHints();
+
+private:
+  static QPalette createFixedPalette();
 };
 } // namespace MantidWidgets
 } // namepsace MantidQt
diff --git a/qt/widgets/common/src/HintingLineEdit.cpp b/qt/widgets/common/src/HintingLineEdit.cpp
index a085a2f56797f97cc7b7473e29ccfc900dc01797..ada5ffda61f3bb72bac710f01581a3e5a3a36198 100644
--- a/qt/widgets/common/src/HintingLineEdit.cpp
+++ b/qt/widgets/common/src/HintingLineEdit.cpp
@@ -5,6 +5,7 @@
 #include <QLabel>
 #include <QStyle>
 #include <QToolTip>
+#include <boost/algorithm/string.hpp>
 
 namespace MantidQt {
 namespace MantidWidgets {
@@ -20,7 +21,7 @@ HintingLineEdit::HintingLineEdit(
   m_hintLabel->setWordWrap(true);
   m_hintLabel->setIndent(1);
   m_hintLabel->setAutoFillBackground(true);
-  m_hintLabel->setPalette(QToolTip::palette());
+  m_hintLabel->setPalette(createFixedPalette());
   m_hintLabel->setForegroundRole(QPalette::ToolTipText);
   m_hintLabel->setBackgroundRole(QPalette::ToolTipBase);
   m_hintLabel->ensurePolished();
@@ -30,6 +31,29 @@ HintingLineEdit::HintingLineEdit(
   connect(this, SIGNAL(editingFinished()), this, SLOT(hideHints()));
 }
 
+/** Fixes the colour pallete so that the hints are readable.
+
+    Tooltips use the inactive text colours since they are never 'in focus'.
+    This causes problems on some linux distributions (specifically Fedora 26
+    and Ubuntu 16.04) where the inactive text colours are particularly light
+    and lack contrast with the colour used for the background.
+
+    This method creates a modified tooltip pallete which uses the active
+    window text colour instead.
+
+    @returns A tooltip pallete with contrasting tooltip text and background
+    colours.
+*/
+QPalette HintingLineEdit::createFixedPalette() {
+  auto toolTipPalette = QToolTip::palette();
+
+  auto const activeTextColour =
+      toolTipPalette.color(QPalette::ColorGroup::Active, QPalette::WindowText);
+  toolTipPalette.setColor(QPalette::ColorGroup::Inactive, QPalette::ToolTipText,
+                          activeTextColour);
+  return toolTipPalette;
+}
+
 HintingLineEdit::~HintingLineEdit() {}
 
 /** Handle a key press event.
diff --git a/scripts/Diffraction/isis_powder/pearl.py b/scripts/Diffraction/isis_powder/pearl.py
index b677f99b10339e40d5ac5ffc0ae05ddfb1047584..e1ac04b9647d9b370561b358d1f22d7f4d49977c 100644
--- a/scripts/Diffraction/isis_powder/pearl.py
+++ b/scripts/Diffraction/isis_powder/pearl.py
@@ -4,7 +4,8 @@ import mantid.simpleapi as mantid
 
 from isis_powder.routines import common, instrument_settings
 from isis_powder.abstract_inst import AbstractInst
-from isis_powder.pearl_routines import pearl_algs, pearl_output, pearl_advanced_config, pearl_param_mapping
+from isis_powder.pearl_routines import pearl_advanced_config, pearl_algs, pearl_calibration_algs, pearl_output, \
+    pearl_param_mapping
 
 
 class Pearl(AbstractInst):
@@ -41,6 +42,31 @@ class Pearl(AbstractInst):
         else:
             self._run_create_vanadium()
 
+    def create_cal(self, **kwargs):
+        self._switch_long_mode_inst_settings(kwargs.get("long_mode"))
+        self._inst_settings.update_attributes(kwargs=kwargs)
+        run_details = self._get_run_details(self._inst_settings.run_number)
+
+        cross_correlate_params = {"ReferenceSpectra": self._inst_settings.reference_spectra,
+                                  "WorkspaceIndexMin": self._inst_settings.cross_corr_ws_min,
+                                  "WorkspaceIndexMax": self._inst_settings.cross_corr_ws_max,
+                                  "XMin": self._inst_settings.cross_corr_x_min,
+                                  "XMax": self._inst_settings.cross_corr_x_max}
+        get_detector_offsets_params = {"DReference": self._inst_settings.d_reference,
+                                       "Step": self._inst_settings.get_det_offsets_step,
+                                       "XMin": self._inst_settings.get_det_offsets_x_min,
+                                       "XMax": self._inst_settings.get_det_offsets_x_max}
+
+        return pearl_calibration_algs.create_calibration(calibration_runs=self._inst_settings.run_number,
+                                                         instrument=self,
+                                                         offset_file_name=run_details.offset_file_path,
+                                                         grouping_file_name=run_details.grouping_file_path,
+                                                         calibration_dir=self._inst_settings.calibration_dir,
+                                                         rebin_1_params=self._inst_settings.cal_rebin_1,
+                                                         rebin_2_params=self._inst_settings.cal_rebin_2,
+                                                         cross_correlate_params=cross_correlate_params,
+                                                         get_det_offset_params=get_detector_offsets_params)
+
     def _run_create_vanadium(self):
         # Provides a minimal wrapper so if we have tt_mode 'all' we can loop round
         return self._create_vanadium(run_number_string=self._inst_settings.run_in_range,
diff --git a/scripts/Diffraction/isis_powder/pearl_routines/pearl_advanced_config.py b/scripts/Diffraction/isis_powder/pearl_routines/pearl_advanced_config.py
index 39341287ba9d8fd04f2dcac2c23c6f58a3bc1b4d..7d7cbe90991a867ebb04b42b1c6672f4f847b5a0 100644
--- a/scripts/Diffraction/isis_powder/pearl_routines/pearl_advanced_config.py
+++ b/scripts/Diffraction/isis_powder/pearl_routines/pearl_advanced_config.py
@@ -9,14 +9,15 @@ general_params = {
     "spline_coefficient": 60,
 
     "file_names": {
-        "vanadium_absorb_filename": "pearl_absorp_sphere_10mm_newinst2_long.nxs",
-        "tt88_grouping_filename": "pearl_group_12_1_TT88.cal",
-        "tt70_grouping_filename": "pearl_group_12_1_TT70.cal",
-        "tt35_grouping_filename": "pearl_group_12_1_TT35.cal"
+         "vanadium_absorb_filename": "pearl_absorp_sphere_10mm_newinst2_long.nxs",
+         "tt88_grouping_filename": "pearl_group_12_1_TT88.cal",
+         "tt70_grouping_filename": "pearl_group_12_1_TT70.cal",
+         "tt35_grouping_filename": "pearl_group_12_1_TT35.cal"
     },
 }
 
 long_mode_off_params = {
+    "create_cal_rebin_1_params": "100,-0.0006,19950",
     "monitor_lambda_crop_range": (0.03, 6.00),
     "monitor_integration_range": (0.6, 5.0),
     # This needs to be greater than the bank TOF cropping values or you will get data that divides to 0/inf
@@ -41,6 +42,7 @@ long_mode_off_params = {
 }
 
 long_mode_on_params = {
+    "create_cal_rebin_1_params": "20300,-0.0006,39990",
     "monitor_lambda_crop_range": (5.9, 12.0),
     "monitor_integration_range": (6, 10),
     # raw_data_tof_cropping needs to be have smaller/larger values than the bank TOF cropping values or
@@ -65,6 +67,22 @@ long_mode_on_params = {
     ]
 }
 
+calibration_params = {
+    "create_cal_rebin_2_params": "1.8,0.002,2.1",
+    "create_cal_cross_correlate_params": {
+        "cross_corr_reference_spectra": 20,
+        "cross_corr_ws_index_min": 9,
+        "cross_corr_ws_index_max": 1063,
+        "cross_corr_x_min": 1.8,
+        "cross_corr_x_max": 2.1
+    },
+    "create_cal_get_detector_offsets_params": {
+        "get_det_offsets_step": 0.002,
+        "get_det_offsets_x_min": -200,
+        "get_det_offsets_x_max": 200,
+        "get_det_offsets_d_ref": 1.912795
+    }
+}
 
 variable_help = {
     "long_mode_<on/off>_params": {
@@ -100,6 +118,22 @@ variable_help = {
                                       "workspace. This is used to normalise the workspace current.",
         "spline_coefficient": "The coefficient to use whilst calculating a spline for each bank during "
                               "a vanadium calibration."
+    },
+
+    "calibration_params": {
+        "create_cal_rebin_1_params": "The parameters for the first rebin step used to create a calibration file",
+        "create_cal_rebin_2_params": "The parameters for the second rebin step used to create a calibration file",
+        "cross_corr_reference_spectra": "The Workspace Index of the spectra to correlate all other spectra against",
+        "cross_corr_ws_index_min": "The workspace index of the first member of the range of spectra to cross-correlate "
+                                   "against",
+        "cross_corr_ws_index_max": "The workspace index of the last member of the range of spectra to cross-correlate "
+                                   "against",
+        "cross_corr_x_min": "The starting point of the region to be cross correlated",
+        "cross_corr_x_max": "The ending point of the region to be cross correlated",
+        "get_det_offsets_step": "Step size used to bin d-spacing data in GetDetectorOffsets",
+        "get_det_offsets_x_min": "Minimum of CrossCorrelation data to search for peak, usually negative",
+        "get_det_offsets_x_max": "Maximum of CrossCorrelation data to search for peak, usually positive",
+        "get_det_offsets_d_ref": "Center of reference peak in d-space"
     }
 }
 
@@ -107,6 +141,7 @@ variable_help = {
 def get_all_adv_variables(is_long_mode_on=False):
     long_mode_params = long_mode_on_params if is_long_mode_on else long_mode_off_params
     advanced_config_dict = {}
+    advanced_config_dict.update(calibration_params)
     advanced_config_dict.update(general_params)
     advanced_config_dict.update(long_mode_params)
     return advanced_config_dict
diff --git a/scripts/Diffraction/isis_powder/pearl_routines/pearl_calibration_algs.py b/scripts/Diffraction/isis_powder/pearl_routines/pearl_calibration_algs.py
index 39d0f90d2734f79dee6a1e60bf71413c9ea220f1..d85053d168add6538d7032ec4f7385be882076ec 100644
--- a/scripts/Diffraction/isis_powder/pearl_routines/pearl_calibration_algs.py
+++ b/scripts/Diffraction/isis_powder/pearl_routines/pearl_calibration_algs.py
@@ -3,92 +3,49 @@ from __future__ import (absolute_import, division, print_function)
 import os
 import mantid.simpleapi as mantid
 import isis_powder.routines.common as common
-from isis_powder.routines.common_enums import INPUT_BATCHING
-
-# TODO this entire file needs cleaning and refactoring
-
-
-def create_calibration(self, calibration_runs, offset_file_name, grouping_file_name):
-    input_ws_list = common.load_current_normalised_ws_list(run_number_string=calibration_runs, instrument=self,
+from isis_powder.routines.common_enums import INPUT_BATCHING, WORKSPACE_UNITS
+
+
+def create_calibration(calibration_runs, instrument, offset_file_name, grouping_file_name, calibration_dir,
+                       rebin_1_params, rebin_2_params, cross_correlate_params, get_det_offset_params):
+    """
+    Create a calibration file from (usually) a ceria run
+    :param calibration_runs: Run number(s) for this run
+    :param instrument: The PEARL instrument object
+    :param offset_file_name: Name of the file to write detector offset information to
+    :param grouping_file_name: Name of grouping calibration file
+    :param calibration_dir: Path to directory containing calibration information
+    :param rebin_1_params: Parameters for the first rebin step (as a string in the usual format)
+    :param rebin_2_params: Parameters for the second rebin step (as a string in the usual format)
+    :param cross_correlate_params: Parameters for CrossCorrelate (as a dictionary PropertyName: PropertyValue)
+    :param get_det_offset_params: Parameters for GetDetectorOffsets (as a dictionary PropertyName: PropertyValue)
+    """
+    input_ws_list = common.load_current_normalised_ws_list(run_number_string=calibration_runs, instrument=instrument,
                                                            input_batching=INPUT_BATCHING.Summed)
-    input_ws = input_ws_list[0]
-    run_details = self._get_run_details(calibration_runs)
-
-    if run_details.instrument_version == "new" or run_details.instrument_version == "new2":
-        input_ws = mantid.Rebin(InputWorkspace=input_ws, Params="100,-0.0006,19950")
-
-    d_spacing_cal = mantid.ConvertUnits(InputWorkspace=input_ws, Target="dSpacing")
-    d_spacing_cal = mantid.Rebin(InputWorkspace=d_spacing_cal, Params="1.8,0.002,2.1")
-
-    if run_details.instrument_version == "new2":
-        cross_cor_ws = mantid.CrossCorrelate(InputWorkspace=d_spacing_cal, ReferenceSpectra=20,
-                                             WorkspaceIndexMin=9, WorkspaceIndexMax=1063, XMin=1.8, XMax=2.1)
-
-    elif run_details.instrument_version == "new":
-        cross_cor_ws = mantid.CrossCorrelate(InputWorkspace=d_spacing_cal, ReferenceSpectra=20,
-                                             WorkspaceIndexMin=9, WorkspaceIndexMax=943, XMin=1.8, XMax=2.1)
-    else:
-        cross_cor_ws = mantid.CrossCorrelate(InputWorkspace=d_spacing_cal, ReferenceSpectra=500,
-                                             WorkspaceIndexMin=1, WorkspaceIndexMax=1440, XMin=1.8, XMax=2.1)
-    if self._old_api_uses_full_paths:  # Workaround for old API setting full paths
-        grouping_file_path = grouping_file_name
-        offset_file_path = offset_file_name
-    else:
-        offset_file_path = os.path.join(self.calibration_dir, offset_file_name)
-        grouping_file_path = os.path.join(self.calibration_dir, grouping_file_name)
-
-    # Ceo Cell refined to 5.4102(3) so 220 is 1.912795
-    offset_output_path = mantid.GetDetectorOffsets(InputWorkspace=cross_cor_ws, Step=0.002, DReference=1.912795,
-                                                   XMin=-200, XMax=200, GroupingFileName=offset_file_path)
-    del offset_output_path  # This isn't used so delete it to keep linters happy
-    aligned_ws = mantid.AlignDetectors(InputWorkspace=input_ws, CalibrationFile=offset_file_path)
-    cal_grouped_ws = mantid.DiffractionFocussing(InputWorkspace=aligned_ws, GroupingFileName=grouping_file_path)
-
-    common.remove_intermediate_workspace(d_spacing_cal)
-    common.remove_intermediate_workspace(cross_cor_ws)
-    common.remove_intermediate_workspace(aligned_ws)
-    common.remove_intermediate_workspace(cal_grouped_ws)
 
+    input_ws = input_ws_list[0]
+    calibration_ws = mantid.Rebin(InputWorkspace=input_ws, Params=rebin_1_params)
 
-def do_silicon_calibration(self, runs_to_process, cal_file_name, grouping_file_name):
-    # TODO fix all of this as the script is too limited to be useful
-    create_si_ws = common.load_current_normalised_ws_list(run_number_string=runs_to_process, instrument=self)
-    cycle_details = self._get_label_information(runs_to_process)
-    instrument_version = cycle_details["instrument_version"]
+    if calibration_ws.getAxis(0).getUnit().unitID() != WORKSPACE_UNITS.d_spacing:
+        calibration_ws = mantid.ConvertUnits(InputWorkspace=calibration_ws, Target="dSpacing")
 
-    if instrument_version == "new" or instrument_version == "new2":
-        create_si_ws = mantid.Rebin(InputWorkspace=create_si_ws, Params="100,-0.0006,19950")
+    rebinned = mantid.Rebin(InputWorkspace=calibration_ws, Params=rebin_2_params)
+    cross_correlated = mantid.CrossCorrelate(InputWorkspace=rebinned, **cross_correlate_params)
 
-    create_si_d_spacing_ws = mantid.ConvertUnits(InputWorkspace=create_si_ws, Target="dSpacing")
+    offset_file = os.path.join(calibration_dir, offset_file_name)
+    # Offsets workspace must be referenced as string so it can be deleted, as simpleapi doesn't recognise it as a ws
+    offsets_ws_name = "offsets"
+    mantid.GetDetectorOffsets(InputWorkspace=cross_correlated, GroupingFileName=offset_file,
+                              OutputWorkspace=offsets_ws_name, **get_det_offset_params)
 
-    if instrument_version == "new2":
-        create_si_d_spacing_rebin_ws = mantid.Rebin(InputWorkspace=create_si_d_spacing_ws, Params="1.71,0.002,2.1")
-        create_si_cross_corr_ws = mantid.CrossCorrelate(InputWorkspace=create_si_d_spacing_rebin_ws,
-                                                        ReferenceSpectra=20, WorkspaceIndexMin=9,
-                                                        WorkspaceIndexMax=1063, XMin=1.71, XMax=2.1)
-    elif instrument_version == "new":
-        create_si_d_spacing_rebin_ws = mantid.Rebin(InputWorkspace=create_si_d_spacing_ws, Params="1.85,0.002,2.05")
-        create_si_cross_corr_ws = mantid.CrossCorrelate(InputWorkspace=create_si_d_spacing_rebin_ws,
-                                                        ReferenceSpectra=20, WorkspaceIndexMin=9,
-                                                        WorkspaceIndexMax=943, XMin=1.85, XMax=2.05)
-    elif instrument_version == "old":
-        create_si_d_spacing_rebin_ws = mantid.Rebin(InputWorkspace=create_si_d_spacing_ws, Params="3,0.002,3.2")
-        create_si_cross_corr_ws = mantid.CrossCorrelate(InputWorkspace=create_si_d_spacing_rebin_ws,
-                                                        ReferenceSpectra=500, WorkspaceIndexMin=1,
-                                                        WorkspaceIndexMax=1440, XMin=3, XMax=3.2)
-    else:
-        raise NotImplementedError("The instrument version is not supported for creating a silicon calibration")
+    rebinned_tof = mantid.ConvertUnits(InputWorkspace=rebinned, Target="TOF")
+    aligned = mantid.AlignDetectors(InputWorkspace=rebinned_tof, CalibrationFile=offset_file)
 
-    common.remove_intermediate_workspace(create_si_d_spacing_ws)
-    common.remove_intermediate_workspace(create_si_d_spacing_rebin_ws)
+    grouping_file = os.path.join(calibration_dir, grouping_file_name)
+    focused = mantid.DiffractionFocussing(InputWorkspace=aligned, GroupingFileName=grouping_file,
+                                          OutputWorkspace=instrument._generate_output_file_name(calibration_runs)
+                                          + "_grouped")
 
-    calibration_output_path = self.calibration_dir + cal_file_name
-    create_si_offsets_ws = mantid.GetDetectorOffsets(InputWorkspace=create_si_cross_corr_ws,
-                                                     Step=0.002, DReference=1.920127251, XMin=-200, XMax=200,
-                                                     GroupingFileName=calibration_output_path)
-    create_si_aligned_ws = mantid.AlignDetectors(InputWorkspace=create_si_ws,
-                                                 CalibrationFile=calibration_output_path)
-    grouping_output_path = self.calibration_dir + grouping_file_name
-    create_si_grouped_ws = mantid.DiffractionFocussing(InputWorkspace=create_si_aligned_ws,
-                                                       GroupingFileName=grouping_output_path)
-    del create_si_offsets_ws, create_si_grouped_ws
+    common.remove_intermediate_workspace([calibration_ws, rebinned, cross_correlated, rebinned_tof, aligned,
+                                          offsets_ws_name])
+    return focused
diff --git a/scripts/Diffraction/isis_powder/pearl_routines/pearl_param_mapping.py b/scripts/Diffraction/isis_powder/pearl_routines/pearl_param_mapping.py
index 5c3de085f7b9607beced67d1407b4c99129d4062..cc7902e28d57964fd80280658f4116da6471ad8a 100644
--- a/scripts/Diffraction/isis_powder/pearl_routines/pearl_param_mapping.py
+++ b/scripts/Diffraction/isis_powder/pearl_routines/pearl_param_mapping.py
@@ -6,32 +6,43 @@ from isis_powder.pearl_routines.pearl_enums import PEARL_FOCUS_MODES, PEARL_TT_M
 #                 Maps friendly user name (ext_name) -> script name (int_name)
 attr_mapping = \
     [
-        ParamMapEntry(ext_name="attenuation_file_path",      int_name="attenuation_file_path"),
-        ParamMapEntry(ext_name="config_file",                int_name="config_file_name"),
-        ParamMapEntry(ext_name="calibration_mapping_file",   int_name="cal_mapping_path"),
-        ParamMapEntry(ext_name="calibration_directory",      int_name="calibration_dir"),
-        ParamMapEntry(ext_name="do_absorb_corrections",      int_name="absorb_corrections"),
-        ParamMapEntry(ext_name="file_ext",                   int_name="file_extension", optional=True),
-        ParamMapEntry(ext_name="focused_cropping_values",    int_name="tof_cropping_values"),
-        ParamMapEntry(ext_name="focus_mode",                 int_name="focus_mode", enum_class=PEARL_FOCUS_MODES),
-        ParamMapEntry(ext_name="long_mode",                  int_name="long_mode"),
-        ParamMapEntry(ext_name="monitor_lambda_crop_range",  int_name="monitor_lambda"),
-        ParamMapEntry(ext_name="monitor_integration_range",  int_name="monitor_integration_range"),
-        ParamMapEntry(ext_name="monitor_mask_regions",       int_name="monitor_mask_regions"),
-        ParamMapEntry(ext_name="monitor_spectrum_number",    int_name="monitor_spec_no"),
-        ParamMapEntry(ext_name="monitor_spline_coefficient", int_name="monitor_spline"),
-        ParamMapEntry(ext_name="output_directory",           int_name="output_dir"),
-        ParamMapEntry(ext_name="perform_attenuation",        int_name="perform_atten"),
-        ParamMapEntry(ext_name="raw_data_tof_cropping",      int_name="raw_data_crop_vals"),
-        ParamMapEntry(ext_name="run_in_cycle",               int_name="run_in_range"),
-        ParamMapEntry(ext_name="run_number",                 int_name="run_number"),
-        ParamMapEntry(ext_name="spline_coefficient",         int_name="spline_coefficient"),
-        ParamMapEntry(ext_name="tt88_grouping_filename",     int_name="tt88_grouping"),
-        ParamMapEntry(ext_name="tt70_grouping_filename",     int_name="tt70_grouping"),
-        ParamMapEntry(ext_name="tt35_grouping_filename",     int_name="tt35_grouping"),
-        ParamMapEntry(ext_name="tt_mode",                    int_name="tt_mode", enum_class=PEARL_TT_MODES),
-        ParamMapEntry(ext_name="user_name",                  int_name="user_name"),
-        ParamMapEntry(ext_name="vanadium_absorb_filename",   int_name="van_absorb_file"),
-        ParamMapEntry(ext_name="vanadium_tof_cropping",      int_name="van_tof_cropping"),
-        ParamMapEntry(ext_name="vanadium_normalisation",     int_name="van_norm")
+        ParamMapEntry(ext_name="attenuation_file_path",        int_name="attenuation_file_path"),
+        ParamMapEntry(ext_name="config_file",                  int_name="config_file_name"),
+        ParamMapEntry(ext_name="calibration_mapping_file",     int_name="cal_mapping_path"),
+        ParamMapEntry(ext_name="calibration_directory",        int_name="calibration_dir"),
+        ParamMapEntry(ext_name="create_cal_rebin_1_params",    int_name="cal_rebin_1"),
+        ParamMapEntry(ext_name="create_cal_rebin_2_params",    int_name="cal_rebin_2"),
+        ParamMapEntry(ext_name="cross_corr_reference_spectra", int_name="reference_spectra"),
+        ParamMapEntry(ext_name="cross_corr_ws_index_max",      int_name="cross_corr_ws_max"),
+        ParamMapEntry(ext_name="cross_corr_ws_index_min",      int_name="cross_corr_ws_min"),
+        ParamMapEntry(ext_name="cross_corr_x_min",             int_name="cross_corr_x_min"),
+        ParamMapEntry(ext_name="cross_corr_x_max",             int_name="cross_corr_x_max"),
+        ParamMapEntry(ext_name="do_absorb_corrections",        int_name="absorb_corrections"),
+        ParamMapEntry(ext_name="file_ext",                     int_name="file_extension", optional=True),
+        ParamMapEntry(ext_name="focused_cropping_values",      int_name="tof_cropping_values"),
+        ParamMapEntry(ext_name="focus_mode",                   int_name="focus_mode", enum_class=PEARL_FOCUS_MODES),
+        ParamMapEntry(ext_name="get_det_offsets_d_ref",        int_name="d_reference"),
+        ParamMapEntry(ext_name="get_det_offsets_step",         int_name="get_det_offsets_step"),
+        ParamMapEntry(ext_name="get_det_offsets_x_min",        int_name="get_det_offsets_x_min"),
+        ParamMapEntry(ext_name="get_det_offsets_x_max",        int_name="get_det_offsets_x_max"),
+        ParamMapEntry(ext_name="long_mode",                    int_name="long_mode"),
+        ParamMapEntry(ext_name="monitor_lambda_crop_range",    int_name="monitor_lambda"),
+        ParamMapEntry(ext_name="monitor_integration_range",    int_name="monitor_integration_range"),
+        ParamMapEntry(ext_name="monitor_mask_regions",         int_name="monitor_mask_regions"),
+        ParamMapEntry(ext_name="monitor_spectrum_number",      int_name="monitor_spec_no"),
+        ParamMapEntry(ext_name="monitor_spline_coefficient",   int_name="monitor_spline"),
+        ParamMapEntry(ext_name="output_directory",             int_name="output_dir"),
+        ParamMapEntry(ext_name="perform_attenuation",          int_name="perform_atten"),
+        ParamMapEntry(ext_name="raw_data_tof_cropping",        int_name="raw_data_crop_vals"),
+        ParamMapEntry(ext_name="run_in_cycle",                 int_name="run_in_range"),
+        ParamMapEntry(ext_name="run_number",                   int_name="run_number"),
+        ParamMapEntry(ext_name="spline_coefficient",           int_name="spline_coefficient"),
+        ParamMapEntry(ext_name="tt88_grouping_filename",       int_name="tt88_grouping"),
+        ParamMapEntry(ext_name="tt70_grouping_filename",       int_name="tt70_grouping"),
+        ParamMapEntry(ext_name="tt35_grouping_filename",       int_name="tt35_grouping"),
+        ParamMapEntry(ext_name="tt_mode",                      int_name="tt_mode", enum_class=PEARL_TT_MODES),
+        ParamMapEntry(ext_name="user_name",                    int_name="user_name"),
+        ParamMapEntry(ext_name="vanadium_absorb_filename",     int_name="van_absorb_file"),
+        ParamMapEntry(ext_name="vanadium_tof_cropping",        int_name="van_tof_cropping"),
+        ParamMapEntry(ext_name="vanadium_normalisation",       int_name="van_norm")
     ]
diff --git a/scripts/Diffraction/isis_powder/routines/common.py b/scripts/Diffraction/isis_powder/routines/common.py
index 60378e6b51879c9c45a1d3d3fca28eb1baba9624..61fe1cb7f64e66f0e8f90105d47253c641430414 100644
--- a/scripts/Diffraction/isis_powder/routines/common.py
+++ b/scripts/Diffraction/isis_powder/routines/common.py
@@ -206,8 +206,11 @@ def get_first_run_number(run_number_string):
     :return: The first run for the user input of runs
     """
     run_numbers = generate_run_numbers(run_number_string=run_number_string)
-    if isinstance(run_numbers, list):
-        run_numbers = run_numbers[0]
+
+    if not run_numbers:
+        raise RuntimeError("Attempted to load empty set of workspaces. Please input at least one valid run number")
+
+    run_numbers = run_numbers[0]
 
     return run_numbers