Mantid
Loading...
Searching...
No Matches
ImageInfoModelMatrixWS.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2020 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 +
7
9#include "MantidAPI/Axis.h"
10#include "MantidAPI/Run.h"
13#include "MantidKernel/Logger.h"
14#include "MantidKernel/Unit.h"
17#include <limits>
18
19using namespace Mantid::API;
20using namespace Mantid::Kernel;
21using namespace Mantid::Geometry;
22
23namespace {
24
28static const std::array<std::tuple<Unit_sptr, bool>, 6> &displayUnits() {
29 static const std::array<std::tuple<Unit_sptr, bool>, 6> units = {
30 std::make_tuple(UnitFactory::Instance().create("TOF"), false),
31 std::make_tuple(UnitFactory::Instance().create("Wavelength"), false),
32 std::make_tuple(UnitFactory::Instance().create("Energy"), false),
33 std::make_tuple(UnitFactory::Instance().create("dSpacing"), false),
34 std::make_tuple(UnitFactory::Instance().create("MomentumTransfer"), false),
35 std::make_tuple(UnitFactory::Instance().create("DeltaE"), true)};
36 return units;
37}
38
39Logger g_log("ImageInfoModelMatrixWS");
40} // namespace
41
43
49 : m_workspace(std::move(workspace)), m_spectrumInfo(nullptr) {
51}
52
54ImageInfoModel::ImageInfo ImageInfoModelMatrixWS::info(const double x, const double y, const double signal,
55 const QMap<QString, QString> &) const {
57 if (x == UnsetValue || y == UnsetValue || signal == UnsetValue)
58 return info;
59
61 const auto yAxis = m_workspace->getAxis(1);
62 const auto wsIndex = yAxis->indexOfValue(y);
63 const auto &spectrum = m_workspace->getSpectrum(wsIndex);
64 if (yAxis->isSpectra()) {
65 info.setValue(1, defaultFormat(spectrum.getSpectrumNo()));
66 } else {
68 }
69 info.setValue(2, defaultFormat(signal));
70
71 if (!(m_instrument && m_source && m_sample))
72 return info;
73
74 // Everything else requires an instrument
75 if (m_spectrumInfo->hasDetectors(wsIndex)) {
76 info.setValue(3, defaultFormat(*spectrum.getDetectorIDs().begin()));
78 try {
81 setUnitsInfo(&info, 7, wsIndex, x);
82 } catch (const std::exception &exc) {
83 g_log.debug() << "Unable to fill in instrument angle-related value: " << exc.what() << "\n";
84 }
85 }
86
87 return info;
88}
89
97void ImageInfoModelMatrixWS::setUnitsInfo(ImageInfoModel::ImageInfo *info, int infoIndex, const size_t wsIndex,
98 const double x) const {
99 const auto l1 = m_spectrumInfo->l1();
100 auto emode = m_workspace->getEMode();
102 m_spectrumInfo->getDetectorValues(Units::Empty(), Units::Empty(), emode, false, wsIndex, pmap);
103 double efixed = 0.;
104 if (pmap.find(UnitParams::efixed) != pmap.end()) {
105 efixed = pmap[UnitParams::efixed];
106 }
107 // if it's not possible to find an efixed we are forced to treat is as elastic
108 if (efixed == 0.0)
109 emode = DeltaEMode::Elastic;
110 double tof(0.0);
111 const auto &unitFactory = UnitFactory::Instance();
112 const auto tofUnit = unitFactory.create("TOF");
113 if (m_xIsTOF) {
114 // set as first element in list already
115 tof = x;
116 } else {
117 try {
118 tof = m_xunit->convertSingleToTOF(x, l1, emode, pmap);
119 } catch (std::exception &exc) {
120 // without TOF we can't get to the other units
121 if (g_log.is(Logger::Priority::PRIO_DEBUG))
122 g_log.debug() << "Error calculating TOF from " << m_xunit->unitID() << ": " << exc.what() << "\n";
123 return;
124 }
125 }
126 for (auto [unit, requiresEFixed] : displayUnits()) {
127 if (unit->unitID() == m_xunit->unitID())
128 continue;
129 if (!requiresEFixed || efixed > 0.0) {
130 try {
131 // the final parameter is unused and a relic
132 const auto unitValue = unit->convertSingleFromTOF(tof, l1, emode, pmap);
133 info->setValue(infoIndex, defaultFormat(unitValue));
134 } catch (std::exception &exc) {
135 if (g_log.is(Logger::Priority::PRIO_DEBUG))
136 g_log.debug() << "Error calculating " << unit->unitID() << " from " << m_xunit->unitID() << ": " << exc.what()
137 << "\n";
138 }
139 ++infoIndex;
140 }
141 }
142}
143
148 g_log.debug("Updating cached workspace info");
149 m_spectrumInfo = &m_workspace->spectrumInfo();
150 m_instrument = m_workspace->getInstrument();
151 if (m_instrument) {
152 m_source = m_instrument->getSource();
153 if (!m_source) {
154 g_log.debug("No source on instrument in MatrixWorkspace");
155 }
156
157 m_sample = m_instrument->getSample();
158 if (!m_sample) {
159 g_log.debug("No sample on instrument in MatrixWorkspace");
160 }
161 } else {
162 g_log.debug("No instrument on MatrixWorkspace");
163 }
164 m_xunit = m_workspace->getAxis(0)->unit();
165 m_xIsTOF = (m_xunit->unitID() == "TOF");
167}
168
174 auto appendName = [this](const auto &name) { m_names.emplace_back(name); };
175 auto shortUnitName = [](const Unit &unit) {
176 const auto caption = unit.caption();
177 if (caption.rfind("-flight") != std::string::npos)
178 return QString("TOF");
179 else if (caption == "q")
180 return QString("|Q|");
181 else
182 return QString::fromStdString(caption);
183 };
184 auto appendUnit = [&appendName, &shortUnitName](const auto &unit) {
185 QString name = shortUnitName(unit);
186 const auto unitLabel = unit.label().utf8();
187 if (!unitLabel.empty()) {
188 name += "(" + MantidQt::API::toQStringInternal(unitLabel) + ")";
189 }
190 appendName(name);
191 };
192
193 // General information first
194 if (m_xunit && !m_xunit->caption().empty())
195 appendUnit(*m_xunit);
196 else
197 appendName("x");
198 if (auto yaxis = m_workspace->getAxis(1)) {
199 if (yaxis->isSpectra())
200 appendName("Spectrum");
201 else if (auto yunit = yaxis->unit()) {
202 if (!yunit->caption().empty())
203 appendUnit(*yunit);
204 else
205 appendName("y");
206 }
207 } else
208 appendName("y");
209 appendName("Signal");
210 appendName("Det ID");
211 appendName("L2(m)");
212 appendName("TwoTheta(Deg)");
213 appendName("Azimuthal(Deg)");
214
215 // Add conversions to common units
216 auto appendUnitIfNotX = [this, &appendUnit](const auto &unit) {
217 if (unit.unitID() == m_xunit->unitID())
218 return;
219 appendUnit(unit);
220 };
221 for (const auto &unitInfo : displayUnits()) {
222 appendUnitIfNotX(*std::get<0>(unitInfo));
223 }
224}
225
226} // namespace MantidQt::MantidWidgets
IPeaksWorkspace_sptr workspace
Definition: IndexPeaks.cpp:114
const Mantid::API::SpectrumInfo * m_spectrumInfo
ImageInfoModel::ImageInfo info(const double x, const double y, const double signal, const QMap< QString, QString > &extraValues) const override
Creates information about the point at the given coordinates in the workspace.
std::shared_ptr< const Mantid::Geometry::Instrument > m_instrument
void createItemNames()
Create a sequence of names for each item this model will produce and store it internally.
std::shared_ptr< const Mantid::Geometry::IComponent > m_sample
ImageInfoModel::ImageInfo::StringItems m_names
ImageInfoModelMatrixWS(Mantid::API::MatrixWorkspace_sptr workspace)
Constructor.
void cacheWorkspaceInfo()
Cache metadata for the workspace for faster lookup.
std::shared_ptr< const Mantid::Geometry::IComponent > m_source
void setUnitsInfo(ImageInfoModel::ImageInfo *info, int infoIndex, const size_t wsIndex, const double x) const
Add the unit-related quantities to the info list.
void setValue(int index, const QString &value) noexcept
static constexpr auto UnsetValue
Value to indicate that a MissingValue should be shown.
static const QString defaultFormat(const double x)
double signedTwoTheta(const size_t index) const
Returns the signed scattering angle 2 theta in radians (angle w.r.t.
bool hasDetectors(const size_t index) const
Returns true if the spectrum is associated with detectors in the instrument.
double l2(const size_t index) const
Returns L2 (distance from sample to spectrum).
double azimuthal(const size_t index) const
Returns the out-of-plane angle in radians (angle w.r.t.
double l1() const
Returns L1 (distance from source to sample).
void getDetectorValues(const Kernel::Unit &inputUnit, const Kernel::Unit &outputUnit, const Kernel::DeltaEMode::Type emode, const bool signedTheta, int64_t wsIndex, Kernel::UnitParametersMap &pmap) const
Get the detector values relevant to unit conversion for a workspace index.
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition: Logger.h:52
void debug(const std::string &msg)
Logs at debug level.
Definition: Logger.cpp:114
bool is(int level) const
Returns true if at least the given log level is set.
Definition: Logger.cpp:146
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
The base units (abstract) class.
Definition: Unit.h:41
QString toQStringInternal(const wchar_t *str)
Internal version of QString::fromStdWString.
Definition: QStringUtils.h:21
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::unique_ptr< T > create(const P &parent, const IndexArg &indexArg, const HistArg &histArg)
This is the create() method that all the other create() methods call.
constexpr double rad2deg
Radians to degrees conversion factor.
Definition: AngleUnits.h:23
std::unordered_map< UnitParams, double > UnitParametersMap
Definition: Unit.h:30
Generate a tableworkspace to store the calibration results.
STL namespace.