diff --git a/notebooks/LPD/LPDChar_Darks_NBC.ipynb b/notebooks/LPD/LPDChar_Darks_NBC.ipynb
index de76f651d6b3f713b3e96102a8dd793eb850a3d9..bae9e2fb0649c67f53e73471c0ad9b32bef40ef6 100644
--- a/notebooks/LPD/LPDChar_Darks_NBC.ipynb
+++ b/notebooks/LPD/LPDChar_Darks_NBC.ipynb
@@ -33,6 +33,7 @@
     "karabo_id = \"FXE_DET_LPD1M-1\" # karabo karabo_id\n",
     "karabo_da = ['-1']  # a list of data aggregators names, Default [-1] for selecting all data aggregators\n",
     "source_name = \"{}/DET/{}CH0:xtdf\"  # Source name for raw detector data - filled with karabo_id & module number\n",
+    "ctrl_src_template =  \"{}/COMP/FEM_MDL_COMP\"  # Control device source name template.\n",
     "\n",
     "use_dir_creation_date = True # use the creation date of the directory for database time derivation\n",
     "cal_db_interface = \"tcp://max-exfl-cal001:8015#8025\" # the database interface to use\n",
@@ -97,7 +98,10 @@
     "from extra_data import RunDirectory\n",
     "\n",
     "from cal_tools.enums import BadPixels\n",
-    "from cal_tools.lpdlib import make_cell_order_condition\n",
+    "from cal_tools.lpdlib import (\n",
+    "    make_cell_order_condition,\n",
+    "    sort_dark_runs_by_gain,\n",
+    ")\n",
     "from cal_tools.plotting import (\n",
     "    create_constant_overview,\n",
     "    plot_badpix_3d,\n",
@@ -114,6 +118,7 @@
     "    map_gain_stages,\n",
     "    module_index_to_qm,\n",
     "    parse_runs,\n",
+    "    raw_data_location_string,\n",
     "    reorder_axes,\n",
     "    run_prop_seq_from_path,\n",
     "    save_const_to_h5,\n",
@@ -131,7 +136,12 @@
     "max_cells = mem_cells\n",
     "cells = np.arange(max_cells)\n",
     "gain_names = ['High', 'Medium', 'Low']\n",
-    "    \n",
+    "# Check dark runs order and sort if needed.\n",
+    "run_nums = sort_dark_runs_by_gain(\n",
+    "    raw_folder=in_folder,\n",
+    "    runs=[run_high, run_med, run_low],\n",
+    "    ctrl_src=ctrl_src_template.format(karabo_id),\n",
+    ")\n",
     "if karabo_da[0] == '-1':\n",
     "    if modules[0] == -1:\n",
     "        modules = list(range(16))\n",
@@ -143,7 +153,7 @@
     "\n",
     "creation_time = None\n",
     "if use_dir_creation_date:\n",
-    "    creation_time = get_dir_creation_date(in_folder, run_high)\n",
+    "    creation_time = get_dir_creation_date(in_folder, run_nums[0])\n",
     "    print(\"Using {} as creation time\".format(creation_time))\n",
     "\n",
     "if inject_cell_order not in {'auto', 'always', 'never'}:\n",
@@ -157,7 +167,7 @@
     "print('CalDB Interface {}'.format(cal_db_interface))\n",
     "print(\"Proposal: {}\".format(prop))\n",
     "print(\"Memory cells: {}/{}\".format(mem_cells, max_cells))\n",
-    "print(\"Runs: {}, {}, {}\".format(run_high, run_med, run_low))\n",
+    "print(\"Runs: {}\".format(run_nums))\n",
     "print(\"Using DB: {}\".format(db_output))\n",
     "print(\"Input: {}\".format(in_folder))\n",
     "print(\"Output: {}\".format(out_folder))\n",
@@ -275,7 +285,7 @@
     "\n",
     "\n",
     "inp = []\n",
-    "for gg, run_num in enumerate([run_high, run_med, run_low]):\n",
+    "for gg, run_num in enumerate(run_nums):\n",
     "    run_path = Path(in_folder, f\"r{run_num:04d}\")\n",
     "    for i in modules:\n",
     "        inp.append((run_path, i, gg))\n",
