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, std::string &name, int wi,
74 int spec, int period, const boost::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 } else {
101 wi = default_wi;
102 }
103 }
104 int period = 1;
105 if (params.count() > 2 && !params[2].empty()) {
106 period = lexCast<int>(params[2], "Incorrect value for a period: " + params[2]);
107 }
108
109 auto workspaceOptional = getWorkspace(name, period);
110 if (!workspaceOptional)
111 continue;
112
113 auto wsg = std::dynamic_pointer_cast<API::WorkspaceGroup>(workspaceOptional.value());
114 auto wsMatrix = std::dynamic_pointer_cast<API::MatrixWorkspace>(workspaceOptional.value());
115 if (wsg) {
116 addGroupWorkspace(nameList, start, end, wi, spec, period, wsg);
117
118 } else if (wsMatrix) {
119 addMatrixworkspace(nameList, start, end, name, wi, spec, period, workspaceOptional, wsMatrix);
120 }
121 }
122 return nameList;
123}
124void addMatrixworkspace(std::vector<InputSpectraToFit> &nameList, double start, double end, std::string &name, int wi,
125 int spec, int period, const boost::optional<API::Workspace_sptr> &workspaceOptional,
126 const std::shared_ptr<API::MatrixWorkspace> &wsMatrix) {
127 auto workspaceIndices = getWorkspaceIndicesFromAxes(*wsMatrix, wi, spec, start, end);
128
129 for (auto workspaceIndex : workspaceIndices) {
130 nameList.emplace_back(name, workspaceIndex, period);
131 if (workspaceOptional) {
132 nameList.back().ws = wsMatrix;
133 }
134 }
135}
136void addGroupWorkspace(std::vector<InputSpectraToFit> &nameList, double start, double end, int wi, int spec, int period,
137 const std::shared_ptr<API::WorkspaceGroup> &wsg) {
138 const std::vector<std::string> wsNames = wsg->getNames();
139
140 for (const auto &wsName : wsNames) {
141 if (auto workspace =
142 std::dynamic_pointer_cast<API::MatrixWorkspace>(API::AnalysisDataService::Instance().retrieve(wsName))) {
143 auto workspaceIndices = getWorkspaceIndicesFromAxes(*workspace, wi, spec, start, end);
144
145 for (auto workspaceIndex : workspaceIndices) {
146 nameList.emplace_back(wsName, workspaceIndex, period);
147 nameList.back().ws = workspace;
148 }
149 }
150 }
151}
152
161std::vector<int> getWorkspaceIndicesFromAxes(API::MatrixWorkspace &ws, int workspaceIndex, int spectrumNumber,
162 double start, double end) {
163 if (workspaceIndex >= 0) {
164 return std::vector<int>({workspaceIndex});
165 }
166 std::vector<int> out;
167 API::Axis *axis = ws.getAxis(1);
168 if (axis->isSpectra()) {
169 if (spectrumNumber < 0) {
170 for (size_t i = 0; i < axis->length(); ++i) {
171 auto s = double(axis->spectraNo(i));
172 if (s >= start && s <= end) {
173 out.emplace_back(static_cast<int>(i));
174 }
175 }
176
177 } else {
178 for (size_t i = 0; i < axis->length(); ++i) {
179 int j = axis->spectraNo(i);
180 if (j == spectrumNumber) {
181 out.emplace_back(static_cast<int>(i));
182 break;
183 }
184 }
185 }
186 } else { // numeric axis
187 if (workspaceIndex <= SpecialIndex::WHOLE_RANGE) {
188 start = (*axis)(0);
189 end = (*axis)(axis->length() - 1);
190 }
191 for (size_t i = 0; i < axis->length(); ++i) {
192 double s = (*axis)(i);
193 if (s >= start && s <= end) {
194 out.emplace_back(static_cast<int>(i));
195 }
196 }
197 }
198
199 return out;
200}
201
202boost::optional<API::Workspace_sptr> getWorkspace(const std::string &workspaceName, int period) {
203 if (API::AnalysisDataService::Instance().doesExist(workspaceName)) {
204 return API::AnalysisDataService::Instance().retrieve(workspaceName);
205 } else {
206 std::string::size_type i = workspaceName.find_last_of('.');
207 if (i == std::string::npos) {
208 g_log.warning() << "Cannot open file " << workspaceName << "\n";
209 return {};
210 }
211 auto load = Mantid::API::AlgorithmManager::Instance().createUnmanaged("Load");
212 load->setChild(true);
213 load->initialize();
214 load->setPropertyValue("FileName", workspaceName);
215 load->setProperty("OutputWorkspace", "__NotUsed");
216 load->setRethrows(false);
217 load->execute();
218 if (load->isExecuted()) {
219 API::Workspace_sptr rws = load->getProperty("OutputWorkspace");
220 if (rws) {
221 if (std::dynamic_pointer_cast<DataObjects::Workspace2D>(rws)) {
222 return rws;
223 } else {
224 API::WorkspaceGroup_sptr gws = std::dynamic_pointer_cast<API::WorkspaceGroup>(rws);
225 if (gws) {
226 std::string propName = "OUTPUTWORKSPACE_" + std::to_string(period);
227 if (load->existsProperty(propName)) {
228 API::Workspace_sptr rws1 = load->getProperty(propName);
229 return rws1;
230 }
231 }
232 }
233 }
234 }
235 }
236 return {};
237}
238
239} // namespace Mantid::CurveFitting::Algorithms
IPeaksWorkspace_sptr workspace
Definition: IndexPeaks.cpp:114
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
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
Base MatrixWorkspace Abstract Class.
virtual Axis * getAxis(const std::size_t &axisIndex) const
Get a non owning pointer to a workspace axis.
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition: Logger.h:52
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
@ 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
Definition: Workspace_fwd.h:20
Kernel::Logger g_log("ExperimentInfo")
static logger object
Type lexCast(std::string input, const std::string &errorMessage)
void parseValueRange(const std::string &index, double &start, double &end, int &wi, int &spec)
void addGroupWorkspace(std::vector< InputSpectraToFit > &nameList, double start, double end, int wi, int spec, int period, const std::shared_ptr< API::WorkspaceGroup > &wsg)
MANTID_CURVEFITTING_DLL std::vector< InputSpectraToFit > makeNames(const std::string &inputList, int default_wi, int default_spec)
Create a list of input workspace names.
MANTID_CURVEFITTING_DLL boost::optional< API::Workspace_sptr > getWorkspace(const std::string &name, int period)
void addMatrixworkspace(std::vector< InputSpectraToFit > &nameList, double start, double end, std::string &name, int wi, int spec, int period, const boost::optional< API::Workspace_sptr > &workspaceOptional, const std::shared_ptr< API::MatrixWorkspace > &wsMatrix)
MANTID_CURVEFITTING_DLL std::vector< int > getWorkspaceIndicesFromAxes(API::MatrixWorkspace &ws, int workspaceIndex, int spectrumNumber, double start, double end)
Get a workspace.
std::string to_string(const wide_integer< Bits, Signed > &n)