streamobs.observed module#
- class streamobs.observed.StreamInjector(survey, **kwargs)[source]#
Bases:
objectInject observational effects into stream data for a given survey.
This class handles the core injection logic while keeping survey data separate. All survey data is loaded once and cached, making multiple injections efficient.
- mask_cache#
Cache of previously created HEALPix masks to avoid recomputation.
- Type:
dict (class attribute)
- _last_gc_frame#
The most recently used great circle frame. This allows reusing the same sky location across multiple inject() calls when gc_frame=’last’.
- Type:
GreatCircleICRSFrame or None
Examples
Initialize with a survey:
>>> injector = StreamInjector('lsst', release='dc2')
Or with a pre-loaded Survey object:
>>> survey = Survey.load('lsst', release='dc2') >>> injector = StreamInjector(survey)
Methods
Clear the mask cache.
complete_data(data[, bands])Validate and complete the columns needed for injection.
detect_flag(pix[, mag, band])Apply the survey selection to determine detection flags for stars.
fluxToMag(flux)Convert from flux to AB magnitude.
getFluxError(mag, mag_error)Convert magnitude error to flux error.
inject(data[, bands])Add observed quantities from the survey to the given data.
List all cached masks.
magToFlux(mag)Convert from AB magnitude to flux.
phi_to_radec(phi1, phi2[, gc_frame, seed, ...])Transform stream coordinates (phi1, phi2) to sky coordinates (RA, Dec).
plot_stream_in_mask(data, mask_type[, ...])Plot the stream over the footprint mask.
sample_measured_magnitudes(mag_true, ...)Sample measured magnitudes from true apparent magnitudes and errors.
- classmethod clear_mask_cache()[source]#
Clear the mask cache.
This can be useful if you want to free memory or force masks to be recomputed.
Examples
>>> StreamInjector.clear_mask_cache()
- complete_data(data, bands=['r', 'g'], **kwargs)[source]#
Validate and complete the columns needed for injection.
This function ensures sky coordinates are present and, if requested, fills missing photometric magnitude columns using a stream model. Specifically:
If (ra, dec) are missing but (phi1, phi2) exist, it converts to sky coordinates via
phi_to_radec.It checks for
mag_<band>for each requested band; any missing bands are generated viaStreamModel.complete_catalogwhen astream_configis provided.Existing columns are preserved and are not overwritten.
- Parameters:
data (pandas.DataFrame) – Input catalog. Must contain either (ra, dec) or (phi1, phi2). The DataFrame is copied; the input object is not modified in place.
bands (list[str], optional) – Photometric bands to ensure (as
mag_<band>). Default is['r', 'g'].**kwargs –
Additional options:
- rngnumpy.random.Generator, optional
Random number generator instance.
- seedint, optional
Random seed used to initialize an RNG if
rngis not given.- gc_framegala.coordinates.GreatCircleICRSFrame or ‘last’, optional
Great circle frame to use. If ‘last’, uses the frame from the previous call. If None, generates a new random frame.
- stream_configdict, optional
Configuration passed to
StreamModel. Required only when at least one requested magnitude band is missing. SeeStreamModelfor the expected schema (e.g., track, distance modulus, isochrone).
Keyword arguments forwarded to
phi_to_radec(only used when converting from (phi1, phi2)):- mask_typelist[str] or str, optional
Mask(s) used when searching a frame (e.g., ‘footprint’, ‘maglim_r’, ‘ebv’).
- percentile_thresholdfloat, optional
Fraction of points that must lie inside the mask when selecting a frame. Default defined in
phi_to_radec.- max_iterint, optional
Maximum trials when searching a frame. Default defined in
phi_to_radec.
- Returns:
A copy of the input with the required columns present:
ra,dec, and onemag_<band>column per requested band.- Return type:
pandas.DataFrame
- Raises:
ValueError – If neither (ra, dec) nor (phi1, phi2) are present; or if one or more magnitude bands are missing and
stream_configis not provided; or if after completion a required column is still absent.
Notes
Only missing magnitude columns are synthesized; existing values are left untouched.
Magnitudes are produced by
StreamModel.complete_catalogand rely on the model’s configuration (e.g., isochrone and distance modulus).When a new gc_frame is created or used, it is stored in
self._last_gc_framefor potential reuse viagc_frame='last'.
Examples
Convert from (phi1, phi2) and generate both bands:
>>> df = pd.DataFrame({'phi1': [-5, 0, 5], 'phi2': [0, 0, 0]}) >>> cfg = {...} # stream model config >>> out = injector.complete_data(df, bands=['r', 'g'], stream_config=cfg)
Use already existing ra/dec and fill a missing ‘g’ band from a model:
>>> df = pd.DataFrame({'phi1': [-5, 0, 5], 'phi2': [0, 0, 0], 'ra': [10.1, 12.5, 24.7], 'dec': [5.2, 6.2, 7.2],}) >>> out = injector.complete_data(df, bands=['r', 'g'], stream_config=cfg, seed=42)
Reuse the same gc_frame for multiple streams:
>>> data1 = injector.complete_data(df1, seed=42) # Creates new frame >>> data2 = injector.complete_data(df2, gc_frame='last') # Reuses frame from data1
- detect_flag(pix, mag=None, band='r', **kwargs)[source]#
Apply the survey selection to determine detection flags for stars.
This method uses the survey completeness function and random sampling to determine which stars would be detected by the survey.
- Parameters:
pix (int or np.ndarray) – HEALPix pixel index/indices.
mag (float or np.ndarray, optional) – Magnitude(s). Default is None.
band (str, optional) – Band to consider for detection. Default is ‘r’.
**kwargs –
Additional keyword arguments:
- rngnumpy.random.Generator, optional
Random number generator instance.
- seedint, optional
Random seed if rng is not provided.
- perfect_galstarsepbool, optional
If True, assumes perfect star/galaxy separation. Default is False.
- Returns:
Boolean array: True for detected stars, False otherwise.
- Return type:
np.ndarray
- Raises:
ValueError – If magnitude values are not provided.
- static fluxToMag(flux)[source]#
Convert from flux to AB magnitude.
- Parameters:
flux (float or np.ndarray) – Flux in Janskys (Jy).
- Returns:
AB magnitude(s).
- Return type:
float or np.ndarray
- static getFluxError(mag, mag_error)[source]#
Convert magnitude error to flux error.
- Parameters:
mag (float or np.ndarray) – Magnitude(s).
mag_error (float or np.ndarray) – Magnitude error(s).
- Returns:
Flux error in Janskys (Jy).
- Return type:
float or np.ndarray
- inject(data, bands=['r', 'g'], **kwargs)[source]#
Add observed quantities from the survey to the given data.
This method applies observational effects including photometric errors, magnitude measurements, and detection flags based on survey properties.
- Parameters:
data (str or pd.DataFrame) – Input data as DataFrame or path to the file (CSV or Excel). Must contain either (ra, dec) or (phi1, phi2) coordinates, and magnitude columns for the specified bands.
bands (list of str, optional) – List of photometric bands to process. Default is [‘r’, ‘g’].
**kwargs –
Additional keyword arguments:
- seedint, optional
Random seed for reproducibility.
- nsideint, optional
HEALPix nside parameter. Default is 4096.
- detection_mag_cutlist of str, optional
Bands to apply SNR detection cut. Default is [‘g’].
- savebool, optional
Whether to save the output data. Default is False.
- folderstr or Path, optional
Output folder path if save=True.
- dust_correctionbool, optional
Whether to apply dust correction to observed magnitudes. Default is True.
- perfect_galstarsepbool, optional
If True, also computes a flag assuming perfect star/galaxy separation (detection efficiency only, no classification losses). Default is False.
- verbosebool, optional
Whether to print progress information. Default is True.
- Returns:
DataFrame with the following added columns:
mag_<band>_obs : Observed magnitudes for each band
magerr_<band> : Photometric errors for each band
flag_observed : Boolean flag (True=detected, False=not detected). Includes both detection and classification efficiencies.
flag_perfect_galstarsep : Boolean flag assuming perfect star/galaxy separation (detection efficiency only, no classification losses; only if requested with perfect_galstarsep=True)
ra, dec : Sky coordinates (if not already present)
- Return type:
pd.DataFrame
- Raises:
ValueError – If required columns are missing or bands are not supported.
- classmethod list_cached_masks()[source]#
List all cached masks.
- Returns:
List of cache keys (survey_name, mask_types, ebv_threshold)
- Return type:
list of tuples
Examples
>>> StreamInjector.list_cached_masks() [('LSST', ('footprint', 'maglim_r'), None), ('LSST', ('ebv', 'footprint'), 0.2)]
- static magToFlux(mag)[source]#
Convert from AB magnitude to flux.
- Parameters:
mag (float or np.ndarray) – AB magnitude(s).
- Returns:
Flux in Janskys (Jy).
- Return type:
float or np.ndarray
- mask_cache = {}#
- phi_to_radec(phi1, phi2, gc_frame=None, seed=None, rng=None, mask_type=['footprint'], **kwargs)[source]#
Transform stream coordinates (phi1, phi2) to sky coordinates (RA, Dec).
This method converts stream coordinates to celestial coordinates using a great circle frame. If no frame is provided, it automatically finds one randomly chosen such that a given percentile of the points lie within the mask defined with mask_type.
The frame used (whether provided or generated) is stored in
self._last_gc_framefor potential reuse viagc_frame='last'in subsequent calls.- Parameters:
phi1 (array-like) – Stream coordinates in degrees.
phi2 (array-like) – Stream coordinates in degrees.
gc_frame (gala.coordinates.GreatCircleICRSFrame or 'last', optional) – Great circle coordinate frame. If None, will be automatically determined. If ‘last’, uses the frame from the previous call (stored in self._last_gc_frame).
seed (int, optional) – Random seed for reproducible frame selection.
rng (numpy.random.Generator, optional) – Random number generator instance.
mask_type (list of str, optional) – Types of masks to use for footprint validation. Options: [“footprint”, “maglim_g”, “maglim_r”, “ebv”]. Default is [“footprint”].
**kwargs –
Additional keyword arguments passed to _find_gc_frame():
- percentile_thresholdfloat, optional
Minimum fraction of points that must be in mask. Default is 0.99.
- max_iterint, optional
Maximum number of random trials. Default is 1000.
- Returns:
Sky coordinates in ICRS frame.
- Return type:
astropy.coordinates.SkyCoord
- Raises:
ValueError – If phi1 and phi2 have different lengths or contain invalid values.
RuntimeError – If no suitable great circle frame could be found.
Examples
Convert stream coordinates to sky coordinates:
>>> phi1 = np.linspace(-10, 10, 1000) >>> phi2 = np.zeros_like(phi1) >>> coords = injector.phi_to_radec(phi1, phi2, seed=42)
Reuse the frame from a previous call:
>>> coords2 = injector.phi_to_radec(phi1_2, phi2_2, gc_frame='last')
- plot_stream_in_mask(data, mask_type, ebv_threshold=0.2, **kwargs)[source]#
Plot the stream over the footprint mask.
Creates a visualization showing the stream’s position relative to the survey footprint or other masks.
- Parameters:
data (pd.DataFrame) – Data containing ‘ra’ and ‘dec’ columns.
mask_type (str or list of str) – Type(s) of masks to plot. Options: [“footprint”, “coverage”, “maglim_<band>”, “ebv”].
ebv_threshold (float, optional) – E(B-V) threshold (only used if ‘ebv’ in mask_type). Default is 0.2.
**kwargs –
Additional arguments passed to plotting function:
- output_folderstr, optional
Path to save the figure.
- Returns:
fig (matplotlib.figure.Figure) – The figure object.
ax (matplotlib.axes.Axes) – The axes object.
- Raises:
ValueError – If mask cannot be created from mask_type parameter.
Examples
Plot stream in footprint:
>>> fig, ax = injector.plot_stream_in_mask(data, ['footprint', 'maglim_r'])
Plot with custom E(B-V) threshold:
>>> fig, ax = injector.plot_stream_in_mask( ... data, ['footprint', 'ebv'], ebv_threshold=0.15 ... )
- sample_measured_magnitudes(mag_true, mag_err, **kwargs)[source]#
Sample measured magnitudes from true apparent magnitudes and errors.
This method adds photometric noise to true magnitudes by sampling from a Gaussian distribution in flux space.
- Parameters:
mag_true (float or np.ndarray) – True apparent magnitude(s).
mag_err (float or np.ndarray) – Magnitude error(s).
**kwargs –
Additional keyword arguments:
- rngnumpy.random.Generator, optional
Random number generator instance.
- seedint, optional
Random seed if rng is not provided.
- Returns:
Measured magnitude(s). Returns “BAD_MAG” for objects with negative flux.
- Return type:
np.ndarray or str