@@ -334,7 +344,7 @@
    "source": [
     "# Read report path and create file location tuple to add with the injection\n",
     "proposal = list(filter(None, in_folder.strip('/').split('/')))[-2]\n",
-    "file_loc = 'proposal:{} runs:{} {} {}'.format(proposal, run_low, run_med, run_high)\n",
+    "file_loc = raw_data_location_string(proposal, run_nums)\n",
     "\n",
     "report = get_report(metadata_folder)"
    ]
diff --git a/notebooks/LPDMini/LPD_Mini_Char_Darks_NBC.ipynb b/notebooks/LPDMini/LPD_Mini_Char_Darks_NBC.ipynb
index a875f52a4c458590bbaae4c4fe3d08035628eab1..f3ccaa445187d055eac71d04cee66cebc6df8554 100644
--- a/notebooks/LPDMini/LPD_Mini_Char_Darks_NBC.ipynb
+++ b/notebooks/LPDMini/LPD_Mini_Char_Darks_NBC.ipynb
@@ -88,13 +88,17 @@
     "\n",
     "from cal_tools.calcat_interface import CalCatApi\n",
     "from cal_tools.enums import BadPixels\n",
-    "from cal_tools.lpdlib import make_cell_order_condition\n",
+    "from cal_tools.lpdlib import (\n",
+    "    make_cell_order_condition,\n",
+    "    sort_dark_runs_by_gain,\n",
+    ")\n",
     "from cal_tools.plotting import plot_badpix_3d\n",
     "from cal_tools.restful_config import calibration_client\n",
     "from cal_tools.tools import (\n",
     "    calcat_creation_time,\n",
     "    get_from_db,\n",
     "    get_report,\n",
+    "    raw_data_location_string,\n",
     "    run_prop_seq_from_path,\n",
     "    save_const_to_h5,\n",
     "    send_to_db,\n",
@@ -110,28 +114,35 @@
     "mem_cells = 512\n",
     "gain_names = ['High', 'Medium', 'Low']\n",
     "const_shape = (mem_cells, 32, 256, 3)  # cells, slow_scan, fast_scan, gain\n",
-    "    \n",
+    "\n",
+    "source_name = source_name.format(karabo_id)\n",
+    "control_source_name = control_source_name.format(karabo_id)\n",
+    "\n",
+    "# Check dark runs order and sort if needed.\n",
+    "run_nums = sort_dark_runs_by_gain(\n",
+    "    raw_folder=in_folder,\n",
+    "    runs=[run_high, run_med, run_low],\n",
+    "    ctrl_src=control_source_name.format(karabo_id),\n",
+    ")\n",
+    "\n",
     "gain_runs = {}\n",
     "if capacitor_setting == 5:\n",
-    "    gain_runs[\"high_5pf\"] = run_high\n",
-    "    gain_runs[\"med_5pf\"] =  run_med\n",
-    "    gain_runs[\"low_5pf\"] =  run_low\n",
+    "    gain_runs[\"high_5pf\"] = run_nums[0]\n",
+    "    gain_runs[\"med_5pf\"] =  run_nums[1]\n",
+    "    gain_runs[\"low_5pf\"] =  run_nums[2]\n",
     "elif capacitor_setting == 50:\n",
-    "    gain_runs[\"high_50pf\"] = run_high\n",
-    "    gain_runs[\"med_50pf\"] =  run_med\n",
-    "    gain_runs[\"low_50pf\"] =  run_low\n",
+    "    gain_runs[\"high_50pf\"] = run_nums[0]\n",
+    "    gain_runs[\"med_50pf\"] =  run_nums[1]\n",
+    "    gain_runs[\"low_50pf\"] =  run_nums[2]\n",
     "\n",
     "capacitor_settings = [capacitor_setting]\n",
     "capacitor_settings = ['{}pf'.format(c) for c in capacitor_settings]\n",
     "\n",
-    "creation_time = calcat_creation_time(in_folder, run_high, creation_time)\n",
+    "creation_time = calcat_creation_time(in_folder, run_nums[0], creation_time)\n",
     "print(f\"Using {creation_time} as creation time\")\n",
     "\n",
