Mantid
Loading...
Searching...
No Matches
SpectrumAlgorithm.h
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2016 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7#pragma once
8
9#include <tuple>
10
11#include "MantidAPI/Algorithm.h"
13#include "MantidAlgorithms/DllConfig.h"
15
16namespace Mantid {
17
18namespace DataObjects {
19class EventWorkspace;
20}
21
22namespace Algorithms {
23
37class MANTID_ALGORITHMS_DLL SpectrumAlgorithm : public API::Algorithm {
38private:
43 template <std::size_t...> struct seq {};
44 // Doxygen does not like recursive types.
45 template <std::size_t N, std::size_t... S>
46 struct gens
47 : gens<N - 1, N - 1, S...> {
48 };
49 template <std::size_t... S> struct gens<0, S...> {
50 using type = seq<S...>;
51 };
52
57 template <typename Tp, typename... List> struct contains : std::true_type {};
58 template <typename Tp, typename Head, typename... Rest>
59 struct contains<Tp, Head, Rest...>
60 : std::conditional<std::is_same<Tp, Head>::value, std::true_type, contains<Tp, Rest...>>::type {};
61 template <typename Tp> struct contains<Tp> : std::false_type {};
62
64 template <class... Flags, class WS, class T, std::size_t... S, class OP>
65 void for_each(WS &workspace, T getters, seq<S...>, const OP &operation) {
66 // If we get the flag Indices::FromProperty we use a potential user-defined
67 // range property, otherwise default to the full range of all histograms.
68 Kernel::IndexSet indexSet(workspace.getNumberHistograms());
70 indexSet = getWorkspaceIndexSet(workspace);
71 auto size = static_cast<int64_t>(indexSet.size());
72 API::Progress progress(this, 0.0, 1.0, size);
73
74 PARALLEL_FOR_IF(Kernel::threadSafe(workspace))
75 for (int64_t i = 0; i < size; ++i) {
77 // Note the small but for now negligible overhead from the IndexSet access
78 // in the case where it is not used.
79 operation(std::get<S>(getters)(workspace, indexSet[i])...);
80 progress.report(name());
82 }
84
85 ifEventWorkspaceClearMRU(workspace);
86 }
87
90 template <class WS> void ifEventWorkspaceClearMRU(const WS &workspace) { UNUSED_ARG(workspace); }
91
95
96protected:
97 ~SpectrumAlgorithm() = default;
98
100 // A strongly typed enum used in non-type variadic template arguments would
101 // have been the other candidate. However, combining flags from multiple enums
102 // would not have been possible, so all flags would have been required to be
103 // in the same scoped enum, and we want to avoid noisy flag definitions like
104 // Flags::IndicesFromProperty or Flags::SkipMasked.
105 struct Indices {
107 struct FromProperty {};
108 };
109
121 template <class... Flags, class WS, class... Args, class OP>
122 void for_each(WS &workspace, std::tuple<Args...> getters, const OP &operation) {
123 // This comment explains some of the rationale and mechanism for the way
124 // templates are used in this and other variants of for_each().
125 // For several variants of for_each() we require a variable number of
126 // arguments for more than one entity, e.g., getters for the input workspace
127 // and getters for the output workspace. For both of them we would thus like
128 // to use a variadic template. However, we cannot make all those getters
129 // direct arguments to for_each(), because the compiler then cannot tell
130 // were the boundary between the two parameter packs is. Therefore getters
131 // are packed into tuples.
132 // At some point we need to extract the getters from the tuple. To this end,
133 // we use the gens template, which recursively constructs a sequence of
134 // indices which are gen used with std::get<>.
135 // The Flags template parameter is used for passing in flags known at
136 // compile time.
137 for_each<Flags...>(workspace, getters, typename gens<sizeof...(Args)>::type(), operation);
138 }
139
140 void declareWorkspaceIndexSetProperties(const std::string &indexMinPropertyName = "IndexMin",
141 const std::string &indexMaxPropertyName = "IndexMax",
142 const std::string &indexRangePropertyName = "WorkspaceIndexList");
143 Kernel::IndexSet getWorkspaceIndexSet(const API::MatrixWorkspace &workspace) const;
144};
145
147
149using SpectrumAlgorithm_sptr = std::shared_ptr<SpectrumAlgorithm>;
150
151} // namespace Algorithms
152} // namespace Mantid
IPeaksWorkspace_sptr workspace
Definition: IndexPeaks.cpp:114
#define PARALLEL_START_INTERRUPT_REGION
Begins a block to skip processing is the algorithm has been interupted Note the end of the block if n...
Definition: MultiThreaded.h:94
#define PARALLEL_END_INTERRUPT_REGION
Ends a block to skip processing is the algorithm has been interupted Note the start of the block if n...
#define PARALLEL_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition: System.h:64
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:85
Base MatrixWorkspace Abstract Class.
Helper class for reporting progress from algorithms.
Definition: Progress.h:25
SpectrumAlgorithm is a base class for algorithms that work with MatrixWorkspace.
void for_each(WS &workspace, T getters, seq< S... >, const OP &operation)
Internal implementation of for_each().
void for_each(WS &workspace, std::tuple< Args... > getters, const OP &operation)
Provides a mechanism for looping over spectra in a workspace.
void ifEventWorkspaceClearMRU(const WS &workspace)
Templated function used as 'compile-time conditional', together with specialization.
This class is intended to fulfill the design specified in <https://github.com/mantidproject/documents...
IndexSet is a container that can be used to define and access a subset of elements in a larger contai...
Definition: IndexSet.h:26
size_t size() const
Returns the size of the set.
Definition: IndexSet.h:33
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
Definition: ProgressBase.h:51
std::shared_ptr< SpectrumAlgorithm > SpectrumAlgorithm_sptr
Typedef for a shared pointer to a SpectrumAlgorithm.
Helper class which provides the Collimation Length for SANS instruments.
Flag: Include only indices specified via properties in for_each.
Dummy struct holding compile-time flags to for_each().
Helpers for for_each(), struct contains and 2 specializations.
Helpers for for_each(), struct seq and gens with a specialization.