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, Kernel::Direction::Input),
m_workspaceProp(workspaceProp), m_indexTypeProp(indexTypeProp), m_min(0),
m_max(0), m_indices(0), m_indicesExtracted(false) {}
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.";
}
if (!m_validString.empty())
error += " " + m_validString;
return error;
}
std::vector<int> &IndexProperty::operator=(const std::vector<int> &rhs) {
m_indicesExtracted = false;
m_min = m_max = 0;
m_validString = "";
// Instead of just copying vector, determine if we have a pure range.
if (rhs.size() > 0) {
auto res = std::minmax_element(rhs.cbegin(), rhs.cend());
auto minIndex = res.first - rhs.begin();
auto maxIndex = res.second - rhs.begin();
bool isPureRange = (rhs[maxIndex] - rhs[minIndex] + 1) == rhs.size();
if (isPureRange) {
m_min = static_cast<size_t>(rhs[0]);
m_max = static_cast<size_t>(rhs[rhs.size() - 1]);
m_value = std::vector<int>();
} else
m_value = rhs;
}
return m_value;
}
std::string IndexProperty::setValue(const std::string &value) {
m_indicesExtracted = false;
m_min = m_max = 0;
// Check whether or not string value is simply a range
if (std::count(value.cbegin(), value.cend(), ':') == 1 &&
std::count(value.cbegin(), value.cend(), ',') == 0) {
auto pos = value.find(":");
auto min = value.substr(0, pos);
auto max = value.substr(pos + 1, value.size() - 1);
std::string err = "";
try {
m_min = stoi(min);
m_max = stoi(max);
} catch (std::invalid_argument &) {
err += value + " could not be converted to integer list.";
}
if (!err.empty())
return m_validString = err;
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
if (m_min >= m_max)
err += " min should be less than max";
if (m_min < 0 || m_max < 0)
err += " min and max values should be greater than zero";
return m_validString = err;
} else {
return m_validString = ArrayProperty<int>::setValue(value);
}
}
std::string IndexProperty::value() const {
if (m_min != m_max)
return std::to_string(m_min) + ":" + std::to_string(m_max);
else
return ArrayProperty<int>::value();
}
Indexing::SpectrumIndexSet IndexProperty::getIndices() const {
if (m_indicesExtracted)
return m_indices;
auto wksp = boost::dynamic_pointer_cast<MatrixWorkspace>(
m_workspaceProp.getWorkspace());
if (wksp == nullptr)
throw std::runtime_error("Invalid workspace type provided to "
"IndexProperty. Must be convertible to "
"MatrixWorkspace.");
const auto &indexInfo = wksp->indexInfo();
auto type = m_indexTypeProp.selectedType();
if (m_min != m_max) {
switch (type) {
case IndexType::WorkspaceIndex:
return m_indices = indexInfo.makeIndexSet(
static_cast<Indexing::GlobalSpectrumIndex>(m_min),
static_cast<Indexing::GlobalSpectrumIndex>(m_max));
case IndexType::SpectrumNum:
return m_indices = indexInfo.makeIndexSet(
static_cast<Indexing::SpectrumNumber>(m_min),
static_cast<Indexing::SpectrumNumber>(m_max));
}
} else if (m_value.empty()) {
return m_indices = indexInfo.makeIndexSet();
} else {
switch (type) {
case IndexType::WorkspaceIndex:
return m_indices = indexInfo.makeIndexSet(
std::vector<Indexing::GlobalSpectrumIndex>(m_value.begin(),
m_value.end()));
case IndexType::SpectrumNum:
return m_indices =
indexInfo.makeIndexSet(std::vector<Indexing::SpectrumNumber>(
m_value.begin(), m_value.end()));
}
}
m_indicesExtracted = true;
return m_indices;
}
} // namespace API
} // namespace Mantid