/
ApplyFloodWorkspace.cpp
134 lines (113 loc) · 4.89 KB
/
ApplyFloodWorkspace.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
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidAlgorithms/ApplyFloodWorkspace.h"
#include "MantidAPI/Axis.h"
#include "MantidAPI/IEventWorkspace.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidAPI/WorkspaceFactory.h"
#include "MantidAlgorithms/BinaryOperation.h"
#include "MantidKernel/Unit.h"
using namespace Mantid::Kernel;
using namespace Mantid::Algorithms;
using namespace Mantid::API;
namespace {
namespace Prop {
std::string const INPUT_WORKSPACE("InputWorkspace");
std::string const FLOOD_WORKSPACE("FloodWorkspace");
std::string const OUTPUT_WORKSPACE("OutputWorkspace");
} // namespace Prop
/// The division operation on event workspaces can make
/// a mixture of TOF and WEIGHTED events. This function
/// will switch all events to WEIGHTED.
void correctEvents(MatrixWorkspace *ws) {
auto eventWS = dynamic_cast<IEventWorkspace *>(ws);
if (eventWS) {
auto const nSpec = eventWS->getNumberHistograms();
for (size_t i = 0; i < nSpec; ++i) {
eventWS->getSpectrum(i).switchTo(EventType::WEIGHTED);
}
}
}
/// Make sure that the returned flood workspace match the input workspace
/// in number and order of the spectra.
MatrixWorkspace_sptr makeEqualSizes(const MatrixWorkspace_sptr &input, const MatrixWorkspace_sptr &flood) {
auto newFlood = WorkspaceFactory::Instance().create(flood, input->getNumberHistograms());
auto const table = BinaryOperation::buildBinaryOperationTable(input, flood);
auto const floodBlocksize = flood->blocksize();
const ISpectrum *missingSpectrum = nullptr;
for (size_t i = 0; i < table->size(); ++i) {
auto const j = (*table)[i];
if (j < 0) {
if (missingSpectrum) {
newFlood->getSpectrum(i).copyDataFrom(*missingSpectrum);
} else {
newFlood->dataY(i).assign(floodBlocksize, 1.0);
newFlood->dataE(i).assign(floodBlocksize, 0.0);
missingSpectrum = &newFlood->getSpectrum(i);
}
} else {
newFlood->getSpectrum(i).copyDataFrom(flood->getSpectrum(j));
}
}
return newFlood;
}
} // namespace
namespace Mantid::Algorithms {
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(ApplyFloodWorkspace)
const std::string ApplyFloodWorkspace::name() const { return "ApplyFloodWorkspace"; }
const std::string ApplyFloodWorkspace::summary() const {
return "Algorithm to apply a flood correction to a workspace.";
}
int ApplyFloodWorkspace::version() const { return 1; }
const std::vector<std::string> ApplyFloodWorkspace::seeAlso() const {
return {"ReflectometryReductionOneAuto", "CreateFloodWorkspace"};
}
const std::string ApplyFloodWorkspace::category() const { return "Reflectometry\\ISIS"; }
void ApplyFloodWorkspace::init() {
declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>(Prop::INPUT_WORKSPACE, "", Direction::Input),
"The workspace to correct.");
declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>(Prop::FLOOD_WORKSPACE, "", Direction::Input),
"The flood workspace.");
declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>(Prop::OUTPUT_WORKSPACE, "", Direction::Output),
"The corrected workspace.");
}
void ApplyFloodWorkspace::exec() {
MatrixWorkspace_sptr input = getProperty(Prop::INPUT_WORKSPACE);
MatrixWorkspace_sptr flood = getProperty(Prop::FLOOD_WORKSPACE);
if (input->size() != flood->size()) {
flood = makeEqualSizes(input, flood);
}
auto const inputXUnitId = input->getAxis(0)->unit()->unitID();
bool const doConvertUnits = flood->getAxis(0)->unit()->unitID() != inputXUnitId;
bool const doRebin = flood->blocksize() > 1;
if (doRebin) {
if (doConvertUnits) {
auto convert = createChildAlgorithm("ConvertUnits", 0, 1);
convert->setProperty("InputWorkspace", flood);
convert->setProperty("Target", inputXUnitId);
convert->setProperty("OutputWorkspace", "dummy");
convert->execute();
flood = convert->getProperty("OutputWorkspace");
}
auto rebin = createChildAlgorithm("RebinToWorkspace", 0, 1);
rebin->setProperty("WorkspaceToRebin", flood);
rebin->setProperty("WorkspaceToMatch", input);
rebin->setProperty("OutputWorkspace", "dummy");
rebin->execute();
flood = rebin->getProperty("OutputWorkspace");
}
auto divide = createChildAlgorithm("Divide", 0, 1);
divide->setProperty("LHSWorkspace", input);
divide->setProperty("RHSWorkspace", flood);
divide->setProperty("OutputWorkspace", "dummy");
divide->execute();
MatrixWorkspace_sptr output = divide->getProperty("OutputWorkspace");
correctEvents(output.get());
setProperty(Prop::OUTPUT_WORKSPACE, output);
}
} // namespace Mantid::Algorithms