Home > bml > annot > bml_annot2spike.m

bml_annot2spike

PURPOSE ^

BML_ANNOT2SPIKE creates a ft_datatype_spike structure from an annotation table

SYNOPSIS ^

function spike = bml_annot2spike(cfg, annot, raw)

DESCRIPTION ^

 BML_ANNOT2SPIKE creates a ft_datatype_spike structure from an annotation table

 Use as
   spike = bml_annot2spike(cfg, annot)
   spike = bml_annot2spike(cfg, annot, raw)
   spike = bml_annot2spike(cfg, annot, spike_waveform)
 
 cfg.roi - roi table used to transform the times in annot.starts to
       timestamps (ie, samples). Required if raw is not provided. 
 cfg.waveform_mult - double, multiplying factor for waveform. Defaults to 1.
 cfg.waveform_extract - boolean indicating if waveforms whould be cropped
       from raw. Defaults to false. 
 cfg.waveform_samples - integer indicating number of sample for the
       waveforms. Defauls to 44. 
 cfg.annot_spike_id - string, indicates which variable of annot should be
       treated as spike index for waveform extraction. Defaults to 'spike_idx'
 cfg.unit_delimiter - string to delimit units from channels. Defaults to
       '_unit'

 annot - annotation table to transform to spike timestamps. Only the
         starts vector is used. Normally obtained from bml_plexon2annot
 raw - ft_datatype_raw from where to use as template for the spikes
       timestamps and to crop the snippets from. 
 spike_waveform - ft_datatype_spike as returned by ft_read_spike or
       bml_plexon2annot. waveforms are extracted from here if available. 
       should contain fields 'waveform' and 'label'. 

 returns a ft_datatype_spike structure. Each label correspons to an
 individual unit named as <channel>_<unit>. 

 If spike_waveform is provided, a waveform field will be present in the 
 output, where the mapping of units to waveform is based on annot.channel,
 annot.spike_idx, spike_waveform.label and spike_waveform.waveform. 

 If raw is provided, a waveform field will be present in the output, where the 
 mapping of snippets are extracted from the raw vector. The labels of raw
 must match annot.channel.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function spike = bml_annot2spike(cfg, annot, raw)
