-
Notifications
You must be signed in to change notification settings - Fork 122
/
SumRowColumn.cpp
129 lines (109 loc) · 4.77 KB
/
SumRowColumn.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAlgorithms/SumRowColumn.h"
#include "MantidAPI/Axis.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidAPI/WorkspaceFactory.h"
#include "MantidKernel/BoundedValidator.h"
#include "MantidKernel/ListValidator.h"
#include "MantidKernel/Unit.h"
namespace Mantid {
namespace Algorithms {
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(SumRowColumn)
using namespace Mantid::Kernel;
using namespace Mantid::API;
void SumRowColumn::init() {
// Assume input workspace has correct spectra in it - no more and no less
declareProperty(
make_unique<WorkspaceProperty<>>("InputWorkspace", "", Direction::Input),
"The input workspace, which must contain all the spectra from the bank "
"of interest - no more and no less (so 128x128 or 192x192).");
declareProperty(make_unique<WorkspaceProperty<>>("OutputWorkspace", "",
Direction::Output),
"The name of the workspace in which to store the result.");
// Need to select whether to sum rows or columns
std::vector<std::string> orientation{"D_H", "D_V"};
declareProperty("Orientation", "",
boost::make_shared<StringListValidator>(orientation),
"Whether to sum rows (D_H) or columns (D_V).");
// This is the range to select - the whole lot by default
declareProperty(
"XMin", EMPTY_DBL(),
"The starting X value for each spectrum to include in the summation.");
declareProperty(
"XMax", EMPTY_DBL(),
"The ending X value for each spectrum to include in the summation.");
// For selecting a column range - the whole lot by default
auto mustBePositive = boost::make_shared<BoundedValidator<int>>();
mustBePositive->setLower(0);
declareProperty("HOverVMin", EMPTY_INT(), mustBePositive,
"The first row to include in the summation when summing by "
"columns, or vice versa.");
declareProperty("HOverVMax", EMPTY_INT(), mustBePositive,
"The last row to include in the summation when summing by "
"columns, or vice versa.");
}
void SumRowColumn::exec() {
// First task is to integrate the input workspace
MatrixWorkspace_const_sptr integratedWS = integrateWorkspace();
const size_t numSpec = integratedWS->getNumberHistograms();
// Check number of spectra is 128*128 or 192*192. Print warning if not.
if (numSpec != 16384 && numSpec != 36864) {
g_log.warning()
<< "The input workspace has " << numSpec << " spectra."
<< "This is not 128*128 or 192*192 - did you make a mistake?\n";
}
// This is the dimension if all rows/columns are included
const int dim = static_cast<int>(std::sqrt(static_cast<double>(numSpec)));
// Check the column range properties
int start = getProperty("HOverVMin");
int end = getProperty("HOverVMax");
if (isEmpty(start))
start = 0;
if (isEmpty(end) || end > dim - 1)
end = dim - 1;
if (start > end) {
g_log.error("H/V_Min must be less than H/V_Max");
throw std::out_of_range("H/V_Min must be less than H/V_Max");
}
MatrixWorkspace_sptr outputWS =
WorkspaceFactory::Instance().create(integratedWS, 1, dim, dim);
// Remove the unit
outputWS->getAxis(0)->unit().reset(new Mantid::Kernel::Units::Empty);
// Get references to the vectors for the results
auto &X = outputWS->mutableX(0);
auto &Y = outputWS->mutableY(0);
// Get the orientation
const std::string orientation = getProperty("Orientation");
const bool horizontal = (orientation == "D_H" ? 1 : 0);
Progress progress(this, 0, 1, dim);
for (int i = 0; i < dim; ++i) {
// Copy X values
X[i] = i;
// Now loop over calculating Y's
for (int j = start; j <= end; ++j) {
const int index = (horizontal ? (i + j * dim) : (i * dim + j));
Y[i] += integratedWS->y(index)[0];
}
}
setProperty("OutputWorkspace", outputWS);
}
/** Call Integration as a Child Algorithm
* @return The integrated workspace
*/
MatrixWorkspace_sptr SumRowColumn::integrateWorkspace() {
g_log.debug() << "Integrating input workspace\n";
IAlgorithm_sptr childAlg = createChildAlgorithm("Integration");
// pass inputed values straight to this Child Algorithm, checking must be done
// there
childAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace",
getProperty("InputWorkspace"));
childAlg->setProperty<double>("RangeLower", getProperty("XMin"));
childAlg->setProperty<double>("RangeUpper", getProperty("XMax"));
childAlg->executeAsChildAlg();
return childAlg->getProperty("OutputWorkspace");
}
} // namespace Algorithms
} // namespace Mantid