Home > bml > sync > bml_sync_consolidate.m

bml_sync_consolidate

PURPOSE ^

BML_SYNC_CONSOLIDATE consolidates file synchronization chunks

SYNOPSIS ^

function consolidated = bml_sync_consolidate(cfg)

DESCRIPTION ^

 BML_SYNC_CONSOLIDATE consolidates file synchronization chunks 

 Use as
   consolidated = bml_sync_consolidate(cfg)
   consolidated = bml_sync_consolidate(cfg.roi)

 cfg.roi - roi table with sync chunks to consolidate
 cfg.timetol - double: time tolerance allowed in consolidation. Defaults
               to 1e-2
 cfg.contiguous - logical: should time contiguous files of the same type
               be consolidated toghether. Defaults to true. 
 cfg.group - variable indicating grouping criteria. Entries of different groups 
               are not consolidated. Defaults to 'session_id'
 cfg.timewarp - boolean, indicates if linear time warping is allowed in
               consolidation. If false, uses nominal Fs value in roi
               table. Defaults to true.
 cfg.rowisfile - boolean, indicates if row refer to files. Defaults to true.

 If chunking for consolidation was done, each file can have several entries in the
 sync roi table. This function consolidates those entries into one per file.
 It does this by finding the sync curve that better fits all chunks.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function consolidated = bml_sync_consolidate(cfg)
0002 
0003 % BML_SYNC_CONSOLIDATE consolidates file synchronization chunks
0004 %
0005 % Use as
0006 %   consolidated = bml_sync_consolidate(cfg)
0007 %   consolidated = bml_sync_consolidate(cfg.roi)
0008 %
0009 % cfg.roi - roi table with sync chunks to consolidate
0010 % cfg.timetol - double: time tolerance allowed in consolidation. Defaults
0011 %               to 1e-2
0012 % cfg.contiguous - logical: should time contiguous files of the same type
0013 %               be consolidated toghether. Defaults to true.
0014 % cfg.group - variable indicating grouping criteria. Entries of different groups
0015 %               are not consolidated. Defaults to 'session_id'
0016 % cfg.timewarp - boolean, indicates if linear time warping is allowed in
0017 %               consolidation. If false, uses nominal Fs value in roi
0018 %               table. Defaults to true.
0019 % cfg.rowisfile - boolean, indicates if row refer to files. Defaults to true.
0020 %
0021 % If chunking for consolidation was done, each file can have several entries in the
0022 % sync roi table. This function consolidates those entries into one per file.
0023 % It does this by finding the sync curve that better fits all chunks.
0024 
0025 if istable(cfg)
0026   cfg = struct('roi',cfg);
0027 end
0028 roi             = bml_getopt(cfg,'roi');
0029 timetol         = bml_getopt(cfg,'timetol',1e-2);
0030 contiguous      = bml_getopt(cfg,'contiguous',true);
0031 group           = bml_getopt_single(cfg,'group','session_id');
0032 timewarp        = bml_getopt(cfg,'timewarp',true);
0033 rowisfile       = bml_getopt(cfg,'rowisfile',true);
0034 group_specified = ismember("group",fieldnames(cfg));
0035 
0036 REQUIRED_VARS2 = {'folder','name','chantype','filetype'};
0037 if ~all(ismember(REQUIRED_VARS2,roi.Properties.VariableNames))
0038   if rowisfile
0039     error('Variables %s required',strjoin(REQUIRED_VARS2))
0040   else
0041     for i=1:length(REQUIRED_VARS2)
0042       roi.(REQUIRED_VARS2{i})=repmat({'NA'},height(roi),1);
0043     end
0044   end
0045 end
0046 
0047 roi = bml_roi_table(roi);
0048 
0049 % REQUIRED_VARS = {'s1','t1','s2','t2','nSamples','Fs'};
0050 % assert(all(ismember(REQUIRED_VARS,roi.Properties.VariableNames)),...
0051 %   'Variables %s required',strjoin(REQUIRED_VARS))
0052 
0053 roi.fullfile = fullfile(roi.folder,roi.name);
0054 if ismember(group,roi.Properties.VariableNames)
0055   if group_specified
0056     fprintf("grouping by %s \n",group);
0057   end
0058   if isnumeric(roi.(group))
0059     roi.fullfile = strcat(roi.fullfile,'_',num2str(roi.(group)));
0060   else
0061     roi.fullfile = strcat(roi.fullfile,'_',roi.(group));
0062   end
0063 end
0064 roi.sync_id = roi.id;
0065 uff = unique(roi.fullfile); %unique fullfile
0066 consolidated = table();
0067 
0068 %consolidating several entries for the same file.
0069 for i_uff=1:length(uff)
0070   i_roi = roi(strcmp(roi.fullfile,uff(i_uff)),:);
0071   if height(i_roi)>1
0072 
0073     %doing linear fit to assess if consolidation is plausible
0074     s = [i_roi.s1; i_roi.s2];
0075     t = [i_roi.t1; i_roi.t2];
0076     if timewarp
0077       p = polyfit(s,t,1);
0078     else
0079       assert(length(unique(i_roi.Fs))==1,"Inconsistent Fs");
0080       p1 = 1/unique(i_roi.Fs);
0081       p = [p1, mean(t-p1*s)];
0082     end
0083     tfit = polyval(p,s);
0084     
0085     max_delta_t = max(abs(t - tfit));
0086     if max_delta_t <= timetol %consolidating
0087       consrow = i_roi(1,:);
0088       consrow.starts = min(i_roi.starts);
0089       consrow.ends = max(i_roi.ends);
0090       consrow.s1 = min(i_roi.s1);
0091       consrow.s2 = max(i_roi.s2);
0092       consrow.t1 = polyval(p,consrow.s1);
0093       consrow.t2 = polyval(p,consrow.s2);
0094       if ismember('warpfactor',i_roi.Properties.VariableNames)
0095         consrow.warpfactor = 1/(consrow.Fs * p(1));
0096       end
0097       i_roi = consrow;      
0098     else  
0099       error('can''t consolidate within tolerance. Max delta t %f > %f',max_delta_t,timetol)
0100     end
0101   end
0102   consolidated = [consolidated; i_roi];
0103 end
0104 
0105 consolidated.id=[];
0106 roi.fullfile=[];
0107 consolidated = bml_roi_table(consolidated);
0108 
0109 %consolidating several time contiguos files together
0110 if contiguous
0111   roi = consolidated;
0112   consolidated = table();
0113   roi.filetype_chantype = strcat(roi.filetype,roi.chantype,num2str(roi.Fs));
0114   ufc = unique(roi.filetype_chantype);
0115   for i_ufc=1:length(ufc)
0116       i_roi = roi(strcmp(roi.filetype_chantype,ufc(i_ufc)),:);
0117     if  height(i_roi)>1 && length(unique(i_roi.name))<=1
0118       %probably the first consolidation failed. Returning with a warning
0119       error('multiple chunks for single file after per file consolidation');
0120       consolidated = bml_roi_table(roi);
0121       return
0122     end
0123     %detecting contiguos stretches
0124     cfg=[];
0125     cfg.criterion = @(x) abs(sum(x.duration)-max(x.ends)+min(x.starts)) < height(x)*timetol;
0126     i_roi_cont = bml_annot_consolidate(cfg,i_roi);   
0127     
0128     for j=1:height(i_roi_cont)
0129         i_roi_cont_j = i_roi(i_roi.id>=i_roi_cont.id_starts(j) & i_roi.id<=i_roi_cont.id_ends(j),:);
0130     
0131       if height(i_roi_cont_j)>1
0132         
0133         left_complete = i_roi_cont_j.starts(1)<=i_roi_cont_j.t1(1);
0134         right_complete = i_roi_cont_j.ends(end)>=i_roi_cont_j.t2(end);
0135         
0136         %calculating raw samples of contiguous file
0137         cs = cumsum(i_roi_cont_j.s2-i_roi_cont_j.s1) + i_roi_cont_j.s1(1);
0138         cs = cs + (0:(height(i_roi_cont_j)-1))';
0139         cs = [0; cs(1:end-1)];
0140         i_roi_cont_j.raw1 = i_roi_cont_j.s1 + cs;
0141         i_roi_cont_j.raw2 = i_roi_cont_j.s2 + cs;
0142         
0143         %doing linear fit to asses if consolidation is plausible
0144         s = [i_roi_cont_j.raw1; i_roi_cont_j.raw2];
0145         t = [i_roi_cont_j.t1; i_roi_cont_j.t2];
0146         %plot(s,t,'o')
0147         if timewarp
0148           p = polyfit(s,t,1);
0149         else
0150           assert(length(unique(i_roi_cont_j.Fs))==1,"Inconsistent Fs");
0151           p1 = 1/unique(i_roi_cont_j.Fs);
0152           p = [p1, mean(t-p1*s)];
0153         end
0154         tfit = polyval(p,s);
0155       
0156         max_delta_t = max(abs(t - tfit));
0157         if max_delta_t <= timetol %consolidating
0158           i_roi_cont_j.t1 = polyval(p,i_roi_cont_j.raw1);
0159           i_roi_cont_j.t2 = polyval(p,i_roi_cont_j.raw2);
0160           if ismember('warpfactor',i_roi_cont_j.Properties.VariableNames)
0161             i_roi_cont_j.warpfactor = 1 ./ (i_roi_cont_j.Fs .* p(1));
0162           end
0163         else  
0164           error('can''t consolidate within tolerance. Max delta t %f > %f',max_delta_t,timetol);
0165         end
0166         i_roi_cont_j.raw1=[];
0167         i_roi_cont_j.raw2=[];          
0168         
0169         %adjusting starts and ends to take to confluence
0170         if left_complete
0171           i_roi_cont_j.starts(1) = i_roi_cont_j.t1(1) - 0.5/i_roi_cont_j.Fs(1);
0172         end
0173         for i=1:(height(i_roi_cont_j)-1)
0174           i_roi_cont_j.ends(i)     = (i_roi_cont_j.t2(i) + i_roi_cont_j.t1(i+1))/2;
0175           i_roi_cont_j.starts(i+1) = (i_roi_cont_j.t2(i) + i_roi_cont_j.t1(i+1))/2;        
0176         end
0177         if right_complete
0178           i_roi_cont_j.ends(1) = i_roi_cont_j.t2(1) + 0.5/i_roi_cont_j.Fs(1);
0179         end
0180     
0181         consolidated = [consolidated; i_roi_cont_j];
0182       else
0183         consolidated = [consolidated; i_roi_cont_j];
0184       end
0185     end
0186   end
0187 end
0188 
0189 consolidated = bml_roi_table(consolidated);
0190

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