/
BoxControllerSettingsAlgorithmTest.h
252 lines (207 loc) · 9.61 KB
/
BoxControllerSettingsAlgorithmTest.h
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#ifndef MANTID_MDEVENTS_BOXCONTROLLERSETTINGSALGORITHMTEST_H_
#define MANTID_MDEVENTS_BOXCONTROLLERSETTINGSALGORITHMTEST_H_
#include <cxxtest/TestSuite.h>
#include "MantidKernel/Timer.h"
#include "MantidKernel/System.h"
#include "MantidAPI/FrameworkManager.h"
#include <iostream>
#include <iomanip>
#include "MantidMDEvents/BoxControllerSettingsAlgorithm.h"
#include "MantidTestHelpers/WorkspaceCreationHelper.h"
#include "MantidDataHandling/LoadParameterFile.h"
#include "MantidTestHelpers/ComponentCreationHelper.h"
#include "MantidTestHelpers/WorkspaceCreationHelper.h"
#include "MantidTestHelpers/ScopedFileHelper.h"
#include <boost/format.hpp>
using namespace Mantid;
using namespace Mantid::MDEvents;
using namespace Mantid::API;
using ScopedFileHelper::ScopedFile;
//------------------------------------------------------------------------------------------------
/** Concrete declaration of BoxControllerSettingsAlgorithm for testing */
class BoxControllerSettingsAlgorithmImpl : public BoxControllerSettingsAlgorithm
{
// Make all the members public so I can test them.
friend class BoxControllerSettingsAlgorithmTest;
public:
virtual const std::string name() const { return "BoxControllerSettingsAlgorithmImpl";};
virtual int version() const { return 1;};
virtual const std::string category() const { return "Testing";}
virtual const std::string summary() const { return "Summary of this test."; }
void init() {}
void exec() {}
};
class BoxControllerSettingsAlgorithmTest : public CxxTest::TestSuite
{
private:
/**
Helper function. Runs LoadParameterAlg, to get an instrument parameter definition from a file onto a workspace.
*/
void apply_instrument_parameter_file_to_workspace(MatrixWorkspace_sptr ws, const ScopedFile& file)
{
// Load the Instrument Parameter file over the existing test workspace + instrument.
using DataHandling::LoadParameterFile;
LoadParameterFile loadParameterAlg;
loadParameterAlg.setRethrows(true);
loadParameterAlg.initialize();
loadParameterAlg.setPropertyValue("Filename", file.getFileName());
loadParameterAlg.setProperty("Workspace", ws);
loadParameterAlg.execute();
}
MatrixWorkspace_sptr create_workspace_with_splitting_params(int splitThreshold, int splitInto, int maxRecursionDepth)
{
auto ws = boost::make_shared<Mantid::DataObjects::Workspace2D>();
ws->initialize(1, 2, 1);
ws->setInstrument(ComponentCreationHelper::createTestInstrumentRectangular(6, 1, 0.0));
const std::string instrumentName = ws->getInstrument()->getName();
// Create a parameter file, with a root equation that will apply to all detectors.
const std::string parameterFileContents = boost::str(boost::format(
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\
<parameter-file instrument = \"%1%\" date = \"2013-01-31T00:00:00\">\n\
<component-link name=\"%1%\">\n\
<parameter name=\"SplitThreshold\">\n\
<value val=\"%2%\"/>\n\
</parameter>\n\
<parameter name=\"SplitInto\">\n\
<value val=\"%3%\"/>\n\
</parameter>\n\
<parameter name=\"MaxRecursionDepth\">\n\
<value val=\"%4%\"/>\n\
</parameter>\n\
</component-link>\n\
</parameter-file>\n") % instrumentName % splitThreshold % splitInto % maxRecursionDepth);
// Create a temporary Instrument Parameter file.
ScopedFile file(parameterFileContents, instrumentName + "_Parameters.xml");
// Apply parameter file to workspace.
apply_instrument_parameter_file_to_workspace(ws, file);
return ws;
}
public:
void test_defaultProps()
{
BoxControllerSettingsAlgorithmImpl alg;
alg.initBoxControllerProps();
BoxController_sptr bc(new BoxController(3));
alg.setBoxController(bc);
TS_ASSERT_EQUALS( bc->getSplitInto(0), 5 );
TS_ASSERT_EQUALS( bc->getSplitThreshold(), 1000 );
TS_ASSERT_EQUALS( bc->getMaxDepth(), 5 );
}
/** You can change the defaults given to the props */
void test_initProps_otherDefaults()
{
BoxControllerSettingsAlgorithmImpl alg;
alg.initBoxControllerProps("6", 1234, 34);
BoxController_sptr bc(new BoxController(3));
alg.setBoxController(bc);
TS_ASSERT_EQUALS( bc->getSplitInto(0), 6 );
TS_ASSERT_EQUALS( bc->getSplitThreshold(), 1234 );
TS_ASSERT_EQUALS( bc->getMaxDepth(), 34 );
}
void doTest(BoxController_sptr bc,
std::string SplitInto="", std::string SplitThreshold="", std::string MaxRecursionDepth="")
{
BoxControllerSettingsAlgorithmImpl alg;
alg.initBoxControllerProps();
if (!SplitInto.empty()) alg.setPropertyValue("SplitInto",SplitInto);
if (!SplitThreshold.empty()) alg.setPropertyValue("SplitThreshold",SplitThreshold);
if (!MaxRecursionDepth.empty()) alg.setPropertyValue("MaxRecursionDepth",MaxRecursionDepth);
alg.setBoxController(bc);
}
void test_SplitInto()
{
BoxController_sptr bc(new BoxController(3));
TSM_ASSERT_THROWS_ANYTHING("Too few parameters", doTest(bc, "5,5") );
TSM_ASSERT_THROWS_ANYTHING("Too many parameters", doTest(bc, "1,2,3,4") );
doTest(bc,"4");
TS_ASSERT_EQUALS( bc->getSplitInto(2), 4 );
doTest(bc,"7,6,5");
TS_ASSERT_EQUALS( bc->getSplitInto(0), 7 );
TS_ASSERT_EQUALS( bc->getSplitInto(1), 6 );
TS_ASSERT_EQUALS( bc->getSplitInto(2), 5 );
}
void test_SplitThreshold()
{
BoxController_sptr bc(new BoxController(3));
TSM_ASSERT_THROWS_ANYTHING("Negative threshold", doTest(bc, "", "-3") );
doTest(bc,"", "1234");
TS_ASSERT_EQUALS( bc->getSplitThreshold(), 1234 );
}
void test_MaxRecursionDepth()
{
BoxController_sptr bc(new BoxController(3));
TSM_ASSERT_THROWS_ANYTHING("Negative MaxRecursionDepth", doTest(bc, "", "", "-1") );
doTest(bc,"", "", "34");
TS_ASSERT_EQUALS( bc->getMaxDepth(), 34 );
}
void test_take_instrument_parameters()
{
const int splitInto = 4;
const int splitThreshold = 16;
const int maxRecursionDepth = 5;
// Workspace has instrument has parameters for all box splitting parameters.
auto ws = create_workspace_with_splitting_params(splitThreshold, splitInto, maxRecursionDepth);
BoxController_sptr bc(new BoxController(1));
BoxControllerSettingsAlgorithmImpl alg;
alg.initBoxControllerProps();
/* Note, not properties are set, so the algorithm will have defaults set. and should therefore look to
pick-up any available in the instrument parameters.*/
alg.setBoxController(bc, ws->getInstrument());
int actualSplitThreshold = alg.getProperty("SplitThreshold");
TS_ASSERT_EQUALS(splitThreshold, actualSplitThreshold);
std::vector<int> actualSplitInto = alg.getProperty("SplitInto");
TS_ASSERT_EQUALS(bc->getNDims(), actualSplitInto.size());
std::vector<int> expectedSplitInto(bc->getNDims(), splitInto);
TS_ASSERT_EQUALS(expectedSplitInto, actualSplitInto);
int actualMaxRecursionDepth = alg.getProperty("MaxRecursionDepth");
TS_ASSERT_EQUALS(maxRecursionDepth, actualMaxRecursionDepth);
}
// Test that the user providied values for spliting have precedence.
void test_ignore_instrument_parameters()
{
const int splitInto = 8;
const int splitThreshold = 16;
const int maxRecursionDepth = 5;
// Workspace has instrument has parameters for all box splitting parameters.
auto ws = create_workspace_with_splitting_params(splitThreshold, splitInto, maxRecursionDepth);
BoxController_sptr bc(new BoxController(1));
// Create splitting parameters that are not default and not the same as those on the instrument parameters.
const std::vector<int> nonDefaultSplitInto = std::vector<int>(bc->getNDims(), splitInto+1);
const int nonDefaultSplitThreshold = splitThreshold + 1;
const int nonDefaultMaxRecursionDepth = maxRecursionDepth + 1;
BoxControllerSettingsAlgorithmImpl alg;
alg.initBoxControllerProps();
alg.setProperty("SplitInto", nonDefaultSplitInto);
alg.setProperty("SplitThreshold", nonDefaultSplitThreshold);
alg.setProperty("MaxRecursionDepth", nonDefaultMaxRecursionDepth);
alg.setBoxController(bc, ws->getInstrument());
int actualSplitThreshold = alg.getProperty("SplitThreshold");
TS_ASSERT_EQUALS(nonDefaultSplitThreshold, actualSplitThreshold);
std::vector<int> actualSplitInto = alg.getProperty("SplitInto");
TS_ASSERT_EQUALS(bc->getNDims(), actualSplitInto.size());
TS_ASSERT_EQUALS(nonDefaultSplitInto, actualSplitInto);
int actualMaxRecursionDepth = alg.getProperty("MaxRecursionDepth");
TS_ASSERT_EQUALS(nonDefaultMaxRecursionDepth, actualMaxRecursionDepth);
}
void test_with_no_instrument_parameters()
{
// Create a workspace with an instrument, but no instrument parameters for box splitting.
auto ws = boost::make_shared<Mantid::DataObjects::Workspace2D>();
ws->initialize(1, 2, 1);
ws->setInstrument(ComponentCreationHelper::createTestInstrumentRectangular(6, 1, 0));
BoxController_sptr bc(new BoxController(1));
BoxControllerSettingsAlgorithmImpl alg;
alg.initBoxControllerProps();
// Note that no properties are actually set. All properties should fall-back to their default values.
alg.setRethrows(true);
TSM_ASSERT_THROWS_NOTHING("Lack of specific instrument parameters should not cause algorithm to fail.", alg.setBoxController(bc, ws->getInstrument()));
// Check that the properties are unaffected. Should just reflect the defaults.
Mantid::Kernel::Property* p = alg.getProperty("SplitThreshold");
TS_ASSERT(p->isDefault());
p = alg.getProperty("SplitInto");
TS_ASSERT(p->isDefault());
p = alg.getProperty("MaxRecursionDepth");
TS_ASSERT(p->isDefault());
}
};
#endif /* MANTID_MDEVENTS_BOXCONTROLLERSETTINGSALGORITHMTEST_H_ */