21#include "MantidIndexing/IndexInfo.h"
33 std::vector<Mantid::detid_t> nonMonitorDetectors;
34 nonMonitorDetectors.reserve(pixelIDs.size());
36 for (
Mantid::detid_t detIdx = 0; std::cmp_less(detIdx, pixelIDs.size()); detIdx++) {
38 nonMonitorDetectors.push_back(pixelIDs.at(detIdx));
41 return nonMonitorDetectors;
59 std::make_shared<CommonBinsValidator>()),
60 "The name of the first input workspace");
62 std::make_shared<CommonBinsValidator>()),
63 "The name of the second input workspace");
65 declareProperty(
"ValidateInputs",
true,
"Perform a set of checks that the two input workspaces are compatible.");
67 "Append the spectra from InputWorkspace2 multiple times.");
70 "The name of the output workspace");
72 declareProperty(
"MergeLogs",
false,
"Whether to combine the logs of the two input workspaces");
74 "Whether to append y axis labels; this is done automatically if there is spectra overlap");
76 "Rewrites the detectorID associated with each spectrum, moving each detector to the position on the "
77 "original workspace");
81 std::map<std::string, std::string> inputs;
88 if (((eventWs1) && (!eventWs2)) || ((!eventWs1) && (eventWs2))) {
89 const std::string msg =
"Only one of the input workspaces are of type "
90 "EventWorkspace; please use matching workspace "
91 "types (both EventWorkspace or both "
93 inputs[
"InputWorkspace1"] = msg;
94 inputs[
"InputWorkspace2"] = msg;
98 inputs[
"RewriteSpectraMap"] +=
"Rewrite spectra only implemented when number is 1. ";
100 if (
const auto &inst1Name = ws1->getInstrumentName(), inst2Name = ws2->getInstrumentName();
101 inst1Name.empty() || inst2Name.empty() || (inst1Name != inst2Name)) {
102 inputs[
"RewriteSpectraMap"] +=
"Both input workspace must have valid instruments to rewrite the spectra maps.";
105 const auto &spectrumInfo =
workspace->spectrumInfo();
108 if (!spectrumInfo.isMonitor(
index))
113 if (ws1->getInstrument()->getNumberDetectors(
true) < countNonMonitorSpectra(ws1) + countNonMonitorSpectra(ws2)) {
114 inputs[
"RewriteSpectraMap"] +=
115 "There are less available detectors than total number of spectrum in the appended workspace. "
116 "Not possible to rewrite their positions.";
132 bool ValidateInputs = this->
getProperty(
"ValidateInputs");
133 if (ValidateInputs) {
142 if (eventWs1 && eventWs2) {
145 for (
int i = 1; i < number; i++) {
146 eOutput = this->
execEvent(*eOutput, *eventWs2);
148 output = std::static_pointer_cast<MatrixWorkspace>(eOutput);
151 if (ws1->blocksize() != ws2->blocksize())
152 throw std::runtime_error(
"Workspace2D's must have the same number of bins.");
155 for (
int i = 1; i < number; i++) {
164 combineLogs(ws1->run(), ws2->run(), output->mutableRun());
167 setProperty(
"OutputWorkspace", std::dynamic_pointer_cast<MatrixWorkspace>(output));
188 const bool appendYAxis =
getProperty(
"AppendYAxisLabels");
189 if (ws2min <= ws1max) {
195 }
else if (appendYAxis) {
202 const auto yAxisNum = 1;
203 const auto yAxisWS1 = ws1.
getAxis(yAxisNum);
204 const auto yAxisWS2 = ws2.
getAxis(yAxisNum);
205 const auto outputYAxis = output.
getAxis(yAxisNum);
208 const bool isSpectra = yAxisWS1->isSpectra() && yAxisWS2->isSpectra();
209 const bool isTextAxis = yAxisWS1->isText() && yAxisWS2->isText();
210 const bool isNumericAxis = yAxisWS1->isNumeric() && yAxisWS2->isNumeric();
212 if (!isSpectra && !isTextAxis && !isNumericAxis) {
213 const std::string message(
214 "Y-Axis type mismatch. Ensure that the Y-axis types in both workspaces match. The Y-axis should be set to the "
215 "same type in each workspace, whether it be Numeric, Spectra, or Text.");
217 throw std::invalid_argument(message);
222 auto outputTextAxis =
dynamic_cast<TextAxis *
>(outputYAxis);
224 for (
size_t i = 0; i < outputLen; ++i) {
227 const std::string inputLabel = i < ws1Len ? yAxisWS1->label(i) : yAxisWS2->label(i - ws1Len);
228 outputTextAxis->setLabel(i, !inputLabel.empty() ? inputLabel :
"");
230 }
else if (isNumericAxis) {
232 const double inputVal = i < ws1Len ? yAxisWS1->getValue(i) : yAxisWS2->getValue(i - ws1Len);
233 outputYAxis->setValue(i, inputVal);
249 const size_t lenWs1 = ws1->getNumberHistograms();
250 const size_t totLength = lenWs1 + ws2->getNumberHistograms();
251 const auto &detectorInfo = output->detectorInfo();
252 const auto &pixelIDs = getDetectorsSkippingMonitors(detectorInfo);
254 auto &componentInfo = output->mutableComponentInfo();
255 const auto &spInfo1 = ws1->spectrumInfo();
256 const auto &spInfo2 = ws2->spectrumInfo();
258 for (
size_t i = 0; i < totLength; i++) {
259 if (i < lenWs1 ? spInfo1.isMonitor(i) : spInfo2.isMonitor(i - lenWs1)) {
262 const auto pos = i < lenWs1 ? spInfo1.position(i) : spInfo2.position(i - lenWs1);
263 const auto detID = pixelIDs.at(detIndex);
265 const auto &detIDidx = detectorInfo.
indexOf(detID);
266 auto &sp = output->getSpectrum(i);
268 componentInfo.setPosition(detIDidx, pos);
269 sp.setDetectorID(detID);
#define DECLARE_ALGORITHM(classname)
const std::vector< double > & rhs
IPeaksWorkspace_sptr workspace
std::map< DeltaEMode::Type, std::string > index
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
bool isDefault(const std::string &name) const
Stores numeric values that are assumed to be bin edge values.
Base MatrixWorkspace Abstract Class.
virtual std::size_t getNumberHistograms() const =0
Returns the number of histograms in the workspace.
const Indexing::IndexInfo & indexInfo() const
Returns a const reference to the IndexInfo object of the workspace.
virtual Axis * getAxis(const std::size_t &axisIndex) const
Get a non owning pointer to a workspace axis.
void setIndexInfo(const Indexing::IndexInfo &indexInfo)
Sets the IndexInfo object of the workspace.
This class stores information regarding an experimental run as a series of log entries.
Class to represent a text axis of a workspace.
A property class for workspaces.
Joins two partial, non-overlapping workspaces into one.
void combineLogs(const API::Run &lhs, const API::Run &rhs, API::Run &ans)
void rewriteSpectraMap(const API::MatrixWorkspace_const_sptr &ws1, const API::MatrixWorkspace_const_sptr &ws2, const API::MatrixWorkspace_sptr &output)
void appendYAxisLabels(const API::MatrixWorkspace &ws1, const API::MatrixWorkspace &ws2, const API::MatrixWorkspace &output)
void fixSpectrumNumbers(const API::MatrixWorkspace &ws1, const API::MatrixWorkspace &ws2, API::MatrixWorkspace &output) override
If there is an overlap in spectrum numbers between ws1 and ws2 or the y axis is a bin edges axis,...
int version() const override
Algorithm's version for identification.
void init() override
Initialize the algorithm's properties.
void exec() override
Execute the algorithm.
std::map< std::string, std::string > validateInputs() override
Method checking errors on ALL the inputs, before execution.
void checkCompatibility(const API::MatrixWorkspace &ws1, const API::MatrixWorkspace &ws2)
Checks that the two input workspace have the same instrument, unit and distribution flag.
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.
Geometry::DetectorInfo is an intermediate step towards a DetectorInfo that is part of Instrument-2....
const std::vector< detid_t > & detectorIDs() const
Returns a sorted vector of all detector IDs.
size_t indexOf(const detid_t id) const
Returns the index of the detector with the given detector ID.
bool isMonitor(const size_t index) const
Returns true if the detector is a monitor.
BoundedValidator is a validator that requires the values to be between upper or lower bounds,...
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< const EventWorkspace > EventWorkspace_const_sptr
shared pointer to a const Workspace2D
std::shared_ptr< EventWorkspace > EventWorkspace_sptr
shared pointer to the EventWorkspace class
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
int32_t detid_t
Typedef for a detector ID.
int32_t specnum_t
Typedef for a spectrum Number.
@ Input
An input workspace.
@ Output
An output workspace.