fSTG-Toolkit 1.0.0__tar.gz → 1.2.0__tar.gz

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.
Files changed (54) hide show
  1. fstg_toolkit-1.2.0/PKG-INFO +131 -0
  2. fstg_toolkit-1.2.0/README.md +89 -0
  3. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/pyproject.toml +9 -2
  4. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/__init__.py +12 -7
  5. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/__main__.py +13 -10
  6. fstg_toolkit-1.2.0/src/fstg_toolkit/app/assets/common.js +93 -0
  7. fstg_toolkit-1.2.0/src/fstg_toolkit/app/assets/favicon.ico +0 -0
  8. fstg_toolkit-1.2.0/src/fstg_toolkit/app/figures/common.py +73 -0
  9. fstg_toolkit-1.2.0/src/fstg_toolkit/app/figures/frequent.py +600 -0
  10. fstg_toolkit-1.2.0/src/fstg_toolkit/app/figures/metrics.py +240 -0
  11. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/figures/subject.py +41 -16
  12. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/views/frequent.py +78 -25
  13. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/views/subject.py +22 -4
  14. fstg_toolkit-1.2.0/src/fstg_toolkit/frequent/__init__.py +54 -0
  15. fstg_toolkit-1.2.0/src/fstg_toolkit/frequent/patterns.py +731 -0
  16. fstg_toolkit-1.2.0/src/fstg_toolkit/frequent/spminer.py +111 -0
  17. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/io.py +83 -75
  18. fstg_toolkit-1.0.0/PKG-INFO +0 -231
  19. fstg_toolkit-1.0.0/README.md +0 -195
  20. fstg_toolkit-1.0.0/src/fstg_toolkit/app/assets/common.js +0 -138
  21. fstg_toolkit-1.0.0/src/fstg_toolkit/app/figures/frequent.py +0 -160
  22. fstg_toolkit-1.0.0/src/fstg_toolkit/app/figures/metrics.py +0 -88
  23. fstg_toolkit-1.0.0/src/fstg_toolkit/frequent.py +0 -415
  24. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/LICENSE +0 -0
  25. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/__init__.py +0 -0
  26. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/assets/custom.css +0 -0
  27. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/core/__init__.py +0 -0
  28. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/core/color.py +0 -0
  29. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/core/config.py +0 -0
  30. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/core/datafilesdb.py +0 -0
  31. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/core/geometry.py +0 -0
  32. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/core/processing.py +0 -0
  33. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/core/utils.py +0 -0
  34. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/figures/__init__.py +0 -0
  35. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/figures/data.py +0 -0
  36. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/figures/matrices.py +0 -0
  37. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/fstg_view.py +0 -0
  38. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/pages/dashboard.py +0 -0
  39. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/pages/home.py +0 -0
  40. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/pages/list.py +0 -0
  41. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/pages/submit.py +0 -0
  42. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/views/__init__.py +0 -0
  43. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/views/common.py +0 -0
  44. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/views/data.py +0 -0
  45. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/views/matrices.py +0 -0
  46. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/app/views/metrics.py +0 -0
  47. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/factory.py +0 -0
  48. {fstg_toolkit-1.0.0/src/fstg_toolkit → fstg_toolkit-1.2.0/src/fstg_toolkit/frequent}/_docker_utils.py +0 -0
  49. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/graph.py +0 -0
  50. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/logging.yml +0 -0
  51. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/metrics.py +0 -0
  52. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/simulation.py +0 -0
  53. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/utils.py +0 -0
  54. {fstg_toolkit-1.0.0 → fstg_toolkit-1.2.0}/src/fstg_toolkit/visualization.py +0 -0
