LoadInstrumentTest.h 26.4 KB
Newer Older
1
2
3
#ifndef LOADINSTRUMENTTEST_H_
#define LOADINSTRUMENTTEST_H_

4
#include "MantidAPI/Algorithm.h"
5
#include "MantidAPI/AnalysisDataService.h"
6
7
#include "MantidAPI/Axis.h"
#include "MantidAPI/ExperimentInfo.h"
8
#include "MantidAPI/FrameworkManager.h"
9
#include "MantidAPI/InstrumentDataService.h"
10
#include "MantidAPI/Workspace.h"
11
12
13
14
#include "MantidAPI/WorkspaceFactory.h"
#include "MantidDataHandling/LoadInstrument.h"
#include "MantidDataObjects/Workspace2D.h"
#include "MantidGeometry/Instrument/FitParameter.h"
15
#include "MantidGeometry/Instrument.h"
16
17
#include "MantidGeometry/Instrument/RectangularDetector.h"
#include "MantidKernel/Exception.h"
18
#include "MantidKernel/Strings.h"
19
20
#include "MantidTestHelpers/WorkspaceCreationHelper.h"
#include <cxxtest/TestSuite.h>
21

22
23
#include <fstream>
#include <string>
24
#include <vector>
25

26
using namespace Mantid;
27
28
29
30
31
32
using namespace Mantid::API;
using namespace Mantid::Kernel;
using namespace Mantid::Geometry;
using namespace Mantid::DataHandling;
using namespace Mantid::DataObjects;

33
class LoadInstrumentTest : public CxxTest::TestSuite {
34
public:
35
36
  void testInit() {
    TS_ASSERT(!loader.isInitialized());
37
    loader.initialize();
38
    TS_ASSERT(loader.isInitialized());
39
40
  }

41
42
43
  void testExecHET() {
    if (!loader.isInitialized())
      loader.initialize();
44

45
    // create a workspace with some sample data
46
47
48
    wsName = "LoadInstrumentTestHET";
    int histogramNumber = 2584;
    int timechannels = 100;
49
50
    Workspace_sptr ws = WorkspaceFactory::Instance().create(
        "Workspace2D", histogramNumber, timechannels, timechannels);
51
    Workspace2D_sptr ws2D = boost::dynamic_pointer_cast<Workspace2D>(ws);
52
53
54
55
56
    // loop to create data
    for (int i = 0; i < histogramNumber; i++) {
      boost::shared_ptr<Mantid::MantidVec> timeChannelsVec(
          new Mantid::MantidVec),
          v(new Mantid::MantidVec), e(new Mantid::MantidVec);
57
58
59
      timeChannelsVec->resize(timechannels);
      v->resize(timechannels);
      e->resize(timechannels);
60
61
62
63
64
      // timechannels
      for (int j = 0; j < timechannels; j++) {
        (*timeChannelsVec)[j] = j * 100;
        (*v)[j] = (i + j) % 256;
        (*e)[j] = (i + j) % 78;
65
66
67
68
69
70
      }
      // Populate the workspace.
      ws2D->setX(i, timeChannelsVec);
      ws2D->setData(i, v, e);
    }

71
    // put this workspace in the data service
72
    TS_ASSERT_THROWS_NOTHING(AnalysisDataService::Instance().add(wsName, ws2D));
73
    // We want to test id the spectra mapping changes
74
75
76
    TS_ASSERT_EQUALS(ws2D->getSpectrum(0)->getSpectrumNo(), 1);
    TS_ASSERT_EQUALS(ws2D->getSpectrum(256)->getSpectrumNo(), 257);
    TS_ASSERT_EQUALS(ws2D->getNumberHistograms(), 2584);
77

78
    loader.setPropertyValue("Filename", "HET_Definition.xml");
79
    loader.setProperty("RewriteSpectraMap", OptionalBool(true));
80
81
82
83
    inputFile = loader.getPropertyValue("Filename");
    loader.setPropertyValue("Workspace", wsName);

    std::string result;
84
85
    TS_ASSERT_THROWS_NOTHING(result = loader.getPropertyValue("Filename"));
    TS_ASSERT(!result.compare(inputFile));
86

87
88
    TS_ASSERT_THROWS_NOTHING(result = loader.getPropertyValue("Workspace"));
    TS_ASSERT(!result.compare(wsName));
89
90
91

    TS_ASSERT_THROWS_NOTHING(loader.execute());

92
    TS_ASSERT(loader.isExecuted());
93

94
    TS_ASSERT_EQUALS(loader.getPropertyValue("MonitorList"), "601,602,603,604");
95

96
97
98
99
100
101
102
103
    //    std::vector<detid_t> dets = ws2D->getInstrument()->getDetectorIDs();
    //    std::cout << dets.size() << " detectors in the instrument" <<
    //    std::endl;
    //    for (size_t i=0; i<dets.size(); i++)
    //    {
    //      if (i % 10 == 0) std::cout << std::endl;
    //      std::cout << dets[i] << ", ";
    //    }
104

105
106
    // Get back the saved workspace
    MatrixWorkspace_sptr output;
107
108
109
    TS_ASSERT_THROWS_NOTHING(
        output = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
            wsName));
110

111
112
    boost::shared_ptr<const Instrument> i =
        output->getInstrument()->baseInstrument();
113
    boost::shared_ptr<const IComponent> source = i->getSource();
114
115
    TS_ASSERT_EQUALS(source->getName(), "undulator");
    TS_ASSERT_DELTA(source->getPos().Y(), 0.0, 0.01);
116

117
    boost::shared_ptr<const IComponent> samplepos = i->getSample();
118
119
    TS_ASSERT_EQUALS(samplepos->getName(), "nickel-holder");
    TS_ASSERT_DELTA(samplepos->getPos().Z(), 0.0, 0.01);
120

121
    boost::shared_ptr<const IDetector> ptrDet103 = i->getDetector(103);
122
123
124
125
    TS_ASSERT_EQUALS(ptrDet103->getID(), 103);
    TS_ASSERT_EQUALS(ptrDet103->getName(), "pixel");
    TS_ASSERT_DELTA(ptrDet103->getPos().X(), 0.4013, 0.01);
    TS_ASSERT_DELTA(ptrDet103->getPos().Z(), 2.4470, 0.01);
126
    double d = ptrDet103->getPos().distance(samplepos->getPos());
127
    TS_ASSERT_DELTA(d, 2.512, 0.0001);
128
    double cmpDistance = ptrDet103->getDistance(*samplepos);
129
    TS_ASSERT_DELTA(cmpDistance, 2.512, 0.0001);
130
131

