From 8e9081ce83b7e5c7f4d8103f24c8968990f85997 Mon Sep 17 00:00:00 2001
From: Andre Anjos <andre.dos.anjos@gmail.com>
Date: Sun, 6 Aug 2023 00:29:23 +0200
Subject: [PATCH] [models] Improve documentation of config files; Make ptbench
 config work again

---
 doc/links.rst                                 |   7 +
 pyproject.toml                                |   2 +-
 src/ptbench/data/hivtb/datamodule.py          |   5 +
 src/ptbench/data/hivtb/fold_0.py              |  10 +-
 src/ptbench/data/hivtb/fold_1.py              |  10 +-
 src/ptbench/data/hivtb/fold_2.py              |  10 +-
 src/ptbench/data/hivtb/fold_3.py              |  10 +-
 src/ptbench/data/hivtb/fold_4.py              |  10 +-
 src/ptbench/data/hivtb/fold_5.py              |  10 +-
 src/ptbench/data/hivtb/fold_6.py              |  10 +-
 src/ptbench/data/hivtb/fold_7.py              |  10 +-
 src/ptbench/data/hivtb/fold_8.py              |  10 +-
 src/ptbench/data/hivtb/fold_9.py              |  10 +-
 src/ptbench/data/indian/datamodule.py         |   7 +-
 src/ptbench/data/indian/default.py            |   6 +
 src/ptbench/data/indian/fold_0.py             |  10 +-
 src/ptbench/data/indian/fold_1.py             |  10 +-
 src/ptbench/data/indian/fold_2.py             |  10 +-
 src/ptbench/data/indian/fold_3.py             |  10 +-
 src/ptbench/data/indian/fold_4.py             |  10 +-
 src/ptbench/data/indian/fold_5.py             |  10 +-
 src/ptbench/data/indian/fold_6.py             |  10 +-
 src/ptbench/data/indian/fold_7.py             |  10 +-
 src/ptbench/data/indian/fold_8.py             |  10 +-
 src/ptbench/data/indian/fold_9.py             |  10 +-
 src/ptbench/data/montgomery/datamodule.py     |   4 +
 src/ptbench/data/montgomery/default.py        |   6 +
 src/ptbench/data/montgomery/fold_0.py         |  10 +-
 src/ptbench/data/montgomery/fold_1.py         |  10 +-
 src/ptbench/data/montgomery/fold_2.py         |  10 +-
 src/ptbench/data/montgomery/fold_3.py         |  10 +-
 src/ptbench/data/montgomery/fold_4.py         |  10 +-
 src/ptbench/data/montgomery/fold_5.py         |  10 +-
 src/ptbench/data/montgomery/fold_6.py         |  10 +-
 src/ptbench/data/montgomery/fold_7.py         |  10 +-
 src/ptbench/data/montgomery/fold_8.py         |  10 +-
 src/ptbench/data/montgomery/fold_9.py         |  10 +-
 .../data/montgomery_shenzhen/default.py       |   8 +-
 .../data/montgomery_shenzhen/fold_0.py        |   8 +-
 .../data/montgomery_shenzhen/fold_1.py        |   8 +-
 .../data/montgomery_shenzhen/fold_2.py        |   8 +-
 .../data/montgomery_shenzhen/fold_3.py        |   8 +-
 .../data/montgomery_shenzhen/fold_4.py        |   8 +-
 .../data/montgomery_shenzhen/fold_5.py        |   8 +-
 .../data/montgomery_shenzhen/fold_6.py        |   8 +-
 .../data/montgomery_shenzhen/fold_7.py        |   8 +-
 .../data/montgomery_shenzhen/fold_8.py        |   8 +-
 .../data/montgomery_shenzhen/fold_9.py        |   8 +-
 .../montgomery_shenzhen_indian/datamodule.py  |   2 +
 .../montgomery_shenzhen_indian/default.py     |   8 +-
 .../data/montgomery_shenzhen_indian/fold_0.py |   8 +-
 .../data/montgomery_shenzhen_indian/fold_1.py |   8 +-
 .../data/montgomery_shenzhen_indian/fold_2.py |   8 +-
 .../data/montgomery_shenzhen_indian/fold_3.py |   8 +-
 .../data/montgomery_shenzhen_indian/fold_4.py |   8 +-
 .../data/montgomery_shenzhen_indian/fold_5.py |   8 +-
 .../data/montgomery_shenzhen_indian/fold_6.py |   8 +-
 .../data/montgomery_shenzhen_indian/fold_7.py |   8 +-
 .../data/montgomery_shenzhen_indian/fold_8.py |   8 +-
 .../data/montgomery_shenzhen_indian/fold_9.py |   8 +-
 .../datamodule.py                             |   5 +-
 .../default.py                                |   4 +-
 .../datamodule.py                             |   5 +-
 .../v1_fold_0.py                              |   6 +
 .../v1_fold_1.py                              |   6 +
 .../v1_fold_2.py                              |   6 +
 .../v1_fold_3.py                              |   6 +
 .../v1_fold_4.py                              |   6 +
 .../v1_fold_5.py                              |   6 +
 .../v1_fold_6.py                              |   6 +
 .../v1_fold_7.py                              |   6 +
 .../v1_fold_8.py                              |   6 +
 .../v1_fold_9.py                              |   6 +
 .../v1_healthy_vs_atb.py                      |   7 +
 .../v2_fold_0.py                              |   7 +
 .../v2_fold_1.py                              |   7 +
 .../v2_fold_2.py                              |   7 +
 .../v2_fold_3.py                              |   7 +
 .../v2_fold_4.py                              |   7 +
 .../v2_fold_5.py                              |   7 +
 .../v2_fold_6.py                              |   7 +
 .../v2_fold_7.py                              |   7 +
 .../v2_fold_8.py                              |   7 +
 .../v2_fold_9.py                              |   7 +
 .../v2_others_vs_atb.py                       |   7 +
 src/ptbench/data/nih_cxr14/cardiomegaly.py    |   9 ++
 src/ptbench/data/nih_cxr14/datamodule.py      |   4 +
 src/ptbench/data/nih_cxr14/default.py         |   8 +-
 src/ptbench/data/nih_cxr14_padchest/idiap.py  |   2 +
 .../data/padchest/cardiomegaly_idiap.py       |  10 +-
 src/ptbench/data/padchest/datamodule.py       |   4 +
 src/ptbench/data/padchest/idiap.py            |  10 +-
 src/ptbench/data/padchest/no_tb_idiap.py      |  14 +-
 src/ptbench/data/padchest/tb_idiap.py         |  13 +-
 src/ptbench/data/shenzhen/datamodule.py       |   4 +
 src/ptbench/data/shenzhen/default.py          |  10 +-
 src/ptbench/data/shenzhen/fold_0.py           |  10 +-
 src/ptbench/data/shenzhen/fold_1.py           |  10 +-
 src/ptbench/data/shenzhen/fold_2.py           |  10 +-
 src/ptbench/data/shenzhen/fold_3.py           |  10 +-
 src/ptbench/data/shenzhen/fold_4.py           |  10 +-
 src/ptbench/data/shenzhen/fold_5.py           |  10 +-
 src/ptbench/data/shenzhen/fold_6.py           |  10 +-
 src/ptbench/data/shenzhen/fold_7.py           |  10 +-
 src/ptbench/data/shenzhen/fold_8.py           |  10 +-
 src/ptbench/data/shenzhen/fold_9.py           |  10 +-
 src/ptbench/data/tbpoc/fold_0.py              |  10 +-
 src/ptbench/data/tbpoc/fold_1.py              |  10 +-
 src/ptbench/data/tbpoc/fold_2.py              |  10 +-
 src/ptbench/data/tbpoc/fold_3.py              |  10 +-
 src/ptbench/data/tbpoc/fold_4.py              |  10 +-
 src/ptbench/data/tbpoc/fold_5.py              |  10 +-
 src/ptbench/data/tbpoc/fold_6.py              |  10 +-
 src/ptbench/data/tbpoc/fold_7.py              |  10 +-
 src/ptbench/data/tbpoc/fold_8.py              |  10 +-
 src/ptbench/data/tbpoc/fold_9.py              |  10 +-
 src/ptbench/data/tbx11k/v1_fold_0.py          |   7 +
 src/ptbench/data/tbx11k/v1_fold_1.py          |   7 +
 src/ptbench/data/tbx11k/v1_fold_2.py          |   7 +
 src/ptbench/data/tbx11k/v1_fold_3.py          |   7 +
 src/ptbench/data/tbx11k/v1_fold_4.py          |   7 +
 src/ptbench/data/tbx11k/v1_fold_5.py          |   7 +
 src/ptbench/data/tbx11k/v1_fold_6.py          |   7 +
 src/ptbench/data/tbx11k/v1_fold_7.py          |   7 +
 src/ptbench/data/tbx11k/v1_fold_8.py          |   7 +
 src/ptbench/data/tbx11k/v1_fold_9.py          |   7 +
 src/ptbench/data/tbx11k/v1_healthy_vs_atb.py  |  12 +-
 src/ptbench/data/tbx11k/v2_fold_0.py          |   7 +
 src/ptbench/data/tbx11k/v2_fold_1.py          |   7 +
 src/ptbench/data/tbx11k/v2_fold_2.py          |   7 +
 src/ptbench/data/tbx11k/v2_fold_3.py          |   7 +
 src/ptbench/data/tbx11k/v2_fold_4.py          |   7 +
 src/ptbench/data/tbx11k/v2_fold_5.py          |   7 +
 src/ptbench/data/tbx11k/v2_fold_6.py          |   7 +
 src/ptbench/data/tbx11k/v2_fold_7.py          |   7 +
 src/ptbench/data/tbx11k/v2_fold_8.py          |   7 +
 src/ptbench/data/tbx11k/v2_fold_9.py          |   7 +
 src/ptbench/data/tbx11k/v2_others_vs_atb.py   |  12 +-
 src/ptbench/models/config/alexnet.py          |   7 +-
 .../models/config/alexnet_pretrained.py       |   9 +-
 src/ptbench/models/config/densenet.py         |   7 +-
 .../models/config/densenet_pretrained.py      |   9 +-
 src/ptbench/models/config/densenet_rs.py      |   8 +-
 .../models/config/logistic_regression.py      |  25 +---
 src/ptbench/models/config/mlp.py              |  13 ++
 src/ptbench/models/config/pasa.py             |   2 +-
 src/ptbench/models/config/signs_to_tb.py      |  28 ----
 src/ptbench/models/logistic_regression.py     |  93 ++++++++-----
 src/ptbench/models/mlp.py                     | 130 ++++++++++++++++++
 src/ptbench/models/signs_to_tb.py             | 102 --------------
 src/ptbench/scripts/config.py                 |  40 ++----
 151 files changed, 1050 insertions(+), 548 deletions(-)
 create mode 100644 src/ptbench/models/config/mlp.py
 delete mode 100644 src/ptbench/models/config/signs_to_tb.py
 create mode 100644 src/ptbench/models/mlp.py
 delete mode 100644 src/ptbench/models/signs_to_tb.py

diff --git a/doc/links.rst b/doc/links.rst
index d773d1ae..2e454082 100644
--- a/doc/links.rst
+++ b/doc/links.rst
@@ -21,3 +21,10 @@
 .. _PadChest: https://bimcv.cipf.es/bimcv-projects/padchest/
 .. _TBX11K: https://mmcheng.net/tb/
 .. _TBX11K_simplified: https://www.kaggle.com/datasets/vbookshelf/tbx11k-simplified
+
+.. models
+.. _imagenet: https://www.image-net.org
+.. _alexnet: https://en.wikipedia.org/wiki/AlexNet
+.. _alexnet_pytorch: https://pytorch.org/hub/pytorch_vision_alexnet/
+.. _densenet: https://arxiv.org/abs/1608.06993
+.. _densenet_pytorch: https://pytorch.org/hub/pytorch_vision_densenet/
diff --git a/pyproject.toml b/pyproject.toml
index 67bd370c..f2de6fd4 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -71,7 +71,7 @@ ptbench = "ptbench.scripts.cli:cli"
 
 # models
 pasa = "ptbench.models.config.pasa"