-    "source_name = source_name.format(karabo_id)\n",
-    "control_source_name = control_source_name.format(karabo_id)\n",
-    "\n",
     "if -1 in {bias_voltage_0, bias_voltage_1}:\n",
-    "    run_data = RunDirectory(os.path.join(in_folder, f\"r{run_high:04d}\"))\n",
+    "    run_data = RunDirectory(os.path.join(in_folder, f\"r{run_nums[0]:04d}\"))\n",
     "    if bias_voltage_0 == -1:\n",
     "        bias_voltage_0 = run_data[control_source_name, 'sensorBiasVoltage0'].as_single_value(atol=5.)\n",
     "    if bias_voltage_1 == -1:\n",
@@ -143,7 +154,7 @@
     "print(f'CalDB Interface {cal_db_interface}')\n",
     "print(f\"Proposal: {prop}\")\n",
     "print(f\"Memory cells: {mem_cells}\")\n",
-    "print(f\"Runs: {run_high}, {run_med}, {run_low}\")\n",
+    "print(f\"Runs: {run_nums}\")\n",
     "print(f\"Using DB: {db_output}\")\n",
     "print(f\"Input: {in_folder}\")\n",
     "print(f\"Output: {out_folder}\")\n",
@@ -331,7 +342,7 @@
    "source": [
     "# Read report path and create file location tuple to add with the injection\n",
     "proposal = list(filter(None, in_folder.strip('/').split('/')))[-2]\n",
-    "file_loc = 'proposal:{} runs:{} {} {}'.format(proposal, run_low, run_med, run_high)\n",
+    "file_loc = raw_data_location_string(proposal, run_nums)\n",
     "\n",
     "report = get_report(metadata_folder)"
    ]
diff --git a/src/cal_tools/lpdlib.py b/src/cal_tools/lpdlib.py
index b61652b33005bf31e1838103c9d5fb59c2f889c9..deb38f44b613e96570a2c10cd003ff54a23a6804 100644
--- a/src/cal_tools/lpdlib.py
+++ b/src/cal_tools/lpdlib.py
@@ -1,9 +1,12 @@
 import copy
+from logging import warning
+from pathlib import Path
 from typing import List, Optional, Tuple
 from warnings import warn
 
 import h5py
 import numpy as np
+from extra_data import RunDirectory
 from iCalibrationDB import Conditions, Constants, Detectors
 
 from cal_tools.enums import BadPixels
@@ -807,3 +810,41 @@ def make_cell_order_condition(use_param, cellid_pattern) -> Optional[str]:
         use = (use_param == 'always')
 
     return (",".join([str(c) for c in cellid_pattern]) + ",") if use else None
+
+
+def sort_dark_runs_by_gain(raw_folder, runs, ctrl_src):
+    """Check gain factors [100, 10, 1] to decide,
+    if provided dark runs are in the correct order.
+    
+    Args:
+        raw_folder (Union[str, Path]): The raw data path.
+        runs (list): A list of 3 runs.
+        ctrl_src (str): The CTRL source to check `RUN/.../femAsicGain`.
+    Return:
+        (list): Sorted dark runs.
+    """
+    run_to_gain = dict()
+    expected_gain_factors = [100, 10, 1]
+    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_gain[r] = RunDirectory(
+            Path(raw_folder) / f"r{r:04d}").get_run_value(
+                ctrl_src, "femAsicGain")
+
+    if len(set(run_to_gain.values())) < 3:
+        raise ValueError(
+            f"Incorrect gain factors for the provided dark runs: {run_to_gain}."
+            f" The expected gain factors for these runs are {expected_gain_factors}.")
+
+    sorted_run_to_gain = dict(sorted(
+        run_to_gain.items(),
+        key=lambda x: expected_gain_factors.index(x[1])))
+
+    sorted_runs = list(sorted_run_to_gain.keys())
+    if list(run_to_gain.values()) != expected_gain_factors:
+        warning(
+            "Dark runs were incorrectly sorted and "
+            f"have now been corrected to: {sorted_runs}.")
+
+    return sorted_runs
diff --git a/src/cal_tools/tools.py b/src/cal_tools/tools.py
index 88ab28d1e03c23264bb77c1c9a0e6b707a1535a1..d9e5e5f9e420a41dfff546b38e95a5fbd81c7bf8 100644
--- a/src/cal_tools/tools.py
+++ b/src/cal_tools/tools.py
@@ -1044,3 +1044,24 @@ def reorder_axes(a, from_order, to_order):
     from_order = list(from_order)
     order = tuple([from_order.index(lbl) for lbl in to_order])
     return a.transpose(order)
