##// END OF EJS Templates
WIP Multicomponent TS...
jeandet -
r1431:8eb0c93bfd80
parent child
Show More
@@ -0,0 +1,17
1 import sys
2 sys.path.append("/home/jeandet/Documents/prog/build-SciQLop-Desktop-Debug/core")
3 import PythonProviders
4 import pysciqlopcore
5 import numpy as np
6
7 someglobal = 1
8
9 def test(name,start,stop):
10 x = np.arange(start, stop)
11 y = np.cos(x/10.)
12 return pysciqlopcore.ScalarTimeSerie(x,y)
13
14
15 #PythonProviders.register_product(["/folder1/folder2/product1", "/folder1/folder3/product2", "/folder4/folder5/product3"],test)
16
17
@@ -1,1 +1,1
1 Subproject commit b9379e008899fce30581fbbf2b3fefd6fe36cee2
1 Subproject commit 41273d8529cddde1c8b6bcea03d71d9cd1a18c06
@@ -1,445 +1,519
1 1 #include "Visualization/VisualizationGraphHelper.h"
2 2 #include "Visualization/qcustomplot.h"
3 3
4 4 #include <Data/ScalarTimeSerie.h>
5 5 #include <Data/SpectrogramTimeSerie.h>
6 6 #include <Data/VectorTimeSerie.h>
7 7
8 8 #include <Variable/Variable2.h>
9 9
10 10 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
11 11
12 12 namespace
13 13 {
14 14
15 15 class SqpDataContainer : public QCPGraphDataContainer
16 16 {
17 17 public:
18 18 void appendGraphData(const QCPGraphData& data) { mData.append(data); }
19 19 };
20 20
21 21 /**
22 22 * Struct used to create plottables, depending on the type of the data series from which to create
23 23 * them
24 24 * @tparam T the data series' type
25 25 * @remarks Default implementation can't create plottables
26 26 */
27 27 template <typename T, typename Enabled = void>
28 28 struct PlottablesCreator
29 29 {
30 static PlottablesMap createPlottables(QCustomPlot&) { return {}; }
30 static PlottablesMap createPlottables(QCustomPlot&, const std::shared_ptr<T>& dataSeries)
31 {
32 return {};
33 }
31 34 };
32 35
33 36 PlottablesMap createGraphs(QCustomPlot& plot, int nbGraphs)
34 37 {
35 38 PlottablesMap result {};
36 39
37 40 // Creates {nbGraphs} QCPGraph to add to the plot
38 41 for (auto i = 0; i < nbGraphs; ++i)
39 42 {
40 43 auto graph = plot.addGraph();
41 44 result.insert({ i, graph });
42 45 }
43 46
44 47 plot.replot();
45 48
46 49 return result;
47 50 }
48 51
49 52 /**
50 53 * Specialization of PlottablesCreator for scalars
51 54 * @sa ScalarSeries
52 55 */
53 56 template <typename T>
54 57 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<ScalarTimeSerie, T>::value>>
55 58 {
56 static PlottablesMap createPlottables(QCustomPlot& plot) { return createGraphs(plot, 1); }
59 static PlottablesMap createPlottables(QCustomPlot& plot, const std::shared_ptr<T>& dataSeries)
60 {
61 return createGraphs(plot, 1);
62 }
57 63 };
58 64
59 65 /**
60 66 * Specialization of PlottablesCreator for vectors
61 67 * @sa VectorSeries
62 68 */
63 69 template <typename T>
64 70 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<VectorTimeSerie, T>::value>>
65 71 {
66 static PlottablesMap createPlottables(QCustomPlot& plot) { return createGraphs(plot, 3); }
72 static PlottablesMap createPlottables(QCustomPlot& plot, const std::shared_ptr<T>& dataSeries)
73 {
74 return createGraphs(plot, 3);
75 }
76 };
77
78 /**
79 * Specialization of PlottablesCreator for MultiComponentTimeSeries
80 * @sa VectorSeries
81 */
82 template <typename T>
83 struct PlottablesCreator<T,
84 typename std::enable_if_t<std::is_base_of<MultiComponentTimeSerie, T>::value>>
85 {
86 static PlottablesMap createPlottables(QCustomPlot& plot, const std::shared_ptr<T>& dataSeries)
87 {
88 return createGraphs(plot, dataSeries->size(1));
89 }
67 90 };
68 91
69 92 /**
70 93 * Specialization of PlottablesCreator for spectrograms
71 94 * @sa SpectrogramSeries
72 95 */
73 96 template <typename T>
74 97 struct PlottablesCreator<T,
75 98 typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>>
76 99 {
77 static PlottablesMap createPlottables(QCustomPlot& plot)
100 static PlottablesMap createPlottables(QCustomPlot& plot, const std::shared_ptr<T>& dataSeries)
78 101 {
79 102 PlottablesMap result {};
80 103 result.insert({ 0, new QCPColorMap { plot.xAxis, plot.yAxis } });
81 104
82 105 plot.replot();
83 106
84 107 return result;
85 108 }
86 109 };
87 110
88 111 /**
89 112 * Struct used to update plottables, depending on the type of the data series from which to update
90 113 * them
91 114 * @tparam T the data series' type
92 115 * @remarks Default implementation can't update plottables
93 116 */
94 117 template <typename T, typename Enabled = void>
95 118 struct PlottablesUpdater
96 119 {
97 120 static void setPlotYAxisRange(T&, const DateTimeRange&, QCustomPlot&)
98 121 {
99 122 qCCritical(LOG_VisualizationGraphHelper())
100 123 << QObject::tr("Can't set plot y-axis range: unmanaged data series type");
101 124 }
102 125
103 126 static void updatePlottables(T&, PlottablesMap&, const DateTimeRange&, bool)
104 127 {
105 128 qCCritical(LOG_VisualizationGraphHelper())
106 129 << QObject::tr("Can't update plottables: unmanaged data series type");
107 130 }
108 131 };
109 132
110 133 /**
111 134 * Specialization of PlottablesUpdater for scalars and vectors
112 135 * @sa ScalarSeries
113 136 * @sa VectorSeries
114 137 */
115 138 template <typename T>
116 139 struct PlottablesUpdater<T, typename std::enable_if_t<std::is_base_of<ScalarTimeSerie, T>::value>>
117 140 {
118 141 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
119 142 {
120 143 auto minValue = 0., maxValue = 0.;
121 144 if (auto serie = dynamic_cast<ScalarTimeSerie*>(&dataSeries))
122 145 {
123 146 if (serie->size())
124 147 {
125 148 maxValue = (*std::max_element(std::begin(*serie), std::end(*serie))).v();
126 149 minValue = (*std::min_element(std::begin(*serie), std::end(*serie))).v();
127 150 }
128 151 }
129 152 plot.yAxis->setRange(QCPRange { minValue, maxValue });
130 153 }
131 154
132 155 static void updatePlottables(
133 156 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
134 157 {
135 158
136 159 // For each plottable to update, resets its data
137 160 for (const auto& plottable : plottables)
138 161 {
139 162 if (auto graph = dynamic_cast<QCPGraph*>(plottable.second))
140 163 {
141 164 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
142 165 if (auto serie = dynamic_cast<ScalarTimeSerie*>(&dataSeries))
143 166 {
144 167 std::for_each(
145 168 std::begin(*serie), std::end(*serie), [&dataContainer](const auto& value) {
146 169 dataContainer->appendGraphData(QCPGraphData(value.t(), value.v()));
147 170 });
148 171 }
149 172 graph->setData(dataContainer);
150 173 }
151 174 }
152 175
153 176 if (!plottables.empty())
154 177 {
155 178 auto plot = plottables.begin()->second->parentPlot();
156 179
157 180 if (rescaleAxes)
158 181 {
159 182 plot->rescaleAxes();
160 183 }
161 184 }
162 185 }
163 186 };
164 187
165 188
166 189 template <typename T>
167 190 struct PlottablesUpdater<T, typename std::enable_if_t<std::is_base_of<VectorTimeSerie, T>::value>>
168 191 {
169 192 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
170 193 {
171 194 double minValue = 0., maxValue = 0.;
172 195 if (auto serie = dynamic_cast<VectorTimeSerie*>(&dataSeries))
173 196 {
174 197 std::for_each(
175 198 std::begin(*serie), std::end(*serie), [&minValue, &maxValue](const auto& v) {
176 199 minValue = std::min({ minValue, v.v().x, v.v().y, v.v().z });
177 200 maxValue = std::max({ maxValue, v.v().x, v.v().y, v.v().z });
178 201 });
179 202 }
180 203
181 204 plot.yAxis->setRange(QCPRange { minValue, maxValue });
182 205 }
183 206
184 207 static void updatePlottables(
185 208 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
186 209 {
187 210
188 211 // For each plottable to update, resets its data
189 212 for (const auto& plottable : plottables)
190 213 {
191 214 if (auto graph = dynamic_cast<QCPGraph*>(plottable.second))
192 215 {
193 216 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
194 217 if (auto serie = dynamic_cast<VectorTimeSerie*>(&dataSeries))
195 218 {
196 219 switch (plottable.first)
197 220 {
198 221 case 0:
199 222 std::for_each(std::begin(*serie), std::end(*serie),
200 223 [&dataContainer](const auto& value) {
201 224 dataContainer->appendGraphData(
202 225 QCPGraphData(value.t(), value.v().x));
203 226 });
204 227 break;
205 228 case 1:
206 229 std::for_each(std::begin(*serie), std::end(*serie),
207 230 [&dataContainer](const auto& value) {
208 231 dataContainer->appendGraphData(
209 232 QCPGraphData(value.t(), value.v().y));
210 233 });
211 234 break;
212 235 case 2:
213 236 std::for_each(std::begin(*serie), std::end(*serie),
214 237 [&dataContainer](const auto& value) {
215 238 dataContainer->appendGraphData(
216 239 QCPGraphData(value.t(), value.v().z));
217 240 });
218 241 break;
219 242 default:
220 243 break;
221 244 }
222 245 }
223 246 graph->setData(dataContainer);
224 247 }
225 248 }
226 249
227 250 if (!plottables.empty())
228 251 {
229 252 auto plot = plottables.begin()->second->parentPlot();
230 253
231 254 if (rescaleAxes)
232 255 {
233 256 plot->rescaleAxes();
234 257 }
235 258 }
236 259 }
237 260 };
238 261
262
263 template <typename T>
264 struct PlottablesUpdater<T, typename std::enable_if_t<std::is_base_of<MultiComponentTimeSerie, T>::value>>
265 {
266 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
267 {
268 double minValue = 0., maxValue = 0.;
269 if (auto serie = dynamic_cast<MultiComponentTimeSerie*>(&dataSeries))
270 {
271 // TODO
272 // std::for_each(
273 // std::begin(*serie), std::end(*serie), [&minValue, &maxValue](const auto& v) {
274 // minValue = std::min({ minValue, std::min_element(v.begin(),v.end()) });
275 // maxValue = std::max({ maxValue, std::max_element(v.begin(),v.end()) });
276 // });
277 }
278
279 plot.yAxis->setRange(QCPRange { minValue, maxValue });
280 }
281
282 static void updatePlottables(
283 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
284 {
285 for (const auto& plottable : plottables)
286 {
287 if (auto graph = dynamic_cast<QCPGraph*>(plottable.second))
288 {
289 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
290 if (auto serie = dynamic_cast<MultiComponentTimeSerie*>(&dataSeries))
291 {
292 // TODO
293 }
294 graph->setData(dataContainer);
295 }
296 }
297
298 if (!plottables.empty())
299 {
300 auto plot = plottables.begin()->second->parentPlot();
301
302 if (rescaleAxes)
303 {
304 plot->rescaleAxes();
305 }
306 }
307 }
308 };
309
239 310 /**
240 311 * Specialization of PlottablesUpdater for spectrograms
241 312 * @sa SpectrogramSeries
242 313 */
243 314 template <typename T>
244 315 struct PlottablesUpdater<T,
245 316 typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>>
246 317 {
247 318 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
248 319 {
249 320 // TODO
250 321 // double min, max;
251 322 // std::tie(min, max) = dataSeries.yBounds();
252 323
253 324 // if (!std::isnan(min) && !std::isnan(max))
254 325 // {
255 326 // plot.yAxis->setRange(QCPRange { min, max });
256 327 // }
257 328 }
258 329
259 330 static void updatePlottables(
260 331 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
261 332 {
262 333 // TODO
263 334 // if (plottables.empty())
264 335 // {
265 336 // qCDebug(LOG_VisualizationGraphHelper())
266 337 // << QObject::tr("Can't update spectrogram: no colormap has been
267 338 // associated");
268 339 // return;
269 340 // }
270 341
271 342 // // Gets the colormap to update (normally there is only one colormap)
272 343 // Q_ASSERT(plottables.size() == 1);
273 344 // auto colormap = dynamic_cast<QCPColorMap*>(plottables.at(0));
274 345 // Q_ASSERT(colormap != nullptr);
275 346
276 347 // dataSeries.lockRead();
277 348
278 349 // // Processing spectrogram data for display in QCustomPlot
279 350 // auto its = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd);
280 351
281 352 // // Computes logarithmic y-axis resolution for the spectrogram
282 353 // auto yData = its.first->y();
283 354 // auto yResolution = DataSeriesUtils::resolution(yData.begin(), yData.end(), true);
284 355
285 356 // // Generates mesh for colormap
286 357 // auto mesh = DataSeriesUtils::regularMesh(its.first, its.second,
287 358 // DataSeriesUtils::Resolution { dataSeries.xResolution() }, yResolution);
288 359
289 360 // dataSeries.unlock();
290 361
291 362 // colormap->data()->setSize(mesh.m_NbX, mesh.m_NbY);
292 363 // if (!mesh.isEmpty())
293 364 // {
294 365 // colormap->data()->setRange(QCPRange { mesh.m_XMin, mesh.xMax() },
295 366 // // y-axis range is converted to linear values
296 367 // QCPRange { std::pow(10, mesh.m_YMin), std::pow(10, mesh.yMax()) });
297 368
298 369 // // Sets values
299 370 // auto index = 0;
300 371 // for (auto it = mesh.m_Data.begin(), end = mesh.m_Data.end(); it != end; ++it,
301 372 // ++index)
302 373 // {
303 374 // auto xIndex = index % mesh.m_NbX;
304 375 // auto yIndex = index / mesh.m_NbX;
305 376
306 377 // colormap->data()->setCell(xIndex, yIndex, *it);
307 378
308 379 // // Makes the NaN values to be transparent in the colormap
309 380 // if (std::isnan(*it))
310 381 // {
311 382 // colormap->data()->setAlpha(xIndex, yIndex, 0);
312 383 // }
313 384 // }
314 385 // }
315 386
316 387 // // Rescales axes
317 388 // auto plot = colormap->parentPlot();
318 389
319 390 // if (rescaleAxes)
320 391 // {
321 392 // plot->rescaleAxes();
322 393 // }
323 394 }
324 395 };
325 396
326 397 /**
327 398 * Helper used to create/update plottables
328 399 */
329 400 struct IPlottablesHelper
330 401 {
331 402 virtual ~IPlottablesHelper() noexcept = default;
332 403 virtual PlottablesMap create(QCustomPlot& plot) const = 0;
333 404 virtual void setYAxisRange(const DateTimeRange& xAxisRange, QCustomPlot& plot) const = 0;
334 405 virtual void update(
335 406 PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes = false) const = 0;
336 407 };
337 408
338 409 /**
339 410 * Default implementation of IPlottablesHelper, which takes data series to create/update plottables
340 411 * @tparam T the data series' type
341 412 */
342 413 template <typename T>
343 414 struct PlottablesHelper : public IPlottablesHelper
344 415 {
345 416 explicit PlottablesHelper(std::shared_ptr<T> dataSeries) : m_DataSeries { dataSeries } {}
346 417
347 418 PlottablesMap create(QCustomPlot& plot) const override
348 419 {
349 return PlottablesCreator<T>::createPlottables(plot);
420 return PlottablesCreator<T>::createPlottables(plot, m_DataSeries);
350 421 }
351 422
352 423 void update(
353 424 PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes) const override
354 425 {
355 426 if (m_DataSeries)
356 427 {
357 428 PlottablesUpdater<T>::updatePlottables(*m_DataSeries, plottables, range, rescaleAxes);
358 429 }
359 430 else
360 431 {
361 432 qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
362 433 "between the type of data series and the "
363 434 "type supposed";
364 435 }
365 436 }
366 437
367 438 void setYAxisRange(const DateTimeRange& xAxisRange, QCustomPlot& plot) const override
368 439 {
369 440 if (m_DataSeries)
370 441 {
371 442 PlottablesUpdater<T>::setPlotYAxisRange(*m_DataSeries, xAxisRange, plot);
372 443 }
373 444 else
374 445 {
375 446 qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
376 447 "between the type of data series and the "
377 448 "type supposed";
378 449 }
379 450 }
380 451
381 452 std::shared_ptr<T> m_DataSeries;
382 453 };
383 454
384 455 /// Creates IPlottablesHelper according to the type of data series a variable holds
385 456 std::unique_ptr<IPlottablesHelper> createHelper(std::shared_ptr<Variable2> variable) noexcept
386 457 {
387 458 switch (variable->type())
388 459 {
389 460 case DataSeriesType::SCALAR:
390 461 return std::make_unique<PlottablesHelper<ScalarTimeSerie>>(
391 462 std::dynamic_pointer_cast<ScalarTimeSerie>(variable->data()));
392 463 case DataSeriesType::SPECTROGRAM:
393 464 return std::make_unique<PlottablesHelper<SpectrogramTimeSerie>>(
394 465 std::dynamic_pointer_cast<SpectrogramTimeSerie>(variable->data()));
395 466 case DataSeriesType::VECTOR:
396 467 return std::make_unique<PlottablesHelper<VectorTimeSerie>>(
397 468 std::dynamic_pointer_cast<VectorTimeSerie>(variable->data()));
469 case DataSeriesType::MULTICOMPONENT:
470 return std::make_unique<PlottablesHelper<MultiComponentTimeSerie>>(
471 std::dynamic_pointer_cast<MultiComponentTimeSerie>(variable->data()));
398 472 default:
399 473 // Creates default helper
400 474 break;
401 475 }
402 476
403 477 return std::make_unique<PlottablesHelper<TimeSeries::ITimeSerie>>(nullptr);
404 478 }
405 479
406 480 } // namespace
407 481
408 482 PlottablesMap VisualizationGraphHelper::create(
409 483 std::shared_ptr<Variable2> variable, QCustomPlot& plot) noexcept
410 484 {
411 485 if (variable)
412 486 {
413 487 auto helper = createHelper(variable);
414 488 auto plottables = helper->create(plot);
415 489 return plottables;
416 490 }
417 491 else
418 492 {
419 493 qCDebug(LOG_VisualizationGraphHelper())
420 494 << QObject::tr("Can't create graph plottables : the variable is null");
421 495 return PlottablesMap {};
422 496 }
423 497 }
424 498
425 499 void VisualizationGraphHelper::setYAxisRange(
426 500 std::shared_ptr<Variable2> variable, QCustomPlot& plot) noexcept
427 501 {
428 502 if (variable)
429 503 {
430 504 auto helper = createHelper(variable);
431 505 helper->setYAxisRange(variable->range(), plot);
432 506 }
433 507 else
434 508 {
435 509 qCDebug(LOG_VisualizationGraphHelper())
436 510 << QObject::tr("Can't set y-axis range of plot: the variable is null");
437 511 }
438 512 }
439 513
440 514 void VisualizationGraphHelper::updateData(
441 515 PlottablesMap& plottables, std::shared_ptr<Variable2> variable, const DateTimeRange& dateTime)
442 516 {
443 517 auto helper = createHelper(variable);
444 518 helper->update(plottables, dateTime);
445 519 }
@@ -1,60 +1,61
1 1 import sys
2 2 sys.path.append("/home/jeandet/Documents/prog/build-SciQLop-Desktop-Debug/core")
3 import traceback
3 4 import os
4 import datetime
5 from datetime import datetime, timedelta, timezone
5 6 import PythonProviders
6 7 import pysciqlopcore
7 8 import numpy as np
8 9 import pandas as pds
9 10 import requests
10 11 from spwc.amda import AMDA
11 12
12 13 amda = AMDA()
13 14
14 15 def get_sample(metadata,start,stop):
15 16 ts_type = pysciqlopcore.ScalarTimeSerie
16 17 try:
17 18 param_id = None
18 19 for key,value in metadata:
19 20 if key == 'xml:id':
20 21 param_id = value
21 22 elif key == 'type':
22 23 if value == 'vector':
23 24 ts_type = pysciqlopcore.VectorTimeSerie
24 tstart=datetime.datetime.fromtimestamp(start)
25 tend=datetime.datetime.fromtimestamp(stop)
25 tstart=datetime.datetime.utcfromtimestamp(start)
26 tend=datetime.datetime.utcfromtimestamp(stop)
26 27 df = amda.get_parameter(start_time=tstart, stop_time=tend, parameter_id=param_id)
27 t = np.array([d.timestamp()-7200 for d in df.index])
28 #t = np.array([d.timestamp()-7200 for d in df.index])
29 t = np.array([d.timestamp() for d in df.index])
28 30 values = df.values
29 print(len(t))
30 print(len(values))
31 31 return ts_type(t,values)
32 32 return ts_type(1)
33 33 except Exception as e:
34 print(traceback.format_exc())
34 35 print("Error in amda.py ",str(e))
35 36 return ts_type(1)
36 37
37 38
38 39 if len(amda.component) is 0:
39 40 amda.update_inventory()
40 41 parameters = amda.parameter.copy()
41 42 for name,component in amda.component.items():
42 43 if 'components' in parameters[component['parameter']]:
43 44 parameters[component['parameter']]['components'].append(component)
44 45 else:
45 46 parameters[component['parameter']]['components']=[component]
46 47
47 48 products = []
48 49 for key,parameter in parameters.items():
49 50 path = f"/AMDA/{parameter['mission']}/{parameter['instrument']}/{parameter['dataset']}/{parameter['name']}"
50 51 components = [component['name'] for component in parameter.get('components',[])]
51 52 metadata = [ (key,item) for key,item in parameter.items() if key is not 'components' ]
52 53 if parameter.get('size',0) is '3':
53 54 metadata.append(("type","vector"))
54 55 else:
55 56 metadata.append(("type","scalar"))
56 57 products.append( (path, components, metadata))
57 58
58 59 PythonProviders.register_product(products, get_sample)
59 60
60 61
@@ -1,44 +1,29
1 1 import sys
2 2 sys.path.append("/home/jeandet/Documents/prog/build-SciQLop-Desktop-Debug/core")
3 3 import os
4 4 import datetime
5 5 import PythonProviders
6 6 import pysciqlopcore
7 7 import numpy as np
8 8 import pandas as pds
9 9 import requests
10 10 from spwc.cdaweb import cdaweb
11 11
12 12 cd = cdaweb()
13 13
14 14 def get_sample(name,start,stop):
15 15 try:
16 tstart=datetime.datetime.fromtimestamp(start).strftime('%Y%m%dT%H%M%SZ')
17 tend=datetime.datetime.fromtimestamp(stop).strftime('%Y%m%dT%H%M%SZ')
18 req_url=f"https://cdaweb.gsfc.nasa.gov/WS/cdasr/1/dataviews/sp_phys/datasets/MMS4_SCM_SRVY_L2_SCSRVY/data/{tstart},{tend}/mms4_scm_acb_gse_scsrvy_srvy_l2?format=csv"
19 resp = requests.get(req_url,headers={"Accept":"application/json"})
20 csv_url = resp.json()['FileDescription'][0]['Name']
21 df = pds.read_csv(csv_url,comment='#',index_col=0, infer_datetime_format=True,parse_dates=True)
22 t = np.array([d.timestamp()-7200 for d in df.index])
23 values = df.values
24 return pysciqlopcore.VectorTimeSerie(t,values)
25 except Exception as e:
26 print("fuck ",str(e))
27 return pysciqlopcore.VectorTimeSerie(1)
28
29 def get_sample(name,start,stop):
30 try:
31 16 tstart=datetime.datetime.fromtimestamp(start)
32 17 tend=datetime.datetime.fromtimestamp(stop)
33 18 df = cd.get_variable(dataset="MMS2_SCM_SRVY_L2_SCSRVY",variable="mms2_scm_acb_gse_scsrvy_srvy_l2",tstart=tstart,tend=tend)
34 19 t = np.array([d.timestamp()-7200 for d in df.index])
35 20 values = df.values
36 21 return pysciqlopcore.VectorTimeSerie(t,values)
37 22 except Exception as e:
38 23 print("fuck ",str(e))
39 24 return pysciqlopcore.VectorTimeSerie(1)
40 25
41 26
42 27 PythonProviders.register_product([("/CDA/mms4_scm_acb_gse_scsrvy_srvy_l2",[],[("type","vector")])],get_sample)
43 28
44 29
@@ -1,151 +1,150
1 1 #include "python_providers.h"
2 2 #include <Data/DataProviderParameters.h>
3 3 #include <Data/DateTimeRange.h>
4 4 #include <Data/IDataProvider.h>
5 5 #include <Data/ScalarTimeSerie.h>
6 6 #include <Data/SpectrogramTimeSerie.h>
7 7 #include <Data/TimeSeriesUtils.h>
8 8 #include <Data/VectorTimeSerie.h>
9 9 #include <DataSource/DataSourceController.h>
10 10 #include <DataSource/DataSourceItem.h>
11 11 #include <DataSource/DataSourceItemAction.h>
12 12 #include <QDir>
13 13 #include <QStandardPaths>
14 14 #include <QStringList>
15 15 #include <SqpApplication.h>
16 16 #include <TimeSeries.h>
17 17 #include <functional>
18 18 #include <iostream>
19 19
20 20
21 21 const auto DATA_SOURCE_NAME = QStringLiteral("PythonProviders");
22 22
23 23 class PythonProvider : public IDataProvider
24 24 {
25 25 public:
26 PythonProvider(PythonInterpreter::provider_funct_t f) : _pythonFunction { f } {}
26 explicit PythonProvider(PythonInterpreter::provider_funct_t f) : _pythonFunction { f } {}
27 27
28 28 PythonProvider(const PythonProvider& other) : _pythonFunction { other._pythonFunction } {}
29 29
30 30 std::shared_ptr<IDataProvider> clone() const override
31 31 {
32 32 return std::make_shared<PythonProvider>(*this);
33 33 }
34 34 virtual TimeSeries::ITimeSerie* getData(const DataProviderParameters& parameters) override
35 35 {
36 36 auto product = parameters.m_Data.value("PRODUCT", "").toString().toStdString();
37 37 auto range = parameters.m_Range;
38 38 std::vector<std::tuple<std::string, std::string>> metadata;
39 39 std::transform(parameters.m_Data.constKeyValueBegin(), parameters.m_Data.constKeyValueEnd(),
40 40 std::back_inserter(metadata), [](const auto& item) {
41 41 return std::tuple<std::string, std::string> { item.first.toStdString(),
42 42 item.second.toString().toStdString() };
43 43 });
44 44 auto result = _pythonFunction(metadata, range.m_TStart, range.m_TEnd);
45 45 return TimeSeriesUtils::copy(result);
46 46 }
47 47
48 48 private:
49 49 PythonInterpreter::provider_funct_t _pythonFunction;
50 50 };
51 51
52 52
53 53 void PythonProviders::initialize()
54 54 {
55 55 _interpreter.add_register_callback(
56 56 [this](const std::vector<PythonInterpreter::product_t>& product_list,
57 57 PythonInterpreter::provider_funct_t f) { this->register_product(product_list, f); });
58 58
59 59 for (const auto& path : QStandardPaths::standardLocations(QStandardPaths::AppLocalDataLocation))
60 60 {
61 61 auto dir = QDir(path + "/python");
62 62 if (dir.exists())
63 63 {
64 64 for (const auto& entry :
65 65 dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name))
66 66 {
67 67 if (entry.isFile() && entry.suffix() == "py")
68 68 {
69 69 _interpreter.eval(entry.absoluteFilePath().toStdString());
70 70 }
71 71 }
72 72 }
73 73 }
74 74 _interpreter.release();
75 75 }
76 76
77 77 PythonProviders::~PythonProviders() {}
78 78
79 79 std::unique_ptr<DataSourceItem> make_folder_item(const QString& name)
80 80 {
81 81 return std::make_unique<DataSourceItem>(DataSourceItemType::NODE, name);
82 82 }
83 83
84 84 template <typename T>
85 85 DataSourceItem* make_path_items(
86 86 const T& path_list_begin, const T& path_list_end, DataSourceItem* root)
87 87 {
88 88 std::for_each(path_list_begin, path_list_end, [&root](const auto& folder_name) mutable {
89 89 auto folder_ptr = root->findItem(folder_name);
90 90 if (folder_ptr == nullptr)
91 91 {
92 92 auto folder = make_folder_item(folder_name);
93 93 folder_ptr = folder.get();
94 94 root->appendChild(std::move(folder));
95 95 }
96 96 root = folder_ptr;
97 97 });
98 98 return root;
99 99 }
100 100
101 101 std::unique_ptr<DataSourceItem> make_product_item(
102 102 const QVariantHash& metaData, const QUuid& dataSourceUid)
103 103 {
104 104 auto result = std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT, metaData);
105 105
106 106 // Adds plugin name to product metadata
107 107 result->setData(DataSourceItem::PLUGIN_DATA_KEY, DATA_SOURCE_NAME);
108 108 result->setData(DataSourceItem::ID_DATA_KEY, metaData.value(DataSourceItem::NAME_DATA_KEY));
109 109
110 110 auto productName = metaData.value(DataSourceItem::NAME_DATA_KEY).toString();
111 111
112 112 // Add action to load product from DataSourceController
113 113 result->addAction(
114 114 std::make_unique<DataSourceItemAction>(QObject::tr("Load %1 product").arg(productName),
115 115 [productName, dataSourceUid](DataSourceItem& item) {
116 116 if (auto app = sqpApp)
117 117 {
118 118 app->dataSourceController().loadProductItem(dataSourceUid, item);
119 119 }
120 120 }));
121 121
122 122 return result;
123 123 }
124 124
125 125 void PythonProviders::register_product(
126 126 const std::vector<PythonInterpreter::product_t>& product_list,
127 127 PythonInterpreter::provider_funct_t f)
128 128 {
129 129 auto& dataSourceController = sqpApp->dataSourceController();
130 130 QString test = DATA_SOURCE_NAME + QUuid::createUuid().toString();
131 131 auto id = dataSourceController.registerDataSource(test);
132 132 auto root = make_folder_item(test);
133 133 std::for_each(std::cbegin(product_list), std::cend(product_list),
134 134 [id, f, root = root.get()](const auto& product) {
135 135 const auto& path = std::get<0>(product);
136 136 auto path_list = QString::fromStdString(path).split('/');
137 137 auto name = *(std::cend(path_list) - 1);
138 138 auto path_item
139 139 = make_path_items(std::cbegin(path_list), std::cend(path_list) - 1, root);
140 140 QVariantHash metaData { { DataSourceItem::NAME_DATA_KEY, name } };
141 141 std::for_each(std::cbegin(std::get<2>(product)), std::cend(std::get<2>(product)),
142 142 [&metaData](const auto& mdata) {
143 143 metaData[QString::fromStdString(mdata.first)]
144 144 = QString::fromStdString(mdata.second);
145 145 });
146 146 path_item->appendChild(make_product_item(metaData, id));
147 147 });
148 148 dataSourceController.setDataSourceItem(id, std::move(root));
149 149 dataSourceController.setDataProvider(id, std::make_unique<PythonProvider>(f));
150 std::cout << "Gone there" << std::endl;
151 150 }
General Comments 0
You need to be logged in to leave comments. Login now