k8ik-stm/Calculations/rendered/Laserbeam.md
2025-09-10 07:06:21 +02:00

132 lines
3.3 KiB
Markdown

```python
import imageio.v2 as imageio
import matplotlib.pyplot as plt
import numpy as np
from scipy import ndimage
# sensor horizontal size
sensor_width = 7.75
# image file
laser = imageio.imread("laser-img/2025-09-07-012621-2mm-aperture.jpg")
```
```python
dimensions = np.array([sensor_width * laser.shape[0] / laser.shape[1], sensor_width])
half_size = dimensions / 2
# Mean of all color channels as an approximation of the monochrome image
laser_monochrome = np.mean(laser, axis=2)
# Normalized intensity map
intensity_map = laser_monochrome / np.max(laser_monochrome)
# Summed intensity in each axis
intensity_x = np.sum(laser_monochrome, axis=0)
intensity_y = np.sum(laser_monochrome, axis=1)
# Center of mass of the laser beam
center = (
(ndimage.center_of_mass(laser_monochrome) / np.array(laser_monochrome.shape) - 0.5)
* dimensions
* [-1, 1]
)
print(f"Center of the beam is at {center[0]:.3f}/{center[1]:.3f}")
# Calculate FWHM in each axis
def fwhm(curve, width):
assert curve.ndim == 1
half_max = (np.max(curve) + np.min(curve)) / 2
diff = curve - half_max
indices = np.where(diff > 0)[0]
return (indices[-1] - indices[0]) / curve.size * width
fwhm_y = fwhm(intensity_y, dimensions[0])
fwhm_x = fwhm(intensity_x, dimensions[1])
print(f"FWHM in X/Y: {fwhm_x:.2f}/{fwhm_y:.2f}")
eccentricity = np.sqrt(1 - (min(fwhm_y, fwhm_x) ** 2 / max(fwhm_y, fwhm_x) ** 2))
print(f"Eccentricity (along cartesian axes): {eccentricity:.5f}")
```
Center of the beam is at -0.088/0.238
FWHM in X/Y: 2.16/1.46
Eccentricity (along cartesian axes): 0.73687
```python
with plt.style.context("dark_background"):
fig, ax = plt.subplots(figsize=(14, 14))
im = ax.imshow(
intensity_map,
cmap="magma",
extent=(-half_size[1], half_size[1], -half_size[0], half_size[0]),
interpolation="none",
vmin=0,
)
ax.set_xlim(-np.max(half_size), np.max(half_size))
ax.set_ylim(-np.max(half_size), np.max(half_size))
xy_scale = max(np.max(intensity_x), np.max(intensity_y))
ax.plot(
np.linspace(-half_size[1], half_size[1], intensity_x.size),
intensity_x / xy_scale - np.max(half_size),
color="red",
)
ax.plot(
intensity_y / xy_scale - np.max(half_size),
np.linspace(half_size[0], -half_size[0], intensity_y.size),
color="red",
)
# reticle
ax.axvline(x=center[1], color="white", linestyle=":")
ax.axhline(y=center[0], color="white", linestyle=":")
ax.axvline(x=center[1] - fwhm_x / 2, color="gray", linestyle=":")
ax.axvline(x=center[1] + fwhm_x / 2, color="gray", linestyle=":")
ax.axhline(y=center[0] - fwhm_y / 2, color="gray", linestyle=":")
ax.axhline(y=center[0] + fwhm_y / 2, color="gray", linestyle=":")
cax = fig.add_axes(
[
ax.get_position().x1 + 0.01,
ax.get_position().y0,
0.02,
ax.get_position().height,
]
)
fig.colorbar(im, cax=cax)
text = (
f"FWHM X/Y: {fwhm_x:.2f} mm/{fwhm_y:.2f} mm\n"
f"Eccentricity: {eccentricity:.5f}\n"
f"Offset X/Y: {center[1]:+.3f} mm/{center[0]:+.3f} mm"
)
fig.text(0.5, 0.05, text, ha="center")
fig
```
![png](Laserbeam_files/Laserbeam_2_0.png)
![png](Laserbeam_files/Laserbeam_2_1.png)
```python
```