diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FindPeaksMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FindPeaksMD.h
index f152fb820814381fa219ee40cd7cb4942b241e9c..64dc5bb72c26030d3c3a0a0bb1536cf1990daeb4 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FindPeaksMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FindPeaksMD.h
@@ -9,7 +9,9 @@
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/ExperimentInfo.h"
 #include "MantidAPI/IMDEventWorkspace_fwd.h"
+#include "MantidAPI/IPeaksWorkspace.h"
 #include "MantidAPI/Progress.h"
+#include "MantidDataObjects/LeanElasticPeaksWorkspace.h"
 #include "MantidDataObjects/MDEventWorkspace.h"
 #include "MantidDataObjects/MDHistoWorkspace.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
@@ -58,18 +60,29 @@ private:
   void exec() override;
 
   /// Read member variables from experiment info
-  void readExperimentInfo(const Mantid::API::ExperimentInfo_sptr &ei,
-                          const Mantid::API::IMDWorkspace_sptr &ws);
+  void readExperimentInfo(const Mantid::API::ExperimentInfo_sptr &ei);
+  void checkWorkspaceDims(const Mantid::API::IMDWorkspace_sptr &ws);
+  void determineOutputType(const std::string peakType,
+                           const uint16_t numExperimentInfo);
 
   /// Adds a peak based on Q, bin count & a set of detector IDs
   void addPeak(const Mantid::Kernel::V3D &Q, const double binCount,
                const Geometry::InstrumentRayTracer &tracer);
 
+  /// Adds a peak based on Q, bin count
+  void addLeanElasticPeak(const Mantid::Kernel::V3D &Q, const double binCount,
+                          const bool useGoniometer = false);
+
   /// Adds a peak based on Q, bin count
   std::shared_ptr<DataObjects::Peak>
   createPeak(const Mantid::Kernel::V3D &Q, const double binCount,
              const Geometry::InstrumentRayTracer &tracer);
 
+  /// Adds a peak based on Q, bin count
+  std::shared_ptr<DataObjects::LeanElasticPeak>
+  createLeanElasticPeak(const Mantid::Kernel::V3D &Q, const double binCount,
+                        const bool useGoniometer = false);
+
   /// Run find peaks on an MDEventWorkspace
   template <typename MDE, size_t nd>
   void findPeaks(typename DataObjects::MDEventWorkspace<MDE, nd>::sptr ws);
@@ -77,7 +90,7 @@ private:
   void findPeaksHisto(const Mantid::DataObjects::MDHistoWorkspace_sptr &ws);
 
   /// Output PeaksWorkspace
-  Mantid::DataObjects::PeaksWorkspace_sptr peakWS;
+  Mantid::API::IPeaksWorkspace_sptr peakWS;
 
   /// Estimated radius of peaks. Boxes closer than this are rejected
   coord_t peakRadiusSquared;
@@ -121,6 +134,8 @@ private:
   static const std::string volumeNormalization;
   /// NumberOfEventNormalization
   static const std::string numberOfEventsNormalization;
+
+  bool m_leanElasticPeak = false;
 };
 
 } // namespace MDAlgorithms
diff --git a/Framework/MDAlgorithms/src/FindPeaksMD.cpp b/Framework/MDAlgorithms/src/FindPeaksMD.cpp
index 22f5f9ac99dafd87b7b2bdab07c75939e8384014..3b4418be39eb815de36ba48dd95955350a53ceb1 100644
--- a/Framework/MDAlgorithms/src/FindPeaksMD.cpp
+++ b/Framework/MDAlgorithms/src/FindPeaksMD.cpp
@@ -8,7 +8,6 @@
 #include "MantidAPI/Run.h"
 #include "MantidDataObjects/MDEventFactory.h"
 #include "MantidDataObjects/MDHistoWorkspace.h"
-#include "MantidDataObjects/PeaksWorkspace.h"
 #include "MantidGeometry/Crystal/EdgePixel.h"
 #include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidGeometry/Objects/InstrumentRayTracer.h"
@@ -227,8 +226,11 @@ void FindPeaksMD::init() {
                       std::make_unique<EnabledWhenProperty>(
                           "CalculateGoniometerForCW",
                           Mantid::Kernel::ePropertyCriterion::IS_NOT_DEFAULT));
