junifer 0.0.6.dev6__py3-none-any.whl → 0.0.6.dev16__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
junifer/_version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.0.6.dev6'
16
- __version_tuple__ = version_tuple = (0, 0, 6, 'dev6')
15
+ __version__ = version = '0.0.6.dev16'
16
+ __version_tuple__ = version_tuple = (0, 0, 6, 'dev16')
@@ -13,7 +13,7 @@ from nilearn.connectome import (
13
13
  prec_to_partial,
14
14
  sym_matrix_to_vec,
15
15
  )
16
- from scipy import linalg
16
+ from scipy import linalg, stats
17
17
  from sklearn.base import clone
18
18
  from sklearn.covariance import EmpiricalCovariance
19
19
 
@@ -314,15 +314,18 @@ class JuniferConnectivityMeasure(ConnectivityMeasure):
314
314
  * default ``cov_estimator`` is
315
315
  :class:`sklearn.covariance.EmpiricalCovariance`
316
316
  * default ``kind`` is ``"correlation"``
317
+ * supports Spearman's correlation via ``kind="spearman correlation"``
317
318
 
318
319
  Parameters
319
320
  ----------
320
321
  cov_estimator : estimator object, optional
321
322
  The covariance estimator
322
323
  (default ``EmpiricalCovariance(store_precision=False)``).
323
- kind : {"covariance", "correlation", "partial correlation", \
324
- "tangent", "precision"}, optional
325
- The matrix kind. For the use of ``"tangent"`` see [1]_
324
+ kind : {"covariance", "correlation", "spearman correlation", \
325
+ "partial correlation", "tangent", "precision"}, optional
326
+ The matrix kind. The default value uses Pearson's correlation.
327
+ If ``"spearman correlation"`` is used, the data will be ranked before
328
+ estimating the covariance. For the use of ``"tangent"`` see [1]_
326
329
  (default "correlation").
327
330
  vectorize : bool, optional
328
331
  If True, connectivity matrices are reshaped into 1D arrays and only
@@ -400,17 +403,22 @@ class JuniferConnectivityMeasure(ConnectivityMeasure):
400
403
  self.cov_estimator_ = clone(self.cov_estimator)
401
404
 
402
405
  # Compute all the matrices, stored in "connectivities"
403
- if self.kind == "correlation":
404
- covariances_std = [
405
- self.cov_estimator_.fit(
406
- signal.standardize_signal(
407
- x,
408
- detrend=False,
409
- standardize=self.standardize,
410
- )
411
- ).covariance_
412
- for x in X
413
- ]
406
+ if self.kind in ["correlation", "spearman correlation"]:
407
+ covariances_std = []
408
+ for x in X:
409
+ x = signal.standardize_signal(
410
+ x,
411
+ detrend=False,
412
+ standardize=self.standardize,
413
+ )
414
+
415
+ # rank data if spearman correlation
416
+ # before calculating covariance
417
+ if self.kind == "spearman correlation":
418
+ x = stats.rankdata(x, axis=0)
419
+
420
+ covariances_std.append(self.cov_estimator_.fit(x).covariance_)
421
+
414
422
  connectivities = [cov_to_corr(cov) for cov in covariances_std]
415
423
  else:
416
424
  covariances = [self.cov_estimator_.fit(x).covariance_ for x in X]
@@ -71,6 +71,7 @@ CONNECTIVITY_KINDS = (
71
71
  "tangent",
72
72
  "precision",
73
73
  "partial correlation",
74
+ "spearman correlation",
74
75
  )
75
76
 
76
77
  N_FEATURES = 49
@@ -4,6 +4,7 @@
4
4
  # License: AGPL
5
5
 
6
6
  from .read_transform import read_transform
7
+ from . import _brainprint as brainprint
7
8
 
8
9
 
