Utilities#
Utility functions for IFU spectral cube processing.
This module provides essential helpers for working with synthetic and observed IFU data: beam annotation for figures, circular aperture masks for simple photometry, beam convolution, and noise application (with or without beam correlation). Functions are kept small and focused to aid reuse.
- GalCubeCraft.utils.add_beam(ax, bmin_pix, bmaj_pix, bpa_deg, xy_offset=(10, 10), color='white', crosshair=True)[source]#
Add a synthesized beam ellipse visualization to a matplotlib plot.
This function draws the instrumental beam pattern for radio interferometric observations, showing both the beam ellipse and optional crosshairs indicating the major/minor axes. Essential for displaying the angular resolution and orientation of radio telescope data.
The beam represents the point spread function (PSF) of the interferometer, which determines the minimum resolvable angular scale and affects how sources appear in the image. The elliptical shape results from the distribution of baselines in the interferometer array.
- Parameters:
ax (matplotlib.axes.Axes) – The matplotlib Axes object where the beam will be drawn. Should be the same axes containing the astronomical image.
bmin_pix (float) – Minor axis of the beam ellipse in pixels. Represents the highest angular resolution direction of the interferometer. Typical values: 1-20 pixels depending on image resolution and beam size.
bmaj_pix (float) – Major axis of the beam ellipse in pixels. Represents the lower angular resolution direction of the interferometer. Always >= bmin_pix for proper ellipse definition.
bpa_deg (float) – Beam position angle in degrees, measured counter-clockwise from the x-axis (East). Follows astronomical convention where 0° points East, 90° points North. Range: typically -90° to +90° but can be any angle.
xy_offset (tuple of float, optional) – Offset from bottom-left corner of plot in pixels, by default (10, 10). Controls beam ellipse placement for optimal visibility. Adjust if beam overlaps with important image features.
color (str, optional) – Color of the beam ellipse and crosshair lines, by default ‘white’. Choose color for good contrast against the background image. Common choices: ‘white’, ‘black’, ‘red’, ‘cyan’.
crosshair (bool, optional) – Whether to draw crosshairs along major/minor axes, by default True. Crosshairs help visualize beam orientation and principal axes. Set False for cleaner appearance when beam orientation is not critical.
Notes
Beam Coordinate System: - Position angle follows astronomical convention (counter-clockwise from East) - Ellipse center positioned relative to plot limits, not data coordinates - Crosshairs align with beam principal axes for orientation reference
Typical Usage in Radio Astronomy: - ALMA observations: circular to mildly elliptical beams
The beam size should be derived from the observation metadata: - ALMA: BMAJ, BMIN, BPA header keywords - Synthetic data: Specified during simulation setup
Examples
>>> fig, ax = plt.subplots() >>> ax.imshow(radio_image) >>> # Add beam for ALMA observation >>> add_beam(ax, bmin_pix=2.5, bmaj_pix=3.2, bpa_deg=45.0, ... xy_offset=(15, 15), color='white')
>>> # Simple circular beam without crosshairs >>> add_beam(ax, bmin_pix=4.0, bmaj_pix=4.0, bpa_deg=0.0, ... crosshair=False, color='red')
- GalCubeCraft.utils.apply_and_convolve_noise(spectral_cube, beam_list, peak_snr)[source]#
Apply realistic interferometric noise with beam convolution to a spectral cube.
This function simulates realistic interferometer observations by adding correlated noise convolved with a synthesized beam PSF to each spectral channel
The process follows standard radio astronomy calibration procedures where raw visibility data contains thermal noise that becomes correlated after imaging and beam convolution during the CLEAN deconvolution process.
- Parameters:
spectral_cube (numpy.ndarray) – Input 3D spectral cube with shape (N, M, M) where: - N is the number of spectral channels - M x M is the spatial dimension Units: Surface brightness (e.g., Jy/beam, mJy/beam)
beam_list (list of float, length 3) –
Beam parameters [bmin_pixels, bmaj_pixels, theta_degrees] where: - bmin_pixels: Minor axis FWHM in pixels (highest resolution direction) - bmaj_pixels: Major axis FWHM in pixels (lowest resolution direction) - theta_degrees: Position angle in degrees measured counterclockwise
from positive X-axis (East direction in astronomical coordinates)
peak_snr (float) – Target peak signal-to-noise ratio Defined as: peak_flux / rms_noise Higher values produce cleaner data with less noise
- Returns:
Noisy, beam-convolved spectral cube with same shape as input Units: Surface brightness per beam (e.g., Jy/beam, mJy/beam)
- Return type:
numpy.ndarray
Examples
>>> # Simulate ALMA-like observation with circular beam >>> cube = np.random.randn(100, 64, 64) * 0.1 # Mock spectral cube >>> beam = [3.0, 3.0, 0.0] # Circular beam: [bmin, bmaj, theta] >>> snr = 10.0 # Target peak SNR >>> observed_cube = apply_and_convolve_noise(cube, beam, snr)
>>> # High-resolution VLA observation with elliptical beam >>> beam_params = [2.5, 4.2, 45.0] # Elliptical beam at 45° PA >>> noisy_cube = apply_and_convolve_noise(clean_cube, beam_params, 15.0)
See also
apply_noiseAdd noise without beam convolution
convolve_beamBeam convolution without noise addition
- GalCubeCraft.utils.apply_noise(spectral_cube, peak_snr)[source]#
Add uncorrelated Gaussian thermal noise to a spectral cube.
This function simulates basic noise that would be present in an interferometric observation before any spatial processing or beam convolution. The noise is purely white (uncorrelated) and scales with the peak signal to achieve a specified signal-to-noise ratio.
- Parameters:
spectral_cube (numpy.ndarray) – Input 3D spectral cube with shape (N, M, M) where: - N is the number of spectral channels - M x M is the spatial dimension Units: Surface brightness (e.g., Jy/beam, mJy/beam)
peak_snr (float) – Target peak signal-to-noise ratio Defined as: peak_flux / rms_noise Higher values produce cleaner data with less noise
- Returns:
Noisy spectral cube with same shape and units as input Contains original signal plus additive Gaussian noise
- Return type:
numpy.ndarray
Notes
Noise is spatially uncorrelated (white noise)
Each pixel receives independent random noise
Noise level scales inversely with peak_snr parameter
Does not account for beam-induced spatial correlation
Commonly used for initial noise studies and algorithm testing
See also
apply_and_convolve_noiseAdd noise with beam convolution effects
convolve_beamSpatial convolution without noise addition
- GalCubeCraft.utils.convolve_beam(spectral_cube, beam_list)[source]#
Convolve a 3D spectral cube with an elliptical 2D Gaussian beam to simulate instrumental effects.
This function applies beam convolution to each spectral channel independently, simulating the spatial point spread function (PSF) of radio interferometers or single-dish telescopes. The convolution accounts for the finite angular resolution of the instrument and properly scales flux values to maintain surface brightness units.
The beam convolution process: 1. Creates a normalized 2D Gaussian kernel representing the instrument beam 2. Convolves each spectral slice with this kernel using FFT for efficiency 3. Scales the result by beam area to maintain proper flux density units
This is essential for creating realistic synthetic observations that match the resolution and flux scale of actual telescope data.
- Parameters:
spectral_cube (np.ndarray, shape (n_channels, nx, ny)) – Input 3D spectral cube with spectral axis first. Flux units should be surface brightness (e.g., Jy/beam, K, MJy/sr). Each spectral_cube[i,:,:] is convolved independently.
beam_list (list of float, length 3) –
Beam parameters [bmin_pixels, bmaj_pixels, theta_degrees] where: - bmin_pixels: Minor axis FWHM in pixels (highest resolution direction) - bmaj_pixels: Major axis FWHM in pixels (lowest resolution direction) - theta_degrees: Position angle in degrees measured counterclockwise
from positive X-axis (East direction in astronomical coordinates)
- Returns:
convolved_spectral_cube_beam – Beam-convolved spectral cube with proper flux scaling. Output flux units preserved from input (e.g., Jy/beam → Jy/beam). Spatial resolution reduced to match specified beam size.
- Return type:
np.ndarray, shape (n_channels, nx, ny)
Notes
Beam Kernel Properties: - Uses 2D Gaussian with specified major/minor axes and position angle - Position angle measured counterclockwise from positive X-axis (East) - Kernel normalized to preserve total flux during convolution - Standard deviation calculated from FWHM using Gaussian relation: σ = FWHM / (2√(2ln2))
Flux Scaling: - Convolution spreads flux over larger area, reducing peak values - Multiplication by beam area restores proper surface brightness scale - Beam area = π × bmaj × bmin / (4 × ln(2)) for elliptical Gaussian beam - Accounts for flux conservation during spatial redistribution
Performance Considerations: - Uses FFT convolution for computational efficiency O(N log N) - Memory usage scales linearly with cube size - Processing time dominated by FFT operations per channel
Common Applications: - Synthetic observation generation for algorithm testing - Data simulation matching specific telescope characteristics - Resolution degradation for cross-instrument comparisons - Noise correlation modeling in realistic observations
Examples
>>> # Convolve with circular 5-pixel beam >>> beam_params = [5.0, 5.0, 0.0] # [bmin, bmaj, theta] >>> convolved_cube = convolve_beam(cube, beam_params)
>>> # Simulate ALMA elliptical beam >>> alma_beam = [2.3, 3.1, 45.0] # Minor axis, major axis, 45° PA >>> alma_cube = convolve_beam(high_res_cube, alma_beam)
>>> # VLA beam with specific orientation >>> vla_beam = [4.2, 6.8, 120.0] # Elliptical beam at 120° PA >>> vla_cube = convolve_beam(sim_cube, vla_beam)
See also
astropy.convolution.convolve_fftUnderlying convolution implementation
astropy.convolution.Gaussian2DKernel2D Gaussian kernel creation
radio_beamPackage for more sophisticated beam handling
- GalCubeCraft.utils.create_circular_aperture_mask(cube, R_e, beam_width_px, x_center=None, y_center=None)[source]#
Create a circular aperture mask for photometric analysis of spectral cubes.
This function generates a 3D boolean mask for extracting flux from a circular region, with intelligent sizing based on source effective radius and beam size. The aperture automatically adapts to ensure optimal flux recovery while minimizing noise contamination.
The algorithm chooses the larger of twice the effective radius (2×R_e) or the beam width to define the aperture diameter. This ensures that both extended sources and beam-limited sources are properly captured.
- Parameters:
cube (np.ndarray, shape (n_channels, nx, ny)) – Input 3D spectral cube with spectral axis first. Each cube[i,:,:] represents a 2D image at a specific wavelength/velocity.
R_e (float) – Effective radius of the source in pixels. Typical definition: radius containing ~63% of total flux (1-sigma for Gaussian). For extended sources, should be measured from integrated emission maps.
beam_width_px (float) – Beam width (diameter) in pixels, representing instrumental resolution. For circular beams: beam_width_px = beam_fwhm_px For elliptical beams: use geometric mean or major axis depending on analysis needs.
x_center (float, optional) – X-coordinate of aperture center in pixels, by default None. If None, uses geometric center of the image (nx // 2). Should be determined from source detection or moment analysis.
y_center (float, optional) – Y-coordinate of aperture center in pixels, by default None. If None, uses geometric center of the image (ny // 2). Should match x_center coordinate system and source location.
- Returns:
mask_3d – 3D boolean mask where True indicates pixels inside the aperture. Same dimensions as input cube for direct masking operations. Use as: flux = np.sum(cube[mask_3d]) for aperture photometry.
- Return type:
np.ndarray, shape (n_channels, nx, ny), dtype=bool
Notes
Aperture Sizing Logic: - If source diameter (2×R_e) >= beam width: aperture = 2×(2×R_e) = 4×R_e - If beam width > source diameter: aperture = 2×beam_width - This ensures capture of both source extent and beam-convolved emission
The factor of 2 expansion accounts for: - Beam convolution effects that spread flux beyond source boundaries - Safety margin for flux recovery in low SNR conditions - Compensation for imperfect source centering
Best Practices: - Measure R_e from high SNR integrated emission maps when possible - Use beam parameters from observation metadata (BMAJ, BMIN headers) - Center coordinates should come from source detection algorithms - Consider background subtraction before applying aperture masks
Common Applications: - Aperture photometry for flux measurements - Signal-to-noise ratio calculations - Emission line analysis in specific regions - Performance evaluation of denoising algorithms
Examples
>>> # Create mask for compact source >>> mask = create_circular_aperture_mask(cube, R_e=2.5, beam_width_px=4.0) >>> aperture_flux = np.sum(cube[mask])
>>> # Create mask centered on detected source >>> mask = create_circular_aperture_mask(cube, R_e=3.2, beam_width_px=5.1, ... x_center=45.3, y_center=67.8)
See also
astropy.photutils.aperture_photometryMore sophisticated aperture analysis
photutils.CircularApertureAlternative aperture implementation