diff --git a/pyproject.toml b/pyproject.toml
index 67211c83b61683f212a437ce4269c7c9d06d3104..b936dddb51fc0ce848186e1321bbb88880f9da3e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -293,28 +293,28 @@ mc_ch_rs_f7 = "ptbench.configs.datasets.mc_ch_RS.fold_7"
 mc_ch_rs_f8 = "ptbench.configs.datasets.mc_ch_RS.fold_8"
 mc_ch_rs_f9 = "ptbench.configs.datasets.mc_ch_RS.fold_9"
 # montgomery-shenzhen-indian aggregated dataset
-mc_ch_in = "ptbench.configs.datasets.mc_ch_in.default"
-mc_ch_in_rgb = "ptbench.configs.datasets.mc_ch_in.rgb"
-mc_ch_in_f0 = "ptbench.configs.datasets.mc_ch_in.fold_0"
-mc_ch_in_f1 = "ptbench.configs.datasets.mc_ch_in.fold_1"
-mc_ch_in_f2 = "ptbench.configs.datasets.mc_ch_in.fold_2"
-mc_ch_in_f3 = "ptbench.configs.datasets.mc_ch_in.fold_3"
-mc_ch_in_f4 = "ptbench.configs.datasets.mc_ch_in.fold_4"
-mc_ch_in_f5 = "ptbench.configs.datasets.mc_ch_in.fold_5"
-mc_ch_in_f6 = "ptbench.configs.datasets.mc_ch_in.fold_6"
-mc_ch_in_f7 = "ptbench.configs.datasets.mc_ch_in.fold_7"
-mc_ch_in_f8 = "ptbench.configs.datasets.mc_ch_in.fold_8"
-mc_ch_in_f9 = "ptbench.configs.datasets.mc_ch_in.fold_9"
-mc_ch_in_f0_rgb = "ptbench.configs.datasets.mc_ch_in.fold_0_rgb"
-mc_ch_in_f1_rgb = "ptbench.configs.datasets.mc_ch_in.fold_1_rgb"
-mc_ch_in_f2_rgb = "ptbench.configs.datasets.mc_ch_in.fold_2_rgb"
-mc_ch_in_f3_rgb = "ptbench.configs.datasets.mc_ch_in.fold_3_rgb"
-mc_ch_in_f4_rgb = "ptbench.configs.datasets.mc_ch_in.fold_4_rgb"
-mc_ch_in_f5_rgb = "ptbench.configs.datasets.mc_ch_in.fold_5_rgb"
-mc_ch_in_f6_rgb = "ptbench.configs.datasets.mc_ch_in.fold_6_rgb"
-mc_ch_in_f7_rgb = "ptbench.configs.datasets.mc_ch_in.fold_7_rgb"
-mc_ch_in_f8_rgb = "ptbench.configs.datasets.mc_ch_in.fold_8_rgb"
-mc_ch_in_f9_rgb = "ptbench.configs.datasets.mc_ch_in.fold_9_rgb"
+mc_ch_in = "ptbench.data.mc_ch_in.default"
+mc_ch_in_rgb = "ptbench.data.mc_ch_in.rgb"
+mc_ch_in_f0 = "ptbench.data.mc_ch_in.fold_0"
+mc_ch_in_f1 = "ptbench.data.mc_ch_in.fold_1"
+mc_ch_in_f2 = "ptbench.data.mc_ch_in.fold_2"
+mc_ch_in_f3 = "ptbench.data.mc_ch_in.fold_3"
+mc_ch_in_f4 = "ptbench.data.mc_ch_in.fold_4"
+mc_ch_in_f5 = "ptbench.data.mc_ch_in.fold_5"
+mc_ch_in_f6 = "ptbench.data.mc_ch_in.fold_6"
+mc_ch_in_f7 = "ptbench.data.mc_ch_in.fold_7"
+mc_ch_in_f8 = "ptbench.data.mc_ch_in.fold_8"
+mc_ch_in_f9 = "ptbench.data.mc_ch_in.fold_9"
+mc_ch_in_f0_rgb = "ptbench.data.mc_ch_in.fold_0_rgb"
+mc_ch_in_f1_rgb = "ptbench.data.mc_ch_in.fold_1_rgb"
+mc_ch_in_f2_rgb = "ptbench.data.mc_ch_in.fold_2_rgb"
+mc_ch_in_f3_rgb = "ptbench.data.mc_ch_in.fold_3_rgb"
+mc_ch_in_f4_rgb = "ptbench.data.mc_ch_in.fold_4_rgb"
+mc_ch_in_f5_rgb = "ptbench.data.mc_ch_in.fold_5_rgb"
+mc_ch_in_f6_rgb = "ptbench.data.mc_ch_in.fold_6_rgb"
+mc_ch_in_f7_rgb = "ptbench.data.mc_ch_in.fold_7_rgb"
+mc_ch_in_f8_rgb = "ptbench.data.mc_ch_in.fold_8_rgb"
+mc_ch_in_f9_rgb = "ptbench.data.mc_ch_in.fold_9_rgb"
 # extended montgomery-shenzhen-indian aggregated dataset
 # (with radiological signs)
 mc_ch_in_rs = "ptbench.configs.datasets.mc_ch_in_RS.default"
