NeurodataWithoutBorders / matnwb

A Matlab interface for reading and writing NWB files
BSD 2-Clause "Simplified" License
50 stars 32 forks source link

[Bug]: Discrepancy between accepted dimensions #489

Closed KyzarNexus closed 1 year ago

KyzarNexus commented 1 year ago

What happened?

There appears to be a discrepancy between the data dimensions accepted for '+types+core\OpticalSeries.m' & the schema definition in 'nwb-schema\2.6.0\core\nwb.image.yaml'. For the nwb.image.yaml OpticalSeries definition, the accepted dimensions for an RGB image are [frame, x, y, 3] (ln159-162). However, the valid RGB shape allowable for OpticalSeries.m is [3, Inf, Inf, Inf] (ln 60). That being said, the error resulting from this can be circumvented by permuting the data before adding it to an OpticalSeries, but is there a reason why the acceptable dimensions are reversed here?

Steps to Reproduce

nwb = NwbFile();

% Dims: (#Frames, Xpixel, Ypixel, numRGB) According to 2.6.0 OpticalSeries Schema
sampleData = uint8(randi([0 255],10,200,100,3));
% sampleData = permute(sampleData,[4, 3, 2, 1]); % Permutation for compatability with types+\core+\OpticalSeries.m ; Uncomment to resolve error. 
timestamps = 1:10;

stimulus = types.core.OpticalSeries(...
           'description', 'Images presented to the subject. Data is stored in the dimensions [nrFrames,nrPixelsX,nrPixelsY,rgbCount].', ...
           'data', sampleData, ...
           'timestamps', timestamps, ...
           'orientation', 'lower left', ...
           'format', 'raw', ...
           'distance', 0.7, ...
           'field_of_view', [0.3, 0.4, 0.7], ...
           'dimension', [200,100, 3], ...
           'data_unit', 'meters');
nwb.stimulus_presentation.set('StimulusPresentation', stimulus);

Error Message

Matrix dimensions must agree.

Error in types.util.checkDims>getIsSizeMatch (line 51)
tf = length(expectedSize) <= length(actualSize) && all(openSizeMask | expectedSize == actualSize);

Error in types.util.checkDims (line 17)
        isSizeMatch = getIsSizeMatch(expectedSize, valueSize);

Error in types.core.OpticalSeries/validate_data (line 61)
        types.util.checkDims(valsz, validshapes);

Error in types.core.TimeSeries/set.data (line 90)
        obj.data = obj.validate_data(val);

Error in types.core.TimeSeries (line 59)
        obj.data = p.Results.data;

Error in types.core.ImageSeries (line 20)
        obj = obj@types.core.TimeSeries(varargin{:});

Error in types.core.OpticalSeries (line 15)
        obj = obj@types.core.ImageSeries(varargin{:});

Error in opticalSeriesTest (line 8)
stimulus = types.core.OpticalSeries(...

Operating System

Windows

Matlab Version

R2019a

Code of Conduct

lawrence-mbf commented 1 year ago

Hi @KyzarNexus ,

This just has to do with how MATLAB orders its data when writing using the HDF5 library. As a result, the dimension validation is intentionally flipped for better compatibility with HDF5, C, and Python and so we don't have to do rehapes on large data.

You can read more about this here: https://www.mathworks.com/help/matlab/import_export/export-to-hdf5-files.html#bqyqs27

KyzarNexus commented 1 year ago

Hi @lawrence-mbf ,

Thanks for clarifying!