    // test if detector with det_id=603 has been marked as a monitor
132
    boost::shared_ptr<const IDetector> ptrMonitor = i->getDetector(601);
133
    TS_ASSERT(ptrMonitor->isMonitor());
134

135
136
    // Spectra mapping has been updated
    TS_ASSERT_EQUALS(output->getAxis(1)->spectraNo(0), 1);
137
    TS_ASSERT_EQUALS(output->getAxis(1)->spectraNo(255), 256);
138
139
    TS_ASSERT_EQUALS(output->getAxis(1)->spectraNo(256), 257);
    TS_ASSERT_EQUALS(output->getAxis(1)->spectraNo(257), 258);
140
141

    std::set<detid_t> ids_from_map = output->getSpectrum(257)->getDetectorIDs();
142
    IDetector_const_sptr det_from_ws = output->getDetector(257);
143
    TS_ASSERT_EQUALS(ids_from_map.size(), 1);
144
    TS_ASSERT_EQUALS(*ids_from_map.begin(), 602);
145
    TS_ASSERT_EQUALS(det_from_ws->getID(), 602);
146

147
148
    // also a few tests on the last detector and a test for the one beyond the
    // last
149
    boost::shared_ptr<const IDetector> ptrDetLast = i->getDetector(413256);
150
151
    TS_ASSERT_EQUALS(ptrDetLast->getID(), 413256);
    TS_ASSERT_EQUALS(ptrDetLast->getName(), "pixel");
152
153
154
    TS_ASSERT_THROWS(i->getDetector(413257), Exception::NotFoundError);

