diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index f6106d2..02411f4 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -15,7 +15,8 @@ if(NOT BUILD_SHARED_LIBS) add_definitions(-DQT_STATICPLUGIN) if(BUILD_PLUGINS) target_link_libraries(sciqlopapp mockplugin) - target_link_libraries(sciqlopapp amdaplugin) + #target_link_libraries(sciqlopapp amdaplugin) + target_link_libraries(sciqlopapp python_providers) endif() endif() diff --git a/app/src/Main.cpp b/app/src/Main.cpp index 9d75277..96416fe 100644 --- a/app/src/Main.cpp +++ b/app/src/Main.cpp @@ -46,8 +46,9 @@ int main(int argc, char* argv[]) #ifdef QT_STATICPLUGIN #ifndef SQP_NO_PLUGINS Q_IMPORT_PLUGIN(MockPlugin) - Q_IMPORT_PLUGIN(AmdaPlugin) - Q_INIT_RESOURCE(amdaresources); + Q_IMPORT_PLUGIN(PythonProviders) + // Q_IMPORT_PLUGIN(AmdaPlugin) + // Q_INIT_RESOURCE(amdaresources); #endif #endif Q_INIT_RESOURCE(sqpguiresources); diff --git a/app/src/MainWindow.cpp b/app/src/MainWindow.cpp index 14b07ad..6e3e9e6 100644 --- a/app/src/MainWindow.cpp +++ b/app/src/MainWindow.cpp @@ -304,12 +304,12 @@ MainWindow::MainWindow(QWidget* parent) // Visualization connect(&sqpApp->visualizationController(), - SIGNAL(variableAboutToBeDeleted(std::shared_ptr)), m_Ui->view, - SLOT(onVariableAboutToBeDeleted(std::shared_ptr))); + SIGNAL(variableAboutToBeDeleted(std::shared_ptr)), m_Ui->view, + SLOT(onVariableAboutToBeDeleted(std::shared_ptr))); connect(&sqpApp->visualizationController(), - SIGNAL(rangeChanged(std::shared_ptr, const DateTimeRange&)), m_Ui->view, - SLOT(onRangeChanged(std::shared_ptr, const DateTimeRange&))); + SIGNAL(rangeChanged(std::shared_ptr, const DateTimeRange&)), m_Ui->view, + SLOT(onRangeChanged(std::shared_ptr, const DateTimeRange&))); // Widgets / widgets connections diff --git a/core b/core index cc26524..00ce7df 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit cc26524fb5d10feca3820e6921c9cd3cfb1a3591 +Subproject commit 00ce7df31d3e11df8a418988c601247f6dc64d13 diff --git a/gui/include/Visualization/VisualizationTabWidget.h b/gui/include/Visualization/VisualizationTabWidget.h index f840f8b..cb7321e 100644 --- a/gui/include/Visualization/VisualizationTabWidget.h +++ b/gui/include/Visualization/VisualizationTabWidget.h @@ -11,7 +11,7 @@ Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationTabWidget) -class Variable; +class Variable2; class VisualizationZoneWidget; namespace Ui diff --git a/gui/src/Visualization/VisualizationGraphHelper.cpp b/gui/src/Visualization/VisualizationGraphHelper.cpp index da62da8..2a0bc4d 100644 --- a/gui/src/Visualization/VisualizationGraphHelper.cpp +++ b/gui/src/Visualization/VisualizationGraphHelper.cpp @@ -120,8 +120,11 @@ struct PlottablesUpdater(&dataSeries)) { - maxValue = (*std::max_element(std::begin(*serie), std::end(*serie))).v(); - minValue = (*std::min_element(std::begin(*serie), std::end(*serie))).v(); + if (serie->size()) + { + maxValue = (*std::max_element(std::begin(*serie), std::end(*serie))).v(); + minValue = (*std::min_element(std::begin(*serie), std::end(*serie))).v(); + } } plot.yAxis->setRange(QCPRange { minValue, maxValue }); } diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 9716678..0c8e886 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory(mockplugin) -add_subdirectory(amda) -add_subdirectory(generic_ws) +add_subdirectory(python_providers) +#add_subdirectory(amda) +#add_subdirectory(generic_ws) diff --git a/plugins/amda/include/AmdaProvider.h b/plugins/amda/include/AmdaProvider.h index 65534cb..3f14e93 100644 --- a/plugins/amda/include/AmdaProvider.h +++ b/plugins/amda/include/AmdaProvider.h @@ -17,14 +17,14 @@ class QNetworkRequest; /** * @brief The AmdaProvider class is an example of how a data provider can generate data */ -class SCIQLOP_AMDA_EXPORT AmdaProvider : public IDataProvider { +class SCIQLOP_AMDA_EXPORT AmdaProvider : public IDataProvider +{ Q_OBJECT public: explicit AmdaProvider(); std::shared_ptr clone() const override; - virtual IDataSeries *getData(const DataProviderParameters ¶meters)override; - + virtual TimeSeries::ITimeSerie* getData(const DataProviderParameters& parameters) override; }; #endif // SCIQLOP_AMDAPROVIDER_H diff --git a/plugins/amda/src/AmdaProvider.cpp b/plugins/amda/src/AmdaProvider.cpp index 11a525c..79914b1 100644 --- a/plugins/amda/src/AmdaProvider.cpp +++ b/plugins/amda/src/AmdaProvider.cpp @@ -7,18 +7,18 @@ #include #include #include -#include +#include +#include #include #include #include #include -#include -#include Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider") -namespace { +namespace +{ /// URL format for a request on AMDA server. The parameters are as follows: /// - %1: server URL @@ -54,10 +54,7 @@ QString dateFormat(double sqpRange) noexcept } // namespace -AmdaProvider::AmdaProvider() -{ - -} +AmdaProvider::AmdaProvider() {} std::shared_ptr AmdaProvider::clone() const { @@ -65,7 +62,7 @@ std::shared_ptr AmdaProvider::clone() const return std::make_shared(); } -IDataSeries* AmdaProvider::getData(const DataProviderParameters ¶meters) +TimeSeries::ITimeSerie* AmdaProvider::getData(const DataProviderParameters& parameters) { auto range = parameters.m_Range; auto metaData = parameters.m_Data; @@ -74,15 +71,15 @@ IDataSeries* AmdaProvider::getData(const DataProviderParameters ¶meters) = DataSeriesTypeUtils::fromString(metaData.value(AMDA_DATA_TYPE_KEY).toString()); auto startDate = dateFormat(range.m_TStart); auto endDate = dateFormat(range.m_TEnd); - QVariantHash urlProperties{{AMDA_SERVER_KEY, metaData.value(AMDA_SERVER_KEY)}}; - auto token_url = QString{AMDA_TOKEN_URL_FORMAT}.arg(AmdaServer::instance().url(urlProperties)); + QVariantHash urlProperties { { AMDA_SERVER_KEY, metaData.value(AMDA_SERVER_KEY) } }; + auto token_url + = QString { AMDA_TOKEN_URL_FORMAT }.arg(AmdaServer::instance().url(urlProperties)); auto response = Downloader::get(token_url); - auto url = QString{AMDA_URL_FORMAT_WITH_TOKEN}.arg(AmdaServer::instance().url(urlProperties), - startDate, endDate, productId, QString(response.data())); + auto url = QString { AMDA_URL_FORMAT_WITH_TOKEN }.arg(AmdaServer::instance().url(urlProperties), + startDate, endDate, productId, QString(response.data())); response = Downloader::get(url); auto test = QJsonDocument::fromJson(response.data()); url = test["dataFileURLs"].toString(); response = Downloader::get(url); - return AmdaResultParser::readTxt(QTextStream{response.data()},productValueType); + return nullptr; // AmdaResultParser::readTxt(QTextStream { response.data() }, productValueType); } - diff --git a/plugins/amda/src/AmdaResultParser.cpp b/plugins/amda/src/AmdaResultParser.cpp index 15ffbd0..b9de134 100644 --- a/plugins/amda/src/AmdaResultParser.cpp +++ b/plugins/amda/src/AmdaResultParser.cpp @@ -4,7 +4,6 @@ #include -#include #include Q_LOGGING_CATEGORY(LOG_AmdaResultParser, "AmdaResultParser") diff --git a/plugins/amda/tests/FuzzingDefs.h b/plugins/amda/tests/FuzzingDefs.h index 07c0cb8..0277ea0 100644 --- a/plugins/amda/tests/FuzzingDefs.h +++ b/plugins/amda/tests/FuzzingDefs.h @@ -67,9 +67,10 @@ extern const QString VALIDATION_FREQUENCY_BOUNDS_PROPERTY; // /////// // class Variable; -struct VariableState { - std::shared_ptr m_Variable{nullptr}; - DateTimeRange m_Range{INVALID_RANGE}; +struct VariableState +{ + std::shared_ptr m_Variable { nullptr }; + DateTimeRange m_Range { INVALID_RANGE }; }; using VariableId = int; @@ -80,9 +81,10 @@ using VariablesPool = std::map; * with each other, and the current range of the group (i.e. range of the last synchronized variable * that has been moved) */ -struct SyncGroup { - std::set m_Variables{}; - DateTimeRange m_Range{INVALID_RANGE}; +struct SyncGroup +{ + std::set m_Variables {}; + DateTimeRange m_Range { INVALID_RANGE }; }; using SyncGroupId = QUuid; @@ -92,12 +94,13 @@ using SyncGroupsPool = std::map; * Defines a current state during a fuzzing state. It contains all the variables manipulated during * the test, as well as the synchronization status of these variables. */ -struct FuzzingState { - const SyncGroup &syncGroup(SyncGroupId id) const; - SyncGroup &syncGroup(SyncGroupId id); +struct FuzzingState +{ + const SyncGroup& syncGroup(SyncGroupId id) const; + SyncGroup& syncGroup(SyncGroupId id); - const VariableState &variableState(VariableId id) const; - VariableState &variableState(VariableId id); + const VariableState& variableState(VariableId id) const; + VariableState& variableState(VariableId id); /// @return the identifier of the synchronization group in which the variable passed in /// parameter is located. If the variable is not in any group, returns an invalid identifier @@ -119,7 +122,7 @@ struct FuzzingState { /// Updates the range of a variable and all variables to which it is synchronized /// @param the variable for which to affect the range /// @param the range to affect - void updateRanges(VariableId variableId, const DateTimeRange &newRange); + void updateRanges(VariableId variableId, const DateTimeRange& newRange); VariablesPool m_VariablesPool; SyncGroupsPool m_SyncGroupsPool; diff --git a/plugins/mockplugin/include/CosinusProvider.h b/plugins/mockplugin/include/CosinusProvider.h index 0bf24ef..1d29844 100644 --- a/plugins/mockplugin/include/CosinusProvider.h +++ b/plugins/mockplugin/include/CosinusProvider.h @@ -13,17 +13,18 @@ /** * @brief The CosinusProvider class is an example of how a data provider can generate data */ -class SCIQLOP_MOCKPLUGIN_EXPORT CosinusProvider : public IDataProvider { +class SCIQLOP_MOCKPLUGIN_EXPORT CosinusProvider : public IDataProvider +{ public: std::shared_ptr clone() const override; - virtual IDataSeries* getData(const DataProviderParameters ¶meters) override; + virtual TimeSeries::ITimeSerie* getData(const DataProviderParameters& parameters) override; private: - std::shared_ptr - retrieveData(QUuid acqIdentifier, const DateTimeRange &dataRangeRequested, const QVariantHash &data); + std::shared_ptr retrieveData( + QUuid acqIdentifier, const DateTimeRange& dataRangeRequested, const QVariantHash& data); - IDataSeries* _generate(const DateTimeRange &range, const QVariantHash &metaData); + TimeSeries::ITimeSerie* _generate(const DateTimeRange& range, const QVariantHash& metaData); QHash m_VariableToEnableProvider; }; diff --git a/plugins/mockplugin/src/CosinusProvider.cpp b/plugins/mockplugin/src/CosinusProvider.cpp index 3cd94f1..2ca3135 100644 --- a/plugins/mockplugin/src/CosinusProvider.cpp +++ b/plugins/mockplugin/src/CosinusProvider.cpp @@ -2,9 +2,9 @@ #include "MockDefs.h" #include -#include -#include -#include +#include +#include +#include #include #include @@ -14,145 +14,18 @@ #include -namespace { +namespace +{ /// Number of bands generated for a spectrogram const auto SPECTROGRAM_NUMBER_BANDS = 30; /// Bands for which to generate NaN values for a spectrogram -const auto SPECTROGRAM_NAN_BANDS = std::set{1, 3, 10, 20}; +const auto SPECTROGRAM_NAN_BANDS = std::set { 1, 3, 10, 20 }; /// Bands for which to generate zeros for a spectrogram -const auto SPECTROGRAM_ZERO_BANDS = std::set{2, 15, 19, 29}; - -/// Abstract cosinus type -struct ICosinusType { - virtual ~ICosinusType() = default; - /// @return the number of components generated for the type - virtual std::size_t componentCount() const = 0; - /// @return the data series created for the type - virtual IDataSeries* createDataSeries(std::vector xAxisData, - std::vector valuesData) const = 0; - /// Generates values (one value per component) - /// @param x the x-axis data used to generate values - /// @param values the vector in which to insert the generated values - /// @param dataIndex the index of insertion of the generated values - /// - virtual void generateValues(double x, std::vector &values, int dataIndex) const = 0; -}; - -struct ScalarCosinus : public ICosinusType { - std::size_t componentCount() const override { return 1; } - - IDataSeries* createDataSeries(std::vector xAxisData, - std::vector valuesData) const override - { - return new ScalarSeries(std::move(xAxisData), std::move(valuesData), - Unit{QStringLiteral("t"), true}, Unit{}); - } - - void generateValues(double x, std::vector &values, int dataIndex) const override - { - values[dataIndex] = std::cos(x); - } -}; - -struct SpectrogramCosinus : public ICosinusType { - /// Ctor with y-axis - explicit SpectrogramCosinus(std::vector yAxisData, Unit yAxisUnit, Unit valuesUnit) - : m_YAxisData{std::move(yAxisData)}, - m_YAxisUnit{std::move(yAxisUnit)}, - m_ValuesUnit{std::move(valuesUnit)} - { - } - - std::size_t componentCount() const override { return m_YAxisData.size(); } - - IDataSeries* createDataSeries(std::vector xAxisData, - std::vector valuesData) const override - { - return new SpectrogramSeries( - std::move(xAxisData), m_YAxisData, std::move(valuesData), - Unit{QStringLiteral("t"), true}, m_YAxisUnit, m_ValuesUnit); - } - - void generateValues(double x, std::vector &values, int dataIndex) const override - { - auto componentCount = this->componentCount(); - for (int i = 0; i < componentCount; ++i) { - auto y = m_YAxisData[i]; - - double value; - -// if (SPECTROGRAM_ZERO_BANDS.find(y) != SPECTROGRAM_ZERO_BANDS.end()) { -// value = 0.; -// } -// else if (SPECTROGRAM_NAN_BANDS.find(y) != SPECTROGRAM_NAN_BANDS.end()) { -// value = std::numeric_limits::quiet_NaN(); -// } -// else - { - // Generates value for non NaN/zero bands - //auto r = 3 * std::sqrt(x * x + y * y) + 1e-2; - //value = 2 * x * (std::cos(r + 2) / r - std::sin(r + 2) / r); - value = x + 10*y; - } - - values[componentCount * dataIndex + i] = value; - } - } - - std::vector m_YAxisData; - Unit m_YAxisUnit; - Unit m_ValuesUnit; -}; - -struct VectorCosinus : public ICosinusType { - std::size_t componentCount() const override { return 3; } +const auto SPECTROGRAM_ZERO_BANDS = std::set { 2, 15, 19, 29 }; - IDataSeries* createDataSeries(std::vector xAxisData, - std::vector valuesData) const override - { - return new VectorSeries(std::move(xAxisData), std::move(valuesData), - Unit{QStringLiteral("t"), true}, Unit{}); - } - - void generateValues(double x, std::vector &values, int dataIndex) const override - { - // Generates value for each component: cos(x), cos(x)/2, cos(x)/3 - auto xValue = std::cos(x); - auto componentCount = this->componentCount(); - for (auto i = 0; i < componentCount; ++i) { - values[componentCount * dataIndex + i] = xValue / (i + 1); - } - } -}; - -/// Converts string to cosinus type -/// @return the cosinus type if the string could be converted, nullptr otherwise -std::unique_ptr cosinusType(const QString &type) noexcept -{ - if (type.compare(QStringLiteral("scalar"), Qt::CaseInsensitive) == 0) { - return std::make_unique(); - } - else if (type.compare(QStringLiteral("spectrogram"), Qt::CaseInsensitive) == 0) { - // Generates default y-axis data for spectrogram [0., 1., 2., ...] - std::vector yAxisData(SPECTROGRAM_NUMBER_BANDS); - std::iota(yAxisData.begin(), yAxisData.end(), 1.); - for (auto & v:yAxisData) - { - v = std::pow(2,v); - } - return std::make_unique(std::move(yAxisData), Unit{"eV"}, - Unit{"eV/(cm^2-s-sr-eV)"}); - } - else if (type.compare(QStringLiteral("vector"), Qt::CaseInsensitive) == 0) { - return std::make_unique(); - } - else { - return nullptr; - } -} } // namespace @@ -162,43 +35,53 @@ std::shared_ptr CosinusProvider::clone() const return std::make_shared(); } -IDataSeries *CosinusProvider::_generate(const DateTimeRange &range, const QVariantHash &metaData) +TimeSeries::ITimeSerie* CosinusProvider::_generate( + const DateTimeRange& range, const QVariantHash& metaData) { - auto dataIndex = 0; - // Retrieves cosinus type auto typeVariant = metaData.value(COSINUS_TYPE_KEY, COSINUS_TYPE_DEFAULT_VALUE); - auto type = cosinusType(typeVariant.toString()); auto freqVariant = metaData.value(COSINUS_FREQUENCY_KEY, COSINUS_FREQUENCY_DEFAULT_VALUE); + const auto fs = 200.; double freq = freqVariant.toDouble(); double start = std::ceil(range.m_TStart * freq); double end = std::floor(range.m_TEnd * freq); - if (end < start) { + if (end < start) + { std::swap(start, end); } std::size_t dataCount = static_cast(end - start + 1); - std::size_t componentCount = type->componentCount(); - - auto xAxisData = std::vector{}; - xAxisData.resize(dataCount); - - auto valuesData = std::vector{}; - valuesData.resize(dataCount * componentCount); - - int progress = 0; - auto progressEnd = dataCount; - for (auto time = start; time <= end; ++time, ++dataIndex) + if (typeVariant.toString() == QStringLiteral("scalar")) { - const auto x = time / freq; - xAxisData[dataIndex] = x; - // Generates values (depending on the type) - type->generateValues(x, valuesData, dataIndex); + auto ts = new ScalarTimeSerie(dataCount); + std::generate( + std::begin(*ts), std::end(*ts), [range, freq, fs, dt = 1. / freq, i = 0.]() mutable { + auto t = range.m_TStart + i * dt; + i++; + return std::pair { t, std::cos(2 * 3.14 * freq / fs * t) }; + }); + return ts; } - return type->createDataSeries(std::move(xAxisData), std::move(valuesData)); + if (typeVariant.toString() == QStringLiteral("vector")) + { + auto ts = new VectorTimeSerie(dataCount); + std::generate( + std::begin(*ts), std::end(*ts), [range, freq, fs, dt = 1. / freq, i = 0.]() mutable { + auto t = range.m_TStart + i * dt; + i++; + return std::pair { t, + { std::cos(2 * 3.14 * freq / fs * t), std::sin(2 * 3.14 * freq / fs * t), + std::cos(2 * 3.14 * freq / fs * t) * std::sin(2 * 3.14 * freq / fs * t) } }; + }); + return ts; + } + if (typeVariant.toString() == QStringLiteral("spectrogram")) + { + return nullptr; + } + return nullptr; } -IDataSeries* CosinusProvider::getData(const DataProviderParameters ¶meters) +TimeSeries::ITimeSerie* CosinusProvider::getData(const DataProviderParameters& parameters) { return _generate(parameters.m_Range, parameters.m_Data); } - diff --git a/plugins/mockplugin/tests/PyTestMockPluginWrapper.cpp b/plugins/mockplugin/tests/PyTestMockPluginWrapper.cpp index 4819bd5..65917e6 100644 --- a/plugins/mockplugin/tests/PyTestMockPluginWrapper.cpp +++ b/plugins/mockplugin/tests/PyTestMockPluginWrapper.cpp @@ -19,45 +19,41 @@ /*-- Author : Alexis Jeandet -- Mail : alexis.jeandet@member.fsf.org ----------------------------------------------------------------------------*/ -#include -#include #include +#include +#include -#include -#include +#include #include #include -#include +#include +#include +#include +#include +#include #include -#include #include