Skip to content
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

Bug in Matnwb: use nwb.units.getRow() to retrieve "waveforms" data #301

Closed
jiumao2 opened this issue Aug 20, 2021 · 13 comments
Closed

Bug in Matnwb: use nwb.units.getRow() to retrieve "waveforms" data #301

jiumao2 opened this issue Aug 20, 2021 · 13 comments
Assignees
Labels
category: bug errors in the code or code behavior

Comments

@jiumao2
Copy link

jiumao2 commented Aug 20, 2021

I wonder whether you have modified nwb.units.getRow() to get "waveforms" data?
I think I have set "waveforms_index" and "waveforms_index_index" right.
The "waveforms" data can't be retrieved with nwb.units.getRow(), while "spikes_time" can be retrieved normally.

This is what I have:
1629463694(1)

@jiumao2
Copy link
Author

jiumao2 commented Aug 20, 2021

Sorry for putting this issue in wrong place

@oruebel oruebel transferred this issue from NeurodataWithoutBorders/nwb-schema Aug 20, 2021
@oruebel
Copy link
Contributor

oruebel commented Aug 20, 2021

@ln-vidrio

@bendichter
Copy link
Contributor

@jjumao2 yes it's possible the getRow function does not work with multiple indexes. Good catch

@lawrence-mbf
Copy link
Collaborator

How is your colnames property set?

@lawrence-mbf
Copy link
Collaborator

Actually, it'd be helpful if you provided the snippet of code which populated the Unit table.

@jiumao2
Copy link
Author

jiumao2 commented Aug 22, 2021

nwb.units = types.core.Units( ...
'colnames', {'spike_times', 'waveforms', 'waveforms_index', 'waveforms_index_index', 'unit_type','cluster_id','polytrode'}, ...
'description', ['units table, Definition for unit_type: ',r.Units.Definition{2}, ' ', r.Units.Definition{3}], ...
'id', types.hdmf_common.ElementIdentifiers( ...
'data', int64(0:length(spikes) - 1)), ...
'spike_times', spike_times_vector, ...
'spike_times_index', spike_times_index, ...
'waveforms', waveforms_vector, ...
'waveforms_index', waveforms_index_vector, ...
'waveforms_index_index', waveforms_index_index_vector, ...
'electrodes', electrode_table_region, ...
'electrodes_index', electrode_index, ...
'cluster_id', cluster_id, ...
'unit_type', unit_type, ...
'polytrode', polytrode);

waveforms_vector =

VectorData with properties:

description: 'None'
       data: [67852480×1 double]

waveforms_index_vector =

VectorIndex with properties:

     target: [1×1 types.untyped.ObjectView]
description: 'None'
       data: [1060195×1 uint32]

waveforms_index_index_vector =

VectorIndex with properties:

     target: [1×1 types.untyped.ObjectView]
description: 'None'
       data: [16×1 uint32]

16 spikes are detected. Each spike is dectected by one channel.
I have modified the file according to #302 but it doesn't help.

nwb.units.getRow(1)

ans =

1×8 table

  spike_times       spike_times_index     waveforms     waveforms_index     waveforms_index_index    unit_type    cluster_id    polytrode
________________    _________________    ___________    ________________    _____________________    _________    __________    _________

{42110×1 double}          42110          {[79.7143]}    {42110×1 uint32}            42110                1            1             0    

@lawrence-mbf
Copy link
Collaborator

@jiumao2 Can you pull from that branch and try getRow again?

@jiumao2
Copy link
Author

jiumao2 commented Aug 25, 2021

Is it related to the "colname" or dimension of "waveforms"?
The following error emerged when trying my previous dataset.

Array indices must be positive integers or logical values.

Error in types.util.dynamictable.getRow>select (line 52)
column = colIndStack{end};

