Grid cell oscillatory interference with noisy network oscillators (Zilli and Hasselmo 2010)

 Download zip file 
Help downloading and running models
Accession:128812
To examine whether an oscillatory interference model of grid cell activity could work if the oscillators were noisy neurons, we implemented these simulations. Here the oscillators are networks (either synaptically- or gap-junction--coupled) of one or more noisy neurons (either Izhikevich's simple model or a Hodgkin-Huxley--type biophysical model) which drive a postsynaptic cell (which may be integrate-and-fire, resonate-and-fire, or the simple model) which should fire spatially as a grid cell if the simulation is successful.
Reference:
1 . Zilli EA, Hasselmo ME (2010) Coupled Noisy Spiking Neurons as Velocity-Controlled Oscillators in a Model of Grid Cell Spatial Firing J. Neurosci. 30(41):13850-13860
Citations  Citation Browser
Model Information (Click on a link to find other models with that property)
Model Type: Realistic Network; Neuron or other electrically excitable cell;
Brain Region(s)/Organism:
Cell Type(s): Neocortex spiny stellate cell; Abstract integrate-and-fire leaky neuron;
Channel(s): I Na,p; I Na,t; I K; I K,leak; I h;
Gap Junctions: Gap junctions;
Receptor(s):
Gene(s):
Transmitter(s):
Simulation Environment: MATLAB;
Model Concept(s): Oscillations; Synchronization; Simplified Models; Spike Frequency Adaptation; Grid cell;
Implementer(s): Zilli, Eric [zilli at bu.edu];
Search NeuronDB for information about:  I Na,p; I Na,t; I K; I K,leak; I h;
/
ZilliHasselmo2010
README.txt
Acker_sn_FI_n250.mat
fig_RS2sn_filthaftingtraj_n5000_p01_1noise_02res_July13_2D_spikes_0a.txt
fig_RS2sn_filthaftingtraj_n5000_p01_1noise_02res_July13_C_0a.mat
FigS4ABC_izh_simple0b_RS4sn_LIF_oct30_vary_gandncells_1noise_newpost_draft1.txt
FigS4DEF_izh_simple0b_RS4gn_LIF_oct30_vary_gandncells_1noise_newpost_draft1.txt
FigS8_izh_simple0b_RS2gn_LIF_nov08_vary_gandncells_0.125noise_newpost_draft1.txt
FigS8_izh_simple0b_RS2gn_LIF_nov08_vary_gandncells_0.25noise_newpost_draft1.txt
FigS8_izh_simple0b_RS2gn_LIF_nov08_vary_gandncells_0.5noise_newpost_draft1.txt
FigS8_izh_simple0b_RS2gn_LIF_nov08_vary_gandncells_1noise_newpost_draft1.txt
FigS8_izh_simple0b_RS2gn_LIF_nov08_vary_gandncells_2noise_newpost_draft1.txt
FigS8_izh_simple0b_RS2gn_LIF_nov08_vary_gandncells_4noise_newpost_draft1.txt
hafting_trajectory.m
rat_10925.mat
SI_acker_model_2d_grid.m
SI_acker_model_FI_history_dependence.m
SI_acker_model_FI_relations.m
SI_acker_model_stability_vs_params.m
SI_simple_model_2d_grid.m
SI_simple_model_FI_history_dependence.m
SI_simple_model_FI_relation.m
SI_simple_model_stability_vs_params.m
simple_model_RS1_FI_Jan09_n1.mat
simple_model_RS1gn_FI_Jan09_n250.mat
simple_model_RS1n_FI_Jan09_n1.mat
simple_model_RS1sn_FI_Jan09_n250.mat
simple_model_RS2_ext_FI_Jan09_n1.mat
simple_model_RS2_FI_Jan09_n1.mat *
simple_model_RS2gn_FI_Jan09_n250.mat
simple_model_RS2n_FI_Jan09_n1.mat
simple_model_RS2sn_FI_Jan01_n5000.mat
simple_model_RS2sn_FI_Jan01_n5000.txt
simple_model_RS2sn_FI_Jan09_n250.mat *
simple_model_RS2sn_FI_Jul10_n5000.mat
simple_model_RS2sn_FI_Jul10_n5000.txt
simple_model_RS2sn_FI_Jul11_n5000.mat
simple_model_RS2sn_FI_Jul11_n5000.txt
                            
% izhikevich simple model neuron network with random connectivity
% with time constant input at varying levels with LIF-measured stability
% eric zilli - june 28, 2009 using simple model MATLAB code from
% Izhikevich's book modified to be a network
%
% release version 1.0. check modeldb for updates.
%
% this source code is released into the public domain
% 
% This script calculates the FI curve of a network of simple model neurons.
%
% Note: this is a cleaned up version of the script used to generate the
% paper figures--it is possible errors were introduced during the cleaning!
% Feel free to contact me if there is any difficulty reproducing any
% results from the manuscript.
%
% Note 2: This can take a while, but it is highly parallelizable because
% each of the ~200 runs (4 Hz/0.02 (Hz/run)) are completely independent. This also makes it a
% quick matter to estimate how long running a complete FI will take: number
% of simulations times length of single simulation.
%
% Note 3: Careful of the n=1 noisy case where there is no coupling to
% cancel out the noise: the resolution of the FI curve you can get will be
% very limited unless you run extremely long simulations.
%
% Note 4: If you're trying to run simulations not shown in the paper (i.e.
% going off into your own territory), I advise paying particular attention
% to the estimated stability time over the FI curve. In particular, it's
% going to decrease at higher frequencies and you're going to want even the
% lowest value to be at least as long as the length of the
% spatial trajectory you're going to run (and if the stability time is,
% say, twice as high, all the better!). Try increasing ncells if you want
% higher values, but you may have to go back and find a new g value that
% works for it.
%
% Note 5: If generating FI curves for 2D grid simulations is going slow,
% try a coarser resolution then come back and run this again to fill in the
% blanks if it turns out the FI curve didn't have enough resolution (which
% will manifest as a large slope in the VCO phase differences vs. time: the
% overall slope should be essentially flat/zero if the resolution is high enough, I
% think). If you have sampled x:a:y, try (x+a/2):a:y then (x+a/4):a/2:y
% then (x+a/8):a/4:y, etc. (this doubles the resolution each time without
% overlapping a previous run).


