1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- function [spktimes, rate_function] = simulate_spikes(event_ts, kernel, event_weights, varargin)
- %[spktimes, rate_function] = simulate_spikes(event_ts, kernel, event_weights, [krn_bin_size, krn_offset, baseline])
- % Inputs:
- % event_ts An N x M matrix, where N is the number of trials, and M is
- % the number of distinct events in that trial. Each element is the time of
- % the event relative to the beginning of the session.
- % kernel A cell array of length M. Each kernel is convolved with the
- % respective event in event_ts.
- % event_weights A matrix the same size as event_ts. These weights scale the
- % kernel for each event on each trial.
- %
- %
- % krn_bin_size [0.2 s] This is the resolution of the kernels.
- % krn_offset [0] By default each krn is center-aligned to the respective event
- % To shift this (e.g. to have the kernel follow or
- % preceed the event) pass in either a single offset, which
- % will be applied to all kernels or a list of M offsets to
- % apply to the M specified kernels. The offset should be in
- % bins.
- %
- %
- % E.g.
- if nargin==0 % Part of help!
- fprintf(1,'Running demo....\n');
- krn_bin_size = 0.1;
- kernel = {gampdf(0:krn_bin_size:2,3,0.1), gampdf(0:0.1:6,5,0.4)};
- kernel{1} = [zeros(size(kernel{1})), kernel{1}./max(kernel{1})*7];
- kernel{2} = [zeros(size(kernel{2})),kernel{2}./max(kernel{2})*2];
- n_trials = 100;
- trial_starts = linspace(0,500, n_trials )';
- event_ts = [trial_starts trial_starts + rand(size(trial_starts))+0.1];
- event_weights = randi([-1 5], n_trials, numel(kernel))*3;
- [spktimes, rate_function] = stats.simulate_spikes(event_ts, kernel, event_weights,'krn_bin_size',krn_bin_size,'baseline',20);
- figure; draw.exampleraster(event_ts(:,1), spktimes,'cnd',event_weights(:,1),'errorbars',0)
- figure; draw.exampleraster(event_ts(:,2), spktimes,'cnd',event_weights(:,2),'errorbars',0)
- return
-
- end
- %%
- inpd = @utils.inputordefault;
- [krn_bin_size, args] = inpd('krn_bin_size',0.2, varargin);
- [krn_offset, args] = inpd('krn_offset',0, args);
- [baseline, args] = inpd('baseline',0, args);
- if ~isempty(args)
- warning('Did not process some inputs in simulate_spikes. Did you make some typos?')
- disp(args)
- end
- if isscalar(krn_offset)
- krn_offset = zeros(size(kernel))+krn_offset;
- end
- % Shift the kernels by the offset by padding with zeros
- for kx = 1:numel(kernel)
- if krn_offset(kx)<0
- kernel{kx} = [kernel{kx}(:); zeros(abs(krn_offset),1)];
- elseif krn_offset(kx)>0
- kernel{kx} = [zeros(krn_offset,1); kernel{kx}(:)];
- end
- end
- %% Check args
- assert(all(size(event_ts) == size(event_weights)), 'event_ts and event_weight must have the same size');
- assert(numel(kernel) == size(event_ts,2), 'kernel should be a cell array with number of elements equal to columns of event_ts');
- assert(isscalar(baseline),'baseline must be a scalar')
- assert(numel(krn_offset)==1 || numel(krn_offset)==numel(kernel), 'krn_offset must be 1 or the number of kernels.')
- %% Generate delta functions
- start_time = min(event_ts(:)) - min(krn_offset)*krn_bin_size;
- stop_time = max(event_ts(:)) + max(cellfun(@(x)numel(x), kernel))*krn_bin_size;
- timeax = start_time:krn_bin_size:stop_time;
- deltas = zeros(numel(timeax), numel(kernel));
- cdeltas = deltas;
- for kx = 1:numel(kernel)
- this_ind = stats.qfind(timeax, event_ts(:,kx));
- deltas(this_ind,kx) = event_weights(:,kx);
- cdeltas(:,kx) = conv(deltas(:,kx), kernel{kx}, 'same');
- end
- rate_function = sum(cdeltas,2) + baseline;
- f = @(x)utils.nanidx(stats.qfind(timeax,x),rate_function);
- spktimes = stats.inhomopoissrnd(f, 'pre',start_time,'post',stop_time,'binsize',krn_bin_size);
|