Aperture Geometry and Pupil Configurations¶
What you will learn:
- How the secondary mirror obstruction affects the PSF
- How support spider struts create diffraction spikes
- How to compare different aperture versions side-by-side
Prerequisites: 02_getting_started.ipynb
Background¶
The pupil is the 2-D mask that describes which parts of the incoming wavefront reach the detector.
For a Newtonian telescope it has three components:
- Primary mirror — a circular aperture of radius $R_1$
- Secondary mirror — a circular obstruction of radius $R_2$ (blocks the central area)
- Spider struts — thin supports holding the secondary; they produce diffraction spikes
PSFCraft encodes these as NewtonianTelescopeAperture with a version string:
| Version | Geometry |
|---|---|
'0' |
No secondary, no struts (ideal circular aperture) |
'1_N' |
$N$ equally-spaced straight struts (e.g. '1_3', '1_4') |
'2' |
Euclid-like asymmetric strut placement |
'3' |
4 cross-shaped struts |
'5' |
4 tangent-offset struts |
'6' |
8 star-shaped struts |
%matplotlib inline
import psfcraft
import matplotlib.pyplot as plt
pysynphot is not installed. Please install it to use PSF generation with polychromatic sources.
1. Effect of the Number of Spider Struts¶
We iterate over version = '1_N' for $N = 0 \ldots 5$ struts and display both the pupil and the resulting PSF.
n_configs = 6 # N = 0 … 5 struts
wavelength = 1e-6 # 1 µm
fig, axes = plt.subplots(2, n_configs, figsize=(18, 6))
plt.subplots_adjust(hspace=0.15, wspace=0.15)
for col, n_struts in enumerate(range(n_configs)):
version = f"1_{n_struts}"
tel = psfcraft.NewtonianTelescope(version=version)
tel.pixelscale = 0.05
psf = tel.calc_psf(monochromatic=wavelength, fov_pixels=64)
# Row 0: pupil
tel.optsys.display(
what="intensity", ax=axes[0, col],
title=f"{n_struts} struts",
colorbar=False,
)
# Row 1: PSF
psfcraft.display_psf(psf, ax=axes[1, col], title="", colorbar=False)
axes[0, col].set_xlabel("")
axes[0, 0].set_ylabel("Pupil")
axes[1, 0].set_ylabel("PSF")
plt.suptitle("Pupil geometry and PSF — varying number of spider struts", fontsize=13)
plt.show()
Interpretation:
- Each strut creates two symmetric diffraction spikes separated by 180°.
0struts → no spikes; pure Airy-ring pattern with a central dark spot from the secondary.3struts → 6-spike pattern (most common in small telescopes).4struts → familiar 4-spike cross (Hubble Space Telescope style).
2. Special Aperture Geometries¶
PSFCraft also ships a few hand-crafted aperture models that mimic real telescope pupils.
special_versions = {
"0": "No spider\n(ideal)",
"1_3": "3-strut\n(classic)",
"1_4": "4-strut\n(cross)",
"3": "4-strut\n(v3)",
"5": "4-strut\n(tangent offset)",
"6": "8-strut\n(star shape)",
}
fig, axes = plt.subplots(2, len(special_versions), figsize=(18, 6))
plt.subplots_adjust(hspace=0.15, wspace=0.15)
for col, (ver, label) in enumerate(special_versions.items()):
tel = psfcraft.NewtonianTelescope(version=ver)
tel.pixelscale = 0.05
psf = tel.calc_psf(monochromatic=1e-6, fov_pixels=64)
tel.optsys.display(what="intensity", ax=axes[0, col], title=label, colorbar=False)
psfcraft.display_psf(psf, ax=axes[1, col], title="", colorbar=False)
axes[0, col].set_xlabel("")
axes[0, 0].set_ylabel("Pupil")
axes[1, 0].set_ylabel("PSF")
plt.suptitle("Special aperture geometries", fontsize=13)
plt.show()
3. Effect of the Secondary Obstruction Ratio¶
The obstruction ratio $\epsilon = R_2 / R_1$ affects the height of the PSF core and the prominence of the Airy rings. A larger secondary suppresses the core and redistributes power into the rings.
primary_radius = 0.5 # fixed
secondary_ratios = [0.0, 0.1, 0.2, 0.33, 0.5] # ε = R2/R1
fig, axes = plt.subplots(2, len(secondary_ratios), figsize=(15, 6))
plt.subplots_adjust(hspace=0.15, wspace=0.15)
for col, epsilon in enumerate(secondary_ratios):
secondary_r = epsilon * primary_radius
# version '0' = no struts, version '1_0' = secondary with no struts
version = "0" if epsilon == 0.0 else "1_0"
tel = psfcraft.NewtonianTelescope(
version=version,
primary_radius=primary_radius,
secondary_radius=secondary_r if epsilon > 0 else 0.001,
)
tel.pixelscale = 0.05
psf = tel.calc_psf(monochromatic=1e-6, fov_pixels=64)
tel.optsys.display(what="intensity", ax=axes[0, col],
title=f"ε = {epsilon:.2f}", colorbar=False)
psfcraft.display_psf(psf, ax=axes[1, col], title="", colorbar=False)
axes[0, col].set_xlabel("")
axes[0, 0].set_ylabel("Pupil")
axes[1, 0].set_ylabel("PSF")
plt.suptitle("Effect of secondary obstruction ratio ε = R₂/R₁", fontsize=13)
plt.show()
Key Takeaways¶
- The
versionparameter controls the spider architecture; use'1_N'for $N$ evenly-spaced struts. - Each strut generates two diffraction spikes;
Nstruts →2Nspikes (orNif $N$ is even, due to symmetry pairing). - The
version='0'aperture is the ideal reference: no secondary, no spikes. - Increasing the secondary obstruction ratio redistributes PSF energy from the core to the rings.
Next: 04_wavefront_aberrations.ipynb — model optical aberrations with Zernike polynomials.