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< \
454 AQNWB::IO::ReadDataWrapper<AQNWB::NWB::AttributeField, VTYPE>> \
455 name() const \
456 { \
457 return std::make_unique< \
458 AQNWB::IO::ReadDataWrapper<AQNWB::NWB::AttributeField, VTYPE>>( \
459 m_io, AQNWB::mergePaths(m_path, fieldPath)); \
460 }
461
483#define DEFINE_DATASET_FIELD( \
484 readName, writeName, default_type, fieldPath, description) \
485 \
493 template<typename VTYPE = default_type> \
494 inline std::unique_ptr< \
495 AQNWB::IO::ReadDataWrapper<AQNWB::NWB::DatasetField, VTYPE>> \
496 readName() const \
497 { \
498 return std::make_unique< \
499 AQNWB::IO::ReadDataWrapper<AQNWB::NWB::DatasetField, VTYPE>>( \
500 m_io, AQNWB::mergePaths(m_path, fieldPath)); \
501 } \
502 \
515 inline std::shared_ptr<AQNWB::IO::BaseRecordingData> writeName(bool reset = \
516 false) \
517 { \
518 std::string fullPath = AQNWB::mergePaths(m_path, fieldPath); \
519 if (!reset) { \
520 /* Check if the dataset is already in the cache */ \
521 auto it = m_recordingDataCache.find(fullPath); \
522 if (it != m_recordingDataCache.end()) { \
523 return it->second; \
524 } \
525 } \
526 /* Get the dataset from IO and cache it */ \
527 auto dataset = m_io->getDataSet(fullPath); \
528 if (dataset) { \
529 m_recordingDataCache[fullPath] = dataset; \
530 } \
531 return dataset; \
532 }
533
540
555#define DEFINE_REGISTERED_FIELD(name, registeredType, fieldPath, description) \
556 \
568 template<typename RTYPE = registeredType> \
569 inline std::shared_ptr<RTYPE> name() const \
570 { \
571 std::string objectPath = AQNWB::mergePaths(m_path, fieldPath); \
572 if (m_io->objectExists(objectPath)) { \
573 return RegisteredType::create<RTYPE>(objectPath, m_io); \
574 } \
575 return nullptr; \
576 }
577
602#define DEFINE_UNNAMED_REGISTERED_FIELD( \
603 readName, writeName, registeredType, fieldPrefixPath, description) \
604 \
617 template<typename RTYPE = registeredType> \
618 inline std::shared_ptr<RTYPE> readName(const std::string& objectName) const \
619 { \
620 std::string prefixPath = AQNWB::mergePaths(m_path, fieldPrefixPath); \
621 std::string objectPath = AQNWB::mergePaths(prefixPath, objectName); \
622 if (m_io->objectExists(objectPath)) { \
623 return RegisteredType::create<RTYPE>(objectPath, m_io); \
624 } \
625 return nullptr; \
626 } \
627\
628 \
642 template<typename RTYPE = registeredType> \
643 inline std::unique_ptr<RTYPE> writeName(const std::string& objectName) const \
644 { \
645 std::string prefixPath = AQNWB::mergePaths(m_path, fieldPrefixPath); \
646 std::string objectPath = AQNWB::mergePaths(prefixPath, objectName); \
647 return std::make_unique<RTYPE>(objectPath, m_io); \
648 }
649
671#define DEFINE_REFERENCED_REGISTERED_FIELD( \
672 name, registeredType, fieldPath, description) \
673 \
685 template<typename RTYPE = registeredType> \
686 inline std::shared_ptr<RTYPE> name() const \
687 { \
688 try { \
689 std::string attrPath = AQNWB::mergePaths(m_path, fieldPath); \
690 std::string objectPath = m_io->readReferenceAttribute(attrPath); \
691 if (m_io->objectExists(objectPath)) { \
692 return RegisteredType::create<RTYPE>(objectPath, m_io); \
693 } \
694 } catch (const std::exception& e) { \
695 std::cerr << "WARNING Error occurred in " << #name << " " << e.what() \
696 << std::endl; \
697 return nullptr; \
698 } \
699 return nullptr; \
700 }
701
702} // namespace NWB
703} // namespace AQNWB
AQNWB::Types::StorageObjectType StorageObjectType
Definition BaseIO.hpp:21
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
Read a field that is itself a RegisteredType.
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 NWBContainer.hpp:18
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