From a0887b3c0f77464ce0ba33e01a2c7effd839e969 Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Tue, 18 Mar 2025 17:20:08 +0100 Subject: [PATCH 01/17] feat: add support for xi correlation in JuniferConnectivityMeasure --- .../nilearn/junifer_connectivity_measure.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/junifer/external/nilearn/junifer_connectivity_measure.py b/junifer/external/nilearn/junifer_connectivity_measure.py index 17e246123..379d450ea 100644 --- a/junifer/external/nilearn/junifer_connectivity_measure.py +++ b/junifer/external/nilearn/junifer_connectivity_measure.py @@ -3,6 +3,7 @@ # Authors: Synchon Mandal # License: AGPL +from itertools import product from typing import Callable, Optional import numpy as np @@ -322,7 +323,8 @@ class JuniferConnectivityMeasure(ConnectivityMeasure): The covariance estimator (default ``EmpiricalCovariance(store_precision=False)``). kind : {"covariance", "correlation", "spearman correlation", \ - "partial correlation", "tangent", "precision"}, optional + "partial correlation", "xi correlation", "tangent", \ + "precision"}, optional The matrix kind. The default value uses Pearson's correlation. If ``"spearman correlation"`` is used, the data will be ranked before estimating the covariance. For the use of ``"tangent"`` see [1]_ @@ -420,6 +422,17 @@ class JuniferConnectivityMeasure(ConnectivityMeasure): covariances_std.append(self.cov_estimator_.fit(x).covariance_) connectivities = [cov_to_corr(cov) for cov in covariances_std] + elif self.kind == "xi correlation": + connectivities = [] + for x in X: + n_rois = x.shape[1] + connectivity = np.ones((n_rois, n_rois)) + for i, j in product(range(n_rois), range(n_rois)): + if i != j: + connectivity[i, j] = stats.chatterjeexi( + x[:, i], x[:, j], y_continuous=True + ).statistic + connectivities.append(connectivity) else: covariances = [self.cov_estimator_.fit(x).covariance_ for x in X] if self.kind in ("covariance", "tangent"): @@ -434,6 +447,7 @@ class JuniferConnectivityMeasure(ConnectivityMeasure): allowed_kinds = ( "correlation", "partial correlation", + "xi correlation", "tangent", "covariance", "precision", -- 2.52.0 From f989f8473501e28d13e0c985ac8ed66169391c53 Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Tue, 18 Mar 2025 17:21:10 +0100 Subject: [PATCH 02/17] chore: update tests for JuniferConnectivityMeasure to include xi correlation --- .../nilearn/tests/test_junifer_connectivity_measure.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py index e5ccb1be5..baa2044d6 100644 --- a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +++ b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py @@ -72,6 +72,7 @@ CONNECTIVITY_KINDS = ( "precision", "partial correlation", "spearman correlation", + "xi correlation", ) N_FEATURES = 49 @@ -829,7 +830,7 @@ def test_connectivity_measure_check_mean( assert (conn_measure.mean_).shape == (N_FEATURES, N_FEATURES) - if kind != "tangent": + if kind not in ("tangent", "xi correlation"): assert_array_almost_equal( conn_measure.mean_, np.mean(conn_measure.transform(signals), axis=0), -- 2.52.0 From 195180cb35ee45eecb28a94b11ec35530649dcc3 Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Tue, 18 Mar 2025 17:21:39 +0100 Subject: [PATCH 03/17] fix: add missing spearman correlation whitelist for allowed kinds in JuniferConnectivityMeasure --- junifer/external/nilearn/junifer_connectivity_measure.py | 1 + 1 file changed, 1 insertion(+) diff --git a/junifer/external/nilearn/junifer_connectivity_measure.py b/junifer/external/nilearn/junifer_connectivity_measure.py index 379d450ea..acbdee316 100644 --- a/junifer/external/nilearn/junifer_connectivity_measure.py +++ b/junifer/external/nilearn/junifer_connectivity_measure.py @@ -447,6 +447,7 @@ class JuniferConnectivityMeasure(ConnectivityMeasure): allowed_kinds = ( "correlation", "partial correlation", + "spearman correlation", "xi correlation", "tangent", "covariance", -- 2.52.0 From e9139f6e68fb2d622c996b0ac52258dca754fad1 Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Tue, 18 Mar 2025 17:26:09 +0100 Subject: [PATCH 04/17] chore: add changelog 333.enh --- docs/changes/newsfragments/333.enh | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/changes/newsfragments/333.enh diff --git a/docs/changes/newsfragments/333.enh b/docs/changes/newsfragments/333.enh new file mode 100644 index 000000000..1f125761a --- /dev/null +++ b/docs/changes/newsfragments/333.enh @@ -0,0 +1 @@ +Add support for Chatterjee's xi correlation in :class:`.JuniferConnectivityMeasure` by `Synchon Mandal`_ -- 2.52.0 From 5549e085e8f615a1787ff883c1102249338d4ab0 Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Tue, 18 Mar 2025 17:27:57 +0100 Subject: [PATCH 05/17] chore: remove unnecessary whitelisting in JuniferConnectivityMeasure --- junifer/external/nilearn/junifer_connectivity_measure.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/junifer/external/nilearn/junifer_connectivity_measure.py b/junifer/external/nilearn/junifer_connectivity_measure.py index acbdee316..2e551c440 100644 --- a/junifer/external/nilearn/junifer_connectivity_measure.py +++ b/junifer/external/nilearn/junifer_connectivity_measure.py @@ -447,8 +447,6 @@ class JuniferConnectivityMeasure(ConnectivityMeasure): allowed_kinds = ( "correlation", "partial correlation", - "spearman correlation", - "xi correlation", "tangent", "covariance", "precision", -- 2.52.0 From 2d6ab360e18c0b150110b009d6594dcd67a00227 Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Wed, 19 Mar 2025 15:42:43 +0100 Subject: [PATCH 06/17] chore: update JuniferConnectivityMeasure docstring --- .../external/nilearn/junifer_connectivity_measure.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/junifer/external/nilearn/junifer_connectivity_measure.py b/junifer/external/nilearn/junifer_connectivity_measure.py index 2e551c440..33c54a463 100644 --- a/junifer/external/nilearn/junifer_connectivity_measure.py +++ b/junifer/external/nilearn/junifer_connectivity_measure.py @@ -327,8 +327,9 @@ class JuniferConnectivityMeasure(ConnectivityMeasure): "precision"}, optional The matrix kind. The default value uses Pearson's correlation. If ``"spearman correlation"`` is used, the data will be ranked before - estimating the covariance. For the use of ``"tangent"`` see [1]_ - (default "correlation"). + estimating the covariance. For ``"xi correlation"``, the coefficient + is not symmetric and should be interpreted as a measure of dependence + [2]_ . For the use of ``"tangent"`` see [1]_ (default "correlation"). vectorize : bool, optional If True, connectivity matrices are reshaped into 1D arrays and only their flattened lower triangular parts are returned (default False). @@ -374,6 +375,12 @@ class JuniferConnectivityMeasure(ConnectivityMeasure): Springer. doi:10/cn2h9c. + .. [2] Chatterjee, S. + A new coefficient of correlation. + Journal of the American Statistical Association 116.536 (2021): + 2009-2022. + doi:10.1080/01621459.2020.1758115. + """ def __init__( -- 2.52.0 From cf3af36229ac6e7a1efe2f82c0d7790439e34571 Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Wed, 19 Mar 2025 15:43:20 +0100 Subject: [PATCH 07/17] update: add separate test for JuniferConnectivityMeasure to check xi correlation --- .../test_junifer_connectivity_measure.py | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py index baa2044d6..686bab157 100644 --- a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +++ b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py @@ -12,7 +12,11 @@ import numpy as np import pytest from nilearn.connectome.connectivity_matrices import sym_matrix_to_vec from nilearn.tests.test_signal import generate_signals -from numpy.testing import assert_array_almost_equal, assert_array_equal +from numpy.testing import ( + assert_allclose, + assert_array_almost_equal, + assert_array_equal, +) from pandas import DataFrame from scipy import linalg from sklearn.covariance import EmpiricalCovariance, LedoitWolf @@ -1089,3 +1093,23 @@ def test_connectivity_measure_standardize( ).fit_transform(signals) for m in record: assert match not in m.message + + +def test_xi_correlation() -> None: + """Check xi correlation according to paper.""" + rng = np.random.default_rng(25982435982346983) + x = rng.random(size=10) + y = rng.random(size=10) + arr = np.column_stack((x, y)) + expected = np.array( + [ + [ + [1.0, -0.3030303], + [-0.18181818, 1.0], + ] + ] + ) + got = JuniferConnectivityMeasure(kind="xi correlation").fit_transform( + [arr] + ) + assert_allclose(expected, got) -- 2.52.0 From 4e52847d26609d48601100cc1c5f24fa9be782cc Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Wed, 19 Mar 2025 15:44:00 +0100 Subject: [PATCH 08/17] update: correct storage for FunctionalConnectivity markers if xi correlation is used --- .../functional_connectivity_base.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/junifer/markers/functional_connectivity/functional_connectivity_base.py b/junifer/markers/functional_connectivity/functional_connectivity_base.py index 5176b2b37..6394a3751 100644 --- a/junifer/markers/functional_connectivity/functional_connectivity_base.py +++ b/junifer/markers/functional_connectivity/functional_connectivity_base.py @@ -143,14 +143,17 @@ class FunctionalConnectivityBase(BaseMarker): }, ) # Create dictionary for output + labels = aggregation["aggregation"]["col_names"] return { "functional_connectivity": { "data": connectivity.fit_transform( [aggregation["aggregation"]["data"]] )[0], - # Create column names - "row_names": aggregation["aggregation"]["col_names"], - "col_names": aggregation["aggregation"]["col_names"], - "matrix_kind": "tril", + "row_names": labels, + "col_names": labels, + # xi correlation coefficient is not symmetric + "matrix_kind": ( + "full" if self.conn_method == "xi correlation" else "tril" + ), }, } -- 2.52.0 From 297be0642c9b6ec52ef6befdc87ff689a886083e Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Mon, 31 Mar 2025 12:56:30 +0200 Subject: [PATCH 09/17] chore: add error for using scipy.stats.chatterjeexi in python 3.9 --- junifer/external/nilearn/junifer_connectivity_measure.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/junifer/external/nilearn/junifer_connectivity_measure.py b/junifer/external/nilearn/junifer_connectivity_measure.py index 33c54a463..665ebc19e 100644 --- a/junifer/external/nilearn/junifer_connectivity_measure.py +++ b/junifer/external/nilearn/junifer_connectivity_measure.py @@ -3,6 +3,7 @@ # Authors: Synchon Mandal # License: AGPL +import sys from itertools import product from typing import Callable, Optional @@ -430,6 +431,14 @@ class JuniferConnectivityMeasure(ConnectivityMeasure): connectivities = [cov_to_corr(cov) for cov in covariances_std] elif self.kind == "xi correlation": + if sys.version_info < (3, 10): # pragma: no cover + raise_error( + klass=RuntimeError, + msg=( + "scipy.stats.chatterjeexi is available from " + "scipy 1.15.0 and that requires Python 3.10 and above." + ), + ) connectivities = [] for x in X: n_rois = x.shape[1] -- 2.52.0 From 59a48d24b856d5e592732b9374a50b38a911ebc7 Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Mon, 31 Mar 2025 12:57:50 +0200 Subject: [PATCH 10/17] chore: update tests for JuniferConnectivityMeasure --- .../tests/test_junifer_connectivity_measure.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py index 686bab157..576d29018 100644 --- a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +++ b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py @@ -4,6 +4,7 @@ # License: AGPL import copy +import sys import warnings from math import cosh, exp, log, sinh, sqrt from typing import TYPE_CHECKING, Optional, Union @@ -642,8 +643,11 @@ def test_connectivity_measure_generic( conn_measure = JuniferConnectivityMeasure( kind=kind, cov_estimator=cov_estimator ) - connectivities = conn_measure.fit_transform(signals) + if sys.version_info < (3, 10) and kind == "xi correlation": + with pytest.raises(RuntimeError, msg="scipy 1.15.0"): + connectivities = conn_measure.fit_transform(signals) + connectivities = conn_measure.fit_transform(signals) # Generic assert isinstance(connectivities, np.ndarray) assert len(connectivities) == len(covs) @@ -830,6 +834,10 @@ def test_connectivity_measure_check_mean( """ conn_measure = JuniferConnectivityMeasure(kind=kind) + if sys.version_info < (3, 10) and kind == "xi correlation": + with pytest.raises(RuntimeError, msg="scipy 1.15.0"): + conn_measure.fit_transform(signals) + conn_measure.fit_transform(signals) assert (conn_measure.mean_).shape == (N_FEATURES, N_FEATURES) @@ -866,6 +874,9 @@ def test_connectivity_measure_check_vectorization_option( conn_measure = JuniferConnectivityMeasure(kind=kind) connectivities = conn_measure.fit_transform(signals) conn_measure = JuniferConnectivityMeasure(vectorize=True, kind=kind) + if sys.version_info < (3, 10) and kind == "xi correlation": + with pytest.raises(RuntimeError, msg="scipy 1.15.0"): + vectorized_connectivities = conn_measure.fit_transform(signals) vectorized_connectivities = conn_measure.fit_transform(signals) assert_array_almost_equal( -- 2.52.0 From 0fb99ccd323f3b657780dff5015ef5b4f3aee0fc Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Mon, 31 Mar 2025 13:35:24 +0200 Subject: [PATCH 11/17] fix: correct pytest.raises args for JuniferConnectivityMeasure tests --- .../nilearn/tests/test_junifer_connectivity_measure.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py index 576d29018..ff72e67b2 100644 --- a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +++ b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py @@ -644,7 +644,7 @@ def test_connectivity_measure_generic( kind=kind, cov_estimator=cov_estimator ) if sys.version_info < (3, 10) and kind == "xi correlation": - with pytest.raises(RuntimeError, msg="scipy 1.15.0"): + with pytest.raises(RuntimeError, match="scipy 1.15.0"): connectivities = conn_measure.fit_transform(signals) connectivities = conn_measure.fit_transform(signals) @@ -835,7 +835,7 @@ def test_connectivity_measure_check_mean( """ conn_measure = JuniferConnectivityMeasure(kind=kind) if sys.version_info < (3, 10) and kind == "xi correlation": - with pytest.raises(RuntimeError, msg="scipy 1.15.0"): + with pytest.raises(RuntimeError, match="scipy 1.15.0"): conn_measure.fit_transform(signals) conn_measure.fit_transform(signals) @@ -875,7 +875,7 @@ def test_connectivity_measure_check_vectorization_option( connectivities = conn_measure.fit_transform(signals) conn_measure = JuniferConnectivityMeasure(vectorize=True, kind=kind) if sys.version_info < (3, 10) and kind == "xi correlation": - with pytest.raises(RuntimeError, msg="scipy 1.15.0"): + with pytest.raises(RuntimeError, match="scipy 1.15.0"): vectorized_connectivities = conn_measure.fit_transform(signals) vectorized_connectivities = conn_measure.fit_transform(signals) -- 2.52.0 From ad32c5929a4f4700af744aa7012de62ec4200009 Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Mon, 31 Mar 2025 14:24:45 +0200 Subject: [PATCH 12/17] fix: correct condition for pytest.raises in JuniferConnectivityMeasure tests --- .../test_junifer_connectivity_measure.py | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py index ff72e67b2..76741b764 100644 --- a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +++ b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py @@ -646,8 +646,8 @@ def test_connectivity_measure_generic( if sys.version_info < (3, 10) and kind == "xi correlation": with pytest.raises(RuntimeError, match="scipy 1.15.0"): connectivities = conn_measure.fit_transform(signals) - - connectivities = conn_measure.fit_transform(signals) + else: + connectivities = conn_measure.fit_transform(signals) # Generic assert isinstance(connectivities, np.ndarray) assert len(connectivities) == len(covs) @@ -837,8 +837,8 @@ def test_connectivity_measure_check_mean( if sys.version_info < (3, 10) and kind == "xi correlation": with pytest.raises(RuntimeError, match="scipy 1.15.0"): conn_measure.fit_transform(signals) - - conn_measure.fit_transform(signals) + else: + conn_measure.fit_transform(signals) assert (conn_measure.mean_).shape == (N_FEATURES, N_FEATURES) @@ -877,7 +877,8 @@ def test_connectivity_measure_check_vectorization_option( if sys.version_info < (3, 10) and kind == "xi correlation": with pytest.raises(RuntimeError, match="scipy 1.15.0"): vectorized_connectivities = conn_measure.fit_transform(signals) - vectorized_connectivities = conn_measure.fit_transform(signals) + else: + vectorized_connectivities = conn_measure.fit_transform(signals) assert_array_almost_equal( vectorized_connectivities, sym_matrix_to_vec(connectivities) @@ -1120,7 +1121,13 @@ def test_xi_correlation() -> None: ] ] ) - got = JuniferConnectivityMeasure(kind="xi correlation").fit_transform( - [arr] - ) + if sys.version_info < (3, 10): + with pytest.raises(RuntimeError, match="scipy 1.15.0"): + got = JuniferConnectivityMeasure( + kind="xi correlation" + ).fit_transform([arr]) + else: + got = JuniferConnectivityMeasure(kind="xi correlation").fit_transform( + [arr] + ) assert_allclose(expected, got) -- 2.52.0 From bcd069697d0fbb4c5ca6cd37bc61222cc06ea599 Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Tue, 1 Apr 2025 11:41:53 +0200 Subject: [PATCH 13/17] Revert "fix: correct condition for pytest.raises in JuniferConnectivityMeasure tests" This reverts commit ad32c5929a4f4700af744aa7012de62ec4200009. --- .../test_junifer_connectivity_measure.py | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py index 76741b764..ff72e67b2 100644 --- a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +++ b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py @@ -646,8 +646,8 @@ def test_connectivity_measure_generic( if sys.version_info < (3, 10) and kind == "xi correlation": with pytest.raises(RuntimeError, match="scipy 1.15.0"): connectivities = conn_measure.fit_transform(signals) - else: - connectivities = conn_measure.fit_transform(signals) + + connectivities = conn_measure.fit_transform(signals) # Generic assert isinstance(connectivities, np.ndarray) assert len(connectivities) == len(covs) @@ -837,8 +837,8 @@ def test_connectivity_measure_check_mean( if sys.version_info < (3, 10) and kind == "xi correlation": with pytest.raises(RuntimeError, match="scipy 1.15.0"): conn_measure.fit_transform(signals) - else: - conn_measure.fit_transform(signals) + + conn_measure.fit_transform(signals) assert (conn_measure.mean_).shape == (N_FEATURES, N_FEATURES) @@ -877,8 +877,7 @@ def test_connectivity_measure_check_vectorization_option( if sys.version_info < (3, 10) and kind == "xi correlation": with pytest.raises(RuntimeError, match="scipy 1.15.0"): vectorized_connectivities = conn_measure.fit_transform(signals) - else: - vectorized_connectivities = conn_measure.fit_transform(signals) + vectorized_connectivities = conn_measure.fit_transform(signals) assert_array_almost_equal( vectorized_connectivities, sym_matrix_to_vec(connectivities) @@ -1121,13 +1120,7 @@ def test_xi_correlation() -> None: ] ] ) - if sys.version_info < (3, 10): - with pytest.raises(RuntimeError, match="scipy 1.15.0"): - got = JuniferConnectivityMeasure( - kind="xi correlation" - ).fit_transform([arr]) - else: - got = JuniferConnectivityMeasure(kind="xi correlation").fit_transform( - [arr] - ) + got = JuniferConnectivityMeasure(kind="xi correlation").fit_transform( + [arr] + ) assert_allclose(expected, got) -- 2.52.0 From e206dac99469d73a7784f7c263210e3ad1c21f95 Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Tue, 1 Apr 2025 11:42:05 +0200 Subject: [PATCH 14/17] Revert "fix: correct pytest.raises args for JuniferConnectivityMeasure tests" This reverts commit 0fb99ccd323f3b657780dff5015ef5b4f3aee0fc. --- .../nilearn/tests/test_junifer_connectivity_measure.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py index ff72e67b2..576d29018 100644 --- a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +++ b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py @@ -644,7 +644,7 @@ def test_connectivity_measure_generic( kind=kind, cov_estimator=cov_estimator ) if sys.version_info < (3, 10) and kind == "xi correlation": - with pytest.raises(RuntimeError, match="scipy 1.15.0"): + with pytest.raises(RuntimeError, msg="scipy 1.15.0"): connectivities = conn_measure.fit_transform(signals) connectivities = conn_measure.fit_transform(signals) @@ -835,7 +835,7 @@ def test_connectivity_measure_check_mean( """ conn_measure = JuniferConnectivityMeasure(kind=kind) if sys.version_info < (3, 10) and kind == "xi correlation": - with pytest.raises(RuntimeError, match="scipy 1.15.0"): + with pytest.raises(RuntimeError, msg="scipy 1.15.0"): conn_measure.fit_transform(signals) conn_measure.fit_transform(signals) @@ -875,7 +875,7 @@ def test_connectivity_measure_check_vectorization_option( connectivities = conn_measure.fit_transform(signals) conn_measure = JuniferConnectivityMeasure(vectorize=True, kind=kind) if sys.version_info < (3, 10) and kind == "xi correlation": - with pytest.raises(RuntimeError, match="scipy 1.15.0"): + with pytest.raises(RuntimeError, msg="scipy 1.15.0"): vectorized_connectivities = conn_measure.fit_transform(signals) vectorized_connectivities = conn_measure.fit_transform(signals) -- 2.52.0 From 237d4031bf4ec1635ab718aa7afb4be7856750e8 Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Tue, 1 Apr 2025 11:44:10 +0200 Subject: [PATCH 15/17] Revert "chore: update tests for JuniferConnectivityMeasure" This reverts commit 59a48d24b856d5e592732b9374a50b38a911ebc7. --- .../tests/test_junifer_connectivity_measure.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py index 576d29018..686bab157 100644 --- a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +++ b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py @@ -4,7 +4,6 @@ # License: AGPL import copy -import sys import warnings from math import cosh, exp, log, sinh, sqrt from typing import TYPE_CHECKING, Optional, Union @@ -643,11 +642,8 @@ def test_connectivity_measure_generic( conn_measure = JuniferConnectivityMeasure( kind=kind, cov_estimator=cov_estimator ) - if sys.version_info < (3, 10) and kind == "xi correlation": - with pytest.raises(RuntimeError, msg="scipy 1.15.0"): - connectivities = conn_measure.fit_transform(signals) - connectivities = conn_measure.fit_transform(signals) + # Generic assert isinstance(connectivities, np.ndarray) assert len(connectivities) == len(covs) @@ -834,10 +830,6 @@ def test_connectivity_measure_check_mean( """ conn_measure = JuniferConnectivityMeasure(kind=kind) - if sys.version_info < (3, 10) and kind == "xi correlation": - with pytest.raises(RuntimeError, msg="scipy 1.15.0"): - conn_measure.fit_transform(signals) - conn_measure.fit_transform(signals) assert (conn_measure.mean_).shape == (N_FEATURES, N_FEATURES) @@ -874,9 +866,6 @@ def test_connectivity_measure_check_vectorization_option( conn_measure = JuniferConnectivityMeasure(kind=kind) connectivities = conn_measure.fit_transform(signals) conn_measure = JuniferConnectivityMeasure(vectorize=True, kind=kind) - if sys.version_info < (3, 10) and kind == "xi correlation": - with pytest.raises(RuntimeError, msg="scipy 1.15.0"): - vectorized_connectivities = conn_measure.fit_transform(signals) vectorized_connectivities = conn_measure.fit_transform(signals) assert_array_almost_equal( -- 2.52.0 From 493bc98eb2c3e35b8544d5748b754c72c0560c46 Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Tue, 1 Apr 2025 11:44:47 +0200 Subject: [PATCH 16/17] Revert "chore: update tests for JuniferConnectivityMeasure to include xi correlation" This reverts commit f989f8473501e28d13e0c985ac8ed66169391c53. --- .../nilearn/tests/test_junifer_connectivity_measure.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py index 686bab157..c1759fd36 100644 --- a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +++ b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py @@ -76,7 +76,6 @@ CONNECTIVITY_KINDS = ( "precision", "partial correlation", "spearman correlation", - "xi correlation", ) N_FEATURES = 49 @@ -834,7 +833,7 @@ def test_connectivity_measure_check_mean( assert (conn_measure.mean_).shape == (N_FEATURES, N_FEATURES) - if kind not in ("tangent", "xi correlation"): + if kind != "tangent": assert_array_almost_equal( conn_measure.mean_, np.mean(conn_measure.transform(signals), axis=0), -- 2.52.0 From 6df61d19627c5b69a0d2d785fd97c5f237b2f4bb Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Tue, 1 Apr 2025 11:59:42 +0200 Subject: [PATCH 17/17] chore: simplify tests for JuniferConnectivityMeasure using xi correlation --- .../test_junifer_connectivity_measure.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py index c1759fd36..837f6f678 100644 --- a/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +++ b/junifer/external/nilearn/tests/test_junifer_connectivity_measure.py @@ -4,6 +4,7 @@ # License: AGPL import copy +import sys import warnings from math import cosh, exp, log, sinh, sqrt from typing import TYPE_CHECKING, Optional, Union @@ -1094,6 +1095,25 @@ def test_connectivity_measure_standardize( assert match not in m.message +@pytest.mark.skipif( + sys.version_info > (3, 9), + reason="will have correct scipy version so no error", +) +def test_xi_correlation_error() -> None: + """Check xi correlation according to paper.""" + with pytest.raises(RuntimeError, match="scipy.stats.chatterjeexi"): + JuniferConnectivityMeasure(kind="xi correlation").fit_transform( + np.zeros((2, 2)) + ) + + +@pytest.mark.skipif( + sys.version_info < (3, 10), + reason=( + "needs scipy 1.15.0 and above which in turn requires " + "python 3.10 and above" + ), +) def test_xi_correlation() -> None: """Check xi correlation according to paper.""" rng = np.random.default_rng(25982435982346983) -- 2.52.0