Skip to content

Commit c177dd5

Browse files
authored
Merge pull request #409 from predictive-clinical-neuroscience/maint/add_federated_example
enh - add federated learning and evaluation metrics tutorials
2 parents 303d67c + d3a7cba commit c177dd5

60 files changed

Lines changed: 4336 additions & 4220 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

doc/convert_notebooks.py

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,84 @@
1+
# To run this script, execute "python doc/convert_notebooks.py" from the root
2+
# of the repository.
3+
14
import glob
25
import os
36
import shutil
47
import subprocess
8+
import sys
59

6-
EXAMPLES_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "examples"))
7-
TUTORIALS_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "pages", "tutorials"))
10+
EXAMPLES_DIR = os.path.abspath(
11+
os.path.join(os.path.dirname(__file__), "..", "examples")
12+
)
13+
TUTORIALS_DIR = os.path.abspath(
14+
os.path.join(os.path.dirname(__file__), "pages", "tutorials")
15+
)
816

917
os.makedirs(TUTORIALS_DIR, exist_ok=True)
1018

1119

12-
# Clean up old rst and support files in tutorials dir
13-
def clean_tutorials_dir():
20+
def clean_tutorials_dir() -> None:
21+
"""Remove previously generated RST files and support png's."""
22+
# Delete every generated .rst file in the tutorials output dir
1423
for f in glob.glob(os.path.join(TUTORIALS_DIR, "*.rst")):
1524
os.remove(f)
25+
# Delete every notebook-support directory that ends with "_files/".
26+
# This deletes all the png's
1627
for d in glob.glob(os.path.join(TUTORIALS_DIR, "*_files")):
1728
shutil.rmtree(d)
1829

1930

20-
def convert_notebooks():
31+
def convert_notebooks() -> None:
32+
"""Convert every example notebook to RST using nbconvert.
33+
"""
34+
# Collect all notebooks in the examples directory
2135
notebooks = glob.glob(os.path.join(EXAMPLES_DIR, "*.ipynb"))
36+
2237
for nb_path in notebooks:
38+
# Derive the rst filename from the notebook name
2339
nb_name = os.path.splitext(os.path.basename(nb_path))[0]
24-
rst_path = os.path.join(TUTORIALS_DIR, f"{nb_name}.rst")
25-
# Convert notebook to rst
40+
2641
subprocess.run(
27-
["jupyter", "nbconvert", "--to", "rst", nb_path, "--output", nb_name, "--output-dir", TUTORIALS_DIR], check=True
42+
[
43+
sys.executable, # resolve "jupyter" from the virtual
44+
# environment that is running this script
45+
"-m",
46+
"jupyter",
47+
"nbconvert", # nbconvert needs the package "pandoc". Please
48+
# install with
49+
# "conda install -c conda-forge pandoc"
50+
"--to",
51+
"rst",
52+
nb_path,
53+
"--output",
54+
nb_name,
55+
"--output-dir",
56+
TUTORIALS_DIR,
57+
],
58+
check=True,
2859
)
2960

3061

62+
def fix_image_paths() -> None:
63+
"""Fix image paths in generated RST files in Windows.
64+
"""
65+
# Iterate over every generated RST file in the tutorials dir
66+
for rst_path in glob.glob(os.path.join(TUTORIALS_DIR, "*.rst")):
67+
# Read the file content as text
68+
with open(rst_path, "r", encoding="utf-8") as fh:
69+
content = fh.read()
70+
71+
# Fix Windows paths
72+
fixed = content.replace("%5C", "/")
73+
74+
# Only write back if the content actually changed
75+
if fixed != content:
76+
with open(rst_path, "w", encoding="utf-8") as fh:
77+
fh.write(fixed)
78+
79+
3180
if __name__ == "__main__":
3281
clean_tutorials_dir()
3382
convert_notebooks()
83+
if os.name == "nt": # Only fix image paths on Windows
84+
fix_image_paths()

doc/index.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ Welcome to PCNToolkit's documentation!
1919
pages/tutorials/04_HBR_SHASH.rst
2020
pages/tutorials/05_HBR_Beta.rst
2121
pages/tutorials/06_transfer_extend.rst
22-
pages/tutorials/10_merge.rst
2322
pages/tutorials/07_model_comparison.rst
2423
pages/tutorials/08_cluster.rst
2524
pages/tutorials/09_command_line_interface.rst
25+
pages/tutorials/12_federated_learning.rst
26+
pages/tutorials/13_evaluation_metrics.rst
2627

2728

2829
.. toctree::

