diff --git a/Framework/API/src/IMDWorkspace.cpp b/Framework/API/src/IMDWorkspace.cpp
index 944da88b66a6a7468da5d5db654e988bfeb5565e..3adef955ad3a01989ffe7bb14f0328aee87aa0f7 100644
--- a/Framework/API/src/IMDWorkspace.cpp
+++ b/Framework/API/src/IMDWorkspace.cpp
@@ -1,6 +1,7 @@
 #include "MantidAPI/IMDWorkspace.h"
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/IPropertyManager.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/VMD.h"
 
 #include <sstream>
@@ -88,6 +89,14 @@ const std::string IMDWorkspace::toString() const {
     os << "Binned from '" << getOriginalWorkspace()->getName();
   }
   os << "\n";
+  std::string convention =
+      Kernel::ConfigService::Instance().getString("Q.convention");
+  if (convention == "Crystallography")
+    os << "Crystallography: ki-kf";
+  else
+    os << "Inelastic: kf-ki";
+  os << "\n";
+
   return os.str();
 }
 
diff --git a/Framework/API/src/MDGeometry.cpp b/Framework/API/src/MDGeometry.cpp
index 00a8f284dfd1a9215d4929e98df18b7c170a9dfb..fac8f0cfd003edbfdf987cedc80e349f40b42de3 100644
--- a/Framework/API/src/MDGeometry.cpp
+++ b/Framework/API/src/MDGeometry.cpp
@@ -379,7 +379,10 @@ void MDGeometry::transformDimensions(std::vector<double> &scaling,
                   static_cast<coord_t>(offset[d]);
     coord_t max = (dim->getMaximum() * static_cast<coord_t>(scaling[d])) +
                   static_cast<coord_t>(offset[d]);
-    dim->setRange(dim->getNBins(), min, max);
+    if (min < max)
+      dim->setRange(dim->getNBins(), min, max);
+    else
+      dim->setRange(dim->getNBins(), max, min);
   }
   // Clear the original workspace
   setOriginalWorkspace(boost::shared_ptr<Workspace>());
diff --git a/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h b/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h
index 1ecb3c3c954cc50d4c6bdf35e63a4a2d53148943..4ea4de97af84216aba5933991197e191cddabec1 100644
--- a/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h
+++ b/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h
@@ -59,7 +59,7 @@ private:
   /// Read a single peak from peaks file
   DataObjects::Peak readPeak(DataObjects::PeaksWorkspace_sptr outWS,
                              std::string &lastStr, std::ifstream &in,
-                             int &seqNum, std::string bankName);
+                             int &seqNum, std::string bankName, double qSign);
 
   int findPixelID(Geometry::Instrument_const_sptr inst, std::string bankName,
                   int col, int row);