clear all;
warning off

% type=1 - (Figure 1) class 2 excitable, n=1, noise-free
% type=2 - (Figure 1) class 2 excitable, n=1, noisy
% type=3 - (Figure 1) class 2 excitable, n=250, gap-junction, noisy
% type=4 - (Figure 1) class 2 excitable, n=250, synaptic, noisy
% type=5 - class 1 excitable, n=1, noise-free
% type=6 - class 1 excitable, n=1, noisy
% type=7 - class 1 excitable, n=250, gap-junction, noisy
% type=8 - class 1 excitable, n=250, synaptic, noisy
% type=9 - class 2 excitable, n=1, noise-free, extended past 11 Hz for history dependence script
% type=10 - class 2 excitable, n=5000, p=0.01, synaptic, noisy
% (type=11 is commented out below but might be of interest)

for type=[10];
  disp(sprintf('type = %d',type))
  
  % simulation time step
  dt = .1; % ms

  nruns = 1;

  % whether or not per-run statistics are saved to a file
  % (from this output file the FI curve can be found in the I and mean
  % period columns)
  fileOut = 1;

  % if fileOut==1, this uses the output saved in the output file to create
  % a .mat file of the FI curve that can be used in the 2D simulations
  generateFIfile = 1;
  
  % if fileOut==1 and generateFIfile==1, this will load a pre-existing FI
  % file (if it exists) and merge the new results in, e.g. to increase the
  % resolution of an existing file (new values will overwrite old values)
  mergeOld = 1;
  
  % set number of ISIs to skip from beginning of simulation, which are likely to
  % be corrupted by start-up transients
  skipISIs = 5;
  skipFirstHalf = 0;
  pcon = 1;
  useNoise = 1;
  commonNoiseSTD = 0;

  % if not-empty, this filed will be loaded to provide the connectivity
  % matrix C
  loadC = '';
