Skip to content
Snippets Groups Projects
IndexProperty.cpp 5.01 KiB
Newer Older
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
//   NScD Oak Ridge National Laboratory, European Spallation Source,
//   Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#include <utility>

#include "MantidAPI/IndexProperty.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidIndexing/GlobalSpectrumIndex.h"
#include "MantidIndexing/IndexInfo.h"
#include "MantidIndexing/SpectrumNumber.h"
#include "MantidKernel/WarningSuppressions.h"
namespace Mantid {
namespace API {
IndexProperty::IndexProperty(const std::string &name,
                             const IWorkspaceProperty &workspaceProp,
                             const IndexTypeProperty &indexTypeProp,
                             const Kernel::IValidator_sptr &validator)
    : ArrayProperty(name, "", std::move(validator)),
      m_workspaceProp(workspaceProp), m_indexTypeProp(indexTypeProp),
      m_indices(0), m_indicesExtracted(false) {}
IndexProperty *IndexProperty::clone() const { return new IndexProperty(*this); }

bool IndexProperty::isDefault() const { return m_value.empty(); }
LamarMoore's avatar
LamarMoore committed

std::string IndexProperty::isValid() const {
  std::string error;
  // No workspace acts as an empty set and so is considered valid
  if (!m_workspaceProp.getWorkspace())
    return error;

  try {
    getIndices();
  } catch (std::runtime_error &e) {
    error = e.what();
  } catch (std::out_of_range &e) {
    error = "Indices provided to IndexProperty are out of range: ";
    error.append(e.what());
  } catch (std::logic_error &) {
    error = "Duplicate indices supplied to IndexProperty.";
  }

  return error;
}

IndexProperty &IndexProperty::operator=(const std::string &rhs) {
LamarMoore's avatar
LamarMoore committed
}

LamarMoore's avatar
LamarMoore committed
IndexProperty::operator Indexing::SpectrumIndexSet() const {
  return getIndices();
}

Indexing::SpectrumIndexSet IndexProperty::getIndices() const {
  const auto &indexInfo = getIndexInfoFromWorkspace();
  auto type = m_indexTypeProp.selectedType();

  if (m_value.empty()) {
    return indexInfo.makeIndexSet();
  } else {
    auto min = m_value.front();
    auto max = m_value.back();
LamarMoore's avatar
LamarMoore committed
    auto isRange = (max - min) == static_cast<int>(m_value.size() - 1);
    if (isRange) {
      switch (type) {
      case IndexType::WorkspaceIndex:
        return indexInfo.makeIndexSet(
            static_cast<Indexing::GlobalSpectrumIndex>(min),
            static_cast<Indexing::GlobalSpectrumIndex>(max));
      case IndexType::SpectrumNum:
        return indexInfo.makeIndexSet(
            static_cast<Indexing::SpectrumNumber>(static_cast<int32_t>(min)),
            static_cast<Indexing::SpectrumNumber>(static_cast<int32_t>(max)));
      }
    } else {
      MSVC_DIAG_OFF(4244);
      switch (type) {
      case IndexType::WorkspaceIndex:
        return indexInfo.makeIndexSet(
            std::vector<Indexing::GlobalSpectrumIndex>(m_value.begin(),
                                                       m_value.end()));
      case IndexType::SpectrumNum: {
        std::vector<Indexing::SpectrumNumber> spectrumNumbers(m_value.cbegin(),
                                                              m_value.cend());
        return indexInfo.makeIndexSet(spectrumNumbers);
      }
    }
  }

  m_indicesExtracted = true;
  return m_indices;
}
/** Return IndexInfo created from workspace but containing selected spectra.
 *
 * The selected spectra are the same as in the SpectrumIndexSet returned by this
 * property and the order is guaranteed to be consistent. That is, if the Nth
 * entry in the SpectrumIndexSet is M, the spectrum with index M in the input
 * workspace is equal to the spectrum with index N in the returned IndexInfo. */
Indexing::IndexInfo IndexProperty::getFilteredIndexInfo() const {
  const auto &indexInfo = getIndexInfoFromWorkspace();
  if (m_value.empty())
    return indexInfo;
  switch (m_indexTypeProp.selectedType()) {
  case IndexType::WorkspaceIndex:
    return {std::vector<Indexing::GlobalSpectrumIndex>(m_value.begin(),
                                                       m_value.end()),
            indexInfo};
  case IndexType::SpectrumNum: {
    std::vector<Indexing::SpectrumNumber> spectrumNumbers(m_value.cbegin(),
                                                          m_value.cend());
    return {spectrumNumbers, indexInfo};
  }
  default:
    throw std::runtime_error(
        "IndexProperty::getFilteredIndexInfo -- unsupported index type");
  }
}

std::string IndexProperty::generatePropertyName(const std::string &name) {
  return name + "IndexSet";
}

const Indexing::IndexInfo &IndexProperty::getIndexInfoFromWorkspace() const {
  auto wksp = boost::dynamic_pointer_cast<MatrixWorkspace>(
      m_workspaceProp.getWorkspace());
  if (!wksp)
    throw std::runtime_error("Invalid workspace type provided to "
                             "IndexProperty. Must be convertible to "
                             "MatrixWorkspace.");
  return wksp->indexInfo();
}

} // namespace API