    // Test input data is unchanged
155
156
    Workspace2D_sptr output2DInst =
        boost::dynamic_pointer_cast<Workspace2D>(output);
157
    // Should be 2584
158
    TS_ASSERT_EQUALS(output2DInst->getNumberHistograms(), histogramNumber);
159

160
161
    // Check running algorithm for same XML file leads to same instrument object
    // being attached
162
    boost::shared_ptr<Instrument> instr = boost::make_shared<Instrument>();
163
    output->setInstrument(instr);
164
    TS_ASSERT_EQUALS(output->getInstrument()->baseInstrument(), instr);
165
    LoadInstrument loadAgain;
166
    TS_ASSERT_THROWS_NOTHING(loadAgain.initialize());
167
168
    loadAgain.setPropertyValue("Filename", inputFile);
    loadAgain.setPropertyValue("Workspace", wsName);
169
    loadAgain.setProperty("RewriteSpectraMap", OptionalBool(true));
170
171
    TS_ASSERT_THROWS_NOTHING(loadAgain.execute());
    TS_ASSERT_EQUALS(output->getInstrument()->baseInstrument(), i);
172

173
174
175
    // Valid-from/to
    Kernel::DateAndTime validFrom("1900-01-31T23:59:59");
    Kernel::DateAndTime validTo("2100-01-31 23:59:59");
176
177
    TS_ASSERT_EQUALS(i->getValidFromDate(), validFrom);
    TS_ASSERT_EQUALS(i->getValidToDate(), validTo);
178

179
180
181
    AnalysisDataService::Instance().remove(wsName);
  }

182
  void testExecSLS() {
183
184
185
186
    LoadInstrument loaderSLS;

    TS_ASSERT_THROWS_NOTHING(loaderSLS.initialize());

187
    // create a workspace with some sample data
188
    wsName = "LoadInstrumentTestSLS";
189
190
    Workspace_sptr ws =
        WorkspaceFactory::Instance().create("Workspace2D", 1, 1, 1);
191
192
    Workspace2D_sptr ws2D = boost::dynamic_pointer_cast<Workspace2D>(ws);

193
    // put this workspace in the data service
194
    TS_ASSERT_THROWS_NOTHING(AnalysisDataService::Instance().add(wsName, ws2D));
195
    loaderSLS.setPropertyValue("Filename", "SANDALS_Definition.xml");
196
    loaderSLS.setProperty("RewriteSpectraMap", OptionalBool(true));
197
198
199
200
201
    inputFile = loaderSLS.getPropertyValue("Filename");

    loaderSLS.setPropertyValue("Workspace", wsName);

    std::string result;
202
203
    TS_ASSERT_THROWS_NOTHING(result = loaderSLS.getPropertyValue("Filename"));
    TS_ASSERT(!result.compare(inputFile));
204

205
206
    TS_ASSERT_THROWS_NOTHING(result = loaderSLS.getPropertyValue("Workspace"));
    TS_ASSERT(!result.compare(wsName));
207
208
209

    TS_ASSERT_THROWS_NOTHING(loaderSLS.execute());

210
    TS_ASSERT(loaderSLS.isExecuted());
211
212
213

    // Get back the saved workspace
    MatrixWorkspace_sptr output;
214
215
216
    TS_ASSERT_THROWS_NOTHING(
        output = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
            wsName));
217

218
    boost::shared_ptr<const Instrument> i = output->getInstrument();
219
    boost::shared_ptr<const IComponent> source = i->getSource();
220
221
    TS_ASSERT_EQUALS(source->getName(), "undulator");
    TS_ASSERT_DELTA(source->getPos().Z(), -11.016, 0.01);
222

223
224
225
226
    boost::shared_ptr<const IObjComponent> samplepos =
        boost::dynamic_pointer_cast<const IObjComponent>(i->getSample());
    TS_ASSERT_EQUALS(samplepos->getName(), "nickel-holder");
    TS_ASSERT_DELTA(samplepos->getPos().Y(), 0.0, 0.01);
227

228
    boost::shared_ptr<const IDetector> ptrDet = i->getDetector(101);
229
    TS_ASSERT_EQUALS(ptrDet->getID(), 101);
230

231
    boost::shared_ptr<const IDetector> ptrMonitor = i->getDetector(1);
232
    TS_ASSERT(ptrMonitor->isMonitor());
233

234
    boost::shared_ptr<const IDetector> ptrDetShape = i->getDetector(102);
235
236
237
238
239
    TS_ASSERT(ptrDetShape->isValid(V3D(0.0, 0.0, 0.0) + ptrDetShape->getPos()));
    TS_ASSERT(
        ptrDetShape->isValid(V3D(0.0, 0.0, 0.000001) + ptrDetShape->getPos()));
    TS_ASSERT(ptrDetShape->isValid(V3D(0.005, 0.1, 0.000002) +
                                   ptrDetShape->getPos()));
240
241

    // test of sample shape