diff --git a/Framework/Crystal/src/LoadHKL.cpp b/Framework/Crystal/src/LoadHKL.cpp
index f58e8609a8352212dd4accaea248ea35c4c30f5e..c9ecad34a84444ce09a81b78702b2e336cb68a02 100644
--- a/Framework/Crystal/src/LoadHKL.cpp
+++ b/Framework/Crystal/src/LoadHKL.cpp
@@ -33,9 +33,11 @@ LoadHKL::~LoadHKL() {}
 /** Initialize the algorithm's properties.
  */
 void LoadHKL::init() {
-  declareProperty(
-      new FileProperty("Filename", "", FileProperty::Load, {".hkl"}),
-      "Path to an hkl file to save.");
+  std::vector<std::string> exts;
+  exts.push_back(".hkl");
+
+  declareProperty(new FileProperty("Filename", "", FileProperty::Load, exts),
+                  "Path to an hkl file to save.");
 
   declareProperty(new WorkspaceProperty<PeaksWorkspace>("OutputWorkspace", "",
                                                         Direction::Output),
@@ -58,6 +60,11 @@ void LoadHKL::exec() {
   //    % (H, K, L, FSQ, SIGFSQ, hstnum, WL, TBAR, CURHST, SEQNUM, TRANSMISSION,
   //    DN, TWOTH, DSP))
   // HKL is flipped by -1 due to different q convention in ISAW vs mantid.
+  // Default for kf-ki has -q
+  double qSign = -1.0;
+  std::string convention = ConfigService::Instance().getString("Q.convention");
+  if (convention == "Crystallography")
+    qSign = 1.0;
   Instrument_sptr inst(new Geometry::Instrument);
   Detector *detector = new Detector("det1", -1, 0);
   detector->setPos(0.0, 0.0, 0.0);
@@ -105,7 +112,7 @@ void LoadHKL::exec() {
     }
 
     Peak peak(inst, scattering, wl);
-    peak.setHKL(-h, -k, -l);
+    peak.setHKL(qSign * h, qSign * k, qSign * l);
     peak.setIntensity(Inti);
     peak.setSigmaIntensity(SigI);
     peak.setRunNumber(run);
diff --git a/Framework/Crystal/src/LoadIsawPeaks.cpp b/Framework/Crystal/src/LoadIsawPeaks.cpp
index 839acbadf6f0ee3e9d089e73f28288a94b3d9e69..ddcf35096274e9757bf48135e28545dd11c420eb 100644
--- a/Framework/Crystal/src/LoadIsawPeaks.cpp
+++ b/Framework/Crystal/src/LoadIsawPeaks.cpp
@@ -328,12 +328,13 @@ std::string LoadIsawPeaks::readHeader(PeaksWorkspace_sptr outWS,
  * @param in :: input stream
  * @param seqNum [out] :: the sequence number of the peak
  * @param bankName :: the bank number from the ISAW file.
+ * @param qSign :: For inelastic this is 1; for crystallography this is -1
  * @return the Peak the Peak object created
  */
 DataObjects::Peak LoadIsawPeaks::readPeak(PeaksWorkspace_sptr outWS,
                                           std::string &lastStr,
                                           std::ifstream &in, int &seqNum,
-                                          std::string bankName) {
+                                          std::string bankName, double qSign) {
   double h;
   double k;
   double l;
@@ -406,8 +407,7 @@ DataObjects::Peak LoadIsawPeaks::readPeak(PeaksWorkspace_sptr outWS,
 
   // Create the peak object
   Peak peak(outWS->getInstrument(), pixelID, wl);
-  // HKL's are flipped by -1 because of the internal Q convention
-  peak.setHKL(-h, -k, -l);
+  peak.setHKL(qSign * h, qSign * k, qSign * l);
   peak.setIntensity(Inti);
   peak.setSigmaIntensity(SigI);
   peak.setBinCount(IPK);
@@ -504,7 +504,12 @@ std::string LoadIsawPeaks::readPeakBlockHeader(std::string lastStr,
  */
 void LoadIsawPeaks::appendFile(PeaksWorkspace_sptr outWS,
                                std::string filename) {
-
+  // HKL's are flipped by -1 because of the internal Q convention
+  // unless Crystallography convention
+  double qSign = -1.0;
+  std::string convention = ConfigService::Instance().getString("Q.convention");
+  if (convention == "Crystallography")
+    qSign = 1.0;
   // Open the file
   std::ifstream in(filename.c_str());
 
@@ -564,7 +569,7 @@ void LoadIsawPeaks::appendFile(PeaksWorkspace_sptr outWS,
 
     try {
       // Read the peak
-      Peak peak = readPeak(outWS, s, in, seqNum, bankName);
+      Peak peak = readPeak(outWS, s, in, seqNum, bankName, qSign);
 
       // Get the calculated goniometer matrix
       Matrix<double> gonMat = uniGonio.getR();
diff --git a/Framework/Crystal/src/SaveHKL.cpp b/Framework/Crystal/src/SaveHKL.cpp
index 35cc554271270b77ebae900db3d65a08523513bf..51eddf20ef8f46a5f2c725650ffaff4fb95e8b3e 100644
--- a/Framework/Crystal/src/SaveHKL.cpp
+++ b/Framework/Crystal/src/SaveHKL.cpp
@@ -126,6 +126,12 @@ void SaveHKL::exec() {
   int runSequence = 0;
   int bankold = -1;
   int runold = -1;
+  // HKL is flipped by -1 due to different q convention in ISAW vs mantid.
+  // Default for kf-ki has -q
+  double qSign = -1.0;
+  std::string convention = ConfigService::Instance().getString("Q.convention");
+  if (convention == "Crystallography")
+    qSign = 1.0;
 
   std::fstream out;
   bool append = getProperty("AppendFile");
@@ -308,14 +314,14 @@ void SaveHKL::exec() {
     // hklFile.write('%4d%4d%4d%8.2f%8.2f%4d%8.4f%7.4f%7d%7d%7.4f%4d%9.5f%9.4f\n'
     //    % (H, K, L, FSQ, SIGFSQ, hstnum, WL, TBAR, CURHST, SEQNUM,
     //    TRANSMISSION, DN, TWOTH, DSP))
-    // HKL is flipped by -1 due to different q convention in ISAW vs mantid.
     if (p.getH() == 0 && p.getK() == 0 && p.getL() == 0) {
       banned.push_back(wi);
       continue;
     }
     if (decimalHKL == EMPTY_INT())
-      out << std::setw(4) << Utils::round(-p.getH()) << std::setw(4)
-          << Utils::round(-p.getK()) << std::setw(4) << Utils::round(-p.getL());
+      out << std::setw(4) << Utils::round(qSign * p.getH()) << std::setw(4)
+          << Utils::round(qSign * p.getK()) << std::setw(4)
+          << Utils::round(qSign * p.getL());
     else
       out << std::setw(5 + decimalHKL) << std::fixed
           << std::setprecision(decimalHKL) << -p.getH()
diff --git a/Framework/Crystal/src/SaveIsawPeaks.cpp b/Framework/Crystal/src/SaveIsawPeaks.cpp
index 957dc07f27a19753b15793e2b95d5de093d26ad0..9e09c3d107db26065eb205ba7a74f493665f4ce0 100644
--- a/Framework/Crystal/src/SaveIsawPeaks.cpp
+++ b/Framework/Crystal/src/SaveIsawPeaks.cpp
@@ -247,7 +247,12 @@ void SaveIsawPeaks::exec() {
       }
     }
   }
-
+  // HKL's are flipped by -1 because of the internal Q convention
+  // unless Crystallography convention
+  double qSign = -1.0;
+  std::string convention = ConfigService::Instance().getString("Q.convention");
+  if (convention == "Crystallography")
+    qSign = 1.0;
   // ============================== Save all Peaks
   // =========================================
   // Sequence number
@@ -305,11 +310,11 @@ void SaveIsawPeaks::exec() {
           // Sequence (run) number
           out << "3" << std::setw(7) << seqNum;
 
-          // HKL is flipped by -1 due to different q convention in ISAW vs
-          // mantid.
-          out << std::setw(5) << Utils::round(-p.getH()) << std::setw(5)
-              << Utils::round(-p.getK()) << std::setw(5)
-              << Utils::round(-p.getL());
+          // HKL's are flipped by -1 because of the internal Q convention
+          // unless Crystallography convention
+          out << std::setw(5) << Utils::round(qSign * p.getH()) << std::setw(5)
+              << Utils::round(qSign * p.getK()) << std::setw(5)
+              << Utils::round(qSign * p.getL());
 
           // Row/column
           out << std::setw(8) << std::fixed << std::setprecision(2)
diff --git a/Framework/Crystal/src/SaveLauenorm.cpp b/Framework/Crystal/src/SaveLauenorm.cpp
index 339c05f661de42f35bec75af98fde98ee01a4000..e74a2a5ea9313eeedd88f78e8cccabb1533caf64 100644
--- a/Framework/Crystal/src/SaveLauenorm.cpp
+++ b/Framework/Crystal/src/SaveLauenorm.cpp
@@ -111,6 +111,12 @@ void SaveLauenorm::exec() {
 
   // ============================== Save all Peaks
   // =========================================
+  // HKL is flipped by -1 due to different q convention in ISAW vs mantid.
+  // Default for kf-ki has -q
+  double qSign = -1.0;
+  std::string convention = ConfigService::Instance().getString("Q.convention");
+  if (convention == "Crystallography")
+    qSign = 1.0;
 
   // Go through each peak at this run / bank
   for (int wi = 0; wi < ws->getNumberPeaks(); wi++) {
@@ -170,10 +176,12 @@ void SaveLauenorm::exec() {
     // h k l lambda theta intensity and  sig(intensity)  in format
     // (3I5,2F10.5,2I10)
     // HKL is flipped by -1 due to different q convention in ISAW vs mantid.
+    // unless Crystallography convention
     if (p.getH() == 0 && p.getK() == 0 && p.getL() == 0)
       continue;
-    out << std::setw(5) << Utils::round(-p.getH()) << std::setw(5)
-        << Utils::round(-p.getK()) << std::setw(5) << Utils::round(-p.getL());
+    out << std::setw(5) << Utils::round(qSign * p.getH()) << std::setw(5)
+        << Utils::round(qSign * p.getK()) << std::setw(5)
+        << Utils::round(qSign * p.getL());
     out << std::setw(10) << std::fixed << std::setprecision(5) << lambda;
     // Assume that want theta not two-theta
     out << std::setw(10) << std::fixed << std::setprecision(5)
diff --git a/Framework/DataHandling/src/LoadNexusProcessed.cpp b/Framework/DataHandling/src/LoadNexusProcessed.cpp
index f7b3c20e71aaa366148e78e1aa5840ba38933e26..9b988daed4c4ef9edee41ce3197b086977b61053 100644
--- a/Framework/DataHandling/src/LoadNexusProcessed.cpp
+++ b/Framework/DataHandling/src/LoadNexusProcessed.cpp
@@ -1071,6 +1071,14 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) {
   // peaks_workspace
   m_cppFile->closeGroup();
 
+  // HKL is flipped by -1 due to different q convention in Crystallography.
+  // Always write out in ki-kf so consistent with old files
+  double qSign = 1.0;
+  std::string convention =
+      ConfigService::Instance().getString("default.convention");
+  if (convention == "Crystallography")
+    qSign = -1.0;
+
   for (int r = 0; r < numberPeaks; r++) {
     Kernel::V3D v3d;
     v3d[2] = 1.0;
@@ -1097,7 +1105,7 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) {
       nxDouble.load();
 
       for (int r = 0; r < numberPeaks; r++) {
-        double val = nxDouble[r];
+        double val = qSign * nxDouble[r];
         peakWS->getPeak(r).setH(val);
       }
     }
@@ -1107,7 +1115,7 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) {
       nxDouble.load();
 
       for (int r = 0; r < numberPeaks; r++) {
-        double val = nxDouble[r];
+        double val = qSign * nxDouble[r];
         peakWS->getPeak(r).setK(val);
       }
     }
@@ -1117,7 +1125,7 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) {
       nxDouble.load();
 
       for (int r = 0; r < numberPeaks; r++) {
-        double val = nxDouble[r];
+        double val = qSign * nxDouble[r];
         peakWS->getPeak(r).setL(val);
       }
     }
@@ -1629,20 +1637,11 @@ void LoadNexusProcessed::readInstrumentGroup(
 
   // Now build the spectra list
   int index = 0;
-  bool haveSpectraAxis = local_workspace->getAxis(1)->isSpectra();
 
   for (int i = 1; i <= spectraInfo.nSpectra; ++i) {
     int spectrum(-1);
-    // prefer the spectra number from the instrument section
-    // over anything else. If not there then use a spectra axis
-    // number if we have one, else make one up as nothing was
-    // written to the file. We should always set it so that
-    // CompareWorkspaces gives the expected answer on a Save/Load
-    // round trip.
     if (spectraInfo.hasSpectra) {
       spectrum = spectraInfo.spectraNumbers[i - 1];
-    } else if (haveSpectraAxis && !m_axis1vals.empty()) {
-      spectrum = static_cast<specid_t>(m_axis1vals[i - 1]);
     } else {
       spectrum = i + 1;
     }
@@ -1652,7 +1651,11 @@ void LoadNexusProcessed::readInstrumentGroup(
          find(m_spec_list.begin(), m_spec_list.end(), i) !=
              m_spec_list.end())) {
       ISpectrum *spec = local_workspace->getSpectrum(index);
-      spec->setSpectrumNo(spectrum);
+      if (m_axis1vals.empty()) {
+        spec->setSpectrumNo(spectrum);
+      } else {
+        spec->setSpectrumNo(static_cast<specid_t>(m_axis1vals[i - 1]));
+      }
       ++index;
 
       int start = spectraInfo.detectorIndex[i - 1];
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDBox.tcc b/Framework/DataObjects/inc/MantidDataObjects/MDBox.tcc
index 2b9ca29de1b3af05929c6e08526cbd8475e61b89..bdcdfe3e2c4dd5d9433208a261464cab727d6562 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDBox.tcc
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDBox.tcc
@@ -690,6 +690,7 @@ TMDE(void MDBox)::centroidSphere(Mantid::API::CoordTransform &radiusTransform,
 TMDE(void MDBox)::transformDimensions(std::vector<double> &scaling,
                                       std::vector<double> &offset) {
   MDBoxBase<MDE, nd>::transformDimensions(scaling, offset);
+  this->calculateCentroid(this->m_centroid);
   std::vector<MDE> &events = this->getEvents();
   typename std::vector<MDE>::iterator it;
   typename std::vector<MDE>::iterator it_end = events.end();
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc
index fabb4d85c77d76247462e3ccebae607825a0aaed..6727acdd4be60473491d1b026dc8d3f9142c3e1d 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc
@@ -16,6 +16,8 @@
 #include "MantidDataObjects/MDFramesToSpecialCoordinateSystem.h"
 #include "MantidDataObjects/MDGridBox.h"
 #include "MantidDataObjects/MDLeanEvent.h"
+#include "MantidKernel/ConfigService.h"
+
 #include <iomanip>
 #include <functional>
 #include <algorithm>
@@ -327,6 +329,7 @@ TMDE(signal_t MDEventWorkspace)::getSignalWithMaskAtCoord(
   }
   // Check if masked
   const API::IMDNode *box = data->getBoxAtCoord(coords);
+  if (!box) return MDMaskValue;
   if (box->getIsMasked()) {
     return MDMaskValue;
   }
@@ -376,6 +379,7 @@ TMDE(std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>>
 TMDE(std::vector<std::string> MDEventWorkspace)::getBoxControllerStats() const {
   std::vector<std::string> out;
   std::ostringstream mess;
+ 
   size_t mem;
   mem = (this->m_BoxController->getTotalNumMDBoxes() * sizeof(MDBox<MDE, nd>)) /
         1024;
diff --git a/Framework/DataObjects/inc/MantidDataObjects/Peak.h b/Framework/DataObjects/inc/MantidDataObjects/Peak.h
index 313ddb6d90a6efd95ac3740606cbd97ea7bdee41..b6d0ccfa09bf7677d6312491dec31d812d19efc2 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/Peak.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/Peak.h
@@ -9,6 +9,7 @@
 #include "MantidKernel/PhysicalConstants.h"
 #include "MantidKernel/System.h"
 #include "MantidGeometry/Crystal/PeakShape.h"
+#include "MantidKernel/ConfigService.h"
 #include <boost/shared_ptr.hpp>
 #include <boost/optional.hpp>
 
@@ -214,6 +215,10 @@ private:
 
   /// Static logger
   static Mantid::Kernel::Logger g_log;
+
+  // ki-kf for Inelastic convention; kf-ki for Crystallography convention
+  std::string convention =
+      Kernel::ConfigService::Instance().getString("Q.convention");
 };
 
 } // namespace Mantid
diff --git a/Framework/DataObjects/src/MDBoxFlatTree.cpp b/Framework/DataObjects/src/MDBoxFlatTree.cpp
index 145e24246674856d2e1cfe7bc1d55293ee572f4a..d4b7d418f05c5b7a8784e5c989e93c4d04533d49 100644
--- a/Framework/DataObjects/src/MDBoxFlatTree.cpp
+++ b/Framework/DataObjects/src/MDBoxFlatTree.cpp
@@ -749,6 +749,12 @@ void MDBoxFlatTree::saveWSGenericInfo(::NeXus::File *const file,
   file->writeData("coordinate_system",
                   static_cast<uint32_t>(ws->getSpecialCoordinateSystem()));
 
+  // Write out the Qconvention
+  // ki-kf for Inelastic convention; kf-ki for Crystallography convention
+  std::string m_QConvention =
+      Kernel::ConfigService::Instance().getString("Q.convention");
+  file->writeData("QConvention", m_QConvention);
+
   // Write out the set display normalization
   file->writeData("visual_normalization",
                   static_cast<uint32_t>(ws->displayNormalization()));
@@ -808,6 +814,8 @@ void MDBoxFlatTree::saveAffineTransformMatricies(
 void MDBoxFlatTree::saveAffineTransformMatrix(
     ::NeXus::File *const file, API::CoordTransform const *transform,
     std::string entry_name) {
+  if (!transform)
+    return;
   Kernel::Matrix<coord_t> matrix = transform->makeAffineMatrix();
   g_log.debug() << "TRFM: " << matrix.str() << std::endl;
   saveMatrix<coord_t>(file, entry_name, matrix, ::NeXus::FLOAT32,
diff --git a/Framework/DataObjects/src/Peak.cpp b/Framework/DataObjects/src/Peak.cpp
index 412f64c13970708fd6ccd14dc2a77cccc4e3e955..fea8ff8399c47bd57f4d3d80f6be5a555786f552 100644
--- a/Framework/DataObjects/src/Peak.cpp
+++ b/Framework/DataObjects/src/Peak.cpp
@@ -452,7 +452,11 @@ Mantid::Kernel::V3D Peak::getQLabFrame() const {
   // Now calculate the wavevector of the scattered neutron
   double wvf = (2.0 * M_PI) / this->getWavelength();
   // And Q in the lab frame
-  return beamDir * wvi - detDir * wvf;
+  // Default for ki-kf is positive
+  double qSign = 1.0;
+  if (convention == "Crystallography")
+    qSign = -1.0;
+  return (beamDir * wvi - detDir * wvf) * qSign;
 }
 
 //----------------------------------------------------------------------------------------------
@@ -528,7 +532,11 @@ void Peak::setQLabFrame(Mantid::Kernel::V3D QLabFrame,
   boost::shared_ptr<const ReferenceFrame> refFrame =
       this->m_inst->getReferenceFrame();
   const V3D refBeamDir = refFrame->vecPointingAlongBeam();
-  const double qBeam = q.scalar_prod(refBeamDir);
+  // Default for ki-kf has -q
+  double qSign = 1.0;
+  if (convention == "Crystallography")
+    qSign = -1.0;
+  const double qBeam = q.scalar_prod(refBeamDir) * qSign;
 
   if (norm_q == 0.0)
     throw std::invalid_argument("Peak::setQLabFrame(): Q cannot be 0,0,0.");
@@ -548,7 +556,12 @@ void Peak::setQLabFrame(Mantid::Kernel::V3D QLabFrame,
   // Save the wavelength
   this->setWavelength(wl);
 
-  V3D detectorDir = q * -1.0;
+  // Default for ki-kf has -q
+  qSign = -1.0;
+  if (convention == "Crystallography")
+    qSign = 1.0;
+
+  V3D detectorDir = q * qSign;
   detectorDir[refFrame->pointingAlongBeam()] = one_over_wl - qBeam;
   detectorDir.normalize();
 
diff --git a/Framework/DataObjects/src/PeaksWorkspace.cpp b/Framework/DataObjects/src/PeaksWorkspace.cpp
index 5f60d4dd27b2d85681491721f7ee737bdefb5355..e8789ecd492ca45bdfbc1643ddc89a33ea697752 100644
--- a/Framework/DataObjects/src/PeaksWorkspace.cpp
+++ b/Framework/DataObjects/src/PeaksWorkspace.cpp
@@ -605,14 +605,21 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const {
   std::vector<double> goniometerMatrix(9 * np);
   std::vector<std::string> shapes(np);
 
+  // HKL is flipped by -1 due to different q convention in Crystallography.
+  // Always write out in ki-kf so consistent with old files
+  double qSign = 1.0;
+  std::string convention = ConfigService::Instance().getString("Q.convention");
+  if (convention == "Crystallography")
+    qSign = -1.0;
+
   // Populate column vectors from Peak Workspace
   size_t maxShapeJSONLength = 0;
   for (size_t i = 0; i < np; i++) {
     Peak p = peaks[i];
     detectorID[i] = p.getDetectorID();
-    H[i] = p.getH();
-    K[i] = p.getK();
-    L[i] = p.getL();
+    H[i] = qSign * p.getH();
+    K[i] = qSign * p.getK();
+    L[i] = qSign * p.getL();
     intensity[i] = p.getIntensity();
     sigmaIntensity[i] = p.getSigmaIntensity();
     binCount[i] = p.getBinCount();
diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDDimensionExtents.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDDimensionExtents.h
index 4960525bd89a8b8ac183af9118005a9303c79f89..0ff5e834ca339fb202c473fc82af66abc2b00007 100644
--- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDDimensionExtents.h
+++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDDimensionExtents.h
@@ -58,6 +58,12 @@ public:
     min = static_cast<T>(min * scaling + offset);
     max = static_cast<T>(max * scaling + offset);
     m_size = static_cast<T>(m_size * scaling);
+    if (max < min) {
+      T tmp = max;
+      max = min;
+      min = tmp;
+      m_size = std::fabs(m_size);
+    }
   }
   // it looks like this loses accuracy?
   void expand(MDDimensionExtents &other) {
diff --git a/Framework/Kernel/src/ConfigService.cpp b/Framework/Kernel/src/ConfigService.cpp
index 943bfe6415faea2a7ead5db0bbfa1675cd059a4e..f6330235d517b60be3f96252a4511569326da1ad 100644
--- a/Framework/Kernel/src/ConfigService.cpp
+++ b/Framework/Kernel/src/ConfigService.cpp
@@ -673,10 +673,15 @@ void ConfigServiceImpl::createUserPropertiesFile() const {
     filestr << "## e.g.: ISIS, SNS, ILL" << std::endl;
     filestr << "default.facility=" << std::endl;
     filestr << std::endl;
-    filestr << "## Stes the default instrument" << std::endl;
+    filestr << "## Sets the default instrument" << std::endl;
     filestr << "## e.g. IRIS, HET, NIMROD" << std::endl;
     filestr << "default.instrument=" << std::endl;
     filestr << std::endl;
+    filestr << std::endl;
+    filestr << "## Sets the Q.convention" << std::endl;
+    filestr << "## Set to Crystallography for kf-ki instead of default "
+               "Inelastic which is ki-kf" << std::endl;
+    filestr << "#Q.convention=Crystallography" << std::endl;
     filestr << "##" << std::endl;
     filestr << "## DIRECTORIES" << std::endl;
     filestr << "##" << std::endl;
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CalculateCoverageDGS.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CalculateCoverageDGS.h
index c27d40674a83b6b84dd546cdebcba17b6abd7647..b8d05117f485dfb26b42a6b5cb746d2bfd516997 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CalculateCoverageDGS.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CalculateCoverageDGS.h
@@ -46,6 +46,9 @@ private:
   void init();
   void exec();
 
+  // ki-kf for Inelastic convention; kf-ki for Crystallography convention
+  std::string convention =
+      Kernel::ConfigService::Instance().getString("Q.convention");
   /// limits for h,k,l,dE dimensions
   coord_t m_hmin, m_hmax, m_kmin, m_kmax, m_lmin, m_lmax, m_dEmin, m_dEmax;
   /// cached values for incident energy and momentum, final momentum min/max
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h
index 2d696925f79d13e41f66ce9450bac5dae76264fb..ead3c69d6e3d0d4121d7e1103dfa0bbc7bc34253 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h
@@ -66,6 +66,10 @@ private:
   /// Run the algorithm
   void exec();
 
+  // ki-kf for Inelastic convention; kf-ki for Crystallography convention
+  std::string convention =
+      Kernel::ConfigService::Instance().getString("Q.convention");
+
   /// Helper method
   template <typename MDE, size_t nd>
   void doLoad(typename DataObjects::MDEventWorkspace<MDE, nd>::sptr ws);
@@ -84,6 +88,8 @@ private:
 
   void loadCoordinateSystem();
 
+  void loadQConvention();
+
   void loadVisualNormalization(
       const std::string &key,
       boost::optional<Mantid::API::MDNormalization> &normalization);
@@ -114,6 +120,8 @@ private:
   std::vector<Mantid::Geometry::IMDDimension_sptr> m_dims;
   /// Coordinate system
   Kernel::SpecialCoordinateSystem m_coordSystem;
+  /// QConvention
+  std::string m_QConvention;
   /// load only the box structure with empty boxes but do not tload boxes events
   bool m_BoxStructureAndMethadata;
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h
index 375dea557814745e6daab6a00e8116651f5ee0ad..232723120d92fe7003425cf34ada76b348cf0d00 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h
@@ -88,6 +88,9 @@ private:
   Kernel::V3D m_samplePos;
   /// Beam direction
   Kernel::V3D m_beamDir;
+  /// ki-kf for Inelastic convention; kf-ki for Crystallography convention
+  std::string convention =
+      Kernel::ConfigService::Instance().getString("Q.convention");
 };
 
 } // namespace MDAlgorithms
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h
index a0c1a0ed9d66e176118196357774d42e7e2f6ff9..092f86fed045cba75d9da35ece64d60c87316c6f 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h
@@ -91,6 +91,9 @@ private:
   Kernel::V3D m_samplePos;
   /// Beam direction
   Kernel::V3D m_beamDir;
+  /// ki-kf for Inelastic convention; kf-ki for Crystallography convention
+  std::string convention =
+      Kernel::ConfigService::Instance().getString("Q.convention");
 };
 
 } // namespace MDAlgorithms
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfQ3D.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfQ3D.h
index 8c63d3573d746cea5370cba35f0db997f17e2e8e..c5971198784c5adaa4e2a1d6c591910383cc510f 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfQ3D.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfQ3D.h
@@ -4,6 +4,7 @@
 #include "MantidMDAlgorithms/MDTransfInterface.h"
 #include "MantidMDAlgorithms/MDTransfFactory.h"
 #include "MantidMDAlgorithms/MDTransfModQ.h"
+#include "MantidKernel/ConfigService.h"
 //
 namespace Mantid {
 namespace MDAlgorithms {
@@ -98,6 +99,9 @@ protected:
   // current value of Sin(Theta)^2 corresponding to the current detector value
   // and used to calculate Lorentz corrections
   double m_SinThetaSq;
+  // ki-kf for Inelastic convention; kf-ki for Crystallography convention
+  std::string convention =
+      Kernel::ConfigService::Instance().getString("Q.convention");
   // all other variables are the same as in ModQ
   // hole near origin of Q
   double m_AbsMin;
diff --git a/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp b/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp
index 314e164716b3e9d5fe7bb3da0486358ab3b8567f..2394ac3c37955b9ae5385fe14bb4076c708c9774 100644
--- a/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp
+++ b/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp
@@ -456,8 +456,13 @@ CalculateCoverageDGS::calculateIntersections(const double theta,
                                              const double phi) {
   V3D qout(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)),
       qin(0., 0., m_ki);
+
   qout = m_rubw * qout;
   qin = m_rubw * qin;
+  if (convention == "Crystallography") {
+    qout *= -1;
+    qin *= -1;
+  }
   double hStart = qin.X() - qout.X() * m_kfmin,
          hEnd = qin.X() - qout.X() * m_kfmax;
   double kStart = qin.Y() - qout.Y() * m_kfmin,
diff --git a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp
index 4f6bf32e23452dd2ec1d8b6ba2a0ed9ec04cddb4..0dfce62de24cd82a3e37aa9e0bb94d790d69409e 100644
--- a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp
+++ b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp
@@ -19,6 +19,7 @@
 #include "MantidDataObjects/MDEventWorkspace.h"
 #include "MantidAPI/MemoryManager.h"
 #include "MantidKernel/ListValidator.h"
+#include "MantidKernel/ConfigService.h"
 
 using namespace Mantid;
 using namespace Mantid::Kernel;
@@ -215,6 +216,12 @@ void ConvertToDiffractionMDWorkspace::convertEventList(int workspaceIndex,
     //  = input beam direction (normalized to 1) - output beam direction
     //  (normalized to 1)
     V3D Q_dir_lab_frame = beamDir - detDir;
+    double qSign = -1.0;
+    std::string convention =
+        ConfigService::Instance().getString("Q.convention");
+    if (convention == "Crystallography")
+      qSign = 1.0;
+    Q_dir_lab_frame *= qSign;
 
     // Multiply by the rotation matrix to convert to Q in the sample frame (take
     // out goniometer rotation)
diff --git a/Framework/MDAlgorithms/src/LoadMD.cpp b/Framework/MDAlgorithms/src/LoadMD.cpp
index 81158d0064b724131d98aaefcbdff284b8e03bb6..4a30585b717f35867217c4d4096716c62765037d 100644
--- a/Framework/MDAlgorithms/src/LoadMD.cpp
+++ b/Framework/MDAlgorithms/src/LoadMD.cpp
@@ -1,6 +1,7 @@
 #include "MantidAPI/ExperimentInfo.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/IMDEventWorkspace.h"
+#include "MantidAPI/IMDWorkspace.h"
 #include "MantidAPI/RegisterFileLoader.h"
 #include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include "MantidGeometry/MDGeometry/IMDDimensionFactory.h"
@@ -22,6 +23,7 @@
 #include "MantidDataObjects/MDHistoWorkspace.h"
 #include "MantidDataObjects/BoxControllerNeXusIO.h"
 #include "MantidDataObjects/CoordTransformAffine.h"
+#include "MantidKernel/ConfigService.h"
 #include <nexus/NeXusException.hpp>
 #include <boost/algorithm/string.hpp>
 #include <vector>
@@ -186,6 +188,9 @@ void LoadMD::exec() {
   // Coordinate system
   this->loadCoordinateSystem();
 
+  // QConvention (Inelastic or Crystallography)
+  this->loadQConvention();
+
   // Display normalization settting
   if (levelEntries.find(VISUAL_NORMALIZATION_KEY) != levelEntries.end()) {
     this->loadVisualNormalization(VISUAL_NORMALIZATION_KEY,
@@ -226,6 +231,25 @@ void LoadMD::exec() {
     if (m_requiresMDFrameCorrection) {
       setMDFrameOnWorkspaceFromLegacyFile(ws);
     }
+    // Write out the Qconvention
+    // ki-kf for Inelastic convention; kf-ki for Crystallography convention
+    std::string pref_QConvention =
+        Kernel::ConfigService::Instance().getString("Q.convention");
+    g_log.information() << "Convention for Q in Preferences is "
+                        << pref_QConvention
+                        << "; Convention of Q in NeXus file is "
+                        << m_QConvention << std::endl;
+
+    if (pref_QConvention != m_QConvention) {
+      g_log.information() << "Transforming Q" << std::endl;
+      Algorithm_sptr transform_alg = createChildAlgorithm("TransformMD");
+      transform_alg->setProperty("InputWorkspace",
+                                 boost::dynamic_pointer_cast<IMDWorkspace>(ws));
+      transform_alg->setProperty("Scaling", "-1.0");
+      transform_alg->executeAsChildAlg();
+      IMDWorkspace_sptr tmp = transform_alg->getProperty("OutputWorkspace");
+      ws = boost::dynamic_pointer_cast<IMDEventWorkspace>(tmp);
+    }
     // Save to output
     setProperty("OutputWorkspace",
                 boost::dynamic_pointer_cast<IMDWorkspace>(ws));
@@ -314,6 +338,26 @@ void LoadMD::loadHisto() {
     setMDFrameOnWorkspaceFromLegacyFile(ws);
   }
 
+  // Write out the Qconvention
+  // ki-kf for Inelastic convention; kf-ki for Crystallography convention
+  std::string pref_QConvention =
+      Kernel::ConfigService::Instance().getString("Q.convention");
+  g_log.information() << "Convention for Q in Preferences is "
+                      << pref_QConvention
+                      << "; Convention of Q in NeXus file is " << m_QConvention
+                      << std::endl;
+
+  if (pref_QConvention != m_QConvention) {
+    g_log.information() << "Transforming Q" << std::endl;
+    Algorithm_sptr transform_alg = createChildAlgorithm("TransformMD");
+    transform_alg->setProperty("InputWorkspace",
+                               boost::dynamic_pointer_cast<IMDWorkspace>(ws));
+    transform_alg->setProperty("Scaling", "-1.0");
+    transform_alg->executeAsChildAlg();
+    IMDWorkspace_sptr tmp = transform_alg->getProperty("OutputWorkspace");
+    ws = boost::dynamic_pointer_cast<MDHistoWorkspace>(tmp);
+  }
+
   // Save to output
   setProperty("OutputWorkspace", boost::dynamic_pointer_cast<IMDWorkspace>(ws));
 }
@@ -420,6 +464,15 @@ void LoadMD::loadCoordinateSystem() {
   }
 }
 
+/** Load the convention for Q  **/
+void LoadMD::loadQConvention() {
+  try {
+    m_file->readData("QConvention", m_QConvention);
+  } catch (::NeXus::Exception &) {
+    m_QConvention = "Inelastic";
+  }
+}
+
 //----------------------------------------------------------------------------------------------
 /** Do the loading.
 *
diff --git a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp
index efc710413ea131fd80af16c803aac3de848021df..551d0f5bdfac5aeddf6f5b678b145928d835b476 100644
--- a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp
+++ b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp
@@ -8,6 +8,7 @@
 #include "MantidKernel/CompositeValidator.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidKernel/VectorHelper.h"
+#include "MantidKernel/ConfigService.h"
 
 namespace Mantid {
 namespace MDAlgorithms {
@@ -606,8 +607,13 @@ std::vector<Kernel::VMD>
 MDNormDirectSC::calculateIntersections(const double theta, const double phi) {
   V3D qout(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)),
       qin(0., 0., m_ki);
+
   qout = m_rubw * qout;
   qin = m_rubw * qin;
+  if (convention != "Crystallography") {
+    qout *= -1;
+    qin *= -1;
+  }
   double hStart = qin.X() - qout.X() * m_kfmin,
          hEnd = qin.X() - qout.X() * m_kfmax;
   double kStart = qin.Y() - qout.Y() * m_kfmin,
diff --git a/Framework/MDAlgorithms/src/MDNormSCD.cpp b/Framework/MDAlgorithms/src/MDNormSCD.cpp
index 665807725fa4ce720c79046990b032f45b559e0e..60f66f91755027f74d80af51e14ff8ce2f20f822 100644
--- a/Framework/MDAlgorithms/src/MDNormSCD.cpp
+++ b/Framework/MDAlgorithms/src/MDNormSCD.cpp
@@ -642,6 +642,10 @@ std::vector<Kernel::VMD> MDNormSCD::calculateIntersections(const double theta,
                                                            const double phi) {
   V3D q(-sin(theta) * cos(phi), -sin(theta) * sin(phi), 1. - cos(theta));
   q = m_rubw * q;
+  if (convention != "Crystallography") {
+    q *= -1;
+  }
+
   double hStart = q.X() * m_kiMin, hEnd = q.X() * m_kiMax;
   double kStart = q.Y() * m_kiMin, kEnd = q.Y() * m_kiMax;
   double lStart = q.Z() * m_kiMin, lEnd = q.Z() * m_kiMax;
diff --git a/Framework/MDAlgorithms/src/MDTransfQ3D.cpp b/Framework/MDAlgorithms/src/MDTransfQ3D.cpp
index 3a79ff96bc4584f006cd49ae3803944af1e2ac36..507bb342b132e736555c8741d30afe0653d331b7 100644
--- a/Framework/MDAlgorithms/src/MDTransfQ3D.cpp
+++ b/Framework/MDAlgorithms/src/MDTransfQ3D.cpp
@@ -80,6 +80,12 @@ bool MDTransfQ3D::calcMatrixCoord3DInelastic(
   double qy = -m_ey * k_tr;
   double qz = m_Ki - m_ez * k_tr;
 
+  if (convention == "Crystallography") {
+    qx = -qx;
+    qy = -qy;
+    qz = -qz;
+  }
+
   Coord[0] = (coord_t)(m_RotMat[0] * qx + m_RotMat[1] * qy + m_RotMat[2] * qz);
   if (Coord[0] < m_DimMin[0] || Coord[0] >= m_DimMax[0])
     return false;
@@ -120,6 +126,12 @@ bool MDTransfQ3D::calcMatrixCoord3DElastic(const double &k0,
   double qx = -m_ex * k0;
   double qy = -m_ey * k0;
   double qz = (1 - m_ez) * k0;
+  if (convention == "Crystallography") {
+    qx = -qx;
+    qy = -qy;
+    qz = -qz;
+  }
+
   Coord[0] = (coord_t)(m_RotMat[0] * qx + m_RotMat[1] * qy + m_RotMat[2] * qz);
   if (Coord[0] < m_DimMin[0] || Coord[0] >= m_DimMax[0])
     return false;
diff --git a/Framework/MDAlgorithms/src/SaveMD2.cpp b/Framework/MDAlgorithms/src/SaveMD2.cpp
index 3cf980d9286fd7348ae528bf989911cc1216eb30..c521bf1df27f17033fe9cd76436250001f50cf17 100644
--- a/Framework/MDAlgorithms/src/SaveMD2.cpp
+++ b/Framework/MDAlgorithms/src/SaveMD2.cpp
@@ -14,6 +14,7 @@
 #include "MantidDataObjects/MDHistoWorkspace.h"
 #include "MantidDataObjects/MDBoxFlatTree.h"
 #include "MantidDataObjects/BoxControllerNeXusIO.h"
+#include "MantidKernel/ConfigService.h"
 
 // clang-format off
 #if defined(__GLIBCXX__) && __GLIBCXX__ >= 20100121 // libstdc++-4.4.3
@@ -105,6 +106,12 @@ void SaveMD2::doSaveHisto(Mantid::DataObjects::MDHistoWorkspace_sptr ws) {
   file->writeData("coordinate_system",
                   static_cast<uint32_t>(ws->getSpecialCoordinateSystem()));
 
+  // Write out the Qconvention
+  // ki-kf for Inelastic convention; kf-ki for Crystallography convention
+  std::string m_QConvention =
+      Kernel::ConfigService::Instance().getString("Q.convention");
+  file->writeData("QConvention", m_QConvention);
+
   // Write out the visual normalization
   file->writeData("visual_normalization",
                   static_cast<uint32_t>(ws->displayNormalization()));
diff --git a/Framework/MDAlgorithms/src/TransformMD.cpp b/Framework/MDAlgorithms/src/TransformMD.cpp
index cb4f2fed3ff3ca4ade2b2639d73b3b212f29d05d..6588c30bee462dfb38a59db37ae80b912806f1d0 100644
--- a/Framework/MDAlgorithms/src/TransformMD.cpp
+++ b/Framework/MDAlgorithms/src/TransformMD.cpp
@@ -5,6 +5,7 @@
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidDataObjects/MDEventWorkspace.h"
 #include "MantidDataObjects/MDEventFactory.h"
+#include "MantidGeometry/MDGeometry/IMDDimension.h"
 
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
@@ -101,6 +102,7 @@ void TransformMD::exec() {
 
   inWS = getProperty("InputWorkspace");
   outWS = getProperty("OutputWorkspace");
+  std::string outName = getPropertyValue("OutputWorkspace");
 
   if (boost::dynamic_pointer_cast<MatrixWorkspace>(inWS))
     throw std::runtime_error("TransformMD can only transform a "
@@ -147,12 +149,64 @@ void TransformMD::exec() {
   if (histo) {
     // Recalculate all the values since the dimensions changed.
     histo->cacheValues();
+    this->setProperty("OutputWorkspace", histo);
   } else if (event) {
     // Call the method for this type of MDEventWorkspace.
     CALL_MDEVENT_FUNCTION(this->doTransform, outWS);
+    Progress *prog2 = NULL;
+    ThreadScheduler *ts = new ThreadSchedulerFIFO();
+    ThreadPool tp(ts, 0, prog2);
+    event->splitAllIfNeeded(ts);
+    // prog2->resetNumSteps( ts->size(), 0.4, 0.6);
+    tp.joinAll();
+    event->refreshCache();
+    // Set the special coordinate system.
+    IMDEventWorkspace_sptr inEvent =
+        boost::dynamic_pointer_cast<IMDEventWorkspace>(inWS);
+    event->setCoordinateSystem(inEvent->getSpecialCoordinateSystem());
+
+    if (m_scaling[0] < 0) {
+      // Only need these 2 algorithms for transforming with negative number
+      std::vector<double> extents;
+      std::vector<std::string> names, units;
+      for (size_t d = 0; d < nd; d++) {
+        Geometry::IMDDimension_const_sptr dim = event->getDimension(d);
+        // Find the extents
+        extents.push_back(dim->getMinimum());
+        extents.push_back(dim->getMaximum());
+        names.push_back(std::string(dim->getName()));
+        units.push_back(dim->getUnits());
+      }
+      Algorithm_sptr create_alg = createChildAlgorithm("CreateMDWorkspace");
+      create_alg->setProperty("Dimensions", static_cast<int>(nd));
+      create_alg->setProperty("EventType", event->getEventTypeName());
+      create_alg->setProperty("Extents", extents);
+      create_alg->setProperty("Names", names);
+      create_alg->setProperty("Units", units);
+      create_alg->setPropertyValue("OutputWorkspace", "__none");
+      create_alg->executeAsChildAlg();
+      Workspace_sptr none = create_alg->getProperty("OutputWorkspace");
+
+      AnalysisDataService::Instance().addOrReplace(outName, event);
+      AnalysisDataService::Instance().addOrReplace("__none", none);
+      Mantid::API::BoxController_sptr boxController = event->getBoxController();
+      std::vector<int> splits;
+      for (size_t d = 0; d < nd; d++) {
+        splits.push_back(static_cast<int>(boxController->getSplitInto(d)));
+      }
+      Algorithm_sptr merge_alg = createChildAlgorithm("MergeMD");
+      merge_alg->setPropertyValue("InputWorkspaces", outName + ",__none");
+      merge_alg->setProperty("SplitInto", splits);
+      merge_alg->setProperty(
+          "SplitThreshold",
+          static_cast<int>(boxController->getSplitThreshold()));
+      merge_alg->setProperty("MaxRecursionDepth", 13);
+      merge_alg->executeAsChildAlg();
+      event = merge_alg->getProperty("OutputWorkspace");
+      AnalysisDataService::Instance().remove("__none");
+    }
+    this->setProperty("OutputWorkspace", event);
   }
-
-  this->setProperty("OutputWorkspace", outWS);
 }
 
 } // namespace Mantid
diff --git a/Framework/Properties/Mantid.properties.template b/Framework/Properties/Mantid.properties.template
index 8b00a1f10274348bc64560905e6bc82d9b034e85..5ec631d5008b300ca3550642a690e6ee167f9631 100644
--- a/Framework/Properties/Mantid.properties.template
+++ b/Framework/Properties/Mantid.properties.template
@@ -15,6 +15,10 @@ default.facility = ISIS
 # Set a default instrument
 default.instrument =
 
+# This flag controls the convention for converting to Q.  Default is ki-kf
+# Change to Crystallography for kf-ki
+Q.convention = Inelastic
+
 # Set of PyQt interfaces to add to the Interfaces menu, separated by a space.  Interfaces are seperated from their respective categories by a "/".
 mantidqt.python_interfaces = Direct/DGS_Reduction.py Direct/DGSPlanner.py SANS/ORNL_SANS.py Reflectometry/REFL_Reduction.py Reflectometry/REFL_SF_Calculator.py Reflectometry/REFM_Reduction.py Utility/TofConverter.py Reflectometry/ISIS_Reflectometry.py Diffraction/Powder_Diffraction_Reduction.py Utility/FilterEvents.py Diffraction/HFIR_Powder_Diffraction_Reduction.py Diffraction/HFIR_4Circle_Reduction.py
 
diff --git a/MantidPlot/src/ConfigDialog.cpp b/MantidPlot/src/ConfigDialog.cpp
index 87e74e4ea83cab6eb72537345019aeadb92dc4f3..7d2b76c1949f031beb7210661341118f58ee4bc1 100644
--- a/MantidPlot/src/ConfigDialog.cpp
+++ b/MantidPlot/src/ConfigDialog.cpp
@@ -690,6 +690,14 @@ void ConfigDialog::initMantidPage()
   ckIgnoreParaView->setChecked(ignoreParaView);
   grid->addWidget(ckIgnoreParaView, 3, 0);
 
+  //Change to Crystallography Convention
+  ckQconvention = new QCheckBox("Crystallography Convention");
+  ckQconvention->setToolTip("Change from default ki-kf to kf-ki.");
+  const std::string QconventionProperty = "Q.convention";
+  bool Qconvention =  cfgSvc.hasProperty(QconventionProperty) && bool(cfgSvc.getString(QconventionProperty) == "Crystallography");
+  ckQconvention->setChecked(Qconvention);
+  grid->addWidget(ckQconvention, 4, 0);
+
   // Populate boxes
   auto faclist =  cfgSvc.getFacilityNames();
   for ( auto it = faclist.begin(); it != faclist.end(); ++it )
@@ -2464,6 +2472,10 @@ void ConfigDialog::apply()
    cfgSvc.setString("default.facility", facility->currentText().toStdString());
    cfgSvc.setString("default.instrument", defInstr->currentText().toStdString());
    cfgSvc.setString("paraview.ignore", QString::number(ckIgnoreParaView->isChecked()).toStdString());
+   if (ckQconvention->isChecked())
+     cfgSvc.setString("Q.convention", "Crystallography");
+   else
+     cfgSvc.setString("Q.convention", "Inelastic");
 
 
   updateDirSearchSettings();
diff --git a/MantidPlot/src/ConfigDialog.h b/MantidPlot/src/ConfigDialog.h
index 64f80367c2e9aa5119081d709160ca78fdd0591a..d8122326fc17d458599aac7eb33e9a718270f0d7 100644
--- a/MantidPlot/src/ConfigDialog.h
+++ b/MantidPlot/src/ConfigDialog.h
@@ -188,6 +188,7 @@ private:
   QComboBox *facility;
   MantidQt::MantidWidgets::InstrumentSelector  *defInstr;
   QCheckBox* ckIgnoreParaView;
+  QCheckBox* ckQconvention;
 
   /// Mantid tab for setting directories
   QWidget *directoriesPage;
diff --git a/MantidQt/SliceViewer/src/SliceViewer.cpp b/MantidQt/SliceViewer/src/SliceViewer.cpp
index 4c5a8db6be421861df08e00b16de7e7ca216df41..028a7a0d39227147646fd0526a133079a20d9527 100644
--- a/MantidQt/SliceViewer/src/SliceViewer.cpp
+++ b/MantidQt/SliceViewer/src/SliceViewer.cpp
@@ -701,6 +701,12 @@ void SliceViewer::setWorkspace(Mantid::API::IMDWorkspace_sptr ws) {
     // MDEWs)
     coord_t min = m_ws->getDimension(d)->getMinimum();
     coord_t max = m_ws->getDimension(d)->getMaximum();
+    if (max < min)
+    {
+      coord_t tmp = max;
+      max = min;
+      min = tmp;
+    }
     if (boost::math::isnan(min) || boost::math::isinf(min) ||
         boost::math::isnan(max) || boost::math::isinf(max)) {
       mess << "Dimension " << m_ws->getDimension(d)->getName()
diff --git a/docs/source/concepts/PropertiesFile.rst b/docs/source/concepts/PropertiesFile.rst
index 41e0caf18671dffc0579bcdf180063be2adc5803..8961e803ae109b2aa3506adb16210620eae0d7f4 100644
--- a/docs/source/concepts/PropertiesFile.rst
+++ b/docs/source/concepts/PropertiesFile.rst
@@ -43,19 +43,23 @@ General properties
 Facility and instrument properties
 **********************************
 
-+------------------------------+---------------------------------------------------+-------------+
-|Property                      |Description                                        |Example value|
-+==============================+===================================================+=============+
-|default.facility              |The name of the default facility. The facility must| ISIS        |
-|                              |be defined within the facilites.xml file to be     |             |
-|                              |considered valid. The file is described here.      |             |
-|                              |:ref:`here <Facilities file>`.                     |             |
-+------------------------------+---------------------------------------------------+-------------+
-|default.instrument            |The name of the default instrument. The instrument | WISH        |
-|                              |must be defined within the facilities.xml file to  |             |
-|                              |be valid. The file is described                    |             |
-|                              |:ref:`here <Facilities file>`.                     |             |
-+------------------------------+---------------------------------------------------+-------------+
++------------------------------+---------------------------------------------------+-----------------+
+|Property                      |Description                                        |Example value    |
++==============================+===================================================+=================+
+|default.facility              |The name of the default facility. The facility must| ISIS            |
+|                              |be defined within the facilites.xml file to be     |                 |
+|                              |considered valid. The file is described here.      |                 |
+|                              |:ref:`here <Facilities file>`.                     |                 |
++------------------------------+---------------------------------------------------+-----------------+
+|default.instrument            |The name of the default instrument. The instrument | WISH            |
+|                              |must be defined within the facilities.xml file to  |                 |
+|                              |be valid. The file is described                    |                 |
+|                              |:ref:`here <Facilities file>`.                     |                 |
++------------------------------+---------------------------------------------------+-----------------+
+|Q.convention                  |The convention for converting to Q. For inelastic  | Crystallography |
+|                              |the convention is ki-kf.  For Crystallography the  |                 |
+|                              |convention is kf-ki.                               |                 |
++------------------------------+---------------------------------------------------+-----------------+
 
 Directory Properties
 ********************
diff --git a/tools/DefaultConfigFiles/Mantid.user.properties b/tools/DefaultConfigFiles/Mantid.user.properties
index 41c121da74ccbbf296af05679a6b0a17a285f97b..3bebfafb771c9a58963dac9b46c4503aa5313ade 100644
--- a/tools/DefaultConfigFiles/Mantid.user.properties
+++ b/tools/DefaultConfigFiles/Mantid.user.properties
@@ -31,6 +31,10 @@ default.facility=
 ## e.g. IRIS, HET, NIMROD
 default.instrument=
 
+# This flag controls the convention for converting to Q.  Default is ki-kf
+# Change to Crystallography for kf-ki
+Q.convention = Inelastic
+
 ##
 ## DIRECTORIES
 ##