Skip to content

Commit 71a5559

Browse files
authored
Merge pull request #1 from barbaLab/copilot/add-modulation-index-script
Add d-prime modulation index metric to +metrics package
2 parents 120e790 + 0cae6ef commit 71a5559

5 files changed

Lines changed: 80 additions & 0 deletions

File tree

+metrics/+compute/dprime.m

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
function dp = dprime(data, baseline_idx, signal_idx)
2+
%DPRIME computes the d-prime modulation index between two time windows
3+
%
4+
% Inputs:
5+
% data - nDims x nTime x nTrials array of embedded signals
6+
% baseline_idx - indices of baseline time points
7+
% signal_idx - indices of signal time points
8+
%
9+
% Output:
10+
% dp - 1 x nDims vector of d' values
11+
12+
if isempty(data)
13+
dp = nan;
14+
return;
15+
end
16+
17+
[nDims, ~, nTrials] = size(data);
18+
19+
if nTrials < 2
20+
dp = nan(1, nDims);
21+
return;
22+
end
23+
24+
% Mean activity per trial within each window
25+
baseline = squeeze(mean(data(:, baseline_idx, :), 2)); % nDims x nTrials
26+
signal = squeeze(mean(data(:, signal_idx, :), 2)); % nDims x nTrials
27+
28+
% When nDims == 1, squeeze reduces 1x1xnTrials to a nTrials×1 column;
29+
% reshape to 1×nTrials so that trailing dimension is always trials.
30+
if nDims == 1
31+
baseline = baseline(:)';
32+
signal = signal(:)';
33+
end
34+
35+
% Compute d' per dimension (statistics across trials)
36+
mu_b = mean(baseline, 2);
37+
mu_s = mean(signal, 2);
38+
std_b = std(baseline, 0, 2);
39+
std_s = std(signal, 0, 2);
40+
41+
% Pooled standard deviation: sqrt( (sigma_b^2 + sigma_s^2) / 2 )
42+
pooled_std = sqrt(0.5 .* (std_b.^2 + std_s.^2));
43+
44+
dp = (mu_s - mu_b) ./ pooled_std;
45+
46+
% Return as 1 x nDims row vector
47+
dp = dp';
48+
49+
end

+metrics/+pars/DPrime.m

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
function pars = DPrime()
2+
3+
pars.baseline_idx = [];
4+
pars.signal_idx = [];
5+
6+
7+
end

+metrics/DPrime.m

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
function dp = DPrime(E, pars)
2+
%DPRIME computes d-prime modulation index between baseline and signal windows
3+
%
4+
% input
5+
% E 1xnTrials cell array, each with nDims×nTime matrix
6+
% pars parameter struct with fields:
7+
% .baseline_idx indices of baseline time points
8+
% .signal_idx indices of signal time points
9+
% output
10+
% dp 1×nDims vector of d' values
11+
12+
if nargin < 2 || isempty(pars)
13+
pars = metrics.pars.DPrime();
14+
end
15+
16+
dp = metrics.compute.dprime(cat(3, E{:}), pars.baseline_idx, pars.signal_idx);
17+
18+
end

@NeuralEmbedding/NeuralEmbedding.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@
6969

7070
% Metrics computation
7171
appendM = false
72+
baseline_idx = []
73+
signal_idx = []
7274

7375
% Metadata
7476
Meta = struct("AnName","","ExpGroup","");

@NeuralEmbedding/computeMetrics.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
case {'Alignment','alignment','align','Align'}
2020
type = "Alignment";
2121
parNames = [""];
22+
23+
case {'DPrime','dprime','dPrime','d_prime','d-prime'}
24+
type = "DPrime";
25+
parNames = ["baseline_idx","signal_idx"];
2226
otherwise
2327
error("Specific metric not found.")
2428
end

0 commit comments

Comments
 (0)