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
157 if (ws1.getInstrument()->getName() != ws2.getInstrument()->getName()) {
158 const std::string message("The input workspaces are not compatible because "
159 "they come from different instruments");
160 throw std::invalid_argument(message);
161 }
162
163 Unit_const_sptr ws1_unit = ws1.getAxis(0)->unit();
164 Unit_const_sptr ws2_unit = ws2.getAxis(0)->unit();
165 const std::string ws1_unitID = (ws1_unit ? ws1_unit->unitID() : "");
166 const std::string ws2_unitID = (ws2_unit ? ws2_unit->unitID() : "");
167
168 if (ws1_unitID != ws2_unitID) {
169 const std::string message("The input workspaces are not compatible because "
170 "they have different units on the X axis");
171 throw std::invalid_argument(message);
172 }
173
174 if (ws1.isDistribution() != ws2.isDistribution()) {
175 const std::string message("The input workspaces have inconsistent distribution flags");
176 throw std::invalid_argument(message);
177 }
178}
179
188 size_t length = ws.getNumberHistograms();
189 // initial values
190 min = max = ws.getSpectrum(0).getSpectrumNo();
191 for (size_t i = 0; i < length; i++) {
192 const auto temp = ws.getSpectrum(i).getSpectrumNo();
193 // Adjust min/max
194 if (temp < min)
195 min = temp;
196 if (temp > max)
197 max = temp;
198 }
199}
200
201} // 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...
#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:76
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:96
specnum_t getSpectrumNo() const
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 the same instrument, unit and distribution flag.
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.
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:196
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.
int32_t specnum_t
Typedef for a spectrum Number.
Definition IDTypes.h:14