0002 
0003 % BML_ANNOT2SPIKE creates a ft_datatype_spike structure from an annotation table
0004 %
0005 % Use as
0006 %   spike = bml_annot2spike(cfg, annot)
0007 %   spike = bml_annot2spike(cfg, annot, raw)
0008 %   spike = bml_annot2spike(cfg, annot, spike_waveform)
0009 %
0010 % cfg.roi - roi table used to transform the times in annot.starts to
0011 %       timestamps (ie, samples). Required if raw is not provided.
0012 % cfg.waveform_mult - double, multiplying factor for waveform. Defaults to 1.
0013 % cfg.waveform_extract - boolean indicating if waveforms whould be cropped
0014 %       from raw. Defaults to false.
0015 % cfg.waveform_samples - integer indicating number of sample for the
0016 %       waveforms. Defauls to 44.
0017 % cfg.annot_spike_id - string, indicates which variable of annot should be
0018 %       treated as spike index for waveform extraction. Defaults to 'spike_idx'
0019 % cfg.unit_delimiter - string to delimit units from channels. Defaults to
0020 %       '_unit'
0021 %
0022 % annot - annotation table to transform to spike timestamps. Only the
0023 %         starts vector is used. Normally obtained from bml_plexon2annot
0024 % raw - ft_datatype_raw from where to use as template for the spikes
0025 %       timestamps and to crop the snippets from.
0026 % spike_waveform - ft_datatype_spike as returned by ft_read_spike or
0027 %       bml_plexon2annot. waveforms are extracted from here if available.
0028 %       should contain fields 'waveform' and 'label'.
0029 %
0030 % returns a ft_datatype_spike structure. Each label correspons to an
0031 % individual unit named as <channel>_<unit>.
0032 %
0033 % If spike_waveform is provided, a waveform field will be present in the
0034 % output, where the mapping of units to waveform is based on annot.channel,
0035 % annot.spike_idx, spike_waveform.label and spike_waveform.waveform.
0036 %
0037 % If raw is provided, a waveform field will be present in the output, where the
0038 % mapping of snippets are extracted from the raw vector. The labels of raw
0039 % must match annot.channel.
0040 
0041 if nargin == 3
0042   assert(isstruct(raw), "Invalid third argument");
0043   if all(ismember({'trial','time','label'},fieldnames(raw)))
0044     % Usage spike = bml_annot2spike(cfg, annot, raw)
0045     spike_waveform = [];
0046   elseif    all(ismember({'waveform','label'},fieldnames(raw)))
0047     % Usage spike = bml_annot2spike(cfg, annot, spike_waveform)
0048     spike_waveform = raw;
0049     raw = [];
0050   else
0051     error("invalid third argument");
0052   end  
0053 elseif nargin == 2
0054   spike_waveform = [];  
0055     raw = [];
0056 else
0057   error("Incorrect number of arguments");
0058 end
0059 
0060 roi = bml_getopt(cfg,'roi');
0061 if isempty(roi) 
0062   if ~isempty(raw)
0063     roi = bml_raw2annot(raw);
0064   else
0065     error("cfg.roi or raw required");
0066   end
0067 end
0068 
0069 annot = bml_annot_table(annot,[],inputname(2));
0070 assert(all(ismember({'channel','unit'},annot.Properties.VariableNames)),...
0071   "channel and unit columns required in annot");
0072 
0073 waveform_mult    = bml_getopt(cfg,'waveform_mult',1);
0074 waveform_extract = bml_getopt(cfg,'waveform_extract',false);
0075 waveform_samples = bml_getopt(cfg,'waveform_samples',44);
0076 unit_delimiter   = bml_getopt_single(cfg,'unit_delimiter','_unit');
0077 
0078 annot_spike_id   = bml_getopt_single(cfg,'annot_spike_id','spike_idx');
0079 has_spike_idx = ismember({annot_spike_id},annot.Properties.VariableNames);
0080 
0081 annot.channel_unit = strcat(annot.channel,unit_delimiter,num2str(annot.unit));
0082 tot_units = length(unique(annot.channel_unit));
0083 
0084 spike=struct();
0085 spike.timestamp=cell(1,tot_units);
0086 spike.label=cell(1,tot_units);
0087 spike_idx=cell(1,tot_units);
0088 channel=cell(1,tot_units);
0089 
0090 lev_channel = unique(annot.channel);
0091 i_tot_unit = 1;
0092 annot = bml_annot_filter(annot,roi);
0093 assert(height(annot)>0,'no events in annot in specified time window');
0094 for i_ch=1:length(lev_channel)
0095   assert(i_tot_unit<=tot_units);
0096   ch_annot = annot(strcmp(annot.channel,lev_channel(i_ch)),:);
0097   lev_unit = unique(ch_annot.unit);
0098   for i_u=1:length(lev_unit)
0099     u_ch_annot = ch_annot(ch_annot.unit == lev_unit(i_u),:);
0100     spike.timestamp{i_tot_unit} = bml_time2idx(roi,u_ch_annot.starts);
0101     spike.label(i_tot_unit) = strcat(lev_channel(i_ch),unit_delimiter,num2str(lev_unit(i_u)));
0102     if has_spike_idx
0103       spike_idx{i_tot_unit} = u_ch_annot.spike_idx;
0104       channel{i_tot_unit} = lev_channel(i_ch);
0105     end
0106     i_tot_unit = i_tot_unit + 1;
0107   end
0108 end
0109 
0110 if has_spike_idx && ~isempty(spike_waveform)
0111   %getting waveforms from spike_waveform
0112   spike.waveform=cell(1,length(spike_idx));
0113   for i_wf=1:length(spike_idx)
0114     orig_wf_idx = bml_getidx(channel{i_wf},spike_waveform.label);
0115     spike.waveform{1,i_wf} = waveform_mult .* spike_waveform.waveform{orig_wf_idx}(:,:,spike_idx{i_wf});
0116   end
0117 end
0118 
0119 if ~isempty(raw) && waveform_extract
0120   error("waveform extraction not implemented yet");
0121 end
0122 
0123 
0124 
0125 
0126 
0127 
0128 
0129

Generated on Tue 25-Sep-2018 10:08:19 by m2html © 2005