-
-  declareProperty(std::make_unique<WorkspaceProperty<PeaksWorkspace>>(
+  std::vector<std::string> peakTypes = {"Automatic", "Peak", "LeanElasticPeak"};
+  declareProperty("OutputType", "Automatic",
+                  std::make_shared<StringListValidator>(peakTypes),
+                  "Type of Peak in OutputWorkspace");
+  declareProperty(std::make_unique<WorkspaceProperty<IPeaksWorkspace>>(
                       "OutputWorkspace", "", Direction::Output),
                   "An output PeaksWorkspace with the peaks' found positions.");
 
@@ -245,13 +247,25 @@ void FindPeaksMD::init() {
 
 //----------------------------------------------------------------------------------------------
 /** Extract needed data from the workspace's experiment info */
-void FindPeaksMD::readExperimentInfo(const ExperimentInfo_sptr &ei,
-                                     const IMDWorkspace_sptr &ws) {
+void FindPeaksMD::readExperimentInfo(const ExperimentInfo_sptr &ei) {
   // Instrument associated with workspace
   inst = ei->getInstrument();
   // Find the run number
   m_runNumber = ei->getRunNumber();
 
+  // Find the goniometer rotation matrix
+  m_goniometer =
+      Mantid::Kernel::Matrix<double>(3, 3, true); // Default IDENTITY matrix
+  try {
+    m_goniometer = ei->mutableRun().getGoniometerMatrix();
+  } catch (std::exception &e) {
+    g_log.warning() << "Error finding goniometer matrix. It will not be set in "
+                       "the peaks found.\n";
+    g_log.warning() << e.what() << '\n';
+  }
+}
+
+void FindPeaksMD::checkWorkspaceDims(const IMDWorkspace_sptr &ws) {
   // Check that the workspace dimensions are in Q-sample-frame or Q-lab-frame.
   std::string dim0 = ws->getDimension(0)->getName();
   if (dim0 == "H") {
@@ -265,16 +279,22 @@ void FindPeaksMD::readExperimentInfo(const ExperimentInfo_sptr &ei,
   else
     throw std::runtime_error(
         "Unexpected dimensions: need either Q_lab_x or Q_sample_x.");
+}
 
-  // Find the goniometer rotation matrix
-  m_goniometer =
-      Mantid::Kernel::Matrix<double>(3, 3, true); // Default IDENTITY matrix
-  try {
-    m_goniometer = ei->mutableRun().getGoniometerMatrix();
-  } catch (std::exception &e) {
-    g_log.warning() << "Error finding goniometer matrix. It will not be set in "
-                       "the peaks found.\n";
-    g_log.warning() << e.what() << '\n';
+void FindPeaksMD::determineOutputType(const std::string peakType,
+                                      const uint16_t numExperimentInfo) {
+  // This method will be expanded later to check a property on the
+  // input workspace which can specify a default peak type for that
+  // instrument.
+  m_leanElasticPeak = false;
+  if (peakType == "Automatic") {
+    if (numExperimentInfo == 0)
+      m_leanElasticPeak = true;
+  } else if (peakType == "LeanElasticPeak") {
+    m_leanElasticPeak = true;
+  } else { // Peak
+    if (numExperimentInfo == 0)
+      throw std::runtime_error("Cannot create Peak output with 0 expInfo");
   }
 }
 
@@ -301,6 +321,20 @@ void FindPeaksMD::addPeak(const V3D &Q, const double binCount,
   }
 }
 
+//----------------------------------------------------------------------------------------------
+/** Create and add a LeanElasticPeak to the output workspace
+ *
+ * @param Q :: Q_lab or Q_sample, depending on workspace
+ * @param binCount :: bin count to give to the peak.
+ * @param useGoniometer :: if to include set goniometer from the input workspace
+ * in the peak
+ */
+void FindPeaksMD::addLeanElasticPeak(const V3D &Q, const double binCount,
+                                     const bool useGoniometer) {
+  auto p = this->createLeanElasticPeak(Q, binCount, useGoniometer);
+  peakWS->addPeak(*p);
+}
+
 /**
  * Creates a Peak object from Q & bin count
  * */
@@ -324,9 +358,9 @@ FindPeaksMD::createPeak(const Mantid::Kernel::V3D &Q, const double binCount,
         if (inst->hasParameter("wavelength")) {
           wavelength = inst->getNumberParameter("wavelength").at(0);
         } else {
-          throw std::runtime_error(
-              "Could not get wavelength, neither Wavelength algorithm property "
-              "set nor instrument wavelength parameter");
+          throw std::runtime_error("Could not get wavelength, neither "
+                                   "Wavelength algorithm property "
+                                   "set nor instrument wavelength parameter");
         }
       }
 
@@ -359,9 +393,32 @@ FindPeaksMD::createPeak(const Mantid::Kernel::V3D &Q, const double binCount,
   return p;
 }
 
+/**
+ * Creates a Peak object from Q & bin count
+ * */
+std::shared_ptr<DataObjects::LeanElasticPeak>
+FindPeaksMD::createLeanElasticPeak(const Mantid::Kernel::V3D &Q,
+                                   const double binCount,
+                                   const bool useGoniometer) {
+  std::shared_ptr<DataObjects::LeanElasticPeak> p;
+  if (dimType == QSAMPLE) {
+    if (useGoniometer)
+      p = std::make_shared<LeanElasticPeak>(Q, m_goniometer);
+    else
+      p = std::make_shared<LeanElasticPeak>(Q);
+  } else {
+    throw std::invalid_argument(
+        "Cannot find peaks unless the dimension is QSAMPLE");
+  }
+
+  p->setBinCount(binCount);
+  // Save the run number found before.
+  p->setRunNumber(m_runNumber);
+  return p;
+}
 //----------------------------------------------------------------------------------------------
-/** Integrate the peaks of the workspace using parameters saved in the algorithm
- * class
+/** Integrate the peaks of the workspace using parameters saved in the
+ * algorithm class
  * @param ws ::  MDEventWorkspace to integrate
  */
 template <typename MDE, size_t nd>
@@ -384,168 +441,127 @@ void FindPeaksMD::findPeaks(typename MDEventWorkspace<MDE, nd>::sptr ws) {
   // Make sure all centroids are fresh
   // ws->getBox()->refreshCentroid();
 
-  uint16_t nexp = ws->getNumExperimentInfo();
-
-  if (nexp == 0)
-    throw std::runtime_error(
-        "No instrument was found in the MDEventWorkspace. Cannot find peaks.");
-
-  for (uint16_t iexp = 0; iexp < ws->getNumExperimentInfo(); iexp++) {
-    ExperimentInfo_sptr ei = ws->getExperimentInfo(iexp);
-    this->readExperimentInfo(ei, std::dynamic_pointer_cast<IMDWorkspace>(ws));
-
-    Geometry::InstrumentRayTracer tracer(inst);
-    // Copy the instrument, sample, run to the peaks workspace.
-    peakWS->copyExperimentInfoFrom(ei.get());
-
-    // Calculate a threshold below which a box is too diffuse to be considered a
-    // peak.
-    signal_t threshold =
-        m_useNumberOfEventsNormalization
-            ? ws->getBox()->getSignalByNEvents() * m_signalThresholdFactor
-            : ws->getBox()->getSignalNormalized() * DensityThresholdFactor;
-    threshold *= m_densityScaleFactor;
-
-    if (!std::isfinite(threshold)) {
-      g_log.warning()
-          << "Infinite or NaN overall density found. Your input data "
-             "may be invalid. Using a 0 threshold instead.\n";
-      threshold = 0;
-    }
-    g_log.information() << "Threshold signal density: " << threshold << '\n';
-
-    using boxPtr = API::IMDNode *;
-    // We will fill this vector with pointers to all the boxes (up to a given
-    // depth)
-    typename std::vector<API::IMDNode *> boxes;
-
-    // Get all the MDboxes
-    progress(0.10, "Getting Boxes");
-    ws->getBox()->getBoxes(boxes, 1000, true);
-
-    // This pair is the <density, ptr to the box>
-    using dens_box = std::pair<double, API::IMDNode *>;
-
-    // Map that will sort the boxes by increasing density. The key = density;
-    // value = box *.
-    typename std::multimap<double, API::IMDNode *> sortedBoxes;
-
-    // --------------- Sort and Filter by Density -----------------------------
-    progress(0.20, "Sorting Boxes by Density");
-    auto it1 = boxes.begin();
-    auto it1_end = boxes.end();
-    for (; it1 != it1_end; it1++) {
-      auto box = *it1;
-      double value = m_useNumberOfEventsNormalization
-                         ? box->getSignalByNEvents()
-                         : box->getSignalNormalized();
-      value *= m_densityScaleFactor;
-      // Skip any boxes with too small a signal value.
-      if (value > threshold)
-        sortedBoxes.insert(dens_box(value, box));
-    }
+  // Calculate a threshold below which a box is too diffuse to be considered a
+  // peak.
+  signal_t threshold =
+      m_useNumberOfEventsNormalization
+          ? ws->getBox()->getSignalByNEvents() * m_signalThresholdFactor
+          : ws->getBox()->getSignalNormalized() * DensityThresholdFactor;
+  threshold *= m_densityScaleFactor;
+
+  if (!std::isfinite(threshold)) {
+    g_log.warning() << "Infinite or NaN overall density found. Your input data "
+                       "may be invalid. Using a 0 threshold instead.\n";
+    threshold = 0;
+  }
+  g_log.information() << "Threshold signal density: " << threshold << '\n';
+
+  using boxPtr = API::IMDNode *;
+  // We will fill this vector with pointers to all the boxes (up to a given
+  // depth)
+  typename std::vector<API::IMDNode *> boxes;
+
+  // Get all the MDboxes
+  progress(0.10, "Getting Boxes");
+  ws->getBox()->getBoxes(boxes, 1000, true);
+
+  // This pair is the <density, ptr to the box>
+  using dens_box = std::pair<double, API::IMDNode *>;
+
+  // Map that will sort the boxes by increasing density. The key = density;
+  // value = box *.
+  typename std::multimap<double, API::IMDNode *> sortedBoxes;
+
+  // --------------- Sort and Filter by Density -----------------------------
+  progress(0.20, "Sorting Boxes by Density");
+  auto it1 = boxes.begin();
+  auto it1_end = boxes.end();
+  for (; it1 != it1_end; it1++) {
+    auto box = *it1;
+    double value = m_useNumberOfEventsNormalization
+                       ? box->getSignalByNEvents()
+                       : box->getSignalNormalized();
+    value *= m_densityScaleFactor;
+    // Skip any boxes with too small a signal value.
+    if (value > threshold)
+      sortedBoxes.insert(dens_box(value, box));
+  }
 
-    // --------------- Find Peak Boxes -----------------------------
-    // List of chosen possible peak boxes.
-    std::vector<API::IMDNode *> peakBoxes;
+  // --------------- Find Peak Boxes -----------------------------
+  // List of chosen possible peak boxes.
+  std::vector<API::IMDNode *> peakBoxes;
 
-    prog = std::make_unique<Progress>(this, 0.30, 0.95, m_maxPeaks);
+  prog = std::make_unique<Progress>(this, 0.30, 0.95, m_maxPeaks);
 
-    // used for selecting method for calculating BinCount
-    bool isMDEvent(ws->id().find("MDEventWorkspace") != std::string::npos);
+  // used for selecting method for calculating BinCount
+  bool isMDEvent(ws->id().find("MDEventWorkspace") != std::string::npos);
 
-    int64_t numBoxesFound = 0;
-    // Now we go (backwards) through the map
-    // e.g. from highest density down to lowest density.
-    typename std::multimap<double, boxPtr>::reverse_iterator it2;
-    auto it2_end = sortedBoxes.rend();
-    for (it2 = sortedBoxes.rbegin(); it2 != it2_end; ++it2) {
-      signal_t density = it2->first;
-      boxPtr box = it2->second;
+  int64_t numBoxesFound = 0;
+  // Now we go (backwards) through the map
+  // e.g. from highest density down to lowest density.
+  typename std::multimap<double, boxPtr>::reverse_iterator it2;
+  auto it2_end = sortedBoxes.rend();
+  for (it2 = sortedBoxes.rbegin(); it2 != it2_end; ++it2) {
+    signal_t density = it2->first;
+    boxPtr box = it2->second;
 #ifndef MDBOX_TRACK_CENTROID
-      coord_t boxCenter[nd];
-      box->calculateCentroid(boxCenter);
+    coord_t boxCenter[nd];
+    box->calculateCentroid(boxCenter);
 #else
-      const coord_t *boxCenter = box->getCentroid();
+    const coord_t *boxCenter = box->getCentroid();
 #endif
 
-      // Compare to all boxes already picked.
-      bool badBox = false;
-      for (auto &peakBoxe : peakBoxes) {
+    // Compare to all boxes already picked.
+    bool badBox = false;
+    for (auto &peakBoxe : peakBoxes) {
 
 #ifndef MDBOX_TRACK_CENTROID
-        coord_t otherCenter[nd];
-        (*it3)->calculateCentroid(otherCenter);
+      coord_t otherCenter[nd];
+      (*it3)->calculateCentroid(otherCenter);
 #else
-        const coord_t *otherCenter = peakBoxe->getCentroid();
+      const coord_t *otherCenter = peakBoxe->getCentroid();
 #endif
 
-        // Distance between this box and a box we already put in.
-        coord_t distSquared = 0.0;
-        for (size_t d = 0; d < nd; d++) {
-          coord_t dist = otherCenter[d] - boxCenter[d];
-          distSquared += (dist * dist);
-        }
-
-        // Reject this box if it is too close to another previously found box.
-        if (distSquared < peakRadiusSquared) {
-          badBox = true;
-          break;
-        }
+      // Distance between this box and a box we already put in.
+      coord_t distSquared = 0.0;
+      for (size_t d = 0; d < nd; d++) {
+        coord_t dist = otherCenter[d] - boxCenter[d];
+        distSquared += (dist * dist);
       }
 
-      // The box was not rejected for another reason.
-      if (!badBox) {
-        if (numBoxesFound++ >= m_maxPeaks) {
-          g_log.notice() << "Number of peaks found exceeded the limit of "
-                         << m_maxPeaks << ". Stopping peak finding.\n";
-          break;
-        }
+      // Reject this box if it is too close to another previously found box.
+      if (distSquared < peakRadiusSquared) {
+        badBox = true;
+        break;
+      }
+    }
 
-        peakBoxes.emplace_back(box);
-        g_log.debug() << "Found box at ";
-        for (size_t d = 0; d < nd; d++)
-          g_log.debug() << (d > 0 ? "," : "") << boxCenter[d];
-        g_log.debug() << "; Density = " << density << '\n';
-        // Report progres for each box found.
-        prog->report("Finding Peaks");
+    // The box was not rejected for another reason.
+    if (!badBox) {
+      if (numBoxesFound++ >= m_maxPeaks) {
+        g_log.notice() << "Number of peaks found exceeded the limit of "
+                       << m_maxPeaks << ". Stopping peak finding.\n";
+        break;
       }
+
+      peakBoxes.emplace_back(box);
+      g_log.debug() << "Found box at ";
+      for (size_t d = 0; d < nd; d++)
+        g_log.debug() << (d > 0 ? "," : "") << boxCenter[d];
+      g_log.debug() << "; Density = " << density << '\n';
+      // Report progres for each box found.
+      prog->report("Finding Peaks");
     }
+  }
 
-    prog->resetNumSteps(numBoxesFound, 0.95, 1.0);
+  prog->resetNumSteps(numBoxesFound, 0.95, 1.0);
 
+  uint16_t numExperimentInfo = ws->getNumExperimentInfo();
+
+  if (numExperimentInfo == 0) {
     // --- Convert the "boxes" to peaks ----
     for (auto box : peakBoxes) {
-      //  If no events from this experimental contribute to the box then skip
-      if (nexp > 1) {
-        auto *mdbox = dynamic_cast<MDBox<MDE, nd> *>(box);
-        const std::vector<MDE> &events = mdbox->getEvents();
-        if (std::none_of(events.cbegin(), events.cend(),
-                         [&iexp, &nexp](MDE event) {
-                           return event.getRunIndex() == iexp ||
-                                  event.getRunIndex() >= nexp;
-                         }))
-          continue;
-      }
-
-      // If multiple goniometers than use the average one from the
-      // events in the box, that matches this runIndex, this assumes
-      // the events are added in same order as the goniometers
-      if (ei->run().getNumGoniometers() > 1) {
-        const std::vector<MDE> &events =
-            dynamic_cast<MDBox<MDE, nd> *>(box)->getEvents();
-        double sum = 0;
-        double count = 0;
-        for (const auto &event : events) {
-          if (event.getRunIndex() == iexp) {
-            sum += event.getGoniometerIndex();
-            count++;
-          }
-        }
-        m_goniometer = ei->mutableRun().getGoniometerMatrix(lrint(sum / count));
-      }
       // The center of the box = Q in the lab frame
-
 #ifndef MDBOX_TRACK_CENTROID
       coord_t boxCenter[nd];
       box->calculateCentroid(boxCenter);
@@ -556,42 +572,111 @@ void FindPeaksMD::findPeaks(typename MDEventWorkspace<MDE, nd>::sptr ws) {
       // Q of the centroid of the box
       V3D Q(boxCenter[0], boxCenter[1], boxCenter[2]);
 
-      // The "bin count" used will be the box density or the number of events in
-      // the box
+      // The "bin count" used will be the box density.
       double binCount = box->getSignalNormalized() * m_densityScaleFactor;
       if (isMDEvent)
         binCount = static_cast<double>(box->getNPoints());
 
-      try {
-        auto p = this->createPeak(Q, binCount, tracer);
-        if (m_addDetectors) {
-          auto mdBox = dynamic_cast<MDBoxBase<MDE, nd> *>(box);
-          if (!mdBox) {
-            throw std::runtime_error("Failed to cast box to MDBoxBase");
+      // Create the peak
+      addLeanElasticPeak(Q, binCount);
+
+      // Report progres for each box found.
+      prog->report("Adding Peaks");
+
+    } // for each box found
+  } else {
+    for (uint16_t iexp = 0; iexp < ws->getNumExperimentInfo(); iexp++) {
+      ExperimentInfo_sptr ei = ws->getExperimentInfo(iexp);
+      this->readExperimentInfo(ei);
+
+      Geometry::InstrumentRayTracer tracer(inst);
+      // Copy the instrument, sample, run to the peaks workspace.
+      peakWS->copyExperimentInfoFrom(ei.get());
+
+      // --- Convert the "boxes" to peaks ----
+      for (auto box : peakBoxes) {
+        //  If no events from this experimental contribute to the box then skip
+        if (numExperimentInfo > 1) {
+          auto *mdbox = dynamic_cast<MDBox<MDE, nd> *>(box);
+          const std::vector<MDE> &events = mdbox->getEvents();
+          if (std::none_of(events.cbegin(), events.cend(),
+                           [&iexp, &numExperimentInfo](MDE event) {
+                             return event.getRunIndex() == iexp ||
+                                    event.getRunIndex() >= numExperimentInfo;
+                           }))
+            continue;
+        }
+
+        // If multiple goniometers than use the average one from the
+        // events in the box, that matches this runIndex, this assumes
+        // the events are added in same order as the goniometers
+        if (ei->run().getNumGoniometers() > 1) {
+          const std::vector<MDE> &events =
+              dynamic_cast<MDBox<MDE, nd> *>(box)->getEvents();
+          double sum = 0;
+          double count = 0;
+          for (const auto &event : events) {
+            if (event.getRunIndex() == iexp) {
+              sum += event.getGoniometerIndex();
+              count++;
+            }
           }
-          addDetectors(*p, *mdBox);
+          m_goniometer =
+              ei->mutableRun().getGoniometerMatrix(lrint(sum / count));
         }
-        if (p->getDetectorID() != -1) {
-          if (m_edge > 0) {
-            if (!edgePixel(inst, p->getBankName(), p->getCol(), p->getRow(),
-                           m_edge))
-              peakWS->addPeak(*p);
-            ;
-          } else {
-            peakWS->addPeak(*p);
+        // The center of the box = Q in the lab frame
+
+#ifndef MDBOX_TRACK_CENTROID
+        coord_t boxCenter[nd];
+        box->calculateCentroid(boxCenter);
+#else
+        const coord_t *boxCenter = box->getCentroid();
+#endif
+
+        // Q of the centroid of the box
+        V3D Q(boxCenter[0], boxCenter[1], boxCenter[2]);
+
+        // The "bin count" used will be the box density or the number of events
+        // in the box
+        double binCount = box->getSignalNormalized() * m_densityScaleFactor;
+        if (isMDEvent)
+          binCount = static_cast<double>(box->getNPoints());
+
+        if (m_leanElasticPeak) {
+          addLeanElasticPeak(Q, binCount, true);
+        } else {
+          try {
+            auto p = this->createPeak(Q, binCount, tracer);
+            if (m_addDetectors) {
+              auto mdBox = dynamic_cast<MDBoxBase<MDE, nd> *>(box);
+              if (!mdBox) {
+                throw std::runtime_error("Failed to cast box to MDBoxBase");
+              }
+              addDetectors(*p, *mdBox);
+            }
+            if (p->getDetectorID() != -1) {
+              if (m_edge > 0) {
+                if (!edgePixel(inst, p->getBankName(), p->getCol(), p->getRow(),
+                               m_edge))
+                  peakWS->addPeak(*p);
+                ;
+              } else {
+                peakWS->addPeak(*p);
+              }
+              g_log.information() << "Add new peak with Q-center = " << Q[0]
+                                  << ", " << Q[1] << ", " << Q[2] << "\n";
+            }
+          } catch (std::exception &e) {
+            g_log.notice() << "Error creating peak at " << Q << " because of '"
+                           << e.what() << "'. Peak will be skipped.\n";
           }
-          g_log.information() << "Add new peak with Q-center = " << Q[0] << ", "
-                              << Q[1] << ", " << Q[2] << "\n";
         }
-      } catch (std::exception &e) {
-        g_log.notice() << "Error creating peak at " << Q << " because of '"
-                       << e.what() << "'. Peak will be skipped.\n";
-      }
 
-      // Report progress for each box found.
-      prog->report("Adding Peaks");
+        // Report progress for each box found.
+        prog->report("Adding Peaks");
 
-    } // for each box found
+      } // for each box found
+    }
   }
   g_log.notice() << "Number of peaks found: " << peakWS->getNumberPeaks()
                  << '\n';
@@ -611,105 +696,94 @@ void FindPeaksMD::findPeaksHisto(
   g_log.warning("Workspace is an MDHistoWorkspace. Resultant PeaksWorkspaces "
                 "will not contain full detector information.");
 
-  if (ws->getNumExperimentInfo() == 0)
-    throw std::runtime_error(
-        "No instrument was found in the workspace. Cannot find peaks.");
-
-  for (uint16_t iexp = 0; iexp < ws->getNumExperimentInfo(); iexp++) {
-    ExperimentInfo_sptr ei = ws->getExperimentInfo(iexp);
-    this->readExperimentInfo(ei, std::dynamic_pointer_cast<IMDWorkspace>(ws));
-    Geometry::InstrumentRayTracer tracer(inst);
-
-    // Copy the instrument, sample, run to the peaks workspace.
-    peakWS->copyExperimentInfoFrom(ei.get());
-
-    // This pair is the <density, box index>
-    using dens_box = std::pair<double, size_t>;
-
-    // Map that will sort the boxes by increasing density. The key = density;
-    // value = box index.
-    std::multimap<double, size_t> sortedBoxes;
-
-    size_t numBoxes = ws->getNPoints();
-
-    // --------- Count the overall signal density -----------------------------
-    progress(0.10, "Counting Total Signal");
-    double totalSignal = 0;
-    for (size_t i = 0; i < numBoxes; i++)
-      totalSignal += ws->getSignalAt(i);
-    // Calculate the threshold density
-    double thresholdDensity =
-        (totalSignal * ws->getInverseVolume() / double(numBoxes)) *
-        DensityThresholdFactor * m_densityScaleFactor;
-    if (!std::isfinite(thresholdDensity)) {
-      g_log.warning()
-          << "Infinite or NaN overall density found. Your input data "
-             "may be invalid. Using a 0 threshold instead.\n";
-      thresholdDensity = 0;
-    }
-    g_log.information() << "Threshold signal density: " << thresholdDensity
-                        << '\n';
-
-    // -------------- Sort and Filter by Density -----------------------------
-    progress(0.20, "Sorting Boxes by Density");
-    for (size_t i = 0; i < numBoxes; i++) {
-      double density = ws->getSignalNormalizedAt(i) * m_densityScaleFactor;
-      // Skip any boxes with too small a signal density.
-      if (density > thresholdDensity)
-        sortedBoxes.insert(dens_box(density, i));
-    }
-
-    // --------------- Find Peak Boxes -----------------------------
-    // List of chosen possible peak boxes.
-    std::vector<size_t> peakBoxes;
-
-    prog = std::make_unique<Progress>(this, 0.30, 0.95, m_maxPeaks);
-
-    int64_t numBoxesFound = 0;
-    // Now we go (backwards) through the map
-    // e.g. from highest density down to lowest density.
-    std::multimap<double, size_t>::reverse_iterator it2;
-    auto it2_end = sortedBoxes.rend();
-    for (it2 = sortedBoxes.rbegin(); it2 != it2_end; ++it2) {
-      signal_t density = it2->first;
-      size_t index = it2->second;
-      // Get the center of the box
-      VMD boxCenter = ws->getCenter(index);
-
-      // Compare to all boxes already picked.
-      bool badBox = false;
-      for (auto &peakBoxe : peakBoxes) {
-        VMD otherCenter = ws->getCenter(peakBoxe);
-
-        // Distance between this box and a box we already put in.
-        coord_t distSquared = 0.0;
-        for (size_t d = 0; d < nd; d++) {
-          coord_t dist = otherCenter[d] - boxCenter[d];
-          distSquared += (dist * dist);
-        }
+  // This pair is the <density, box index>
+  using dens_box = std::pair<double, size_t>;
+
+  // Map that will sort the boxes by increasing density. The key = density;
+  // value = box index.
+  std::multimap<double, size_t> sortedBoxes;
+
+  size_t numBoxes = ws->getNPoints();
+
+  // --------- Count the overall signal density -----------------------------
+  progress(0.10, "Counting Total Signal");
+  double totalSignal = 0;
+  for (size_t i = 0; i < numBoxes; i++)
+    totalSignal += ws->getSignalAt(i);
+  // Calculate the threshold density
+  double thresholdDensity =
+      (totalSignal * ws->getInverseVolume() / double(numBoxes)) *
+      DensityThresholdFactor * m_densityScaleFactor;
+  if (!std::isfinite(thresholdDensity)) {
+    g_log.warning() << "Infinite or NaN overall density found. Your input data "
+                       "may be invalid. Using a 0 threshold instead.\n";
+    thresholdDensity = 0;
+  }
+  g_log.information() << "Threshold signal density: " << thresholdDensity
+                      << '\n';
+
+  // -------------- Sort and Filter by Density -----------------------------
+  progress(0.20, "Sorting Boxes by Density");
+  for (size_t i = 0; i < numBoxes; i++) {
+    double density = ws->getSignalNormalizedAt(i) * m_densityScaleFactor;
+    // Skip any boxes with too small a signal density.
+    if (density > thresholdDensity)
+      sortedBoxes.insert(dens_box(density, i));
+  }
 
-        // Reject this box if it is too close to another previously found box.
-        if (distSquared < peakRadiusSquared) {
-          badBox = true;
-          break;
-        }
+  // --------------- Find Peak Boxes -----------------------------
+  // List of chosen possible peak boxes.
+  std::vector<size_t> peakBoxes;
+
+  prog = std::make_unique<Progress>(this, 0.30, 0.95, m_maxPeaks);
+
+  int64_t numBoxesFound = 0;
+  // Now we go (backwards) through the map
+  // e.g. from highest density down to lowest density.
+  std::multimap<double, size_t>::reverse_iterator it2;
+  auto it2_end = sortedBoxes.rend();
+  for (it2 = sortedBoxes.rbegin(); it2 != it2_end; ++it2) {
+    signal_t density = it2->first;
+    size_t index = it2->second;
+    // Get the center of the box
+    VMD boxCenter = ws->getCenter(index);
+
+    // Compare to all boxes already picked.
+    bool badBox = false;
+    for (auto &peakBoxe : peakBoxes) {
+      VMD otherCenter = ws->getCenter(peakBoxe);
+
+      // Distance between this box and a box we already put in.
+      coord_t distSquared = 0.0;
+      for (size_t d = 0; d < nd; d++) {
+        coord_t dist = otherCenter[d] - boxCenter[d];
+        distSquared += (dist * dist);
       }
 
-      // The box was not rejected for another reason.
-      if (!badBox) {
-        if (numBoxesFound++ >= m_maxPeaks) {
-          g_log.notice() << "Number of peaks found exceeded the limit of "
-                         << m_maxPeaks << ". Stopping peak finding.\n";
-          break;
-        }
+      // Reject this box if it is too close to another previously found box.
+      if (distSquared < peakRadiusSquared) {
+        badBox = true;
+        break;
+      }
+    }
 
-        peakBoxes.emplace_back(index);
-        g_log.debug() << "Found box at index " << index;
-        g_log.debug() << "; Density = " << density << '\n';
-        // Report progres for each box found.
-        prog->report("Finding Peaks");
+    // The box was not rejected for another reason.
+    if (!badBox) {
+      if (numBoxesFound++ >= m_maxPeaks) {
+        g_log.notice() << "Number of peaks found exceeded the limit of "
+                       << m_maxPeaks << ". Stopping peak finding.\n";
+        break;
       }
+
+      peakBoxes.emplace_back(index);
+      g_log.debug() << "Found box at index " << index;
+      g_log.debug() << "; Density = " << density << '\n';
+      // Report progres for each box found.
+      prog->report("Finding Peaks");
     }
+  }
+
+  if (ws->getNumExperimentInfo() == 0) {
     // --- Convert the "boxes" to peaks ----
     for (auto index : peakBoxes) {
       // The center of the box = Q in the lab frame
@@ -722,36 +796,84 @@ void FindPeaksMD::findPeaksHisto(
       double binCount = ws->getSignalNormalizedAt(index) * m_densityScaleFactor;
 
       // Create the peak
-      addPeak(Q, binCount, tracer);
+      addLeanElasticPeak(Q, binCount);
 
       // Report progres for each box found.
       prog->report("Adding Peaks");
 
     } // for each box found
+  } else {
+    for (uint16_t iexp = 0; iexp < ws->getNumExperimentInfo(); iexp++) {
+      ExperimentInfo_sptr ei = ws->getExperimentInfo(iexp);
+      this->readExperimentInfo(ei);
+      Geometry::InstrumentRayTracer tracer(inst);
+
+      // Copy the instrument, sample, run to the peaks workspace.
+      peakWS->copyExperimentInfoFrom(ei.get());
+
+      // --- Convert the "boxes" to peaks ----
+      for (auto index : peakBoxes) {
+        // The center of the box = Q in the lab frame
+        VMD boxCenter = ws->getCenter(index);
+
+        // Q of the centroid of the box
+        V3D Q(boxCenter[0], boxCenter[1], boxCenter[2]);
+
+        // The "bin count" used will be the box density.
+        double binCount =
+            ws->getSignalNormalizedAt(index) * m_densityScaleFactor;
+
+        // Create the peak
+        if (m_leanElasticPeak)
+          addLeanElasticPeak(Q, binCount, true);
+        else
+          addPeak(Q, binCount, tracer);
+
+        // Report progres for each box found.
+        prog->report("Adding Peaks");
+
+      } // for each box found
+    }
   }
   g_log.notice() << "Number of peaks found: " << peakWS->getNumberPeaks()
                  << '\n';
-}
+} // namespace MDAlgorithms
 
 //----------------------------------------------------------------------------------------------
 /** Execute the algorithm.
  */
 void FindPeaksMD::exec() {
 
-  bool AppendPeaks = getProperty("AppendPeaks");
-
-  // Output peaks workspace, create if needed
-  peakWS = getProperty("OutputWorkspace");
-  if (!peakWS || !AppendPeaks)
-    peakWS = PeaksWorkspace_sptr(new PeaksWorkspace());
-
   // The MDEventWorkspace as input
   IMDWorkspace_sptr inWS = getProperty("InputWorkspace");
+  checkWorkspaceDims(inWS);
   MDHistoWorkspace_sptr inMDHW =
       std::dynamic_pointer_cast<MDHistoWorkspace>(inWS);
   IMDEventWorkspace_sptr inMDEW =
       std::dynamic_pointer_cast<IMDEventWorkspace>(inWS);
 
+  bool AppendPeaks = getProperty("AppendPeaks");
+
+  uint16_t numExperimentInfo = 0;
+  if (inMDHW)
+    numExperimentInfo = inMDHW->getNumExperimentInfo();
+  else if (inMDEW)
+    numExperimentInfo = inMDEW->getNumExperimentInfo();
+
+  std::string peakType = getProperty("OutputType");
+
+  determineOutputType(peakType, numExperimentInfo);
+
+  // Output peaks workspace, create if needed
+  peakWS = getProperty("OutputWorkspace");
+
+  if (!peakWS || !AppendPeaks) {
+    if (m_leanElasticPeak)
+      peakWS = LeanElasticPeaksWorkspace_sptr(new LeanElasticPeaksWorkspace());
+    else
+      peakWS = PeaksWorkspace_sptr(new PeaksWorkspace());
+  }
+
   // Other parameters
   double PeakDistanceThreshold = getProperty("PeakDistanceThreshold");
   peakRadiusSquared =
@@ -785,7 +907,7 @@ void FindPeaksMD::exec() {
   peakWS->sort(criteria);
 
   for (auto i = 0; i != peakWS->getNumberPeaks(); ++i) {
-    Peak &p = peakWS->getPeak(i);
+    Mantid::Geometry::IPeak &p = peakWS->getPeak(i);
     p.setPeakNumber(i + 1);
   }
   // Save the output
@@ -805,6 +927,8 @@ std::map<std::string, std::string> FindPeaksMD::validateInputs() {
   IMDWorkspace_sptr inWS = getProperty("InputWorkspace");
   IMDEventWorkspace_sptr inMDEW =
       std::dynamic_pointer_cast<IMDEventWorkspace>(inWS);
+  MDHistoWorkspace_sptr inMDHW =
+      std::dynamic_pointer_cast<MDHistoWorkspace>(inWS);
 
   if (useNumberOfEventsNormalization && !inMDEW) {
     result["PeakFindingStrategy"] = "The NumberOfEventsNormalization selection "
@@ -812,6 +936,19 @@ std::map<std::string, std::string> FindPeaksMD::validateInputs() {
                                     "as the input.";
   }
 
+  uint16_t numExperimentInfo = 0;
+  if (inMDHW)
+    numExperimentInfo = inMDHW->getNumExperimentInfo();
+  else if (inMDEW)
+    numExperimentInfo = inMDEW->getNumExperimentInfo();
+
+  std::string peakType = getProperty("OutputType");
+
+  if (peakType == "Peak" && numExperimentInfo == 0)
+    result["OutputType"] =
+        "The InputWorkspace doesn't contain any experiment information so the "
+        "OutputType cannot be Peak.";
+
   return result;
 }
 
diff --git a/Framework/MDAlgorithms/test/FindPeaksMDTest.h b/Framework/MDAlgorithms/test/FindPeaksMDTest.h
index 0ba29c344a1658d51272cab7e7d592002e0d4870..a92363972e578950db03b74ce4f56ea4c7586e18 100644
--- a/Framework/MDAlgorithms/test/FindPeaksMDTest.h
+++ b/Framework/MDAlgorithms/test/FindPeaksMDTest.h
@@ -7,6 +7,7 @@
 #pragma once
 
 #include "MantidAPI/FrameworkManager.h"
+#include "MantidDataObjects/LeanElasticPeaksWorkspace.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
 #include "MantidKernel/PropertyWithValue.h"
 #include "MantidMDAlgorithms/FindPeaksMD.h"
@@ -29,7 +30,7 @@ static void createMDEW() {
       "CreateMDWorkspace", 18, "Dimensions", "3", "EventType", "MDEvent",
       "Extents", "-10,10,-10,10,-10,10", "Names", "Q_lab_x,Q_lab_y,Q_lab_z",
       "Units", "-,-,-", "SplitInto", "5", "SplitThreshold", "20",
-      "MaxRecursionDepth", "15", "OutputWorkspace", "MDEWS");
+      "MaxRecursionDepth", "15", "OutputWorkspace", "MDWS");
 
   // Give it an instrument
   Instrument_sptr inst =
@@ -37,7 +38,7 @@ static void createMDEW() {
   IMDEventWorkspace_sptr ws;
   TS_ASSERT_THROWS_NOTHING(
       ws = AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>(
-          "MDEWS"));
+          "MDWS"));
   ExperimentInfo_sptr ei(new ExperimentInfo());
   ei->setInstrument(inst);
   // Give it a run number
@@ -52,14 +53,14 @@ static void addPeak(size_t num, double x, double y, double z, double radius) {
   std::ostringstream mess;
   mess << num / 2 << ", " << x << ", " << y << ", " << z << ", " << radius;
   FrameworkManager::Instance().exec("FakeMDEventData", 4, "InputWorkspace",
-                                    "MDEWS", "PeakParams", mess.str().c_str());
+                                    "MDWS", "PeakParams", mess.str().c_str());
 
   // Add a center with more events (half radius, half the total), to create a
   // "peak"
   std::ostringstream mess2;
   mess2 << num / 2 << ", " << x << ", " << y << ", " << z << ", " << radius / 2;
   FrameworkManager::Instance().exec("FakeMDEventData", 4, "InputWorkspace",
-                                    "MDEWS", "PeakParams", mess2.str().c_str());
+                                    "MDWS", "PeakParams", mess2.str().c_str());
 }
 
 //=====================================================================================
@@ -91,14 +92,14 @@ public:
       FrameworkManager::Instance().exec(
           "BinMD", 14, "AxisAligned", "1", "AlignedDim0", "Q_lab_x,-10,10,100",
           "AlignedDim1", "Q_lab_y,-10,10,100", "AlignedDim2",
-          "Q_lab_z,-10,10,100", "IterateEvents", "1", "InputWorkspace", "MDEWS",
-          "OutputWorkspace", "MDEWS");
+          "Q_lab_z,-10,10,100", "IterateEvents", "1", "InputWorkspace", "MDWS",
+          "OutputWorkspace", "MDWS");
     }
 
     FindPeaksMD alg;
     TS_ASSERT_THROWS_NOTHING(alg.initialize())
     TS_ASSERT(alg.isInitialized())
-    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("InputWorkspace", "MDEWS"));
+    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("InputWorkspace", "MDWS"));
     TS_ASSERT_THROWS_NOTHING(
         alg.setPropertyValue("OutputWorkspace", outWSName));
     TS_ASSERT_THROWS_NOTHING(
@@ -160,7 +161,7 @@ public:
       // Remove workspace from the data service.
       AnalysisDataService::Instance().remove(outWSName);
     }
-    AnalysisDataService::Instance().remove("MDEWS");
+    AnalysisDataService::Instance().remove("MDWS");
   }
 
   /** Running the algo twice with same output workspace = replace the output,
@@ -225,14 +226,14 @@ public:
     FrameworkManager::Instance().exec(
         "BinMD", 14, "AxisAligned", "1", "AlignedDim0", "Q_lab_x,-10,10,100",
         "AlignedDim1", "Q_lab_y,-10,10,100", "AlignedDim2",
-        "Q_lab_z,-10,10,100", "IterateEvents", "1", "InputWorkspace", "MDEWS",
-        "OutputWorkspace", "MDEWS");
+        "Q_lab_z,-10,10,100", "IterateEvents", "1", "InputWorkspace", "MDWS",
+        "OutputWorkspace", "MDWS");
 
     FindPeaksMD alg;
     alg.setRethrows(true);
     TS_ASSERT_THROWS_NOTHING(alg.initialize());
     TS_ASSERT(alg.isInitialized());
-    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("InputWorkspace", "MDEWS"));
+    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("InputWorkspace", "MDWS"));
     TS_ASSERT_THROWS_NOTHING(
         alg.setPropertyValue("OutputWorkspace", "place_holder"));
     TS_ASSERT_THROWS_NOTHING(
@@ -245,7 +246,113 @@ public:
     TS_ASSERT_THROWS_NOTHING(alg.setProperty("SignalThresholdFactor", 1.3));
     TS_ASSERT_THROWS(alg.execute(), const std::runtime_error &);
 
-    AnalysisDataService::Instance().remove("MDEWS");
+    AnalysisDataService::Instance().remove("MDWS");
+  }
+
+  void do_test_LeanElastic(bool expInfo, bool histo) {
+    FrameworkManager::Instance().exec(
+        "CreateMDWorkspace", 18, "Dimensions", "3", "EventType", "MDEvent",
+        "Extents", "-10,10,-10,10,-10,10", "Names",
+        "Q_sample_x,Q_sample_y,Q_sample_z", "Units", "-,-,-", "SplitInto", "5",
+        "SplitThreshold", "20", "MaxRecursionDepth", "15", "OutputWorkspace",
+        "MDWS");
+
+    if (expInfo) {
+      Instrument_sptr inst =
+          ComponentCreationHelper::createTestInstrumentRectangular2(1, 100,
+                                                                    0.05);
+      IMDEventWorkspace_sptr ws;
+      TS_ASSERT_THROWS_NOTHING(
+          ws = AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>(
+              "MDWS"));
+      ExperimentInfo_sptr ei(new ExperimentInfo());
+      ei->setInstrument(inst);
+      // Give it a run number
+      ei->mutableRun().addProperty(
+          new PropertyWithValue<std::string>("run_number", "12345"), true);
+      ws->addExperimentInfo(ei);
+    }
+
+    addPeak(1000, 1, 2, 3, 0.1);
+    addPeak(3000, 4, 5, 6, 0.2);
+    addPeak(5000, -5, -5, 5, 0.2);
+
+    if (histo) {
+      FrameworkManager::Instance().exec(
+          "BinMD", 14, "AxisAligned", "1", "AlignedDim0",
+          "Q_sample_x,-10,10,100", "AlignedDim1", "Q_sample_y,-10,10,100",
+          "AlignedDim2", "Q_sample_z,-10,10,100", "IterateEvents", "1",
+          "InputWorkspace", "MDWS", "OutputWorkspace", "MDWS");
+    }
+
+    std::string outWSName("peaksFound");
+    FindPeaksMD alg;
+    TS_ASSERT_THROWS_NOTHING(alg.initialize())
+    TS_ASSERT(alg.isInitialized())
+    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("InputWorkspace", "MDWS"));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("OutputWorkspace", outWSName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("DensityThresholdFactor", "2.0"));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("PeakDistanceThreshold", "0.7"));
+
+    if (expInfo)
+      TS_ASSERT_THROWS_NOTHING(
+          alg.setPropertyValue("OutputType", "LeanElasticPeak"));
+
+    TS_ASSERT_THROWS_NOTHING(alg.execute(););
+    TS_ASSERT(alg.isExecuted());
+
+    // Retrieve the workspace from data service.
+    LeanElasticPeaksWorkspace_sptr ws;
+    TS_ASSERT_THROWS_NOTHING(
+        ws = AnalysisDataService::Instance()
+                 .retrieveWS<LeanElasticPeaksWorkspace>(outWSName));
+    TS_ASSERT(ws);
+    if (!ws)
+      return;
+
+    // Should find all 3 peaks.
+    TS_ASSERT_EQUALS(ws->getNumberPeaks(), 3);
+
+    TS_ASSERT_DELTA(ws->getPeak(0).getQSampleFrame()[0], -5.0, 0.11);
+    TS_ASSERT_DELTA(ws->getPeak(0).getQSampleFrame()[1], -5.0, 0.11);
+    TS_ASSERT_DELTA(ws->getPeak(0).getQSampleFrame()[2], 5.0, 0.11);
+    if (expInfo) {
+      TS_ASSERT_EQUALS(ws->getPeak(0).getRunNumber(), 12345);
+    } else {
+      TS_ASSERT_EQUALS(ws->getPeak(0).getRunNumber(), -1);
+    }
+    // Bin count = density of the box / 1e6
+    double BinCount = ws->getPeak(0).getBinCount();
+    if (histo) {
+      TS_ASSERT_DELTA(BinCount, 0.08375, 0.001);
+    } else {
+      TS_ASSERT_DELTA(BinCount, 7., 001000.);
+    }
+
+    TS_ASSERT_DELTA(ws->getPeak(1).getQSampleFrame()[0], 4.0, 0.11);
+    TS_ASSERT_DELTA(ws->getPeak(1).getQSampleFrame()[1], 5.0, 0.11);
+    TS_ASSERT_DELTA(ws->getPeak(1).getQSampleFrame()[2], 6.0, 0.11);
+
+    TS_ASSERT_DELTA(ws->getPeak(2).getQSampleFrame()[0], 1.0, 0.11);
+    TS_ASSERT_DELTA(ws->getPeak(2).getQSampleFrame()[1], 2.0, 0.11);
+    TS_ASSERT_DELTA(ws->getPeak(2).getQSampleFrame()[2], 3.0, 0.11);
+
+    AnalysisDataService::Instance().remove("MDWS");
+  }
+
+  void test_exec_LeanElastic() { do_test_LeanElastic(false, false); }
+
+  void test_exec_LeanElastic_histo() { do_test_LeanElastic(false, true); }
+
+  void test_exec_LeanElastic_with_expInfo() {
+    do_test_LeanElastic(true, false);
+  }
+
+  void test_exec_LeanElastic_histo_with_expInfo() {
+    do_test_LeanElastic(true, true);
   }
 };
 
@@ -286,7 +393,7 @@ public:
     FindPeaksMD alg;
     alg.initialize();
 
-    alg.setPropertyValue("InputWorkspace", "MDEWS");
+    alg.setPropertyValue("InputWorkspace", "MDWS");
     alg.setPropertyValue("OutputWorkspace", outWSName);
     alg.setPropertyValue("DensityThresholdFactor", "2.0");
     alg.setPropertyValue("PeakDistanceThreshold", "0.7");
diff --git a/Testing/SystemTests/tests/framework/ConvertHFIRSCDtoMDETest.py b/Testing/SystemTests/tests/framework/ConvertHFIRSCDtoMDETest.py
index d1bc1ab2b9c77983da9a83d474b89b5b8deb7628..3c2bc4deba30f6c3b7547839ecf01c955f508697 100644
--- a/Testing/SystemTests/tests/framework/ConvertHFIRSCDtoMDETest.py
+++ b/Testing/SystemTests/tests/framework/ConvertHFIRSCDtoMDETest.py
@@ -45,6 +45,18 @@ class ConvertHFIRSCDtoMDETest(systemtesting.MantidSystemTest):
                                        atol=0.005,
                                        err_msg=f"mismatch for peak {p}")
 
+        # now try using LeanElasticPeak
+        ConvertHFIRSCDtoMDETest_peaks3 = FindPeaksMD(InputWorkspace=ConvertHFIRSCDtoMDETest_Q, PeakDistanceThreshold=2.2,
+                                                     OutputType='LeanElasticPeak')
+
+        self.assertEqual(ConvertHFIRSCDtoMDETest_peaks3.getNumberPeaks(), 14)
+
+        for p in range(14):
+            np.testing.assert_allclose(ConvertHFIRSCDtoMDETest_peaks3.getPeak(p).getQSampleFrame(),
+                                       ConvertHFIRSCDtoMDETest_peaks.getPeak(p).getQSampleFrame(),
+                                       atol=0.005,
+                                       err_msg=f"mismatch for peak {p}")
+
 
 class ConvertHFIRSCDtoMDE_HB3A_Test(systemtesting.MantidSystemTest):
     def requiredMemoryMB(self):
diff --git a/Testing/SystemTests/tests/framework/TOPAZPeakFinding.py b/Testing/SystemTests/tests/framework/TOPAZPeakFinding.py
index 55e6b9354bfd4e1a8921c25df0337e7b5486a8bc..104f80fc754bbae89dee2880ed5317b016ee7bd9 100644
--- a/Testing/SystemTests/tests/framework/TOPAZPeakFinding.py
+++ b/Testing/SystemTests/tests/framework/TOPAZPeakFinding.py
@@ -13,6 +13,7 @@ them.
 import systemtesting
 import numpy
 from mantid.simpleapi import *
+from mantid.dataobjects import PeaksWorkspace, LeanElasticPeaksWorkspace
 
 
 class TOPAZPeakFinding(systemtesting.MantidSystemTest):
@@ -72,6 +73,42 @@ class TOPAZPeakFinding(systemtesting.MantidSystemTest):
         ConvertToDiffractionMDWorkspace(InputWorkspace='topaz_3132',OutputWorkspace='topaz_3132_QSample',
                                         OutputDimensions='Q (sample frame)',LorentzCorrection='1',SplitInto='2',SplitThreshold='150')
         FindPeaksMD(InputWorkspace='topaz_3132_QSample',PeakDistanceThreshold='0.12',MaxPeaks='200',OutputWorkspace='peaks_QSample')
+        self.assertTrue(isinstance(mtd['peaks_QSample'], PeaksWorkspace))
+        FindUBUsingFFT(PeaksWorkspace='peaks_QSample',MinD='2',MaxD='16')
+        CopySample(InputWorkspace='peaks_QSample',OutputWorkspace='topaz_3132',CopyName='0',CopyMaterial='0',
+                   CopyEnvironment='0',CopyShape='0')
+
+        # Index the peaks and check
+        results = IndexPeaks(PeaksWorkspace='peaks_QSample')
+        indexed = results[0]
+        if indexed < 199:
+            raise Exception("Expected at least 199 of 200 peaks to be indexed. Only indexed %d!" % indexed)
+
+        # Check the UB matrix
+        w = mtd["topaz_3132"]
+        s = w.sample()
+        ol = s.getOrientedLattice()
+        self.assertDelta( ol.a(), 4.714, 0.01, "Correct lattice a value not found.")
+        self.assertDelta( ol.b(), 6.06, 0.01, "Correct lattice b value not found.")
+        self.assertDelta( ol.c(), 10.42, 0.01, "Correct lattice c value not found.")
+        self.assertDelta( ol.alpha(), 90, 0.4, "Correct lattice angle alpha value not found.")
+        self.assertDelta( ol.beta(), 90, 0.4, "Correct lattice angle beta value not found.")
+        self.assertDelta( ol.gamma(), 90, 0.4, "Correct lattice angle gamma value not found.")
+
+        # Compare new and old UBs
+        newUB = numpy.array(mtd["topaz_3132"].sample().getOrientedLattice().getUB())
+        # UB Matrices are not necessarily the same, some of the H,K and/or L sign can be reversed
+        diff = abs(newUB) - abs(originalUB) < 0.001
+        for c in range(3):
+            # This compares each column, allowing old == new OR old == -new
+            if not numpy.all(diff[:,c]) :
+                raise Exception("More than 0.001 difference between UB matrices: Q (lab frame):\n"
+                                "%s\nQ (sample frame):\n%s" % (originalUB, newUB) )
+
+        # repeat but use LeanElasticPeaks
+        FindPeaksMD(InputWorkspace='topaz_3132_QSample',PeakDistanceThreshold='0.12',MaxPeaks='200',OutputWorkspace='peaks_QSample',
+                    OutputType='LeanElasticPeak')
+        self.assertTrue(isinstance(mtd['peaks_QSample'], LeanElasticPeaksWorkspace))
         FindUBUsingFFT(PeaksWorkspace='peaks_QSample',MinD='2',MaxD='16')
         CopySample(InputWorkspace='peaks_QSample',OutputWorkspace='topaz_3132',CopyName='0',CopyMaterial='0',
                    CopyEnvironment='0',CopyShape='0')
diff --git a/docs/source/algorithms/FindPeaksMD-v1.rst b/docs/source/algorithms/FindPeaksMD-v1.rst
index 2834f2473e5c9df77d6c1fff7f854033d75be3a9..b1a132ae9e850c60566e00977a718db95f9c0a75 100644
--- a/docs/source/algorithms/FindPeaksMD-v1.rst
+++ b/docs/source/algorithms/FindPeaksMD-v1.rst
@@ -33,9 +33,13 @@ The algorithm proceeds in this way:
 
 -  This is repeated until we find up to MaxPeaks peaks.
 
-Each peak created is placed in the output
-:ref:`PeaksWorkspace <PeaksWorkspace>`, which can be a new workspace or
-replace the old one.
+Each peak created is placed in the output :ref:`PeaksWorkspace
+<PeaksWorkspace>` or :ref:`LeanElasticPeaksWorkspace
+<LeanElasticPeaksWorkspace>` (depending on the `OutputType` option),
+which can be a new workspace or replace the old one. If `OutputType`
+is the default `Automatic` then the output type will be PeakWorkspace
+unless the input workspace doesn't contain an experiment info in which
+case it will default to LeanElasticPeaksWorkspace.
 
 This algorithm works on a :ref:`MDHistoWorkspace <MDHistoWorkspace>`
 resulting from the :ref:`algm-BinMD` algorithm also. It works in the
diff --git a/docs/source/concepts/LeanElasticPeaksWorkspace.rst b/docs/source/concepts/LeanElasticPeaksWorkspace.rst
index 70a8894e138236d949e92b8152354eb5f3948e86..ca6861724acb369a7736fd8020ed521621d8d3eb 100644
--- a/docs/source/concepts/LeanElasticPeaksWorkspace.rst
+++ b/docs/source/concepts/LeanElasticPeaksWorkspace.rst
@@ -10,6 +10,7 @@ of single crystal LeanElasticPeak objects. It is the equivalent to the
 Creating a LeanElasticPeaksWorkspace
 ------------------------------------
 
+* :ref:`FindPeaksMD <algm-FindPeaksMD>` will find peaks in reciprocal space in a :ref:`MDWorkspace <MDWorkspace>`.
 * :ref:`CreatePeaksWorkspace <algm-CreatePeaksWorkspace>` will create an empty LeanElasticPeaksWorkspace that you can then edit.
 
 Viewing a LeanElasticPeaksWorkspace
diff --git a/docs/source/release/v6.1.0/diffraction.rst b/docs/source/release/v6.1.0/diffraction.rst
index 3d8a6cdd9545ded42227054b8e0461a3893978eb..b2c5ad09d7754c069a717142a59b40e04a15e862 100644
--- a/docs/source/release/v6.1.0/diffraction.rst
+++ b/docs/source/release/v6.1.0/diffraction.rst
@@ -99,7 +99,8 @@ this peak is a Q-sample vector. There are a number of modifications
 made to facilitate this.
 
 - New LeanElasticPeak and LeanElasticPeakWorkspace has been created :ref:`LeanElasticPeaksWorkspace <LeanElasticPeaksWorkspace>`
-- :ref:`CreatePeaksWorkspace <algm-CreatePeaksWorkspace>` has been modified to optionally create a  :ref:`LeanElasticPeaksWorkspace <LeanElasticPeaksWorkspace>`.
+- :ref:`CreatePeaksWorkspace <algm-CreatePeaksWorkspace>` has been modified to optionally create a :ref:`LeanElasticPeaksWorkspace <LeanElasticPeaksWorkspace>`.
+- :ref:`FindPeaksMD <algm-FindPeaksMD>` has been modified to optionally create a :ref:`LeanElasticPeaksWorkspace <LeanElasticPeaksWorkspace>`.
 - These following other algorithms have either been made to work or confirmed to already work with the LeanElasticPeak:
 
    - :ref:`algm-AddPeakHKL`
@@ -113,6 +114,8 @@ made to facilitate this.
    - :ref:`algm-FindUBUsingMinMaxD`
    - :ref:`algm-IndexPeaks`
    - :ref:`algm-IntegratePeaksMD`
+   - :ref:`algm-LoadNexusProcessed`
+   - :ref:`algm-SaveNexusProcessed`
    - :ref:`algm-SelectCellOfType`
    - :ref:`algm-SelectCellWithForm`
    - :ref:`algm-ShowPossibleCells`