LoadILLSANSTest.h 11.3 KB
Newer Older
1
2
3
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4
5
//   NScD Oak Ridge National Laboratory, European Spallation Source,
//   Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6
// SPDX - License - Identifier: GPL - 3.0 +
7
#pragma once
8
9
10

#include <cxxtest/TestSuite.h>

11
#include "MantidAPI/AnalysisDataService.h"
LamarMoore's avatar
LamarMoore committed
12
#include "MantidAPI/Axis.h"
13
#include "MantidAPI/MatrixWorkspace.h"
14
#include "MantidDataHandling/LoadILLSANS.h"
15
16
17
18
#include "MantidGeometry/IComponent.h"
#include "MantidGeometry/Instrument.h"
#include "MantidGeometry/Instrument/DetectorInfo.h"
#include "MantidKernel/ConfigService.h"
19
#include "MantidKernel/Unit.h"
20
#include "MantidTypes/Core/DateAndTimeHelpers.h"
21

LamarMoore's avatar
LamarMoore committed
22
using Mantid::API::AnalysisDataService;
23
using Mantid::API::Axis;
24
using Mantid::API::MatrixWorkspace_const_sptr;
LamarMoore's avatar
LamarMoore committed
25
using Mantid::DataHandling::LoadILLSANS;
26
using Mantid::Geometry::IComponent_const_sptr;
27
using Mantid::Geometry::IDetector_const_sptr;
28
using Mantid::Geometry::Instrument;
LamarMoore's avatar
LamarMoore committed
29
30
31
using Mantid::Kernel::ConfigService;
using Mantid::Kernel::Unit;
using Mantid::Kernel::V3D;
32
using detid2det_map = std::map<Mantid::detid_t, IDetector_const_sptr>;
33

