diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/GeneralFrame.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/GeneralFrame.h
index 36d50272477132199609b1e96b98644f444fb0e2..f4098803b32fc201b7420ee9ce40253f7038073e 100644
--- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/GeneralFrame.h
+++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/GeneralFrame.h
@@ -46,6 +46,8 @@ public:
   Kernel::UnitLabel getUnitLabel() const;
   const Kernel::MDUnit &getMDUnit() const;
   bool canConvertTo(const Kernel::MDUnit &otherUnit) const;
+  bool isQ() const;
+  bool isSameType(const MDFrame& frame) const;
   std::string name() const;
   virtual GeneralFrame *clone() const;
   Mantid::Kernel::SpecialCoordinateSystem
diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/HKL.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/HKL.h
index 8b38ca560612c0c4cea7a4410e058e28ed7f9567..a0d6d91668f210d2fed47b6b23c2a08fba0dcf8a 100644
--- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/HKL.h
+++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/HKL.h
@@ -47,6 +47,8 @@ public:
   Kernel::UnitLabel getUnitLabel() const;
   const Kernel::MDUnit &getMDUnit() const;
   bool canConvertTo(const Kernel::MDUnit &otherUnit) const;
+  bool isQ() const;
+  bool isSameType(const MDFrame& frame) const;
   std::string name() const;
   HKL *clone() const;
   Mantid::Kernel::SpecialCoordinateSystem
diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrame.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrame.h
index 35f424eecc120c80cf85a1f0f6f7d9f15804d563..4c5a59f1b0eb030e0cd471a44ae30263c4cb9ed1 100644
--- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrame.h
+++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrame.h
@@ -40,6 +40,8 @@ public:
   virtual Mantid::Kernel::UnitLabel getUnitLabel() const = 0;
   virtual const Mantid::Kernel::MDUnit &getMDUnit() const = 0;
   virtual bool canConvertTo(const Mantid::Kernel::MDUnit &otherUnit) const = 0;
+  virtual bool isQ() const = 0;
+  virtual bool isSameType(const MDFrame& frame) const = 0;
   virtual std::string name() const = 0;
   virtual Mantid::Kernel::SpecialCoordinateSystem
   equivalientSpecialCoordinateSystem() const = 0;
@@ -49,6 +51,8 @@ public:
 
 typedef std::unique_ptr<MDFrame> MDFrame_uptr;
 typedef std::unique_ptr<const MDFrame> MDFrame_const_uptr;
+typedef std::shared_ptr<MDFrame> MDFrame_sptr;
+typedef std::shared_ptr<const MDFrame> MDFrame_const_sptr;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/QLab.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/QLab.h
index a66782c34f8443c54d2719385412b1e4147cf7bd..8de9491dc9ead43d9ef47568934cda73ba38feec 100644
--- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/QLab.h
+++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/QLab.h
@@ -41,6 +41,8 @@ public:
   Mantid::Kernel::UnitLabel getUnitLabel() const;
   const Mantid::Kernel::MDUnit &getMDUnit() const;
   bool canConvertTo(const Mantid::Kernel::MDUnit &otherUnit) const;
+  bool isQ() const;
+  bool isSameType(const MDFrame& frame) const;
   virtual std::string name() const;
   QLab *clone() const;
   Mantid::Kernel::SpecialCoordinateSystem
diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/QSample.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/QSample.h
index bc90b2e7fc5e69513fd439172f09d0921f7d8c83..24f2b0f0803311d01cc5541fc953649f3b9a61ae 100644
--- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/QSample.h
+++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/QSample.h
@@ -42,6 +42,8 @@ public:
   Kernel::UnitLabel getUnitLabel() const;
   const Kernel::MDUnit &getMDUnit() const;
   bool canConvertTo(const Kernel::MDUnit &otherUnit) const;
+  bool isQ() const;
+  bool isSameType(const MDFrame& frame) const;
   std::string name() const;
   QSample *clone() const;
   Mantid::Kernel::SpecialCoordinateSystem
diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/UnknownFrame.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/UnknownFrame.h
index 2500e39c6f7de98158dfc38f4f65eb2e928e3298..9e593e23872968628316c8344a18d6a3f95e7614 100644
--- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/UnknownFrame.h
+++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/UnknownFrame.h
@@ -41,6 +41,8 @@ public:
   virtual ~UnknownFrame();
   std::string name() const;
   bool canConvertTo(const Mantid::Kernel::MDUnit &otherUnit) const;
