fix(LamNI): use the real setup logo in the PDF report, fix column gaps
Replace the ASCII-art header with the actual LamNI.png logo, embedded via PDFWriter's underlying fpdf object (bec_lib's PDFWriter has no public image API). Also fix the label/value formatting: values were right-justified in a wide fixed field, leaving a big ragged gap after short labels -- left-justify both instead for a clean, tight "label: value" layout. Also fixes a real bug found along the way: the scilog attachment referenced "LamNI_logo.png", a file that has never existed (the actual file is LamNI.png) -- the resulting FileNotFoundError was swallowed by write_pdf_report()'s generic try/except, so the scilog message has been silently failing to send every time. Now uses the one correct, shared logo_path for both the PDF and the scilog attachment.
This commit is contained in:
@@ -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", "</p><p>")).add_tag(
|
||||
["BEC", "tomo_parameters", f"dataset_id_{dataset_id}", "LamNI", self.sample_name]
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user