Merge branch 'master' of whale:scientificComputing
This commit is contained in:
commit
68622b3f9e
83
projects/project_onset_fi/solution/boltzmannFit.m
Normal file
83
projects/project_onset_fi/solution/boltzmannFit.m
Normal file
@ -0,0 +1,83 @@
|
||||
function [best_params] = boltzmannFit(contrasts, onset_fi)
|
||||
% use a gradient descent approach to fit the fi curve owith a Boltzmann
|
||||
% sigmoidal function
|
||||
%
|
||||
% Arguments:
|
||||
% constrasts: the x-values (must be sorted ascendingly)
|
||||
% onset_fi: the measured neuronal responses
|
||||
%
|
||||
% Returns the parameters leading to the best fit.
|
||||
|
||||
% we will make some educated guesses for the start parameters; minimum:
|
||||
% minimum fi response; saturation: maximum fi response; inflection: zero
|
||||
% contrast; slope: response range/contrast range
|
||||
start_params = [min(onset_fi), max(onset_fi), 0, ...
|
||||
(max(onset_fi) - min(onset_fi))/(max(contrasts) - min(contrasts))];
|
||||
|
||||
best_params = gradientDescent(start_params, contrasts, onset_fi);
|
||||
|
||||
|
||||
%% subfunctions that could be separate m-files, but are only used in this context
|
||||
|
||||
function bp = gradientDescent(p, x, y)
|
||||
% performs the gradient descent. Input arguments:
|
||||
% p: the list of starting parameters for the search
|
||||
% x: the x-values
|
||||
% y: the measured y-values
|
||||
%
|
||||
% returns the parameters leading to the best fit
|
||||
|
||||
delta = 0.001;
|
||||
gradient = getGradient(p, x, y, delta);
|
||||
eps = [0.001 0.001, 0.00001, 0.00001]; % key point; use smaller changes for the more delicate parameters
|
||||
while norm(gradient) > 0.5
|
||||
p = p - eps .* gradient;
|
||||
gradient = getGradient(p, x, y, delta);
|
||||
end
|
||||
bp = p;
|
||||
end
|
||||
|
||||
function g = getGradient(p, x, y, delta)
|
||||
% calculate the gradient in the error surface for a small step
|
||||
% along all parameters
|
||||
% p: the parameter list
|
||||
% x: the x-values
|
||||
% y: the measured y-values
|
||||
% delta: the step used or the gradient
|
||||
%
|
||||
% returns the gradient
|
||||
g = zeros(size(p));
|
||||
|
||||
for i = 1:length(p)
|
||||
np = p;
|
||||
np(i) = np(i) + delta;
|
||||
g(i) = (costFunction(np, x, y) - costFunction(p, x, y)) / delta;
|
||||
end
|
||||
end
|
||||
|
||||
function cost = costFunction(p, x, y)
|
||||
% cost function that relates the model to the data. Applies a
|
||||
% Boltzman model and calculates the error in a mean square error
|
||||
% sense.
|
||||
% p: the set of parameters used for the model
|
||||
% x: the x-values
|
||||
% y: the measured y-values
|
||||
%
|
||||
% returns the costs related to that parameterization
|
||||
|
||||
y_est = boltzmannModel(p, x);
|
||||
cost = msqError(y, y_est);
|
||||
end
|
||||
|
||||
function e = msqError(y, y_est)
|
||||
% calculates the deviation between y and y_est in the mean square
|
||||
% error sense
|
||||
% y and y_est must have the same size
|
||||
%
|
||||
% returns the error
|
||||
e = mean((y - y_est).^2);
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
10
projects/project_onset_fi/solution/boltzmannModel.m
Normal file
10
projects/project_onset_fi/solution/boltzmannModel.m
Normal file
@ -0,0 +1,10 @@
|
||||
function y = boltzmannModel(p, x)
|
||||
% computes the Boltmannfunction given the parameters given in p
|
||||
% the following order is assumed
|
||||
% p(1) = minimum y-value
|
||||
% p(2) = maximum y-value, i.e. the saturation
|
||||
% p(3) = the position of the inflection point
|
||||
% p(4) = the slope at the inflection
|
||||
|
||||
y = ((p(1) - p(2))) ./ (1 + exp((x-p(3))/p(4))) + p(2);
|
||||
end
|
27
projects/project_onset_fi/solution/convolutionRate.m
Normal file
27
projects/project_onset_fi/solution/convolutionRate.m
Normal file
@ -0,0 +1,27 @@
|
||||
function [time, rate] = convolution_rate(spikes, sigma, dt, t_max)
|
||||
% PSTH computed with convolution method.
|
||||
%
|
||||
% [time, rate] = convolution_rate(spikes, sigma, dt, t_max)
|
||||
%
|
||||
% Arguments:
|
||||
% spikes: a vector containing the spike times.
|
||||
% sigma : the standard deviation of the Gaussian kernel in seconds.
|
||||
% dt : the temporal resolution in seconds.
|
||||
% t_max : the trial duration in seconds.
|
||||
%
|
||||
% Returns: two vectors containing the time and the rate.
|
||||
|
||||
time = 0:dt:t_max - dt;
|
||||
rate = zeros(size(time));
|
||||
spike_indices = round(spikes / dt);
|
||||
rate(spike_indices) = 1;
|
||||
kernel = gaussKernel(sigma, dt);
|
||||
|
||||
rate = conv(rate, kernel, 'same');
|
||||
end
|
||||
|
||||
|
||||
function y = gaussKernel(s, step)
|
||||
x = -4 * s:step:4 * s;
|
||||
y = exp(-0.5 .* (x ./ s) .^ 2) ./ sqrt(2 * pi) / s;
|
||||
end
|
12
projects/project_onset_fi/solution/getFICurve.m
Normal file
12
projects/project_onset_fi/solution/getFICurve.m
Normal file
@ -0,0 +1,12 @@
|
||||
function [fi, fi_std, sort_contrasts] = getFICurve(firing_rates, time, duration, contrasts)
|
||||
|
||||
[sort_contrasts, sort_idx] = sort(contrasts);
|
||||
fi = zeros(length(sort_contrasts), 1);
|
||||
fi_std = zeros(length(sort_contrasts), 1);
|
||||
|
||||
for i = 1:length(sort_contrasts)
|
||||
responses = firing_rates{sort_idx(i)};
|
||||
onset_responses = mean(responses((time > 0) & (time <= duration), :),1);
|
||||
fi(i) = mean(onset_responses);
|
||||
fi_std(i) = std(onset_responses);
|
||||
end
|
10
projects/project_onset_fi/solution/getFiringRates.m
Normal file
10
projects/project_onset_fi/solution/getFiringRates.m
Normal file
@ -0,0 +1,10 @@
|
||||
function [time, rates] = getFiringRates(all_spikes, min_t, max_t, dt)
|
||||
|
||||
|
||||
time = min_t:dt:max_t-dt;
|
||||
rates = zeros(length(time), length(all_spikes));
|
||||
for i = 1:length(all_spikes)
|
||||
spike_times = all_spikes{i}/1000 - min_t;
|
||||
spike_times(spike_times == 0.0) = dt;
|
||||
[t, rates(:, i)] = convolutionRate(spike_times, 0.01, dt, max_t-min_t);
|
||||
end
|
36
projects/project_onset_fi/solution/main.m
Normal file
36
projects/project_onset_fi/solution/main.m
Normal file
@ -0,0 +1,36 @@
|
||||
%% solution for project onset-FI
|
||||
|
||||
clear all
|
||||
close all
|
||||
|
||||
dt = 1./20000;
|
||||
t_min = -0.2;
|
||||
t_max = 1.825;
|
||||
data_folder = strcat('..', filesep, 'data');
|
||||
files = dir(strcat(data_folder, filesep, '*.mat'));
|
||||
|
||||
contrasts = zeros(length(files), 1);
|
||||
rates = {};
|
||||
for i = 1:length(files)
|
||||
data = load(strcat(data_folder, filesep, files(i).name));
|
||||
contrasts(i) = data.contrast;
|
||||
spikes_times = data.spike_times;
|
||||
[t, rates{i}] = getFiringRates(spikes_times, t_min, t_max, dt);
|
||||
end
|
||||
|
||||
%% create a plot of the average response for the different contrasts
|
||||
plotAverageResponse(rates, t, contrasts, 'averageResponse')
|
||||
|
||||
%% extract the onset and the steady-state firing rate
|
||||
[fi, fi_std, contr] = getFICurve(rates, t, 0.015, contrasts);
|
||||
|
||||
%% plot FI curve
|
||||
plotFICurve(fi, fi_std, contr, 'ficurve')
|
||||
|
||||
%% fit FICurve with Boltzmann function
|
||||
best_params = boltzmannFit(contr, fi);
|
||||
|
||||
% plot the fi curve with the fit
|
||||
plotFICurveFit(fi, fi_std, contr, best_params, 'ficurvefit')
|
||||
|
||||
|
47
projects/project_onset_fi/solution/plotAverageResponse.m
Normal file
47
projects/project_onset_fi/solution/plotAverageResponse.m
Normal file
@ -0,0 +1,47 @@
|
||||
function [] = plotAverageResponse(rates, time, contrasts, filename)
|
||||
[sort_contrasts, sort_idx] = sort(contrasts);
|
||||
|
||||
figure
|
||||
set(gcf, 'paperunits', 'centimeters', 'papersize', [20 20], ...
|
||||
'paperposition', [0.0 0.0 20, 20], 'color', 'white')
|
||||
axes = cell(size(sort_contrasts));
|
||||
for i = 1:length(sort_contrasts)
|
||||
subplot(ceil(length(sort_contrasts)/2), 2, i);
|
||||
responses = rates{sort_idx(i)};
|
||||
avg_response = mean(responses, 2)';
|
||||
std_response = std(responses, [], 2)';
|
||||
f = fill([time fliplr(time)], [avg_response + std_response fliplr(avg_response - std_response)], ...
|
||||
'b', 'EdgeColor','none', 'displayname', 'std');
|
||||
alpha(f, 0.25)
|
||||
hold on
|
||||
plot(time, avg_response, 'b', 'displayname', 'average response')
|
||||
text(1.2, 500, sprintf('contrast: %i %', sort_contrasts(i)), ...
|
||||
'fontsize', 9, 'FontWeight', 'bold')
|
||||
xlim([time(1) time(end)])
|
||||
ylim([0, 600])
|
||||
set(gca, 'XTick', time(1):0.2:time(end), 'YTick', 0:200:600)
|
||||
if mod(i,2) == 1
|
||||
ylabel('firing rate [Hz]', 'fontsize', 11);
|
||||
else
|
||||
set(gca, 'yticklabels', []);
|
||||
end
|
||||
if i > length(sort_contrasts) - 2
|
||||
xlabel('time [s]', 'fontsize', 11)
|
||||
else
|
||||
set(gca, 'xticklabels', []);
|
||||
end
|
||||
|
||||
box('off')
|
||||
axes{i} = gca();
|
||||
if i == 1
|
||||
l = legend('show');
|
||||
l.FontSize = 9;
|
||||
l.Box = 'off';
|
||||
l.Orientation = 'horizontal';
|
||||
l.Position = [0.25, 0.96, .5, 0.01];
|
||||
end
|
||||
end
|
||||
|
||||
axes{1}.Position = [axes{3}.Position(1) axes{2}.Position(2) ...
|
||||
axes{2}.Position(3) axes{3}.Position(4)];
|
||||
saveas(gcf, filename, 'pdf')
|
16
projects/project_onset_fi/solution/plotFICurve.m
Normal file
16
projects/project_onset_fi/solution/plotFICurve.m
Normal file
@ -0,0 +1,16 @@
|
||||
function plotFICurve(fi, fi_std, contrasts, filename)
|
||||
|
||||
figure()
|
||||
set(gcf, 'paperunits', 'centimeters', 'papersize', [10 10], ...
|
||||
'paperposition', [0.0 0.0 10, 10], 'color', 'white')
|
||||
|
||||
errorbar(contrasts, fi, fi_std, 'o', 'displayname', 'onset response')
|
||||
xlim([-20, 20])
|
||||
ylim([0, 600])
|
||||
xlabel('stimulus contrast [%]', 'fontsize', 11)
|
||||
ylabel('firing rate [Hz]', 'fontsize', 11)
|
||||
box('off')
|
||||
|
||||
if ~isempty(filename)
|
||||
saveas(gcf, filename, 'pdf')
|
||||
end
|
8
projects/project_onset_fi/solution/plotFICurveFit.m
Normal file
8
projects/project_onset_fi/solution/plotFICurveFit.m
Normal file
@ -0,0 +1,8 @@
|
||||
function plotFICurveFit(fi, fi_error, contrasts, fit_parameter, filename)
|
||||
|
||||
plotFICurve(fi, fi_error, contrasts, '')
|
||||
fit = boltzmannModel(fit_parameter, min(contrasts):0.1:max(contrasts));
|
||||
hold on
|
||||
plot(min(contrasts):0.1:max(contrasts), fit, 'displayname', 'Boltzmann fit')
|
||||
legend('Location', 'northwest')
|
||||
saveas(gcf, filename, 'pdf')
|
Reference in New Issue
Block a user