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

Electrodes table schema change #176

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions +file/fillClass.m
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,22 @@
depnm = ['types.' strrep(ParentNamespace.name, '-', '_') '.' parentName]; %WRITE
end

rawClass = namespace.getClass(name);
switch rawClass('class_type')
case 'groups'
h5TypeName = 'types.untyped.IsGroup';
case 'datasets'
h5TypeName = 'types.untyped.IsDataset';
otherwise
error('NWB:File:FillClass:InvalidClassType',...
'`class_type` must be of `groups` or `datasets`');
end

%% return classfile string
classDef = [...
'classdef ' name ' < ' depnm newline... %header, dependencies
'% ' upper(name) ' ' class.doc]; %name, docstr
sprintf('classdef %s < %s & %s\n', name, depnm, h5TypeName)... % header, dependencies
sprintf('%% %s %s', upper(name), class.doc)]; % name, docstr

propgroups = {...
@()file.fillProps(classprops, readonly, 'SetAccess=protected')...
@()file.fillProps(classprops, setdiff([required optional], readonly))...
Expand Down
5 changes: 5 additions & 0 deletions +types/+untyped/IsDataset.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
classdef IsDataset < handle
%ISDATASET Stub defining this class as a Dataset object

end

5 changes: 5 additions & 0 deletions +types/+untyped/IsGroup.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
classdef IsGroup < handle
%ISGROUP Stub class stating that this class is a H5 Group object.

end

4 changes: 2 additions & 2 deletions +types/+untyped/MetaClass.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
end


if isa(obj, 'types.core.NWBContainer')
if isa(obj, 'types.untyped.IsGroup')
io.writeGroup(fid, fullpath);
elseif isa(obj, 'types.core.NWBData') || isa(obj, 'types.core.SpecFile')
elseif isa(obj, 'types.untyped.IsDataset')
try
if isa(obj.data, 'types.untyped.DataStub')
refs = obj.data.export(fid, fullpath, refs);
Expand Down
5 changes: 3 additions & 2 deletions nwb-schema/core/nwb.file.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ groups:
doc: Physical group of electrodes.
quantity: '*'
- name: electrodes
neurodata_type_def: Electrodes
neurodata_type_inc: DynamicTable
doc: A table of all electrodes (i.e. channels) used for recording.
quantity: '?'
Expand All @@ -331,7 +332,7 @@ groups:
doc: Impedance of the channel.
- name: location
neurodata_type_inc: VectorData
dtype: text
dtype: ascii
doc: Location of the electrode (channel). Specify the area, layer, comments
on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use
standard atlas names for anatomical regions when possible.
Expand All @@ -347,7 +348,7 @@ groups:
doc: Reference to the ElectrodeGroup this electrode is a part of.
- name: group_name
neurodata_type_inc: VectorData
dtype: text
dtype: ascii
doc: Name of the ElectrodeGroup this electrode is a part of.
- name: rel_x
neurodata_type_inc: VectorData
Expand Down
1 change: 1 addition & 0 deletions nwb-schema/core/nwb.misc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ groups:
doc: The metric used, e.g. phase, amplitude, power.
groups:
- name: bands
neurodata_type_def: FrequencyBands
neurodata_type_inc: DynamicTable
doc: Table for describing the bands that this series was generated from. There
should be one row in this table for each band.
Expand Down
49 changes: 36 additions & 13 deletions tutorials/ecephys.m
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,10 @@
device_name = 'implant';
nwb.general_devices.set(device_name, types.core.Device());
device_link = types.untyped.SoftLink(['/general/devices/' device_name]);
group_data = [];
group_name_data = {};
for ishank = 1:length(shank_channels)
nelecs = shank_channels(ishank);
nelecs_in_shank = shank_channels(ishank);
group_name = ['shank' num2str(ishank)];
nwb.general_extracellular_ephys.set(group_name, ...
types.core.ElectrodeGroup( ...
Expand All @@ -59,22 +61,43 @@
'device', device_link));
group_object_view = types.untyped.ObjectView( ...
['/general/extracellular_ephys/' group_name]);
for ielec = 1:length(nelecs)
if ishank == 1 && ielec == 1
tbl = table(NaN, NaN, NaN, NaN, {'unknown'}, {'unknown'}, ...
group_object_view, {[group_name 'elec' num2str(ielec)]}, ...
'VariableNames', variables);
else
tbl = [tbl; {NaN, NaN, NaN, NaN, 'unknown', 'unknown', ...
group_object_view, [group_name 'elec' num2str(ielec)]}];
end
end
group_data = [group_data, repmat(group_object_view, 1, nelecs_in_shank)];
group_name_vec = cell(1, nelecs_in_shank);
group_name_vec(:) = {group_name};
group_name_data = [group_name_data, group_name_vec];
end

nelecs = sum(shank_channels);

filtering_data = cell(1, nelecs);
filtering_data(:) = {'n/a'};
location_data = filtering_data;

electrode_table = types.core.Electrodes( ...
'colnames', {'x', 'y', 'z', 'imp', 'location', 'filtering', 'group', 'label'}, ...
'description', 'description', ...
'id', types.hdmf_common.ElementIdentifiers('data', 0:(nelecs-1)), ...
'x', types.hdmf_common.VectorData('data', NaN(1,nelecs), ...
'description', 'x'), ...
'y', types.hdmf_common.VectorData('data', NaN(1,nelecs), ...
'description', 'y'), ...
'z', types.hdmf_common.VectorData('data', NaN(1,nelecs), ...
'description', 'z'), ...
'imp', types.hdmf_common.VectorData('data', NaN(1,nelecs), ...
'description', 'imp'), ...
'filtering', types.hdmf_common.VectorData('data', filtering_data, ...
'description', 'filtering'), ...
'location', types.hdmf_common.VectorData('data', location_data, ...
'description', 'location'), ...
'group', types.hdmf_common.VectorData('data', group_data, ...
'description', 'electrode group'), ...
'group_name', types.hdmf_common.VectorData('data', group_name_data, ...
'description', 'group name'));


% add the |DynamicTable| object to the NWB file in
% /general/extracellular_ephys/electrodes

electrode_table = util.table2nwb(tbl, 'all electrodes');
nwb.general_extracellular_ephys_electrodes = electrode_table;

%% Multielectrode recording
Expand All @@ -91,7 +114,7 @@
electrode_table_region = types.hdmf_common.DynamicTableRegion( ...
'table', electrodes_object_view, ...
'description', 'all electrodes', ...
'data', [0 height(tbl)-1]');
'data', [0 nelecs-1]');

%%
% once you have the |ElectrodeTableRegion| object, you can create an
Expand Down