##// END OF EJS Templates
Added basic tests around Amda plugin Python wrapper...
jeandet -
r1340:02cea38fdcb4
parent child
Show More
@@ -0,0 +1,54
1 import sys
2 import os
3 if not hasattr(sys, 'argv'):
4 sys.argv = ['']
5 current_script_path = os.path.dirname(os.path.realpath(__file__))
6 sys.path.append(current_script_path)
7 import amda
8 import pytestamda
9
10 import numpy as np
11 import datetime
12 import time
13 import unittest
14 import ddt
15
16 def wait_for_downloads():
17 while pytestamda.VariableController.hasPendingDownloads():
18 time.sleep(0.1)
19
20 def extract_vector(variable):
21 return zip(*[(pt.x, pt.value(0), pt.value(1), pt.value(2)) for pt in variable])
22
23 def compare_with_ref(var, ref):
24 t_ref, x_ref, y_ref, z_ref = ref
25 t,x,y,z = extract_vector(var)
26 return all([
27 all([t_ref[i].astype(float)/1000000 == t[i] for i in range(len(t))]),
28 all([x_ref[i] == x[i] for i in range(len(x))]),
29 all([y_ref[i] == y[i] for i in range(len(y))]),
30 all([z_ref[i] == z[i] for i in range(len(z))])
31 ])
32
33 @ddt.ddt
34 class FunctionalTests(unittest.TestCase):
35 def setUp(self):
36 pass
37
38 @ddt.data(
39 (datetime.datetime(2012,10,20,8,10,00),datetime.datetime(2012,10,20,12,0,0)),
40 (datetime.datetime(2025,1,1,15,0,0),datetime.datetime(2025,1,1,16,0,0)),
41 (datetime.datetime(2000,1,1,0,0,0),datetime.datetime(2000,1,1,12,0,0))
42 )
43 def test_simple_download(self, case):
44 tstart = case[0]
45 tstop = case[1]
46 pytestamda.TimeController.setTime(pytestamda.SqpRange(tstart, tstop))
47 variable = pytestamda.VariableController.createVariable("bx_gse",pytestamda.amda_provider())
48 wait_for_downloads()
49 t_ref, x_ref, y_ref, z_ref = amda.generate_data(np.datetime64(tstart), np.datetime64(tstop), 4)
50 self.assertTrue( compare_with_ref(variable,(t_ref, x_ref, y_ref, z_ref) ) )
51
52
53 if __name__ == '__main__':
54 unittest.main(exit=False)
@@ -0,0 +1,39
1 import sys
2 import os
3 if not hasattr(sys, 'argv'):
4 sys.argv = ['']
5 current_script_path = os.path.dirname(os.path.realpath(__file__))
6 sys.path.append(current_script_path)
7 import pytestamda
8 import amda
9
10 import numpy as np
11 import datetime
12 import time
13 import unittest
14 import ddt
15
16 path = current_script_path+'/../tests-resources/TestAmdaResultParser/ValidScalar1.txt'
17
18 @ddt.ddt
19 class FunctionalTests(unittest.TestCase):
20 def setUp(self):
21 pass
22
23 @ddt.data(
24 current_script_path+'/../tests-resources/TestAmdaResultParser/ValidScalar1.txt'
25 )
26 def test_correct_scalars(self, case):
27 scalar_sciqlop = pytestamda.AmdaResultParser.readScalarTxt(case)
28 scalar_ref = amda.load_scalar(case)
29 self.assertTrue(len(scalar_ref) == len(scalar_sciqlop))
30 self.assertTrue(all(
31 [scalar_ref[i][1] == scalar_sciqlop[i].value()
32 for i in range(len(scalar_sciqlop))]))
33 self.assertTrue(all(
34 [scalar_ref[i][0].timestamp() == scalar_sciqlop[i].x
35 for i in range(len(scalar_sciqlop))]))
36
37
38 if __name__ == '__main__':
39 unittest.main(exit=False)
@@ -0,0 +1,29
1 import sys
2 import os
3 import numpy as np
4 import datetime
5 import time
6
7 os.environ['TZ'] = 'UTC'
8 epoch_2000 = np.datetime64('2000-01-01T00:00:00',tzinfo=datetime.timezone.utc)
9
10 def load_scalar(fname):
11 with open(fname, "r") as f:
12 return [[
13 datetime.datetime(*(time.strptime(line.split()[0], '%Y-%m-%dT%H:%M:%S.%f')[0:6]),
14 tzinfo=datetime.timezone.utc),
15 float(line.split()[1])]
16 for line in f if "#" not in line]
17
18 """
19 Copied from myAMDA should be factored in somehow
20 """
21 def generate_data(tstart, tstop, dt):
22 delta = np.timedelta64(dt, 's')
23 vector_size = int(np.round((tstop-tstart)/delta)) + 1
24 t = [tstart+i*delta for i in range(vector_size)]
25 x0 = tstart-epoch_2000
26 x = [(x0 + i * delta).astype('float')/1000000 for i in range(vector_size)]
27 y = [(x0 + (i+1) * delta).astype('float')/1000000 for i in range(vector_size)]
28 z = [(x0 + (i+2) * delta).astype('float')/1000000 for i in range(vector_size)]
29 return t,x,y,z
@@ -1,144 +1,148
1 1 #ifndef SCIQLOP_VARIABLECONTROLLER_H
2 2 #define SCIQLOP_VARIABLECONTROLLER_H
3 3
4 4 #include "CoreGlobal.h"
5 5
6 6 #include <Data/AcquisitionDataPacket.h>
7 7 #include <Data/SqpRange.h>
8 8
9 9 #include <QLoggingCategory>
10 10 #include <QObject>
11 11 #include <QUuid>
12 12
13 13 #include <Common/spimpl.h>
14 14
15 15 class IDataProvider;
16 16 class QItemSelectionModel;
17 17 class TimeController;
18 18 class Variable;
19 19 class VariableModel;
20 20
21 21 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableController)
22 22
23 23
24 24 /**
25 25 * Possible types of zoom operation
26 26 */
27 27 enum class AcquisitionZoomType { ZoomOut, ZoomIn, PanRight, PanLeft, Unknown };
28 28
29 29
30 30 /**
31 31 * @brief The VariableController class aims to handle the variables in SciQlop.
32 32 */
33 33 class SCIQLOP_CORE_EXPORT VariableController : public QObject {
34 34 Q_OBJECT
35 35 public:
36 36 explicit VariableController(QObject *parent = 0);
37 37 virtual ~VariableController();
38 38
39 39 VariableModel *variableModel() noexcept;
40 40 QItemSelectionModel *variableSelectionModel() noexcept;
41 41
42 42 void setTimeController(TimeController *timeController) noexcept;
43 43
44 44 /**
45 45 * Clones the variable passed in parameter and adds the duplicate to the controller
46 46 * @param variable the variable to duplicate
47 47 * @return the duplicate created, nullptr if the variable couldn't be created
48 48 */
49 49 std::shared_ptr<Variable> cloneVariable(std::shared_ptr<Variable> variable) noexcept;
50 50
51 51 /// Returns the MIME data associated to a list of variables
52 52 QByteArray mimeDataForVariables(const QList<std::shared_ptr<Variable> > &variables) const;
53 53
54 54 /// Returns the list of variables contained in a MIME data
55 55 QList<std::shared_ptr<Variable> > variablesForMimeData(const QByteArray &mimeData) const;
56 56
57 57 static AcquisitionZoomType getZoomType(const SqpRange &range, const SqpRange &oldRange);
58
59 /// Returns True if there are pending downloads
60 bool hasPendingDownloads();
58 61 signals:
59 62 /// Signal emitted when a variable is about to be deleted from the controller
60 63 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
61 64
62 65 /// Signal emitted when a data acquisition is requested on a range for a variable
63 66 void rangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range);
64 67
65 68 /// Signal emitted when a sub range of the cacheRange of the variable can be displayed
66 69 void updateVarDisplaying(std::shared_ptr<Variable> variable, const SqpRange &range);
67 70
68 71 /// Signal emitted when all acquisitions related to the variables have been completed (whether
69 72 /// validated, canceled, or failed)
70 73 void acquisitionFinished();
71 74
72 75 void variableAdded(const std::shared_ptr<Variable> &variable);
73 76
74 77 public slots:
75 78 /**
76 79 * Deletes from the controller the variable passed in parameter.
77 80 *
78 81 * Delete a variable includes:
79 82 * - the deletion of the various references to the variable in SciQlop
80 83 * - the deletion of the model variable
81 84 * - the deletion of the provider associated with the variable
82 85 * - removing the cache associated with the variable
83 86 *
84 87 * @param variable the variable to delete from the controller.
85 88 */
86 89 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
87 90
88 91 /**
89 92 * Deletes from the controller the variables passed in parameter.
90 93 * @param variables the variables to delete from the controller.
91 94 * @sa deleteVariable()
92 95 */
93 96 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
94 97
95 98 /// Request the data loading of the variable whithin range
96 99 void onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables, const SqpRange &range,
97 100 bool synchronise);
98 101 /**
99 102 * Creates a new variable and adds it to the model
100 103 * @param name the name of the new variable
101 104 * @param metadata the metadata of the new variable
102 105 * @param provider the data provider for the new variable
103 106 * @return the pointer to the new variable or nullptr if the creation failed
104 107 */
105 108 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata,
106 109 std::shared_ptr<IDataProvider> provider) noexcept;
107 110
108 111 /// Update the temporal parameters of every selected variable to dateTime
109 112 void onDateTimeOnSelection(const SqpRange &dateTime);
110 113
111 114 /// Update the temporal parameters of the specified variable
112 115 void onUpdateDateTime(std::shared_ptr<Variable> variable, const SqpRange &dateTime);
113 116
114 117
115 118 void onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
116 119 const SqpRange &cacheRangeRequested,
117 120 QVector<AcquisitionDataPacket> dataAcquired);
118 121
119 122 void onVariableRetrieveDataInProgress(QUuid identifier, double progress);
120 123
121 124 /// Cancel the current request for the variable
122 125 void onAbortProgressRequested(std::shared_ptr<Variable> variable);
123 126 void onAbortAcquisitionRequested(QUuid vIdentifier);
124 127
125 128 // synchronization group methods
126 129 void onAddSynchronizationGroupId(QUuid synchronizationGroupId);
127 130 void onRemoveSynchronizationGroupId(QUuid synchronizationGroupId);
128 131 void onAddSynchronized(std::shared_ptr<Variable> variable, QUuid synchronizationGroupId);
129 132
130 133 /// Desynchronizes the variable of the group whose identifier is passed in parameter
131 134 /// @remarks the method does nothing if the variable is not part of the group
132 135 void desynchronize(std::shared_ptr<Variable> variable, QUuid synchronizationGroupId);
133 136
134 137 void initialize();
135 138 void finalize();
136 139
137 140 private:
138 141 void waitForFinish();
139 142
140 143 class VariableControllerPrivate;
141 144 spimpl::unique_impl_ptr<VariableControllerPrivate> impl;
142 145 };
143 146
147
144 148 #endif // SCIQLOP_VARIABLECONTROLLER_H
@@ -1,1104 +1,1114
1 1 #include <Variable/Variable.h>
2 2 #include <Variable/VariableAcquisitionWorker.h>
3 3 #include <Variable/VariableCacheStrategy.h>
4 4 #include <Variable/VariableCacheStrategyFactory.h>
5 5 #include <Variable/VariableController.h>
6 6 #include <Variable/VariableModel.h>
7 7 #include <Variable/VariableSynchronizationGroup.h>
8 8
9 9 #include <Data/DataProviderParameters.h>
10 10 #include <Data/IDataProvider.h>
11 11 #include <Data/IDataSeries.h>
12 12 #include <Data/VariableRequest.h>
13 13 #include <Time/TimeController.h>
14 14
15 15 #include <QDataStream>
16 16 #include <QMutex>
17 17 #include <QThread>
18 18 #include <QUuid>
19 19 #include <QtCore/QItemSelectionModel>
20 20
21 21 #include <deque>
22 22 #include <set>
23 23 #include <unordered_map>
24 24
25 25 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
26 26
27 27 namespace {
28 28
29 29 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
30 30 const SqpRange &oldGraphRange)
31 31 {
32 32 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
33 33
34 34 auto varRangeRequested = varRange;
35 35 switch (zoomType) {
36 36 case AcquisitionZoomType::ZoomIn: {
37 37 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
38 38 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
39 39 varRangeRequested.m_TStart += deltaLeft;
40 40 varRangeRequested.m_TEnd -= deltaRight;
41 41 break;
42 42 }
43 43
44 44 case AcquisitionZoomType::ZoomOut: {
45 45 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
46 46 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
47 47 varRangeRequested.m_TStart -= deltaLeft;
48 48 varRangeRequested.m_TEnd += deltaRight;
49 49 break;
50 50 }
51 51 case AcquisitionZoomType::PanRight: {
52 52 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
53 53 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
54 54 varRangeRequested.m_TStart += deltaLeft;
55 55 varRangeRequested.m_TEnd += deltaRight;
56 56 break;
57 57 }
58 58 case AcquisitionZoomType::PanLeft: {
59 59 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
60 60 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
61 61 varRangeRequested.m_TStart -= deltaLeft;
62 62 varRangeRequested.m_TEnd -= deltaRight;
63 63 break;
64 64 }
65 65 case AcquisitionZoomType::Unknown: {
66 66 qCCritical(LOG_VariableController())
67 67 << VariableController::tr("Impossible to synchronize: zoom type unknown");
68 68 break;
69 69 }
70 70 default:
71 71 qCCritical(LOG_VariableController()) << VariableController::tr(
72 72 "Impossible to synchronize: zoom type not take into account");
73 73 // No action
74 74 break;
75 75 }
76 76
77 77 return varRangeRequested;
78 78 }
79 79 }
80 80
81 81 enum class VariableRequestHandlerState { OFF, RUNNING, PENDING };
82 82
83 83 struct VariableRequestHandler {
84 84
85 85 VariableRequestHandler()
86 86 {
87 87 m_CanUpdate = false;
88 88 m_State = VariableRequestHandlerState::OFF;
89 89 }
90 90
91 91 QUuid m_VarId;
92 92 VariableRequest m_RunningVarRequest;
93 93 VariableRequest m_PendingVarRequest;
94 94 VariableRequestHandlerState m_State;
95 95 bool m_CanUpdate;
96 96 };
97 97
98 98 struct VariableController::VariableControllerPrivate {
99 99 explicit VariableControllerPrivate(VariableController *parent)
100 100 : m_WorkingMutex{},
101 101 m_VariableModel{new VariableModel{parent}},
102 102 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
103 103 // m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
104 104 m_VariableCacheStrategy{VariableCacheStrategyFactory::createCacheStrategy(
105 105 CacheStrategy::SingleThreshold)},
106 106 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
107 107 q{parent}
108 108 {
109 109
110 110 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
111 111 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
112 112 }
113 113
114 114
115 115 virtual ~VariableControllerPrivate()
116 116 {
117 117 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
118 118 m_VariableAcquisitionWorkerThread.quit();
119 119 m_VariableAcquisitionWorkerThread.wait();
120 120 }
121 121
122 122
123 123 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
124 124 QUuid varRequestId);
125 125
126 126 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
127 127 std::shared_ptr<IDataSeries>
128 128 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
129 129
130 130 void registerProvider(std::shared_ptr<IDataProvider> provider);
131 131
132 132 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
133 133 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
134 134 void updateVariables(QUuid varRequestId);
135 135 void updateVariableRequest(QUuid varRequestId);
136 136 void cancelVariableRequest(QUuid varRequestId);
137 137 void executeVarRequest(std::shared_ptr<Variable> var, VariableRequest &varRequest);
138
138 bool hasPendingDownloads();
139 139 template <typename VariableIterator>
140 140 void desynchronize(VariableIterator variableIt, const QUuid &syncGroupId);
141 141
142 142 QMutex m_WorkingMutex;
143 143 /// Variable model. The VariableController has the ownership
144 144 VariableModel *m_VariableModel;
145 145 QItemSelectionModel *m_VariableSelectionModel;
146 146
147 147
148 148 TimeController *m_TimeController{nullptr};
149 149 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
150 150 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
151 151 QThread m_VariableAcquisitionWorkerThread;
152 152
153 153 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
154 154 m_VariableToProviderMap;
155 155 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
156 156 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
157 157 m_GroupIdToVariableSynchronizationGroupMap;
158 158 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
159 159 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
160 160
161 161 std::map<QUuid, std::list<QUuid> > m_VarGroupIdToVarIds;
162 162 std::map<QUuid, std::unique_ptr<VariableRequestHandler> > m_VarIdToVarRequestHandler;
163 163
164 164 VariableController *q;
165 165 };
166 166
167 167
168 168 VariableController::VariableController(QObject *parent)
169 169 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
170 170 {
171 171 qCDebug(LOG_VariableController()) << tr("VariableController construction")
172 172 << QThread::currentThread();
173 173
174 174 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
175 175 &VariableController::onAbortProgressRequested);
176 176
177 177 connect(impl->m_VariableAcquisitionWorker.get(),
178 178 &VariableAcquisitionWorker::variableCanceledRequested, this,
179 179 &VariableController::onAbortAcquisitionRequested);
180 180
181 181 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
182 182 &VariableController::onDataProvided);
183 183 connect(impl->m_VariableAcquisitionWorker.get(),
184 184 &VariableAcquisitionWorker::variableRequestInProgress, this,
185 185 &VariableController::onVariableRetrieveDataInProgress);
186 186
187 187
188 188 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
189 189 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
190 190 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
191 191 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
192 192
193 193 connect(impl->m_VariableModel, &VariableModel::requestVariableRangeUpdate, this,
194 194 &VariableController::onUpdateDateTime);
195 195
196 196 impl->m_VariableAcquisitionWorkerThread.start();
197 197 }
198 198
199 199 VariableController::~VariableController()
200 200 {
201 201 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
202 202 << QThread::currentThread();
203 203 this->waitForFinish();
204 204 }
205 205
206 206 VariableModel *VariableController::variableModel() noexcept
207 207 {
208 208 return impl->m_VariableModel;
209 209 }
210 210
211 211 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
212 212 {
213 213 return impl->m_VariableSelectionModel;
214 214 }
215 215
216 216 void VariableController::setTimeController(TimeController *timeController) noexcept
217 217 {
218 218 impl->m_TimeController = timeController;
219 219 }
220 220
221 221 std::shared_ptr<Variable>
222 222 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
223 223 {
224 224 if (impl->m_VariableModel->containsVariable(variable)) {
225 225 // Clones variable
226 226 auto duplicate = variable->clone();
227 227
228 228 // Adds clone to model
229 229 impl->m_VariableModel->addVariable(duplicate);
230 230
231 231 // Generates clone identifier
232 232 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
233 233
234 234 // Registers provider
235 235 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
236 236 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
237 237
238 238 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
239 239 if (duplicateProvider) {
240 240 impl->registerProvider(duplicateProvider);
241 241 }
242 242
243 243 return duplicate;
244 244 }
245 245 else {
246 246 qCCritical(LOG_VariableController())
247 247 << tr("Can't create duplicate of variable %1: variable not registered in the model")
248 248 .arg(variable->name());
249 249 return nullptr;
250 250 }
251 251 }
252 252
253 253 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
254 254 {
255 255 if (!variable) {
256 256 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
257 257 return;
258 258 }
259 259
260 260 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
261 261 // make some treatments before the deletion
262 262 emit variableAboutToBeDeleted(variable);
263 263
264 264 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
265 265 Q_ASSERT(variableIt != impl->m_VariableToIdentifierMap.cend());
266 266
267 267 auto variableId = variableIt->second;
268 268
269 269 // Removes variable's handler
270 270 impl->m_VarIdToVarRequestHandler.erase(variableId);
271 271
272 272 // Desynchronizes variable (if the variable is in a sync group)
273 273 auto syncGroupIt = impl->m_VariableIdGroupIdMap.find(variableId);
274 274 if (syncGroupIt != impl->m_VariableIdGroupIdMap.cend()) {
275 275 impl->desynchronize(variableIt, syncGroupIt->second);
276 276 }
277 277
278 278 // Deletes identifier
279 279 impl->m_VariableToIdentifierMap.erase(variableIt);
280 280
281 281 // Deletes provider
282 282 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
283 283 qCDebug(LOG_VariableController())
284 284 << tr("Number of providers deleted for variable %1: %2")
285 285 .arg(variable->name(), QString::number(nbProvidersDeleted));
286 286
287 287
288 288 // Deletes from model
289 289 impl->m_VariableModel->deleteVariable(variable);
290 290 }
291 291
292 292 void VariableController::deleteVariables(
293 293 const QVector<std::shared_ptr<Variable> > &variables) noexcept
294 294 {
295 295 for (auto variable : qAsConst(variables)) {
296 296 deleteVariable(variable);
297 297 }
298 298 }
299 299
300 300 QByteArray
301 301 VariableController::mimeDataForVariables(const QList<std::shared_ptr<Variable> > &variables) const
302 302 {
303 303 auto encodedData = QByteArray{};
304 304
305 305 QVariantList ids;
306 306 for (auto &var : variables) {
307 307 auto itVar = impl->m_VariableToIdentifierMap.find(var);
308 308 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
309 309 qCCritical(LOG_VariableController())
310 310 << tr("Impossible to find the data for an unknown variable.");
311 311 }
312 312
313 313 ids << itVar->second.toByteArray();
314 314 }
315 315
316 316 QDataStream stream{&encodedData, QIODevice::WriteOnly};
317 317 stream << ids;
318 318
319 319 return encodedData;
320 320 }
321 321
322 322 QList<std::shared_ptr<Variable> >
323 323 VariableController::variablesForMimeData(const QByteArray &mimeData) const
324 324 {
325 325 auto variables = QList<std::shared_ptr<Variable> >{};
326 326 QDataStream stream{mimeData};
327 327
328 328 QVariantList ids;
329 329 stream >> ids;
330 330
331 331 for (auto id : ids) {
332 332 auto uuid = QUuid{id.toByteArray()};
333 333 auto var = impl->findVariable(uuid);
334 334 variables << var;
335 335 }
336 336
337 337 return variables;
338 338 }
339 339
340 340 std::shared_ptr<Variable>
341 341 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
342 342 std::shared_ptr<IDataProvider> provider) noexcept
343 343 {
344 344 if (!impl->m_TimeController) {
345 345 qCCritical(LOG_VariableController())
346 346 << tr("Impossible to create variable: The time controller is null");
347 347 return nullptr;
348 348 }
349 349
350 350 auto range = impl->m_TimeController->dateTime();
351 351
352 352 if (auto newVariable = impl->m_VariableModel->createVariable(name, metadata)) {
353 353 auto varId = QUuid::createUuid();
354 354
355 355 // Create the handler
356 356 auto varRequestHandler = std::make_unique<VariableRequestHandler>();
357 357 varRequestHandler->m_VarId = varId;
358 358
359 359 impl->m_VarIdToVarRequestHandler.insert(
360 360 std::make_pair(varId, std::move(varRequestHandler)));
361 361
362 362 // store the provider
363 363 impl->registerProvider(provider);
364 364
365 365 // Associate the provider
366 366 impl->m_VariableToProviderMap[newVariable] = provider;
367 367 impl->m_VariableToIdentifierMap[newVariable] = varId;
368 368
369 369 this->onRequestDataLoading(QVector<std::shared_ptr<Variable> >{newVariable}, range, false);
370 370
371 371 // auto varRequestId = QUuid::createUuid();
372 372 // qCInfo(LOG_VariableController()) << "createVariable: " << varId << varRequestId;
373 373 // impl->processRequest(newVariable, range, varRequestId);
374 374 // impl->updateVariableRequest(varRequestId);
375 375
376 376 emit variableAdded(newVariable);
377 377
378 378 return newVariable;
379 379 }
380 380
381 381 qCCritical(LOG_VariableController()) << tr("Impossible to create variable");
382 382 return nullptr;
383 383 }
384 384
385 385 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
386 386 {
387 387 // NOTE: Even if acquisition request is aborting, the graphe range will be changed
388 388 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
389 389 << QThread::currentThread()->objectName();
390 390 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
391 391
392 392 // NOTE we only permit the time modification for one variable
393 393 // DEPRECATED
394 394 // auto variables = QVector<std::shared_ptr<Variable> >{};
395 395 // for (const auto &selectedRow : qAsConst(selectedRows)) {
396 396 // if (auto selectedVariable =
397 397 // impl->m_VariableModel->variable(selectedRow.row())) {
398 398 // variables << selectedVariable;
399 399
400 400 // // notify that rescale operation has to be done
401 401 // emit rangeChanged(selectedVariable, dateTime);
402 402 // }
403 403 // }
404 404 // if (!variables.isEmpty()) {
405 405 // this->onRequestDataLoading(variables, dateTime, synchro);
406 406 // }
407 407 if (selectedRows.size() == 1) {
408 408
409 409 if (auto selectedVariable
410 410 = impl->m_VariableModel->variable(qAsConst(selectedRows).first().row())) {
411 411
412 412 onUpdateDateTime(selectedVariable, dateTime);
413 413 }
414 414 }
415 415 else if (selectedRows.size() > 1) {
416 416 qCCritical(LOG_VariableController())
417 417 << tr("Impossible to set time for more than 1 variable in the same time");
418 418 }
419 419 else {
420 420 qCWarning(LOG_VariableController())
421 421 << tr("There is no variable selected to set the time one");
422 422 }
423 423 }
424 424
425 425 void VariableController::onUpdateDateTime(std::shared_ptr<Variable> variable,
426 426 const SqpRange &dateTime)
427 427 {
428 428 auto itVar = impl->m_VariableToIdentifierMap.find(variable);
429 429 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
430 430 qCCritical(LOG_VariableController())
431 431 << tr("Impossible to onDateTimeOnSelection request for unknown variable");
432 432 return;
433 433 }
434 434
435 435 // notify that rescale operation has to be done
436 436 emit rangeChanged(variable, dateTime);
437 437
438 438 auto synchro
439 439 = impl->m_VariableIdGroupIdMap.find(itVar->second) != impl->m_VariableIdGroupIdMap.cend();
440 440
441 441 this->onRequestDataLoading(QVector<std::shared_ptr<Variable> >{variable}, dateTime, synchro);
442 442 }
443 443
444 444 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
445 445 const SqpRange &cacheRangeRequested,
446 446 QVector<AcquisitionDataPacket> dataAcquired)
447 447 {
448 448 qCDebug(LOG_VariableController()) << tr("onDataProvided") << QThread::currentThread();
449 449 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
450 450 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
451 451 if (!varRequestId.isNull()) {
452 452 impl->updateVariables(varRequestId);
453 453 }
454 454 }
455 455
456 456 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
457 457 {
458 458 qCDebug(LOG_VariableController())
459 459 << "TORM: variableController::onVariableRetrieveDataInProgress"
460 460 << QThread::currentThread()->objectName() << progress;
461 461 if (auto var = impl->findVariable(identifier)) {
462 462 impl->m_VariableModel->setDataProgress(var, progress);
463 463 }
464 464 else {
465 465 qCCritical(LOG_VariableController())
466 466 << tr("Impossible to notify progression of a null variable");
467 467 }
468 468 }
469 469
470 470 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
471 471 {
472 472 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortProgressRequested"
473 473 << QThread::currentThread()->objectName() << variable->name();
474 474
475 475 auto itVar = impl->m_VariableToIdentifierMap.find(variable);
476 476 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
477 477 qCCritical(LOG_VariableController())
478 478 << tr("Impossible to onAbortProgressRequested request for unknown variable");
479 479 return;
480 480 }
481 481
482 482 auto varId = itVar->second;
483 483
484 484 auto itVarHandler = impl->m_VarIdToVarRequestHandler.find(varId);
485 485 if (itVarHandler == impl->m_VarIdToVarRequestHandler.cend()) {
486 486 qCCritical(LOG_VariableController())
487 487 << tr("Impossible to onAbortProgressRequested for variable with unknown handler");
488 488 return;
489 489 }
490 490
491 491 auto varHandler = itVarHandler->second.get();
492 492
493 493 // case where a variable has a running request
494 494 if (varHandler->m_State != VariableRequestHandlerState::OFF) {
495 495 impl->cancelVariableRequest(varHandler->m_RunningVarRequest.m_VariableGroupId);
496 496 }
497 497 }
498 498
499 499 void VariableController::onAbortAcquisitionRequested(QUuid vIdentifier)
500 500 {
501 501 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortAcquisitionRequested"
502 502 << QThread::currentThread()->objectName() << vIdentifier;
503 503
504 504 if (auto var = impl->findVariable(vIdentifier)) {
505 505 this->onAbortProgressRequested(var);
506 506 }
507 507 else {
508 508 qCCritical(LOG_VariableController())
509 509 << tr("Impossible to abort Acquisition Requestof a null variable");
510 510 }
511 511 }
512 512
513 513 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
514 514 {
515 515 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
516 516 << QThread::currentThread()->objectName()
517 517 << synchronizationGroupId;
518 518 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
519 519 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
520 520 std::make_pair(synchronizationGroupId, vSynchroGroup));
521 521 }
522 522
523 523 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
524 524 {
525 525 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
526 526 }
527 527
528 528 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
529 529 QUuid synchronizationGroupId)
530 530
531 531 {
532 532 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
533 533 << synchronizationGroupId;
534 534 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
535 535 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
536 536 auto groupIdToVSGIt
537 537 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
538 538 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
539 539 impl->m_VariableIdGroupIdMap.insert(
540 540 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
541 541 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
542 542 }
543 543 else {
544 544 qCCritical(LOG_VariableController())
545 545 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
546 546 << variable->name();
547 547 }
548 548 }
549 549 else {
550 550 qCCritical(LOG_VariableController())
551 551 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
552 552 }
553 553 }
554 554
555 555 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
556 556 QUuid synchronizationGroupId)
557 557 {
558 558 // Gets variable id
559 559 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
560 560 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
561 561 qCCritical(LOG_VariableController())
562 562 << tr("Can't desynchronize variable %1: variable identifier not found")
563 563 .arg(variable->name());
564 564 return;
565 565 }
566 566
567 567 impl->desynchronize(variableIt, synchronizationGroupId);
568 568 }
569 569
570 570 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
571 571 const SqpRange &range, bool synchronise)
572 572 {
573 573 // variables is assumed synchronized
574 574 // TODO: Asser variables synchronization
575 575 // we want to load data of the variable for the dateTime.
576 576 if (variables.isEmpty()) {
577 577 return;
578 578 }
579 579
580 580 auto varRequestId = QUuid::createUuid();
581 581 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
582 582 << QThread::currentThread()->objectName() << varRequestId
583 583 << range << synchronise;
584 584
585 585 if (!synchronise) {
586 586 auto varIds = std::list<QUuid>{};
587 587 for (const auto &var : variables) {
588 588 auto vId = impl->m_VariableToIdentifierMap.at(var);
589 589 varIds.push_back(vId);
590 590 }
591 591 impl->m_VarGroupIdToVarIds.insert(std::make_pair(varRequestId, varIds));
592 592 for (const auto &var : variables) {
593 593 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId
594 594 << varIds.size();
595 595 impl->processRequest(var, range, varRequestId);
596 596 }
597 597 }
598 598 else {
599 599 auto vId = impl->m_VariableToIdentifierMap.at(variables.first());
600 600 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
601 601 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
602 602 auto groupId = varIdToGroupIdIt->second;
603 603
604 604 auto vSynchronizationGroup
605 605 = impl->m_GroupIdToVariableSynchronizationGroupMap.at(groupId);
606 606 auto vSyncIds = vSynchronizationGroup->getIds();
607 607
608 608 auto varIds = std::list<QUuid>{};
609 609 for (auto vId : vSyncIds) {
610 610 varIds.push_back(vId);
611 611 }
612 612 impl->m_VarGroupIdToVarIds.insert(std::make_pair(varRequestId, varIds));
613 613
614 614 for (auto vId : vSyncIds) {
615 615 auto var = impl->findVariable(vId);
616 616
617 617 // Don't process already processed var
618 618 if (var != nullptr) {
619 619 qCDebug(LOG_VariableController()) << "processRequest synchro for" << var->name()
620 620 << varRequestId;
621 621 auto vSyncRangeRequested
622 622 = variables.contains(var)
623 623 ? range
624 624 : computeSynchroRangeRequested(var->range(), range,
625 625 variables.first()->range());
626 626 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
627 627 impl->processRequest(var, vSyncRangeRequested, varRequestId);
628 628 }
629 629 else {
630 630 qCCritical(LOG_VariableController())
631 631
632 632 << tr("Impossible to synchronize a null variable");
633 633 }
634 634 }
635 635 }
636 636 }
637 637
638 638 impl->updateVariables(varRequestId);
639 639 }
640 640
641 641
642 642 void VariableController::initialize()
643 643 {
644 644 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
645 645 impl->m_WorkingMutex.lock();
646 646 qCDebug(LOG_VariableController()) << tr("VariableController init END");
647 647 }
648 648
649 649 void VariableController::finalize()
650 650 {
651 651 impl->m_WorkingMutex.unlock();
652 652 }
653 653
654 654 void VariableController::waitForFinish()
655 655 {
656 656 QMutexLocker locker{&impl->m_WorkingMutex};
657 657 }
658 658
659 bool VariableController::hasPendingDownloads()
660 {
661 return impl->hasPendingDownloads();
662 }
663
659 664 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
660 665 {
661 666 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
662 667 auto zoomType = AcquisitionZoomType::Unknown;
663 668 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
664 669 qCDebug(LOG_VariableController()) << "zoomtype: ZoomOut";
665 670 zoomType = AcquisitionZoomType::ZoomOut;
666 671 }
667 672 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
668 673 qCDebug(LOG_VariableController()) << "zoomtype: PanRight";
669 674 zoomType = AcquisitionZoomType::PanRight;
670 675 }
671 676 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
672 677 qCDebug(LOG_VariableController()) << "zoomtype: PanLeft";
673 678 zoomType = AcquisitionZoomType::PanLeft;
674 679 }
675 680 else if (range.m_TStart >= oldRange.m_TStart && oldRange.m_TEnd >= range.m_TEnd) {
676 681 qCDebug(LOG_VariableController()) << "zoomtype: ZoomIn";
677 682 zoomType = AcquisitionZoomType::ZoomIn;
678 683 }
679 684 else {
680 685 qCDebug(LOG_VariableController()) << "getZoomType: Unknown type detected";
681 686 }
682 687 return zoomType;
683 688 }
684 689
685 690 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
686 691 const SqpRange &rangeRequested,
687 692 QUuid varRequestId)
688 693 {
689 694 auto itVar = m_VariableToIdentifierMap.find(var);
690 695 if (itVar == m_VariableToIdentifierMap.cend()) {
691 696 qCCritical(LOG_VariableController())
692 697 << tr("Impossible to process request for unknown variable");
693 698 return;
694 699 }
695 700
696 701 auto varId = itVar->second;
697 702
698 703 auto itVarHandler = m_VarIdToVarRequestHandler.find(varId);
699 704 if (itVarHandler == m_VarIdToVarRequestHandler.cend()) {
700 705 qCCritical(LOG_VariableController())
701 706 << tr("Impossible to process request for variable with unknown handler");
702 707 return;
703 708 }
704 709
705 710 auto oldRange = var->range();
706 711
707 712 auto varHandler = itVarHandler->second.get();
708 713
709 714 if (varHandler->m_State != VariableRequestHandlerState::OFF) {
710 715 oldRange = varHandler->m_RunningVarRequest.m_RangeRequested;
711 716 }
712 717
713 718 auto varRequest = VariableRequest{};
714 719 varRequest.m_VariableGroupId = varRequestId;
715 720 auto varStrategyRangesRequested
716 721 = m_VariableCacheStrategy->computeRange(oldRange, rangeRequested);
717 722 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
718 723 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
719 724
720 725 switch (varHandler->m_State) {
721 726 case VariableRequestHandlerState::OFF: {
722 727 qCDebug(LOG_VariableController()) << tr("Process Request OFF")
723 728 << varRequest.m_RangeRequested
724 729 << varRequest.m_CacheRangeRequested;
725 730 varHandler->m_RunningVarRequest = varRequest;
726 731 varHandler->m_State = VariableRequestHandlerState::RUNNING;
727 732 executeVarRequest(var, varRequest);
728 733 break;
729 734 }
730 735 case VariableRequestHandlerState::RUNNING: {
731 736 qCDebug(LOG_VariableController()) << tr("Process Request RUNNING")
732 737 << varRequest.m_RangeRequested
733 738 << varRequest.m_CacheRangeRequested;
734 739 varHandler->m_State = VariableRequestHandlerState::PENDING;
735 740 varHandler->m_PendingVarRequest = varRequest;
736 741 break;
737 742 }
738 743 case VariableRequestHandlerState::PENDING: {
739 744 qCDebug(LOG_VariableController()) << tr("Process Request PENDING")
740 745 << varRequest.m_RangeRequested
741 746 << varRequest.m_CacheRangeRequested;
742 747 auto variableGroupIdToCancel = varHandler->m_PendingVarRequest.m_VariableGroupId;
743 748 cancelVariableRequest(variableGroupIdToCancel);
744 749 // Cancel variable can make state downgrade
745 750 varHandler->m_State = VariableRequestHandlerState::PENDING;
746 751 varHandler->m_PendingVarRequest = varRequest;
747 752
748 753 break;
749 754 }
750 755 default:
751 756 qCCritical(LOG_VariableController())
752 757 << QObject::tr("Unknown VariableRequestHandlerState");
753 758 }
754 759 }
755 760
756 761 std::shared_ptr<Variable>
757 762 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
758 763 {
759 764 std::shared_ptr<Variable> var;
760 765 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
761 766
762 767 auto end = m_VariableToIdentifierMap.cend();
763 768 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
764 769 if (it != end) {
765 770 var = it->first;
766 771 }
767 772 else {
768 773 qCCritical(LOG_VariableController())
769 774 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
770 775 }
771 776
772 777 return var;
773 778 }
774 779
775 780 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
776 781 const QVector<AcquisitionDataPacket> acqDataPacketVector)
777 782 {
778 783 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
779 784 << acqDataPacketVector.size();
780 785 std::shared_ptr<IDataSeries> dataSeries;
781 786 if (!acqDataPacketVector.isEmpty()) {
782 787 dataSeries = acqDataPacketVector[0].m_DateSeries;
783 788 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
784 789 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
785 790 }
786 791 }
787 792 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
788 793 << acqDataPacketVector.size();
789 794 return dataSeries;
790 795 }
791 796
792 797 void VariableController::VariableControllerPrivate::registerProvider(
793 798 std::shared_ptr<IDataProvider> provider)
794 799 {
795 800 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
796 801 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
797 802 << provider->objectName();
798 803 m_ProviderSet.insert(provider);
799 804 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
800 805 &VariableAcquisitionWorker::onVariableDataAcquired);
801 806 connect(provider.get(), &IDataProvider::dataProvidedProgress,
802 807 m_VariableAcquisitionWorker.get(),
803 808 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
804 809 connect(provider.get(), &IDataProvider::dataProvidedFailed,
805 810 m_VariableAcquisitionWorker.get(),
806 811 &VariableAcquisitionWorker::onVariableAcquisitionFailed);
807 812 }
808 813 else {
809 814 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
810 815 }
811 816 }
812 817
813 818 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
814 819 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
815 820 {
816 821 auto itVarHandler = m_VarIdToVarRequestHandler.find(varId);
817 822 if (itVarHandler == m_VarIdToVarRequestHandler.cend()) {
818 823 return QUuid();
819 824 }
820 825
821 826 auto varHandler = itVarHandler->second.get();
822 827 if (varHandler->m_State == VariableRequestHandlerState::OFF) {
823 828 qCCritical(LOG_VariableController())
824 829 << tr("acceptVariableRequest impossible on a variable with OFF state");
825 830 }
826 831
827 832 varHandler->m_RunningVarRequest.m_DataSeries = dataSeries;
828 833 varHandler->m_CanUpdate = true;
829 834
830 835 // Element traité, on a déjà toutes les données necessaires
831 836 auto varGroupId = varHandler->m_RunningVarRequest.m_VariableGroupId;
832 837 qCDebug(LOG_VariableController()) << "Variable::acceptVariableRequest" << varGroupId
833 838 << m_VarGroupIdToVarIds.size();
834 839
835 840 return varHandler->m_RunningVarRequest.m_VariableGroupId;
836 841 }
837 842
838 843 void VariableController::VariableControllerPrivate::updateVariables(QUuid varRequestId)
839 844 {
840 845 qCDebug(LOG_VariableController()) << "VariableControllerPrivate::updateVariables"
841 846 << QThread::currentThread()->objectName() << varRequestId;
842 847
843 848 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
844 849 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
845 850 qCWarning(LOG_VariableController())
846 851 << tr("Impossible to updateVariables of unknown variables") << varRequestId;
847 852 return;
848 853 }
849 854
850 855 auto &varIds = varGroupIdToVarIdsIt->second;
851 856 auto varIdsEnd = varIds.end();
852 857 bool processVariableUpdate = true;
853 858 qCDebug(LOG_VariableController()) << "VariableControllerPrivate::updateVariables"
854 859 << varRequestId << varIds.size();
855 860 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd) && processVariableUpdate;
856 861 ++varIdsIt) {
857 862 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
858 863 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
859 864 processVariableUpdate &= itVarHandler->second->m_CanUpdate;
860 865 }
861 866 }
862 867
863 868 if (processVariableUpdate) {
864 869 qCDebug(LOG_VariableController()) << "Final update OK for the var request" << varIds.size();
865 870 for (auto varIdsIt = varIds.begin(); varIdsIt != varIdsEnd; ++varIdsIt) {
866 871 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
867 872 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
868 873 if (auto var = findVariable(*varIdsIt)) {
869 874 auto &varRequest = itVarHandler->second->m_RunningVarRequest;
870 875 var->setRange(varRequest.m_RangeRequested);
871 876 var->setCacheRange(varRequest.m_CacheRangeRequested);
872 877 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
873 878 << varRequest.m_RangeRequested
874 879 << varRequest.m_CacheRangeRequested;
875 880 qCDebug(LOG_VariableController()) << tr("2: onDataProvided var points before")
876 881 << var->nbPoints()
877 882 << varRequest.m_DataSeries->nbPoints();
878 883 var->mergeDataSeries(varRequest.m_DataSeries);
879 884 qCDebug(LOG_VariableController()) << tr("3: onDataProvided var points after")
880 885 << var->nbPoints();
881 886
882 887 emit var->updated();
883 888 qCDebug(LOG_VariableController()) << tr("Update OK");
884 889 }
885 890 else {
886 891 qCCritical(LOG_VariableController())
887 892 << tr("Impossible to update data to a null variable");
888 893 }
889 894 }
890 895 }
891 896 updateVariableRequest(varRequestId);
892 897
893 898 // cleaning varRequestId
894 899 qCDebug(LOG_VariableController()) << tr("m_VarGroupIdToVarIds erase") << varRequestId;
895 900 m_VarGroupIdToVarIds.erase(varRequestId);
896 901 if (m_VarGroupIdToVarIds.empty()) {
897 902 emit q->acquisitionFinished();
898 903 }
899 904 }
900 905 }
901 906
902 907
903 908 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
904 909 {
905 910 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
906 911 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
907 912 qCCritical(LOG_VariableController()) << QObject::tr(
908 913 "Impossible to updateVariableRequest since varGroupdId isn't here anymore");
909 914
910 915 return;
911 916 }
912 917
913 918 auto &varIds = varGroupIdToVarIdsIt->second;
914 919 auto varIdsEnd = varIds.end();
915 920 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd); ++varIdsIt) {
916 921 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
917 922 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
918 923
919 924 auto varHandler = itVarHandler->second.get();
920 925 varHandler->m_CanUpdate = false;
921 926
922 927
923 928 switch (varHandler->m_State) {
924 929 case VariableRequestHandlerState::OFF: {
925 930 qCCritical(LOG_VariableController())
926 931 << QObject::tr("Impossible to update a variable with handler in OFF state");
927 932 } break;
928 933 case VariableRequestHandlerState::RUNNING: {
929 934 varHandler->m_State = VariableRequestHandlerState::OFF;
930 935 varHandler->m_RunningVarRequest = VariableRequest{};
931 936 break;
932 937 }
933 938 case VariableRequestHandlerState::PENDING: {
934 939 varHandler->m_State = VariableRequestHandlerState::RUNNING;
935 940 varHandler->m_RunningVarRequest = varHandler->m_PendingVarRequest;
936 941 varHandler->m_PendingVarRequest = VariableRequest{};
937 942 auto var = findVariable(itVarHandler->first);
938 943 executeVarRequest(var, varHandler->m_RunningVarRequest);
939 944 updateVariables(varHandler->m_RunningVarRequest.m_VariableGroupId);
940 945 break;
941 946 }
942 947 default:
943 948 qCCritical(LOG_VariableController())
944 949 << QObject::tr("Unknown VariableRequestHandlerState");
945 950 }
946 951 }
947 952 }
948 953 }
949 954
950 955
951 956 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
952 957 {
953 958 qCDebug(LOG_VariableController()) << tr("cancelVariableRequest") << varRequestId;
954 959
955 960 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
956 961 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
957 962 qCCritical(LOG_VariableController())
958 963 << tr("Impossible to cancelVariableRequest for unknown varGroupdId") << varRequestId;
959 964 return;
960 965 }
961 966
962 967 auto &varIds = varGroupIdToVarIdsIt->second;
963 968 auto varIdsEnd = varIds.end();
964 969 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd); ++varIdsIt) {
965 970 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
966 971 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
967 972
968 973 auto varHandler = itVarHandler->second.get();
969 974 varHandler->m_VarId = QUuid{};
970 975 switch (varHandler->m_State) {
971 976 case VariableRequestHandlerState::OFF: {
972 977 qCWarning(LOG_VariableController())
973 978 << QObject::tr("Impossible to cancel a variable with no running request");
974 979 break;
975 980 }
976 981 case VariableRequestHandlerState::RUNNING: {
977 982
978 983 if (varHandler->m_RunningVarRequest.m_VariableGroupId == varRequestId) {
979 984 auto var = findVariable(itVarHandler->first);
980 985 auto varProvider = m_VariableToProviderMap.at(var);
981 986 if (varProvider != nullptr) {
982 987 m_VariableAcquisitionWorker->abortProgressRequested(
983 988 itVarHandler->first);
984 989 }
985 990 m_VariableModel->setDataProgress(var, 0.0);
986 991 varHandler->m_CanUpdate = false;
987 992 varHandler->m_State = VariableRequestHandlerState::OFF;
988 993 varHandler->m_RunningVarRequest = VariableRequest{};
989 994 }
990 995 else {
991 996 // TODO: log Impossible to cancel the running variable request beacause its
992 997 // varRequestId isn't not the canceled one
993 998 }
994 999 break;
995 1000 }
996 1001 case VariableRequestHandlerState::PENDING: {
997 1002 if (varHandler->m_RunningVarRequest.m_VariableGroupId == varRequestId) {
998 1003 auto var = findVariable(itVarHandler->first);
999 1004 auto varProvider = m_VariableToProviderMap.at(var);
1000 1005 if (varProvider != nullptr) {
1001 1006 m_VariableAcquisitionWorker->abortProgressRequested(
1002 1007 itVarHandler->first);
1003 1008 }
1004 1009 m_VariableModel->setDataProgress(var, 0.0);
1005 1010 varHandler->m_CanUpdate = false;
1006 1011 varHandler->m_State = VariableRequestHandlerState::RUNNING;
1007 1012 varHandler->m_RunningVarRequest = varHandler->m_PendingVarRequest;
1008 1013 varHandler->m_PendingVarRequest = VariableRequest{};
1009 1014 executeVarRequest(var, varHandler->m_RunningVarRequest);
1010 1015 }
1011 1016 else if (varHandler->m_PendingVarRequest.m_VariableGroupId == varRequestId) {
1012 1017 varHandler->m_State = VariableRequestHandlerState::RUNNING;
1013 1018 varHandler->m_PendingVarRequest = VariableRequest{};
1014 1019 }
1015 1020 else {
1016 1021 // TODO: log Impossible to cancel the variable request beacause its
1017 1022 // varRequestId isn't not the canceled one
1018 1023 }
1019 1024 break;
1020 1025 }
1021 1026 default:
1022 1027 qCCritical(LOG_VariableController())
1023 1028 << QObject::tr("Unknown VariableRequestHandlerState");
1024 1029 }
1025 1030 }
1026 1031 }
1027 1032 qCDebug(LOG_VariableController()) << tr("cancelVariableRequest: erase") << varRequestId;
1028 1033 m_VarGroupIdToVarIds.erase(varRequestId);
1029 1034 if (m_VarGroupIdToVarIds.empty()) {
1030 1035 emit q->acquisitionFinished();
1031 1036 }
1032 1037 }
1033 1038
1034 1039 void VariableController::VariableControllerPrivate::executeVarRequest(std::shared_ptr<Variable> var,
1035 1040 VariableRequest &varRequest)
1036 1041 {
1037 1042 qCDebug(LOG_VariableController()) << tr("TORM: executeVarRequest");
1038 1043
1039 1044 auto varIdIt = m_VariableToIdentifierMap.find(var);
1040 1045 if (varIdIt == m_VariableToIdentifierMap.cend()) {
1041 1046 qCWarning(LOG_VariableController()) << tr(
1042 1047 "Can't execute request of a variable that is not registered (may has been deleted)");
1043 1048 return;
1044 1049 }
1045 1050
1046 1051 auto varId = varIdIt->second;
1047 1052
1048 1053 auto varCacheRange = var->cacheRange();
1049 1054 auto varCacheRangeRequested = varRequest.m_CacheRangeRequested;
1050 1055 auto notInCacheRangeList
1051 1056 = Variable::provideNotInCacheRangeList(varCacheRange, varCacheRangeRequested);
1052 1057 auto inCacheRangeList
1053 1058 = Variable::provideInCacheRangeList(varCacheRange, varCacheRangeRequested);
1054 1059
1055 1060 if (!notInCacheRangeList.empty()) {
1056 1061
1057 1062 auto varProvider = m_VariableToProviderMap.at(var);
1058 1063 if (varProvider != nullptr) {
1059 1064 qCDebug(LOG_VariableController()) << "executeVarRequest " << varRequest.m_RangeRequested
1060 1065 << varRequest.m_CacheRangeRequested;
1061 1066 m_VariableAcquisitionWorker->pushVariableRequest(
1062 1067 varRequest.m_VariableGroupId, varId, varRequest.m_RangeRequested,
1063 1068 varRequest.m_CacheRangeRequested,
1064 1069 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
1065 1070 varProvider);
1066 1071 }
1067 1072 else {
1068 1073 qCCritical(LOG_VariableController())
1069 1074 << "Impossible to provide data with a null provider";
1070 1075 }
1071 1076
1072 1077 if (!inCacheRangeList.empty()) {
1073 1078 emit q->updateVarDisplaying(var, inCacheRangeList.first());
1074 1079 }
1075 1080 }
1076 1081 else {
1077 1082 acceptVariableRequest(varId,
1078 1083 var->dataSeries()->subDataSeries(varRequest.m_CacheRangeRequested));
1079 1084 }
1080 1085 }
1081 1086
1087 bool VariableController::VariableControllerPrivate::hasPendingDownloads()
1088 {
1089 return !m_VarGroupIdToVarIds.empty();
1090 }
1091
1082 1092 template <typename VariableIterator>
1083 1093 void VariableController::VariableControllerPrivate::desynchronize(VariableIterator variableIt,
1084 1094 const QUuid &syncGroupId)
1085 1095 {
1086 1096 const auto &variable = variableIt->first;
1087 1097 const auto &variableId = variableIt->second;
1088 1098
1089 1099 // Gets synchronization group
1090 1100 auto groupIt = m_GroupIdToVariableSynchronizationGroupMap.find(syncGroupId);
1091 1101 if (groupIt == m_GroupIdToVariableSynchronizationGroupMap.cend()) {
1092 1102 qCCritical(LOG_VariableController())
1093 1103 << tr("Can't desynchronize variable %1: unknown synchronization group")
1094 1104 .arg(variable->name());
1095 1105 return;
1096 1106 }
1097 1107
1098 1108 // Removes variable from synchronization group
1099 1109 auto synchronizationGroup = groupIt->second;
1100 1110 synchronizationGroup->removeVariableId(variableId);
1101 1111
1102 1112 // Removes link between variable and synchronization group
1103 1113 m_VariableIdGroupIdMap.erase(variableId);
1104 1114 }
@@ -1,62 +1,73
1 1 include_directories(include)
2 2 FILE (GLOB_RECURSE amdaplugin_SRCS
3 3 include/*.h
4 4 src/*.cpp
5 5 resources/*.qrc
6 6 )
7 7
8 8
9 9 set(AMDA_server_type hybrid CACHE STRING "AMDA server type selected at CMake configure time")
10 10
11 11 set(AMDA_SERVER_TYPE "hybrid;amdatest;localhost" CACHE STRING
12 12 "List of possible for AMDA server type")
13 13
14 14 set_property(CACHE AMDA_server_type PROPERTY STRINGS ${AMDA_SERVER_TYPE})
15 15 add_definitions(-DSCIQLOP_AMDA_SERVER="${AMDA_server_type}")
16 16
17 17 add_definitions(-DQT_PLUGIN)
18 18 add_definitions(-DSCIQLOP_PLUGIN_JSON_FILE_PATH="${CMAKE_CURRENT_SOURCE_DIR}/resources/amda.json")
19 19 if(NOT BUILD_SHARED_LIBS)
20 20 add_definitions(-DQT_STATICPLUGIN)
21 21 endif()
22 22
23 23 add_library(amdaplugin ${amdaplugin_SRCS})
24 24 SET_TARGET_PROPERTIES(amdaplugin PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
25 25
26 26 target_link_libraries(amdaplugin PUBLIC sciqlopgui)
27 27
28 28 install(TARGETS amdaplugin
29 29 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/SciQlop
30 30 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/SciQlop
31 31 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
32 32
33 33 include(sciqlop_tests)
34 34
35 35 add_definitions(-DAMDA_TESTS_RESOURCES_DIR="${CMAKE_CURRENT_LIST_DIR}/tests-resources")
36 36
37 37 declare_test(TestAmdaParser TestAmdaParser tests/TestAmdaParser.cpp "amdaplugin;Qt5::Test")
38 38 declare_test(TestAmdaResultParser TestAmdaResultParser tests/TestAmdaResultParser.cpp "amdaplugin;Qt5::Test")
39 39 declare_test(TestAmdaAcquisition TestAmdaAcquisition tests/TestAmdaAcquisition.cpp "amdaplugin;Qt5::Test")
40 40 declare_test(TestAmdaFuzzing TestAmdaFuzzing "tests/TestAmdaFuzzing.cpp;tests/FuzzingValidators.cpp;tests/FuzzingUtils.cpp;tests/FuzzingOperations.cpp;tests/FuzzingDefs.cpp" "amdaplugin;Qt5::Test")
41 41
42 42 pybind11_add_module(pytestamda tests/PyTestAmdaWrapper.cpp)
43 43 target_link_libraries(pytestamda PUBLIC amdaplugin)
44 44
45 45 #pybind11_add_module(pytestamdalib SHARED tests/PyTestAmdaWrapper.cpp)
46 46 add_library(pytestamdalib tests/PyTestAmdaWrapper.cpp)
47 47 target_link_libraries(pytestamdalib PUBLIC pybind11::module)
48 48 target_link_libraries(pytestamdalib PUBLIC pybind11::embed)
49 49 target_link_libraries(pytestamdalib PUBLIC amdaplugin)
50 50
51 declare_test(TestPytestamda TestPytestamda "tests/PyTestAmdaWrapperExe.cpp" "amdaplugin;pytestamdalib")
52 target_compile_definitions(TestPytestamda PRIVATE -DPYTESTAMDA_SCRIPT="${CMAKE_CURRENT_LIST_DIR}/tests/pyamdatests.py")
51 declare_test(TestAmdaFileParserEmbed TestAmdaFileParserEmbed "tests/PyTestAmdaWrapperExe.cpp" "amdaplugin;pytestamdalib")
52 target_compile_definitions(TestAmdaFileParserEmbed PRIVATE -DPYTESTAMDA_SCRIPT="${CMAKE_CURRENT_LIST_DIR}/tests/TestAmdaFileParser.py")
53
54 declare_test(TestAmdaDownloadEmbed TestAmdaDownloadEmbed "tests/PyTestAmdaWrapperExe.cpp" "amdaplugin;pytestamdalib")
55 target_compile_definitions(TestAmdaDownloadEmbed PRIVATE -DPYTESTAMDA_SCRIPT="${CMAKE_CURRENT_LIST_DIR}/tests/TestAmdaDownload.py")
56
53 57
54 58 find_package(PythonInterp 3 REQUIRED)
55 59
56 add_test(NAME pyamdatests
60 add_test(NAME TestAmdaFileParser
61 COMMAND ${PYTHON_EXECUTABLE}
62 ${CMAKE_CURRENT_LIST_DIR}/tests/TestAmdaFileParser.py
63 TestAmdaFileParser)
64 set_tests_properties(TestAmdaFileParser PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR})
65
66
67 add_test(NAME TestAmdaDownload
57 68 COMMAND ${PYTHON_EXECUTABLE}
58 ${CMAKE_CURRENT_LIST_DIR}/tests/pyamdatests.py
59 pyamdatests)
69 ${CMAKE_CURRENT_LIST_DIR}/tests/TestAmdaDownload.py
70 TestAmdaDownload)
71 set_tests_properties(TestAmdaDownload PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR})
60 72
61 set_tests_properties(pyamdatests PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR})
62 73
@@ -1,164 +1,244
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the SciQLOP Software
3 3 -- Copyright (C) 2018, Plasma Physics Laboratory - CNRS
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 2 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------*/
19 19 /*-- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@member.fsf.org
21 21 ----------------------------------------------------------------------------*/
22 22 #include <string>
23 23 #include <sstream>
24 24 #include <memory>
25 25
26 26 #include <pybind11/pybind11.h>
27 27 #include <pybind11/operators.h>
28 28 #include <pybind11/embed.h>
29 #include <pybind11/numpy.h>
30 #include <pybind11/chrono.h>
29 31
30 32 #include <SqpApplication.h>
31 33 #include <Variable/VariableController.h>
32 34 #include <Time/TimeController.h>
33 35 #include <Data/SqpRange.h>
34 36 #include <Data/DataSeriesType.h>
35 37 #include <Common/DateUtils.h>
36 38 #include <Variable/Variable.h>
37 39 #include <Data/ScalarSeries.h>
40 #include <Data/VectorSeries.h>
38 41
39 42 #include <AmdaProvider.h>
40 43 #include <AmdaResultParser.h>
41 44
42 45 #include <QDate>
43 46 #include <QTime>
44 47 #include <QUuid>
45 48 #include <QString>
46 49 #include <QFile>
47 50
51 using namespace std::chrono;
48 52 namespace py = pybind11;
49 53
50 54 std::ostream &operator <<(std::ostream& os, const Unit& u)
51 55 {
52 56 os << "=========================" << std::endl
53 57 << "Unit:" << std::endl
54 << "Name:" << std::endl << u.m_Name.toStdString() << std::endl
55 << "Is_TimeUnit: " << u.m_TimeUnit << std::endl;
58 << " Name: " << u.m_Name.toStdString() << std::endl
59 << " Is_TimeUnit: " << u.m_TimeUnit << std::endl;
56 60 return os;
57 61 }
58 62
59 63 std::ostream &operator <<(std::ostream& os, const IDataSeries& ds)
60 64 {
61 65 os << "=========================" << std::endl
62 66 << "DataSerie:" << std::endl
63 << "Number of points:" << ds.nbPoints() << std::endl
64 << "X Axis Unit:" << std::endl << ds.xAxisUnit() << std::endl
65 << "Y Axis Unit:" << std::endl << ds.yAxisUnit()<< std::endl
66 << "Values Axis Unit:" << std::endl << ds.valuesUnit()<< std::endl;
67 << " Number of points:" << ds.nbPoints() << std::endl
68 << " X Axis Unit:" << std::endl << ds.xAxisUnit() << std::endl
69 << " Y Axis Unit:" << std::endl << ds.yAxisUnit()<< std::endl
70 << " Values Axis Unit:" << std::endl << ds.valuesUnit()<< std::endl;
71 return os;
72 }
73
74 std::ostream &operator <<(std::ostream& os, const SqpRange& range)
75 {
76 os << "=========================" << std::endl
77 << "SqpRange:" << std::endl
78 << " Start date: " << DateUtils::dateTime(range.m_TStart).toString().toStdString() << std::endl
79 << " Stop date: " << DateUtils::dateTime(range.m_TEnd).toString().toStdString() << std::endl;
80 return os;
81 }
82
83 std::ostream &operator <<(std::ostream& os, const Variable& variable)
84 {
85 os << "=========================" << std::endl
86 << "Variable:" << std::endl
87 << " Name: " << variable.name().toStdString() << std::endl
88 << " range: " << std::endl << variable.range() << std::endl
89 << " cache range: " << std::endl << variable.cacheRange() << std::endl;
67 90 return os;
68 91 }
69 92
70 93 template <typename T>
71 94 std::string __repr__(const T& obj)
72 95 {
73 96 std::stringstream sstr;
74 97 sstr << obj;
75 98 return sstr.str();
76 99 }
77 100
78 101
102
103
79 104 PYBIND11_MODULE(pytestamda, m){
105 int argc = 0;
106 char ** argv=nullptr;
107 SqpApplication::setOrganizationName("LPP");
108 SqpApplication::setOrganizationDomain("lpp.fr");
109 SqpApplication::setApplicationName("SciQLop");
110 static SqpApplication app(argc, argv);
111
80 112 m.doc() = "hello";
81 113
114 auto amda_provider = std::make_shared<AmdaProvider>();
115 m.def("amda_provider",[amda_provider](){return amda_provider;}, py::return_value_policy::copy);
116
82 117 py::enum_<DataSeriesType>(m, "DataSeriesType")
83 118 .value("SCALAR", DataSeriesType::SCALAR)
84 119 .value("SPECTROGRAM", DataSeriesType::SPECTROGRAM)
85 120 .value("UNKNOWN", DataSeriesType::UNKNOWN)
86 121 .export_values();
87 122
88 123 py::class_<Unit>(m, "Unit")
89 124 .def_readwrite("name", &Unit::m_Name)
90 125 .def_readwrite("time_unit", &Unit::m_TimeUnit)
91 126 .def(py::self == py::self)
92 127 .def(py::self != py::self)
93 128 .def("__repr__",__repr__<Unit>);
94 129
130 py::class_<DataSeriesIteratorValue>(m,"DataSeriesIteratorValue")
131 .def_property_readonly("x", &DataSeriesIteratorValue::x)
132 .def("value", py::overload_cast<>(&DataSeriesIteratorValue::value, py::const_))
133 .def("value", py::overload_cast<int>(&DataSeriesIteratorValue::value, py::const_));
134
95 135 py::class_<IDataSeries, std::shared_ptr<IDataSeries>>(m, "IDataSeries")
96 136 .def("nbPoints", &IDataSeries::nbPoints)
97 137 .def_property_readonly("xAxisUnit", &IDataSeries::xAxisUnit)
98 138 .def_property_readonly("yAxisUnit", &IDataSeries::yAxisUnit)
99 139 .def_property_readonly("valuesUnit", &IDataSeries::valuesUnit)
140 .def("__getitem__", [](IDataSeries& serie, int key) {
141 return *(serie.begin()+key);
142 }, py::is_operator())
143 .def("__len__", &IDataSeries::nbPoints)
144 .def("__iter__", [](IDataSeries& serie) {
145 return py::make_iterator(serie.begin(), serie.end());
146 }, py::keep_alive<0, 1>())
100 147 .def("__repr__",__repr__<IDataSeries>);
101 148
102
103
104 149 py::class_<ScalarSeries, std::shared_ptr<ScalarSeries>, IDataSeries>(m, "ScalarSeries")
105 150 .def("nbPoints", &ScalarSeries::nbPoints);
106 151
152 py::class_<VectorSeries, std::shared_ptr<VectorSeries>, IDataSeries>(m, "VectorSeries")
153 .def("nbPoints", &VectorSeries::nbPoints);
154
107 155 py::class_<QString>(m, "QString")
108 156 .def(py::init([](const std::string& value){return QString::fromStdString(value);}))
109 157 .def("__repr__", &QString::toStdString);
110 158
111 py::class_<VariableController>(m, "VariableController");
159 py::class_<VariableController>(m, "VariableController")
160 .def_static("createVariable",[](const QString &name,
161 std::shared_ptr<IDataProvider> provider){
162 return sqpApp->variableController().createVariable(name, {{"dataType", "vector"}, {"xml:id", "c1_b"}}, provider);
163 })
164 .def_static("hasPendingDownloads",
165 [](){return sqpApp->variableController().hasPendingDownloads();}
166 );
112 167
113 py::class_<AmdaProvider>(m, "AmdaProvider");
168 py::class_<TimeController>(m,"TimeController")
169 .def_static("setTime", [](SqpRange range){sqpApp->timeController().onTimeToUpdate(range);});
170
171 py::class_<IDataProvider, std::shared_ptr<IDataProvider>>(m, "IDataProvider");
172
173 py::class_<AmdaProvider, std::shared_ptr<AmdaProvider>, IDataProvider>(m, "AmdaProvider");
114 174
115 175 py::class_<AmdaResultParser>(m, "AmdaResultParser")
116 176 .def_static("readTxt", AmdaResultParser::readTxt)
117 177 .def("readScalarTxt", [](const QString& path){
118 178 return std::dynamic_pointer_cast<ScalarSeries>(AmdaResultParser::readTxt(path, DataSeriesType::SCALAR));
119 179 }, py::return_value_policy::copy);
120 180
121 py::class_<Variable>(m, "Variable")
181 py::class_<Variable,std::shared_ptr<Variable>>(m, "Variable")
122 182 .def(py::init<const QString&>())
123 183 .def_property("name", &Variable::name, &Variable::setName)
124 184 .def_property("range", &Variable::range, &Variable::setRange)
125 .def_property("cacheRange", &Variable::cacheRange, &Variable::setCacheRange);
185 .def_property("cacheRange", &Variable::cacheRange, &Variable::setCacheRange)
186 .def_property_readonly("nbPoints", &Variable::nbPoints)
187 .def_property_readonly("dataSeries", &Variable::dataSeries)
188 .def("__len__", [](Variable& variable) {
189 auto rng = variable.dataSeries()->xAxisRange(variable.range().m_TStart,variable.range().m_TEnd);
190 return std::distance(rng.first,rng.second);
191 })
192 .def("__iter__", [](Variable& variable) {
193 auto rng = variable.dataSeries()->xAxisRange(variable.range().m_TStart,variable.range().m_TEnd);
194 return py::make_iterator(rng.first, rng.second);
195 }, py::keep_alive<0, 1>())
196 .def("__getitem__", [](Variable& variable, int key) {
197 //insane and slow!
198 auto rng = variable.dataSeries()->xAxisRange(variable.range().m_TStart,variable.range().m_TEnd);
199 if(key<0)
200 return *(rng.second+key);
201 else
202 return *(rng.first+key);
203 })
204 .def("__repr__",__repr__<Variable>);
126 205
127 206 py::implicitly_convertible<std::string, QString>();
128 207
129 py::class_<TimeController>(m,"TimeController");
130 208
131 209 py::class_<SqpRange>(m,"SqpRange")
132 210 .def("fromDateTime", &SqpRange::fromDateTime, py::return_value_policy::move)
133 211 .def(py::init([](double start, double stop){return SqpRange{start, stop};}))
134 .def("__repr__", [](const SqpRange& range){
135 QString repr = QString("SqpRange:\n Start date: %1\n Stop date: %2")
136 .arg(DateUtils::dateTime(range.m_TStart).toString())
137 .arg(DateUtils::dateTime(range.m_TEnd).toString());
138 return repr.toStdString();
139 });
212 .def(py::init([](system_clock::time_point start, system_clock::time_point stop)
213 {
214 double start_ = 0.001 * duration_cast<milliseconds>(start.time_since_epoch()).count();
215 double stop_ = 0.001 * duration_cast<milliseconds>(stop.time_since_epoch()).count();
216 return SqpRange{start_, stop_};
217 }))
218 .def_property_readonly("start", [](const SqpRange& range){
219 return system_clock::from_time_t(range.m_TStart);
220 })
221 .def_property_readonly("stop", [](const SqpRange& range){
222 return system_clock::from_time_t(range.m_TEnd);
223 })
224 .def("__repr__", __repr__<SqpRange>);
140 225
141 226 py::class_<QUuid>(m,"QUuid");
142 227
143 228 py::class_<QDate>(m,"QDate")
144 229 .def(py::init<int,int,int>());
145 230
146 231 py::class_<QTime>(m,"QTime")
147 232 .def(py::init<int,int,int>());
148 233
149 234 }
150 235
151 236
152 int pytestamda_test(int argc, char** argv, const char* testScriptPath )
237 int pytestamda_test(const char* testScriptPath )
153 238 {
154 SqpApplication::setOrganizationName("LPP");
155 SqpApplication::setOrganizationDomain("lpp.fr");
156 SqpApplication::setApplicationName("SciQLop");
157 SqpApplication app(argc, argv);
158 239 py::scoped_interpreter guard{};
159
160 240 py::globals()["__file__"] = py::str(testScriptPath);
161 241 py::eval_file(testScriptPath);
162 242 return 0;
163 243 }
164 244
@@ -1,33 +1,33
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the SciQLOP Software
3 3 -- Copyright (C) 2018, Plasma Physics Laboratory - CNRS
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 2 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------*/
19 19 /*-- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@member.fsf.org
21 21 ----------------------------------------------------------------------------*/
22 22 #include <QString>
23 extern int pytestamda_test(int argc, char** argv, const char* testScriptPath );
23 extern int pytestamda_test(const char* testScriptPath );
24 24
25 25 int main(int argc, char** argv)
26 26 {
27 pytestamda_test(argc, argv, PYTESTAMDA_SCRIPT);
27 pytestamda_test(PYTESTAMDA_SCRIPT);
28 28 return 0;
29 29 }
30 30
31 31
32 32
33 33
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now