-signs-to-tb = "ptbench.models.config.signs_to_tb"
+mlp = "ptbench.models.config.mlp"
 logistic-regression = "ptbench.models.config.logistic_regression"
 alexnet = "ptbench.models.config.alexnet"
 alexnet-pretrained = "ptbench.models.config.alexnet_pretrained"
diff --git a/src/ptbench/data/hivtb/datamodule.py b/src/ptbench/data/hivtb/datamodule.py
index 2f1dcb85..2c68c85d 100644
--- a/src/ptbench/data/hivtb/datamodule.py
+++ b/src/ptbench/data/hivtb/datamodule.py
@@ -1,6 +1,11 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""HIV-TB dataset for computer-aided diagnosis (only BMP files)
+
+Database reference: [HIV-TB-2019]_
+"""
+
 
 import importlib.resources
 import os
diff --git a/src/ptbench/data/hivtb/fold_0.py b/src/ptbench/data/hivtb/fold_0.py
index 6919907d..c8a11de1 100644
--- a/src/ptbench/data/hivtb/fold_0.py
+++ b/src/ptbench/data/hivtb/fold_0.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-0.json")
 """HIV-TB dataset for TB detection (cross validation fold 0).
 
+Database reference: [HIV-TB-2019]_
+
 See :py:class:`.hivtb.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-0.json")
diff --git a/src/ptbench/data/hivtb/fold_1.py b/src/ptbench/data/hivtb/fold_1.py
index 1f4b1dd0..3b2434e0 100644
--- a/src/ptbench/data/hivtb/fold_1.py
+++ b/src/ptbench/data/hivtb/fold_1.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-1.json")
 """HIV-TB dataset for TB detection (cross validation fold 1).
 
+Database reference: [HIV-TB-2019]_
+
 See :py:class:`.hivtb.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-1.json")
diff --git a/src/ptbench/data/hivtb/fold_2.py b/src/ptbench/data/hivtb/fold_2.py
index 9c9fbe65..ac95eca1 100644
--- a/src/ptbench/data/hivtb/fold_2.py
+++ b/src/ptbench/data/hivtb/fold_2.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-2.json")
 """HIV-TB dataset for TB detection (cross validation fold 2).
 
+Database reference: [HIV-TB-2019]_
+
 See :py:class:`.hivtb.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-2.json")
diff --git a/src/ptbench/data/hivtb/fold_3.py b/src/ptbench/data/hivtb/fold_3.py
index ef07c591..1d662e27 100644
--- a/src/ptbench/data/hivtb/fold_3.py
+++ b/src/ptbench/data/hivtb/fold_3.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-3.json")
 """HIV-TB dataset for TB detection (cross validation fold 3).
 
+Database reference: [HIV-TB-2019]_
+
 See :py:class:`.hivtb.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-3.json")
diff --git a/src/ptbench/data/hivtb/fold_4.py b/src/ptbench/data/hivtb/fold_4.py
index 6683006d..1f59dcf5 100644
--- a/src/ptbench/data/hivtb/fold_4.py
+++ b/src/ptbench/data/hivtb/fold_4.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-4.json")
 """HIV-TB dataset for TB detection (cross validation fold 4).
 
+Database reference: [HIV-TB-2019]_
+
 See :py:class:`.hivtb.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-4.json")
diff --git a/src/ptbench/data/hivtb/fold_5.py b/src/ptbench/data/hivtb/fold_5.py
index cf67833a..03170e28 100644
--- a/src/ptbench/data/hivtb/fold_5.py
+++ b/src/ptbench/data/hivtb/fold_5.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-5.json")
 """HIV-TB dataset for TB detection (cross validation fold 5).
 
+Database reference: [HIV-TB-2019]_
+
 See :py:class:`.hivtb.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-5.json")
diff --git a/src/ptbench/data/hivtb/fold_6.py b/src/ptbench/data/hivtb/fold_6.py
index 94614fc4..9950b0df 100644
--- a/src/ptbench/data/hivtb/fold_6.py
+++ b/src/ptbench/data/hivtb/fold_6.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-6.json")
 """HIV-TB dataset for TB detection (cross validation fold 6).
 
+Database reference: [HIV-TB-2019]_
+
 See :py:class:`.hivtb.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-6.json")
diff --git a/src/ptbench/data/hivtb/fold_7.py b/src/ptbench/data/hivtb/fold_7.py
index 259446c8..043ef9de 100644
--- a/src/ptbench/data/hivtb/fold_7.py
+++ b/src/ptbench/data/hivtb/fold_7.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-7.json")
 """HIV-TB dataset for TB detection (cross validation fold 7).
 
+Database reference: [HIV-TB-2019]_
+
 See :py:class:`.hivtb.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-7.json")
diff --git a/src/ptbench/data/hivtb/fold_8.py b/src/ptbench/data/hivtb/fold_8.py
index d243db08..9aa80c51 100644
--- a/src/ptbench/data/hivtb/fold_8.py
+++ b/src/ptbench/data/hivtb/fold_8.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-8.json")
 """HIV-TB dataset for TB detection (cross validation fold 8).
 
+Database reference: [HIV-TB-2019]_
+
 See :py:class:`.hivtb.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-8.json")
diff --git a/src/ptbench/data/hivtb/fold_9.py b/src/ptbench/data/hivtb/fold_9.py
index 340bc661..94a38a15 100644
--- a/src/ptbench/data/hivtb/fold_9.py
+++ b/src/ptbench/data/hivtb/fold_9.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-9.json")
 """HIV-TB dataset for TB detection (cross validation fold 9).
 
+Database reference: [HIV-TB-2019]_
+
 See :py:class:`.hivtb.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-9.json")
diff --git a/src/ptbench/data/indian/datamodule.py b/src/ptbench/data/indian/datamodule.py
index ee53da80..a17a0bef 100644
--- a/src/ptbench/data/indian/datamodule.py
+++ b/src/ptbench/data/indian/datamodule.py
@@ -1,6 +1,10 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Indian database for TB detection (a.k.a. Dataset A/Dataset B).
+
+Database reference: [INDIAN-2013]_
+"""
 
 import importlib.resources
 
@@ -19,13 +23,14 @@ def make_split(basename: str) -> DatabaseSplit:
 
 
 class DataModule(CachingDataModule):
-    """Indian collection dataset for computer-aided diagnosis.
+    """Indian database for TB detection (a.k.a. Dataset A/Dataset B).
 
     The Indian collection database has been established to foster research in
     computer-aided diagnosis of pulmonary diseases with a special focus on
     pulmonary tuberculosis (TB).  This database is also known as the "Database
     A/Database B" database.
 
+    * Database reference: [INDIAN-2013]_
     * Original images PNG, 8-bit grayscale, 1024 x 1024 pixels
     * Split reference: [INDIAN-2013]_ with 20% of train set for the validation set
 
diff --git a/src/ptbench/data/indian/default.py b/src/ptbench/data/indian/default.py
index 2b8a8fb2..cd5c98bf 100644
--- a/src/ptbench/data/indian/default.py
+++ b/src/ptbench/data/indian/default.py
@@ -1,6 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Indian database for TB detection (a.k.a. Dataset A/Dataset B).
+
+Database reference: [INDIAN-2013]_
+
+See :py:class:`.indian.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/indian/fold_0.py b/src/ptbench/data/indian/fold_0.py
index 635b542f..e316888d 100644
--- a/src/ptbench/data/indian/fold_0.py
+++ b/src/ptbench/data/indian/fold_0.py
@@ -1,12 +1,14 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-0.json")
 """Indian collection dataset for computer-aided diagnosis (cross validation
 fold 0).
 
+Database reference: [INDIAN-2013]_
+
 See :py:class:`.indian.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-0.json")
diff --git a/src/ptbench/data/indian/fold_1.py b/src/ptbench/data/indian/fold_1.py
index 5a3a0213..000a8410 100644
--- a/src/ptbench/data/indian/fold_1.py
+++ b/src/ptbench/data/indian/fold_1.py
@@ -1,12 +1,14 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-1.json")
 """Indian collection dataset for computer-aided diagnosis (cross validation
 fold 1).
 
+Database reference: [INDIAN-2013]_
+
 See :py:class:`.indian.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-1.json")
diff --git a/src/ptbench/data/indian/fold_2.py b/src/ptbench/data/indian/fold_2.py
index cbf1aee4..9f9152b3 100644
--- a/src/ptbench/data/indian/fold_2.py
+++ b/src/ptbench/data/indian/fold_2.py
@@ -1,12 +1,14 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-2.json")
 """Indian collection dataset for computer-aided diagnosis (cross validation
 fold 2).
 
+Database reference: [INDIAN-2013]_
+
 See :py:class:`.indian.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-2.json")
diff --git a/src/ptbench/data/indian/fold_3.py b/src/ptbench/data/indian/fold_3.py
index 369c9528..16475b98 100644
--- a/src/ptbench/data/indian/fold_3.py
+++ b/src/ptbench/data/indian/fold_3.py
@@ -1,12 +1,14 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-3.json")
 """Indian collection dataset for computer-aided diagnosis (cross validation
 fold 3).
 
+Database reference: [INDIAN-2013]_
+
 See :py:class:`.indian.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-3.json")
diff --git a/src/ptbench/data/indian/fold_4.py b/src/ptbench/data/indian/fold_4.py
index e9137b65..e2844b97 100644
--- a/src/ptbench/data/indian/fold_4.py
+++ b/src/ptbench/data/indian/fold_4.py
@@ -1,12 +1,14 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-4.json")
 """Indian collection dataset for computer-aided diagnosis (cross validation
 fold 4).
 
+Database reference: [INDIAN-2013]_
+
 See :py:class:`.indian.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-4.json")
diff --git a/src/ptbench/data/indian/fold_5.py b/src/ptbench/data/indian/fold_5.py
index d6f34d69..ef583528 100644
--- a/src/ptbench/data/indian/fold_5.py
+++ b/src/ptbench/data/indian/fold_5.py
@@ -1,12 +1,14 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-5.json")
 """Indian collection dataset for computer-aided diagnosis (cross validation
 fold 5).
 
+Database reference: [INDIAN-2013]_
+
 See :py:class:`.indian.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-5.json")
diff --git a/src/ptbench/data/indian/fold_6.py b/src/ptbench/data/indian/fold_6.py
index a293530d..59c168c5 100644
--- a/src/ptbench/data/indian/fold_6.py
+++ b/src/ptbench/data/indian/fold_6.py
@@ -1,12 +1,14 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-6.json")
 """Indian collection dataset for computer-aided diagnosis (cross validation
 fold 6).
 
+Database reference: [INDIAN-2013]_
+
 See :py:class:`.indian.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-6.json")
diff --git a/src/ptbench/data/indian/fold_7.py b/src/ptbench/data/indian/fold_7.py
index 22ea3439..9eda09ad 100644
--- a/src/ptbench/data/indian/fold_7.py
+++ b/src/ptbench/data/indian/fold_7.py
@@ -1,12 +1,14 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-7.json")
 """Indian collection dataset for computer-aided diagnosis (cross validation
 fold 7).
 
+Database reference: [INDIAN-2013]_
+
 See :py:class:`.indian.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-7.json")
diff --git a/src/ptbench/data/indian/fold_8.py b/src/ptbench/data/indian/fold_8.py
index 77cf20ee..abc54bac 100644
--- a/src/ptbench/data/indian/fold_8.py
+++ b/src/ptbench/data/indian/fold_8.py
@@ -1,12 +1,14 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-8.json")
 """Indian collection dataset for computer-aided diagnosis (cross validation
 fold 8).
 
+Database reference: [INDIAN-2013]_
+
 See :py:class:`.indian.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-8.json")
diff --git a/src/ptbench/data/indian/fold_9.py b/src/ptbench/data/indian/fold_9.py
index a0f881bc..cb4aa6be 100644
--- a/src/ptbench/data/indian/fold_9.py
+++ b/src/ptbench/data/indian/fold_9.py
@@ -1,12 +1,14 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-9.json")
 """Indian collection dataset for computer-aided diagnosis (cross validation
 fold 9).
 
+Database reference: [INDIAN-2013]_
+
 See :py:class:`.indian.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-9.json")
diff --git a/src/ptbench/data/montgomery/datamodule.py b/src/ptbench/data/montgomery/datamodule.py
index f3ac8ffc..b5ed48dd 100644
--- a/src/ptbench/data/montgomery/datamodule.py
+++ b/src/ptbench/data/montgomery/datamodule.py
@@ -1,6 +1,10 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Montgomery datamodule for TB detection.
+
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+"""
 
 import importlib.resources
 import os
diff --git a/src/ptbench/data/montgomery/default.py b/src/ptbench/data/montgomery/default.py
index 2b8a8fb2..ad32e45b 100644
--- a/src/ptbench/data/montgomery/default.py
+++ b/src/ptbench/data/montgomery/default.py
@@ -1,6 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Montgomery datamodule for TB detection.
+
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
+See :py:class:`.montgomery.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery/fold_0.py b/src/ptbench/data/montgomery/fold_0.py
index a271fa0f..7f842d59 100644
--- a/src/ptbench/data/montgomery/fold_0.py
+++ b/src/ptbench/data/montgomery/fold_0.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-0.json")
 """Montgomery datamodule for TB detection (cross validation fold 0).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.montgomery.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-0.json")
diff --git a/src/ptbench/data/montgomery/fold_1.py b/src/ptbench/data/montgomery/fold_1.py
index 626cf2d0..abdfbcf1 100644
--- a/src/ptbench/data/montgomery/fold_1.py
+++ b/src/ptbench/data/montgomery/fold_1.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-1.json")
 """Montgomery datamodule for TB detection (cross validation fold 1).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.montgomery.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-1.json")
diff --git a/src/ptbench/data/montgomery/fold_2.py b/src/ptbench/data/montgomery/fold_2.py
index b6146d06..8614cc00 100644
--- a/src/ptbench/data/montgomery/fold_2.py
+++ b/src/ptbench/data/montgomery/fold_2.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-2.json")
 """Montgomery datamodule for TB detection (cross validation fold 2).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.montgomery.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-2.json")
diff --git a/src/ptbench/data/montgomery/fold_3.py b/src/ptbench/data/montgomery/fold_3.py
index f1b1c53e..50ac23f5 100644
--- a/src/ptbench/data/montgomery/fold_3.py
+++ b/src/ptbench/data/montgomery/fold_3.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-3.json")
 """Montgomery datamodule for TB detection (cross validation fold 3).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.montgomery.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-3.json")
diff --git a/src/ptbench/data/montgomery/fold_4.py b/src/ptbench/data/montgomery/fold_4.py
index eaa5fd27..c83e1060 100644
--- a/src/ptbench/data/montgomery/fold_4.py
+++ b/src/ptbench/data/montgomery/fold_4.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-4.json")
 """Montgomery datamodule for TB detection (cross validation fold 4).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.montgomery.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-4.json")
diff --git a/src/ptbench/data/montgomery/fold_5.py b/src/ptbench/data/montgomery/fold_5.py
index 142ae715..30b97b03 100644
--- a/src/ptbench/data/montgomery/fold_5.py
+++ b/src/ptbench/data/montgomery/fold_5.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-5.json")
 """Montgomery datamodule for TB detection (cross validation fold 5).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.montgomery.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-5.json")
diff --git a/src/ptbench/data/montgomery/fold_6.py b/src/ptbench/data/montgomery/fold_6.py
index 715d9b84..86e35ca5 100644
--- a/src/ptbench/data/montgomery/fold_6.py
+++ b/src/ptbench/data/montgomery/fold_6.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-6.json")
 """Montgomery datamodule for TB detection (cross validation fold 6).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.montgomery.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-6.json")
diff --git a/src/ptbench/data/montgomery/fold_7.py b/src/ptbench/data/montgomery/fold_7.py
index fc53e24e..9f0bd3da 100644
--- a/src/ptbench/data/montgomery/fold_7.py
+++ b/src/ptbench/data/montgomery/fold_7.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-7.json")
 """Montgomery datamodule for TB detection (cross validation fold 7).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.montgomery.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-7.json")
diff --git a/src/ptbench/data/montgomery/fold_8.py b/src/ptbench/data/montgomery/fold_8.py
index 2b917a6b..5ea2dfc9 100644
--- a/src/ptbench/data/montgomery/fold_8.py
+++ b/src/ptbench/data/montgomery/fold_8.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-8.json")
 """Montgomery datamodule for TB detection (cross validation fold 8).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.montgomery.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-8.json")
diff --git a/src/ptbench/data/montgomery/fold_9.py b/src/ptbench/data/montgomery/fold_9.py
index f404ace1..41025b73 100644
--- a/src/ptbench/data/montgomery/fold_9.py
+++ b/src/ptbench/data/montgomery/fold_9.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-9.json")
 """Montgomery datamodule for TB detection (cross validation fold 9).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.montgomery.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-9.json")
diff --git a/src/ptbench/data/montgomery_shenzhen/default.py b/src/ptbench/data/montgomery_shenzhen/default.py
index c332f4be..5a9208f4 100644
--- a/src/ptbench/data/montgomery_shenzhen/default.py
+++ b/src/ptbench/data/montgomery_shenzhen/default.py
@@ -1,12 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("default.json")
 """Aggregated datamodule composed of Montgomery and Shenzhen datasets (default
 split).
 
 See :py:class:`.montgomery_shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("default.json")
diff --git a/src/ptbench/data/montgomery_shenzhen/fold_0.py b/src/ptbench/data/montgomery_shenzhen/fold_0.py
index f3e8ef02..722876a6 100644
--- a/src/ptbench/data/montgomery_shenzhen/fold_0.py
+++ b/src/ptbench/data/montgomery_shenzhen/fold_0.py
@@ -1,12 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-0.json")
 """Aggregated datamodule composed of Montgomery and Shenzhen datasets (cross
 validation fold 0).
 
 See :py:class:`.montgomery_shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-0.json")
diff --git a/src/ptbench/data/montgomery_shenzhen/fold_1.py b/src/ptbench/data/montgomery_shenzhen/fold_1.py
index f6d73de3..81ee4224 100644
--- a/src/ptbench/data/montgomery_shenzhen/fold_1.py
+++ b/src/ptbench/data/montgomery_shenzhen/fold_1.py
@@ -1,12 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-1.json")
 """Aggregated datamodule composed of Montgomery and Shenzhen datasets (cross
 validation fold 1).
 
 See :py:class:`.montgomery_shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-1.json")
diff --git a/src/ptbench/data/montgomery_shenzhen/fold_2.py b/src/ptbench/data/montgomery_shenzhen/fold_2.py
index 9b956052..afd77ed3 100644
--- a/src/ptbench/data/montgomery_shenzhen/fold_2.py
+++ b/src/ptbench/data/montgomery_shenzhen/fold_2.py
@@ -1,12 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-2.json")
 """Aggregated datamodule composed of Montgomery and Shenzhen datasets (cross
 validation fold 2).
 
 See :py:class:`.montgomery_shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-2.json")
diff --git a/src/ptbench/data/montgomery_shenzhen/fold_3.py b/src/ptbench/data/montgomery_shenzhen/fold_3.py
index 826e0abb..cc1e48a5 100644
--- a/src/ptbench/data/montgomery_shenzhen/fold_3.py
+++ b/src/ptbench/data/montgomery_shenzhen/fold_3.py
@@ -1,12 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-3.json")
 """Aggregated datamodule composed of Montgomery and Shenzhen datasets (cross
 validation fold 3).
 
 See :py:class:`.montgomery_shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-3.json")
diff --git a/src/ptbench/data/montgomery_shenzhen/fold_4.py b/src/ptbench/data/montgomery_shenzhen/fold_4.py
index f7261a43..b20ba0e3 100644
--- a/src/ptbench/data/montgomery_shenzhen/fold_4.py
+++ b/src/ptbench/data/montgomery_shenzhen/fold_4.py
@@ -1,12 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-4.json")
 """Aggregated datamodule composed of Montgomery and Shenzhen datasets (cross
 validation fold 4).
 
 See :py:class:`.montgomery_shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-4.json")
diff --git a/src/ptbench/data/montgomery_shenzhen/fold_5.py b/src/ptbench/data/montgomery_shenzhen/fold_5.py
index 7dfb6f90..a521e26f 100644
--- a/src/ptbench/data/montgomery_shenzhen/fold_5.py
+++ b/src/ptbench/data/montgomery_shenzhen/fold_5.py
@@ -1,12 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-5.json")
 """Aggregated datamodule composed of Montgomery and Shenzhen datasets (cross
 validation fold 5).
 
 See :py:class:`.montgomery_shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-5.json")
diff --git a/src/ptbench/data/montgomery_shenzhen/fold_6.py b/src/ptbench/data/montgomery_shenzhen/fold_6.py
index 57f19130..44454a52 100644
--- a/src/ptbench/data/montgomery_shenzhen/fold_6.py
+++ b/src/ptbench/data/montgomery_shenzhen/fold_6.py
@@ -1,12 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-6.json")
 """Aggregated datamodule composed of Montgomery and Shenzhen datasets (cross
 validation fold 6).
 
 See :py:class:`.montgomery_shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-6.json")
diff --git a/src/ptbench/data/montgomery_shenzhen/fold_7.py b/src/ptbench/data/montgomery_shenzhen/fold_7.py
index 3fc7c8bf..95128328 100644
--- a/src/ptbench/data/montgomery_shenzhen/fold_7.py
+++ b/src/ptbench/data/montgomery_shenzhen/fold_7.py
@@ -1,12 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-7.json")
 """Aggregated datamodule composed of Montgomery and Shenzhen datasets (cross
 validation fold 7).
 
 See :py:class:`.montgomery_shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-7.json")
diff --git a/src/ptbench/data/montgomery_shenzhen/fold_8.py b/src/ptbench/data/montgomery_shenzhen/fold_8.py
index 7b631543..220ce854 100644
--- a/src/ptbench/data/montgomery_shenzhen/fold_8.py
+++ b/src/ptbench/data/montgomery_shenzhen/fold_8.py
@@ -1,12 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-8.json")
 """Aggregated datamodule composed of Montgomery and Shenzhen datasets (cross
 validation fold 8).
 
 See :py:class:`.montgomery_shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-8.json")
diff --git a/src/ptbench/data/montgomery_shenzhen/fold_9.py b/src/ptbench/data/montgomery_shenzhen/fold_9.py
index 565b71e7..01fc7503 100644
--- a/src/ptbench/data/montgomery_shenzhen/fold_9.py
+++ b/src/ptbench/data/montgomery_shenzhen/fold_9.py
@@ -1,12 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-9.json")
 """Aggregated datamodule composed of Montgomery and Shenzhen datasets (cross
 validation fold 9).
 
 See :py:class:`.montgomery_shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-9.json")
diff --git a/src/ptbench/data/montgomery_shenzhen_indian/datamodule.py b/src/ptbench/data/montgomery_shenzhen_indian/datamodule.py
index 3c555a62..6df9a850 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian/datamodule.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian/datamodule.py
@@ -1,6 +1,8 @@
 # Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen and Indian
+datasets."""
 
 from ..datamodule import ConcatDataModule
 from ..indian.datamodule import RawDataLoader as IndianLoader
diff --git a/src/ptbench/data/montgomery_shenzhen_indian/default.py b/src/ptbench/data/montgomery_shenzhen_indian/default.py
index e4a05f63..691885b1 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian/default.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian/default.py
@@ -1,12 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("default.json")
 """Aggregated datamodule composed of Montgomery, Shenzhen and Indian datasets.
 
 See :py:class:`.montgomery_shenzhen_indian.datamodule.DataModule` for technical
 details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("default.json")
diff --git a/src/ptbench/data/montgomery_shenzhen_indian/fold_0.py b/src/ptbench/data/montgomery_shenzhen_indian/fold_0.py
index 6f08e25a..d9df2f75 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian/fold_0.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian/fold_0.py
@@ -1,13 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-0.json")
 """Aggregated datamodule composed of Montgomery, Shenzhen and Indian datasets
 (cross validation fold 0).
 
 See :py:class:`.montgomery_shenzhen_indian.datamodule.DataModule` for technical
 details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-0.json")
diff --git a/src/ptbench/data/montgomery_shenzhen_indian/fold_1.py b/src/ptbench/data/montgomery_shenzhen_indian/fold_1.py
index 3d7529cf..e95a72bd 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian/fold_1.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian/fold_1.py
@@ -1,12 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-1.json")
 """Aggregated datamodule composed of Montgomery, Shenzhen and Indian datasets
 (cross validation fold 1).
 
 See :py:class:`.montgomery_shenzhen_indian.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-1.json")
diff --git a/src/ptbench/data/montgomery_shenzhen_indian/fold_2.py b/src/ptbench/data/montgomery_shenzhen_indian/fold_2.py
index 2e914281..1532a9fb 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian/fold_2.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian/fold_2.py
@@ -1,13 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-2.json")
 """Aggregated datamodule composed of Montgomery, Shenzhen and Indian datasets
 (cross validation fold 2).
 
 See :py:class:`.montgomery_shenzhen_indian.datamodule.DataModule` for technical
 details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-2.json")
diff --git a/src/ptbench/data/montgomery_shenzhen_indian/fold_3.py b/src/ptbench/data/montgomery_shenzhen_indian/fold_3.py
index dfd4c9cd..21605168 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian/fold_3.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian/fold_3.py
@@ -1,13 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-3.json")
 """Aggregated datamodule composed of Montgomery, Shenzhen and Indian datasets
 (cross validation fold 3).
 
 See :py:class:`.montgomery_shenzhen_indian.datamodule.DataModule` for technical
 details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-3.json")
diff --git a/src/ptbench/data/montgomery_shenzhen_indian/fold_4.py b/src/ptbench/data/montgomery_shenzhen_indian/fold_4.py
index 84e66cef..287afbdd 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian/fold_4.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian/fold_4.py
@@ -1,13 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-4.json")
 """Aggregated datamodule composed of Montgomery, Shenzhen and Indian datasets
 (cross validation fold 4).
 
 See :py:class:`.montgomery_shenzhen_indian.datamodule.DataModule` for technical
 details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-4.json")
diff --git a/src/ptbench/data/montgomery_shenzhen_indian/fold_5.py b/src/ptbench/data/montgomery_shenzhen_indian/fold_5.py
index 650292f7..52fd19d2 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian/fold_5.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian/fold_5.py
@@ -1,13 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-5.json")
 """Aggregated datamodule composed of Montgomery, Shenzhen and Indian datasets
 (cross validation fold 5).
 
 See :py:class:`.montgomery_shenzhen_indian.datamodule.DataModule` for technical
 details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-5.json")
diff --git a/src/ptbench/data/montgomery_shenzhen_indian/fold_6.py b/src/ptbench/data/montgomery_shenzhen_indian/fold_6.py
index 8f673689..7232f1c3 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian/fold_6.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian/fold_6.py
@@ -1,13 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-6.json")
 """Aggregated datamodule composed of Montgomery, Shenzhen and Indian datasets
 (cross validation fold 6).
 
 See :py:class:`.montgomery_shenzhen_indian.datamodule.DataModule` for technical
 details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-6.json")
diff --git a/src/ptbench/data/montgomery_shenzhen_indian/fold_7.py b/src/ptbench/data/montgomery_shenzhen_indian/fold_7.py
index 33eed540..16ba67fe 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian/fold_7.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian/fold_7.py
@@ -1,12 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-7.json")
 """Aggregated datamodule composed of Montgomery, Shenzhen and Indian datasets
 (cross validation fold 7).
 
 See :py:class:`.montgomery_shenzhen_indian.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-7.json")
diff --git a/src/ptbench/data/montgomery_shenzhen_indian/fold_8.py b/src/ptbench/data/montgomery_shenzhen_indian/fold_8.py
index 4de80f69..f6d0788e 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian/fold_8.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian/fold_8.py
@@ -1,13 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-8.json")
 """Aggregated datamodule composed of Montgomery, Shenzhen and Indian datasets
 (cross validation fold 8).
 
 See :py:class:`.montgomery_shenzhen_indian.datamodule.DataModule` for technical
 details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-8.json")
diff --git a/src/ptbench/data/montgomery_shenzhen_indian/fold_9.py b/src/ptbench/data/montgomery_shenzhen_indian/fold_9.py
index f33e691b..b4d9073c 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian/fold_9.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian/fold_9.py
@@ -1,12 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-9.json")
 """Aggregated datamodule composed of Montgomery, Shenzhen and Indian datasets
 (cross validation fold 9).
 
 See :py:class:`.montgomery_shenzhen_indian.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-9.json")
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_padchest/datamodule.py b/src/ptbench/data/montgomery_shenzhen_indian_padchest/datamodule.py
index 9f6a3b09..b4317ac4 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_padchest/datamodule.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_padchest/datamodule.py
@@ -1,6 +1,8 @@
 # Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and PadChest
+datasets."""
 
 from ..datamodule import ConcatDataModule
 from ..indian.datamodule import RawDataLoader as IndianLoader
@@ -14,7 +16,8 @@ from ..shenzhen.datamodule import make_split as make_shenzhen_split
 
 
 class DataModule(ConcatDataModule):
-    """Aggregated datamodule composed of Montgomery and Shenzhen datasets."""
+    """Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and
+    PadChest datasets."""
 
     def __init__(self, split_filename: str, padchest_split_filename: str):
         montgomery_loader = MontgomeryLoader()
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_padchest/default.py b/src/ptbench/data/montgomery_shenzhen_indian_padchest/default.py
index 5368466a..bc5ca3d8 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_padchest/default.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_padchest/default.py
@@ -1,9 +1,9 @@
 # Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated dataset composed of Montgomery, Shenzhen, Indian and Padchest
+datasets."""
 
 from .datamodule import DataModule
 
 datamodule = DataModule("default.json", "tb-idiap.json")
-"""Aggregated dataset composed of Montgomery, Shenzhen, Indian and Padchest
-datasets."""
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/datamodule.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/datamodule.py
index 02599187..6f7ee8bc 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/datamodule.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/datamodule.py
@@ -1,6 +1,8 @@
 # Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets."""
 
 from ..datamodule import ConcatDataModule
 from ..indian.datamodule import RawDataLoader as IndianLoader
@@ -14,7 +16,8 @@ from ..tbx11k.datamodule import make_split as make_tbx11k_split
 
 
 class DataModule(ConcatDataModule):