9
- __all__ = ["read_transform"]
10
+ __all__ = ["read_transform", "brainprint"]
@@ -0,0 +1,141 @@
1
+ """Provide onthefly functions for BrainPrint post-analysis."""
2
+
3
+ # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
4
+ # License: AGPL
5
+
6
+ from typing import TYPE_CHECKING, Dict, Optional, Type
7
+
8
+ import numpy as np
9
+ import pandas as pd
10
+
11
+ from ..utils import raise_error
12
+
13
+
14
+ if TYPE_CHECKING:
15
+ from junifer.storage import BaseFeatureStorage
16
+
17
+
18
+ __all__ = ["normalize", "reweight"]
19
+
20
+
21
+ def normalize(
22
+ storage: Type["BaseFeatureStorage"],
23
+ features: Dict[str, Dict[str, Optional[str]]],
24
+ kind: str,
25
+ ) -> pd.DataFrame:
26
+ """Read stored brainprint data and normalize either surfaces or volumes.
27
+
28
+ Parameters
29
+ ----------
30
+ storage : storage-like
31
+ The storage class, for example, :class:`.HDF5FeatureStorage`.
32
+ features : dict, optional
33
+ The feature names or MD5 hashes to read as dict.
34
+ The dict should have the keys:
35
+
36
+ * ``"areas"`` (if ``kind="surface"``)
37
+ * ``"volumes"`` (if ``kind="volume"``)
38
+ * ``"eigenvalues"``
39
+
40
+ and the corresponding value for each of the keys is again
41
+ a dict with the keys:
42
+
43
+ * ``"feature_name"`` : str or None
44
+ * ``"feature_md5"`` : str or None
45
+
46
+ Either one of ``"feature_name"`` or ``"feature_md5"`` needs to be
47
+ not None for each first-level key, but both keys are mandatory.
48
+
49
+ kind : {"surface", "volume"}
50
+ The kind of normalization.
51
+
52
+ Returns
53
+ -------
54
+ pandas.DataFrame
55
+ The transformed feature as a ``pandas.DataFrame``.
56
+
57
+ Raises
58
+ ------
59
+ ValueError
60
+ If ``kind`` is invalid.
61
+
62
+ """
63
+ # Read storage
64
+ data_dict = {}
65
+ for k, v in features.items():
66
+ data_dict[k] = storage.read_df(**v) # type: ignore
67
+
68
+ # Check and normalize
69
+ valid_kind = ["surface", "volume"]
70
+ normalized_df = None
71
+ if kind == "surface":
72
+ eigenvalues_df = data_dict["eigenvalues"]
73
+ areas_df = data_dict["areas"]
74
+ normalized_df = eigenvalues_df.combine(
75
+ areas_df, lambda left, right: left * right
76
+ )
77
+ elif kind == "volume":
78
+ eigenvalues_df = data_dict["eigenvalues"]
79
+ volumes_df = data_dict["volumes"]
80
+ normalized_df = eigenvalues_df.combine(
81
+ volumes_df, lambda left, right: left * right ** np.divide(2.0, 3.0)
82
+ )
83
+ else:
84
+ raise_error(
85
+ "Invalid value for `kind`, should be one of: " f"{valid_kind}"
86
+ )
87
+
88
+ return normalized_df
89
+
90
+
91
+ def reweight(
92
+ storage: Type["BaseFeatureStorage"],
93
+ feature_name: Optional[str] = None,
94
+ feature_md5: Optional[str] = None,
95
+ ) -> pd.DataFrame:
96
+ """Read stored brainprint data and reweight eigenvalues.
97
+
98
+ Parameters
99
+ ----------
100
+ storage : storage-like
101
+ The storage class, for example, :class:`.HDF5FeatureStorage`.
102
+ feature_name : str, optional
103
+ Name of the feature to read (default None).
104
+ feature_md5 : str, optional
105
+ MD5 hash of the feature to read (default None).
106
+
107
+ Returns
108
+ -------
109
+ pandas.DataFrame
110
+ The transformed feature as a ``pandas.DataFrame``.
111
+
112
+ """
113
+ # Read storage
114
+ eigenvalues_df = storage.read_df(
115
+ feature_name=feature_name, feature_md5=feature_md5
116
+ ) # type: ignore
117
+
118
+ # Create data for operation
119
+ exploded_count_idx_df = (
120
+ eigenvalues_df.reset_index("eigenvalue")
121
+ .index.value_counts()
122
+ .apply(lambda x: np.arange(1, x + 1).astype(float))
123
+ .to_frame()
124
+ .explode("count")
125
+ )
126
+ idx_data = (
127
+ pd.concat(
128
+ [exploded_count_idx_df] * len(eigenvalues_df.columns), axis=1
129
+ )
130
+ .reset_index()
131
+ .drop("subject", axis=1, inplace=False)
132
+ .to_numpy()
133
+ )
134
+ idx_df = pd.DataFrame(
135
+ data=idx_data,
136
+ index=eigenvalues_df.index,
137
+ columns=eigenvalues_df.columns,
138
+ )
139
+
140
+ # Combine
141
+ return eigenvalues_df.combine(idx_df, lambda left, right: left / right)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: junifer
3
- Version: 0.0.6.dev6
3
+ Version: 0.0.6.dev16
4
4
  Summary: JUelich NeuroImaging FEature extractoR