242
243
    TS_ASSERT(samplepos->isValid(V3D(0.0, 0.0, 0.005) + samplepos->getPos()));
    TS_ASSERT(!samplepos->isValid(V3D(0.0, 0.0, 0.05) + samplepos->getPos()));
244
245
246
247

    AnalysisDataService::Instance().remove(wsName);
  }

248
  void testExecNIMROD() {
249
250
251
252
    LoadInstrument loaderNIMROD;

    TS_ASSERT_THROWS_NOTHING(loaderNIMROD.initialize());

253
    // create a workspace with some sample data
254
    wsName = "LoadInstrumentTestNIMROD";
255
256
    Workspace_sptr ws =
        WorkspaceFactory::Instance().create("Workspace2D", 1, 1, 1);
257
258
    Workspace2D_sptr ws2D = boost::dynamic_pointer_cast<Workspace2D>(ws);

259
    // put this workspace in the data service
260
261
    TS_ASSERT_THROWS_NOTHING(AnalysisDataService::Instance().add(wsName, ws2D));

262
    loaderNIMROD.setPropertyValue("Filename", "NIM_Definition.xml");
263
    loaderNIMROD.setProperty("RewriteSpectraMap", OptionalBool(true));
264
265
266
267
268
    inputFile = loaderNIMROD.getPropertyValue("Filename");

    loaderNIMROD.setPropertyValue("Workspace", wsName);

    std::string result;
269
270
271
    TS_ASSERT_THROWS_NOTHING(result =
                                 loaderNIMROD.getPropertyValue("Filename"));
    TS_ASSERT(!result.compare(inputFile));
272

273
274
275
    TS_ASSERT_THROWS_NOTHING(result =
                                 loaderNIMROD.getPropertyValue("Workspace"));
    TS_ASSERT(!result.compare(wsName));
276
277
278

    TS_ASSERT_THROWS_NOTHING(loaderNIMROD.execute());

279
    TS_ASSERT(loaderNIMROD.isExecuted());
280
281
282

    // Get back the saved workspace
    MatrixWorkspace_sptr output;
283
284
285
    TS_ASSERT_THROWS_NOTHING(
        output = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
            wsName));
286

287
    boost::shared_ptr<const Instrument> i = output->getInstrument();
288

289
    boost::shared_ptr<const IDetector> ptrDet = i->getDetector(20201001);
290
291
292
293
294
    TS_ASSERT_EQUALS(ptrDet->getName(), "det 1");
    TS_ASSERT_EQUALS(ptrDet->getID(), 20201001);
    TS_ASSERT_DELTA(ptrDet->getPos().X(), -0.0909, 0.0001);
    TS_ASSERT_DELTA(ptrDet->getPos().Y(), 0.3983, 0.0001);
    TS_ASSERT_DELTA(ptrDet->getPos().Z(), 4.8888, 0.0001);
295
296
297
298

    AnalysisDataService::Instance().remove(wsName);
  }

299
300
301
302
303
  void testExecHRP2() {
    // Test Parameter file in instrument folder is used by an IDF file not in
    // the instrument folder
    doTestParameterFileSelection("IDFs_for_UNIT_TESTING/HRPD_Definition.xml",
                                 "HRPD_Parameters.xml", "S");
304
305
  }

306
307
308
309
310
311
312
313
  void testExecHRP3() {
    // Test Parameter file in instrument folder is used by an IDF file not in
    // the instrument folder and
    // with an extension of its name after the 'Definition' not present in a
    // parameter file.
    doTestParameterFileSelection(
        "IDFs_for_UNIT_TESTING/HRPD_Definition_Test3.xml",
        "HRPD_Parameters.xml", "S");
314
315
  }

316
317
318
319
320
321
322
323
  void testExecHRP4() {
    // Test Parameter file outside of instrument folder is used by an IDF file
    // in the same folder and
    // with the same extension ('_Test4') of its name after the 'Definition' or
    // 'Parameter'.
    doTestParameterFileSelection(
        "IDFs_for_UNIT_TESTING/HRPD_Definition_Test4.xml",
        "IDFs_for_UNIT_TESTING/HRPD_Parameters_Test4.xml", "T");
324
  }
325

326
327
328
329
330
331
  void testExecHRP5() {
    // Test Parameter file outside instrument folder is used by an IDF file in
    // the same folder
    doTestParameterFileSelection(
        "IDFs_for_UNIT_TESTING/HRPDTEST_Definition.xml",
        "IDFs_for_UNIT_TESTING/HRPDTEST_Parameters.xml", "U");
332
  }
