Electrostimulation to reduce synaptic scaling driven progression of Alzheimers (Rowan et al. 2014)

 Download zip file   Auto-launch 
Help downloading and running models
Accession:154096
"... As cells die and synapses lose their drive, remaining cells suffer an initial decrease in activity. Neuronal homeostatic synaptic scaling then provides a feedback mechanism to restore activity. ... The scaling mechanism increases the firing rates of remaining cells in the network to compensate for decreases in network activity. However, this effect can itself become a pathology, ... Here, we present a mechanistic explanation of how directed brain stimulation might be expected to slow AD progression based on computational simulations in a 470-neuron biomimetic model of a neocortical column. ... "
Reference:
1 . Rowan MS, Neymotin SA, Lytton WW (2014) Electrostimulation to reduce synaptic scaling driven progression of Alzheimer's disease. Front Comput Neurosci 8:39 [PubMed]
Citations  Citation Browser
Model Information (Click on a link to find other models with that property)
Model Type: Realistic Network;
Brain Region(s)/Organism: Neocortex;
Cell Type(s): Neocortex L5/6 pyramidal GLU cell; Neocortex L2/3 pyramidal GLU cell; Neocortex V1 interneuron basket PV GABA cell; Neocortex fast spiking (FS) interneuron; Neocortex spiny stellate cell; Neocortex spiking regular (RS) neuron; Neocortex spiking low threshold (LTS) neuron;
Channel(s):
Gap Junctions:
Receptor(s): GabaA; AMPA; NMDA;
Gene(s):
Transmitter(s): Gaba; Glutamate;
Simulation Environment: NEURON; Python;
Model Concept(s): Long-term Synaptic Plasticity; Aging/Alzheimer`s; Deep brain stimulation; Homeostasis;
Implementer(s): Lytton, William [bill.lytton at downstate.edu]; Neymotin, Sam [Samuel.Neymotin at nki.rfmh.org]; Rowan, Mark [m.s.rowan at cs.bham.ac.uk];
Search NeuronDB for information about:  Neocortex L5/6 pyramidal GLU cell; Neocortex L2/3 pyramidal GLU cell; Neocortex V1 interneuron basket PV GABA cell; GabaA; AMPA; NMDA; Gaba; Glutamate;
/
RowanEtAl2014
batchscripts
mod
README
alz.hoc
alzinfo.m
autotune.hoc *
basestdp.hoc *
batch.hoc *
batch2.hoc *
batchcommon
checkirreg.hoc *
clusterrun.sh
col.dot *
col.hoc *
comppowspec.hoc *
condisconcellfig.hoc *
condisconpowfig.hoc *
declist.hoc *
decmat.hoc *
decnqs.hoc *
decvec.hoc *
default.hoc *
drline.hoc *
e2hubsdisconpow.hoc *
e2incconpow.hoc *
filtutils.hoc *
flexinput.hoc
geom.hoc *
graphplug.hoc *
grvec.hoc *
infot.hoc *
init.hoc *
labels.hoc *
load.hoc *
local.hoc *
makepopspikenq.hoc *
matfftpowplug.hoc *
matpmtmplug.hoc *
matpmtmsubpopplug.hoc *
matspecplug.hoc *
mosinit.hoc
network.hoc *
nload.hoc *
nqpplug.hoc *
nqs.hoc *
nqsnet.hoc *
nrnoc.hoc *
params.hoc
plot.py
plotavg.py
plotbatch.sh
plotbatchcluster.sh
plotdeletions.py
plotntes.py
powchgtest.hoc *
pyhoc.py
python.hoc *
pywrap.hoc *
ratlfp.dat *
redE2.hoc *
run.hoc
runsim.sh
setup.hoc *
shufmua.hoc *
sim.hoc
simctrl.hoc *
spkts.hoc *
stats.hoc *
syncode.hoc *
vsampenplug.hoc *
writedata.hoc
xgetargs.hoc *
                            
% Runs Crumiller code on a set of experimental results (i.e. different runs
% of an experiment, all held within subdirectories)

% This code descends into the subdirectories and runs Crumiller's calcinfo2
% on the default set of filenames (info-uniques.csv and info-repeats.csv).
% It also reads in the info-celldeaths.csv file to obtain times-of-death
% and to enable mapping between neurosim ('real') cell IDs and the cell IDs
% emerging from the Crumiller information code.

% Finally, it plots a scatter graph of information-contribution vs time of
% death for the given set of folders

% Usage: alzinfo(filepath[, makeclean])
% Where:   filepath is the path to a directory containing subdirs,
%            each with an info-uniques.csv and info-repeats.csv file
%          makeclean is an optional flag. Set true to force re-generation
%            of all info plots, or false to use existing info-processed.mat
%            files (if any). Defaults to false.

function alzinfo(filepath, varargin)
addpath('info-matlab') % Add info-matlab to path

% See if the 'make clean' flag was set
if length(varargin) > 0
    makeclean = varargin{1};
else
    makeclean = false;
end

% Use current directory if it contains info-uniques and info-repeats, otherwise
% search the subdirectories (this allows us to process either a single
% experiment or a whole directory of multiple experiments)
if exist(strcat(filepath, '/info-processed.mat')) | (exist(strcat(filepath, '/info-uniques.csv')) & exist(strcat(filepath, '/info-repeats.csv')))
    currentDir = filepath;
    subfolders={''};
else
    % Find all subdirectories under 'filepath' (each containing an
    % experimental run)
    d = dir(filepath);
    isub = [d(:).isdir]; %# returns logical vector
    subfolders = {d(isub).name}'
    subfolders(ismember(subfolders,{'.','..'})) = []; % Strip out '.' and '..'
end

allinfos = []; % Store all points for information contribution
alldeaths = []; % Store all points for time-of-death
allscales = []; % Store all points for scale factor at time of death
allpops = []; % Store all population labels
alldelproportions = {[], [], [], [], [], [], [], [], [], [], [], [], []}; % Cell struct containing 
% { { pop1del1 pop1del1 pop1del1; pop1del2 pop1del2 pop1del2 }; { pop2del1 pop2del1 pop2del1; pop2del1 pop2del1 pop2del1 } }
% Access using alldelproportions{pop}(run_no, :)

% Create sliding window for smoothed average plots
windowSize = 10;
h = ones(1,windowSize)/windowSize;

% Define colours for each population
colours = {'b', 'c', 'g', 'y', 'r', 'b', 'c', 'g', 'y', 'r', 'b', 'c', 'g'};

% Run info-matlab/calcinfo2 on the uniques/repeats files to generate the info-processed file
for experiment = 1:length(subfolders)
    currentDir = strcat(filepath, '/', subfolders{experiment});
    if exist(strcat(currentDir, '/info-celldeaths.csv'))

        cellidmap = []; % Make Crumiller info calc variables available
        info_cell = []; % outside the if-else-end block below
        
        if exist(strcat(currentDir, '/info-processed.mat')) & ~makeclean
            fprintf('Loading pre-processed info data from %s\n', currentDir)
            load(strcat(currentDir, '/info-processed.mat'))
        else
            fprintf('Calling Crumiller code for experiment %s\n', currentDir);
            % Call Crumiller info code
            % (This also saves processed data as 'info-processed.mat')
            [cellidmap,~,info_cell,~] = calcinfo2(currentDir);
        end
        
        % Load list of times-of-death
        deathtimescsv = csvread(strcat(currentDir, '/info-celldeaths.csv'));

        numcells = length(cellidmap);
        theseinfos = zeros(1,numcells); % Store points for this run's info contribution
        thesedeaths = zeros(1,numcells); % Store points for this run's cell death times
        thesescales = zeros(1,numcells); % Store points for this run's scale factors
        thesepops = zeros(1,numcells); % Store label of population for each point
        
        
        %% Process information-per-cell
        % Find cumulative sum of all values but bound final value to >= 0
        sum_info_cell = sum(info_cell'); % Sum info across the columns for each cell
        sum_info_cell(sum_info_cell < 0) = 0; % Bound all -ve values to zero
        
        % Find information per population
        cellscale = 1; % Unless we're running a bigger sim...
        poplabels = { 'E6' 'I6' 'I6L' 'E5B' 'E5R' 'I5' 'I5L' 'E4' 'I4' 'I4L' 'E2' 'I2' 'I2L'};
        popsizes = [59 25 13 17 65 25 13 30 20 14 150 25 13]*cellscale; % First element was 60, but cell 0 always seems to be missing
        %colours = [1 3 4 6 8 10 11 12 13 14 15 16 17]; % stretched rainbow
        %colours = [1 0 0 2 2.5 0 0 3 0 0 3.5 0 0]; % When only using E-populations
        
        % sum_info_cell now contains information-per-cell, but its indices
        % don't match up with actual cell IDs from the network simulation.
        % cellidmap provides us with the actual network cell ID for each
        % element in info_cell, so we can find that cell's time of death.
        for j = 1:length(sum_info_cell)
            theseinfos(j) = sum_info_cell(j);
            thesedeaths(j) = deathtimescsv((deathtimescsv(:,1) == cellidmap(j)), 2);
            thesescales(j) = deathtimescsv((deathtimescsv(:,1) == cellidmap(j)), 3);
            thesepops(j) = find(cellidmap(j) <= cumsum(popsizes), 1); % Find population to which this cell belongs (returns first index only)
        end
        thesedeaths = thesedeaths .* 1/1000/60/60/24; % Convert ms -> days
        
        
        %% Plot this run's info vs time scattergraph, coloured by population
        thisruninfofig = figure;
        xlabel('Time of death (days)');
        ylabel('Information contribution (bits/s)');
        hold on;
        
        thisrundelfig = figure;
        xlabel('Time of death (days)');
        ylabel('Proportion of cells deleted');
        hold on;
        
        plotnum = 0; % Keep track of current plot colour
        for pop = unique(thesepops)
            plotnum = plotnum + 1;
            % Extract only the points for this population
            thispopinfos = theseinfos(find(thesepops==pop));
            thispopdeaths = thesedeaths(find(thesepops==pop));
            
            % Sort data points into increasing-time order
            [sortedthispoptimes,i] = sort(thispopdeaths);
            sortedthispopinfos = thispopinfos(i);
           
            % For all times with > 1 corresponding death, replace each entry with avg
            [x,idx,bins] = unique(sortedthispoptimes); % x = death time, idx = unique indices locations, bin = death-time bin number for each cell
            averagedthispopinfos = zeros(length(idx),1);
            stdthispopinfos = zeros(length(idx),1);
            numdeleted = zeros(length(idx),1);
            
            % For each 'bin', get the mean, std, and total num deleted
            for bin = 1:length(idx)
                averagedthispopinfos(bin) = mean(sortedthispopinfos(find(bins==bin)));
                stdthispopinfos(bin) = std(sortedthispopinfos(find(bins==bin)));
                numdeleted(bin) = max(numdeleted) + length(sortedthispopinfos(find(bins==bin)));
            end
            numdeleted = numdeleted ./ popsizes(pop); % Normalise by population size
            % numdeleted gives us a y-axis for the line, but at arbitrary x points
            % So now we can interpolate across numdeleted to generate deletion-proportions at fixed x-intervals
            % which then allow us to find mean/std etc. for an average plot later.
            xi = (0:0.02:2); % Interpolate over ~100 points from 0->2 days
            intp = interp1q(x',numdeleted,xi');
            b = find(isnan(intp)); % Get indices of nans
            intp(b(b<length(intp)/2)) = 0; % Convert NaN->0 at start of line
            intp(b(b>length(intp)/2)) = 1; % Convert NaN->1 at end of line  intp(find(~isnan(intp), 1, 'last')); % Convert NaN->final value at end of line
            alldelproportions{plotnum} = vertcat(alldelproportions{plotnum}, num2cell(intp)');
            % { { pop1del1 pop1del1 pop1del1; pop1del2 pop1del2 pop1del2 }; { pop2del1 pop2del1 pop2del1; pop2del1 pop2del1 pop2del1 } }
            % Access using alldelproportions{pop}(run_no, :)
            
            % Draw the individual points
            figure(thisruninfofig);
            hold on;
            scgrph = scatter(thispopdeaths, thispopinfos, 60, colours{plotnum}, '.');
            set(get(get(scgrph,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off'); % Exclude points from legend
            
            % Draw the average line for this pop
            % Append mean of windowSize first data points to start of the
            % data, to eradicate the rise time.
            risetime = ones(1,windowSize)*mean(averagedthispopinfos(1:windowSize));
            filtereddata = filter(h, 1, [risetime averagedthispopinfos']);
            % Now plot only the part of the filtered data after the initial window size
            plot(x, filtereddata(windowSize+1:end), colours{plotnum});
            
            % Draw (on the other figure) the plot of deletion proportion
            figure(thisrundelfig);
            hold on;
            plot(x, numdeleted, colours{plotnum}, 'linewidth', 2);
        end
        
        % Plot smoothed moving-window average of info vs time
        % From http://stackoverflow.com/questions/1515977/how-to-smoothen-a-plot-in-matlab
        % Sort death times and info of dead cells into ascending order
        [sortedtimes,i] = sort(thesedeaths);
        sortedinfos = theseinfos(i);
        % For all times with > 1 corresponding death, replace each entry with avg
        [d,idx,bins] = unique(sortedtimes); % d = death time, idx = unique indices locations, bin = death-time bin number for each cell
        averagedinfos = zeros(length(idx),1);
        % For each 'bin', find the average info of cells
        for bin = 1:length(idx)
            averagedinfos(bin) = mean(sortedinfos(find(bins==bin)));
        end
        
        % Add average line to info plot.
        % Append mean of windowSize first data points to start of the
        % data, to eradicate the rise time.
        risetime = ones(1,windowSize)*mean(averagedinfos(1:windowSize));
        filtereddata = filter(h, 1, [risetime averagedinfos']);
        figure(thisruninfofig);
        hold on;
        plot(d, filtereddata(windowSize+1:end), 'k', 'linewidth', 2);
        
        % Add legend and save fig
        legend('E6', 'E5b', 'E5a', 'E4', 'E2/3', 'Average', 'Location', 'NorthWest');
        curylim = ylim;
        ylim([-2 curylim(2)]) % Set bottom of plot to -2, but set top to current value
        saveas(thisruninfofig, strcat(currentDir, '/infotime.fig'));
        print(thisruninfofig, '-painters', '-depsc', '-r900', strcat(currentDir, '/infotime'));
        
        % Add legend to the deletion plot too, and save
        figure(thisrundelfig);
        hold on;
        legend('E6', 'E5b', 'E5a', 'E4', 'E2/3', 'Location', 'NorthWest');
        saveas(thisrundelfig, strcat(currentDir, '/popdeltime.fig'));
        print(thisrundelfig, '-painters', '-depsc', '-r900', strcat(currentDir, '/popdeltime'));
        
        %% Plot info vs scalefactor scattergraph
        %figure;
        %plot(thesescales, theseinfos, 'x');
        %xlabel('Scale factor at time of death');
        %ylabel('Information contribution');
        % Save plot in individual run's directory
        %saveas(gcf, strcat(currentDir, '/infoscale.fig'));
        %print(gcf, '-painters', '-depsc', '-r300', strcat(currentDir, '/infoscale'));
        
        close all;
        
        %% Keep total record of info vs time-of-death points
        allinfos = [allinfos theseinfos];
        alldeaths = [alldeaths thesedeaths];
        allscales = [allscales thesescales];
        allpops = [allpops thesepops];
    else
        fprintf('No info-celldeaths.csv file present');
    end
end

%examine_data(filepath) % Run data analysis on the processed information measures


%% Plot average combination of all info vs time-of-death runs

%%% Process the data to find averages over all populations

% Sort data points into increasing-time order
[sortedalltimes,i] = sort(alldeaths);
sortedallinfos = allinfos(i);

% For all times with > 1 corresponding death, replace each entry with avg
[avgx,idx,bins] = unique(sortedalltimes); % x = death time, idx = unique indices locations, bin = death-time bin number for each cell
averagedallinfos = zeros(length(idx),1);
stdallinfos = zeros(length(idx),1);

% For each 'bin', get the mean and std
for bin = 1:length(idx)
    averagedallinfos(bin) = mean(sortedallinfos(find(bins==bin)));
    stdallinfos(bin) = std(sortedallinfos(find(bins==bin)));
end

% Plot line showing average over all populations
figure;
hold on;
risetime = ones(1,windowSize)*mean(averagedallinfos(1:windowSize));
filteredavgdata = filter(h, 1, [risetime averagedallinfos']);
boundedline(avgx, filteredavgdata(windowSize+1:end), stdallinfos, 'k');

% Set up rest of figure
xlabel('Time of death (days)');
ylabel('Information contribution (bits/s)');
curylim = ylim;
ylim([-0.2 curylim(2)]) % Set bottom of plot to 0, but set top to current value


%%% Add separate moving-window average for each population
plotnum = 0; % Keep track of current plot colour
for pop = unique(allpops)
    plotnum = plotnum + 1;
    % Extract only the points for this population
    thispopinfos = allinfos(find(allpops==pop));
    thispopdeaths = alldeaths(find(allpops==pop));
    
    % Sort data points into increasing-time order
    [sortedthispoptimes,i] = sort(thispopdeaths);
    sortedthispopinfos = thispopinfos(i);
    
    % For all times with > 1 corresponding death, replace each entry with avg
    [x,idx,bins] = unique(sortedthispoptimes); % x = death time, idx = unique indices locations, bin = death-time bin number for each cell
    averagedthispopinfos = zeros(length(idx),1);
    stdthispopinfos = zeros(length(idx),1);
    
    % For each 'bin', get the mean and std
    for bin = 1:length(idx)
        averagedthispopinfos(bin) = mean(sortedthispopinfos(find(bins==bin)));
        stdthispopinfos(bin) = std(sortedthispopinfos(find(bins==bin)));
    end
    
    % Draw the line
    %boundedline(x, filter(h, 1, averagedthispopinfos), stdthispopinfos, colourcelllist{pop}, 'alpha');
    risetime = ones(1,windowSize)*mean(averagedthispopinfos(1:windowSize));
    filtereddata = filter(h, 1, [risetime averagedthispopinfos']);
    toplot = filtereddata(windowSize+1:end);
    plot(x, toplot, colours{plotnum}, 'linewidth', 1);
end

% Re-draw average line (but not error patch) on top
toplot = filteredavgdata(windowSize+1:end);
plot(avgx, toplot, 'k', 'linewidth', 2);

% Save plot in parent directory
legend('Std.dev', 'Mean', 'E6', 'E5b', 'E5a', 'E4', 'E2/3', 'Location', 'NorthEast');
saveas(gcf, strcat(currentDir, '/../avginfotime.fig'));
%print(gcf, '-painters', '-depsc', '-r900', strcat(currentDir, '/../avginfotime'));
plot2svg(strcat(currentDir, '/../avginfotime.svg'), gcf, 'png'); % Save as SVG to get transparency
convcommand = sprintf('rsvg-convert -f pdf -w 500 -h 500 -o %s %s', strcat(currentDir, '/../avginfotime.pdf'), strcat(currentDir, '/../avginfotime.svg'));
system(convcommand);

%%% Add individual data points and save another figure (looks messy, not for printing!)
%scatter(alldeaths, allinfos, 60, allcolours, '.');
% Save plot in parent directory
%saveas(gcf, strcat(currentDir, '/../avginfotimepoints.fig'));
%print(gcf, '-painters', '-depsc', '-r900', strcat(currentDir, '/../avginfotimepoints'));


%% Plot average deletion proportion graphs over all the runs
% Store (time, proportion) tuples for each population in separate cell structs
%   (during processing in the loop above).
% For each experiment, append future tuples to the existing population cell struct
% Then sort the tuples on the time axis -- there should be plenty of overlap
% Finally, plot a boundedline for each population cell struct using mean,std

figure;
hold on;

for pop = 1:plotnum
    % Obtain set of deletion vs time data for this pop
    times = (0:0.02:2); % Fixed x-axis
    dels = cell2mat(alldelproportions{pop});
    zerocols = sum(dels)>0;
    dels = dels(:, zerocols); % Keep only non-zero columns
    times = times(:, zerocols);
    
    % Find the moving-window average
    %risetime = ones(1,windowSize)*mean(avgdels(1:windowSize));
    %filtereddata = filter(h, 1, [risetime avgdels']);
    %toplot = filtereddata(windowSize+1:end);
    [blplot, blpatch] = boundedline(times, mean(dels), std(dels), colours{pop}, 'alpha');
    set(get(get(blplot,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off'); % Exclude avg from legend
    set(get(get(blpatch,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off'); % Exclude std from legend
    plot(times, mean(dels), colours{pop}, 'linewidth', 2);
end
ylim([0 1]); % Bound axes to 0,1
xlabel('Time of death (days)');
ylabel('Proportion of cells deleted');
legend('E6', 'E5b', 'E5a', 'E4', 'E2/3', 'Location', 'NorthWest');
saveas(gcf, strcat(currentDir, '/../avgpopdeltime.fig'));
%print(gcf, '-painters', '-depsc', '-r900', strcat(currentDir, '/../avgpopdeltime'));
plot2svg(strcat(currentDir, '/../avgpopdeltime.svg'), gcf, 'png'); % Save as SVG to get transparency
convcommand = sprintf('rsvg-convert -f pdf -w 500 -h 500 -o %s %s', strcat(currentDir, '/../avgpopdeltime.pdf'), strcat(currentDir, '/../avgpopdeltime.svg'));
system(convcommand);

%% Plot combination of all info vs scalefactor runs
%clf;
%plot(allscales, allinfos, 'x');
%xlabel('Scale factor at time of death');
%ylabel('Information contribution');
% Save plot in parent directory
%saveas(gcf, strcat(currentDir, '/../avginfoscale.fig'));
%print(gcf, '-painters', '-dpdf', '-r300', strcat(currentDir, '/../avginfoscale'));

rmpath('info-matlab') % Housekeeping (remove info-matlab from path)
save(strcat(currentDir, '/../avginfo.mat')); % Save all data to file
end