|
@@
-9,6
+9,7
|
|
9
|
#include <Common/cpp_utils.h>
|
|
9
|
#include <Common/cpp_utils.h>
|
|
10
|
#include <Variable/Variable2.h>
|
|
10
|
#include <Variable/Variable2.h>
|
|
11
|
#include <algorithm>
|
|
11
|
#include <algorithm>
|
|
|
|
|
12
|
#include <cmath>
|
|
12
|
|
|
13
|
|
|
13
|
Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
|
|
14
|
Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
|
|
14
|
|
|
15
|
|
|
@@
-272,11
+273,10
struct PlottablesUpdater<T,
|
|
272
|
double minValue = 0., maxValue = 0.;
|
|
273
|
double minValue = 0., maxValue = 0.;
|
|
273
|
if (auto serie = dynamic_cast<MultiComponentTimeSerie*>(&dataSeries))
|
|
274
|
if (auto serie = dynamic_cast<MultiComponentTimeSerie*>(&dataSeries))
|
|
274
|
{
|
|
275
|
{
|
|
275
|
std::for_each(
|
|
276
|
std::for_each(std::begin(*serie), std::end(*serie), [&minValue, &maxValue](auto& v) {
|
|
276
|
std::begin(*serie), std::end(*serie), [&minValue, &maxValue](const auto& v) {
|
|
277
|
minValue = std::min(minValue, std::min_element(v.begin(), v.end())->v());
|
|
277
|
minValue = std::min(minValue, std::min_element(v.begin(), v.end())->v());
|
|
278
|
maxValue = std::max(maxValue, std::max_element(v.begin(), v.end())->v());
|
|
278
|
maxValue = std::max(maxValue, std::max_element(v.begin(), v.end())->v());
|
|
279
|
});
|
|
279
|
});
|
|
|
|
|
280
|
}
|
|
280
|
}
|
|
281
|
plot.yAxis->setRange(QCPRange { minValue, maxValue });
|
|
281
|
plot.yAxis->setRange(QCPRange { minValue, maxValue });
|
|
282
|
}
|
|
282
|
}
|
|
@@
-314,6
+314,46
struct PlottablesUpdater<T,
|
|
314
|
}
|
|
314
|
}
|
|
315
|
};
|
|
315
|
};
|
|
316
|
|
|
316
|
|
|
|
|
|
317
|
/*=============================================================*/
|
|
|
|
|
318
|
// TODO move this to dedicated srcs
|
|
|
|
|
319
|
/*=============================================================*/
|
|
|
|
|
320
|
struct ColomapProperties
|
|
|
|
|
321
|
{
|
|
|
|
|
322
|
int h_size_px;
|
|
|
|
|
323
|
int v_size_px;
|
|
|
|
|
324
|
double h_resolutuon;
|
|
|
|
|
325
|
double v_resolutuon;
|
|
|
|
|
326
|
};
|
|
|
|
|
327
|
|
|
|
|
|
328
|
inline ColomapProperties CMAxisAnalysis(const TimeSeriesUtils::axis_properties& xAxisProperties,
|
|
|
|
|
329
|
const TimeSeriesUtils::axis_properties& yAxisProperties)
|
|
|
|
|
330
|
{
|
|
|
|
|
331
|
int colormap_h_size
|
|
|
|
|
332
|
= std::min(32000, static_cast<int>(xAxisProperties.range / xAxisProperties.max_resolution));
|
|
|
|
|
333
|
int colormap_v_size = static_cast<int>(yAxisProperties.range / yAxisProperties.max_resolution);
|
|
|
|
|
334
|
double colormap_h_resolution = xAxisProperties.range / static_cast<double>(colormap_h_size);
|
|
|
|
|
335
|
double colormap_v_resolution = yAxisProperties.range / static_cast<double>(colormap_v_size);
|
|
|
|
|
336
|
return ColomapProperties { colormap_h_size, colormap_v_size, colormap_h_resolution,
|
|
|
|
|
337
|
colormap_v_resolution };
|
|
|
|
|
338
|
}
|
|
|
|
|
339
|
|
|
|
|
|
340
|
inline std::vector<std::pair<int, int>> build_access_pattern(const std::vector<double>& axis,
|
|
|
|
|
341
|
const TimeSeriesUtils::axis_properties& axisProperties,
|
|
|
|
|
342
|
const ColomapProperties& colormap_properties)
|
|
|
|
|
343
|
{
|
|
|
|
|
344
|
std::vector<std::pair<int, int>> access_pattern;
|
|
|
|
|
345
|
for (int index = 0, cel_index = 0; index < colormap_properties.v_size_px; index++)
|
|
|
|
|
346
|
{
|
|
|
|
|
347
|
double current_y = pow(10., (axisProperties.max_resolution * index) + axisProperties.min);
|
|
|
|
|
348
|
if (current_y > axis[cel_index])
|
|
|
|
|
349
|
cel_index++;
|
|
|
|
|
350
|
access_pattern.push_back({ index, axis.size() - 1 - cel_index });
|
|
|
|
|
351
|
}
|
|
|
|
|
352
|
return access_pattern;
|
|
|
|
|
353
|
}
|
|
|
|
|
354
|
|
|
|
|
|
355
|
/*=============================================================*/
|
|
|
|
|
356
|
|
|
317
|
/**
|
|
357
|
/**
|
|
318
|
* Specialization of PlottablesUpdater for spectrograms
|
|
358
|
* Specialization of PlottablesUpdater for spectrograms
|
|
319
|
* @sa SpectrogramSeries
|
|
359
|
* @sa SpectrogramSeries
|
|
@@
-354,57
+394,75
struct PlottablesUpdater<T,
|
|
354
|
auto yAxis = serie->axis(1); // copy for in place reverse order
|
|
394
|
auto yAxis = serie->axis(1); // copy for in place reverse order
|
|
355
|
std::reverse(std::begin(yAxis), std::end(yAxis));
|
|
395
|
std::reverse(std::begin(yAxis), std::end(yAxis));
|
|
356
|
auto xAxisProperties = TimeSeriesUtils::axis_analysis<TimeSeriesUtils::IsLinear,
|
|
396
|
auto xAxisProperties = TimeSeriesUtils::axis_analysis<TimeSeriesUtils::IsLinear,
|
|
357
|
TimeSeriesUtils::CheckMedian>(xAxis);
|
|
397
|
TimeSeriesUtils::CheckMedian>(xAxis, serie->min_sampling);
|
|
358
|
auto yAxisProperties = TimeSeriesUtils::axis_analysis<TimeSeriesUtils::IsLog,
|
|
398
|
auto yAxisProperties = TimeSeriesUtils::axis_analysis<TimeSeriesUtils::IsLog,
|
|
359
|
TimeSeriesUtils::DontCheckMedian>(yAxis);
|
|
399
|
TimeSeriesUtils::DontCheckMedian>(yAxis);
|
|
|
|
|
400
|
auto colormap_properties = CMAxisAnalysis(xAxisProperties, yAxisProperties);
|
|
360
|
|
|
401
|
|
|
361
|
int colormap_h_size = std::min(32000,
|
|
402
|
colormap->data()->setSize(
|
|
362
|
static_cast<int>(xAxisProperties.range / xAxisProperties.max_resolution));
|
|
403
|
colormap_properties.h_size_px, colormap_properties.v_size_px);
|
|
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);
|
|
|
|
|
367
|
colormap->data()->setRange(
|
|
404
|
colormap->data()->setRange(
|
|
368
|
QCPRange { serie->begin()->t(), (serie->end() - 1)->t() },
|
|
405
|
QCPRange { xAxisProperties.min, xAxisProperties.max }, { minValue, maxValue });
|
|
369
|
{ minValue, maxValue });
|
|
|
|
|
370
|
|
|
406
|
|
|
371
|
std::vector<std::pair<int, int>> y_access_pattern;
|
|
407
|
auto y_access_pattern
|
|
372
|
for (int y_index = 0, cel_index = 0; y_index < colormap_v_size; y_index++)
|
|
408
|
= build_access_pattern(yAxis, yAxisProperties, colormap_properties);
|
|
373
|
{
|
|
|
|
|
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
|
|
|
409
|
|
|
381
|
auto line = serie->begin();
|
|
410
|
auto line = serie->begin();
|
|
382
|
double current_time = xAxis[0];
|
|
411
|
auto next_line = line + 1;
|
|
|
|
|
412
|
double current_time = xAxisProperties.min;
|
|
383
|
int x_index = 0;
|
|
413
|
int x_index = 0;
|
|
384
|
|
|
414
|
auto x_min_resolution
|
|
385
|
while (x_index < colormap_h_size)
|
|
415
|
= std::fmin(2. * serie->max_sampling, xAxisProperties.max_resolution * 100.);
|
|
|
|
|
416
|
std::vector<double> line_values(serie->size(1));
|
|
|
|
|
417
|
double avg_coef = 0.;
|
|
|
|
|
418
|
bool has_nan = false;
|
|
|
|
|
419
|
while (x_index < colormap_properties.h_size_px)
|
|
386
|
{
|
|
420
|
{
|
|
387
|
if (current_time > (line + 1)->t())
|
|
421
|
if (next_line != std::end(*serie) and current_time >= next_line->t())
|
|
388
|
{
|
|
422
|
{
|
|
389
|
line++;
|
|
423
|
line = next_line;
|
|
|
|
|
424
|
next_line++;
|
|
390
|
}
|
|
425
|
}
|
|
391
|
if ((current_time - xAxis[0])
|
|
426
|
if ((current_time - xAxisProperties.min)
|
|
392
|
> (x_index * xAxisProperties.range / colormap_h_size))
|
|
427
|
> (static_cast<double>(x_index + 1) * colormap_properties.h_resolutuon))
|
|
393
|
{
|
|
428
|
{
|
|
|
|
|
429
|
std::for_each(std::cbegin(y_access_pattern), std::cend(y_access_pattern),
|
|
|
|
|
430
|
[&colormap, &line_values, x_index, avg_coef](const auto& acc) {
|
|
|
|
|
431
|
colormap->data()->setCell(
|
|
|
|
|
432
|
x_index, acc.first, line_values[acc.second] / avg_coef);
|
|
|
|
|
433
|
});
|
|
|
|
|
434
|
std::fill(std::begin(line_values), std::end(line_values), 0.);
|
|
394
|
x_index++;
|
|
435
|
x_index++;
|
|
|
|
|
436
|
avg_coef = 0.;
|
|
|
|
|
437
|
has_nan = false;
|
|
395
|
}
|
|
438
|
}
|
|
396
|
if (line->t() <= (current_time + xAxisProperties.max_resolution))
|
|
439
|
if (line->t() + x_min_resolution > current_time)
|
|
397
|
{
|
|
440
|
{
|
|
398
|
std::for_each(std::cbegin(y_access_pattern), std::cend(y_access_pattern),
|
|
441
|
if (has_nan)
|
|
399
|
[&colormap, &line, x_index](const auto& acc) {
|
|
442
|
{
|
|
400
|
colormap->data()->setCell(x_index, acc.first, (*line)[acc.second]);
|
|
443
|
std::transform(std::begin(*line), std::end(*line),
|
|
401
|
});
|
|
444
|
std::begin(line_values),
|
|
|
|
|
445
|
[](const auto& input) { return input.v(); });
|
|
|
|
|
446
|
has_nan = false;
|
|
|
|
|
447
|
}
|
|
|
|
|
448
|
else
|
|
|
|
|
449
|
{
|
|
|
|
|
450
|
std::transform(std::begin(*line), std::end(*line),
|
|
|
|
|
451
|
std::cbegin(line_values), std::begin(line_values),
|
|
|
|
|
452
|
[](const auto& input, auto output) { return input.v() + output; });
|
|
|
|
|
453
|
}
|
|
|
|
|
454
|
avg_coef += 1.;
|
|
402
|
}
|
|
455
|
}
|
|
403
|
else
|
|
456
|
else
|
|
404
|
{
|
|
457
|
{
|
|
405
|
for (int y_index = 0; y_index < colormap_v_size; y_index++)
|
|
458
|
for (int y_index = 0; y_index < colormap_properties.v_size_px; y_index++)
|
|
406
|
{
|
|
459
|
{
|
|
407
|
colormap->data()->setCell(x_index, y_index, std::nan(""));
|
|
460
|
if (avg_coef > 0.)
|
|
|
|
|
461
|
{
|
|
|
|
|
462
|
has_nan = true;
|
|
|
|
|
463
|
std::fill(
|
|
|
|
|
464
|
std::begin(line_values), std::end(line_values), std::nan(""));
|
|
|
|
|
465
|
}
|
|
408
|
}
|
|
466
|
}
|
|
409
|
}
|
|
467
|
}
|
|
410
|
current_time += xAxisProperties.max_resolution;
|
|
468
|
current_time += xAxisProperties.max_resolution;
|