Home > bml > sync > bml_timealign_annot.m

bml_timealign_annot

PURPOSE ^

BML_TIMEALIGN_ANNOT aligns slave to master and returns the slave's delta t

SYNOPSIS ^

function [slave_delta_t, min_cost, warpfactor] = bml_timealign_annot(cfg, master, slave)

DESCRIPTION ^

 BML_TIMEALIGN_ANNOT aligns slave to master and returns the slave's delta t

 Use as
   slave_delta_t = bml_timealign(cfg, master, slave)
   [slave_delta_t, max_corr] = bml_timealign(cfg, master, slave)

 cfg is a configuration structure with fields:
 cfg.scan - double: time window in which to scan for a maximal correlation
            if a scalar is given the time window is [-scan, scan]
            if a length 2 vector is given it should be [-a, b], where 'a'
            and 'b' are positive numbers in seconds. 
 cfg.scan_step - double: time step for initial scan in seconds
 cfg.timewarp - logical: should time warping be allowed. Defaults to false

 master - annot table 
 slave - annot table

 returns
 slave_delta_t - double: time in seconds by which to shift the slave to 
           align it to master
 max_corr - double:

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [slave_delta_t, min_cost, warpfactor] = bml_timealign_annot(cfg, master, slave)
0002 
0003   % BML_TIMEALIGN_ANNOT aligns slave to master and returns the slave's delta t
0004   %
0005   % Use as
0006   %   slave_delta_t = bml_timealign(cfg, master, slave)
0007   %   [slave_delta_t, max_corr] = bml_timealign(cfg, master, slave)
0008   %
0009   % cfg is a configuration structure with fields:
0010   % cfg.scan - double: time window in which to scan for a maximal correlation
0011   %            if a scalar is given the time window is [-scan, scan]
0012   %            if a length 2 vector is given it should be [-a, b], where 'a'
0013   %            and 'b' are positive numbers in seconds.
0014   % cfg.scan_step - double: time step for initial scan in seconds
0015   % cfg.timewarp - logical: should time warping be allowed. Defaults to false
0016   %
0017   % master - annot table
0018   % slave - annot table
0019   %
0020   % returns
0021   % slave_delta_t - double: time in seconds by which to shift the slave to
0022   %           align it to master
0023   % max_corr - double:
0024 
0025   scan      = bml_getopt(cfg, 'scan', 100);
0026   scan_step = bml_getopt(cfg, 'scan_step', 0.1);
0027   timewarp  = bml_getopt(cfg, 'timewarp', false);
0028   
0029   master    = bml_annot_table(master);
0030   slave     = bml_annot_table(slave);
0031   slave_starts_mean = mean(slave.starts);
0032   slave_starts_minus_mean = slave.starts-slave_starts_mean;
0033   
0034   %cost function with timewarp
0035   %cost=costfun([slave_delta_t, warpfactor])
0036   function cost=costfun(x0)
0037     y=master.starts;
0038     x=slave_starts_minus_mean .* x0(2) + slave_starts_mean + x0(1);
0039     cost=0;
0040     for i=1:length(x)
0041      cost = cost + min(abs(x(i)-y))^2;
0042     end
0043     cost = sqrt(cost);
0044   end
0045 
0046   %cost function without timewarp (timewarp = 1)
0047   %cost=costfun(slave_delta_t)
0048   function cost=costfun1(x0)
0049     y=master.starts;
0050     x=slave.starts + x0(1);
0051     cost=0;
0052     for i=1:length(x)
0053      cost = cost + min(abs(x(i)-y))^2;
0054     end
0055     cost = sqrt(cost);
0056   end
0057 
0058   %initial brute force scan
0059   initial_scan = linspace(-scan,scan,floor(2*scan/scan_step)+1);
0060   warpfactor = 1;
0061   slave_delta_t=0;
0062   min_cost=costfun1(slave_delta_t);
0063   for j=1:length(initial_scan)
0064     i_cost = costfun1(initial_scan(j));
0065     if i_cost < min_cost
0066       min_cost = i_cost;
0067       slave_delta_t=initial_scan(j);
0068     end
0069   end
0070 
0071   %censoring unpaired slave events
0072   slave_master_dt = zeros(height(slave),1);
0073   for i_slave=1:height(slave)
0074     slave_master_dt(i_slave) = min(abs(slave.starts(i_slave) + slave_delta_t - master.starts));
0075   end
0076   censored_slave = slave_master_dt > scan_step;
0077   if sum(censored_slave)>0
0078     warning("%i slave events censored in synchronization",sum(censored_slave));
0079     slave = slave(~censored_slave,:);
0080     slave_starts_mean = mean(slave.starts);
0081     slave_starts_minus_mean = slave.starts-slave_starts_mean;
0082   end
0083   
0084   %optimizing
0085   if timewarp
0086     fitted=fminsearch(@costfun,[slave_delta_t, warpfactor]);
0087     slave_delta_t=fitted(1);
0088     warpfactor = fitted(2);
0089   else
0090     fitted=fminsearch(@costfun1,slave_delta_t);
0091     slave_delta_t=fitted(1);
0092   end
0093   min_cost = costfun([slave_delta_t,warpfactor]);
0094   
0095 end
0096   
0097 
0098     
0099     
0100

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