From edbe3b68e9bdebe0067c439b62d766d37f8294ff Mon Sep 17 00:00:00 2001
From: Anton Piccardo-Selg <anton.piccardo-selg@tessella.com>
Date: Tue, 8 Mar 2016 12:35:06 +0000
Subject: [PATCH] Refs #15482 Implement correct behaviour for spectra list

---
 .../MantidDataHandling/DataBlockComposite.h   |  152 +-
 .../DataHandling/src/DataBlockComposite.cpp   |  665 ++++---
 Framework/DataHandling/src/LoadISISNexus2.cpp |   21 +-
 .../test/DataBlockCompositeTest.h             | 1660 ++++++++++-------
 .../DataHandling/test/LoadISISNexusTest.h     |    8 +
 5 files changed, 1456 insertions(+), 1050 deletions(-)

diff --git a/Framework/DataHandling/inc/MantidDataHandling/DataBlockComposite.h b/Framework/DataHandling/inc/MantidDataHandling/DataBlockComposite.h
index 0d91d4e222a..76cde9bb0cd 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/DataBlockComposite.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/DataBlockComposite.h
@@ -4,8 +4,10 @@
 #include "MantidDataHandling/DataBlock.h"
 #include "MantidDataHandling/DllConfig.h"
 
-namespace Mantid {
-namespace DataHandling {
+namespace Mantid
+{
+namespace DataHandling
+{
 
 /** DataBlockComposite: The DataBlockComposite handles a collection
     of DataBlocks. It represents a set of contiguous spectrum numbers
@@ -33,81 +35,133 @@ File change history is stored at:
 <https://github.com/mantidproject/mantid>
 Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
-class DLLExport DataBlockComposite : public DataBlock {
+class DLLExport DataBlockComposite : public DataBlock
+{
 public:
-  int64_t getMinSpectrumID() const override;
-  void setMinSpectrumID(int64_t) override;
+    int64_t getMinSpectrumID() const override;
+    void setMinSpectrumID(int64_t) override;
 
-  int64_t getMaxSpectrumID() const override;
-  void setMaxSpectrumID(int64_t) override;
+    int64_t getMaxSpectrumID() const override;
+    void setMaxSpectrumID(int64_t) override;
 
-  size_t getNumberOfSpectra() const override;
-  size_t getNumberOfChannels() const override;
-  int getNumberOfPeriods() const override;
+    size_t getNumberOfSpectra() const override;
+    size_t getNumberOfChannels() const override;
+    int getNumberOfPeriods() const override;
 
-  std::unique_ptr<DataBlockGenerator> getGenerator() const override;
+    std::unique_ptr<DataBlockGenerator> getGenerator() const override;
 
-  bool operator==(const DataBlockComposite &other) const;
+    bool operator==(const DataBlockComposite &other) const;
 
-  // DataBlockComposite only mehtods
-  void addDataBlock(DataBlock dataBlock);
-  std::vector<DataBlock> getDataBlocks();
-  DataBlockComposite operator+(const DataBlockComposite &other);
-  void removeSpectra(DataBlockComposite &toRemove);
-  void truncate(int64_t specMin, int64_t specMax);
+    // DataBlockComposite only mehtods
+    void addDataBlock(DataBlock dataBlock);
+    std::vector<DataBlock> getDataBlocks();
+    DataBlockComposite operator+(const DataBlockComposite &other);
+    void removeSpectra(DataBlockComposite &toRemove);
+    void truncate(int64_t specMin, int64_t specMax);
+    std::vector<int64_t> getAllSpectrumNumbers();
 
 private:
-  std::vector<DataBlock> m_dataBlocks;
+    std::vector<DataBlock> m_dataBlocks;
 };
 
+namespace
+{
+void handleWhenElementIsMonitor(
+    Mantid::DataHandling::DataBlockComposite &dataBlockComposite,
+    int numberOfPeriods, size_t numberOfChannels, int64_t previousValue,
+    int64_t startValue)
+{
+    if (previousValue - startValue > 0) {
+        auto numberOfSpectra
+            = previousValue
+              - startValue; /* Should be from [start, previousValue -1]*/
+        DataBlock dataBlock(numberOfPeriods, numberOfSpectra, numberOfChannels);
+        dataBlock.setMinSpectrumID(startValue);
+        dataBlock.setMaxSpectrumID(previousValue - 1);
+        dataBlockComposite.addDataBlock(dataBlock);
+    }
+
+    // Save out the monitor
+    DataBlock dataBlock(numberOfPeriods, 1, numberOfChannels);
+    dataBlock.setMinSpectrumID(previousValue);
+    dataBlock.setMaxSpectrumID(previousValue);
+    dataBlockComposite.addDataBlock(dataBlock);
+}
+
+
+void handleWhenElementMadeAJump(
+    Mantid::DataHandling::DataBlockComposite &dataBlockComposite,
+    int numberOfPeriods, size_t numberOfChannels, int64_t previousValue,
+    int64_t startValue)
+{
+  auto numberOfSpectra = previousValue - startValue + 1;
+  DataBlock dataBlock(numberOfPeriods, numberOfSpectra,
+                      numberOfChannels);
+  dataBlock.setMinSpectrumID(startValue);
+  dataBlock.setMaxSpectrumID(previousValue);
+  dataBlockComposite.addDataBlock(dataBlock);
+}
+
+}
+
 /**
 * Populates a DataBlockComposite with DataBlocks which are extracted from a
 * indexable collection (array-type). Note that std::is_array does not
 * work on boost::shared_array which is one of the use cases. Hence this
-* function could get abused.
+* function could get abused. Monitor spectra get their own data block
 * @param dataBlockComposite: the detector block composite which will get
 * populated
 * @param indexContainer: the container of indices
 * @param nArray: the number of array elements
 * @param numberOfPeriods: the number of periods
 * @param numberOfChannels: the number of channels
+* @param monitorSpectra: a collection of monitor spectrum numbers
 */
 template <typename T>
 void DLLExport
 populateDataBlockCompositeWithContainer(DataBlockComposite &dataBlockComposite,
                                         T &indexContainer, int64_t nArray,
                                         int numberOfPeriods,
-                                        size_t numberOfChannels) {
-
-  // Find all intervals among the index array (this assumes that spectrum index
-  // increases monotonically, else we would have to sort first)
-  int64_t startValue = indexContainer[0];
-  int64_t previousValue = startValue;
-
-  for (int64_t arrayIndex = 1; arrayIndex < nArray; ++arrayIndex) {
-    auto isSequential = (indexContainer[arrayIndex] - previousValue) == 1;
-    if (!isSequential) {
-      // We must have completed an interval, we create a DataBlock and add it
-      auto numberOfSpectra = previousValue - startValue + 1;
-      DataBlock dataBlock(numberOfPeriods, numberOfSpectra, numberOfChannels);
-      dataBlock.setMinSpectrumID(startValue);
-      dataBlock.setMaxSpectrumID(previousValue);
-      dataBlockComposite.addDataBlock(dataBlock);
-
-      // Now reset the startValue to the beginning of the new index
-      startValue = indexContainer[arrayIndex];
+                                        size_t numberOfChannels,
+                                        std::vector<int64_t> monitorSpectra)
+{
+    auto isMonitor = [&monitorSpectra](int64_t index) {
+        return std::find(std::begin(monitorSpectra), std::end(monitorSpectra),
+                         index) != std::end(monitorSpectra);
+    };
+
+    auto startValue = indexContainer[0];
+    auto previousValue = startValue;
+
+    for (int64_t arrayIndex = 1; arrayIndex < nArray; ++arrayIndex) {
+        // There are two ways to write data out. Either when we have a jump of
+        // the indices or there is a monitor. In case of a monitor we also need
+        // to clear the data that was potentially before the monitor.
+
+        if (isMonitor(previousValue)) {
+            handleWhenElementIsMonitor(dataBlockComposite, numberOfPeriods,
+                                       numberOfChannels, previousValue, startValue);
+            startValue = indexContainer[arrayIndex];
+        } else if ((indexContainer[arrayIndex] - previousValue) != 1) {
+            // We must have completed an interval, we create a DataBlock and add
+            // it
+            handleWhenElementMadeAJump(dataBlockComposite, numberOfPeriods,
+                                       numberOfChannels, previousValue, startValue);
+            startValue = indexContainer[arrayIndex];
+        }
+
+        // Set the previous value to the current value;
+        previousValue = indexContainer[arrayIndex];
     }
 
-    // Set the previous value to the current value;
-    previousValue = indexContainer[arrayIndex];
-  }
-
-  // The last interval would not have been added
-  auto numberOfSpectra = previousValue - startValue + 1;
-  DataBlock dataBlock(numberOfPeriods, numberOfSpectra, numberOfChannels);
-  dataBlock.setMinSpectrumID(startValue);
-  dataBlock.setMaxSpectrumID(previousValue);
-  dataBlockComposite.addDataBlock(dataBlock);
+    // The last interval would not have been added.
+    if (isMonitor(previousValue)) {
+        handleWhenElementIsMonitor(dataBlockComposite, numberOfPeriods,
+                                   numberOfChannels, previousValue, startValue);
+    } else {
+      handleWhenElementMadeAJump(dataBlockComposite, numberOfPeriods,
+                                   numberOfChannels, previousValue, startValue);
+    }
 }
 }
 }
diff --git a/Framework/DataHandling/src/DataBlockComposite.cpp b/Framework/DataHandling/src/DataBlockComposite.cpp
index 189d88ad536..88aecc05847 100644
--- a/Framework/DataHandling/src/DataBlockComposite.cpp
+++ b/Framework/DataHandling/src/DataBlockComposite.cpp
@@ -3,7 +3,8 @@
 #include <algorithm>
 #include <cassert>
 
