NeurodataWithoutBorders / matnwb

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

Error loading columns with spaces in names #305

Closed ryaoki closed 3 years ago

ryaoki commented 3 years ago

When I tried to load spike time from one of the datasets of Steinmetz et al, 2019 (https://figshare.com/articles/dataset/Datasets_from_Steinmetz_et_al_2019_in_NWB_format/11274968/1) with the following snippet,

%% load nwb file
nwb = nwbRead('xxxxxx\Steinmetz2019_Cori_2016-12-14.nwb');
unit_ids = nwb.units.id.data.load;
unit_colnames = nwb.units.colnames

unit_colnames{6} ans =

'spike_times         '

nwb.units.getRow(unit_ids(1), 'useID', true, 'columns', unit_colnames(6)) and I got the following error.

Error using containers.Map/subsref
The specified key is not present in this container.

Error in types.untyped.Set/get (line 165)
                o{i} = obj.map(name{i});

Error in types.util.dynamictable.getRow (line 39)
        VectorData = DynamicTable.vectordata.get(cn);

Error in types.hdmf_common.DynamicTable/getRow (line 135)
        row = types.util.dynamictable.getRow(obj, id,
        varargin{:});

It seems to be related to the fact that column name ('spike_times ') have extra spaces at the end, but when I tried with "deblanking", it returned another error.

nwb.units.getRow(unit_ids(1), 'useID', true, 'columns', deblank(unit_colnames(6)))

Error using types.util.dynamictable.getIndex (line 11)
Column name not found `spike_times`

Error in types.util.dynamictable.getRow (line 34)
    indexName =
    types.util.dynamictable.getIndex(DynamicTable, cn);

Error in types.hdmf_common.DynamicTable/getRow (line 135)
        row = types.util.dynamictable.getRow(obj, id,
        varargin{:});

Thank you in advance.

lawrence-mbf commented 3 years ago

This looks like because we assert that colnames matches the name of the column stored in the DynamicTable exactly. If you replace colnames temporarily with the deblanked version that will work as a workaround.

nwb.units.colnames = deblank(nwb.units.colnames);
nwb.units.getRow(unit_ids(1), 'useID', true, 'columns', nwb.units.colnames(6))) % should work

I have a hunch this was legacy MatNWB behavior but I cannot say for certain until I know how this data was created. This is certainly not recreatable in current MatNWB.

oruebel commented 3 years ago

This looks like because we assert that colnames matches the name of the column stored in the DynamicTable exactly.

For a valid NWB file, this should be the case. colnames is used to indicate the order of columns in the table, and as such the values in colnames should match the names of the column datasets. As such, this seems to be an error in the file.

ryaoki commented 3 years ago

The workaround worked. Thank you very much!