diff --git a/core/include/Data/Unit.h b/core/include/Data/Unit.h index 24cdc47..7f5c0dd 100644 --- a/core/include/Data/Unit.h +++ b/core/include/Data/Unit.h @@ -1,6 +1,8 @@ #ifndef SCIQLOP_UNIT_H #define SCIQLOP_UNIT_H +#include + #include #include @@ -20,4 +22,6 @@ struct Unit { bool m_TimeUnit; ///< The unit is a unit of time (UTC) }; +SCIQLOP_REGISTER_META_TYPE(UNIT_REGISTRY, Unit) + #endif // SCIQLOP_UNIT_H diff --git a/core/tests/Data/TestOptionalAxis.cpp b/core/tests/Data/TestOptionalAxis.cpp index f02f256..201495a 100644 --- a/core/tests/Data/TestOptionalAxis.cpp +++ b/core/tests/Data/TestOptionalAxis.cpp @@ -5,7 +5,6 @@ #include Q_DECLARE_METATYPE(OptionalAxis) -Q_DECLARE_METATYPE(Unit) class TestOptionalAxis : public QObject { Q_OBJECT diff --git a/plugins/amda/include/AmdaResultParserDefs.h b/plugins/amda/include/AmdaResultParserDefs.h new file mode 100644 index 0000000..b1b4136 --- /dev/null +++ b/plugins/amda/include/AmdaResultParserDefs.h @@ -0,0 +1,35 @@ +#ifndef SCIQLOP_AMDARESULTPARSERDEFS_H +#define SCIQLOP_AMDARESULTPARSERDEFS_H + +#include +#include +#include + +// ////////// // +// Properties // +// ////////// // + +/// Alias to represent properties read in the header of AMDA file +using Properties = QVariantHash; + +extern const QString X_AXIS_UNIT_PROPERTY; + +// /////////////////// // +// Regular expressions // +// /////////////////// // + +// AMDA V2 +// /// ... PARAMETER_UNITS : nT ... +// /// ... PARAMETER_UNITS:nT ... +// /// ... PARAMETER_UNITS: m² ... +// /// ... PARAMETER_UNITS : m/s ... +// const auto UNIT_REGEX = QRegularExpression{QStringLiteral("\\s*PARAMETER_UNITS\\s*:\\s*(.+)")}; + +/// Regex to find x-axis unit in a line. Examples of valid lines: +/// ... - Units : nT - ... +/// ... -Units:nT- ... +/// ... -Units: m²- ... +/// ... - Units : m/s - ... +extern const QRegularExpression DEFAULT_X_AXIS_UNIT_REGEX; + +#endif // SCIQLOP_AMDARESULTPARSERDEFS_H diff --git a/plugins/amda/include/AmdaResultParserHelper.h b/plugins/amda/include/AmdaResultParserHelper.h index 7a42607..e161fd4 100644 --- a/plugins/amda/include/AmdaResultParserHelper.h +++ b/plugins/amda/include/AmdaResultParserHelper.h @@ -1,6 +1,8 @@ #ifndef SCIQLOP_AMDARESULTPARSERHELPER_H #define SCIQLOP_AMDARESULTPARSERHELPER_H +#include "AmdaResultParserDefs.h" + #include #include @@ -52,6 +54,9 @@ public: std::shared_ptr createSeries() override; void readPropertyLine(const QString &line) override; void readResultLine(const QString &line) override; + +private: + Properties m_Properties{}; }; /** @@ -63,6 +68,9 @@ public: std::shared_ptr createSeries() override; void readPropertyLine(const QString &line) override; void readResultLine(const QString &line) override; + +private: + Properties m_Properties{}; }; #endif // SCIQLOP_AMDARESULTPARSERHELPER_H diff --git a/plugins/amda/meson.build b/plugins/amda/meson.build index b9d95a0..f53a5e3 100644 --- a/plugins/amda/meson.build +++ b/plugins/amda/meson.build @@ -10,6 +10,7 @@ amdaplugin_sources = [ 'src/AmdaPlugin.cpp', 'src/AmdaProvider.cpp', 'src/AmdaResultParser.cpp' + 'src/AmdaResultParserDefs.cpp' 'src/AmdaResultParserHelper.cpp' ] diff --git a/plugins/amda/src/AmdaResultParserDefs.cpp b/plugins/amda/src/AmdaResultParserDefs.cpp new file mode 100644 index 0000000..c6b5bf5 --- /dev/null +++ b/plugins/amda/src/AmdaResultParserDefs.cpp @@ -0,0 +1,6 @@ +#include "AmdaResultParserDefs.h" + +const QString X_AXIS_UNIT_PROPERTY = QStringLiteral("xAxisUnit"); + +const QRegularExpression DEFAULT_X_AXIS_UNIT_REGEX + = QRegularExpression{QStringLiteral("-\\s*Units\\s*:\\s*(.+?)\\s*-")}; diff --git a/plugins/amda/src/AmdaResultParserHelper.cpp b/plugins/amda/src/AmdaResultParserHelper.cpp index 93fab6b..8a9d3b2 100644 --- a/plugins/amda/src/AmdaResultParserHelper.cpp +++ b/plugins/amda/src/AmdaResultParserHelper.cpp @@ -1,14 +1,82 @@ #include "AmdaResultParserHelper.h" +#include + Q_LOGGING_CATEGORY(LOG_AmdaResultParserHelper, "AmdaResultParserHelper") +namespace { + +// /////// // +// Methods // +// /////// // + +/** + * Checks that the properties contain a specific unit and that this unit is valid + * @param properties the properties map in which to search unit + * @param key the key to search for the unit in the properties + * @param errorMessage the error message to log in case the unit is invalid + * @return true if the unit is valid, false it it's invalid or was not found in the properties + */ +bool checkUnit(const Properties &properties, const QString &key, const QString &errorMessage) +{ + auto unit = properties.value(key).value(); + if (unit.m_Name.isEmpty()) { + qCWarning(LOG_AmdaResultParserHelper()) << errorMessage; + return false; + } + + return true; +} + +/** + * Reads a line from the AMDA file and tries to extract a property from it + * @param properties the properties map in which to put the property extracted from the line + * @param key the key to which the property is added in the properties map + * @param line the line to read to extract the property + * @param regex the expected regex to extract the property. If the line matches this regex, the + * property is generated + * @param fun the function used to generate the property + * @return true if the property could be generated, false if the line does not match the regex, or + * if a property has already been generated for the key + */ +template +bool tryReadProperty(Properties &properties, const QString &key, const QString &line, + const QRegularExpression ®ex, GeneratePropertyFun fun) +{ + if (properties.contains(key)) { + return false; + } + + auto match = regex.match(line); + if (match.hasMatch()) { + properties.insert(key, fun(match)); + } + + return match.hasMatch(); +} + +/** + * Reads a line from the AMDA file and tries to extract a unit from it + * @sa tryReadProperty() + */ +bool tryReadUnit(Properties &properties, const QString &key, const QString &line, + const QRegularExpression ®ex, bool timeUnit = false) +{ + return tryReadProperty(properties, key, line, regex, [timeUnit](const auto &match) { + return QVariant::fromValue(Unit{match.captured(1), timeUnit}); + }); +} + +} // namespace + // ////////////////// // // ScalarParserHelper // // ////////////////// // bool ScalarParserHelper::checkProperties() { - /// @todo ALX + return checkUnit(m_Properties, X_AXIS_UNIT_PROPERTY, + QObject::tr("The x-axis unit could not be found in the file")); } std::shared_ptr ScalarParserHelper::createSeries() @@ -18,7 +86,7 @@ std::shared_ptr ScalarParserHelper::createSeries() void ScalarParserHelper::readPropertyLine(const QString &line) { - /// @todo ALX + tryReadUnit(m_Properties, X_AXIS_UNIT_PROPERTY, line, DEFAULT_X_AXIS_UNIT_REGEX, true); } void ScalarParserHelper::readResultLine(const QString &line) @@ -32,7 +100,8 @@ void ScalarParserHelper::readResultLine(const QString &line) bool VectorParserHelper::checkProperties() { - /// @todo ALX + return checkUnit(m_Properties, X_AXIS_UNIT_PROPERTY, + QObject::tr("The x-axis unit could not be found in the file")); } std::shared_ptr VectorParserHelper::createSeries() @@ -42,7 +111,7 @@ std::shared_ptr VectorParserHelper::createSeries() void VectorParserHelper::readPropertyLine(const QString &line) { - /// @todo ALX + tryReadUnit(m_Properties, X_AXIS_UNIT_PROPERTY, line, DEFAULT_X_AXIS_UNIT_REGEX, true); } void VectorParserHelper::readResultLine(const QString &line)