-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add data read #85
base: main
Are you sure you want to change the base?
Add data read #85
Conversation
@stephprince when you get a chance ,could you please do a first code review of this PR to make sure this is heading in the right direction. I now have a first outline of one possible solution for how we might implement read. There is still a lot more work to be done before this PR is ready, but it would be useful if you could take a look before I go any further with this approach. I would start by looking at:
|
@stephprince I just added a documentation page as well, which hopefully helps explain the current proposed design for read so we can review and discuss. |
Co-authored-by: Steph Prince <[email protected]>
We decide not to do this and to continue testing only for the merged version. We decided to add a note in the developer docs to clarify this behavior. |
Add read for neurodata_types, e.g., Container, TimeSeries
@stephprince I synced the branch with the main branch. However, Windows tests are currently failing due to |
Windows tests are working again. I had to add boost multi-array to the windows Action to fix the include error for |
This PR is to try and implement the proposed approach for data read from #83 to see if this approach is viable. This PR is experimental right now and should not be merged.
2. Proposed Implementation for reading data arrays
BaseReadData
ReadDatasetWrapper
andReadAttributeWrapper
classes for reading data. This is modified from the proposal, which suggested a singleBaseReadData
class for reading any array (datasets, attributes) from a file.BaseRecordingData
to inherit fromReadDataWrapper
because the two are not compatible right now.BaseReadData
uses the io and the path to access the data, whereasBaseRecordingData
leaves that choice to the I/O backend and stores the references to the dataset. We may or may not want to change this.BaseIO
BaseIO
(or more accurately I remove them) because: 1) I wanted to use the shared_ptr to the I/O rather than a raw pointer, which I can't get from BaseIO, and 2) with the ReadDatasetWrapper this is more approbriately done in the Container class directly.HDF5IO
BaseReadData
forHDF5
but left read logic toHDF5IO
itself so that theReadDatasetWrapper
can remain generic. To make this more manageable, I definedReadAttributeWrapper
separatelyHDF5ReadDataSet
andHDF5ReadAttribute
wrappers can call can call for readgetObjectType
method for getting the storage object type (Group, Dataset, Attribute) for a given pathContainer
io
object on theContainer
so that we can callio->readDataset
andio->readAttribute
in the read methodsNWB types:
TimeSeries
,ElectricalSeries
etc.Container
classes and replace them with access methods that returnBaseReadData
objects instead. This allows for reading in both read and write mode and avoids keeping data in memory that we have already written to disk. For example, inTimeSeries
, these variables would need to change to properties:aqnwb/src/nwb/base/TimeSeries.hpp
Lines 91 to 140 in e873d95
BaseReadData
for missing fields3. Proposed implementation for reading whole
Containers
(e.g., to read anElectricalSeries
)Container
that owns the respective objects, e.g.,NWBFile
owningElectricalSeries
objects to retrieve the objectContainer
to create an instance of the specificContainer
type using only theio
andpath
for theContainer
as input. The specificContainer
classes, such asTimeSeries
will then need to implement a corresponding constructor that usesio
andpath
as input.Step 1: Define the Template Factory Method in
Container
Step 2: Implement the constructors on the specific
Container
classes (e.g.,TimeSeries
)4. Proposed implementation for reading untyped groups (e.g.,
/acquisition
)I'm not sure we'll need do this, since a group by itself does not define data. To access the contents we could define access methods on the parent
Container
class (e.g.,NWBFile
) that owns the untyped group to access its contents.TODO
ReadDatasetWrapper
,ReadAttributeWrapper
(See Add read for neurodata_types, e.g., Container, TimeSeries #91)ReadDatasetWrapper
andReadAttributeWrapper
(I think this could be useful)Items moved to new issues
REGISTER_SUBCLASS_WITH_TYPENAME
#115Next steps
DEFINE_FIELDS
specified for read can be read. As part of writing the tests, we should also double-check for each type, that all fields that AqNWB writes, that they are also exposed for read.TimeSeries
ElectricalSeries
SpikeEventSeries
Device
NWBFile
. NOTE: For reading the NWBFile container, there is the special case thatNWBFile
requires the path to the "/" so this may require some additional logic in the tests.aqnwb/src/nwb/NWBFile.cpp
Lines 39 to 44 in bfa740a
ElectrodeTable
. NOTE: ElectrodeTable is currently not aneurodata_type
and usesREGISTER_SUBCLASS_WITH_TYPENAME
. I.e., on read this will return aDynamicTable
instead of anElectrodeTable
right now. See Support read with classes usingREGISTER_SUBCLASS_WITH_TYPENAME
#115ElectrodeGroup
DynamicTable
Data
VectorData
ElementIdentifiers
src/Utils.cpp , mergePaths()
functionHDF5IO
functions (which are core functions new inBaseIO
). While some of these are partially covered by theDEFINE_FIELDS
read tests, it will be useful to more fully test these separatelyHDF5IO::findTypes
(implemented inBaseIO::findTypes
)HDF5IO::readDataset
(incl. with start, count, stride, and block parameters set). This is to test that reading subsets of larger arrays works as expected.HDF5IO::open(FileMode mode)
test that file modes are being set correctlyHDF5IO::readAttribute
HDF5IO::getStorageObjectType
HDF5IO::getGroupObjects
HDF5IO::attributeExists
HDF5IO::objectExists
HDF5IO
-specifc functions (i.e., not inherited fromBaseIO
. These may be moved to a separate PR:HDF5IO::getH5ObjectType
HDF5IO::getNativeType
HDF5IO::getH5Type
HDF5IO
internal functions. These may not require separate dedicated tested, but may be covered via the tests of the public core interfaces functions. However, we should check that they are indeed covered:HDF5IO:: readDataHelper
(note, there are two variants of this function)HDF5IO::readStringDataHelper
(note there are two variants of this function)HDF5IO::getAttribute
colNames
fromDynamicTable
constructor toinitialize
RegisteredType
. This should be largely covered by the other tests, but we should check.ReadIO
. This should be largely covered by the other tests, but we should check.DEFINE_FIELD
create virtual functions and resolve this comment https://github.com/NeurodataWithoutBorders/aqnwb/pull/85/files#r1894223365 NOTE: I created Allow virtual function for DEFINE_FIELD #117 for this and added a note to the docs to example this. I think it is fine to address this later.DynamicTable
may require additional discussion on how to read columns. I think right now we would read individualVectorData
columns manually'boost/multi_array.hpp': No such file or directory