-
Notifications
You must be signed in to change notification settings - Fork 122
/
ComptonScatteringCountRateTest.h
329 lines (273 loc) · 11.8 KB
/
ComptonScatteringCountRateTest.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
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
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
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
#ifndef MANTID_CURVEFITTING_COMPTONSCATTERINGCOUNTRATETEST_H_
#define MANTID_CURVEFITTING_COMPTONSCATTERINGCOUNTRATETEST_H_
#include <cxxtest/TestSuite.h>
#include "MantidCurveFitting/ComptonScatteringCountRate.h"
#include "ComptonProfileTestHelpers.h"
class ComptonScatteringCountRateTest : 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 ComptonScatteringCountRateTest *createSuite() { return new ComptonScatteringCountRateTest(); }
static void destroySuite( ComptonScatteringCountRateTest *suite ) { delete suite; }
void test_Function_Has_Expected_Intensity_Attribute_And_No_Parameters()
{
auto countRate = createFunction();
TS_ASSERT(countRate->nAttributes() > 1);
TS_ASSERT_THROWS_NOTHING(countRate->getAttribute("IntensityConstraints"));
TS_ASSERT_EQUALS(0, countRate->nParams());
}
void test_Empty_String_For_Intensity_Attribute_Throws_Error()
{
auto countRate = createFunction();
TS_ASSERT_THROWS(countRate->setAttributeValue("IntensityConstraints", ""), std::invalid_argument);
}
void test_Incorrect_String_For_Intensity_Attribute_Throws_Error()
{
auto countRate = createFunction();
TS_ASSERT_THROWS(countRate->setAttributeValue("IntensityConstraints", "Matrix"), std::invalid_argument);
}
void test_Single_Row_In_Intensity_Attribute_Does_Not_Throw()
{
auto countRate = createFunction();
// Single row
TS_ASSERT_THROWS_NOTHING(countRate->setAttributeValue("IntensityConstraints", "Matrix(1,4)0|1|0|4"));
}
void test_Multiple_Rows_In_Intensity_Attribute_Does_Not_Throw()
{
auto countRate = createFunction();
// Multiple rows
TS_ASSERT_THROWS_NOTHING(countRate->setAttributeValue("IntensityConstraints", "Matrix(2,4)0|1|0|4|0|0|2|5"));
}
void test_Function_Accepts_Having_No_Equality_Constraints_When_Setting_Workspace()
{
using namespace Mantid::API;
IFunction_sptr func = createFunctionNoBackground(); // No equality matrix set
double x0(165.0),x1(166.0),dx(0.5);
auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1,x0,x1,dx);
TS_ASSERT_THROWS_NOTHING(func->setWorkspace(testWS));
}
void test_Function_With_No_Background_Gives_Expected_Results_Given_Test_Data()
{
using namespace Mantid::API;
IFunction_sptr func = createFunctionNoBackground();
double x0(165.0),x1(166.0),dx(0.5);
auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1,x0,x1,dx);
auto & dataX = testWS->dataX(0);
std::transform(dataX.begin(), dataX.end(), dataX.begin(), std::bind2nd(std::multiplies<double>(),1e-06)); // to seconds
func->setWorkspace(testWS);
FunctionDomain1DView domain(dataX.data(), dataX.size());
FunctionValues values(domain);
TS_ASSERT_THROWS_NOTHING(func->function(domain, values));
const double tol(1e-10);
TS_ASSERT_DELTA(2, values.getCalculated(0), tol); // Each member returns 1
TS_ASSERT_DELTA(2, values.getCalculated(1), tol);
TS_ASSERT_DELTA(2, values.getCalculated(2), tol);
}
void test_Function_Including_Background_Gives_Expected_Results_Given_Test_Data()
{
using namespace Mantid::API;
IFunction_sptr func = createFunctionWithBackground();
double x0(165.0),x1(166.0),dx(0.5);
auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1,x0,x1,dx);
auto & dataX = testWS->dataX(0);
std::transform(dataX.begin(), dataX.end(), dataX.begin(), std::bind2nd(std::multiplies<double>(),1e-06)); // to seconds
func->setWorkspace(testWS);
FunctionDomain1DView domain(dataX.data(), dataX.size());
FunctionValues values(domain);
TS_ASSERT_THROWS_NOTHING(func->function(domain, values));
const double tol(1e-10);
TS_ASSERT_DELTA(2.25, values.getCalculated(0), tol); // Each member returns 1
TS_ASSERT_DELTA(2.25, values.getCalculated(1), tol);
TS_ASSERT_DELTA(2.25, values.getCalculated(2), tol);
}
void test_Iteration_Starting_Resets_Intensity_Parameters_Correctly_Without_Equality_Matrix()
{
using namespace Mantid::API;
IFunction_sptr func = createFunctionNoBackground();
double x0(165.0),x1(166.0),dx(0.5);
auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1,x0,x1,dx);
auto & dataX = testWS->dataX(0);
std::transform(dataX.begin(), dataX.end(), dataX.begin(), std::bind2nd(std::multiplies<double>(),1e-06)); // to seconds
func->setWorkspace(testWS);
func->iterationStarting();
TS_ASSERT_DELTA(func->getParameter(0),5.0, 1e-10);
TS_ASSERT_DELTA(func->getParameter(1),0.5, 1e-10);
TS_ASSERT_DELTA(func->getParameter(2),10.0, 1e-10);
TS_ASSERT_DELTA(func->getParameter(3),0.5, 1e-10);
}
void test_Iteration_Starting_Resets_Intensity_Parameters_Satisfying_Equality_Matrix()
{
using namespace Mantid::API;
IFunction_sptr func = createFunctionNoBackground();
func->setAttributeValue("IntensityConstraints", "Matrix(1|2)1|-2"); // I_1 = 2I_2
double x0(165.0),x1(166.0),dx(0.5);
auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1,x0,x1,dx);
auto & dataX = testWS->dataX(0);
std::transform(dataX.begin(), dataX.end(), dataX.begin(), std::bind2nd(std::multiplies<double>(),1e-06)); // to seconds
func->setWorkspace(testWS);
func->iterationStarting();
TS_ASSERT_DELTA(func->getParameter(0),5.0, 1e-10); // width_1
TS_ASSERT_DELTA(func->getParameter(1),0.6666666633, 1e-10); // I_1
TS_ASSERT_DELTA(func->getParameter(2),10.0, 1e-10); // width_2
TS_ASSERT_DELTA(func->getParameter(3),0.3333333317, 1e-10); //I_2
}
void test_Iteration_Starting_Resets_Intensity_Parameters_When_Number_Intensity_Pars_Does_Not_Match_Number_Masses()
{
using namespace Mantid::API;
const bool useTwoIntensityFuncAsFirst = true;
IFunction_sptr func = createFunctionNoBackground(useTwoIntensityFuncAsFirst);
double x0(165.0),x1(166.0),dx(0.5);
auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1,x0,x1,dx);
auto & dataX = testWS->dataX(0);
std::transform(dataX.begin(), dataX.end(), dataX.begin(), std::bind2nd(std::multiplies<double>(),1e-06)); // to seconds
func->setWorkspace(testWS);
func->iterationStarting();
TS_ASSERT_DELTA(func->getParameter(0),5.0, 1e-10); // width_1
TS_ASSERT_DELTA(func->getParameter(1),0.33333333, 1e-8); // first mass intensity 1
TS_ASSERT_DELTA(func->getParameter(2),0.33333333, 1e-8); // first mass intensity 2
TS_ASSERT_DELTA(func->getParameter(3),10.0, 1e-10); // width_2
TS_ASSERT_DELTA(func->getParameter(4),0.33333333, 1e-8); // second mass intensity
}
void xtest_Iteration_Starting_Resets_Intensity_Parameters_And_Background_Parameters_With_Background_Included()
{
using namespace Mantid::API;
IFunction_sptr func = createFunctionWithBackground();
func->setAttributeValue("IntensityConstraints", "Matrix(1|2)1|-2"); // I_1 = 2I_2
double x0(165.0),x1(166.0),dx(0.5);
auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1,x0,x1,dx);
auto & dataX = testWS->dataX(0);
std::transform(dataX.begin(), dataX.end(), dataX.begin(), std::bind2nd(std::multiplies<double>(),1e-06)); // to seconds
func->setWorkspace(testWS);
func->iterationStarting();
// TS_ASSERT_DELTA(func->getParameter(0),5.0, 1e-10); // width_1
// TS_ASSERT_DELTA(func->getParameter(1),-0.0506748344, 1e-10); // I_1
// TS_ASSERT_DELTA(func->getParameter(2),10.0, 1e-10); //width_2
// TS_ASSERT_DELTA(func->getParameter(3),-0.0253374172, 1e-10); // I_2
// TS_ASSERT_DELTA(func->getParameter(4),-0.0422290287, 1e-10); // background A_0
// TS_ASSERT_DELTA(func->getParameter(5),0.00675680781, 1e-10); // background A_1
}
private:
/// A simple working object to use for the testing
/// Provides a canned answer of 1 for the massProfile
class ComptonProfileStub : public Mantid::CurveFitting::ComptonProfile
{
public:
ComptonProfileStub() : ComptonProfile()
{
declareParameter("Width",1.0);
declareParameter("Intensity",1.0);
}
std::string name() const { return "ComptonProfileStub"; }
std::vector<size_t> intensityParameterIndices() const { return std::vector<size_t>(1,1); }
size_t fillConstraintMatrix(Mantid::Kernel::DblMatrix & cmatrix,const size_t start,
const std::vector<double>&) const
{
for(size_t i = 0; i < cmatrix.numRows(); ++i)
{
cmatrix[i][start] = 1.0;
}
return 1;
}
void massProfile(double * result, const size_t nData) const
{
for(size_t i = 0; i < nData; ++i) result[i] = 1;
}
};
/// A simple working object that has 2 intensity parameters to use for the testing
/// Provides a canned answer of 1 for the massProfile
class TwoIntensitiesComptonProfileStub : public ComptonProfileStub
{
public:
TwoIntensitiesComptonProfileStub() : ComptonProfileStub()
{
declareParameter("Intensity_2",1.0);
}
std::string name() const { return "TwoIntensitiesComptonProfileStub"; }
std::vector<size_t> intensityParameterIndices() const
{
std::vector<size_t> indices(2,1); // index 1
indices[1] = 2; // index 2
return indices;
}
size_t fillConstraintMatrix(Mantid::Kernel::DblMatrix & cmatrix,const size_t start,
const std::vector<double>&) const
{
for(size_t i = 0; i < cmatrix.numRows(); ++i)
{
for(size_t j = start; j < start + 2; ++j)
{
cmatrix[i][j] = 1.0;
}
}
return 2; //used 2 columns
}
};
/// Background impl for testing
/// Retursns canned answer of 0.25
class LinearStub : public Mantid::API::IFunction1D, Mantid::API::ParamFunction
{
public:
LinearStub()
{
declareAttribute("n",Mantid::API::IFunction::Attribute(1));
declareParameter("A0",1.0);
declareParameter("A1",1.0);
}
std::string name() const { return "LinearStub"; }
void function1D(double* out, const double*, const size_t nData) const
{
for(size_t i = 0; i < nData; ++i) out[i] = 0.25;
}
};
Mantid::API::IFunction_sptr createFunctionWithBackground()
{
auto func = createFunctionNoBackground();
auto background = boost::make_shared<LinearStub>();
background->initialize();
func->addFunction(background);
func->setUpForFit();
return func;
}
boost::shared_ptr<Mantid::CurveFitting::ComptonScatteringCountRate>
createFunctionNoBackground(const bool useTwoIntensityFuncAsFirst = false)
{
boost::shared_ptr<ComptonProfileStub> func1;
if(useTwoIntensityFuncAsFirst)
{
func1 = boost::make_shared<TwoIntensitiesComptonProfileStub>();
func1->initialize();
func1->setParameter("Intensity_2", 3.0);
}
else
{
func1 = boost::make_shared<ComptonProfileStub>();
func1->initialize();
}
func1->setAttributeValue("WorkspaceIndex",0);
func1->setAttributeValue("Mass",1.0);
func1->setParameter("Width", 5.0);
func1->setParameter("Intensity", 2.0);
auto func2 = boost::make_shared<ComptonProfileStub>();
func2->initialize();
func2->setAttributeValue("WorkspaceIndex",0);
func2->setAttributeValue("Mass",1.0);
func2->setParameter("Width", 10.0);
func2->setParameter("Intensity", 3.0);
using Mantid::CurveFitting::ComptonScatteringCountRate;
auto profile = boost::make_shared<ComptonScatteringCountRate>();
profile->initialize();
profile->addFunction(func1);
profile->addFunction(func2);
profile->setUpForFit();
return profile;
}
Mantid::API::IFunction_sptr createFunction()
{
using Mantid::CurveFitting::ComptonScatteringCountRate;
auto profile = boost::make_shared<ComptonScatteringCountRate>();
profile->initialize();
return profile;
}
};
#endif /* MANTID_CURVEFITTING_COMPTONSCATTERINGCOUNTRATETEST_H_ */