diff --git a/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni.py b/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni.py index 4e2bd65..9f332e9 100644 --- a/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni.py +++ b/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni.py @@ -2145,17 +2145,15 @@ class LamNI(TomoQueueMixin, LamNIAlignmentMixin, LamNIOpticsMixin, LamniGuiTools def write_pdf_report(self): """Create and write the PDF report with current LamNI settings.""" dev = builtins.__dict__.get("dev") - header = ( - " \n" * 3 - + " ::: ::: ::: ::: :::: ::: ::::::::::: \n" - + " :+: :+: :+: :+:+: :+:+: :+:+: :+: :+: \n" - + " +:+ +:+ +:+ +:+ +:+:+ +:+ :+:+:+ +:+ +:+ \n" - + " +#+ +#++:++#++: +#+ +:+ +#+ +#+ +:+ +#+ +#+ \n" - + " +#+ +#+ +#+ +#+ +#+ +#+ +#+#+# +#+ \n" - + " #+# #+# #+# #+# #+# #+# #+#+# #+# \n" - + " ########## ### ### ### ### ### #### ########### \n" - ) - padding = 20 + # LamNI.png (not the previously-referenced, nonexistent + # "LamNI_logo.png" -- that typo silently broke the scilog logo + # attachment below, since the resulting FileNotFoundError was caught + # by the generic try/except and never surfaced). + logo_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "LamNI.png") + # 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 piezo_range = f"{self.lamni_piezo_range_x:.2f}/{self.lamni_piezo_range_y:.2f}" stitching = f"{self.lamni_stitch_x:.2f}/{self.lamni_stitch_y:.2f}" dataset_id = str(self.client.queue.next_dataset_number) @@ -2169,32 +2167,39 @@ class LamNI(TomoQueueMixin, LamNIAlignmentMixin, LamNIOpticsMixin, LamniGuiTools except Exception: energy_str = "N/A" 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(self.client.username):>{padding}}\n", - f"{'Number of projections:':<{padding}}{report_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 + report_total_projections + 10:>{padding}}\n", - f"{'Current photon energy:':<{padding}}{energy_str:>{padding}}\n", - f"{'Exposure time:':<{padding}}{self.tomo_countingtime:>{padding}.2f}\n", - f"{'Fermat spiral step size:':<{padding}}{self.tomo_shellstep:>{padding}.2f}\n", - f"{'Piezo range (FOV sample plane):':<{padding}}{piezo_range:>{padding}}\n", - f"{'Restriction to circular FOV:':<{padding}}{self.tomo_circfov:>{padding}.2f}\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"{'Tomo type:':<{padding}}{self.tomo_type:>{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}}{self.client.username}\n", + f"{'Number of projections:':<{padding}}{report_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 + report_total_projections + 10}\n", + f"{'Current photon energy:':<{padding}}{energy_str}\n", + f"{'Exposure time:':<{padding}}{self.tomo_countingtime:.2f}\n", + f"{'Fermat spiral step size:':<{padding}}{self.tomo_shellstep:.2f}\n", + f"{'Piezo range (FOV sample plane):':<{padding}}{piezo_range}\n", + f"{'Restriction to circular FOV:':<{padding}}{self.tomo_circfov:.2f}\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", + f"{'Tomo type:':<{padding}}{self.tomo_type}\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 os.path.exists(logo_path): + logo_w = 50 + file._pdf.image(logo_path, x=(210 - logo_w) / 2, w=logo_w) + file._pdf.ln(5) file.write(content) if hook_source: file.write( @@ -2213,7 +2218,6 @@ class LamNI(TomoQueueMixin, LamNIAlignmentMixin, LamNIOpticsMixin, LamniGuiTools f"\n\nAt-each-angle hook source ('{self.at_each_angle_hook}'):\n{hook_source}" ) msg = bec.logbook.LogbookMessage() - logo_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "LamNI_logo.png") msg.add_file(logo_path).add_text(scilog_text.replace("\n", "

")).add_tag( ["BEC", "tomo_parameters", f"dataset_id_{dataset_id}", "LamNI", self.sample_name] )