MatNWB <-> HDF5 Dimension Mapping

This tutorial is easier to follow if you have already looked at the dimensionMapNoDataPipes tutorial or if you compare these side by side.
The key difference when using DataPipe instead of VectorData is that 1D data can be represented in HDF5 as 2D, thus allowing you to write either row or column vectors. This is made possible because of the maxSize property of the DataPipe class, which lets you specify a max size for each dimension. By setting the maxSize to [1, N] or [N, 1], vectors in HDF5 are represented as 2D arrays, just like in MATLAB. The flipping of the dimension order still applies, so a row vector in MATLAB becomes a column vector in HDF5 and vice versa.
Please note: The following tutorial mixes row and column vectors and does not produce a valid dynamic table. The tutorial is only meant to showcase how data maps onto HDF5 datasets when using DataPipe objects.

Create Table

First, create an expandable TimeIntervals table of height 10.
% 1D column
start_col = types.hdmf_common.VectorData( ...
'description', 'start times column', ...
'data', types.untyped.DataPipe( ...
'data', 1:10, ... # maps onto HDF5 dataset of size (10, )
'maxSize', Inf ...
) ...
);
% 1D column
stop_col = types.hdmf_common.VectorData( ...
'description', 'stop times column', ...
'data', types.untyped.DataPipe( ...
'data', 1:10, ... # maps onto HDF5 dataset of size (10, 1)
'maxSize', [1 Inf], ...
'axis', 2 ...
) ...
);
% 1D column
cond_col = types.hdmf_common.VectorData( ...
'description', 'condition column', ...
'data', types.untyped.DataPipe( ...
'data', randi(2,10,1), ... # maps onto HDF5 dataset of size (1, 10)
'maxSize', [Inf, 1], ...
'axis', 1 ...
) ...
);
% 4D column
randomval_col = types.hdmf_common.VectorData( ...
'description', 'randomvalues column', ...
'data', types.untyped.DataPipe( ...
'data', rand(5,2,3,10), ... # maps onto HDF5 dataset of size (10, 3, 2, 5)
'maxSize', [5, 2, 3, Inf], ...
'axis', 4 ...
) ...
);
% 1D column
ids_col = types.hdmf_common.ElementIdentifiers( ...
'data', types.untyped.DataPipe( ...
'data', int64(0:9), ... # maps onto HDF5 dataset of size (10, )
'maxSize', Inf ...
) ...
);
% Create table
trials_table = types.core.TimeIntervals(...
'description', 'test dynamic table column',...
'colnames', {'start_time', 'stop_time', 'randomvalues', 'conditions'}, ...
'start_time', start_col, ...
'stop_time', stop_col, ...
'conditions', cond_col, ...
'randomvalues', randomval_col, ...
'id', ids_col ...
);

Export Table

Create NWB file with expandable TimeIntervals table and export.
% Create NwbFile object with required arguments
file = NwbFile( ...
'session_start_time', datetime('2022-01-01 00:00:00', 'TimeZone', 'local'), ...
'identifier', 'ident1', ...
'session_description', 'test file' ...
);
% Assign to intervals_trials
file.intervals_trials = trials_table;
% Export
nwbExport(file, 'testFileWithDataPipes.nwb');
You can examine the dimensions of the datasets on file using HDFView. Screenshots for this file are below.
Screen Shot 2022-01-12 at 1.12.42 PM.png
Screen Shot 2022-01-12 at 1.12.47 PM.png
Screen Shot 2022-01-07 at 4.26.21 PM.png
Screen Shot 2022-01-07 at 4.26.12 PM.png