% Example code to extract and plot data from source data files for the % paper "Receptive field center-surround interactions mediate context-dependent % spatial contrast encoding in the retina" by Max Turner, Greg Schwartz, % and Fred Rieke. eLife. % % Prepared by Max Turner % mhturner@stanford.edu % 2018.09.03 %% Figure 2 - Source Data 1 % LinearEquivalentDiscModSurround is a structure array, each entry % corresponds to one Off parasol RGC. For each cell, there are fields: % .Responses (no. images tested x no. surrounds tested). Each response % structure has matrices of individual trial spike binaries for image % and linear equivalent disc stimuli % .Image (for each image tested) % .SurroundContrast (no. images tested x no. surrounds tested) % The stimulus comes on at 200 msec and stays on for 200 msec load('Figure 2 - Source Data 1.mat') CellIndex = 1; ImageIndex = 1; %Filter parameters for converting spike binary trains to PSTH sampleRate = 1e4; PSTHsigma = 10; %msec filterSigma = (PSTHsigma / 1e3) * sampleRate; %msec -> datapoints newFilt = gaussFilter1D(filterSigma); StimImage = LinearEquivalentDiscModSurround(CellIndex).Image{ImageIndex}; figure; clf; for ss = 1:9 subplot(1,10,ss); hold on; image_psth = sampleRate*conv(mean(LinearEquivalentDiscModSurround(CellIndex).Responses{ImageIndex,ss}.imageResponse),newFilt.amp,'same'); disc_psth = sampleRate*conv(mean(LinearEquivalentDiscModSurround(CellIndex).Responses{ImageIndex,ss}.discResponse),newFilt.amp,'same'); plot(image_psth,'k') plot(disc_psth,'r') axis off title(num2str(LinearEquivalentDiscModSurround(CellIndex).SurroundContrast(ss))) end subplot(1,10,10); imagesc(StimImage'); colormap(gray); axis image; %% Figure 3 - Source Data 1, 2, 3 % Source Data 1: Fig. 3A-C % Source Data 2: Fig. 3D-F % Source Data 3: Fig. 3 - Suppl. 1 % FlashedGratingModulatedSurround is a struct array. Each entry corresponds % to one cell. The fields of each structure are: % .GratingContrast = array of grating contrasts used for this cell % .SurroundContrast = array of surround contrasts used for this cell % .responses = (noGratingContrasts x noSurroundContrasts) cell array of % structs, each with a gratingResponse and a noGratingResponse for the % corresponding grating contrast and surround contrast. The extracellular % data contains both raw traces as well as binarized spike response % vectors % The stimulus comes on at 200 msec and stays on for 200 msec load('Figure 3 - Source Data 3.mat') cellIndex = 3; figure; clf; subplot(211); hold on; plot(mean(FlashedGratingModulatedSurround(cellIndex).responses{4,5}.gratingResponse),'k') plot(mean(FlashedGratingModulatedSurround(cellIndex).responses{4,5}.noGratingResponse),'r') title('No surround') subplot(212); hold on; plot(mean(FlashedGratingModulatedSurround(cellIndex).responses{4,1}.gratingResponse),'k') plot(mean(FlashedGratingModulatedSurround(cellIndex).responses{4,1}.noGratingResponse),'r') title('+Surround') %% Figure 4 - Source Data 1 % CenterSurroundWhiteNoise is a cell array, each entry of which is a structure that corresponds % to a cell in the dataset. Structure fields: % .stimulus = concatenated stimulus traces for .center and .surround % stimuli % .response = concatenated excitatory conductance response traces (in nS) % for .center, .surround and .centerSurround stimuli % Note that data are concatenated and grouped for convenience, but were % acquired in interleaved trials load('Figure 4 - Source Data 1.mat') figure(10); clf; for cc = 1:15 cellInd = cc; sampleRate = 1e4; %Hz filterLen = 500; %msec, length of linear filter to compute %frequency after which to cut off filter spectrum. The stimulus updated at 30 %Hz, so the cutoff should be below that value to avoid ringing filterPts = (filterLen/1000)*sampleRate; %msec -> datapoints centerFilter = getLinearFilter(CenterSurroundWhiteNoise{cellInd}.stimulus.center,... CenterSurroundWhiteNoise{cellInd}.response.center); centerFilter = centerFilter(1:filterPts); %trim to just filterLen surroundFilter = getLinearFilter(CenterSurroundWhiteNoise{cellInd}.stimulus.surround,... CenterSurroundWhiteNoise{cellInd}.response.surround); surroundFilter = surroundFilter(1:filterPts); %trim to just filterLen filterTimeVector = (1:filterPts) ./ sampleRate; %sec subplot(4,4,cc); hold on; plot(filterTimeVector, centerFilter,'b') plot(filterTimeVector, surroundFilter,'r') end %% Figure 7 - Source Data 1 % CenterSurroundNaturalImageLuminance is a cell array, each entry is a % structure corresponding to one cell. OFFcellInds and ONcellInds indicate % the elements of the array that ar OFF and ON parasol RGCs, respectively. % Each cell structure has stimuli and individual baseline-subtracted % excitatory current responses for each of the stimulus conditions: center % alone, surround alone, or center + surround in both control (correlated) % and shuffled conditions load('Figure 7 - Source Data 1.mat') cellInd = 2; figure; clf; subplot(221); hold on; plot(CenterSurroundNaturalImageLuminance{cellInd}.stimulus.controlCenter,'b') plot(CenterSurroundNaturalImageLuminance{cellInd}.stimulus.controlSurround,'r') title('Control') subplot(222); hold on; plot(CenterSurroundNaturalImageLuminance{cellInd}.stimulus.controlCenter,'b') plot(CenterSurroundNaturalImageLuminance{cellInd}.stimulus.shuffleSurround,'r') title('shuffled') subplot(223); hold on; plot(mean(CenterSurroundNaturalImageLuminance{cellInd}.response.controlCenterSurround),'k') plot(mean(CenterSurroundNaturalImageLuminance{cellInd}.response.controlCenter) +... mean(CenterSurroundNaturalImageLuminance{cellInd}.response.controlSurround),'color',[0.7 0.7 0.7]) subplot(224); hold on; plot(mean(CenterSurroundNaturalImageLuminance{cellInd}.response.shuffleCenterSurround),'k') plot(mean(CenterSurroundNaturalImageLuminance{cellInd}.response.shuffleCenter +... CenterSurroundNaturalImageLuminance{cellInd}.response.shuffleSurround),'color',[0.7 0.7 0.7]) %% convenience functions... function res = gaussFilter1D(sigma) % Just a one-dimensional gaussian filter, for PSTH smoothing x = -5*sigma:5*sigma; amp = exp((-x.^2)./(2*sigma^2)); amp = amp./(sum(amp)); %integrates to 1 res.x = x; res.amp = amp; end function LinearFilter = getLinearFilter(stimulus, response) % Quickly estimate a linear filter using a white noise stimulus and response FilterFft = mean((fft(response,[],2).*conj(fft(stimulus,[],2))),1) ; LinearFilter = real(ifft(FilterFft)) ; end