+  bool isQ() const;
+  bool isSameType(const MDFrame& frame) const;
   Mantid::Kernel::UnitLabel getUnitLabel() const;
   const Mantid::Kernel::MDUnit &getMDUnit() const;
   Mantid::Kernel::SpecialCoordinateSystem
diff --git a/Framework/Geometry/src/MDGeometry/GeneralFrame.cpp b/Framework/Geometry/src/MDGeometry/GeneralFrame.cpp
index af098ed36d196b919561a2beccc335a30ffd4e52..502f4ebbdc3fe8be5f33c3e4e3198cccbdbb5955 100644
--- a/Framework/Geometry/src/MDGeometry/GeneralFrame.cpp
+++ b/Framework/Geometry/src/MDGeometry/GeneralFrame.cpp
@@ -42,5 +42,17 @@ GeneralFrame::equivalientSpecialCoordinateSystem() const {
   return Mantid::Kernel::SpecialCoordinateSystem::None;
 }
 
+bool GeneralFrame::isQ() const { return false; }
+
+bool GeneralFrame::isSameType(const MDFrame &frame) const {
+  auto isSameType = true;
+  try {
+    dynamic_cast<const GeneralFrame &>(frame);
+  } catch (std::bad_cast &) {
+    isSameType = false;
+  }
+  return isSameType;
+}
+
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/src/MDGeometry/HKL.cpp b/Framework/Geometry/src/MDGeometry/HKL.cpp
index b109b8b99fc40efe5e817f966113ee141be9cb04..3501e925cba6c479af8140a67666d3296cd934ee 100644
--- a/Framework/Geometry/src/MDGeometry/HKL.cpp
+++ b/Framework/Geometry/src/MDGeometry/HKL.cpp
@@ -69,5 +69,16 @@ HKL::equivalientSpecialCoordinateSystem() const {
   return Mantid::Kernel::SpecialCoordinateSystem::HKL;
 }
 
+bool HKL::isQ() const { return true; }
+
+bool HKL::isSameType(const MDFrame &frame) const {
+  auto isSameType = true;
+  try {
+    dynamic_cast<const HKL &>(frame);
+  } catch (std::bad_cast &) {
+    isSameType = false;
+  }
+  return isSameType;
+}
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/src/MDGeometry/QLab.cpp b/Framework/Geometry/src/MDGeometry/QLab.cpp
index 85622c3f5c718b6963aca95e67d73ffd526d55e4..28f50d7dce6e44d94ab0ec5b8e20bf8397d4f627 100644
--- a/Framework/Geometry/src/MDGeometry/QLab.cpp
+++ b/Framework/Geometry/src/MDGeometry/QLab.cpp
@@ -40,5 +40,19 @@ QLab::equivalientSpecialCoordinateSystem() const {
   return Mantid::Kernel::SpecialCoordinateSystem::QLab;
 }
 
+bool QLab::isQ() const {
+  return true;
+}
+
+bool QLab::isSameType(const MDFrame& frame) const {
+  auto isSameType = true;
+  try {
+    dynamic_cast<const QLab&>(frame);
+  } catch (std::bad_cast&) {
+    isSameType = false;
+  }
+  return isSameType;
+}
+
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/src/MDGeometry/QSample.cpp b/Framework/Geometry/src/MDGeometry/QSample.cpp
index 8a616e53010d0fc54de7e5617e0e9f954d9b63a4..6575ad0629532adc4679987e7e72d391bc796953 100644
--- a/Framework/Geometry/src/MDGeometry/QSample.cpp
+++ b/Framework/Geometry/src/MDGeometry/QSample.cpp
@@ -35,5 +35,17 @@ QSample::equivalientSpecialCoordinateSystem() const {
   return Mantid::Kernel::SpecialCoordinateSystem::QSample;
 }
 