doc/pages/tutorials/01_loading_data.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Here are examples of both.
6565
sex (2)
6666
site (23)
6767
68-
68+
6969
7070
7171
@@ -107,7 +107,7 @@ Here are examples of both.
107107
- 1 batch effects:
108108
batch_effect_0 (2)
109109
110-
110+
111111
112112
113113
@@ -1378,13 +1378,13 @@ values - ``statistic``: The name of the computed statistics
13781378
Process: 75157 - 2025-11-20 13:18:58 - Computing yhat for WM-hypointensities.
13791379
Process: 75157 - 2025-11-20 13:18:58 - Computing yhat for Left-Lateral-Ventricle.
13801380
Process: 75157 - 2025-11-20 13:18:58 - Computing yhat for Brain-Stem.
1381-
1381+
13821382
13831383
.. parsed-literal::
13841384
13851385
/opt/anaconda3/envs/ptk/lib/python3.12/site-packages/pcntoolkit/dataio/norm_data.py:1094: FutureWarning: The previous implementation of stack is deprecated and will be removed in a future version of pandas. See the What's New notes for pandas 2.1.0 for details. Specify future_stack=True to adopt the new implementation and silence this warning.
13861386
subject_ids = subject_ids.stack(level="centile")
1387-
1387+
13881388
13891389
.. parsed-literal::
13901390
@@ -1407,7 +1407,7 @@ values - ``statistic``: The name of the computed statistics
14071407
Process: 75157 - 2025-11-20 13:18:58 - Harmonizing data for Brain-Stem.
14081408
Process: 75157 - 2025-11-20 13:18:59 - Saving model to:
14091409
/Users/stijndeboer/.pcntoolkit/saves.
1410-
1410+
14111411
14121412
.. code:: ipython3
14131413
@@ -2742,7 +2742,7 @@ applicable to both of them.
27422742
sex (2)
27432743
site (18)
27442744
2745-
2745+
27462746
27472747
.. code:: ipython3
27482748
@@ -2753,7 +2753,7 @@ applicable to both of them.
27532753
.. parsed-literal::
27542754
27552755
True
2756-
2756+
27572757
27582758
.. code:: ipython3
27592759

doc/pages/tutorials/02_BLR.rst

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
Bayesian Linear Regression (BLR)
2-
================================
1+
Bayesian Linear Regression
2+
==========================
33