@@ -0,0 +1,131 @@
1
+ Metadata-Version: 2.4
2
+ Name: fSTG-Toolkit
3
+ Version: 1.2.0
4
+ Summary: Aan Open-Source Software for Spatio-Temporal Graph Analysis of fMRI data.
5
+ License-Expression: CECILL-B
6
+ License-File: LICENSE
7
+ Author: Julien PONTABRY
8
+ Author-email: jpontabry@unistra.fr
9
+ Requires-Python: >=3.12,<=3.13
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Provides-Extra: dashboard
14
+ Provides-Extra: dev
15
+ Provides-Extra: docs
16
+ Provides-Extra: frequent
17
+ Provides-Extra: plot
18
+ Requires-Dist: click (>=8.1.8,<9.0.0)
19
+ Requires-Dist: coverage (>=7.13.4,<8.0.0) ; extra == "dev"
20
+ Requires-Dist: dash (>=3.0.2,<4.0.0) ; extra == "dashboard"
21
+ Requires-Dist: dash-bootstrap-components (>=2.0.0,<3.0.0) ; extra == "dashboard"
22
+ Requires-Dist: dash-breakpoints (>=0.1.0,<0.2.0) ; extra == "dashboard"
23
+ Requires-Dist: dash-daq (>=0.6.0,<0.7.0) ; extra == "dashboard"
24
+ Requires-Dist: dash-uploader (==0.7.0a2) ; extra == "dashboard"
25
+ Requires-Dist: docker (>=7.1.0,<8.0.0) ; extra == "frequent"
26
+ Requires-Dist: furo (>=2024.8.6,<2025.0.0) ; extra == "docs"
27
+ Requires-Dist: matplotlib (>=3.10.1,<4.0.0) ; extra == "plot"
28
+ Requires-Dist: myst-parser (>=4.0.0,<5.0.0) ; extra == "docs"
29
+ Requires-Dist: networkx (>=3.4.2,<4.0.0)
30
+ Requires-Dist: numpy (>=2.2.3,<3.0.0)
31
+ Requires-Dist: orjson (>=3.10.16,<4.0.0) ; extra == "dashboard"
32
+ Requires-Dist: pandas (>=2.2.3,<3.0.0)
33
+ Requires-Dist: pip-audit (>=2.10.0,<3.0.0) ; extra == "dev"
34
+ Requires-Dist: pyyaml (>=6.0.3,<7.0.0)
35
+ Requires-Dist: rich-click (>=1.9.7,<2.0.0)
36
+ Requires-Dist: screeninfo (>=0.8.1,<0.9.0)
37
+ Requires-Dist: sphinx (>=8.0.0,<9.0.0) ; extra == "docs"
38
+ Requires-Dist: sphinx-click (>=6.0.0,<7.0.0) ; extra == "docs"
39
+ Requires-Dist: sphinx-copybutton (>=0.5.2,<0.6.0) ; extra == "docs"
40
+ Description-Content-Type: text/markdown
41
+
42
+ <div style="text-align: center">
43
+ <img src="docs/_static/images/fSTG_logo_large.svg" alt="fSTG Toolkit" width="480"/>
44
+ </div>
45
+
46
+ <div style="text-align: center">
47
+
48
+ ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/fSTG-Toolkit)
49
+ [![CI](https://github.com/julienpontabry/fstg_toolkit/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/julienpontabry/fstg_toolkit/actions/workflows/ci.yml)
50
+ ![PyPI - Version](https://img.shields.io/pypi/v/fSTG-Toolkit)
51
+ ![PyPI - License](https://img.shields.io/pypi/l/fSTG-Toolkit)
52
+ [![Read the Docs](https://img.shields.io/readthedocs/fSTG-Toolkit)](https://fstg-toolkit.readthedocs.io/)
53
+
54
+ </div>
55
+
56
+ # fSTG Toolkit: an Open-Source Software for Spatio-Temporal Graph Analysis of fMRI data
57
+
58
+ ## Overview
59
+
60
+ **fSTG Toolkit** is an open-source software dedicated to longitudinal analysis of brain connectivity, modeling data as spatio-temporal graphs. It enables the study of dynamics and reorganization of brain regions, primarily using functional MRI (fMRI) data, but is also compatible with any type of connectivity data.
61
+
62
+ Current main features:
63
+ - Building of spatio-temporal graphs from correlation matrices and region definitions.
64
+ - Advanced graph metrics computation.
65
+ - Interactive visualization of results via a web dashboard.
66
+ - Simulation of connectivity patterns and sequences.
67
+ - Frequent subgraph pattern mining via SPMiner integration.
68
+
69
+ ## Installation
70
+
71
+ ### Installation from PyPI
72
+
73
+ The easiest way to get started is to install the package from PyPI. Make sure you have a Python environment ready with a supported version (see the badge above), then run:
74
+ ```shell
75
+ pip install fSTG-Toolkit
76
+ ```
77
+
78
+ To install optional feature sets:
79
+ ```shell
80
+ pip install "fSTG-Toolkit[dashboard]" # web dashboard
81
+ pip install "fSTG-Toolkit[plot]" # matplotlib plots
82
+ pip install "fSTG-Toolkit[frequent]" # frequent pattern mining (requires Docker)
83
+ pip install "fSTG-Toolkit[dashboard,plot,frequent]" # everything
84
+ ```
85
+
86
+ ### Installation from Source
87
+
88
+ To install from source, create a new environment with the required Python and Poetry binaries. Using conda:
89
+ ```shell
90
+ conda env create -n <env_name> -f environment.yml
91
+ conda activate <env_name>
92
+ ```
93
+
94
+ Then in the project's root folder, install the dependencies:
95
+ ```shell
96
+ poetry install
97
+ ```
98
+
99
+ To install optional feature sets:
100
+ ```shell
101
+ poetry install --extras dashboard # web dashboard
102
+ poetry install --extras plot # matplotlib plots
103
+ poetry install --extras frequent # frequent pattern mining (requires Docker)
104
+ poetry install --all-extras # everything
105
+ ```
106
+
107
+ ## Quick Start
108
+
109
+ ```shell
110
+ # Build graphs from a correlation matrix file and an areas CSV
111
+ python -m fstg_toolkit graph build -o my_graphs.zip areas.csv matrices.npz
112
+
113
+ # Compute graph metrics
114
+ python -m fstg_toolkit graph metrics my_graphs.zip
115
+
116
+ # Open the interactive dashboard
117
+ python -m fstg_toolkit dashboard show my_graphs.zip
118
+ ```
119
+
120
+ The areas CSV must contain `Id_Area`, `Name_Area`, and `Name_Region` columns. Correlation matrices must be NumPy files (`.npz` or `.npy`) with shape `(T, N, N)`.
121
+
122
+ Use `--help` on any command for full options:
123
+ ```shell
124
+ python -m fstg_toolkit --help
125
+ python -m fstg_toolkit graph build --help
126
+ ```
127
+
128
+ Full usage documentation, tutorials, and API reference are available at **[fstg-toolkit.readthedocs.io](https://fstg-toolkit.readthedocs.io/)**.
129
+
130
+ ![Illustration of the dashboard.](docs/_static/images/illustration_web-viewer.png)
131
+
@@ -0,0 +1,89 @@
1
+ <div style="text-align: center">
2
+ <img src="docs/_static/images/fSTG_logo_large.svg" alt="fSTG Toolkit" width="480"/>
3
+ </div>
4
+
5
+ <div style="text-align: center">
6
+
7
+ ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/fSTG-Toolkit)
8
+ [![CI](https://github.com/julienpontabry/fstg_toolkit/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/julienpontabry/fstg_toolkit/actions/workflows/ci.yml)
9
+ ![PyPI - Version](https://img.shields.io/pypi/v/fSTG-Toolkit)
10
+ ![PyPI - License](https://img.shields.io/pypi/l/fSTG-Toolkit)
11
+ [![Read the Docs](https://img.shields.io/readthedocs/fSTG-Toolkit)](https://fstg-toolkit.readthedocs.io/)
12
+
13
+ </div>
14
+
15
+ # fSTG Toolkit: an Open-Source Software for Spatio-Temporal Graph Analysis of fMRI data
16
+
17
+ ## Overview
18
+
19
+ **fSTG Toolkit** is an open-source software dedicated to longitudinal analysis of brain connectivity, modeling data as spatio-temporal graphs. It enables the study of dynamics and reorganization of brain regions, primarily using functional MRI (fMRI) data, but is also compatible with any type of connectivity data.
20
+
21
+ Current main features:
22
+ - Building of spatio-temporal graphs from correlation matrices and region definitions.
23
+ - Advanced graph metrics computation.
24
+ - Interactive visualization of results via a web dashboard.
25
+ - Simulation of connectivity patterns and sequences.
26
+ - Frequent subgraph pattern mining via SPMiner integration.
27
+
28
+ ## Installation
29
+
30
+ ### Installation from PyPI
31
+
32
+ The easiest way to get started is to install the package from PyPI. Make sure you have a Python environment ready with a supported version (see the badge above), then run:
33
+ ```shell
34
+ pip install fSTG-Toolkit
35
+ ```
36
+
37
+ To install optional feature sets:
38
+ ```shell
39
+ pip install "fSTG-Toolkit[dashboard]" # web dashboard
40
+ pip install "fSTG-Toolkit[plot]" # matplotlib plots
41
+ pip install "fSTG-Toolkit[frequent]" # frequent pattern mining (requires Docker)
42
+ pip install "fSTG-Toolkit[dashboard,plot,frequent]" # everything
43
+ ```
44
+
45
+ ### Installation from Source
46
+
47
+ To install from source, create a new environment with the required Python and Poetry binaries. Using conda:
48
+ ```shell
49
+ conda env create -n <env_name> -f environment.yml
50
+ conda activate <env_name>
51
+ ```
52
+
53
+ Then in the project's root folder, install the dependencies:
54
+ ```shell
55
+ poetry install
56
+ ```
57
+
58
+ To install optional feature sets:
59
+ ```shell
60
+ poetry install --extras dashboard # web dashboard
61
+ poetry install --extras plot # matplotlib plots
62
+ poetry install --extras frequent # frequent pattern mining (requires Docker)
63
+ poetry install --all-extras # everything
64
+ ```
65
+
66
+ ## Quick Start
67
+
68
+ ```shell
69
+ # Build graphs from a correlation matrix file and an areas CSV
70
+ python -m fstg_toolkit graph build -o my_graphs.zip areas.csv matrices.npz
71
+
72
+ # Compute graph metrics
73
+ python -m fstg_toolkit graph metrics my_graphs.zip
74
+
75
+ # Open the interactive dashboard
76
+ python -m fstg_toolkit dashboard show my_graphs.zip
77
+ ```
78
+
79
+ The areas CSV must contain `Id_Area`, `Name_Area`, and `Name_Region` columns. Correlation matrices must be NumPy files (`.npz` or `.npy`) with shape `(T, N, N)`.
80
+
81
+ Use `--help` on any command for full options:
82
+ ```shell
83
+ python -m fstg_toolkit --help
84
+ python -m fstg_toolkit graph build --help
85
+ ```
86
+
87
+ Full usage documentation, tutorials, and API reference are available at **[fstg-toolkit.readthedocs.io](https://fstg-toolkit.readthedocs.io/)**.
88
+
89
+ ![Illustration of the dashboard.](docs/_static/images/illustration_web-viewer.png)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fSTG-Toolkit"
3
- version = "1.0.0"
3
+ version = "1.2.0"
4
4
  description = "Aan Open-Source Software for Spatio-Temporal Graph Analysis of fMRI data."
5
5
  authors = [
6
6
  {name = "Julien PONTABRY",email = "jpontabry@unistra.fr"}
@@ -8,7 +8,7 @@ authors = [
8
8
  readme = "README.md"
9
9
  license = "CECILL-B"
10
10
  license-files = ["LICENSE"]
11
- requires-python = ">=3.12,<4.0"
11
+ requires-python = ">=3.12,<=3.13"
12
12
  dependencies = [
13
13
  "networkx (>=3.4.2,<4.0.0)",
14
14
  "pandas (>=2.2.3,<3.0.0)",
@@ -38,6 +38,13 @@ dev = [
38
38
  "coverage (>=7.13.4,<8.0.0)",
39
39
  "pip-audit (>=2.10.0,<3.0.0)",
40
40
  ]
41
+ docs = [
42
+ "sphinx (>=8.0.0,<9.0.0)",
43
+ "furo (>=2024.8.6,<2025.0.0)",
44
+ "myst-parser (>=4.0.0,<5.0.0)",
45
+ "sphinx-click (>=6.0.0,<7.0.0)",
46
+ "sphinx-copybutton (>=0.5.2,<0.6.0)",
47
+ ]
41
48
 
42
49
  [tool.setuptools.package-data]
43
50
  fstg_toolkit = ["logging.yml"]
@@ -31,18 +31,13 @@
31
31
  # The fact that you are presently reading this means that you have had
32
32
  # knowledge of the CeCILL-B license and that you accept its terms.
33
33
 
34
+ from importlib.metadata import version
35
+
34
36
  from .factory import spatio_temporal_graph_from_corr_matrices
35
37
  from .graph import SpatioTemporalGraph
36
38
  from .io import load_spatio_temporal_graph, save_spatio_temporal_graph
37
39
  from .simulation import CorrelationMatrixSequenceSimulator, generate_pattern, SpatioTemporalGraphSimulator
38
40
 
39
- try:
40
- from .visualization import multipartite_plot, spatial_plot, temporal_plot
41
- except ImportError:
42
- pass
43
-
44
- from importlib.metadata import version
45
-
46
41
  __version__ = version(__package__)
47
42
 
48
43
  __all__ = [
@@ -54,3 +49,13 @@ __all__ = [
54
49
  'generate_pattern',
55
50
  'SpatioTemporalGraphSimulator'
56
51
  ]
52
+
53
+ try:
54
+ from .visualization import multipartite_plot, spatial_plot, temporal_plot
55
+ __all__ += [
56
+ 'multipartite_plot',
57
+ 'spatial_plot',
58
+ 'temporal_plot',
59
+ ]
60
+ except ImportError:
61
+ pass
@@ -32,6 +32,7 @@
32
32
  # knowledge of the CeCILL-B license and that you accept its terms.
33
33
 
34
34
  __help_epilog = []
35
+ __graph_help_epilog = []
35
36
 
36
37
  import multiprocessing
37
38
  import re
@@ -78,7 +79,9 @@ try:
78
79
  from .frequent import SPMinerService
79
80
  except ImportError as e:
80
81
  SPMinerService = None
81
- __help_epilog.append(f"⚠️ Install '{__package__}[frequent]' to unlock the frequent patterns analysis command.")
82
+ epilog_tip = f"⚠️ Install '{__package__}[frequent]' to unlock the frequent patterns analysis command."
83
+ __help_epilog.append(epilog_tip)
84
+ __graph_help_epilog.append(epilog_tip)
82
85
 
83
86
 
84
87
  console = Console()
@@ -126,7 +129,7 @@ def __load_graph(filepath: Path) -> SpatioTemporalGraph:
126
129
  ## building and computing #####################################################
127
130
 
128
131
 
129
- @click.group()
132
+ @click.group(epilog="\n\n".join(__graph_help_epilog))
130
133
  def graph():
131
134
  """Build, calculate metrics and simulate graphs."""
132
135
  pass
@@ -772,16 +775,16 @@ def serve(data_path: Path, upload_path: Path, debug: bool, port: int, db_path: P
772
775
 
773
776
  ## main entry point ###########################################################
774
777
 
775
- if __name__ == '__main__':
776
- cli.add_command(graph)
778
+ cli.add_command(graph)
777
779
 
778
- if plt is not None:
779
- cli.add_command(plot)
780
+ if plt is not None:
781
+ cli.add_command(plot)
780
782
 
781
- if app_config is not None:
782
- cli.add_command(dashboard)
783
+ if app_config is not None:
784
+ cli.add_command(dashboard)
783
785
 
784
- if SPMinerService is not None:
785
- graph.add_command(frequent)
786
+ if SPMinerService is not None:
787
+ graph.add_command(frequent)
786
788
 
789
+ if __name__ == '__main__':
787
790
  cli()
@@ -0,0 +1,93 @@
1
+ // Copyright 2025 ICube (University of Strasbourg - CNRS)
2
+ // author: Julien PONTABRY (ICube)
3
+ //
4
+ // This software is a computer program whose purpose is to provide a toolkit
5
+ // to model, process and analyze the longitudinal reorganization of brain
6
+ // connectivity data, as functional MRI for instance.
7
+ //
8
+ // This software is governed by the CeCILL-B license under French law and
9
+ // abiding by the rules of distribution of free software. You can use,
10
+ // modify and/or redistribute the software under the terms of the CeCILL-B
11
+ // license as circulated by CEA, CNRS and INRIA at the following URL
12
+ // "http://www.cecill.info".
13
+ //
14
+ // As a counterpart to the access to the source code and rights to copy,
15
+ // modify and redistribute granted by the license, users are provided only
16
+ // with a limited warranty and the software's author, the holder of the
17
+ // economic rights, and the successive licensors have only limited
18
+ // liability.
19
+ //
20
+ // In this respect, the user's attention is drawn to the risks associated
21
+ // with loading, using, modifying and/or developing or reproducing the
22
+ // software by the user in light of its specific status of free software,
23
+ // that may mean that it is complicated to manipulate, and that also
24
+ // therefore means that it is reserved for developers and experienced
25
+ // professionals having in-depth computer knowledge. Users are therefore
26
+ // encouraged to load and test the software's suitability as regards their
27
+ // requirements in conditions enabling the security of their systems and/or
28
+ // data to be ensured and, more generally, to use and operate it in the
29
+ // same conditions as regards security.
30
+ //
31
+ // The fact that you are presently reading this means that you have had
32
+ // knowledge of the CeCILL-B license and that you accept its terms.
33
+
34
+ let _hoverDebounceTimer = null;
35
+
36
+ window.dash_clientside = Object.assign({}, window.dash_clientside, {
37
+ clientside: {
38
+ subject_node_hover: function(hoverData, storeHoverGraph) {
39
+ if (!hoverData || !hoverData.points || hoverData.points.length === 0 || !storeHoverGraph) {
40
+ return window.dash_clientside.no_update;
41
+ }
42
+
43
+ clearTimeout(_hoverDebounceTimer);
44
+ _hoverDebounceTimer = setTimeout(() => {
45
+ const graphDiv = document.getElementById('st-graph');
46
+ const figure = graphDiv && graphDiv.querySelector('.js-plotly-plot');
47
+ if (!figure || !figure.data) return;
48
+
49
+ const point = hoverData.points[0];
50
+ const props = storeHoverGraph[point.x] && storeHoverGraph[point.x][point.y];
51
+ if (!props || props.length !== 2) return;
52
+
53
+ const size = 10, min_size = 1, max_size = size * 2 - 1;
54
+ const ys = [point.y, ...props[0]];
55
+ const ws = [size, ...props[1].map(w => Math.abs(w) * max_size + min_size)];
56
+ const xs = Array(ys.length).fill(point.x);
57
+ const colors = ['black', ...props[1].map(w =>
58
+ `hsl(${w < 0 ? 240 : 0}, ${Math.abs(w) * 100}%, 50%)`
59
+ )];
60
+
61
+ Plotly.restyle(figure, {
62
+ x: [xs], y: [ys],
63
+ 'marker.color': [colors],
64
+ 'marker.size': [ws],
65
+ }, figure.data.length - 1);
66
+ }, 16); // ~60 fps cap
67
+
68
+ return window.dash_clientside.no_update;
69
+ },
70
+
71
+ subject_clear_out: function(id) {
72
+ setTimeout(() => {
73
+ const graph = document.querySelector(`#${id} > .js-plotly-plot`);
74
+
75
+ graph.on('plotly_unhover', (eventData) => {
76
+ if (!eventData || !eventData.event || eventData.event.type !== 'mouseout') return;
77
+
78
+ const graphDiv = document.getElementById('st-graph');
79
+ const figure = graphDiv && graphDiv.querySelector('.js-plotly-plot');
80
+ if (!figure || !figure.data) return;
81
+
82
+ const n = figure.data.length;
83
+ if (figure.data[n-1].name === 'hover-spatial-connections') {
84
+ Plotly.restyle(figure, { x: [[]], y: [[]], 'marker.size': [[]], 'marker.color': [[]] }, n-1);
85
+ }
86
+ });
87
+ }, 300);
88
+
89
+ return window.dash_clientside.no_update;
90
+ }
91
+ }
92
+ });
93
+
@@ -0,0 +1,73 @@
1
+ # Copyright 2025 ICube (University of Strasbourg - CNRS)
2
+ # author: Julien PONTABRY (ICube)
3
+ #
4
+ # This software is a computer program whose purpose is to provide a toolkit
5
+ # to model, process and analyze the longitudinal reorganization of brain
6
+ # connectivity data, as functional MRI for instance.
7
+ #
8
+ # This software is governed by the CeCILL-B license under French law and
9
+ # abiding by the rules of distribution of free software. You can use,
10
+ # modify and/or redistribute the software under the terms of the CeCILL-B
11
+ # license as circulated by CEA, CNRS and INRIA at the following URL
12
+ # "http://www.cecill.info".
13
+ #
14
+ # As a counterpart to the access to the source code and rights to copy,
15
+ # modify and redistribute granted by the license, users are provided only
16
+ # with a limited warranty and the software's author, the holder of the
17
+ # economic rights, and the successive licensors have only limited
18
+ # liability.
19
+ #
20
+ # In this respect, the user's attention is drawn to the risks associated
21
+ # with loading, using, modifying and/or developing or reproducing the
22
+ # software by the user in light of its specific status of free software,
23
+ # that may mean that it is complicated to manipulate, and that also
24
+ # therefore means that it is reserved for developers and experienced
25
+ # professionals having in-depth computer knowledge. Users are therefore
26
+ # encouraged to load and test the software's suitability as regards their
27
+ # requirements in conditions enabling the security of their systems and/or
28
+ # data to be ensured and, more generally, to use and operate it in the
29
+ # same conditions as regards security.
30
+ #
31
+ # The fact that you are presently reading this means that you have had
32
+ # knowledge of the CeCILL-B license and that you accept its terms.
33
+
34
+ import numpy as np
35
+
36
+
37
+ def integer_tick_step(max_val: int, max_range: int = 5) -> int:
38
+ """Return a tick step so that ticks land only on integers.
39
+
40
+ For small ranges (≤ `max_range`) every integer is shown. For larger ranges the step
41
+ is chosen so that roughly 8 ticks appear, avoiding float tick values.
42
+ """
43
+ if max_val <= max_range:
44
+ return 1
45
+ return max(1, round(max_val / 8))
46
+
47
+
48
+ def hex_to_rgba(hex_color: str, alpha: float) -> str:
49
+ """Convert a hex colour string to an RGBA CSS string.
50
+
51
+ Parameters
52
+ ----------
53
+ hex_color : str
54
+ Colour in ``#RRGGBB`` format (e.g. ``'#636EFA'``).
55
+ alpha : float
56
+ Opacity in the range [0, 1].
57
+
58
+ Returns
59
+ -------
60
+ str
61
+ Colour in ``rgba(R, G, B, alpha)`` format suitable for Plotly.
62
+ """
63
+ r = int(hex_color[1:3], 16)
64
+ g = int(hex_color[3:5], 16)
65
+ b = int(hex_color[5:7], 16)
66
+ return f'rgba({r},{g},{b},{alpha})'
67
+
68
+
69
+ def norm_min_max_size(s: list[float], new_min: float = 0, new_max: float = 1) -> list[float]:
70
+ s_min = np.min(s)
71
+ s_max = np.max(s)
72
+ scale = s_max - s_min
73
+ return ((new_max - new_min) * np.subtract(s, s_min) / scale + new_min).tolist()