Source code for beamprofiler.utils.report

# -*- coding: utf-8 -*-
"""
This module handles the report generation of the beam analysis.
"""

import os

import xlsxwriter


[docs]def write(path, fileName, beam): """ `write` writes the beam analysis report in a `.xlsx` format. Parameters ---------- path : str directory where the input file is saved. fileName : str name of the input file. beam : Beam object of type `Beam`. Returns ------- None. """ # Name of the input and output file fileName = os.path.splitext(fileName)[0] outFile = 'Beam Analysis - ' + fileName + '.xlsx' # Create a new Excel file wb = xlsxwriter.Workbook(os.path.join(path, outFile)) # Create formats for this workbook bold = wb.add_format({ 'bold': True }) italic = wb.add_format({ 'italic': True }) number = wb.add_format({ 'num_format': '#,##0.00' }) # Define a method to write the header def header(sheet): sheet.write('A1', 'Item', bold) sheet.write('B1', 'Value', bold) sheet.write('C1', 'Unit', bold) sheet.write('D1', 'Remark', bold) # Define a method to write the sub header def sub_header(sheet, row, value): sheet.write('A'+str(row), value, italic) # Define a method to write an empty line def empty_line(sheet, row): sheet.write('A'+str(row), '') # Define a method to write the entry def entry(sheet, row, value): sheet.write('A'+str(row), value[0]) sheet.write('B'+str(row), value[1], number) sheet.write('C'+str(row), value[2]) sheet.write('D'+str(row), value[3]) # Define a method to insert an image def image(sheet, cell, path): sheet.insert_image(cell, path) def column_width(sheet): sheet.set_column('A:A', 30) sheet.set_column('B:B', 15) sheet.set_column('D:D', 70) # ========================================================================= # Create and populate the ISO sheet # ========================================================================= ws = wb.add_worksheet('ISO') column_width(ws) header(ws) sub_header(ws, 2, 'Beam power') entry(ws, 3, ['Total power', beam.totalPower, 'ADC', 'Independent of the clip-level']) entry(ws, 4, ['Clip-level power', beam.power_eta, 'ADC', 'Clip-level: ' + str(beam.eta*100) + '%']) empty_line(ws, 5) sub_header(ws, 6, 'Beam power density') entry(ws, 7, ['Maximum power density', beam.maxPowerDensity, 'ADC', 'Independent of the clip-level']) entry(ws, 8, ['Clip-level power density', beam.powerDensity_eta, 'ADC', 'Clip-level: ' + str(beam.eta*100) + '%']) entry(ws, 9, ['Clip-level average power density', beam.averagePowerDensity_eta, 'ADC', 'Clip-level: ' + str(beam.eta*100) + '%']) empty_line(ws, 10) sub_header(ws, 11, 'Beam position') entry(ws, 12, ['Beam centroid x-axis', beam.centerX * beam.xResolution, 'mm', 'Independent of the clip-level']) entry(ws, 13, ['Beam centroid y-axis', beam.centerY * beam.yResolution, 'mm', 'Independent of the clip-level']) empty_line(ws, 14) sub_header(ws, 15, 'Effective beam size') entry(ws, 16, ['Beam width x-axis', beam.widthX * beam.xResolution, 'mm', 'Independent of the clip-level']) entry(ws, 17, ['Beam width y-axis', beam.widthY * beam.yResolution, 'mm', 'Independent of the clip-level']) entry(ws, 18, ['Clip-level irradiation area', beam.irradiationArea_epsilon, 'mm', 'Clip-level: ' + str(beam.epsilon*100) + '%']) entry(ws, 19, ['Clip-level irradiation area', beam.irradiationArea_eta, 'mm', 'Clip-level: ' + str(beam.eta*100) + '%']) empty_line(ws, 20) sub_header(ws, 21, 'Beam shape') entry(ws, 22, ['Beam aspect ratio', beam.aspectRatio, 'N/A', 'Independent of the clip-level. Equals 1 for a perfect ' 'square']) entry(ws, 23, ['Fractional power', beam.fractionalPower_eta, 'N/A', 'Clip-level: ' + str(beam.eta*100) + '%.']) entry(ws, 24, ['Flatness factor', beam.flatnessFactor_eta, 'N/A', 'Clip-level: ' + str(beam.eta*100) + '%. Equals 1 for a ' 'perfect flat top']) entry(ws, 25, ['Beam uniformity', beam.beamUniformity_eta, 'N/A', 'Clip-level: ' + str(beam.eta*100) + '%. Equals 0 for a ' 'perfect flat top with vertical edges']) entry(ws, 26, ['Plateau uniformity', beam.plateauUniformity_eta, 'N/A', 'Clip-level: ' + str(beam.eta*100) + '%. Equals 0 for a ' 'perfect flat top']) entry(ws, 27, ['Edge steepness', beam.edgeSteepness_eta, 'N/A', 'Clip-level: ' + str(beam.eta*100) + '%. Equals 0 for a ' 'perfect vertical edge']) try: image(ws, 'E1', os.path.join(path, fileName + ' - histogram.png')) image(ws, 'E17', os.path.join(path, fileName + ' - 2d heat map.png')) image(ws, 'J17', os.path.join(path, fileName + ' - 3d heat map.png')) except xlsxwriter.exceptions.UnsupportedImageFormat: print("Unknown or unsupported image file format. Image will not be " "included in the summary file.") # ========================================================================= # Create and populate the non ISO sheet # ========================================================================= ws = wb.add_worksheet('non ISO') column_width(ws) header(ws) sub_header(ws, 2, 'Effective beam size') entry(ws, 3, ['Clip-level beam width x-axis', beam.widthX_eta * beam.xResolution, 'mm', 'Clip-level: ' + str(beam.eta*100) + '%']) entry(ws, 4, ['Clip-level beam width y-axis', beam.widthY_eta * beam.yResolution, 'mm', 'Clip-level: ' + str(beam.eta*100) + '%']) entry(ws, 5, ['Clip-level edge width x-axis', beam.edgeX_epsilon_eta * beam.xResolution, 'mm', 'Clip-level: ' + str(beam.epsilon*100) + '% and ' + str(beam.eta*100) + '%']) entry(ws, 6, ['Clip-level edge width y-axis', beam.edgeY_epsilon_eta * beam.yResolution, 'mm', 'Clip-level: ' + str(beam.epsilon*100) + '% and ' + str(beam.eta*100) + '%']) empty_line(ws, 7) sub_header(ws, 8, 'Beam shape') entry(ws, 9, ['Plateau uniformity', beam.modPlateauUniformity_eta, 'N/A', 'Clip-level: ' + str(beam.eta*100) + '%. Equals 0 for a ' 'perfect flat top']) entry(ws, 10, ['Top-hat factor', beam.topHatFactor, 'N/A', 'Independent of the clip-level. Equals 1 for a perfect ' 'square']) image(ws, 'E1', os.path.join(path, fileName + ' - energy curve.png')) try: wb.close() except xlsxwriter.exceptions.FileCreateError: print("The file is currently open and won't be saved. Please, close " "the file and run the analysis again.")