44
Welcome to this tutorial notebook that will go through the fitting and
55
evaluation of Normative models with Bayesian Linear Regression (BLR).
@@ -79,7 +79,7 @@ First we download a small example dataset from github.
7979
sex (2)
8080
site (23)
8181
82-
82+
8383
8484
.. code:: ipython3
8585
@@ -202,7 +202,7 @@ All results can be found in the save directory.
202202
Process: 75222 - 2025-11-20 13:13:43 - Fitting models on 4 response variables.
203203
Process: 75222 - 2025-11-20 13:13:43 - Fitting model for WM-hypointensities.
204204
Process: 75222 - 2025-11-20 13:13:44 - Fitting model for Right-Lateral-Ventricle.
205-
205+
206206
207207
.. parsed-literal::
208208
@@ -258,12 +258,12 @@ All results can be found in the save directory.
258258
return f(*arrays, *other_args, **kwargs)
259259
/opt/anaconda3/envs/ptk/lib/python3.12/site-packages/scipy/_lib/_util.py:1226: LinAlgWarning: Ill-conditioned matrix (rcond=6.36754e-17): result may not be accurate.
260260
return f(*arrays, *other_args, **kwargs)
261-
261+
262262
263263
.. parsed-literal::
264264
265265
Process: 75222 - 2025-11-20 13:13:46 - Fitting model for Right-Amygdala.
266-
266+
267267
268268
.. parsed-literal::
269269
@@ -290,7 +290,7 @@ All results can be found in the save directory.
290290
return f(*arrays, *other_args, **kwargs)
291291
/opt/anaconda3/envs/ptk/lib/python3.12/site-packages/scipy/_lib/_util.py:1226: LinAlgWarning: Ill-conditioned matrix (rcond=1.95743e-41): result may not be accurate.
292292
return f(*arrays, *other_args, **kwargs)
293-
293+
294294
295295
.. parsed-literal::
296296
@@ -341,7 +341,7 @@ All results can be found in the save directory.
341341
Process: 75222 - 2025-11-20 13:13:48 - Computing yhat for Right-Amygdala.
342342
Process: 75222 - 2025-11-20 13:13:48 - Saving model to:
343343
resources/blr/save_dir.
344-
344+
345345
346346
347347
@@ -1182,7 +1182,7 @@ Let’s start with the centiles.
11821182
scatter_data=train, # Scatter this data along with the centiles
11831183
batch_effects={"site": ["Beijing_Zang", "AnnArbor_a"], "sex": ["M"]}, # Highlight these groups
11841184
show_other_data=True, # scatter data not in those groups as smaller black circles
1185-
harmonize=True, # harmonize the scatterdata, this means that we 'remove' the batch effects from the data, by simulating what the data would have looked like if all data was from the same batch.
1185+
harmonize_data=True, # harmonize the scatterdata, this means that we 'remove' the batch effects from the data, by simulating what the data would have looked like if all data was from the same batch.
11861186
show_yhat=True,
11871187
)
11881188
@@ -1213,7 +1213,7 @@ Let’s start with the centiles.
12131213
Process: 75222 - 2025-11-20 13:13:49 - Harmonizing data for WM-hypointensities.
12141214
Process: 75222 - 2025-11-20 13:13:49 - Harmonizing data for CortexVol.
12151215
Process: 75222 - 2025-11-20 13:13:49 - Harmonizing data for Right-Amygdala.
1216-
1216+
12171217
12181218
12191219
.. image:: 02_BLR_files/02_BLR_14_1.png
@@ -1301,7 +1301,7 @@ And finally the ridge plot:
13011301
self._figure.tight_layout(*args, **kwargs)
13021302
/opt/anaconda3/envs/ptk/lib/python3.12/site-packages/pcntoolkit/util/plotter.py:817: UserWarning: Tight layout not applied. tight_layout cannot make Axes height small enough to accommodate all Axes decorations.
13031303
plt.tight_layout()
1304-
1304+
13051305
13061306
13071307
.. image:: 02_BLR_files/02_BLR_20_1.png
@@ -1321,7 +1321,7 @@ And finally the ridge plot:
13211321
self._figure.tight_layout(*args, **kwargs)
13221322
/opt/anaconda3/envs/ptk/lib/python3.12/site-packages/pcntoolkit/util/plotter.py:817: UserWarning: Tight layout not applied. tight_layout cannot make Axes height small enough to accommodate all Axes decorations.
13231323
plt.tight_layout()
1324-
1324+
13251325
13261326
13271327
.. image:: 02_BLR_files/02_BLR_20_3.png
@@ -1341,7 +1341,7 @@ And finally the ridge plot:
13411341
self._figure.tight_layout(*args, **kwargs)
13421342
/opt/anaconda3/envs/ptk/lib/python3.12/site-packages/pcntoolkit/util/plotter.py:817: UserWarning: Tight layout not applied. tight_layout cannot make Axes height small enough to accommodate all Axes decorations.
13431343
plt.tight_layout()
1344-
1344+
13451345
13461346
13471347
.. image:: 02_BLR_files/02_BLR_20_5.png
@@ -1361,7 +1361,7 @@ And finally the ridge plot:
13611361
self._figure.tight_layout(*args, **kwargs)
13621362
/opt/anaconda3/envs/ptk/lib/python3.12/site-packages/pcntoolkit/util/plotter.py:817: UserWarning: Tight layout not applied. tight_layout cannot make Axes height small enough to accommodate all Axes decorations.
13631363
plt.tight_layout()
1364-
1364+
13651365
13661366
13671367
.. image:: 02_BLR_files/02_BLR_20_7.png
@@ -1642,7 +1642,7 @@ Predicting
16421642
Process: 75222 - 2025-11-20 13:13:50 - Computing yhat for WM-hypointensities.
16431643
Process: 75222 - 2025-11-20 13:13:50 - Computing yhat for CortexVol.
16441644
Process: 75222 - 2025-11-20 13:13:50 - Computing yhat for Right-Amygdala.
1645-
1645+
16461646
16471647
16481648
@@ -2502,7 +2502,7 @@ Harmonize
25022502
Process: 75222 - 2025-11-20 13:13:51 - Harmonizing data for WM-hypointensities.
25032503
Process: 75222 - 2025-11-20 13:13:51 - Harmonizing data for CortexVol.
25042504
Process: 75222 - 2025-11-20 13:13:51 - Harmonizing data for Right-Amygdala.
2505-
2505+
25062506
25072507
25082508
.. image:: 02_BLR_files/02_BLR_27_1.png
@@ -2575,7 +2575,7 @@ site B.
25752575
Process: 75222 - 2025-11-20 13:13:53 - Harmonizing data for WM-hypointensities.
25762576
Process: 75222 - 2025-11-20 13:13:53 - Harmonizing data for CortexVol.
25772577
Process: 75222 - 2025-11-20 13:13:53 - Harmonizing data for Right-Amygdala.
2578-
2578+
25792579
25802580
25812581
.. image:: 02_BLR_files/02_BLR_29_1.png
@@ -2641,7 +2641,7 @@ site B.
26412641
Process: 75222 - 2025-11-20 13:13:53 - Harmonizing data for WM-hypointensities.
26422642
Process: 75222 - 2025-11-20 13:13:53 - Harmonizing data for CortexVol.
26432643
Process: 75222 - 2025-11-20 13:13:53 - Harmonizing data for Right-Amygdala.
2644-
2644+
26452645
26462646
26472647
.. image:: 02_BLR_files/02_BLR_30_1.png

0 commit comments

Comments
 (0)