+bool QSample::isQ() const { return true; }
+
+bool QSample::isSameType(const MDFrame &frame) const {
+  auto isSameType = true;
+  try {
+    dynamic_cast<const QSample &>(frame);
+  } catch (std::bad_cast &) {
+    isSameType = false;
+  }
+  return isSameType;
+}
+
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/src/MDGeometry/UnknownFrame.cpp b/Framework/Geometry/src/MDGeometry/UnknownFrame.cpp
index 29790a44322a47528ac00cc404c612962e1d4e14..6978a0fae51e3056471ede3e888713ab560c9918 100644
--- a/Framework/Geometry/src/MDGeometry/UnknownFrame.cpp
+++ b/Framework/Geometry/src/MDGeometry/UnknownFrame.cpp
@@ -35,5 +35,20 @@ UnknownFrame::equivalientSpecialCoordinateSystem() const {
 UnknownFrame *UnknownFrame::clone() const {
   return new UnknownFrame(std::unique_ptr<Kernel::MDUnit>(m_unit->clone()));
 }
+
+bool UnknownFrame::isQ() const{
+  return false;
+}
+
+bool UnknownFrame::isSameType(const MDFrame &frame) const {
+  auto isSameType = true;
+  try {
+    dynamic_cast<const UnknownFrame &>(frame);
+  } catch (std::bad_cast &) {
+    isSameType = false;
+  }
+  return isSameType;
+}
+
 }
 }
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SlicingAlgorithm.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SlicingAlgorithm.h
index 72827e329c5224df45e81c4b7f9c6102811fb641..6f824da3cfaafb5f5422e6bc8261e057462102d5 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SlicingAlgorithm.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SlicingAlgorithm.h
@@ -152,8 +152,18 @@ protected:
   bool m_NormalizeBasisVectors;
 
   private:
-  //Mantid::Geometry::MDFrame_uptr createMDFrameForNonAxisAligned(std::string units) const;
-
+    Mantid::Geometry::MDFrame_uptr
+    createMDFrameForNonAxisAligned(std::string units,
+                                   Mantid::Kernel::VMD basisVector) const;
+    std::vector<Mantid::Kernel::VMD> getOldBasis(size_t dimension) const;
+    bool isProjectingOnFrame(const Mantid::Kernel::VMD &oldVector,
+                             const Mantid::Kernel::VMD &basisVector) const;
+    std::vector<size_t> getIndicesWithProjection(
+        const Mantid::Kernel::VMD &basisVector,
+        const std::vector<Mantid::Kernel::VMD> &oldBasis) const;
+    Mantid::Geometry::MDFrame_uptr
+    extractMDFrameForNonAxisAligned(std::vector<size_t> indicesWithProjection,
+                                    std::string units) const;
 };
 
 } // namespace DataObjects
diff --git a/Framework/MDAlgorithms/src/MDEventWSWrapper.cpp b/Framework/MDAlgorithms/src/MDEventWSWrapper.cpp
index a7586ccdb57fda588dfee283bad4f658a9022050..f288262e3067891cc48ba147582667dd4a901318 100644
--- a/Framework/MDAlgorithms/src/MDEventWSWrapper.cpp
+++ b/Framework/MDAlgorithms/src/MDEventWSWrapper.cpp
@@ -39,9 +39,10 @@ void MDEventWSWrapper::createEmptyEventWS(const MDWSDescription &description) {
           Mantid::coord_t(description.getDimMax()[d]), nBins);
 
     } else {
+      Mantid::Geometry::GeneralFrame frame(description.getDimNames()[d],
+                                           description.getDimUnits()[d]);
       dim = new Geometry::MDHistoDimension(
-          description.getDimNames()[d], description.getDimIDs()[d],
-          description.getDimUnits()[d],
+          description.getDimNames()[d], description.getDimIDs()[d], frame,
           Mantid::coord_t(description.getDimMin()[d]),
           Mantid::coord_t(description.getDimMax()[d]), nBins);
     }
