diff --git a/Framework/API/inc/MantidAPI/IMDHistoWorkspace.h b/Framework/API/inc/MantidAPI/IMDHistoWorkspace.h
index f81b29807e3ffe3614a7e6b9cea4b7c8d697e9d6..048f8624cbd2c93eab095dde05157cb1301212a7 100644
--- a/Framework/API/inc/MantidAPI/IMDHistoWorkspace.h
+++ b/Framework/API/inc/MantidAPI/IMDHistoWorkspace.h
@@ -35,9 +35,14 @@ public:
   }
   /// See the MDHistoWorkspace definition for descriptions of these
   virtual coord_t getInverseVolume() const = 0;
-  virtual signal_t *getSignalArray() const = 0;
-  virtual signal_t *getErrorSquaredArray() const = 0;
-  virtual signal_t *getNumEventsArray() const = 0;
+  virtual const signal_t *getSignalArray() const = 0;
+  virtual const signal_t *getErrorSquaredArray() const = 0;
+  virtual const signal_t *getNumEventsArray() const = 0;
+
+  virtual signal_t *mutableSignalArray() = 0;
+  virtual signal_t *mutableErrorSquaredArray() = 0;
+  virtual signal_t *mutableNumEventsArray() = 0;
+
   virtual void setTo(signal_t signal, signal_t errorSquared,
                      signal_t numEvents) = 0;
   virtual Mantid::Kernel::VMD getCenter(size_t linearIndex) const = 0;
diff --git a/Framework/DataObjects/inc/MantidDataObjects/CoordTransformAligned.h b/Framework/DataObjects/inc/MantidDataObjects/CoordTransformAligned.h
index 44428626a31d90bfae143d117973b4f3558f8777..b50e5e60b4cd00658d3d2ac68c18e981137c793c 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/CoordTransformAligned.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/CoordTransformAligned.h
@@ -42,11 +42,10 @@ public:
                         const size_t *dimensionToBinFrom, const coord_t *origin,
                         const coord_t *scaling);
   CoordTransformAligned(const size_t inD, const size_t outD,
-                        const std::vector<size_t> dimensionToBinFrom,
-                        const std::vector<coord_t> origin,
-                        const std::vector<coord_t> scaling);
+                        std::vector<size_t> dimensionToBinFrom,
+                        std::vector<coord_t> origin,
+                        std::vector<coord_t> scaling);
   CoordTransform *clone() const override;
-  ~CoordTransformAligned() override;
 
   std::string toXMLString() const override;
   std::string id() const override;
@@ -56,11 +55,11 @@ public:
 protected:
   /// For each dimension in the output, index in the input workspace of which
   /// dimension it is
-  size_t *m_dimensionToBinFrom;
+  std::vector<size_t> m_dimensionToBinFrom;
   /// Offset (minimum) position in each of the output dimensions, sized [outD]
-  coord_t *m_origin;
+  std::vector<coord_t> m_origin;
   /// Scaling from the input to the output dimension, sized [outD]
-  coord_t *m_scaling;
+  std::vector<coord_t> m_scaling;
 };
 
 } // namespace DataObjects
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h
index 4e6b7d112417f56c13e660971a1938b9a367500a..f681a3162e6fffde9e7acdbf5ac5c8d13f470a68 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h
@@ -11,15 +11,12 @@
 #include "MantidAPI/IMDIterator.h"
 #include "MantidAPI/IMDWorkspace.h"
 #include "MantidAPI/MDGeometry.h"
+#include "MantidDataObjects/DllConfig.h"
 #include "MantidDataObjects/WorkspaceSingleValue.h"
 #include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include "MantidGeometry/MDGeometry/MDHistoDimension.h"
 #include "MantidGeometry/MDGeometry/MDImplicitFunction.h"
 #include "MantidKernel/Exception.h"
