diff --git a/bin/slurm_calibrate.sh b/bin/slurm_calibrate.sh
index a22f322e802cf1949599d7c3aa78f2aaf0e2478d..700f21c8939dfae81f99da12df718c56726ccbc1 100755
--- a/bin/slurm_calibrate.sh
+++ b/bin/slurm_calibrate.sh
@@ -1,4 +1,6 @@
 #!/bin/bash
+# This script is used to run a parameterised copy of a Jupyter notebook. It is
+# typically run through Slurm with the sbatch command.
 
 set -euo pipefail
 
diff --git a/src/xfel_calibrate/calibrate.py b/src/xfel_calibrate/calibrate.py
index a6bf414b24bebb459d941fb019f7c5a1152d7de1..ee8bd63c407fc12ec271705f33a944689fc022e1 100755
--- a/src/xfel_calibrate/calibrate.py
+++ b/src/xfel_calibrate/calibrate.py
@@ -8,6 +8,7 @@ import math
 import os
 import pprint
 import re
+import shutil
 import stat
 import string
 import sys
@@ -771,7 +772,7 @@ def prepare_job(
     nbformat.write(new_nb, nbpath)
 
     return JobArgs([
-        "{pkg_dir}/bin/slurm_calibrate.sh",
+        "pycalib-run-nb.sh",
         new_name,
         "{python}",
         cluster_profile,
@@ -793,9 +794,7 @@ class JobArgs:
         return isinstance(other, JobArgs) and (self.args == other.args)
 
     def format_cmd(self, python):
-        return [a.format(
-            python=python, pkg_dir=PKG_DIR
-        ) for a in self.args]
+        return [a.format(python=python) for a in self.args]
 
     def run_direct(self, work_dir, python) -> int:
         return call(self.format_cmd(python), cwd=work_dir)
@@ -1014,6 +1013,12 @@ def run():
     # And save the invocation of this script itself
     save_executed_command(run_tmp_path, version)
 
+    # Copy the bash script which will be used to run notebooks
+    shutil.copy2(
+        os.path.join(PKG_DIR, "bin", "slurm_calibrate.sh"),
+        os.path.join(run_tmp_path, "pycalib-run-nb.sh")
+    )
+
     # wait on all jobs to run and then finalize the run by creating a report from the notebooks
     out_path = Path(default_report_path) / detector.upper() / caltype.upper() / datetime.now().isoformat()
     if try_report_to_output: