0001 function [raw, loaded_epoch, file_raw_map] = bml_load_epoched(cfg)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
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
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
0088 cfg.electrode = bml_annot_intersect(cfg_keep_x, electrode, cfg.roi);
0089
0090
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
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
0149 elseif ~allow_missing
0150 error("No roi info for epoch
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