From 41b6a2b7a6f93b34baa5c5eab5a755e5a62c7c6b Mon Sep 17 00:00:00 2001
From: Simon Heybrock <simon.heybrock@esss.se>
Date: Mon, 13 Nov 2017 16:06:38 +0100
Subject: [PATCH] Re #0. Tests for IndexInfo detector -> spectrum mapper.

---
 Framework/Indexing/src/IndexInfo.cpp    | 23 +++++--
 Framework/Indexing/test/IndexInfoTest.h | 84 +++++++++++++++++++++++++
 2 files changed, 101 insertions(+), 6 deletions(-)

diff --git a/Framework/Indexing/src/IndexInfo.cpp b/Framework/Indexing/src/IndexInfo.cpp
index a4e0bd69e6b..049189c7307 100644
--- a/Framework/Indexing/src/IndexInfo.cpp
+++ b/Framework/Indexing/src/IndexInfo.cpp
@@ -202,14 +202,18 @@ SpectrumIndexSet IndexInfo::makeIndexSet(
 std::vector<GlobalSpectrumIndex>
 IndexInfo::globalSpectrumIndicesFromDetectorIndices(
     const std::vector<size_t> &detectorIndices) const {
-  std::vector<bool> detectorMap;
+  if (!m_spectrumDefinitions)
+    throw std::runtime_error("IndexInfo::"
+                             "globalSpectrumIndicesFromDetectorIndices -- no "
+                             "spectrum definitions available");
+  std::vector<char> detectorMap;
   for (const auto &index : detectorIndices) {
     // IndexInfo has no knowledge of the maximum detector index so we workaround
     // this knowledge gap by assuming below that any index beyond the end of the
-    // map is `false`.
+    // map is 0.
     if (index >= detectorMap.size())
-      detectorMap.resize(index + 1, false);
-    detectorMap[index] = true;
+      detectorMap.resize(index + 1, 0);
+    detectorMap[index] = 1;
   }
 
   std::vector<GlobalSpectrumIndex> spectrumIndices;
@@ -217,13 +221,20 @@ IndexInfo::globalSpectrumIndicesFromDetectorIndices(
     const auto &spectrumDefinition = m_spectrumDefinitions->operator[](i);
     if (spectrumDefinition.size() == 1) {
       const auto detectorIndex = spectrumDefinition[0].first;
-      if (detectorMap.size() > detectorIndex && detectorMap[detectorIndex])
+      if (detectorMap.size() > detectorIndex &&
+          detectorMap[detectorIndex] != 0) {
+        if (detectorMap[detectorIndex] > 1)
+          throw std::runtime_error(
+              "Multiple spectra correspond to the same detector");
+        // Increment flag to catch two spectra mapping to same detector.
+        ++detectorMap[detectorIndex];
         spectrumIndices.push_back(i);
+      }
     }
     if (spectrumDefinition.size() > 1)
       throw std::runtime_error("SpectrumDefinition containes multiple entries. "
                                "No unique mapping from detector to spectrum "
-                               "possible.");
+                               "possible");
   }
   if (detectorIndices.size() != spectrumIndices.size())
     throw std::runtime_error(
diff --git a/Framework/Indexing/test/IndexInfoTest.h b/Framework/Indexing/test/IndexInfoTest.h
index 0b5434423fa..b4f32d48e78 100644
--- a/Framework/Indexing/test/IndexInfoTest.h
+++ b/Framework/Indexing/test/IndexInfoTest.h
@@ -187,6 +187,90 @@ public:
     TS_ASSERT_EQUALS(info.spectrumDefinitions().get(), defs.get());
   }
 
+  void test_globalSpectrumIndicesFromDetectorIndices_fails_without_spec_defs() {
+    IndexInfo info(3);
+    std::vector<size_t> detectorIndices{6, 8};
+    TS_ASSERT_THROWS_EQUALS(
+        info.globalSpectrumIndicesFromDetectorIndices(detectorIndices),
+        const std::runtime_error &e, std::string(e.what()),
+        "IndexInfo::globalSpectrumIndicesFromDetectorIndices -- no spectrum "
+        "definitions available");
+  }
+
+  void test_globalSpectrumIndicesFromDetectorIndices_fails_multiple() {
+    IndexInfo info(3);
+    std::vector<size_t> detectorIndices{6, 8};
+    std::vector<SpectrumDefinition> specDefs(3);
+    specDefs[0].add(6);
+    specDefs[1].add(7);
+    specDefs[1].add(77);
+    specDefs[2].add(8);
+    info.setSpectrumDefinitions(specDefs);
+    TS_ASSERT_THROWS_EQUALS(
+        info.globalSpectrumIndicesFromDetectorIndices(detectorIndices),
+        const std::runtime_error &e, std::string(e.what()),
+        "SpectrumDefinition containes multiple entries. No unique mapping from "
+        "detector to spectrum possible");
+  }
+
+  void test_globalSpectrumIndicesFromDetectorIndices_fails_missing() {
+    IndexInfo info(3);
+    std::vector<size_t> detectorIndices{6, 8};
+    std::vector<SpectrumDefinition> specDefs(3);
+    // Nothing maps to 8
+    specDefs[0].add(6);
+    specDefs[1].add(7);
+    info.setSpectrumDefinitions(specDefs);
+    TS_ASSERT_THROWS_EQUALS(
+        info.globalSpectrumIndicesFromDetectorIndices(detectorIndices),
+        const std::runtime_error &e, std::string(e.what()),
+        "Some of the requested detectors do not have a corresponding spectrum");
+  }
+
+  void test_globalSpectrumIndicesFromDetectorIndices_fails_conflict() {
+    IndexInfo info(3);
+    std::vector<size_t> detectorIndices{6, 8};
+    std::vector<SpectrumDefinition> specDefs(3);
+    // Two indices map to same detector.
+    specDefs[0].add(6);
+    specDefs[1].add(6);
+    specDefs[2].add(8);
+    info.setSpectrumDefinitions(specDefs);
+    TS_ASSERT_THROWS_EQUALS(
+        info.globalSpectrumIndicesFromDetectorIndices(detectorIndices),
+        const std::runtime_error &e, std::string(e.what()),
+        "Multiple spectra correspond to the same detector");
+  }
+
+  void test_globalSpectrumIndicesFromDetectorIndices_fails_conflict_miss() {
+    IndexInfo info(3);
+    std::vector<size_t> detectorIndices{6, 8};
+    std::vector<SpectrumDefinition> specDefs(3);
+    // Two indices map to same detector, but additionally one is missing.
+    specDefs[0].add(6);
+    specDefs[1].add(6);
+    info.setSpectrumDefinitions(specDefs);
+    TS_ASSERT_THROWS_EQUALS(
+        info.globalSpectrumIndicesFromDetectorIndices(detectorIndices),
+        const std::runtime_error &e, std::string(e.what()),
+        "Multiple spectra correspond to the same detector");
+  }
+
+  void test_globalSpectrumIndicesFromDetectorIndices() {
+    IndexInfo info(3);
+    std::vector<size_t> detectorIndices{6, 8};
+    std::vector<SpectrumDefinition> specDefs(3);
+    specDefs[0].add(6);
+    specDefs[1].add(7);
+    specDefs[2].add(8);
+    info.setSpectrumDefinitions(specDefs);
+    const auto &indices =
+        info.globalSpectrumIndicesFromDetectorIndices(detectorIndices);
+    TS_ASSERT_EQUALS(indices.size(), detectorIndices.size());
+    TS_ASSERT_EQUALS(indices[0], 0);
+    TS_ASSERT_EQUALS(indices[1], 2);
+  }
+
   void test_StorageMode_Cloned() {
     runParallel(run_StorageMode_Cloned);
     // Trivial: Run with one partition.
-- 
GitLab