62 double mean_energy {};
68 std::array<int, 5> level_counts {};
83 uint32_t window_size {};
132template <ComputeData InputType = std::vector<Kakshya::DataVariant>, ComputeData OutputType = Eigen::VectorXd>
180 return safe_any_cast_or_throw<EnergyAnalysis>(result);
212 return Reflect::get_enum_names_lowercase<EnergyMethod>();
223 [&method](
const std::string& m) {
224 return std::equal(method.begin(), method.end(), m.begin(), m.end(),
225 [](
char a,
char b) { return std::tolower(a) == std::tolower(b); });
261 if (silent >= quiet || quiet >= moderate || moderate >= loud) {
303 return channel.
level_counts[
static_cast<size_t>(level)];
323 if (str ==
"default")
325 return Reflect::string_to_enum_or_throw_case_insensitive<EnergyMethod>(str,
"EnergyMethod");
345 return "EnergyAnalyzer";
359 std::vector<std::span<const double>> channel_spans;
360 for (
auto& span : data_span)
361 channel_spans.emplace_back(span.data(), span.size());
363 for (
const auto& channel_span : channel_spans) {
369 std::vector<std::vector<double>> energy_values;
370 energy_values.reserve(channel_spans.size());
371 for (
const auto& channel_span : channel_spans) {
376 energy_values, channel_spans, structure_info);
381 }
catch (
const std::exception& e) {
385 error_result.
metadata[
"error"] = std::string(
"Analysis failed: ") + e.what();
395 if (
name ==
"method") {
396 if (
auto str_result = safe_any_cast<std::string>(
value)) {
401 if (
auto enum_result = safe_any_cast<EnergyMethod>(
value)) {
407 std::source_location::current(),
408 "Invalid method parameter - expected string or EnergyMethod enum");
409 }
else if (
name ==
"window_size") {
410 if (
auto result = safe_any_cast<uint32_t>(
value)) {
415 }
else if (
name ==
"hop_size") {
416 if (
auto result = safe_any_cast<uint32_t>(
value)) {
421 }
else if (
name ==
"classification_enabled") {
422 if (
auto result = safe_any_cast<bool>(
value)) {
436 if (
name ==
"method")
438 if (
name ==
"window_size")
440 if (
name ==
"hop_size")
442 if (
name ==
"classification_enabled")
476 const std::vector<std::vector<double>>& energy_values,
477 std::vector<std::span<const double>> original_data,
485 if (energy_values.empty()) {
489 result.
channels.resize(energy_values.size());
491 for (
size_t ch = 0; ch < energy_values.size(); ch++) {
493 auto& channel_result = result.
channels[ch];
494 const auto& ch_energy = energy_values[ch];
496 channel_result.energy_values = ch_energy;
498 if (!ch_energy.empty()) {
499 auto [min_it, max_it] = std::ranges::minmax_element(ch_energy);
500 channel_result.min_energy = *min_it;
501 channel_result.max_energy = *max_it;
503 const double sum = std::accumulate(ch_energy.begin(), ch_energy.end(), 0.0);
504 channel_result.mean_energy = sum /
static_cast<double>(ch_energy.size());
506 const double mean = channel_result.mean_energy;
507 const double var_sum = std::transform_reduce(
508 ch_energy.begin(), ch_energy.end(), 0.0, std::plus {},
509 [mean](
double val) { return (val - mean) * (val - mean); });
510 channel_result.variance = var_sum /
static_cast<double>(ch_energy.size());
513 const size_t data_size = (ch < original_data.size()) ? original_data[ch].
size() : 0;
514 channel_result.window_positions.reserve(ch_energy.size());
516 for (
size_t i = 0; i < ch_energy.size(); ++i) {
518 const size_t end = std::min(start +
m_window_size, data_size);
519 channel_result.window_positions.emplace_back(start, end);
522 if (ch < original_data.size()) {
526 original_data[ch], 0.0);
532 original_data[ch], peak_threshold,
m_hop_size / 4);
548 channel_result.classifications.reserve(ch_energy.size());
549 channel_result.level_counts.fill(0);
551 for (
double energy : ch_energy) {
553 channel_result.classifications.push_back(level);
554 channel_result.level_counts[
static_cast<size_t>(level)]++;
567 std::vector<std::vector<double>> channel_energies;
568 channel_energies.reserve(analysis_result.
channels.size());
570 for (
const auto& ch : analysis_result.
channels) {
571 channel_energies.push_back(ch.energy_values);
578 output.
metadata[
"source_analyzer"] =
"EnergyAnalyzer";
584 if (!analysis_result.
channels.empty()) {
585 std::vector<double> channel_means, channel_maxs, channel_mins, channel_variances;
586 std::vector<size_t> channel_window_counts;
588 for (
const auto& ch : analysis_result.
channels) {
589 channel_means.push_back(ch.mean_energy);
590 channel_maxs.push_back(ch.max_energy);
591 channel_mins.push_back(ch.min_energy);
592 channel_variances.push_back(ch.variance);
593 channel_window_counts.push_back(ch.energy_values.size());
596 output.
metadata[
"mean_energy_per_channel"] = channel_means;
597 output.
metadata[
"max_energy_per_channel"] = channel_maxs;
598 output.
metadata[
"min_energy_per_channel"] = channel_mins;
599 output.
metadata[
"variance_per_channel"] = channel_variances;
600 output.
metadata[
"window_count_per_channel"] = channel_window_counts;
654template <ComputeData InputType = std::vector<Kakshya::DataVariant>>
658template <ComputeData InputType = std::vector<Kakshya::DataVariant>>
689 const auto& ch = analysis.
channels[0];
690 const std::string
q = qualifier.empty() ?
"mean_energy" : qualifier;
692 if (
q ==
"mean_energy")
693 return ch.mean_energy;
694 if (
q ==
"max_energy")
695 return ch.max_energy;
696 if (
q ==
"min_energy")
697 return ch.min_energy;
700 if (
q ==
"dynamic_range")
701 return ch.max_energy - ch.min_energy;
702 if (
q ==
"event_count")
703 return static_cast<double>(ch.event_positions.size());
704 if (
q ==
"window_count")
705 return static_cast<double>(ch.energy_values.size());
707 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(const EnergyAnalyzerConfig &config)
Construct and configure an energy analyzer in one step.
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.
void set_parameter(const std::string &name, std::any value) override
Type-safe parameter management with analysis-specific defaults.
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
void set_analysis_granularity(AnalysisGranularity granularity)
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.
AnalysisGranularity
Output granularity control for analysis results.
@ RAW_VALUES
Direct analysis results.
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
Dimensions, modality, source type, and optional Composite field schema.
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.
std::map< std::string, std::any > parameters
Additional named parameters applied last.
std::array< double, 4 > thresholds
Silent, quiet, moderate, and loud boundaries, in that order.
bool classification_enabled
Whether to classify energy levels.
uint32_t hop_size
Distance between successive windows in samples.
AnalysisGranularity granularity
Level at which the analyzer processes input.
EnergyMethod method
Energy calculation to perform.
uint32_t window_size
Analysis window length in samples.
Initial settings for energy analysis.