Skip to content

Commit 0435cf7

Browse files
authored
[BACKPORT] [BUG] Fix normalisation procedure for antisymmetrised PAC (#115) (#139)
1 parent d0915cf commit 0435cf7

File tree

4 files changed

+31
-10
lines changed

4 files changed

+31
-10
lines changed

changelog.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
- No changes.
55

66

7-
## [Version 1.2](https://pybispectra.readthedocs.io/en/1.2.2/)
7+
## [Version 1.2](https://pybispectra.readthedocs.io/en/1.2.3/)
88

99
##### Enhancements
1010
- Added general `Bispectrum` and `Threenorm` classes for computing with flexible kmn channel combinations.
@@ -14,6 +14,7 @@
1414
- Fixed error where bandpass filter settings for the SSD method in `SpatioSpectralFilter` were not being applied correctly.
1515
- Fixed error where `indices` in `ResultsCFC`, `ResultsTDE`, and `ResultsGeneral` classes were not being mapped to results correctly.
1616
- Fixed error where NumPy integers and floats were not being recognised as valid types.
17+
- Fixed error where univariate normalisation of antisymmetrised PAC was not being applied correctly.
1718

1819
##### API
1920
- Changed the default value of `min_ratio` in `SpatioSpectralFilter.get_transformed_data()` from `1.0` to `-inf`.

docs/source/refs.bib

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ @article{Chella2014
4444
doi={10.1016/j.neuroimage.2013.12.064}
4545
}
4646

47+
@article{Chella2016,
48+
title={Bispectral pairwise interacting source analysis for identifying systems of cross-frequency interacting brain sources from electroencephalographic or magnetoencephalographic signals},
49+
author={Chella, Federico and Pizzella, Vittorio and Zappasodi, Filippo and Nolte, Guido and Marzetti, Laura},
50+
journal={Physical Review E},
51+
volume={93},
52+
number={5},
53+
pages={052420},
54+
year={2016},
55+
publisher={APS},
56+
doi={10.1103/PhysRevE.93.052420}
57+
}
58+
4759
@inbook{Chen2004,
4860
title={Time {D}elay {E}stimation},
4961
author={Chen, Jingdong and Huang, Yiteng and Benesty, Jacob},

examples/plot_compute_pac.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,16 @@
5454
#
5555
# where the resulting values lie in the range :math:`[0, 1]`. Furthermore, PAC can be
5656
# antisymmetrised by subtracting the results from those found using the transposed
57-
# bispectrum, :math:`\textbf{B}_{xyx}`, :footcite:`Chella2014`
57+
# bispectrum, :math:`\textbf{B}_{yxy}`, :footcite:`Chella2014`
5858
#
5959
# :math:`\textrm{PAC}_{\textrm{antisym}}(\textbf{x}_{f_1},\textbf{y}_{f_2})=|
60-
# \textbf{B}_{xyy}-\textbf{B}_{xyx}|` .
60+
# \textbf{B}_{xyy}(f_1,f_2)-\textbf{B}_{yxy}(f_1,f_2)|` .
6161
#
6262
# In the context of analysing PAC between two signals, antisymmetrisation allows you to
6363
# correct for spurious estimates of coupling arising from interactions within the
6464
# signals themselves in instances of source mixing, providing a more robust connectivity
6565
# metric :footcite:`PellegriniPreprint`. The same principle applies for the
66-
# antisymmetrisation of the bicoherence.
66+
# antisymmetrisation of the bicoherence :footcite:`Chella2016`.
6767

6868
########################################################################################
6969
# Loading data and computing Fourier coefficients

src/pybispectra/cfc/pac.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,17 @@ def compute(
140140
141141
where the resulting values lie in the range :math:`[0, 1]`. Furthermore, PAC can
142142
be antisymmetrised by subtracting the results from those found using the
143-
transposed bispectrum, :math:`\textbf{B}_{xyx}`, :footcite:`Chella2014`
143+
transposed bispectrum, :math:`\textbf{B}_{yxy}`, :footcite:`Chella2014`
144144
145145
:math:`\textrm{PAC}_{\textrm{antisym}}(\textbf{x}_{f_1},\textbf{y}_{f_2})=
146-
|\textbf{B}_{xyy}-\textbf{B}_{xyx}|` .
146+
|\textbf{B}_{xyy}(f_1,f_2)-\textbf{B}_{yxy}(f_1,f_2)|` .
147+
148+
A modified approach is used for the normalisation of antisymmetrised PAC
149+
:footcite:`Chella2016`
150+
151+
:math:`\textrm{PAC}_{\textrm{norm,antisym}}(\textbf{x}_{f_1},\textbf{y}_{f_2})=
152+
\Large|\frac{\textbf{B}_{xyy}(f_1,f_2)-\textbf{B}_{yxy}(f_1,f_2)}
153+
{\textbf{N}_{xyy}(f_1,f_2)+\textbf{N}_{yxy}(f_1,f_2)}|` .
147154
148155
If the seed and target for a given connection is the same channel and
149156
antisymmetrisation is being performed, :obj:`numpy.nan` values are returned.
@@ -171,7 +178,6 @@ def compute(
171178
self._compute_bispectrum()
172179
if self._return_threenorm:
173180
self._compute_threenorm()
174-
self._bicoherence = self._bispectrum / self._threenorm
175181
self._compute_pac()
176182
self._store_results()
177183

@@ -189,7 +195,6 @@ def _reset_attrs(self) -> None:
189195

190196
self._bispectrum = None
191197
self._threenorm = None
192-
self._bicoherence = None
193198

194199
self._pac_nosym_nonorm = None
195200
self._pac_nosym_threenorm = None
@@ -340,10 +345,13 @@ def _compute_pac(self) -> None:
340345

341346
if self._return_threenorm:
342347
if self._return_nosym:
343-
self._pac_nosym_threenorm = np.abs(self._bicoherence[0])
348+
self._pac_nosym_threenorm = np.abs(
349+
self._bispectrum[0] / self._threenorm[0]
350+
)
344351
if self._return_antisym:
345352
self._pac_antisym_threenorm = np.abs(
346-
self._bicoherence[0] - self._bicoherence[1]
353+
(self._bispectrum[0] - self._bispectrum[1])
354+
/ (self._threenorm[0] + self._threenorm[1])
347355
)
348356
for con_i, seed, target in zip(
349357
range(self._n_cons), self._seeds, self._targets

0 commit comments

Comments
 (0)