31 return *std::static_pointer_cast<PlotProcessor>(
m_processor);
41 m_data.emplace_back(std::vector<double>(
count, 0.0));
47 MF_INFO(C, X,
"PlotContainer: added series '{}' at index {} ({} samples, role={}, modality={})",
49 static_cast<int>(role),
57 if (index >=
m_data.size()) {
58 MF_ERROR(C, X,
"PlotContainer::write_series: index {} out of range", index);
62 auto* vec = std::get_if<std::vector<double>>(&
m_data[index]);
64 MF_ERROR(C, X,
"PlotContainer::write_series: series {} has unexpected variant type", index);
68 const uint64_t n = std::min<uint64_t>(samples.size(), vec->size());
69 std::copy_n(samples.begin(), n, vec->begin());
74 if (index >=
m_data.size()) {
75 MF_ERROR(C, X,
"PlotContainer::write_sample: series index {} out of range", index);
79 auto* vec = std::get_if<std::vector<double>>(&
m_data[index]);
80 if (!vec || sample_index >= vec->size()) {
81 MF_ERROR(C, X,
"PlotContainer::write_sample: sample index {} out of range in series {}", sample_index, index);
85 (*vec)[sample_index] = value;
90 if (index >=
m_data.size()) {
91 MF_ERROR(C, X,
"PlotContainer::resize_series: index {} out of range", index);
95 auto* vec = std::get_if<std::vector<double>>(&
m_data[index]);
99 vec->resize(
count, 0.0);
103 pv->resize(
count, 0.0);
115 static const std::string empty;
123 if (index >=
m_data.size())
125 const auto* vec = std::get_if<std::vector<double>>(&
m_data[index]);
126 return vec ?
static_cast<uint64_t
>(vec->size()) : 0;
143 p.bind_node(series_index, std::move(node));
150 std::shared_ptr<Buffers::AudioBuffer> buffer)
153 p.bind_audio_buffer(series_index, std::move(buffer));
160 std::shared_ptr<Nodes::Network::NodeNetwork>
network)
163 p.bind_network(series_index, std::move(
network));
170 std::function<
void(std::vector<double>&)> fn)
173 p.bind_callable(series_index, std::move(fn));
182 p.set_raw(series_index, std::move(data));
191 std::static_pointer_cast<PlotProcessor>(
m_processor)->unbind(series_index);
206 for (
const auto& v :
m_data) {
207 const auto* vec = std::get_if<std::vector<double>>(&v);
209 total += vec->size();
216 return static_cast<uint64_t
>(
m_data.size());
225 if (series_idx >=
m_data.size())
228 const auto* src = std::get_if<std::vector<double>>(&
m_data[series_idx]);
229 if (!src || src->empty())
234 ? std::min(region.
end_coordinates[1],
static_cast<uint64_t
>(src->size() - 1))
235 :
static_cast<uint64_t
>(src->size() - 1);
240 std::vector<double> slice(src->begin() +
static_cast<ptrdiff_t
>(s),
241 src->begin() +
static_cast<ptrdiff_t
>(e + 1));
251 if (series_idx >=
m_data.size())
254 auto* dst = std::get_if<std::vector<double>>(&
m_data[series_idx]);
258 const auto* src = std::get_if<std::vector<double>>(&data[0]);
259 if (!src || src->empty())
264 ? std::min(region.
end_coordinates[1],
static_cast<uint64_t
>(dst->size() - 1))
265 :
static_cast<uint64_t
>(dst->size() - 1);
270 const uint64_t n = std::min<uint64_t>(src->size(), e - s + 1);
271 std::copy_n(src->begin(), n, dst->begin() +
static_cast<ptrdiff_t
>(s));
276 std::vector<DataVariant> result;
277 for (
const auto& r : group.
regions) {
279 for (
auto& v : slice)
280 result.push_back(std::move(v));
292 if (frame_index >=
m_data.size())
294 const auto* vec = std::get_if<std::vector<double>>(&
m_data[frame_index]);
295 if (!vec || vec->empty())
297 return { vec->data(), vec->size() };
303 for (uint64_t i = start_frame; i < start_frame + num_frames && i <
m_data.size(); ++i) {
304 const auto* vec = std::get_if<std::vector<double>>(&
m_data[i]);
307 for (
double v : *vec) {
308 if (out >= output.size())
317 if (coordinates.size() < 2 || coordinates[0] >=
m_data.size())
319 const auto* vec = std::get_if<std::vector<double>>(&
m_data[coordinates[0]]);
320 if (!vec || coordinates[1] >= vec->size())
322 return (*vec)[coordinates[1]];
327 if (coordinates.size() < 2 || coordinates[0] >=
m_data.size())
329 auto* vec = std::get_if<std::vector<double>>(&
m_data[coordinates[0]]);
330 if (!vec || coordinates[1] >= vec->size())
332 (*vec)[coordinates[1]] = value;
337 if (coordinates.size() < 2)
339 return coordinates[1];
344 return { 0, linear };
359 const auto* vec = std::get_if<std::vector<double>>(&
m_data[0]);
360 return (vec && !vec->empty()) ? vec->data() :
nullptr;
370 if (index >=
m_data.size()) {
372 static std::vector<DataDimension> empty_dims;
380 std::vector<DataAccess> result;
381 result.reserve(
m_data.size());
382 for (
size_t i = 0; i <
m_data.size(); ++i) {
383 result.emplace_back(
m_data[i],
430 std::function<
void(
const std::shared_ptr<SignalSourceContainer>&,
ProcessingState)> cb)
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
Core::GlobalNetworkConfig network
Type-erased accessor for NDData with semantic view construction.
void bind(uint32_t series_index, std::shared_ptr< Nodes::Node > node)
Bind a series to a Node.
std::span< const double > get_frame(uint64_t frame_index) const override
Get a single frame of data efficiently.
std::unordered_map< std::string, RegionGroup > get_all_region_groups() const override
Get all region groups in the container.
PlotProcessor & ensure_processor()
Return the PlotProcessor, creating and attaching it if absent.
std::vector< DataAccess > all_channel_data() override
Get all channel data as accessors.
void unbind(uint32_t series_index)
Remove the source binding for a series.
std::vector< DataVariant > m_data
void mark_ready_for_processing(bool ready) override
Mark the container as ready or not ready for processing.
void remove_region_group(const std::string &name) override
Remove a region group by name.
PlotContainer()
Construct an empty container.
std::function< void(const std::shared_ptr< SignalSourceContainer > &, ProcessingState)> m_state_cb
std::atomic< ProcessingState > m_processing_state
void write_series(uint32_t index, std::span< const double > samples)
Write the full sample buffer for a series.
uint32_t add_series(std::string name, uint64_t count, DataDimension::Role role=DataDimension::Role::CUSTOM, DataModality modality=DataModality::TENSOR_ND)
Add a named series with a given capacity, zero-initialised.
std::unordered_map< std::string, RegionGroup > m_region_groups
void set_value_at(const std::vector< uint64_t > &coordinates, double value) override
Set a single value at the specified coordinates.
std::vector< DataDimension > get_dimensions() const override
Get the dimensions describing the structure of the data.
bool has_data() const override
Check if the container currently holds any data.
void write_sample(uint32_t index, uint64_t sample_index, double value)
Write a single sample within a series.
std::vector< DataVariant > get_region_data(const Region ®ion) const override
Extract a sample range from a single series.
std::vector< DataVariant > m_processed_data
ContainerDataStructure m_structure
std::vector< DataVariant > get_region_group_data(const RegionGroup &group) const override
Get data for multiple regions efficiently.
const void * get_raw_data() const override
Get a raw pointer to the underlying data storage.
const RegionGroup & get_region_group(const std::string &name) const override
Get a region group by name.
uint64_t coordinates_to_linear_index(const std::vector< uint64_t > &coordinates) const override
Convert coordinates to linear index based on current memory layout.
const std::string & series_name(uint32_t index) const
Return the name of a series.
void resize_series(uint32_t index, uint64_t count)
Resize a series.
uint64_t series_size(uint32_t index) const
Return the sample count of a series.
void process_default() override
Process the container's data using the default processor.
uint32_t series_count() const
Return the number of series.
void create_default_processor() override
Create and configure a default processor for this container.
DataAccess channel_data(size_t index) override
Get channel data with semantic interpretation.
void set_default_processor(const std::shared_ptr< DataProcessor > &processor) override
Set the default data processor for this container.
std::shared_ptr< DataProcessor > get_default_processor() const override
Get the current default data processor.
void clear() override
Clear all data in the container.
uint64_t get_total_elements() const override
Get the total number of elements in the container.
void update_processing_state(ProcessingState state) override
Update the processing state of the container.
std::vector< uint64_t > linear_index_to_coordinates(uint64_t linear_index) const override
Convert linear index to coordinates based on current memory layout.
std::vector< DataVariant > get_segments_data(const std::vector< RegionSegment > &segments) const override
Get data for multiple region segments efficiently.
void add_region_group(const RegionGroup &group) override
Add a named group of regions to the container.
void unregister_state_change_callback() override
Unregister the state change callback, if any.
std::shared_ptr< DataProcessor > m_processor
void set_raw(uint32_t series_index, std::vector< double > data)
Push raw sample data into a series.
void get_frames(std::span< double > output, uint64_t start_frame, uint64_t num_frames) const override
Get multiple frames efficiently.
bool is_ready_for_processing() const override
Check if the container is ready for processing.
void register_state_change_callback(std::function< void(const std::shared_ptr< SignalSourceContainer > &, ProcessingState)> cb) override
Register a callback to be invoked on processing state changes.
ProcessingState get_processing_state() const override
Get the current processing state of the container.
double get_value_at(const std::vector< uint64_t > &coordinates) const override
Get a single value at the specified coordinates.
DataDimension::Role series_role(uint32_t index) const
Return the role of a series.
void set_region_data(const Region ®ion, const std::vector< DataVariant > &data) override
Write a sample range back into a series.
uint64_t get_num_frames() const override
Get the number of frames in the primary (temporal) dimension.
DataProcessor that acquires per-series data from heterogeneous sources and writes into PlotContainer:...
@ ContainerProcessing
Container operations (Kakshya - file/stream/region processing)
@ 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.
@ IDLE
Container is inactive with no data or not ready for processing.
@ PROCESSING
Container is actively being processed.
@ PROCESSED
Container has completed processing and results are available.
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.
DataModality
Data modality types for cross-modal analysis.
@ TENSOR_ND
N-dimensional tensor.
@ ROW_MAJOR
C/C++ style (last dimension varies fastest)
@ PLANAR
Separate DataVariant per logical unit (LLL...RRR for stereo)
std::string_view modality_to_string(DataModality modality)
Convert DataModality enum to string representation.
std::vector< DataDimension > dimensions
Container structure for consistent dimension ordering.
Role
Semantic role of the dimension.
@ CUSTOM
User-defined or application-specific.
std::vector< Region > regions
Collection of regions belonging to this group.
std::string name
Descriptive name of the group.
Organizes related signal regions into a categorized collection.
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.