stdpipe.simulation module¶
Image simulation module for generating realistic stellar fields with contaminants.
This module provides functions for creating simulated astronomical images with: - Stars with Gaussian and Moffat PSF (pixel-integrated) - Extended sources (galaxies with Sersic profiles) - Imaging artifacts (cosmic rays, hot pixels, bad columns, satellite trails) - Diffraction spikes and optical ghosts for bright sources
Designed for real-bogus classifier development and photometry testing.
- stdpipe.simulation.create_psf_model(fwhm=3.0, psf_type='gaussian', beta=2.5, size=None, oversampling=2, defocus=0.0, astigmatism_x=0.0, astigmatism_y=0.0, coma_x=0.0, coma_y=0.0, wavelength=5.5e-07, pupil_diameter=1.0)[source]¶
Create an oversampled PSF model compatible with PSFEx format.
This creates a PSF model that can be used with psf.place_psf_stamp() and other STDPipe routines. Uses oversampling for accurate flux conservation and fast evaluation with sub-pixel positioning.
Optical aberrations can be added via Zernike polynomial coefficients (Noll ordering). When any aberration coefficient is non-zero, a diffraction PSF is computed via Fourier optics and convolved with the atmospheric seeing PSF (Gaussian or Moffat). When all coefficients are zero, the existing analytical path is used unchanged.
- Parameters:
- fwhmfloat, optional
Full width at half maximum in pixels.
- psf_typestr, optional
Type of PSF model (‘gaussian’ or ‘moffat’).
- betafloat, optional
Moffat beta parameter (default 2.5, only used for psf_type=’moffat’).
- sizeint, optional
Output stamp size in pixels (after downsampling). If None, automatically sized to capture ~99% of PSF flux (>=8*FWHM).
- oversamplingint, optional
Oversampling factor (default 2).
- defocusfloat, optional
Zernike Z4 defocus coefficient in waves (default 0.0).
- astigmatism_xfloat, optional
Zernike Z5 oblique astigmatism coefficient in waves (default 0.0).
- astigmatism_yfloat, optional
Zernike Z6 vertical astigmatism coefficient in waves (default 0.0).
- coma_xfloat, optional
Zernike Z7 vertical coma coefficient in waves (default 0.0).
- coma_yfloat, optional
Zernike Z8 horizontal coma coefficient in waves (default 0.0).
- wavelengthfloat, optional
Observation wavelength in meters (default 550e-9, affects diffraction scale).
- pupil_diameterfloat, optional
Pupil diameter in meters (default 1.0, affects diffraction scale).
- Returns:
- dict
Dictionary with PSFEx-compatible structure containing the PSF model.
- stdpipe.simulation.create_sersic_profile(size, x0, y0, amplitude=1.0, r_eff=5.0, n=1.0, ellipticity=0.0, position_angle=0.0)[source]¶
Create a Sersic profile for galaxy simulation.
The Sersic profile is: I(r) = amplitude * exp(-b_n * ((r/r_eff)^(1/n) - 1)) where b_n ≈ 2n - 0.324 for n >= 0.5 (more accurate formula used internally)
Common cases: - n=0.5: Gaussian-like profile - n=1.0: Exponential disk (typical spiral galaxy disk) - n=4.0: de Vaucouleurs profile (typical elliptical galaxy)
- Parameters:
- sizeint
Size of the profile stamp (must be odd).
- x0float
X center position within the stamp.
- y0float
Y center position within the stamp.
- amplitudefloat, optional
Central surface brightness amplitude.
- r_efffloat, optional
Effective radius in pixels (half-light radius).
- nfloat, optional
Sersic index (shape parameter).
- ellipticityfloat, optional
Ellipticity (0 = circular, 0.5 = moderate, 0.9 = very elongated).
- position_anglefloat, optional
Position angle in degrees (0 = vertical, increases CCW).
- Returns:
- numpy.ndarray
2D array of shape (size, size) with Sersic profile.
- stdpipe.simulation.place_galaxy(image, x0, y0, flux, r_eff=5.0, n=1.0, ellipticity=0.0, position_angle=0.0)[source]¶
Place a galaxy with Sersic profile into an image.
The galaxy stamp is created, scaled to the requested flux, and added to the image. Similar to psf.place_psf_stamp() but for extended sources.
The image is modified in-place.
- Parameters:
- imagenumpy.ndarray
Target image (2D array), modified in-place.
- x0float
X coordinate where to place the galaxy center.
- y0float
Y coordinate where to place the galaxy center.
- fluxfloat
Total integrated flux in ADU units.
- r_efffloat, optional
Effective radius in pixels.
- nfloat, optional
Sersic index.
- ellipticityfloat, optional
Ellipticity (0 = circular, 1 = line).
- position_anglefloat, optional
Position angle in degrees.
- stdpipe.simulation.create_cosmic_ray(length, width, angle, max_intensity, profile='sharp')[source]¶
Create a cosmic ray track.
Cosmic rays appear as elongated tracks with sharp edges, oriented randomly.
- Parameters:
- lengthfloat
Length of the track in pixels.
- widthfloat
Width of the track in pixels.
- anglefloat
Angle in degrees (0 = horizontal, increases CCW).
- max_intensityfloat
Peak intensity in ADU.
- profilestr, optional
Intensity profile (‘sharp’, ‘tapered’, ‘worm’).
- Returns:
- dict
Dictionary with ‘stamp’ (2D array), ‘size’ (stamp dimensions).
- stdpipe.simulation.add_cosmic_rays(image, n_rays=5, length_range=(5, 50), width_range=(1, 3), intensity_range=(1000, 10000), profile='sharp')[source]¶
Add cosmic ray tracks to an image.
Cosmic rays are placed at random positions with random orientations.
- Parameters:
- imagenumpy.ndarray
Target image (modified in-place).
- n_raysint, optional
Number of cosmic rays to add.
- length_rangetuple, optional
(min, max) length in pixels.
- width_rangetuple, optional
(min, max) width in pixels.
- intensity_rangetuple, optional
(min, max) peak intensity in ADU.
- profilestr, optional
Intensity profile (‘sharp’, ‘tapered’, ‘worm’).
- Returns:
- astropy.table.Table
Catalog of added cosmic rays with columns: x, y, length, width, angle, intensity, type.
- stdpipe.simulation.add_hot_pixels(image, n_pixels=10, intensity_range=(500, 5000), clustering=False, cluster_size=3)[source]¶
Add hot pixels to an image.
Hot pixels are single bright pixels at random locations, optionally clustered to simulate physical detector defects.
- Parameters:
- imagenumpy.ndarray
Target image (modified in-place).
- n_pixelsint, optional
Number of hot pixels to add.
- intensity_rangetuple, optional
(min, max) intensity in ADU.
- clusteringbool, optional
If True, create clusters of hot pixels.
- cluster_sizeint, optional
Number of pixels per cluster (if clustering=True).
- Returns:
- astropy.table.Table
Catalog of added hot pixels with columns: x, y, intensity, type.
- stdpipe.simulation.add_bad_columns(image, n_columns=2, intensity_range=None, bad_type='dead', orientation='vertical')[source]¶
Add bad columns or rows to an image.
Bad columns can be dead (low/zero values), hot (high values), or noisy (high variance).
- Parameters:
- imagenumpy.ndarray
Target image (modified in-place).
- n_columnsint, optional
Number of bad columns/rows to add.
- intensity_rangetuple, optional
(min, max) intensity for ‘hot’ type. Ignored for ‘dead’ and ‘noisy’.
- bad_typestr, optional
Type of bad column (‘dead’, ‘hot’, ‘noisy’).
- orientationstr, optional
‘vertical’ for columns, ‘horizontal’ for rows.
- Returns:
- astropy.table.Table
Catalog of bad columns with columns: position, bad_type, orientation, type.
- stdpipe.simulation.create_satellite_trail(length, width, intensity, angle=None, profile='linear', tumbling=False)[source]¶
Create a satellite trail.
Satellite trails are long, thin, bright streaks caused by satellites passing through the field.
- Parameters:
- lengthfloat
Length of the trail in pixels.
- widthfloat
Width of the trail in pixels.
- intensityfloat
Peak intensity in ADU.
- anglefloat, optional
Angle in degrees (0 = horizontal). If None, random.
- profilestr, optional
Transverse profile (‘linear’, ‘gaussian’).
- tumblingbool, optional
If True, add intensity variations along the trail (tumbling satellite).
- Returns:
- dict
Dictionary with ‘stamp’ (2D array), ‘angle’ (actual angle used).
- stdpipe.simulation.add_satellite_trails(image, n_trails=1, length_range=(100, 400), width_range=(2, 8), intensity_range=(5000, 20000), profile='linear', tumbling_prob=0.2)[source]¶
Add satellite trails to an image.
- Parameters:
- imagenumpy.ndarray
Target image (modified in-place).
- n_trailsint, optional
Number of satellite trails to add.
- length_rangetuple, optional
(min, max) length in pixels.
- width_rangetuple, optional
(min, max) width in pixels.
- intensity_rangetuple, optional
(min, max) peak intensity in ADU.
- profilestr, optional
Transverse profile (‘linear’, ‘gaussian’).
- tumbling_probfloat, optional
Probability of tumbling satellite (intensity variations).
- Returns:
- astropy.table.Table
Catalog of added trails.
- stdpipe.simulation.create_diffraction_spikes(size, x0, y0, star_flux, n_spikes=4, spike_length=50, spike_width=2)[source]¶
Create diffraction spikes for a bright star.
Diffraction spikes are caused by the support structure of telescopes (refractors, SCTs). Typically 4 spikes at 45-degree intervals.
- Parameters:
- sizeint
Size of the stamp.
- x0float
X center (star position).
- y0float
Y center (star position).
- star_fluxfloat
Flux of the source star (determines spike intensity).
- n_spikesint, optional
Number of spikes (typically 4).
- spike_lengthfloat, optional
Length of each spike in pixels.
- spike_widthfloat, optional
Width of each spike in pixels.
- Returns:
- numpy.ndarray
2D array with diffraction spikes.
- stdpipe.simulation.create_optical_ghost(size, x0, y0, source_flux, ghost_fraction=0.05, offset=(50, 50), blur_sigma=5.0)[source]¶
Create an optical ghost (reflection artifact).
Optical ghosts are faint, blurred copies of bright sources caused by reflections in the optical system.
- Parameters:
- sizeint
Minimum size of the stamp (will be expanded if needed to fit ghost).
- x0float
X center of original source within stamp.
- y0float
Y center of original source within stamp.
- source_fluxfloat
Flux of the original source.
- ghost_fractionfloat, optional
Fraction of source flux appearing in ghost (typically 0.01-0.1).
- offsettuple, optional
(dx, dy) offset of ghost from source in pixels.
- blur_sigmafloat, optional
Gaussian blur sigma for the ghost.
- Returns:
- dict
Dictionary with ‘stamp’ (2D array) and ‘source_pos’ (x, y) giving the source position within the stamp (needed to align stamp onto the image).
- stdpipe.simulation.add_close_companions_to_catalog(catalog, fwhm, fraction=0.2, min_separation_fwhm=1.0, max_separation_fwhm=3.0, flux_variation=(0.5, 1.5), image_shape=None, edge=10)[source]¶
Add close companions to stars in a catalog (before image placement).
This function creates a new catalog with additional companion stars placed near existing stars to simulate crowded fields. Companions are only added to sources with type=’star’.
- Parameters:
- catalogastropy.table.Table
Input catalog with ‘x’, ‘y’, ‘flux’, ‘type’ columns.
- fwhmfloat
FWHM of the PSF in pixels (used to calculate separations).
- fractionfloat, optional
Fraction of stars (0-1) that will have companions.
- min_separation_fwhmfloat, optional
Minimum separation in FWHM units.
- max_separation_fwhmfloat, optional
Maximum separation in FWHM units.
- flux_variationtuple, optional
(min, max) flux ratio for companion relative to primary.
- image_shapetuple, optional
(height, width) tuple for bounds checking, or None to skip.
- edgeint, optional
Minimum distance from edges when bounds checking.
- Returns:
- astropy.table.Table
New catalog with companions added (original catalog unchanged).
- stdpipe.simulation.add_stars(image, n=100, flux_range=(100, 10000), fwhm=3.0, psf='gaussian', beta=2.5, edge=0, saturation=None, diffraction_spikes=False, spike_threshold=50000, optical_ghosts=False, ghost_threshold=100000, wcs=None)[source]¶
Add stars to an image with realistic PSF.
- Parameters:
- imagenumpy.ndarray
Target image (modified in-place).
- nint, optional
Number of stars to add.
- flux_rangetuple, optional
(min, max) flux range in ADU.
- fwhmfloat, optional
FWHM of the PSF in pixels (used if psf is a string).
- psfstr or dict, optional
PSF specification — either a string (‘gaussian’, ‘moffat’) or a PSF model dictionary (PSFEx format).
- betafloat, optional
Moffat beta parameter (only used if psf=’moffat’).
- edgeint, optional
Minimum distance from image edges.
- saturationfloat, optional
Saturation level in ADU.
- diffraction_spikesbool, optional
If True, add diffraction spikes to bright stars.
- spike_thresholdfloat, optional
Flux threshold for adding diffraction spikes.
- optical_ghostsbool, optional
If True, add optical ghosts to very bright stars.
- ghost_thresholdfloat, optional
Flux threshold for adding optical ghosts.
- wcsastropy.wcs.WCS, optional
WCS object for computing RA/Dec.
- Returns:
- astropy.table.Table
Catalog of added stars.
- stdpipe.simulation.add_galaxies(image, n=20, flux_range=(500, 5000), r_eff_range=(3, 15), n_range=(0.5, 4.0), ellipticity_range=(0.0, 0.7), edge=0, wcs=None)[source]¶
Add galaxies with Sersic profiles to an image.
- Parameters:
- imagenumpy.ndarray
Target image (modified in-place).
- nint, optional
Number of galaxies to add.
- flux_rangetuple, optional
(min, max) total flux in ADU.
- r_eff_rangetuple, optional
(min, max) effective radius in pixels.
- n_rangetuple, optional
(min, max) Sersic index.
- ellipticity_rangetuple, optional
(min, max) ellipticity.
- edgeint, optional
Minimum distance from image edges.
- wcsastropy.wcs.WCS, optional
WCS object for computing RA/Dec.
- Returns:
- astropy.table.Table
Catalog of added galaxies.
- stdpipe.simulation.simulate_image(width, height, n_stars=100, star_flux_range=(100, 10000), star_fwhm=3.0, star_psf='gaussian', star_beta=2.5, n_galaxies=20, galaxy_flux_range=(500, 5000), galaxy_r_eff_range=(3, 15), galaxy_n_range=(0.5, 4.0), galaxy_ellipticity_range=(0.0, 0.7), n_cosmic_rays=5, cosmic_ray_length_range=(5, 50), cosmic_ray_width_range=(1, 3), cosmic_ray_intensity_range=(1000, 10000), cosmic_ray_profile='worm', n_hot_pixels=10, hot_pixel_intensity_range=(500, 5000), n_bad_columns=0, bad_column_type='dead', n_satellites=0, satellite_length_range=(100, 400), satellite_width_range=(2, 8), satellite_intensity_range=(5000, 20000), diffraction_spikes=False, spike_threshold=50000, optical_ghosts=False, ghost_threshold=100000, add_companions=False, companion_fraction=0.2, companion_separation_fwhm=(1.0, 3.0), companion_flux_ratio=(0.5, 1.5), background=1000.0, readnoise=10.0, gain=1.0, edge=10, wcs=None, return_catalog=True, return_masks=False, seed=None, verbose=False)[source]¶
Simulate a realistic astronomical image with stars, galaxies, and contaminants.
This is the high-level API that creates a complete simulated image in one call.
- Parameters:
- widthint, optional
Image width in pixels.
- heightint, optional
Image height in pixels.
- n_starsint, optional
Number of stars to add.
- star_flux_rangetuple, optional
(min, max) star flux in ADU.
- star_fwhmfloat, optional
FWHM of stellar PSF in pixels.
- star_psfstr or dict, optional
PSF type — either a string (‘gaussian’, ‘moffat’) or a PSF model dict (from create_psf_model). Use dict to specify aberrated PSFs.
- star_betafloat, optional
Moffat beta parameter (if star_psf=’moffat’).
- n_galaxiesint, optional
Number of galaxies to add.
- galaxy_flux_rangetuple, optional
(min, max) galaxy flux in ADU.
- galaxy_r_eff_rangetuple, optional
(min, max) effective radius in pixels.
- galaxy_n_rangetuple, optional
(min, max) Sersic index.
- galaxy_ellipticity_rangetuple, optional
(min, max) ellipticity.
- n_cosmic_raysint, optional
Number of cosmic ray tracks.
- cosmic_ray_length_rangetuple, optional
(min, max) cosmic ray length in pixels.
- cosmic_ray_width_rangetuple, optional
(min, max) cosmic ray width in pixels.
- cosmic_ray_intensity_rangetuple, optional
(min, max) cosmic ray peak intensity.
- cosmic_ray_profilestr, optional
Cosmic ray profile (‘sharp’, ‘tapered’, ‘worm’).
- n_hot_pixelsint, optional
Number of hot pixels.
- hot_pixel_intensity_rangetuple, optional
(min, max) hot pixel intensity.
- n_bad_columnsint, optional
Number of bad columns.
- bad_column_typestr, optional
Type of bad columns (‘dead’, ‘hot’, ‘noisy’).
- n_satellitesint, optional
Number of satellite trails.
- satellite_length_rangetuple, optional
(min, max) satellite trail length in pixels.
- satellite_width_rangetuple, optional
(min, max) satellite trail width in pixels.
- satellite_intensity_rangetuple, optional
(min, max) satellite trail intensity.
- diffraction_spikesbool, optional
Add diffraction spikes to bright stars.
- spike_thresholdfloat, optional
Flux threshold for diffraction spikes.
- optical_ghostsbool, optional
Add optical ghosts to very bright stars.
- ghost_thresholdfloat, optional
Flux threshold for optical ghosts.
- add_companionsbool, optional
If True, add close stellar companions to simulate crowded fields.
- companion_fractionfloat, optional
Fraction of stars (0-1) that will have companions.
- companion_separation_fwhmtuple, optional
(min, max) companion separation in FWHM units.
- companion_flux_ratiotuple, optional
(min, max) companion flux relative to primary star.
- backgroundfloat, optional
Background level in ADU.
- readnoisefloat, optional
Read noise in ADU.
- gainfloat, optional
Detector gain in e-/ADU.
- edgeint, optional
Minimum distance from image edges for sources.
- wcsastropy.wcs.WCS, optional
WCS object for computing sky coordinates.
- return_catalogbool, optional
If True, return catalog of all injected sources.
- return_masksbool, optional
If True, return separate masks for each artifact type.
- seedint, optional
Random seed for reproducibility. If set, calls np.random.seed(seed).
- verbosebool, optional
Enable verbose output.
- Returns:
- dict
Dictionary with ‘image’, ‘catalog’ (if requested), ‘masks’ (if requested), ‘background’, ‘noise’.
- stdpipe.simulation.generate_realbogus_training_data(n_images=100, image_size=(2048, 2048), n_stars_range=(50, 200), n_galaxies_range=(10, 50), fwhm_range=(1.5, 8.0), background_range=(100, 10000), n_cosmic_rays_range=(5, 20), n_hot_pixels_range=(5, 30), n_satellites_range=(0, 2), detection_threshold=3.0, match_radius=3.0, cutout_radius=15, augment=True, real_source_types=['star'], close_pair_fraction=0.2, min_separation_fwhm=1.0, max_separation_fwhm=3.0, aberration_fraction=0.0, defocus_range=(0.0, 2.0), astigmatism_range=(0.0, 1.5), coma_range=(0.0, 1.0), readnoise_range=(5.0, 20.0), gain_range=(0.5, 2.0), asinh_softening=None, seed=None, verbose=False)[source]¶
Generate labeled training data for real-bogus classifier.
This function creates a dataset of labeled cutouts by: 1. Simulating images with known source positions 2. Running object detection 3. Matching detections to truth catalog 4. Labeling matched detections as ‘real’, others as ‘bogus’ 5. Extracting and preprocessing cutouts 6. Optionally applying data augmentation
Flux ranges are automatically calculated for each image based on the background noise level to ensure sources are detectable: - Minimum flux = detection_threshold × noise (e.g., 3σ for detectability) - Maximum flux = 1000 × noise (bright sources) This prevents generating sources that are too faint to detect or unrealistically bright.
Close pairs are automatically added to ensure the classifier learns to accept crowded sources. A fraction of stars will have stellar companions added at controlled separations (e.g., 1-3 FWHM). Companions are only added to stars, not galaxies.
PSF diversity can be included in training data by setting aberration_fraction > 0. A fraction of images will use aberrated PSFs with randomized Zernike coefficients (defocus, astigmatism, coma) computed via Fourier optics, helping the classifier handle realistic PSF variations from optical aberrations.
- Parameters:
- n_imagesint, optional
Number of simulated images to generate.
- image_sizetuple, optional
(width, height) of simulated images.
- n_stars_rangetuple, optional
(min, max) number of stars per image.
- n_galaxies_rangetuple, optional
(min, max) number of galaxies per image.
- fwhm_rangetuple, optional
(min, max) FWHM in pixels (varied per image).
- background_rangetuple, optional
(min, max) background level in ADU.
- n_cosmic_rays_rangetuple, optional
(min, max) cosmic rays per image.
- n_hot_pixels_rangetuple, optional
(min, max) hot pixels per image.
- n_satellites_rangetuple, optional
(min, max) satellite trails per image.
- detection_thresholdfloat, optional
Detection threshold in sigma (also used for min flux calculation).
- match_radiusfloat, optional
Matching radius in pixels for truth matching.
- cutout_radiusint, optional
Cutout radius in pixels.
- augmentbool, optional
Apply data augmentation (rotations, flips).
- real_source_typeslist, optional
List of source types to consider ‘real’. Default: [‘star’] treats only stars as real and galaxies as bogus. Use [‘star’, ‘galaxy’] to treat both as real.
- close_pair_fractionfloat, optional
Fraction of sources (0-1) that will have close companions added. Default: 0.2 (20% of sources get companions).
- min_separation_fwhmfloat, optional
Minimum separation for companions in FWHM units. Default: 1.0 (1x FWHM).
- max_separation_fwhmfloat, optional
Maximum separation for companions in FWHM units. Default: 3.0 (3x FWHM).
- aberration_fractionfloat, optional
Fraction of images (0-1) with aberrated PSFs. Default: 0.0 (all Gaussian). When > 0 and aberration ranges have non-zero max values, uses Fourier optics with Zernike polynomials. Otherwise falls back to Moffat PSFs as a simpler proxy.
- defocus_rangetuple, optional
(min, max) defocus aberration in waves (default: (0.0, 2.0)).
- astigmatism_rangetuple, optional
(min, max) astigmatism aberration in waves (default: (0.0, 1.5)).
- coma_rangetuple, optional
(min, max) coma aberration in waves (default: (0.0, 1.0)).
- readnoise_rangetuple, optional
(min, max) read noise in ADU (randomized per image).
- gain_rangetuple, optional
(min, max) detector gain in e-/ADU (randomized per image).
- asinh_softeningfloat, optional
Asinh softening in units of background sigma for realbogus preprocessing. If None, uses DEFAULT_ASINH_SOFTENING_SIGMA.
- seedint, optional
Random seed for reproducibility. If set, calls np.random.seed(seed).
- verbosebool, optional
Print progress.
- Returns:
- dict
Dictionary with ‘X’ (cutouts), ‘y’ (labels), ‘fwhm’ (FWHM values), ‘metadata’.