pgmuvi.synthetic

Synthetic light-curve generators for testing and demonstration.

This module provides a uniform interface for generating synthetic astronomical light curves. Four model families are provided:

  1. make_simple_sinusoid_1d() A 1-D light curve consisting of a single sinusoidal component plus optional Gaussian noise.

  2. make_multi_sinusoid_1d() A 1-D light curve with three (or more) sinusoidal components that each peak at a different phase.

  3. make_chromatic_sinusoid_2d() A 2-D (time x wavelength) light curve whose amplitude and phase both have a wavelength dependence. Two amplitude laws are supported:

    • "linear" - amplitude scales linearly with wavelength.

    • "extinction" - amplitude follows a power-law dust-extinction law, A(wl) = overall_amplitude * exp(-tau * wl**alpha), mimicking the wavelength-dependent attenuation discussed elsewhere in the code.

  4. make_multi_sinusoid_chromatic_2d() A 2-D light curve with multiple sinusoidal components, each of which carries its own wavelength-dependent amplitude and phase.

All functions return a Lightcurve object so that they slot directly into the normal pgmuvi workflow. The raw time, wavelength and flux arrays can be recovered via lc.xdata and lc.ydata.

Examples

Generate a simple 1-D sinusoid:

from pgmuvi.synthetic import make_simple_sinusoid_1d
lc = make_simple_sinusoid_1d(period=5.0, noise_level=0.1, seed=42)

Generate a chromatic 2-D light curve with extinction-law amplitude:

from pgmuvi.synthetic import make_chromatic_sinusoid_2d
lc = make_chromatic_sinusoid_2d(
    period=400.0,
    wavelengths=[0.8, 1.2, 2.2],
    amplitude_law="extinction",
    tau=2.0,
    alpha=1.7,
    seed=0,
)
pgmuvi.synthetic.make_chromatic_sinusoid_2d(n_per_band: int | tuple[int, int] | list[int] = 50, period: float = 150.0, amplitude: float = 1.0, phase: float = 0.0, wavelengths: list[float] | None = None, amplitude_law: str = 'linear', amplitude_slope: float = 0.3, wl_ref: float = 0.0, overall_amplitude: float = 5.0, tau: float = 2.0, alpha: float = 1.7, offset: float = 0.0, phase_law: str = 'none', phase_slope: float = 0.1, noise_level: float = 0.1, noise_type: str | None = 'poisson', t_min: float = 0.0, t_span: float | None = None, irregular: bool = True, seed: int | None = None) Lightcurve

Create a 2-D Lightcurve with wavelength-dependent amplitude and phase.

The light curve is observed at several wavelength bands; within each band the underlying signal is sinusoidal, but both its amplitude and phase vary with wavelength.

Two amplitude laws are provided:

  • "linear" (default) - A(wl) = amplitude * (1 + amplitude_slope * (wl - wl_ref))

  • "extinction" - A(wl) = overall_amplitude * exp(-tau * wl**alpha) + offset (dust power-law extinction, matching the DustMean mean function).

Two phase laws are provided:

  • "none" (default) - constant phase.

  • "linear" - phi(wl) = phase + phase_slope * (wl - wl_ref)

Parameters:
  • n_per_band

    Number of observations per wavelength band. Three forms are accepted:

    • int - every band gets the same number of observations.

    • tuple (min, max) - each band independently draws a random count from randint(min, max) (inclusive), so different bands may have different numbers of observations. Useful for simulating realistic uneven coverage across wavelengths.

    • list[int] - explicit count per band; length must equal the number of wavelengths.

  • period – Period of the sinusoid. Defaults to 150.0 days.

  • amplitude – Base amplitude used by the "linear" law.

  • phase – Reference phase (radians), used by both phase laws.

  • wavelengths – List of wavelength values (in whatever units the model uses). If None defaults to [450.0, 600.0, 750.0] (nm scale).

  • amplitude_law"linear" or "extinction".

  • amplitude_slope – Slope of the linear amplitude law.

  • wl_ref – Reference wavelength for the linear laws.

  • overall_amplitude – Pre-extinction amplitude used by the extinction law.

  • tau – Dust optical depth for the extinction law.

  • alpha – Extinction power-law index (typical ISM value: 1.7).

  • offset – Additive offset applied by the extinction law.

  • phase_law"none" or "linear".

  • phase_slope – Slope of the linear phase law (radians per wavelength unit).

  • noise_level – Overall noise scale. Interpretation depends on noise_type.

  • noise_type"poisson" (default) - shot-noise approximation (brighter = lower fractional noise), applied independently per band. "gaussian" - constant-sigma Gaussian noise. None - no noise is added and yerr is not populated.

  • t_min – Start time.

  • t_span – Total time span. If None (default) the span is set to _DEFAULT_TSPAN_FACTOR * period.

  • irregular – If True observation times within each band are randomly sampled.

  • seed – Optional random seed.