+
+
+def raw_data_location_string(proposal: str, runs: List[int]):
+    """Create RAW data location string to inject as a
+    metadata along with the calibration parameters.
+
+    Args:
+        proposal (string): The proposal number including the preceding `p`.
+            e.g. p900203
+        runs (list): A list of the run numbers
+
+    Returns:
+        str: The string for raw data_location.
+            e.g. `proposal p900203 runs: 9008, 9009, 90010`
+    """
+    if not isinstance(proposal, str) or proposal[0] != "p":
+        raise ValueError(
+            "Invalid proposal format. The proposal should be a string with"
+            " a preceding 'p'. Example: 'p900203'")
+
+    return f"proposal:{proposal} runs:{' '.join(map(str, runs))}"
diff --git a/tests/test_cal_tools.py b/tests/test_cal_tools.py
index 3eb962b0ec1a12c29efd03584b77d5340cd277cf..577a82a4f57122b6153cd4ef92e5f548a424f1de 100644
--- a/tests/test_cal_tools.py
+++ b/tests/test_cal_tools.py
@@ -18,6 +18,7 @@ from cal_tools.tools import (
     get_pdu_from_db,
     map_seq_files,
     module_index_to_qm,
+    raw_data_location_string,
     recursive_update,
     send_to_db,
     write_constants_fragment,
@@ -567,3 +568,16 @@ def test_reorder_axes():
 
     to_order = ('gain', 'fast_scan', 'slow_scan', 'cells')
     assert reorder_axes(a, from_order, to_order).shape == (3, 256, 32, 10)
+
+
+def test_raw_data_location_string():
+    raw_data_loc = raw_data_location_string("p900203", [9008, 9009, 9010])
+    assert raw_data_loc == "proposal:p900203 runs:9008 9009 9010"
+
+
+def test_raise_raw_data_location_string():
+    with pytest.raises(ValueError):
+        raw_data_location_string(900203, [9008, 9009, 9010])
+
+    with pytest.raises(ValueError):
+        raw_data_location_string("900203", [9008, 9009, 9010])
diff --git a/tests/test_lpdlib.py b/tests/test_lpdlib.py
new file mode 100644
index 0000000000000000000000000000000000000000..09a5d5530b228b514ceaa849f52f40b1b03a8bc0
--- /dev/null
+++ b/tests/test_lpdlib.py
@@ -0,0 +1,29 @@
+import pytest
+
+from cal_tools.lpdlib import sort_dark_runs_by_gain
+
+
+@pytest.mark.requires_gpfs
+def test_sort_dark_runs_by_gain():
+    # TODO: update used raw data to test data when available.
+    raw_folder = "/gpfs/exfel/exp/CALLAB/202130/p900203/raw"
+    ctrl_src = "FXE_DET_LPD1M-1/COMP/FEM_MDL_COMP"
+    runs = [9008, 9010, 9009]
+    sorted_runs = sort_dark_runs_by_gain(raw_folder, runs, ctrl_src)
+    assert sorted_runs == [9008, 9009, 9010]
+
+
+@pytest.mark.requires_gpfs
+def test_raise_sort_dark_runs_by_gain():
+    # TODO: update used raw data to test data when available.
+    raw_folder = "/gpfs/exfel/exp/CALLAB/202130/p900203/raw"
+    ctrl_src = "FXE_DET_LPD1M-1/COMP/FEM_MDL_COMP"
+    runs = [9008, 9009]
+    with pytest.raises(AssertionError):  # Only two runs provided
+        sort_dark_runs_by_gain(raw_folder, runs, ctrl_src)
+
+    runs = [9008, 9008, 9009]  # Same two runs provided
+    with pytest.raises(AssertionError):
+        sort_dark_runs_by_gain(raw_folder, runs, ctrl_src)
+
+    #TODO: Add a ValueError check when more LPD dark runs added in p900203