Newer
Older
#ifndef MANTID_ALGORITHMS_CONVOLUTIONFITSEQUENTIALTEST_H_
#define MANTID_ALGORITHMS_CONVOLUTIONFITSEQUENTIALTEST_H_
#include <cxxtest/TestSuite.h>
#include "MantidAPI/FrameworkManager.h"
#include "MantidAPI/WorkspaceFactory.h"
#include "MantidWorkflowAlgorithms/ConvolutionFitSequential.h"
#include "MantidDataObjects/Workspace2D.h"
#include "MantidKernel/TimeSeriesProperty.h"
#include "MantidTestHelpers/WorkspaceCreationHelper.h"
#include <boost/assign/list_of.hpp>
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
using Mantid::Algorithms::ConvolutionFitSequential;
using namespace Mantid::API;
using namespace Mantid::DataObjects;
class ConvolutionFitSequentialTest : public CxxTest::TestSuite {
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static ConvolutionFitSequentialTest *createSuite() {
return new ConvolutionFitSequentialTest();
}
static void destroySuite(ConvolutionFitSequentialTest *suite) {
delete suite;
}
ConvolutionFitSequentialTest() { FrameworkManager::Instance(); }
void test_fit_function_is_valid_for_convolution_fitting() {
Mantid::Algorithms::ConvolutionFitSequential alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize());
TS_ASSERT_THROWS_NOTHING(alg.setProperty(
"Function", "function=test,name=Convolution,name=Resolution"));
}
//-------------------------- Failure cases ----------------------------
void test_empty_function_is_not_allowed() {
Mantid::Algorithms::ConvolutionFitSequential alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize());
TS_ASSERT_THROWS(alg.setPropertyValue("Function", ""),
std::invalid_argument);
}
void test_empty_startX_is_not_allowed() {
Mantid::Algorithms::ConvolutionFitSequential alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize());
TS_ASSERT_THROWS(alg.setPropertyValue("StartX", ""), std::invalid_argument);
}
void test_empty_endX_is_not_allowed() {
Mantid::Algorithms::ConvolutionFitSequential alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize());
TS_ASSERT_THROWS(alg.setPropertyValue("EndX", ""), std::invalid_argument);
}
void test_empty_specMin_is_not_allowed() {
Mantid::Algorithms::ConvolutionFitSequential alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize());
TS_ASSERT_THROWS(alg.setPropertyValue("SpecMin", ""),
std::invalid_argument);
}
void test_empty_specMax_is_not_allowed() {
Mantid::Algorithms::ConvolutionFitSequential alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize());
TS_ASSERT_THROWS(alg.setPropertyValue("SpecMax", ""),
std::invalid_argument);
}
void test_empty_maxIterations_is_not_allowed() {
Mantid::Algorithms::ConvolutionFitSequential alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize());
TS_ASSERT_THROWS(alg.setPropertyValue("MaxIterations", ""),
std::invalid_argument);
}
void test_spectra_min_or_max_number_can_not_be_negative() {
Mantid::Algorithms::ConvolutionFitSequential alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize());
TS_ASSERT_THROWS(alg.setPropertyValue("SpecMin", "-1"),
std::invalid_argument);
TS_ASSERT_THROWS(alg.setPropertyValue("SpecMax", "-1"),
std::invalid_argument);
}
void test_max_iterations_can_not_be_a_negative_number() {
Mantid::Algorithms::ConvolutionFitSequential alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize());
TS_ASSERT_THROWS(alg.setPropertyValue("MaxIterations", "-1"),
std::invalid_argument);
}
void test_fit_function_that_does_not_contain_resolution_is_not_allowed() {
Mantid::Algorithms::ConvolutionFitSequential alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize());
TS_ASSERT_THROWS(
alg.setProperty("Function", "function=test,name=Convolution"),
std::invalid_argument);
}
void test_fit_function_that_does_not_contain_convolution_is_not_allowed() {
Mantid::Algorithms::ConvolutionFitSequential alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize());
TS_ASSERT_THROWS(
alg.setProperty("Function", "function=test,name=Resolution"),
std::invalid_argument);
}
//------------------------- Execution cases ---------------------------
void test_exec_with_red_file() {
auto resWs = create2DWorkspace(5, 1);
auto redWs = create2DWorkspace(totalBins, 5);
createConvFitResWorkspace(5, totalBins);
AnalysisDataService::Instance().add("ResolutionWs_", resWs);
AnalysisDataService::Instance().add("ReductionWs_", redWs);
Mantid::Algorithms::ConvolutionFitSequential alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize());
alg.setProperty("InputWorkspace", redWs);
alg.setProperty("Function",
"name=LinearBackground,A0=0,A1=0,ties=(A0=0.000000,A1=0.0);"
"(composite=Convolution,FixResolution=true,NumDeriv=true;"
"name=Resolution,Workspace=__ConvFit_Resolution,"
"WorkspaceIndex=0;((composite=ProductFunction,NumDeriv="
"false;name=Lorentzian,Amplitude=1,PeakCentre=0,FWHM=0."
"0175)))");
alg.setProperty("BackgroundType", "Fixed Flat");
alg.setProperty("StartX", 0.0);
alg.setProperty("EndX", 3.0);
alg.setProperty("SpecMin", 0);
alg.setProperty("SpecMax", 5);
alg.setProperty("Convolve", true);
alg.setProperty("Minimizer", "Levenberg-Marquardt");
alg.setProperty("MaxIterations", 500);
TS_ASSERT_THROWS_NOTHING(alg.execute());
TS_ASSERT(alg.isExecuted());
// Retrieve and analyse parameter table - Param table does not require
// further testing as this is tested in the ProcessIndirectFitParameters
// Algorithm
ITableWorkspace_sptr paramTable;
TS_ASSERT_THROWS_NOTHING(
paramTable =
AnalysisDataService::Instance().retrieveWS<ITableWorkspace>(
"ReductionWs_conv_1LFixF_s0_to_5_Parameters"));
// Retrieve and analyse results table
MatrixWorkspace_sptr resultWs;
TS_ASSERT_THROWS_NOTHING(
resultWs = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
"ReductionWs_conv_1LFixF_s0_to_5_Result"));
TS_ASSERT_EQUALS(resultWs->blocksize(), totalBins);
// Retrieve and analyse group table
WorkspaceGroup_sptr groupWs;
TS_ASSERT_THROWS_NOTHING(
groupWs = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>(
"ReductionWs_conv_1LFixF_s0_to_5_Workspaces"));
// Check number of expected Histograms and Histogram deminsions
int entities = groupWs->getNumberOfEntries();
TS_ASSERT_EQUALS(entities, redWs->getNumberHistograms());
auto groupMember =
groupWs->getItem("ReductionWs_conv_1LFixF_s0_to_5_0_Workspace");
auto matrixMember =
boost::dynamic_pointer_cast<MatrixWorkspace>(groupMember);
TS_ASSERT_EQUALS(matrixMember->blocksize(), resWs->blocksize());
// Check oringal Log was copied correctly
auto &memberRun = matrixMember->mutableRun();
auto &originalRun = redWs->mutableRun();
TS_ASSERT_EQUALS(memberRun.getLogData().at(1)->value(),
originalRun.getLogData().at(1)->value());
// Check new Log data is present
auto memberLogs = memberRun.getLogData();
TS_ASSERT_EQUALS(memberLogs.at(2)->value(), "FixF");
TS_ASSERT_EQUALS(memberLogs.at(3)->value(), "true");
TS_ASSERT_EQUALS(memberLogs.at(4)->value(), "false");
TS_ASSERT_EQUALS(memberLogs.at(5)->value(), "ConvFit");
TS_ASSERT_EQUALS(memberLogs.at(6)->value(), "ReductionWs_");
TS_ASSERT_EQUALS(memberLogs.at(7)->value(), "1");
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
AnalysisDataService::Instance().clear();
}
void test_exec_with_sqw_file() {
auto sqwWs = createGenericWorkspace("SqwWs_", true);
auto resWs = createGenericWorkspace("ResolutionWs_", false);
auto convFitRes = createGenericWorkspace("__ConvFit_Resolution", false);
Mantid::Algorithms::ConvolutionFitSequential alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize());
alg.setProperty("InputWorkspace", sqwWs);
alg.setProperty("Function",
"name=LinearBackground,A0=0,A1=0,ties=(A0=0.000000,A1=0.0);"
"(composite=Convolution,FixResolution=true,NumDeriv=true;"
"name=Resolution,Workspace=__ConvFit_Resolution,"
"WorkspaceIndex=0;((composite=ProductFunction,NumDeriv="
"false;name=Lorentzian,Amplitude=1,PeakCentre=0,FWHM=0."
"0175)))");
alg.setProperty("BackgroundType", "Fixed Flat");
alg.setProperty("StartX", 0.0);
alg.setProperty("EndX", 5.0);
alg.setProperty("SpecMin", 0);
alg.setProperty("SpecMax", 0);
alg.setProperty("Convolve", true);
alg.setProperty("Minimizer", "Levenberg-Marquardt");
alg.setProperty("MaxIterations", 500);
TS_ASSERT_THROWS_NOTHING(alg.execute());
TS_ASSERT(alg.isExecuted());
// Assert that output is in ADS
TS_ASSERT_THROWS_NOTHING(
AnalysisDataService::Instance().retrieveWS<ITableWorkspace>(
"SqwWs_conv_1LFixF_s0_to_5_Parameters"));
TS_ASSERT_THROWS_NOTHING(
AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
"SqwWs_conv_1LFixF_s0_to_5_Result"));
TS_ASSERT_THROWS_NOTHING(
AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>(
"SqwWs_conv_1LFixF_s0_to_5_Workspaces"));
AnalysisDataService::Instance().clear();
}
//------------------------ Private Functions---------------------------
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
MatrixWorkspace_sptr createGenericWorkspace(const std::string &wsName,
const bool numericAxis) {
const auto xData = boost::assign::list_of(1)(2)(3)(4)(5)
.convert_to_container<Mantid::MantidVec>();
const auto yData = boost::assign::list_of(0)(1)(3)(1)(0)
.convert_to_container<Mantid::MantidVec>();
auto createWorkspace = AlgorithmManager::Instance().create("CreateWorkspace");
createWorkspace->initialize();
if (numericAxis) {
createWorkspace->setProperty("UnitX", "DeltaE");
createWorkspace->setProperty("VerticalAxisUnit", "MomentumTransfer");
createWorkspace->setProperty("VerticalAxisValues", "1");
} else {
createWorkspace->setProperty("UnitX", "DeltaE");
createWorkspace->setProperty("VerticalAxisUnit", "SpectraNumber");
}
createWorkspace->setProperty("DataX", xData);
createWorkspace->setProperty("DataY", yData);
createWorkspace->setProperty("NSpec", 1);
createWorkspace->setPropertyValue("OutputWorkspace", wsName);
createWorkspace->execute();
MatrixWorkspace_sptr sqwWS =
AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(wsName);
return sqwWS;
}
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
MatrixWorkspace_sptr create2DWorkspace(int xlen, int ylen) {
auto ws = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(
xlen, ylen, false, false, true, "testInst");
boost::shared_ptr<Mantid::MantidVec> x1(new Mantid::MantidVec(xlen, 0.0));
boost::shared_ptr<Mantid::MantidVec> y1(
new Mantid::MantidVec(xlen - 1, 3.0));
boost::shared_ptr<Mantid::MantidVec> e1(
new Mantid::MantidVec(xlen - 1, sqrt(3.0)));
MatrixWorkspace_sptr testWs(ws);
testWs->initialize(ylen, xlen, xlen - 1);
double j = 1.0;
for (int i = 0; i < xlen; i++) {
(*x1)[i] = j * 0.5;
j += 1.5;
}
for (int i = 0; i < ylen; i++) {
testWs->setX(i, x1);
testWs->setData(i, y1, e1);
}
testWs->getAxis(0)->setUnit("DeltaE");
for (int i = 0; i < xlen; i++) {
testWs->setEFixed((i + 1), 0.50);
}
auto &run = testWs->mutableRun();
auto timeSeries =
new Mantid::Kernel::TimeSeriesProperty<std::string>("TestTimeSeries");
timeSeries->addValue("2010-09-14T04:20:12", "0.02");
run.addProperty(timeSeries);
auto test = run.getLogData("TestTimeSeries")->value();
return testWs;
}
void createConvFitResWorkspace(int totalHist, int totalBins) {
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
auto convFitRes = WorkspaceFactory::Instance().create(
"Workspace2D", totalHist + 1, totalBins + 1, totalBins);
boost::shared_ptr<Mantid::MantidVec> x1(
new Mantid::MantidVec(totalBins + 1, 0.0));
boost::shared_ptr<Mantid::MantidVec> y1(
new Mantid::MantidVec(totalBins, 3.0));
boost::shared_ptr<Mantid::MantidVec> e1(
new Mantid::MantidVec(totalBins, sqrt(3.0)));
MatrixWorkspace_sptr testWs(convFitRes);
testWs->initialize(totalHist + 1, totalBins + 1, totalBins);
double j = 1.0;
for (int i = 0; i < totalBins; i++) {
(*x1)[i] = j * 0.5;
j += 1.5;
}
for (int i = 0; i < totalBins; i++) {
testWs->setX(i, x1);
testWs->setData(i, y1, e1);
}
AnalysisDataService::Instance().add("__ConvFit_Resolution", convFitRes);
}
};
#endif /* MANTID_ALGORITHMS_CONVOLUTIONFITSEQUENTIALTEST_H_ */