From 0d42cb303bbdc46df69db5babe0554db426ddd35 Mon Sep 17 00:00:00 2001 From: Mirko Holler Date: Fri, 25 Sep 2026 14:31:49 +0200 Subject: [PATCH] fix(lamni,flomni): create documentation folder before writing the tomo PDF report PDFWriter does not create directories, so tomo_scan() failed with FileNotFoundError when ~/data/raw/documentation did not exist. Also add an omny TODO for porting the remaining ~/Data10 paths and the same folder fix. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_016gUjUT2xCNpnBQkThn3CqP --- .../bec_ipython_client/plugins/LamNI/lamni.py | 1 + .../plugins/flomni/flomni.py | 1 + .../TODO_data10_to_new_data_structure.md | 46 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 csaxs_bec/bec_ipython_client/plugins/omny/AI_docs/TODO_data10_to_new_data_structure.md diff --git a/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni.py b/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni.py index 79f91958..831a18fd 100644 --- a/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni.py +++ b/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni.py @@ -2492,6 +2492,7 @@ class LamNI(TomoQueueMixin, LamNIAlignmentMixin, LamNIOpticsMixin, LamniGuiTools user_target = os.path.expanduser( f"~/data/raw/documentation/tomo_scan_ID_{self.tomo_id}.pdf" ) + os.makedirs(os.path.dirname(user_target), exist_ok=True) with PDFWriter(user_target) as file: self._add_psi_footer(file) # PDFWriter (bec_lib) has no public image API -- reach into its diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py index 60205aed..b46837bf 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py @@ -4289,6 +4289,7 @@ class Flomni( user_target = os.path.expanduser( f"~/data/raw/documentation/tomo_scan_ID_{self.tomo_id}.pdf" ) + os.makedirs(os.path.dirname(user_target), exist_ok=True) with PDFWriter(user_target) as file: self._add_psi_footer(file) # PDFWriter (bec_lib) has no public image API -- reach into its diff --git a/csaxs_bec/bec_ipython_client/plugins/omny/AI_docs/TODO_data10_to_new_data_structure.md b/csaxs_bec/bec_ipython_client/plugins/omny/AI_docs/TODO_data10_to_new_data_structure.md new file mode 100644 index 00000000..26ee8171 --- /dev/null +++ b/csaxs_bec/bec_ipython_client/plugins/omny/AI_docs/TODO_data10_to_new_data_structure.md @@ -0,0 +1,46 @@ +# TODO: OMNY still uses the old `~/Data10` layout, and its PDF report can fail on a missing folder + +LamNI and flomni write their files under the new data structure (`~/data/raw/...`). +OMNY still points at the old `~/Data10/...` tree in several places and needs porting. +Not done yet, to avoid conflicting with other in-progress OMNY changes. + +## 1. Port `~/Data10` paths to the new data structure + +Where OMNY (`csaxs_bec/bec_ipython_client/plugins/omny/`) still uses `~/Data10`: + +| File | Line | Path | LamNI/flomni equivalent | +|---|---|---|---| +| `omny.py` | 1217 | `tomo_reconstruct(base_path="~/Data10/specES1")` | `~/data/raw/logs/reconstruction_queue` | +| `omny.py` | 1236 | `~/Data10/specES1/dat-files/tomography_scannumbers.txt` | `~/data/raw/logs/tomography_scannumbers.txt` | +| `omny.py` | 1484 | `~/Data10/documentation/tomo_scan_ID_.pdf` | `~/data/raw/documentation/tomo_scan_ID_.pdf` | +| `omny.py` | 1489 | `xterm /work/sls/spec/local/XOMNY/bin/upload/upload_last_pon.sh &` | old spec upload script, check it still applies | +| `x_ray_eye_align.py` | 392 | `~/Data10/specES1/internal/xrayeye_alignmentvalues` | `~/data/raw/logs/xrayeye_alignmentvalues/` (timestamped HDF5) | +| `omny_alignment_mixin.py` | 62 | `~/Data10/specES1/internal/` | see the same alignment-values location | + +The reconstruction queue folder in the new layout is created and written by the shared +`PtychoReconstructor.write()` (`OMNY_shared/omny_general_tools.py`), which OMNY does not use +yet. See also `TODO_tomo_reconstruct_stale_scan_list.md` (already ported to flomni and LamNI, +so switching OMNY to the shared reconstructor would cover both items). + +## 2. Create the documentation folder if it does not exist + +`OMNY.write_pdf_report()` (`omny.py:1439`) opens `PDFWriter(user_target)` without creating the +target folder first. `PDFWriter.close()` calls fpdf's `output(path)` +(`bec_lib/pdf_writer.py:90`), which does not create directories, so on an account without the +folder `tomo_scan()` fails with: + +``` +FileNotFoundError: [Errno 2] No such file or directory: '.../documentation/tomo_scan_ID_0.pdf' +``` + +Seen on LamNI; flomni had the identical pattern. Both are fixed by creating the folder before +the writer is opened: + +```python +os.makedirs(os.path.dirname(user_target), exist_ok=True) +with PDFWriter(user_target) as file: +``` + +Apply the same line in `OMNY.write_pdf_report()`, and use the new-structure path from item 1. +Note the later steps in that method (the `upload_last_pon.sh` call and the logbook message) +only run if the PDF write succeeds.