diff --git a/src/ptbench/configs/datasets/mc_ch_in/__init__.py b/src/ptbench/configs/datasets/mc_ch_in/__init__.py
deleted file mode 100644
index 41023bb3d8b0340fb369fe007001d8f68da21440..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/__init__.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from torch.utils.data.dataset import ConcatDataset
-
-
-def _maker(protocol):
-    if protocol == "default":
-        from ..indian import default as indian
-        from ..montgomery import default as mc
-        from ..shenzhen import default as ch
-    elif protocol == "rgb":
-        from ..indian import rgb as indian
-        from ..montgomery import rgb as mc
-        from ..shenzhen import rgb as ch
-    elif protocol == "fold_0":
-        from ..indian import fold_0 as indian
-        from ..montgomery import fold_0 as mc
-        from ..shenzhen import fold_0 as ch
-    elif protocol == "fold_1":
-        from ..indian import fold_1 as indian
-        from ..montgomery import fold_1 as mc
-        from ..shenzhen import fold_1 as ch
-    elif protocol == "fold_2":
-        from ..indian import fold_2 as indian
-        from ..montgomery import fold_2 as mc
-        from ..shenzhen import fold_2 as ch
-    elif protocol == "fold_3":
-        from ..indian import fold_3 as indian
-        from ..montgomery import fold_3 as mc
-        from ..shenzhen import fold_3 as ch
-    elif protocol == "fold_4":
-        from ..indian import fold_4 as indian
-        from ..montgomery import fold_4 as mc
-        from ..shenzhen import fold_4 as ch
-    elif protocol == "fold_5":
-        from ..indian import fold_5 as indian
-        from ..montgomery import fold_5 as mc
-        from ..shenzhen import fold_5 as ch
-    elif protocol == "fold_6":
-        from ..indian import fold_6 as indian
-        from ..montgomery import fold_6 as mc
-        from ..shenzhen import fold_6 as ch
-    elif protocol == "fold_7":
-        from ..indian import fold_7 as indian
-        from ..montgomery import fold_7 as mc
-        from ..shenzhen import fold_7 as ch
-    elif protocol == "fold_8":
-        from ..indian import fold_8 as indian
-        from ..montgomery import fold_8 as mc
-        from ..shenzhen import fold_8 as ch
-    elif protocol == "fold_9":
-        from ..indian import fold_9 as indian
-        from ..montgomery import fold_9 as mc
-        from ..shenzhen import fold_9 as ch
-    elif protocol == "fold_0_rgb":
-        from ..indian import fold_0_rgb as indian
-        from ..montgomery import fold_0_rgb as mc
-        from ..shenzhen import fold_0_rgb as ch
-    elif protocol == "fold_1_rgb":
-        from ..indian import fold_1_rgb as indian
-        from ..montgomery import fold_1_rgb as mc
-        from ..shenzhen import fold_1_rgb as ch
-    elif protocol == "fold_2_rgb":
-        from ..indian import fold_2_rgb as indian
-        from ..montgomery import fold_2_rgb as mc
-        from ..shenzhen import fold_2_rgb as ch
-    elif protocol == "fold_3_rgb":
-        from ..indian import fold_3_rgb as indian
-        from ..montgomery import fold_3_rgb as mc
-        from ..shenzhen import fold_3_rgb as ch
-    elif protocol == "fold_4_rgb":
-        from ..indian import fold_4_rgb as indian
-        from ..montgomery import fold_4_rgb as mc
-        from ..shenzhen import fold_4_rgb as ch
-    elif protocol == "fold_5_rgb":
-        from ..indian import fold_5_rgb as indian
-        from ..montgomery import fold_5_rgb as mc
-        from ..shenzhen import fold_5_rgb as ch
-    elif protocol == "fold_6_rgb":
-        from ..indian import fold_6_rgb as indian
-        from ..montgomery import fold_6_rgb as mc
-        from ..shenzhen import fold_6_rgb as ch
-    elif protocol == "fold_7_rgb":
-        from ..indian import fold_7_rgb as indian
-        from ..montgomery import fold_7_rgb as mc
-        from ..shenzhen import fold_7_rgb as ch
-    elif protocol == "fold_8_rgb":
-        from ..indian import fold_8_rgb as indian
-        from ..montgomery import fold_8_rgb as mc
-        from ..shenzhen import fold_8_rgb as ch
-    elif protocol == "fold_9_rgb":
-        from ..indian import fold_9_rgb as indian
-        from ..montgomery import fold_9_rgb as mc
-        from ..shenzhen import fold_9_rgb as ch
-
-    mc = mc.dataset
-    ch = ch.dataset
-    indian = indian.dataset
-
-    dataset = {}
-    dataset["__train__"] = ConcatDataset(
-        [mc["__train__"], ch["__train__"], indian["__train__"]]
-    )
-    dataset["train"] = ConcatDataset(
-        [mc["train"], ch["train"], indian["train"]]
-    )
-    dataset["__valid__"] = ConcatDataset(
-        [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
-    )
-    dataset["validation"] = ConcatDataset(
-        [mc["validation"], ch["validation"], indian["validation"]]
-    )
-    dataset["test"] = ConcatDataset([mc["test"], ch["test"], indian["test"]])
-
-    return dataset
diff --git a/src/ptbench/configs/datasets/mc_ch_in/default.py b/src/ptbench/configs/datasets/mc_ch_in/default.py
deleted file mode 100644
index 8408ffb222cf722c2065f90a0d7eb3060fbd5338..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/default.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets."""
-
-from . import _maker
-
-dataset = _maker("default")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_0.py b/src/ptbench/configs/datasets/mc_ch_in/fold_0.py
deleted file mode 100644
index 405bb426a875b68c58ac6f8c17244b2716aea06b..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_0.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 0)"""
-
-from . import _maker
-
-dataset = _maker("fold_0")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_0_rgb.py b/src/ptbench/configs/datasets/mc_ch_in/fold_0_rgb.py
deleted file mode 100644
index 9ff3224ab0bfd80ab4e5bf4a7581a9debffb12ec..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_0_rgb.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 0, RGB)"""
-
-from . import _maker
-
-dataset = _maker("fold_0_rgb")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_1.py b/src/ptbench/configs/datasets/mc_ch_in/fold_1.py
deleted file mode 100644
index 2d3c5fad142e55ead6da70db0a57985ca457009d..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_1.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 1)"""
-
-from . import _maker
-
-dataset = _maker("fold_1")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_1_rgb.py b/src/ptbench/configs/datasets/mc_ch_in/fold_1_rgb.py
deleted file mode 100644
index b478b75b8800fe153eaa939d0e6707bfd7aac150..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_1_rgb.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 1, RGB)"""
-
-from . import _maker
-
-dataset = _maker("fold_1_rgb")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_2.py b/src/ptbench/configs/datasets/mc_ch_in/fold_2.py
deleted file mode 100644
index d726858c7c84251dc94f7d62ae43af7a3aea6b44..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_2.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 2)"""
-
-from . import _maker
-
-dataset = _maker("fold_2")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_2_rgb.py b/src/ptbench/configs/datasets/mc_ch_in/fold_2_rgb.py
deleted file mode 100644
index 0cf81050686c320a3519cd223b639e0ba87284fe..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_2_rgb.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 2, RGB)"""
-
-from . import _maker
-
-dataset = _maker("fold_2_rgb")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_3.py b/src/ptbench/configs/datasets/mc_ch_in/fold_3.py
deleted file mode 100644
index 92e1ac8d167321386a056fa5920bf6a94d0989f6..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_3.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 3)"""
-
-from . import _maker
-
-dataset = _maker("fold_3")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_3_rgb.py b/src/ptbench/configs/datasets/mc_ch_in/fold_3_rgb.py
deleted file mode 100644
index 23651bb05c2c43a06bc479e1c459ed3982127c2d..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_3_rgb.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 3, RGB)"""
-
-from . import _maker
-
-dataset = _maker("fold_3_rgb")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_4.py b/src/ptbench/configs/datasets/mc_ch_in/fold_4.py
deleted file mode 100644
index 6e3aaa3c0ee8fa920451798a281e495cb1e734ec..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_4.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 4)"""
-
-from . import _maker
-
-dataset = _maker("fold_4")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_4_rgb.py b/src/ptbench/configs/datasets/mc_ch_in/fold_4_rgb.py
deleted file mode 100644
index 9addb86a70bff81a2cf1d6d6e50edc885c435b58..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_4_rgb.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 4, RGB)"""
-
-from . import _maker
-
-dataset = _maker("fold_4_rgb")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_5.py b/src/ptbench/configs/datasets/mc_ch_in/fold_5.py
deleted file mode 100644
index edae2bae4ae11a8fd49c9fc5525e94b2bd56f59f..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_5.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 5)"""
-
-from . import _maker
-
-dataset = _maker("fold_5")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_5_rgb.py b/src/ptbench/configs/datasets/mc_ch_in/fold_5_rgb.py
deleted file mode 100644
index 20a0b32494da50d7424b325e1835ce13abb32ac1..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_5_rgb.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 5, RGB)"""
-
-from . import _maker
-
-dataset = _maker("fold_5_rgb")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_6.py b/src/ptbench/configs/datasets/mc_ch_in/fold_6.py
deleted file mode 100644
index 5ae1c3cc414fe85e7a41d6595aa93916c5cbd504..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_6.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 6)"""
-
-from . import _maker
-
-dataset = _maker("fold_6")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_6_rgb.py b/src/ptbench/configs/datasets/mc_ch_in/fold_6_rgb.py
deleted file mode 100644
index 874057b36f397af6828e32a4cea43f0bba6b7142..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_6_rgb.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 6, RGB)"""
-
-from . import _maker
-
-dataset = _maker("fold_6_rgb")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_7.py b/src/ptbench/configs/datasets/mc_ch_in/fold_7.py
deleted file mode 100644
index 5ab352c67e0b03151b9925eff39197d2c3be54d7..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_7.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 7)"""
-
-from . import _maker
-
-dataset = _maker("fold_7")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_7_rgb.py b/src/ptbench/configs/datasets/mc_ch_in/fold_7_rgb.py
deleted file mode 100644
index 5014ff5bfa01130e003f669abeb0a9d1b7367391..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_7_rgb.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 7, RGB)"""
-
-from . import _maker
-
-dataset = _maker("fold_7_rgb")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_8.py b/src/ptbench/configs/datasets/mc_ch_in/fold_8.py
deleted file mode 100644
index 49ec1c405da89d2f87b5065207e3ad6015765c18..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_8.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 8)"""
-
-from . import _maker
-
-dataset = _maker("fold_8")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_8_rgb.py b/src/ptbench/configs/datasets/mc_ch_in/fold_8_rgb.py
deleted file mode 100644
index deb1e4a9d3788d4041a253939f8d2e48fc8eef6a..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_8_rgb.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 8, RGB)"""
-
-from . import _maker
-
-dataset = _maker("fold_8_rgb")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_9.py b/src/ptbench/configs/datasets/mc_ch_in/fold_9.py
deleted file mode 100644
index b701a9c888facf74973880579b333bcbbf3e1ddf..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_9.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 9)"""
-
-from . import _maker
-
-dataset = _maker("fold_9")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/fold_9_rgb.py b/src/ptbench/configs/datasets/mc_ch_in/fold_9_rgb.py
deleted file mode 100644
index a6b3b43b273fa3cf2cd1d0e8023419984cee4e44..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/fold_9_rgb.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian datasets
-(cross validation fold 9, RGB)"""
-
-from . import _maker
-
-dataset = _maker("fold_9_rgb")
diff --git a/src/ptbench/configs/datasets/mc_ch_in/rgb.py b/src/ptbench/configs/datasets/mc_ch_in/rgb.py
deleted file mode 100644
index 5f0d47577671aad992e158ad5d7fe1ccc379a1a4..0000000000000000000000000000000000000000
--- a/src/ptbench/configs/datasets/mc_ch_in/rgb.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Copyright © 2023 Idiap Research Institute <contact@idiap.ch>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-"""Aggregated dataset composed of Montgomery, Shenzhen and Indian (RGB)
-datasets."""
-
-from . import _maker
-
-dataset = _maker("rgb")
diff --git a/src/ptbench/data/mc_ch_in/__init__.py b/src/ptbench/data/mc_ch_in/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..662d5c1326651b4d9f48d47bc4b503df23d17216
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/__init__.py
@@ -0,0 +1,3 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/src/ptbench/data/mc_ch_in/default.py b/src/ptbench/data/mc_ch_in/default.py
new file mode 100644
index 0000000000000000000000000000000000000000..7d2d6fc0accce0409d0eb0ae51c7ffba03bada15
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/default.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.default import datamodule as indian_datamodule
+from ..montgomery.default import datamodule as mc_datamodule
+from ..shenzhen.default import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_0.py b/src/ptbench/data/mc_ch_in/fold_0.py
new file mode 100644
index 0000000000000000000000000000000000000000..66e9e07e32c51453a6ac379e6749acb5891e638a
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_0.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_0 import datamodule as indian_datamodule
+from ..montgomery.fold_0 import datamodule as mc_datamodule
+from ..shenzhen.fold_0 import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_0_rgb.py b/src/ptbench/data/mc_ch_in/fold_0_rgb.py
new file mode 100644
index 0000000000000000000000000000000000000000..bb4b7fc1f4d034e68c774846da7dbd2909457ccf
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_0_rgb.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_0_rgb import datamodule as indian_datamodule
+from ..montgomery.fold_0_rgb import datamodule as mc_datamodule
+from ..shenzhen.fold_0_rgb import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_1.py b/src/ptbench/data/mc_ch_in/fold_1.py
new file mode 100644
index 0000000000000000000000000000000000000000..d98c097e234ec0521a3853e650961655951d6b9a
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_1.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_1 import datamodule as indian_datamodule
+from ..montgomery.fold_1 import datamodule as mc_datamodule
+from ..shenzhen.fold_1 import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_1_rgb.py b/src/ptbench/data/mc_ch_in/fold_1_rgb.py
new file mode 100644
index 0000000000000000000000000000000000000000..32a94a5d68567ab4361686ac11118330e0b911b0
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_1_rgb.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_1_rgb import datamodule as indian_datamodule
+from ..montgomery.fold_1_rgb import datamodule as mc_datamodule
+from ..shenzhen.fold_1_rgb import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_2.py b/src/ptbench/data/mc_ch_in/fold_2.py
new file mode 100644
index 0000000000000000000000000000000000000000..15eaf1aa9c6515c3d8e892930baa00fb2c9f0aac
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_2.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_2 import datamodule as indian_datamodule
+from ..montgomery.fold_2 import datamodule as mc_datamodule
+from ..shenzhen.fold_2 import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_2_rgb.py b/src/ptbench/data/mc_ch_in/fold_2_rgb.py
new file mode 100644
index 0000000000000000000000000000000000000000..4582172feaf3eaa390b1d403c6c2cc6d92757e58
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_2_rgb.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_2_rgb import datamodule as indian_datamodule
+from ..montgomery.fold_2_rgb import datamodule as mc_datamodule
+from ..shenzhen.fold_2_rgb import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_3.py b/src/ptbench/data/mc_ch_in/fold_3.py
new file mode 100644
index 0000000000000000000000000000000000000000..54b8e1c56c8f0d4b07d5c5d96930dfd0a2dac401
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_3.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_3 import datamodule as indian_datamodule
+from ..montgomery.fold_3 import datamodule as mc_datamodule
+from ..shenzhen.fold_3 import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_3_rgb.py b/src/ptbench/data/mc_ch_in/fold_3_rgb.py
new file mode 100644
index 0000000000000000000000000000000000000000..bcc22dad4850153e13dcb9c0fb6428555ec2d25e
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_3_rgb.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_3_rgb import datamodule as indian_datamodule
+from ..montgomery.fold_3_rgb import datamodule as mc_datamodule
+from ..shenzhen.fold_3_rgb import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_4.py b/src/ptbench/data/mc_ch_in/fold_4.py
new file mode 100644
index 0000000000000000000000000000000000000000..a3dde80192f8e922bec9f0aae4aaf7bc85a75b40
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_4.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_4 import datamodule as indian_datamodule
+from ..montgomery.fold_4 import datamodule as mc_datamodule
+from ..shenzhen.fold_4 import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_4_rgb.py b/src/ptbench/data/mc_ch_in/fold_4_rgb.py
new file mode 100644
index 0000000000000000000000000000000000000000..ee076ac0930f63bf0ebebb579ff0e4189d555b37
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_4_rgb.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_4_rgb import datamodule as indian_datamodule
+from ..montgomery.fold_4_rgb import datamodule as mc_datamodule
+from ..shenzhen.fold_4_rgb import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_5.py b/src/ptbench/data/mc_ch_in/fold_5.py
new file mode 100644
index 0000000000000000000000000000000000000000..dcbf4fbb3721786b7953a0366df6f9ca1bf0077a
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_5.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_5 import datamodule as indian_datamodule
+from ..montgomery.fold_5 import datamodule as mc_datamodule
+from ..shenzhen.fold_5 import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_5_rgb.py b/src/ptbench/data/mc_ch_in/fold_5_rgb.py
new file mode 100644
index 0000000000000000000000000000000000000000..660037c67dc0c3fc878179d398fb95a73189cfb4
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_5_rgb.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_5_rgb import datamodule as indian_datamodule
+from ..montgomery.fold_5_rgb import datamodule as mc_datamodule
+from ..shenzhen.fold_5_rgb import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_6.py b/src/ptbench/data/mc_ch_in/fold_6.py
new file mode 100644
index 0000000000000000000000000000000000000000..20a797cb6060577501835e71ea0d079f8b78f8ae
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_6.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_6 import datamodule as indian_datamodule
+from ..montgomery.fold_6 import datamodule as mc_datamodule
+from ..shenzhen.fold_6 import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_6_rgb.py b/src/ptbench/data/mc_ch_in/fold_6_rgb.py
new file mode 100644
index 0000000000000000000000000000000000000000..a90cbfea5c34c1b1610d88fceccd224524e1e311
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_6_rgb.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_6_rgb import datamodule as indian_datamodule
+from ..montgomery.fold_6_rgb import datamodule as mc_datamodule
+from ..shenzhen.fold_6_rgb import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_7.py b/src/ptbench/data/mc_ch_in/fold_7.py
new file mode 100644
index 0000000000000000000000000000000000000000..086f2503bb204797562a2dabe63c404be8a6ca13
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_7.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_7 import datamodule as indian_datamodule
+from ..montgomery.fold_7 import datamodule as mc_datamodule
+from ..shenzhen.fold_7 import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_7_rgb.py b/src/ptbench/data/mc_ch_in/fold_7_rgb.py
new file mode 100644
index 0000000000000000000000000000000000000000..b8efe821d581ce2a645da30bc6d3a35a300b9639
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_7_rgb.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_7_rgb import datamodule as indian_datamodule
+from ..montgomery.fold_7_rgb import datamodule as mc_datamodule
+from ..shenzhen.fold_7_rgb import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_8.py b/src/ptbench/data/mc_ch_in/fold_8.py
new file mode 100644
index 0000000000000000000000000000000000000000..a02325aab8876f1721346d07c1d573099b64a827
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_8.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_8 import datamodule as indian_datamodule
+from ..montgomery.fold_8 import datamodule as mc_datamodule
+from ..shenzhen.fold_8 import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_8_rgb.py b/src/ptbench/data/mc_ch_in/fold_8_rgb.py
new file mode 100644
index 0000000000000000000000000000000000000000..190440f50440d3ce76414b6d53a1c29ece3adb0e
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_8_rgb.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_8_rgb import datamodule as indian_datamodule
+from ..montgomery.fold_8_rgb import datamodule as mc_datamodule
+from ..shenzhen.fold_8_rgb import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_9.py b/src/ptbench/data/mc_ch_in/fold_9.py
new file mode 100644
index 0000000000000000000000000000000000000000..bf14f21f42edc11e0b9d74b1f8dd55989df9ae2a
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_9.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_9 import datamodule as indian_datamodule
+from ..montgomery.fold_9 import datamodule as mc_datamodule
+from ..shenzhen.fold_9 import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/fold_9_rgb.py b/src/ptbench/data/mc_ch_in/fold_9_rgb.py
new file mode 100644
index 0000000000000000000000000000000000000000..7a7bc632e70cfa0ca78ddb635bd7a72d4221b8eb
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/fold_9_rgb.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.fold_9_rgb import datamodule as indian_datamodule
+from ..montgomery.fold_9_rgb import datamodule as mc_datamodule
+from ..shenzhen.fold_9_rgb import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule
diff --git a/src/ptbench/data/mc_ch_in/rgb.py b/src/ptbench/data/mc_ch_in/rgb.py
new file mode 100644
index 0000000000000000000000000000000000000000..e10748b2ebfbd6eb97b2c5d7339a3c11d730006c
--- /dev/null
+++ b/src/ptbench/data/mc_ch_in/rgb.py
@@ -0,0 +1,81 @@
+# Copyright © 2022 Idiap Research Institute <contact@idiap.ch>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Aggregated dataset composed of Montgomery and Shenzhen datasets."""
+
+from clapper.logging import setup
+from torch.utils.data.dataset import ConcatDataset
+
+from .. import return_subsets
+from ..base_datamodule import BaseDataModule, get_dataset_from_module
+from ..indian.rgb import datamodule as indian_datamodule
+from ..montgomery.rgb import datamodule as mc_datamodule
+from ..shenzhen.rgb import datamodule as ch_datamodule
+
+logger = setup(__name__.split(".")[0], format="%(levelname)s: %(message)s")
+
+
+class DefaultModule(BaseDataModule):
+    def __init__(
+        self,
+        train_batch_size=1,
+        predict_batch_size=1,
+        drop_incomplete_batch=False,
+        multiproc_kwargs=None,
+    ):
+        self.train_batch_size = train_batch_size
+        self.predict_batch_size = predict_batch_size
+        self.drop_incomplete_batch = drop_incomplete_batch
+        self.multiproc_kwargs = multiproc_kwargs
+
+        super().__init__(
+            train_batch_size=train_batch_size,
+            predict_batch_size=predict_batch_size,
+            drop_incomplete_batch=drop_incomplete_batch,
+            multiproc_kwargs=multiproc_kwargs,
+        )
+
+    def setup(self, stage: str):
+        # Instantiate other datamodules and get their datasets
+
+        module_args = {
+            "train_batch_size": self.train_batch_size,
+            "predict_batch_size": self.predict_batch_size,
+            "drop_incomplete_batch": self.drop_incomplete_batch,
+            "multiproc_kwargs": self.multiproc_kwargs,
+        }
+
+        mc = get_dataset_from_module(mc_datamodule, stage, **module_args)
+        ch = get_dataset_from_module(ch_datamodule, stage, **module_args)
+        indian = get_dataset_from_module(
+            indian_datamodule, stage, **module_args
+        )
+
+        # Combine datasets
+        self.dataset = {}
+        self.dataset["__train__"] = ConcatDataset(
+            [mc["__train__"], ch["__train__"], indian["__train__"]]
+        )
+        self.dataset["train"] = ConcatDataset(
+            [mc["train"], ch["train"], indian["train"]]
+        )
+        self.dataset["__valid__"] = ConcatDataset(
+            [mc["__valid__"], ch["__valid__"], indian["__valid__"]]
+        )
+        self.dataset["validation"] = ConcatDataset(
+            [mc["validation"], ch["validation"], indian["validation"]]
+        )
+        self.dataset["test"] = ConcatDataset(
+            [mc["test"], ch["test"], indian["test"]]
+        )
+
+        (
+            self.train_dataset,
+            self.validation_dataset,
+            self.extra_validation_datasets,
+            self.predict_dataset,
+        ) = return_subsets(self.dataset)
+
+
+datamodule = DefaultModule