FunctionQDependsTest.h 7.13 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
11
12
13
14
15

// Mantid Coding standars <http://www.mantidproject.org/Coding_Standards>

// Mantid Headers from the same project
#include "MantidCurveFitting/Functions/FunctionQDepends.h"
// Mantid headers from other projects
#include "MantidAPI/IFunction.h"
#include "MantidAPI/MatrixWorkspace.h"
LamarMoore's avatar
LamarMoore committed
16
17
18
#include "MantidAPI/NumericAxis.h"
#include "MantidAPI/ParamFunction.h"
#include "MantidDataHandling/LoadNexus.h"
19
20
#include "MantidDataObjects/Workspace2D.h"
#include "MantidKernel/EmptyValues.h"
LamarMoore's avatar
LamarMoore committed
21
#include "MantidTestHelpers/WorkspaceCreationHelper.h"
22
23
24
25
26
27
28
29
// 3rd party library headers
#include <cxxtest/TestSuite.h>
// Standard library
// N/A

using Attr = Mantid::API::IFunction::Attribute;

namespace {
Jose Borreguero's avatar
Jose Borreguero committed
30
31
class ImplementsFunctionQDepends
    : public Mantid::CurveFitting::Functions::FunctionQDepends {
32
33
34
35

public:
  std::string name() const override { return "ImplementsFunctionQDepends"; }

Jose Borreguero's avatar
Jose Borreguero committed
36
37
  void function1D(double *out, const double *xValues,
                  const size_t nData) const override {
38
    double Q = this->getAttribute("Q").asDouble();
Jose Borreguero's avatar
Jose Borreguero committed
39
    for (size_t i = 0; i < nData; i++) {
40
41
42
43
44
45
46
      out[i] = Q * xValues[i];
    }
  }
};
} // end of namespace

class FunctionQDependsTest : public CxxTest::TestSuite {
47

48
49
50
public:
  // This pair of boilerplate methods prevent the suite being created statically
  // This means the constructor isn't called when running other tests
Jose Borreguero's avatar
Jose Borreguero committed
51
52
53
  static FunctionQDependsTest *createSuite() {
    return new FunctionQDependsTest();
  }
54
55
56
57
58
59
  static void destroySuite(FunctionQDependsTest *suite) { delete suite; }

  void testConstruction() {
    TS_ASSERT_THROWS_NOTHING(ImplementsFunctionQDepends f);
  }

60
61
62
63
64
  void testInitialization() {
    ImplementsFunctionQDepends f;
    TS_ASSERT_THROWS_NOTHING(f.initialize());
  }

65
66
67
  void testSetWorkspace() {
    double startX{0.0}, endX{1.0};
    ImplementsFunctionQDepends f;
68
    f.initialize(); // declare attributes
69
    // test with an non matrix workspace
Jose Borreguero's avatar
Jose Borreguero committed
70
71
    TS_ASSERT_THROWS_NOTHING(
        f.setMatrixWorkspace(this->unsuitableWS(), 0, startX, endX));
72
    // test with a non-suitable matrix workspace
Jose Borreguero's avatar
Jose Borreguero committed
73
74
    TS_ASSERT_THROWS_NOTHING(
        f.setMatrixWorkspace(this->withoutQ(), 0, startX, endX));
75
    // test with a workspace containing Q values in the vertical axis
Jose Borreguero's avatar
Jose Borreguero committed
76
77
    TS_ASSERT_THROWS_NOTHING(
        f.setMatrixWorkspace(this->withQonVerticalAxis(), 0, startX, endX));
78
    // test with a workspace containing detectors for calculation of Q values
Jose Borreguero's avatar
Jose Borreguero committed
79
80
    TS_ASSERT_THROWS_NOTHING(
        f.setMatrixWorkspace(this->withDetectors(), 0, startX, endX));
81
82
83
84
85
  }

  void testQAttribute() {
    double startX{0.0}, endX{1.0};
    ImplementsFunctionQDepends f;
86
    f.initialize(); // declare attributes
87
88
89
90
91
92
93
94
95
96
97
    auto Q = f.getAttribute("Q").asDouble();
    TS_ASSERT_EQUALS(Q, Mantid::EMPTY_DBL());
    f.setMatrixWorkspace(this->unsuitableWS(), 0, startX, endX);
    TS_ASSERT_EQUALS(Q, Mantid::EMPTY_DBL());
    f.setMatrixWorkspace(this->withoutQ(), 0, startX, endX);
    TS_ASSERT_EQUALS(Q, Mantid::EMPTY_DBL());
    // test assigning Q when no matrix workspace has been set
    f.setAttribute("Q", Attr(0.18));
    TS_ASSERT_EQUALS(f.getAttribute("Q").asDouble(), 0.18);
    // test assigning Q when a workspace has been set
    f.setMatrixWorkspace(this->withQonVerticalAxis(), 1, startX, endX);
Jose Borreguero's avatar
Jose Borreguero committed
98
    TS_ASSERT_EQUALS(f.getAttribute("Q").asDouble(), 0.5); // Q overwritten
99
100
101
102
103
104
105
    f.setAttribute("Q", Attr(0.18));
    TS_ASSERT_EQUALS(f.getAttribute("Q").asDouble(), 0.5); // Q not overwritten
  }