333

334
335
336
337
338
339
340
341
342
343
  void testExecHRP6() {
    // Test Parameter file outside of instrument folder is used by an IDF file
    // in the same folder and
    // with the same extension ('_Test6') of its name after the 'Definition' or
    // 'Parameter'
    // even though there is a definition file without an extension in the same
    // folder.
    doTestParameterFileSelection(
        "IDFs_for_UNIT_TESTING/HRPDTEST_Definition_Test6.xml",
        "IDFs_for_UNIT_TESTING/HRPDTEST_Parameters_Test6.xml", "V");
344
345
  }

346
347
348
349
350
351
352
353
  void testExecHRP7() {
    // Test Parameter file outside instrument folder is used by an IDF file in
    // same instrument folder and
    // with an extension of its name after the 'Definition' not present in a
    // parameter file.
    doTestParameterFileSelection(
        "IDFs_for_UNIT_TESTING/HRPDTEST_Definition_Test7.xml",
        "HRPDTEST_Parameters.xml", "U");
354
355
  }

356
  void testNeutronicPositions() {
357
    // Make sure the IDS is empty
358
    InstrumentDataServiceImpl &IDS = InstrumentDataService::Instance();
359
    IDS.clear();
360

361
362
    LoadInstrument loader;
    loader.initialize();
363
364
365
366
367
    loader.setPropertyValue("Filename",
                            "IDFs_for_UNIT_TESTING/INDIRECT_Definition.xml");
    MatrixWorkspace_sptr ws =
        WorkspaceFactory::Instance().create("Workspace2D", 1, 1, 1);
    loader.setProperty("Workspace", ws);
368
    loader.setProperty("RewriteSpectraMap", OptionalBool(true));
369
370
371
372
373
374
375
376
377
378
    TS_ASSERT(loader.execute());

    // This kind of IDF should lead to 2 instrument definitions - the physical
    // and the neutronic
    // But only 1 goes into the IDS (the neutronic instrument holds the physical
    // instrument within itself)
    TS_ASSERT_EQUALS(IDS.size(), 1);
    if (IDS.size() != 1)
      return;
    TS_ASSERT_EQUALS(IDS.getObjects()[0]->getName(), "INDIRECT");
379

380
    // Retrieve the neutronic instrument from the InstrumentDataService
381
    Instrument_const_sptr neutronicInst = IDS.getObjects()[0];
382
383
    // And pull out a handle to the physical instrument from within the
    // neutronic one
384
    Instrument_const_sptr physicalInst = neutronicInst->getPhysicalInstrument();
385
    // They should not be the same object
386
387
388
389
    TS_ASSERT_DIFFERS(physicalInst.get(), neutronicInst.get());
    // Not true in general, but in this case we should not be getting a
    // paramaterized instrument
    TS_ASSERT(!physicalInst->isParametrized());
390

391
    // Check the positions of the 6 detectors in the physical instrument
392
393
394
395
396
397
    TS_ASSERT_EQUALS(physicalInst->getDetector(1000)->getPos(), V3D(0, 0, 0));
    TS_ASSERT_EQUALS(physicalInst->getDetector(1001)->getPos(), V3D(0, 1, 0));
    TS_ASSERT_EQUALS(physicalInst->getDetector(1002)->getPos(), V3D(1, 0, 0));
    TS_ASSERT_EQUALS(physicalInst->getDetector(1003)->getPos(), V3D(1, 1, 0));
    TS_ASSERT_EQUALS(physicalInst->getDetector(1004)->getPos(), V3D(2, 0, 0));
    TS_ASSERT_EQUALS(physicalInst->getDetector(1005)->getPos(), V3D(2, 1, 0));
398

399
    // Check the right instrument ended up on the workspace
400
401
    TS_ASSERT_EQUALS(neutronicInst.get(),
                     ws->getInstrument()->baseInstrument().get());
402
    // Check the neutronic positions
403
404
405
406
    TS_ASSERT_EQUALS(neutronicInst->getDetector(1000)->getPos(), V3D(2, 2, 0));
    TS_ASSERT_EQUALS(neutronicInst->getDetector(1001)->getPos(), V3D(2, 3, 0));
    TS_ASSERT_EQUALS(neutronicInst->getDetector(1002)->getPos(), V3D(3, 2, 0));
    TS_ASSERT_EQUALS(neutronicInst->getDetector(1003)->getPos(), V3D(3, 3, 0));
407
    // Note that one of the physical pixels doesn't exist in the neutronic space
408
409
410
411
412
413
414
415
    TS_ASSERT_THROWS(neutronicInst->getDetector(1004),
                     Exception::NotFoundError);
    TS_ASSERT_EQUALS(neutronicInst->getDetector(1005)->getPos(), V3D(4, 3, 0));

    // Check that the first 2 detectors share the same shape in the physical
    // instrument...
    TS_ASSERT_EQUALS(physicalInst->getDetector(1000)->shape(),
                     physicalInst->getDetector(1001)->shape())
416
    // ...but not in the neutronic instrument
417
418
    TS_ASSERT_DIFFERS(neutronicInst->getDetector(1000)->shape(),
                      neutronicInst->getDetector(1001)->shape())
419
    // Also, the same shape is shared between the corresponding '1000' detectors
420
421
    TS_ASSERT_EQUALS(physicalInst->getDetector(1000)->shape(),
                     neutronicInst->getDetector(1000)->shape())
422

423
    // Check the monitor is in the same place in each instrument
424
425
    TS_ASSERT_EQUALS(physicalInst->getDetector(1)->getPos(),
                     neutronicInst->getDetector(1)->getPos());
426
    // ...but is not the same object
427
428
    TS_ASSERT_DIFFERS(physicalInst->getDetector(1).get(),
                      neutronicInst->getDetector(1).get());
429

430
431
432
    // Clean up
    IDS.clear();
  }
