diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Utils.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Utils.h
index 10d89f4b94a5b7839e1caf51088d592a54b9910c..e53ef353320531563f25afcfef32b993c83153e8 100644
--- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Utils.h
+++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Utils.h
@@ -286,14 +286,14 @@ inline void getIndicesFromLinearIndex(const size_t linear_index,
  * @param subject_indices
  * @param num_bins
  * @param index_max
- * @param range
+ * @param widths : width in pixels per dimension
  * @return True if the are neighbours, otherwise false.
  */
 inline bool isNeighbourOfSubject(const size_t ndims,
                                  const size_t neighbour_linear_index,
                                  const size_t *subject_indices,
                                  const size_t *num_bins,
-                                 const size_t *index_max, const size_t range = 1) {
+                                 const size_t *index_max, const std::vector<int>& widths) {
   std::vector<size_t> neighbour_indices(ndims);
   Utils::NestedForLoop::GetIndicesFromLinearIndex(ndims, neighbour_linear_index,
                                                   num_bins, index_max,
@@ -303,7 +303,7 @@ inline bool isNeighbourOfSubject(const size_t ndims,
     long double diff =
         std::abs(static_cast<long double>(subject_indices[ind]) -
                  static_cast<long double>(neighbour_indices[ind]));
-    if (diff > range) {
+    if (diff > widths[ind]/2) {
       return false;
     }
   }
diff --git a/Code/Mantid/Framework/MDAlgorithms/src/SmoothMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/SmoothMD.cpp
index 8d7fcbc8123fa68abe576e181cec2a481d40b865..5412eff169a7d857a95bbc3165a3adea942b0c7d 100644
--- a/Code/Mantid/Framework/MDAlgorithms/src/SmoothMD.cpp
+++ b/Code/Mantid/Framework/MDAlgorithms/src/SmoothMD.cpp
@@ -31,11 +31,13 @@ using namespace Mantid::MDEvents;
 typedef std::vector<int> WidthVector;
 
 // Typedef for an optional md histo workspace
-typedef boost::optional<IMDHistoWorkspace_const_sptr> OptionalIMDHistoWorkspace_const_sptr;
+typedef boost::optional<IMDHistoWorkspace_const_sptr>
+    OptionalIMDHistoWorkspace_const_sptr;
 
 // Typedef for a smoothing function
 typedef boost::function<IMDHistoWorkspace_sptr(
-    IMDHistoWorkspace_const_sptr, const WidthVector &, OptionalIMDHistoWorkspace_const_sptr)> SmoothFunction;
+    IMDHistoWorkspace_const_sptr, const WidthVector &,
+    OptionalIMDHistoWorkspace_const_sptr)> SmoothFunction;
 
 // Typedef for a smoothing function map keyed by name.
 typedef std::map<std::string, SmoothFunction> SmoothFunctionMap;
@@ -57,12 +59,13 @@ std::vector<std::string> functions() {
  * Maps a function name to a smoothing function
  * @return function map
  */
-SmoothFunctionMap makeFunctionMap(Mantid::MDAlgorithms::SmoothMD * instance) {
+SmoothFunctionMap makeFunctionMap(Mantid::MDAlgorithms::SmoothMD *instance) {
   SmoothFunctionMap map;
-  map.insert(std::make_pair("Hat",  boost::bind( &Mantid::MDAlgorithms::SmoothMD::hatSmooth, instance, _1, _2, _3 )));
+  map.insert(std::make_pair(
+      "Hat", boost::bind(&Mantid::MDAlgorithms::SmoothMD::hatSmooth, instance,
+                         _1, _2, _3)));
   return map;
 }
-
 }
 
 namespace Mantid {
@@ -105,15 +108,18 @@ const std::string SmoothMD::summary() const {
  * @param weightingWS : Weighting workspace (optional)
  * @return Smoothed MDHistoWorkspace
  */
-IMDHistoWorkspace_sptr SmoothMD::hatSmooth(IMDHistoWorkspace_const_sptr toSmooth,
-                                 const WidthVector &widthVector, OptionalIMDHistoWorkspace_const_sptr weightingWS) {
+IMDHistoWorkspace_sptr
+SmoothMD::hatSmooth(IMDHistoWorkspace_const_sptr toSmooth,
+                    const WidthVector &widthVector,
+                    OptionalIMDHistoWorkspace_const_sptr weightingWS) {
 
   const bool useWeights = weightingWS.is_initialized();
   uint64_t nPoints = toSmooth->getNPoints();
-  Progress progress(this, 0, 1, size_t( double(nPoints) * 1.1 ) );
+  Progress progress(this, 0, 1, size_t(double(nPoints) * 1.1));
   // Create the output workspace.
   IMDHistoWorkspace_sptr outWS = toSmooth->clone();
-  progress.reportIncrement(size_t(double(nPoints) * 0.1)); // Report ~10% progress
+  progress.reportIncrement(
+      size_t(double(nPoints) * 0.1)); // Report ~10% progress
 
   const int nThreads = Mantid::API::FrameworkManager::Instance()
                            .getNumOMPThreads(); // NThreads to Request
@@ -129,51 +135,48 @@ IMDHistoWorkspace_sptr SmoothMD::hatSmooth(IMDHistoWorkspace_const_sptr toSmooth
 
     do {
       // Gets all vertex-touching neighbours
-        size_t iteratorIndex = iterator->getLinearIndex();
+      size_t iteratorIndex = iterator->getLinearIndex();
 
-      if(useWeights) {
+      if (useWeights) {
 
-          // Check that we could measuer here.
-          if ( (*weightingWS)->getSignalAt(iteratorIndex) == 0 ) {
+        // Check that we could measuer here.
+        if ((*weightingWS)->getSignalAt(iteratorIndex) == 0) {
 
-              outWS->setSignalAt(iteratorIndex, std::numeric_limits<double>::quiet_NaN());
+          outWS->setSignalAt(iteratorIndex,
+                             std::numeric_limits<double>::quiet_NaN());
 
-              outWS->setErrorSquaredAt(iteratorIndex, std::numeric_limits<double>::quiet_NaN());
+          outWS->setErrorSquaredAt(iteratorIndex,
+                                   std::numeric_limits<double>::quiet_NaN());
 
-              continue; // Skip we couldn't measure here.
-          }
+          continue; // Skip we couldn't measure here.
+        }
       }
 
       std::vector<size_t> neighbourIndexes =
-          iterator->findNeighbourIndexesByWidth(
-              widthVector.front()); // TODO we should use the whole width vector
-                                    // not just the first element.
+          iterator->findNeighbourIndexesByWidth(widthVector);
+
       size_t nNeighbours = neighbourIndexes.size();
       double sumSignal = iterator->getSignal();
       double sumSqError = iterator->getError();
       for (size_t i = 0; i < neighbourIndexes.size(); ++i) {
-        if(useWeights) {
-            if ( (*weightingWS)->getSignalAt(neighbourIndexes[i]) == 0 )
-            {
-                // Nothing measured here. We cannot use that neighbouring point.
-                nNeighbours -= 1;
-                continue;
-            }
+        if (useWeights) {
+          if ((*weightingWS)->getSignalAt(neighbourIndexes[i]) == 0) {
+            // Nothing measured here. We cannot use that neighbouring point.
+            nNeighbours -= 1;
+            continue;
+          }
         }
         sumSignal += toSmooth->getSignalAt(neighbourIndexes[i]);
         double error = toSmooth->getErrorAt(neighbourIndexes[i]);
         sumSqError += (error * error);
-
       }
 
       // Calculate the mean
-      outWS->setSignalAt(iteratorIndex,
-                         sumSignal / double(nNeighbours + 1));
+      outWS->setSignalAt(iteratorIndex, sumSignal / double(nNeighbours + 1));
       // Calculate the sample variance
       outWS->setErrorSquaredAt(iteratorIndex,
                                sumSqError / double(nNeighbours + 1));
 
-
       progress.report();
 
     } while (iterator->next());
@@ -184,7 +187,6 @@ IMDHistoWorkspace_sptr SmoothMD::hatSmooth(IMDHistoWorkspace_const_sptr toSmooth
   return outWS;
 }
 
-
 //----------------------------------------------------------------------------------------------
 /** Initialize the algorithm's properties.
  */
@@ -219,7 +221,8 @@ void SmoothMD::init() {
       docBuffer.str());
 
   declareProperty(new WorkspaceProperty<API::IMDHistoWorkspace>(
-                      "InputNormalizationWorkspace", "", Direction::Input, PropertyMode::Optional),
+                      "InputNormalizationWorkspace", "", Direction::Input,
+                      PropertyMode::Optional),
                   "Multidimensional weighting workspace. Optional.");
 
   declareProperty(new WorkspaceProperty<API::IMDHistoWorkspace>(
@@ -236,15 +239,21 @@ void SmoothMD::exec() {
   IMDHistoWorkspace_sptr toSmooth = this->getProperty("InputWorkspace");
 
   // Get the input weighting workspace
-  IMDHistoWorkspace_sptr weightingWS = this->getProperty("InputNormalizationWorkspace");
+  IMDHistoWorkspace_sptr weightingWS =
+      this->getProperty("InputNormalizationWorkspace");
   OptionalIMDHistoWorkspace_const_sptr optionalWeightingWS;
-  if(weightingWS)
-  {
-      optionalWeightingWS = weightingWS;
+  if (weightingWS) {
+    optionalWeightingWS = weightingWS;
   }
 
   // Get the width vector
-  const std::vector<int> widthVector = this->getProperty("WidthVector");
+  std::vector<int> widthVector = this->getProperty("WidthVector");
+  if (widthVector.size() == 1) {
+    // Pad the width vector out to the right size if only one entry has been
+    // provided.
+    widthVector =
+        std::vector<int>(toSmooth->getNumDims(), widthVector.front());
+  }
 
   // Find the choosen smooth operation
   const std::string smoothFunctionName = this->getProperty("Function");
@@ -264,55 +273,67 @@ std::map<std::string, std::string> SmoothMD::validateInputs() {
 
   std::map<std::string, std::string> product;
 
+  IMDHistoWorkspace_sptr toSmoothWs = this->getProperty("InputWorkspace");
+
   // Check the width vector
   const std::string widthVectorPropertyName = "WidthVector";
   std::vector<int> widthVector = this->getProperty(widthVectorPropertyName);
-  for (auto it = widthVector.begin(); it != widthVector.end(); ++it) {
-    const int widthEntry = *it;
-    if (widthEntry % 2 == 0) {
-      std::stringstream message;
-      message << widthVectorPropertyName
-              << " entries must be odd numbers. Bad entry is " << widthEntry;
-      product.insert(std::make_pair(widthVectorPropertyName, message.str()));
+
+  if (widthVector.size() != 1 && widthVector.size() != toSmoothWs->getNumDims()) {
+    product.insert(std::make_pair(widthVectorPropertyName,
+                                  widthVectorPropertyName +
+                                      " can either have one entry or needs to "
+                                      "have entries for each dimension of the "
+                                      "InputWorkspace."));
+  } else {
+    for (auto it = widthVector.begin(); it != widthVector.end(); ++it) {
+      const int widthEntry = *it;
+      if (widthEntry % 2 == 0) {
+        std::stringstream message;
+        message << widthVectorPropertyName
+                << " entries must be odd numbers. Bad entry is " << widthEntry;
+        product.insert(std::make_pair(widthVectorPropertyName, message.str()));
+      }
     }
   }
 
   // Check the dimensionality of the normalization workspace
-  const std::string normalisationWorkspacePropertyName = "InputNormalizationWorkspace";
-  IMDHistoWorkspace_sptr toSmoothWs = this->getProperty("InputWorkspace");
-  IMDHistoWorkspace_sptr normWs = this->getProperty(normalisationWorkspacePropertyName);
-  if(normWs)
-  {
-      const size_t nDimsNorm = normWs->getNumDims();
-      const size_t nDimsSmooth = toSmoothWs->getNumDims();
-      if(nDimsNorm != nDimsSmooth) {
+  const std::string normalisationWorkspacePropertyName =
+      "InputNormalizationWorkspace";
+
+  IMDHistoWorkspace_sptr normWs =
+      this->getProperty(normalisationWorkspacePropertyName);
+  if (normWs) {
+    const size_t nDimsNorm = normWs->getNumDims();
+    const size_t nDimsSmooth = toSmoothWs->getNumDims();
+    if (nDimsNorm != nDimsSmooth) {
+      std::stringstream message;
+      message << normalisationWorkspacePropertyName
+              << " has a different number of dimensions than InputWorkspace. "
+                 "Shapes of inputs must be the same. Cannot continue "
+                 "smoothing.";
+      product.insert(
+          std::make_pair(normalisationWorkspacePropertyName, message.str()));
+    } else {
+      // Loop over dimensions and check nbins.
+      for (size_t i = 0; i < nDimsNorm; ++i) {
+        const size_t nBinsNorm = normWs->getDimension(i)->getNBins();
+        const size_t nBinsSmooth = toSmoothWs->getDimension(i)->getNBins();
+        if (nBinsNorm != nBinsSmooth) {
           std::stringstream message;
           message << normalisationWorkspacePropertyName
-                  << " has a different number of dimensions than InputWorkspace. Shapes of inputs must be the same. Cannot continue smoothing.";
-          product.insert(std::make_pair(normalisationWorkspacePropertyName, message.str()));
-      }
-      else
-      {
-          // Loop over dimensions and check nbins.
-          for(size_t i = 0; i < nDimsNorm; ++i)
-          {
-              const size_t nBinsNorm = normWs->getDimension(i)->getNBins();
-              const size_t nBinsSmooth = toSmoothWs->getDimension(i)->getNBins();
-              if(nBinsNorm != nBinsSmooth)
-              {
-                  std::stringstream message;
-                  message << normalisationWorkspacePropertyName
-                          << ". Number of bins from dimension with index "<< i << " do not match. "
-                          << nBinsSmooth << " expected. Got " << nBinsNorm
-                          << ". Shapes of inputs must be the same. Cannot continue smoothing.";
-                  product.insert(std::make_pair(normalisationWorkspacePropertyName, message.str()));
-                  break;
-              }
-          }
+                  << ". Number of bins from dimension with index " << i
+                  << " do not match. " << nBinsSmooth << " expected. Got "
+                  << nBinsNorm << ". Shapes of inputs must be the same. Cannot "
+                                  "continue smoothing.";
+          product.insert(std::make_pair(normalisationWorkspacePropertyName,
+                                        message.str()));
+          break;
+        }
       }
+    }
   }
 
-
   return product;
 }
 
diff --git a/Code/Mantid/Framework/MDAlgorithms/test/SmoothMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/SmoothMDTest.h
index dd00e34212beb1784f171bbf0606f961a7421fbc..1920aed9aa6e530c223a01cf488d7b52dba3a52f 100644
--- a/Code/Mantid/Framework/MDAlgorithms/test/SmoothMDTest.h
+++ b/Code/Mantid/Framework/MDAlgorithms/test/SmoothMDTest.h
@@ -75,6 +75,24 @@ public:
                       alg.execute(), std::runtime_error &);
   }
 
+  void test_width_vector_must_not_be_arbitrary_size() {
+      auto toSmooth = MDEventsTestHelper::makeFakeMDHistoWorkspace(
+          1 /*signal*/, 2 /*numDims*/, 3 /*numBins in each dimension*/);
+
+      std::vector<int> badWidths(11, 3); // odd number value = 3, but size of 11 has no meaning
+
+      SmoothMD alg;
+      alg.setChild(true);
+      alg.initialize();
+      alg.setPropertyValue("OutputWorkspace", "dummy");
+      alg.setProperty("InputWorkspace", toSmooth);
+      alg.setProperty(
+          "WidthVector",
+          badWidths); // Width vector is the wrong size
+      TSM_ASSERT_THROWS("Size of with vector is wrong should throw.", alg.execute(),
+                        std::runtime_error &);
+  }
+
   void test_simple_smooth_hat_function() {
     auto toSmooth = MDEventsTestHelper::makeFakeMDHistoWorkspace(
         1 /*signal*/, 2 /*numDims*/, 3 /*numBins in each dimension*/);
@@ -207,6 +225,59 @@ public:
     TS_ASSERT_EQUALS(z, out->getSignalAt(12));
   }
 
+
+  void test_smooth_hat_function_mixed_widths() {
+
+    auto toSmooth = MDEventsTestHelper::makeFakeMDHistoWorkspace(
+        2 /*signal*/, 2 /*numDims*/, 5 /*numBins in each dimension*/);
+    toSmooth->setSignalAt(2, 1.0);
+    toSmooth->setSignalAt(22, 1.0);
+
+    /*
+     2D MDHistoWorkspace Input
+
+     2 - 2 - 1 - 2 - 2
+     2 - 2 - 2 - 2 - 2
+     2 - 2 - 2 - 2 - 2
+     2 - 2 - 2 - 2 - 2
+     2 - 2 - 1 - 2 - 2
+
+    */
+
+    SmoothMD alg;
+    alg.setChild(true);
+    alg.initialize();
+    std::vector<int> widthVector;
+    widthVector.push_back(3); // 3 = width in zeroth dimension
+    widthVector.push_back(5); // 5 = width in first dimension
+    alg.setProperty("WidthVector", widthVector);
+    alg.setProperty("InputWorkspace", toSmooth);
+    alg.setPropertyValue("OutputWorkspace", "dummy");
+    alg.execute();
+    IMDHistoWorkspace_sptr out = alg.getProperty("OutputWorkspace");
+
+    /*
+     Smoothing region for centre point
+
+     2 - |2 - 1 - 2| - 2
+     2 - |2 - 2 - 2| - 2
+     2 - |2 -|2|- 2| - 2
+     2 - |2 - 2 - 2| - 2
+     2 - |2 - 1 - 2| - 2
+
+     3 by 5 with.
+
+     average for centre point should be [ (3 * 5) - 2 ] * 2 / (3 * 5) = 28 / 15
+
+    */
+
+    // Check vertexes
+    double expectedSmoothedValue  = 28.0 / 15;
+
+    TS_ASSERT_EQUALS(expectedSmoothedValue, out->getSignalAt(12));
+  }
+
+
   void test_dimensional_check_of_weight_ws() {
 
       MDHistoWorkspace_sptr a =
diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspaceIterator.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspaceIterator.h
index af649ba80233cf8053c8e1f078d28634dde785f6..5e88c423bc9abef3d551a2ec6e14a3f95637fb13 100644
--- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspaceIterator.h
+++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspaceIterator.h
@@ -7,12 +7,13 @@
 #include "MantidGeometry/MDGeometry/MDImplicitFunction.h"
 #include "MantidMDEvents/SkippingPolicy.h"
 #include <map>
+#include <vector>
 
 namespace Mantid {
 namespace MDEvents {
 
 // Typdef for a map for mapping width of neighbours (key) to permutations needed in the calcualtion.
-typedef std::map<size_t, std::vector<int64_t> > PermutationsMap;
+typedef std::map<std::vector<int>, std::vector<int64_t> > PermutationsMap;
 
 /** An implementation of IMDIterator that iterates through
   a MDHistoWorkspace. It treats the bin in the workspace as
@@ -113,7 +114,9 @@ public:
 
   std::vector<size_t> findNeighbourIndexesFaceTouching() const;
 
-  std::vector<size_t> findNeighbourIndexesByWidth(const int width) const;
+  std::vector<size_t> findNeighbourIndexesByWidth(const int& width) const;
+
+  std::vector<size_t> findNeighbourIndexesByWidth(const std::vector<int>& widths) const;
 
   virtual bool isWithinBounds(size_t index) const;
 
@@ -166,7 +169,7 @@ protected:
   SkippingPolicy_scptr m_skippingPolicy;
 
   /// Create or fetch permutations relating to a given neighbour width.
-  std::vector<int64_t> createPermutations(const int width) const;
+  std::vector<int64_t> createPermutations(const std::vector<int>& widths) const;
 };
 
 } // namespace MDEvents
diff --git a/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspaceIterator.cpp b/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspaceIterator.cpp
index d1510c15ba339c55ef6f90d7c19a79d320b60a2d..a7fdba24e77080849e78677a9f8d68e2d519cf81 100644
--- a/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspaceIterator.cpp
+++ b/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspaceIterator.cpp
@@ -5,6 +5,8 @@
 #include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include <algorithm>
 #include <utility>
+#include <functional>
+#include <numeric>
 
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
@@ -418,6 +420,7 @@ MDHistoWorkspaceIterator::findNeighbourIndexesFaceTouching() const {
                                                   m_indexMax, m_index);
 
   std::vector<size_t> neighbourIndexes; // Accumulate neighbour indexes.
+  std::vector<int> widths(m_nd, 3); // Face touching width is always 3 in each dimension
   for (size_t i = 0; i < m_permutationsFaceTouching.size(); ++i) {
     if (m_permutationsFaceTouching[i] == 0) {
       continue;
@@ -426,7 +429,7 @@ MDHistoWorkspaceIterator::findNeighbourIndexesFaceTouching() const {
     size_t neighbour_index = m_pos + m_permutationsFaceTouching[i];
     if (neighbour_index < m_ws->getNPoints() &&
         Utils::isNeighbourOfSubject(m_nd, neighbour_index, m_index,
-                                    m_indexMaker, m_indexMax)) {
+                                    m_indexMaker, m_indexMax, widths)) {
       neighbourIndexes.push_back(neighbour_index);
     }
   }
@@ -449,30 +452,36 @@ bool MDHistoWorkspaceIterator::isWithinBounds(size_t index) const {
  *the iterator is moved and the method is called,
  * we can cache the results, and re-use them as the only factors are the and the
  *dimensionality, the width (n-neighbours).
- *
- * @return
+ * @param widths : vector of integer widths.
+ * @return index permutations
  */
 std::vector<int64_t>
-MDHistoWorkspaceIterator::createPermutations(const int width) const {
+MDHistoWorkspaceIterator::createPermutations(const std::vector<int>& widths) const {
   // look-up
-  PermutationsMap::iterator it = m_permutationsVertexTouchingMap.find(width);
+  PermutationsMap::iterator it = m_permutationsVertexTouchingMap.find(widths);
   if (it == m_permutationsVertexTouchingMap.end()) {
 
-    if (width % 2 == 0) {
+    if (widths[0] % 2 == 0) {
       throw std::invalid_argument("MDHistoWorkspaceIterator::"
                                   "findNeighbourIndexesByWidth, width must "
                                   "always be an even number");
     }
+    if (widths.size() != m_nd) {
+        throw std::invalid_argument("MDHistoWorkspaceIterator::"
+                                    "findNeighbourIndexesByWidth, size of widths must be the same as the number of dimensions.");
+    }
 
     int64_t offset = 1;
 
     // Size of block will be width ^ nd
     std::vector<int64_t> permutationsVertexTouching;
-    permutationsVertexTouching.reserve(integerPower(width, m_nd));
+    // Calculate maximum permutations size.
+    int product = std::accumulate(widths.begin(), widths.end(), 1, std::multiplies<int>());
+    permutationsVertexTouching.reserve(product);
 
-    int centreIndex = (width) / 2; // Deliberately truncate to get centre index
+    int centreIndex = widths[0] / 2; // Deliberately truncate to get centre index
 
-    for (int i = 0; i < width; ++i) {
+    for (int i = 0; i < widths[0]; ++i) {
       // for width = 3 : -1, 0, 1
       // for width = 5 : -2, -1, 0, 1, 2
       permutationsVertexTouching.push_back(centreIndex - i);
@@ -485,7 +494,7 @@ MDHistoWorkspaceIterator::createPermutations(const int width) const {
           offset * static_cast<int64_t>(m_ws->getDimension(j - 1)->getNBins());
 
       size_t nEntries = permutationsVertexTouching.size();
-      for (int k = 1; k <= width / 2; ++k) {
+      for (int k = 1; k <= widths[j] / 2; ++k) {
         for (size_t m = 0; m < nEntries; m++) {
           permutationsVertexTouching.push_back((offset * k) +
                                                permutationsVertexTouching[m]);
@@ -495,23 +504,38 @@ MDHistoWorkspaceIterator::createPermutations(const int width) const {
       }
     }
 
-    m_permutationsVertexTouchingMap.insert(std::make_pair(width, permutationsVertexTouching));
+    m_permutationsVertexTouchingMap.insert(std::make_pair(widths, permutationsVertexTouching));
   }
 
   // In either case, get the result.
-  return m_permutationsVertexTouchingMap[width];
+  return m_permutationsVertexTouchingMap[widths];
 }
 
 /**
  * Find vertex-touching neighbours.
+ *
+ * Expands out the width to make a n-dimensional vector filled with the requested width.
+ *
  * @param width : Odd number of pixels for all dimensions.
  * @return collection of indexes.
  */
 std::vector<size_t>
-MDHistoWorkspaceIterator::findNeighbourIndexesByWidth(const int width) const {
+MDHistoWorkspaceIterator::findNeighbourIndexesByWidth(const int & width) const {
+
+    return this->findNeighbourIndexesByWidth(std::vector<int>(m_nd, width));
+}
+
+
+/**
+ * Find vertex-touching neighbours.
+ * @param widths : Vector containing odd number of pixels per dimension. Entries match dimensions of iterator.
+ * @return collection of indexes.
+ */
+std::vector<size_t>
+MDHistoWorkspaceIterator::findNeighbourIndexesByWidth(const std::vector<int>& widths) const {
 
   // Find existing or create required index permutations.
-  std::vector<int64_t> permutationsVertexTouching = createPermutations(width);
+  std::vector<int64_t> permutationsVertexTouching = createPermutations(widths);
 
   Utils::NestedForLoop::GetIndicesFromLinearIndex(m_nd, m_pos, m_indexMaker,
                                                   m_indexMax, m_index);
@@ -527,7 +551,7 @@ MDHistoWorkspaceIterator::findNeighbourIndexesByWidth(const int width) const {
     size_t neighbour_index = m_pos + permutationsVertexTouching[i];
     if (neighbour_index < m_ws->getNPoints() &&
         Utils::isNeighbourOfSubject(m_nd, neighbour_index, m_index,
-                                    m_indexMaker, m_indexMax, width / 2)) {
+                                    m_indexMaker, m_indexMax, widths) ) {
       neighbourIndexes.push_back(neighbour_index);
     }
   }
diff --git a/Code/Mantid/Framework/MDEvents/test/MDHistoWorkspaceIteratorTest.h b/Code/Mantid/Framework/MDEvents/test/MDHistoWorkspaceIteratorTest.h
index 50a722742a840ac2f69914a755a8aa90818017e1..2f5bb66efc31c7b79817d11465b1b8807fd03395 100644
--- a/Code/Mantid/Framework/MDEvents/test/MDHistoWorkspaceIteratorTest.h
+++ b/Code/Mantid/Framework/MDEvents/test/MDHistoWorkspaceIteratorTest.h
@@ -800,16 +800,93 @@ public:
     neighbourIndexes = it->findNeighbourIndexesByWidth(width);
     TS_ASSERT_EQUALS(8, neighbourIndexes.size());
     // Is on an edge
-    TSM_ASSERT( "Neighbour at index 0 is 5", doesContainIndex(neighbourIndexes, 5));
-    TSM_ASSERT( "Neighbour at index 0 is 6", doesContainIndex(neighbourIndexes, 6));
-    TSM_ASSERT( "Neighbour at index 0 is 7", doesContainIndex(neighbourIndexes, 7));
-    TSM_ASSERT( "Neighbour at index 0 is 9", doesContainIndex(neighbourIndexes, 9));
-    TSM_ASSERT( "Neighbour at index 0 is 10", doesContainIndex(neighbourIndexes, 10));
-    TSM_ASSERT( "Neighbour at index 0 is 11", doesContainIndex(neighbourIndexes, 11));
-    TSM_ASSERT( "Neighbour at index 0 is 13", doesContainIndex(neighbourIndexes, 13));
-    TSM_ASSERT( "Neighbour at index 0 is 14", doesContainIndex(neighbourIndexes, 14));
+    TSM_ASSERT( "Neighbour at index is 5", doesContainIndex(neighbourIndexes, 5));
+    TSM_ASSERT( "Neighbour at index is 6", doesContainIndex(neighbourIndexes, 6));
+    TSM_ASSERT( "Neighbour at index is 7", doesContainIndex(neighbourIndexes, 7));
+    TSM_ASSERT( "Neighbour at index is 9", doesContainIndex(neighbourIndexes, 9));
+    TSM_ASSERT( "Neighbour at index is 10", doesContainIndex(neighbourIndexes, 10));
+    TSM_ASSERT( "Neighbour at index is 11", doesContainIndex(neighbourIndexes, 11));
+    TSM_ASSERT( "Neighbour at index is 13", doesContainIndex(neighbourIndexes, 13));
+    TSM_ASSERT( "Neighbour at index is 14", doesContainIndex(neighbourIndexes, 14));
   }
 
+  void test_neighbours_2d_vertex_touching_by_width_vector()
+  {
+    const size_t nd = 2;
+    std::vector<int> widthVector;
+    widthVector.push_back(5);
+    widthVector.push_back(3);
+
+    MDHistoWorkspace_sptr ws = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, nd, 4);
+    /*
+     2D MDHistoWorkspace
+
+     0 - 1 - 2 - 3
+     4 - 5 - 6 - 7
+     8 - 9 -10 -11
+     12-13 -14 -15
+     */
+    MDHistoWorkspaceIterator * it = new MDHistoWorkspaceIterator(ws);
+
+    // At initial position
+    /*
+     |0| - 1 - 2 - 3
+     4 - 5 - 6 - 7
+     8 - 9 -10 -11
+     12-13 -14 -15
+     */
+    std::vector<size_t> neighbourIndexes = it->findNeighbourIndexesByWidth(widthVector);
+    TS_ASSERT_EQUALS(5, neighbourIndexes.size());
+    // Is on an edge
+    TSM_ASSERT( "Neighbour at index is 1", doesContainIndex(neighbourIndexes, 1));
+    TSM_ASSERT( "Neighbour at index is 2", doesContainIndex(neighbourIndexes, 2));
+    TSM_ASSERT( "Neighbour at index is 4", doesContainIndex(neighbourIndexes, 4));
+    TSM_ASSERT( "Neighbour at index is 5", doesContainIndex(neighbourIndexes, 5));
+    TSM_ASSERT( "Neighbour at index is 6", doesContainIndex(neighbourIndexes, 6));
+
+
+
+    // At centreish position
+    /*
+     0 - 1 - 2 - 3
+     4 - |5| - 6 - 7
+     8 - 9 -10 -11
+     12-13 -14 -15
+     */
+    it->jumpTo(5);
+    neighbourIndexes = it->findNeighbourIndexesByWidth(widthVector);
+    TS_ASSERT_EQUALS(11, neighbourIndexes.size());
+    // Is on an edge
+    for(int i = 0; i < 12; ++i)
+    {
+        if(i == 5)
+        {
+            continue; // skip over the current index of the iterator.
+        }
+        std::stringstream buffer;
+        buffer << "Neighbour at index 5 should include " << i;
+        TSM_ASSERT( buffer.str(), doesContainIndex(neighbourIndexes, i));
+    }
+
+    // At end position
+    /*
+     0 - 1 - 2 - 3
+     4 - 5 - 6 - 7
+     8 - 9 -10 -11
+     12-13 -14 -|15|
+     */
+    it->jumpTo(15);
+    neighbourIndexes = it->findNeighbourIndexesByWidth(widthVector);
+    TS_ASSERT_EQUALS(5, neighbourIndexes.size());
+    // Is on an edge
+    TSM_ASSERT( "Neighbour at index is 9", doesContainIndex(neighbourIndexes, 9));
+    TSM_ASSERT( "Neighbour at index is 10", doesContainIndex(neighbourIndexes, 10));
+    TSM_ASSERT( "Neighbour at index is 11", doesContainIndex(neighbourIndexes, 11));
+    TSM_ASSERT( "Neighbour at index is 13", doesContainIndex(neighbourIndexes, 13));
+    TSM_ASSERT( "Neighbour at index is 14", doesContainIndex(neighbourIndexes, 14));
+  }
+
+
   void test_neighbours_3d_vertex_touching_width()
   {
     const size_t nd = 3;