|
@@
-337,21
+337,112
inline ColomapProperties CMAxisAnalysis(const TimeSeriesUtils::axis_properties&
|
|
337
|
colormap_v_resolution };
|
|
337
|
colormap_v_resolution };
|
|
338
|
}
|
|
338
|
}
|
|
339
|
|
|
339
|
|
|
|
|
|
340
|
|
|
|
|
|
341
|
template <bool condition, typename T, typename U>
|
|
|
|
|
342
|
std::enable_if_t<condition, T> constexpr conditional_v(T first, U second)
|
|
|
|
|
343
|
{
|
|
|
|
|
344
|
return first;
|
|
|
|
|
345
|
}
|
|
|
|
|
346
|
|
|
|
|
|
347
|
template <bool condition, typename T, typename U>
|
|
|
|
|
348
|
std::enable_if_t<!condition, U> constexpr conditional_v(T first, U second)
|
|
|
|
|
349
|
{
|
|
|
|
|
350
|
return second;
|
|
|
|
|
351
|
}
|
|
|
|
|
352
|
|
|
|
|
|
353
|
template <bool reversedAxis = true, bool reversedData = true>
|
|
340
|
inline std::vector<std::pair<int, int>> build_access_pattern(const std::vector<double>& axis,
|
|
354
|
inline std::vector<std::pair<int, int>> build_access_pattern(const std::vector<double>& axis,
|
|
341
|
const TimeSeriesUtils::axis_properties& axisProperties,
|
|
355
|
const TimeSeriesUtils::axis_properties& axisProperties,
|
|
342
|
const ColomapProperties& colormap_properties)
|
|
356
|
const ColomapProperties& colormap_properties)
|
|
343
|
{
|
|
357
|
{
|
|
344
|
std::vector<std::pair<int, int>> access_pattern;
|
|
358
|
std::vector<std::pair<int, int>> access_pattern;
|
|
345
|
for (int index = 0, cel_index = axis.size() - 1; index < colormap_properties.v_size_px; index++)
|
|
359
|
for (int index = 0, axis_index = conditional_v<reversedAxis>(axis.size() - 1, 0),
|
|
|
|
|
360
|
data_index = conditional_v<reversedData>(axis.size() - 1, 0);
|
|
|
|
|
361
|
index < colormap_properties.v_size_px; index++)
|
|
346
|
{
|
|
362
|
{
|
|
347
|
double current_y = pow(10., (axisProperties.max_resolution * index) + axisProperties.min);
|
|
363
|
double current_y = (axisProperties.max_resolution * index) + axisProperties.min;
|
|
348
|
if (current_y > axis[cel_index])
|
|
364
|
if (current_y > axis[axis_index])
|
|
349
|
cel_index--;
|
|
365
|
{
|
|
350
|
access_pattern.push_back({ index, cel_index });
|
|
366
|
conditional_v<reversedAxis>(
|
|
|
|
|
367
|
[&axis_index]() { axis_index--; }, [&axis_index]() { axis_index++; })();
|
|
|
|
|
368
|
conditional_v<reversedData>(
|
|
|
|
|
369
|
[&data_index]() { data_index--; }, [&data_index]() { data_index++; })();
|
|
|
|
|
370
|
}
|
|
|
|
|
371
|
access_pattern.push_back({ index, data_index });
|
|
351
|
}
|
|
372
|
}
|
|
352
|
return access_pattern;
|
|
373
|
return access_pattern;
|
|
353
|
}
|
|
374
|
}
|
|
354
|
|
|
375
|
|
|
|
|
|
376
|
inline bool is_log(const std::vector<double>& axis)
|
|
|
|
|
377
|
{
|
|
|
|
|
378
|
if (axis.size() > 2)
|
|
|
|
|
379
|
{
|
|
|
|
|
380
|
auto first = axis.front(), midle = axis[axis.size() / 2], last = axis.back();
|
|
|
|
|
381
|
auto error_linear = (midle - (last + first) / 2) / midle;
|
|
|
|
|
382
|
first = log10(first);
|
|
|
|
|
383
|
midle = log10(midle);
|
|
|
|
|
384
|
last = log10(last);
|
|
|
|
|
385
|
auto error_log = (midle - (last + first) / 2) / midle;
|
|
|
|
|
386
|
return error_log < error_linear;
|
|
|
|
|
387
|
}
|
|
|
|
|
388
|
return false;
|
|
|
|
|
389
|
}
|
|
|
|
|
390
|
|
|
|
|
|
391
|
template <typename accessPattern_t, typename colomapT, typename axProp_t, typename cmProp_t>
|
|
|
|
|
392
|
inline void fill_data(SpectrogramTimeSerie* serie, colomapT* colormap,
|
|
|
|
|
393
|
const accessPattern_t& y_access_pattern, const axProp_t& xAxisProperties,
|
|
|
|
|
394
|
const cmProp_t& colormap_properties)
|
|
|
|
|
395
|
{
|
|
|
|
|
396
|
auto line = serie->begin();
|
|
|
|
|
397
|
auto next_line = line + 1;
|
|
|
|
|
398
|
double current_time = xAxisProperties.min;
|
|
|
|
|
399
|
int x_index = 0;
|
|
|
|
|
400
|
auto x_min_resolution
|
|
|
|
|
401
|
= std::fmin(2. * serie->max_sampling, xAxisProperties.max_resolution * 100.);
|
|
|
|
|
402
|
std::vector<double> line_values(serie->size(1));
|
|
|
|
|
403
|
double avg_coef = 0.;
|
|
|
|
|
404
|
while (x_index < colormap_properties.h_size_px)
|
|
|
|
|
405
|
{
|
|
|
|
|
406
|
if (next_line != std::end(*serie) and current_time >= next_line->t())
|
|
|
|
|
407
|
{
|
|
|
|
|
408
|
line = next_line;
|
|
|
|
|
409
|
next_line++;
|
|
|
|
|
410
|
}
|
|
|
|
|
411
|
if ((current_time - xAxisProperties.min)
|
|
|
|
|
412
|
> (static_cast<double>(x_index + 1) * colormap_properties.h_resolutuon))
|
|
|
|
|
413
|
{
|
|
|
|
|
414
|
std::for_each(std::cbegin(y_access_pattern), std::cend(y_access_pattern),
|
|
|
|
|
415
|
[&colormap, &line_values, x_index, avg_coef](const auto& acc) {
|
|
|
|
|
416
|
colormap->data()->setCell(
|
|
|
|
|
417
|
x_index, acc.first, line_values[acc.second] / avg_coef);
|
|
|
|
|
418
|
});
|
|
|
|
|
419
|
std::fill(std::begin(line_values), std::end(line_values), 0.);
|
|
|
|
|
420
|
x_index++;
|
|
|
|
|
421
|
avg_coef = 0.;
|
|
|
|
|
422
|
}
|
|
|
|
|
423
|
if (line->t() + x_min_resolution > current_time)
|
|
|
|
|
424
|
{
|
|
|
|
|
425
|
{
|
|
|
|
|
426
|
std::transform(std::begin(*line), std::end(*line), std::cbegin(line_values),
|
|
|
|
|
427
|
std::begin(line_values),
|
|
|
|
|
428
|
[](const auto& input, auto output) { return input.v() + output; });
|
|
|
|
|
429
|
}
|
|
|
|
|
430
|
avg_coef += 1.;
|
|
|
|
|
431
|
}
|
|
|
|
|
432
|
else
|
|
|
|
|
433
|
{
|
|
|
|
|
434
|
for (int y_index = 0; y_index < colormap_properties.v_size_px; y_index++)
|
|
|
|
|
435
|
{
|
|
|
|
|
436
|
if (avg_coef > 0.)
|
|
|
|
|
437
|
{
|
|
|
|
|
438
|
std::fill(std::begin(line_values), std::end(line_values), 0);
|
|
|
|
|
439
|
}
|
|
|
|
|
440
|
}
|
|
|
|
|
441
|
}
|
|
|
|
|
442
|
current_time += xAxisProperties.max_resolution * 0.9;
|
|
|
|
|
443
|
}
|
|
|
|
|
444
|
}
|
|
|
|
|
445
|
|
|
355
|
/*=============================================================*/
|
|
446
|
/*=============================================================*/
|
|
356
|
|
|
447
|
|
|
357
|
/**
|
|
448
|
/**
|
|
@@
-365,7
+456,6
struct PlottablesUpdater<T,
|
|
365
|
static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
|
|
456
|
static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
|
|
366
|
{
|
|
457
|
{
|
|
367
|
auto [minValue, maxValue] = dataSeries.axis_range(1);
|
|
458
|
auto [minValue, maxValue] = dataSeries.axis_range(1);
|
|
368
|
std::cout << "min=" << minValue << " max=" << maxValue << std::endl;
|
|
|
|
|
369
|
plot.yAxis->setRange(QCPRange { minValue, maxValue });
|
|
459
|
plot.yAxis->setRange(QCPRange { minValue, maxValue });
|
|
370
|
}
|
|
460
|
}
|
|
371
|
|
|
461
|
|
|
@@
-390,8
+480,13
struct PlottablesUpdater<T,
|
|
390
|
{
|
|
480
|
{
|
|
391
|
if (serie->size(0) > 2)
|
|
481
|
if (serie->size(0) > 2)
|
|
392
|
{
|
|
482
|
{
|
|
|
|
|
483
|
if (serie->y_is_log)
|
|
|
|
|
484
|
colormap->setDataScaleType(QCPAxis::stLogarithmic);
|
|
|
|
|
485
|
else
|
|
|
|
|
486
|
colormap->setDataScaleType(QCPAxis::stLinear);
|
|
393
|
const auto& xAxis = serie->axis(0);
|
|
487
|
const auto& xAxis = serie->axis(0);
|
|
394
|
auto yAxis = serie->axis(1); // copy for in place reverse order
|
|
488
|
auto yAxis = serie->axis(1); // copy for in place reverse order
|
|
|
|
|
489
|
auto y_is_log = is_log(yAxis);
|
|
395
|
std::reverse(std::begin(yAxis), std::end(yAxis));
|
|
490
|
std::reverse(std::begin(yAxis), std::end(yAxis));
|
|
396
|
auto xAxisProperties = TimeSeriesUtils::axis_analysis<TimeSeriesUtils::IsLinear,
|
|
491
|
auto xAxisProperties = TimeSeriesUtils::axis_analysis<TimeSeriesUtils::IsLinear,
|
|
397
|
TimeSeriesUtils::CheckMedian>(xAxis, serie->min_sampling);
|
|
492
|
TimeSeriesUtils::CheckMedian>(xAxis, serie->min_sampling);
|
|
@@
-404,57
+499,9
struct PlottablesUpdater<T,
|
|
404
|
colormap->data()->setRange(
|
|
499
|
colormap->data()->setRange(
|
|
405
|
QCPRange { xAxisProperties.min, xAxisProperties.max }, { minValue, maxValue });
|
|
500
|
QCPRange { xAxisProperties.min, xAxisProperties.max }, { minValue, maxValue });
|
|
406
|
|
|
501
|
|
|
407
|
auto y_access_pattern
|
|
502
|
auto y_access_pattern = build_access_pattern<false, true>(
|
|
408
|
= build_access_pattern(serie->axis(1), yAxisProperties, colormap_properties);
|
|
503
|
yAxis, yAxisProperties, colormap_properties);
|
|
409
|
|
|
504
|
fill_data(serie, colormap, y_access_pattern, xAxisProperties, colormap_properties);
|
|
410
|
auto line = serie->begin();
|
|
|
|
|
411
|
auto next_line = line + 1;
|
|
|
|
|
412
|
double current_time = xAxisProperties.min;
|
|
|
|
|
413
|
int x_index = 0;
|
|
|
|
|
414
|
auto x_min_resolution
|
|
|
|
|
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
|
while (x_index < colormap_properties.h_size_px)
|
|
|
|
|
419
|
{
|
|
|
|
|
420
|
if (next_line != std::end(*serie) and current_time >= next_line->t())
|
|
|
|
|
421
|
{
|
|
|
|
|
422
|
line = next_line;
|
|
|
|
|
423
|
next_line++;
|
|
|
|
|
424
|
}
|
|
|
|
|
425
|
if ((current_time - xAxisProperties.min)
|
|
|
|
|
426
|
> (static_cast<double>(x_index + 1) * colormap_properties.h_resolutuon))
|
|
|
|
|
427
|
{
|
|
|
|
|
428
|
std::for_each(std::cbegin(y_access_pattern), std::cend(y_access_pattern),
|
|
|
|
|
429
|
[&colormap, &line_values, x_index, avg_coef](const auto& acc) {
|
|
|
|
|
430
|
colormap->data()->setCell(
|
|
|
|
|
431
|
x_index, acc.first, line_values[acc.second] / avg_coef);
|
|
|
|
|
432
|
});
|
|
|
|
|
433
|
std::fill(std::begin(line_values), std::end(line_values), 0.);
|
|
|
|
|
434
|
x_index++;
|
|
|
|
|
435
|
avg_coef = 0.;
|
|
|
|
|
436
|
}
|
|
|
|
|
437
|
if (line->t() + x_min_resolution > current_time)
|
|
|
|
|
438
|
{
|
|
|
|
|
439
|
{
|
|
|
|
|
440
|
std::transform(std::begin(*line), std::end(*line),
|
|
|
|
|
441
|
std::cbegin(line_values), std::begin(line_values),
|
|
|
|
|
442
|
[](const auto& input, auto output) { return input.v() + output; });
|
|
|
|
|
443
|
}
|
|
|
|
|
444
|
avg_coef += 1.;
|
|
|
|
|
445
|
}
|
|
|
|
|
446
|
else
|
|
|
|
|
447
|
{
|
|
|
|
|
448
|
for (int y_index = 0; y_index < colormap_properties.v_size_px; y_index++)
|
|
|
|
|
449
|
{
|
|
|
|
|
450
|
if (avg_coef > 0.)
|
|
|
|
|
451
|
{
|
|
|
|
|
452
|
std::fill(std::begin(line_values), std::end(line_values), 0);
|
|
|
|
|
453
|
}
|
|
|
|
|
454
|
}
|
|
|
|
|
455
|
}
|
|
|
|
|
456
|
current_time += xAxisProperties.max_resolution * 0.9;
|
|
|
|
|
457
|
}
|
|
|
|
|
458
|
}
|
|
505
|
}
|
|
459
|
colormap->rescaleDataRange(true);
|
|
506
|
colormap->rescaleDataRange(true);
|
|
460
|
if (rescaleAxes)
|
|
507
|
if (rescaleAxes)
|