@@ -1,1 +1,1 | |||
|
1 | Subproject commit 698d7cfa01b05427c2377ce2799f1290b9eab2ca | |
|
1 | Subproject commit 483146a07a5ffeec8f0a2d61459e94d95e851572 |
@@ -3,9 +3,12 | |||
|
3 | 3 | |
|
4 | 4 | #include <Data/ScalarTimeSerie.h> |
|
5 | 5 | #include <Data/SpectrogramTimeSerie.h> |
|
6 | #include <Data/TimeSeriesUtils.h> | |
|
6 | 7 | #include <Data/VectorTimeSerie.h> |
|
7 | 8 | |
|
9 | #include <Common/cpp_utils.h> | |
|
8 | 10 | #include <Variable/Variable2.h> |
|
11 | #include <algorithm> | |
|
9 | 12 | |
|
10 | 13 | Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper") |
|
11 | 14 | |
@@ -321,31 +324,14 struct PlottablesUpdater<T, | |||
|
321 | 324 | { |
|
322 | 325 | static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot) |
|
323 | 326 | { |
|
324 | // TODO | |
|
325 | // double min, max; | |
|
326 | // std::tie(min, max) = dataSeries.yBounds(); | |
|
327 | ||
|
328 | // if (!std::isnan(min) && !std::isnan(max)) | |
|
329 | // { | |
|
330 | // plot.yAxis->setRange(QCPRange { min, max }); | |
|
331 | // } | |
|
332 | double minValue = 0., maxValue = 0.; | |
|
333 | if (auto serie = dynamic_cast<SpectrogramTimeSerie*>(&dataSeries)) | |
|
334 | { | |
|
335 | auto& yAxis = serie->axis(1); | |
|
336 | if (yAxis.size()) | |
|
337 | { | |
|
338 | minValue = *std::min_element(std::cbegin(yAxis), std::cend(yAxis)); | |
|
339 | maxValue = *std::max_element(std::cbegin(yAxis), std::cend(yAxis)); | |
|
340 | } | |
|
341 | } | |
|
327 | auto [minValue, maxValue] = dataSeries.axis_range(1); | |
|
328 | std::cout << "min=" << minValue << " max=" << maxValue << std::endl; | |
|
342 | 329 | plot.yAxis->setRange(QCPRange { minValue, maxValue }); |
|
343 | 330 | } |
|
344 | 331 | |
|
345 | 332 | static void updatePlottables( |
|
346 | 333 | T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes) |
|
347 | 334 | { |
|
348 | // TODO | |
|
349 | 335 | if (plottables.empty()) |
|
350 | 336 | { |
|
351 | 337 | qCDebug(LOG_VisualizationGraphHelper()) |
@@ -353,80 +339,82 struct PlottablesUpdater<T, | |||
|
353 | 339 | return; |
|
354 | 340 | } |
|
355 | 341 | |
|
356 | ||
|
357 | // // Gets the colormap to update (normally there is only one colormap) | |
|
342 | // Gets the colormap to update (normally there is only one colormap) | |
|
358 | 343 | Q_ASSERT(plottables.size() == 1); |
|
359 | 344 | auto colormap = dynamic_cast<QCPColorMap*>(plottables.at(0)); |
|
360 | 345 | Q_ASSERT(colormap != nullptr); |
|
346 | auto plot = colormap->parentPlot(); | |
|
347 | auto [minValue, maxValue] = dataSeries.axis_range(1); | |
|
348 | plot->yAxis->setRange(QCPRange { minValue, maxValue }); | |
|
361 | 349 | if (auto serie = dynamic_cast<SpectrogramTimeSerie*>(&dataSeries)) |
|
362 | 350 | { |
|
363 | colormap->data()->setSize(serie->shape()[0], serie->shape()[1]); | |
|
364 | if (serie->size(0)) | |
|
351 | if (serie->size(0) > 2) | |
|
365 | 352 | { |
|
353 | const auto& xAxis = serie->axis(0); | |
|
354 | auto yAxis = serie->axis(1); // copy for in place reverse order | |
|
355 | std::reverse(std::begin(yAxis), std::end(yAxis)); | |
|
356 | auto xAxisProperties = TimeSeriesUtils::axis_analysis<TimeSeriesUtils::IsLinear, | |
|
357 | TimeSeriesUtils::CheckMedian>(xAxis); | |
|
358 | auto yAxisProperties = TimeSeriesUtils::axis_analysis<TimeSeriesUtils::IsLog, | |
|
359 | TimeSeriesUtils::DontCheckMedian>(yAxis); | |
|
360 | ||
|
361 | int colormap_h_size = std::min(32000, | |
|
362 | static_cast<int>(xAxisProperties.range / xAxisProperties.max_resolution)); | |
|
363 | auto colormap_v_size | |
|
364 | = static_cast<int>(yAxisProperties.range / yAxisProperties.max_resolution); | |
|
365 | ||
|
366 | colormap->data()->setSize(colormap_h_size, colormap_v_size); | |
|
366 | 367 | colormap->data()->setRange( |
|
367 | 368 | QCPRange { serie->begin()->t(), (serie->end() - 1)->t() }, |
|
368 |
|
|
|
369 | for (int x_index = 0; x_index < serie->shape()[0]; x_index++) | |
|
369 | { minValue, maxValue }); | |
|
370 | ||
|
371 | std::vector<std::pair<int, int>> y_access_pattern; | |
|
372 | for (int y_index = 0, cel_index = 0; y_index < colormap_v_size; y_index++) | |
|
370 | 373 | { |
|
371 | auto pixline = (*serie)[x_index]; | |
|
372 | for (int y_index = 0; y_index < serie->shape()[1]; y_index++) | |
|
374 | double current_y = pow( | |
|
375 | 10., (yAxisProperties.max_resolution * y_index) + std::log10(minValue)); | |
|
376 | if (current_y > yAxis[cel_index]) | |
|
377 | cel_index++; | |
|
378 | y_access_pattern.push_back({ y_index, yAxis.size() - 1 - cel_index }); | |
|
379 | } | |
|
380 | ||
|
381 | auto line = serie->begin(); | |
|
382 | double current_time = xAxis[0]; | |
|
383 | int x_index = 0; | |
|
384 | ||
|
385 | while (x_index < colormap_h_size) | |
|
386 | { | |
|
387 | if (current_time > (line + 1)->t()) | |
|
373 | 388 | { |
|
374 |
|
|
|
375 | colormap->data()->setCell(x_index, y_index, value); | |
|
376 | if (std::isnan(value)) | |
|
389 | line++; | |
|
390 | } | |
|
391 | if ((current_time - xAxis[0]) | |
|
392 | > (x_index * xAxisProperties.range / colormap_h_size)) | |
|
393 | { | |
|
394 | x_index++; | |
|
395 | } | |
|
396 | if (line->t() <= (current_time + xAxisProperties.max_resolution)) | |
|
397 | { | |
|
398 | std::for_each(std::cbegin(y_access_pattern), std::cend(y_access_pattern), | |
|
399 | [&colormap, &line, x_index](const auto& acc) { | |
|
400 | colormap->data()->setCell(x_index, acc.first, (*line)[acc.second]); | |
|
401 | }); | |
|
402 | } | |
|
403 | else | |
|
404 | { | |
|
405 | for (int y_index = 0; y_index < colormap_v_size; y_index++) | |
|
377 | 406 | { |
|
378 |
colormap->data()->set |
|
|
407 | colormap->data()->setCell(x_index, y_index, std::nan("")); | |
|
379 | 408 | } |
|
380 | 409 | } |
|
410 | current_time += xAxisProperties.max_resolution; | |
|
381 | 411 | } |
|
382 | 412 | } |
|
383 | } | |
|
384 | // dataSeries.lockRead(); | |
|
385 | ||
|
386 | // // Processing spectrogram data for display in QCustomPlot | |
|
387 | // auto its = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd); | |
|
388 | ||
|
389 | // // Computes logarithmic y-axis resolution for the spectrogram | |
|
390 | // auto yData = its.first->y(); | |
|
391 | // auto yResolution = DataSeriesUtils::resolution(yData.begin(), yData.end(), true); | |
|
392 | ||
|
393 | // // Generates mesh for colormap | |
|
394 | // auto mesh = DataSeriesUtils::regularMesh(its.first, its.second, | |
|
395 | // DataSeriesUtils::Resolution { dataSeries.xResolution() }, yResolution); | |
|
396 | ||
|
397 | // dataSeries.unlock(); | |
|
398 | ||
|
399 | // colormap->data()->setSize(mesh.m_NbX, mesh.m_NbY); | |
|
400 | // if (!mesh.isEmpty()) | |
|
401 | // { | |
|
402 | // colormap->data()->setRange(QCPRange { mesh.m_XMin, mesh.xMax() }, | |
|
403 | // // y-axis range is converted to linear values | |
|
404 | // QCPRange { std::pow(10, mesh.m_YMin), std::pow(10, mesh.yMax()) }); | |
|
405 | ||
|
406 | // // Sets values | |
|
407 | // auto index = 0; | |
|
408 | // for (auto it = mesh.m_Data.begin(), end = mesh.m_Data.end(); it != end; ++it, | |
|
409 | // ++index) | |
|
410 | // { | |
|
411 | // auto xIndex = index % mesh.m_NbX; | |
|
412 | // auto yIndex = index / mesh.m_NbX; | |
|
413 | ||
|
414 | // colormap->data()->setCell(xIndex, yIndex, *it); | |
|
415 | ||
|
416 | // // Makes the NaN values to be transparent in the colormap | |
|
417 | // if (std::isnan(*it)) | |
|
418 | // { | |
|
419 | // colormap->data()->setAlpha(xIndex, yIndex, 0); | |
|
420 | // } | |
|
421 | // } | |
|
422 | // } | |
|
423 | ||
|
424 | // // Rescales axes | |
|
425 | auto plot = colormap->parentPlot(); | |
|
426 | setPlotYAxisRange(dataSeries, {}, *plot); | |
|
427 | if (rescaleAxes) | |
|
428 | { | |
|
429 | plot->rescaleAxes(); | |
|
413 | ||
|
414 | if (rescaleAxes) | |
|
415 | { | |
|
416 | plot->rescaleAxes(); | |
|
417 | } | |
|
430 | 418 | } |
|
431 | 419 | } |
|
432 | 420 | }; |
@@ -444,7 +432,8 struct IPlottablesHelper | |||
|
444 | 432 | }; |
|
445 | 433 | |
|
446 | 434 | /** |
|
447 |
* Default implementation of IPlottablesHelper, which takes data series to create/update |
|
|
435 | * Default implementation of IPlottablesHelper, which takes data series to create/update | |
|
436 | * plottables | |
|
448 | 437 | * @tparam T the data series' type |
|
449 | 438 | */ |
|
450 | 439 | template <typename T> |
@@ -10,9 +10,42 from spwc.amda import AMDA | |||
|
10 | 10 | |
|
11 | 11 | amda = AMDA() |
|
12 | 12 | |
|
13 | def get_sample(metadata,start,stop): | |
|
14 | ts_type = pysciqlopcore.ScalarTimeSerie | |
|
15 | default_ctor_args = 1 | |
|
13 | def amda_make_scalar(var=None): | |
|
14 | if var is None: | |
|
15 | return pysciqlopcore.ScalarTimeSerie(1) | |
|
16 | else: | |
|
17 | return pysciqlopcore.ScalarTimeSerie(var.time,var.data) | |
|
18 | ||
|
19 | def amda_make_vector(var=None): | |
|
20 | if var is None: | |
|
21 | return pysciqlopcore.VectorTimeSerie(1) | |
|
22 | else: | |
|
23 | return pysciqlopcore.VectorTimeSerie(var.time,var.data) | |
|
24 | ||
|
25 | def amda_make_multi_comp(var=None): | |
|
26 | if var is None: | |
|
27 | return pysciqlopcore.MultiComponentTimeSerie((0,2)) | |
|
28 | else: | |
|
29 | return pysciqlopcore.MultiComponentTimeSerie(var.time,var.data) | |
|
30 | ||
|
31 | def amda_make_spectro(var=None): | |
|
32 | if var is None: | |
|
33 | return pysciqlopcore.SpectrogramTimeSerie((0,2)) | |
|
34 | else: | |
|
35 | if "PARAMETER_TABLE_MIN_VALUES[1]" in var.meta: | |
|
36 | min_v = np.array([ float(v) for v in var.meta["PARAMETER_TABLE_MIN_VALUES[1]"].split(',') ]) | |
|
37 | max_v = np.array([ float(v) for v in var.meta["PARAMETER_TABLE_MAX_VALUES[1]"].split(',') ]) | |
|
38 | y = (max_v + min_v)/2. | |
|
39 | elif "PARAMETER_TABLE_MIN_VALUES[0]" in var.meta: | |
|
40 | min_v = np.array([ float(v) for v in var.meta["PARAMETER_TABLE_MIN_VALUES[0]"].split(',') ]) | |
|
41 | max_v = np.array([ float(v) for v in var.meta["PARAMETER_TABLE_MAX_VALUES[0]"].split(',') ]) | |
|
42 | y = (max_v + min_v)/2. | |
|
43 | else: | |
|
44 | y = np.logspace(1,3,var.data.shape[1])[::-1] | |
|
45 | return pysciqlopcore.SpectrogramTimeSerie(var.time,y,var.data) | |
|
46 | ||
|
47 | def amda_get_sample(metadata,start,stop): | |
|
48 | ts_type = amda_make_scalar | |
|
16 | 49 | try: |
|
17 | 50 | param_id = None |
|
18 | 51 | for key,value in metadata: |
@@ -20,18 +53,19 def get_sample(metadata,start,stop): | |||
|
20 | 53 | param_id = value |
|
21 | 54 | elif key == 'type': |
|
22 | 55 | if value == 'vector': |
|
23 |
ts_type = |
|
|
56 | ts_type = amda_make_vector | |
|
24 | 57 | elif value == 'multicomponent': |
|
25 |
ts_type = |
|
|
26 | default_ctor_args = (0,2) | |
|
58 | ts_type = amda_make_multi_comp | |
|
59 | elif value == 'spectrogram': | |
|
60 | ts_type = amda_make_spectro | |
|
27 | 61 | tstart=datetime.fromtimestamp(start, tz=timezone.utc) |
|
28 | 62 | tend=datetime.fromtimestamp(stop, tz=timezone.utc) |
|
29 | 63 | var = amda.get_parameter(start_time=tstart, stop_time=tend, parameter_id=param_id, method="REST") |
|
30 |
return ts_type(var |
|
|
64 | return ts_type(var) | |
|
31 | 65 | except Exception as e: |
|
32 | 66 | print(traceback.format_exc()) |
|
33 | 67 | print("Error in amda.py ",str(e)) |
|
34 |
return ts_type( |
|
|
68 | return ts_type() | |
|
35 | 69 | |
|
36 | 70 | |
|
37 | 71 | if len(amda.component) is 0: |
@@ -49,17 +83,16 for key,parameter in parameters.items(): | |||
|
49 | 83 | components = [component['name'] for component in parameter.get('components',[])] |
|
50 | 84 | metadata = [ (key,item) for key,item in parameter.items() if key is not 'components' ] |
|
51 | 85 | n_components = parameter.get('size',0) |
|
52 |
if n_components |
|
|
86 | if n_components == '3': | |
|
53 | 87 | metadata.append(("type","vector")) |
|
88 | elif parameter.get('display_type','')=="spectrogram": | |
|
89 | metadata.append(("type","spectrogram")) | |
|
54 | 90 | elif n_components !=0: |
|
55 | if parameter.get('display_type','')=="spectrogram": | |
|
56 | metadata.append(("type","spectrogram")) | |
|
57 | else: | |
|
58 | metadata.append(("type","multicomponent")) | |
|
91 | metadata.append(("type","multicomponent")) | |
|
59 | 92 | else: |
|
60 | 93 | metadata.append(("type","scalar")) |
|
61 | 94 | products.append( (path, components, metadata)) |
|
62 | 95 | |
|
63 | PythonProviders.register_product(products, get_sample) | |
|
96 | PythonProviders.register_product(products, amda_get_sample) | |
|
64 | 97 | |
|
65 | 98 |
@@ -64,7 +64,7 def get_data(metadata,start,stop): | |||
|
64 | 64 | ts_type = pysciqlopcore.MultiComponentTimeSerie |
|
65 | 65 | default_ctor_args = (0,2) |
|
66 | 66 | elif value == 'spectrogram': |
|
67 | ts_type = lambda t,values: pysciqlopcore.SpectrogramTimeSerie(t,np.logspace(1,3,32),values) | |
|
67 | ts_type = lambda t,values: pysciqlopcore.SpectrogramTimeSerie(t,np.logspace(1,3,32)[::-1],values) | |
|
68 | 68 | default_ctor_args = (0,2) |
|
69 | 69 | if key == 'cache' and value == 'true': |
|
70 | 70 | use_cache = True |
General Comments 0
You need to be logged in to leave comments.
Login now