433

434
  void test_loading_via_InstrumentXML_property() {
435
    // Make sure the IDS is empty
436
    InstrumentDataServiceImpl &IDS = InstrumentDataService::Instance();
437
438
439
440
441
    IDS.clear();

    // Minimal XML instrument, inspired by IDF_for_UNIT_TESTING3.xml
    const std::string instrumentXML =
        "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
442
443
444
        "<instrument name=\"xmlInst\" valid-from=\"1900-01-31 23:59:59\" "
        "valid-to=\"2100-01-31 23:59:59\" "
        "last-modified=\"2010-10-06T16:21:30\">"
445
446
        "<defaults />"
        "<component type=\"panel\" idlist=\"idlist_for_bank1\">"
447
448
        "<location r=\"0\" t=\"0\" rot=\"0\" axis-x=\"0\" axis-y=\"1\" "
        "axis-z=\"0\" name=\"bank1\" xpixels=\"3\" ypixels=\"2\" />"
449
450
        "</component>"
        "<type is=\"detector\" name=\"panel\">"
451
452
453
454
        "<properties/>"
        "<component type=\"pixel\">"
        "<location y=\"1\" x=\"1\"/>"
        "</component>"
455
456
        "</type>"
        "<type is=\"detector\" name=\"pixel\">"
457
458
        "<cuboid id=\"pixel-shape\" />"
        "<algebra val=\"pixel-shape\"/>"
459
460
        "</type>"
        "<idlist idname=\"idlist_for_bank1\">"
461
        "<id start=\"1005\" end=\"1005\" />"
462
463
464
465
        "</idlist>"
        "</instrument>";

    LoadInstrument instLoader;
466
    instLoader.setRethrows(true);
467
    instLoader.initialize();
468
    instLoader.setProperty("RewriteSpectraMap", OptionalBool(true));
469
470
471
472
473
474
    instLoader.setProperty("Workspace", WorkspaceFactory::Instance().create(
                                            "EventWorkspace", 1, 1, 1));
    instLoader.setProperty("InstrumentXML", instrumentXML);
    instLoader.setProperty(
        "InstrumentName",
        "Nonsense"); // Want to make sure it doesn't matter what we call it
475

476
    instLoader.execute();
477

478
    TS_ASSERT_EQUALS(1, IDS.size())
479
480
  }

481
  void test_failure_if_InstrumentXML_property_set_but_not_InstrumentName() {
482
483
    LoadInstrument instLoader;
    instLoader.initialize();
484
485
486
    instLoader.setProperty("Workspace", WorkspaceFactory::Instance().create(
                                            "EventWorkspace", 1, 1, 1));
    instLoader.setProperty("InstrumentXML", "<doesn't matter what>");
487
    instLoader.setProperty("RewriteSpectraMap", OptionalBool(true));
488
    TS_ASSERT(!instLoader.execute())
489
490
  }

