diff --git a/notebooks/Gotthard2/Characterize_Darks_Gotthard2_NBC.ipynb b/notebooks/Gotthard2/Characterize_Darks_Gotthard2_NBC.ipynb
index 3a1edb65e7aa4b7208ec5886b500a9afc9c0c559..885d30e9f0030d1fbc72759e51f755faa22c747e 100644
--- a/notebooks/Gotthard2/Characterize_Darks_Gotthard2_NBC.ipynb
+++ b/notebooks/Gotthard2/Characterize_Darks_Gotthard2_NBC.ipynb
@@ -85,6 +85,7 @@
     "    calcat_creation_time,\n",
     "    get_constant_from_db_and_time,\n",
     "    get_report,\n",
+    "    raw_data_location_string,\n",
     "    save_const_to_h5,\n",
     "    send_to_db,\n",
     ")\n",
@@ -106,17 +107,22 @@
     "out_folder = Path(out_folder)\n",
     "out_folder.mkdir(parents=True, exist_ok=True)\n",
     "\n",
+    "if not karabo_id_control:\n",
+    "    karabo_id_control = karabo_id\n",
+    "\n",
     "ctrl_src = ctrl_source_template.format(karabo_id_control, control_template)\n",
+    "run_nums = gotthard2lib.sort_dark_runs_by_gain(\n",
+    "    raw_folder=in_folder,\n",
+    "    runs=run_nums,\n",
+    "    ctrl_src=ctrl_src,\n",
+    ")\n",
     "\n",
     "# Read report path to associate it later with injected constants.\n",
     "report = get_report(metadata_folder)\n",
     "\n",
     "# Run's creation time:\n",
-    "creation_time = calcat_creation_time(in_folder, run_high, creation_time)\n",
-    "print(f\"Creation time: {creation_time}\")\n",
-    "\n",
-    "if not karabo_id_control:\n",
-    "    karabo_id_control = karabo_id"
+    "creation_time = calcat_creation_time(in_folder, run_nums[0], creation_time)\n",
+    "print(f\"Creation time: {creation_time}\")"
    ]
   },
   {
@@ -126,8 +132,9 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "run_dc = RunDirectory(in_folder / f\"r{run_high:04d}\")\n",
-    "file_loc = f\"proposal:{run_dc.run_metadata()['proposalNumber']} runs:{run_high} {run_med} {run_low}\"  # noqa\n",
+    "run_dc = RunDirectory(in_folder / f\"r{run_nums[0]:04d}\")\n",
+    "file_loc = raw_data_location_string(\n",
+    "    f\"p{run_dc.run_metadata()['proposalNumber']}\", run_nums)\n",
     "receiver_names = [f\"*{receiver_template.format(x)}*\" for x in receiver_affixes]\n",
     "data_sources = sorted(list(run_dc.select(receiver_names).all_sources))"
    ]
@@ -154,7 +161,6 @@
     "step_timer.start()\n",
     "run_dcs_dict = dict()\n",
     "\n",
-    "ctrl_src = ctrl_source_template.format(karabo_id_control, control_template)\n",
     "conditions = {\n",
     "    \"bias_voltage\": set(),\n",
     "    \"exposure_time\": set(),\n",
diff --git a/src/cal_tools/gotthard2/gotthard2lib.py b/src/cal_tools/gotthard2/gotthard2lib.py
index 586c4af0120769f0afca6bcdd8f24f9d9858645a..061bea183c596e4cd48efbe250ec4f07bdabadc9 100644
--- a/src/cal_tools/gotthard2/gotthard2lib.py
+++ b/src/cal_tools/gotthard2/gotthard2lib.py
@@ -1,3 +1,7 @@
+from logging import warning
+from pathlib import Path
+from typing import List, Union
+
 import extra_data
 
 
@@ -58,3 +62,45 @@ class Gotthard2Ctrl():
         return bool(
                 self.run_dc[
                     self.ctrl_src, "reverseSlaveReadOutMode"].as_single_value())
+
+
+def sort_dark_runs_by_gain(
+    raw_folder: Union[str, Path],
+    runs: List[int],
+    ctrl_src: str,
+):
+    """Sort the three dark runs based /RUN/.../settings/.
+    The expected value options are [dynamicgain, fixgain1, fixgain2]
+    Args:
+        raw_folder (Union[str, Path]): The raw folder for the three runs to be sorted.
+        runs (list): A list of three dark runs.
+        ctrl_src: The CTRL source for checking `settings` dataset value.
+    Return:
+        List: Ordered list of runs.
+    """
+
+    run_to_setting = dict()
+    expected_settings = ["dynamicgain", "fixgain1", "fixgain2"]
+    assert len(set(runs)) == 3, f"A list of {len(runs)} runs is provided, three different dark runs are expected."  # noqa
+
+    for r in runs:
+        run_to_setting[r] = extra_data.RunDirectory(
+            Path(raw_folder) / f"r{r:04d}").get_run_value(
+                ctrl_src, "settings")
+
+    if len(set(run_to_setting.values())) < 3:
+        raise ValueError(
+            f"Incorrect gain settings for the provided dark runs: {run_to_setting}."
+            f" The expected settings for these runs are {expected_settings}.")
+
+    sorted_run_to_setting = dict(sorted(
+        run_to_setting.items(),
+        key=lambda x: expected_settings.index(x[1])))
+
+    sorted_runs = list(sorted_run_to_setting.keys())
+    if list(run_to_setting.values()) != expected_settings:
+        warning(
+            "Dark runs were incorrectly sorted and "
+            f"have now been corrected to: {sorted_runs}.")
+
+    return sorted_runs
diff --git a/tests/test_gotthard2lib.py b/tests/test_gotthard2lib.py
new file mode 100644
index 0000000000000000000000000000000000000000..713ddaa6e1c3a5d6509b6ef9cc541e010c164a0f
--- /dev/null
+++ b/tests/test_gotthard2lib.py
@@ -0,0 +1,26 @@
+import pytest
+
+from cal_tools.gotthard2.gotthard2lib import sort_dark_runs_by_gain
+
+# TODO: Uncomment when test proposal have GH2 dark runs.
+# xcaltst has no permission to access other than CALLAB RAW data.
+# @pytest.mark.requires_gpfs
+# def test_sort_dark_runs_by_gain():
+#     raw_folder = "/gpfs/exfel/exp/FXE/202231/p900298/raw"
+#     ctrl_src = "FXE_XAD_G2XES/DET/CONTROL"
+#     runs = [9, 8, 7]
+#     sorted_runs = sort_dark_runs_by_gain(raw_folder, runs, ctrl_src)
+#     assert sorted_runs == [7, 8, 9]
+
+
+# @pytest.mark.requires_gpfs
+# def test_raise_sort_dark_runs_by_gain():
+#     raw_folder = "/gpfs/exfel/exp/SA1/202331/p900384/raw"
+#     ctrl_src = "SA1_XTD9_HIREX/DET/GOTTHARD2_CTRL"
+#     runs = [60, 61, 62, 63]
+#     with pytest.raises(AssertionError):  # More than 3 runs
+#         sort_dark_runs_by_gain(raw_folder, runs, ctrl_src)
+
+#     runs = [89, 61, 63]  # dynamicgain, dynamicgain, fixgain2
+#     with pytest.raises(ValueError):  # Two high gain runs
+#         sort_dark_runs_by_gain(raw_folder, runs, ctrl_src)