Home > bml > io > bml_load_epoched.m

bml_load_epoched

PURPOSE ^

BML_LOAD_EPOCHED loads an epoched raw from one or more files

SYNOPSIS ^

function [raw, loaded_epoch, file_raw_map] = bml_load_epoched(cfg)

DESCRIPTION ^

 BML_LOAD_EPOCHED loads an epoched raw from one or more files

 Use as 
   raw = bml_load_epoched(cfg)
   [raw, file_raw_map] = bml_load_epoched(cfg)

 cfg.roi - ROI table with file synchronization information
 cfg.epoch - ANNOT table with epochs of interest. 
 cfg.allow_missing - logical, indicating if missing epochs should be
           allowed. Defaults to false.
 cfg.electrode - ANNOT table with electrodes of interest. Must contain
           'channel' and 'eletrode' variables.
 cfg.load_empty - logical, indicates how to proceed if a the
           electrode annotation for a channel doesn't span the entire 
           epoch. In this case the channel is 'empty'. defaults to true.
 cfg.relabel - optinbal cellstr with new names of channels. 
 cfg.warn - logical indicating if warnings should be issued

 cfg... further arguments for BML_LOAD_CONTINUOUS 
 cfg.chantype
 cfg.channel

 --- resampling arguments ---
 cfg.resamplefs
 cfg.detrend 
 cfg.demean
 cfg.feedback

 returns a FT_DATATYPE_RAW with one trial per epoch. 
 file_raw_map is the mapping between files and samples in trials
 loaded_epoch are the efectively loaded epochs

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [raw, loaded_epoch, file_raw_map] = bml_load_epoched(cfg)
0002 
0003 % BML_LOAD_EPOCHED loads an epoched raw from one or more files
0004 %
0005 % Use as
0006 %   raw = bml_load_epoched(cfg)
0007 %   [raw, file_raw_map] = bml_load_epoched(cfg)
0008 %
0009 % cfg.roi - ROI table with file synchronization information
0010 % cfg.epoch - ANNOT table with epochs of interest.
0011 % cfg.allow_missing - logical, indicating if missing epochs should be
0012 %           allowed. Defaults to false.
0013 % cfg.electrode - ANNOT table with electrodes of interest. Must contain
0014 %           'channel' and 'eletrode' variables.
0015 % cfg.load_empty - logical, indicates how to proceed if a the
0016 %           electrode annotation for a channel doesn't span the entire
0017 %           epoch. In this case the channel is 'empty'. defaults to true.
0018 % cfg.relabel - optinbal cellstr with new names of channels.
0019 % cfg.warn - logical indicating if warnings should be issued
0020 %
0021 % cfg... further arguments for BML_LOAD_CONTINUOUS
0022 % cfg.chantype
0023 % cfg.channel
0024 %
0025 % --- resampling arguments ---
0026 % cfg.resamplefs
0027 % cfg.detrend
0028 % cfg.demean
0029 % cfg.feedback
0030 %
0031 % returns a FT_DATATYPE_RAW with one trial per epoch.
0032 % file_raw_map is the mapping between files and samples in trials
0033 % loaded_epoch are the efectively loaded epochs
0034 
0035 roi           = bml_roi_table(bml_getopt(cfg,'roi'),'roi');
0036 epoch         = bml_annot_table(bml_getopt(cfg,'epoch'),'epoch');
0037 resamplefs    = bml_getopt(cfg,'resamplefs');
0038 detrend       = bml_getopt_single(cfg,'detrend','no');
0039 demean        = bml_getopt_single(cfg,'demean','no');
0040 feedback      = bml_getopt_single(cfg,'feedback','no');
0041 electrode     = bml_annot_table(bml_getopt(cfg,'electrode'),'electrode');
0042 relabel       = bml_getopt(cfg,'relabel');
0043 warn          = bml_getopt(cfg,'warn',true);
0044 allow_missing = bml_getopt(cfg,'allow_missing',false);
0045 load_empty    = bml_getopt(cfg,'load_empty',true);
0046 
0047 cfg.roi = [];
0048 cfg.epoch = [];
0049 cfg.resamplefs=[];
0050 cfg.detrend = [];
0051 cfg.demean = [];
0052 cfg.electrode = [];
0053 
0054 cfg_resample = [];
0055 if ~isempty(resamplefs)
0056   cfg_resample.resamplefs = resamplefs;
0057   cfg_resample.detrend = detrend;
0058   cfg_resample.demean = demean;
0059   cfg_resample.feedback = feedback;
0060 end
0061 
0062 assert(istable(epoch),"epoch required");
0063 if ~ismember('epoch_id',epoch.Properties.VariableNames)
0064   epoch.epoch_id = epoch.id;
0065 end
0066 
0067 first = true;
0068 raw = {};
0069 file_raw_map = [];
0070 loaded_epoch = table();
0071 
0072 for i=1:height(epoch)
0073   fprintf("\n --- Loading epoch id %i (%i of %i) --- \n",epoch.id(i),i,height(epoch));
0074   
0075   i_loaded_epoch = epoch(i,:);
0076   cfg_keep_x = struct('keep','x');
0077   cfg.roi = bml_annot_intersect(cfg_keep_x, roi, epoch(i,:));
0078   if height(cfg.roi)>0
0079     cfg.roi = bml_sync_consolidate(cfg.roi);
0080 
0081     if ~isempty(electrode)
0082       if load_empty
0083         cfg.electrode = electrode;
0084         cfg.electrode.starts(:) = min(cfg.roi.starts);
0085         cfg.electrode.ends(:) = max(cfg.roi.ends);
0086       else
0087         %intersecting electrodes with ROIs
0088         cfg.electrode = bml_annot_intersect(cfg_keep_x, electrode, cfg.roi);
0089         %consolidating electrode rows corresponding to same epoched and channel
0090         %(for neuroomega files it can get split because of the chunking)
0091         if isempty(cfg.electrode)
0092           error("No electrodes left after intersection with roi. Check electrodes starts and ends, or use load_empty = true.")
0093         end
0094       end
0095       cfg.electrode=sortrows(cfg.electrode,...
0096         bml_getidx({'filetype','channel','starts'},cfg.electrode.Properties.VariableNames));
0097       cfg.electrode.id=(1:height(cfg.electrode))';
0098       
0099       cfg1=[];
0100       cfg1.criterion = @(x) (length(unique(x.filetype))==1) && (length(unique(x.channel))==1);                        
0101       cfg.electrode=bml_annot_consolidate(cfg1,cfg.electrode);
0102     else
0103       cfg.electrode = [];
0104     end
0105 
0106     [i_raw,i_file_raw_map] = bml_load_continuous(cfg);
0107     i_file_raw_map.epoch_id(:) = epoch.id(i);
0108 
0109     if ~isempty(cfg_resample)
0110       i_raw = ft_resampledata(cfg_resample,i_raw);
0111     end
0112 
0113     if first %initializing stuff
0114       if isempty(relabel)
0115         label = i_raw.label;
0116       else
0117         assert(numel(relabel)==numel(i_raw.label), "incorrect length for relabel");
0118         label = relabel;
0119         i_raw.label = label;
0120       end
0121       raw = {i_raw};
0122       i_file_raw_map.trial(:) = 1;
0123       file_raw_map = i_file_raw_map;
0124       if ismember('hdr',fields(i_raw))
0125         hdr=i_raw.hdr;
0126       else
0127         hdr=[];
0128       end
0129       i_loaded_epoch.id=1;
0130       first = false;
0131     else
0132       if ~isequal(label,i_raw.label)
0133         if warn && isempty(relabel)
0134           warning('inconsistent channel names. Renaming.')
0135         end
0136         i_raw.label = label;
0137       end   
0138       raw = [raw, i_raw];
0139       i_trial = max(file_raw_map.trial)+1;
0140       i_file_raw_map.trial(:) = i_trial;
0141       file_raw_map = [file_raw_map; i_file_raw_map];
0142       i_loaded_epoch.id=i_trial;
0143     end
0144 
0145     loaded_epoch = [loaded_epoch; i_loaded_epoch];
0146   else
0147     if warn && allow_missing
0148       warning("No roi info for epoch %i (epoch_id = %i)",i,epoch.epoch_id(i));
0149     elseif ~allow_missing
0150       error("No roi info for epoch %i (epoch_id = %i)",i,epoch.epoch_id(i));
0151     end
0152   end
0153 end
0154 
0155 cfg=[];
0156 cfg.appenddim = 'rpt';
0157 raw = ft_appenddata(cfg, raw{:});
0158 
0159 if ~isempty(hdr)
0160   raw.hdr = hdr;
0161 end
0162 
0163 file_raw_map.id=[];
0164 file_raw_map = bml_roi_table(file_raw_map);
0165 
0166 
0167 
0168 
0169

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