-
Notifications
You must be signed in to change notification settings - Fork 122
/
RemoveMaskedSpectra.cpp
167 lines (144 loc) · 5.88 KB
/
RemoveMaskedSpectra.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include "MantidAlgorithms/RemoveMaskedSpectra.h"
#include "MantidAPI/NumericAxis.h"
#include "MantidAPI/TextAxis.h"
#include "MantidAPI/WorkspaceFactory.h"
#include "MantidDataObjects/MaskWorkspace.h"
namespace Mantid {
namespace Algorithms {
using namespace Kernel;
using namespace API;
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(RemoveMaskedSpectra)
//----------------------------------------------------------------------------------------------
/** Constructor
*/
RemoveMaskedSpectra::RemoveMaskedSpectra() {}
//----------------------------------------------------------------------------------------------
/** Destructor
*/
RemoveMaskedSpectra::~RemoveMaskedSpectra() {}
//----------------------------------------------------------------------------------------------
/// Algorithms name for identification. @see Algorithm::name
const std::string RemoveMaskedSpectra::name() const {
return "RemoveMaskedSpectra";
}
/// Algorithm's version for identification. @see Algorithm::version
int RemoveMaskedSpectra::version() const { return 1; };
/// Algorithm's category for identification. @see Algorithm::category
const std::string RemoveMaskedSpectra::category() const {
return "Transforms\\Splitting";
}
/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
const std::string RemoveMaskedSpectra::summary() const {
return "Extracts unmasked spectra from a workspace and places them in a new "
"workspace.";
}
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void RemoveMaskedSpectra::init() {
declareProperty(
new WorkspaceProperty<>("InputWorkspace", "", Direction::Input),
"An input workspace.");
declareProperty(new WorkspaceProperty<>("MaskedWorkspace", "",
Direction::Input,
PropertyMode::Optional),
"If given but not as a MaskWorkspace, the masking from "
"this workspace will be used. If given as a "
"MaskWorkspace, the masking is read from its Y values.");
declareProperty(
new WorkspaceProperty<>("OutputWorkspace", "", Direction::Output),
"An output workspace.");
}
//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void RemoveMaskedSpectra::exec() {
MatrixWorkspace_sptr inputWorkspace = getProperty("InputWorkspace");
MatrixWorkspace_sptr maskedWorkspace = getProperty("MaskedWorkspace");
if (!maskedWorkspace){
maskedWorkspace = inputWorkspace;
} else if (inputWorkspace->getNumberHistograms() != maskedWorkspace->getNumberHistograms()) {
throw std::runtime_error("Masked workspace has a different number of spectra.");
}
// Find indices of the unmasked spectra.
std::vector<size_t> indices;
makeIndexList(indices, maskedWorkspace.get());
// Number of spectra in the cropped workspace.
size_t nSpectra = indices.size();
// Number of bins/data points in the cropped workspace.
size_t nBins = inputWorkspace->blocksize();
size_t histogram = inputWorkspace->isHistogramData() ? 1 : 0;
// Create the output workspace.
MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create(
inputWorkspace, nSpectra, nBins + histogram, nBins);
// If this is a Workspace2D, get the spectra axes for copying in the spectraNo
// later.
Axis *inAxis1(NULL), *outAxis1(NULL);
TextAxis *outTxtAxis(NULL);
if (inputWorkspace->axes() > 1) {
inAxis1 = inputWorkspace->getAxis(1);
outAxis1 = outputWorkspace->getAxis(1);
outTxtAxis = dynamic_cast<TextAxis *>(outAxis1);
}
// Check for common boundaries in input workspace.
bool commonBoundaries = WorkspaceHelpers::commonBoundaries(inputWorkspace);
MantidVecPtr newX;
if (commonBoundaries) newX = inputWorkspace->refX(0);
// Add spectra to the output workspace.
for (size_t j = 0; j < nSpectra; ++j) {
auto i = indices[j];
// copy the x bins
if (commonBoundaries) {
outputWorkspace->setX(j, newX);
} else {
outputWorkspace->setX(j, inputWorkspace->refX(i));
}
// Copy the y values and errors.
outputWorkspace->getSpectrum(j)->setData(inputWorkspace->readY(i), inputWorkspace->readE(i));
// Copy spectrum number & detectors
outputWorkspace->getSpectrum(j)
->copyInfoFrom(*inputWorkspace->getSpectrum(i));
// Copy over the axis entry for each spectrum, regardless of the type of
// axes present.
if (inAxis1) {
if (outAxis1->isText()) {
outTxtAxis->setLabel(j, inAxis1->label(i));
} else if (!outAxis1->isSpectra()) // handled by copyInfoFrom line
{
dynamic_cast<NumericAxis *>(outAxis1)
->setValue(j, inAxis1->operator()(i));
}
}
}
setProperty("OutputWorkspace", outputWorkspace);
}
//----------------------------------------------------------------------------------------------
/// Fill in a vector with spectra indices to be extracted.
/// @param indices :: A reference to a vector to fill with the indices.
/// @param maskedWorkspace :: A workspace with masking information.
void RemoveMaskedSpectra::makeIndexList(
std::vector<size_t> &indices, const API::MatrixWorkspace *maskedWorkspace) {
auto mask = dynamic_cast<const DataObjects::MaskWorkspace *>(maskedWorkspace);
if (mask) {
for (size_t i = 0; i < mask->getNumberHistograms(); ++i) {
if (mask->readY(i)[0] == 0.0) {
indices.push_back(i);
}
}
} else {
for (size_t i = 0; i < maskedWorkspace->getNumberHistograms(); ++i) {
Geometry::IDetector_const_sptr det;
try {
det = maskedWorkspace->getDetector(i);
} catch (Exception::NotFoundError &) {
continue;
}
if (det->isMasked()) {
indices.push_back(i);
}
}
}
}
} // namespace Algorithms
} // namespace Mantid