Skip to content
Snippets Groups Projects
IndexProperty.cpp 4.53 KiB
Newer Older
#include "MantidAPI/IndexProperty.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidIndexing/GlobalSpectrumIndex.h"
#include "MantidIndexing/IndexInfo.h"
#include "MantidIndexing/SpectrumNumber.h"

namespace Mantid {
namespace API {
IndexProperty::IndexProperty(const std::string &name,
                             const IWorkspaceProperty &workspaceProp,
                             const IndexTypeProperty &indexTypeProp,
                             Kernel::IValidator_sptr validator)
    : ArrayProperty(name, "", 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;

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

  return error;
}

IndexProperty& IndexProperty::operator=(const std::string &rhs) {
  setValue(rhs);
  return *this;
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 {
      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;
        for (const auto index : m_value)
          spectrumNumbers.push_back(static_cast<Indexing::SpectrumNumber>(
              static_cast<int32_t>(index)));
        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;
    for (const auto index : m_value)
      spectrumNumbers.push_back(
          static_cast<Indexing::SpectrumNumber>(static_cast<int32_t>(index)));
    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