Mantid
Loading...
Searching...
No Matches
PlotPeakByLogValueHelper.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
9#include "MantidAPI/Axis.h"
11#include "MantidAPI/Workspace.h"
15#include <boost/lexical_cast.hpp>
16
17namespace {
18Mantid::Kernel::Logger g_log("PlotPeakByLogValue");
19}
20
22
23// Ideally this would use boost::try_lexical_cast in order to avoid too many
24// exceptions
25// but we do not yet have the correct version of boost.
26template <class Type> Type lexCast(std::string input, const std::string &errorMessage) {
27 try {
28 return boost::lexical_cast<Type>(input);
29 } catch (boost::bad_lexical_cast &) {
30 throw std::runtime_error(errorMessage + input);
31 }
32}
33
34void parseValueRange(const std::string &index, double &start, double &end, int &wi, int &spec) {
35 if (index.size() > 1) { // there is some text after 'v'
38 if (range.count() < 1) {
39 wi = WHOLE_RANGE; // means use the whole range
40 } else if (range.count() == 1) {
41 try {
42 start = boost::lexical_cast<double>(range[0]);
43 } catch (boost::bad_lexical_cast &) {
44 throw std::runtime_error(std::string("Provided incorrect range values. Range is "
45 "specfifed by start_value:stop_value, but "
46 "provided ") +
47 range[0]);
48 }
49
50 end = start;
51 wi = NOT_SET;
52 spec = NOT_SET;
53 } else {
54 std::string errorMessage = std::string("Provided incorrect range values. Range is "
55 "specfifed by start_value:stop_value, but "
56 "provided ") +
57 range[0] + std::string(" and ") + range[1];
58 start = lexCast<double>(range[0], errorMessage);
59 end = lexCast<double>(range[1], errorMessage);
60
61 if (start > end)
62 std::swap(start, end);
63 wi = NOT_SET;
64 spec = NOT_SET;
65 }
66 } else {
67 wi = WHOLE_RANGE;
68 }
69}
70
71void addGroupWorkspace(std::vector<InputSpectraToFit> &nameList, double start, double end, int wi, int spec, int period,
72 const std::shared_ptr<API::WorkspaceGroup> &wsg);
73void addMatrixworkspace(std::vector<InputSpectraToFit> &nameList, double start, double end, const std::string &name,
74 int wi, int spec, int period, const std::optional<API::Workspace_sptr> &workspaceOptional,
75 const std::shared_ptr<API::MatrixWorkspace> &wsMatrix);
77std::vector<InputSpectraToFit> makeNames(const std::string &inputList, int default_wi, int default_spec) {
78 std::vector<InputSpectraToFit> nameList;
79
80 double start = 0;
81 double end = 0;
82
85 for (const auto &input : names) {
86 tokenizer params(input, ",", tokenizer::TOK_TRIM);
87 std::string name = params[0];
88 int wi = default_wi;
89 int spec = default_spec;
90 if (params.count() > 1) {
91 std::string index = params[1]; // spectrum or workspace index with a prefix
92 if (index.size() > 2 && index.substr(0, 2) == "sp") { // spectrum number
93 spec = boost::lexical_cast<int>(index.substr(2));
94 wi = SpecialIndex::NOT_SET; // undefined yet
95 } else if (index.size() > 1 && index[0] == 'i') { // workspace index
96 wi = boost::lexical_cast<int>(index.substr(1));
97 spec = SpecialIndex::NOT_SET; // undefined yet
98 } else if (!index.empty() && index[0] == 'v') {
99 parseValueRange(index, start, end, wi, spec);
100 }
101 }
102 int period = 1;
103 if (params.count() > 2 && !params[2].empty()) {
104 period = lexCast<int>(params[2], "Incorrect value for a period: " + params[2]);
105 }
106
107 auto workspaceOptional = getWorkspace(name, period);
108 if (!workspaceOptional)
109 continue;
110
111 auto wsg = std::dynamic_pointer_cast<API::WorkspaceGroup>(workspaceOptional.value());
112 auto wsMatrix = std::dynamic_pointer_cast<API::MatrixWorkspace>(workspaceOptional.value());
113 if (wsg) {
114 addGroupWorkspace(nameList, start, end, wi, spec, period, wsg);
115
116 } else if (wsMatrix) {
117 addMatrixworkspace(nameList, start, end, name, wi, spec, period, workspaceOptional, wsMatrix);
118 }
119 }
120 return nameList;
121}
122void addMatrixworkspace(std::vector<InputSpectraToFit> &nameList, double start, double end, const std::string &name,
123 int wi, int spec, int period, const std::optional<API::Workspace_sptr> &workspaceOptional,
124 const std::shared_ptr<API::MatrixWorkspace> &wsMatrix) {
125 appendInputSpectraToList(nameList, name, wsMatrix, wi, spec, start, end, period, workspaceOptional.has_value());
126}
127void addGroupWorkspace(std::vector<InputSpectraToFit> &nameList, double start, double end, int wi, int spec, int period,
128 const std::shared_ptr<API::WorkspaceGroup> &wsg) {
129 const std::vector<std::string> wsNames = wsg->getNames();
130
131 for (const auto &wsName : wsNames) {
132 if (auto workspace =
133 std::dynamic_pointer_cast<API::MatrixWorkspace>(API::AnalysisDataService::Instance().retrieve(wsName))) {
134 appendInputSpectraToList(nameList, wsName, workspace, wi, spec, start, end, period, true);
135 }
136 }
137}
138
150void appendInputSpectraToList(std::vector<InputSpectraToFit> &nameList, const std::string &name,
151 const std::shared_ptr<API::MatrixWorkspace> &ws, int workspaceIndex, int spectrumNumber,
152 double start, double end, int period, const bool &workspaceOptional) {
153 auto mws = workspaceOptional ? ws : nullptr;
154 if (workspaceIndex >= 0) {
155 nameList.emplace_back(name, workspaceIndex, -1, -1, period, mws);
156 return;
157 }
158
159 API::Axis *axis = ws->getAxis(1);
160 if (axis->isSpectra()) {
161 if (spectrumNumber < 0) {
162 double specStart = axis->spectraNo(0);
163 double specEnd = axis->spectraNo(axis->length() - 1);
164
165 if (start < specStart || end > specEnd) {
166 // Invalid input range append dummy spectra
167 nameList.emplace_back("", -1, -1, -1, -1, nullptr);
168 return;
169 }
170
171 for (size_t i = 0; i < axis->length(); ++i) {
172 double spec = double(axis->spectraNo(i));
173 int wsIdx = static_cast<int>(i);
174 if (spec >= start && spec <= end) {
175 nameList.emplace_back(name, wsIdx, spec, -1, period, mws);
176 }
177 }
178 } else {
179 for (size_t i = 0; i < axis->length(); ++i) {
180 int j = axis->spectraNo(i);
181 int wsIdx = static_cast<int>(i);
182 if (j == spectrumNumber) {
183 nameList.emplace_back(name, wsIdx, j, -1, period, mws);
184 break;
185 }
186 }
187 }
188 } else { // numeric axis
189 double numericStart = (*axis)(0);
190 double numericEnd = (*axis)(axis->length() - 1);
191
192 if (workspaceIndex <= SpecialIndex::WHOLE_RANGE) {
193 start = numericStart;
194 end = numericEnd;
195 }
196
197 if (start < numericStart || end > numericEnd) {
198 // Invalid input range append dummy spectra
199 nameList.emplace_back("", -1, -1, -1, -1, nullptr);
200 return;
201 }
202
203 for (size_t i = 0; i < axis->length(); ++i) {
204 double value = (*axis)(i);
205 int wsIdx = static_cast<int>(i);
206 if (value >= start && value <= end) {
207 nameList.emplace_back(name, wsIdx, -1, value, period, mws);
208 }
209 }
210 }
211}
212
213std::optional<API::Workspace_sptr> getWorkspace(const std::string &workspaceName, int period) {
214 if (API::AnalysisDataService::Instance().doesExist(workspaceName)) {
215 return API::AnalysisDataService::Instance().retrieve(workspaceName);
216 } else {
217 std::string::size_type i = workspaceName.find_last_of('.');
218 if (i == std::string::npos) {
219 g_log.warning() << "Cannot open file " << workspaceName << "\n";
220 return {};
221 }
222 auto load = Mantid::API::AlgorithmManager::Instance().createUnmanaged("Load");
223 load->setChild(true);
224 load->initialize();
225 load->setPropertyValue("FileName", workspaceName);
226 load->setProperty("OutputWorkspace", "__NotUsed");
227 load->setRethrows(false);
228 load->execute();
229 if (load->isExecuted()) {
230 API::Workspace_sptr rws = load->getProperty("OutputWorkspace");
231 if (rws) {
232 if (std::dynamic_pointer_cast<DataObjects::Workspace2D>(rws)) {
233 return rws;
234 } else {
235 API::WorkspaceGroup_sptr gws = std::dynamic_pointer_cast<API::WorkspaceGroup>(rws);
236 if (gws) {
237 std::string propName = "OUTPUTWORKSPACE_" + std::to_string(period);
238 if (load->existsProperty(propName)) {
239 API::Workspace_sptr rws1 = load->getProperty(propName);
240 return rws1;
241 }
242 }
243 }
244 }
245 }
246 }
247 return {};
248}
249
250} // namespace Mantid::CurveFitting::Algorithms
std::string name
Definition Run.cpp:60
double value
The value of the point.
Definition FitMW.cpp:51
IPeaksWorkspace_sptr workspace
std::map< DeltaEMode::Type, std::string > index
Class to represent the axis of a workspace.
Definition Axis.h:30
virtual specnum_t spectraNo(const std::size_t &index) const
Get the spectrum number.
Definition Axis.cpp:60
virtual std::size_t length() const =0
Get the length of the axis.
virtual bool isSpectra() const
Returns true is the axis is a Spectra axis.
Definition Axis.h:50
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition Logger.h:51
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
@ TOK_IGNORE_EMPTY
ignore empty tokens
@ TOK_TRIM
remove leading and trailing whitespace from tokens
std::size_t count() const
Get the total number of tokens.
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
Kernel::Logger g_log("DetermineSpinStateOrder")
Type lexCast(std::string input, const std::string &errorMessage)
MANTID_CURVEFITTING_DLL void appendInputSpectraToList(std::vector< InputSpectraToFit > &nameList, const std::string &name, const std::shared_ptr< API::MatrixWorkspace > &ws, int workspaceIndex, int spectrumNumber, double start, double end, int period, const bool &workspaceOptional)
Get a workspace.
void parseValueRange(const std::string &index, double &start, double &end, int &wi, int &spec)
MANTID_CURVEFITTING_DLL std::optional< API::Workspace_sptr > getWorkspace(const std::string &name, int period)
void addGroupWorkspace(std::vector< InputSpectraToFit > &nameList, double start, double end, int wi, int spec, int period, const std::shared_ptr< API::WorkspaceGroup > &wsg)
void addMatrixworkspace(std::vector< InputSpectraToFit > &nameList, double start, double end, const std::string &name, int wi, int spec, int period, const std::optional< API::Workspace_sptr > &workspaceOptional, const std::shared_ptr< API::MatrixWorkspace > &wsMatrix)
MANTID_CURVEFITTING_DLL std::vector< InputSpectraToFit > makeNames(const std::string &inputList, int default_wi, int default_spec)
Create a list of input workspace names.
std::string to_string(const wide_integer< Bits, Signed > &n)