PeakTest.h 11.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
#ifndef MANTID_DATAOBJECTS_PEAKTEST_H_
#define MANTID_DATAOBJECTS_PEAKTEST_H_

#include <cxxtest/TestSuite.h>
#include "MantidKernel/Timer.h"
#include "MantidKernel/System.h"
#include <iostream>
#include <iomanip>

#include "MantidDataObjects/Peak.h"
11
#include "MantidTestHelpers/ComponentCreationHelper.h"
12
13

using namespace Mantid::DataObjects;
14
15
using namespace Mantid::Geometry;
using namespace Mantid::Kernel;
16
17
18
19

class PeakTest : public CxxTest::TestSuite
{
public:
20
  /// Common instrument
21
  Instrument_sptr inst;
22
23
24
25
26
27
28
29
30
31
32
33
34
  void setUp()
  {
    inst = ComponentCreationHelper::createTestInstrumentRectangular(5, 100);
  }

  void test_constructor()
  {
    // detector IDs start at 10000
    Peak p(inst, 10000, 2.0);
    TS_ASSERT_DELTA(p.getH(), 0.0, 1e-5)
    TS_ASSERT_DELTA(p.getK(), 0.0, 1e-5)
    TS_ASSERT_DELTA(p.getL(), 0.0, 1e-5)
    TS_ASSERT_EQUALS(p.getDetectorID(), 10000)
35
36
    TS_ASSERT_EQUALS(p.getDetector()->getID(), 10000)
    TS_ASSERT_EQUALS(p.getInstrument(), inst)
37
    check_Contributing_Detectors(p, std::vector<int>(1, 10000));
38
39
  }

40
41
42
43
44
45
46
47
48
49
  void test_constructorHKL()
  {
    // detector IDs start at 10000
    Peak p(inst, 10000, 2.0, V3D(1,2,3) );
    TS_ASSERT_DELTA(p.getH(), 1.0, 1e-5)
    TS_ASSERT_DELTA(p.getK(), 2.0, 1e-5)
    TS_ASSERT_DELTA(p.getL(), 3.0, 1e-5)
    TS_ASSERT_EQUALS(p.getDetectorID(), 10000)
    TS_ASSERT_EQUALS(p.getDetector()->getID(), 10000)
    TS_ASSERT_EQUALS(p.getInstrument(), inst)
50
    check_Contributing_Detectors(p, std::vector<int>(1, 10000));
51
52
  }

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
  void test_constructorHKLGon()
  {
    Matrix<double> mats(3,3),mat(3,3);
    for (int x=0; x<3; x++)
      for (int y=0; y<3; y++)
        mats[x][y]=1.0*x+1.0*y;
    mat[0][0]=1.0;mat[1][2]=1.0;mat[2][1]=1.0;
    
    // detector IDs start at 10000
    TS_ASSERT_THROWS_ANYTHING(Peak ps(inst, 10000, 2.0, V3D(1,2,3),mats );)
    TS_ASSERT_THROWS_NOTHING(Peak p(inst, 10000, 2.0, V3D(1,2,3),mat );) 
    Peak p(inst, 10000, 2.0, V3D(1,2,3),mat );
    TS_ASSERT_DELTA(p.getH(), 1.0, 1e-5)
    TS_ASSERT_DELTA(p.getK(), 2.0, 1e-5)
    TS_ASSERT_DELTA(p.getL(), 3.0, 1e-5)
    TS_ASSERT_EQUALS(p.getDetectorID(), 10000)
    TS_ASSERT_EQUALS(p.getDetector()->getID(), 10000)
    TS_ASSERT_EQUALS(p.getInstrument(), inst)
    TS_ASSERT_EQUALS( p.getGoniometerMatrix(), mat);
72
    check_Contributing_Detectors(p, std::vector<int>(1, 10000));
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
  void test_ConstructorFromIPeakInterface()
  {
    Peak p(inst, 10102, 2.0);
    p.setHKL(1,2,3);
    p.setRunNumber(1234);
    p.addContributingDetID(10103);

    const Mantid::API::IPeak & ipeak = p;
    Peak p2(ipeak);
    TS_ASSERT_EQUALS(p.getRow(), p2.getRow());
    TS_ASSERT_EQUALS(p.getCol(), p2.getCol());
    TS_ASSERT_EQUALS(p.getH(), p2.getH());
    TS_ASSERT_EQUALS(p.getK(), p2.getK());
    TS_ASSERT_EQUALS(p.getL(), p2.getL());
    TS_ASSERT_EQUALS(p.getGoniometerMatrix(), p2.getGoniometerMatrix());
    TS_ASSERT_EQUALS(p.getRunNumber(), p2.getRunNumber());
    TS_ASSERT_EQUALS(p.getDetector(), p2.getDetector())
    TS_ASSERT_EQUALS(p.getInstrument(), p2.getInstrument())
    auto expectedIDs = std::vector<int>(2, 10102);
    expectedIDs[1] = 10103;
    check_Contributing_Detectors(p2, expectedIDs);
  }


99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
  void test_copyConstructor()
  {
    Peak p(inst, 10102, 2.0);
    p.setHKL(1,2,3);
    p.setRunNumber(1234);
    // Default (not-explicit) copy constructor
    Peak p2(p);
    TS_ASSERT_EQUALS(p.getRow(), p2.getRow());
    TS_ASSERT_EQUALS(p.getCol(), p2.getCol());
    TS_ASSERT_EQUALS(p.getH(), p2.getH());
    TS_ASSERT_EQUALS(p.getK(), p2.getK());
    TS_ASSERT_EQUALS(p.getL(), p2.getL());
    TS_ASSERT_EQUALS(p.getGoniometerMatrix(), p2.getGoniometerMatrix());
    TS_ASSERT_EQUALS(p.getRunNumber(), p2.getRunNumber());
    TS_ASSERT_EQUALS(p.getDetector(), p2.getDetector())
    TS_ASSERT_EQUALS(p.getInstrument(), p2.getInstrument())
115
116

    check_Contributing_Detectors(p2, std::vector<int>(1, 10102));
117
118
  }

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
  void test_getValueByColName()
  {
    Peak p(inst, 10102, 2.0);
    p.setHKL(1,2,3);
    p.setRunNumber(1234);
    TS_ASSERT_EQUALS(p.getValueByColName("Row"), p.getRow());
    TS_ASSERT_EQUALS(p.getValueByColName("Col"), p.getCol());
    TS_ASSERT_EQUALS(p.getValueByColName("H"), p.getH());
    TS_ASSERT_EQUALS(p.getValueByColName("K"), p.getK());
    TS_ASSERT_EQUALS(p.getValueByColName("L"), p.getL());
    TS_ASSERT_EQUALS(p.getValueByColName("RunNumber"), p.getRunNumber());
    TS_ASSERT_EQUALS(p.getValueByColName("DetId"), p.getDetectorID())
    TS_ASSERT_THROWS_ANYTHING( p.getValueByColName("bankname") );
  }

134
135
136
137
138
139
140
141
  /** Set the wavelength and see the other "versions" of it get calculated. */
  void test_wavelength_conversion()
  {
    //1 angstroms wavelength, and at the opposite corner of the detector
    Peak p(inst, 19999, 1.0);
    // Energy in meV
    TS_ASSERT_DELTA(p.getInitialEnergy(), 81.805, 1e-3) // Conversion table at : www.ncnr.nist.gov/instruments/dcs/dcs_usersguide/Conversion_Factors.pdf
    TS_ASSERT_DELTA(p.getFinalEnergy(), p.getInitialEnergy(), 1e-5)
142
143
144
145
    V3D dp=p.getDetPos();
    double tt=dp.angle(V3D(0,0,1));
    double d=0.5/sin(0.5*tt);  //d=lambda/2/sin(theta)=4.5469
    TS_ASSERT_DELTA(p.getDSpacing(), d, 1e-3);
146
147
148
149
150
    TS_ASSERT_DELTA(p.getTOF(), 3823, 1);

    // Back-converting to wavelength should give you the same.
    TS_ASSERT_DELTA(p.getWavelength(), 1.00, 1e-2);

151
152
153
154
155
156
157
  }

  void test_badDetectorID_throws()
  {
    Peak p(inst, 10000, 2.0);
    TS_ASSERT_THROWS_ANYTHING( p.setDetectorID(7) );
  }
158

159
160
161
162
163
164
165
166
167
  void test_setDetector_Adds_ID_To_Contributing_List_And_Does_Not_Remove_Old_From_Contrib_List()
  {
    int expectedIDs[2] = {10000, 10001};
    Peak peak(inst, expectedIDs[0], 2.0);
    peak.setDetectorID(expectedIDs[1]);

    check_Contributing_Detectors(peak, std::vector<int>(expectedIDs,expectedIDs+2));
  }

168
169
170
171
172
173
174
175
176
177
  void test_runNumber()
  {
    Peak p(inst, 10000, 2.0);
    p.setRunNumber(12345);
    TS_ASSERT_EQUALS( p.getRunNumber(), 12345);
  }

  void test_GoniometerMatrix()
  {
    Peak p(inst, 10000, 2.0);
178
    Matrix<double> mats(3,3),mat(3,3);
179
180
    for (int x=0; x<3; x++)
      for (int y=0; y<3; y++)
181
182
183
184
185
        mats[x][y]=1.0*x+1.0*y;
    TS_ASSERT_THROWS_ANYTHING(p.setGoniometerMatrix(mats)); //matrix is singular
    TS_ASSERT_EQUALS( p.getGoniometerMatrix(), mats);
    mat[0][0]=1.0;mat[1][2]=1.0;mat[2][1]=1.0;
    TS_ASSERT_THROWS_NOTHING(p.setGoniometerMatrix(mat)); //matrix is not singular
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
    TS_ASSERT_EQUALS( p.getGoniometerMatrix(), mat);
    // Matrix must be 3x3
    Matrix<double> mat2(4,3);
    TS_ASSERT_THROWS_ANYTHING( p.setGoniometerMatrix(mat2) );
  }

  void test_HKL()
  {
    Peak p(inst, 10000, 2.0);
    p.setHKL(1.0, 2.0, 3.0);
    TS_ASSERT_EQUALS( p.getH(), 1.0);
    TS_ASSERT_EQUALS( p.getK(), 2.0);
    TS_ASSERT_EQUALS( p.getL(), 3.0);
    p.setH(5);
    p.setK(6);
    p.setL(7);
    TS_ASSERT_EQUALS( p.getH(), 5.0);
    TS_ASSERT_EQUALS( p.getK(), 6.0);
    TS_ASSERT_EQUALS( p.getL(), 7.0);
205
206
207
208
209
    p.setHKL(V3D(1.0, 2.0, 3.0));
    TS_ASSERT_EQUALS( p.getH(), 1.0);
    TS_ASSERT_EQUALS( p.getK(), 2.0);
    TS_ASSERT_EQUALS( p.getL(), 3.0);
    TS_ASSERT_EQUALS( p.getHKL(), V3D(1.0, 2.0, 3.0));
210
211
  }

212
  void test_getBank_and_row()
213
  {
214
215
216
217
    Peak p(inst, 10000, 2.0);
    TS_ASSERT_EQUALS(p.getBankName(), "bank1")
    TS_ASSERT_EQUALS(p.getRow(), 0)
    TS_ASSERT_EQUALS(p.getCol(), 0)
218
219
220
221
222
223
    p.setDetectorID(10050);
    TS_ASSERT_EQUALS(p.getRow(), 50)
    TS_ASSERT_EQUALS(p.getCol(), 0)
    p.setDetectorID(10100);
    TS_ASSERT_EQUALS(p.getRow(), 0)
    TS_ASSERT_EQUALS(p.getCol(), 1)
224
225
  }

226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
  void test_getQSampleFrame()
  {
    // Peak 3 is phi,chi,omega of 90,0,0; giving this matrix:
    Matrix<double> r2(3,3,false);
    r2[0][2] = 1;
    r2[1][1] = 1;
    r2[2][0] = -1;

    Peak p(inst, 10000, 2.0);
    p.setGoniometerMatrix(r2);

    // Q in the lab frame
    V3D qLab = p.getQLabFrame();
    // q in the sample frame.
    V3D qSample = p.getQSampleFrame();
    // If we re-rotate q in the sample frame by the gonio matrix, we should get q in the lab frame
    V3D qSampleRotated = r2 * qSample;

    // Did the peak properly invert the rotation matrix?
    TS_ASSERT_EQUALS(qLab, qSampleRotated);
  }

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

  //------------------------------------------------------------------------------------
  /** Can't have Q = 0,0,0 or 0 in the Z direction when creating */
  void test_setQLabFrame_ThrowsIfQIsNull()
  {
    Peak p1(inst, 10000, 2.0);
    TS_ASSERT_THROWS_ANYTHING(Peak p2(inst, V3D(0,0,0), 1.0));
    TS_ASSERT_THROWS_ANYTHING(Peak p2(inst, V3D(1,2,0), 1.0));
  }


  /** Compare two peaks, but not the detector IDs etc. */
  void comparePeaks(Peak & p1, Peak & p2)
  {
    TS_ASSERT_EQUALS( p1.getQLabFrame(), p2.getQLabFrame() );
    TS_ASSERT_EQUALS( p1.getQSampleFrame(), p2.getQSampleFrame() );
    TS_ASSERT_EQUALS( p1.getDetPos(), p2.getDetPos() );
    TS_ASSERT_EQUALS( p1.getHKL(), p2.getHKL() );
    TS_ASSERT_DELTA( p1.getWavelength(), p2.getWavelength(), 1e-5 );
    TS_ASSERT_DELTA( p1.getL1(), p2.getL1(), 1e-5 );
    TS_ASSERT_DELTA( p1.getL2(), p2.getL2(), 1e-5 );
    TS_ASSERT_DELTA( p1.getTOF(), p2.getTOF(), 1e-5 );
    TS_ASSERT_DELTA( p1.getInitialEnergy(), p2.getInitialEnergy(), 1e-5 );
    TS_ASSERT_DELTA( p1.getFinalEnergy(), p2.getFinalEnergy(), 1e-5 );
    TS_ASSERT( p1.getGoniometerMatrix().equals(p2.getGoniometerMatrix(), 1e-5) );
  }

  /** Create peaks using Q in the lab frame */
  void test_setQLabFrame()
  {
    Peak p1(inst, 19999, 2.0);
    V3D Qlab1 = p1.getQLabFrame();
    V3D detPos1 = p1.getDetPos();

    // Construct using just Q
    Peak p2(inst, Qlab1, detPos1.norm());
    comparePeaks(p1, p2);
    TS_ASSERT_EQUALS( p2.getBankName(), "None");
    TS_ASSERT_EQUALS( p2.getRow(), -1);
    TS_ASSERT_EQUALS( p2.getCol(), -1);
    TS_ASSERT_EQUALS( p2.getDetectorID(), -1);
  }

  /** Create peaks using Q in sample frame + a goniometer rotation matrix*/
  void test_setQSampleFrame()
  {
    // A goniometer rotation matrix
    Matrix<double> r2(3,3,false);
    r2[0][2] = 1;
    r2[1][1] = 1;
    r2[2][0] = -1;

    Peak p1(inst, 19999, 2.0, V3D(1,2,3), r2);
    V3D q = p1.getQSampleFrame();
    V3D detPos1 = p1.getDetPos();

    // Construct using Q + rotation matrix
    Peak p2(inst, q, r2, detPos1.norm());
    p2.setHKL(V3D(1,2,3)); // Make sure HKL matches too.
    comparePeaks(p1, p2);
    TS_ASSERT_EQUALS( p2.getBankName(), "None");
    TS_ASSERT_EQUALS( p2.getRow(), -1);
    TS_ASSERT_EQUALS( p2.getCol(), -1);
    TS_ASSERT_EQUALS( p2.getDetectorID(), -1);
  }


315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
  /** Create peaks using Q in the lab frame,
   * then find the corresponding detector ID */
  void test_findDetector()
  {
    Peak p1(inst, 19999, 2.0);
    V3D Qlab1 = p1.getQLabFrame();
    V3D detPos1 = p1.getDetPos();

    // Construct using just Q
    Peak p2(inst, Qlab1, detPos1.norm());
    TS_ASSERT( p2.findDetector() );
    comparePeaks(p1, p2);
    TS_ASSERT_EQUALS( p2.getBankName(), "bank1");
    TS_ASSERT_EQUALS( p2.getRow(), 99);
    TS_ASSERT_EQUALS( p2.getCol(), 99);
    TS_ASSERT_EQUALS( p2.getDetectorID(), 19999);
  }

333
334
335
336
337
338
339
340
341
342
private:
  void check_Contributing_Detectors(const Peak & peak, const std::vector<int> & expected)
  {
    auto peakIDs = peak.getContributingDetIDs();
    for(auto it = expected.begin(); it != expected.end(); ++it)
    {
      const int id = *it;
      TSM_ASSERT_EQUALS("Expected " + boost::lexical_cast<std::string>(id) + " in contribution list", 1, peakIDs.count(id))
    }
  }
343
344
345
346
347
};


#endif /* MANTID_DATAOBJECTS_PEAKTEST_H_ */