diff --git a/notebooks/Gotthard2/Characterize_Darks_Gotthard2_NBC.ipynb b/notebooks/Gotthard2/Characterize_Darks_Gotthard2_NBC.ipynb
index 547fc77e307aee0b3e820c525ed0434d0e2b7af6..2b63c4f9b1e983cb556ddf6ba2480600553aa813 100644
--- a/notebooks/Gotthard2/Characterize_Darks_Gotthard2_NBC.ipynb
+++ b/notebooks/Gotthard2/Characterize_Darks_Gotthard2_NBC.ipynb
@@ -135,8 +135,8 @@
     "run_dc = RunDirectory(in_folder / f\"r{run_nums[0]:04d}\")\n",
     "proposal = list(filter(None, str(in_folder).strip('/').split('/')))[-2]\n",
     "file_loc = raw_data_location_string(proposal, run_nums)\n",
-    "receiver_names = [f\"*{receiver_template.format(x)}:daqOutput\" for x in receiver_affixes]\n",
-    "data_sources = list(run_dc.select(receiver_names).all_sources)"
+    "da_to_source = gotthard2lib.map_da_to_source(\n",
+    "    karabo_da, receiver_affixes, receiver_template, run_dc)"
    ]
   },
   {
@@ -329,7 +329,7 @@
     "for mod in karabo_da:\n",
     "    # For 50um idx always 0. For 25um pick the right data source\n",
     "    # from list of 2 sources.\n",
-    "    src = data_sources[da_to_pdu[mod][\"idx\"]]\n",
+    "    src = da_to_source[mod]\n",
     "\n",
     "    # Retrieve LUT constant\n",
     "    lut, time = get_constant_from_db_and_time(\n",
diff --git a/notebooks/Gotthard2/Correction_Gotthard2_NBC.ipynb b/notebooks/Gotthard2/Correction_Gotthard2_NBC.ipynb
index 03ece08777ef83059deb6f1a7945e7a326c9c757..3a0f6234ca23e2088ee72ddd73ff331ce6a1bd3c 100644
--- a/notebooks/Gotthard2/Correction_Gotthard2_NBC.ipynb
+++ b/notebooks/Gotthard2/Correction_Gotthard2_NBC.ipynb
@@ -66,7 +66,7 @@
     "ctrl_source_template = \"{}/DET/{}\"  # template for control source name (filled with karabo_id_control)\n",
     "karabo_id_control = \"\"  # Control karabo ID. Set to empty string to use the karabo-id\n",
     "corr_source_template = \"{}/CORR/{}:daqOutput\"  # Correction data source template. filled with karabo_id and correction receiver\n",
-    "corr_receiver = \"\"  # The receiver name of the corrected data. Leave empty for using the same receiver name for the 50um GH2 or the first(Master) receiver for the 25um GH2.\n",
+    "corr_receiver = \"\"  # Receiver name for corrected data. Leave empty to use the default receiver: - For 50um GH2 data, it will use the same receiver name - For 25um GH2 data, it will use the first (e.g. .._Master) receiver. Specifying a receiver name is recommended.\n",
     "\n",
     "# Parameters for calibration database.\n",
     "cal_db_interface = \"tcp://max-exfl-cal001:8016#8025\"  # the database interface to use.\n",
@@ -240,16 +240,15 @@
     "\n",
     "print(f\"Process modules: {db_modules} for run {run}\")\n",
     "\n",
-    "# Create the correction receiver name.\n",
-    "receiver_names = [f\"*{receiver_template.format(x)}:daqOutput\" for x in receiver_affixes]\n",
-    "data_sources = list(run_dc.select(receiver_names).all_sources)\n",
-    "\n",
+    "da_to_source = gotthard2lib.map_da_to_source(\n",
+    "    karabo_da, receiver_affixes, receiver_template, run_dc)\n",
+    "data_sources = list(da_to_source.values())\n",
     "if not corr_receiver:\n",
-    "    # This part assumes this data_source structure: '{karabo_id}/DET/{receiver_name}:{output_channel}'\n",
-    "    if gh2_detector == \"25um\":  # For 25um use virtual karabo_das for CALCAT data mapping.\n",
-    "        corr_receiver = data_sources[0].split(\"/\")[-1].split(\":\")[0]\n",
-    "    else:\n",
-    "        corr_receiver = data_sources[0].split(\"/\")[-1].split(\":\")[0]\n",
+    "    # Defaulting to the first receiver from data_sources.\n",
+    "    # Format expected: '{karabo_id}/DET/{receiver_name}:{output_channel}'.\n",
+    "    # This is acceptable for 50um data but may not be ideal for 25um data. \n",
+    "    # Using corr_receiver is recommended when possible.\n",
+    "    corr_receiver = data_sources[0].split(\"/\")[-1].split(\":\")[0]\n",
     "    print(f\"Using {corr_receiver} as a receiver name for the corrected data.\")"
    ]
   },
@@ -261,7 +260,8 @@
    "outputs": [],
    "source": [
     "# Check the available trains to correct.\n",
-    "total_trains = len(RunDirectory(run_folder).select(data_sources, require_all=True).train_ids)\n",
+    "total_trains = len(\n",
+    "    RunDirectory(run_folder).select(data_sources, require_all=True).train_ids)\n",
     "if total_trains:\n",
     "    print(f\"Correcting {total_trains}.\")\n",
     "else:\n",
@@ -450,7 +450,8 @@
     "    else:\n",
     "        data_stored, gain_stored, mask_stored = None, None, None\n",
     "\n",
-    "    for i, (src, mod) in enumerate(zip(data_sources, karabo_da)):\n",
+    "    for i, mod in enumerate(karabo_da):\n",
+    "        src = da_to_source[mod]\n",
     "        step_timer.start()\n",
     "        print(f\"Correcting {src} for {raw_file}\")\n",
     "\n",
diff --git a/src/cal_tools/gotthard2/gotthard2lib.py b/src/cal_tools/gotthard2/gotthard2lib.py
index 8b24818332c419c44a6a5a4db5abca5aaa28c6f1..d6fa4eba67935baffbcf460ad68a3379212d32f4 100644
--- a/src/cal_tools/gotthard2/gotthard2lib.py
+++ b/src/cal_tools/gotthard2/gotthard2lib.py
@@ -5,6 +5,22 @@ from typing import List, Union
 import extra_data
 
 
+def map_da_to_source(
+    da, affixes, template, dc):
+    if len(affixes) != len(da):
+        raise ValueError(
+            "receiver_affixes & karabo_da are not the same length")
+
+    da_to_source = {}
+    for da, aff in zip(da, affixes):
+        sources = dc.select(f"*{template.format(aff)}:daqOutput").all_sources
+        if len(sources) != 1:
+            raise ValueError(f"No/multiple sources found for {aff!r}")
+        da_to_source[da] = list(sources)[0]
+
+    return da_to_source
+
+
 class Gotthard2Ctrl():
     def __init__(
         self,