34
class LoadILLSANSTest : public CxxTest::TestSuite {
35
public:
36
37
38
39
40
  // This pair of boilerplate methods prevent the suite being created statically
  // This means the constructor isn't called when running other tests
  static LoadILLSANSTest *createSuite() { return new LoadILLSANSTest(); }
  static void destroySuite(LoadILLSANSTest *suite) { delete suite; }

41
42
43
44
45
46
47
  LoadILLSANSTest() {
    ConfigService::Instance().appendDataSearchSubDir("ILL/D11/");
    ConfigService::Instance().appendDataSearchSubDir("ILL/D22/");
    ConfigService::Instance().appendDataSearchSubDir("ILL/D33/");
    ConfigService::Instance().appendDataSearchSubDir("ILL/D16/");
    ConfigService::Instance().setFacility("ILL");
  }
48

Gagik Vardanyan's avatar
Gagik Vardanyan committed
49
  void tearDown() override { AnalysisDataService::Instance().clear(); }
50

51
  void test_name() {
52
53
54
55
    LoadILLSANS alg;
    TS_ASSERT_EQUALS(alg.name(), "LoadILLSANS");
  }

56
  void test_version() {
57
58
59
60
    LoadILLSANS alg;
    TS_ASSERT_EQUALS(alg.version(), 1);
  }

61
  void test_init() {
62
63
64
65
66
    LoadILLSANS alg;
    TS_ASSERT_THROWS_NOTHING(alg.initialize())
    TS_ASSERT(alg.isInitialized())
  }

67
  void test_D11() {
68
69
70
71
72
73
74
75
76
77
    LoadILLSANS alg;
    alg.setChild(true);
    alg.initialize();
    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filename", "010560.nxs"))
    TS_ASSERT_THROWS_NOTHING(
        alg.setPropertyValue("OutputWorkspace", "__unused_for_child"))
    TS_ASSERT_THROWS_NOTHING(alg.execute())
    TS_ASSERT(alg.isExecuted())
    MatrixWorkspace_const_sptr outputWS = alg.getProperty("OutputWorkspace");
    TS_ASSERT(outputWS)
78
    TS_ASSERT_EQUALS(outputWS->getNumberHistograms(), 128 * 128 + 2)
79
    TS_ASSERT_EQUALS(outputWS->blocksize(), 1)
80
81
    TS_ASSERT(outputWS->detectorInfo().isMonitor(128 * 128))
    TS_ASSERT(outputWS->detectorInfo().isMonitor(128 * 128 + 1))
82
83
84
    TS_ASSERT(outputWS->isHistogramData())
    TS_ASSERT(!outputWS->isDistribution())
    const auto &instrument = outputWS->getInstrument();
85
86
    IComponent_const_sptr component =
        instrument->getComponentByName("detector");
87
88
    V3D pos = component->getPos();
    TS_ASSERT_DELTA(pos.Z(), 20.007, 1E-3)
89
90
91
    const auto &xAxis = outputWS->x(0).rawData();
    const auto &spec6 = outputWS->y(6).rawData();
    const auto &err6 = outputWS->e(6).rawData();
92
    TS_ASSERT_EQUALS(xAxis.size(), 2)
93
94
    TS_ASSERT_DELTA(xAxis[0], 5.73, 1E-5)
    TS_ASSERT_DELTA(xAxis[1], 6.27, 1E-5)
95
    TS_ASSERT_EQUALS(spec6[0], 20)
96
97
98
    TS_ASSERT_DELTA(err6[0], sqrt(20), 1E-5)
    const auto unit = outputWS->getAxis(0)->unit()->unitID();
    TS_ASSERT_EQUALS(unit, "Wavelength");
99
    checkTimeFormat(outputWS);
100
  }
101

102
  void test_D22() {
103
104
105
106
107
108
109
110
111
112
    LoadILLSANS alg;
    alg.setChild(true);
    alg.initialize();
    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filename", "192068.nxs"))
    TS_ASSERT_THROWS_NOTHING(
        alg.setPropertyValue("OutputWorkspace", "__unused_for_child"))
    TS_ASSERT_THROWS_NOTHING(alg.execute())
    TS_ASSERT(alg.isExecuted())
    MatrixWorkspace_const_sptr outputWS = alg.getProperty("OutputWorkspace");
    TS_ASSERT(outputWS)
113
    TS_ASSERT_EQUALS(outputWS->getNumberHistograms(), 128 * 256 + 2)
114
    TS_ASSERT_EQUALS(outputWS->blocksize(), 1)
115
116
    TS_ASSERT(outputWS->detectorInfo().isMonitor(128 * 256))
    TS_ASSERT(outputWS->detectorInfo().isMonitor(128 * 256 + 1))
117
118
119
    TS_ASSERT(outputWS->isHistogramData())
    TS_ASSERT(!outputWS->isDistribution())
    const auto &instrument = outputWS->getInstrument();
120
121
    IComponent_const_sptr component =
        instrument->getComponentByName("detector");
122
123
    V3D pos = component->getPos();
    TS_ASSERT_DELTA(pos.Z(), 8, 0.01)
124
    TS_ASSERT_DELTA(pos.X(), -0.35, 0.01)
125
126
127
    const auto &xAxis = outputWS->x(0).rawData();
    const auto &spec6 = outputWS->y(6).rawData();
    const auto &err6 = outputWS->e(6).rawData();
128
    TS_ASSERT_EQUALS(xAxis.size(), 2)
129
130
    TS_ASSERT_DELTA(xAxis[0], 4.75, 1E-5)
    TS_ASSERT_DELTA(xAxis[1], 5.25, 1E-5)
131
    TS_ASSERT_EQUALS(spec6[0], 45)
132
133
134
    TS_ASSERT_DELTA(err6[0], sqrt(45), 1E-5)
    const auto unit = outputWS->getAxis(0)->unit()->unitID();
    TS_ASSERT_EQUALS(unit, "Wavelength");
135
    checkTimeFormat(outputWS);
136
  }
137

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  void test_D16() {
    LoadILLSANS alg;
    alg.setChild(true);
    alg.initialize();
    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filename", "218356.nxs"));
    TS_ASSERT_THROWS_NOTHING(
        alg.setPropertyValue("OutputWorkspace", "__unused_for_child"));
    TS_ASSERT_THROWS_NOTHING(alg.execute());
    TS_ASSERT(alg.isExecuted());
    MatrixWorkspace_const_sptr outputWS = alg.getProperty("OutputWorkspace");
    TS_ASSERT(outputWS);

    TS_ASSERT(outputWS->detectorInfo().isMonitor(320 * 320));
    TS_ASSERT(outputWS->detectorInfo().isMonitor(320 * 320 + 1));

    const auto &instrument = outputWS->getInstrument();
    IComponent_const_sptr component =
        instrument->getComponentByName("detector");
    V3D pos = component->getPos();
    V3D origin(0, 0, 0);
    TS_ASSERT_DELTA(pos.distance(origin), 1, 1E-5);
159
160
    TS_ASSERT_DELTA(pos.X(), -0.17365, 1E-5); // sin(10)
    TS_ASSERT_DELTA(pos.Z(), 0.98481, 1E-5);  // cos(10)
161
162
163
164
165
166
167

    Mantid::detid_t bl_id, tr_id;
    instrument->getMinMaxDetectorIDs(bl_id, tr_id);

    detid2det_map det_map;
    instrument->getDetectors(det_map);

168
169
    IDetector_const_sptr bottom_right_pixel = det_map[bl_id];
    IDetector_const_sptr top_left_pixel = det_map[320 * 320 - 1];
170

171
172
    V3D br_pos = bottom_right_pixel->getPos();
    V3D tl_pos = top_left_pixel->getPos();
173
174

    // check the detector has 10 degrees angle
175
176
    TS_ASSERT_DELTA(br_pos.distance(origin), 1.02512, 1E-5);
    TS_ASSERT_DELTA(tl_pos.distance(origin), 1.02512, 1E-5);
177

178
179
180
181
    TS_ASSERT_DELTA(tl_pos.X(), -0.33073, 1E-5);
    TS_ASSERT_DELTA(tl_pos.Z(), 0.95711, 1E-5);
    TS_ASSERT_DELTA(br_pos.X(), -0.01657, 1E-5);
    TS_ASSERT_DELTA(br_pos.Z(), 1.01250, 1E-5);
182
183
184
185
186

    const auto &xAxis = outputWS->x(0).rawData();
    const auto &spec = outputWS->y(51972).rawData();
    const auto &err = outputWS->e(51972).rawData();
    TS_ASSERT_EQUALS(xAxis.size(), 2)
187
188
    TS_ASSERT_DELTA(xAxis[0], 6.965, 1E-3)
    TS_ASSERT_DELTA(xAxis[1], 7.035, 1E-3)
189
190
    TS_ASSERT_EQUALS(spec[0], 17)
    TS_ASSERT_DELTA(err[0], sqrt(17), 1E-5)
191
    checkTimeFormat(outputWS);
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
  void test_D33() {
    LoadILLSANS alg;
    alg.setChild(true);
    alg.initialize();
    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filename", "002294.nxs"))
    TS_ASSERT_THROWS_NOTHING(
        alg.setPropertyValue("OutputWorkspace", "__unused_for_child"))
    TS_ASSERT_THROWS_NOTHING(alg.execute())
    TS_ASSERT(alg.isExecuted())
    MatrixWorkspace_const_sptr outputWS = alg.getProperty("OutputWorkspace");
    TS_ASSERT(outputWS)
    TS_ASSERT_EQUALS(outputWS->getNumberHistograms(), 256 * 256 + 2)
    TS_ASSERT_EQUALS(outputWS->blocksize(), 1)
    TS_ASSERT(outputWS->detectorInfo().isMonitor(256 * 256))
    TS_ASSERT(outputWS->detectorInfo().isMonitor(256 * 256 + 1))
    TS_ASSERT(outputWS->isHistogramData())
    TS_ASSERT(!outputWS->isDistribution())
    const auto &xAxis = outputWS->x(0).rawData();
    const auto &spec = outputWS->y(15947).rawData();
    const auto &err = outputWS->e(15947).rawData();
    TS_ASSERT_EQUALS(xAxis.size(), 2)
    TS_ASSERT_DELTA(xAxis[0], 9.5, 1E-3)
    TS_ASSERT_DELTA(xAxis[1], 10.5, 1E-3)
    TS_ASSERT_EQUALS(spec[0], 220)
    TS_ASSERT_DELTA(err[0], sqrt(220), 1E-5)
    const auto &instrument = outputWS->getInstrument();
    IComponent_const_sptr back =
        instrument->getComponentByName("back_detector");
    TS_ASSERT_EQUALS(back->getPos(), V3D(0, 0, 10.1128));
    IComponent_const_sptr right =
        instrument->getComponentByName("front_detector_right");
    TS_ASSERT_EQUALS(right->getPos(), V3D(-0.41, 0, 1.4968));
    IComponent_const_sptr left =
        instrument->getComponentByName("front_detector_left");
    TS_ASSERT_EQUALS(left->getPos(), V3D(0.41, 0, 1.4968));
    IComponent_const_sptr top =
        instrument->getComponentByName("front_detector_top");
    TS_ASSERT_EQUALS(top->getPos(), V3D(0, 0.41, 1.3118));
    IComponent_const_sptr bottom =
        instrument->getComponentByName("front_detector_bottom");
    TS_ASSERT_EQUALS(bottom->getPos(), V3D(0, -0.41, 1.3118));
    const auto unit = outputWS->getAxis(0)->unit()->unitID();
    TS_ASSERT_EQUALS(unit, "Wavelength");
237
    checkTimeFormat(outputWS);
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
  }

  void test_D33_TOF() {
    LoadILLSANS alg;
    alg.setChild(true);
    alg.initialize();
    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filename", "042610.nxs"))
    TS_ASSERT_THROWS_NOTHING(
        alg.setPropertyValue("OutputWorkspace", "__unused_for_child"))
    TS_ASSERT_THROWS_NOTHING(alg.execute())
    TS_ASSERT(alg.isExecuted())
    MatrixWorkspace_const_sptr outputWS = alg.getProperty("OutputWorkspace");
    TS_ASSERT(outputWS)
    TS_ASSERT_EQUALS(outputWS->getNumberHistograms(), 256 * 256 + 2)
    TS_ASSERT_EQUALS(outputWS->blocksize(), 200)
    TS_ASSERT(outputWS->detectorInfo().isMonitor(256 * 256))
    TS_ASSERT(outputWS->detectorInfo().isMonitor(256 * 256 + 1))
    TS_ASSERT(outputWS->isHistogramData())
    TS_ASSERT(!outputWS->isDistribution())
    const auto &x = outputWS->x(0).rawData();
    TS_ASSERT_DELTA(x[0], 0.04969, 1E-5)
    TS_ASSERT_DELTA(x[1], 0.14873, 1E-5)
    TS_ASSERT_DELTA(x[200], 19.85713, 1E-5)
    const auto &run = outputWS->run();
    TS_ASSERT(run.hasProperty("tof_mode"))
    const auto tof = run.getLogData("tof_mode");
    TS_ASSERT_EQUALS(tof->value(), "TOF");
    const auto unit = outputWS->getAxis(0)->unit()->unitID();
    TS_ASSERT_EQUALS(unit, "Wavelength");
267
268
269
270
    checkTimeFormat(outputWS);
  }

  void checkTimeFormat(MatrixWorkspace_const_sptr outputWS) {
271
    TS_ASSERT(outputWS->run().hasProperty("start_time"));
272
    TS_ASSERT(Mantid::Types::Core::DateAndTimeHelpers::stringIsISO8601(
273
        outputWS->run().getProperty("start_time")->value()));
274
  }
275
276
};

277
278
279
class LoadILLSANSTestPerformance : public CxxTest::TestSuite {
public:
  void setUp() override {
280
281
282
283
    m_alg.initialize();
    m_alg.setChild(true);
    m_alg.setPropertyValue("Filename", "ILL/D33/042610.nxs");
    m_alg.setPropertyValue("OutputWorkspace", "__unused_for_child");
284
285
  }
  void testLoadILLSANSPerformance() {
286
287
    for (int i = 0; i < 10; ++i) {
      TS_ASSERT_THROWS_NOTHING(m_alg.execute());
288
289
    }
  }
290
  void tearDown() override { AnalysisDataService::Instance().clear(); }
291
292

private:
293
  LoadILLSANS m_alg;
294
};