%   % to make a C:
%   C = (rand(ncells)<pcon)>0;
%   C = sparse(C-eye(size(C))>0); % remove autoconnections
%   save C_simple_nX_pX.mat C
  
  if type==1
    excitationClass = 2;
    useGapJunctions = 1;
    g = 0;
    useNoise = 0;
    uniqueNoiseSTD = 100*useNoise;
    simdur = 2500; % ms
    ncells = 1;
    inputMags = 100:0.1:128;
  elseif type==2
    excitationClass = 2;
    useGapJunctions = 1;
    g = 0;
    uniqueNoiseSTD = 100*useNoise;
    simdur = 60000; % ms
    ncells = 1;
    inputMags = 100:0.1:128; % note: due to noise this resolution is probably too high
  elseif type==3
    excitationClass = 2;
    useGapJunctions = 1;
    g = 0.1;
    uniqueNoiseSTD = 100*useNoise;
    simdur = 15000; % ms
    ncells = 250;
    inputMags = 100:0.1:128;
  elseif type==4
    excitationClass = 2;
    useGapJunctions = 0;
    g = 256;
    uniqueNoiseSTD = 100*useNoise;
    simdur = 15000; % ms
    ncells = 250;
    inputMags = 2.^[6.5:.005:8];
  elseif type==5
    excitationClass = 1;
    useGapJunctions = 1;
    g = 0;
    useNoise = 0;
    uniqueNoiseSTD = 100*useNoise;
    simdur = 2500; % ms
    ncells = 1;
    inputMags = [60:.1:80];
  elseif type==6
    excitationClass = 1;
    useGapJunctions = 1;
    g = 0;
    uniqueNoiseSTD = 130*useNoise;
    simdur = 60000; % ms
    ncells = 1;
    inputMags = [60:.1:80]; % note: due to noise this resolution is probably too high
  elseif type==7
    excitationClass = 1;
    useGapJunctions = 1;
    g = 0.1;
    uniqueNoiseSTD = 130*useNoise;
    simdur = 15000; % ms
    ncells = 250;
    inputMags = 80; [56:.1:80];
  elseif type==8
    excitationClass = 1;
    useGapJunctions = 0;
    g = 128;
    uniqueNoiseSTD = 130*useNoise;
    simdur = 15000; % ms
    ncells = 250;
    inputMags = [70:.1:120];
  elseif type==9
    excitationClass = 2;
    useGapJunctions = 1;
    g = 0;
    useNoise = 0;
    uniqueNoiseSTD = 100*useNoise;
    simdur = 2500; % ms
    ncells = 1;
    inputMags = 100:0.1:133;
  elseif type==10
    excitationClass = 2;
    useGapJunctions = 0;
    g = 256;
    pcon = 0.01;
    loadC = 'C_simple_sn_n5000_p01.mat';
    useNoise = 1;
    uniqueNoiseSTD = 100*useNoise;
    simdur = 10000; % ms
    ncells = 5000;
    inputMags = [100.5:1:125];
  end
  