491
  void test_failure_if_InstrumentXML_is_malformed() {
492
493
    LoadInstrument instLoader;
    instLoader.initialize();
494
495
496
    instLoader.setProperty("Workspace", WorkspaceFactory::Instance().create(
                                            "EventWorkspace", 1, 1, 1));
    instLoader.setProperty("InstrumentXML", "<instrument>");
497
    instLoader.setProperty("InstrumentName", "Nonsense");
498
    instLoader.setProperty("RewriteSpectraMap", OptionalBool(true));
499

500
    TS_ASSERT(!instLoader.execute())
501
  }
502

503
  void test_loading_default_view() {
504
    // Make sure the IDS is empty
505
    InstrumentDataServiceImpl &IDS = InstrumentDataService::Instance();
506
507
508
509
510
    IDS.clear();

    // Minimal XML instrument
    const std::string instrumentXML =
        "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
511
512
513
        "<instrument name=\"xmlInst\" valid-from=\"1900-01-31 23:59:59\" "
        "valid-to=\"2100-01-31 23:59:59\" "
        "last-modified=\"2010-10-06T16:21:30\">"
514
515
516
        "<defaults>"
        "<!-- view -->"
        "</defaults>"
517

518
        "<component type=\"panel\" idlist=\"idlist_for_bank1\">"
519
520
        "<location r=\"0\" t=\"0\" rot=\"0\" axis-x=\"0\" axis-y=\"1\" "
        "axis-z=\"0\" name=\"bank1\" xpixels=\"3\" ypixels=\"2\" />"
521
522
        "</component>"
        "<type is=\"detector\" name=\"panel\">"
523
524
525
526
        "<properties/>"
        "<component type=\"pixel\">"
        "<location y=\"1\" x=\"1\"/>"
        "</component>"
527
528
        "</type>"
        "<type is=\"detector\" name=\"pixel\">"
529
530
        "<cuboid id=\"pixel-shape\" />"
        "<algebra val=\"pixel-shape\"/>"
531
532
        "</type>"
        "<idlist idname=\"idlist_for_bank1\">"
533
        "<id start=\"1005\" end=\"1005\" />"
534
535
536
537
538
539
        "</idlist>"
        "</instrument>";

    LoadInstrument instLoader;
    instLoader.setRethrows(true);
    instLoader.initialize();
540
541
542
    instLoader.setProperty("Workspace", WorkspaceFactory::Instance().create(
                                            "EventWorkspace", 1, 1, 1));
    instLoader.setProperty("InstrumentXML", instrumentXML);
543
    instLoader.setProperty("RewriteSpectraMap", OptionalBool(true));
544
545
546
    instLoader.setProperty(
        "InstrumentName",
        "Nonsense"); // Want to make sure it doesn't matter what we call it
547
548
549
550
551
552

    instLoader.execute();

    TS_ASSERT_EQUALS(1, IDS.size());
    // test that the default default view is "3D"
    auto instr = IDS.getObjects().front();
553
    TS_ASSERT_EQUALS(instr->getDefaultView(), "3D");
554
555
556
    IDS.clear();

    // explicitely set the default instrument view
557
558
559
    const std::string instrumentXMLwithView = Mantid::Kernel::Strings::replace(
        instrumentXML, "<!-- view -->",
        "<default-view view=\"cylindrical_y\"/>");
560

561
562
563
    instLoader.setProperty("Workspace", WorkspaceFactory::Instance().create(
                                            "EventWorkspace", 1, 1, 1));
    instLoader.setProperty("InstrumentXML", instrumentXMLwithView);
564
    instLoader.setProperty("RewriteSpectraMap", OptionalBool(true));
565
566
567
    instLoader.setProperty(
        "InstrumentName",
        "Nonsense"); // Want to make sure it doesn't matter what we call it
568
569
570
571
572
573

    instLoader.execute();

    TS_ASSERT_EQUALS(1, IDS.size());
    // test that the default view is cylindrical_y
    instr = IDS.getObjects().front();
574
    TS_ASSERT_EQUALS(instr->getDefaultView(), "CYLINDRICAL_Y");
575
576
577
    IDS.clear();
  }

578
private:
579
  // @param filename Filename to an IDF
580
581
  // @param paramFilename Expected parameter file to be loaded as part of
  // LoadInstrument
582
  // @param par A specific parameter to check if have been loaded