5
5
  Author-email: Fede Raimondo <f.raimondo@fz-juelich.de>, Synchon Mandal <s.mandal@fz-juelich.de>
6
6
  Maintainer-email: Fede Raimondo <f.raimondo@fz-juelich.de>, Synchon Mandal <s.mandal@fz-juelich.de>
@@ -1,5 +1,5 @@
1
1
  junifer/__init__.py,sha256=-T9XmiCCL0j3YLx-0Pph15sPfL5FlcBDscajjJ-V4sU,604
2
- junifer/_version.py,sha256=nVn_509eHiH2KjeZJLZwflBXCcWgR8aVl2f9Ym1ItyM,424
2
+ junifer/_version.py,sha256=6F6uOGNcjX6dbq-EmRB3esRKologELcdzkhY7J6HmO0,426
3
3
  junifer/stats.py,sha256=BjQb2lfTGDP9l4UuQYmJFcJJNRfbJDGlNvC06SJaDDE,6237
4
4
  junifer/api/__init__.py,sha256=lwyIF0hPc7fICuSoddJfay0LPqlTRxHJ_xbtizgFYZA,312
5
5
  junifer/api/cli.py,sha256=53pews3mXkJ7DUDSkV51PbitYnuVAdQRkWG-gjO08Uw,16142
@@ -134,9 +134,9 @@ junifer/external/h5io/h5io/_version.py,sha256=mFY0GwwuN-a3M8w93_mskS6GZIvv9SNdjL
134
134
  junifer/external/h5io/h5io/chunked_array.py,sha256=K1HWf7R2Jc7gCzBqAoBjx0ZnMmUhTe3iAO6RF6PdUO4,3338
135
135
  junifer/external/h5io/h5io/chunked_list.py,sha256=1Y5BbuWzurJlEFQzJNuDdC3fNZ39ENEMba99X_4VeSM,1952
136
136
  junifer/external/nilearn/__init__.py,sha256=UdUKYArx3hvcziln89iaSGZcNGwHvsmbB4E5gS1zvOs,321
137
- junifer/external/nilearn/junifer_connectivity_measure.py,sha256=y6MSWz_7YjRNfahLiS8_ptmEBoSBqhj6J9E0p7cN1Jw,16847
137
+ junifer/external/nilearn/junifer_connectivity_measure.py,sha256=c8aLIlSs2eo6uHj-ZtYAto4szjbj21Zlj5JTQRrAnu8,17322
138
138
  junifer/external/nilearn/junifer_nifti_spheres_masker.py,sha256=DbSK2hKrgpHZ_vCRLbVv3YJpLZNkEAG0HFfQQpG6zdU,16546
139
- junifer/external/nilearn/tests/test_junifer_connectivity_measure.py,sha256=cwm-RMSHLS6GF-z2ioSNln3N9WoSrLf41mGvyYYMd7w,33918
139
+ junifer/external/nilearn/tests/test_junifer_connectivity_measure.py,sha256=yBsi9g_31UDo_oG7K6eKRp36CZ28G5cbNcKM3aTT53s,33946
140
140
  junifer/external/nilearn/tests/test_junifer_nifti_spheres_masker.py,sha256=zpvBYIvaNjUj9fIUg5K78LRzJqbyMYlUo2UQYS9_lo4,12275
141
141
  junifer/markers/__init__.py,sha256=u4BFgS_3GXAwFN2HfqdAhlBkyenLw4IYlMlwXwnjkVQ,1235
142
142
  junifer/markers/base.py,sha256=__Z0owDdjTwb7alQneOeoaUqaeCVbHwFRnaRZERi37M,8364
@@ -206,7 +206,8 @@ junifer/markers/tests/test_marker_utils.py,sha256=SR3ADWI3uGv4ozYqVu-rMZnJVqP6Jn
206
206
  junifer/markers/tests/test_markers_base.py,sha256=XYe1Z_88h2g1WX6Em4aM8VMyBuCpy5sNHbbpC0I89m4,2979
