Skip to content
Snippets Groups Projects
Algorithm.tcc 6.93 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 "MantidAPI/Algorithm.h"
#include "MantidAPI/IndexProperty.h"
#include "MantidAPI/WorkspaceProperty.h"
LamarMoore's avatar
LamarMoore committed
#include "MantidIndexing/SpectrumIndexSet.h"

namespace {
template <typename T1, typename T2>
void setWorkspaceProperty(Mantid::API::WorkspaceProperty<T1> *wsProp,
                          const T2 &wksp, const boost::true_type &) {
  *wsProp = wksp;
}

template <typename T1, typename T2>
void setWorkspaceProperty(Mantid::API::WorkspaceProperty<T1> *wsProp,
                          const T2 &wksp, const boost::false_type &) {
  wsProp->setValue(wksp);
}
} // namespace

namespace Mantid {
namespace API {
/** Declare a property which defines the workspace and allowed index types, as
* well as a property for capturing the indices all at once. This method is
* only enabled if T is convertible to MatrixWorkspace.
@param propertyName Name of property which will be reserved
@param allowedIndexTypes combination of allowed index types. Default
IndexType::WorkspaceIndex
@param wsPropArgs a parameter pack of arguments forwarded to WorkspaceProperty.
Can contain PropertyMode, LockMode, and validators.
@param doc Property documentation string.
*/
template <typename T, const int AllowedIndexTypes, typename... WSPropArgs,
          typename>
LamarMoore's avatar
LamarMoore committed
void Algorithm::declareWorkspaceInputProperties(const std::string &propertyName,
                                                const std::string &doc,
                                                WSPropArgs &&... wsPropArgs) {
  auto wsProp = std::make_unique<WorkspaceProperty<T>>(
      propertyName, "", Kernel::Direction::Input,
      std::forward<WSPropArgs>(wsPropArgs)...);
LamarMoore's avatar
LamarMoore committed
  const auto &wsPropRef = *wsProp;
  declareProperty(std::move(wsProp), doc);

  auto indexTypePropName =
      IndexTypeProperty::generatePropertyName(propertyName);
Sam Jenkins's avatar
Sam Jenkins committed
  auto indexTypeProp =
      std::make_unique<IndexTypeProperty>(indexTypePropName, AllowedIndexTypes);
LamarMoore's avatar
LamarMoore committed
  const auto &indexTypePropRef = *indexTypeProp;

  declareProperty(std::move(indexTypeProp),
                  "The type of indices in the optional index set; For optimal "
                  "performance WorkspaceIndex should be preferred;");
LamarMoore's avatar
LamarMoore committed

  auto indexPropName = IndexProperty::generatePropertyName(propertyName);
  declareProperty(std::make_unique<IndexProperty>(indexPropName, wsPropRef,
Sam Jenkins's avatar
Sam Jenkins committed
                                                  indexTypePropRef),
                  "An optional set of spectra that will be processed by the "
                  "algorithm; If not set, all spectra will be processed; The "
                  "indices in this list can be workspace indices or possibly "
                  "spectrum numbers, depending on the selection made for the "
                  "index type; Indices are entered as a comma-separated list "
                  "of values, and/or ranges; For example, '4,6,10-20,1000';");
  m_reservedList.emplace_back(propertyName);
  m_reservedList.emplace_back(indexTypePropName);
  m_reservedList.emplace_back(indexPropName);
template <typename T1, typename T2, typename WsType>
LamarMoore's avatar
LamarMoore committed
void Algorithm::doSetInputProperties(const std::string &name, const T1 &wksp,
                                     IndexType type, const T2 &list) {
  if (!isCompoundProperty(name))
LamarMoore's avatar
LamarMoore committed
    throw std::runtime_error(
        "Algorithm::setWorkspaceInputProperties can only be used "
        "with properties declared using "
        "declareWorkspaceInputProperties.");
  auto *wsProp =
      dynamic_cast<WorkspaceProperty<WsType> *>(getPointerToProperty(name));
  auto *indexTypeProp = dynamic_cast<IndexTypeProperty *>(
      getPointerToProperty(IndexTypeProperty::generatePropertyName(name)));
LamarMoore's avatar
LamarMoore committed
  auto *indexProp = dynamic_cast<IndexProperty *>(
      getPointerToProperty(IndexProperty::generatePropertyName(name)));
  setWorkspaceProperty<WsType, T1>(
      wsProp, wksp, boost::is_convertible<T1, boost::shared_ptr<WsType>>());

  *indexTypeProp = type;

  *indexProp = list;
}

/** Mechanism for setting the index property with a workspace shared pointer.
* This method can only be used if T1 is convertible to a MatrixWorkspace and
* T2 is either std::string or std::vector<int>

@param name Property name
@param wksp Workspace as a pointer
@param type Index type IndexType::WorkspaceIndex or IndexType::SpectrumNum
@param list List of indices to be used.
*/
template <typename T1, typename T2, typename, typename>
LamarMoore's avatar
LamarMoore committed
void Algorithm::setWorkspaceInputProperties(const std::string &name,
                                            const boost::shared_ptr<T1> &wksp,
                                            IndexType type, const T2 &list) {
  doSetInputProperties<boost::shared_ptr<T1>, T2, T1>(name, wksp, type, list);
}

/** Mechanism for setting the index property with a workspace shared pointer.
* This method can only be used if T1 is convertible to a MatrixWorkspace and
* T2 is either std::string or std::vector<int64_t>
@param name Property name
LamarMoore's avatar
LamarMoore committed
@param wsName Workspace name as string
@param type Index type IndexType::WorkspaceIndex or IndexType::SpectrumNum
@param list List of indices to be used.
*/
template <typename T1, typename T2, typename, typename>
LamarMoore's avatar
LamarMoore committed
void Algorithm::setWorkspaceInputProperties(const std::string &name,
                                            const std::string &wsName,
                                            IndexType type, const T2 &list) {
  doSetInputProperties<std::string, T2, T1>(name, wsName, type, list);
}

/** Mechanism for retriving the index property. This method can only be used
if T is convertible to a MatrixWorkspace.

@param name Property name
@returns Tuple containing Workspace shared pointer and SpectrumIndexSet
*/
template <typename T, typename>
std::tuple<boost::shared_ptr<T>, Indexing::SpectrumIndexSet>
LamarMoore's avatar
LamarMoore committed
Algorithm::getWorkspaceAndIndices(const std::string &name) const {
  if (!isCompoundProperty(name))
LamarMoore's avatar
LamarMoore committed
    throw std::runtime_error(
        "Algorithm::getWorkspacesAndIndices can only be used "
        "with properties declared using "
        "declareWorkspaceInputProperties.");
LamarMoore's avatar
LamarMoore committed
  boost::shared_ptr<T> ws = getProperty(name);

  // Not able to use the regular getProperty mechanism because types, in this
  // case SpectrumIndexSet, need to be known upfront. Since SpectrumIndexSet is
  // not declared at a level where it can be used in Kernel, this will not work.
  // There is an issue which has been created which may solve this and other
  // problems related to the property mechanism in the future:
  // https://github.com/mantidproject/mantid/issues/20092

  auto indexProp = dynamic_cast<IndexProperty *>(
      getPointerToProperty(IndexProperty::generatePropertyName(name)));
LamarMoore's avatar
LamarMoore committed
  Indexing::SpectrumIndexSet indexSet = *indexProp;
LamarMoore's avatar
LamarMoore committed
  return std::make_tuple(ws, indexSet);
}
} // namespace API