583
584
585
  void doTestParameterFileSelection(std::string filename,
                                    std::string paramFilename,
                                    std::string par) {
586
587
588
589
590
591
    InstrumentDataService::Instance().clear();

    LoadInstrument loader;

    TS_ASSERT_THROWS_NOTHING(loader.initialize());

592
    // create a workspace with some sample data
593
    wsName = "LoadInstrumentTestForParameterFileSelection";
594
595
    Workspace_sptr ws =
        WorkspaceFactory::Instance().create("Workspace2D", 1, 1, 1);
596
597
    Workspace2D_sptr ws2D = boost::dynamic_pointer_cast<Workspace2D>(ws);

598
    // put this workspace in the data service
599
600
    TS_ASSERT_THROWS_NOTHING(AnalysisDataService::Instance().add(wsName, ws2D));

601
    // load IDF
602
    loader.setPropertyValue("Filename", filename);
603
    loader.setProperty("RewriteSpectraMap", OptionalBool(true));
604
605
606
    inputFile = loader.getPropertyValue("Filename");
    loader.setPropertyValue("Workspace", wsName);
    TS_ASSERT_THROWS_NOTHING(loader.execute());
607
    TS_ASSERT(loader.isExecuted());
608

609
610
    // Get back the saved workspace
    MatrixWorkspace_sptr output;
611
612
613
    TS_ASSERT_THROWS_NOTHING(
        output = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
            wsName));
614
615
616
617

    boost::shared_ptr<const Instrument> i = output->getInstrument();

    // test if a dummy parameter has been read in
618
619
620
    boost::shared_ptr<const IComponent> comp =
        i->getComponentByName("bank_90degnew");
    TS_ASSERT_EQUALS(comp->getName(), "bank_90degnew");
621

622
    ParameterMap &paramMap = output->instrumentParameters();
623

624
625
    // It's "X0" in parameter file
    // IDFs_for_UNIT_TESTING/HRPD_Parameters_Test4.xml
626
    Parameter_sptr param = paramMap.getRecursive(&(*comp), par, "fitting");
627
628
629
630
631
632
633
    TS_ASSERT(param);
    if (param != 0) {
      const FitParameter &fitParam4 = param->value<FitParameter>();
      TS_ASSERT(fitParam4.getTie().compare("") == 0);
      TS_ASSERT(fitParam4.getFunction().compare("BackToBackExponential") == 0);
    } else {
      TS_FAIL("Did not select " + paramFilename + " for " + filename);
634
635
636
637
638
    }

    AnalysisDataService::Instance().remove(wsName);
  }

639
640
641
642
643
  LoadInstrument loader;
  std::string inputFile;
  std::string wsName;
};

644
class LoadInstrumentTestPerformance : public CxxTest::TestSuite {
645
646
647
public:
  MatrixWorkspace_sptr ws;

648
  void setUp() { ws = WorkspaceCreationHelper::Create2DWorkspace(1, 2); }
649

650
651
  void doTest(std::string filename, size_t numTimes = 1) {
    for (size_t i = 0; i < numTimes; ++i) {
652
653
654
655
656
      // Remove any existing instruments, so each time they are loaded.
      InstrumentDataService::Instance().clear();
      // Load it fresh
      LoadInstrument loader;
      loader.initialize();
657
      loader.setProperty("RewriteSpectraMap", OptionalBool(true));
658
659
660
      loader.setProperty("Workspace", ws);
      loader.setPropertyValue("Filename", filename);
      loader.execute();
661
      TS_ASSERT(loader.isExecuted());
662
663
664
    }
  }

665
  void test_GEM() { doTest("GEM_Definition.xml", 10); }
666

667
  void test_WISH() { doTest("WISH_Definition.xml", 1); }
668

669
  void test_BASIS() { doTest("BASIS_Definition_0-20130119.xml", 5); }
670

671
  void test_CNCS() { doTest("CNCS_Definition.xml", 5); }
672

673
  void test_SEQUOIA() { doTest("SEQUOIA_Definition.xml", 5); }
674

675
  void test_POWGEN_2011() { doTest("POWGEN_Definition_2011-02-25.xml", 10); }
676

677
  void test_TOPAZ_2010() { doTest("TOPAZ_Definition_2010.xml", 1); }
678

679
  void test_TOPAZ_2011() { doTest("TOPAZ_Definition_2011-01-01.xml", 1); }
680

681
  void test_SNAP() { doTest("SNAP_Definition.xml", 1); }
682
683
};

684
#endif /*LOADINSTRUMENTTEST_H_*/