Error in types.util.dynamictable.getRow>select (line 77)
selected{iSelection} = select(...

Error in types.util.dynamictable.getRow (line 44)
row{i} = select(DynamicTable, indexNames, ind);

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

When I tried to form new dataset with identical codes, the function "util.create_indexed_column()" didn't work. I met the following error:

Error using types.util.correctType (line 60)
Value must be of signage uint

Error in types.util.checkDtype (line 111)
val = types.util.correctType(val, type);

Error in types.hdmf_common.VectorIndex/validate_data (line 36)
val = types.util.checkDtype('data', 'uint8', val);

Error in types.hdmf_common.Data/set.data (line 31)
obj.data = obj.validate_data(val);

Error in types.hdmf_common.Data (line 24)
obj.data = p.Results.data;

Error in types.hdmf_common.VectorData (line 15)
obj = [email protected]_common.Data(varargin{:});

Error in types.hdmf_common.VectorIndex (line 15)
obj = [email protected]_common.VectorData(varargin{:});

Error in util.create_indexed_column (line 44)
data_index = types.hdmf_common.VectorIndex( ...

Error in dataToNwb (line 334)
[spike_times_vector, spike_times_index] = util.create_indexed_column( ...

@lawrence-mbf
Copy link
Collaborator

If you have the dataset creation script that would be helpful as there are a multitude of ways to actually create dynamic tables. It currently looks like your waveforms dataset is not a VectorData object which is not expected.

I have fixed the util.create_indexed_column call as well if you wish to test that. This was due to a minor change to how index types are "shrinkwrapped".

@lawrence-mbf lawrence-mbf self-assigned this Aug 25, 2021
@jiumao2
Copy link
Author

jiumao2 commented Aug 25, 2021

waveforms_vector = types.hdmf_common.VectorData();
waveforms_vector.data = waveforms;
waveforms_vector.description = 'None';

target = types.untyped.ObjectView('/units/waveforms');

waveforms_index_vector = types.hdmf_common.VectorIndex();
waveforms_index_vector.data = (1:a)';
waveforms_index_vector.target = target;
waveforms_index_vector.description = 'None';

target2 = types.untyped.ObjectView('/units/waveforms_index');

waveforms_index_index_vector = types.hdmf_common.VectorIndex();
waveforms_index_index_vector.data = waveforms_index_index;
waveforms_index_index_vector.target = target2;
waveforms_index_index_vector.description = 'None';

nwb.units = types.core.Units( ...
    'colnames', {'spike_times', 'spike_times_index', 'waveforms', 'waveforms_index', 'waveforms_index_index','electrodes_index','unit_type','cluster_id','polytrode'}, ...
    'description', ['units table, Definition for unit_type: ',r.Units.Definition{2}, ' ', r.Units.Definition{3}], ...
    'id', types.hdmf_common.ElementIdentifiers( ...
    'data', int64(0:length(spikes) - 1)), ...
    'spike_times', spike_times_vector, ...
    'spike_times_index', spike_times_index, ...
    'waveforms', waveforms_vector, ...
    'waveforms_index', waveforms_index_vector, ...
    'waveforms_index_index', waveforms_index_index_vector, ...
    'electrodes', electrode_table_region, ...
    'electrodes_index', electrode_index, ...
    'cluster_id', cluster_id, ...
    'unit_type', unit_type, ...
    'polytrode', polytrode);

a: 1060195
waveforms: 1060195x64 double.
waveforms_index_index: 16x1 double (I have 16 units)

@lawrence-mbf
Copy link
Collaborator

So if I'm reading this right, you wish to divide the entire waveforms column into 16 parts evenly. In that case, you may not need waveforms_index_index (it is not a required property if you check the export function). So you can leave that property empty, omit it from colnames and use waveforms_index directly.

I'm also seeing that your data is a matrix and not an actual vector. That might be a bug on our end.

@lawrence-mbf
Copy link
Collaborator

lawrence-mbf commented Aug 26, 2021

@jiumao2 I have fixed multidimensional matrices.

Without manually debugging your ragged array indices, I'm not sure what other issue this could be. Would it be possible to reformat the code such that your code uses addRow instead? For instance, if your table only has 16 rows, you can do this:

dt = types.hdmf_common.DynamicTable('colnames', {'waveforms'});

matDims = [1060195 64];
numRows = 16;
segmentSize = floor(matDims(1) / numRows);
lastSeg = segmentSize + mod(matDims(1), segmentSize);

for i = 1:(numRows - 1)
    dt.addRow('waveforms', repmat(i, [segmentSize matDims(2)]));
end

dt.addRow('waveforms', repmat(numRows, [lastSeg matDims(2)]));

Not dynamically generating the data obviously.

@lawrence-mbf lawrence-mbf added the category: bug errors in the code or code behavior label Oct 12, 2021
@lawrence-mbf
Copy link
Collaborator

Closed as stale

@lawrence-mbf lawrence-mbf closed this as not planned Won't fix, can't repro, duplicate, stale May 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category: bug errors in the code or code behavior
Projects
None yet
Development

No branches or pull requests

4 participants