Skip to content
Snippets Groups Projects
IndexInfo.cpp 3.84 KiB
Newer Older
#include "MantidIndexing/IndexInfo.h"
#include "MantidIndexing/SpectrumNumberTranslator.h"
#include "MantidKernel/make_cow.h"
#include "MantidTypes/SpectrumDefinition.h"

#include <algorithm>
#include <functional>

namespace Mantid {
namespace Indexing {

/// Construct a default IndexInfo, with contiguous spectrum numbers starting at
/// 1 and no detector IDs.
IndexInfo::IndexInfo(const size_t globalSize)
    : m_size(globalSize),
      m_spectrumNumbers(Kernel::make_cow<std::vector<specnum_t>>(globalSize)),
      m_detectorIDs(
          Kernel::make_cow<std::vector<std::vector<detid_t>>>(globalSize)) {
  // Default to spectrum numbers 1...globalSize
  auto &specNums = m_spectrumNumbers.access();
  std::iota(specNums.begin(), specNums.end(), 1);
}

/// Construct with given spectrum number and vector of detector IDs for each
/// index.
IndexInfo::IndexInfo(std::vector<specnum_t> &&spectrumNumbers,
                     std::vector<std::vector<detid_t>> &&detectorIDs)
    : m_size(spectrumNumbers.size()) {
  if (spectrumNumbers.size() != detectorIDs.size())
    throw std::runtime_error("IndexInfo: Size mismatch between spectrum number "
                             "and detector ID vectors");
  m_spectrumNumbers.access() = std::move(spectrumNumbers);
  m_detectorIDs.access() = std::move(detectorIDs);
}

// Defined as default in source for forward declaration with std::unique_ptr.
IndexInfo::~IndexInfo() = default;

/// The *local* size, i.e., the number of spectra in this partition.
size_t IndexInfo::size() const { return m_size; }
/// Returns the spectrum number for given index.
specnum_t IndexInfo::spectrumNumber(const size_t index) const {
  return (*m_spectrumNumbers)[index];
}

/// Return a vector of the detector IDs for given index.
const std::vector<detid_t> &IndexInfo::detectorIDs(const size_t index) const {
  return (*m_detectorIDs)[index];
}

/// Set a spectrum number for each index.
void IndexInfo::setSpectrumNumbers(std::vector<specnum_t> &&spectrumNumbers) & {
  if (size() != spectrumNumbers.size())
        "IndexInfo: Size mismatch when setting new spectrum numbers");
  m_spectrumNumbers.access() = std::move(spectrumNumbers);
/// Set a single detector ID for each index.
void IndexInfo::setDetectorIDs(const std::vector<detid_t> &detectorIDs) & {
  if (size() != detectorIDs.size())
        "IndexInfo: Size mismatch when setting new detector IDs");
  auto &detIDs = m_detectorIDs.access();
  for (size_t i = 0; i < detectorIDs.size(); ++i)
    detIDs[i] = {detectorIDs[i]};
  // Setting new detector ID grouping makes definitions outdated.
  m_spectrumDefinitions =
      Kernel::cow_ptr<std::vector<SpectrumDefinition>>(nullptr);
/// Set a vector of detector IDs for each index.
void IndexInfo::setDetectorIDs(
    std::vector<std::vector<detid_t>> &&detectorIDs) & {
  if (size() != detectorIDs.size())
        "IndexInfo: Size mismatch when setting new detector IDs");

  auto &detIDs = m_detectorIDs.access();
  detIDs = std::move(detectorIDs);
  for (auto &ids : detIDs) {
    std::sort(ids.begin(), ids.end());
    ids.erase(std::unique(ids.begin(), ids.end()), ids.end());
  }
  // Setting new detector ID grouping makes definitions outdated.
  m_spectrumDefinitions =
      Kernel::cow_ptr<std::vector<SpectrumDefinition>>(nullptr);
void IndexInfo::setSpectrumDefinitions(
    Kernel::cow_ptr<std::vector<SpectrumDefinition>> spectrumDefinitions) {
  if (!spectrumDefinitions || (size() != spectrumDefinitions->size()))
    throw std::runtime_error(
        "IndexInfo: Size mismatch when setting new spectrum definitions");
  m_spectrumDefinitions = spectrumDefinitions;
}

const Kernel::cow_ptr<std::vector<SpectrumDefinition>> &
IndexInfo::spectrumDefinitions() const {
  return m_spectrumDefinitions;
}

} // namespace Indexing
} // namespace Mantid