Mantid
Loading...
Searching...
No Matches
WorkspaceJoiners.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 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 +
8
9#include "MantidAPI/Axis.h"
15#include "MantidKernel/Unit.h"
16
17namespace Mantid::Algorithms {
18
19using namespace Kernel;
20using namespace API;
21using namespace DataObjects;
22
25WorkspaceJoiners::WorkspaceJoiners() : Algorithm(), m_progress(nullptr) {}
26
28const std::string WorkspaceJoiners::category() const { return "Transforms\\Merging"; }
29
34 // Create the output workspace
35 const size_t totalHists = ws1.getNumberHistograms() + ws2.getNumberHistograms();
37 WorkspaceFactory::Instance().create("Workspace2D", totalHists, ws1.x(0).size(), ws1.y(0).size());
38 // Copy over stuff from first input workspace. This will include the spectrum
39 // masking
40 WorkspaceFactory::Instance().initializeFromParent(ws1, *output, true);
41
42 // Initialize the progress reporting object
43 m_progress = std::make_unique<API::Progress>(this, 0.0, 1.0, totalHists);
44
45 // Loop over the input workspaces in turn copying the data into the output one
46 const int64_t &nhist1 = ws1.getNumberHistograms();
48 for (int64_t i = 0; i < nhist1; ++i) {
50 auto &outSpec = output->getSpectrum(i);
51 const auto &inSpec = ws1.getSpectrum(i);
52
53 outSpec.setHistogram(inSpec.histogram());
54 // Copy the spectrum number/detector IDs
55 outSpec.copyInfoFrom(inSpec);
56
57 // Propagate binmasking, if needed
58 if (ws1.hasMaskedBins(i)) {
59 for (const auto &inputMask : ws1.maskedBins(i)) {
60 output->flagMasked(i, inputMask.first, inputMask.second);
61 }
62 }
63
64 m_progress->report();
66 }
68
69 // For second loop we use the offset from the first
70 const int64_t &nhist2 = ws2.getNumberHistograms();
71 const auto &spectrumInfo = ws2.spectrumInfo();
72 auto &outSpectrumInfo = output->mutableSpectrumInfo();
74 for (int64_t j = 0; j < nhist2; ++j) {
76 // The spectrum in the output workspace
77 auto &outSpec = output->getSpectrum(nhist1 + j);
78 // Spectrum in the second workspace
79 const auto &inSpec = ws2.getSpectrum(j);
80
81 outSpec.setHistogram(inSpec.histogram());
82 // Copy the spectrum number/detector IDs
83 outSpec.copyInfoFrom(inSpec);
84
85 // Propagate masking, if needed
86 if (ws2.hasMaskedBins(j)) {
87 for (const auto &inputMask : ws2.maskedBins(j)) {
88 output->flagMasked(nhist1 + j, inputMask.first, inputMask.second);
89 }
90 }
91 // Propagate spectrum masking
92 if (spectrumInfo.hasDetectors(j) && spectrumInfo.isMasked(j)) {
93 output->getSpectrum(nhist1 + j).clearData();
94 PARALLEL_CRITICAL(setMasked) { outSpectrumInfo.setMasked(nhist1 + j, true); }
95 }
96
97 m_progress->report();
99 }
101
102 fixSpectrumNumbers(ws1, ws2, *output);
103
104 return output;
105}
106
113 const DataObjects::EventWorkspace &eventWs2) {
114 // Create the output workspace
115 const size_t totalHists = eventWs1.getNumberHistograms() + eventWs2.getNumberHistograms();
116 auto output = create<EventWorkspace>(eventWs1, totalHists, eventWs1.binEdges(0));
117
118 // Initialize the progress reporting object
119 m_progress = std::make_unique<API::Progress>(this, 0.0, 1.0, totalHists);
120
121 const int64_t &nhist1 = eventWs1.getNumberHistograms();
122 for (int64_t i = 0; i < nhist1; ++i) {
123 output->getSpectrum(i) = eventWs1.getSpectrum(i);
124 m_progress->report();
125 }
126
127 // For second loop we use the offset from the first
128 const int64_t &nhist2 = eventWs2.getNumberHistograms();
129 const auto &spectrumInfo = eventWs2.spectrumInfo();
130 auto &outSpectrumInfo = output->mutableSpectrumInfo();
131 for (int64_t j = 0; j < nhist2; ++j) {
132 // This is the workspace index at which we assign in the output
133 int64_t outputWi = j + nhist1;
134 output->getSpectrum(outputWi) = eventWs2.getSpectrum(j);
135
136 // Propagate spectrum masking. First workspace will have been done by the
137 // factory
138 if (spectrumInfo.hasDetectors(j) && spectrumInfo.isMasked(j)) {
139 output->getSpectrum(outputWi).clearData();
140 PARALLEL_CRITICAL(setMaskedEvent) { outSpectrumInfo.setMasked(outputWi, true); }
141 }
142
143 m_progress->report();
144 }
145
146 fixSpectrumNumbers(eventWs1, eventWs2, *output);
147
148 return output;
149}
150
158 if (ws1.getInstrument()->getName() != ws2.getInstrument()->getName()) {
159 const std::string message("The input workspaces are not compatible because "
160 "they come from different instruments");
161 throw std::invalid_argument(message);
162 }
163
164 Unit_const_sptr ws1_unit = ws1.getAxis(0)->unit();
165 Unit_const_sptr ws2_unit = ws2.getAxis(0)->unit();
166 const std::string ws1_unitID = (ws1_unit ? ws1_unit->unitID() : "");
167 const std::string ws2_unitID = (ws2_unit ? ws2_unit->unitID() : "");
168
169 if (ws1_unitID != ws2_unitID) {
170 const std::string message("The input workspaces are not compatible because "
171 "they have different units on the X axis");
172 throw std::invalid_argument(message);
173 }
174
175 if (ws1.isDistribution() != ws2.isDistribution()) {
176 const std::string message("The input workspaces have inconsistent distribution flags");
177 throw std::invalid_argument(message);
178 }
179}
180
189 size_t length = ws.getNumberHistograms();
190 // initial values
191 min = max = ws.getSpectrum(0).getSpectrumNo();
192 for (size_t i = 0; i < length; i++) {
193 const auto temp = ws.getSpectrum(i).getSpectrumNo();
194 // Adjust min/max
195 if (temp < min)
196 min = temp;
197 if (temp > max)
198 max = temp;
199 }
200}
201
202} // namespace Mantid::Algorithms
#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_CRITICAL(name)
#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.
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:85
const std::shared_ptr< Kernel::Unit > & unit() const
The unit for this axis.
Definition: Axis.cpp:28
const SpectrumInfo & spectrumInfo() const
Return a reference to the SpectrumInfo object.
Geometry::Instrument_const_sptr getInstrument() const
Returns the parameterized instrument.
void setHistogram(T &&...data)
Sets the Histogram associated with this spectrum.
Definition: ISpectrum.h:97
specnum_t getSpectrumNo() const
Definition: ISpectrum.cpp:123
Base MatrixWorkspace Abstract Class.
const MaskList & maskedBins(const size_t &workspaceIndex) const
Returns the list of masked bins for a spectrum.
virtual ISpectrum & getSpectrum(const size_t index)=0
Return the underlying ISpectrum ptr at the given workspace index.
HistogramData::BinEdges binEdges(const size_t index) const
virtual std::size_t getNumberHistograms() const =0
Returns the number of histograms in the workspace.
bool hasMaskedBins(const size_t &workspaceIndex) const
Does this spectrum contain any masked bins.
const HistogramData::HistogramX & x(const size_t index) const
bool isDistribution() const
Are the Y-values dimensioned?
virtual Axis * getAxis(const std::size_t &axisIndex) const
Get a non owning pointer to a workspace axis.
const HistogramData::HistogramY & y(const size_t index) const
void checkCompatibility(const API::MatrixWorkspace &ws1, const API::MatrixWorkspace &ws2)
Checks that the two input workspace have common size and the same instrument & unit.
std::unique_ptr< API::Progress > m_progress
Progress reporting object.
DataObjects::EventWorkspace_sptr execEvent(const DataObjects::EventWorkspace &eventWs1, const DataObjects::EventWorkspace &eventWs2)
Executes the algorithm for event workspace inputs.
void getMinMax(const API::MatrixWorkspace &ws, specnum_t &min, specnum_t &max)
Determine the minimum and maximum spectra ids.
API::MatrixWorkspace_sptr execWS2D(const API::MatrixWorkspace &ws1, const API::MatrixWorkspace &ws2)
Executes the algorithm for histogram workspace inputs.
const std::string category() const override
Algorithm's category for identification.
virtual void fixSpectrumNumbers(const API::MatrixWorkspace &ws1, const API::MatrixWorkspace &ws2, API::MatrixWorkspace &output)=0
Abstract method to be implemented in concrete algorithm classes.
void clearData() override
Mask the spectrum to this value. Removes all events.
Definition: EventList.cpp:880
This class is intended to fulfill the design specified in <https://github.com/mantidproject/documents...
EventList & getSpectrum(const size_t index) override
Return the underlying ISpectrum ptr at the given workspace index.
std::size_t getNumberHistograms() const override
Get the number of histograms, usually the same as the number of pixels or detectors.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< EventWorkspace > EventWorkspace_sptr
shared pointer to the EventWorkspace class
std::shared_ptr< const Unit > Unit_const_sptr
Shared pointer to the Unit base class (const version)
Definition: Unit.h:231
std::enable_if< std::is_pointer< Arg >::value, bool >::type threadSafe(Arg workspace)
Thread-safety check Checks the workspace to ensure it is suitable for multithreaded access.
Definition: MultiThreaded.h:22
int32_t specnum_t
Typedef for a spectrum Number.
Definition: IDTypes.h:16