diff --git a/Framework/MDAlgorithms/src/SlicingAlgorithm.cpp b/Framework/MDAlgorithms/src/SlicingAlgorithm.cpp
index aa6e472019c7d11a5a857bba679776c7dd07e9fa..123a988f17833a16f216a48b627f27ded3b2beb9 100644
--- a/Framework/MDAlgorithms/src/SlicingAlgorithm.cpp
+++ b/Framework/MDAlgorithms/src/SlicingAlgorithm.cpp
@@ -251,11 +251,11 @@ void SlicingAlgorithm::makeBasisVectorFromString(const std::string &str) {
   std::string units = Strings::strip(strs[0]);
 
   // Create the appropriate frame
-  //auto frame = createMDFrame(units);
+  auto frame = createMDFrameForNonAxisAligned(units, basis);
 
   // Create the output dimension
   MDHistoDimension_sptr out(
-      new MDHistoDimension(name, id, units, static_cast<coord_t>(min),
+      new MDHistoDimension(name, id, *frame, static_cast<coord_t>(min),
                            static_cast<coord_t>(max), numBins));
 
   // Put both in the algo for future use
@@ -513,7 +513,7 @@ void SlicingAlgorithm::makeAlignedDimensionFromString(const std::string &str) {
 
     // Copy the dimension name, ID and units
     IMDDimension_const_sptr inputDim = m_inWS->getDimension(dim_index);
-    const auto& frame = inputDim->getMDFrame();
+    const auto &frame = inputDim->getMDFrame();
     m_binDimensions.push_back(MDHistoDimension_sptr(
         new MDHistoDimension(inputDim->getName(), inputDim->getDimensionId(),
                              frame, min, max, numBins)));
@@ -1006,18 +1006,97 @@ SlicingAlgorithm::getImplicitFunctionForChunk(const size_t *const chunkMin,
   }
 }
 
-#if 0
 /**
- * Create an MDFrame for the Non-Axis-Aligned case
- * 1. Check that Q-based frames are not mixed with non-Q-based frames
- * 2. Select Q-based frame if available
+ * Create an MDFrame for the Non-Axis-Aligned case. Make sure that
+ * MDFrames onto which the basis vector projects are not mixed, e.g. no mixing
+ * of HKL and GenerFrame
  * @param units: the units
+ * @param basisVector: the basis vector
  * @returns the unique pointer
  */
-Mantid::Geometry::MDFrame_uptr SlicingAlgorithm::createMDFrameForNonAxisAligned(std::string units) const {
+Mantid::Geometry::MDFrame_uptr SlicingAlgorithm::createMDFrameForNonAxisAligned(
+    std::string units, Mantid::Kernel::VMD basisVector) const {
+  // Get set of basis vectors
+  auto oldBasis = getOldBasis(m_inWS->getNumDims());
 
+  // Get indices onto which the vector projects
+  auto indicesWithProjection = getIndicesWithProjection(basisVector, oldBasis);
+
+  // Extract MDFrame
+  return extractMDFrameForNonAxisAligned(indicesWithProjection, units);
+}
+
+std::vector<Mantid::Kernel::VMD>
+SlicingAlgorithm::getOldBasis(size_t dimension) const {
+  std::vector<Mantid::Kernel::VMD> oldBasis;
+  for (size_t i = 0; i < dimension; ++i) {
+    Mantid::Kernel::VMD basisVector(dimension);
+    basisVector[i] = 1.0;
+    oldBasis.push_back(basisVector);
+  }
+  return oldBasis;
+}
+
+/**
+ * Check if the two vectors are orthogonal or not
+ * @param oldVector: the old vector
+ * @param basisVector: the vector under investigation
+ * @returns true if there is a projection  else false
+ */
+bool SlicingAlgorithm::isProjectingOnFrame(
+    const Mantid::Kernel::VMD &oldVector,
+    const Mantid::Kernel::VMD &basisVector) const {
+  return std::fabs(oldVector.scalar_prod(basisVector)) > 0.0;
+}
+
+/**
+ * Get indices which have a projection contribution
+ * @param basisVector: the vector under investigation
+ * @param oldBasis: the old basis vectors
+ * @returns the indices of vectors onto which the basisVector projects
+ */
+std::vector<size_t> SlicingAlgorithm::getIndicesWithProjection(
+    const Mantid::Kernel::VMD &basisVector,
+    const std::vector<Mantid::Kernel::VMD> &oldBasis) const {
+  std::vector<size_t> indexWithProjection;
+  for (size_t index = 0; index < oldBasis.size(); ++index) {
+    if (isProjectingOnFrame(oldBasis[index], basisVector)) {
+      indexWithProjection.push_back(index);
+    }
+  }
+  return indexWithProjection;
+}
+
+/**
+ * Extract the MDFrame. Make sure that all MDFrames are compatible -- if not
+ * throw
+ * @param indicesWithProjection: list of indices of dimensions which have a
+ * projection
+ * @param units: the units
+ */
+Mantid::Geometry::MDFrame_uptr
+SlicingAlgorithm::extractMDFrameForNonAxisAligned(
+    std::vector<size_t> indicesWithProjection, std::string units) const {
+  if (indicesWithProjection.empty()) {
+    throw std::runtime_error("Slicing Algorithm: Chosen vector does not "
+                             "project on any vector of the old basis.");
+  }
+  // Get a reference frame to perform pairwise comparison
+  const auto& referenceMDFrame =
+      m_inWS->getDimension(indicesWithProjection[0])->getMDFrame();
+
+  for (auto it = indicesWithProjection.begin();
+       it != indicesWithProjection.end(); ++it) {
+    const auto& toCheckMDFrame = m_inWS->getDimension(*it)->getMDFrame();
+    if (!referenceMDFrame.isSameType(toCheckMDFrame)) {
+      throw std::runtime_error("Slicing Algorithm: New basis yvector tries to "
+                               "mix un-mixable MDFrame types.");
+    }
+  }
+
+  Mantid::Geometry::MDFrame_uptr mdFrame(referenceMDFrame.clone());
+  return mdFrame;
 }
-#endif
 
 } // namespace Mantid
 } // namespace DataObjects
diff --git a/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h b/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h
index 762ffd5f2d12c660586fb3b8f01095fac3a46d4d..66f413e8876215ee1379cd730db1cf4015811894 100644
--- a/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h
+++ b/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h
@@ -4,9 +4,11 @@
 #include "MantidKernel/VMD.h"
 #include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include "MantidGeometry/MDGeometry/MDImplicitFunction.h"
+#include "MantidGeometry/MDGeometry/QSample.h"
 #include "MantidMDAlgorithms/SlicingAlgorithm.h"
 #include "MantidTestHelpers/MDEventsTestHelper.h"
-
+#include "MantidKernel/MDUnit.h"
+#include "MantidKernel/UnitLabel.h"
 #include <cxxtest/TestSuite.h>
 
 using namespace Mantid::API;
@@ -48,6 +50,8 @@ public:
   IMDEventWorkspace_sptr ws3;
   IMDEventWorkspace_sptr ws4;
   IMDEventWorkspace_sptr ws5;
+  IMDEventWorkspace_sptr wsQSample;
+  IMDEventWorkspace_sptr wsMixedFrames;
   IMDEventWorkspace_sptr ws_names;
 
   SlicingAlgorithmTest() {
@@ -57,6 +61,19 @@ public:
     ws3 = MDEventsTestHelper::makeMDEW<3>(5, 0.0, 10.0, 1);
     ws4 = MDEventsTestHelper::makeMDEW<4>(5, 0.0, 10.0, 1);
     ws5 = MDEventsTestHelper::makeMDEW<5>(5, 0.0, 10.0, 1);
+    // Workspace with QSample frames
+    Mantid::Geometry::QSample qSampleFrame;
+    wsQSample = MDEventsTestHelper::makeMDEWWithFrames<3>(5, 0.0, 10.0,
+                                                          qSampleFrame, 1);
+    // Workspace with mixed frames
+    std::vector<Mantid::Geometry::MDFrame_sptr> frames;
+    frames.push_back(std::make_shared<Mantid::Geometry::QSample>());
+    frames.push_back(std::make_shared<Mantid::Geometry::QSample>());
+    frames.push_back(std::make_shared<Mantid::Geometry::QSample>());
+    frames.push_back(std::make_shared<Mantid::Geometry::GeneralFrame>(
+        Mantid::Geometry::GeneralFrame::GeneralFrameDistance, "m"));
+    wsMixedFrames = MDEventsTestHelper::makeMDEWWithIndividualFrames<4>(
+        5, 0.0, 10.0, frames, 1);
     /// Workspace with custom names
     ws_names = MDEventsTestHelper::makeAnyMDEW<MDEvent<3>, 3>(
         3, 0.0, 10.0, 1, "", "[%dh,k,l]", "Q%d");
@@ -95,7 +112,7 @@ public:
         alg.makeAlignedDimensionFromString("Axis0, 11.0, 9.0"));
   }
 
