Extract data from regions with values above statistical mean.
323{
324 std::vector<std::vector<double>> result;
325 result.reserve(data.size());
326
327 for (const auto& channel : data) {
328 if (channel.empty()) {
329 result.emplace_back();
330 continue;
331 }
332
333 uint32_t effective_window_size = std::min(window_size, static_cast<uint32_t>(channel.size()));
334 uint32_t effective_hop_size = std::min(hop_size, effective_window_size / 2);
335 if (effective_hop_size == 0)
336 effective_hop_size = 1;
337
338 if (!validate_extraction_parameters(effective_window_size, effective_hop_size, channel.size())) {
339 result.emplace_back();
340 continue;
341 }
342
343 try {
344 auto stat_analyzer = std::make_shared<StatisticalAnalyzer<std::vector<Kakshya::DataVariant>, Eigen::VectorXd>>(
345 effective_window_size, effective_hop_size);
346 stat_analyzer->set_parameter("method", "mean");
347
348 std::vector<Kakshya::DataVariant> data_variant { Kakshya::DataVariant { std::vector<double>(channel.begin(), channel.end()) } };
349 ChannelStatistics stat_result = stat_analyzer->analyze_statistics(data_variant).channel_statistics[0];
350
351 if (stat_result.statistical_values.empty() || stat_result.window_positions.empty()) {
352 result.emplace_back();
353 continue;
354 }
355
356 const double threshold = stat_result.mean_stat * mean_multiplier;
357
358 std::vector<std::pair<size_t, size_t>> qualifying_windows;
359 for (size_t i = 0; i < stat_result.statistical_values.size(); ++i) {
360 if (stat_result.statistical_values[i] > threshold) {
361 auto [start_idx, end_idx] = stat_result.window_positions[i];
362 if (start_idx < channel.size() && end_idx <= channel.size() && start_idx < end_idx) {
363 qualifying_windows.emplace_back(start_idx, end_idx);
364 }
365 }
366 }
367
368 auto merged_windows = merge_overlapping_windows(qualifying_windows);
369
370 std::vector<double> extracted_data;
371 for (const auto& [start_idx, end_idx] : merged_windows) {
372 std::ranges::copy(channel.subspan(start_idx, end_idx - start_idx),
373 std::back_inserter(extracted_data));
374 }
375
376 result.push_back(std::move(extracted_data));
377 } catch (const std::exception&) {
378 result.emplace_back();
379 }
380 }
381
382 return result;
383}