aqnwb 0.1.0
Loading...
Searching...
No Matches
RegisteredType.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <filesystem>
4#include <functional>
5#include <memory>
6#include <string>
7#include <unordered_map>
8#include <unordered_set>
9
10#include "Types.hpp"
11#include "Utils.hpp"
12#include "io/BaseIO.hpp"
13#include "io/ReadIO.hpp"
14
15namespace AQNWB
16{
17namespace NWB
18{
19
23constexpr auto AttributeField = AQNWB::Types::StorageObjectType::Attribute;
24
28constexpr auto DatasetField = AQNWB::Types::StorageObjectType::Dataset;
29
48{
49public:
59 RegisteredType(const std::string& path,
60 std::shared_ptr<AQNWB::IO::BaseIO> io);
61
65 virtual ~RegisteredType();
66
71 inline std::string getPath() const { return m_path; }
72
80 inline std::string getName() const
81 {
82 return std::filesystem::path(m_path).filename().string();
83 }
84
89 inline std::shared_ptr<AQNWB::IO::BaseIO> getIO() const { return m_io; }
90
95 inline void clearRecordingDataCache() { this->m_recordingDataCache.clear(); }
96
101 inline const std::unordered_map<std::string,
102 std::shared_ptr<IO::BaseRecordingData>>&
104 {
105 return this->m_recordingDataCache;
106 }
107
119 static std::unordered_set<std::string>& getRegistry();
120
132 static std::unordered_map<
133 std::string,
134 std::pair<std::function<std::unique_ptr<RegisteredType>(
135 const std::string&, std::shared_ptr<AQNWB::IO::BaseIO>)>,
136 std::pair<std::string, std::string>>>&
138
154 static std::shared_ptr<RegisteredType> create(
155 const std::string& fullClassName,
156 const std::string& path,
157 std::shared_ptr<IO::BaseIO> io,
158 bool fallbackToBase = false);
159
180 static std::shared_ptr<AQNWB::NWB::RegisteredType> create(
181 const std::string& path,
182 std::shared_ptr<IO::BaseIO> io,
183 bool fallbackToBase = false);
184
194 template<typename T>
195 static inline std::shared_ptr<T> create(const std::string& path,
196 std::shared_ptr<AQNWB::IO::BaseIO> io)
197 {
198 static_assert(std::is_base_of<RegisteredType, T>::value,
199 "T must be a derived class of RegisteredType");
200 return std::shared_ptr<T>(new T(path, io));
201 }
202
213 virtual std::string getTypeName() const;
214
226 virtual std::string getNamespace() const;
227
236 inline std::string getFullTypeName() const
237 {
238 return (getNamespace() + "::" + getTypeName());
239 }
240
261 template<StorageObjectType SOT,
262 typename VTYPE,
263 typename std::enable_if<Types::IsDataStorageObjectType<SOT>::value,
264 int>::type = 0>
265 inline std::unique_ptr<AQNWB::IO::ReadDataWrapper<SOT, VTYPE>> readField(
266 const std::string& fieldPath) const
267 {
268 return std::make_unique<AQNWB::IO::ReadDataWrapper<SOT, VTYPE>>(
269 m_io, AQNWB::mergePaths(m_path, fieldPath));
270 }
271
280 inline std::shared_ptr<AQNWB::NWB::RegisteredType> readField(
281 const std::string& fieldPath) const
282 {
283 return this->create(AQNWB::mergePaths(m_path, fieldPath), m_io);
284 }
285
304 virtual std::unordered_map<std::string, std::string> findOwnedTypes(
305 const std::unordered_set<std::string>& types = {},
306 const AQNWB::IO::SearchMode& search_mode =
308
309protected:
312 static const std::string m_defaultUnregisteredGroupTypeClass;
313
317
327 static void registerSubclass(
328 const std::string& fullClassName,
329 std::function<std::unique_ptr<RegisteredType>(
330 const std::string&, std::shared_ptr<AQNWB::IO::BaseIO>)>
331 factoryFunction,
332 const std::string& typeName,
333 const std::string& typeNamespace);
334
338 std::string m_path;
339
343 std::shared_ptr<IO::BaseIO> m_io;
344
357 std::unordered_map<std::string, std::shared_ptr<IO::BaseRecordingData>>
359};
360
378#define REGISTER_SUBCLASS_WITH_TYPENAME(T, NAMESPACE_VAR, TYPENAME) \
379 static bool registerSubclass() \
380 { \
381 AQNWB::NWB::RegisteredType::registerSubclass( \
382 std::string(NAMESPACE_VAR) + "::" + #T, \
383 [](const std::string& path, std::shared_ptr<AQNWB::IO::BaseIO> io) \
384 -> std::unique_ptr<AQNWB::NWB::RegisteredType> \
385 { return std::make_unique<T>(path, io); }, \
386 TYPENAME, \
387 NAMESPACE_VAR); \
388 return true; \
389 } \
390 static bool registered_; \
391 virtual std::string getTypeName() const override \
392 { \
393 return TYPENAME; \
394 } \
395 virtual std::string getNamespace() const override \
396 { \
397 return NAMESPACE_VAR; \
398 }
399
410#define REGISTER_SUBCLASS(T, NAMESPACE) \
411 REGISTER_SUBCLASS_WITH_TYPENAME(T, NAMESPACE, #T)
412
422#define REGISTER_SUBCLASS_IMPL(T) bool T::registered_ = T::registerSubclass();
423
443#define DEFINE_ATTRIBUTE_FIELD(name, default_type, fieldPath, description) \
444 \
452 template<typename VTYPE = default_type> \
453 inline std::unique_ptr<AQNWB::IO::ReadDataWrapper<AttributeField, VTYPE>> \
454 name() const \
455 { \
456 return std::make_unique< \
457 AQNWB::IO::ReadDataWrapper<AttributeField, VTYPE>>( \
458 m_io, AQNWB::mergePaths(m_path, fieldPath)); \
459 }
460
482#define DEFINE_DATASET_FIELD( \
483 readName, writeName, default_type, fieldPath, description) \
484 \
492 template<typename VTYPE = default_type> \
493 inline std::unique_ptr< \
494 AQNWB::IO::ReadDataWrapper<AQNWB::NWB::DatasetField, VTYPE>> \
495 readName() const \
496 { \
497 return std::make_unique< \
498 AQNWB::IO::ReadDataWrapper<AQNWB::NWB::DatasetField, VTYPE>>( \
499 m_io, AQNWB::mergePaths(m_path, fieldPath)); \
500 } \
501 \
514 inline std::shared_ptr<AQNWB::IO::BaseRecordingData> writeName(bool reset = \
515 false) \
516 { \
517 std::string fullPath = AQNWB::mergePaths(m_path, fieldPath); \
518 if (!reset) { \
519 /* Check if the dataset is already in the cache */ \
520 auto it = m_recordingDataCache.find(fullPath); \
521 if (it != m_recordingDataCache.end()) { \
522 return it->second; \
523 } \
524 } \
525 /* Get the dataset from IO and cache it */ \
526 auto dataset = m_io->getDataSet(fullPath); \
527 if (dataset) { \
528 m_recordingDataCache[fullPath] = dataset; \
529 } \
530 return dataset; \
531 }
532
539
554#define DEFINE_REGISTERED_FIELD(name, registeredType, fieldPath, description) \
555 \
567 template<typename RTYPE = registeredType> \
568 inline std::shared_ptr<RTYPE> name() const \
569 { \
570 std::string objectPath = AQNWB::mergePaths(m_path, fieldPath); \
571 if (m_io->objectExists(objectPath)) { \
572 return RegisteredType::create<RTYPE>(objectPath, m_io); \
573 } \
574 return nullptr; \
575 }
576
598#define DEFINE_REFERENCED_REGISTERED_FIELD( \
599 name, registeredType, fieldPath, description) \
600 \
612 template<typename RTYPE = registeredType> \
613 inline std::shared_ptr<RTYPE> name() const \
614 { \
615 try { \
616 std::string attrPath = AQNWB::mergePaths(m_path, fieldPath); \
617 std::string objectPath = m_io->readReferenceAttribute(attrPath); \
618 if (m_io->objectExists(objectPath)) { \
619 return RegisteredType::create<RTYPE>(objectPath, m_io); \
620 } \
621 } catch (const std::exception& e) { \
622 return nullptr; \
623 } \
624 return nullptr; \
625 }
626
627} // namespace NWB
628} // namespace AQNWB
AQNWB::Types::StorageObjectType StorageObjectType
Definition BaseIO.hpp:21
std::shared_ptr< AQNWB::NWB::RegisteredType > readField(const std::string &fieldPath) const
Read a field that is itself a RegisteredType.
Definition RegisteredType.hpp:280
std::string getFullTypeName() const
Get the full name of the type, i.e., namespace::typename
Definition RegisteredType.hpp:236
virtual std::string getTypeName() const
Get the name of the class type.
Definition RegisteredType.cpp:60
static std::shared_ptr< T > create(const std::string &path, std::shared_ptr< AQNWB::IO::BaseIO > io)
Factory method to create an instance of a subclass of RegisteredType by type.
Definition RegisteredType.hpp:195
std::string m_path
The path of the registered type.
Definition RegisteredType.hpp:338
static const std::string m_defaultUnregisteredDatasetTypeClass
Save the default RegisteredType to use for reading Dataset types that are not registered.
Definition RegisteredType.hpp:316
void clearRecordingDataCache()
Clear the BaseRecordingData object cache to reset the recording state.
Definition RegisteredType.hpp:95
std::unordered_map< std::string, std::shared_ptr< IO::BaseRecordingData > > m_recordingDataCache
Cache for BaseRecordingData objects for datasets to retain recording state.
Definition RegisteredType.hpp:358
std::shared_ptr< IO::BaseIO > m_io
A shared pointer to the IO object.
Definition RegisteredType.hpp:343
virtual std::string getNamespace() const
Get the schema namespace of the class type.
Definition RegisteredType.cpp:67
static void registerSubclass(const std::string &fullClassName, std::function< std::unique_ptr< RegisteredType >(const std::string &, std::shared_ptr< AQNWB::IO::BaseIO >)> factoryFunction, const std::string &typeName, const std::string &typeNamespace)
Register a subclass name and its factory function in the registry.
Definition RegisteredType.cpp:46
static std::shared_ptr< RegisteredType > create(const std::string &fullClassName, const std::string &path, std::shared_ptr< IO::BaseIO > io, bool fallbackToBase=false)
Create an instance of a registered subclass by name.
Definition RegisteredType.cpp:72
static std::unordered_map< std::string, std::pair< std::function< std::unique_ptr< RegisteredType >(const std::string &, std::shared_ptr< AQNWB::IO::BaseIO >)>, std::pair< std::string, std::string > > > & getFactoryMap()
Get the factory map for creating instances of subclasses.
Definition RegisteredType.cpp:35
virtual std::unordered_map< std::string, std::string > findOwnedTypes(const std::unordered_set< std::string > &types={}, const AQNWB::IO::SearchMode &search_mode=AQNWB::IO::SearchMode::STOP_ON_TYPE) const
Find all typed objects that are owned by this object, i.e., objects that have a neurodata_type and na...
Definition RegisteredType.cpp:118
std::string getName() const
Get the name of the object.
Definition RegisteredType.hpp:80
RegisteredType(const std::string &path, std::shared_ptr< AQNWB::IO::BaseIO > io)
Constructor.
Definition RegisteredType.cpp:15
std::string getPath() const
Gets the path of the registered type.
Definition RegisteredType.hpp:71
std::shared_ptr< AQNWB::IO::BaseIO > getIO() const
Get a shared pointer to the IO object.
Definition RegisteredType.hpp:89
static std::unordered_set< std::string > & getRegistry()
Get the registry of subclass names.
Definition RegisteredType.cpp:24
virtual ~RegisteredType()
Destructor.
Definition RegisteredType.cpp:22
static const std::string m_defaultUnregisteredGroupTypeClass
Save the default RegisteredType to use for reading Group types that are not registered.
Definition RegisteredType.hpp:312
const std::unordered_map< std::string, std::shared_ptr< IO::BaseRecordingData > > & getCacheRecordingData() const
Get the cache of BaseRecordingData objects.
Definition RegisteredType.hpp:103
std::unique_ptr< AQNWB::IO::ReadDataWrapper< SOT, VTYPE > > readField(const std::string &fieldPath) const
Support reading of arbitrary fields by their relative path.
Definition RegisteredType.hpp:265
SearchMode
Enum class for specifying the search mode for findTypes.
Definition BaseIO.hpp:152
@ STOP_ON_TYPE
Stop searching inside an object once a matching type is found.
Definition BaseIO.hpp:156
Namespace for all classes related to the NWB data standard.
Definition TimeSeries.hpp:13
constexpr auto AttributeField
Alias for AQNWB::Types::StorageObjectType::Attribute.
Definition RegisteredType.hpp:23
constexpr auto DatasetField
Alias for AQNWB::Types::StorageObjectType::Dataset.
Definition RegisteredType.hpp:28
The main namespace for AqNWB.
Definition Channel.hpp:11
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:112