-  void test_makeAlignedDimensionFromString() {
+    void test_makeAlignedDimensionFromString() {
     SlicingAlgorithmImpl alg;
     alg.m_inWS = ws;
     TSM_ASSERT_THROWS_NOTHING(
@@ -112,6 +129,28 @@ public:
     TS_ASSERT_EQUALS(dim->getX(10), 9.0);
   }
 
+  void test_makeAlignedDimensionFromStringWithMDFrameSetToQSample() {
+    SlicingAlgorithmImpl alg;
+    alg.m_inWS = wsQSample;
+    TSM_ASSERT_THROWS_NOTHING(
+        "", alg.makeAlignedDimensionFromString("Axis2, 1.0, 9.0, 10"));
+    TS_ASSERT_EQUALS(alg.m_dimensionToBinFrom.size(), 1);
+    TS_ASSERT_EQUALS(alg.m_binDimensions.size(), 1);
+
+    TS_ASSERT_EQUALS(alg.m_dimensionToBinFrom[0], 2);
+
+    IMDDimension_sptr dim = alg.m_binDimensions[0];
+    TS_ASSERT_EQUALS(dim->getName(), "Axis2");
+    TS_ASSERT_EQUALS(
+        dim->getUnits(),
+        Mantid::Kernel::InverseAngstromsUnit().getUnitLabel().ascii());
+    TSM_ASSERT_THROWS_NOTHING(
+        "Should be a QSample",
+        dynamic_cast<const Mantid::Geometry::QSample &>(dim->getMDFrame()))
+    TS_ASSERT_EQUALS(dim->getNBins(), 10);
+    TS_ASSERT_EQUALS(dim->getX(10), 9.0);
+  }
+
   /// Dimension name is of style "[x,y,z]". Handle this.
   void test_makeAlignedDimensionFromString_NameWithCommas() {
     SlicingAlgorithmImpl alg;
@@ -373,7 +412,8 @@ public:
       TS_ASSERT_EQUALS(alg.m_bases[0], basis);
       IMDDimension_sptr dim = alg.m_binDimensions[0];
       TS_ASSERT_EQUALS(dim->getName(), "name");
-      TS_ASSERT_EQUALS(dim->getUnits(), "units");
+      TSM_ASSERT("The units selection is ignored", dim->getUnits() != "units");
+      TSM_ASSERT("The unit is in m", dim->getUnits() == "m");
       TS_ASSERT_EQUALS(dim->getNBins(), 20);
       TS_ASSERT_EQUALS(dim->getMinimum(), -5);
       TS_ASSERT_EQUALS(dim->getMaximum(), +5);
@@ -397,6 +437,68 @@ public:
     }
   }
 
+
+  void test_makeBasisVectorFromStringWithPureQSampleInput() {
+    // Test WITH and WITHOUT basis vector normalization
+    for (int normalize = 0; normalize < 2; normalize++) {
+      SlicingAlgorithmImpl alg;
+      alg.m_inWS = wsQSample; // All dimensions are QSample
+      // Set up data that comes from other properties
+      alg.m_minExtents.push_back(-5.0);
+      alg.m_maxExtents.push_back(+5.0);
+      alg.m_numBins.push_back(20);
+      alg.m_NormalizeBasisVectors = (normalize > 0);
+
+      TS_ASSERT_EQUALS(alg.m_bases.size(), 0);
+      TSM_ASSERT_THROWS_NOTHING(
+          "", alg.makeBasisVectorFromString(" name, units  , 1,2,3"));
+      TS_ASSERT_EQUALS(alg.m_bases.size(), 1);
+      TS_ASSERT_EQUALS(alg.m_binDimensions.size(), 1);
+      TS_ASSERT_EQUALS(alg.m_binningScaling.size(), 1);
+      TS_ASSERT_EQUALS(alg.m_transformScaling.size(), 1);
+
+      VMD basis(1., 2., 3.);
+      if (alg.m_NormalizeBasisVectors)
+        basis.normalize();
+
+      TS_ASSERT_EQUALS(alg.m_bases[0], basis);
+      IMDDimension_sptr dim = alg.m_binDimensions[0];
+      TS_ASSERT_EQUALS(dim->getName(), "name");
+      TSM_ASSERT("The units selection is ignored", dim->getUnits() != "units");
+      TS_ASSERT_EQUALS(
+          dim->getUnits(),
+          Mantid::Kernel::InverseAngstromsUnit().getUnitLabel().ascii());
+      TSM_ASSERT_THROWS_NOTHING(
+          "Should be a QSample",
+          dynamic_cast<const Mantid::Geometry::QSample &>(dim->getMDFrame()))
+
+      TS_ASSERT_EQUALS(dim->getNBins(), 20);
+      TS_ASSERT_EQUALS(dim->getMinimum(), -5);
+      TS_ASSERT_EQUALS(dim->getMaximum(), +5);
+      TS_ASSERT_DELTA(dim->getX(5), -2.5, 1e-5);
+
+      if (alg.m_NormalizeBasisVectors) {
+        TSM_ASSERT_DELTA("Unit transformation scaling if normalizing",
+                         alg.m_transformScaling[0], 1.0, 1e-5);
+        TSM_ASSERT_DELTA("A bin ranges from 0-0.5 in OUTPUT, which is 0.5 long "
+                         "in the INPUT, "
+                         "so the binningScaling is 2.",
+                         alg.m_binningScaling[0], 2., 1e-5);
+      } else {
+        TSM_ASSERT_DELTA("Length sqrt(14) in INPUT = 1.0 in output",
+                         alg.m_transformScaling[0], sqrt(1.0 / 14.0), 1e-5);
+        TSM_ASSERT_DELTA("A bin ranges from 0-0.5 in OUTPUT, which is "
+                         "0.5/sqrt(14) long in the INPUT, "
+                         "so the binningScaling is 2/sqrt(14)",
+                         alg.m_binningScaling[0], 2. / sqrt(14.0), 1e-5);
+      }
+    }
+  }
+
+
+
+
+
   /// Create a basis vector with a dimension with [commas,etc] in the name.
   void test_makeBasisVectorFromString_NameWithCommas() {
     SlicingAlgorithmImpl alg;
@@ -424,7 +526,8 @@ public:
     IMDDimension_sptr dim = alg.m_binDimensions[0];
     TS_ASSERT_EQUALS(dim->getName(), "[Dumb,Name]");
     TS_ASSERT_EQUALS(dim->getDimensionId(), "[Dumb,Name]");
-    TS_ASSERT_EQUALS(dim->getUnits(), "units");
+    TSM_ASSERT("The units selection is ignored", dim->getUnits() != "units");
+    TSM_ASSERT("The unit is in m", dim->getUnits() == "m");
     TS_ASSERT_EQUALS(dim->getNBins(), 20);
     TS_ASSERT_EQUALS(dim->getMinimum(), -5);
     TS_ASSERT_EQUALS(dim->getMaximum(), +5);
@@ -627,6 +730,23 @@ public:
     TS_ASSERT(!func->isPointContained(VMD(1.5, 1.5, 1.5, 11.5)));
   }
 
+  void test_createGeneralTransform_4D_to_4D_with_mixed_frames() {
+    SlicingAlgorithmImpl *alg = do_createGeneralTransform(
+        wsMixedFrames, "OutX, m, 1,0,0,0", "OutY, m, 0,1,0,0", "OutZ, m, 0,0,1,0",
+        "OutE,m, 0,0,0,1", VMD(1, 1, 1, 1), "0,10,0,10,0,10,0,10", "5,5,5,5");
+    TS_ASSERT_EQUALS(alg->m_bases.size(), 4);
+
+    // The implicit function
+    MDImplicitFunction *func(NULL);
+    TS_ASSERT_THROWS_NOTHING(func =
+                                 alg->getImplicitFunctionForChunk(NULL, NULL));
+    TS_ASSERT(func);
+    TS_ASSERT_EQUALS(func->getNumPlanes(), 8);
+    TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 1.5, 1.5)));
+    TS_ASSERT(!func->isPointContained(VMD(1.5, 1.5, 1.5, -1.5)));
+    TS_ASSERT(!func->isPointContained(VMD(1.5, 1.5, 1.5, 11.5)));
+  }
+
   /** 4D "left-handed" coordinate system
    * obtained by flipping the Y basis vector.  */
   void test_createGeneralTransform_4D_to_4D_LeftHanded() {
diff --git a/Framework/SINQ/src/LoadFlexiNexus.cpp b/Framework/SINQ/src/LoadFlexiNexus.cpp
index d589ce89c86d6df3055e64532ff7ba7071916091..644c05118e1e465dfc1b12ba359349b97d17997c 100644
--- a/Framework/SINQ/src/LoadFlexiNexus.cpp
+++ b/Framework/SINQ/src/LoadFlexiNexus.cpp
@@ -297,8 +297,9 @@ MDHistoDimension_sptr LoadFlexiNexus::makeDimension(NeXus::File *fin, int index,
     min = tmp;
     g_log.notice("WARNING: swapped axis values on " + name);
   }
+  Mantid::Geometry::GeneralFrame frame(name, "");
   return MDHistoDimension_sptr(
-      new MDHistoDimension(name, name, "", min, max, length));
+      new MDHistoDimension(name, name, frame, min, max, length));
 }
 void LoadFlexiNexus::addMetaData(NeXus::File *fin, Workspace_sptr ws,
                                  ExperimentInfo_sptr info) {
diff --git a/Framework/SINQ/test/LoadFlexiNexusTest.h b/Framework/SINQ/test/LoadFlexiNexusTest.h
index ad43fde6f3a26ec322a66a43df263aa5be0a6d29..418b57ab0ad487126d0fe2783870dcb4974b5030 100644
--- a/Framework/SINQ/test/LoadFlexiNexusTest.h
+++ b/Framework/SINQ/test/LoadFlexiNexusTest.h
@@ -65,6 +65,8 @@ public:
     TS_ASSERT_DELTA(dimi->getMinimum(), -86, .1);
     TS_ASSERT_DELTA(dimi->getMaximum(), 84.65, .1);
 
+
+
     // test some meta data
     std::string title = data->getTitle();
     size_t found = title.find("Selene");
diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h b/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h
index ea95ef80a6ed36f323cdfccca0604147933443ca..c2edb75dc8ff427f4f97ce48f83e79af5d3245c1 100644
--- a/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h
+++ b/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h
@@ -75,6 +75,26 @@ void addMDDimensionsWithFrames(
   out->initialize();
 }
 
+template <typename MDE, size_t nd>
+void addMDDimensionsWithIndividualFrames(
+    boost::shared_ptr<Mantid::DataObjects::MDEventWorkspace<MDE, nd>> out,
+    Mantid::coord_t min, Mantid::coord_t max,
+    std::vector<Mantid::Geometry::MDFrame_sptr> frame,
+    std::string axisNameFormat, std::string axisIdFormat) {
+  for (size_t d = 0; d < nd; d++) {
+    char name[200];
+    sprintf(name, axisNameFormat.c_str(), d);
+    char id[200];
+    sprintf(id, axisIdFormat.c_str(), d);
+
+    // Use the same frame for all dimensions
+    auto dim = boost::make_shared<Mantid::Geometry::MDHistoDimension>(
+        std::string(name), std::string(id), *frame[d], min, max, 10);
+    out->addDimension(dim);
+  }
+  out->initialize();
+}
+
 template <typename MDE, size_t nd>
 void addData(
     boost::shared_ptr<Mantid::DataObjects::MDEventWorkspace<MDE, nd>> out,
@@ -197,6 +217,47 @@ makeAnyMDEW(size_t splitInto, coord_t min, coord_t max,
   return out;
 }
 
+
+/** Create a test MDEventWorkspace<nd> . Dimensions are names Axis0, Axis1, etc.
+ *  But you can set an MDFrame. The frames can be set individually.
+ *
+ * @param splitInto :: each dimension will split into this many subgrids
+ * @param min :: extent of each dimension (min)
+ * @param max :: extent of each dimension (max)
+ * @param frames:: the chosen frame
+ * @param numEventsPerBox :: will create one MDLeanEvent in the center of each
+ *sub-box.
+ *        0 = don't split box, don't add events
+ * @param wsName :: if specified, then add the workspace to the analysis data
+ *service
+ * @param axisNameFormat :: string for the axis name, processed via sprintf()
+ * @param axisIdFormat :: string for the axis ID, processed via sprintf()
+ * @return shared ptr to the created workspace
+ */
+template <typename MDE, size_t nd>
+boost::shared_ptr<Mantid::DataObjects::MDEventWorkspace<MDE, nd>>
+makeAnyMDEWWithIndividualFrames(size_t splitInto, coord_t min, coord_t max,
+                      std::vector<Mantid::Geometry::MDFrame_sptr>frames,
+                      size_t numEventsPerBox = 0, std::string wsName = "",
+                      std::string axisNameFormat = "Axis%d",
+                      std::string axisIdFormat = "Axis%d") {
+  // Create bare workspace
+  auto out = createOutputWorkspace<MDE, nd>(splitInto);
+
+  // Add standard dimensions
+  addMDDimensionsWithIndividualFrames<MDE, nd>(out, min, max, frames, axisNameFormat,
+                                     axisIdFormat);
+
+  // Add data
+  addData<MDE, nd>(out, splitInto, min, max, numEventsPerBox);
+
+  // Add to ADS on option
+  if (!wsName.empty())
+    Mantid::API::AnalysisDataService::Instance().addOrReplace(wsName, out);
+
+  return out;
+}
+
 /** Create a test MDEventWorkspace<nd> . Dimensions are names Axis0, Axis1, etc.
  *  But you can set an MDFrame. For now the same frame for all dimensions
  *  is used.
@@ -256,6 +317,18 @@ makeMDEWWithFrames(size_t splitInto, coord_t min, coord_t max,
                                                     numEventsPerBox);
 }
 
+/** Make a MDEventWorkspace with MDLeanEvents and individual MDFrames*/
+template <size_t nd>
+boost::shared_ptr<MDEventWorkspace<MDLeanEvent<nd>, nd>>
+makeMDEWWithIndividualFrames(size_t splitInto, coord_t min, coord_t max,
+                   std::vector<Mantid::Geometry::MDFrame_sptr> frame,
+                   size_t numEventsPerBox = 0) {
+  return makeAnyMDEWWithIndividualFrames<MDLeanEvent<nd>, nd>(splitInto, min, max, frame,
+                                                    numEventsPerBox);
+}
+
+
+
 /** Make a MDEventWorkspace with MDEvents  - updated to split dims by splitInto,
  * not 10 */
 template <size_t nd>