62 double mean_energy {};
68 std::array<int, 5> level_counts {};
83 uint32_t window_size {};
108template <ComputeData InputType = std::vector<Kakshya::DataVariant>, ComputeData OutputType = Eigen::VectorXd>
135 return safe_any_cast_or_throw<EnergyAnalysis>(result);
167 return Reflect::get_enum_names_lowercase<EnergyMethod>();
178 [&method](
const std::string& m) {
179 return std::equal(method.begin(), method.end(), m.begin(), m.end(),
180 [](
char a,
char b) { return std::tolower(a) == std::tolower(b); });
216 if (silent >= quiet || quiet >= moderate || moderate >= loud) {
258 return channel.
level_counts[
static_cast<size_t>(level)];
278 if (str ==
"default")
280 return Reflect::string_to_enum_or_throw_case_insensitive<EnergyMethod>(str,
"EnergyMethod");
300 return "EnergyAnalyzer";
314 std::vector<std::span<const double>> channel_spans;
315 for (
auto& span : data_span)
316 channel_spans.emplace_back(span.data(), span.size());
318 for (
const auto& channel_span : channel_spans) {
324 std::vector<std::vector<double>> energy_values;
325 energy_values.reserve(channel_spans.size());
326 for (
const auto& channel_span : channel_spans) {
331 energy_values, channel_spans, structure_info);
336 }
catch (
const std::exception& e) {
340 error_result.
metadata[
"error"] = std::string(
"Analysis failed: ") + e.what();
350 if (name ==
"method") {
351 if (
auto str_result = safe_any_cast<std::string>(value)) {
356 if (
auto enum_result = safe_any_cast<EnergyMethod>(value)) {
362 std::source_location::current(),
363 "Invalid method parameter - expected string or EnergyMethod enum");
364 }
else if (name ==
"window_size") {
365 if (
auto result = safe_any_cast<uint32_t>(value)) {
370 }
else if (name ==
"hop_size") {
371 if (
auto result = safe_any_cast<uint32_t>(value)) {
376 }
else if (name ==
"classification_enabled") {
377 if (
auto result = safe_any_cast<bool>(value)) {
391 if (name ==
"method")
393 if (name ==
"window_size")
395 if (name ==
"hop_size")
397 if (name ==
"classification_enabled")
431 const std::vector<std::vector<double>>& energy_values,
432 std::vector<std::span<const double>> original_data,
440 if (energy_values.empty()) {
444 result.
channels.resize(energy_values.size());
446 for (
size_t ch = 0; ch < energy_values.size(); ch++) {
448 auto& channel_result = result.
channels[ch];
449 const auto& ch_energy = energy_values[ch];
451 channel_result.energy_values = ch_energy;
453 if (!ch_energy.empty()) {
454 auto [min_it, max_it] = std::ranges::minmax_element(ch_energy);
455 channel_result.min_energy = *min_it;
456 channel_result.max_energy = *max_it;
458 const double sum = std::accumulate(ch_energy.begin(), ch_energy.end(), 0.0);
459 channel_result.mean_energy = sum /
static_cast<double>(ch_energy.size());
461 const double mean = channel_result.mean_energy;
462 const double var_sum = std::transform_reduce(
463 ch_energy.begin(), ch_energy.end(), 0.0, std::plus {},
464 [
mean](
double val) { return (val - mean) * (val - mean); });
465 channel_result.variance = var_sum /
static_cast<double>(ch_energy.size());
468 const size_t data_size = (ch < original_data.size()) ? original_data[ch].size() : 0;
469 channel_result.window_positions.reserve(ch_energy.size());
471 for (
size_t i = 0; i < ch_energy.size(); ++i) {
473 const size_t end = std::min(start +
m_window_size, data_size);
474 channel_result.window_positions.emplace_back(start, end);
477 if (ch < original_data.size()) {
481 original_data[ch], 0.0);
487 original_data[ch], peak_threshold,
m_hop_size / 4);
503 channel_result.classifications.reserve(ch_energy.size());
504 channel_result.level_counts.fill(0);
506 for (
double energy : ch_energy) {
508 channel_result.classifications.push_back(level);
509 channel_result.level_counts[
static_cast<size_t>(level)]++;
522 std::vector<std::vector<double>> channel_energies;
523 channel_energies.reserve(analysis_result.
channels.size());
525 for (
const auto& ch : analysis_result.
channels) {
526 channel_energies.push_back(ch.energy_values);
533 output.
metadata[
"source_analyzer"] =
"EnergyAnalyzer";
539 if (!analysis_result.
channels.empty()) {
540 std::vector<double> channel_means, channel_maxs, channel_mins, channel_variances;
541 std::vector<size_t> channel_window_counts;
543 for (
const auto& ch : analysis_result.
channels) {
544 channel_means.push_back(ch.mean_energy);
545 channel_maxs.push_back(ch.max_energy);
546 channel_mins.push_back(ch.min_energy);
547 channel_variances.push_back(ch.variance);
548 channel_window_counts.push_back(ch.energy_values.size());
551 output.
metadata[
"mean_energy_per_channel"] = channel_means;
552 output.
metadata[
"max_energy_per_channel"] = channel_maxs;
553 output.
metadata[
"min_energy_per_channel"] = channel_mins;
554 output.
metadata[
"variance_per_channel"] = channel_variances;
555 output.
metadata[
"window_count_per_channel"] = channel_window_counts;
609template <ComputeData InputType = std::vector<Kakshya::DataVariant>>
613template <ComputeData InputType = std::vector<Kakshya::DataVariant>>
644 const auto& ch = analysis.
channels[0];
645 const std::string
q = qualifier.empty() ?
"mean_energy" : qualifier;
647 if (
q ==
"mean_energy")
648 return ch.mean_energy;
649 if (
q ==
"max_energy")
650 return ch.max_energy;
651 if (
q ==
"min_energy")
652 return ch.min_energy;
655 if (
q ==
"dynamic_range")
656 return ch.max_energy - ch.min_energy;
657 if (
q ==
"event_count")
658 return static_cast<double>(ch.event_positions.size());
659 if (
q ==
"window_count")
660 return static_cast<double>(ch.energy_values.size());
662 return ch.mean_energy;
Discrete sequence analysis primitives for MayaFlux::Kinesis.
#define MF_ERROR(comp, ctx,...)
Core::GlobalInputConfig input
Modern, digital-first universal analyzer framework for Maya Flux.
output_type convert_result(std::vector< std::vector< double > > &result_data, DataStructureInfo &metadata)
Convert processed double data back to OutputType using metadata and optional callback.
EnergyMethod get_energy_method() const
Get current energy computation method.
size_t calculate_num_windows(size_t data_size) const
Calculate number of windows for given data size.
bool supports_method(const std::string &method) const override
Check if a specific method is supported.
output_type create_pipeline_output(const input_type &input, const EnergyAnalysis &analysis_result, DataStructureInfo &info)
Create pipeline output from input and energy values.
static EnergyMethod string_to_method(const std::string &str)
Convert string to energy method enum.
void enable_classification(bool enabled)
Enable or disable energy level classification.
AnalysisType get_analysis_type() const override
Get analysis type category.
EnergyAnalyzer(uint32_t window_size=256, uint32_t hop_size=128)
Construct EnergyAnalyzer with configurable window parameters.
EnergyAnalysis create_analysis_result(const std::vector< std::vector< double > > &energy_values, std::vector< std::span< const double > > original_data, const DataStructureInfo &) const
Create comprehensive analysis result from energy computation.
void validate_window_parameters() const
void set_energy_method(EnergyMethod method)
Set energy computation method.
std::any get_analysis_parameter(const std::string &name) const override
Get analysis-specific parameter.
double m_silent_threshold
int get_level_count(const ChannelEnergy &channel, EnergyLevel level)
Get count of windows in a specific energy level for a channel.
static std::string method_to_string(EnergyMethod method)
Convert energy method enum to string.
output_type analyze_implementation(const input_type &input) override
Core analysis implementation - creates analysis result AND pipeline output.
void set_energy_thresholds(double silent, double quiet, double moderate, double loud)
Set energy level classification thresholds.
std::vector< double > compute_energy_values(std::span< const double > data, EnergyMethod method) const
Compute energy values using span (zero-copy processing)
double m_moderate_threshold
std::vector< std::string > get_available_methods() const override
Get available analysis methods.
EnergyAnalysis analyze_energy(const input_type &data)
Type-safe energy analysis method.
void set_window_parameters(uint32_t window_size, uint32_t hop_size)
Set window parameters for analysis.
static std::string energy_level_to_string(EnergyLevel level)
Convert energy level enum to string.
std::string get_analyzer_name() const override
Get analyzer name.
EnergyAnalysis analyze_energy(const InputType &data)
void set_analysis_parameter(const std::string &name, std::any value) override
Handle analysis-specific parameters.
EnergyLevel classify_energy_level(double energy) const
Classify energy value into qualitative level.
bool m_classification_enabled
EnergyAnalysis get_energy_analysis() const
Get last energy analysis result (type-safe)
High-performance energy analyzer with zero-copy processing.
static std::tuple< std::vector< std::span< double > >, DataStructureInfo > extract_structured_double(T &compute_data)
Extract structured double data from Datum container or direct ComputeData with automatic container ha...
virtual void set_analysis_parameter(const std::string &name, std::any value)
Analysis-specific parameter handling (override for custom parameters)
std::any get_current_analysis() const
Access cached analysis from last operation.
std::any analyze_data(const input_type &data)
User-facing analysis method - returns analysis results directly.
virtual std::any get_analysis_parameter(const std::string &name) const
void store_current_analysis(AnalysisResultType &&result) const
Template-flexible analyzer base with instance-defined I/O types.
@ ComputeMatrix
Compute operations (Yantra - algorithms, matrices, DSP)
@ Yantra
DSP algorithms, computational units, matrix operations, Grammar.
std::vector< double > low_frequency_energy(std::span< const double > data, size_t n_windows, uint32_t hop_size, uint32_t window_size, double low_bin_fraction)
Low-frequency spectral energy per window.
std::vector< double > spectral_energy(std::span< const double > data, size_t n_windows, uint32_t hop_size, uint32_t window_size)
Spectral energy per window using Hann-windowed FFT.
std::vector< double > power(std::span< const double > data, size_t n_windows, uint32_t hop_size, uint32_t window_size)
Power (sum of squares) per window.
std::vector< size_t > zero_crossing_positions(std::span< const double > data, double threshold)
Sample indices of zero crossings in the full span.
std::vector< double > peak(std::span< const double > data, size_t n_windows, uint32_t hop_size, uint32_t window_size)
Peak amplitude per window.
std::vector< double > dynamic_range(std::span< const double > data, size_t n_windows, uint32_t hop_size, uint32_t window_size)
Dynamic range in dB per window.
std::vector< size_t > peak_positions(std::span< const double > data, double threshold, size_t min_distance)
Sample indices of local peak maxima in the full span.
std::vector< double > zero_crossing_rate(std::span< const double > data, size_t n_windows, uint32_t hop_size, uint32_t window_size)
Zero-crossing rate per window.
std::vector< double > rms(std::span< const double > data, size_t n_windows, uint32_t hop_size, uint32_t window_size)
RMS energy per window.
std::string enum_to_lowercase_string(EnumType value) noexcept
Universal enum to lowercase string converter using magic_enum.
AnalysisType
Categories of analysis operations for discovery and organization.
@ FEATURE
Feature extraction and characterization.
MAYAFLUX_API double extract_scalar_energy(const EnergyAnalysis &analysis, const std::string &qualifier)
Extract a named scalar from an EnergyAnalysis result.
EnergyMethod
Supported energy computation methods.
@ SPECTRAL
Spectral energy (FFT-based)
@ DYNAMIC_RANGE
Dynamic range (dB)
@ RMS
Root Mean Square energy.
@ ZERO_CROSSING
Zero-crossing rate.
@ HARMONIC
Harmonic energy (low-frequency content)
@ POWER
Power (sum of squares)
EnergyLevel
Qualitative classification of energy values.
double mean(const std::vector< double > &data)
Calculate mean of single-channel data.
std::vector< size_t > event_positions
std::vector< EnergyLevel > classifications
std::vector< std::pair< size_t, size_t > > window_positions
std::array< int, 5 > level_counts
std::vector< double > energy_values
Metadata about data structure for reconstruction.
std::unordered_map< std::string, std::any > metadata
Associated metadata.
Input/Output container for computation pipeline data flow with structure preservation.
std::vector< ChannelEnergy > channels
Analysis result structure for energy analysis.