Skip to content

Commit 6b9ffe2

Browse files
Add a CombineTableWorkspaces algorithm (#39181)
* initial algorithm and tests * test input validation checks * updated type coverage and tests * remove outputWS from validation * mark const variables, cast loop lengths to int * added doc page and release note * fix test warnings * fix loop type * more type casting * update reference links * review updates * test updates * add code to docs * change to inferred typing * change loop to size_t * Remove static_cast from for loop --------- Co-authored-by: James Clarke <139879523+jclarkeSTFC@users.noreply.github.com>
1 parent 297e6fa commit 6b9ffe2

File tree

6 files changed

+714
-0
lines changed

6 files changed

+714
-0
lines changed

Framework/Algorithms/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ set(SRC_FILES
4646
src/ClearMaskFlag.cpp
4747
src/CloneWorkspace.cpp
4848
src/CombineDiffCal.cpp
49+
src/CombineTableWorkspaces.cpp
4950
src/Comment.cpp
5051
src/CommutativeBinaryOperation.cpp
5152
src/CompareWorkspaces.cpp
@@ -396,6 +397,7 @@ set(INC_FILES
396397
inc/MantidAlgorithms/ClearMaskFlag.h
397398
inc/MantidAlgorithms/CloneWorkspace.h
398399
inc/MantidAlgorithms/CombineDiffCal.h
400+
inc/MantidAlgorithms/CombineTableWorkspaces.h
399401
inc/MantidAlgorithms/Comment.h
400402
inc/MantidAlgorithms/CommutativeBinaryOperation.h
401403
inc/MantidAlgorithms/CompareWorkspaces.h
@@ -753,6 +755,7 @@ set(TEST_FILES
753755
ClearMaskFlagTest.h
754756
CloneWorkspaceTest.h
755757
CombineDiffCalTest.h
758+
CombineTableWorkspacesTest.h
756759
CommentTest.h
757760
CommutativeBinaryOperationTest.h
758761
CompareWorkspacesTest.h
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Mantid Repository : https://github.com/mantidproject/mantid
2+
//
3+
// Copyright &copy; 2021 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 "MantidAPI/Algorithm.h"
10+
#include "MantidAlgorithms/DllConfig.h"
11+
#include "MantidDataObjects/TableWorkspace.h"
12+
13+
namespace Mantid {
14+
namespace Algorithms {
15+
16+
/** CombineTableWorkspaces : Take a pair of table workspaces and combine them into a single table
17+
* by appending the rows of the second onto the first
18+
*/
19+
class MANTID_ALGORITHMS_DLL CombineTableWorkspaces final : public API::Algorithm {
20+
public:
21+
const std::string name() const override;
22+
int version() const override;
23+
const std::string category() const override;
24+
const std::string summary() const override;
25+
std::map<std::string, std::string> validateInputs() override;
26+
static const std::map<std::string, int> &allowedTypes();
27+
28+
private:
29+
void init() override;
30+
void exec() override;
31+
};
32+
33+
} // namespace Algorithms
34+
} // namespace Mantid
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// Mantid Repository : https://github.com/mantidproject/mantid
2+
//
3+
// Copyright &copy; 2025 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+
8+
#include "MantidAlgorithms/CombineTableWorkspaces.h"
9+
#include "MantidAPI/TableRow.h"
10+
#include "MantidDataObjects/TableWorkspace.h"
11+
12+
namespace Mantid::Algorithms {
13+
using Mantid::API::Progress;
14+
using Mantid::API::TableRow;
15+
using Mantid::API::WorkspaceProperty;
16+
using Mantid::Kernel::Direction;
17+
using Mantid::Kernel::V3D;
18+
19+
// Register the algorithm into the AlgorithmFactory
20+
DECLARE_ALGORITHM(CombineTableWorkspaces)
21+
22+
//----------------------------------------------------------------------------------------------
23+
24+
/// Algorithms name for identification. @see Algorithm::name
25+
const std::string CombineTableWorkspaces::name() const { return "CombineTableWorkspaces"; }
26+
27+
/// Algorithm's version for identification. @see Algorithm::version
28+
int CombineTableWorkspaces::version() const { return 1; }
29+
30+
/// Algorithm's category for identification. @see Algorithm::category
31+
const std::string CombineTableWorkspaces::category() const { return "Utility\\Workspaces"; }
32+
33+
/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
34+
const std::string CombineTableWorkspaces::summary() const {
35+
return "Algorithm takes two table workspaces and, if they have the same column titles and data types, combines them "
36+
"into a single table. Currently supports data types of double, int, float, string, bool, size_t and V3D.";
37+
}
38+
39+
//----------------------------------------------------------------------------------------------
40+
/** Initialize the algorithm's properties.
41+
*/
42+
void CombineTableWorkspaces::init() {
43+
declareProperty(
44+
std::make_unique<WorkspaceProperty<DataObjects::TableWorkspace>>("LHSWorkspace", "", Direction::Input),
45+
"The first table workspace.");
46+
declareProperty(
47+
std::make_unique<WorkspaceProperty<DataObjects::TableWorkspace>>("RHSWorkspace", "", Direction::Input),
48+
"The second table workspace.");
49+
declareProperty(
50+
std::make_unique<WorkspaceProperty<DataObjects::TableWorkspace>>("OutputWorkspace", "", Direction::Output),
51+
"The combined table workspace.");
52+
}
53+
54+
const std::map<std::string, int> &CombineTableWorkspaces::allowedTypes() {
55+
static const std::map<std::string, int> types = {{"double", 0}, {"int", 1}, {"str", 2}, {"bool", 3},
56+
{"size_t", 4}, {"float", 5}, {"V3D", 6}};
57+
return types;
58+
}
59+
60+
std::map<std::string, std::string> CombineTableWorkspaces::validateInputs() {
61+
std::map<std::string, std::string> results;
62+
63+
const DataObjects::TableWorkspace_sptr LHSWorkspace = getProperty("LHSWorkspace");
64+
const DataObjects::TableWorkspace_sptr RHSWorkspace = getProperty("RHSWorkspace");
65+
66+
const std::size_t expectedCols = LHSWorkspace->columnCount();
67+
68+
// check correct number of columns
69+
if (RHSWorkspace->columnCount() != expectedCols) {
70+
results.emplace("LHSWorkspace", "Both Table Workspaces must have the same number of columns");
71+
results.emplace("RHSWorkspace", "Both Table Workspaces must have the same number of columns");
72+
return results;
73+
}
74+
75+
// get column titles
76+
const auto lColNames = LHSWorkspace->getColumnNames();
77+
const auto rColNames = RHSWorkspace->getColumnNames();
78+
79+
const std::map<std::string, int> &allowedColumnTypes = allowedTypes();
80+
81+
bool matchingColumnNames = true;
82+
bool matchingColumnTypes = true;
83+
bool allColumnTypesAllowed = true;
84+
85+
for (std::size_t i = 0; i < expectedCols; i++) {
86+
if (lColNames[i] != rColNames[i]) {
87+
matchingColumnNames = false;
88+
break;
89+
}
90+
auto LHType = LHSWorkspace->getColumn(i)->type();
91+
if (LHType != RHSWorkspace->getColumn(i)->type()) {
92+
matchingColumnTypes = false;
93+
break;
94+
}
95+
auto it = allowedColumnTypes.find(LHType);
96+
if (it == allowedColumnTypes.end()) {
97+
allColumnTypesAllowed = false;
98+
break;
99+
}
100+
}
101+
102+
if (!matchingColumnNames) {
103+
results.emplace("LHSWorkspace", "Both Table Workspaces must have the same column titles");
104+
results.emplace("RHSWorkspace", "Both Table Workspaces must have the same column titles");
105+
}
106+
107+
if (!matchingColumnTypes) {
108+
results.emplace("LHSWorkspace", "Both Table Workspaces must have the same data types for corresponding columns");
109+
results.emplace("RHSWorkspace", "Both Table Workspaces must have the same data types for corresponding columns");
110+
}
111+
112+
if (!allColumnTypesAllowed) {
113+
results.emplace("LHSWorkspace", "Only supported data types are: double, int, string, bool, size_t, float, and V3D");
114+
results.emplace("RHSWorkspace", "Only supported data types are: double, int, string, bool, size_t, float, and V3D");
115+
}
116+
117+
return results;
118+
}
119+
120+
//----------------------------------------------------------------------------------------------
121+
/** Execute the algorithm.
122+
*/
123+
void CombineTableWorkspaces::exec() {
124+
const DataObjects::TableWorkspace_sptr LHSWorkspace = getProperty("LHSWorkspace");
125+
const DataObjects::TableWorkspace_sptr RHSWorkspace = getProperty("RHSWorkspace");
126+
127+
const std::map<std::string, int> &allowedColumnTypes = allowedTypes();
128+
129+
// Copy the first workspace to our output workspace
130+
DataObjects::TableWorkspace_sptr outputWS = LHSWorkspace->clone();
131+
// Get hold of the peaks in the second workspace
132+
const auto nRows = RHSWorkspace->rowCount();
133+
const auto nCols = RHSWorkspace->columnCount();
134+
135+
std::vector<std::string> colTypes = {};
136+
for (std::size_t i = 0; i < nCols; i++) {
137+
colTypes.emplace_back(RHSWorkspace->getColumn(i)->type());
138+
}
139+
140+
Progress progress(this, 0.0, 1.0, nRows);
141+
142+
for (std::size_t r = 0; r < nRows; r++) {
143+
TableRow newRow = outputWS->appendRow();
144+
TableRow currentRow = RHSWorkspace->getRow(r);
145+
for (std::size_t c = 0; c < nCols; c++) {
146+
const auto dType = colTypes[c];
147+
const int dTypeVal = allowedColumnTypes.at(dType);
148+
switch (dTypeVal) {
149+
case 0:
150+
newRow << currentRow.Double(c);
151+
break;
152+
case 1:
153+
newRow << currentRow.Int(c);
154+
break;
155+
case 2:
156+
newRow << currentRow.cell<std::string>(c);
157+
break;
158+
case 3:
159+
newRow << currentRow.cell<Mantid::API::Boolean>(c);
160+
break;
161+
case 4:
162+
newRow << currentRow.cell<std::size_t>(c);
163+
break;
164+
case 5:
165+
newRow << currentRow.cell<float>(c);
166+
break;
167+
case 6:
168+
newRow << currentRow.cell<V3D>(c);
169+
break;
170+
default:
171+
// this should be caught by the input validation anyway
172+
throw std::runtime_error("Unsupported Data Type");
173+
}
174+
}
175+
progress.report();
176+
}
177+
178+
setProperty("OutputWorkspace", outputWS);
179+
}
180+
181+
} // namespace Mantid::Algorithms

0 commit comments

Comments
 (0)