FindDeadDetectorsTest.h 5.86 KB
Newer Older
Nick Draper's avatar
re #244  
Nick Draper committed
1
2
3
4
5
6
7
8
9
#ifndef FINDDEADDETECTORSTEST_H_
#define FINDDEADDETECTORSTEST_H_

#include <cxxtest/TestSuite.h>

#include "MantidAlgorithms/FindDeadDetectors.h"
#include "MantidAPI/AnalysisDataService.h"
#include "MantidAPI/WorkspaceFactory.h"
#include "MantidDataObjects/Workspace2D.h"
10
#include "MantidGeometry/Instrument.h"
11
#include "MantidTestHelpers/WorkspaceCreationHelper.h"
12

13
#include <Poco/File.h>
Nick Draper's avatar
re #244  
Nick Draper committed
14

15
16
#include <fstream>

Nick Draper's avatar
re #244  
Nick Draper committed
17
18
19
20
using namespace Mantid::API;
using namespace Mantid::Kernel;
using namespace Mantid::Algorithms;
using namespace Mantid::DataObjects;
21
using namespace Mantid::Geometry;
Nick Draper's avatar
re #244  
Nick Draper committed
22

23
class FindDeadDetectorsTest : public CxxTest::TestSuite {
Nick Draper's avatar
re #244  
Nick Draper committed
24
public:
25
  void testInit() {
Nick Draper's avatar
re #244  
Nick Draper committed
26
27
28
    FindDeadDetectors alg;

    TS_ASSERT_THROWS_NOTHING(alg.initialize());
29
    TS_ASSERT(alg.isInitialized());
Nick Draper's avatar
re #244  
Nick Draper committed
30
31
  }

32
  void testExec() {
33
34
    const std::string liveVal = "1", deadVal = "2";
    const int sizex = 10, sizey = 20;
35
36
    // Register the workspace in the data service and initialise it with abitary
    // data
37
    Workspace2D_sptr work_in =
38
39
        // the x values look like this -1, 2, 5, 8, 11, 14, 17, 20, 23, 26
        WorkspaceCreationHelper::Create2DWorkspaceBinned(sizey, sizex, -1, 3.0);
40

41
42
43
    Instrument_sptr instr(new Instrument);
    work_in->setInstrument(instr);

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
    // yVeryDead is a detector that never responds and produces no counts
    boost::shared_ptr<Mantid::MantidVec> yVeryDead(
        new Mantid::MantidVec(sizex, 0));
    // yTooDead gives some counts at the start but has a whole region full of
    // zeros
    double TD[sizex] = {2, 4, 5, 1, 0, 0, 0, 0, 0, 0};
    boost::shared_ptr<Mantid::MantidVec> yTooDead(
        new Mantid::MantidVec(TD, TD + 10));
    // yStrange dies after giving some counts but then comes back
    double S[sizex] = {0.2, 4, 50, 0.001, 0, 0, 0, 0, 1, 0};
    boost::shared_ptr<Mantid::MantidVec> yStrange(
        new Mantid::MantidVec(S, S + 10));
    for (int i = 0; i < sizey; i++) {
      if (i % 3 == 0) { // the last column is set arbitrarily to have the same
                        // values as the second because the errors shouldn't
                        // make any difference
60
61
        work_in->setData(i, yTooDead, yTooDead);
      }
62
      if (i % 2 == 0) {
63
64
        work_in->setData(i, yVeryDead, yVeryDead);
      }
65
      if (i == 19) {
66
67
        work_in->setData(i, yStrange, yTooDead);
      }
68
69
      work_in->getSpectrum(i)->setSpectrumNo(i);

70
71
      Mantid::Geometry::Detector *det =
          new Mantid::Geometry::Detector("", i, NULL);
72
73
      instr->add(det);
      instr->markAsDetector(det);
74
      work_in->getSpectrum(i)->setDetectorID(i);
75
76
77
78
79
80
    }

    FindDeadDetectors alg;

    AnalysisDataService::Instance().add("testdead_in", work_in);
    alg.initialize();
81
82
83
    alg.setPropertyValue("InputWorkspace", "testdead_in");
    alg.setPropertyValue("OutputWorkspace", "testdead_out");
    alg.setPropertyValue("DeadThreshold", "0");
84
85
    alg.setPropertyValue("LiveValue", liveVal);
    alg.setPropertyValue("DeadValue", deadVal);
86
    std::string filename = "testFile.txt";
87
    alg.setPropertyValue("OutputFile", filename);
88
89
90

    // Testing behavour with Range_lower or Range_upper not set
    TS_ASSERT_THROWS_NOTHING(alg.execute());
91
    TS_ASSERT(alg.isExecuted());
92
    std::vector<int> deadDets;
93
94
95
96
    TS_ASSERT_THROWS_NOTHING(deadDets = alg.getProperty("FoundDead"))
    // it will scan the whole range and so only find the very dead detectors,
    // there are 10 of them
    TS_ASSERT_EQUALS(deadDets.size(), 10)
97
98
99

    // Get back the output workspace
    MatrixWorkspace_sptr work_out;
100
101
102
    TS_ASSERT_THROWS_NOTHING(
        work_out = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
            "testdead_out"));
103

104
    for (int i = 0; i < sizey; i++) {
105
106
      const double val = work_out->readY(i)[0];
      double valExpected = 1;
107
108
109
      if (i % 2 == 0) {
        valExpected = 2;
        TS_ASSERT_EQUALS(deadDets[i / 2], i)
110
      }
111
      TS_ASSERT_DELTA(val, valExpected, 1e-9);
112
113
114
    }