%% this case may be of interest to people hoping to eliminate
%% history-dependence on firing frequency:
%   elseif type==11
%     excitationClass = -1; % -1 means type 1 with u resetting instead of incrementing
%     useGapJunctions = 1;
%     g = 0.1;
%     uniqueNoiseSTD = 130*useNoise;
%     I = 62;
%     inputMags = [58:.05:86];


  
  outfilename = ['simple_model_RS' sprintf('%d',excitationClass)];
  if ncells>1
    if useGapJunctions
      outfilename = [outfilename 'g'];
    else
      outfilename = [outfilename 's'];
    end
  end
  if useNoise
    outfilename = [outfilename 'n'];
  end
  if type==9
    outfilename = [outfilename '_ext'];
  end
  outfilename = [outfilename '_FI_' datestr(now,'mmmdd') '_n' num2str(ncells) '.txt'];

  outfilename = 'simple_model_RS2sn_FI_Jul11_n5000.txt';
  disp('outfilename is being overridden!')
  
  disp(outfilename)
  
  % file to save statistics for every individual cell in network, don't
  % save if indivname = ''
  indivname = '';
  % indivname = [strtok(outfilename,'.') '_individualcells.txt'];

  Cf=100; vr=-60; vt=-40; k=0.7; % parameters used for RS
  a=0.03; c=-50; d=100; % neocortical pyramidal neurons
  vpeak=35; % spike cutoff
  if abs(excitationClass)==1
    b=-2;
  elseif abs(excitationClass)==2
    b = 2;
  end

  if excitationClass<0
    d = 60; % reset to 60 instead of 100
  end

  n=round(simdur/dt); % number of simulation steps

  if ~isempty(loadC)
    load(loadC)
  else
    % connectivity matrix
    C = (rand(ncells)<pcon)>0;
    C = sparse(C.*(1-eye(ncells))); % remove autoconnections
  end

  for inputi=1:length(inputMags)

    stabilities = zeros(1,nruns);
    stabilities2 = zeros(1,nruns);
    for run=1:nruns
      % activity of postsynaptic I&F
      npost = 1;
      post = zeros(npost, round(simdur/dt)+1);

      % spike times of postsynaptic I&F
      postspikes = spalloc(npost, round(simdur/dt)+1, 20*simdur); % expect firing at 20 Hz

      % I&F params
      tau = 4.5; % (ms)
      membraneDecay = exp(-dt/tau);
      postWeight=1.2/ncells;
      if type==10
        postWeight = 0.0006;
      end

      % magnitude of noise added to all cells on each step
      commonNoiseSTD = 0;
      commonNoise = 0;

      t = 0; % current time in simulation
      v = vr*ones(ncells,1);
      u = 0*v; % initial values

      % save state of one cell over simulation:
      state = zeros(2,simdur/dt);

      % binary array indicating which cells fire on each time steps
      spikes = zeros(ncells, 1);

      tic
      while t<simdur
        t = t+dt; % advance to next time step
        tind = 1+round(t/dt);

        if commonNoiseSTD
          commonNoise = commonNoiseSTD*randn;
        end

        I = inputMags(inputi); % externally applied input

        oldv = v;
        oldu = u;
        if useGapJunctions
          if pcon==1
            % if all-to-all connected, the gap-junctions are equivalent
            % to sum(v)-ncells*v
            v = oldv + dt*(k*(oldv-vr).*(oldv-vt) - oldu + I + commonNoise + uniqueNoiseSTD*randn(ncells,1) + g*(sum(v)-ncells*v))/Cf;
          else
            % make matrix of differences in membrane potential
            vdiffs = C.*(repmat(oldv',ncells,1) - repmat(oldv,1,ncells));
            v = oldv + dt*(k*(oldv-vr).*(oldv-vt) - oldu + I + commonNoise + uniqueNoiseSTD*randn(ncells,1) + g*sum(vdiffs,2))/Cf;
            %% slowest way:
            % v = oldv + dt*(k*(oldv-vr).*(oldv-vt) - oldu + I + commonNoise + uniqueNoiseSTD*randn(ncells,1) + g*sum(C.*vdiffs,2))/Cf;
          end
        else
          if pcon==1
            v = oldv + dt*(k*(oldv-vr).*(oldv-vt) - oldu + I + commonNoise + uniqueNoiseSTD*randn(ncells,1) + g*(sum(spikes,1)-spikes))/Cf;
          else
            v = oldv + dt*(k*(oldv-vr).*(oldv-vt) - oldu + I + commonNoise + uniqueNoiseSTD*randn(ncells,1) + g*(C*double(spikes)))/Cf;
          end
        end
        u = oldu + dt*a*(b*(oldv-vr)-oldu);

        % save and reset spikes when v>=vpeak
        spikes = v>=vpeak;
        if excitationClass>0
          u(v>=vpeak) = u(v>=vpeak)+d;
        else
          u(v>=vpeak) = d;
        end
        oldv(v>=vpeak) = vpeak;
        v(v>=vpeak) = c;

        state(:,tind) = [oldv(1); oldu(1)];

        post(:,tind) = post(:,tind-1)*membraneDecay + tau*postWeight*sum(spikes);
        % to save memory, instead of keeping a separate matrix for the
        % times the postsynaptic cell fired, we reset it to
        % ever-so-slightly below 0 to identify when it has spiked
        post(post(:,tind)>1,tind) = -1e-10;
      end
      toc
      % calculate mean and variance of ISIs for each postsynaptic cell
      npost = 1; %size(post,1);
      ISImeans = zeros(1,npost);
      ISIstds = zeros(1,npost);
      ISIstabilities = zeros(1,nruns);
      
      %% calculate ISI statistics for the postsynaptic LIF neurons
      for ce=1:npost % only run this once because we only save the last value in stabilities
        spikeTimes = find(post(ce,:)==-1e-10);
        ISIs = dt*diff(spikeTimes)/1000; % convert to seconds

        % count ISIs as occuring between initial
        % spikes of bursts (and additional spikes as occuring in a given
        % burst if they are < 50 ms apart);
        fISIs = [];
        csum = 0;
        for is=1:length(ISIs)
          csum = csum + ISIs(is);
          if ISIs(is)>.050
            fISIs = [fISIs csum];
            csum=0;
          end
        end
        ISIs = fISIs;

        if skipISIs
          ISIs = ISIs(skipISIs:end);
        end
        if skipFirstHalf
          ISIs = ISIs(end/2:end);
        end


        ISImeans(ce) = mean(ISIs);
        ISIstds(ce) = std(ISIs);
        ISIstabilities(ce) = 5*ISImeans(ce)^3/16/pi^2/(eps+ISIstds(ce))^2;
      end

      % save to file:
      if fileOut
        fid = fopen(outfilename,'a');
        fprintf(fid,'%d\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%d\n', ...
          ncells,pcon,I,g,simdur/1000, useNoise*uniqueNoiseSTD,tau,postWeight,...
          Cf,vr,vt,k,a,b,c,d,vpeak,...
          mean(1./ISIs),ISImeans(1),ISIstds(1),ISIstabilities(1),length(ISIs),...
          length(spikeTimes));
        fclose(fid);
      end
      fprintf('%d\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%d\n', ...
        ncells,pcon,I,g,simdur/1000, useNoise*uniqueNoiseSTD,tau,postWeight,...
        Cf,vr,vt,k,a,b,c,d,vpeak,...
        mean(1./ISIs),ISImeans(1),ISIstds(1),ISIstabilities(1),length(ISIs), ...
        length(spikeTimes));

      if ~isempty(indivname)
        fid = fopen(indivname,'a');
        fprintf(fid,'%d\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%d\n', ...
          ncells,pcon,I,g,simdur/1000, useNoise*uniqueNoiseSTD,tau,postWeight,...
          mean(1./ISIs),ISImeans(1),ISIstds(1),ISIstabilities(1),length(ISIs),...
          length(spikeTimes));
        fclose(fid);
      end
    end

  end

  % now re-open the text file we just wrote and save the relevant bits as a
  % .mat file
  if fileOut && generateFIfile
    clear freqs currents;
    FIfilename = [strtok(outfilename,'.') '.mat'];
    data = textread(outfilename);

    if mergeOld && exist(FIfilename)==2
      load(FIfilename);
    else
      freqs = []; currents = [];
    end
    freqs = [freqs(:); data(:,18)];
    currents = [currents(:); data(:,3)];
    
    % in case of duplicates, use the newer one:
    [currents,m,n] = unique(currents);
    freqs = freqs(m);
    [freqs,m,n] = unique(freqs);
    currents = currents(m);

    if any(diff(freqs)<0)
      warning('badness happened! freqs is non-monotonic! generally noise causes this: increasing simdur may help; else use parameters to lower effects of noise. dropping bad samples')
      bads = find(diff(freqs)<0);
      freqs(bads+1) = [];
      currents(bads+1) = [];
    end
    
    save(FIfilename,'freqs','currents');
  end
end

warning on
return

%% To generate Figure 4 itself once the FI curves are generated
ms = 16;
figure; hold on;
load simple_model_RS2gn_FI_Jan05_n250.mat;
% load RS4gnFI_250b;
plot(currents,freqs,'b.-','MarkerSize',ms);
load simple_model_RS2n_FI_Jan05_n1.mat;
% load RS4nFI_1b;
plot(currents,freqs,'r.-','MarkerSize',ms);
load simple_model_RS2_FI_Jan05_n1.mat;
% load RS4FI_1b;
plot(currents,freqs,'k.-','MarkerSize',10); 
load simple_model_RS2sn_FI_Jan05_n250.mat;
% load RS4snFI_250b; % load last to use in other fig
plot(currents,freqs,'m.-','MarkerSize',14);
xlabel('Input current magnitude','fontsize',12); ylabel('Network frequency (Hz)','fontsize',12)
set(gcf,'position',[82 404 2*257 302])
set(gca,'xlim',[100 300])
set(gca,'ylim',[4 11])
set(gca,'fontsize',12)
if exist('fig4a_RS2all_freq_vs_I.eps')~=2
  print_eps('fig4a_RS2all_freq_vs_I.eps')
  saveas(gcf,'fig4a_RS2all_freq_vs_I.fig')
end

figure;
beta=2; omegab=freqs(1)/2+freqs(end)/2;
vels = (freqs-omegab)/beta;
plot(vels,currents);
xlabel('Velocity (m/s)','fontsize',12); ylabel('Input current magnitude','fontsize',12);
set(gcf,'position',[82 404 1*257 302])
set(gca,'xlim',[min(vels) max(vels)]);
set(gca,'ylim',[min(currents) max(currents)]);
set(gca,'fontsize',12)
if exist('fig4b_RS2all_vel_vs_I.eps')~=2
  print_eps('fig4b_RS2all_vel_vs_I.eps')
  saveas(gcf,'fig4b_RS2all_vel_vs_I.fig')
end