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)
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;
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)
112 const auto structure = container->get_structure();
113 auto channel_count = structure.get_channel_count();
115 if (channel_index >= channel_count) {
119 auto data = container->get_data();
122 if (channel_index >= data.size()) {
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()) {
135 if (interleaved_span.size() % channel_count != 0) {
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));
157 const std::vector<DataVariant>& pd,
159 uint64_t num_channels,
161 std::span<double> output)
163 if (pd.empty() || output.empty()) {
164 std::ranges::fill(output, 0.0);
169 thread_local std::vector<double> tmp;
170 auto data_span = extract_from_variant<double>(pd[0], tmp);
172 const auto samples_to_copy = std::min<size_t>(
174 data_span.size() / std::max<uint64_t>(num_channels, 1));
176 for (
auto s : std::views::iota(0UZ, samples_to_copy)) {
177 const auto idx = s * num_channels + ch;
178 output[s] = idx < data_span.size() ? data_span[idx] : 0.0;
181 if (samples_to_copy < output.size())
182 std::ranges::fill(output.subspan(samples_to_copy), 0.0);
184 if (ch >= pd.size()) {
185 std::ranges::fill(output, 0.0);
189 thread_local std::vector<double> tmp;
190 auto ch_span = extract_from_variant<double>(pd[ch], tmp);
192 const auto samples_to_copy = std::min(output.size(), ch_span.size());
193 std::ranges::copy_n(ch_span.begin(), samples_to_copy, output.begin());
195 if (samples_to_copy < output.size())
196 std::ranges::fill(output.subspan(samples_to_copy), 0.0);
202 const std::shared_ptr<SignalSourceContainer>& container,
208 auto variants = container->get_region_data(region);
210 if (
channel >= variants.size())
214 Kakshya::extract_from_variant<double>(variants[
channel],
storage);
218std::pair<std::shared_ptr<SignalSourceContainer>, std::vector<DataDimension>>
221 if (!container || !container->has_data()) {
225 auto dimensions = container->get_dimensions();
226 if (dimensions.empty()) {
230 return std::make_pair(container, std::move(dimensions));
235 if (!container || !container->has_data()) {
239 auto container_data = container->get_data();
241 return container_data
242 | std::views::transform([](
DataVariant& variant) -> std::span<double> {
245 | std::ranges::to<std::vector>();
249 const std::string& operation_name,
256 if (data.size() < min_size) {
260 if (
auto invalid_it = std::ranges::find_if_not(data, [](
double val) {
261 return std::isfinite(val);
263 invalid_it != data.end()) {
265 const auto index = std::distance(data.begin(), invalid_it);
@ Runtime
General runtime operations (default fallback)
@ Kakshya
Containers[Signalsource, Stream, File], Regions, DataProcessors.
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::span< double > convert_variant_to_double(DataVariant &data, ComplexConversionStrategy strategy=ComplexConversionStrategy::MAGNITUDE)
Convert variant to double span.
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.
OrganizationStrategy
Data organization strategy for multi-channel/multi-frame data.
@ PLANAR
Separate DataVariant per logical unit (LLL...RRR for stereo)
@ INTERLEAVED
Single DataVariant with interleaved data (LRLRLR 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.
void extract_processed_data(const std::vector< DataVariant > &pd, OrganizationStrategy organization, uint64_t num_channels, uint32_t ch, std::span< double > output)
Extract one channel's samples from a processed dynamic data block.
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::vector< double > extract_region_channel(const Region ®ion, const std::shared_ptr< SignalSourceContainer > &container, uint32_t channel)
Extract samples for a single channel within a Region from a container.
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.