MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
NDimensionalContainer.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "NDData/NDData.hpp"
4
5namespace MayaFlux::Kakshya {
6
7/**
8 * @brief Forward declarations for region structures used in N-dimensional data containers.
9 */
10struct Region;
11struct RegionGroup;
12struct RegionSegment;
13
14/**
15 * @brief Container structure for consistent dimension ordering.
16 *
17 * Provides standard indices and layout structures for common data types,
18 * supporting digital-first, data-driven workflows. These structures are
19 * not tied to analog metaphors, but instead facilitate generic, flexible
20 * processing of multi-dimensional data.
21 */
22struct MAYAFLUX_API ContainerDataStructure {
23
24 // Image/Video structures
25 // static constexpr size_t FRAME_DIM = 0;
26 // static constexpr size_t COLOR_DIM = 3;
27
28 // Spectral structures
29 // static constexpr size_t TIME_WINDOW_DIM = 0;
30
31 std::vector<DataDimension> dimensions;
32
33 std::optional<size_t> time_dims;
34 std::optional<size_t> channel_dims;
35 std::optional<size_t> height_dims;
36 std::optional<size_t> width_dims;
37 std::optional<size_t> frequency_dims;
38
39 DataModality modality {};
40 MemoryLayout memory_layout = MemoryLayout::ROW_MAJOR;
41 OrganizationStrategy organization = OrganizationStrategy::PLANAR;
42
43 /**
44 * @brief Construct a container structure with specified parameters.
45 * @param mod Data modality type
46 * @param org Organization strategy (default: PLANAR)
47 * @param layout Memory layout (default: ROW_MAJOR)
48 */
50 OrganizationStrategy org = OrganizationStrategy::PLANAR,
51 MemoryLayout layout = MemoryLayout::ROW_MAJOR);
52
54
55 /**
56 * @brief Get the expected dimension roles for this structure's modality.
57 * @return Vector of dimension roles in order
58 */
59 [[nodiscard]] std::vector<DataDimension::Role> get_expected_dimension_roles() const;
60
61 /**
62 * @brief Create structure for planar audio data.
63 * @return Containerstructure configured for planar audio
64 */
65 static ContainerDataStructure audio_planar();
66
67 /**
68 * @brief Create structure for interleaved audio data.
69 * @return Containerstructure configured for interleaved audio
70 */
71 static ContainerDataStructure audio_interleaved();
72
73 /**
74 * @brief Create structure for planar image data.
75 * @return Containerstructure configured for planar images
76 */
77 static ContainerDataStructure image_planar();
78
79 /**
80 * @brief Create structure for interleaved image data.
81 * @return Containerstructure configured for interleaved images
82 */
83 static ContainerDataStructure image_interleaved();
84
85 /**
86 * @brief Calculate expected number of data variants for given dimensions.
87 * @param dimensions Vector of dimension descriptors
88 * @return Expected number of DataVariant objects needed
89 */
90 [[nodiscard]] size_t get_expected_variant_count(const std::vector<DataDimension>& dimensions) const;
91
92 /**
93 * @brief Calculate size of a specific variant in the organization.
94 * @param dimensions Vector of dimension descriptors
95 * @param modality Data modality type
96 * @param organization Organization strategy
97 * @param variant_index Index of the variant (0-based)
98 * @return Number of elements in the specified variant
99 */
100 [[nodiscard]] static uint64_t get_variant_size(const std::vector<DataDimension>& dimensions,
101 DataModality modality, OrganizationStrategy organization, size_t variant_index = 0);
102 [[nodiscard]] uint64_t get_variant_size() const { return get_variant_size(dimensions, modality, organization); }
103
104 /**
105 * @brief Validate that dimensions match this structure's expectations.
106 * @param dimensions Vector of dimension descriptors to validate
107 * @return true if dimensions are valid for this structure
108 */
109 [[nodiscard]] bool validate_dimensions(const std::vector<DataDimension>& dimensions) const;
110
111 /**
112 * @brief Find the index of a dimension with the specified role.
113 * @param dimensions Vector of dimension descriptors to search
114 * @param role Dimension role to find
115 * @return Index of the dimension with the specified role
116 */
117 [[nodiscard]] size_t get_dimension_index_for_role(const std::vector<DataDimension>& dimensions,
118 DataDimension::Role role) const;
119
120 /**
121 * @brief Get total elements across all dimensions.
122 * @param dimensions Vector of dimension descriptors
123 * @return Total number of elements
124 */
125 [[nodiscard]] static uint64_t get_total_elements(const std::vector<DataDimension>& dimensions);
126 [[nodiscard]] uint64_t get_total_elements() const { return get_total_elements(dimensions); }
127
128 /**
129 * @brief Extract sample count from dimensions.
130 * @param dimensions Vector of dimension descriptors
131 * @return Number of samples in the temporal dimension
132 */
133 [[nodiscard]] static uint64_t get_samples_count(const std::vector<DataDimension>& dimensions);
134 [[nodiscard]] uint64_t get_samples_count() const { return get_samples_count(dimensions); }
135
136 /**
137 * @brief Get samples per channel (time dimension only).
138 * @param dimensions Vector of dimension descriptors
139 * @return Number of samples per channel
140 */
141 [[nodiscard]] static uint64_t get_samples_count_per_channel(const std::vector<DataDimension>& dimensions);
142 [[nodiscard]] uint64_t get_samples_count_per_channel() const { return get_samples_count_per_channel(dimensions); }
143
144 /**
145 * @brief Extract channel count from dimensions.
146 * @param dimensions Vector of dimension descriptors
147 * @return Number of channels
148 */
149 [[nodiscard]] static uint64_t get_channel_count(const std::vector<DataDimension>& dimensions);
150 [[nodiscard]] uint64_t get_channel_count() const { return get_channel_count(dimensions); }
151
152 /**
153 * @brief Get pixel count (spatial dimensions only).
154 * @param dimensions Vector of dimension descriptors
155 * @return Number of pixels
156 */
157 [[nodiscard]] static uint64_t get_pixels_count(const std::vector<DataDimension>& dimensions);
158 [[nodiscard]] uint64_t get_pixels_count() const { return get_pixels_count(dimensions); }
159
160 /**
161 * @brief Extract height from image/video dimensions.
162 * @param dimensions Vector of dimension descriptors
163 * @return Height in pixels
164 */
165 [[nodiscard]] static uint64_t get_height(const std::vector<DataDimension>& dimensions);
166 [[nodiscard]] uint64_t get_height() const { return get_height(dimensions); }
167
168 /**
169 * @brief Extract width from image/video dimensions.
170 * @param dimensions Vector of dimension descriptors
171 * @return Width in pixels
172 */
173 [[nodiscard]] static uint64_t get_width(const std::vector<DataDimension>& dimensions);
174 [[nodiscard]] uint64_t get_width() const { return get_width(dimensions); }
175
176 /**
177 * @brief Extract frame count from video dimensions.
178 * @param dimensions Vector of dimension descriptors
179 * @return Number of frames
180 */
181 [[nodiscard]] static size_t get_frame_count(const std::vector<DataDimension>& dimensions);
182 [[nodiscard]] size_t get_frame_count() const { return get_frame_count(dimensions); }
183
184 /**
185 * @brief Extract the size of non time dimensions (channel, spatial, frequency)
186 * @param dimensions Vector of dimension descriptors
187 * @return cumulative size of non time dimensions
188 */
189 [[nodiscard]] static size_t get_frame_size(const std::vector<DataDimension>& dimensions);
190 [[nodiscard]] size_t get_frame_size() const { return get_frame_size(dimensions); }
191};
192
193/**
194 * @class NDDataContainer
195 * @brief Abstract interface for N-dimensional data containers.
196 *
197 * NDDataContainer provides a dimension-agnostic API for accessing and manipulating
198 * multi-dimensional data (audio, video, tensors, etc). It is designed for digital-first,
199 * data-driven workflows, enabling flexible, efficient, and generic processing of
200 * structured data without imposing analog metaphors or legacy constraints.
201 *
202 * Key features:
203 * - Arbitrary dimension support (not limited to 2D or 3D)
204 * - Explicit memory layout control (row-major/column-major)
205 * - Region-based access for efficient subsetting and streaming
206 * - Thread-safe locking for concurrent processing
207 * - Support for multiple data types and precisions
208 * - Designed for composability with processors, buffers, and computational nodes
209 *
210 * This interface is the foundation for all high-level data containers in Maya Flux,
211 * enabling advanced workflows such as real-time streaming, offline analysis, and
212 * hybrid computational models.
213 */
214class MAYAFLUX_API NDDataContainer {
215public:
216 virtual ~NDDataContainer() = default;
217
218 /**
219 * @brief Get the dimensions describing the structure of the data.
220 * @return Vector of DataDimension objects (one per axis)
221 */
222 [[nodiscard]] virtual std::vector<DataDimension> get_dimensions() const = 0;
223
224 /**
225 * @brief Get the total number of elements in the container.
226 * @return Product of all dimension sizes
227 */
228 [[nodiscard]] virtual uint64_t get_total_elements() const = 0;
229
230 /**
231 * @brief Get the memory layout used by this container.
232 * @return Current memory layout (row-major or column-major)
233 */
234 [[nodiscard]] virtual MemoryLayout get_memory_layout() const = 0;
235
236 /**
237 * @brief Set the memory layout for this container.
238 * @param layout New memory layout to use
239 * @note May trigger data reorganization if implementation supports both layouts
240 */
241 virtual void set_memory_layout(MemoryLayout layout) = 0;
242
243 /**
244 * @brief Get the number of elements that constitute one "frame".
245 * For audio: channels per sample. For images: pixels per frame.
246 * @return Number of elements per frame
247 */
248 [[nodiscard]] virtual uint64_t get_frame_size() const = 0;
249
250 /**
251 * @brief Get the number of frames in the primary (temporal) dimension.
252 * @return Number of frames
253 */
254 [[nodiscard]] virtual uint64_t get_num_frames() const = 0;
255
256 /**
257 * @brief Get data for a specific region.
258 * @param region The region to extract data from
259 * @return std::vector<DataVariant> containing the region's data
260 */
261 [[nodiscard]] virtual std::vector<DataVariant> get_region_data(const Region& region) const = 0;
262
263 /**
264 * @brief Get data for multiple regions efficiently.
265 * @param regions Vector of regions to extract data from
266 * @return Vector of DataVariant vectors, one per region
267 */
268 [[nodiscard]] virtual std::vector<DataVariant> get_region_group_data(const RegionGroup& regions) const = 0;
269
270 /**
271 * @brief Get data for multiple region segments efficiently.
272 * @param segments Vector of region segments to extract data from
273 * @return Vector of DataVariant vectors, one per segment
274 */
275 [[nodiscard]] virtual std::vector<DataVariant> get_segments_data(const std::vector<RegionSegment>& segments) const = 0;
276
277 /**
278 * @brief Set data for a specific region.
279 * @param region The region to write data to
280 * @param data The data to write
281 */
282 virtual void set_region_data(const Region& region, const std::vector<DataVariant>& data) = 0;
283
284 /**
285 * @brief Get a single frame of data efficiently.
286 * @param frame_index Index of the frame (in the temporal dimension)
287 * @return Span of data representing one complete frame
288 */
289 [[nodiscard]] virtual std::span<const double> get_frame(uint64_t frame_index) const = 0;
290
291 /**
292 * @brief Get multiple frames efficiently.
293 * @param output Buffer to write frames into
294 * @param start_frame First frame index
295 * @param num_frames Number of frames to retrieve
296 */
297 virtual void get_frames(std::span<double> output, uint64_t start_frame, uint64_t num_frames) const = 0;
298
299 /**
300 * @brief Get a single value at the specified coordinates.
301 * @param coordinates N-dimensional coordinates
302 * @return Value at the specified location
303 */
304 [[nodiscard]] virtual double get_value_at(const std::vector<uint64_t>& coordinates) const = 0;
305
306 /**
307 * @brief Set a single value at the specified coordinates.
308 * @param coordinates N-dimensional coordinates
309 * @param value Value to set
310 */
311 virtual void set_value_at(const std::vector<uint64_t>& coordinates, double value) = 0;
312
313 /**
314 * @brief Add a named group of regions to the container.
315 * @param group RegionGroup to add
316 */
317 virtual void add_region_group(const RegionGroup& group) = 0;
318
319 /**
320 * @brief Get a region group by name.
321 * @param name Name of the region group
322 * @return Reference to the RegionGroup
323 */
324 [[nodiscard]] virtual const RegionGroup& get_region_group(const std::string& name) const = 0;
325
326 /**
327 * @brief Get all region groups in the container.
328 * @return Map of region group names to RegionGroup objects
329 */
330 [[nodiscard]] virtual std::unordered_map<std::string, RegionGroup> get_all_region_groups() const = 0;
331
332 /**
333 * @brief Remove a region group by name.
334 * @param name Name of the region group to remove
335 */
336 virtual void remove_region_group(const std::string& name) = 0;
337
338 /**
339 * @brief Check if a region is loaded in memory.
340 * @param region Region to check
341 * @return true if region is loaded, false otherwise
342 */
343 [[nodiscard]] virtual bool is_region_loaded(const Region& region) const = 0;
344
345 /**
346 * @brief Load a region into memory.
347 * @param region Region to load
348 */
349 virtual void load_region(const Region& region) = 0;
350
351 /**
352 * @brief Unload a region from memory.
353 * @param region Region to unload
354 */
355 virtual void unload_region(const Region& region) = 0;
356
357 /**
358 * @brief Convert coordinates to linear index based on current memory layout.
359 * @param coordinates N-dimensional coordinates
360 * @return Linear index into the underlying data storage
361 */
362 [[nodiscard]] virtual uint64_t coordinates_to_linear_index(const std::vector<uint64_t>& coordinates) const = 0;
363
364 /**
365 * @brief Convert linear index to coordinates based on current memory layout.
366 * @param linear_index Linear index into the underlying data storage
367 * @return N-dimensional coordinates
368 */
369 [[nodiscard]] virtual std::vector<uint64_t> linear_index_to_coordinates(uint64_t linear_index) const = 0;
370
371 /**
372 * @brief Clear all data in the container.
373 */
374 virtual void clear() = 0;
375
376 /**
377 * @brief Acquire a lock for thread-safe access.
378 */
379 virtual void lock() = 0;
380
381 /**
382 * @brief Release a previously acquired lock.
383 */
384 virtual void unlock() = 0;
385
386 /**
387 * @brief Attempt to acquire a lock without blocking.
388 * @return true if lock was acquired, false otherwise
389 */
390 virtual bool try_lock() = 0;
391
392 /**
393 * @brief Get a raw pointer to the underlying data storage.
394 * @return Pointer to raw data (type depends on DataVariant)
395 */
396 [[nodiscard]] virtual const void* get_raw_data() const = 0;
397
398 /**
399 * @brief Check if the container currently holds any data.
400 * @return true if data is present, false otherwise
401 */
402 [[nodiscard]] virtual bool has_data() const = 0;
403
404 /**
405 * @brief Get the data structure defining this container's layout.
406 * @return Reference to the ContainerDataStructure
407 */
408 [[nodiscard]] virtual ContainerDataStructure& get_structure() = 0;
409 [[nodiscard]] virtual const ContainerDataStructure& get_structure() const = 0;
410
411 /**
412 * @brief Set the data structure for this container.
413 * @param structure New ContainerDataStructure to apply
414 * @note This may trigger reorganization of existing data to match the new structure.
415 */
416 virtual void set_structure(ContainerDataStructure structure) = 0;
417};
418
419} // namespace MayaFlux::Kakshya
virtual std::vector< DataVariant > get_region_group_data(const RegionGroup &regions) const =0
Get data for multiple regions efficiently.
virtual void set_region_data(const Region &region, const std::vector< DataVariant > &data)=0
Set data for a specific region.
virtual void unload_region(const Region &region)=0
Unload a region from memory.
virtual void clear()=0
Clear all data in the container.
virtual const RegionGroup & get_region_group(const std::string &name) const =0
Get a region group by name.
virtual void set_value_at(const std::vector< uint64_t > &coordinates, double value)=0
Set a single value at the specified coordinates.
virtual std::span< const double > get_frame(uint64_t frame_index) const =0
Get a single frame of data efficiently.
virtual void add_region_group(const RegionGroup &group)=0
Add a named group of regions to the container.
virtual double get_value_at(const std::vector< uint64_t > &coordinates) const =0
Get a single value at the specified coordinates.
virtual const ContainerDataStructure & get_structure() const =0
virtual void get_frames(std::span< double > output, uint64_t start_frame, uint64_t num_frames) const =0
Get multiple frames efficiently.
virtual bool has_data() const =0
Check if the container currently holds any data.
virtual bool try_lock()=0
Attempt to acquire a lock without blocking.
virtual std::vector< DataDimension > get_dimensions() const =0
Get the dimensions describing the structure of the data.
virtual void set_memory_layout(MemoryLayout layout)=0
Set the memory layout for this container.
virtual ContainerDataStructure & get_structure()=0
Get the data structure defining this container's layout.
virtual void load_region(const Region &region)=0
Load a region into memory.
virtual void set_structure(ContainerDataStructure structure)=0
Set the data structure for this container.
virtual std::unordered_map< std::string, RegionGroup > get_all_region_groups() const =0
Get all region groups in the container.
virtual bool is_region_loaded(const Region &region) const =0
Check if a region is loaded in memory.
virtual void remove_region_group(const std::string &name)=0
Remove a region group by name.
virtual void unlock()=0
Release a previously acquired lock.
virtual void lock()=0
Acquire a lock for thread-safe access.
virtual const void * get_raw_data() const =0
Get a raw pointer to the underlying data storage.
virtual std::vector< DataVariant > get_segments_data(const std::vector< RegionSegment > &segments) const =0
Get data for multiple region segments efficiently.
virtual std::vector< DataVariant > get_region_data(const Region &region) const =0
Get data for a specific region.
virtual MemoryLayout get_memory_layout() const =0
Get the memory layout used by this container.
virtual uint64_t coordinates_to_linear_index(const std::vector< uint64_t > &coordinates) const =0
Convert coordinates to linear index based on current memory layout.
virtual uint64_t get_frame_size() const =0
Get the number of elements that constitute one "frame".
virtual uint64_t get_total_elements() const =0
Get the total number of elements in the container.
virtual uint64_t get_num_frames() const =0
Get the number of frames in the primary (temporal) dimension.
virtual std::vector< uint64_t > linear_index_to_coordinates(uint64_t linear_index) const =0
Convert linear index to coordinates based on current memory layout.
Abstract interface for N-dimensional data containers.
DataModality
Data modality types for cross-modal analysis.
Definition NDData.hpp:78
MemoryLayout
Memory layout for multi-dimensional data.
Definition NDData.hpp:36
OrganizationStrategy
Data organization strategy for multi-channel/multi-frame data.
Definition NDData.hpp:46
Container structure for consistent dimension ordering.
Role
Semantic role of the dimension.
Definition NDData.hpp:145
Organizes related signal regions into a categorized collection.
Represents a point or span in N-dimensional space.
Definition Region.hpp:67