|
@@ -1,13 +1,14 @@
|
|
|
-function [naturalMovie_output]=BC_predNaturalMovies(loadData,filename,Hz,STA_output,NL_output)
|
|
|
-%[naturalMovie_output]=BC_predNaturalMovies(loadData,filename,pixelSize,Hz,STA_output,NL_output)
|
|
|
+function [naturalMovie_output]=BC_predNaturalMovies(loadData,filename,movieSignal,STA_output,NL_output,Hz)
|
|
|
+%[naturalMovie_output]=BC_predNaturalMovies(movieSignal,STA_output,NL_output)
|
|
|
%this function shows the prinicpal calculation for the prediction of the
|
|
|
%response to the natural movie, from the linear-nonlinear model (LN-model)
|
|
|
%computed with white noise stimulus.
|
|
|
%Inputs:
|
|
|
% loadData = the folder path of the natural movie files
|
|
|
% filename = the filename of the BC of interest
|
|
|
-% movieData
|
|
|
-% Hz = stimulus update rate
|
|
|
+% movieSignal = the preprocessed natural movie signal the
|
|
|
+% output of the BC_getNaturalMovies.m. Important that the
|
|
|
+% movie signal has the same dimensions as the STA_output
|
|
|
% STA_output = output of the BC_STA function; containing the
|
|
|
% STA (filter) of the white noise stimulus
|
|
|
% NL_output = output of the BC_NL function; containing the
|
|
@@ -16,27 +17,33 @@ function [naturalMovie_output]=BC_predNaturalMovies(loadData,filename,Hz,STA_out
|
|
|
%Outpus: naturalMovie_output = structure containing the output of the
|
|
|
% prediction
|
|
|
%
|
|
|
-%
|
|
|
-
|
|
|
-%-------------------------------------------------------------------------------
|
|
|
-%% 1. Get the movie contrast values
|
|
|
-%the movies can be downloaded under the following
|
|
|
-%link:https://zenodo.org/record/46481. See documentation.data.pdf for
|
|
|
-%further instructions, also which frames to take.
|
|
|
-%they have to be prepared as follow:
|
|
|
+% code by HS last modiefied Feb 2021
|
|
|
|
|
|
+%% Constants
|
|
|
+findBreak=500; %the movie is repeated multiple times. Between the movies there is
|
|
|
+%a break/gray screen of >0.5s. To find the start of each movie trial, you find the gray screen between the movies
|
|
|
|
|
|
+%-------------------------------------------------------------------------------
|
|
|
+%% 1. cut the natural movie signal to the size of the filter
|
|
|
+%in the BC_STA.m function, the STA was cut. Here the natural movie signal
|
|
|
+%has to be cut to the same dimensions.
|
|
|
+movieSignal_zoom=movieSignal(STA_output.rangeY_zoom,STA_output.rangeX_zoom,:);
|
|
|
+%make the signal 2D for prediction
|
|
|
+movieSignal2D_zoom=reshape(movieSignal_zoom,size(movieSignal_zoom,1)*...
|
|
|
+ size(movieSignal_zoom,2),size(movieSignal_zoom,3));
|
|
|
|
|
|
%-------------------------------------------------------------------------------
|
|
|
%% 2. compute the prediction
|
|
|
%% 2.1 convolution
|
|
|
-%convolve the new stimulus sequence (not used for prediciton) with the
|
|
|
+%normalize the filter
|
|
|
+linearFiler=normSTA(STA_output.STA2D_zoom);
|
|
|
+%convolve the natural movie stimulus sequence with the
|
|
|
%normalized STA
|
|
|
-stim2pred=filter2(STA_norm,stimPred,'valid');
|
|
|
+stim2pred=filter2(linearFiler,movieSignal2D_zoom,'valid');
|
|
|
|
|
|
%% 2.2 compute the prediction through linear interpolation
|
|
|
-NL_x=bins.NL_xbin;
|
|
|
-NL_y=bins.NL_ybin;
|
|
|
+NL_x=NL_output.bins.NL_xbin;
|
|
|
+NL_y=NL_output.bins.NL_ybin;
|
|
|
%example of how to make the prediction through linear interpolation
|
|
|
predMemP_y=nan(1,size(stim2pred,2));
|
|
|
for kk=1:size(stim2pred,2)
|
|
@@ -51,36 +58,74 @@ for kk=1:size(stim2pred,2)
|
|
|
end
|
|
|
|
|
|
%-------------------------------------------------------------------------------
|
|
|
-%% 3. evaluate the prediction performance
|
|
|
+%% 4. compute the average response to the move
|
|
|
+%% 4.1 load movie response
|
|
|
+data=load([loadData,filename]); %load the file
|
|
|
+
|
|
|
+%sort the different pulses for the different trials
|
|
|
+diffttls=diff(data.ttls_ms);
|
|
|
+nbrTrials=find(diffttls>findBreak); %to find out which pulse correspond to a new trial (gray break)
|
|
|
+nbrFrames=diff(nbrTrials);
|
|
|
+if isempty(nbrFrames)
|
|
|
+ nbrFrames=nbrTrials;
|
|
|
+end
|
|
|
+%I get the membrane potential per trial & frames per trial
|
|
|
+reOrderFrames=nan(nbrFrames(1),length(nbrTrials));
|
|
|
+membranePerTrial_origRes=cell(1,length(nbrTrials));
|
|
|
+for kk=1:length(nbrTrials)
|
|
|
+ if kk==1 %first trial
|
|
|
+ reOrderFrames(:,kk)=data.ttls_ms(1:nbrTrials(kk));
|
|
|
+ membranePerTrial_origRes{kk}=data.membPot(reOrderFrames(1,kk):reOrderFrames(end,kk)-1); %-1 because the last frame is the start of the gray screen
|
|
|
+ else
|
|
|
+ reOrderFrames(:,kk)=data.ttls_ms(nbrTrials(kk-1)+1:nbrTrials(kk)); %end of previous trial +1 (starts at 999)
|
|
|
+ membranePerTrial_origRes{kk}=data.membPot(reOrderFrames(1,kk):reOrderFrames(end,kk)-1);
|
|
|
+ end
|
|
|
+end
|
|
|
+%I only include trials here that here fully finished until the break!
|
|
|
+
|
|
|
+%------------------------------------------------------------------------------------------
|
|
|
+%% 4.2 Natural Movie Build average per frame
|
|
|
+%make one value for the membrane potential between two stimulus signal (two
|
|
|
+%frames), where the same image was shown
|
|
|
+memPperTrial_Movie=avgPerFrameNatMovies(data.membPot,...
|
|
|
+ reOrderFrames,nbrFrames(1),Hz);
|
|
|
+
|
|
|
+memP_AVGMovie=mean(memPperTrial_Movie,2);
|
|
|
+
|
|
|
+%------------------------------------------------------------------------------------------
|
|
|
+%% 5 compute the pearson correlation coefficient
|
|
|
%pearson correlation
|
|
|
-corrcoeff_temp=corrcoef(voltPred(STA_output.STA_fnbr:end),predMemP_y); %the first value is at the length of the filter
|
|
|
+corrcoeff_temp=corrcoef(memP_AVGMovie(STA_output.STA_fnbr:end),predMemP_y);
|
|
|
pearCorrSqrt=corrcoeff_temp(2)^2;
|
|
|
+%not with this method the prediction value is a bit lower than what we report in the
|
|
|
+%manuscript. To get the same values as in the mansucript, you have to
|
|
|
+%cut 3sigma around the RF and perform the SVD (see also Manuscript and
|
|
|
+%BC_STA, BC_NL)
|
|
|
|
|
|
%-------------------------------------------------------------------------------
|
|
|
-%% 4. plot the output
|
|
|
+%% 6. plot the output
|
|
|
figure;
|
|
|
-%STA
|
|
|
-subplot(2,2,1)
|
|
|
-[~,indx_Zoom]=max(abs(STA3D_norm(:))); %max intensity value of STA
|
|
|
-[~,~,posZ]=ind2sub(size(STA3D_norm),indx_Zoom); %get the frame position
|
|
|
-imagesc(STA3D_norm(:,:,posZ))
|
|
|
+%plot the first frame of the move
|
|
|
+subplot(2,1,1)
|
|
|
+imagesc(movieSignal(:,:,1))
|
|
|
colormap('gray'); %how the sitmulus was shown
|
|
|
axis equal; axis tight;
|
|
|
-title('STA best frame')
|
|
|
-%NL
|
|
|
-subplot(2,2,2)
|
|
|
-plot(NL_xAxis,NL_yAxis,'.','color','k') %plot non-binned signal
|
|
|
-hold on;
|
|
|
-plot(bins.NL_xbin,bins.NL_ybin,'o','markerfacecolor','r','markeredgecolor','r') %plot binned signal
|
|
|
-title('NL')
|
|
|
-axis tight
|
|
|
-xlabel('generator signal')
|
|
|
-ylabel('voltage (mV)')
|
|
|
-%prediction
|
|
|
-subplot(2,2,3:4)
|
|
|
-plot(voltPred(STA_output.STA_fnbr:end),'k') %original membrane potential
|
|
|
+xticks([]); yticks([]);
|
|
|
+
|
|
|
+%plot the prediction trace
|
|
|
+subplot(2,1,2)
|
|
|
+%only for visual comparison we normalize the predicted trace to have the
|
|
|
+%same mean and std as the response to the movie.
|
|
|
+x=predMemP_y;
|
|
|
+m2=mean(memP_AVGMovie);
|
|
|
+s2=std(memP_AVGMovie);
|
|
|
+s1=std(x);
|
|
|
+m1=mean(x);
|
|
|
+corrPredMemPred=m2+(x-m1)*(s2/s1);
|
|
|
+
|
|
|
+plot(memP_AVGMovie(STA_output.STA_fnbr:end),'k') %original membrane potential
|
|
|
hold on;
|
|
|
-plot(predMemP_y,'r')%predicted membrane potential
|
|
|
+plot(corrPredMemPred,'r')%predicted membrane potential
|
|
|
title(['pCorr:' mat2str(round(pearCorrSqrt,2)) ' Filename: ' STA_output.filename])
|
|
|
xlabel('stimulus frames')
|
|
|
ylabel('voltage (ms)')
|
|
@@ -88,8 +133,8 @@ legend('original response','predicted response')
|
|
|
|
|
|
%-------------------------------------------------------------------------------
|
|
|
%% 5. add variables into the output
|
|
|
-pred_output.pearCorrSqrt=pearCorrSqrt;
|
|
|
-
|
|
|
+naturalMovie_output.pearCorrSqrt=pearCorrSqrt;
|
|
|
+naturalMovie_output.memP_AVGMovie=memP_AVGMovie;
|
|
|
end
|
|
|
|
|
|
function [IndS,IndL]= getIndex(x,valConv,Points)
|
|
@@ -112,4 +157,15 @@ elseif isempty(IndL)|| length(IndL)<Points %if you are on the right border
|
|
|
IndS=find(x<valConv,Points*2-length(IndL));
|
|
|
end
|
|
|
end
|
|
|
-end
|
|
|
+end
|
|
|
+
|
|
|
+% %make SVD of the filter
|
|
|
+% [sp,sigma,temp] = svd(STA_output.STA2D_zoom,'econ');
|
|
|
+% sp=sp(:,1);
|
|
|
+% imagesc(reshape(sp,size(STA_output.rangeY_zoom,2),size(STA_output.rangeX_zoom,2)));
|
|
|
+% temp=temp(:,1);
|
|
|
+% %linear filters
|
|
|
+% linearFiler1=normSTA(sp);
|
|
|
+% linearFiler2=normSTA(temp);
|
|
|
+% stim2pred=filter2(linearFiler1,movieSignal2D_zoom,'valid');
|
|
|
+% stim2pred=filter2(linearFiler2',stim2pred,'valid');
|