207
207
  junifer/markers/tests/test_parcel_aggregation.py,sha256=FkB0O0HjTk1CnLOn-dzNs_9_byUOISRc4jV92shN2Kc,27655
208
208
  junifer/markers/tests/test_sphere_aggregation.py,sha256=TGn5S7zKK0SJ4nHIxRZQSCpqRBmz7c8Sb8C79dLoHjE,10611
209
- junifer/onthefly/__init__.py,sha256=WykjD_q_zWyX40Y5iKsFXhPJLzD1NPcN-XKFKZDMXfc,184
209
+ junifer/onthefly/__init__.py,sha256=TA6tPuw54ynDlumb9Ii-2p59hw2rGoCMe1-vQ89JzZ8,238
210
+ junifer/onthefly/_brainprint.py,sha256=-q5j5xOkuZD_f-pjWi-b8VRqM9ZXDk1TnccuQDfLwz4,3860
210
211
  junifer/onthefly/read_transform.py,sha256=kZ-N_fKe9glaBTjhj_HXrdTtWXGI-fMoBpsawcOgsTw,4340
211
212
  junifer/onthefly/tests/test_read_transform.py,sha256=D2C3IpXQHdsJSF07v8rEwGntLGXjZOserlRhebJUAVM,4719
212
213
  junifer/pipeline/__init__.py,sha256=mmhtYuRGetBmBvKPVb9MxklcEK_R9ly-dgkzQiOp3g8,363
@@ -266,10 +267,10 @@ junifer/utils/logging.py,sha256=ardaiJkDfZMYvak5UIL5Etxg5Ii7inmVQSBdFLdgtb8,9781
266
267
  junifer/utils/tests/test_fs.py,sha256=WQS7cKlKEZ742CIuiOYYpueeAhY9PqlastfDVpVVtvE,923
267
268
  junifer/utils/tests/test_helpers.py,sha256=k5qqfxK8dFyuewTJyR1Qn6-nFaYNuVr0ysc18bfPjyU,929
268
269
  junifer/utils/tests/test_logging.py,sha256=duO4ou365hxwa_kwihFtKPLaL6LC5XHiyhOijrrngbA,8009
269
- junifer-0.0.6.dev6.dist-info/AUTHORS.rst,sha256=rmULKpchpSol4ExWFdm-qu4fkpSZPYqIESVJBZtGb6E,163
270
- junifer-0.0.6.dev6.dist-info/LICENSE.md,sha256=MqCnOBu8uXsEOzRZWh9EBVfVz-kE9NkXcLCrtGXo2yU,34354
271
- junifer-0.0.6.dev6.dist-info/METADATA,sha256=xiXPBGQgwXibZ7Lv-Jh8gMDr17N_ExAeOOHaDUG-KPE,8278
272
- junifer-0.0.6.dev6.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
273
- junifer-0.0.6.dev6.dist-info/entry_points.txt,sha256=DxFvKq0pOqRunAK0FxwJcoDfV1-dZvsFDpD5HRqSDhw,48
274
- junifer-0.0.6.dev6.dist-info/top_level.txt,sha256=4bAq1R2QFQ4b3hohjys2JBvxrl0GKk5LNFzYvz9VGcA,8
275
- junifer-0.0.6.dev6.dist-info/RECORD,,
270
+ junifer-0.0.6.dev16.dist-info/AUTHORS.rst,sha256=rmULKpchpSol4ExWFdm-qu4fkpSZPYqIESVJBZtGb6E,163
271
+ junifer-0.0.6.dev16.dist-info/LICENSE.md,sha256=MqCnOBu8uXsEOzRZWh9EBVfVz-kE9NkXcLCrtGXo2yU,34354
272
+ junifer-0.0.6.dev16.dist-info/METADATA,sha256=aKu6mGcLd9lgmR5bN_3DPrnsQTbWteKq9f_tdfHXYV0,8279
273
+ junifer-0.0.6.dev16.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
274
+ junifer-0.0.6.dev16.dist-info/entry_points.txt,sha256=DxFvKq0pOqRunAK0FxwJcoDfV1-dZvsFDpD5HRqSDhw,48
275
+ junifer-0.0.6.dev16.dist-info/top_level.txt,sha256=4bAq1R2QFQ4b3hohjys2JBvxrl0GKk5LNFzYvz9VGcA,8
276
+ junifer-0.0.6.dev16.dist-info/RECORD,,