diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py index 9d8c46f..ff7cb1c 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py @@ -3770,19 +3770,19 @@ class Flomni( def write_pdf_report(self): """create and write the pdf report with the current flomni settings""" dev = builtins.__dict__.get("dev") - # header = "" - header = ( - " \n" * 3 - + " .d888 888 .d88888b. 888b d888 888b 888 8888888 \n" - + ' d88P" 888 d88P" "Y88b 8888b d8888 8888b 888 888 \n' - + " 888 888 888 888 88888b.d88888 88888b 888 888 \n" - + " 888888 888 888 888 888Y88888P888 888Y88b 888 888 \n" - + " 888 888 888 888 888 Y888P 888 888 Y88b888 888 \n" - + " 888 888 888 888 888 Y8P 888 888 Y88888 888 \n" - + ' 888 888 Y88b. .d88P 888 " 888 888 Y8888 888 \n' - + ' 888 888 "Y88888P" 888 888 888 Y888 8888888 \n' - ) - padding = 20 + import csaxs_bec + + # Ensure this is a Path object, not a string + csaxs_bec_basepath = Path(csaxs_bec.__file__) + logo_file_rel = "flOMNI.png" + # Build the absolute path correctly + logo_file = ( + csaxs_bec_basepath.parent / "bec_ipython_client" / "plugins" / "flomni" / logo_file_rel + ).resolve() + # Widest label below ("Number of individual sub-tomograms:") is 36 + # chars; left-justify both label and value (no right-justify) so + # short values don't leave a big ragged gap after the label. + padding = 38 fovxy = f"{self.fovx:.1f}/{self.fovy:.1f}" stitching = f"{self.stitch_x:.0f}/{self.stitch_y:.0f}" dataset_id = str(self.client.queue.next_dataset_number) @@ -3792,33 +3792,40 @@ class Flomni( # recompute int((tomo_angle_range/tomo_angle_stepsize)*8) locally. _, _, tomo_type1_total_projections = self._tomo_type1_actual_grid() content = [ - f"{'Sample Name:':<{padding}}{self.sample_name:>{padding}}\n", - f"{'Measurement ID:':<{padding}}{str(self.tomo_id):>{padding}}\n", - f"{'Dataset ID:':<{padding}}{dataset_id:>{padding}}\n", - f"{'Sample Info:':<{padding}}{'Sample Info':>{padding}}\n", - f"{'e-account:':<{padding}}{str(account):>{padding}}\n", - f"{'Number of projections:':<{padding}}{tomo_type1_total_projections:>{padding}}\n", - f"{'First scan number:':<{padding}}{self.client.queue.next_scan_number:>{padding}}\n", - f"{'Last scan number approx.:':<{padding}}{self.client.queue.next_scan_number + tomo_type1_total_projections + 10:>{padding}}\n", + f"{'Sample Name:':<{padding}}{self.sample_name}\n", + f"{'Measurement ID:':<{padding}}{self.tomo_id}\n", + f"{'Dataset ID:':<{padding}}{dataset_id}\n", + f"{'Sample Info:':<{padding}}Sample Info\n", + f"{'e-account:':<{padding}}{account}\n", + f"{'Number of projections:':<{padding}}{tomo_type1_total_projections}\n", + f"{'First scan number:':<{padding}}{self.client.queue.next_scan_number}\n", + f"{'Last scan number approx.:':<{padding}}" + f"{self.client.queue.next_scan_number + tomo_type1_total_projections + 10}\n", f"{'Current photon energy:':<{padding}}To be implemented\n", - # f"{'Current photon energy:':<{padding}}{dev.mokev.read()['mokev']['value']:>{padding}.4f}\n", - f"{'Exposure time:':<{padding}}{self.tomo_countingtime:>{padding}.2f}\n", - f"{'Fermat spiral step size:':<{padding}}{self.tomo_shellstep:>{padding}.2f}\n", - f"{'FOV:':<{padding}}{fovxy:>{padding}}\n", - f"{'Stitching:':<{padding}}{stitching:>{padding}}\n", - f"{'Number of individual sub-tomograms:':<{padding}}{8:>{padding}}\n", - f"{'Angular step within sub-tomogram:':<{padding}}{self.tomo_angle_stepsize:>{padding}.2f}\n", + # f"{'Current photon energy:':<{padding}}{dev.mokev.read()['mokev']['value']:.4f}\n", + f"{'Exposure time:':<{padding}}{self.tomo_countingtime:.2f}\n", + f"{'Fermat spiral step size:':<{padding}}{self.tomo_shellstep:.2f}\n", + f"{'FOV:':<{padding}}{fovxy}\n", + f"{'Stitching:':<{padding}}{stitching}\n", + f"{'Number of individual sub-tomograms:':<{padding}}8\n", + f"{'Angular step within sub-tomogram:':<{padding}}{self.tomo_angle_stepsize:.2f}\n", ] hook_description = self._describe_active_hook() if hook_description: - content.append(f"{'At-each-angle hook:':<{padding}}{hook_description:>{padding}}\n") + content.append(f"{'At-each-angle hook:':<{padding}}{hook_description}\n") content = "".join(content) hook_source = self._active_hook_source() user_target = os.path.expanduser( f"~/data/raw/documentation/tomo_scan_ID_{self.tomo_id}.pdf" ) with PDFWriter(user_target) as file: - file.write(header) + # PDFWriter (bec_lib) has no public image API -- reach into its + # underlying fpdf object directly. logo_w chosen to keep the + # header modest relative to the A4 page width (210mm). + if logo_file.exists(): + logo_w = 50 + file._pdf.image(str(logo_file), x=(210 - logo_w) / 2, w=logo_w) + file._pdf.ln(5) file.write(content) if hook_source: file.write( @@ -3827,18 +3834,7 @@ class Flomni( # Replaces the old upload_last_pon.sh script (broken, never rewritten) # with a direct HTTP upload to the samples web folder. self._upload_pdf_report_to_samples(user_target) - import csaxs_bec - # Ensure this is a Path object, not a string - csaxs_bec_basepath = Path(csaxs_bec.__file__) - - logo_file_rel = "flOMNI.png" - - # Build the absolute path correctly - logo_file = ( - csaxs_bec_basepath.parent / "bec_ipython_client" / "plugins" / "flomni" / logo_file_rel - ).resolve() - print(logo_file) scilog = getattr(bec.messaging, "scilog", None) if scilog is None or not getattr(scilog, "_enabled", False): logger.warning("SciLog is not enabled; skipping PDF report entry.")