Mantid
Loading...
Searching...
No Matches
WorkspaceUtils.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2019 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 +
10
11#include "MantidAPI/Axis.h"
14#include "MantidAPI/TextAxis.h"
16#include <boost/algorithm/string.hpp>
17#include <regex>
18
19using namespace Mantid::API;
20
21namespace {
22Mantid::Kernel::Logger g_log("WorkspaceUtils");
23
24double roundToPrecision(double value, double precision) { return value - std::remainder(value, precision); }
25
26std::pair<double, double> roundRangeToPrecision(double rangeStart, double rangeEnd, double precision) {
27 return std::pair<double, double>(roundToPrecision(rangeStart, precision) + precision,
28 roundToPrecision(rangeEnd, precision) - precision);
29}
30
31auto const regDigits = std::regex("\\d+");
32} // namespace
33namespace MantidQt {
34namespace MantidWidgets {
35namespace WorkspaceUtils {
36
44std::optional<std::size_t> maximumIndex(const Mantid::API::MatrixWorkspace_sptr &workspace) {
45 if (workspace) {
46 const auto numberOfHistograms = workspace->getNumberHistograms();
47 if (numberOfHistograms > 0)
48 return numberOfHistograms - 1;
49 }
50 return std::nullopt;
51}
52
54 const auto maximum = maximumIndex(workspace);
55 if (maximum)
56 return "0-" + std::to_string(*maximum);
57 return "";
58}
59
60std::string getIndexString(const std::string &workspaceName) { return getIndexString(getADSWorkspace(workspaceName)); }
61
68std::string getWorkspaceSuffix(const std::string &wsName) {
69 auto const lastUnderscoreIndex = wsName.find_last_of("_");
70 if (lastUnderscoreIndex == wsName.npos)
71 return std::string();
72 return wsName.substr(lastUnderscoreIndex + 1);
73}
74
84std::string getWorkspaceBasename(const std::string &wsName) {
85 auto lastUnderscoreIndex = wsName.find_last_of("_");
86 if (lastUnderscoreIndex == wsName.npos)
87 return wsName;
88
89 return wsName.substr(0, lastUnderscoreIndex);
90}
91
92/* Extracts the labels from the axis at the specified index in the
93 * specified workspace.
94 *
95 * @param workspace Constant reference to the matrix workspace
96 * @param axisIndex Index of the selected axis
97 * @return map of label, index pairs of labels of selected axis.
98 */
99std::unordered_map<std::string, size_t> extractAxisLabels(const Mantid::API::MatrixWorkspace_const_sptr &workspace,
100 const size_t &axisIndex) {
101 Axis *axis = workspace->getAxis(axisIndex);
102 if (!axis->isText())
103 return std::unordered_map<std::string, size_t>();
104
105 auto *textAxis = static_cast<TextAxis *>(axis);
106 std::unordered_map<std::string, size_t> labels;
107
108 for (size_t i = 0; i < textAxis->length(); ++i)
109 labels[textAxis->label(i)] = i;
110 return labels;
111}
112
123 Mantid::Kernel::Unit_sptr xUnit = ws->getAxis(0)->unit();
124 std::string xUnitName = xUnit->caption();
125
126 g_log.debug() << "X unit name is: " << xUnitName << '\n';
127 if (boost::algorithm::find_first(xUnitName, "d-Spacing"))
128 return "Elastic";
129
130 return "Indirect";
131}
132
139std::optional<double> getEFixed(const Mantid::API::MatrixWorkspace_sptr &ws) {
140 Mantid::Geometry::Instrument_const_sptr inst = ws->getInstrument();
141 if (!inst)
142 return std::nullopt;
143
144 // Try to get it from the analyser component
145 if (inst->hasParameter("analyser")) {
146 auto const analyserName = inst->getStringParameter("analyser")[0];
147 auto const analyserComp = inst->getComponentByName(analyserName != "fmica" ? analyserName : "mica");
148
149 if (analyserComp && analyserComp->hasParameter("Efixed"))
150 return analyserComp->getNumberParameter("Efixed")[0];
151 }
152
153 // Try to get the parameter form the base instrument
154 if (inst->hasParameter("Efixed"))
155 return inst->getNumberParameter("Efixed")[0];
156 return std::nullopt;
157}
158
167bool getResolutionRangeFromWs(const std::string &workspace, std::pair<double, double> &res) {
168 auto const ws =
169 Mantid::API::AnalysisDataService::Instance().retrieveWS<const Mantid::API::MatrixWorkspace>(workspace);
170 return getResolutionRangeFromWs(ws, res);
171}
181 std::pair<double, double> &res) {
182 if (workspace) {
183 auto const instrument = workspace->getInstrument();
184 if (instrument && instrument->hasParameter("analyser")) {
185 auto const analyser = instrument->getStringParameter("analyser");
186 if (analyser.size() > 0) {
187 auto comp = instrument->getComponentByName(analyser[0]);
188 if (comp) {
189 auto params = comp->getNumberParameter("resolution", true);
190
191 // set the default instrument resolution
192 if (params.size() > 0) {
193 res = std::pair(-params[0], params[0]);
194 return true;
195 }
196 }
197 }
198 }
199 }
200 return false;
201}
202
203std::pair<double, double> getXRangeFromWorkspace(std::string const &workspaceName, double precision) {
204 auto const &ads = AnalysisDataService::Instance();
205 if (ads.doesExist(workspaceName))
206 return getXRangeFromWorkspace(ads.retrieveWS<MatrixWorkspace>(workspaceName), precision);
207 return std::pair<double, double>(0.0, 0.0);
208}
209
211 double precision, std::size_t wsIndex) {
212 assert(workspace != nullptr);
213 if (wsIndex >= workspace->getNumberHistograms())
214 wsIndex = 0;
215 auto const &xValues = workspace->x(wsIndex);
216 return roundRangeToPrecision(xValues.front(), xValues.back(), precision);
217}
218
219bool doesExistInADS(std::string const &workspaceName) {
220 return AnalysisDataService::Instance().doesExist(workspaceName);
221}
222
223bool doAllWsExistInADS(std::vector<std::string> const &workspaceNames) {
224 return AnalysisDataService::Instance().doAllWsExist(workspaceNames);
225}
226
227void removeADSWorkspace(std::string const &workspaceName) {
228 if (doesExistInADS(workspaceName)) {
229 AnalysisDataService::Instance().remove(workspaceName);
230 }
231}
232
243void setNumericQAxis(std::string const &workspaceName) {
244 if (workspaceName.empty() || !doesExistInADS(workspaceName)) {
245 return;
246 }
247
248 auto const ws = getADSWorkspace(workspaceName);
249 if (!ws) {
250 return;
251 }
252
253 auto const &axis = ws->getAxis(1);
254 if (!axis->isNumeric()) {
255 auto numericAxis = std::make_unique<NumericAxis>(ws->getNumberHistograms());
256 for (size_t i = 0; i < ws->getNumberHistograms(); ++i) {
257 numericAxis->setValue(i, axis->getValue(i));
258 }
259 ws->replaceAxis(1, std::move(numericAxis));
260 }
261
262 auto const unitID = ws->getAxis(1)->unit()->unitID();
263 if (unitID == "Empty" || unitID == "Label") {
264 ws->getAxis(1)->setUnit("MomentumTransfer");
265 }
266}
267
268std::vector<std::string> attachPrefix(std::vector<std::string> const &strings, std::string const &prefix) {
269 return transformElements(strings.begin(), strings.end(), [&prefix](std::string const &str) { return prefix + str; });
270}
271
281std::string parseRunNumbers(std::vector<std::string> const &workspaceNames) {
282 auto names = WorkspaceUtils::transformElements(workspaceNames.begin(), workspaceNames.end(),
283 [](auto &name) { return name.substr(0, name.find_first_of('_')); });
284 std::smatch match;
285 std::vector<int> runNumbers;
286 std::string prefix;
287 if (workspaceNames.empty()) {
288 return std::string("");
289 }
290 std::string suffix = workspaceNames[0].substr(workspaceNames[0].find_first_of('_'));
291 for (auto const &name : names)
292 if (std::regex_search(name, match, regDigits)) {
293 runNumbers.push_back(std::stoi(match.str(0)));
294 if (prefix.empty())
295 prefix = match.prefix().str();
296 }
297 if (runNumbers.empty() || runNumbers.size() == 1)
298 return workspaceNames[0];
299 else {
300 auto [min, max] = std::minmax_element(runNumbers.cbegin(), runNumbers.cend());
301 return prefix + std::to_string(*min) + "-" + std::to_string(*max) + suffix;
302 }
303}
304
305} // namespace WorkspaceUtils
306} // namespace MantidWidgets
307} // namespace MantidQt
std::string name
Definition Run.cpp:60
double value
The value of the point.
Definition FitMW.cpp:51
IPeaksWorkspace_sptr workspace
Class to represent the axis of a workspace.
Definition Axis.h:30
virtual bool isText() const
Returns true if the axis is Text.
Definition Axis.h:54
const std::shared_ptr< Kernel::Unit > & unit() const
The unit for this axis.
Definition Axis.cpp:28
Base MatrixWorkspace Abstract Class.
Class to represent a text axis of a workspace.
Definition TextAxis.h:36
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition Logger.h:51
void debug(const std::string &msg)
Logs at debug level.
Definition Logger.cpp:145
EXPORT_OPT_MANTIDQT_COMMON std::string getIndexString(const std::string &workspaceName)
EXPORT_OPT_MANTIDQT_COMMON std::string getWorkspaceBasename(const std::string &wsName)
Returns the basename of a workspace (i.e.
EXPORT_OPT_MANTIDQT_COMMON std::optional< std::size_t > maximumIndex(const Mantid::API::MatrixWorkspace_sptr &workspace)
Gets the maximum number of histograms for a 2D Workspace.
EXPORT_OPT_MANTIDQT_COMMON bool getResolutionRangeFromWs(const std::string &workspace, std::pair< double, double > &res)
Checks the workspace's instrument for a resolution parameter to use as a default for the energy range...
std::shared_ptr< T > getADSWorkspace(std::string const &workspaceName)
EXPORT_OPT_MANTIDQT_COMMON bool doesExistInADS(std::string const &workspaceName)
EXPORT_OPT_MANTIDQT_COMMON std::string getEMode(const Mantid::API::MatrixWorkspace_sptr &ws)
Gets the energy mode from a workspace based on the X unit.
EXPORT_OPT_MANTIDQT_COMMON std::string parseRunNumbers(std::vector< std::string > const &workspaceNames)
Checks the name of the input workspace against a regexp for prefixes in the form instrName\#runNumber...
EXPORT_OPT_MANTIDQT_COMMON std::string getWorkspaceSuffix(const std::string &wsName)
Gets the suffix of a workspace (i.e.
EXPORT_OPT_MANTIDQT_COMMON std::pair< double, double > getXRangeFromWorkspace(const Mantid::API::MatrixWorkspace_const_sptr &workspace, double precision=0.00001, std::size_t wsIndex=0)
EXPORT_OPT_MANTIDQT_COMMON void removeADSWorkspace(std::string const &workspaceName)
EXPORT_OPT_MANTIDQT_COMMON void setNumericQAxis(std::string const &workspaceName)
Ensures the vertical (spectrum) axis of the named workspace is a numeric axis, and labels it with the...
EXPORT_OPT_MANTIDQT_COMMON std::optional< double > getEFixed(const Mantid::API::MatrixWorkspace_sptr &ws)
Gets the eFixed value from the workspace using the instrument parameters.
EXPORT_OPT_MANTIDQT_COMMON std::unordered_map< std::string, size_t > extractAxisLabels(const Mantid::API::MatrixWorkspace_const_sptr &workspace, const size_t &axisIndex)
std::vector< std::string > transformElements(Iterator const fromIter, Iterator const toIter, Functor const &functor)
EXPORT_OPT_MANTIDQT_COMMON bool doAllWsExistInADS(std::vector< std::string > const &workspaceNames)
EXPORT_OPT_MANTIDQT_COMMON std::vector< std::string > attachPrefix(std::vector< std::string > const &strings, std::string const &prefix)
The AlgorithmProgressDialogPresenter keeps track of the running algorithms and displays a progress ba...
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
std::shared_ptr< Unit > Unit_sptr
Shared pointer to the Unit base class.
Definition Unit.h:239
std::string to_string(const wide_integer< Bits, Signed > &n)