    std::fstream outFile(filename.c_str());
115
    TS_ASSERT(outFile)
116
117
118
    outFile.close();
    Poco::File(filename).remove();

119
120
    // Set Range_lower to later in the histogram when the yTooDead detectors
    // stop working
121
122
123
    alg.setPropertyValue("RangeLower", "11.0");
    alg.initialize();
    TS_ASSERT_THROWS_NOTHING(alg.execute());
124
125
    TS_ASSERT(alg.isExecuted());
    // retrieve the output workspace
126
    TS_ASSERT_THROWS_NOTHING(
127
128
129
130
        work_out = boost::dynamic_pointer_cast<MatrixWorkspace>(
            AnalysisDataService::Instance().retrieve("testdead_out")))
    // Check the dead detectors found agrees with what was setup above
    for (int i = 0; i < sizey; i++) {
131
132
      const double val = work_out->readY(i)[0];
      double valExpected = boost::lexical_cast<double>(liveVal);
133
134
135
136
      // i%2 == 0 is the veryDead i%3 == 0 is the TooDead
      if (i % 2 == 0 || i % 3 == 0)
        valExpected = boost::lexical_cast<double>(deadVal);
      TS_ASSERT_DELTA(val, valExpected, 1e-9);
137
138
139
140
141
142
    }

    // Set Range_upper to before the end which will pickup the strange
    alg.setPropertyValue("RangeUpper", "20");
    alg.initialize();
    TS_ASSERT_THROWS_NOTHING(alg.execute());
143
144
    TS_ASSERT(alg.isExecuted());
    // retrieve the output workspace
145
    TS_ASSERT_THROWS_NOTHING(
146
147
148
149
        work_out = boost::dynamic_pointer_cast<MatrixWorkspace>(
            AnalysisDataService::Instance().retrieve("testdead_out")))
    // Check the dead detectors found agrees with what was setup above
    for (int i = 0; i < sizey; i++) {
150
151
      const double val = work_out->readY(i)[0];
      double valExpected = boost::lexical_cast<double>(liveVal);
152
153
154
155
      // i%2 == 0 is the veryDead i%3 == 0 is the TooDead i == 19 is the strange
      if (i % 2 == 0 || i % 3 == 0 || i == 19)
        valExpected = boost::lexical_cast<double>(deadVal);
      TS_ASSERT_DELTA(val, valExpected, 1e-9);
156
157
158
    }

    AnalysisDataService::Instance().remove("testdead_in");
Nick Draper's avatar
re #244  
Nick Draper committed
159
160
161
162
163
    AnalysisDataService::Instance().remove("testdead_out");
  }
};

#endif /*FINDDEADDETECTORSTEST_H_*/