Metric validation for detection of delayed and directed coupling.
The 7 matches · 2 of them tie a paragraph to a whole file, not to given lines: weak matches, whose lines are not tinted
- [1] § Methods › Network reconstruction metrics ↔ idtxl/__init__.py, lines 1–21 · score 0.75 · Information Dynamics Toolkit, IDTxl, multivariate transfer entropy, bivariate
- [2] § Methods › Network simulations ↔ gen_model.m, the whole file · a weak match · score 0.65 · coupling strength, coupling matrix, measurement noise, model, delays, connectivity
- [3] § Results › Measurement noise ↔ paper_figures.m, lines 553–627 · score 0.61 · Dunn Sidak, zero lag mutual, Granger causality, transfer entropy, Kruskal, mutual information
- [4] § Results › Network coverage ↔ paper_figures.m, lines 744–815 · score 0.55 · Dunn Sidak, Granger causality, zero lag, coverage, transfer entropy, Kruskal
- [5] § Methods › Network simulations ↔ paper_figures.m, lines 85–125 · score 0.53 · uncoupled nodes, amplitude, Channel, coupling
- [6] § Methods › Network simulations ↔ gen_model.m, the whole file · a weak match · score 0.53 · coupling strength, vector, dynamics, neural, models, delays
- [7] § Results › Number of nodes ↔ paper_figures.m, lines 553–627 · score 0.53 · Dunn Sidak, Granger causality, zero lag, transfer entropy, Kruskal, mutual information
Paper
Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC
The paper is loaded when this pane is shown.
The authors' code
MATLAB · 815 lines · 25 KB · no license · 4 matches
- %% ========================================================================
- % Name: paper_figures.m
- % Author: Kate Dembny
- % Date: 1/20/23
- % Updated: 6/16/23
- % Syntax:
- % Arguments:
- % Description: figures for paper
- % Requirements: matlab
- % Notes:
- %% ========================================================================
- clearvars
- % DIRECTORIES
- scr_dir = pwd;
- pdir = fileparts(cd);
- data_dir = [pdir filesep() 'data'];
- fig_dir = [pdir filesep() 'figures'];
- addpath("/home/kdembny/MATLAB/toolboxes/violinplot/Violinplot-Matlab-master")
- addpath("/home/kdembny/MATLAB/toolboxes/sigstar")
- addpath('/home/kdembny/MATLAB/toolboxes/cprintf/cprintf/')
- %% ========================================================================
- % Figure 1 - appearance of data
- cwd = [data_dir filesep() 'nodes' filesep() '10' filesep() '004' ];
- load([cwd filesep() 'orig' filesep() 'orig_data.mat'])
- % establish figure
- f = figure;
- f.Position = [100 100 1200 700];
- set(gcf,'renderer','Painters')
- % third tile - adjacency matrix - 1/0 connection
- subplot(2,3,1)
- imagesc(tcoup)
- colormap(flipud(bone))
- xlabel("Reciever Node")
- ylabel("Source Node")
- title('True Network Connections')
- yticks(1:10)
- yticklabels(1:10)
- xticks(1:10)
- xticklabels(1:10)
- text(-1.2,0, ['A)'], 'FontSize', 20)
- % second tile - adjacency matrix - node to node
- subplot(2,3,4)
- dg = digraph(tcoup);
- plot(dg, 'Layout', 'force', 'EdgeColor', "k", 'NodeColor', 'k')
- ax = gca;
- ax.FontSize=16;
- text(-3.5,3, ['B)'], 'FontSize', 20)
- % first set of tiles - timeseries data
- subplot(2,3,[2:3, 5:6])
- hold on
- for i = 1:size(ts, 1)
- plot(ts(i,1:1000) - 0.25*i, 'Color', "k")
- end
- ax = gca;
- ax.FontSize=16;
- ylim([-0.25*(i+1),0])
- yticks(-0.25*(i):0.25:-0.25)
- yticklabels(size(ts,1):-1:1)
- ylabel('Node Number')
- xlabel('Time (samples)')
- ax = gca;
- ax.FontSize=16;
- text(-70,.07, ['C)'], 'FontSize', 20)
- saveas(gcf, [fig_dir filesep() '01_methods.jpg'])
- exportgraphics(gcf, [fig_dir filesep() '01_methods.eps'], 'ContentType', 'vector')
- %% ========================================================================
- % Figure 2 - Coupled vs uncoupled channels
- % assign colors
- colors = [136 34 85; 102 17 0; 17 119 51; 68 170 153; 102 153 204; 51 34 136; 204 102 119; 170 68 153; 153 153 51; 148 148 148]/255;
- % establish figure
- f = figure;
- f.Position = [100 100 1600 1000];
- set(gcf,'renderer','Painters')
- lw = 2;
- nd_end = 100;
- subplot(211)
- hold on
- plot(ts(1,1:nd_end), 'LineWidth', lw, 'Color', [colors(3,:)])
- plot(ts(6,1:nd_end), 'LineWidth', lw, 'Color', [colors(7,:)])
- legend(["Node 1", "Node 6"])
- xlabel('Time (samples)')
- ylabel('Amplitude')
- ylim([-0.12, 0.12])
- title('Coupled Nodes')
- ax = gca;
- ax.FontSize=16;
- subplot(212)
- hold on
- plot(ts(1,1:nd_end), 'Linewidth',lw, 'Color', [colors(3,:)])
- plot(ts(7,1:nd_end), 'Linewidth',lw, 'Color', [colors(5,:)])
- legend(["Node 1", "Node 7"])
- xlabel('Time (samples)')
- ylim([-0.12, 0.12])
- ylabel('Amplitude')
- title('Uncoupled Nodes')
- ax = gca;
- ax.FontSize=16;
- saveas(gcf, [fig_dir filesep() '02.coupled_noncoupled.jpg'])
- exportgraphics(gcf, [fig_dir filesep() '02.coupled_noncoupled.eps'], 'ContentType', 'vector')
- %% ========================================================================
- % Figure 3 - Network Reconstructions
- % load data
- pt_file = [data_dir filesep() 'nodes' filesep() '10' filesep() '004'];
- load([pt_file filesep() 'orig' filesep() 'orig_data.mat'])
- load([pt_file filesep() 'ml_fc' filesep() 'xc_biv.mat'])
- load([pt_file filesep() 'ml_fc' filesep() 'xc_pt.mat'])
- load([pt_file filesep() 'ml_fc' filesep() 'gc.mat'])
- load([pt_file filesep() 'bvte' filesep() 'te_bivar.mat'])
- load([pt_file filesep() 'mvte' filesep() 'te_multivar.mat'])
- load([pt_file filesep() 'mi_lagged' filesep() 'mi_lagged.mat'])
- load([pt_file filesep() 'mi_zerolag' filesep() 'mi_zerolag.mat'])
- load([pt_file filesep() 'ml_fc' filesep() 'xc_zerolag_biv.mat'])
- load([pt_file filesep() 'ml_fc' filesep() 'xc_zerolag_pt.mat'])
- calc_mi = calc_mi_lag;
- load([pt_file filesep() 'shuff' filesep() 'shuff.mat'])
- % plot
- labs = {{"True Network Connections"},{"Biv. Cross-Corr"}, {"Pt. Cross-Corr"}, {"Mv. Granger Causality"}, ...
- {"Mutual Information"}, {"Biv. Transfer Entropy"},{"Mv. Transfer Entropy"},...
- {"Zero-Lag Biv.","Cross-Corr"}, {"Zero-Lag Pt.","Cross-Corr"}, {"Zero-Lag Mutual","Information"}, {"Shuffled"}};
- arrs = zeros(size(labs,2), size(gc,1), size(gc,2));
- arrs(1,:,:) = tcoup;
- arrs(8,:,:) = xc_zerolag_biv;
- arrs(9,:,:) = xc_zerolag_partial;
- arrs(10,:,:) = calc_mi_zerolag;
- arrs(6,:,:) = te_bivar;
- arrs(2,:,:) = xc_biv(:,:,1);
- arrs(3,:,:) = xc_partial(:,:,1);
- arrs(4,:,:) = gc;
- arrs(5,:,:) = calc_mi;
- arrs(7,:,:) = te_multivar;
- arrs(11,:,:) = shuff;
- num_cols = round((size(arrs,1))/2) + 1;
- figLabs = 'A':'K';
- f = figure;
- clf
- f.Position = [100 100 2000 500];
- set(gcf,'renderer','Painters')
- subplot(2,num_cols,[1,2,num_cols + 1,num_cols + 2])
- imagesc(squeeze(arrs(1,:,:)))
- title(labs{1})
- axis square
- ylabel("Source Node")
- xlabel("Receiver Node")
- c = colorbar();
- c.Ticks = [0, 1];
- c.TickLabels = ["2%", "98%"];
- text(-1,.7,[figLabs(1) ')'], 'FontSize', 20)
- for i = 2:size(arrs,1)
- if i < num_cols
- loc = i+1;
- else
- loc = i+3;
- end
- subplot(2,num_cols,loc)
- imagesc(squeeze(arrs(i,:,:)))
- title(labs{i})
- axis square
- pct2 = prctile(arrs(i,:,:), 2, 'all');
- pct98 = prctile(arrs(i,:,:), 98, 'all');
- if i<11
- clim([pct2 pct98])
- else
- clim([0 1])
- end
- text(-2.2,0.7,[figLabs(i) ')'], 'FontSize', 20)
- end
- saveas(gcf, [fig_dir filesep() '03.samp_recons.jpg'])
- exportgraphics(gcf, [fig_dir filesep() '03.samp_recons.eps'], 'ContentType', 'vector')
- %% ========================================================================
- % Figure 4 - number of nodes by metric
- cwd = [data_dir filesep() 'agg'];
- load([cwd filesep() 'nodes_all_dist.mat'])
- nodes_alpha = 0.05/15;
- makeFig_byMetric(nodes_cos_dist, nodes_opts, nodes_alpha, 'Number of Nodes', 'Cosine Distance')
- saveas(gcf, [fig_dir filesep() '04.1_nodes_by_metrics.jpg'])
- exportgraphics(gcf, [fig_dir filesep() '04.1_nodes_by_metrics.eps'], 'ContentType', 'vector')
- %
- % Alt Figure 4 - number of nodes by bin of nodes
- makeFig_byParam(nodes_cos_dist, nodes_opts, nodes_alpha, 'Metrics', 'Cosine Distance', 'Nodes')
- saveas(gcf, [fig_dir filesep() '04.2_methods_by_nodes.jpg'])
- exportgraphics(gcf, [fig_dir filesep() '04.2_methods_by_nodes.eps'], 'ContentType', 'vector')
- %%
- % STATS
- clc
- cprintf('red', 'Nodes by Cosine Distance \n')
- doStats(nodes_cos_dist, nodes_opts, nodes_alpha, 'Nodes')
- %% ========================================================================
- % Figure 5 - number of time points by metric
- cwd = [data_dir filesep() 'agg'];
- load([cwd filesep() 'tps_all_dist.mat'])
- tps_alpha = 0.05/14;
- makeFig_byMetric(tps_cos_dist,tps_opts, tps_alpha, 'Number of Time Points', 'Cosine Distance')
- saveas(gcf, [fig_dir filesep() '05.1_tps_by_methods.jpg'])
- exportgraphics(gcf, [fig_dir filesep() '05.1_tps_by_methods.eps'], 'ContentType', 'vector')
- % Alt Figure 5 - number of time points by time points bin
- makeFig_byParam(tps_cos_dist, tps_opts, tps_alpha, 'Metrics', 'Cosine Distance', 'Time Points')
- saveas(gcf, [fig_dir filesep() '05.2_methods_by_tps.jpg'])
- exportgraphics(gcf, [fig_dir filesep() '05.2_methods_by_tps.eps'], 'ContentType', 'vector')
- %% STATS
- clc
- cprintf('red', 'Time Points by Cosine Distance \n')
- doStats(tps_cos_dist, tps_opts, tps_alpha, 'Time Points')
- %% ========================================================================
- % Figure 6 - noise by metric
- cwd = [data_dir filesep() 'agg'];
- load([cwd filesep() 'noise_all_dist.mat'])
- noise_alpha = 0.05/18;
- makeFig_byMetric(noise_cos_dist,noise_opts, noise_alpha, 'SNR', 'Cosine Distance')
- saveas(gcf, [fig_dir filesep() '06.1_noise_by_methods.jpg'])
- exportgraphics(gcf, [fig_dir filesep() '06.1_noise_by_methods.eps'], 'ContentType', 'vector')
- % Alt Figure 6 - noise by SNR bin
- makeFig_byParam(noise_cos_dist, noise_opts, noise_alpha, 'Metrics', 'Cosine Distance', 'SNR')
- saveas(gcf, [fig_dir filesep() '06.2_methods_by_noise.jpg'])
- exportgraphics(gcf, [fig_dir filesep() '06.2_methods_by_noise.eps'], 'ContentType', 'vector')
- %% STATS
- clc
- cprintf('red', 'Noise by Cosine Distance \n')
- doStats(noise_cos_dist, noise_opts, noise_alpha, 'SNR')
- %% ========================================================================
- % Figure 7 - nodes node dropping
- cwd = [data_dir filesep() 'agg'];
- load([cwd filesep() 'nodes_all_dist.mat'])
- ntwkCov_alpha = 0.05/20;
- pcts = ["100%","90%","80%","70%","60%","50%","40%","30%","20%","10%"];
- makeFig_nodeDrop(nodes_cos_dist, pcts, ntwkCov_alpha, '% of Network Covered', 'Cosine Distance')
- saveas(gcf, [fig_dir filesep() '07.1_node_dropping.jpg'])
- exportgraphics(gcf, [fig_dir filesep() '07.1_node_dropping.eps'], 'ContentType', 'vector')
- pcts = ["100%","90%","80%","70%","60%","50%","40%","30%","20%","10%"];
- makeFig_nodeDrop_param(nodes_cos_dist, pcts, ntwkCov_alpha, 'Metrics', 'Cosine Distance')
- saveas(gcf, [fig_dir filesep() '07.2_node_dropping_params.jpg'])
- exportgraphics(gcf, [fig_dir filesep() '07.2_node_dropping_params.eps'], 'ContentType', 'vector')
- %%
- cwd = [data_dir filesep() 'roc'];
- load([cwd filesep() 'nodes_roc.mat'])
- makeFig_nodeDrop(nodes_roc_aucs(:,:,1:9,:), pcts(1:9), ntwkCov_alpha, '% of Network Covered', 'AUC of ROC')
- saveas(gcf, [fig_dir filesep() '07.2_roc_node_dropping.jpg'])
- exportgraphics(gcf, [fig_dir filesep() '07.2_roc_node_dropping.eps'], 'ContentType', 'vector')
- %% compare methods within metric
- for i = 1:10
- [p, tbl, stats] = kruskalwallis(squeeze(nodes_cos_dist(4,:,:,i))); %, pcts);
- disp(labels(i))
- if p < alpha
- results = multcompare(stats);
- tbl2 = array2table(results,"VariableNames", ...
- ["Group A","Group B","Lower Limit","A-B","Upper Limit","P-value"]);
- close all
- disp(tbl2)
- else
- disp('no significant differences')
- end
- disp(' ')
- end
- %% compare methods by percent of nodes dropped
- for i = 1:10
- [p, tbl, stats] = kruskalwallis(squeeze(nodes_cos_dist(4,:,i,:))); %, pcts);
- disp([num2str(100 - (i-1)*10) ' pct covered'])
- if p < alpha
- results = multcompare(stats, 'CriticalValueType', 'dunn-sidak', 'Alpha', ntwkCov_alpha);
- tbl2 = array2table(results,"VariableNames", ...
- ["Group A","Group B","Lower Limit","A-B","Upper Limit","P-value"]);
- close all
- disp(tbl2)
- else
- disp('no significant differences')
- end
- disp(' ')
- end
- %% compare for roc - by metric
- for i = 1:10
- [p, tbl, stats] = kruskalwallis(squeeze(nodes_roc_aucs(4,:,:,i))); %, pcts);
- disp(labels(i))
- disp([num2str(100 - (i-1)*10) ' pct covered'])
- if p < alpha
- results = multcompare(stats);
- tbl2 = array2table(results,"VariableNames", ...
- ["Group A","Group B","Lower Limit","A-B","Upper Limit","P-value"]);
- close all
- disp(tbl2)
- else
- disp('no significant differences')
- end
- disp(' ')
- end
- %% compare for roc - by percent covered
- for i = 1:10
- [p, tbl, stats] = kruskalwallis(squeeze(nodes_roc_aucs(4,:,i,:))); %, pcts);
- disp([num2str(100 - (i-1)*10) ' pct covered'])
- if p < alpha
- results = multcompare(stats);
- tbl2 = array2table(results,"VariableNames", ...
- ["Group A","Group B","Lower Limit","A-B","Upper Limit","P-value"]);
- close all
- disp(tbl2)
- else
- disp('no significant differences')
- end
- disp(' ')
- end
- %% compare methods by node dropping - variance
- for i = 1:10
- [p, stats] = vartestn(squeeze(nodes_cos_dist(4,:,:,i)), 'TestType', 'LeveneQuadratic'); %, pcts);
- close all
- disp(labels(i))
- disp(p)
- disp(stats)
- disp(' ')
- end
- %% ========================================================================
- % Figure 8 - runtimes
- cwd = [data_dir filesep() 'agg'];
- load([cwd filesep() 'nodes_all_rts.mat'])
- labels = ["Biv. Cross-Corr", "Pt. Cross-Corr", "Mv. Granger Causality", "Mutual Information",...
- "Biv. Transfer Entropy", "Mv. Transfer Entropy", "Zero-Lag Biv. Cross-Corr", ...
- "Zero-Lag Pt. Cross-Corr", "Zero-Lag Mutual Information" ];
- colors = [136 34 85; 102 17 0; 17 119 51; 68 170 153; 102 153 204; 51 34 136; 204 102 119; 170 68 153; 153 153 51; 148 148 148]/255;
- f = figure;
- f.Position = [100 100 1500 400];
- for j = 1:size(nodes_opts,2)
- subplot(1,5,j)
- for i = 1:6%size(nodes_runtimes,4)
- vp = Violin({squeeze(nodes_runtimes(j,:,1,i))'}, i, 'MarkerSize', 10, 'ViolinColor', {colors(i,:)});
- end
- xticks(1:6)%size(nodes_runtimes,4))
- xticklabels(labels (1:6))
- ylabel('Runtime (s)')
- xlabel('Metrics')
- title([num2str(nodes_opts(j)) ' Nodes'])
- ax = gca;
- ax.FontSize=12;
- set(gca, 'Yscale', 'log')
- ylim([10^0, 10^6])
- text(-2.3,10^6.5,[figLabs(j) ')'], 'FontSize', 20)
- end
- saveas(gcf, [fig_dir filesep() '08.1_runtimes.jpg'])
- exportgraphics(gcf, [fig_dir filesep() '08.1_runtimes.eps'], 'ContentType', 'vector')
- %% ========================================================================
- % Figure 8 - runtimes - no TE
- cwd = [data_dir filesep() 'agg'];
- load([cwd filesep() 'nodes_all_rts.mat'])
- f = figure;
- f.Position = [100 100 2000 400];
- for j = 2:size(nodes_opts,2)
- subplot(1,5,j)
- for i = 1:4
- vp = Violin({squeeze(nodes_runtimes(j,:,2,i))'}, i, 'MarkerSize', 10, 'ViolinColor', {colors(i,:)});
- end
- xlabel('Method')
- xticks(1:6)
- xticklabels(labels)
- ylabel('Runtime (s)')
- title([num2str(nodes_opts(j)) ' Nodes'])
- ax = gca;
- ax.FontSize=20;
- end
- sgtitle('Reconstruction Time by Method')
- saveas(gcf, [fig_dir filesep() '08.2_runtimes_noTE.jpg'])
- %% ========================================================================
- % Figure 6 - runtimes
- cwd = [data_dir filesep() 'agg'];
- load([cwd filesep() 'tps_all_rts.mat'])
- f = figure;
- f.Position = [100 100 2000 400];
- for j = 1:size(tps_opts,2)
- subplot(1,5,j)
- for i = 1:6
- vp = Violin({squeeze(tps_runtimes(j,:,1,i))'}, i, 'MarkerSize', 10);
- end
- xlabel('Method')
- xticks(1:6)
- xticklabels(labels)
- ylabel('Runtime (s)')
- title([num2str(tps_opts(j)) ' Time Points'])
- ax = gca;
- ax.FontSize=14;
- end
- %sgtitle('Reconstruction Time by Method')
- saveas(gcf, [fig_dir filesep() '08.1_runtimes.jpg'])
- %% ========================================================================
- % FUNCTIONS
- function makeFig_byMetric(data,opts, alpha, xAxLabel, yAxLabel)
- labels = {{"Biv. Cross-Corr"}, {"Pt. Cross-Corr"}, {"Mv. Granger","Causality"}, {"Mutual","Information"},...
- {"Biv. Transfer","Entropy"}, {"Mv. Transfer","Entropy"}, {"Zero-Lag Biv.","Cross-Corr"}, ...
- {"Zero-Lag Pt.","Cross-Corr"}, {"Zero-Lag Mutual","Information"}, {"Shuffled"}};
- colors = [136 34 85; 102 17 0; 17 119 51; 68 170 153; 102 153 204; 51 34 136; 204 102 119; 170 68 153; 153 153 51; 148 148 148]/255;
- set(gcf,'renderer','Painters')
- f = figure(1);
- clf
- f.Position = [10 10 1800 650];
- figLabs = 'A':'J';
- for i = 1:size(data,4)
- [~, ~, stats] = kruskalwallis(squeeze(data(:,:,1,i))', opts);
- results = multcompare(stats, 'CriticalValueType', 'dunn-sidak', 'Alpha', alpha);
- tbl2 = array2table(results,"VariableNames", ...
- ["Group A","Group B","Lower Limit","A-B","Upper Limit","P-value"]);
- disp(tbl2)
- figure(1)
- for j = 1:size(opts,2)
- subplot(2,5,i)
- vp = Violin({round(squeeze(data(j,:,1,i)),4)'}, j, 'MarkerSize', 10, 'ViolinColor', {colors(i,:)});
- end
- grps = [];
- ps = [];
- for ct_p = 1:size(tbl2,1)
- if tbl2.("P-value")(ct_p) < alpha
- grps = [grps; {[tbl2.("Group A")(ct_p), tbl2.("Group B")(ct_p)]}];
- ps = [ps; tbl2.("P-value")(ct_p)];
- end
- end
- mxCompars = size(data,1) * (size(data,1)-1)/2;
- if size(grps,1) == mxCompars
- %text(0.2, 1.15, '*all comparisons significant')
- elseif size(grps,1) == 0
- text(0.2, 0.1, '*no comparisons significant')
- end
- if i > 5
- xlabel(xAxLabel)
- end
- xticks(1:size(opts,2))
- xticklabels(opts)
- if mod(i-1,5) == 0
- ylabel(yAxLabel)
- end
- title(labels{i})
- ylim([0, 1.2])
- text(-1,1.3,[figLabs(i) ')'], 'FontSize', 20)
- ax = gca;
- ax.FontSize=14;
- end
- end
- function makeFig_byParam(data, opts, alpha, xAxLabel, yAxLabel, paramName)
- labels = ["Biv. Cross-Corr", "Pt. Cross-Corr", "Mv. Granger Causality", "Mutual Information", ...
- "Biv. Transfer Entropy", "Mv. Transfer Entropy", "Zero-Lag Biv. Cross-Corr", ...
- "Zero-Lag Pt. Cross-Corr", "Zero-Lag Mutual Information", "Shuffled"];
- figLabs = 'A':'J';
- colors = [136 34 85; 102 17 0; 17 119 51; 68 170 153; 102 153 204; 51 34 136; 204 102 119; 170 68 153; 153 153 51; 148 148 148]/255;
- set(gcf,'renderer','Painters')
- f = figure(2);
- clf
- if size(opts,2) < 8
- f.Position = [100 100 500*size(opts,2) 500];
- else
- f.Position = [100 100 500*size(opts,2)/2 2*500];
- end
- for j = 1:size(opts,2)
- [p, tbl, stats] = kruskalwallis(squeeze(data(j,:,1,:)), labels);
- results = multcompare(stats, 'CriticalValueType', 'dunn-sidak', 'Alpha', alpha);
- tbl2 = array2table(results,"VariableNames", ...
- ["Group A","Group B","Lower Limit","A-B","Upper Limit","P-value"]);
- figure(2)
- if size(opts,2) < 8
- subplot(1,size(opts,2),j)
- else
- subplot(2,size(opts,2)/2,j)
- end
- for i = 1:6 %size(nodes_cos_dist,4)
- vp = Violin({round(squeeze(data(j,:,1,i)),4)'}, i, 'MarkerSize', 10, 'ViolinColor', {colors(i,:)});
- end
- grps = [];
- ps = [];
- for ct_p = 1:size(tbl2,1)
- if tbl2.("P-value")(ct_p) < alpha && tbl2.("Group A")(ct_p) < 7 && tbl2.("Group B")(ct_p) < 7
- grps = [grps; {[tbl2.("Group A")(ct_p), tbl2.("Group B")(ct_p)]}];
- ps = [ps; tbl2.("P-value")(ct_p)];
- end
- end
- mxCompars = (6*5)/2;%size(data,4) * (size(data,4)-1)/2;
- if size(grps,1) == mxCompars
- %text(0.2, 1.15, '*all comparisons significant')
- elseif size(grps,1) == 0
- text(0.2, 0.1, '*no comparisons significant')
- end
- % if size(grps,1) > 0
- % sigstar(grps, ps)
- % end
- xticks(1:size(data,4))
- xticklabels(labels)
- if j == 1
- ylabel(yAxLabel)
- end
- yticks([0, 0.5, 1])
- if size(opts,2) < 8 || j > size(opts,2)/2
- xlabel(xAxLabel)
- end
- title([num2str(opts(j)) ' ' paramName])
- ylim([0, 1.2])
- ax = gca;
- ax.FontSize=14;
- axis square
- text(-1.2,1.2,[figLabs(j) ')'], 'FontSize', 20)
- end
- end
- function doStats(data, opts, alpha, paramName)
- labels = ["Biv. Cross-Corr", "Pt. Cross-Corr", "Mv. Granger Causality", "Mutual Information",...
- "Biv. Transfer Entropy", "Mv. Transfer Entropy", "Zero-Lag Biv. Cross-Corr", ...
- "Zero-Lag Pt. Cross-Corr", "Zero-Lag Mutual Info.", "Shuffled" ];
- % compare metric by parameter
- for i = 1:size(data,1)
- [p, tbl, stats] = kruskalwallis(squeeze(data(i,:,1,:)), labels);
- results = multcompare(stats, 'CriticalValueType', 'dunn-sidak', 'Alpha', alpha);
- disp([num2str(opts(i)) ' ' paramName])
- if p < alpha
- tbl2 = array2table(results,"VariableNames", ...
- ["Group A","Group B","Lower Limit","A-B","Upper Limit","P-value"]);
- close all
- disp(tbl2)
- else
- disp('no significant differences')
- end
- disp(' ')
- end
- %% compare parameter by metric
- for i = 1:size(data,4)
- [p, tbl, stats] = kruskalwallis(squeeze(data(:,:,1,i))', opts);
- disp(labels(i))
- if p < alpha
- results = multcompare(stats, 'CriticalValueType', 'dunn-sidak', 'Alpha', alpha);
- tbl2 = array2table(results,"VariableNames", ...
- ["Group A","Group B","Lower Limit","A-B","Upper Limit","P-value"]);
- close all
- disp(tbl2)
- else
- disp('no significant differences')
- end
- disp(' ')
- end
- end
- function makeFig_nodeDrop(data, opts, alpha, xAxLabel, yAxLabel)
- labels = {{"Biv. Cross-Corr"}, {"Pt. Cross-Corr"}, {"Mv. Granger","Causality"}, {"Mutual","Information"},...
- {"Biv. Transfer","Entropy"}, {"Mv. Transfer","Entropy"}, {"Zero-Lag Biv.","Cross-Corr"}, ...
- {"Zero-Lag Pt.","Cross-Corr"}, {"Zero-Lag Mutual","Information"}, {"Shuffled"}};
- colors = [136 34 85; 102 17 0; 17 119 51; 68 170 153; 102 153 204; 51 34 136; 204 102 119; 170 68 153; 153 153 51; 148 148 148]/255;
- figLabs = 'A':'J';
- f = figure(3);
- clf
- f.Position = [10 10 1800 650];
- set(gcf,'renderer','Painters')
- for i = 1:size(data,4)
- [p, tbl, stats] = kruskalwallis(squeeze(data(4,:,:,i)), opts);
- results = multcompare(stats, 'CriticalValueType', 'dunn-sidak', 'Alpha', alpha);
- tbl2 = array2table(results,"VariableNames", ...
- ["Group A","Group B","Lower Limit","A-B","Upper Limit","P-value"]);
- figure(3)
- subplot(2,5,i)
- for j = 1:size(data,3)
- vp = Violin({round(squeeze(data(4,:,j,i)),4)'}, j, 'MarkerSize', 10, 'ViolinColor', {colors(i,:)});
- end
- grps = [];
- ps = [];
- for ct_p = 1:size(tbl2,1)
- if tbl2.("P-value")(ct_p) < alpha
- grps = [grps; {[tbl2.("Group A")(ct_p), tbl2.("Group B")(ct_p)]}];
- ps = [ps; tbl2.("P-value")(ct_p)];
- end
- end
- mxCompars = size(data,3) * (size(data,1)-3)/2;
- if size(grps,1) == mxCompars
- if mean(data(4,:,j,i), 'omitnan') < 0.6
- %text(0.2, 1.15, '*all comparisons significant')
- else
- %text(0.2, 0.1, '*all comparisons significant')
- end
- elseif size(grps,1) == 0
- if mean(data(4,:,j,i), 'omitnan') < 0.6
- text(0.2, 1.15, '*no comparisons significant')
- % if i < 7
- % text(0.2, 1.15, '*no comparisons significant')
- % else
- else
- text(0.2, 0.1, '*no comparisons significant')
- end
- end
- if i > 5
- xlabel(xAxLabel)
- end
- xticks(1:10)
- xticklabels(opts)
- xtickangle(45)
- if mod(i,5) == 1
- ylabel(yAxLabel)
- end
- title(labels{i})
- ylim([0, 1.2])
- yticks([0 0.5 1])
- ax = gca;
- ax.FontSize=13;
- xlim([0 size(data,3)+1])
- text(-1,1.3,[figLabs(i) ')'], 'FontSize', 18)
- end
- end
- function makeFig_nodeDrop_param(data, opts, alpha, xAxLabel, yAxLabel)
- labels = ["Biv. Cross-Corr", "Pt. Cross-Corr", "Mv. Granger Causality", "Mutual Information",...
- "Biv. Transfer Entropy", "Mv. Transfer Entropy", "Zero-Lag Biv. Cross-Corr", ...
- "Zero-Lag Pt. Cross-Corr", "Zero-Lag Mutual Information", "Shuffled"];
- colors = [136 34 85; 102 17 0; 17 119 51; 68 170 153; 102 153 204; 51 34 136; 204 102 119; 170 68 153; 153 153 51; 148 148 148]/255;
- figLabs = 'A':'J';
- f = figure(3);
- clf
- f.Position = [100 100 1800 900];
- set(gcf,'renderer','Painters')
- for i = 1:size(data,3)
- [p, tbl, stats] = kruskalwallis(squeeze(data(4,:,i,:)), labels);
- results = multcompare(stats, 'CriticalValueType', 'dunn-sidak', 'Alpha', alpha);
- tbl2 = array2table(results,"VariableNames", ...
- ["Group A","Group B","Lower Limit","A-B","Upper Limit","P-value"]);
- figure(3)
- subplot(2,5,i)
- for j = 1:6%size(data,3)
- vp = Violin({round(squeeze(data(4,:,i,j)),4)'}, j, 'MarkerSize', 10, 'ViolinColor', {colors(j,:)});
- end
- grps = [];
- ps = [];
- for ct_p = 1:size(tbl2,1)
- if tbl2.("P-value")(ct_p) < alpha
- grps = [grps; {[tbl2.("Group A")(ct_p), tbl2.("Group B")(ct_p)]}];
- ps = [ps; tbl2.("P-value")(ct_p)];
- end
- end
- mxCompars = size(data,3) * (size(data,1)-3)/2;
- if size(grps,1) == mxCompars
- if mean(data(4,:,j,i), 'omitnan') < 0.6
- %text(0.2, 1.15, '*all comparisons significant')
- else
- %text(0.2, 0.1, '*all comparisons significant')
- end
- elseif size(grps,1) == 0
- if mean(data(4,:,j,i), 'omitnan') < 0.6
- text(0.2, 1.15, '*no comparisons significant')
- % if i < 7
- % text(0.2, 1.15, '*no comparisons significant')
- % else
- else
- text(0.2, 0.1, '*no comparisons significant')
- end
- end
- if i > 5
- xlabel(xAxLabel)
- end
- xticks(1:6)
- xticklabels(labels(1:6))
- xtickangle(45)
- if mod(i,5) == 1
- ylabel(yAxLabel)
- end
- title([convertStringsToChars(opts(i)), ' Coverage'])
- ylim([0, 1.2])
- yticks([0 0.5 1])
- ax = gca;
- ax.FontSize=13;
- xlim([0 7])
- text(-1,1.3,[figLabs(i) ')'], 'FontSize', 18)
- end
- end
paper_figures.m at commit f2d6020, no license · at the source
Overview
- Department of Biomedical Engineering, University of Minnesota, Minneapolis, MN, United States of America
- University of Minnesota, Medical Scientist Training Program, Minneapolis, MN, United States of America
- Department of Psychiatry, University of Minnesota, Minneapolis, MN, United States of America
- University of Minnesota, Medical Discovery Team on Addiction, Minneapolis, MN, United States of America
- Department of Neurosurgery, University of Minnesota, Minneapolis, MN, United States of America
Abstract
Objective. The brain functions as a complex network of billions of interconnected neurons, coordinating processes from basic reflexes to high-level cognition. Dysfunction in these networks contribute to neurological and psychiatric disorders, including epilepsy, depression, and Parkinson’s disease. Understanding these network alterations is essential for developing effective therapies. However, reconstructing network topology from human electrophysiology data is challenging due to sparse spatial sampling, measurement noise, and variable time delays in interregional communication. Effective connectivity (EC) metrics have been developed to infer directed neural interactions, but their accuracy under real-world data constraints remain unclear. This study empirically compares the ability of common EC metrics to reconstruct relationships between simulated time series with known temporal relationships and network topologies in the presence of data limitations common to human electrophysiology data. By utilizing networks and temporal relationships that are mathematically simple, this framework provides broad conceptual backing to understand the reliability of EC metrics and establishes groundwork upon which more complex spatial and temporal relationships between time series can be evaluated. Approach. We generated Erdős–Rényi networks and simulated time series using a time-delayed vector autoregressive model. We systematically varied network size, data length, measurement noise, and network coverage. Variations of four commonly used EC metrics, cross-correlation, Granger causality (GC), mutual information (MI), and transfer entropy, were evaluated for reconstruction accuracy using cosine distance, as well as receiver operating characteristic (ROC) curves, to compare estimated and true coupling matrices. Main Results. Multivariate transfer entropy demonstrated the highest accuracy across various conditions but required significantly longer computation times. For small networks (<30 nodes), MI and GC rapidly and accurately reconstructed networks. For larger networks, partial cross-correlation performed well with good computational efficiency. Notably, zero-lag metrics perform no better than chance for time-lagged time series relationships in nearly all conditions. Significance. The choice of an EC metric should consider specific data constraints. While multivariate transfer entropy is the most reliable across conditions, its long runtime limits its practical application. For large networks, partial cross-correlation offers a faster and reasonably accurate alternative. GC and MI are effective for small networks. Critically, time-lagged metrics are essential for accurate network reconstructions, as failing to account for time delays leads to reconstructions no more accurate than random network models.
Reproduced under the paper's license (CC BY), from the paper cited above.
Repositories
Its files are read in the Code ↔ Paper reader above, with 7 matches between paragraphs and lines of code.
hermandarrowlab
Availability: 1 check, the latest on 28 September 2026: the link answers (HTTP 200)
- 28 September 2026: the link answers (HTTP 200)
pwollstadt/IDTxl
c7eacfd9ce5ca6cdb371e19a52ea286db0d33f3c, 23 April 2026Availability: 1 check, the latest on 28 September 2026: the link answers
- 28 September 2026: the link answers
165 files
- demos/
demo_active_information_ , Python, 17 linesstorage.py - demos/
demo_bivariate_mi.py , Python, 26 lines - demos/
demo_bivariate_pid.py , Python, 70 lines - demos/
demo_bivariate_te.py , Python, 26 lines - demos/
demo_core_estimators.py , Python, 129 lines - demos/
demo_hd_estimator.py , Python, 53 lines - demos/
demo_multivariate_mi.py , Python, 26 lines - demos/
demo_multivariate_pid.py , Python, 374 lines - demos/
demo_multivariate_te.py , Python, 26 lines - demos/
demo_multivariate_te_mpi , Python, 58 lines.py - demos/
demo_multivariate_te_mpi , Shell, 39 lines_slurm.sh - demos/
demo_significant_subgrap , Python, 103 linesh_mining.py - dev/
fast_pid/ , Python, 109 linesPID_analysis_cultures_si ngle_combination.py - dev/
fast_pid/ , Python, 330 linesestimators_fast_pid.py - dev/
fast_pid/ , Python, 428 linesestimators_fast_pid_ext_ rep.py - dev/
fast_pid/ , Python, 33 linestest_and_empirical.py - dev/
fast_pid/ , Python, 31 linestest_and_imposed_prob.py - dev/
fast_pid/ , Python, 76 linestest_estimators_fast_pid .py - dev/
fast_pid/ , Python, 58 linestest_parity_empirical.py - dev/
fast_pid/ , Python, 33 linestest_single_input_copy_e mpirical.py - dev/
fast_pid/ , Python, 31 linestest_single_input_copy_i mposed_prob.py - dev/
fast_pid/ , Python, 33 linestest_xor_empirical.py - dev/
fast_pid/ , Python, 31 linestest_xor_imposed_prob.py - dev/
import_modwt/ , Python, 62 linesimport_modwt.py - dev/
import_modwt/ , C, 50 linesmodwtj.c - dev/
import_modwt/ , MATLAB, 18 linestest_modwtj.m - dev/
search_GPU/ , Python, 1 line__init__.py - dev/
search_GPU/ , CUDA, 279 linesdeliverable1/ gpuKnnBF_kernel.cu - dev/
search_GPU/ , CUDA, 289 linesdeliverable1/ gpuKnnLibrary.cu - dev/
search_GPU/ , CUDA, 227 linesdeliverable1/ helperfunctions.cu - dev/
search_GPU/ , Python, 93 linesdeliverable1/ python_to_c.py - dev/
search_GPU/ , Python, 52 linesdeliverable1/ testKNN_call_multiGPU.py - dev/
search_GPU/ , Python, 115 linesdeliverable1/ testRSAll_call_drop_dime nsions_cuda.py - dev/
search_GPU/ , Python, 48 linesdeliverable1/ testRSAll_call_multiGPU. py - dev/
search_GPU/ , CUDA, 278 linesdeliverable1_1/ gpuKnnBF_kernel.cu - dev/
search_GPU/ , CUDA, 292 linesdeliverable1_1/ gpuKnnLibrary.cu - dev/
search_GPU/ , CUDA, 227 linesdeliverable1_1/ helperfunctions.cu - dev/
search_GPU/ , Python, 93 linesdeliverable1_1/ python_to_c.py - dev/
search_GPU/ , Python, 104 linesdeliverable1_1/ test_cuda_search.py - dev/
search_GPU/ , Python, 179 linesdeliverable2/ clKnnLibrary.py - dev/
search_GPU/ , Python, 50 linesdeliverable2/ testKNN_call.py - dev/
search_GPU/ , Python, 78 linesdeliverable2/ testKNN_callCompare.py - dev/
search_GPU/ , Python, 45 linesdeliverable2/ testRSAll_call.py - dev/
search_GPU/ , Python, 65 linesdeliverable2/ testRSAll_callCompare.py - dev/
search_GPU/ , Python, 128 linesdeliverable2/ testRSAll_call_drop_dime nsions.py - dev/
search_GPU/ , Python, 80 linesdeliverable2/ testRSAll_call_single_po ints.py - dev/
search_GPU/ , Python, 145 linesdeliverable2/ testRSAll_call_single_po ints_memorder.py - dev/
search_GPU/ , Python, 181 linesdeliverable2_1/ clKnnLibrary.py - dev/
search_GPU/ , Python, 130 linesdeliverable2_1/ test_opencl_estimators.p y - dev/
search_GPU/ , CUDA, 279 linesgpuKnnBF_kernel.cu - dev/
search_GPU/ , Python, 109 linesneighbour_search_cuda.py - dev/
search_GPU/ , Python, 485 linesneighbour_search_opencl. py - dev/
search_GPU/ , Python, 295 linesneighbour_search_opencl_ old.py - dev/
search_GPU/ , Python, 204 linestestRSAll_call_single_po ints_new_interface.py - dev/
search_GPU/ , Python, 631 linestest_neighbour_search_cu da.py - docs/
conf.py , Python, 176 lines - docs/
html/ , JavaScript, 326 lines_static/ doctools.js - docs/
html/ , JavaScript, 12 lines_static/ documentation_options.js - docs/
html/ , JavaScript, 7,572 lines_static/ jquery-3.2.1.js - docs/
html/ , JavaScript, 7,429 lines_static/ jquery-3.5.1.js - docs/
html/ , JavaScript, 2 lines_static/ jquery.js - docs/
html/ , JavaScript, 297 lines_static/ language_data.js - docs/
html/ , JavaScript, 529 lines_static/ searchtools.js - docs/
html/ , JavaScript, 2,027 lines_static/ underscore-1.12.0.js - docs/
html/ , JavaScript, 2,042 lines_static/ underscore-1.13.1.js - docs/
html/ , JavaScript, 999 lines_static/ underscore-1.3.1.js - docs/
html/ , JavaScript, 6 lines_static/ underscore.js - docs/
html/ , JavaScript, 808 lines_static/ websupport.js - docs/
html/ , JavaScript, 1 linesearchindex.js - idtxl/
__init__.py , Python, 29 lines, 1 match - idtxl/
active_information_stora , Python, 667 linesge.py - idtxl/
bivariate_mi.py , Python, 323 lines - idtxl/
bivariate_pid.py , Python, 313 lines - idtxl/
bivariate_te.py , Python, 326 lines - idtxl/
data.py , Python, 1,056 lines - idtxl/
data_spiketime.py , Python, 737 lines - idtxl/
embedding_optimization_a , Python, 1,237 linesis_Rudelt.py - idtxl/
estimator.py , Python, 367 lines - idtxl/
estimators_Rudelt.py , Python, 1,278 lines - idtxl/
estimators_jidt.py , Python, 1,800 lines - idtxl/
estimators_mpi.py , Python, 193 lines - idtxl/
estimators_multivariate_ , Python, 181 linespid.py - idtxl/
estimators_opencl.py , Python, 818 lines - idtxl/
estimators_pid.py , Python, 638 lines - idtxl/
estimators_python.py , Python, 161 lines - idtxl/
hde_fast_embedding_utils , Python, 57 lines.py - idtxl/
hde_setup.py , Python, 12 lines - idtxl/
hde_utils.py , Python, 392 lines - idtxl/
idtxl_exceptions.py , Python, 40 lines - idtxl/
idtxl_import.py , Python, 264 lines - idtxl/
idtxl_io.py , Python, 569 lines - idtxl/
idtxl_utils.py , Python, 354 lines - idtxl/
knn/ , Python, 1 line__init__.py - idtxl/
knn/ , Python, 93 linesknn_finder.py - idtxl/
knn/ , Python, 25 linesknn_finder_factory.py - idtxl/
knn/ , Python, 35 linesknn_finder_scipy.py - idtxl/
knn/ , Python, 42 linesknn_finder_sklearn.py - idtxl/
knn/ , Python, 19 linestree_knn_finder.py - idtxl/
lattices.py , Python, 803 lines - idtxl/
multivariate_mi.py , Python, 323 lines - idtxl/
multivariate_pid.py , Python, 320 lines - idtxl/
multivariate_te.py , Python, 333 lines - idtxl/
network_analysis.py , Python, 711 lines - idtxl/
network_comparison.py , Python, 1,041 lines - idtxl/
network_inference.py , Python, 1,196 lines - idtxl/
pid_goettingen.py , Python, 401 lines - idtxl/
postprocessing.py , Python, 1,652 lines - idtxl/
results.py , Python, 1,202 lines - idtxl/
setup_hde_fast_embedding , Python, 16 lines.py - idtxl/
single_process_analysis. , Python, 8 linespy - idtxl/
stats.py , Python, 1,681 lines - idtxl/
synergy_tartu.py , Python, 611 lines - idtxl/
visualise_graph.py , Python, 327 lines - setup.py, Python, 43 lines
- source/
conf.py , Python, 280 lines - test/
generate_test_data.py , Python, 236 lines - test/
performancetest_lorenz_2 , Python, 82 lines.py - test/
performancetest_lorenz_2 , Shell, 33 lines_mpi_slurm.sh - test/
systemtest_active_inform , Python, 66 linesation_storage.py - test/
systemtest_bivariate_pid , Python, 95 lines.py - test/
systemtest_checkpointing , Python, 611 lines_kraskov.py - test/
systemtest_estimators.py , Python, 118 lines - test/
systemtest_lorenz_2.py , Python, 44 lines - test/
systemtest_lorenz_2_open , Python, 44 linescl.py - test/
systemtest_multivariate_ , Python, 313 lineste.py - test/
systemtest_multivariate_ , Python, 334 lineste_discrete.py - test/
systemtest_mute.py , Python, 25 lines - test/
systemtest_neighbour_sea , Python, 132 linesrch_opencl.py - test/
systemtest_network_compa , Python, 150 linesrison.py - test/
systemtest_optimization_ , Python, 335 linesRudelt.py - test/
systemtest_optimize_Rude , Python, 36 lineslt_test_data.py - test/
systemtest_pid_sydney.py , Python, 140 lines - test/
systemtest_visualise_gra , Python, 53 linesph.py - test/
test_active_information_ , Python, 316 linesstorage.py - test/
test_bivariate_mi.py , Python, 552 lines - test/
test_bivariate_pid.py , Python, 197 lines - test/
test_bivariate_te.py , Python, 625 lines - test/
test_checkpointing.py , Python, 1,781 lines - test/
test_checkpointing_mpi.p , Python, 1,950 linesy - test/
test_data.py , Python, 449 lines - test/
test_data_spiketimes.py , Python, 323 lines - test/
test_estimator.py , Python, 89 lines - test/
test_estimators_Rudelt.p , Python, 120 linesy - test/
test_estimators_jidt.py , Python, 817 lines - test/
test_estimators_multivar , Python, 258 linesiate_pid.py - test/
test_estimators_opencl.p , Python, 591 linesy - test/
test_estimators_pid.py , Python, 295 lines - test/
test_estimators_python.p , Python, 184 linesy - test/
test_fast_emb.py , Python, 22 lines - test/
test_idtxl_import.py , Python, 183 lines - test/
test_idtxl_io.py , Python, 328 lines - test/
test_idtxl_utils.py , Python, 108 lines - test/
test_mpi.py , Python, 204 lines - test/
test_multivariate_mi.py , Python, 537 lines - test/
test_multivariate_pid.py , Python, 308 lines - test/
test_multivariate_te.py , Python, 671 lines - test/
test_neighbour_search_op , Python, 466 linesencl.py - test/
test_network_analysis.py , Python, 204 lines - test/
test_network_comparison. , Python, 524 linespy - test/
test_postprocessing.py , Python, 414 lines - test/
test_results.py , Python, 469 lines - test/
test_stats.py , Python, 684 lines - test/
test_visualise_graph.py , Python, 113 lines - LICENSE, License, 674 lines
- README.md, Text, 74 lines
hermandarrowlab/ec-metrics-validation
f2d6020d991f4a40cdb3810d17c7828fb1575a61, 3 April 2025Availability: 1 check, the latest on 28 September 2026: the link answers
- 28 September 2026: the link answers
25 files
- calc_bvte_inplace.py, Python, 117 lines
- calc_mvte_inplace.py, Python, 117 lines
- check_jobs.sh, Shell, 13 lines
- corr_inplace.m, MATLAB, 317 lines
- do01_gen_all_models.m, MATLAB, 147 lines
- do02_drop_nodes.m, MATLAB, 103 lines
- do03_slurm_matlab.sh, Shell, 146 lines
- do03_slurm_matlab_no_dro
p.sh , Shell, 130 lines - do04_slurm_idtxl.sh, Shell, 289 lines
- do04_slurm_idtxl_nodrop.
sh , Shell, 284 lines - do05_slurm_mi.sh, Shell, 207 lines
- do05_slurm_mi_nodrop.sh, Shell, 199 lines
- do06_copy_from_msi.sh, Shell, 41 lines
- do07_calc_distance.m, MATLAB, 230 lines
- do08_agg_data.m, MATLAB, 275 lines
- do09_agg_runtimes.m, MATLAB, 285 lines
- doXX_addShuffs.m, MATLAB, 136 lines
- gen_model.m, MATLAB, 121 lines, 2 matches
- idtxl_te_slurm.sh, Shell, 1 line
- make_slurm.sh, Shell, 84 lines
- mi_inplace.m, MATLAB, 74 lines
- mi_lagged_inplace.m, MATLAB, 83 lines
- mi_zero_lag.m, MATLAB, 86 lines
- mvgc4sims.m, MATLAB, 80 lines
- paper_figures.m, MATLAB, 815 lines, 4 matches
The paper's code and data availability statement is in the Data section.
Tracing map
Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.
What the map holds:
- 3 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
- 188 scripts, each with its path and the digest of its content;
- 7 matches between paragraphs of the paper and lines of the code (method lexical-v1);
- neither the text of the paper nor the code itself.
Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.
Data
No dataset and no data link were found in the paper.
Data availability statement
External Software:
Functional Connectivity Toolbox: https://
Multivariate Granger Causality Toolbox: www.mathworks.com/
Fieldtrip Mutual Information: https://
Information Dynamics Toolbox XL (IDTxl): https://
The data that support the findings of this study are openly available at the following URL/
Supplementary Data 1 available at https://
Reproduced under the paper's license (CC BY), from the paper cited above.
Versions
The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.
Version 2, 28 September 2026
- Publisher: n/a → IOP Publishing
Version 1, 28 September 2026: the first record
Recorded: type, language, journal, volume, issue, pages, dates, 5 authors, 7 keywords, 8 MeSH terms, 5 funders, 60 references.
Cite
This paper
Dembny, K., Farooqi, H., Herman, A. B., Netoff, T. I., & Darrow, D. P. (2026). Metric validation for detection of delayed and directed coupling. Journal of neural engineering, 23(3), 036012. https://
BibTeX
@article{dembny2026metri
author = {Dembny, Kate and Farooqi, Hafsa and Herman, Alexander B and Netoff, Theoden I and Darrow, David P},
title = {{Metric validation for detection of delayed and directed coupling}},
journal = {Journal of neural engineering},
year = {2026},
month = may,
volume = {23},
number = {3},
pages = {036012},
publisher = {IOP Publishing},
issn = {1741-2560},
doi = {10.1088/
url = {https://
pmid = {41985540},
pmcid = {PMC13172737}
}
RIS
TY - JOUR
AU - Dembny, Kate
AU - Farooqi, Hafsa
AU - Herman, Alexander B
AU - Netoff, Theoden I
AU - Darrow, David P
TI - Metric validation for detection of delayed and directed coupling
T2 - Journal of neural engineering
J2 - J Neural Eng
PY - 2026
DA - 2026/
VL - 23
IS - 3
SP - 036012
SN - 1741-2560
PB - IOP Publishing
DO - 10.1088/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.1088/
"type": "article-journal",
"title": "Metric validation for detection of delayed and directed coupling",
"container-title": "Journal of neural engineering",
"author": [
{
"family": "Dembny",
"given": "Kate"
},
{
"family": "Farooqi",
"given": "Hafsa"
},
{
"family": "Herman",
"given": "Alexander B"
},
{
"family": "Netoff",
"given": "Theoden I"
},
{
"family": "Darrow",
"given": "David P"
}
],
"container-title-short":
"volume": "23",
"issue": "3",
"page": "036012",
"DOI": "10.1088/
"PMID": "41985540",
"PMCID": "PMC13172737",
"ISSN": "1741-2560",
"publisher": "IOP Publishing",
"URL": "https://
"language": "en",
"issued": {
"date-parts": [
[
2026,
5,
14
]
]
}
}
The tracing map gets a citation of its own once an author has validated it and it has a DOI.
Similar papers
The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.
- [1] doi:10.1038/s41467-026-75959-w [code]
- Charting higher-order models of brain function beyond pairwise interactions.Journal: Nature communicationsIn common: NetworkX, h5py, statsmodels, 5 other tools, 3 references
- [2] doi:10.1073/pnas.2531706123 [code]
- Metabolism-weighted brain connectome reveals synaptic integration and vulnerability to neurodegeneration.Journal: Proceedings of the National Academy of Sciences of the United States of AmericaIn common: NetworkX, statsmodels, scikit-learn, 3 other tools, 4 references
- [3] doi:10.1016/j.isci.2026.115488 [code]
- An integrated &
lt;i& gt;i& lt;/ i& gt; & lt;i& gt;n vitro& lt;/ i& gt; platform and biophysical modeling approach for studying synaptic transmission in isolated neuronal pairs. Journal: iScienceIn common: NetworkX, h5py, statsmodels, 4 other tools, 2 references - [4] doi:10.1038/s41593-026-02205-3 [code]
- Competitive interactions shape mammalian brain network dynamics and computation.Journal: Nature neuroscienceIn common: NetworkX, Statistics and Machine Learning Toolbox, scikit-learn, 3 other tools, computational modeling (no new data), 2 references
- [5] doi:10.1002/hbm.70483 [code]
- Untamed: Unconstrained Tensor Decomposition and Graph Node Embedding for Cortical Parcellation.Journal: Human brain mappingIn common: FieldTrip, h5py, statsmodels, 5 other tools, 1 reference
- [6] doi:10.1162/imag.a.1319 [code]
- When the inner clock fades: Interoceptive decline and consolidation of phase resetting in cortical rhythms by cardiac events underlie healthy lifespan aging.Journal: Imaging neuroscience (Cambridge, Mass.)In common: FieldTrip, Statistics and Machine Learning Toolbox, SciPy, 1 other tool, 4 references
- [7] doi:10.1038/s41598-026-58505-y [code]
- Remoteness sensitive theta network dynamics during early autobiographical memory access.Journal: Scientific reportsIn common: FieldTrip, NetworkX, Statistics and Machine Learning Toolbox, 3 other tools, 2 references
- [8] doi:10.1038/s41467-026-71918-7 [code]
- Developmental disinhibition gates language lateralization in childhood.Journal: Nature communicationsIn common: FieldTrip, scikit-learn, SciPy, 2 other tools, computational modeling (no new data), 3 references
- [9] doi:10.1038/s41398-026-04025-2 [code]
- Brain energetic landscapes shape state dysregulation in major depressive disorder: a morphological network controllability perspective.Journal: Translational psychiatryIn common: FieldTrip, h5py, Statistics and Machine Learning Toolbox, 4 other tools, 1 reference
- [10] doi:10.1038/s41467-026-76452-0 [code]
- Music evokes shared neural representations of imagined narratives across sensory modalities.Journal: Nature communicationsIn common: FieldTrip, h5py, statsmodels, 5 other tools
Contribute
The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.
Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 3 repositories of the authors' code, each at its verified commit and with its license, 188 scripts, and 7 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:56d389c67d61a6e9…
Add the badge to its README
The badge links the code to this page. Copy one of these into the README of the paper's code: only you decide where it goes, and nothing is changed for you.
Markdown
[, paste the snippet at the top, then “Commit changes…” and, to review it first, “Create a new branch and start a pull request”. You open the pull request; OSCR asks for no permission.
Request its removal
To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).
Discussion, reproductions, activity
Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.
Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.
Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.