-    """Aggregated datamodule composed of Montgomery and Shenzhen datasets."""
+    """Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and
+    TBX11k datasets."""
 
     def __init__(self, split_filename: str, tbx11_split_filename: str):
         montgomery_loader = MontgomeryLoader()
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_0.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_0.py
index 42620697..47e8c4ba 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_0.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_0.py
@@ -1,6 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 0).
+
+This remix dataset combines ``fold-0`` from Montgomery, Shenzhen, and Indian
+datasets with ``v1-fold-0`` of TBX11k (healthy vs. active TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_1.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_1.py
index c7f11aad..4bfa7652 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_1.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_1.py
@@ -1,6 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 1).
+
+This remix dataset combines ``fold-1`` from Montgomery, Shenzhen, and Indian
+datasets with ``v1-fold-1`` of TBX11k (healthy vs. active TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_2.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_2.py
index 8c94b1e9..2dbbb18e 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_2.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_2.py
@@ -1,6 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 2).
+
+This remix dataset combines ``fold-2`` from Montgomery, Shenzhen, and Indian
+datasets with ``v1-fold-2`` of TBX11k (healthy vs. active TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_3.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_3.py
index c90704d1..5f808c6a 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_3.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_3.py
@@ -1,6 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 3).
+
+This remix dataset combines ``fold-3`` from Montgomery, Shenzhen, and Indian
+datasets with ``v1-fold-3`` of TBX11k (healthy vs. active TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_4.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_4.py
index 5d243746..dc9ff8d6 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_4.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_4.py
@@ -1,6 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 4).
+
+This remix dataset combines ``fold-4`` from Montgomery, Shenzhen, and Indian
+datasets with ``v1-fold-4`` of TBX11k (healthy vs. active TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_5.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_5.py
index 65aa7840..137b3c82 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_5.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_5.py
@@ -1,6 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 5).
+
+This remix dataset combines ``fold-5`` from Montgomery, Shenzhen, and Indian
+datasets with ``v1-fold-5`` of TBX11k (healthy vs. active TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_6.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_6.py
index bc175ac2..50641ffa 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_6.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_6.py
@@ -1,6 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 6).
+
+This remix dataset combines ``fold-6`` from Montgomery, Shenzhen, and Indian
+datasets with ``v1-fold-6`` of TBX11k (healthy vs. active TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_7.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_7.py
index 3b7d7f71..54f9eaa2 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_7.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_7.py
@@ -1,6 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 7).
+
+This remix dataset combines ``fold-7`` from Montgomery, Shenzhen, and Indian
+datasets with ``v1-fold-7`` of TBX11k (healthy vs. active TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_8.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_8.py
index 20ac8e5c..dbccf38c 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_8.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_8.py
@@ -1,6 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 8).
+
+This remix dataset combines ``fold-8`` from Montgomery, Shenzhen, and Indian
+datasets with ``v1-fold-8`` of TBX11k (healthy vs. active TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_9.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_9.py
index 413f141d..cd1b5a71 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_9.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_fold_9.py
@@ -1,6 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 9).
+
+This remix dataset combines ``fold-9`` from Montgomery, Shenzhen, and Indian
+datasets with ``v1-fold-9`` of TBX11k (healthy vs. active TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_healthy_vs_atb.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_healthy_vs_atb.py
index 2f5e2226..4c75b15e 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_healthy_vs_atb.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v1_healthy_vs_atb.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (v1-healthy-vs-atb).
+
+This remix dataset combines the ``default`` split from Montgomery, Shenzhen,
+and Indian datasets with ``v1-healthy-vs-atb`` split of TBX11k (healthy vs.
+active TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_0.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_0.py
index 045b9372..6add82d0 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_0.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_0.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 0).
+
+This remix dataset combines ``fold-0`` from Montgomery, Shenzhen, and Indian
+datasets with ``v2-fold-0`` of TBX11k (healthy, sick and latent TB vs. active
+TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_1.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_1.py
index 10de943e..09ada33a 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_1.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_1.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 1).
+
+This remix dataset combines ``fold-1`` from Montgomery, Shenzhen, and Indian
+datasets with ``v2-fold-1`` of TBX11k (healthy, sick and latent TB vs. active
+TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_2.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_2.py
index 12062ae6..756fd9a3 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_2.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_2.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 2).
+
+This remix dataset combines ``fold-2`` from Montgomery, Shenzhen, and Indian
+datasets with ``v2-fold-2`` of TBX11k (healthy, sick and latent TB vs. active
+TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_3.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_3.py
index 453c2b8c..8b72d4f3 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_3.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_3.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 3).
+
+This remix dataset combines ``fold-3`` from Montgomery, Shenzhen, and Indian
+datasets with ``v2-fold-3`` of TBX11k (healthy, sick and latent TB vs. active
+TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_4.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_4.py
index d31da770..4cb6ece8 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_4.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_4.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 4).
+
+This remix dataset combines ``fold-4`` from Montgomery, Shenzhen, and Indian
+datasets with ``v2-fold-4`` of TBX11k (healthy, sick and latent TB vs. active
+TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_5.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_5.py
index 1c50c2e7..c6b8f89e 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_5.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_5.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 5).
+
+This remix dataset combines ``fold-5`` from Montgomery, Shenzhen, and Indian
+datasets with ``v2-fold-5`` of TBX11k (healthy, sick and latent TB vs. active
+TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_6.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_6.py
index 0f15a0fa..2c093671 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_6.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_6.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 6).
+
+This remix dataset combines ``fold-6`` from Montgomery, Shenzhen, and Indian
+datasets with ``v2-fold-6`` of TBX11k (healthy, sick and latent TB vs. active
+TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_7.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_7.py
index 10829456..0a7c37bc 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_7.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_7.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 7).
+
+This remix dataset combines ``fold-7`` from Montgomery, Shenzhen, and Indian
+datasets with ``v2-fold-7`` of TBX11k (healthy, sick and latent TB vs. active
+TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_8.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_8.py
index a90e1111..5cc64e15 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_8.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_8.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 8).
+
+This remix dataset combines ``fold-8`` from Montgomery, Shenzhen, and Indian
+datasets with ``v2-fold-8`` of TBX11k (healthy, sick and latent TB vs. active
+TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_9.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_9.py
index a6cb7d51..b8998a23 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_9.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_fold_9.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (cross-validation fold 9).
+
+This remix dataset combines ``fold-9`` from Montgomery, Shenzhen, and Indian
+datasets with ``v2-fold-9`` of TBX11k (healthy, sick and latent TB vs. active
+TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_others_vs_atb.py b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_others_vs_atb.py
index bef1efce..ccbac352 100644
--- a/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_others_vs_atb.py
+++ b/src/ptbench/data/montgomery_shenzhen_indian_tbx11k/v2_others_vs_atb.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated datamodule composed of Montgomery, Shenzhen, Indian, and TBX11k
+datasets (v2-others-vs-atb).
+
+This remix dataset combines the ``default`` split from Montgomery, Shenzhen,
+and Indian datasets with ``v2-others-vs-atb`` of TBX11k (healthy, sick and
+latent TB vs. active TB samples).
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/nih_cxr14/cardiomegaly.py b/src/ptbench/data/nih_cxr14/cardiomegaly.py
index 0715650d..7b104faa 100644
--- a/src/ptbench/data/nih_cxr14/cardiomegaly.py
+++ b/src/ptbench/data/nih_cxr14/cardiomegaly.py
@@ -1,6 +1,15 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""NIH CXR14 (relabeled) datamodule for computer-aided diagnosis (cardiomegaly
+split).
+
+Database reference: [NIH-CXR14-2017]_
+
+This split contains cardiomegaly cases from the NIH CXR14 database.
+
+See :py:class:`.nih_cxr14.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/nih_cxr14/datamodule.py b/src/ptbench/data/nih_cxr14/datamodule.py
index 58c828b4..996c9feb 100644
--- a/src/ptbench/data/nih_cxr14/datamodule.py
+++ b/src/ptbench/data/nih_cxr14/datamodule.py
@@ -1,6 +1,10 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""NIH CXR14 (relabeled) datamodule for computer-aided diagnosis.
+
+Database reference: [NIH-CXR14-2017]_
+"""
 
 import importlib.resources
 import os
diff --git a/src/ptbench/data/nih_cxr14/default.py b/src/ptbench/data/nih_cxr14/default.py
index af4f2172..c7bc3e2e 100644
--- a/src/ptbench/data/nih_cxr14/default.py
+++ b/src/ptbench/data/nih_cxr14/default.py
@@ -1,10 +1,6 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("default.json.bz2")
 """NIH CXR14 (relabeled) datamodule (``default`` protocol).
 
 * Training samples: 98637
@@ -13,3 +9,7 @@ datamodule = DataModule("default.json.bz2")
 
 See :py:class:`.nih_cxr14.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("default.json.bz2")
diff --git a/src/ptbench/data/nih_cxr14_padchest/idiap.py b/src/ptbench/data/nih_cxr14_padchest/idiap.py
index 45754ea6..f318b4f7 100644
--- a/src/ptbench/data/nih_cxr14_padchest/idiap.py
+++ b/src/ptbench/data/nih_cxr14_padchest/idiap.py
@@ -1,6 +1,8 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Aggregated dataset composed of NIH CXR14 relabeld and PadChest (normalized)
+datasets (no-tb-idiap split)."""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/padchest/cardiomegaly_idiap.py b/src/ptbench/data/padchest/cardiomegaly_idiap.py
index c2f0113f..bd832fdd 100644
--- a/src/ptbench/data/padchest/cardiomegaly_idiap.py
+++ b/src/ptbench/data/padchest/cardiomegaly_idiap.py
@@ -1,14 +1,16 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("cardiomegaly-idiap.json")
 """Padchest cardiomegaly (idiap protocol) dataset for computer-aided diagnosis.
 
+Database reference: [PADCHEST-2019]_
+
 This split contains the first 40 images with cardiomegaly, with parameters:
 Label = "Normal", MethodLabel = "Physician", Projection = "PA"
 
 Read documentation of :py:class:`DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("cardiomegaly-idiap.json")
diff --git a/src/ptbench/data/padchest/datamodule.py b/src/ptbench/data/padchest/datamodule.py
index 69a37ea8..1fc49485 100644
--- a/src/ptbench/data/padchest/datamodule.py
+++ b/src/ptbench/data/padchest/datamodule.py
@@ -1,6 +1,10 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Padchest dataset for computer-aided diagnosis.
+
+Database reference: [PADCHEST-2019]_
+"""
 
 import importlib.resources
 import os
diff --git a/src/ptbench/data/padchest/idiap.py b/src/ptbench/data/padchest/idiap.py
index 52c52123..bf1f9356 100644
--- a/src/ptbench/data/padchest/idiap.py
+++ b/src/ptbench/data/padchest/idiap.py
@@ -1,12 +1,10 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("idiap.json.bz2")
 """Padchest dataset for computer-aided diagnosis (``idiap`` split).
 
+Database reference: [PADCHEST-2019]_
+
 This split contains all images in the database.  Read documentation of
 :py:class:`.padchest.datamodule.DataModule` for technical details.
 
@@ -15,3 +13,7 @@ This split contains all images in the database.  Read documentation of
   * Validation samples: ?
   * Test samples: ?
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("idiap.json.bz2")
diff --git a/src/ptbench/data/padchest/no_tb_idiap.py b/src/ptbench/data/padchest/no_tb_idiap.py
index 68f3e83b..ca787520 100644
--- a/src/ptbench/data/padchest/no_tb_idiap.py
+++ b/src/ptbench/data/padchest/no_tb_idiap.py
@@ -1,12 +1,11 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("no-tb-idiap.json.bz2")
 """Padchest dataset for computer-aided diagnosis (``no-tb-idiap`` split).
 
+Database reference: [PADCHEST-2019]_
+
+* Split:
   * Training samples: 20'126
   * Validation samples: 1'500
   * Test samples: 0
@@ -29,5 +28,10 @@ datamodule = DataModule("no-tb-idiap.json.bz2")
   * fibrosis
   * edema and consolidation
 
-Read documentation of :py:class:`DataModule` for technical details.
+Read documentation of :py:class:`.padchest.datamodule.DataModule` for technical
+details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("no-tb-idiap.json.bz2")
diff --git a/src/ptbench/data/padchest/tb_idiap.py b/src/ptbench/data/padchest/tb_idiap.py
index ddfa889f..d77e5afd 100644
--- a/src/ptbench/data/padchest/tb_idiap.py
+++ b/src/ptbench/data/padchest/tb_idiap.py
@@ -1,16 +1,19 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("tb-idiap.json")
 """Padchest dataset for computer-aided diagnosis (``tb-idiap`` split).
 
+Database reference: [PADCHEST-2019]_
+
 This split contains 125 healthy images are the first 125 padchest images with
 the following parameters: Label = "Normal", MethodLabel = "Physician",
 Projection = "PA" and TB cases.  Labelling matches those for active TB (binary)
 classification datasets.
 
-Read documentation of :py:class:`DataModule` for technical details.
+Read documentation of :py:class:`.padchest.datamodule.DataModule` for technical
+details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("tb-idiap.json")
diff --git a/src/ptbench/data/shenzhen/datamodule.py b/src/ptbench/data/shenzhen/datamodule.py
index 221bc869..af5a4074 100644
--- a/src/ptbench/data/shenzhen/datamodule.py
+++ b/src/ptbench/data/shenzhen/datamodule.py
@@ -1,6 +1,10 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""Shenzhen datamodule for computer-aided diagnosis.
+
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+"""
 
 import importlib.resources
 import os
diff --git a/src/ptbench/data/shenzhen/default.py b/src/ptbench/data/shenzhen/default.py
index 0a73847a..b8cf7172 100644
--- a/src/ptbench/data/shenzhen/default.py
+++ b/src/ptbench/data/shenzhen/default.py
@@ -1,15 +1,17 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("default.json")
 """Default Shenzhen TB database split.
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 * Training samples: 64% of TB and healthy CXR (including labels)
 * Validation samples: 16% of TB and healthy CXR (including labels)
 * Test samples: 20% of TB and healthy CXR (including labels)
 
 See :py:class:`.shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("default.json")
diff --git a/src/ptbench/data/shenzhen/fold_0.py b/src/ptbench/data/shenzhen/fold_0.py
index dc895f78..df1359ae 100644
--- a/src/ptbench/data/shenzhen/fold_0.py
+++ b/src/ptbench/data/shenzhen/fold_0.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-0.json")
 """Shenzhen datamodule for computer-aided diagnosis (cross validation fold 0).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-0.json")
diff --git a/src/ptbench/data/shenzhen/fold_1.py b/src/ptbench/data/shenzhen/fold_1.py
index ce062462..03be3fa6 100644
--- a/src/ptbench/data/shenzhen/fold_1.py
+++ b/src/ptbench/data/shenzhen/fold_1.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-1.json")
 """Shenzhen datamodule for computer-aided diagnosis (cross validation fold 1).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-1.json")
diff --git a/src/ptbench/data/shenzhen/fold_2.py b/src/ptbench/data/shenzhen/fold_2.py
index 3f061c37..f4bd72d8 100644
--- a/src/ptbench/data/shenzhen/fold_2.py
+++ b/src/ptbench/data/shenzhen/fold_2.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-2.json")
 """Shenzhen datamodule for computer-aided diagnosis (cross validation fold 2).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-2.json")
diff --git a/src/ptbench/data/shenzhen/fold_3.py b/src/ptbench/data/shenzhen/fold_3.py
index e3bb067e..b41c7886 100644
--- a/src/ptbench/data/shenzhen/fold_3.py
+++ b/src/ptbench/data/shenzhen/fold_3.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-3.json")
 """Shenzhen datamodule for computer-aided diagnosis (cross validation fold 3).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-3.json")
diff --git a/src/ptbench/data/shenzhen/fold_4.py b/src/ptbench/data/shenzhen/fold_4.py
index f0cb843b..f9105989 100644
--- a/src/ptbench/data/shenzhen/fold_4.py
+++ b/src/ptbench/data/shenzhen/fold_4.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-4.json")
 """Shenzhen datamodule for computer-aided diagnosis (cross validation fold 4).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-4.json")
diff --git a/src/ptbench/data/shenzhen/fold_5.py b/src/ptbench/data/shenzhen/fold_5.py
index 6a27ac51..7882e899 100644
--- a/src/ptbench/data/shenzhen/fold_5.py
+++ b/src/ptbench/data/shenzhen/fold_5.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-5.json")
 """Shenzhen datamodule for computer-aided diagnosis (cross validation fold 5).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-5.json")
diff --git a/src/ptbench/data/shenzhen/fold_6.py b/src/ptbench/data/shenzhen/fold_6.py
index 302d2b8d..4d11aca0 100644
--- a/src/ptbench/data/shenzhen/fold_6.py
+++ b/src/ptbench/data/shenzhen/fold_6.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-6.json")
 """Shenzhen datamodule for computer-aided diagnosis (cross validation fold 6).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-6.json")
diff --git a/src/ptbench/data/shenzhen/fold_7.py b/src/ptbench/data/shenzhen/fold_7.py
index a07f4d29..8a794345 100644
--- a/src/ptbench/data/shenzhen/fold_7.py
+++ b/src/ptbench/data/shenzhen/fold_7.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-7.json")
 """Shenzhen datamodule for computer-aided diagnosis (cross validation fold 7).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-7.json")
diff --git a/src/ptbench/data/shenzhen/fold_8.py b/src/ptbench/data/shenzhen/fold_8.py
index 0c5e6d22..9abe5fa4 100644
--- a/src/ptbench/data/shenzhen/fold_8.py
+++ b/src/ptbench/data/shenzhen/fold_8.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-8.json")
 """Shenzhen datamodule for computer-aided diagnosis (cross validation fold 8).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-8.json")
diff --git a/src/ptbench/data/shenzhen/fold_9.py b/src/ptbench/data/shenzhen/fold_9.py
index bb73ea16..06fab974 100644
--- a/src/ptbench/data/shenzhen/fold_9.py
+++ b/src/ptbench/data/shenzhen/fold_9.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-9.json")
 """Shenzhen datamodule for computer-aided diagnosis (cross validation fold 9).
 
+Database reference: [MONTGOMERY-SHENZHEN-2014]_
+
 See :py:class:`.shenzhen.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-9.json")
diff --git a/src/ptbench/data/tbpoc/fold_0.py b/src/ptbench/data/tbpoc/fold_0.py
index 2beb07fd..5c452504 100644
--- a/src/ptbench/data/tbpoc/fold_0.py
+++ b/src/ptbench/data/tbpoc/fold_0.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-0.json")
 """TB-POC dataset for TB detection (cross validation fold 0).
 
+Database reference: [TB-POC-2018]_
+
 See :py:class:`.tbpoc.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-0.json")
diff --git a/src/ptbench/data/tbpoc/fold_1.py b/src/ptbench/data/tbpoc/fold_1.py
index 338d99b2..a2fe6083 100644
--- a/src/ptbench/data/tbpoc/fold_1.py
+++ b/src/ptbench/data/tbpoc/fold_1.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-1.json")
 """TB-POC dataset for TB detection (cross validation fold 1).
 
+Database reference: [TB-POC-2018]_
+
 See :py:class:`.tbpoc.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-1.json")
diff --git a/src/ptbench/data/tbpoc/fold_2.py b/src/ptbench/data/tbpoc/fold_2.py
index 9df72b54..f0aa508c 100644
--- a/src/ptbench/data/tbpoc/fold_2.py
+++ b/src/ptbench/data/tbpoc/fold_2.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-2.json")
 """TB-POC dataset for TB detection (cross validation fold 2).
 
+Database reference: [TB-POC-2018]_
+
 See :py:class:`.tbpoc.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-2.json")
diff --git a/src/ptbench/data/tbpoc/fold_3.py b/src/ptbench/data/tbpoc/fold_3.py
index 514bf12c..b13213c7 100644
--- a/src/ptbench/data/tbpoc/fold_3.py
+++ b/src/ptbench/data/tbpoc/fold_3.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-3.json")
 """TB-POC dataset for TB detection (cross validation fold 3).
 
+Database reference: [TB-POC-2018]_
+
 See :py:class:`.tbpoc.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-3.json")
diff --git a/src/ptbench/data/tbpoc/fold_4.py b/src/ptbench/data/tbpoc/fold_4.py
index d4f87280..fe153fc6 100644
--- a/src/ptbench/data/tbpoc/fold_4.py
+++ b/src/ptbench/data/tbpoc/fold_4.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-4.json")
 """TB-POC dataset for TB detection (cross validation fold 4).
 
+Database reference: [TB-POC-2018]_
+
 See :py:class:`.tbpoc.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-4.json")
diff --git a/src/ptbench/data/tbpoc/fold_5.py b/src/ptbench/data/tbpoc/fold_5.py
index 2df9a7ff..7759ccc7 100644
--- a/src/ptbench/data/tbpoc/fold_5.py
+++ b/src/ptbench/data/tbpoc/fold_5.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-5.json")
 """TB-POC dataset for TB detection (cross validation fold 5).
 
+Database reference: [TB-POC-2018]_
+
 See :py:class:`.tbpoc.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-5.json")
diff --git a/src/ptbench/data/tbpoc/fold_6.py b/src/ptbench/data/tbpoc/fold_6.py
index 5d4fd08a..35be05a4 100644
--- a/src/ptbench/data/tbpoc/fold_6.py
+++ b/src/ptbench/data/tbpoc/fold_6.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-6.json")
 """TB-POC dataset for TB detection (cross validation fold 6).
 
+Database reference: [TB-POC-2018]_
+
 See :py:class:`.tbpoc.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-6.json")
diff --git a/src/ptbench/data/tbpoc/fold_7.py b/src/ptbench/data/tbpoc/fold_7.py
index 3b0b137f..da5bec1e 100644
--- a/src/ptbench/data/tbpoc/fold_7.py
+++ b/src/ptbench/data/tbpoc/fold_7.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-7.json")
 """TB-POC dataset for TB detection (cross validation fold 7).
 
+Database reference: [TB-POC-2018]_
+
 See :py:class:`.tbpoc.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-7.json")
diff --git a/src/ptbench/data/tbpoc/fold_8.py b/src/ptbench/data/tbpoc/fold_8.py
index f0304467..65339cc0 100644
--- a/src/ptbench/data/tbpoc/fold_8.py
+++ b/src/ptbench/data/tbpoc/fold_8.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-8.json")
 """TB-POC dataset for TB detection (cross validation fold 8).
 
+Database reference: [TB-POC-2018]_
+
 See :py:class:`.tbpoc.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-8.json")
diff --git a/src/ptbench/data/tbpoc/fold_9.py b/src/ptbench/data/tbpoc/fold_9.py
index 327c7156..dd42e068 100644
--- a/src/ptbench/data/tbpoc/fold_9.py
+++ b/src/ptbench/data/tbpoc/fold_9.py
@@ -1,11 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("fold-9.json")
 """TB-POC dataset for TB detection (cross validation fold 9).
 
+Database reference: [TB-POC-2018]_
+
 See :py:class:`.tbpoc.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("fold-9.json")
diff --git a/src/ptbench/data/tbx11k/v1_fold_0.py b/src/ptbench/data/tbx11k/v1_fold_0.py
index 63001c49..ecf1e295 100644
--- a/src/ptbench/data/tbx11k/v1_fold_0.py
+++ b/src/ptbench/data/tbx11k/v1_fold_0.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-0, v1: healthy vs. active TB
+cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v1_fold_1.py b/src/ptbench/data/tbx11k/v1_fold_1.py
index 37a208a5..b74f9ac9 100644
--- a/src/ptbench/data/tbx11k/v1_fold_1.py
+++ b/src/ptbench/data/tbx11k/v1_fold_1.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-1, v1: healthy vs. active TB
+cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v1_fold_2.py b/src/ptbench/data/tbx11k/v1_fold_2.py
index ddc512c9..c52f415a 100644
--- a/src/ptbench/data/tbx11k/v1_fold_2.py
+++ b/src/ptbench/data/tbx11k/v1_fold_2.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-2, v1: healthy vs. active TB
+cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v1_fold_3.py b/src/ptbench/data/tbx11k/v1_fold_3.py
index 52429614..32794848 100644
--- a/src/ptbench/data/tbx11k/v1_fold_3.py
+++ b/src/ptbench/data/tbx11k/v1_fold_3.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-3, v1: healthy vs. active TB
+cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v1_fold_4.py b/src/ptbench/data/tbx11k/v1_fold_4.py
index fbeb9dca..1c149232 100644
--- a/src/ptbench/data/tbx11k/v1_fold_4.py
+++ b/src/ptbench/data/tbx11k/v1_fold_4.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-4, v1: healthy vs. active TB
+cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v1_fold_5.py b/src/ptbench/data/tbx11k/v1_fold_5.py
index 485b8d78..2a74b219 100644
--- a/src/ptbench/data/tbx11k/v1_fold_5.py
+++ b/src/ptbench/data/tbx11k/v1_fold_5.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-5, v1: healthy vs. active TB
+cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v1_fold_6.py b/src/ptbench/data/tbx11k/v1_fold_6.py
index 54e613dd..67562a35 100644
--- a/src/ptbench/data/tbx11k/v1_fold_6.py
+++ b/src/ptbench/data/tbx11k/v1_fold_6.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-6, v1: healthy vs. active TB
+cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v1_fold_7.py b/src/ptbench/data/tbx11k/v1_fold_7.py
index f3fceecf..3d80b71e 100644
--- a/src/ptbench/data/tbx11k/v1_fold_7.py
+++ b/src/ptbench/data/tbx11k/v1_fold_7.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-7, v1: healthy vs. active TB
+cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v1_fold_8.py b/src/ptbench/data/tbx11k/v1_fold_8.py
index 4f33860b..f8e45fe1 100644
--- a/src/ptbench/data/tbx11k/v1_fold_8.py
+++ b/src/ptbench/data/tbx11k/v1_fold_8.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-8, v1: healthy vs. active TB
+cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v1_fold_9.py b/src/ptbench/data/tbx11k/v1_fold_9.py
index 44f767c4..0d394354 100644
--- a/src/ptbench/data/tbx11k/v1_fold_9.py
+++ b/src/ptbench/data/tbx11k/v1_fold_9.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-9, v1: healthy vs. active TB
+cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v1_healthy_vs_atb.py b/src/ptbench/data/tbx11k/v1_healthy_vs_atb.py
index fe0de82a..0845f03b 100644
--- a/src/ptbench/data/tbx11k/v1_healthy_vs_atb.py
+++ b/src/ptbench/data/tbx11k/v1_healthy_vs_atb.py
@@ -1,13 +1,11 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("v1-healthy-vs-atb.json")
 """TBX11k dataset for TB detection.  Split ``v1`` (healthy against active TB
 cases).
 
+Database reference: [TBX11K-2020]_
+
 Split v1 contains healthy subjects against active TB cases (total samples =
 4430):
 
@@ -28,4 +26,10 @@ Split v1 contains healthy subjects against active TB cases (total samples =
   - Healthy: 800
   - Active TB only: 157
   - Total: 957
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("v1-healthy-vs-atb.json")
diff --git a/src/ptbench/data/tbx11k/v2_fold_0.py b/src/ptbench/data/tbx11k/v2_fold_0.py
index 7bf536b5..8ccb73ed 100644
--- a/src/ptbench/data/tbx11k/v2_fold_0.py
+++ b/src/ptbench/data/tbx11k/v2_fold_0.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-0, v2: healthy, sick and latent
+TB vs. active TB cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v2_fold_1.py b/src/ptbench/data/tbx11k/v2_fold_1.py
index 6257e629..9e1c3aca 100644
--- a/src/ptbench/data/tbx11k/v2_fold_1.py
+++ b/src/ptbench/data/tbx11k/v2_fold_1.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-1, v2: healthy, sick and latent
+TB vs. active TB cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v2_fold_2.py b/src/ptbench/data/tbx11k/v2_fold_2.py
index 72d93dba..24a00ece 100644
--- a/src/ptbench/data/tbx11k/v2_fold_2.py
+++ b/src/ptbench/data/tbx11k/v2_fold_2.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-2, v2: healthy, sick and latent
+TB vs. active TB cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v2_fold_3.py b/src/ptbench/data/tbx11k/v2_fold_3.py
index 75d9e2c2..9da2630d 100644
--- a/src/ptbench/data/tbx11k/v2_fold_3.py
+++ b/src/ptbench/data/tbx11k/v2_fold_3.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-3, v2: healthy, sick and latent
+TB vs. active TB cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v2_fold_4.py b/src/ptbench/data/tbx11k/v2_fold_4.py
index d1aad024..0555b567 100644
--- a/src/ptbench/data/tbx11k/v2_fold_4.py
+++ b/src/ptbench/data/tbx11k/v2_fold_4.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-4, v2: healthy, sick and latent
+TB vs. active TB cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v2_fold_5.py b/src/ptbench/data/tbx11k/v2_fold_5.py
index 8b0a5a07..1fddcc2f 100644
--- a/src/ptbench/data/tbx11k/v2_fold_5.py
+++ b/src/ptbench/data/tbx11k/v2_fold_5.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-5, v2: healthy, sick and latent
+TB vs. active TB cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v2_fold_6.py b/src/ptbench/data/tbx11k/v2_fold_6.py
index 5d9f2b72..d9085af1 100644
--- a/src/ptbench/data/tbx11k/v2_fold_6.py
+++ b/src/ptbench/data/tbx11k/v2_fold_6.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-6, v2: healthy, sick and latent
+TB vs. active TB cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v2_fold_7.py b/src/ptbench/data/tbx11k/v2_fold_7.py
index 308a10a1..b324e129 100644
--- a/src/ptbench/data/tbx11k/v2_fold_7.py
+++ b/src/ptbench/data/tbx11k/v2_fold_7.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-7, v2: healthy, sick and latent
+TB vs. active TB cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v2_fold_8.py b/src/ptbench/data/tbx11k/v2_fold_8.py
index cd73fe53..31ed229a 100644
--- a/src/ptbench/data/tbx11k/v2_fold_8.py
+++ b/src/ptbench/data/tbx11k/v2_fold_8.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-8, v2: healthy, sick and latent
+TB vs. active TB cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v2_fold_9.py b/src/ptbench/data/tbx11k/v2_fold_9.py
index 87a5b2d6..74db9a28 100644
--- a/src/ptbench/data/tbx11k/v2_fold_9.py
+++ b/src/ptbench/data/tbx11k/v2_fold_9.py
@@ -1,6 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
+"""TBX11k dataset for TB detection (cross fold-9, v2: healthy, sick and latent
+TB vs. active TB cases).
+
+Database reference: [TBX11K-2020]_
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
+"""
 
 from .datamodule import DataModule
 
diff --git a/src/ptbench/data/tbx11k/v2_others_vs_atb.py b/src/ptbench/data/tbx11k/v2_others_vs_atb.py
index 5bee7bd0..b5f78019 100644
--- a/src/ptbench/data/tbx11k/v2_others_vs_atb.py
+++ b/src/ptbench/data/tbx11k/v2_others_vs_atb.py
@@ -1,13 +1,11 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-
-from .datamodule import DataModule
-
-datamodule = DataModule("v2-others-vs-atb.json")
 """TBX11k dataset for TB detection.  Split ``v1`` (everything else against
 active TB cases).
 
+Database reference: [TBX11K-2020]_
+
 Split v2 contains healthy, sick (no TB), and latent TB subjects against
 active TB cases (total samples = 8369):
 
@@ -28,4 +26,10 @@ active TB cases (total samples = 8369):
   - Healthy, Sick or Latent TB: 1636
   - Active TB only: 157
   - Total: 1793
+
+See :py:class:`.tbx11k.datamodule.DataModule` for technical details.
 """
+
+from .datamodule import DataModule
+
+datamodule = DataModule("v2-others-vs-atb.json")
diff --git a/src/ptbench/models/config/alexnet.py b/src/ptbench/models/config/alexnet.py
index 7dddc4c7..9adcfec8 100644
--- a/src/ptbench/models/config/alexnet.py
+++ b/src/ptbench/models/config/alexnet.py
@@ -1,7 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-"""AlexNet."""
+"""AlexNet_, to be trained from scratch.
+
+This configuration contains a version of AlexNet_ (c.f. `TorchVision's
+page <alexnet_pytorch_>`), modified for a variable number of outputs
+(defaults to 1).
+"""
 
 from torch.nn import BCEWithLogitsLoss
 from torch.optim import SGD
diff --git a/src/ptbench/models/config/alexnet_pretrained.py b/src/ptbench/models/config/alexnet_pretrained.py
index fb9ae5b5..81f72b87 100644
--- a/src/ptbench/models/config/alexnet_pretrained.py
+++ b/src/ptbench/models/config/alexnet_pretrained.py
@@ -1,7 +1,14 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-"""AlexNet."""
+"""AlexNet_, to be fine-tuned. Pre-trained on ImageNet_.
+
+This configuration contains a version of AlexNet_ (c.f. `TorchVision's
+page <alexnet_pytorch_>`), modified for a variable number of outputs
+(defaults to 1).
+
+N.B.: The output layer is **always** initialized from scratch.
+"""
 
 from torch.nn import BCEWithLogitsLoss
 from torch.optim import SGD
diff --git a/src/ptbench/models/config/densenet.py b/src/ptbench/models/config/densenet.py
index 3cece962..bfee577f 100644
--- a/src/ptbench/models/config/densenet.py
+++ b/src/ptbench/models/config/densenet.py
@@ -1,7 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-"""DenseNet."""
+"""DenseNet_, to be trained from scratch.
+
+This configuration contains a version of DenseNet_ (c.f. `TorchVision's
+page <densenet_pytorch_>`), modified for a variable number of outputs
+(defaults to 1).
+"""
 
 from torch.nn import BCEWithLogitsLoss
 from torch.optim import Adam
diff --git a/src/ptbench/models/config/densenet_pretrained.py b/src/ptbench/models/config/densenet_pretrained.py
index 949b1e9e..9b1fa4ca 100644
--- a/src/ptbench/models/config/densenet_pretrained.py
+++ b/src/ptbench/models/config/densenet_pretrained.py
@@ -1,7 +1,14 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-"""DenseNet."""
+"""DenseNet_, to be fine-tuned. Pre-trained on ImageNet_.
+
+This configuration contains a version of DenseNet_ (c.f. `TorchVision's
+page <alexnet_pytorch_>`), modified for a variable number of outputs
+(defaults to 1).
+
+N.B.: The output layer is **always** initialized from scratch.
+"""
 
 from torch.nn import BCEWithLogitsLoss
 from torch.optim import Adam
diff --git a/src/ptbench/models/config/densenet_rs.py b/src/ptbench/models/config/densenet_rs.py
index 57d23f43..3f625686 100644
--- a/src/ptbench/models/config/densenet_rs.py
+++ b/src/ptbench/models/config/densenet_rs.py
@@ -1,10 +1,12 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-"""CNN for detecting radiological findings.
+"""DenseNet_, to be trained from scratch.
 
-A Densenet-121 model for radiological sign detection, using the NIH
-CXR-14 label format (ie. 14 outputs).
+This configuration contains a version of DenseNet_ (c.f. `TorchVision's
+page <densenet_pytorch_>`), modified to have exactly 14 outputs
+(matching the number of classes on NIH CXR-14).  It can be used to train
+weights from scratch for radiological sign detection.
 """
 
 from torch.nn import BCEWithLogitsLoss
diff --git a/src/ptbench/models/config/logistic_regression.py b/src/ptbench/models/config/logistic_regression.py
index 49678bcb..b93589df 100644
--- a/src/ptbench/models/config/logistic_regression.py
+++ b/src/ptbench/models/config/logistic_regression.py
@@ -1,28 +1,13 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-"""Feedforward network for Tuberculosis Detection.
+"""Logistic regression classifier, to be trained from scratch.
 
-Simple feedforward network taking radiological signs in output and
-predicting tuberculosis presence in output.
+This configuration file defines a logistic regression classifier that can take
+the output of :py:mod:`.densenet_rs` and be trained for binary classification
+(e.g. for active TB detection).
 """
-from torch import empty
-from torch.nn import BCEWithLogitsLoss
 
 from ptbench.models.logistic_regression import LogisticRegression
 
-# config
-optimizer_configs = {"lr": 1e-2}
-input_size = 14
-
-# optimizer
-optimizer = "Adam"
-
-# criterion
-criterion = BCEWithLogitsLoss(pos_weight=empty(1))
-criterion_valid = BCEWithLogitsLoss(pos_weight=empty(1))
-
-# model
-model = LogisticRegression(
-    criterion, criterion_valid, optimizer, optimizer_configs, input_size
-)
+model = LogisticRegression(input_size=14)
diff --git a/src/ptbench/models/config/mlp.py b/src/ptbench/models/config/mlp.py
new file mode 100644
index 00000000..c87432d7
--- /dev/null
+++ b/src/ptbench/models/config/mlp.py
@@ -0,0 +1,13 @@
+# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+"""Feedforward shallow MLP for binary classification.
+
+Simple feedforward MLP taking multiple inputs and generating a single
+output (e.g. to predict active TB presence from radiological finding
+estimates).
+"""
+
+from ptbench.models.mlp import MultiLayerPerceptron
+
+model = MultiLayerPerceptron()
diff --git a/src/ptbench/models/config/pasa.py b/src/ptbench/models/config/pasa.py
index 12775592..c419b5fe 100644
--- a/src/ptbench/models/config/pasa.py
+++ b/src/ptbench/models/config/pasa.py
@@ -1,7 +1,7 @@
 # SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
-"""CNN for Tuberculosis Detection.
+"""Simple CNN for Tuberculosis Detection, to be trained from scratch.
 
 Implementation of the model architecture proposed by F. Pasa in the article
 "Efficient Deep Network Architectures for Fast Chest X-Ray Tuberculosis
diff --git a/src/ptbench/models/config/signs_to_tb.py b/src/ptbench/models/config/signs_to_tb.py
deleted file mode 100644
index 21bc79e2..00000000
--- a/src/ptbench/models/config/signs_to_tb.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-"""Feedforward network for Tuberculosis Detection.
-
-Simple feedforward network taking radiological signs in output and
-predicting tuberculosis presence in output.
-"""
-
-from torch import empty
-from torch.nn import BCEWithLogitsLoss
-
-from ptbench.models.signs_to_tb import SignsToTB
-
-# config
-optimizer_configs = {"lr": 1e-2}
-
-# optimizer
-optimizer = "Adam"
-
-# criterion
-criterion = BCEWithLogitsLoss(pos_weight=empty(1))
-criterion_valid = BCEWithLogitsLoss(pos_weight=empty(1))
-
-# model
-model = SignsToTB(
-    criterion, criterion_valid, optimizer, optimizer_configs, 14, 10
-)
diff --git a/src/ptbench/models/logistic_regression.py b/src/ptbench/models/logistic_regression.py
index dfde8318..d0f952bb 100644
--- a/src/ptbench/models/logistic_regression.py
+++ b/src/ptbench/models/logistic_regression.py
@@ -2,37 +2,72 @@
 #
 # SPDX-License-Identifier: GPL-3.0-or-later
 
+import typing
+
 import lightning.pytorch as pl
 import torch
 import torch.nn as nn
 
 
 class LogisticRegression(pl.LightningModule):
-    """Radiological signs to Tuberculosis module."""
+    """Logistic regression classifier with a single output.
+
+    Parameters
+    ----------
+    train_loss
+        The loss to be used during the training.
+
+        .. warning::
+
+           The loss should be set to always return batch averages (as opposed
+           to the batch sum), as our logging system expects it so.
+
+    validation_loss
+        The loss to be used for validation (may be different from the training
+        loss).  If extra-validation sets are provided, the same loss will be
+        used throughout.
+
+        .. warning::
+
+           The loss should be set to always return batch averages (as opposed
+           to the batch sum), as our logging system expects it so.
+
+    optimizer_type
+        The type of optimizer to use for training
+
+    optimizer_arguments
+        Arguments to the optimizer after ``params``.
+
+    input_size
+        The number of inputs this classifer shall process.
+    """
 
     def __init__(
         self,
-        criterion,
-        criterion_valid,
-        optimizer,
-        optimizer_configs,
-        input_size,
+        train_loss: torch.nn.Module = torch.nn.BCEWithLogitsLoss(),
+        validation_loss: torch.nn.Module | None = None,
+        optimizer_type: type[torch.optim.Optimizer] = torch.optim.Adam,
+        optimizer_arguments: dict[str, typing.Any] = {"lr": 1e-2},
+        input_size: int = 14,
     ):
         super().__init__()
 
-        self.save_hyperparameters(ignore=["criterion", "criterion_valid"])
+        self._train_loss = train_loss.to(self.device)
+        self._validation_loss = (
+            validation_loss if validation_loss is not None else train_loss
+        ).to(self.device)
+        self._optimizer_type = optimizer_type
+        self._optimizer_arguments = optimizer_arguments
 
-        self.name = "logistic_regression"
+        self.name = "logistic-regression"
 
-        self.linear = nn.Linear(self.hparams.input_size, 1)
+        self.linear = nn.Linear(input_size, 1)
 
     def forward(self, x):
-        output = self.linear(x)
-
-        return output
+        return self.linear(x)
 
     def training_step(self, batch, batch_idx):
-        images = batch[1]
+        input = batch[1]
         labels = batch[2]
 
         # Increase label dimension if too low
@@ -41,16 +76,16 @@ class LogisticRegression(pl.LightningModule):
             labels = torch.reshape(labels, (labels.shape[0], 1))
 
         # Forward pass on the network
-        outputs = self(images)
+        output = self(input)
 
         # Manually move criterion to selected device, since not part of the model.
-        self.hparams.criterion = self.hparams.criterion.to(self.device)
-        training_loss = self.hparams.criterion(outputs, labels.float())
+        self._train_loss = self._train_loss.to(self.device)
+        training_loss = self._train_loss(output, labels.float())
 
         return {"loss": training_loss}
 
     def validation_step(self, batch, batch_idx, dataloader_idx=0):
-        images = batch[1]
+        input = batch[1]
         labels = batch[2]
 
         # Increase label dimension if too low
@@ -59,13 +94,11 @@ class LogisticRegression(pl.LightningModule):
             labels = torch.reshape(labels, (labels.shape[0], 1))
 
         # data forwarding on the existing network
-        outputs = self(images)
+        output = self(input)
 
         # Manually move criterion to selected device, since not part of the model.
-        self.hparams.criterion_valid = self.hparams.criterion_valid.to(
-            self.device
-        )
-        validation_loss = self.hparams.criterion_valid(outputs, labels.float())
+        self._validation_loss = self._validation_loss.to(self.device)
+        validation_loss = self._validation_loss(output, labels.float())
 
         if dataloader_idx == 0:
             return {"validation_loss": validation_loss}
@@ -74,21 +107,19 @@ class LogisticRegression(pl.LightningModule):
 
     def predict_step(self, batch, batch_idx, dataloader_idx=0, grad_cams=False):
         names = batch[0]
-        images = batch[1]
+        input = batch[1]
 
-        outputs = self(images)
-        probabilities = torch.sigmoid(outputs)
+        output = self(input)
+        probabilities = torch.sigmoid(output)
 
         # necessary check for HED architecture that uses several outputs
         # for loss calculation instead of just the last concatfuse block
-        if isinstance(outputs, list):
-            outputs = outputs[-1]
+        if isinstance(output, list):
+            output = output[-1]
 
         return names[0], torch.flatten(probabilities), torch.flatten(batch[2])
 
     def configure_optimizers(self):
-        optimizer = getattr(torch.optim, self.hparams.optimizer)(
-            self.parameters(), **self.hparams.optimizer_configs
+        return self._optimizer_type(
+            self.parameters(), **self._optimizer_arguments
         )
-
-        return optimizer
diff --git a/src/ptbench/models/mlp.py b/src/ptbench/models/mlp.py
new file mode 100644
index 00000000..54c7cb69
--- /dev/null
+++ b/src/ptbench/models/mlp.py
@@ -0,0 +1,130 @@
+# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+import typing
+
+import lightning.pytorch as pl
+import torch
+
+
+class MultiLayerPerceptron(pl.LightningModule):
+    """MLP with a variable number of inputs and hidden neurons (single layer).
+
+    Parameters
+    ----------
+    train_loss
+        The loss to be used during the training.
+
+        .. warning::
+
+           The loss should be set to always return batch averages (as opposed
+           to the batch sum), as our logging system expects it so.
+
+    validation_loss
+        The loss to be used for validation (may be different from the training
+        loss).  If extra-validation sets are provided, the same loss will be
+        used throughout.
+
+        .. warning::
+
+           The loss should be set to always return batch averages (as opposed
+           to the batch sum), as our logging system expects it so.
+
+    optimizer_type
+        The type of optimizer to use for training
+
+    optimizer_arguments
+        Arguments to the optimizer after ``params``.
+
+    input_size
+        The number of inputs this classifer shall process.
+
+    hidden_size
+        The number of neurons on the single hidden layer.
+    """
+
+    def __init__(
+        self,
+        train_loss: torch.nn.Module = torch.nn.BCEWithLogitsLoss(),
+        validation_loss: torch.nn.Module | None = None,
+        optimizer_type: type[torch.optim.Optimizer] = torch.optim.Adam,
+        optimizer_arguments: dict[str, typing.Any] = {"lr": 1e-2},
+        input_size: int = 14,
+        hidden_size: int = 10,
+    ):
+        super().__init__()
+
+        self._train_loss = train_loss.to(self.device)
+        self._validation_loss = (
+            validation_loss if validation_loss is not None else train_loss
+        ).to(self.device)
+        self._optimizer_type = optimizer_type
+        self._optimizer_arguments = optimizer_arguments
+
+        self.name = "mlp"
+
+        self.fc1 = torch.nn.Linear(input_size, hidden_size)
+        self.relu = torch.nn.ReLU()
+        self.fc2 = torch.nn.Linear(hidden_size, 1)
+
+    def forward(self, x):
+        return self.fc2(self.relu(self.fc1(x)))
+
+    def training_step(self, batch, batch_idx):
+        input = batch[1]
+        labels = batch[2]
+
+        # Increase label dimension if too low
+        # Allows single and multiclass usage
+        if labels.ndim == 1:
+            labels = torch.reshape(labels, (labels.shape[0], 1))
+
+        # Forward pass on the network
+        output = self(input)
+
+        # Manually move criterion to selected device, since not part of the model.
+        self._train_loss = self._train_loss.to(self.device)
+        training_loss = self._train_loss(output, labels.float())
+
+        return {"loss": training_loss}
+
+    def validation_step(self, batch, batch_idx, dataloader_idx=0):
+        input = batch[1]
+        labels = batch[2]
+
+        # Increase label dimension if too low
+        # Allows single and multiclass usage
+        if labels.ndim == 1:
+            labels = torch.reshape(labels, (labels.shape[0], 1))
+
+        # data forwarding on the existing network
+        output = self(input)
+
+        # Manually move criterion to selected device, since not part of the model.
+        self._validation_loss = self._validation_loss.to(self.device)
+        validation_loss = self._validation_loss(output, labels.float())
+
+        if dataloader_idx == 0:
+            return {"validation_loss": validation_loss}
+        else:
+            return {f"extra_validation_loss_{dataloader_idx}": validation_loss}
+
+    def predict_step(self, batch, batch_idx, dataloader_idx=0, grad_cams=False):
+        names = batch[0]
+        input = batch[1]
+
+        output = self(input)
+        probabilities = torch.sigmoid(output)
+
+        # necessary check for HED architecture that uses several outputs
+        # for loss calculation instead of just the last concatfuse block
+        if isinstance(output, list):
+            output = output[-1]
+
+        return names[0], torch.flatten(probabilities), torch.flatten(batch[2])
+
+    def configure_optimizers(self):
+        return self._optimizer_type(
+            self.parameters(), **self._optimizer_arguments
+        )
diff --git a/src/ptbench/models/signs_to_tb.py b/src/ptbench/models/signs_to_tb.py
deleted file mode 100644
index 2f86ded5..00000000
--- a/src/ptbench/models/signs_to_tb.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-import lightning.pytorch as pl
-import torch
-
-
-class SignsToTB(pl.LightningModule):
-    """Radiological signs to Tuberculosis module."""
-
-    def __init__(
-        self,
-        criterion,
-        criterion_valid,
-        optimizer,
-        optimizer_configs,
-        input_size,
-        hidden_size,
-    ):
-        super().__init__()
-
-        self.save_hyperparameters()
-
-        self.name = "signs_to_tb"
-
-        self.fc1 = torch.nn.Linear(
-            self.hparams.input_size, self.hparams.hidden_size
-        )
-        self.relu = torch.nn.ReLU()
-        self.fc2 = torch.nn.Linear(self.hparams.hidden_size, 1)
-
-    def forward(self, x):
-        hidden = self.fc1(x)
-        relu = self.relu(hidden)
-
-        output = self.fc2(relu)
-
-        return output
-
-    def training_step(self, batch, batch_idx):
-        images = batch[1]
-        labels = batch[2]
-
-        # Increase label dimension if too low
-        # Allows single and multiclass usage
-        if labels.ndim == 1:
-            labels = torch.reshape(labels, (labels.shape[0], 1))
-
-        # Forward pass on the network
-        outputs = self(images)
-
-        # Manually move criterion to selected device, since not part of the model.
-        self.hparams.criterion = self.hparams.criterion.to(self.device)
-        training_loss = self.hparams.criterion(outputs, labels.float())
-
-        return {"loss": training_loss}
-
-    def validation_step(self, batch, batch_idx, dataloader_idx=0):
-        images = batch[1]
-        labels = batch[2]
-
-        # Increase label dimension if too low
-        # Allows single and multiclass usage
-        if labels.ndim == 1:
-            labels = torch.reshape(labels, (labels.shape[0], 1))
-
-        # data forwarding on the existing network
-        outputs = self(images)
-
-        # Manually move criterion to selected device, since not part of the model.
-        self.hparams.criterion_valid = self.hparams.criterion_valid.to(
-            self.device
-        )
-        validation_loss = self.hparams.criterion_valid(outputs, labels.float())
-
-        if dataloader_idx == 0:
-            return {"validation_loss": validation_loss}
-        else:
-            return {f"extra_validation_loss_{dataloader_idx}": validation_loss}
-
-    def predict_step(self, batch, batch_idx, dataloader_idx=0, grad_cams=False):
-        names = batch[0]
-        images = batch[1]
-
-        outputs = self(images)
-        probabilities = torch.sigmoid(outputs)
-
-        # necessary check for HED architecture that uses several outputs
-        # for loss calculation instead of just the last concatfuse block
-        if isinstance(outputs, list):
-            outputs = outputs[-1]
-
-        return names[0], torch.flatten(probabilities), torch.flatten(batch[2])
-
-    def configure_optimizers(self):
-        # Dynamically instantiates the optimizer given the configs
-        optimizer = getattr(torch.optim, self.hparams.optimizer)(
-            self.parameters(), **self.hparams.optimizer_configs
-        )
-
-        return optimizer
diff --git a/src/ptbench/scripts/config.py b/src/ptbench/scripts/config.py
index c58d6ff6..a2d49dbf 100644
--- a/src/ptbench/scripts/config.py
+++ b/src/ptbench/scripts/config.py
@@ -16,34 +16,6 @@ from clapper.logging import setup
 logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
 
 
-def _retrieve_entry_points(
-    group: str,
-) -> typing.Iterable[importlib.metadata.EntryPoint]:
-    """Wraps various entry-point retrieval mechanisms.
-
-    For Python 3.9 and 3.10,
-    :py:func:`importlib.metadata.entry_points()`
-    returns a dictionary keyed by entry-point group names.  From Python
-    3.10
-    onwards, one may pass the ``group`` keyword to that function to
-    enable
-    pre-filtering, or use the ``select()`` method on the returned value,
-    which
-    is no longer a dictionary.
-
-    For anything before Python 3.8, you must use the backported library
-    ``importlib_metadata``.
-    """
-    import sys
-
-    if sys.version_info[:2] < (3, 10):
-        all_entry_points = importlib.metadata.entry_points()
-        return all_entry_points.get(group, [])  # Python 3.9
-
-    # Python 3.10 and above
-    return importlib.metadata.entry_points().select(group=group)
-
-
 @click.group(cls=AliasedGroup)
 def config():
     """Commands for listing, describing and copying configuration resources."""
@@ -74,7 +46,9 @@ def config():
 @verbosity_option(logger=logger)
 def list(verbose) -> None:
     """Lists configuration files installed."""
-    entry_points = _retrieve_entry_points("ptbench.config")
+    entry_points = importlib.metadata.entry_points().select(
+        group="ptbench.config"
+    )
     entry_point_dict = {k.name: k for k in entry_points}
 
     # all modules with configuration resources
@@ -158,7 +132,9 @@ def list(verbose) -> None:
 @verbosity_option(logger=logger)
 def describe(name, verbose) -> None:
     """Describes a specific configuration file."""
-    entry_points = _retrieve_entry_points("ptbench.config")
+    entry_points = importlib.metadata.entry_points().select(
+        group="ptbench.config"
+    )
     entry_point_dict = {k.name: k for k in entry_points}
 
     for k in name:
@@ -209,7 +185,9 @@ def copy(source, destination) -> None:
     """Copy a specific configuration resource so it can be modified locally."""
     import shutil
 
-    entry_points = _retrieve_entry_points("ptbench.config")
+    entry_points = importlib.metadata.entry_points().select(
+        group="ptbench.config"
+    )
     entry_point_dict = {k.name: k for k in entry_points}
 
     if source not in entry_point_dict:
-- 
GitLab