  void testWorkspaceIndexAttribute() {
    double startX{0.0}, endX{1.0};
    ImplementsFunctionQDepends f;
106
    f.initialize(); // declare attributes
107
108
109
110
111
112
113
114
    auto wi = f.getAttribute("WorkspaceIndex").asInt();
    TS_ASSERT_EQUALS(wi, Mantid::EMPTY_INT());
    f.setMatrixWorkspace(this->unsuitableWS(), 0, startX, endX);
    TS_ASSERT_EQUALS(wi, Mantid::EMPTY_INT());
    f.setMatrixWorkspace(this->withoutQ(), 0, startX, endX);
    TS_ASSERT_EQUALS(wi, Mantid::EMPTY_INT());
    // test assigning wi when no matrix workspace has been set
    f.setAttribute("WorkspaceIndex", Attr(1));
Jose Borreguero's avatar
Jose Borreguero committed
115
116
    TS_ASSERT_EQUALS(f.getAttribute("WorkspaceIndex").asInt(),
                     Mantid::EMPTY_INT()); // not overwritten
117
118
119
120
    // test assigning wi when a workspace has been set
    f.setMatrixWorkspace(this->withQonVerticalAxis(), 1, startX, endX);
    TS_ASSERT_EQUALS(f.getAttribute("WorkspaceIndex").asInt(), 1);
    f.setAttribute("WorkspaceIndex", Attr(0));
Jose Borreguero's avatar
Jose Borreguero committed
121
122
    TS_ASSERT_EQUALS(f.getAttribute("WorkspaceIndex").asInt(),
                     0); // WorkspaceIndex overwritten
123
124
125
126
127
  }

  void testWorkspaceIndexTiesQ() {
    double startX{0.0}, endX{1.0};
    ImplementsFunctionQDepends f;
128
    f.initialize(); // declare attributes
129
    f.setMatrixWorkspace(this->withQonVerticalAxis(), 1, startX, endX);
Jose Borreguero's avatar
Jose Borreguero committed
130
    TS_ASSERT_EQUALS(f.getAttribute("Q").asDouble(), 0.5); // Q overwritten
131
    f.setAttribute("WorkspaceIndex", Attr(0));
Jose Borreguero's avatar
Jose Borreguero committed
132
    TS_ASSERT_EQUALS(f.getAttribute("Q").asDouble(), 0.3); // Q overwritten
133
    f.setMatrixWorkspace(this->withDetectors(), 9, startX, endX);
Jose Borreguero's avatar
Jose Borreguero committed
134
135
    TS_ASSERT_DELTA(f.getAttribute("Q").asDouble(), 1.82,
                    0.01); // Q overwritten
136
137
138
139
140
    Mantid::API::AnalysisDataService::Instance().clear();
  }

private:
  // return a MatrixWorkspace with Q values on the vertical axis
Jose Borreguero's avatar
Jose Borreguero committed
141
  Mantid::DataObjects::Workspace2D_sptr withQonVerticalAxis() {
142
143
    int nhist{4}, nbins{9};
    // create an axis of Q-values
Jose Borreguero's avatar
Jose Borreguero committed
144
145
    std::vector<double> qvalues{
        0.3, 0.5, 0.5, 0.9}; // as many elements as the value of variable nhist
146
    auto momenta = std::make_unique<Mantid::API::NumericAxis>(qvalues);
147
148
    momenta->setUnit("MomentumTransfer");
    // create the matrix workspace
149
    auto ws = WorkspaceCreationHelper::create2DWorkspaceBinned(nhist, nbins);
150
    ws->replaceAxis(1, std::move(momenta));
151
152
153
154
    return ws;
  }

  // return a MatrixWorkspace with detectors allowing computations of Q values
Jose Borreguero's avatar
Jose Borreguero committed
155
  Mantid::API::MatrixWorkspace_sptr withDetectors() {
156
    Mantid::DataHandling::LoadNexus loader;
Srikanth Ravipati's avatar
Srikanth Ravipati committed
157
158
    Mantid::Kernel::ConfigService::Instance().setString("default.facility",
                                                        "ISIS");
159
160
161
162
163
    loader.initialize();
    loader.setPropertyValue("Filename", "irs26173_graphite002_red");
    loader.setPropertyValue("OutputWorkspace", "irs26173");
    TS_ASSERT_THROWS_NOTHING(loader.execute());
    TS_ASSERT(loader.isExecuted());
Srikanth Ravipati's avatar
Srikanth Ravipati committed
164
    Mantid::Kernel::ConfigService::Instance().setString("default.facility",
165
                                                        " ");
Jose Borreguero's avatar
Jose Borreguero committed
166
167
    return Mantid::API::AnalysisDataService::Instance()
        .retrieveWS<Mantid::API::MatrixWorkspace>("irs26173");
168
169
170
  }

  // return a MatrixWorkspace without Q values
Jose Borreguero's avatar
Jose Borreguero committed
171
  Mantid::DataObjects::Workspace2D_sptr withoutQ() {
172
    int nhist{3}, nbins{9};
173
    return WorkspaceCreationHelper::create2DWorkspaceBinned(nhist, nbins);
174
175
176
  }

  // return a Workspace not of MatrixWorkspace type
Jose Borreguero's avatar
Jose Borreguero committed
177
  Mantid::DataObjects::EventWorkspace_sptr unsuitableWS() {
178
    return WorkspaceCreationHelper::createEventWorkspace();
179
180
  }
};