diff --git a/Framework/Crystal/inc/MantidCrystal/SCDCalibratePanels.h b/Framework/Crystal/inc/MantidCrystal/SCDCalibratePanels.h
index 5dd15e0463d980f34fd05e0dddcf082c299536cb..9de50b587506de1a0b84ed9aaa0e8b193963057e 100644
--- a/Framework/Crystal/inc/MantidCrystal/SCDCalibratePanels.h
+++ b/Framework/Crystal/inc/MantidCrystal/SCDCalibratePanels.h
@@ -180,8 +180,8 @@ private:
                              const std::vector<double> &params,
                              const std::vector<double> &errs);
   /// Function to find peaks near detector edge
-  bool edgePixel(DataObjects::PeaksWorkspace_sptr ws, std::string bankName,
-                 int col, int row, int Edge);
+  bool edgePixel(const DataObjects::PeaksWorkspace &ws,
+                 const std::string &bankName, int col, int row, int Edge);
   /// Function to calculate U
   void findU(DataObjects::PeaksWorkspace_sptr peaksWs);
   /// save workspaces
diff --git a/Framework/Crystal/src/SCDCalibratePanels.cpp b/Framework/Crystal/src/SCDCalibratePanels.cpp
index 31f3b9a47c64c62ffc38d730e85cdb20790557c7..34d0097acc187980cf6f910951fda11284beb068 100644
--- a/Framework/Crystal/src/SCDCalibratePanels.cpp
+++ b/Framework/Crystal/src/SCDCalibratePanels.cpp
@@ -96,22 +96,20 @@ void SCDCalibratePanels::Quat2RotxRotyRotz(const Quat Q, double &Rotx,
   @param  Edge         Number of edge points for each bank
   @return True if peak is on edge
 */
-bool SCDCalibratePanels::edgePixel(PeaksWorkspace_sptr ws, std::string bankName,
-                                   int col, int row, int Edge) {
+bool SCDCalibratePanels::edgePixel(const PeaksWorkspace &ws,
+                                   const std::string &bankName, int col,
+                                   int row, int Edge) {
   if (bankName.compare("None") == 0)
     return false;
-  Geometry::Instrument_const_sptr Iptr = ws->getInstrument();
-  boost::shared_ptr<const IComponent> parent =
-      Iptr->getComponentByName(bankName);
+  auto Iptr = ws.getInstrument();
+  auto parent = Iptr->getComponentByName(bankName);
   if (parent->type().compare("RectangularDetector") == 0) {
-    boost::shared_ptr<const RectangularDetector> RDet =
-        boost::dynamic_pointer_cast<const RectangularDetector>(parent);
-
+    auto RDet = boost::dynamic_pointer_cast<const RectangularDetector>(parent);
     return col < Edge || col >= (RDet->xpixels() - Edge) || row < Edge ||
            row >= (RDet->ypixels() - Edge);
   } else {
     std::vector<Geometry::IComponent_const_sptr> children;
-    boost::shared_ptr<const Geometry::ICompAssembly> asmb =
+    auto asmb =
         boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(parent);
     asmb->getChildren(children, false);
     int startI = 1;
@@ -119,11 +117,11 @@ bool SCDCalibratePanels::edgePixel(PeaksWorkspace_sptr ws, std::string bankName,
       startI = 0;
       parent = children[0];
       children.clear();
-      boost::shared_ptr<const Geometry::ICompAssembly> asmb =
+      auto asmb =
           boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(parent);
       asmb->getChildren(children, false);
     }
-    boost::shared_ptr<const Geometry::ICompAssembly> asmb2 =
+    auto asmb2 =
         boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[0]);
     std::vector<Geometry::IComponent_const_sptr> grandchildren;
     asmb2->getChildren(grandchildren, false);
@@ -139,29 +137,27 @@ bool SCDCalibratePanels::edgePixel(PeaksWorkspace_sptr ws, std::string bankName,
 void SCDCalibratePanels::exec() {
   PeaksWorkspace_sptr peaksWs = getProperty("PeakWorkspace");
   // We must sort the peaks
-  std::vector<std::pair<std::string, bool>> criteria;
-  criteria.push_back(std::pair<std::string, bool>("BankName", true));
+  std::vector<std::pair<std::string, bool>> criteria{{"BankName", true}};
   peaksWs->sort(criteria);
   // Remove peaks on edge
   int edge = this->getProperty("EdgePixels");
   if (edge > 0) {
-    for (int i = int(peaksWs->getNumberPeaks()) - 1; i >= 0; --i) {
-      const std::vector<Peak> &peaks = peaksWs->getPeaks();
-      if (edgePixel(peaksWs, peaks[i].getBankName(), peaks[i].getCol(),
-                    peaks[i].getRow(), edge)) {
-        peaksWs->removePeak(i);
-      }
-    }
+    std::vector<Peak> &peaks = peaksWs->getPeaks();
+    auto it = std::remove_if(
+        peaks.begin(), peaks.end(), [&peaksWs, edge, this](const Peak &pk) {
+          return this->edgePixel(*peaksWs, pk.getBankName(), pk.getCol(),
+                                 pk.getRow(), edge);
+        });
+    peaks.erase(it, peaks.end());
   }
   findU(peaksWs);
 
-  // Remove peaks that were not indexed
-  for (int i = static_cast<int>(peaksWs->getNumberPeaks()) - 1; i >= 0; --i) {
-    Peak peak = peaksWs->getPeak(i);
-    if (peak.getHKL() == V3D(0, 0, 0)) {
-      peaksWs->removePeak(i);
-    }
-  }
+  std::vector<Peak> &peaks = peaksWs->getPeaks();
+  auto it = std::remove_if(peaks.begin(), peaks.end(), [](const Peak &pk) {
+    return pk.getHKL() == V3D(0, 0, 0);
+  });
+  peaks.erase(it, peaks.end());
+
   int nPeaks = static_cast<int>(peaksWs->getNumberPeaks());
   bool changeL1 = getProperty("ChangeL1");
   bool changeSize = getProperty("ChangePanelSize");
@@ -178,18 +174,16 @@ void SCDCalibratePanels::exec() {
   PARALLEL_FOR1(peaksWs)
   for (int i = 0; i < static_cast<int>(MyBankNames.size()); ++i) {
     PARALLEL_START_INTERUPT_REGION
-    boost::container::flat_set<string>::iterator it = MyBankNames.begin();
-    advance(it, i);
-    std::string iBank = *it;
+    const std::string &iBank = *std::next(MyBankNames.begin(), i);
     const std::string bankName = "__PWS_" + iBank;
     PeaksWorkspace_sptr local = peaksWs->clone();
     AnalysisDataService::Instance().addOrReplace(bankName, local);
-    for (int j = nPeaks - 1; j >= 0; --j) {
-      Peak peak = local->getPeak(j);
-      if (peak.getBankName() != iBank) {
-        local->removePeak(j);
-      }
-    }
+    std::vector<Peak> &localPeaks = local->getPeaks();
+    auto lit = std::remove_if(
+        localPeaks.begin(), localPeaks.end(),
+        [&iBank](const Peak &pk) { return pk.getBankName() != iBank; });
+    localPeaks.erase(lit, localPeaks.end());
+
     int nBankPeaks = local->getNumberPeaks();
     if (nBankPeaks < 6) {
       g_log.notice() << "Too few peaks for " << iBank << "\n";
diff --git a/Framework/DataObjects/inc/MantidDataObjects/Peak.h b/Framework/DataObjects/inc/MantidDataObjects/Peak.h
index 90fcea8b70352c6daf25b49cd28b836cdcc95453..ae81526300e5b4325b95c3bd504c3a349d52795d 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/Peak.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/Peak.h
@@ -43,6 +43,8 @@ public:
 
   /// Copy constructor
   Peak(const Peak &other);
+  Peak(Peak &&) noexcept = default;
+  Peak &operator=(Peak &&) noexcept = default;
 
   // Construct a peak from a reference to the interface
 
@@ -54,7 +56,7 @@ public:
   void removeContributingDetector(const int id);
   const std::set<int> &getContributingDetIDs() const;
 
-  void setInstrument(Geometry::Instrument_const_sptr inst) override;
+  void setInstrument(const Geometry::Instrument_const_sptr &inst) override;
   Geometry::IDetector_const_sptr getDetector() const override;
   Geometry::Instrument_const_sptr getInstrument() const override;
 
diff --git a/Framework/DataObjects/src/Peak.cpp b/Framework/DataObjects/src/Peak.cpp
index 291a8998449f218e41fc61095b71a7061636ddf1..92d58b45138e604a8f6ece31ab1376ecac10299f 100644
--- a/Framework/DataObjects/src/Peak.cpp
+++ b/Framework/DataObjects/src/Peak.cpp
@@ -8,6 +8,8 @@
 #include "MantidKernel/Strings.h"
 #include "MantidKernel/System.h"
 
+#include "boost/make_shared.hpp"
+
 #include <algorithm>
 #include <cctype>
 #include <string>
@@ -27,7 +29,7 @@ Peak::Peak()
       m_finalEnergy(0.), m_GoniometerMatrix(3, 3, true),
       m_InverseGoniometerMatrix(3, 3, true), m_runNumber(0), m_monitorCount(0),
       m_row(-1), m_col(-1), m_orig_H(0), m_orig_K(0), m_orig_L(0),
-      m_peakShape(new NoShape) {
+      m_peakShape(boost::make_shared<NoShape>()) {
   convention = Kernel::ConfigService::Instance().getString("Q.convention");
 }
 
@@ -47,7 +49,8 @@ Peak::Peak(Geometry::Instrument_const_sptr m_inst,
     : m_H(0), m_K(0), m_L(0), m_intensity(0), m_sigmaIntensity(0),
       m_binCount(0), m_GoniometerMatrix(3, 3, true),
       m_InverseGoniometerMatrix(3, 3, true), m_runNumber(0), m_monitorCount(0),
-      m_orig_H(0), m_orig_K(0), m_orig_L(0), m_peakShape(new NoShape) {
+      m_orig_H(0), m_orig_K(0), m_orig_L(0),
+      m_peakShape(boost::make_shared<NoShape>()) {
   convention = Kernel::ConfigService::Instance().getString("Q.convention");
   this->setInstrument(m_inst);
   this->setQLabFrame(QLabFrame, detectorDistance);
@@ -73,7 +76,8 @@ Peak::Peak(Geometry::Instrument_const_sptr m_inst,
     : m_H(0), m_K(0), m_L(0), m_intensity(0), m_sigmaIntensity(0),
       m_binCount(0), m_GoniometerMatrix(goniometer),
       m_InverseGoniometerMatrix(goniometer), m_runNumber(0), m_monitorCount(0),
-      m_orig_H(0), m_orig_K(0), m_orig_L(0), m_peakShape(new NoShape) {
+      m_orig_H(0), m_orig_K(0), m_orig_L(0),
+      m_peakShape(boost::make_shared<NoShape>()) {
   convention = Kernel::ConfigService::Instance().getString("Q.convention");
   if (fabs(m_InverseGoniometerMatrix.Invert()) < 1e-8)
     throw std::invalid_argument(
@@ -95,7 +99,8 @@ Peak::Peak(Geometry::Instrument_const_sptr m_inst, int m_detectorID,
     : m_H(0), m_K(0), m_L(0), m_intensity(0), m_sigmaIntensity(0),
       m_binCount(0), m_GoniometerMatrix(3, 3, true),
       m_InverseGoniometerMatrix(3, 3, true), m_runNumber(0), m_monitorCount(0),
-      m_orig_H(0), m_orig_K(0), m_orig_L(0), m_peakShape(new NoShape) {
+      m_orig_H(0), m_orig_K(0), m_orig_L(0),
+      m_peakShape(boost::make_shared<NoShape>()) {
   convention = Kernel::ConfigService::Instance().getString("Q.convention");
   this->setInstrument(m_inst);
   this->setDetectorID(m_detectorID);
@@ -189,11 +194,7 @@ Peak::Peak(const Peak &other)
       samplePos(other.samplePos), detPos(other.detPos),
       m_orig_H(other.m_orig_H), m_orig_K(other.m_orig_K),
       m_orig_L(other.m_orig_L), m_detIDs(other.m_detIDs),
-      m_peakShape(other.m_peakShape->clone())
-
-{
-  convention = Kernel::ConfigService::Instance().getString("Q.convention");
-}
+      m_peakShape(other.m_peakShape->clone()), convention(other.convention) {}
 
 //----------------------------------------------------------------------------------------------
 /** Constructor making a Peak from IPeak interface
@@ -213,7 +214,7 @@ Peak::Peak(const Geometry::IPeak &ipeak)
       m_runNumber(ipeak.getRunNumber()),
       m_monitorCount(ipeak.getMonitorCount()), m_row(ipeak.getRow()),
       m_col(ipeak.getCol()), m_orig_H(0.), m_orig_K(0.), m_orig_L(0.),
-      m_peakShape(new NoShape) {
+      m_peakShape(boost::make_shared<NoShape>()) {
   convention = Kernel::ConfigService::Instance().getString("Q.convention");
   if (fabs(m_InverseGoniometerMatrix.Invert()) < 1e-8)
     throw std::invalid_argument(
@@ -343,7 +344,7 @@ const std::set<int> &Peak::getContributingDetIDs() const { return m_detIDs; }
  *
  * @param inst :: Instrument sptr to use
  */
-void Peak::setInstrument(Geometry::Instrument_const_sptr inst) {
+void Peak::setInstrument(const Geometry::Instrument_const_sptr &inst) {
   m_inst = inst;
   if (!inst)
     throw std::runtime_error("Peak::setInstrument(): No instrument is set!");
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h b/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h
index 278d2c9656fb49a848fab5e368692dc4a3e77af7..e54d48ef936434a40bc28b65baac300e05a7f7b0 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h
@@ -21,7 +21,7 @@ class MANTID_GEOMETRY_DLL IPeak {
 public:
   virtual ~IPeak() = default;
 
-  virtual void setInstrument(Geometry::Instrument_const_sptr inst) = 0;
+  virtual void setInstrument(const Geometry::Instrument_const_sptr &inst) = 0;
 
   virtual int getDetectorID() const = 0;
   virtual void setDetectorID(int m_DetectorID) = 0;
diff --git a/Framework/Geometry/test/MockObjects.h b/Framework/Geometry/test/MockObjects.h
index 6e377fb1b7defaf05343ddb0a6c3834a94c0ed40..60a4b0c697c5e3f71780a8514b00987f23af6373 100644
--- a/Framework/Geometry/test/MockObjects.h
+++ b/Framework/Geometry/test/MockObjects.h
@@ -58,7 +58,8 @@ Mock IPeak
 ------------------------------------------------------------*/
 class MockIPeak : public Mantid::Geometry::IPeak {
 public:
-  MOCK_METHOD1(setInstrument, void(Geometry::Instrument_const_sptr inst));
+  MOCK_METHOD1(setInstrument,
+               void(const Geometry::Instrument_const_sptr &inst));
   MOCK_CONST_METHOD0(getDetectorID, int());
   MOCK_METHOD1(setDetectorID, void(int m_DetectorID));
   MOCK_CONST_METHOD0(getDetector, Geometry::IDetector_const_sptr());
diff --git a/Framework/Kernel/inc/MantidKernel/Matrix.h b/Framework/Kernel/inc/MantidKernel/Matrix.h
index 939025b7529665f52d42f1636956c257bbf0bcb2..6614b67e87ff2c574f91361820cf2c9baac6d96b 100644
--- a/Framework/Kernel/inc/MantidKernel/Matrix.h
+++ b/Framework/Kernel/inc/MantidKernel/Matrix.h
@@ -68,6 +68,8 @@ public:
 
   Matrix(const Matrix<T> &);
   Matrix<T> &operator=(const Matrix<T> &);
+  Matrix(Matrix<T> &&) noexcept;
+  Matrix<T> &operator=(Matrix<T> &&) noexcept;
   ~Matrix();
 
   /// const Array accessor
diff --git a/Framework/Kernel/src/Matrix.cpp b/Framework/Kernel/src/Matrix.cpp
index 4037e3bd37b2c49e2d9178026e98f50dae624b93..5f9ced0d84bb7fb637229c751e16677cc213adb2 100644
--- a/Framework/Kernel/src/Matrix.cpp
+++ b/Framework/Kernel/src/Matrix.cpp
@@ -214,6 +214,27 @@ Matrix<T> &Matrix<T>::operator=(const Matrix<T> &A)
   return *this;
 }
 
+template <typename T>
+Matrix<T>::Matrix(Matrix<T> &&other) noexcept
+    : nx(other.nx), ny(other.ny), V(other.V) {
+  other.nx = 0;
+  other.ny = 0;
+  other.V = nullptr;
+}
+
+template <typename T>
+Matrix<T> &Matrix<T>::operator=(Matrix<T> &&other) noexcept {
+  nx = other.nx;
+  ny = other.ny;
+  V = other.V;
+
+  other.nx = 0;
+  other.ny = 0;
+  other.V = nullptr;
+
+  return *this;
+}
+
 template <typename T>
 Matrix<T>::~Matrix()
 /**