aqnwb 0.4.0
Loading...
Searching...
No Matches
DynamicTable.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <any>
4#include <optional>
5#include <string>
6#include <unordered_map>
7
8#include "Utils.hpp"
9#include "io/BaseIO.hpp"
10#include "io/ReadIO.hpp"
15#include "spec/hdmf_common.hpp"
16
17namespace AQNWB::NWB
18{
19class MeaningsTable;
20} // namespace AQNWB::NWB
21
22namespace AQNWB::NWB
23{
31class DynamicTable : public Container
32{
33public:
35 using DataSpecPtr = std::shared_ptr<DataSpec>;
36
37public:
39 using RowData = std::unordered_map<std::string, CellValue>;
40
41 // Register the TimeSeries as a subclass of Container
45
46protected:
52 DynamicTable(const std::string& path, std::shared_ptr<IO::BaseIO> io);
53
54public:
58 ~DynamicTable() override;
59
71 Status initialize(const std::string& description,
72 const std::vector<DataSpecPtr>& dataSpecs = {});
73
86 const std::vector<DataSpecPtr>& dataSpecs) const;
87
98 static std::vector<DataSpecPtr> createDefaultDataSpecs(
99 const SizeType rowChunkSize = 100);
100
108 Status finalize() override;
109
120 Status addColumn(const std::shared_ptr<VectorData>& vectorData,
121 const std::vector<std::string>& values);
122
137 Status addColumn(const DataSpecPtr& dataSpec);
138
149 Status addColumn(const std::shared_ptr<VectorData>& vectorData);
150
158 Status addReferenceColumn(const std::string& name,
159 const std::string& colDescription,
160 const std::vector<std::string>& dataset);
161
169 const std::optional<int>& rowId = std::nullopt);
170
177 Status addRows(const std::vector<AQNWB::Types::RowData>& rows,
178 const std::vector<int>& rowIds = {});
179
185
199 std::vector<AQNWB::Types::RowData> readRows(
200 SizeType start = 0,
202 const std::vector<std::string>& colNames = {},
203 bool includeId = true);
204
215 std::string toString(SizeType start = 0,
217 const std::vector<std::string>& colNames = {},
218 bool includeId = true);
219
225 Status setRowIDs(const std::vector<int>& values);
226
239 virtual void setColNames(const std::vector<std::string>& newColNames);
240
257 std::shared_ptr<MeaningsTable> createMeaningsTable(
258 const std::string& columnName, const SizeType rowChunkSize = 100);
259
266 template<typename T>
268 {
269 using type =
270 typename std::conditional<std::is_base_of<VectorData, T>::value,
271 T,
273 };
274
281 template<typename T>
282 struct IsVectorDataTyped : std::false_type
283 {
284 };
285
286 template<typename DTYPE>
287 struct IsVectorDataTyped<VectorDataTyped<DTYPE>> : std::true_type
288 {
289 };
290
307 template<typename T = std::any>
308 std::shared_ptr<typename ColumnReturnType<T>::type> readColumn(
309 const std::string& colName)
310 {
311 using ReturnType = typename ColumnReturnType<T>::type;
312 std::string columnPath = AQNWB::mergePaths(m_path, colName);
313 auto ioPtr = getIO();
314 if (ioPtr != nullptr) {
315 if (ioPtr->objectExists(columnPath)) {
316 if (ioPtr->getStorageObjectType(columnPath)
317 == StorageObjectType::Dataset)
318 {
319 if constexpr (std::is_base_of<VectorData, T>::value
321 {
322 // Resolve the concrete on-disk registered type before caching it.
323 auto column = RegisteredType::create(columnPath, ioPtr);
324 return std::dynamic_pointer_cast<ReturnType>(column);
325 } else {
326 return ReturnType::create(columnPath, ioPtr);
327 }
328 }
329 }
330 } else {
331 std::cerr << "IO object has been deleted. Can't read column: " << colName
332 << " in DynamicTable: " << m_path << std::endl;
333 }
334 return nullptr;
335 }
336
338 std::string,
339 "colnames",
340 The names of the columns in the table)
341
343 std::string,
344 "description",
345 Description of what is in this dynamic table)
346
350 "id",
351 "unique identifiers for the rows of this dynamic table")
352
353
365 std::shared_ptr<MeaningsTable> readMeaningsTable(
366 const std::string& objectName) const;
367
383 const std::string& objectName) const;
384
385protected:
397 SizeType addColumnName(const std::string& colName);
398
407
409
414 {
415 std::string name;
417 std::shared_ptr<VectorData>
419 };
420
433 std::shared_ptr<VectorData> getConfiguredColumn(
434 const std::string& name) const;
435
444 SizeType registerColumn(const std::shared_ptr<VectorData>& column);
445
453 void clearColumns();
454
461 Status configureDataObjects(const std::vector<DataSpecPtr>& dataSpecs);
462
469 Status configureDataObject(const DataSpec& dataSpec);
470
482
493
508 template<typename RequiredDataSpec>
509 Status checkRequiredColumnSpec(const std::string& requiredName,
510 const std::vector<DataSpecPtr>& dataSpecs,
511 const std::optional<IO::BaseDataType>&
512 expectedDataType = std::nullopt) const
513 {
514 bool found = false;
515 for (const auto& spec : dataSpecs) {
516 if (!spec || spec->name != requiredName) {
517 continue;
518 }
519
520 found = true;
521 if (!std::dynamic_pointer_cast<RequiredDataSpec>(spec)) {
522 std::cerr << "DynamicTable::checkRequiredColumnSpec: required column '"
523 << requiredName
524 << "' does not use the required concrete DataSpec type."
525 << std::endl;
526 return Status::Failure;
527 }
528 if (spec->getShape().size() != 1) {
529 std::cerr << "DynamicTable::checkRequiredColumnSpec: required column '"
530 << requiredName << "' must be one-dimensional." << std::endl;
531 return Status::Failure;
532 }
533 if (expectedDataType.has_value()
534 && !(spec->getType() == expectedDataType.value()))
535 {
536 std::cerr << "DynamicTable::checkRequiredColumnSpec: required column '"
537 << requiredName << "' has an invalid data type." << std::endl;
538 return Status::Failure;
539 }
540 }
541
542 if (!found) {
543 std::cerr << "DynamicTable::checkRequiredColumnSpec: required column '"
544 << requiredName << "' not found." << std::endl;
545 return Status::Failure;
546 }
547 return Status::Success;
548 }
549
563 const ConfiguredColumn& configuredColumn,
565 SizeType rowCount);
566
573 std::vector<int> generateRowIDs(SizeType rowCount);
574
578 std::vector<std::string> m_colNames;
579
583 std::shared_ptr<ElementIdentifiers> m_rowElementIdentifiers;
584
588 std::vector<ConfiguredColumn> m_configuredColumns;
589
593 std::unordered_map<std::string, SizeType> m_configuredColumnIndices;
594};
595} // namespace AQNWB::NWB
AQNWB::Types::Status Status
Definition BaseIO.hpp:21
AQNWB::Types::SizeType SizeType
Definition Channel.hpp:8
#define REGISTER_SUBCLASS(T, BASE, NAMESPACE)
Macro to register a subclass with the RegisteredType class registry.
Definition RegisteredType.hpp:547
#define DEFINE_ATTRIBUTE_FIELD(name, default_type, fieldPath, description)
Defines a lazy-loaded attribute field accessor function.
Definition RegisteredType.hpp:580
#define DEFINE_REGISTERED_FIELD(name, registeredType, fieldPath, description)
Defines a lazy-loaded accessor function for reading fields that are RegisteredTypes.
Definition RegisteredType.hpp:672
Represents a base data type.
Definition BaseIO.hpp:47
AQNWB::Types::VectorDataVariant BaseDataVectorVariant
Definition BaseIO.hpp:104
Container(const std::string &path, std::shared_ptr< IO::BaseIO > io)
Constructor.
Definition Container.cpp:10
Status initialize()
Initialize the container.
Definition Container.cpp:20
Status flushColNames()
Flush the column names to the file.
Definition DynamicTable.cpp:714
std::vector< std::string > m_colNames
Names of the columns in the table.
Definition DynamicTable.hpp:578
std::vector< ConfiguredColumn > m_configuredColumns
Ordered list of configured columns managed by the table.
Definition DynamicTable.hpp:588
Status addRows(const std::vector< AQNWB::Types::RowData > &rows, const std::vector< int > &rowIds={})
Adds multiple rows to the table.
Definition DynamicTable.cpp:393
SizeType addColumnName(const std::string &colName)
Add a column name to m_colNames while preventing duplicates.
Definition DynamicTable.cpp:113
std::unique_ptr< AQNWB::IO::ReadDataWrapper< AQNWB::NWB::AttributeField, VTYPE > > readDescription() const
Status configureDataObjects(const std::vector< DataSpecPtr > &dataSpecs)
Configure multiple data objects.
Definition DynamicTable.cpp:849
SizeType registerColumn(const std::shared_ptr< VectorData > &column)
Register a column in the table's column registry.
Definition DynamicTable.cpp:898
std::shared_ptr< MeaningsTable > createMeaningsTableInstance(const std::string &objectName) const
Returns the instance of the class representing the named MeaningsTable field for write.
Definition DynamicTable.cpp:817
Status writeColumnBuffer(const ConfiguredColumn &configuredColumn, const IO::BaseDataType::BaseDataVectorVariant &buffer, SizeType rowCount)
Write a buffer of data to a configured column.
virtual Status validateDataSpecs(const std::vector< DataSpecPtr > &dataSpecs) const
Validates the provided data specifications for the table.
Definition DynamicTable.cpp:73
std::shared_ptr< MeaningsTable > readMeaningsTable(const std::string &objectName) const
Returns the instance of the class representing the named MeaningsTable field.
Definition DynamicTable.cpp:800
std::shared_ptr< typename ColumnReturnType< T >::type > readColumn(const std::string &colName)
Read an arbitrary column of the DynamicTable.
Definition DynamicTable.hpp:308
virtual void setColNames(const std::vector< std::string > &newColNames)
Sets the column names of the DynamicTable.
Definition DynamicTable.cpp:89
DynamicTable(const std::string &path, std::shared_ptr< IO::BaseIO > io)
Constructor.
Definition DynamicTable.cpp:19
Data::DataSpecBase DataSpec
Definition DynamicTable.hpp:34
~DynamicTable() override
Destructor.
Definition DynamicTable.cpp:41
std::shared_ptr< MeaningsTable > createMeaningsTable(const std::string &columnName, const SizeType rowChunkSize=100)
Create a MeaningsTable for a specific VectorData column in this DynamicTable.
Definition DynamicTable.cpp:737
Status addRow(const AQNWB::Types::RowData &row, const std::optional< int > &rowId=std::nullopt)
Adds a single row to the table.
Definition DynamicTable.cpp:202
std::shared_ptr< DataSpec > DataSpecPtr
Definition DynamicTable.hpp:35
std::unordered_map< std::string, SizeType > m_configuredColumnIndices
Lookup map from column name to its index in m_configuredColumns.
Definition DynamicTable.hpp:593
SizeType getNumberOfRows() const
Get the number of rows in the table.
Definition DynamicTable.cpp:212
Status checkRequiredColumnSpec(const std::string &requiredName, const std::vector< DataSpecPtr > &dataSpecs, const std::optional< IO::BaseDataType > &expectedDataType=std::nullopt) const
Validate the concrete specification, shape, and optionally data type of a required column.
Definition DynamicTable.hpp:509
std::unique_ptr< AQNWB::IO::ReadDataWrapper< AQNWB::NWB::AttributeField, VTYPE > > readColNames() const
Status loadConfiguredColumnsFromFile()
Load all configured columns and row element identifiers from the file.
Definition DynamicTable.cpp:945
Status setRowIDs(const std::vector< int > &values)
Sets the values of the element identifiers on the table.
Definition DynamicTable.cpp:172
static std::vector< DataSpecPtr > createDefaultDataSpecs(const SizeType rowChunkSize=100)
Create the default data specs for a DynamicTable.
Definition DynamicTable.cpp:80
Status addReferenceColumn(const std::string &name, const std::string &colDescription, const std::vector< std::string > &dataset)
Adds a column of references to the table.
Definition DynamicTable.cpp:682
Status addColumn(const std::shared_ptr< VectorData > &vectorData, const std::vector< std::string > &values)
Adds a column of vector string data to the table.
Definition DynamicTable.cpp:137
Status ensureConfiguredColumnsLoaded()
Ensure that all configured columns are loaded from the file.
Definition DynamicTable.cpp:937
std::vector< AQNWB::Types::RowData > readRows(SizeType start=0, SizeType count=Types::SizeTypeNotSet, const std::vector< std::string > &colNames={}, bool includeId=true)
Read rows from the table.
Definition DynamicTable.cpp:225
std::string toString(SizeType start=0, SizeType count=Types::SizeTypeNotSet, const std::vector< std::string > &colNames={}, bool includeId=true)
Convert the table to a string representation.
Definition DynamicTable.cpp:319
std::vector< int > generateRowIDs(SizeType rowCount)
Generate row IDs for the table.
Definition DynamicTable.cpp:977
AQNWB::NWB::CellValue CellValue
Definition DynamicTable.hpp:38
std::shared_ptr< ElementIdentifiers > m_rowElementIdentifiers
The row ids data object for write.
Definition DynamicTable.hpp:583
std::shared_ptr< VectorData > getConfiguredColumn(const std::string &name) const
Look up an already-configured column by name.
Definition DynamicTable.cpp:831
std::unordered_map< std::string, CellValue > RowData
Definition DynamicTable.hpp:39
Status finalize() override
Finalizes writing the DynamicTable.
Definition DynamicTable.cpp:731
std::shared_ptr< RTYPE > readIdColumn() const
Status configureDataObject(const DataSpec &dataSpec)
Configure a single data object.
Definition DynamicTable.cpp:866
void clearColumns()
Clear all registered columns and column names.
Definition DynamicTable.cpp:841
A list of unique identifiers for values within a dataset, e.g. rows of a DynamicTable.
Definition ElementIdentifiers.hpp:13
A table to store information about the meanings of values in a referenced VectorData object....
Definition MeaningsTable.hpp:38
std::string m_path
The path of the registered type.
Definition RegisteredType.hpp:471
static std::shared_ptr< RegisteredType > create(const std::string &fullClassName, const std::string &path, std::shared_ptr< IO::BaseIO > io, bool fallbackToBase=false)
Create or retrieve the canonical instance of a registered subclass.
Definition RegisteredType.cpp:87
std::shared_ptr< AQNWB::IO::BaseIO > getIO() const
Get a shared pointer to the IO object.
Definition RegisteredType.hpp:77
A typed n-dimensional dataset representing a column of a DynamicTable.
Definition VectorData.hpp:143
Namespace for all classes related to the NWB data standard.
AQNWB::Types::CellValue CellValue
Definition Data.hpp:14
const std::string namespaceName
Definition hdmf_common.hpp:21
constexpr SizeType SizeTypeNotSet
Value to use to indicate that a SizeType index is not set.
Definition Types.hpp:109
std::unordered_map< std::string, CellValue > RowData
Represents a row of data in a DynamicTable.
Definition Types.hpp:372
static std::string mergePaths(const std::string &path1, const std::string &path2)
Merge two paths into a single path, handling extra trailing and starting "/".
Definition Utils.hpp:264
Non-templated base class for runtime Data configuration.
Definition Data.hpp:33
Type trait to determine the return type of readColumn.
Definition DynamicTable.hpp:268
typename std::conditional< std::is_base_of< VectorData, T >::value, T, VectorDataTyped< T > >::type type
Definition DynamicTable.hpp:269
Internal state structure tracking a configured table column.
Definition DynamicTable.hpp:414
IO::BaseDataType dataType
The underlying data type.
Definition DynamicTable.hpp:416
std::shared_ptr< VectorData > column
Shared pointer to the column dataset.
Definition DynamicTable.hpp:418
std::string name
The column name.
Definition DynamicTable.hpp:415
Type trait identifying non-registered typed VectorData facades.
Definition DynamicTable.hpp:283