##// END OF EJS Templates
Spectrogram segfault should be fixed now, added ability to provide Spectrogram min sampling time to avoid computation when possible...
jeandet -
r1467:da44adcd99e4
parent child
Show More
@@ -1,1 +1,1
1 Subproject commit 483146a07a5ffeec8f0a2d61459e94d95e851572
1 Subproject commit 1e3f92d40b0ec24443e067aaa9e7bca385ec27b2
@@ -74,7 +74,7 DateTimeRange TimeWidget::timeRange() const
74 74 void TimeWidget::onTimeUpdateRequested()
75 75 {
76 76 auto dateTime = timeRange();
77 emit timeUpdated(std::move(dateTime));
77 emit timeUpdated(dateTime);
78 78 sqpApp->timeController().setDateTimeRange(dateTime);
79 79 }
80 80
@@ -9,6 +9,7
9 9 #include <Common/cpp_utils.h>
10 10 #include <Variable/Variable2.h>
11 11 #include <algorithm>
12 #include <cmath>
12 13
13 14 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
14 15
@@ -272,11 +273,10 struct PlottablesUpdater<T,
272 273 double minValue = 0., maxValue = 0.;
273 274 if (auto serie = dynamic_cast<MultiComponentTimeSerie*>(&dataSeries))
274 275 {
275 std::for_each(
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());
278 maxValue = std::max(maxValue, std::max_element(v.begin(), v.end())->v());
279 });
276 std::for_each(std::begin(*serie), std::end(*serie), [&minValue, &maxValue](auto& 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());
279 });
280 280 }
281 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 358 * Specialization of PlottablesUpdater for spectrograms
319 359 * @sa SpectrogramSeries
@@ -354,57 +394,75 struct PlottablesUpdater<T,
354 394 auto yAxis = serie->axis(1); // copy for in place reverse order
355 395 std::reverse(std::begin(yAxis), std::end(yAxis));
356 396 auto xAxisProperties = TimeSeriesUtils::axis_analysis<TimeSeriesUtils::IsLinear,
357 TimeSeriesUtils::CheckMedian>(xAxis);
397 TimeSeriesUtils::CheckMedian>(xAxis, serie->min_sampling);
358 398 auto yAxisProperties = TimeSeriesUtils::axis_analysis<TimeSeriesUtils::IsLog,
359 399 TimeSeriesUtils::DontCheckMedian>(yAxis);
400 auto colormap_properties = CMAxisAnalysis(xAxisProperties, yAxisProperties);
360 401
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);
402 colormap->data()->setSize(
403 colormap_properties.h_size_px, colormap_properties.v_size_px);
367 404 colormap->data()->setRange(
368 QCPRange { serie->begin()->t(), (serie->end() - 1)->t() },
369 { minValue, maxValue });
405 QCPRange { xAxisProperties.min, xAxisProperties.max }, { minValue, maxValue });
370 406
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++)
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 }
407 auto y_access_pattern
408 = build_access_pattern(yAxis, yAxisProperties, colormap_properties);
380 409
381 410 auto line = serie->begin();
382 double current_time = xAxis[0];
411 auto next_line = line + 1;
412 double current_time = xAxisProperties.min;
383 413 int x_index = 0;
384
385 while (x_index < colormap_h_size)
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 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])
392 > (x_index * xAxisProperties.range / colormap_h_size))
426 if ((current_time - xAxisProperties.min)
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 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),
399 [&colormap, &line, x_index](const auto& acc) {
400 colormap->data()->setCell(x_index, acc.first, (*line)[acc.second]);
401 });
441 if (has_nan)
442 {
443 std::transform(std::begin(*line), std::end(*line),
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 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 468 current_time += xAxisProperties.max_resolution;
@@ -32,6 +32,8 def amda_make_spectro(var=None):
32 32 if var is None:
33 33 return pysciqlopcore.SpectrogramTimeSerie((0,2))
34 34 else:
35 min_sampling = float(var.meta.get("DATASET_MIN_SAMPLING","nan"))
36 max_sampling = float(var.meta.get("DATASET_MAX_SAMPLING","nan"))
35 37 if "PARAMETER_TABLE_MIN_VALUES[1]" in var.meta:
36 38 min_v = np.array([ float(v) for v in var.meta["PARAMETER_TABLE_MIN_VALUES[1]"].split(',') ])
37 39 max_v = np.array([ float(v) for v in var.meta["PARAMETER_TABLE_MAX_VALUES[1]"].split(',') ])
@@ -42,7 +44,7 def amda_make_spectro(var=None):
42 44 y = (max_v + min_v)/2.
43 45 else:
44 46 y = np.logspace(1,3,var.data.shape[1])[::-1]
45 return pysciqlopcore.SpectrogramTimeSerie(var.time,y,var.data)
47 return pysciqlopcore.SpectrogramTimeSerie(var.time,y,var.data,min_sampling,max_sampling)
46 48
47 49 def amda_get_sample(metadata,start,stop):
48 50 ts_type = amda_make_scalar
@@ -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)[::-1],values)
67 ts_type = lambda t,values: pysciqlopcore.SpectrogramTimeSerie(t,np.logspace(1,3,32)[::-1],values,np.nan,np.nan)
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