13 throw std::invalid_argument(
"Container is null");
16 std::unordered_map<std::string, std::any> state_info;
18 state_info[
"processing_state"] =
static_cast<int>(container->get_processing_state());
19 state_info[
"is_ready"] = container->is_ready_for_processing();
21 if (
auto stream = std::dynamic_pointer_cast<StreamContainer>(container)) {
22 state_info[
"read_position"] = stream->get_read_position();
23 state_info[
"is_stream_container"] =
true;
25 state_info[
"is_stream_container"] =
false;
31std::unordered_map<std::string, std::any>
extract_processor_info(
const std::shared_ptr<SignalSourceContainer>& container)
34 throw std::invalid_argument(
"Container is null");
37 std::unordered_map<std::string, std::any> processor_info;
39 if (
auto processor = container->get_default_processor()) {
40 processor_info[
"has_processor"] =
true;
41 processor_info[
"processor_processing"] = processor->is_processing();
43 processor_info[
"has_processor"] =
false;
46 if (
auto chain = container->get_processing_chain()) {
47 processor_info[
"has_processing_chain"] =
true;
50 processor_info[
"has_processing_chain"] =
false;
53 return processor_info;
58 static const std::unordered_map<ProcessingState, std::unordered_set<ProcessingState>> valid_transitions = {
66 auto it = valid_transitions.find(current_state);
67 if (it != valid_transitions.end() && (it->second.count(new_state) != 0U)) {
68 current_state = new_state;
77 const std::shared_ptr<SignalSourceContainer>& container)
79 std::unordered_map<std::string, std::any> analysis;
82 throw std::invalid_argument(
"Container is null");
85 const auto dimensions = container->get_dimensions();
86 const auto memory_layout = container->get_memory_layout();
89 analysis[
"memory_layout"] =
static_cast<int>(memory_layout);
91 uint64_t region_size = 1;
95 analysis[
"region_size"] = region_size;
97 if (!dimensions.empty()) {
99 analysis[
"access_stride"] = strides[0];
106 uint32_t channel_index)
109 throw std::invalid_argument(
"Container is null");
112 const auto structure = container->get_structure();
113 auto channel_count = structure.get_channel_count();
115 if (channel_index >= channel_count) {
116 throw std::out_of_range(
"Channel index out of range");
119 auto data = container->get_data();
122 if (channel_index >= data.size()) {
123 throw std::out_of_range(
"Channel index out of range for planar data");
125 return data[channel_index];
128 std::vector<double> temp_storage;
129 auto interleaved_span = extract_from_variant<double>(data[0], temp_storage);
131 if (interleaved_span.empty()) {
132 throw std::runtime_error(
"Failed to extract interleaved data");
135 if (interleaved_span.size() % channel_count != 0) {
136 throw std::runtime_error(
"Interleaved data size is not a multiple of channel count");
139#ifdef MAYAFLUX_PLATFORM_MACOS
140 std::vector<double> channel_data;
141 for (
size_t i = channel_index; i < interleaved_span.size(); i += channel_count) {
142 channel_data.push_back(interleaved_span[i]);
145 auto channel_view = interleaved_span
146 | std::views::drop(channel_index)
147 | std::views::stride(channel_count);
149 std::vector<double> channel_data;
150 std::ranges::copy(channel_view, std::back_inserter(channel_data));
156std::pair<std::shared_ptr<SignalSourceContainer>, std::vector<DataDimension>>
159 if (!container || !container->has_data()) {
160 throw std::invalid_argument(
"Container is null or has no data");
163 auto dimensions = container->get_dimensions();
164 if (dimensions.empty()) {
165 throw std::runtime_error(
"Container has no dimensions");
168 return std::make_pair(container, std::move(dimensions));
173 if (!container || !container->has_data()) {
174 throw std::invalid_argument(
"Container is null or has no data");
177 auto container_data = container->get_data();
179 return container_data
180 | std::views::transform([](
DataVariant& variant) -> std::span<double> {
183 | std::ranges::to<std::vector>();
187 const std::string& operation_name,
191 throw std::invalid_argument(
"Cannot perform " + operation_name +
" on empty data");
194 if (data.size() < min_size) {
195 throw std::invalid_argument(operation_name +
" requires at least " + std::to_string(min_size) +
" data points, got " + std::to_string(data.size()));
198 if (
auto invalid_it = std::ranges::find_if_not(data, [](
double val) {
199 return std::isfinite(val);
201 invalid_it != data.end()) {
203 const auto index = std::distance(data.begin(), invalid_it);
204 throw std::invalid_argument(operation_name +
" data contains NaN or infinite values at index " + std::to_string(index));
ProcessingState
Represents the current processing lifecycle state of a container.
@ READY
Container has data loaded and is ready for processing.
@ NEEDS_REMOVAL
Container is marked for removal from the system.
@ IDLE
Container is inactive with no data or not ready for processing.
@ ERROR
Container is in an error state and cannot proceed.
@ PROCESSING
Container is actively being processed.
@ PROCESSED
Container has completed processing and results are available.
std::unordered_map< std::string, std::any > analyze_access_pattern(const Region ®ion, const std::shared_ptr< SignalSourceContainer > &container)
Determine optimal memory access pattern for region.
bool is_region_access_contiguous(const Region ®ion, const std::shared_ptr< SignalSourceContainer > &container)
Check if region access will be contiguous in memory.
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.
std::vector< uint64_t > calculate_strides(const std::vector< DataDimension > &dimensions)
Calculate memory strides for each dimension (row-major order).
DataVariant extract_channel_data(const std::shared_ptr< SignalSourceContainer > &container, uint32_t channel_index)
Extract data from a specific channel.
@ PLANAR
Separate DataVariant per logical unit (LLL...RRR for stereo)
std::unordered_map< std::string, std::any > extract_processing_state_info(const std::shared_ptr< SignalSourceContainer > &container)
Extract processing state information from container.
std::vector< std::span< double > > extract_numeric_data(const std::shared_ptr< SignalSourceContainer > &container)
Extracts numeric data from container with fallback handling.
void validate_numeric_data_for_analysis(const std::vector< double > &data, const std::string &operation_name, size_t min_size)
Validates numeric data for analysis operations.
std::pair< std::shared_ptr< SignalSourceContainer >, std::vector< DataDimension > > validate_container_for_analysis(const std::shared_ptr< SignalSourceContainer > &container)
Validates container for analysis operations with comprehensive checks.
std::span< double > convert_variant_to_double(DataVariant &data, Utils::ComplexConversionStrategy strategy=Utils::ComplexConversionStrategy::MAGNITUDE)
Convert variant to double span.
std::unordered_map< std::string, std::any > extract_processor_info(const std::shared_ptr< SignalSourceContainer > &container)
Extract processor information from container.
bool transition_state(ProcessingState ¤t_state, ProcessingState new_state, std::function< void()> on_transition)
Perform a state transition for a ProcessingState, with optional callback.
std::vector< uint64_t > end_coordinates
Ending frame index (inclusive)
std::vector< uint64_t > start_coordinates
Starting frame index (inclusive)
Represents a point or span in N-dimensional space.