Returns:

A 2-D (time x wavelength) light curve object.

Return type:

Lightcurve

Examples

Extinction-law amplitude, linear phase:

lc = make_chromatic_sinusoid_2d(
    period=400.0,
    wavelengths=[0.8, 1.2, 2.2],
    amplitude_law="extinction",
    tau=2.0, alpha=1.7,
    phase_law="linear", phase_slope=0.2,
    seed=0,
)
pgmuvi.synthetic.make_multi_sinusoid_1d(n_obs: int = 80, components: list[dict] | None = None, noise_level: float = 0.1, noise_type: str | None = 'poisson', t_min: float = 0.0, t_span: float | None = None, irregular: bool = False, seed: int | None = None) Lightcurve

Create a 1-D Lightcurve with multiple sinusoidal components.

Each component is characterised by its own period, amplitude, and phase, so the components peak at different times. The default configuration uses three components spread across the phase circle, providing a signal that is clearly non-sinusoidal.

Parameters:
  • n_obs – Number of observations.

  • components

    List of component dictionaries. Each dictionary must contain:

    "period" (float)

    Period in the same units as t_span.

    "amplitude" (float)

    Peak amplitude.

    "phase" (float)

    Initial phase in radians.

    If None the default three-component model is used:

    [
        {"period": 5.0, "amplitude": 1.0, "phase": 0.0},
        {"period": 3.0, "amplitude": 0.5, "phase": math.pi / 3},
        {"period": 7.0, "amplitude": 0.3, "phase": 2 * math.pi / 3},
    ]
    

  • noise_level – Overall noise scale. Interpretation depends on noise_type.

  • noise_type"poisson" (default) - shot-noise approximation (brighter = lower fractional noise). "gaussian" - constant-sigma Gaussian noise. None - no noise is added and yerr is not populated.

  • t_min – Start time.

  • t_span – Total time span. If None (default) the span is set to _DEFAULT_TSPAN_FACTOR * max(period) across all components.

  • irregular – If True observation times are randomly sampled.

  • seed – Optional random seed.

Returns:

A 1-D light curve object.

Return type:

Lightcurve

Raises:

ValueError – If any component dictionary is missing the required "period", "amplitude", or "phase" keys, or if noise_type is not a recognised value.

Examples

>>> lc = make_multi_sinusoid_1d(seed=0)
>>> lc.ndim
1
pgmuvi.synthetic.make_multi_sinusoid_chromatic_2d(n_per_band: int | tuple[int, int] | list[int] = 50, components: list[dict] | None = None, wavelengths: list[float] | None = None, amplitude_law: str = 'extinction', amplitude_slope: float = 0.3, wl_ref: float = 0.0, overall_amplitude: float = 5.0, tau: float = 2.0, alpha: float = 1.7, offset: float = 0.0, phase_law: str = 'linear', phase_slope: float = 0.1, noise_level: float = 0.1, noise_type: str | None = 'poisson', t_min: float = 0.0, t_span: float | None = None, irregular: bool = True, seed: int | None = None) Lightcurve

Create a 2-D Lightcurve with multiple chromatic sinusoidal components.

Each sinusoidal component has its own wavelength-dependent amplitude and phase, following the laws described in make_chromatic_sinusoid_2d(). Within each band the total signal is the sum of all components.

