ALFCustomInstrumentModel.cpp 7.1 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
#include "ALFCustomInstrumentModel.h"
8
9
10
#include "MantidAPI/Algorithm.h"
#include "MantidAPI/AlgorithmManager.h"
#include "MantidAPI/AnalysisDataService.h"
11
12
13
14
15
16
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidAPI/NumericAxis.h"
#include "MantidGeometry/Instrument.h"
#include "MantidKernel/Unit.h"

#include <utility>
17

18
namespace {
19
20
const std::string EXTRACTEDWS = "extractedTubes_";
const std::string CURVES = "Curves";
21
} // namespace
22

23
using namespace Mantid::API;
24
namespace MantidQt::CustomInterfaces {
25

26
27
28
ALFCustomInstrumentModel::ALFCustomInstrumentModel()
    : m_numberOfTubesInAverage(0),
      m_base(std::make_unique<MantidWidgets::BaseCustomInstrumentModel>("ALF_tmp", "ALF", "ALFData")) {}
29

30
/*
31
 * Runs load data alg
32
33
 * @param name:: string name for ALF data
 */
34
void ALFCustomInstrumentModel::loadAlg(const std::string &name) {
35
  auto alg = AlgorithmManager::Instance().create("Load");
36
37
  alg->initialize();
  alg->setProperty("Filename", name);
38
  alg->setProperty("OutputWorkspace", getTmpName()); // write to tmp ws
39
  alg->execute();
40
}
41
42
43
44
45
46
47

/*
 * Loads data for use in ALFView
 * Loads data, normalise to current and then converts to d spacing
 * @param name:: string name for ALF data
 * @return std::pair<int,std::string>:: the run number and status
 */
Samuel Jones's avatar
Samuel Jones committed
48
std::pair<int, std::string> ALFCustomInstrumentModel::loadData(const std::string &name) {
49
  loadAlg(name);
Samuel Jones's avatar
Samuel Jones committed
50
  auto ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(getTmpName());
51
52
53
54
  int runNumber = ws->getRunNumber();
  std::string message = "success";
  auto bools = isDataValid();
  if (bools["IsValidInstrument"]) {
Anthony Lim's avatar
Anthony Lim committed
55
    rename();
56
    m_numberOfTubesInAverage = 0;
57
58
  } else {
    // reset to the previous data
59
    message = "Not the correct instrument, expected " + getInstrument();
60
61
62
63
64
65
    remove();
  }
  if (bools["IsValidInstrument"] && !bools["IsItDSpace"]) {
    transformData();
  }
  return std::make_pair(runNumber, message);
66
67
68
69
70
71
}
/*
 * Checks loaded data is from ALF
 * Loads data, normalise to current and then converts to d spacing
 * @return pair<bool,bool>:: If the instrument is ALF, if it is d-spacing
 */
72
std::map<std::string, bool> ALFCustomInstrumentModel::isDataValid() {
Samuel Jones's avatar
Samuel Jones committed
73
  auto ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(getTmpName());
74
  bool isItALF = false;
75

76
  if (ws->getInstrument()->getName() == getInstrument()) {
77
78
79
80
    isItALF = true;
  }
  auto axis = ws->getAxis(0);
  auto unit = axis->unit()->unitID();
81
  bool isItDSpace = true;
82
83
  if (unit != "dSpacing") {
    isItDSpace = false;
84
  }
85
  return {{"IsValidInstrument", isItALF}, {"IsItDSpace", isItDSpace}};
86
87
88
89
90
91
}

/*
 * Transforms ALF data; normalise to current and then converts to d spacing
 * If already d-space does nothing.
 */
92
void ALFCustomInstrumentModel::transformData() {
93
  auto normAlg = AlgorithmManager::Instance().create("NormaliseByCurrent");
94
  normAlg->initialize();
95
96
  normAlg->setProperty("InputWorkspace", getWSName());
  normAlg->setProperty("OutputWorkspace", getWSName());
97
98
  normAlg->execute();

99
  auto dSpacingAlg = AlgorithmManager::Instance().create("ConvertUnits");
100
  dSpacingAlg->initialize();
101
  dSpacingAlg->setProperty("InputWorkspace", getWSName());
102
  dSpacingAlg->setProperty("Target", "dSpacing");
103
  dSpacingAlg->setProperty("OutputWorkspace", getWSName());
104
105
106
  dSpacingAlg->execute();
}

107
void ALFCustomInstrumentModel::storeSingleTube(const std::string &name) {
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
  auto alg = AlgorithmManager::Instance().create("ScaleX");
  alg->initialize();
  alg->setProperty("InputWorkspace", CURVES);
  alg->setProperty("OutputWorkspace", EXTRACTEDWS + name);
  alg->setProperty("Factor", 180. / M_PI); // convert to degrees
  alg->execute();

  auto histogramAlg = AlgorithmManager::Instance().create("ConvertToHistogram");
  histogramAlg->initialize();
  histogramAlg->setProperty("InputWorkspace", EXTRACTEDWS + name);
  histogramAlg->setProperty("OutputWorkspace", EXTRACTEDWS + name);
  histogramAlg->execute();

  AnalysisDataService::Instance().remove(CURVES);
}
123

124
std::string ALFCustomInstrumentModel::WSName() {
125
  std::string name = getInstrument() + std::to_string(getCurrentRun());
126
127
  return EXTRACTEDWS + name;
}
128

129
void ALFCustomInstrumentModel::averageTube() {
130
  const std::string name = getInstrument() + std::to_string(getCurrentRun());
131
  const int oldTotalNumber = m_numberOfTubesInAverage;
132
  // multiply up current average
Samuel Jones's avatar
Samuel Jones committed
133
  auto ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(EXTRACTEDWS + name);
Anthony Lim's avatar
Anthony Lim committed
134
  ws *= double(oldTotalNumber);
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

  // get the data to add
  storeSingleTube(name);
  // rebin to match
  auto rebin = AlgorithmManager::Instance().create("RebinToWorkspace");
  rebin->initialize();
  rebin->setProperty("WorkspaceToRebin", EXTRACTEDWS + name);
  rebin->setProperty("WorkspaceToMatch", ws);
  rebin->setProperty("OutputWorkspace", EXTRACTEDWS + name);
  rebin->execute();

  // add together
  auto alg = AlgorithmManager::Instance().create("Plus");
  alg->initialize();
  alg->setProperty("LHSWorkspace", EXTRACTEDWS + name);
  alg->setProperty("RHSWorkspace", ws);
  alg->setProperty("OutputWorkspace", EXTRACTEDWS + name);
  alg->execute();
  // do division
Samuel Jones's avatar
Samuel Jones committed
154
  ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(EXTRACTEDWS + name);
155
156
  ws->mutableY(0) /= (double(oldTotalNumber) + 1.0);
  AnalysisDataService::Instance().addOrReplace(EXTRACTEDWS + name, ws);
157
  m_numberOfTubesInAverage++;
158
159
}

160
bool ALFCustomInstrumentModel::hasTubeBeenExtracted(const std::string &name) {
161
162
163
  return AnalysisDataService::Instance().doesExist(EXTRACTEDWS + name);
}

Samuel Jones's avatar
Samuel Jones committed
164
bool ALFCustomInstrumentModel::extractTubeCondition(std::map<std::string, bool> tabBools) {
165
166
  try {

Samuel Jones's avatar
Samuel Jones committed
167
    bool ifCurve = (tabBools.find("plotStored")->second || tabBools.find("hasCurve")->second);
168
169
170
171
172
173
    return (tabBools.find("isTube")->second && ifCurve);
  } catch (...) {
    return false;
  }
}

Samuel Jones's avatar
Samuel Jones committed
174
bool ALFCustomInstrumentModel::averageTubeCondition(std::map<std::string, bool> tabBools) {
175
176
  try {

Samuel Jones's avatar
Samuel Jones committed
177
178
179
    bool ifCurve = (tabBools.find("plotStored")->second || tabBools.find("hasCurve")->second);
    return (m_numberOfTubesInAverage > 0 && tabBools.find("isTube")->second && ifCurve &&
            hasTubeBeenExtracted(getInstrument() + std::to_string(getCurrentRun())));
180
181
182
183
  } catch (...) {
    return false;
  }
}
184
void ALFCustomInstrumentModel::extractSingleTube() {
185
  storeSingleTube(getInstrument() + std::to_string(getCurrentRun()));
186
187
188
  m_numberOfTubesInAverage = 1;
}

189
CompositeFunction_sptr ALFCustomInstrumentModel::getDefaultFunction() {
190

Samuel Jones's avatar
Samuel Jones committed
191
192
  CompositeFunction_sptr composite = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(
      Mantid::API::FunctionFactory::Instance().createFunction("CompositeFunction"));
Anthony Lim's avatar
Anthony Lim committed
193

Samuel Jones's avatar
Samuel Jones committed
194
  auto func = Mantid::API::FunctionFactory::Instance().createInitialized("name = FlatBackground");
195
  composite->addFunction(func);
Samuel Jones's avatar
Samuel Jones committed
196
  func = Mantid::API::FunctionFactory::Instance().createInitialized("name = Gaussian, Height = 3., Sigma= 1.0");
197
198
199
  composite->addFunction(func);
  return composite;
}
200

201
} // namespace MantidQt::CustomInterfaces