482{
483 std::vector<std::vector<double>> result;
484 result.reserve(data.size());
485
486 for (const auto& channel : data) {
487 if (channel.empty() || region_size == 0) {
488 result.emplace_back();
489 continue;
490 }
491
492 try {
493 auto analyzer = std::make_shared<EnergyAnalyzer<std::vector<Kakshya::DataVariant>, Eigen::VectorXd>>(
494 region_size * 2, static_cast<uint32_t>(min_distance));
495 analyzer->set_parameter("method", "zero_crossing");
496
497 std::vector<Kakshya::DataVariant> data_variant {
499 };
500 EnergyAnalysis energy_result = analyzer->analyze_energy(data_variant);
501
502 if (energy_result.channels.empty()) {
503 result.emplace_back();
504 continue;
505 }
506
507 const auto& crossing_positions = energy_result.channels[0].event_positions;
508
509 if (crossing_positions.empty()) {
510 result.emplace_back();
511 continue;
512 }
513
514 std::vector<size_t> filtered_positions;
515 size_t last_position = 0;
516
517 for (size_t pos : crossing_positions) {
518 if (filtered_positions.empty() || (pos - last_position) >= static_cast<size_t>(min_distance)) {
519 filtered_positions.push_back(pos);
520 last_position = pos;
521 }
522 }
523
524 std::vector<size_t> qualified_positions;
525 for (size_t pos : filtered_positions) {
526 if (pos < channel.size() && std::abs(channel[pos]) >= threshold) {
527 qualified_positions.push_back(pos);
528 }
529 }
530
531 std::vector<double> extracted_data;
532 for (size_t pos : qualified_positions) {
533 const size_t half_region = region_size / 2;
534 const size_t region_start = (pos >= half_region) ? pos - half_region : 0;
535 const size_t region_end = std::min(pos + half_region, channel.size());
536
537 if (region_start < region_end) {
538 auto region = channel.subspan(region_start, region_end - region_start);
539 std::ranges::copy(region, std::back_inserter(extracted_data));
540 }
541 }
542
543 result.push_back(std::move(extracted_data));
544 } catch (const std::exception&) {
545 result.emplace_back();
546 }
547 }
548
549 return result;
550}
std::variant< std::vector< double >, std::vector< float >, std::vector< uint8_t >, std::vector< uint16_t >, std::vector< uint32_t >, std::vector< std::complex< float > >, std::vector< std::complex< double > >, std::vector< glm::vec2 >, std::vector< glm::vec3 >, std::vector< glm::vec4 >, std::vector< glm::mat4 > > DataVariant
Multi-type data storage for different precision needs.