-#include "MantidKernel/System.h"
-
-// using Mantid::DataObjects::WorkspaceSingleValue;
-// using Mantid::API::MDNormalization;
 
 namespace Mantid {
 namespace DataObjects {
@@ -38,7 +35,7 @@ namespace DataObjects {
  * @author Janik Zikovsky
  * @date 2011-03-24 11:21:06.280523
  */
-class DLLExport MDHistoWorkspace : public API::IMDHistoWorkspace {
+class MANTID_DATAOBJECTS_DLL MDHistoWorkspace : public API::IMDHistoWorkspace {
 public:
   MDHistoWorkspace(Mantid::Geometry::MDHistoDimension_sptr dimX,
                    Mantid::Geometry::MDHistoDimension_sptr dimY =
@@ -58,7 +55,6 @@ public:
                    Mantid::API::MDNormalization displayNormalization =
                        Mantid::API::NoNormalization);
   MDHistoWorkspace &operator=(const MDHistoWorkspace &other) = delete;
-  ~MDHistoWorkspace() override;
 
   /// Returns a clone of the workspace
   std::unique_ptr<MDHistoWorkspace> clone() const {
@@ -144,29 +140,51 @@ public:
    * To find the index into the linear array, dim0 + indexMultiplier[0]*dim1 +
    * ...
    */
-  const size_t *getIndexMultiplier() const { return indexMultiplier; }
+  const size_t *getIndexMultiplier() const { return indexMultiplier.data(); }
 
   /** @return the direct pointer to the signal array. For speed */
-  signal_t *getSignalArray() const override { return m_signals; }
+  const signal_t *getSignalArray() const override { return m_signals.data(); }
 
   /** @return the inverse of volume of EACH cell in the workspace. For
    * normalizing. */
   coord_t getInverseVolume() const override { return m_inverseVolume; }
 
   /** @return the direct pointer to the error squared array. For speed */
-  signal_t *getErrorSquaredArray() const override { return m_errorsSquared; }
+  const signal_t *getErrorSquaredArray() const override {
+    return m_errorsSquared.data();
+  }
 
   /** @return the direct pointer to the array of the number of events. For speed
    */
-  signal_t *getNumEventsArray() const override { return m_numEvents; }
+  const signal_t *getNumEventsArray() const override {
+    return m_numEvents.data();
+  }
 
   /** @return the direct pointer to the array of mask bits (bool). For
    * speed/testing */
-  bool *getMaskArray() const { return m_masks; }
+  const bool *getMaskArray() const { return m_masks.get(); }
 
   /** Return the aray of bin withs  (the linear length of a box) for each
    * dimension */
-  const coord_t *getBinWidths() const { return m_boxLength; }
+  const coord_t *getBinWidths() const { return m_boxLength.data(); }
+
+  /** @return the direct pointer to the signal array. For speed. non-const
+   * version */
+  signal_t *mutableSignalArray() override { return m_signals.data(); }
+
+  /** @return the direct pointer to the errors array. For speed. non-const
+   * version */
+  signal_t *mutableErrorSquaredArray() override {
+    return m_errorsSquared.data();
+  }
+
+  /** @return the direct pointer to the errors array. For speed. non-const
+   * version */
+  signal_t *mutableNumEventsArray() override { return m_numEvents.data(); }
+
+  /** @return the direct pointer to the array of mask bits (bool). For
+   * speed/testing */
+  bool *mutableMaskArray() { return m_masks.get(); }
 
   /// Get the special coordinate system.
   Kernel::SpecialCoordinateSystem getSpecialCoordinateSystem() const override;
@@ -446,36 +464,36 @@ private:
   size_t numDimensions;
 
   /// Linear array of signals for each bin
-  signal_t *m_signals;
+  std::vector<signal_t> m_signals;
 
   /// Linear array of errors for each bin
-  signal_t *m_errorsSquared;
+  std::vector<signal_t> m_errorsSquared;
 
   /// Number of contributing events for each bin.
-  signal_t *m_numEvents;
+  std::vector<signal_t> m_numEvents;
 
   /// Length of the m_signals / m_errorsSquared arrays.
   size_t m_length;
 
   /// To find the index into the linear array, dim0 + indexMultiplier[0]*dim1 +
   /// ...
-  size_t *indexMultiplier;
+  std::vector<size_t> indexMultiplier;
   /// For converting to/from linear index to tdimensions
-  size_t *m_indexMaker;
+  std::vector<size_t> m_indexMaker;
   /// Max index into each dimension
-  size_t *m_indexMax;
+  std::vector<size_t> m_indexMax;
 
   /// Inverse of the volume of EACH cell
   coord_t m_inverseVolume;
 
   /// Pre-calculated vertexes array for the 0th box
-  coord_t *m_vertexesArray;
+  std::vector<coord_t> m_vertexesArray;
 
   /// Vector of the length of the box in each dimension
-  coord_t *m_boxLength;
+  std::vector<coord_t> m_boxLength;
 
   /// Vector of the origin in each dimension
-  coord_t *m_origin;
+  std::vector<coord_t> m_origin;
   /// the number of events, contributed into the workspace;
   mutable uint64_t m_nEventsContributed;
 
@@ -502,8 +520,9 @@ protected:
   /// Protected copy constructor. May be used by childs for cloning.
   MDHistoWorkspace(const MDHistoWorkspace &other);
 
-  /// Linear array of masks for each bin
-  bool *m_masks;
+  /// Linear array of masks for each bin. Avoids using vector<bool>
+  /// due to performance concerns.
+  std::unique_ptr<bool[]> m_masks;
 };
 
 /// A shared pointer to a MDHistoWorkspace
diff --git a/Framework/DataObjects/src/CoordTransformAligned.cpp b/Framework/DataObjects/src/CoordTransformAligned.cpp
index 029bfca195ec7e38508743fff314d281cf540397..8df6a99239ac8b5e3d92a22dd21264401978447e 100644
--- a/Framework/DataObjects/src/CoordTransformAligned.cpp
+++ b/Framework/DataObjects/src/CoordTransformAligned.cpp
@@ -6,8 +6,6 @@
 // SPDX - License - Identifier: GPL - 3.0 +
 #include "MantidDataObjects/CoordTransformAligned.h"
 #include "MantidKernel/Matrix.h"
-#include "MantidKernel/Strings.h"
-#include "MantidKernel/System.h"
 
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
@@ -35,24 +33,18 @@ CoordTransformAligned::CoordTransformAligned(const size_t inD,
                                              const size_t *dimensionToBinFrom,
                                              const coord_t *origin,
                                              const coord_t *scaling)
-    : CoordTransform(inD, outD) {
+    : CoordTransform(inD, outD), m_dimensionToBinFrom(outD), m_origin(outD),
+      m_scaling(outD) {
   if (!origin || !scaling || !dimensionToBinFrom)
     throw std::runtime_error("CoordTransformAligned::ctor(): at least one of "
                              "the input arrays is a NULL pointer.");
-  m_dimensionToBinFrom = new size_t[outD];
-  m_origin = new coord_t[outD];
-  m_scaling = new coord_t[outD];
   for (size_t d = 0; d < outD; d++) {
     m_dimensionToBinFrom[d] = dimensionToBinFrom[d];
     if (m_dimensionToBinFrom[d] >= inD) {
-      delete[] m_dimensionToBinFrom;
-      delete[] m_origin;
-      delete[] m_scaling;
       throw std::runtime_error(
           "CoordTransformAligned::ctor(): invalid entry in "
           "dimensionToBinFrom[" +
-          Mantid::Kernel::Strings::toString(d) +
-          "]. Cannot build the coordinate transformation.");
+          std::to_string(d) + "]. Cannot build the coordinate transformation.");
     }
     m_origin[d] = origin[d];
     m_scaling[d] = scaling[d];
@@ -75,31 +67,22 @@ CoordTransformAligned::CoordTransformAligned(const size_t inD,
  *
  */
 CoordTransformAligned::CoordTransformAligned(
-    const size_t inD, const size_t outD,
-    const std::vector<size_t> dimensionToBinFrom,
-    const std::vector<coord_t> origin, const std::vector<coord_t> scaling)
-    : CoordTransform(inD, outD) {
-  if (dimensionToBinFrom.size() != outD || origin.size() != outD ||
-      scaling.size() != outD)
+    const size_t inD, const size_t outD, std::vector<size_t> dimensionToBinFrom,
+    std::vector<coord_t> origin, std::vector<coord_t> scaling)
+    : CoordTransform(inD, outD),
+      m_dimensionToBinFrom(std::move(dimensionToBinFrom)),
+      m_origin(std::move(origin)), m_scaling(std::move(scaling)) {
+  if (m_dimensionToBinFrom.size() != outD || m_origin.size() != outD ||
+      m_scaling.size() != outD)
     throw std::runtime_error("CoordTransformAligned::ctor(): at least one of "
                              "the input vectors is the wrong size.");
-  m_dimensionToBinFrom = new size_t[outD];
-  m_origin = new coord_t[outD];
-  m_scaling = new coord_t[outD];
   for (size_t d = 0; d < outD; d++) {
-    m_dimensionToBinFrom[d] = dimensionToBinFrom[d];
     if (m_dimensionToBinFrom[d] >= inD) {
-      delete[] m_dimensionToBinFrom;
-      delete[] m_origin;
-      delete[] m_scaling;
       throw std::runtime_error(
           "CoordTransformAligned::ctor(): invalid entry in "
           "dimensionToBinFrom[" +
-          Mantid::Kernel::Strings::toString(d) +
-          "]. Cannot build the coordinate transformation.");
+          std::to_string(d) + "]. Cannot build the coordinate transformation.");
     }
-    m_origin[d] = origin[d];
-    m_scaling[d] = scaling[d];
   }
 }
 
@@ -107,18 +90,8 @@ CoordTransformAligned::CoordTransformAligned(
 /** Virtual cloner
  * @return a copy of this object  */
 CoordTransform *CoordTransformAligned::clone() const {
-  auto out = new CoordTransformAligned(inD, outD, m_dimensionToBinFrom,
-                                       m_origin, m_scaling);
-  return out;
-}
-
-//----------------------------------------------------------------------------------------------
-/** Destructor
- */
-CoordTransformAligned::~CoordTransformAligned() {
-  delete[] m_dimensionToBinFrom;
-  delete[] m_origin;
-  delete[] m_scaling;
+  return new CoordTransformAligned(inD, outD, m_dimensionToBinFrom, m_origin,
+                                   m_scaling);
 }
 
 //----------------------------------------------------------------------------------------------
diff --git a/Framework/DataObjects/src/MDHistoWorkspace.cpp b/Framework/DataObjects/src/MDHistoWorkspace.cpp
index 5f2fbe680061ca467fdc4da40fd3bfe7f5025c70..12beca1c71a91b1937f950e12505edb90549103b 100644
--- a/Framework/DataObjects/src/MDHistoWorkspace.cpp
+++ b/Framework/DataObjects/src/MDHistoWorkspace.cpp
@@ -13,7 +13,6 @@
 #include "MantidGeometry/MDGeometry/MDDimensionExtents.h"
 #include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h"
 #include "MantidGeometry/MDGeometry/MDHistoDimension.h"
-#include "MantidKernel/System.h"
 #include "MantidKernel/Utils.h"
 #include "MantidKernel/VMD.h"
 #include "MantidKernel/WarningSuppressions.h"
@@ -69,7 +68,7 @@ MDHistoWorkspace::MDHistoWorkspace(
 MDHistoWorkspace::MDHistoWorkspace(
     std::vector<Mantid::Geometry::MDHistoDimension_sptr> &dimensions,
     Mantid::API::MDNormalization displayNormalization)
-    : IMDHistoWorkspace(), numDimensions(0), m_numEvents(nullptr),
+    : IMDHistoWorkspace(), numDimensions(0),
       m_nEventsContributed(std::numeric_limits<uint64_t>::quiet_NaN()),
       m_coordSystem(None), m_displayNormalization(displayNormalization) {
   this->init(dimensions);
@@ -84,7 +83,7 @@ MDHistoWorkspace::MDHistoWorkspace(
 MDHistoWorkspace::MDHistoWorkspace(
     std::vector<Mantid::Geometry::IMDDimension_sptr> &dimensions,
     Mantid::API::MDNormalization displayNormalization)
-    : IMDHistoWorkspace(), numDimensions(0), m_numEvents(nullptr),
+    : IMDHistoWorkspace(), numDimensions(0),
       m_nEventsContributed(std::numeric_limits<uint64_t>::quiet_NaN()),
       m_coordSystem(None), m_displayNormalization(displayNormalization) {
   this->init(dimensions);
@@ -103,31 +102,15 @@ MDHistoWorkspace::MDHistoWorkspace(const MDHistoWorkspace &other)
   // Dimensions are copied by the copy constructor of MDGeometry
   this->cacheValues();
   // Allocate the linear arrays
-  m_signals = new signal_t[m_length];
-  m_errorsSquared = new signal_t[m_length];
-  m_numEvents = new signal_t[m_length];
-  m_masks = new bool[m_length];
+  m_signals = std::vector<signal_t>(m_length);
+  m_errorsSquared = std::vector<signal_t>(m_length);
+  m_numEvents = std::vector<signal_t>(m_length);
+  m_masks = std::make_unique<bool[]>(m_length);
   // Now copy all the data
-  std::copy_n(other.m_signals, m_length, m_signals);
-  std::copy_n(other.m_errorsSquared, m_length, m_errorsSquared);
-  std::copy_n(other.m_numEvents, m_length, m_numEvents);
-  std::copy_n(other.m_masks, m_length, m_masks);
-}
-
-//----------------------------------------------------------------------------------------------
-/** Destructor
- */
-MDHistoWorkspace::~MDHistoWorkspace() {
-  delete[] m_signals;
-  delete[] m_errorsSquared;
-  delete[] m_numEvents;
-  delete[] indexMultiplier;
-  delete[] m_vertexesArray;
-  delete[] m_boxLength;
-  delete[] m_indexMaker;
-  delete[] m_indexMax;
-  delete[] m_origin;
-  delete[] m_masks;
+  std::copy_n(other.m_signals.begin(), m_length, m_signals.begin());
+  std::copy_n(other.m_errorsSquared.begin(), m_length, m_errorsSquared.begin());
+  std::copy_n(other.m_numEvents.begin(), m_length, m_numEvents.begin());
+  std::copy_n(other.m_masks.get(), m_length, m_masks.get());
 }
 
 //----------------------------------------------------------------------------------------------
@@ -156,10 +139,10 @@ void MDHistoWorkspace::init(
   this->cacheValues();
 
   // Allocate the linear arrays
-  m_signals = new signal_t[m_length];
-  m_errorsSquared = new signal_t[m_length];
-  m_numEvents = new signal_t[m_length];
-  m_masks = new bool[m_length];
+  m_signals = std::vector<signal_t>(m_length);
+  m_errorsSquared = std::vector<signal_t>(m_length);
+  m_numEvents = std::vector<signal_t>(m_length);
+  m_masks = std::make_unique<bool[]>(m_length);
   // Initialize them to NAN (quickly)
   signal_t nan = std::numeric_limits<signal_t>::quiet_NaN();
   this->setTo(nan, nan, nan);
@@ -176,9 +159,9 @@ void MDHistoWorkspace::cacheValues() {
 
   // For indexing.
   if (numDimensions < 4)
-    indexMultiplier = new size_t[4];
+    indexMultiplier = std::vector<size_t>(4);
   else
-    indexMultiplier = new size_t[numDimensions];
+    indexMultiplier = std::vector<size_t>(numDimensions);
 
   // For quick indexing, accumulate these values
   // First multiplier
@@ -216,7 +199,7 @@ void MDHistoWorkspace::initVertexesArray() {
   size_t numVertices = size_t{1} << numDimensions;
 
   // Allocate the array of the right size
-  m_vertexesArray = new coord_t[nd * numVertices];
+  m_vertexesArray = std::vector<coord_t>(nd * numVertices);
 
   // For each vertex, increase an integeer
   for (size_t i = 0; i < numVertices; ++i) {
@@ -239,20 +222,20 @@ void MDHistoWorkspace::initVertexesArray() {
   }
 
   // Now set the m_boxLength and origin
-  m_boxLength = new coord_t[nd];
-  m_origin = new coord_t[nd];
+  m_boxLength = std::vector<coord_t>(nd);
+  m_origin = std::vector<coord_t>(nd);
   for (size_t d = 0; d < nd; d++) {
     m_boxLength[d] = m_dimensions[d]->getX(1) - m_dimensions[d]->getX(0);
     m_origin[d] = m_dimensions[d]->getX(0);
   }
 
   // The index calculator
-  m_indexMax = new size_t[numDimensions];
+  m_indexMax = std::vector<size_t>(numDimensions);
   for (size_t d = 0; d < nd; d++)
     m_indexMax[d] = m_dimensions[d]->getNBins();
-  m_indexMaker = new size_t[numDimensions];
-  Utils::NestedForLoop::SetUpIndexMaker(numDimensions, m_indexMaker,
-                                        m_indexMax);
+  m_indexMaker = std::vector<size_t>(numDimensions);
+  Utils::NestedForLoop::SetUpIndexMaker(numDimensions, m_indexMaker.data(),
+                                        m_indexMax.data());
 }
 
 //----------------------------------------------------------------------------------------------
@@ -264,10 +247,10 @@ void MDHistoWorkspace::initVertexesArray() {
  */
 void MDHistoWorkspace::setTo(signal_t signal, signal_t errorSquared,
                              signal_t numEvents) {
-  std::fill_n(m_signals, m_length, signal);
-  std::fill_n(m_errorsSquared, m_length, errorSquared);
-  std::fill_n(m_numEvents, m_length, numEvents);
-  std::fill_n(m_masks, m_length, false);
+  std::fill_n(m_signals.begin(), m_length, signal);
+  std::fill_n(m_errorsSquared.begin(), m_length, errorSquared);
+  std::fill_n(m_numEvents.begin(), m_length, numEvents);
+  std::fill_n(m_masks.get(), m_length, false);
   m_nEventsContributed = static_cast<uint64_t>(numEvents) * m_length;
 }
 
@@ -326,7 +309,8 @@ MDHistoWorkspace::getVertexesArray(size_t linearIndex,
   // Index into each dimension. Built from the linearIndex.
   size_t dimIndexes[10];
   Utils::NestedForLoop::GetIndicesFromLinearIndex(
-      numDimensions, linearIndex, m_indexMaker, m_indexMax, dimIndexes);
+      numDimensions, linearIndex, m_indexMaker.data(), m_indexMax.data(),
+      dimIndexes);
 
   // The output vertexes coordinates
   auto out = std::make_unique<coord_t[]>(numDimensions * numVertices);
@@ -352,7 +336,8 @@ Mantid::Kernel::VMD MDHistoWorkspace::getCenter(size_t linearIndex) const {
   // Index into each dimension. Built from the linearIndex.
   size_t dimIndexes[10];
   Utils::NestedForLoop::GetIndicesFromLinearIndex(
-      numDimensions, linearIndex, m_indexMaker, m_indexMax, dimIndexes);
+      numDimensions, linearIndex, m_indexMaker.data(), m_indexMax.data(),
+      dimIndexes);
 
   // The output vertexes coordinates
   VMD out(numDimensions);
@@ -1334,7 +1319,7 @@ void MDHistoWorkspace::clearMDMasking() {
 uint64_t MDHistoWorkspace::getNEvents() const {
   volatile uint64_t cach = this->m_nEventsContributed;
   if (cach != this->m_nEventsContributed) {
-    if (!m_numEvents)
+    if (m_numEvents.empty())
       m_nEventsContributed = std::numeric_limits<uint64_t>::quiet_NaN();
     else
       m_nEventsContributed = sumNContribEvents();
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BinMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BinMD.h
index 43d31ced5c7a67f2ebfde20a99b024452c5e44d7..45c040b9f0c9225fc054cbb9b5cc4bb2fe37b90e 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BinMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BinMD.h
@@ -64,10 +64,6 @@ private:
   /// Run the algorithm
   void exec() override;
 
-  //    /// Helper method
-  //    template<typename MDE, size_t nd>
-  //    void do_centerpointBin(typename MDEventWorkspace<MDE, nd>::sptr ws);
-
   /// Helper method
   template <typename MDE, size_t nd>
   void binByIterating(typename DataObjects::MDEventWorkspace<MDE, nd>::sptr ws);
@@ -82,10 +78,10 @@ private:
   /// Progress reporting
   std::unique_ptr<Mantid::API::Progress> prog = nullptr;
   /// ImplicitFunction used
-  Mantid::Geometry::MDImplicitFunction *implicitFunction;
+  std::unique_ptr<Mantid::Geometry::MDImplicitFunction> implicitFunction;
 
   /// Cached values for speed up
-  size_t *indexMultiplier;
+  std::vector<size_t> indexMultiplier;
   signal_t *signals;
   signal_t *errors;
   signal_t *numEvents;
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SlicingAlgorithm.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SlicingAlgorithm.h
index 2b98a3d0a1045c60f60303c4497981a546ca3cb4..d642355bbfb04f4bc0e2cb3ad5ec1db2732b4b13 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SlicingAlgorithm.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SlicingAlgorithm.h
@@ -18,7 +18,6 @@
 #include "MantidDataObjects/MDHistoWorkspace.h"
 #include "MantidGeometry/MDGeometry/MDHistoDimension.h"
 #include "MantidGeometry/MDGeometry/MDImplicitFunction.h"
-#include "MantidKernel/System.h"
 #include "MantidKernel/VMD.h"
 
 namespace Mantid {
@@ -52,10 +51,10 @@ protected:
   void makeAlignedDimensionFromString(const std::string &str);
   void makeBasisVectorFromString(const std::string &str);
 
-  Mantid::Geometry::MDImplicitFunction *
+  std::unique_ptr<Mantid::Geometry::MDImplicitFunction>
   getImplicitFunctionForChunk(const size_t *const chunkMin,
                               const size_t *const chunkMax);
-  Mantid::Geometry::MDImplicitFunction *
+  std::unique_ptr<Mantid::Geometry::MDImplicitFunction>
   getGeneralImplicitFunction(const size_t *const chunkMin,
                              const size_t *const chunkMax);
 
@@ -77,23 +76,24 @@ protected:
   /// Coordinate transformation to apply. This transformation
   /// contains the scaling that makes the output coordinate = bin indexes in the
   /// output MDHistoWorkspace.
-  Mantid::API::CoordTransform *m_transform;
+  std::unique_ptr<API::CoordTransform> m_transform;
 
   /// Coordinate transformation to save in the output workspace
   /// (original->binned)
-  Mantid::API::CoordTransform *m_transformFromOriginal;
+  std::unique_ptr<API::CoordTransform> m_transformFromOriginal;
   /// Coordinate transformation to save in the output workspace
   /// (binned->original)
-  Mantid::API::CoordTransform *m_transformToOriginal;
+  std::unique_ptr<API::CoordTransform> m_transformToOriginal;
 
   /// Intermediate original workspace. Output -> intermediate (MDHisto) ->
   /// original (MDEvent)
   Mantid::API::IMDWorkspace_sptr m_intermediateWS;
   /// Coordinate transformation to save in the output WS, from the intermediate
   /// WS
-  Mantid::DataObjects::CoordTransformAffine *m_transformFromIntermediate;
+  std::unique_ptr<DataObjects::CoordTransformAffine>
+      m_transformFromIntermediate;
   /// Coordinate transformation to save in the intermediate WS
-  Mantid::DataObjects::CoordTransformAffine *m_transformToIntermediate;
+  std::unique_ptr<DataObjects::CoordTransformAffine> m_transformToIntermediate;
 
   /// Set to true if the cut is aligned with the axes
   bool m_axisAligned;
diff --git a/Framework/MDAlgorithms/src/BinMD.cpp b/Framework/MDAlgorithms/src/BinMD.cpp
index 37fefc37f391d9fe8715ef447d4e78e5088db298..15bad624a67aa1ef5c9d767ae5fb53eae7193f51 100644
--- a/Framework/MDAlgorithms/src/BinMD.cpp
+++ b/Framework/MDAlgorithms/src/BinMD.cpp
@@ -38,8 +38,8 @@ using namespace Mantid::DataObjects;
 /** Constructor
  */
 BinMD::BinMD()
-    : outWS(), implicitFunction(nullptr), indexMultiplier(nullptr),
-      signals(nullptr), errors(nullptr), numEvents(nullptr) {}
+  : SlicingAlgorithm(), outWS(), implicitFunction(), indexMultiplier(), signals(nullptr),
+    errors(nullptr), numEvents(nullptr) {}
 
 //----------------------------------------------------------------------------------------------
 /** Initialize the algorithm's properties.
@@ -103,7 +103,7 @@ template <typename MDE, size_t nd>
 inline void BinMD::binMDBox(MDBox<MDE, nd> *box, const size_t *const chunkMin,
                             const size_t *const chunkMax) {
   // An array to hold the rotated/transformed coordinates
-  auto outCenter = new coord_t[m_outD];
+  auto outCenter = std::vector<coord_t>(m_outD);
 
   // Evaluate whether the entire box is in the same bin
   if (box->getNPoints() > (1 << nd) * 2) {
@@ -121,9 +121,7 @@ inline void BinMD::binMDBox(MDBox<MDE, nd> *box, const size_t *const chunkMin,
       const coord_t *inCenter = vertexes.get() + i * nd;
 
       // Now transform to the output dimensions
-      m_transform->apply(inCenter, outCenter);
-      // std::cout << "Input coord " << VMD(nd,inCenter) << " transformed to "
-      // <<  VMD(nd,outCenter) << '\n';
+      m_transform->apply(inCenter, outCenter.data());
 
       // To build up the linear index
       size_t linearIndex = 0;
@@ -174,7 +172,6 @@ inline void BinMD::binMDBox(MDBox<MDE, nd> *box, const size_t *const chunkMin,
 
       // And don't bother looking at each event. This may save lots of time
       // loading from disk.
-      delete[] outCenter;
       return;
     }
   }
@@ -188,7 +185,7 @@ inline void BinMD::binMDBox(MDBox<MDE, nd> *box, const size_t *const chunkMin,
     const coord_t *inCenter = it->getCenter();
 
     // Now transform to the output dimensions
-    m_transform->apply(inCenter, outCenter);
+    m_transform->apply(inCenter, outCenter.data());
 
     // To build up the linear index
     size_t linearIndex = 0;
@@ -222,8 +219,6 @@ inline void BinMD::binMDBox(MDBox<MDE, nd> *box, const size_t *const chunkMin,
   }
   // Done with the events list
   box->releaseEvents();
-
-  delete[] outCenter;
 }
 
 //----------------------------------------------------------------------------------------------
@@ -242,16 +237,16 @@ void BinMD::binByIterating(typename MDEventWorkspace<MDE, nd>::sptr ws) {
   // bc->setCacheParameters(1,0);
 
   // Cache some data to speed up accessing them a bit
-  indexMultiplier = new size_t[m_outD];
+  indexMultiplier.resize(m_outD);
   for (size_t d = 0; d < m_outD; d++) {
     if (d > 0)
       indexMultiplier[d] = outWS->getIndexMultiplier()[d - 1];
     else
       indexMultiplier[d] = 1;
   }
-  signals = outWS->getSignalArray();
-  errors = outWS->getErrorSquaredArray();
-  numEvents = outWS->getNumEventsArray();
+  signals = outWS->mutableSignalArray();
+  errors = outWS->mutableErrorSquaredArray();
+  numEvents = outWS->mutableNumEventsArray();
 
   if (!m_accumulate) {
     // Start with signal/error/numEvents at 0.0
@@ -311,13 +306,13 @@ void BinMD::binByIterating(typename MDEventWorkspace<MDE, nd>::sptr ws) {
 
       // Build an implicit function (it needs to be in the space of the
       // MDEventWorkspace)
-      MDImplicitFunction *function =
+      auto function =
           this->getImplicitFunctionForChunk(chunkMin.data(), chunkMax.data());
 
       // Use getBoxes() to get an array with a pointer to each box
       std::vector<API::IMDNode *> boxes;
       // Leaf-only; no depth limit; with the implicit function passed to it.
-      ws->getBox()->getBoxes(boxes, 1000, true, function);
+      ws->getBox()->getBoxes(boxes, 1000, true, function.get());
 
       // Sort boxes by file position IF file backed. This reduces seeking time,
       // hopefully.
@@ -357,11 +352,9 @@ void BinMD::binByIterating(typename MDEventWorkspace<MDE, nd>::sptr ws) {
       if (prog)
         prog->report("Applying implicit function.");
       signal_t nan = std::numeric_limits<signal_t>::quiet_NaN();
-      outWS->applyImplicitFunction(implicitFunction, nan, nan);
+      outWS->applyImplicitFunction(implicitFunction.get(), nan, nan);
     }
 
-    // return the size of the input workspace write buffer to its initial value
-    // bc->setCacheParameters(sizeof(MDE),writeBufSize);
 }
 
 //----------------------------------------------------------------------------------------------
@@ -378,9 +371,9 @@ void BinMD::exec() {
   std::string ImplicitFunctionXML = getPropertyValue("ImplicitFunctionXML");
   implicitFunction = nullptr;
   if (!ImplicitFunctionXML.empty())
-    implicitFunction =
+    implicitFunction = std::unique_ptr<MDImplicitFunction>(
         Mantid::API::ImplicitFunctionFactory::Instance().createUnwrapped(
-            ImplicitFunctionXML);
+            ImplicitFunctionXML));
 
   // This gets deleted by the thread pool; don't delete it in here.
   prog = std::make_unique<Progress>(this, 0.0, 1.0, 1);
@@ -396,8 +389,8 @@ void BinMD::exec() {
   }
 
   // Saves the geometry transformation from original to binned in the workspace
-  outWS->setTransformFromOriginal(this->m_transformFromOriginal, 0);
-  outWS->setTransformToOriginal(this->m_transformToOriginal, 0);
+  outWS->setTransformFromOriginal(this->m_transformFromOriginal.release(), 0);
+  outWS->setTransformToOriginal(this->m_transformToOriginal.release(), 0);
   for (size_t i = 0; i < m_bases.size(); i++)
     outWS->setBasisVector(i, m_bases[i]);
   outWS->setOrigin(this->m_translation);
@@ -406,8 +399,8 @@ void BinMD::exec() {
   // And the intermediate WS one too, if any
   if (m_intermediateWS) {
     outWS->setOriginalWorkspace(m_intermediateWS, 1);
-    outWS->setTransformFromOriginal(m_transformFromIntermediate, 1);
-    outWS->setTransformToOriginal(m_transformToIntermediate, 1);
+    outWS->setTransformFromOriginal(m_transformFromIntermediate.release(), 1);
+    outWS->setTransformToOriginal(m_transformToIntermediate.release(), 1);
   }
 
   // Wrapper to cast to MDEventWorkspace then call the function
diff --git a/Framework/MDAlgorithms/src/CreateMDHistoWorkspace.cpp b/Framework/MDAlgorithms/src/CreateMDHistoWorkspace.cpp
index 97ed05420bead3a1583c255efe9e9c378c1a8407..1e36bee4b00be9e3b9c26c149cd0c4bcbdd0f741 100644
--- a/Framework/MDAlgorithms/src/CreateMDHistoWorkspace.cpp
+++ b/Framework/MDAlgorithms/src/CreateMDHistoWorkspace.cpp
@@ -112,9 +112,9 @@ void CreateMDHistoWorkspace::init() {
  */
 void CreateMDHistoWorkspace::exec() {
   MDHistoWorkspace_sptr ws = this->createEmptyOutputWorkspace();
-  Mantid::signal_t *signals = ws->getSignalArray();
-  Mantid::signal_t *errors = ws->getErrorSquaredArray();
-  Mantid::signal_t *nEvents = ws->getNumEventsArray();
+  auto signals = ws->mutableSignalArray();
+  auto errors = ws->mutableErrorSquaredArray();
+  auto nEvents = ws->mutableNumEventsArray();
 
   std::vector<double> signalValues = getProperty("SignalInput");
   std::vector<double> errorValues = getProperty("ErrorInput");
diff --git a/Framework/MDAlgorithms/src/EvaluateMDFunction.cpp b/Framework/MDAlgorithms/src/EvaluateMDFunction.cpp
index 885cc1ee114f7179035e680eb6202698814b0e46..9be89662a6ebf1e1b264aab4e17df7f6c8ac1449 100644
--- a/Framework/MDAlgorithms/src/EvaluateMDFunction.cpp
+++ b/Framework/MDAlgorithms/src/EvaluateMDFunction.cpp
@@ -87,7 +87,7 @@ void EvaluateMDFunction::exec() {
 
   double *data = values.getPointerToCalculated(0);
   size_t length = values.size();
-  double *outputData = output->getSignalArray();
+  auto outputData = output->mutableSignalArray();
   std::copy(data, data + length, outputData);
 
   setProperty("OutputWorkspace", output);
diff --git a/Framework/MDAlgorithms/src/ImportMDHistoWorkspace.cpp b/Framework/MDAlgorithms/src/ImportMDHistoWorkspace.cpp
index 3b8ac9b5e805051b133f117a2dec0e6693a7becd..7e2564453c11d8129a7ec3faf1c67e9985f2560b 100644
--- a/Framework/MDAlgorithms/src/ImportMDHistoWorkspace.cpp
+++ b/Framework/MDAlgorithms/src/ImportMDHistoWorkspace.cpp
@@ -93,8 +93,8 @@ void ImportMDHistoWorkspace::exec() {
   }
 
   // Fetch out raw pointers to workspace arrays.
-  double *signals = ws->getSignalArray();
-  double *errors = ws->getErrorSquaredArray();
+  auto signals = ws->mutableSignalArray();
+  double *errors = ws->mutableErrorSquaredArray();
 
   // Write to the signal and error array from the deque.
   size_t currentBox = 0;
diff --git a/Framework/MDAlgorithms/src/IntegratePeaksMDHKL.cpp b/Framework/MDAlgorithms/src/IntegratePeaksMDHKL.cpp
index 6fd540708d198edcaedb9715c805f5bd164261fa..0d5face27563263ba58f0603b9a6c724a47d08e7 100644
--- a/Framework/MDAlgorithms/src/IntegratePeaksMDHKL.cpp
+++ b/Framework/MDAlgorithms/src/IntegratePeaksMDHKL.cpp
@@ -212,7 +212,7 @@ void IntegratePeaksMDHKL::integratePeak(const int neighborPts,
     gridPts.emplace_back(static_cast<int>(out->getDimension(i)->getNBins()));
   }
 
-  double *F = out->getSignalArray();
+  const auto F = out->getSignalArray();
   double Fmax = 0.;
   double Fmin = std::numeric_limits<double>::max();
   for (int i = 0; i < gridPts[0] * gridPts[1] * gridPts[2]; i++) {
@@ -221,7 +221,7 @@ void IntegratePeaksMDHKL::integratePeak(const int neighborPts,
       Fmax = std::max(Fmax, F[i]);
     }
   }
-  double *SqError = out->getErrorSquaredArray();
+  const auto SqError = out->getErrorSquaredArray();
 
   double minIntensity = Fmin + 0.01 * (Fmax - Fmin);
   int measuredPoints = 0;
diff --git a/Framework/MDAlgorithms/src/LoadMD.cpp b/Framework/MDAlgorithms/src/LoadMD.cpp
index 945294a548519a320713fb1ef734b892c41ddbe6..fd79f7ef116bc45596b02ff990ee4838f93e0b56 100644
--- a/Framework/MDAlgorithms/src/LoadMD.cpp
+++ b/Framework/MDAlgorithms/src/LoadMD.cpp
@@ -334,11 +334,11 @@ void LoadMD::loadHisto() {
   if (m_saveMDVersion == 2)
     m_file->openGroup("data", "NXdata");
   // Load each data slab
-  this->loadSlab("signal", ws->getSignalArray(), ws, ::NeXus::FLOAT64);
-  this->loadSlab("errors_squared", ws->getErrorSquaredArray(), ws,
+  this->loadSlab("signal", ws->mutableSignalArray(), ws, ::NeXus::FLOAT64);
+  this->loadSlab("errors_squared", ws->mutableErrorSquaredArray(), ws,
                  ::NeXus::FLOAT64);
-  this->loadSlab("num_events", ws->getNumEventsArray(), ws, ::NeXus::FLOAT64);
-  this->loadSlab("mask", ws->getMaskArray(), ws, ::NeXus::INT8);
+  this->loadSlab("num_events", ws->mutableNumEventsArray(), ws, ::NeXus::FLOAT64);
+  this->loadSlab("mask", ws->mutableMaskArray(), ws, ::NeXus::INT8);
 
   m_file->close();
 
diff --git a/Framework/MDAlgorithms/src/MDNorm.cpp b/Framework/MDAlgorithms/src/MDNorm.cpp
index 7ad0ed6c7944c4772530bd3a54edfea0bdc4065d..8522a1c76b7d86d7ac9c78e248287ff4f3107d42 100644
--- a/Framework/MDAlgorithms/src/MDNorm.cpp
+++ b/Framework/MDAlgorithms/src/MDNorm.cpp
@@ -1310,11 +1310,11 @@ PARALLEL_CHECK_INTERUPT_REGION
 if (m_accumulate) {
   std::transform(
       signalArray.cbegin(), signalArray.cend(), m_normWS->getSignalArray(),
-      m_normWS->getSignalArray(),
+      m_normWS->mutableSignalArray(),
       [](const std::atomic<signal_t> &a, const signal_t &b) { return a + b; });
 } else {
   std::copy(signalArray.cbegin(), signalArray.cend(),
-            m_normWS->getSignalArray());
+            m_normWS->mutableSignalArray());
 }
 m_accumulate = true;
 }
diff --git a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp
index 66c8a85fd78cd0e50ebab41a6765094d2ad01b3d..48121788de18a066d3ddff530b7610ee09534066 100644
--- a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp
+++ b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp
@@ -571,11 +571,11 @@ PARALLEL_CHECK_INTERUPT_REGION
 if (m_accumulate) {
   std::transform(
       signalArray.cbegin(), signalArray.cend(), m_normWS->getSignalArray(),
-      m_normWS->getSignalArray(),
+      m_normWS->mutableSignalArray(),
       [](const std::atomic<signal_t> &a, const signal_t &b) { return a + b; });
 } else {
   std::copy(signalArray.cbegin(), signalArray.cend(),
-            m_normWS->getSignalArray());
+            m_normWS->mutableSignalArray());
 }
 }
 
diff --git a/Framework/MDAlgorithms/src/MDNormSCD.cpp b/Framework/MDAlgorithms/src/MDNormSCD.cpp
index 62829b6cfc5359d76a5f2414f8874e169361431c..5f31243d10a167bc4123deabc470d6475fd7bfdb 100644
--- a/Framework/MDAlgorithms/src/MDNormSCD.cpp
+++ b/Framework/MDAlgorithms/src/MDNormSCD.cpp
@@ -531,11 +531,11 @@ PARALLEL_CHECK_INTERUPT_REGION
 if (m_accumulate) {
   std::transform(
       signalArray.cbegin(), signalArray.cend(), m_normWS->getSignalArray(),
-      m_normWS->getSignalArray(),
+      m_normWS->mutableSignalArray(),
       [](const std::atomic<signal_t> &a, const signal_t &b) { return a + b; });
 } else {
   std::copy(signalArray.cbegin(), signalArray.cend(),
-            m_normWS->getSignalArray());
+            m_normWS->mutableSignalArray());
 }
 }
 
diff --git a/Framework/MDAlgorithms/src/SaveZODS.cpp b/Framework/MDAlgorithms/src/SaveZODS.cpp
index 80068a0360fe7ff8f9cc8262c6589fdb0c21d42c..31ee505e8e89301a407739f989e5dd4586d0dbbc 100644
--- a/Framework/MDAlgorithms/src/SaveZODS.cpp
+++ b/Framework/MDAlgorithms/src/SaveZODS.cpp
@@ -126,7 +126,7 @@ void SaveZODS::exec() {
   file->writeData("size", size_field);
 
   // Copy data into a vector
-  signal_t *signal = ws->getSignalArray();
+  const auto signal = ws->getSignalArray();
   std::vector<double> data;
 
   for (int i = 0; i < size_field[0]; i++)
@@ -139,7 +139,7 @@ void SaveZODS::exec() {
   file->writeData("Data", data, size);
 
   // Copy errors (not squared) into a vector called sigma
-  signal_t *errorSquared = ws->getErrorSquaredArray();
+  const auto errorSquared = ws->getErrorSquaredArray();
   std::vector<double> sigma;
   sigma.reserve(numPoints);
   for (int i = 0; i < size_field[0]; i++)
diff --git a/Framework/MDAlgorithms/src/SliceMD.cpp b/Framework/MDAlgorithms/src/SliceMD.cpp
index eeacd05d98cd0b3f6362d28b587f592d5747fece..29b1129fd1d97e783f1c5262493adf6cd29a60ca 100644
--- a/Framework/MDAlgorithms/src/SliceMD.cpp
+++ b/Framework/MDAlgorithms/src/SliceMD.cpp
@@ -12,7 +12,6 @@
 #include "MantidGeometry/MDGeometry/MDImplicitFunction.h"
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/EnabledWhenProperty.h"
-#include "MantidKernel/System.h"
 #include "MantidKernel/ThreadPool.h"
 #include "MantidKernel/ThreadScheduler.h"
 
@@ -179,12 +178,11 @@ void SliceMD::slice(typename MDEventWorkspace<MDE, nd>::sptr ws) {
 
   // Function defining which events (in the input dimensions) to place in the
   // output
-  MDImplicitFunction *function =
-      this->getImplicitFunctionForChunk(nullptr, nullptr);
+  auto function = this->getImplicitFunctionForChunk(nullptr, nullptr);
 
   std::vector<API::IMDNode *> boxes;
   // Leaf-only; no depth limit; with the implicit function passed to it.
-  ws->getBox()->getBoxes(boxes, 1000, true, function);
+  ws->getBox()->getBoxes(boxes, 1000, true, function.get());
   // Sort boxes by file position IF file backed. This reduces seeking time,
   // hopefully.
   bool fileBackedWS = bc->isFileBacked();
diff --git a/Framework/MDAlgorithms/src/SlicingAlgorithm.cpp b/Framework/MDAlgorithms/src/SlicingAlgorithm.cpp
index 59d96842a35349e114138b9daf03aa0eda98791c..f8d4c2c5c9b2678c4f9750e847e8f9ea2f0bdb56 100644
--- a/Framework/MDAlgorithms/src/SlicingAlgorithm.cpp
+++ b/Framework/MDAlgorithms/src/SlicingAlgorithm.cpp
@@ -396,27 +396,24 @@ void SlicingAlgorithm::createGeneralTransform() {
 
   // OK now find the min/max coordinates of the edges in the INPUT workspace
   m_inputMinPoint = m_translation;
-  for (size_t d = 0; d < m_outD; d++)
+  for (size_t d = 0; d < m_outD; d++) {
     // Translate from the outCoords=(0,0,0) to outCoords=(min,min,min)
     m_inputMinPoint += (m_bases[d] * m_binDimensions[d]->getMinimum());
-  // std::cout << m_inputMinPoint << " m_inputMinPoint \n";
+  }
 
   // Create the CoordTransformAffine for BINNING with these basis vectors
-  auto ct = new DataObjects::CoordTransformAffine(inD, m_outD);
+  auto ct = std::make_unique<DataObjects::CoordTransformAffine>(inD, m_outD);
   // Note: the scaling makes the coordinate correspond to a bin index
-  // ct->buildOrthogonal(m_inputMinPoint, this->m_bases,
-  //                    VMD(this->m_binningScaling));
   ct->buildNonOrthogonal(m_inputMinPoint, this->m_bases,
                          VMD(this->m_binningScaling) / VMD(m_transformScaling));
-  this->m_transform = ct;
+  this->m_transform = std::move(ct);
 
   // Transformation original->binned
-  auto ctFrom = new DataObjects::CoordTransformAffine(inD, m_outD);
-  // ctFrom->buildOrthogonal(m_translation, this->m_bases,
-  //                        VMD(m_transformScaling));
+  auto ctFrom =
+      std::make_unique<DataObjects::CoordTransformAffine>(inD, m_outD);
   ctFrom->buildNonOrthogonal(m_translation, this->m_bases,
                              VMD(m_transformScaling) / VMD(m_transformScaling));
-  m_transformFromOriginal = ctFrom;
+  m_transformFromOriginal = std::move(ctFrom);
 
   // Validate
   if (m_transform->getInD() != inD)
@@ -434,12 +431,15 @@ void SlicingAlgorithm::createGeneralTransform() {
   m_transformToOriginal = nullptr;
   if (m_outD == inD) {
     // Can't reverse transform if you lost dimensions.
-    auto ctTo = new DataObjects::CoordTransformAffine(inD, m_outD);
-    Matrix<coord_t> toMatrix = ctFrom->getMatrix();
+    auto ctTo =
+        std::make_unique<DataObjects::CoordTransformAffine>(inD, m_outD);
+    auto toMatrix = static_cast<DataObjects::CoordTransformAffine *>(
+                        m_transformFromOriginal.get())
+                        ->getMatrix();
     // Invert the affine matrix to get the reverse transformation
     toMatrix.Invert();
     ctTo->setMatrix(toMatrix);
-    m_transformToOriginal = ctTo;
+    m_transformToOriginal = std::move(ctTo);
   }
 }
 
@@ -586,14 +586,15 @@ void SlicingAlgorithm::createAlignedTransform() {
   }
 
   // Transform for binning
-  m_transform = new DataObjects::CoordTransformAligned(
+  m_transform = std::make_unique<DataObjects::CoordTransformAligned>(
       m_inWS->getNumDims(), m_outD, m_dimensionToBinFrom, origin, scaling);
 
   // Transformation original->binned. There is no offset or scaling!
   std::vector<coord_t> unitScaling(m_outD, 1.0);
   std::vector<coord_t> zeroOrigin(m_outD, 0.0);
-  m_transformFromOriginal = new DataObjects::CoordTransformAligned(
-      inD, m_outD, m_dimensionToBinFrom, zeroOrigin, unitScaling);
+  m_transformFromOriginal =
+      std::make_unique<DataObjects::CoordTransformAligned>(
+          inD, m_outD, m_dimensionToBinFrom, zeroOrigin, unitScaling);
 
   // Now the reverse transformation.
   if (m_outD == inD) {
@@ -601,9 +602,9 @@ void SlicingAlgorithm::createAlignedTransform() {
     // dimension index is that?
     Matrix<coord_t> mat = m_transformFromOriginal->makeAffineMatrix();
     mat.Invert();
-    auto tmp = new DataObjects::CoordTransformAffine(inD, m_outD);
+    auto tmp = std::make_unique<DataObjects::CoordTransformAffine>(inD, m_outD);
     tmp->setMatrix(mat);
-    m_transformToOriginal = tmp;
+    m_transformToOriginal = std::move(tmp);
   } else {
     // Changed # of dimensions - can't reverse the transform
     m_transformToOriginal = nullptr;
@@ -718,13 +719,15 @@ void SlicingAlgorithm::createTransform() {
         Matrix<coord_t> matToIntermediate =
             matOriginalToIntermediate * matToOriginal;
 
-        m_transformToIntermediate = new DataObjects::CoordTransformAffine(
-            m_originalWS->getNumDims(), m_intermediateWS->getNumDims());
+        m_transformToIntermediate =
+            std::make_unique<DataObjects::CoordTransformAffine>(
+                m_originalWS->getNumDims(), m_intermediateWS->getNumDims());
         m_transformToIntermediate->setMatrix(matToIntermediate);
         // And now the reverse
         matToIntermediate.Invert();
-        m_transformFromIntermediate = new DataObjects::CoordTransformAffine(
-            m_intermediateWS->getNumDims(), m_originalWS->getNumDims());
+        m_transformFromIntermediate =
+            std::make_unique<DataObjects::CoordTransformAffine>(
+                m_intermediateWS->getNumDims(), m_originalWS->getNumDims());
         m_transformFromIntermediate->setMatrix(matToIntermediate);
       } catch (std::runtime_error &) {
         // Ignore error. Have no transform.
@@ -754,13 +757,13 @@ void SlicingAlgorithm::createTransform() {
  *        NULL to use the entire range.
  * @return MDImplicitFunction created
  */
-MDImplicitFunction *
+std::unique_ptr<MDImplicitFunction>
 SlicingAlgorithm::getGeneralImplicitFunction(const size_t *const chunkMin,
                                              const size_t *const chunkMax) {
   size_t nd = m_inWS->getNumDims();
 
   // General implicit function
-  auto func = new MDImplicitFunction;
+  auto func = std::make_unique<MDImplicitFunction>();
 
   // First origin = min of each basis vector
   VMD o1 = m_translation;
@@ -862,7 +865,7 @@ SlicingAlgorithm::getGeneralImplicitFunction(const size_t *const chunkMin,
  *        NULL to use the entire range.
  * @return MDImplicitFunction created
  */
-MDImplicitFunction *
+std::unique_ptr<MDImplicitFunction>
 SlicingAlgorithm::getImplicitFunctionForChunk(const size_t *const chunkMin,
                                               const size_t *const chunkMax) {
   size_t nd = m_inWS->getNumDims();
@@ -884,8 +887,7 @@ SlicingAlgorithm::getImplicitFunctionForChunk(const size_t *const chunkMin,
         function_max[d] =
             m_binDimensions[bd]->getX(m_binDimensions[bd]->getNBins());
     }
-    auto function = new MDBoxImplicitFunction(function_min, function_max);
-    return function;
+    return std::make_unique<MDBoxImplicitFunction>(function_min, function_max);
   } else {
     // General implicit function
     return getGeneralImplicitFunction(chunkMin, chunkMax);
diff --git a/Framework/MDAlgorithms/src/TransformMD.cpp b/Framework/MDAlgorithms/src/TransformMD.cpp
index e4829cc65e76da6bf26b9f662b8ca0ab8076f0df..e3a59c07c2bb00d8096157692c8cff9fabe51984 100644
--- a/Framework/MDAlgorithms/src/TransformMD.cpp
+++ b/Framework/MDAlgorithms/src/TransformMD.cpp
@@ -171,9 +171,9 @@ void TransformMD::exec() {
         axes[i] = 0;
         if (i > 0)
           histo = transposeMD(histo, axes);
-        signal_t *signals = histo->getSignalArray();
-        signal_t *errorsSq = histo->getErrorSquaredArray();
-        signal_t *numEvents = histo->getNumEventsArray();
+        signal_t *signals = histo->mutableSignalArray();
+        signal_t *errorsSq = histo->mutableErrorSquaredArray();
+        signal_t *numEvents = histo->mutableNumEventsArray();
 
         // Find the extents
         size_t nPoints =
diff --git a/Framework/MDAlgorithms/test/BinMDTest.h b/Framework/MDAlgorithms/test/BinMDTest.h
index a106bb13c0f78e214523d933f8c264f290260587..4a43e136088369ccb7c90cbe985cb2ad8273ca89 100644
--- a/Framework/MDAlgorithms/test/BinMDTest.h
+++ b/Framework/MDAlgorithms/test/BinMDTest.h
@@ -542,11 +542,10 @@ public:
       return;
 
     // Round-trip transform
-    coord_t originalPoint[3] = {1.0, 2.0, 3.0};
-    coord_t *transformedPoint = new coord_t[3];
-    coord_t *originalBack = new coord_t[3];
-    ctFrom->apply(originalPoint, transformedPoint);
-    ctTo->apply(transformedPoint, originalBack);
+    std::vector<coord_t> originalPoint = {1.0, 2.0, 3.0};
+    std::vector<coord_t> transformedPoint(3), originalBack(3);
+    ctFrom->apply(originalPoint.data(), transformedPoint.data());
+    ctTo->apply(transformedPoint.data(), originalBack.data());
     for (size_t d = 0; d < 3; d++) {
       TS_ASSERT_DELTA(originalPoint[d], originalBack[d], 1e-5);
     }
diff --git a/Framework/MDAlgorithms/test/CreateMDHistoWorkspaceTest.h b/Framework/MDAlgorithms/test/CreateMDHistoWorkspaceTest.h
index 18bc860ab5b7cc3ea4b0c6a699e04892ac2f736c..9b700a31d6d851aa549677115906459cd2712223 100644
--- a/Framework/MDAlgorithms/test/CreateMDHistoWorkspaceTest.h
+++ b/Framework/MDAlgorithms/test/CreateMDHistoWorkspaceTest.h
@@ -137,10 +137,10 @@ public:
     TS_ASSERT_EQUALS(5, dim1->getNBins());
 
     // Check the data
-    double *signals = outWs->getSignalArray();
+    const auto signals = outWs->getSignalArray();
     TS_ASSERT_DELTA(1, signals[0], 0.0001); // Check the first signal value
     TS_ASSERT_DELTA(2, signals[1], 0.0001); // Check the second signal value
-    double *errorsSQ = outWs->getErrorSquaredArray();
+    const auto errorsSQ = outWs->getErrorSquaredArray();
     TS_ASSERT_DELTA(0, errorsSQ[0], 0.0001); // Check the first error sq value
     TS_ASSERT_DELTA(0.01, errorsSQ[1],
                     0.0001); // Check the second error sq value
@@ -196,10 +196,10 @@ public:
                       dim2->getMDFrame().name());
 
     // Check the data
-    double *signals = outWs->getSignalArray();
+    const auto signals = outWs->getSignalArray();
     TS_ASSERT_DELTA(1, signals[0], 0.0001); // Check the first signal value
     TS_ASSERT_DELTA(2, signals[1], 0.0001); // Check the second signal value
-    double *errorsSQ = outWs->getErrorSquaredArray();
+    const auto errorsSQ = outWs->getErrorSquaredArray();
     TS_ASSERT_DELTA(0, errorsSQ[0], 0.0001); // Check the first error sq value
     TS_ASSERT_DELTA(0.01, errorsSQ[1],
                     0.0001); // Check the second error sq value
diff --git a/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h b/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h
index 54b7db147e459601b2f11f526817f8c7ee2244ff..4d9e4e836c8b6a3ad4489ab47f45658879aed2bb 100644
--- a/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h
+++ b/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h
@@ -47,9 +47,7 @@ public:
   /// Free up resources.
   ~MDFileObject() {
     m_file.close();
-    if (remove(m_filename.c_str()) != 0) {
-      std::cerr << "Cannot remove '" << m_filename << "'\n";
-    }
+    remove(m_filename.c_str());
   }
 
 private:
@@ -257,10 +255,10 @@ public:
     TS_ASSERT_EQUALS(2, dim2->getNBins());
 
     // Check the data
-    double *signals = outWs->getSignalArray();
+    auto signals = outWs->getSignalArray();
     TS_ASSERT_DELTA(1, signals[0], 0.0001); // Check the first signal value
     TS_ASSERT_DELTA(2, signals[1], 0.0001); // Check the second signal value
-    double *errorsSQ = outWs->getErrorSquaredArray();
+    const auto errorsSQ = outWs->getErrorSquaredArray();
     TS_ASSERT_DELTA(2 * 2, errorsSQ[0],
                     0.0001); // Check the first error sq value
     TS_ASSERT_DELTA(3 * 3, errorsSQ[1],
diff --git a/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h b/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h
index 788291556a1c2d4bb0ed981a55f04dca800f1baa..659c38c06aaa8693501ed63d089f94b61c6ad920 100644
--- a/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h
+++ b/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h
@@ -250,19 +250,19 @@ public:
     VMD outV;
 
     // The "binning" transform
-    CoordTransform *trans = alg->m_transform;
+    CoordTransform *trans = alg->m_transform.get();
     TS_ASSERT(trans);
     trans->apply(in, out);
     TS_ASSERT_EQUALS(VMD(3, out), VMD(0.5, 0.75, 1.25));
 
     // The "real" transform from original
-    CoordTransform *transFrom = alg->m_transformFromOriginal;
+    CoordTransform *transFrom = alg->m_transformFromOriginal.get();
     TS_ASSERT(transFrom);
     transFrom->apply(in, out);
     TS_ASSERT_EQUALS(VMD(3, out), VMD(2.5, 3.5, 4.5));
 
     // The "reverse" transform
-    CoordTransform *transTo = alg->m_transformToOriginal;
+    CoordTransform *transTo = alg->m_transformToOriginal.get();
     TS_ASSERT(transTo);
     transTo->apply(out, in);
     TS_ASSERT_EQUALS(VMD(3, in), VMD(2.5, 3.5, 4.5));
@@ -288,19 +288,19 @@ public:
     VMD outV;
 
     // The "binning" transform
-    CoordTransform *trans = alg->m_transform;
+    CoordTransform *trans = alg->m_transform.get();
     TS_ASSERT(trans);
     trans->apply(in, out);
     TS_ASSERT_EQUALS(VMD(3, out), VMD(1.25, 0.5, 0.75));
 
     // The "real" transform from original
-    CoordTransform *transFrom = alg->m_transformFromOriginal;
+    CoordTransform *transFrom = alg->m_transformFromOriginal.get();
     TS_ASSERT(transFrom);
     transFrom->apply(in, out);
     TS_ASSERT_EQUALS(VMD(3, out), VMD(4.5, 2.5, 3.5));
 
     // The "reverse" transform
-    CoordTransform *transTo = alg->m_transformToOriginal;
+    CoordTransform *transTo = alg->m_transformToOriginal.get();
     TS_ASSERT(transTo);
     transTo->apply(out, in);
     TS_ASSERT_EQUALS(VMD(3, in), VMD(2.5, 3.5, 4.5));
@@ -319,27 +319,26 @@ public:
     coord_t out[1];
 
     // The "binning" transform
-    CoordTransform *trans = alg->m_transform;
+    CoordTransform *trans = alg->m_transform.get();
     TS_ASSERT(trans);
     trans->apply(in, out);
     TS_ASSERT_DELTA(out[0], 0.5, 1e-5);
 
     // The "real" transform from original
-    CoordTransform *transFrom = alg->m_transformFromOriginal;
+    CoordTransform *transFrom = alg->m_transformFromOriginal.get();
     TS_ASSERT(transFrom);
     transFrom->apply(in, out);
     TS_ASSERT_DELTA(out[0], 2.5, 1e-5);
 
     // The "reverse" transform does NOT exist
-    CoordTransform *transTo = alg->m_transformToOriginal;
+    CoordTransform *transTo = alg->m_transformToOriginal.get();
     TS_ASSERT(transTo == nullptr);
   }
 
   void test_aligned_ImplicitFunction() {
     SlicingAlgorithmImpl *alg = do_createAlignedTransform(
         "Axis0, 2.0,8.0, 6", "Axis1, 2.0,8.0, 3", "Axis2, 2.0,8.0, 3", "");
-    MDImplicitFunction *func =
-        alg->getImplicitFunctionForChunk(nullptr, nullptr);
+    auto func = alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 6);
     TS_ASSERT(func->isPointContained(VMD(3, 4, 5)));
@@ -353,8 +352,7 @@ public:
     /* This defines a chunk implicit function between 3-4 in each axis */
     size_t chunkMin[3] = {1, 1, 1};
     size_t chunkMax[3] = {2, 2, 2};
-    MDImplicitFunction *func =
-        alg->getImplicitFunctionForChunk(chunkMin, chunkMax);
+    auto func = alg->getImplicitFunctionForChunk(chunkMin, chunkMax);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 6);
     TS_ASSERT(func->isPointContained(VMD(3.5, 3.5, 3.5)));
@@ -670,26 +668,25 @@ public:
     VMD outV;
 
     // The "binning" transform
-    CoordTransform *trans = alg->m_transform;
+    CoordTransform *trans = alg->m_transform.get();
     TS_ASSERT(trans);
     trans->apply(in, out);
     TS_ASSERT_EQUALS(VMD(3, out), VMD(cos(angle), -sin(angle), 1.3));
 
     // The "real" transform from original
-    CoordTransform *transFrom = alg->m_transformFromOriginal;
+    CoordTransform *transFrom = alg->m_transformFromOriginal.get();
     TS_ASSERT(transFrom);
     transFrom->apply(in, out);
     TS_ASSERT_EQUALS(VMD(3, out), VMD(cos(angle), -sin(angle), 1.3) * 2);
 
     // The "reverse" transform
-    CoordTransform *transTo = alg->m_transformToOriginal;
+    CoordTransform *transTo = alg->m_transformToOriginal.get();
     TS_ASSERT(transTo);
     transTo->apply(out, in);
     TS_ASSERT_EQUALS(VMD(3, in), VMD(3.0, 1.0, 2.6));
 
     // The implicit function
-    MDImplicitFunction *func =
-        alg->getImplicitFunctionForChunk(nullptr, nullptr);
+    auto func = alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 6);
     TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2)));
@@ -728,26 +725,25 @@ public:
     VMD outV;
 
     // The "binning" transform
-    CoordTransform *trans = alg->m_transform;
+    CoordTransform *trans = alg->m_transform.get();
     TS_ASSERT(trans);
     trans->apply(in, out);
     TS_ASSERT_EQUALS(VMD(3, out), VMD(1.5, 0.5, 1.3));
 
     // The "real" transform from original
-    CoordTransform *transFrom = alg->m_transformFromOriginal;
+    CoordTransform *transFrom = alg->m_transformFromOriginal.get();
     TS_ASSERT(transFrom);
     transFrom->apply(in, out);
     TS_ASSERT_EQUALS(VMD(3, out), VMD(3.0, 1.0, 2.6));
 
     // The "reverse" transform
-    CoordTransform *transTo = alg->m_transformToOriginal;
+    CoordTransform *transTo = alg->m_transformToOriginal.get();
     TS_ASSERT(transTo);
     transTo->apply(out, in);
     TS_ASSERT_EQUALS(VMD(3, in), VMD(3.0, -1.0, 2.6));
 
     // The implicit function
-    MDImplicitFunction *func =
-        alg->getImplicitFunctionForChunk(nullptr, nullptr);
+    auto func = alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 6);
     TS_ASSERT(func->isPointContained(VMD(1.5, -1.5, 2)));
@@ -764,7 +760,7 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 3);
 
     // The implicit function
-    MDImplicitFunction *func(nullptr);
+    std::unique_ptr<MDImplicitFunction> func;
     TS_ASSERT_THROWS_NOTHING(
         func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
@@ -785,7 +781,7 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 4);
 
     // The implicit function
-    MDImplicitFunction *func(nullptr);
+    std::unique_ptr<MDImplicitFunction> func;
     TS_ASSERT_THROWS_NOTHING(
         func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
@@ -804,7 +800,7 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 4);
 
     // The implicit function
-    MDImplicitFunction *func(nullptr);
+    std::unique_ptr<MDImplicitFunction> func;
     TS_ASSERT_THROWS_NOTHING(
         func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
@@ -822,7 +818,7 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 3);
 
     // The implicit function
-    MDImplicitFunction *func(nullptr);
+    std::unique_ptr<MDImplicitFunction> func;
     TS_ASSERT_THROWS_NOTHING(
         func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
@@ -843,7 +839,7 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 2);
 
     // The implicit function
-    MDImplicitFunction *func(nullptr);
+    std::unique_ptr<MDImplicitFunction> func;
     TS_ASSERT_THROWS_NOTHING(
         func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
@@ -862,7 +858,7 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 2);
 
     // The implicit function
-    MDImplicitFunction *func(nullptr);
+    std::unique_ptr<MDImplicitFunction> func;
     TS_ASSERT_THROWS_NOTHING(
         func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
@@ -881,7 +877,7 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 2);
 
     // The implicit function
-    MDImplicitFunction *func(nullptr);
+    std::unique_ptr<MDImplicitFunction> func;
     TS_ASSERT_THROWS_NOTHING(
         func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
@@ -923,26 +919,25 @@ public:
     VMD outV;
 
     // The "binning" transform
-    CoordTransform *trans = alg->m_transform;
+    CoordTransform *trans = alg->m_transform.get();
     TS_ASSERT(trans);
     trans->apply(in, out);
     TS_ASSERT_EQUALS(VMD(2, out), VMD(3.0, 1.0));
 
     // The "real" transform from original
-    CoordTransform *transFrom = alg->m_transformFromOriginal;
+    CoordTransform *transFrom = alg->m_transformFromOriginal.get();
     TS_ASSERT(transFrom);
     transFrom->apply(in, out);
     TS_ASSERT_EQUALS(VMD(2, out), VMD(+2, -12));
 
     // The "reverse" transform
-    CoordTransform *transTo = alg->m_transformToOriginal;
+    CoordTransform *transTo = alg->m_transformToOriginal.get();
     TS_ASSERT(transTo);
     transTo->apply(out, in);
     TS_ASSERT_EQUALS(VMD(2, in), VMD(3., -11.));
 
     // The implicit function
-    MDImplicitFunction *func =
-        alg->getImplicitFunctionForChunk(nullptr, nullptr);
+    auto func = alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 4);
     TS_ASSERT(func->isPointContained(VMD(-8.9, -18.9)));
@@ -989,26 +984,25 @@ public:
        which is offset by (11, 17.6) from the minimum (-10, -20)
        with bins of size (4,8) (in the OUTPUT dimensions),
        which means the bin coordinate is (11/4, 17.6/8) */
-    CoordTransform *trans = alg->m_transform;
+    CoordTransform *trans = alg->m_transform.get();
     TS_ASSERT(trans);
     trans->apply(in, out);
     TS_ASSERT_EQUALS(VMD(2, out), VMD(11. / 4., 17.6 / 8.));
 
     // The "real" transform from original
-    CoordTransform *transFrom = alg->m_transformFromOriginal;
+    CoordTransform *transFrom = alg->m_transformFromOriginal.get();
     TS_ASSERT(transFrom);
     transFrom->apply(in, out);
     TS_ASSERT_EQUALS(VMD(2, out), VMD(+1., -2.4));
 
     // The "reverse" transform
-    CoordTransform *transTo = alg->m_transformToOriginal;
+    CoordTransform *transTo = alg->m_transformToOriginal.get();
     TS_ASSERT(transTo);
     transTo->apply(out, in);
     TS_ASSERT_EQUALS(VMD(2, in), VMD(3., -11.));
 
     // The implicit function
-    MDImplicitFunction *func =
-        alg->getImplicitFunctionForChunk(nullptr, nullptr);
+    auto func = alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 4);
     TS_ASSERT(func->isPointContained(VMD(-18.9, -98.9)));
@@ -1036,7 +1030,7 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 2);
 
     // The implicit function
-    MDImplicitFunction *func(nullptr);
+    std::unique_ptr<MDImplicitFunction> func;
     TS_ASSERT_THROWS_NOTHING(
         func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
@@ -1058,7 +1052,7 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 2);
 
     // The implicit function
-    MDImplicitFunction *func(nullptr);
+    std::unique_ptr<MDImplicitFunction> func;
     TS_ASSERT_THROWS_NOTHING(
         func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
@@ -1082,7 +1076,7 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 4);
 
     // The implicit function
-    MDImplicitFunction *func(nullptr);
+    std::unique_ptr<MDImplicitFunction> func;
     TS_ASSERT_THROWS_NOTHING(
         func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
@@ -1103,7 +1097,7 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 3);
 
     // The implicit function
-    MDImplicitFunction *func(nullptr);
+    std::unique_ptr<MDImplicitFunction> func;
     TS_ASSERT_THROWS_NOTHING(
         func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
@@ -1123,8 +1117,7 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 1);
 
     // The implicit function
-    MDImplicitFunction *func =
-        alg->getImplicitFunctionForChunk(nullptr, nullptr);
+    auto func = alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 2);
     TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2, 345)));
@@ -1139,8 +1132,7 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 1);
 
     // The implicit function
-    MDImplicitFunction *func =
-        alg->getImplicitFunctionForChunk(nullptr, nullptr);
+    auto func = alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 2);
     TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2)));
@@ -1155,8 +1147,7 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 1);
 
     // The implicit function
-    MDImplicitFunction *func =
-        alg->getImplicitFunctionForChunk(nullptr, nullptr);
+    auto func = alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 2);
     TS_ASSERT(func->isPointContained(VMD(1.5, 1.5)));
@@ -1173,8 +1164,7 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 1);
 
     // The implicit function
-    MDImplicitFunction *func =
-        alg->getImplicitFunctionForChunk(nullptr, nullptr);
+    auto func = alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 2);
     VMD point(1);
diff --git a/Framework/MDAlgorithms/test/ThresholdMDTest.h b/Framework/MDAlgorithms/test/ThresholdMDTest.h
index 2ee5ebde979eec637dcf01f6af9bb95d9fe5cbee..30819e09f4e65dea303bdf41c090668352a5107b 100644
--- a/Framework/MDAlgorithms/test/ThresholdMDTest.h
+++ b/Framework/MDAlgorithms/test/ThresholdMDTest.h
@@ -37,8 +37,8 @@ public:
         "X", "X", frame, static_cast<coord_t>(0), static_cast<coord_t>(10),
         static_cast<size_t>(nBins));
     MDHistoWorkspace_sptr histo = boost::make_shared<MDHistoWorkspace>(dim);
-    signal_t *signals = histo->getSignalArray();
-    signal_t *errorsSQ = histo->getErrorSquaredArray();
+    auto signals = histo->mutableSignalArray();
+    auto errorsSQ = histo->mutableErrorSquaredArray();
     for (int i = 0; i < nBins; ++i) {
       signals[i] = signal;
       errorsSQ[i] = errorSQ;
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp
index 3d68171c2ff34e0e620bd2c4d7b8dc53f799066f..7e5d2c008cedb99f364ead5f711e575d17fb8d33 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp
@@ -42,7 +42,7 @@ namespace {
  * @param dims :: the dimensions vector (Py_intptr_t type)
  * @returns A python object containing the numpy array
  */
-PyObject *WrapReadOnlyNumpyFArray(Mantid::signal_t *arr,
+PyObject *WrapReadOnlyNumpyFArray(const Mantid::signal_t *arr,
                                   std::vector<Py_intptr_t> dims) {
   int datatype = Converters::NDArrayTypeIndex<Mantid::signal_t>::typenum;
 #if NPY_API_VERSION >= 0x00000007 //(1.7)
diff --git a/Framework/SINQ/src/LoadFlexiNexus.cpp b/Framework/SINQ/src/LoadFlexiNexus.cpp
index 4b0fbcb97b396cf0a45787e8334e237181054da7..51fab8ef01b5e5fc257d04ba3aa96c8cfd372dd6 100644
--- a/Framework/SINQ/src/LoadFlexiNexus.cpp
+++ b/Framework/SINQ/src/LoadFlexiNexus.cpp
@@ -223,8 +223,8 @@ void LoadFlexiNexus::loadMD(NeXus::File *fin) {
 
   auto ws = boost::make_shared<MDHistoWorkspace>(dimensions);
 
-  signal_t *dd = ws->getSignalArray();
-  signal_t *ddE = ws->getErrorSquaredArray();
+  auto dd = ws->mutableSignalArray();
+  signal_t *ddE = ws->mutableErrorSquaredArray();
 
   // assign data
   for (size_t i = 0; i < data.size(); i++) {
diff --git a/Framework/SINQ/src/SINQTranspose3D.cpp b/Framework/SINQ/src/SINQTranspose3D.cpp
index 51593003dd6811967aa5f17a144c498617640d51..1f953d91159a72847bcca37c9504654e91d8ef6a 100644
--- a/Framework/SINQ/src/SINQTranspose3D.cpp
+++ b/Framework/SINQ/src/SINQTranspose3D.cpp
@@ -58,7 +58,6 @@ void SINQTranspose3D::exec() {
 }
 
 void SINQTranspose3D::doYXZ(IMDHistoWorkspace_sptr inWS) {
-  double *inVal, *inErr, *outVal, *outErr;
   size_t idxIn, idxOut;
 
   boost::shared_ptr<const IMDDimension> x, y, z;
@@ -73,10 +72,10 @@ void SINQTranspose3D::doYXZ(IMDHistoWorkspace_sptr inWS) {
 
   auto outWS = boost::make_shared<MDHistoWorkspace>(dimensions);
 
-  inVal = inWS->getSignalArray();
-  inErr = inWS->getErrorSquaredArray();
-  outVal = outWS->getSignalArray();
-  outErr = outWS->getErrorSquaredArray();
+  const auto inVal = inWS->getSignalArray();
+  const auto inErr = inWS->getErrorSquaredArray();
+  auto outVal = outWS->mutableSignalArray();
+  auto outErr = outWS->mutableErrorSquaredArray();
   for (unsigned int xx = 0; xx < x->getNBins(); xx++) {
     for (unsigned int yy = 0; yy < y->getNBins(); yy++) {
       for (unsigned int zz = 0; zz < z->getNBins(); zz++) {
@@ -94,7 +93,6 @@ void SINQTranspose3D::doYXZ(IMDHistoWorkspace_sptr inWS) {
 }
 
 void SINQTranspose3D::doXZY(IMDHistoWorkspace_sptr inWS) {
-  double *inVal, *inErr, *outVal, *outErr;
   size_t idxIn, idxOut;
   unsigned int xdim, ydim, zdim;
 
@@ -110,10 +108,10 @@ void SINQTranspose3D::doXZY(IMDHistoWorkspace_sptr inWS) {
 
   auto outWS = boost::make_shared<MDHistoWorkspace>(dimensions);
 
-  inVal = inWS->getSignalArray();
-  inErr = inWS->getErrorSquaredArray();
-  outVal = outWS->getSignalArray();
-  outErr = outWS->getErrorSquaredArray();
+  const auto inVal = inWS->getSignalArray();
+  const auto inErr = inWS->getErrorSquaredArray();
+  auto outVal = outWS->mutableSignalArray();
+  auto outErr = outWS->mutableErrorSquaredArray();
   xdim = static_cast<unsigned int>(x->getNBins());
   ydim = static_cast<unsigned int>(y->getNBins());
   zdim = static_cast<unsigned int>(z->getNBins());
@@ -133,7 +131,6 @@ void SINQTranspose3D::doXZY(IMDHistoWorkspace_sptr inWS) {
   setProperty("OutputWorkspace", outWS);
 }
 void SINQTranspose3D::doTRICS(IMDHistoWorkspace_sptr inWS) {
-  double *inVal, *inErr, *outVal, *outErr;
   size_t idxIn, idxOut;
   unsigned int xdim, ydim, zdim;
 
@@ -150,10 +147,10 @@ void SINQTranspose3D::doTRICS(IMDHistoWorkspace_sptr inWS) {
   auto outWS = boost::make_shared<MDHistoWorkspace>(dimensions);
   outWS->setTo(.0, .0, .0);
 
-  inVal = inWS->getSignalArray();
-  inErr = inWS->getErrorSquaredArray();
-  outVal = outWS->getSignalArray();
-  outErr = outWS->getErrorSquaredArray();
+  const auto inVal = inWS->getSignalArray();
+  const auto inErr = inWS->getErrorSquaredArray();
+  auto outVal = outWS->mutableSignalArray();
+  auto outErr = outWS->mutableErrorSquaredArray();
   xdim = static_cast<unsigned int>(x->getNBins());
   ydim = static_cast<unsigned int>(y->getNBins());
   zdim = static_cast<unsigned int>(z->getNBins());
@@ -173,7 +170,7 @@ void SINQTranspose3D::doTRICS(IMDHistoWorkspace_sptr inWS) {
   setProperty("OutputWorkspace", outWS);
 }
 void SINQTranspose3D::doAMOR(IMDHistoWorkspace_sptr inWS) {
-  double val, *inVal;
+  double val;
   unsigned int xdim, ydim, zdim, idx;
 
   boost::shared_ptr<const IMDDimension> x, y, z;
@@ -192,7 +189,7 @@ void SINQTranspose3D::doAMOR(IMDHistoWorkspace_sptr inWS) {
   xdim = static_cast<unsigned int>(x->getNBins());
   ydim = static_cast<unsigned int>(y->getNBins());
   zdim = static_cast<unsigned int>(z->getNBins());
-  inVal = inWS->getSignalArray();
+  const auto inVal = inWS->getSignalArray();
   for (unsigned int xx = 0; xx < xdim; xx++) {
     for (unsigned int yy = 0; yy < ydim; yy++) {
       for (unsigned zz = 0; zz < zdim; zz++) {
diff --git a/Framework/SINQ/test/InvertMDDimTest.h b/Framework/SINQ/test/InvertMDDimTest.h
index 23d0aab197b41c5da38ee0aa1000474074a08e7f..042b13cd743c2bdf8405741a1de0d569ddb87480 100644
--- a/Framework/SINQ/test/InvertMDDimTest.h
+++ b/Framework/SINQ/test/InvertMDDimTest.h
@@ -52,7 +52,7 @@ public:
     TS_ASSERT_EQUALS(3, data->getNumDims());
     long nBin = static_cast<long>(data->getNPoints());
     long sum = 0;
-    double *sdata = data->getSignalArray();
+    const auto sdata = data->getSignalArray();
     for (long i = 0; i < nBin; i++) {
       sum += (long)sdata[i];
     }
diff --git a/Framework/SINQ/test/LoadFlexiNexusTest.h b/Framework/SINQ/test/LoadFlexiNexusTest.h
index e90125a0716666d2fb7f431edd1870bb910304fc..d44549b62124db04827ef391314813d0cd1bbfad 100644
--- a/Framework/SINQ/test/LoadFlexiNexusTest.h
+++ b/Framework/SINQ/test/LoadFlexiNexusTest.h
@@ -50,7 +50,7 @@ public:
             outputSpace);
     long nBin = static_cast<long>(data->getNPoints());
     long sum = 0;
-    double *sdata = data->getSignalArray();
+    auto sdata = data->getSignalArray();
     for (long i = 0; i < nBin; i++) {
       sum += (long)sdata[i];
     }
diff --git a/Framework/SINQ/test/ProjectMDTest.h b/Framework/SINQ/test/ProjectMDTest.h
index 393de3df906e9c4d24fa16791fc4ac4088d37586..0033890e8248c3a00d0d9523bde5d000a3e583e7 100644
--- a/Framework/SINQ/test/ProjectMDTest.h
+++ b/Framework/SINQ/test/ProjectMDTest.h
@@ -55,7 +55,7 @@ public:
     TS_ASSERT_EQUALS(2, data->getNumDims());
     long nBin = static_cast<long>(data->getNPoints());
     long sum = 0;
-    double *sdata = data->getSignalArray();
+    const auto sdata = data->getSignalArray();
     for (long i = 0; i < nBin; i++) {
       sum += (long)sdata[i];
     }
@@ -94,7 +94,7 @@ public:
     TS_ASSERT_EQUALS(2, data->getNumDims());
     long nBin = static_cast<long>(data->getNPoints());
     long sum = 0;
-    double *sdata = data->getSignalArray();
+    const auto sdata = data->getSignalArray();
     for (long i = 0; i < nBin; i++) {
       sum += (long)sdata[i];
     }
@@ -133,7 +133,7 @@ public:
     TS_ASSERT_EQUALS(2, data->getNumDims());
     long nBin = static_cast<long>(data->getNPoints());
     long sum = 0;
-    double *sdata = data->getSignalArray();
+    const auto sdata = data->getSignalArray();
     for (long i = 0; i < nBin; i++) {
       sum += (long)sdata[i];
     }
@@ -172,7 +172,7 @@ public:
     TS_ASSERT_EQUALS(2, data->getNumDims());
     long nBin = static_cast<long>(data->getNPoints());
     long sum = 0;
-    double *sdata = data->getSignalArray();
+    const auto sdata = data->getSignalArray();
     for (long i = 0; i < nBin; i++) {
       sum += (long)sdata[i];
     }
diff --git a/Framework/SINQ/test/SliceMDHistoTest.h b/Framework/SINQ/test/SliceMDHistoTest.h
index fd2b94351948ebb0435362a06aebdbf129efdc51..a9fef4c79e086979e813d3cc014ee5cdd98d0320 100644
--- a/Framework/SINQ/test/SliceMDHistoTest.h
+++ b/Framework/SINQ/test/SliceMDHistoTest.h
@@ -54,7 +54,7 @@ public:
             outputSpace);
     long nBin = static_cast<long>(data->getNPoints());
     long sum = 0;
-    double *sdata = data->getSignalArray();
+    auto sdata = data->getSignalArray();
     for (long i = 0; i < nBin; i++) {
       sum += (long)sdata[i];
     }
diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/FakeObjects.h b/Framework/TestHelpers/inc/MantidTestHelpers/FakeObjects.h
index e7ce57bad7fcf65beb9d4ab83b7b359d11e3c055..27dd5ea8bd8d4714b82cb81190e35f0e4c377535 100644
--- a/Framework/TestHelpers/inc/MantidTestHelpers/FakeObjects.h
+++ b/Framework/TestHelpers/inc/MantidTestHelpers/FakeObjects.h
@@ -484,15 +484,27 @@ public:
     throw std::runtime_error("Not Implemented");
   }
 
-  signal_t *getSignalArray() const override {
+  const signal_t *getSignalArray() const override {
     throw std::runtime_error("Not Implemented");
   }
 
-  signal_t *getErrorSquaredArray() const override {
+  const signal_t *getErrorSquaredArray() const override {
     throw std::runtime_error("Not Implemented");
   }
 
-  signal_t *getNumEventsArray() const override {
+  const signal_t *getNumEventsArray() const override {
+    throw std::runtime_error("Not Implemented");
+  }
+
+  signal_t *mutableSignalArray() override {
+    throw std::runtime_error("Not Implemented");
+  }
+
+  signal_t *mutableErrorSquaredArray() override {
+    throw std::runtime_error("Not Implemented");
+  }
+
+  signal_t *mutableNumEventsArray() override {
     throw std::runtime_error("Not Implemented");
   }
 
diff --git a/qt/paraview_ext/VatesAPI/src/vtkMDHistoHexFactory.cpp b/qt/paraview_ext/VatesAPI/src/vtkMDHistoHexFactory.cpp
index 7a70c860202f895ea6d44c49c4d0746feed1d354..887e994bf342ab1c7bfdc2740b390036ad6272c3 100644
--- a/qt/paraview_ext/VatesAPI/src/vtkMDHistoHexFactory.cpp
+++ b/qt/paraview_ext/VatesAPI/src/vtkMDHistoHexFactory.cpp
@@ -141,8 +141,13 @@ static void InitializevtkMDHWSignalArray(
   const vtkIdType nBinsZ = static_cast<int>(ws.getZDimension()->getNBins());
   const vtkIdType imageSize = (nBinsX) * (nBinsY) * (nBinsZ);
   auto norm = static_cast<SignalArrayNormalization>(normalization);
-
-  signal->InitializeArray(ws.getSignalArray(), ws.getNumEventsArray(),
+  // The MDHistoWorkspace interface was improved to make the const getter return
+  // a pointer to a const array. The class generated by ParaView accepts only
+  // a non-const array. Casting away const is preferable to attempting to get
+  // a compatible version of ParaView given VATES will not be improved any
+  // further and will be removed in the future.
+  signal->InitializeArray(const_cast<double *>(ws.getSignalArray()),
+                          const_cast<double *>(ws.getNumEventsArray()),
                           ws.getInverseVolume(), norm, imageSize, offset);
 }
 
@@ -203,7 +208,7 @@ vtkMDHistoHexFactory::create3Dor4D(size_t timestep,
   vtkDataArray *signal = nullptr;
   if (norm == NoNormalization) {
     vtkNew<vtkDoubleArray> raw;
-    raw->SetVoidArray(m_workspace->getSignalArray(), imageSize, 1);
+    raw->SetVoidArray(m_workspace->mutableSignalArray(), imageSize, 1);
     visualDataSet->GetCellData()->SetScalars(raw.Get());
     auto cga = visualDataSet->AllocateCellGhostArray();
     CellGhostArrayWorker<vtkDoubleArray> cgafunc(raw.Get(), cga);
diff --git a/qt/paraview_ext/VatesAPI/test/vtkMDHWSignalArrayTest.h b/qt/paraview_ext/VatesAPI/test/vtkMDHWSignalArrayTest.h
index 9b2ef7df366d616cd758f33bb969e3669a549b43..bc63b88e846a5ce2b4b324da96fa8d4865f7a7e1 100644
--- a/qt/paraview_ext/VatesAPI/test/vtkMDHWSignalArrayTest.h
+++ b/qt/paraview_ext/VatesAPI/test/vtkMDHWSignalArrayTest.h
@@ -40,8 +40,8 @@ public:
     const int nBinsY = static_cast<int>(ws_sptr->getYDimension()->getNBins());
     const int nBinsZ = static_cast<int>(ws_sptr->getZDimension()->getNBins());
     const int imageSize = (nBinsX) * (nBinsY) * (nBinsZ);
-    signal->InitializeArray(ws_sptr->getSignalArray(),
-                            ws_sptr->getNumEventsArray(),
+    signal->InitializeArray(ws_sptr->mutableSignalArray(),
+                            ws_sptr->mutableNumEventsArray(),
                             ws_sptr->getInverseVolume(),
                             SignalArrayNormalization::None, imageSize, offset);
 
@@ -79,8 +79,8 @@ public:
     const int nBinsZ = static_cast<int>(ws_sptr->getZDimension()->getNBins());
     const int imageSize = (nBinsX) * (nBinsY) * (nBinsZ);
 
-    signal->InitializeArray(ws_sptr->getSignalArray(),
-                            ws_sptr->getNumEventsArray(),
+    signal->InitializeArray(ws_sptr->mutableSignalArray(),
+                            ws_sptr->mutableNumEventsArray(),
                             ws_sptr->getInverseVolume(),
                             SignalArrayNormalization::None, imageSize, offset);
 
@@ -119,8 +119,8 @@ public:
     ws_sptr->setMDMaskAt(7, true);
     ws_sptr->setMDMaskAt(42, true);
 
-    signal->InitializeArray(ws_sptr->getSignalArray(),
-                            ws_sptr->getNumEventsArray(),
+    signal->InitializeArray(ws_sptr->mutableSignalArray(),
+                            ws_sptr->mutableNumEventsArray(),
                             ws_sptr->getInverseVolume(),
                             SignalArrayNormalization::None, imageSize, offset);
 
@@ -140,8 +140,8 @@ public:
     const int nBinsZ = static_cast<int>(ws_sptr->getZDimension()->getNBins());
     const int imageSize = (nBinsX) * (nBinsY) * (nBinsZ);
     std::size_t offset = 0;
-    signal->InitializeArray(ws_sptr->getSignalArray(),
-                            ws_sptr->getNumEventsArray(),
+    signal->InitializeArray(ws_sptr->mutableSignalArray(),
+                            ws_sptr->mutableNumEventsArray(),
                             ws_sptr->getInverseVolume(),
                             SignalArrayNormalization::None, imageSize, offset);
 
@@ -167,8 +167,8 @@ public:
     const int nBinsZ = static_cast<int>(ws_sptr->getZDimension()->getNBins());
     const int imageSize = (nBinsX) * (nBinsY) * (nBinsZ);
     std::size_t offset = 0;
-    signal->InitializeArray(ws_sptr->getSignalArray(),
-                            ws_sptr->getNumEventsArray(),
+    signal->InitializeArray(ws_sptr->mutableSignalArray(),
+                            ws_sptr->mutableNumEventsArray(),
                             ws_sptr->getInverseVolume(),
                             SignalArrayNormalization::None, imageSize, offset);
     TS_ASSERT_EQUALS(signal->LookupValue(1.0), -1);
@@ -184,8 +184,8 @@ public:
     const int nBinsZ = static_cast<int>(ws_sptr->getZDimension()->getNBins());
     const int imageSize = (nBinsX) * (nBinsY) * (nBinsZ);
     std::size_t offset = 0;
-    signal->InitializeArray(ws_sptr->getSignalArray(),
-                            ws_sptr->getNumEventsArray(),
+    signal->InitializeArray(ws_sptr->mutableSignalArray(),
+                            ws_sptr->mutableNumEventsArray(),
                             ws_sptr->getInverseVolume(),
                             SignalArrayNormalization::None, imageSize, offset);
 
@@ -217,7 +217,7 @@ public:
     const int nBinsZ = static_cast<int>(ws_sptr->getZDimension()->getNBins());
     imageSize = (nBinsX) * (nBinsY) * (nBinsZ);
     m_signal->InitializeArray(
-        ws_sptr->getSignalArray(), ws_sptr->getNumEventsArray(),
+        ws_sptr->mutableSignalArray(), ws_sptr->mutableNumEventsArray(),
         ws_sptr->getInverseVolume(), SignalArrayNormalization::Volume,
         imageSize, offset);
   }
diff --git a/qt/paraview_ext/VatesAlgorithms/src/LoadVTK.cpp b/qt/paraview_ext/VatesAlgorithms/src/LoadVTK.cpp
index 57a677b70f63385db676cf2ad785a60c80669383..77be0abdda58c53661d9b517ea81a237396de76a 100644
--- a/qt/paraview_ext/VatesAlgorithms/src/LoadVTK.cpp
+++ b/qt/paraview_ext/VatesAlgorithms/src/LoadVTK.cpp
@@ -189,8 +189,8 @@ void LoadVTK::execMDHisto(vtkUnsignedShortArray *signals,
       boost::make_shared<MDHistoWorkspace>(dimX, dimY, dimZ);
 
   // cppcheck-suppress unreadVariable
-  double *destinationSignals = outputWS->getSignalArray();
-  double *destinationErrorsSQ = outputWS->getErrorSquaredArray();
+  double *destinationSignals = outputWS->mutableSignalArray();
+  double *destinationErrorsSQ = outputWS->mutableErrorSquaredArray();
 
   if (errorsSQ) {
     PARALLEL_FOR_NO_WSP_CHECK()