BC_pred.m 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. function [pred_output]=BC_pred(STA_output)
  2. %[pred_output]=BC_pred(STA_output)
  3. %this function shows the prinicpal calculation for the the prediction to
  4. %the white noise stimulus with the linear-nonlinear model (LN-model)for
  5. %continous voltage signals of bipolar cells (BC).
  6. %Inputs:
  7. % STA_output = output of the BC_STA function; containing the
  8. % STA and stimulus signal
  9. %
  10. %Outpus: pred_output = structure containing the output of the
  11. % prediction
  12. %
  13. %
  14. % Note: the function is built only for cells recorded without frozen frames.
  15. % But additional comments are made for cells with frozen frames.
  16. % code by HS, last modified March 2021
  17. %-------------------------------------------------------------------------------
  18. %% 1. recompute STA and nonlinearity without the stimulus signal that we want to predict
  19. %%Important we want to predict a stimulus sequence that was not used to
  20. %%build the model (filter and nonlinearity). Therefore we have to redo the
  21. %%filter(STA) and nonlinearity without the stimulus-sequence that we want
  22. %to predict the response(see Methods of Schreyer&Gollisch,2021).
  23. %In the Manuscript we predict 200 sequences of 300 frames long that where
  24. %randomly chosen (see Method section). Every time we rebuilt the STA and
  25. %NL. The overall prediction performance is then the average R^2 over all
  26. %200 sequences. Here, for simplicity I only show the prediction to one
  27. %sequence. Note however, to get a good estimate of how well the LN-model can predict
  28. %the response of the cell it is important to run it over multiple
  29. %sequences.
  30. %If we recorded Frozen frames, we predict the response to the frozen
  31. %frames from the model (filter and nonlinearity) we build from the running
  32. %frames.
  33. %% 1.1 STA
  34. %to keep the code easy: I here show the principal idea, by predicting the
  35. %response to the last 300frames of the white noise stimulus.
  36. %(in the manuscript we randomly choose 200 sequences and redo this part 200 times)
  37. %take out the stimulus sequence you want to predict
  38. stimPred=STA_output.stimulus2D_zoom(:,end-299:end); %the last 300frames
  39. %voltage trace to predict
  40. voltPred=STA_output.membranPotAVG(end-299:end); %the response to the last 300 frames
  41. %build the STA without the last 300 frames
  42. [STA_norm]=buildSTA ...
  43. (STA_output.stimulus2D_zoom(:,1:end-300),...
  44. STA_output.membranPotAVG(1:end-300),STA_output.STA_fnbr);
  45. STA3D_norm=reshape(STA_norm,size(STA_output.rangeY_zoom,2),size(STA_output.rangeX_zoom,2), ...
  46. size(STA_norm,2));% Y-zoom checkers (monitor axis), X-zoom checkers (monitor axis) and Z (STA_fnbr)
  47. %% 1.2 Nonlinearity
  48. %build the NL from the data without the last 300 frames
  49. generator_signal=filter2(STA_norm,STA_output.stimulus2D_zoom(:,1:end-300),'valid'); %see also Point 7
  50. %in the function BC_STA.m and BC_NL of how you do it when you have a best
  51. %spatial and temporal component and reduce noice by cutting 3-sigma
  52. %contour around the receptive field region.
  53. %get the corresponding membrane potential responses
  54. y_axisNL_unsorted=STA_output.membranPotAVG(STA_output.STA_fnbr:end-300); %the first value is at the length of the filter
  55. %sort the x axis
  56. [NL_xAxis,indx]=sort(generator_signal);
  57. %sort the corresponding y axis
  58. NL_yAxis=y_axisNL_unsorted(indx);
  59. %do a binning with percentile to have same amount of data in each bin
  60. %make 40 bins
  61. nbrbins=40;
  62. bins= doBin(NL_xAxis,NL_yAxis,nbrbins);
  63. %-------------------------------------------------------------------------------
  64. %% 2. compute the prediction
  65. %% 2.1 convolution
  66. %convolve the new stimulus sequence (not used for prediciton) with the
  67. %normalized STA
  68. stim2pred=filter2(STA_norm,stimPred,'valid');
  69. %% 2.2 compute the prediction through linear interpolation
  70. NL_x=bins.NL_xbin;
  71. NL_y=bins.NL_ybin;
  72. %example of how to make the prediction through linear interpolation
  73. predMemP_y=nan(1,size(stim2pred,2));
  74. for kk=1:size(stim2pred,2)
  75. nbrTemp=stim2pred(kk); %first x-axis value to predict
  76. [xIndxS,xIndxL]= getIndex(NL_x,nbrTemp,1); %get those values that are on left and rigth
  77. xValueS=NL_x(xIndxS);
  78. xValueL=NL_x(xIndxL);
  79. %do the linear interpolation
  80. [polyCoeff] = polyfit([xValueS;xValueL],[NL_y(xIndxS);...
  81. NL_y(xIndxL)],1);
  82. predMemP_y(kk)=polyCoeff(1)*nbrTemp+polyCoeff(2);
  83. end
  84. %-------------------------------------------------------------------------------
  85. %% 3. evaluate the prediction performance
  86. %pearson correlation
  87. corrcoeff_temp=corrcoef(voltPred(STA_output.STA_fnbr:end),predMemP_y); %the first value is at the length of the filter
  88. pearCorrSqrt=corrcoeff_temp(2)^2;
  89. %-------------------------------------------------------------------------------
  90. %% 4. plot the output
  91. figure;
  92. %STA
  93. subplot(2,2,1)
  94. [~,indx_Zoom]=max(abs(STA3D_norm(:))); %max intensity value of STA
  95. [~,~,posZ]=ind2sub(size(STA3D_norm),indx_Zoom); %get the frame position
  96. imagesc(STA3D_norm(:,:,posZ))
  97. colormap('gray'); %how the sitmulus was shown
  98. axis equal; axis tight;
  99. title('STA best frame')
  100. %NL
  101. subplot(2,2,2)
  102. plot(NL_xAxis,NL_yAxis,'.','color','k') %plot non-binned signal
  103. hold on;
  104. plot(bins.NL_xbin,bins.NL_ybin,'o','markerfacecolor','r','markeredgecolor','r') %plot binned signal
  105. title('NL')
  106. axis tight
  107. xlabel('generator signal')
  108. ylabel('voltage (mV)')
  109. %prediction
  110. subplot(2,2,3:4)
  111. plot(voltPred(STA_output.STA_fnbr:end),'k') %original membrane potential
  112. hold on;
  113. plot(predMemP_y,'r')%predicted membrane potential
  114. title(['pCorr:' mat2str(round(pearCorrSqrt,2)) ' Filename: ' STA_output.filename])
  115. xlabel('stimulus frames')
  116. ylabel('voltage (ms)')
  117. legend('original response','predicted response')
  118. %-------------------------------------------------------------------------------
  119. %% 5. add variables into the output
  120. pred_output.pearCorrSqrt=pearCorrSqrt;
  121. end
  122. function [IndS,IndL]= getIndex(x,valConv,Points)
  123. IndS=find(x<valConv,Points,'last'); %find the last 5 closest smaller values
  124. IndL=find(x>=valConv,Points);
  125. if isempty(IndS)|| length(IndS)<Points %if you are on the left border
  126. if isempty(IndS) %take value from 1:10
  127. IndL=find(x>=valConv,Points*2);
  128. IndS=IndL(1);
  129. IndL=IndL(2:end);
  130. else
  131. IndL=find(x>=valConv,Points*2-length(IndS));
  132. end
  133. elseif isempty(IndL)|| length(IndL)<Points %if you are on the right border
  134. if isempty(IndL) %take value from 1:10
  135. IndS=find(x<valConv,Points*2,'last');
  136. IndL=IndS(end);
  137. IndS=IndS(1:end-1);
  138. else
  139. IndS=find(x<valConv,Points*2-length(IndL));
  140. end
  141. end
  142. end