annotate trunk/matlab/bmm/carfac/SAI_StabilizeLayer.m @ 619:2e456754fe20

Better functionization of SAI, and new way to make picture with lag marginal and smoothed history of lag marginal.
author dicklyon@google.com
date Mon, 13 May 2013 21:15:56 +0000
parents
children d0ff15c36828
rev   line source
dicklyon@619 1 function layer_struct = SAI_StabilizeLayer(layer_struct)
dicklyon@619 2 % Pick trigger points in buffer, shift rows to offset_from_end,
dicklyon@619 3 % and blend into frame
dicklyon@619 4
dicklyon@619 5 frame = layer_struct.frame;
dicklyon@619 6
dicklyon@619 7 nap_buffer = real(layer_struct.nap_buffer);
dicklyon@619 8 n_buffer_times = size(nap_buffer, 1);
dicklyon@619 9 [n_ch, width] = size(frame);
dicklyon@619 10
dicklyon@619 11 % Make the window to use for all the channels at this layer.
dicklyon@619 12 window_size = layer_struct.window_width;
dicklyon@619 13 n_window_pos = layer_struct.n_window_pos;
dicklyon@619 14 % Windows are always (approx) 50% overlapped:
dicklyon@619 15 d_win = window_size / 2;
dicklyon@619 16
dicklyon@619 17 after_samples = layer_struct.future_lags;
dicklyon@619 18
dicklyon@619 19 window_range = (1:window_size) + ...
dicklyon@619 20 (n_buffer_times - window_size) - after_samples - ...
dicklyon@619 21 floor((n_window_pos - 1) * d_win);
dicklyon@619 22 window = sin((1:window_size)' * pi / window_size);
dicklyon@619 23 % This should not go negative!
dicklyon@619 24 offset_range = (1:width) + ...
dicklyon@619 25 (n_buffer_times - width - window_size) - floor((n_window_pos - 1) * d_win);
dicklyon@619 26 % CHECK
dicklyon@619 27 if any(offset_range < 0)
dicklyon@619 28 error;
dicklyon@619 29 end
dicklyon@619 30
dicklyon@619 31 % smooth across channels; more in later layers
dicklyon@619 32 smoothed_buffer = smooth1d(nap_buffer', layer_struct.channel_smoothing_scale)';
dicklyon@619 33
dicklyon@619 34 % For each buffer column (channel), pick a trigger and align into SAI_frame
dicklyon@619 35 for ch = 1:n_ch
dicklyon@619 36 smooth_wave = smoothed_buffer(:, ch); % for the trigger
dicklyon@619 37
dicklyon@619 38 % Do several window positions and triggers
dicklyon@619 39 for w = 1:n_window_pos
dicklyon@619 40 % move the window to later and go aggain
dicklyon@619 41 [peak_val, trigger_time] = max(smooth_wave(window_range + ...
dicklyon@619 42 floor((w - 1) * d_win)) .* window);
dicklyon@619 43 nap_wave = nap_buffer(:, ch); % for the waveform
dicklyon@619 44 if peak_val <= 0 % just use window center instead
dicklyon@619 45 [peak_val, trigger_time] = max(window);
dicklyon@619 46 end
dicklyon@619 47 % TODO(dicklyon): alpha blend here.
dicklyon@619 48 trigger_time = trigger_time + floor((w - 1) * d_win);
dicklyon@619 49 alpha = (0.025 + peak_val) / (0.5 + peak_val); % alpha 0.05 to near 1.0
dicklyon@619 50 frame(ch, :) = alpha * nap_wave(trigger_time + offset_range)' + ...
dicklyon@619 51 (1 - alpha) * frame(ch, :);
dicklyon@619 52 end
dicklyon@619 53 end
dicklyon@619 54
dicklyon@619 55 layer_struct.frame = frame;