-namespace {
+namespace
+{
 
 const int64_t invalidIntervalValue = std::numeric_limits<int64_t>::min();
 
@@ -19,25 +20,26 @@ const int64_t invalidIntervalValue = std::numeric_limits<int64_t>::min();
 std::vector<std::pair<int64_t, int64_t>>
 getRemovalIntervalsRelevantForTheCurrentOriginalInterval(
     const std::pair<int64_t, int64_t> &original,
-    const std::vector<std::pair<int64_t, int64_t>> &removeIntervals) {
-
-  auto hasOverlap = [](const std::pair<int64_t, int64_t> &original,
-                       const std::pair<int64_t, int64_t> &toRemove) {
-    return ((original.first <= toRemove.first) &&
-            (toRemove.first <= original.second)) ||
-           ((original.first <= toRemove.second) &&
-            (toRemove.second <= original.second)) ||
-           ((toRemove.first <= original.first) &&
-            (original.first <= toRemove.second));
-  };
-
-  std::vector<std::pair<int64_t, int64_t>> overlaps;
-  for (auto &removeInterval : removeIntervals) {
-    if (hasOverlap(original, removeInterval)) {
-      overlaps.push_back(removeInterval);
+    const std::vector<std::pair<int64_t, int64_t>> &removeIntervals)
+{
+
+    auto hasOverlap = [](const std::pair<int64_t, int64_t> &original,
+                         const std::pair<int64_t, int64_t> &toRemove) {
+        return ((original.first <= toRemove.first)
+                && (toRemove.first <= original.second))
+               || ((original.first <= toRemove.second)
+                   && (toRemove.second <= original.second))
+               || ((toRemove.first <= original.first)
+                   && (original.first <= toRemove.second));
+    };
+
+    std::vector<std::pair<int64_t, int64_t>> overlaps;
+    for (auto &removeInterval : removeIntervals) {
+        if (hasOverlap(original, removeInterval)) {
+            overlaps.push_back(removeInterval);
+        }
     }
-  }
-  return overlaps;
+    return overlaps;
 }
 
 /**
@@ -49,8 +51,9 @@ getRemovalIntervalsRelevantForTheCurrentOriginalInterval(
          return: NONE
 */
 void handleLeftHandSideOverlap(std::pair<int64_t, int64_t> &original,
-                               const std::pair<int64_t, int64_t> &toRemove) {
-  original.first = toRemove.second + 1;
+                               const std::pair<int64_t, int64_t> &toRemove)
+{
+    original.first = toRemove.second + 1;
 }
 
 /**
@@ -63,11 +66,12 @@ void handleLeftHandSideOverlap(std::pair<int64_t, int64_t> &original,
 */
 std::pair<int64_t, int64_t>
 handleRightHandSideOverlap(std::pair<int64_t, int64_t> &original,
-                           const std::pair<int64_t, int64_t> &toRemove) {
-  auto newInterval = std::make_pair(original.first, toRemove.first - 1);
-  original.first = invalidIntervalValue;
-  original.second = invalidIntervalValue;
-  return newInterval;
+                           const std::pair<int64_t, int64_t> &toRemove)
+{
+    auto newInterval = std::make_pair(original.first, toRemove.first - 1);
+    original.first = invalidIntervalValue;
+    original.second = invalidIntervalValue;
+    return newInterval;
 }
 
 /**
@@ -80,288 +84,315 @@ handleRightHandSideOverlap(std::pair<int64_t, int64_t> &original,
 */
 std::pair<int64_t, int64_t>
 handleFullyContained(std::pair<int64_t, int64_t> &original,
-                     const std::pair<int64_t, int64_t> &toRemove) {
-  // It is important to first creat the new pair and then perform the cut
-  auto newPair = std::make_pair(original.first, toRemove.first - 1);
-  original.first = toRemove.second + 1;
-  return newPair;
+                     const std::pair<int64_t, int64_t> &toRemove)
+{
+    // It is important to first creat the new pair and then perform the cut
+    auto newPair = std::make_pair(original.first, toRemove.first - 1);
+    original.first = toRemove.second + 1;
+    return newPair;
 }
 
 std::vector<std::pair<int64_t, int64_t>> getSlicedIntervals(
     std::pair<int64_t, int64_t> original,
-    const std::vector<std::pair<int64_t, int64_t>> &removeIntervals) {
-  // If there is nothing to remove return the original
-  if (removeIntervals.empty()) {
-    return std::vector<std::pair<int64_t, int64_t>>{original};
-  }
-
-  // There are several overlap scenarios.
-  // 1. Full overlap
-  //    original :    |-------|      and |------|
-  //    toRemove: ...------------... and |------|
-  // 2. Left hand side overlap
-  //    original :     |------...  and |-----....
-  //    toRemove:   |------|       and |---|
-  // 3. Right hand side overlap
-  //    original :  ...-------|    and ...-----|
-  //    toRemove:          |-----| and     |---|
-  // 4. Fully contained
-  //    original :  ...-------...
-  //    toRemove:       |---|
-
-  auto isFullOverlap = [](const std::pair<int64_t, int64_t> &original,
-                          const std::pair<int64_t, int64_t> &toRemove) {
-    return (toRemove.first <= original.first) &&
-           (original.first <= toRemove.second) &&
-           (toRemove.first <= original.second) &&
-           (original.second <= toRemove.second);
-  };
-
-  auto isLeftHandSideOverlap = [](const std::pair<int64_t, int64_t> &original,
-                                  const std::pair<int64_t, int64_t> &toRemove) {
-    return (toRemove.first <= original.first) &&
-           (original.first <= toRemove.second) &&
-           (toRemove.second < original.second);
-  };
-
-  auto isRightHandSideOverlap =
-      [](const std::pair<int64_t, int64_t> &original,
-         const std::pair<int64_t, int64_t> &toRemove) {
-        return (original.first < toRemove.first) &&
-               (toRemove.first <= original.second) &&
-               (original.second <= toRemove.second);
-      };
-
-  auto isFullyContained = [](const std::pair<int64_t, int64_t> &original,
-                             const std::pair<int64_t, int64_t> &toRemove) {
-    return (original.first < toRemove.first) &&
-           (toRemove.first < original.second) &&
-           (original.first < toRemove.second) &&
-           (toRemove.second < original.second);
-  };
-
-  // Use that removeIntervals has oredred, non-overlapping intervals
-  // Subtract all the removeIntervals
-  std::vector<std::pair<int64_t, int64_t>> newIntervals;
-  for (auto &removeInterval : removeIntervals) {
-
-    if (isFullOverlap(original, removeInterval)) {
-      // In this case we should remove everything. At this point newIntervals
-      // should still be empty, since the remove intervals should not be
-      // overlapping
-      assert(newIntervals.empty() &&
-             "DataBlockComposite: The newIntervals container should be empty");
-      // Set the remainder of the original to invalid, such that we don't pick
-      // it up at the very end
-      original.first = invalidIntervalValue;
-      original.second = invalidIntervalValue;
-      break;
-    } else if (isRightHandSideOverlap(original, removeInterval)) {
-      auto newInterval = handleRightHandSideOverlap(original, removeInterval);
-      newIntervals.push_back(newInterval);
-    } else if (isLeftHandSideOverlap(original, removeInterval)) {
-      handleLeftHandSideOverlap(original, removeInterval);
-    } else if (isFullyContained(original, removeInterval)) {
-      auto newInterval = handleFullyContained(original, removeInterval);
-      newIntervals.push_back(newInterval);
-    } else {
-      throw std::runtime_error(
-          "DataBlockComposite: The intervals don't seem to overlap.");
+    const std::vector<std::pair<int64_t, int64_t>> &removeIntervals)
+{
+    // If there is nothing to remove return the original
+    if (removeIntervals.empty()) {
+        return std::vector<std::pair<int64_t, int64_t>>{original};
+    }
+
+    // There are several overlap scenarios.
+    // 1. Full overlap
+    //    original :    |-------|      and |------|
+    //    toRemove: ...------------... and |------|
+    // 2. Left hand side overlap
+    //    original :     |------...  and |-----....
+    //    toRemove:   |------|       and |---|
+    // 3. Right hand side overlap
+    //    original :  ...-------|    and ...-----|
+    //    toRemove:          |-----| and     |---|
+    // 4. Fully contained
+    //    original :  ...-------...
+    //    toRemove:       |---|
+
+    auto isFullOverlap = [](const std::pair<int64_t, int64_t> &original,
+                            const std::pair<int64_t, int64_t> &toRemove) {
+        return (toRemove.first <= original.first)
+               && (original.first <= toRemove.second)
+               && (toRemove.first <= original.second)
+               && (original.second <= toRemove.second);
+    };
+
+    auto isLeftHandSideOverlap =
+        [](const std::pair<int64_t, int64_t> &original,
+           const std::pair<int64_t, int64_t> &toRemove) {
+            return (toRemove.first <= original.first)
+                   && (original.first <= toRemove.second)
+                   && (toRemove.second < original.second);
+        };
+
+    auto isRightHandSideOverlap =
+        [](const std::pair<int64_t, int64_t> &original,
+           const std::pair<int64_t, int64_t> &toRemove) {
+            return (original.first < toRemove.first)
+                   && (toRemove.first <= original.second)
+                   && (original.second <= toRemove.second);
+        };
+
+    auto isFullyContained = [](const std::pair<int64_t, int64_t> &original,
+                               const std::pair<int64_t, int64_t> &toRemove) {
+        return (original.first < toRemove.first)
+               && (toRemove.first < original.second)
+               && (original.first < toRemove.second)
+               && (toRemove.second < original.second);
+    };
+
+    // Use that removeIntervals has oredred, non-overlapping intervals
+    // Subtract all the removeIntervals
+    std::vector<std::pair<int64_t, int64_t>> newIntervals;
+    for (auto &removeInterval : removeIntervals) {
+
+        if (isFullOverlap(original, removeInterval)) {
+            // In this case we should remove everything. At this point
+            // newIntervals
+            // should still be empty, since the remove intervals should not be
+            // overlapping
+            assert(newIntervals.empty() && "DataBlockComposite: The "
+                                           "newIntervals container should be "
+                                           "empty");
+            // Set the remainder of the original to invalid, such that we don't
+            // pick
+            // it up at the very end
+            original.first = invalidIntervalValue;
+            original.second = invalidIntervalValue;
+            break;
+        } else if (isRightHandSideOverlap(original, removeInterval)) {
+            auto newInterval
+                = handleRightHandSideOverlap(original, removeInterval);
+            newIntervals.push_back(newInterval);
+        } else if (isLeftHandSideOverlap(original, removeInterval)) {
+            handleLeftHandSideOverlap(original, removeInterval);
+        } else if (isFullyContained(original, removeInterval)) {
+            auto newInterval = handleFullyContained(original, removeInterval);
+            newIntervals.push_back(newInterval);
+        } else {
+            throw std::runtime_error(
+                "DataBlockComposite: The intervals don't seem to overlap.");
+        }
     }
-  }
 
-  // There might be some remainder in the original interval, e.g if there wasn't
-  // a full overlap removal
-  // or no righ-hand-side overlap of a removal interval
-  if ((original.first != invalidIntervalValue) &&
-      (original.second != invalidIntervalValue)) {
-    newIntervals.push_back(original);
-  }
+    // There might be some remainder in the original interval, e.g if there
+    // wasn't
+    // a full overlap removal
+    // or no righ-hand-side overlap of a removal interval
+    if ((original.first != invalidIntervalValue)
+        && (original.second != invalidIntervalValue)) {
+        newIntervals.push_back(original);
+    }
 
-  return newIntervals;
+    return newIntervals;
 }
 
 /**
  * Sorts a data block collection.
  */
-template <typename T> void sortDataBlocks(T &dataBlcokCollection) {
-  // Sort the intervals. We sort them by minimum value
-  using namespace Mantid::DataHandling;
-  auto comparison = [](const DataBlock &el1, const DataBlock &el2) {
-    return el1.getMinSpectrumID() < el2.getMinSpectrumID();
-  };
-  std::sort(std::begin(dataBlcokCollection), std::end(dataBlcokCollection),
-            comparison);
+template <typename T> void sortDataBlocks(T &dataBlcokCollection)
+{
+    // Sort the intervals. We sort them by minimum value
+    using namespace Mantid::DataHandling;
+    auto comparison = [](const DataBlock &el1, const DataBlock &el2) {
+        return el1.getMinSpectrumID() < el2.getMinSpectrumID();
+    };
+    std::sort(std::begin(dataBlcokCollection), std::end(dataBlcokCollection),
+              comparison);
 }
 }
 
-namespace Mantid {
-namespace DataHandling {
-
-int64_t DataBlockComposite::getMinSpectrumID() const {
-  int64_t min = std::numeric_limits<int64_t>::max();
-  for (const auto &child : m_dataBlocks) {
-    auto temp = child.getMinSpectrumID();
-    if (temp < min) {
-      min = temp;
+namespace Mantid
+{
+namespace DataHandling
+{
+
+int64_t DataBlockComposite::getMinSpectrumID() const
+{
+    int64_t min = std::numeric_limits<int64_t>::max();
+    for (const auto &child : m_dataBlocks) {
+        auto temp = child.getMinSpectrumID();
+        if (temp < min) {
+            min = temp;
+        }
     }
-  }
-  return min;
+    return min;
 }
 
-void DataBlockComposite::setMinSpectrumID(int64_t) {
-  // DO NOTHING
+void DataBlockComposite::setMinSpectrumID(int64_t)
+{
+    // DO NOTHING
 }
 
-int64_t DataBlockComposite::getMaxSpectrumID() const {
-  int64_t max = std::numeric_limits<int64_t>::min();
-  for (const auto &child : m_dataBlocks) {
-    auto temp = child.getMaxSpectrumID();
-    if (temp > max) {
-      max = temp;
+int64_t DataBlockComposite::getMaxSpectrumID() const
+{
+    int64_t max = std::numeric_limits<int64_t>::min();
+    for (const auto &child : m_dataBlocks) {
+        auto temp = child.getMaxSpectrumID();
+        if (temp > max) {
+            max = temp;
+        }
     }
-  }
-  return max;
+    return max;
 }
 
-void DataBlockComposite::setMaxSpectrumID(int64_t) {
-  // DO NOTHING
+void DataBlockComposite::setMaxSpectrumID(int64_t)
+{
+    // DO NOTHING
 }
 
-std::unique_ptr<DataBlockGenerator> DataBlockComposite::getGenerator() const {
-  std::vector<std::pair<int64_t, int64_t>> intervals;
-  for (const auto &dataBlock : m_dataBlocks) {
-    intervals.push_back(std::make_pair(dataBlock.getMinSpectrumID(),
-                                       dataBlock.getMaxSpectrumID()));
-  }
-  return Mantid::Kernel::make_unique<DataBlockGenerator>(intervals);
+std::unique_ptr<DataBlockGenerator> DataBlockComposite::getGenerator() const
+{
+    std::vector<std::pair<int64_t, int64_t>> intervals;
+    for (const auto &dataBlock : m_dataBlocks) {
+        intervals.push_back(std::make_pair(dataBlock.getMinSpectrumID(),
+                                           dataBlock.getMaxSpectrumID()));
+    }
+    return Mantid::Kernel::make_unique<DataBlockGenerator>(intervals);
 }
 
-void DataBlockComposite::addDataBlock(DataBlock dataBlock) {
-  // Set the number of periods, number of spectra and number of channel
-  m_numberOfPeriods = dataBlock.getNumberOfPeriods();
-  m_numberOfChannels = dataBlock.getNumberOfChannels();
-  m_numberOfSpectra = dataBlock.getNumberOfSpectra();
+void DataBlockComposite::addDataBlock(DataBlock dataBlock)
+{
+    // Set the number of periods, number of spectra and number of channel
+    m_numberOfPeriods = dataBlock.getNumberOfPeriods();
+    m_numberOfChannels = dataBlock.getNumberOfChannels();
+    m_numberOfSpectra = dataBlock.getNumberOfSpectra();
 
-  // Insert the data block
-  m_dataBlocks.push_back(dataBlock);
+    // Insert the data block
+    m_dataBlocks.push_back(dataBlock);
 }
 
-size_t DataBlockComposite::getNumberOfSpectra() const {
-  size_t total = 0;
-  for (const auto &element : m_dataBlocks) {
-    total += element.getNumberOfSpectra();
-  }
-  return total;
+size_t DataBlockComposite::getNumberOfSpectra() const
+{
+    size_t total = 0;
+    for (const auto &element : m_dataBlocks) {
+        total += element.getNumberOfSpectra();
+    }
+    return total;
 }
 
-size_t DataBlockComposite::getNumberOfChannels() const {
-  return m_dataBlocks.empty() ? 0 : m_dataBlocks[0].getNumberOfChannels();
+size_t DataBlockComposite::getNumberOfChannels() const
+{
+    return m_dataBlocks.empty() ? 0 : m_dataBlocks[0].getNumberOfChannels();
 }
 
-int DataBlockComposite::getNumberOfPeriods() const {
-  return m_dataBlocks.empty() ? 0 : m_dataBlocks[0].getNumberOfPeriods();
+int DataBlockComposite::getNumberOfPeriods() const
+{
+    return m_dataBlocks.empty() ? 0 : m_dataBlocks[0].getNumberOfPeriods();
 }
 
 DataBlockComposite DataBlockComposite::
-operator+(const DataBlockComposite &other) {
-  DataBlockComposite output;
-  output.m_dataBlocks.insert(std::end(output.m_dataBlocks),
-                             std::begin(m_dataBlocks), std::end(m_dataBlocks));
-  output.m_dataBlocks.insert(std::end(output.m_dataBlocks),
-                             std::begin(other.m_dataBlocks),
-                             std::end(other.m_dataBlocks));
-  return output;
+operator+(const DataBlockComposite &other)
+{
+    DataBlockComposite output;
+    output.m_dataBlocks.insert(std::end(output.m_dataBlocks),
+                               std::begin(m_dataBlocks),
+                               std::end(m_dataBlocks));
+    output.m_dataBlocks.insert(std::end(output.m_dataBlocks),
+                               std::begin(other.m_dataBlocks),
+                               std::end(other.m_dataBlocks));
+    return output;
 }
 
-std::vector<DataBlock> DataBlockComposite::getDataBlocks() {
-  // Sort the intervals. We sort them by minimum value
-  sortDataBlocks(m_dataBlocks);
-  return m_dataBlocks;
+std::vector<DataBlock> DataBlockComposite::getDataBlocks()
+{
+    // Sort the intervals. We sort them by minimum value
+    sortDataBlocks(m_dataBlocks);
+    return m_dataBlocks;
 }
 
-void DataBlockComposite::truncate(int64_t specMin, int64_t specMax) {
-  sortDataBlocks(m_dataBlocks);
-  // Find the first data block which is not completely cut off by specMin
-  // original: |-----|      |--------|   |------|
-  // spec_min:         | or | or | or|
-  // result:                 this one
-  auto isNotCompletelyCutOffFromMin = [&specMin](DataBlock &block) {
-    return (specMin <= block.getMinSpectrumID()) ||
-           (specMin <= block.getMaxSpectrumID());
-  };
-
-  // Find the last data block which is not completely cut off by specMax
-  // original: |-----|      |--------|         |------|
-  // spec_min:              | or | or| or  |
-  // result:                 this one
-  auto isNotCompletelyCutOffFromMax = [&specMax](DataBlock &block) {
-    return (block.getMinSpectrumID() <= specMax) ||
-           (block.getMaxSpectrumID() <= specMax);
-  };
-
-  auto firstDataBlock =
-      std::find_if(std::begin(m_dataBlocks), std::end(m_dataBlocks),
-                   isNotCompletelyCutOffFromMin);
-
-  // Note that we have to start from the back.
-  auto lastDataBlockReverseIterator = std::find_if(
-      m_dataBlocks.rbegin(), m_dataBlocks.rend(), isNotCompletelyCutOffFromMax);
-  auto lastDataBlock =
-      std::find(std::begin(m_dataBlocks), std::end(m_dataBlocks),
-                *lastDataBlockReverseIterator);
-
-  // Create datablocks
-  // Increment since we want to include the last data block
-  ++lastDataBlock;
-  std::vector<DataBlock> newDataBlocks(firstDataBlock, lastDataBlock);
-
-  // Adjust the spec_min and spec_max value. Only change the block if
-  // the it cuts the block.
-  if (newDataBlocks[0].getMinSpectrumID() < specMin) {
-    auto numberOfSpectra = newDataBlocks[0].getMaxSpectrumID() - specMin + 1;
-    DataBlock block(newDataBlocks[0].getNumberOfPeriods(), numberOfSpectra,
-                    newDataBlocks[0].getNumberOfChannels());
-    block.setMinSpectrumID(specMin);
-    block.setMaxSpectrumID(newDataBlocks[0].getMaxSpectrumID());
-    newDataBlocks[0] = block;
-  }
-
-  auto lastIndex = newDataBlocks.size() - 1;
-  if (specMax < newDataBlocks[lastIndex].getMaxSpectrumID()) {
-    auto numberOfSpectra =
-        specMax - newDataBlocks[lastIndex].getMaxSpectrumID() + 1;
-    DataBlock block(newDataBlocks[lastIndex].getNumberOfPeriods(),
-                    numberOfSpectra,
-                    newDataBlocks[lastIndex].getNumberOfChannels());
-    block.setMinSpectrumID(newDataBlocks[lastIndex].getMinSpectrumID());
-    block.setMaxSpectrumID(specMax);
-    newDataBlocks[lastIndex] = block;
-  }
-
-  m_dataBlocks.swap(newDataBlocks);
+void DataBlockComposite::truncate(int64_t specMin, int64_t specMax)
+{
+    sortDataBlocks(m_dataBlocks);
+    // Find the first data block which is not completely cut off by specMin
+    // original: |-----|      |--------|   |------|
+    // spec_min:         | or | or | or|
+    // result:                 this one
+    auto isNotCompletelyCutOffFromMin = [&specMin](DataBlock &block) {
+        return (specMin <= block.getMinSpectrumID())
+               || (specMin <= block.getMaxSpectrumID());
+    };
+
+    // Find the last data block which is not completely cut off by specMax
+    // original: |-----|      |--------|         |------|
+    // spec_min:              | or | or| or  |
+    // result:                 this one
+    auto isNotCompletelyCutOffFromMax = [&specMax](DataBlock &block) {
+        return (block.getMinSpectrumID() <= specMax)
+               || (block.getMaxSpectrumID() <= specMax);
+    };
+
+    auto firstDataBlock
+        = std::find_if(std::begin(m_dataBlocks), std::end(m_dataBlocks),
+                       isNotCompletelyCutOffFromMin);
+
+    // Note that we have to start from the back.
+    auto lastDataBlockReverseIterator
+        = std::find_if(m_dataBlocks.rbegin(), m_dataBlocks.rend(),
+                       isNotCompletelyCutOffFromMax);
+    auto lastDataBlock
+        = std::find(std::begin(m_dataBlocks), std::end(m_dataBlocks),
+                    *lastDataBlockReverseIterator);
+
+    // Create datablocks
+    // Increment since we want to include the last data block
+    ++lastDataBlock;
+    std::vector<DataBlock> newDataBlocks(firstDataBlock, lastDataBlock);
+
+    // Adjust the spec_min and spec_max value. Only change the block if
+    // the it cuts the block.
+    if (newDataBlocks[0].getMinSpectrumID() < specMin) {
+        auto numberOfSpectra = newDataBlocks[0].getMaxSpectrumID() - specMin
+                               + 1;
+        DataBlock block(newDataBlocks[0].getNumberOfPeriods(), numberOfSpectra,
+                        newDataBlocks[0].getNumberOfChannels());
+        block.setMinSpectrumID(specMin);
+        block.setMaxSpectrumID(newDataBlocks[0].getMaxSpectrumID());
+        newDataBlocks[0] = block;
+    }
+
+    auto lastIndex = newDataBlocks.size() - 1;
+    if (specMax < newDataBlocks[lastIndex].getMaxSpectrumID()) {
+        auto numberOfSpectra
+            = specMax - newDataBlocks[lastIndex].getMaxSpectrumID() + 1;
+        DataBlock block(newDataBlocks[lastIndex].getNumberOfPeriods(),
+                        numberOfSpectra,
+                        newDataBlocks[lastIndex].getNumberOfChannels());
+        block.setMinSpectrumID(newDataBlocks[lastIndex].getMinSpectrumID());
+        block.setMaxSpectrumID(specMax);
+        newDataBlocks[lastIndex] = block;
+    }
+
+    m_dataBlocks.swap(newDataBlocks);
 }
 
-bool DataBlockComposite::operator==(const DataBlockComposite &other) const {
-  if (other.m_dataBlocks.size() != m_dataBlocks.size()) {
-    return false;
-  }
-
-  // Create a copy of the intervals, since the comparison operator should not
-  // have
-  // side effects!!!!! We need the vector sorted to compare though
-  auto otherDataBlocks = other.m_dataBlocks;
-  auto thisDataBlocks = m_dataBlocks;
-  sortDataBlocks(otherDataBlocks);
-  sortDataBlocks(thisDataBlocks);
-
-  auto isEqual = true;
-  auto itOther = otherDataBlocks.cbegin();
-  auto itThis = thisDataBlocks.cbegin();
-  for (; itOther != otherDataBlocks.cend(); ++itOther, ++itThis) {
-    isEqual = isEqual && *itOther == *itThis;
-  }
-  return isEqual;
+bool DataBlockComposite::operator==(const DataBlockComposite &other) const
+{
+    if (other.m_dataBlocks.size() != m_dataBlocks.size()) {
+        return false;
+    }
+
+    // Create a copy of the intervals, since the comparison operator should not
+    // have
+    // side effects!!!!! We need the vector sorted to compare though
+    auto otherDataBlocks = other.m_dataBlocks;
+    auto thisDataBlocks = m_dataBlocks;
+    sortDataBlocks(otherDataBlocks);
+    sortDataBlocks(thisDataBlocks);
+
+    auto isEqual = true;
+    auto itOther = otherDataBlocks.cbegin();
+    auto itThis = thisDataBlocks.cbegin();
+    for (; itOther != otherDataBlocks.cend(); ++itOther, ++itThis) {
+        isEqual = isEqual && *itOther == *itThis;
+    }
+    return isEqual;
 }
 
 /**
@@ -372,49 +403,67 @@ bool DataBlockComposite::operator==(const DataBlockComposite &other) const {
  * toRemove:     |------|       |--|
  * result:   |---|      |------|    |----|
  */
-void DataBlockComposite::removeSpectra(DataBlockComposite &toRemove) {
-  // Get intervals for current data blocks
-  std::vector<std::pair<int64_t, int64_t>> originalIntervals;
-  for (auto &dataBlock : m_dataBlocks) {
-    originalIntervals.emplace_back(std::make_pair(
-        dataBlock.getMinSpectrumID(), dataBlock.getMaxSpectrumID()));
-  }
-
-  // Get intervals for the data blocks which should be removed
-  auto removeBlocks = toRemove.getDataBlocks();
-  std::vector<std::pair<int64_t, int64_t>> toRemoveIntervals;
-  for (auto &dataBlock : removeBlocks) {
-    toRemoveIntervals.emplace_back(std::make_pair(
-        dataBlock.getMinSpectrumID(), dataBlock.getMaxSpectrumID()));
-  }
-
-  // Now create the new intervals which don't include the removeInterval values
-  std::vector<std::pair<int64_t, int64_t>> newIntervals;
-  for (auto &originalInterval : originalIntervals) {
-    // Find all relevant remove intervals. In principal this could
-    // be made more efficient.
-    auto currentRemovalIntervals =
-        getRemovalIntervalsRelevantForTheCurrentOriginalInterval(
-            originalInterval, toRemoveIntervals);
-    auto slicedIntervals =
-        getSlicedIntervals(originalInterval, currentRemovalIntervals);
-    newIntervals.insert(std::end(newIntervals), std::begin(slicedIntervals),
-                        std::end(slicedIntervals));
-  }
-
-  // Create a new set of data blocks
-  auto numberOfPeriods = m_dataBlocks[0].getNumberOfPeriods();
-  auto numberOfChannels = m_dataBlocks[0].getNumberOfChannels();
-
-  m_dataBlocks.clear();
-  for (auto &newInterval : newIntervals) {
-    DataBlock dataBlock(numberOfPeriods,
-                        newInterval.second - newInterval.first + 1,
-                        numberOfChannels);
-    dataBlock.setMinSpectrumID(newInterval.first);
-    dataBlock.setMaxSpectrumID(newInterval.second);
-    m_dataBlocks.push_back(dataBlock);
-  }
+void DataBlockComposite::removeSpectra(DataBlockComposite &toRemove)
+{
+    // Get intervals for current data blocks
+    std::vector<std::pair<int64_t, int64_t>> originalIntervals;
+    for (auto &dataBlock : m_dataBlocks) {
+        originalIntervals.emplace_back(std::make_pair(
+            dataBlock.getMinSpectrumID(), dataBlock.getMaxSpectrumID()));
+    }
+
+    // Get intervals for the data blocks which should be removed
+    auto removeBlocks = toRemove.getDataBlocks();
+    std::vector<std::pair<int64_t, int64_t>> toRemoveIntervals;
+    for (auto &dataBlock : removeBlocks) {
+        toRemoveIntervals.emplace_back(std::make_pair(
+            dataBlock.getMinSpectrumID(), dataBlock.getMaxSpectrumID()));
+    }
+
+    // Now create the new intervals which don't include the removeInterval
+    // values
+    std::vector<std::pair<int64_t, int64_t>> newIntervals;
+    for (auto &originalInterval : originalIntervals) {
+        // Find all relevant remove intervals. In principal this could
+        // be made more efficient.
+        auto currentRemovalIntervals
+            = getRemovalIntervalsRelevantForTheCurrentOriginalInterval(
+                originalInterval, toRemoveIntervals);
+        auto slicedIntervals
+            = getSlicedIntervals(originalInterval, currentRemovalIntervals);
+        newIntervals.insert(std::end(newIntervals), std::begin(slicedIntervals),
+                            std::end(slicedIntervals));
+    }
+
+    // Create a new set of data blocks
+    auto numberOfPeriods = m_dataBlocks[0].getNumberOfPeriods();
+    auto numberOfChannels = m_dataBlocks[0].getNumberOfChannels();
+
+    m_dataBlocks.clear();
+    for (auto &newInterval : newIntervals) {
+        DataBlock dataBlock(numberOfPeriods,
+                            newInterval.second - newInterval.first + 1,
+                            numberOfChannels);
+        dataBlock.setMinSpectrumID(newInterval.first);
+        dataBlock.setMaxSpectrumID(newInterval.second);
+        m_dataBlocks.push_back(dataBlock);
+    }
+}
+
+/**
+ * Provides a container with all spectrum numbers
+ * @returns a container with all sepctrum numbers
+ */
+std::vector<int64_t> DataBlockComposite::getAllSpectrumNumbers()
+{
+    auto generator = getGenerator();
+    std::vector<int64_t> allSpectra;
+
+    for (; !generator->isDone(); generator->next()) {
+        allSpectra.push_back(generator->getValue());
+    }
+
+    return allSpectra;
 }
 }
 }
diff --git a/Framework/DataHandling/src/LoadISISNexus2.cpp b/Framework/DataHandling/src/LoadISISNexus2.cpp
index 08f19fecc8c..fe8bf9a25da 100644
--- a/Framework/DataHandling/src/LoadISISNexus2.cpp
+++ b/Framework/DataHandling/src/LoadISISNexus2.cpp
@@ -553,12 +553,22 @@ void LoadISISNexus2::checkOptionalProperties(bool bseparateMonitors,
       }
     }
 
+    auto monitorSpectra = m_monBlockInfo.getAllSpectrumNumbers();
+
     // Create DataBlocks from the spectrum list
     DataBlockComposite composite;
     populateDataBlockCompositeWithContainer(
         composite, spec_list, spec_list.size(),
         m_loadBlockInfo.getNumberOfPeriods(),
-        m_loadBlockInfo.getNumberOfChannels());
+        m_loadBlockInfo.getNumberOfChannels(),
+        monitorSpectra);
+
+    // If the monitors are to be loaded separately, then we have
+    // to remove them at this point
+    if (bseparateMonitors || bexcludeMonitor) {
+      composite.removeSpectra(m_monBlockInfo);
+    }
+
     m_loadBlockInfo = composite;
 
     hasSpecList = true;
@@ -625,8 +635,8 @@ LoadISISNexus2::prepareSpectraBlocks(std::map<int64_t, std::string> &monitors,
   std::vector<int64_t> includedMonitors;
   // Setup the SpectraBlocks based on the DataBlocks
   auto dataBlocks = LoadBlock.getDataBlocks();
-  auto isMonitor = [&monitors](int64_t spectrumIndex) {
-    return monitors.find(spectrumIndex) != monitors.end();
+  auto isMonitor = [&monitors](int64_t spectrumNumber) {
+    return monitors.find(spectrumNumber) != monitors.end();
   };
   for (const auto &dataBlock : dataBlocks) {
     auto min = dataBlock.getMinSpectrumID();
@@ -1131,9 +1141,12 @@ bool LoadISISNexus2::findSpectraDetRangeInFile(
   // not be contiguous.
   NXData nxData = entry.openNXData("detector_1");
   NXInt data = nxData.openIntData();
+
+  auto monitorSpectra = m_monBlockInfo.getAllSpectrumNumbers();
   populateDataBlockCompositeWithContainer(m_detBlockInfo, spectrum_index, ndets,
                                           data.dim0() /*Number of Periods*/,
-                                          data.dim2() /*Number of channels*/);
+                                          data.dim2() /*Number of channels*/,
+                                          monitorSpectra);
 
   // We should handle legacy files which include the spectrum number of the
   // monitors
diff --git a/Framework/DataHandling/test/DataBlockCompositeTest.h b/Framework/DataHandling/test/DataBlockCompositeTest.h
index 3c60a929e17..431255c103e 100644
--- a/Framework/DataHandling/test/DataBlockCompositeTest.h
+++ b/Framework/DataHandling/test/DataBlockCompositeTest.h
@@ -11,702 +11,984 @@
 using Mantid::DataHandling::DataBlock;
 using Mantid::DataHandling::DataBlockComposite;
 
-class DataBlockCompositeTest : public CxxTest::TestSuite {
+class DataBlockCompositeTest : public CxxTest::TestSuite
+{
 public:
-  // This pair of boilerplate methods prevent the suite being created statically
-  // This means the constructor isn't called when running other tests
-  static DataBlockCompositeTest *createSuite() {
-    return new DataBlockCompositeTest();
-  }
-  static void destroySuite(DataBlockCompositeTest *suite) { delete suite; }
-
-  void
-  test_that_data_block_composite_produces_generator_which_generates_range() {
-    // Arrange
-    int64_t min1 = 2;
-    int64_t max1 = 8;
-    DataBlock dataBlock1;
-    dataBlock1.setMinSpectrumID(min1);
-    dataBlock1.setMaxSpectrumID(max1);
-
-    int64_t min2 = 45;
-    int64_t max2 = 49;
-    DataBlock dataBlock2;
-    dataBlock2.setMinSpectrumID(min2);
-    dataBlock2.setMaxSpectrumID(max2);
-
-    int64_t min3 = 23;
-    int64_t max3 = 27;
-    DataBlock dataBlock3;
-    dataBlock3.setMinSpectrumID(min3);
-    dataBlock3.setMaxSpectrumID(max3);
-
-    DataBlockComposite dataBlockCompsite;
-    dataBlockCompsite.addDataBlock(dataBlock1);
-    dataBlockCompsite.addDataBlock(dataBlock2);
-    dataBlockCompsite.addDataBlock(dataBlock3);
-
-    // Act
-    auto generator = dataBlockCompsite.getGenerator();
-
-    // Assert
-    std::vector<int64_t> expected = {2,  3,  4,  5,  6,  7,  8,  23, 24,
-                                     25, 26, 27, 45, 46, 47, 48, 49};
-    auto index = 0;
-    for (; !generator->isDone(); generator->next(), ++index) {
-      TSM_ASSERT_EQUALS("Should take elements out of the DataBlock interval",
-                        expected[index], generator->getValue());
+    // This pair of boilerplate methods prevent the suite being created
+    // statically
+    // This means the constructor isn't called when running other tests
+    static DataBlockCompositeTest *createSuite()
+    {
+        return new DataBlockCompositeTest();
+    }
+    static void destroySuite(DataBlockCompositeTest *suite) { delete suite; }
+
+    void
+    test_that_data_block_composite_produces_generator_which_generates_range()
+    {
+        // Arrange
+        int64_t min1 = 2;
+        int64_t max1 = 8;
+        DataBlock dataBlock1;
+        dataBlock1.setMinSpectrumID(min1);
+        dataBlock1.setMaxSpectrumID(max1);
+
+        int64_t min2 = 45;
+        int64_t max2 = 49;
+        DataBlock dataBlock2;
+        dataBlock2.setMinSpectrumID(min2);
+        dataBlock2.setMaxSpectrumID(max2);
+
+        int64_t min3 = 23;
+        int64_t max3 = 27;
+        DataBlock dataBlock3;
+        dataBlock3.setMinSpectrumID(min3);
+        dataBlock3.setMaxSpectrumID(max3);
+
+        DataBlockComposite dataBlockCompsite;
+        dataBlockCompsite.addDataBlock(dataBlock1);
+        dataBlockCompsite.addDataBlock(dataBlock2);
+        dataBlockCompsite.addDataBlock(dataBlock3);
+
+        // Act
+        auto generator = dataBlockCompsite.getGenerator();
+
+        // Assert
+        std::vector<int64_t> expected
+            = {2, 3, 4, 5, 6, 7, 8, 23, 24, 25, 26, 27, 45, 46, 47, 48, 49};
+        auto index = 0;
+        for (; !generator->isDone(); generator->next(), ++index) {
+            TSM_ASSERT_EQUALS(
+                "Should take elements out of the DataBlock interval",
+                expected[index], generator->getValue());
+        }
+
+        TSM_ASSERT_EQUALS("Should be equal", index, expected.size());
+    }
+
+    void test_that_getting_dataBlocks_returns_them_sorted()
+    {
+        // Arrange
+        int64_t min1 = 2;
+        int64_t max1 = 8;
+        DataBlock dataBlock1;
+        dataBlock1.setMinSpectrumID(min1);
+        dataBlock1.setMaxSpectrumID(max1);
+
+        int64_t min2 = 45;
+        int64_t max2 = 49;
+        DataBlock dataBlock2;
+        dataBlock2.setMinSpectrumID(min2);
+        dataBlock2.setMaxSpectrumID(max2);
+
+        int64_t min3 = 23;
+        int64_t max3 = 27;
+        DataBlock dataBlock3;
+        dataBlock3.setMinSpectrumID(min3);
+        dataBlock3.setMaxSpectrumID(max3);
+
+        DataBlockComposite dataBlockCompsite;
+        dataBlockCompsite.addDataBlock(dataBlock1);
+        dataBlockCompsite.addDataBlock(dataBlock2);
+        dataBlockCompsite.addDataBlock(dataBlock3);
+
+        // Act
+        auto dataBlocks = dataBlockCompsite.getDataBlocks();
+
+        // Assert
+        TSM_ASSERT_EQUALS("There should be three data blocks", 3,
+                          dataBlocks.size());
+        TSM_ASSERT_EQUALS("The first min should be 2", min1,
+                          dataBlocks[0].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The first max should be 8", max1,
+                          dataBlocks[0].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The second min should be 23", min3,
+                          dataBlocks[1].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The second max should be 27", max3,
+                          dataBlocks[1].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The first min should be 45", min2,
+                          dataBlocks[2].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The first min should be 49", max2,
+                          dataBlocks[2].getMaxSpectrumID());
+    }
+
+    void
+    test_that_add_number_of_spectra_is_returned_as_well_as_correct_min_and_max()
+    {
+        // Arrange
+        int64_t min1 = 2;
+        int64_t max1 = 8;
+        DataBlock dataBlock1;
+        dataBlock1.setMinSpectrumID(min1);
+        dataBlock1.setMaxSpectrumID(max1);
+
+        int64_t min2 = 45;
+        int64_t max2 = 49;
+        DataBlock dataBlock2;
+        dataBlock2.setMinSpectrumID(min2);
+        dataBlock2.setMaxSpectrumID(max2);
+
+        int64_t min3 = 23;
+        int64_t max3 = 27;
+        DataBlock dataBlock3;
+        dataBlock3.setMinSpectrumID(min3);
+        dataBlock3.setMaxSpectrumID(max3);
+
+        DataBlockComposite dataBlockCompsite;
+        dataBlockCompsite.addDataBlock(dataBlock1);
+        dataBlockCompsite.addDataBlock(dataBlock2);
+        dataBlockCompsite.addDataBlock(dataBlock3);
+
+        // Act
+        auto numberOfSpectra = dataBlockCompsite.getNumberOfSpectra();
+        auto min = dataBlockCompsite.getMinSpectrumID();
+        auto max = dataBlockCompsite.getMaxSpectrumID();
+
+        // Assert
+        auto expectedNumberOfSpectra = dataBlock1.getNumberOfSpectra()
+                                       + dataBlock2.getNumberOfSpectra()
+                                       + dataBlock3.getNumberOfSpectra();
+        TSM_ASSERT_EQUALS(
+            "The total number of spectra should be the sum of the "
+            "spectra of the sub datablocks",
+            expectedNumberOfSpectra, numberOfSpectra);
+
+        TSM_ASSERT_EQUALS("The min should be the absolute min of 2", min1, min);
+        TSM_ASSERT_EQUALS("The max should be the aboslute max of 49", max2,
+                          max);
+    }
+
+    void test_adding_composites_prouduces_correct_new_composite()
+    {
+        // Arrange
+        int64_t min1 = 2;
+        int64_t max1 = 8;
+        DataBlock dataBlock1;
+        dataBlock1.setMinSpectrumID(min1);
+        dataBlock1.setMaxSpectrumID(max1);
+
+        int64_t min2 = 45;
+        int64_t max2 = 49;
+        DataBlock dataBlock2;
+        dataBlock2.setMinSpectrumID(min2);
+        dataBlock2.setMaxSpectrumID(max2);
+
+        int64_t min4 = 17;
+        int64_t max4 = 20;
+        DataBlock dataBlock4;
+        dataBlock4.setMinSpectrumID(min4);
+        dataBlock4.setMaxSpectrumID(max4);
+
+        int64_t min3 = 23;
+        int64_t max3 = 27;
+        DataBlock dataBlock3;
+        dataBlock3.setMinSpectrumID(min3);
+        dataBlock3.setMaxSpectrumID(max3);
+
+        DataBlockComposite dataBlockCompsite1;
+        dataBlockCompsite1.addDataBlock(dataBlock1);
+        dataBlockCompsite1.addDataBlock(dataBlock3);
+
+        DataBlockComposite dataBlockCompsite2;
+        dataBlockCompsite2.addDataBlock(dataBlock2);
+        dataBlockCompsite2.addDataBlock(dataBlock4);
+
+        // Act
+        auto dataBlockCompositeAdded = dataBlockCompsite1 + dataBlockCompsite2;
+
+        // Assert
+        auto dataBlocks = dataBlockCompositeAdded.getDataBlocks();
+        size_t expectedNumberOfDataBlocks = 4;
+        TSM_ASSERT_EQUALS("Should have 4 data blocks.",
+                          expectedNumberOfDataBlocks, dataBlocks.size());
+
+        auto min = dataBlockCompositeAdded.getMinSpectrumID();
+        TSM_ASSERT_EQUALS("Shouldd have a min value of 2", min1, min);
+
+        auto max = dataBlockCompositeAdded.getMaxSpectrumID();
+        TSM_ASSERT_EQUALS("Shouldd have a min value of 49", max2, max);
+
+        auto numberOfSpectra = dataBlockCompositeAdded.getNumberOfSpectra();
+        auto expectedNumberOfSpectra = dataBlock1.getNumberOfSpectra()
+                                       + dataBlock2.getNumberOfSpectra()
+                                       + dataBlock3.getNumberOfSpectra()
+                                       + dataBlock4.getNumberOfSpectra();
+        TSM_ASSERT_EQUALS("Should have full number of spectra",
+                          expectedNumberOfSpectra, numberOfSpectra);
+    }
+
+    void test_that_boost_array_can_be_loaded_into_composite()
+    {
+        // Arrange
+        constexpr int64_t size = 11;
+        // Has intervals [1,1], [3,5], [8,11], [16, 16], [21,22]
+        boost::shared_array<int> indexArray(
+            new int[size]{1, 3, 4, 5, 8, 9, 10, 11, 16, 21, 22});
+        DataBlockComposite composite;
+        int numberOfPeriods = 1;
+        size_t numberOfChannels = 100;
+        std::vector<int64_t> monitors;
+
+        // Act
+        Mantid::DataHandling::populateDataBlockCompositeWithContainer(
+            composite, indexArray, size, numberOfPeriods, numberOfChannels,
+            monitors);
+
+        // Assert
+        auto dataBlocks = composite.getDataBlocks();
+        TSM_ASSERT_EQUALS("There should be 5 datablocks present",
+                          dataBlocks.size(), 5);
+
+        TSM_ASSERT_EQUALS("The min of the first data block should be 1", 1,
+                          dataBlocks[0].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the first data block should be 1", 1,
+                          dataBlocks[0].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 1", 1,
+                          dataBlocks[0].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the second data block should be 3", 3,
+                          dataBlocks[1].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the second data block should be 5", 5,
+                          dataBlocks[1].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 3", 3,
+                          dataBlocks[1].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the third data block should be 8", 8,
+                          dataBlocks[2].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the third data block should be 11", 11,
+                          dataBlocks[2].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 4", 4,
+                          dataBlocks[2].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the fourth data block should be 16", 16,
+                          dataBlocks[3].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the fourth data block should be 16", 16,
+                          dataBlocks[3].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 1", 1,
+                          dataBlocks[3].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the fifth data block should be 21", 21,
+                          dataBlocks[4].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the fiffth data block should be 22", 22,
+                          dataBlocks[4].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 2", 2,
+                          dataBlocks[4].getNumberOfSpectra());
+    }
+
+    void test_that_boost_array_can_be_loaded_into_composite_with_monitors()
+    {
+        // Arrange
+        constexpr int64_t size = 11;
+        // Has intervals [1,1], [3,5], [8,11], [16, 16], [21,22]
+        boost::shared_array<int> indexArray(
+            new int[size]{1, 3, 4, 5, 8, 9, 10, 11, 16, 21, 22});
+        DataBlockComposite composite;
+        int numberOfPeriods = 1;
+        size_t numberOfChannels = 100;
+        std::vector<int64_t> monitors{9};
+
+        // Act
+        Mantid::DataHandling::populateDataBlockCompositeWithContainer(
+            composite, indexArray, size, numberOfPeriods, numberOfChannels,
+            monitors);
+
+        // Assert
+        auto dataBlocks = composite.getDataBlocks();
+        TSM_ASSERT_EQUALS("There should be 7 datablocks present",
+                          dataBlocks.size(), 7);
+
+        TSM_ASSERT_EQUALS("The min of the first data block should be 1", 1,
+                          dataBlocks[0].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the first data block should be 1", 1,
+                          dataBlocks[0].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 1", 1,
+                          dataBlocks[0].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the second data block should be 3", 3,
+                          dataBlocks[1].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the second data block should be 5", 5,
+                          dataBlocks[1].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 3", 3,
+                          dataBlocks[1].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the third data block should be 8", 8,
+                          dataBlocks[2].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the third data block should be 8", 8,
+                          dataBlocks[2].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 1", 1,
+                          dataBlocks[2].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the fourth data block should be 9", 9,
+                          dataBlocks[3].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the fourth data block should be 9", 9,
+                          dataBlocks[3].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 1", 1,
+                          dataBlocks[3].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the fifth data block should be 10", 10,
+                          dataBlocks[4].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the fifth data block should be 11", 11,
+                          dataBlocks[4].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 2", 2,
+                          dataBlocks[4].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the sixth data block should be 16", 16,
+                          dataBlocks[5].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the sixth data block should be 16", 16,
+                          dataBlocks[5].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 1", 1,
+                          dataBlocks[5].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the seventh data block should be 21", 21,
+                          dataBlocks[6].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the seventh data block should be 22", 22,
+                          dataBlocks[6].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 2", 2,
+                          dataBlocks[6].getNumberOfSpectra());
+    }
+
+    void
+    test_that_boost_array_can_be_loaded_into_composite_with_monitors_at_the_beginning()
+    {
+        // Arrange
+        constexpr int64_t size = 12;
+        // Has intervals [1,5], [8,11], [16, 16], [21,22]
+        boost::shared_array<int> indexArray(
+            new int[size]{1, 2, 3, 4, 5, 8, 9, 10, 11, 16, 21, 22});
+        DataBlockComposite composite;
+        int numberOfPeriods = 1;
+        size_t numberOfChannels = 100;
+        std::vector<int64_t> monitors{1};
+
+        // Act
+        Mantid::DataHandling::populateDataBlockCompositeWithContainer(
+            composite, indexArray, size, numberOfPeriods, numberOfChannels,
+            monitors);
+
+        // Assert
+        auto dataBlocks = composite.getDataBlocks();
+        TSM_ASSERT_EQUALS("There should be 5 datablocks present",
+                          dataBlocks.size(), 5);
+
+        TSM_ASSERT_EQUALS("The min of the first data block should be 1", 1,
+                          dataBlocks[0].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the first data block should be 1", 1,
+                          dataBlocks[0].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 1", 1,
+                          dataBlocks[0].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the second data block should be 2", 2,
+                          dataBlocks[1].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the second data block should be 5", 5,
+                          dataBlocks[1].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 4", 4,
+                          dataBlocks[1].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the third data block should be 8", 8,
+                          dataBlocks[2].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the third data block should be 11", 11,
+                          dataBlocks[2].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 4", 4,
+                          dataBlocks[2].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the fourth data block should be 16", 16,
+                          dataBlocks[3].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the fourth data block should be 16", 16,
+                          dataBlocks[3].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 1", 1,
+                          dataBlocks[3].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the fifth data block should be 21", 21,
+                          dataBlocks[4].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the fiffth data block should be 22", 22,
+                          dataBlocks[4].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 2", 2,
+                          dataBlocks[4].getNumberOfSpectra());
+    }
+
+    void
+    test_that_boost_array_can_be_loaded_into_composite_with_monitor_at_end()
+    {
+        // Arrange
+        constexpr int64_t size = 11;
+        // Has intervals [1,1], [3,5], [8,11], [16, 16], [21,22]
+        boost::shared_array<int> indexArray(
+            new int[size]{1, 3, 4, 5, 8, 9, 10, 11, 16, 21, 22});
+        DataBlockComposite composite;
+        int numberOfPeriods = 1;
+        size_t numberOfChannels = 100;
+        std::vector<int64_t> monitors{22};
+
+        // Act
+        Mantid::DataHandling::populateDataBlockCompositeWithContainer(
+            composite, indexArray, size, numberOfPeriods, numberOfChannels,
+            monitors);
+
+        // Assert
+        auto dataBlocks = composite.getDataBlocks();
+        TSM_ASSERT_EQUALS("There should be 6 datablocks present",
+                          dataBlocks.size(), 6);
+
+        TSM_ASSERT_EQUALS("The min of the first data block should be 1", 1,
+                          dataBlocks[0].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the first data block should be 1", 1,
+                          dataBlocks[0].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 1", 1,
+                          dataBlocks[0].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the second data block should be 3", 3,
+                          dataBlocks[1].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the second data block should be 5", 5,
+                          dataBlocks[1].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 3", 3,
+                          dataBlocks[1].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the third data block should be 8", 8,
+                          dataBlocks[2].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the third data block should be 11", 11,
+                          dataBlocks[2].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 4", 4,
+                          dataBlocks[2].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the fourth data block should be 16", 16,
+                          dataBlocks[3].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the fourth data block should be 16", 16,
+                          dataBlocks[3].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 1", 1,
+                          dataBlocks[3].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the fifth data block should be 21", 21,
+                          dataBlocks[4].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the fiffth data block should be 21", 21,
+                          dataBlocks[4].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 1", 1,
+                          dataBlocks[4].getNumberOfSpectra());
+
+        TSM_ASSERT_EQUALS("The min of the sixth data block should be 22", 22,
+                          dataBlocks[5].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the sixth data block should be 22", 22,
+                          dataBlocks[5].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The number of spectra should be 1", 1,
+                          dataBlocks[5].getNumberOfSpectra());
+    }
+
+    void
+    test_that_removing_data_blocks_which_dont_overlap_leave_the_composite_unaffected()
+    {
+        // Arrange
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(2, 8), std::make_pair(10, 17),
+               std::make_pair(34, 39)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+
+        auto copiedDataBlockComposite(dataBlockComposite);
+
+        std::vector<std::pair<int64_t, int64_t>> removeIntervals
+            = {std::make_pair(9, 9), std::make_pair(21, 27),
+               std::make_pair(100, 210)};
+        auto dataBlockCompositeForRemoval
+            = getSampleDataBlockComposite(removeIntervals);
+
+        // Act
+        dataBlockComposite.removeSpectra(dataBlockCompositeForRemoval);
+
+        // Assert
+        auto original = copiedDataBlockComposite.getDataBlocks();
+        auto newDataBlocks = dataBlockComposite.getDataBlocks();
+
+        TSM_ASSERT_EQUALS("SHould have the same number of data blocks",
+                          original.size(), newDataBlocks.size());
+        for (size_t index = 0; index < original.size(); ++index) {
+            TSM_ASSERT_EQUALS("Should have the same min spectrum",
+                              original[index].getMinSpectrumID(),
+                              newDataBlocks[index].getMinSpectrumID());
+
+            TSM_ASSERT_EQUALS("Should have the same max spectrum",
+                              original[index].getMaxSpectrumID(),
+                              newDataBlocks[index].getMaxSpectrumID());
+
+            TSM_ASSERT_EQUALS("Should have the same number of periods",
+                              original[index].getNumberOfPeriods(),
+                              newDataBlocks[index].getNumberOfPeriods());
+
+            TSM_ASSERT_EQUALS("Should have the same number of channels",
+                              original[index].getNumberOfChannels(),
+                              newDataBlocks[index].getNumberOfChannels());
+
+            TSM_ASSERT_EQUALS("Should have the same number of spectra",
+                              original[index].getNumberOfSpectra(),
+                              newDataBlocks[index].getNumberOfSpectra());
+        }
+    }
+
+    void test_that_exact_match_removes_everything()
+    {
+        // Arrange
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(2, 8), std::make_pair(10, 17),
+               std::make_pair(34, 39)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+
+        auto dataBlockCompositeForRemoval
+            = getSampleDataBlockComposite(intervals);
+        // Act
+        dataBlockComposite.removeSpectra(dataBlockCompositeForRemoval);
+        // Assert
+        auto newDataBlocks = dataBlockComposite.getDataBlocks();
+
+        // TSM_ASSERT("There should be no data blocks.", newDataBlocks.empty());
+    }
+
+    void test_that_left_hand_overlap_is_handled_correctly_scenario1()
+    {
+        // Arrange
+        // Scaneario:
+        //    original:     |------|
+        //    removal:  |------|
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(5, 10)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+        std::vector<std::pair<int64_t, int64_t>> intervalsRemoval
+            = {std::make_pair(1, 7)};
+        auto dataBlockCompositeRemoval
+            = getSampleDataBlockComposite(intervalsRemoval);
+
+        // Act
+        dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
+
+        // Assert
+        auto dataBlock = dataBlockComposite.getDataBlocks();
+        TSM_ASSERT_EQUALS("Should have a single data block", 1,
+                          dataBlock.size());
+        TSM_ASSERT_EQUALS("Should have a min of 8", 8,
+                          dataBlock[0].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("Should have a max of 10", 10,
+                          dataBlock[0].getMaxSpectrumID());
+    }
+
+    void test_that_left_hand_overlap_is_handled_correctly_scenario2()
+    {
+        // Arrange
+        // Scaneario:
+        //    original:        |------|
+        //    removal:  |------|
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(5, 10)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+        std::vector<std::pair<int64_t, int64_t>> intervalsRemoval
+            = {std::make_pair(1, 5)};
+        auto dataBlockCompositeRemoval
+            = getSampleDataBlockComposite(intervalsRemoval);
+
+        // Act
+        dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
+
+        // Assert
+        auto dataBlock = dataBlockComposite.getDataBlocks();
+        TSM_ASSERT_EQUALS("Should have a single data block", 1,
+                          dataBlock.size());
+        TSM_ASSERT_EQUALS("Should have a min of 6", 6,
+                          dataBlock[0].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("Should have a max of 10", 10,
+                          dataBlock[0].getMaxSpectrumID());
+    }
+
+    void test_that_right_hand_overlap_is_handled_correctly_scenario1()
+    {
+        // Arrange
+        // Scaneario:
+        //    original: |------|
+        //    removal:      |------|
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(5, 10)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+        std::vector<std::pair<int64_t, int64_t>> intervalsRemoval
+            = {std::make_pair(7, 12)};
+        auto dataBlockCompositeRemoval
+            = getSampleDataBlockComposite(intervalsRemoval);
+
+        // Act
+        dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
+
+        // Assert
+        auto dataBlock = dataBlockComposite.getDataBlocks();
+        TSM_ASSERT_EQUALS("Should have a single data block", 1,
+                          dataBlock.size());
+        TSM_ASSERT_EQUALS("Should have a min of 5", 5,
+                          dataBlock[0].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("Should have a max of 6", 6,
+                          dataBlock[0].getMaxSpectrumID());
+    }
+
+    void test_that_right_hand_overlap_is_handled_correctly_scenario2()
+    {
+        // Arrange
+        // Scaneario:
+        //    original: |------|
+        //    removal:         |------|
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(5, 10)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+        std::vector<std::pair<int64_t, int64_t>> intervalsRemoval
+            = {std::make_pair(10, 12)};
+        auto dataBlockCompositeRemoval
+            = getSampleDataBlockComposite(intervalsRemoval);
+
+        // Act
+        dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
+
+        // Assert
+        auto dataBlock = dataBlockComposite.getDataBlocks();
+        TSM_ASSERT_EQUALS("Should have a single data block", 1,
+                          dataBlock.size());
+        TSM_ASSERT_EQUALS("Should have a min of 5", 5,
+                          dataBlock[0].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("Should have a max of 9", 9,
+                          dataBlock[0].getMaxSpectrumID());
+    }
+
+    void test_that_fully_contained_overlap_is_handled_correctly_scenario1()
+    {
+        // Arrange
+        // Scaneario:
+        //    original: |------|
+        //    removal:   |---|
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(5, 12)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+        std::vector<std::pair<int64_t, int64_t>> intervalsRemoval
+            = {std::make_pair(7, 9)};
+        auto dataBlockCompositeRemoval
+            = getSampleDataBlockComposite(intervalsRemoval);
+
+        // Act
+        dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
+
+        // Assert
+        auto dataBlock = dataBlockComposite.getDataBlocks();
+        TSM_ASSERT_EQUALS("Should have two data block", 2, dataBlock.size());
+        TSM_ASSERT_EQUALS("Should have a min of 5", 5,
+                          dataBlock[0].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("Should have a max of 6", 6,
+                          dataBlock[0].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("Should have a min of 10", 10,
+                          dataBlock[1].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("Should have a max of 12", 12,
+                          dataBlock[1].getMaxSpectrumID());
+    }
+
+    void test_that_fully_contained_overlap_is_handled_correctly_scenario2()
+    {
+        // Arrange
+        // Scaneario:
+        //    original: |------|
+        //    removal:  |---|
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(5, 12)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+        std::vector<std::pair<int64_t, int64_t>> intervalsRemoval
+            = {std::make_pair(5, 9)};
+        auto dataBlockCompositeRemoval
+            = getSampleDataBlockComposite(intervalsRemoval);
+
+        // Act
+        dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
+
+        // Assert
+        auto dataBlock = dataBlockComposite.getDataBlocks();
+        TSM_ASSERT_EQUALS("Should have a single data block", 1,
+                          dataBlock.size());
+        TSM_ASSERT_EQUALS("Should have a min of 10", 10,
+                          dataBlock[0].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("Should have a max of 12", 12,
+                          dataBlock[0].getMaxSpectrumID());
+    }
+
+    void test_that_fully_contained_overlap_is_handled_correctly_scenario3()
+    {
+        // Arrange
+        // Scaneario:
+        //    original: |------|
+        //    removal:    |----|
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(5, 12)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+        std::vector<std::pair<int64_t, int64_t>> intervalsRemoval
+            = {std::make_pair(8, 12)};
+        auto dataBlockCompositeRemoval
+            = getSampleDataBlockComposite(intervalsRemoval);
+
+        // Act
+        dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
+
+        // Assert
+        auto dataBlock = dataBlockComposite.getDataBlocks();
+        TSM_ASSERT_EQUALS("Should have a single data block", 1,
+                          dataBlock.size());
+        TSM_ASSERT_EQUALS("Should have a min of 5", 5,
+                          dataBlock[0].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("Should have a max of 7", 7,
+                          dataBlock[0].getMaxSpectrumID());
+    }
+
+    void test_that_full_overlap_is_handled_correctly()
+    {
+        // Arrange
+        // Scaneario:
+        //    original: |------|
+        //    removal: |--------|
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(5, 12)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+        std::vector<std::pair<int64_t, int64_t>> intervalsRemoval
+            = {std::make_pair(4, 14)};
+        auto dataBlockCompositeRemoval
+            = getSampleDataBlockComposite(intervalsRemoval);
+
+        // Act
+        dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
+
+        // Assert
+        auto dataBlock = dataBlockComposite.getDataBlocks();
+        TSM_ASSERT("Should have no data blocks", dataBlock.empty());
+    }
+
+    void
+    test_that_multipiece_overlap_for_single_original_intervals_is_handled_correctly()
+    {
+        // Arrange
+        // Scaneario:
+        //    original:  |------------------|
+        //    removal: |-----|  |--|  |-|
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(5, 16)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+        std::vector<std::pair<int64_t, int64_t>> intervalsRemoval
+            = {std::make_pair(4, 7), std::make_pair(9, 10),
+               std::make_pair(13, 13)};
+        auto dataBlockCompositeRemoval
+            = getSampleDataBlockComposite(intervalsRemoval);
+
+        // Act
+        dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
+
+        // Assert
+        auto dataBlock = dataBlockComposite.getDataBlocks();
+        TSM_ASSERT_EQUALS("Should have three data blocks", 3, dataBlock.size());
+        TSM_ASSERT_EQUALS("The min of the first ata block should be 8", 8,
+                          dataBlock[0].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the first data block should be 8", 8,
+                          dataBlock[0].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The min of the second ata block should be 11", 11,
+                          dataBlock[1].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the second data block should be 12", 12,
+                          dataBlock[1].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The min of the third ata block should be 14", 14,
+                          dataBlock[2].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the third data block should be 16", 16,
+                          dataBlock[2].getMaxSpectrumID());
+    }
+
+    void
+    test_that_multipiece_overlap_for_mulitple_original_intervals_is_handled_correctly()
+    {
+        // Arrange
+        // Scaneario:
+        //    original:  |------------------|  |-------|
+        //    removal: |-----|  |--|  |-|        |--| |--|
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(5, 16), std::make_pair(20, 26)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+        std::vector<std::pair<int64_t, int64_t>> intervalsRemoval = {
+            std::make_pair(4, 7), std::make_pair(9, 10), std::make_pair(13, 13),
+            std::make_pair(21, 22), std::make_pair(25, 30)};
+        auto dataBlockCompositeRemoval
+            = getSampleDataBlockComposite(intervalsRemoval);
+
+        // Act
+        dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
+
+        // Assert
+        auto dataBlock = dataBlockComposite.getDataBlocks();
+        TSM_ASSERT_EQUALS("Should have three data blocks", 5, dataBlock.size());
+        TSM_ASSERT_EQUALS("The min of the first ata block should be 8", 8,
+                          dataBlock[0].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the first data block should be 8", 8,
+                          dataBlock[0].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The min of the second ata block should be 11", 11,
+                          dataBlock[1].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the second data block should be 12", 12,
+                          dataBlock[1].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The min of the third ata block should be 14", 14,
+                          dataBlock[2].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the third data block should be 16", 16,
+                          dataBlock[2].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The min of the third ata block should be 20", 20,
+                          dataBlock[3].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the third data block should be 20", 20,
+                          dataBlock[3].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("The min of the third ata block should be 23", 23,
+                          dataBlock[4].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("The max of the third data block should be 24", 24,
+                          dataBlock[4].getMaxSpectrumID());
+    }
+
+    void test_that_truncation_of_interval_handles_correctly_scenario1()
+    {
+        // Arrange
+        // Scenario:
+        // original   |------|     |------|
+        // truncation   |               |
+        // result       |----|     |----|
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(5, 16), std::make_pair(20, 26)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+        int64_t min = 8;
+        int64_t max = 22;
+
+        // Act
+        dataBlockComposite.truncate(min, max);
+
+        // Assert
+        auto dataBlocks = dataBlockComposite.getDataBlocks();
+        TSM_ASSERT_EQUALS("Should have one datablock", 2, dataBlocks.size());
+        TSM_ASSERT_EQUALS("Should have a minimum of 8", 8,
+                          dataBlocks[0].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("Should have a maximum of 16", 16,
+                          dataBlocks[0].getMaxSpectrumID());
+        TSM_ASSERT_EQUALS("Should have a minimum of 20", 20,
+                          dataBlocks[1].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("Should have a maximum of 22", 22,
+                          dataBlocks[1].getMaxSpectrumID());
+    }
+
+    void test_that_truncation_of_interval_handles_correctly_scenario2()
+    {
+        // Arrange
+        // Scenario:
+        // original   |------|     |------|
+        // truncation |       |
+        // result     |------|
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(5, 16), std::make_pair(20, 26)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+        int64_t min = 5;
+        int64_t max = 18;
+
+        // Act
+        dataBlockComposite.truncate(min, max);
+
+        // Assert
+        auto dataBlocks = dataBlockComposite.getDataBlocks();
+        TSM_ASSERT_EQUALS("Should have one datablock", 1, dataBlocks.size());
+        TSM_ASSERT_EQUALS("Should have a minimum of 5", 5,
+                          dataBlocks[0].getMinSpectrumID());
+        TSM_ASSERT_EQUALS("Should have a maximum of 16", 16,
+                          dataBlocks[0].getMaxSpectrumID());
+    }
+
+    void test_that_truncation_of_interval_handles_correctly_scenario3()
+    {
+        // Arrange
+        // Scenario:
+        // original     |------|     |------|
+        // truncation |                       |
+        // result       |------|     |------|
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(5, 16), std::make_pair(20, 26)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+        int64_t min = 4;
+        int64_t max = 34;
+        auto dataBlockCompositeCopy = dataBlockComposite;
+
+        // Act
+        dataBlockComposite.truncate(min, max);
+
+        // Assert
+        TSM_ASSERT("Should be equal",
+                   dataBlockComposite == dataBlockCompositeCopy);
+    }
+
+    void test_that_data_block_composites_are_equal()
+    {
+        // Arrange
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(5, 16), std::make_pair(20, 26)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+
+        // Act + Assert
+        TSM_ASSERT("Should be equal", dataBlockComposite == dataBlockComposite);
+    }
+
+    void test_that_data_block_composites_are_not_equal()
+    {
+        // Arrange
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(5, 16), std::make_pair(20, 26)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+        std::vector<std::pair<int64_t, int64_t>> intervals2
+            = {std::make_pair(5, 15), std::make_pair(20, 26)};
+        auto dataBlockComposite2 = getSampleDataBlockComposite(intervals2);
+
+        // Act + Assert
+        TSM_ASSERT("Should not be equal",
+                   !(dataBlockComposite == dataBlockComposite2));
     }
 
-    TSM_ASSERT_EQUALS("Should be equal", index, expected.size());
-  }
-
-  void test_that_getting_dataBlocks_returns_them_sorted() {
-    // Arrange
-    int64_t min1 = 2;
-    int64_t max1 = 8;
-    DataBlock dataBlock1;
-    dataBlock1.setMinSpectrumID(min1);
-    dataBlock1.setMaxSpectrumID(max1);
-
-    int64_t min2 = 45;
-    int64_t max2 = 49;
-    DataBlock dataBlock2;
-    dataBlock2.setMinSpectrumID(min2);
-    dataBlock2.setMaxSpectrumID(max2);
-
-    int64_t min3 = 23;
-    int64_t max3 = 27;
-    DataBlock dataBlock3;
-    dataBlock3.setMinSpectrumID(min3);
-    dataBlock3.setMaxSpectrumID(max3);
-
-    DataBlockComposite dataBlockCompsite;
-    dataBlockCompsite.addDataBlock(dataBlock1);
-    dataBlockCompsite.addDataBlock(dataBlock2);
-    dataBlockCompsite.addDataBlock(dataBlock3);
-
-    // Act
-    auto dataBlocks = dataBlockCompsite.getDataBlocks();
-
-    // Assert
-    TSM_ASSERT_EQUALS("There should be three data blocks", 3,
-                      dataBlocks.size());
-    TSM_ASSERT_EQUALS("The first min should be 2", min1,
-                      dataBlocks[0].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("The first max should be 8", max1,
-                      dataBlocks[0].getMaxSpectrumID());
-    TSM_ASSERT_EQUALS("The second min should be 23", min3,
-                      dataBlocks[1].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("The second max should be 27", max3,
-                      dataBlocks[1].getMaxSpectrumID());
-    TSM_ASSERT_EQUALS("The first min should be 45", min2,
-                      dataBlocks[2].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("The first min should be 49", max2,
-                      dataBlocks[2].getMaxSpectrumID());
-  }
-
-  void
-  test_that_add_number_of_spectra_is_returned_as_well_as_correct_min_and_max() {
-    // Arrange
-    int64_t min1 = 2;
-    int64_t max1 = 8;
-    DataBlock dataBlock1;
-    dataBlock1.setMinSpectrumID(min1);
-    dataBlock1.setMaxSpectrumID(max1);
-
-    int64_t min2 = 45;
-    int64_t max2 = 49;
-    DataBlock dataBlock2;
-    dataBlock2.setMinSpectrumID(min2);
-    dataBlock2.setMaxSpectrumID(max2);
-
-    int64_t min3 = 23;
-    int64_t max3 = 27;
-    DataBlock dataBlock3;
-    dataBlock3.setMinSpectrumID(min3);
-    dataBlock3.setMaxSpectrumID(max3);
-
-    DataBlockComposite dataBlockCompsite;
-    dataBlockCompsite.addDataBlock(dataBlock1);
-    dataBlockCompsite.addDataBlock(dataBlock2);
-    dataBlockCompsite.addDataBlock(dataBlock3);
-
-    // Act
-    auto numberOfSpectra = dataBlockCompsite.getNumberOfSpectra();
-    auto min = dataBlockCompsite.getMinSpectrumID();
-    auto max = dataBlockCompsite.getMaxSpectrumID();
-
-    // Assert
-    auto expectedNumberOfSpectra = dataBlock1.getNumberOfSpectra() +
-                                   dataBlock2.getNumberOfSpectra() +
-                                   dataBlock3.getNumberOfSpectra();
-    TSM_ASSERT_EQUALS("The total number of spectra should be the sum of the "
-                      "spectra of the sub datablocks",
-                      expectedNumberOfSpectra, numberOfSpectra);
-
-    TSM_ASSERT_EQUALS("The min should be the absolute min of 2", min1, min);
-    TSM_ASSERT_EQUALS("The max should be the aboslute max of 49", max2, max);
-  }
-
-  void test_adding_composites_prouduces_correct_new_composite() {
-    // Arrange
-    int64_t min1 = 2;
-    int64_t max1 = 8;
-    DataBlock dataBlock1;
-    dataBlock1.setMinSpectrumID(min1);
-    dataBlock1.setMaxSpectrumID(max1);
-
-    int64_t min2 = 45;
-    int64_t max2 = 49;
-    DataBlock dataBlock2;
-    dataBlock2.setMinSpectrumID(min2);
-    dataBlock2.setMaxSpectrumID(max2);
-
-    int64_t min4 = 17;
-    int64_t max4 = 20;
-    DataBlock dataBlock4;
-    dataBlock4.setMinSpectrumID(min4);
-    dataBlock4.setMaxSpectrumID(max4);
-
-    int64_t min3 = 23;
-    int64_t max3 = 27;
-    DataBlock dataBlock3;
-    dataBlock3.setMinSpectrumID(min3);
-    dataBlock3.setMaxSpectrumID(max3);
-
-    DataBlockComposite dataBlockCompsite1;
-    dataBlockCompsite1.addDataBlock(dataBlock1);
-    dataBlockCompsite1.addDataBlock(dataBlock3);
-
-    DataBlockComposite dataBlockCompsite2;
-    dataBlockCompsite2.addDataBlock(dataBlock2);
-    dataBlockCompsite2.addDataBlock(dataBlock4);
-
-    // Act
-    auto dataBlockCompositeAdded = dataBlockCompsite1 + dataBlockCompsite2;
-
-    // Assert
-    auto dataBlocks = dataBlockCompositeAdded.getDataBlocks();
-    size_t expectedNumberOfDataBlocks = 4;
-    TSM_ASSERT_EQUALS("Should have 4 data blocks.", expectedNumberOfDataBlocks,
-                      dataBlocks.size());
-
-    auto min = dataBlockCompositeAdded.getMinSpectrumID();
-    TSM_ASSERT_EQUALS("Shouldd have a min value of 2", min1, min);
-
-    auto max = dataBlockCompositeAdded.getMaxSpectrumID();
-    TSM_ASSERT_EQUALS("Shouldd have a min value of 49", max2, max);
-
-    auto numberOfSpectra = dataBlockCompositeAdded.getNumberOfSpectra();
-    auto expectedNumberOfSpectra =
-        dataBlock1.getNumberOfSpectra() + dataBlock2.getNumberOfSpectra() +
-        dataBlock3.getNumberOfSpectra() + dataBlock4.getNumberOfSpectra();
-    TSM_ASSERT_EQUALS("Should have full number of spectra",
-                      expectedNumberOfSpectra, numberOfSpectra);
-  }
-
-  void test_that_boost_array_can_be_loaded_into_composite() {
-    // Arrange
-    constexpr int64_t size = 11;
-    // Has intervals [1,1], [3,5], [8,11], [16, 16], [21,22]
-    boost::shared_array<int> indexArray(
-        new int[size]{1, 3, 4, 5, 8, 9, 10, 11, 16, 21, 22});
-    DataBlockComposite composite;
-    int numberOfPeriods = 1;
-    size_t numberOfChannels = 100;
-
-    // Act
-    Mantid::DataHandling::populateDataBlockCompositeWithContainer(
-        composite, indexArray, size, numberOfPeriods, numberOfChannels);
-
-    // Assert
-    auto dataBlocks = composite.getDataBlocks();
-    TSM_ASSERT_EQUALS("There should be 5 datablocks present", dataBlocks.size(),
-                      5);
-
-    TSM_ASSERT_EQUALS("The min of the first data block should be 1", 1,
-                      dataBlocks[0].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("The max of the first data block should be 1", 1,
-                      dataBlocks[0].getMaxSpectrumID());
-    TSM_ASSERT_EQUALS("The number of spectra should be 1", 1,
-                      dataBlocks[0].getNumberOfSpectra());
-
-    TSM_ASSERT_EQUALS("The min of the second data block should be 3", 3,
-                      dataBlocks[1].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("The max of the second data block should be 5", 5,
-                      dataBlocks[1].getMaxSpectrumID());
-    TSM_ASSERT_EQUALS("The number of spectra should be 3", 3,
-                      dataBlocks[1].getNumberOfSpectra());
-
-    TSM_ASSERT_EQUALS("The min of the third data block should be 8", 8,
-                      dataBlocks[2].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("The max of the third data block should be 11", 11,
-                      dataBlocks[2].getMaxSpectrumID());
-    TSM_ASSERT_EQUALS("The number of spectra should be 4", 4,
-                      dataBlocks[2].getNumberOfSpectra());
-
-    TSM_ASSERT_EQUALS("The min of the fourth data block should be 16", 16,
-                      dataBlocks[3].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("The max of the fourth data block should be 16", 16,
-                      dataBlocks[3].getMaxSpectrumID());
-    TSM_ASSERT_EQUALS("The number of spectra should be 1", 1,
-                      dataBlocks[3].getNumberOfSpectra());
-
-    TSM_ASSERT_EQUALS("The min of the fifth data block should be 3", 21,
-                      dataBlocks[4].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("The max of the fiffth data block should be 5", 22,
-                      dataBlocks[4].getMaxSpectrumID());
-    TSM_ASSERT_EQUALS("The number of spectra should be 2", 2,
-                      dataBlocks[4].getNumberOfSpectra());
-  }
-
-  void
-  test_that_removing_data_blocks_which_dont_overlap_leave_the_composite_unaffected() {
-    // Arrange
-    std::vector<std::pair<int64_t, int64_t>> intervals = {
-        std::make_pair(2, 8), std::make_pair(10, 17), std::make_pair(34, 39)};
-    auto dataBlockComposite = getSampleDataBlockComposite(intervals);
-
-    auto copiedDataBlockComposite(dataBlockComposite);
-
-    std::vector<std::pair<int64_t, int64_t>> removeIntervals = {
-        std::make_pair(9, 9), std::make_pair(21, 27), std::make_pair(100, 210)};
-    auto dataBlockCompositeForRemoval =
-        getSampleDataBlockComposite(removeIntervals);
-
-    // Act
-    dataBlockComposite.removeSpectra(dataBlockCompositeForRemoval);
-
-    // Assert
-    auto original = copiedDataBlockComposite.getDataBlocks();
-    auto newDataBlocks = dataBlockComposite.getDataBlocks();
-
-    TSM_ASSERT_EQUALS("SHould have the same number of data blocks",
-                      original.size(), newDataBlocks.size());
-    for (size_t index = 0; index < original.size(); ++index) {
-      TSM_ASSERT_EQUALS("Should have the same min spectrum",
-                        original[index].getMinSpectrumID(),
-                        newDataBlocks[index].getMinSpectrumID());
-
-      TSM_ASSERT_EQUALS("Should have the same max spectrum",
-                        original[index].getMaxSpectrumID(),
-                        newDataBlocks[index].getMaxSpectrumID());
-
-      TSM_ASSERT_EQUALS("Should have the same number of periods",
-                        original[index].getNumberOfPeriods(),
-                        newDataBlocks[index].getNumberOfPeriods());
-
-      TSM_ASSERT_EQUALS("Should have the same number of channels",
-                        original[index].getNumberOfChannels(),
-                        newDataBlocks[index].getNumberOfChannels());
-
-      TSM_ASSERT_EQUALS("Should have the same number of spectra",
-                        original[index].getNumberOfSpectra(),
-                        newDataBlocks[index].getNumberOfSpectra());
+    void
+    test_that_data_block_composite_returns_collection_with_all_spectrum_numbers()
+    {
+        // Arrange
+        std::vector<std::pair<int64_t, int64_t>> intervals
+            = {std::make_pair(5, 16), std::make_pair(20, 26)};
+        auto dataBlockComposite = getSampleDataBlockComposite(intervals);
+
+        // Act
+        auto allSpectra = dataBlockComposite.getAllSpectrumNumbers();
+
+        // Assert
+        auto spectrumIsContained = [&allSpectra](int64_t spectrumNumber) {
+            return std::find(std::begin(allSpectra), std::end(allSpectra),
+                             spectrumNumber) != std::end(allSpectra);
+        };
+
+        for (int64_t item = 2; item <= 4; ++item) {
+            TSM_ASSERT("Should not find the value.",
+                       !spectrumIsContained(item));
+        }
+
+        for (int64_t item = 5; item <= 16; ++item) {
+            TSM_ASSERT("Should find the value.", spectrumIsContained(item));
+        }
+
+        for (int64_t item = 17; item <= 19; ++item) {
+            TSM_ASSERT("Should not find the value.",
+                       !spectrumIsContained(item));
+        }
+
+        for (int64_t item = 20; item <= 26; ++item) {
+            TSM_ASSERT("Should find the value.", spectrumIsContained(item));
+        }
+
+        for (int64_t item = 27; item <= 30; ++item) {
+            TSM_ASSERT("Should not find the value.",
+                       !spectrumIsContained(item));
+        }
     }
-  }
-
-  void test_that_exact_match_removes_everything() {
-    // Arrange
-    std::vector<std::pair<int64_t, int64_t>> intervals = {
-        std::make_pair(2, 8), std::make_pair(10, 17), std::make_pair(34, 39)};
-    auto dataBlockComposite = getSampleDataBlockComposite(intervals);
-
-    auto dataBlockCompositeForRemoval = getSampleDataBlockComposite(intervals);
-    // Act
-    dataBlockComposite.removeSpectra(dataBlockCompositeForRemoval);
-    // Assert
-    auto newDataBlocks = dataBlockComposite.getDataBlocks();
-
-    // TSM_ASSERT("There should be no data blocks.", newDataBlocks.empty());
-  }
-
-  void test_that_left_hand_overlap_is_handled_correctly_scenario1() {
-    // Arrange
-    // Scaneario:
-    //    original:     |------|
-    //    removal:  |------|
-    std::vector<std::pair<int64_t, int64_t>> intervals = {
-        std::make_pair(5, 10)};
-    auto dataBlockComposite = getSampleDataBlockComposite(intervals);
-    std::vector<std::pair<int64_t, int64_t>> intervalsRemoval = {
-        std::make_pair(1, 7)};
-    auto dataBlockCompositeRemoval =
-        getSampleDataBlockComposite(intervalsRemoval);
-
-    // Act
-    dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
-
-    // Assert
-    auto dataBlock = dataBlockComposite.getDataBlocks();
-    TSM_ASSERT_EQUALS("Should have a single data block", 1, dataBlock.size());
-    TSM_ASSERT_EQUALS("Should have a min of 8", 8,
-                      dataBlock[0].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("Should have a max of 10", 10,
-                      dataBlock[0].getMaxSpectrumID());
-  }
-
-  void test_that_left_hand_overlap_is_handled_correctly_scenario2() {
-    // Arrange
-    // Scaneario:
-    //    original:        |------|
-    //    removal:  |------|
-    std::vector<std::pair<int64_t, int64_t>> intervals = {
-        std::make_pair(5, 10)};
-    auto dataBlockComposite = getSampleDataBlockComposite(intervals);
-    std::vector<std::pair<int64_t, int64_t>> intervalsRemoval = {
-        std::make_pair(1, 5)};
-    auto dataBlockCompositeRemoval =
-        getSampleDataBlockComposite(intervalsRemoval);
-
-    // Act
-    dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
-
-    // Assert
-    auto dataBlock = dataBlockComposite.getDataBlocks();
-    TSM_ASSERT_EQUALS("Should have a single data block", 1, dataBlock.size());
-    TSM_ASSERT_EQUALS("Should have a min of 6", 6,
-                      dataBlock[0].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("Should have a max of 10", 10,
-                      dataBlock[0].getMaxSpectrumID());
-  }
-
-  void test_that_right_hand_overlap_is_handled_correctly_scenario1() {
-    // Arrange
-    // Scaneario:
-    //    original: |------|
-    //    removal:      |------|
-    std::vector<std::pair<int64_t, int64_t>> intervals = {
-        std::make_pair(5, 10)};
-    auto dataBlockComposite = getSampleDataBlockComposite(intervals);
-    std::vector<std::pair<int64_t, int64_t>> intervalsRemoval = {
-        std::make_pair(7, 12)};
-    auto dataBlockCompositeRemoval =
-        getSampleDataBlockComposite(intervalsRemoval);
-
-    // Act
-    dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
-
-    // Assert
-    auto dataBlock = dataBlockComposite.getDataBlocks();
-    TSM_ASSERT_EQUALS("Should have a single data block", 1, dataBlock.size());
-    TSM_ASSERT_EQUALS("Should have a min of 5", 5,
-                      dataBlock[0].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("Should have a max of 6", 6,
-                      dataBlock[0].getMaxSpectrumID());
-  }
-
-  void test_that_right_hand_overlap_is_handled_correctly_scenario2() {
-    // Arrange
-    // Scaneario:
-    //    original: |------|
-    //    removal:         |------|
-    std::vector<std::pair<int64_t, int64_t>> intervals = {
-        std::make_pair(5, 10)};
-    auto dataBlockComposite = getSampleDataBlockComposite(intervals);
-    std::vector<std::pair<int64_t, int64_t>> intervalsRemoval = {
-        std::make_pair(10, 12)};
-    auto dataBlockCompositeRemoval =
-        getSampleDataBlockComposite(intervalsRemoval);
-
-    // Act
-    dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
-
-    // Assert
-    auto dataBlock = dataBlockComposite.getDataBlocks();
-    TSM_ASSERT_EQUALS("Should have a single data block", 1, dataBlock.size());
-    TSM_ASSERT_EQUALS("Should have a min of 5", 5,
-                      dataBlock[0].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("Should have a max of 9", 9,
-                      dataBlock[0].getMaxSpectrumID());
-  }
-
-  void test_that_fully_contained_overlap_is_handled_correctly_scenario1() {
-    // Arrange
-    // Scaneario:
-    //    original: |------|
-    //    removal:   |---|
-    std::vector<std::pair<int64_t, int64_t>> intervals = {
-        std::make_pair(5, 12)};
-    auto dataBlockComposite = getSampleDataBlockComposite(intervals);
-    std::vector<std::pair<int64_t, int64_t>> intervalsRemoval = {
-        std::make_pair(7, 9)};
-    auto dataBlockCompositeRemoval =
-        getSampleDataBlockComposite(intervalsRemoval);
-
-    // Act
-    dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
-
-    // Assert
-    auto dataBlock = dataBlockComposite.getDataBlocks();
-    TSM_ASSERT_EQUALS("Should have two data block", 2, dataBlock.size());
-    TSM_ASSERT_EQUALS("Should have a min of 5", 5,
-                      dataBlock[0].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("Should have a max of 6", 6,
-                      dataBlock[0].getMaxSpectrumID());
-    TSM_ASSERT_EQUALS("Should have a min of 10", 10,
-                      dataBlock[1].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("Should have a max of 12", 12,
-                      dataBlock[1].getMaxSpectrumID());
-  }
-
-  void test_that_fully_contained_overlap_is_handled_correctly_scenario2() {
-    // Arrange
-    // Scaneario:
-    //    original: |------|
-    //    removal:  |---|
-    std::vector<std::pair<int64_t, int64_t>> intervals = {
-        std::make_pair(5, 12)};
-    auto dataBlockComposite = getSampleDataBlockComposite(intervals);
-    std::vector<std::pair<int64_t, int64_t>> intervalsRemoval = {
-        std::make_pair(5, 9)};
-    auto dataBlockCompositeRemoval =
-        getSampleDataBlockComposite(intervalsRemoval);
-
-    // Act
-    dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
-
-    // Assert
-    auto dataBlock = dataBlockComposite.getDataBlocks();
-    TSM_ASSERT_EQUALS("Should have a single data block", 1, dataBlock.size());
-    TSM_ASSERT_EQUALS("Should have a min of 10", 10,
-                      dataBlock[0].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("Should have a max of 12", 12,
-                      dataBlock[0].getMaxSpectrumID());
-  }
-
-  void test_that_fully_contained_overlap_is_handled_correctly_scenario3() {
-    // Arrange
-    // Scaneario:
-    //    original: |------|
-    //    removal:    |----|
-    std::vector<std::pair<int64_t, int64_t>> intervals = {
-        std::make_pair(5, 12)};
-    auto dataBlockComposite = getSampleDataBlockComposite(intervals);
-    std::vector<std::pair<int64_t, int64_t>> intervalsRemoval = {
-        std::make_pair(8, 12)};
-    auto dataBlockCompositeRemoval =
-        getSampleDataBlockComposite(intervalsRemoval);
-
-    // Act
-    dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
-
-    // Assert
-    auto dataBlock = dataBlockComposite.getDataBlocks();
-    TSM_ASSERT_EQUALS("Should have a single data block", 1, dataBlock.size());
-    TSM_ASSERT_EQUALS("Should have a min of 5", 5,
-                      dataBlock[0].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("Should have a max of 7", 7,
-                      dataBlock[0].getMaxSpectrumID());
-  }
-
-  void test_that_full_overlap_is_handled_correctly() {
-    // Arrange
-    // Scaneario:
-    //    original: |------|
-    //    removal: |--------|
-    std::vector<std::pair<int64_t, int64_t>> intervals = {
-        std::make_pair(5, 12)};
-    auto dataBlockComposite = getSampleDataBlockComposite(intervals);
-    std::vector<std::pair<int64_t, int64_t>> intervalsRemoval = {
-        std::make_pair(4, 14)};
-    auto dataBlockCompositeRemoval =
-        getSampleDataBlockComposite(intervalsRemoval);
-
-    // Act
-    dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
-
-    // Assert
-    auto dataBlock = dataBlockComposite.getDataBlocks();
-    TSM_ASSERT("Should have no data blocks", dataBlock.empty());
-  }
-
-  void
-  test_that_multipiece_overlap_for_single_original_intervals_is_handled_correctly() {
-    // Arrange
-    // Scaneario:
-    //    original:  |------------------|
-    //    removal: |-----|  |--|  |-|
-    std::vector<std::pair<int64_t, int64_t>> intervals = {
-        std::make_pair(5, 16)};
-    auto dataBlockComposite = getSampleDataBlockComposite(intervals);
-    std::vector<std::pair<int64_t, int64_t>> intervalsRemoval = {
-        std::make_pair(4, 7), std::make_pair(9, 10), std::make_pair(13, 13)};
-    auto dataBlockCompositeRemoval =
-        getSampleDataBlockComposite(intervalsRemoval);
-
-    // Act
-    dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
-
-    // Assert
-    auto dataBlock = dataBlockComposite.getDataBlocks();
-    TSM_ASSERT_EQUALS("Should have three data blocks", 3, dataBlock.size());
-    TSM_ASSERT_EQUALS("The min of the first ata block should be 8", 8,
-                      dataBlock[0].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("The max of the first data block should be 8", 8,
-                      dataBlock[0].getMaxSpectrumID());
-    TSM_ASSERT_EQUALS("The min of the second ata block should be 11", 11,
-                      dataBlock[1].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("The max of the second data block should be 12", 12,
-                      dataBlock[1].getMaxSpectrumID());
-    TSM_ASSERT_EQUALS("The min of the third ata block should be 14", 14,
-                      dataBlock[2].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("The max of the third data block should be 16", 16,
-                      dataBlock[2].getMaxSpectrumID());
-  }
-
-  void
-  test_that_multipiece_overlap_for_mulitple_original_intervals_is_handled_correctly() {
-    // Arrange
-    // Scaneario:
-    //    original:  |------------------|  |-------|
-    //    removal: |-----|  |--|  |-|        |--| |--|
-    std::vector<std::pair<int64_t, int64_t>> intervals = {
-        std::make_pair(5, 16), std::make_pair(20, 26)};
-    auto dataBlockComposite = getSampleDataBlockComposite(intervals);
-    std::vector<std::pair<int64_t, int64_t>> intervalsRemoval = {
-        std::make_pair(4, 7), std::make_pair(9, 10), std::make_pair(13, 13),
-        std::make_pair(21, 22), std::make_pair(25, 30)};
-    auto dataBlockCompositeRemoval =
-        getSampleDataBlockComposite(intervalsRemoval);
-
-    // Act
-    dataBlockComposite.removeSpectra(dataBlockCompositeRemoval);
-
-    // Assert
-    auto dataBlock = dataBlockComposite.getDataBlocks();
-    TSM_ASSERT_EQUALS("Should have three data blocks", 5, dataBlock.size());
-    TSM_ASSERT_EQUALS("The min of the first ata block should be 8", 8,
-                      dataBlock[0].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("The max of the first data block should be 8", 8,
-                      dataBlock[0].getMaxSpectrumID());
-    TSM_ASSERT_EQUALS("The min of the second ata block should be 11", 11,
-                      dataBlock[1].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("The max of the second data block should be 12", 12,
-                      dataBlock[1].getMaxSpectrumID());
-    TSM_ASSERT_EQUALS("The min of the third ata block should be 14", 14,
-                      dataBlock[2].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("The max of the third data block should be 16", 16,
-                      dataBlock[2].getMaxSpectrumID());
-    TSM_ASSERT_EQUALS("The min of the third ata block should be 20", 20,
-                      dataBlock[3].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("The max of the third data block should be 20", 20,
-                      dataBlock[3].getMaxSpectrumID());
-    TSM_ASSERT_EQUALS("The min of the third ata block should be 23", 23,
-                      dataBlock[4].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("The max of the third data block should be 24", 24,
-                      dataBlock[4].getMaxSpectrumID());
-  }
-
-  void test_that_truncation_of_interval_handles_correctly_scenario1() {
-    // Arrange
-    // Scenario:
-    // original   |------|     |------|
-    // truncation   |               |
-    // result       |----|     |----|
-    std::vector<std::pair<int64_t, int64_t>> intervals = {
-        std::make_pair(5, 16), std::make_pair(20, 26)};
-    auto dataBlockComposite = getSampleDataBlockComposite(intervals);
-    int64_t min = 8;
-    int64_t max = 22;
-
-    // Act
-    dataBlockComposite.truncate(min, max);
-
-    // Assert
-    auto dataBlocks = dataBlockComposite.getDataBlocks();
-    TSM_ASSERT_EQUALS("Should have one datablock", 2, dataBlocks.size());
-    TSM_ASSERT_EQUALS("Should have a minimum of 8", 8,
-                      dataBlocks[0].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("Should have a maximum of 16", 16,
-                      dataBlocks[0].getMaxSpectrumID());
-    TSM_ASSERT_EQUALS("Should have a minimum of 20", 20,
-                      dataBlocks[1].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("Should have a maximum of 22", 22,
-                      dataBlocks[1].getMaxSpectrumID());
-  }
-
-  void test_that_truncation_of_interval_handles_correctly_scenario2() {
-    // Arrange
-    // Scenario:
-    // original   |------|     |------|
-    // truncation |       |
-    // result     |------|
-    std::vector<std::pair<int64_t, int64_t>> intervals = {
-        std::make_pair(5, 16), std::make_pair(20, 26)};
-    auto dataBlockComposite = getSampleDataBlockComposite(intervals);
-    int64_t min = 5;
-    int64_t max = 18;
-
-    // Act
-    dataBlockComposite.truncate(min, max);
-
-    // Assert
-    auto dataBlocks = dataBlockComposite.getDataBlocks();
-    TSM_ASSERT_EQUALS("Should have one datablock", 1, dataBlocks.size());
-    TSM_ASSERT_EQUALS("Should have a minimum of 5", 5,
-                      dataBlocks[0].getMinSpectrumID());
-    TSM_ASSERT_EQUALS("Should have a maximum of 16", 16,
-                      dataBlocks[0].getMaxSpectrumID());
-  }
-
-  void test_that_truncation_of_interval_handles_correctly_scenario3() {
-    // Arrange
-    // Scenario:
-    // original     |------|     |------|
-    // truncation |                       |
-    // result       |------|     |------|
-    std::vector<std::pair<int64_t, int64_t>> intervals = {
-        std::make_pair(5, 16), std::make_pair(20, 26)};
-    auto dataBlockComposite = getSampleDataBlockComposite(intervals);
-    int64_t min = 4;
-    int64_t max = 34;
-    auto dataBlockCompositeCopy = dataBlockComposite;
-
-    // Act
-    dataBlockComposite.truncate(min, max);
-
-    // Assert
-    TSM_ASSERT("Should be equal", dataBlockComposite == dataBlockCompositeCopy);
-  }
-
-  void test_that_data_block_composites_are_equal() {
-    // Arrange
-    std::vector<std::pair<int64_t, int64_t>> intervals = {
-        std::make_pair(5, 16), std::make_pair(20, 26)};
-    auto dataBlockComposite = getSampleDataBlockComposite(intervals);
-
-    // Act + Assert
-    TSM_ASSERT("Should be equal", dataBlockComposite == dataBlockComposite);
-  }
-
-  void test_that_data_block_composites_are_not_equal() {
-    // Arrange
-    std::vector<std::pair<int64_t, int64_t>> intervals = {
-        std::make_pair(5, 16), std::make_pair(20, 26)};
-    auto dataBlockComposite = getSampleDataBlockComposite(intervals);
-    std::vector<std::pair<int64_t, int64_t>> intervals2 = {
-        std::make_pair(5, 15), std::make_pair(20, 26)};
-    auto dataBlockComposite2 = getSampleDataBlockComposite(intervals2);
-
-    // Act + Assert
-    TSM_ASSERT("Should not be equal",
-               !(dataBlockComposite == dataBlockComposite2));
-  }
 
 private:
-  DataBlockComposite getSampleDataBlockComposite(
-      const std::vector<std::pair<int64_t, int64_t>> &intervals) {
-    DataBlockComposite composite;
-    for (const auto &interval : intervals) {
-      DataBlock dataBlock(1, (interval.second - interval.first + 1), 120);
-      dataBlock.setMinSpectrumID(interval.first);
-      dataBlock.setMaxSpectrumID(interval.second);
-      composite.addDataBlock(dataBlock);
+    DataBlockComposite getSampleDataBlockComposite(
+        const std::vector<std::pair<int64_t, int64_t>> &intervals)
+    {
+        DataBlockComposite composite;
+        for (const auto &interval : intervals) {
+            DataBlock dataBlock(1, (interval.second - interval.first + 1), 120);
+            dataBlock.setMinSpectrumID(interval.first);
+            dataBlock.setMaxSpectrumID(interval.second);
+            composite.addDataBlock(dataBlock);
+        }
+        return composite;
     }
-    return composite;
-  }
 };
 
 #endif /* MANTID_DATAHANDLING_DATABLOCKCOMPOSITETEST_H_ */
diff --git a/Framework/DataHandling/test/LoadISISNexusTest.h b/Framework/DataHandling/test/LoadISISNexusTest.h
index 1fde063af14..ed21772915f 100644
--- a/Framework/DataHandling/test/LoadISISNexusTest.h
+++ b/Framework/DataHandling/test/LoadISISNexusTest.h
@@ -1071,6 +1071,14 @@ public:
                  detIDtoWSIndexMap.count(detID) == 0);
     }
 
+    double delta = 1e-6;
+    // Make sure that the monitor data is correct (should be workspace index 26)
+    TS_ASSERT_DELTA(ws->readY(26)[0], 0.0, delta);
+    TS_ASSERT_DELTA(ws->readY(26)[1], 176660.0, delta);
+    TS_ASSERT_DELTA(ws->readY(26)[2], 57659.0, delta);
+    TS_ASSERT_DELTA(ws->readY(26)[17034], 4851.0, delta);
+    TS_ASSERT_DELTA(ws->readY(26)[17035], 4513.0, delta);
+
     // Clean up
     AnalysisDataService::Instance().remove("outWS");
   }
-- 
GitLab