# -*- 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.")