Parameters:
  • n_per_band

    Number of observations per wavelength band. Three forms are accepted:

    • int - every band gets the same number of observations.

    • tuple (min, max) - each band independently draws a random count from randint(min, max) (inclusive), producing realistic uneven coverage across wavelengths.

    • list[int] - explicit count per band; length must equal the number of wavelengths.

  • components

    List of component dictionaries. Each dictionary may contain:

    "period" (float)

    Period in the same units as t_span.

    "amplitude_fraction" (float)

    Amplitude of this component relative to the band mean amplitude (computed from the chosen law). Defaults to 1.0.

    "phase" (float)

    Reference phase in radians. Defaults to 0.0.

    If None the default two-component model is used, mimicking the fundamental and first harmonic of a Mira-like LPV:

    [
        {"period": 400.0, "amplitude_fraction": 0.4, "phase": 0.0},
        {"period": 200.0, "amplitude_fraction": 0.1,
         "phase": math.pi / 2},
    ]
    

    which mimics the fundamental and first harmonic of a pulsating star.

  • wavelengths – List of wavelength values. Defaults to [0.8, 1.2, 2.2] (µm).

  • amplitude_law"linear" or "extinction". Defaults to "extinction".

  • amplitude_slope – Slope of the linear amplitude law.

  • wl_ref – Reference wavelength for the linear laws.

  • overall_amplitude – Pre-extinction amplitude used by the extinction law.

  • tau – Dust optical depth.

  • alpha – Extinction power-law index.

  • offset – Additive offset for the extinction law.

  • phase_law"none" or "linear". Defaults to "linear".

  • phase_slope – Slope of the linear phase law (radians per wavelength unit).

  • noise_level – Overall noise scale. Interpretation depends on noise_type.

  • noise_type"poisson" (default) - shot-noise approximation (brighter = lower fractional noise), applied independently per band. "gaussian" - constant-sigma Gaussian noise. None - no noise is added and yerr is not populated.

  • t_min – Start time.

  • t_span – Total time span. If None (default) the span is set to _DEFAULT_TSPAN_FACTOR * max(period) across all components.

  • irregular – If True observation times within each band are randomly sampled.

  • seed – Optional random seed.

Returns:

A 2-D (time x wavelength) light curve object.

Return type:

Lightcurve

Examples

Mira-like pulsator with dust attenuation:

lc = make_multi_sinusoid_chromatic_2d(
    n_per_band=60,
    t_span=3 * 400.0,
    components=[
        {"period": 400.0, "amplitude_fraction": 0.4, "phase": 0.0},
        {"period": 200.0, "amplitude_fraction": 0.1,
         "phase": math.pi / 2},
    ],
    wavelengths=[0.8, 1.2, 2.2],
    amplitude_law="extinction",
    tau=2.0, alpha=1.7, overall_amplitude=5.0, offset=0.2,
    phase_law="linear", phase_slope=0.05,
    noise_level=0.05,
    seed=0,
)
pgmuvi.synthetic.make_simple_sinusoid_1d(n_obs: int = 80, period: float = 150.0, amplitude: float = 1.0, phase: float = 0.0, noise_level: float = 0.1, noise_type: str | None = 'poisson', t_min: float = 0.0, t_span: float | None = None, irregular: bool = False, seed: int | None = None) Lightcurve

Create a 1-D Lightcurve from a simple sinusoidal signal.

The observed flux is:

y(t) = A * sin(2*pi*t/P + phi) + noise
Parameters:
  • n_obs – Number of observations.

  • period – Period of the sinusoid, in the same units as t_span (typically days). Defaults to 150.0.

  • amplitude – Peak amplitude A.

  • phase – Initial phase in radians.

  • noise_level – Overall noise scale. Interpretation depends on noise_type. Set to 0 for a noise-free light curve.

  • noise_type"poisson" (default) - shot-noise approximation where the noise standard deviation scales as the square root of the local flux (brighter = lower fractional noise). "gaussian" - constant-sigma Gaussian noise with sigma = noise_level. None - no noise is added and yerr is not populated.

  • t_min – Start time of the observation window.

  • t_span – Total time span of the observations. If None (default) the span is set to _DEFAULT_TSPAN_FACTOR * period.

  • irregular – If True the observation times are drawn uniformly at random from [t_min, t_min + t_span] and then sorted. If False (default) the times are equally spaced.

  • seed – Optional integer seed for the random-number generator, for reproducibility.

Returns:

A 1-D light curve object.

Return type:

Lightcurve

Examples

>>> lc = make_simple_sinusoid_1d(period=5.0, noise_level=0.1, seed=0)
>>> lc.ndim
1