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"
16
17namespace Mantid {
18
19namespace DataObjects {
20class EventWorkspace;
21}
22
23namespace Algorithms {
24
38class MANTID_ALGORITHMS_DLL SpectrumAlgorithm : public API::Algorithm {
39private:
44 template <std::size_t...> struct seq {};
45 // Doxygen does not like recursive types.
46 template <std::size_t N, std::size_t... S>
47 struct gens
48 : gens<N - 1, N - 1, S...> {
49 };
50 template <std::size_t... S> struct gens<0, S...> {
51 using type = seq<S...>;
52 };
53
58 template <typename Tp, typename... List> struct contains : std::true_type {};
59 template <typename Tp, typename Head, typename... Rest>
60 struct contains<Tp, Head, Rest...>
61 : std::conditional<std::is_same<Tp, Head>::value, std::true_type, contains<Tp, Rest...>>::type {};
62 template <typename Tp> struct contains<Tp> : std::false_type {};
63
65 template <class... Flags, class WS, class T, std::size_t... S, class OP>
66 void for_each(WS &workspace, T getters, seq<S...>, const OP &operation) {
67 // If we get the flag Indices::FromProperty we use a potential user-defined
68 // range property, otherwise default to the full range of all histograms.
69 Kernel::IndexSet indexSet(workspace.getNumberHistograms());
71 indexSet = getWorkspaceIndexSet(workspace);
72 auto size = static_cast<int64_t>(indexSet.size());
73 API::Progress progress(this, 0.0, 1.0, size);
74
75 PARALLEL_FOR_IF(Kernel::threadSafe(workspace))
76 for (int64_t i = 0; i < size; ++i) {
78 // Note the small but for now negligible overhead from the IndexSet access
79 // in the case where it is not used.
80 operation(std::get<S>(getters)(workspace, indexSet[i])...);
81 progress.report(name());
83 }
85
86 ifEventWorkspaceClearMRU(workspace);
87 }
88
91 template <class WS> void ifEventWorkspaceClearMRU(const WS &workspace) { UNUSED_ARG(workspace); }
92
96
97protected:
98 ~SpectrumAlgorithm() override = default;
99
101 // A strongly typed enum used in non-type variadic template arguments would
102 // have been the other candidate. However, combining flags from multiple enums
103 // would not have been possible, so all flags would have been required to be
104 // in the same scoped enum, and we want to avoid noisy flag definitions like
105 // Flags::IndicesFromProperty or Flags::SkipMasked.
106 struct Indices {
108 struct FromProperty {};
109 };
110
122 template <class... Flags, class WS, class... Args, class OP>
123 void for_each(WS &workspace, std::tuple<Args...> getters, const OP &operation) {
124 // This comment explains some of the rationale and mechanism for the way
125 // templates are used in this and other variants of for_each().
126 // For several variants of for_each() we require a variable number of
127 // arguments for more than one entity, e.g., getters for the input workspace
128 // and getters for the output workspace. For both of them we would thus like
129 // to use a variadic template. However, we cannot make all those getters
130 // direct arguments to for_each(), because the compiler then cannot tell
131 // were the boundary between the two parameter packs is. Therefore getters
132 // are packed into tuples.
133 // At some point we need to extract the getters from the tuple. To this end,
134 // we use the gens template, which recursively constructs a sequence of
135 // indices which are gen used with std::get<>.
136 // The Flags template parameter is used for passing in flags known at
137 // compile time.
138 for_each<Flags...>(workspace, getters, typename gens<sizeof...(Args)>::type(), operation);
139 }
140
141 void declareWorkspaceIndexSetProperties(const std::string &indexMinPropertyName = "IndexMin",
142 const std::string &indexMaxPropertyName = "IndexMax",
143 const std::string &indexRangePropertyName = "WorkspaceIndexList");
144 Kernel::IndexSet getWorkspaceIndexSet(const API::MatrixWorkspace &workspace) const;
145};
146
148
150using SpectrumAlgorithm_sptr = std::shared_ptr<SpectrumAlgorithm>;
151
152} // namespace Algorithms
153} // namespace Mantid
std::string name
Definition Run.cpp:60
IPeaksWorkspace_sptr workspace
#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...
#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:48
Base class from which all concrete algorithm classes should be derived.
Definition Algorithm.h:76
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.
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.