Models

The lightcurvedb models represent the core data structures for storing and retrieving astronomical time-series data from the TESS mission.

Frame Models

class lightcurvedb.models.FITSFrame(**kwargs)

Bases: LCDBModel, CreatedOnMixin

Represents a FITS (Flexible Image Transport System) frame.

FITSFrame stores metadata about individual FITS files used in astronomical observations. It uses polymorphic inheritance to support different frame types while maintaining FITS standard compliance.

id

Primary key identifier

Type:

int

type

Polymorphic discriminator for frame type

Type:

str

cadence

Time-ordered frame number

Type:

int

observation_id

Foreign key to parent observation

Type:

int

simple

FITS primary keyword - file conforms to FITS standard

Type:

bool

bitpix

FITS primary keyword - bits per pixel

Type:

int

naxis

FITS primary keyword - number of axes

Type:

int

naxis_values

Array representation of NAXIS1, NAXIS2, etc.

Type:

list[int]

extended

FITS primary keyword - file may contain extensions

Type:

bool

bscale

Linear scaling factor (physical = bzero + bscale * stored)

Type:

float

bzero

Zero point offset for scaling

Type:

float

file_path

File system path to the FITS file

Type:

Path, optional

Notes

The type-cadence combination must be unique, enforced by database constraint. Polymorphic on ‘type’ field allows for specialized frame subclasses.

created_on: orm.Mapped[datetime.datetime]

Instrument Models

class lightcurvedb.models.Instrument(**kwargs)

Bases: LCDBModel

Represents a scientific instrument or assembly used for observations.

Instruments form a hierarchical structure where an instrument can be either a physical device (e.g., a CCD) or an assembly containing other instruments (e.g., a camera with multiple CCDs). This allows modeling complex instrument configurations.

id

Unique identifier for the instrument

Type:

UUID

name

Name of the instrument (e.g., “Camera 1”, “CCD 2”)

Type:

str

properties

JSON dictionary of instrument-specific properties and metadata

Type:

dict

parent_id

Foreign key to parent instrument (None for top-level instruments)

Type:

UUID, optional

parent

Parent instrument in the hierarchy

Type:

Instrument, optional

children

Child instruments if this is an assembly

Type:

list[Instrument]

observations

Observations made using this instrument

Type:

list[Observation]

Examples

>>> camera = Instrument(name="TESS Camera 1")
>>> ccd = Instrument(name="CCD 1", parent=camera)

Notes

The self-referential relationship allows building instrument trees of arbitrary depth, useful for complex telescope configurations.

Processing Models

class lightcurvedb.models.PhotometricSource(**kwargs)

Bases: LCDBModel, NameAndDescriptionMixin

Defines a source or method of photometric measurement.

PhotometricSource represents different ways of extracting photometric data from observations, such as aperture photometry with different aperture sizes or PSF photometry.

id

Primary key identifier

Type:

int

name

Name of the photometric method (inherited from mixin)

Type:

str

description

Detailed description (inherited from mixin)

Type:

str

processing_groups

Processing groups using this photometric source

Type:

list[ProcessingGroup]

Examples

>>> aperture_2px = PhotometricSource(name="Aperture_2px",
...                                  description="2 pixel radius aperture")
class lightcurvedb.models.DetrendingMethod(**kwargs)

Bases: LCDBModel, NameAndDescriptionMixin

Represents a method for removing systematic trends from lightcurves.

DetrendingMethod defines algorithms used to remove instrumental or systematic effects from photometric time series, such as PDC-SAP (Pre-search Data Conditioning Simple Aperture Photometry).

id

Primary key identifier

Type:

int

name

Name of the detrending method (inherited from mixin)

Type:

str

description

Detailed description (inherited from mixin)

Type:

str

processing_groups

Processing groups using this detrending method

Type:

list[ProcessingGroup]

Examples

>>> pdc = DetrendingMethod(name="PDC-SAP",
...                        description="Pre-search Data Conditioning")
class lightcurvedb.models.ProcessingGroup(**kwargs)

Bases: LCDBModel, NameAndDescriptionMixin

Combines a photometric source with a detrending method.

ProcessingGroup represents a unique combination of how photometry was extracted and how it was detrended. This allows tracking different processing pipelines applied to the same observations.

id

Primary key identifier

Type:

int

name

Name of the processing group (inherited from mixin)

Type:

str

description

Detailed description (inherited from mixin)

Type:

str

photometric_source_id

Foreign key to photometric source

Type:

int

detrending_method_id

Foreign key to detrending method

Type:

int

photometric_source

The photometric extraction method

Type:

PhotometricSource

detrending_method

The detrending algorithm

Type:

DetrendingMethod

datasets

Lightcurve datasets using this processing

Type:

list[DataSet]

Notes

The combination of photometric_source_id and detrending_method_id must be unique, ensuring no duplicate processing groups.

class lightcurvedb.models.DataSet(**kwargs)

Bases: LCDBModel

A processed lightcurve for a specific target and observation.

DataSet is the central model that connects a target, an observation, and a processing method to produce a final lightcurve. It stores the actual photometric measurements and uncertainties.

id

Primary key identifier

Type:

int

processing_group_id

Foreign key to processing group

Type:

int

target_id

Foreign key to target

Type:

int

observation_id

Foreign key to observation

Type:

int

values

Array of photometric measurements (flux or magnitude)

Type:

ndarray[float64]

errors

Array of measurement uncertainties

Type:

ndarray[float64], optional

processing_group

The processing method used

Type:

ProcessingGroup

target

The astronomical target

Type:

Target

observation

The source observation

Type:

Observation

Notes

This is the main table for storing lightcurve data. Each row represents one complete lightcurve for a target processed with a specific method.

Observation Models

class lightcurvedb.models.Observation(**kwargs)

Bases: LCDBModel

Base class for astronomical observations.

Observation is a polymorphic base class that represents a collection of measurements taken by an instrument. Subclasses can specialize this for different observation types while maintaining a common interface.

This design allows mission-specific observations (e.g., TESSObservation, HSTObservation) to extend the base model with mission-specific fields while sharing common functionality.

id

Primary key identifier

Type:

int

type

Polymorphic discriminator for subclass type

Type:

str

cadence_reference

Array of cadence numbers for time ordering

Type:

ndarray[int64]

instrument_id

Foreign key to the instrument used

Type:

uuid.UUID

instrument

The instrument that made this observation

Type:

Instrument

datasets

Processed versions of this observation

Type:

list[DataSet]

target_specific_times

Target-specific time corrections

Type:

list[TargetSpecificTime]

Examples

Creating a mission-specific observation subclass:

>>> class TESSObservation(Observation):
...     __mapper_args__ = {
...         "polymorphic_identity": "tess_observation",
...     }
...     sector: Mapped[int]
...     orbit_number: Mapped[int]

Notes

This is a polymorphic base class using single table inheritance. The ‘type’ field determines the specific observation subclass. Mission-specific fields should be added via subclassing, not by modifying this base class.

class lightcurvedb.models.TargetSpecificTime(**kwargs)

Bases: LCDBModel

Time series data specific to a target-observation pair.

This model stores barycentric-corrected time values that account for the specific position of a target. It serves as a junction between Target and Observation with additional time data.

id

Primary key identifier

Type:

int

target_id

Foreign key to the target

Type:

int

observation_id

Foreign key to the observation

Type:

int

barycentric_julian_dates

Array of barycentric Julian dates corrected for target position

Type:

ndarray[float64]

target

The astronomical target

Type:

Target

observation

The observation these times correspond to

Type:

Observation

Notes

Barycentric correction accounts for Earth’s motion around the solar system barycenter, providing consistent timing for astronomical observations.

Quality Flag Models

class lightcurvedb.models.QualityFlagArray(**kwargs)

Bases: LCDBModel, CreatedOnMixin

Stores quality flag arrays for astronomical observations.

QualityFlagArray represents bit-encoded quality information for time-series astronomical data. Each element in the array corresponds to a cadence in the observation, with individual bits representing different quality conditions or data issues.

This is a polymorphic base class that can be extended for mission-specific quality flag implementations with specialized bit definitions.

Parameters:
  • type (str) – Quality flag type identifier (e.g., ‘pixel_quality’, ‘cosmic_ray’)

  • observation_id (int) – Foreign key to the parent observation

  • target_id (int, optional) – Foreign key to a specific target when flags are target-specific

  • quality_flags (ndarray[int32]) – Array of 32-bit integers where each bit represents a quality condition

id

Primary key identifier

Type:

int

type

Polymorphic discriminator and quality flag category

Type:

str

observation_id

Reference to the parent observation

Type:

int

target_id

Reference to specific target (null for observation-wide flags)

Type:

int or None

quality_flags

Bit-encoded quality flag array

Type:

ndarray[int32]

observation

Parent observation relationship

Type:

Observation

target

Target relationship when flags are target-specific

Type:

Target or None

created_on

Timestamp of record creation (from CreatedOnMixin)

Type:

datetime

Examples

Creating observation-wide quality flags:

>>> obs_flags = QualityFlagArray(
...     observation_id=12345,
...     quality_flags=np.array([0, 1, 4, 5], dtype=np.int32)
... )

Creating target-specific quality flags:

>>> target_flags = QualityFlagArray(
...     observation_id=12345,
...     target_id=67890,
...     quality_flags=np.array([0, 0, 2, 8], dtype=np.int32)
... )

Interpreting bit flags:

>>> # Bit 0: Cosmic ray
>>> # Bit 1: Saturation
>>> # Bit 2: Bad pixel
>>> cosmic_ray_mask = (flags.quality_flags & 1) != 0
>>> saturated_mask = (flags.quality_flags & 2) != 0

Extending with single-table inheritance (simple approach):

>>> class TESSQualityFlags(QualityFlagArray):
...     """TESS-specific quality flags with known bit definitions."""
...     __mapper_args__ = {
...         "polymorphic_identity": "tess_quality",
...     }
...     @property
...     def cosmic_ray_events(self):
...         """Return mask of cosmic ray events (bit 0)."""
...         flags = np.array(self.quality_flags, dtype=np.int32)
...         return (flags & 1) != 0
...     @property
...     def saturated_pixels(self):
...         """Return mask of saturated pixels (bit 1)."""
...         flags = np.array(self.quality_flags, dtype=np.int32)
...         return (flags & 2) != 0
...     @property
...     def spacecraft_anomaly(self):
...         """Return mask of spacecraft anomalies (bit 4)."""
...         flags = np.array(self.quality_flags, dtype=np.int32)
...         return (flags & 16) != 0

Extending with joined-table inheritance (advanced approach):

class SpectroscopicQualityFlags(QualityFlagArray):
    """Quality flags for spectroscopic observations."""

    __tablename__ = "spectroscopic_quality_flags"
    __mapper_args__ = {
        "polymorphic_identity": "spectroscopic_quality",
    }

    # Primary key also serves as foreign key to parent table
    id = orm.mapped_column(
        sa.ForeignKey("quality_flag_array.id"), primary_key=True
    )

    # Additional columns specific to spectroscopic data
    wavelength_calibration_quality = orm.mapped_column(
        sa.types.Float,
        comment="Wavelength calibration quality score (0-1)"
    )
    spectral_resolution = orm.mapped_column(
        sa.types.Float,
        comment="Actual spectral resolution achieved"
    )
    calibration_lamp_id = orm.mapped_column(
        sa.ForeignKey("calibration_lamp.id"), nullable=True
    )

    @property
    def wavelength_drift(self):
        """Return mask of wavelength drift (bit 8)."""
        flags = np.array(self.quality_flags, dtype=np.int32)
        return (flags & 256) != 0

class PhotometricQualityFlags(QualityFlagArray):
    """Quality flags for photometric observations."""

    __tablename__ = "photometric_quality_flags"
    __mapper_args__ = {
        "polymorphic_identity": "photometric_quality",
    }

    id = orm.mapped_column(
        sa.ForeignKey("quality_flag_array.id"), primary_key=True
    )

    # Photometry-specific metadata
    sky_background_level = orm.mapped_column(
        sa.types.Float,
        comment="Median sky background in counts"
    )
    fwhm = orm.mapped_column(
        sa.types.Float,
        comment="Full width at half maximum of PSF"
    )
    extinction_coefficient = orm.mapped_column(
        sa.types.Float, nullable=True
    )

Polymorphic querying examples:

>>> # Query all quality flags for an observation
>>> all_flags = session.query(QualityFlagArray).filter_by(
...     observation_id=12345
... ).all()
>>> # Query only TESS quality flags
>>> tess_flags = session.query(TESSQualityFlags).filter_by(
...     observation_id=12345
... ).all()
>>> # Use with_polymorphic for efficient joined loading
>>> from sqlalchemy.orm import with_polymorphic
>>>
>>> poly_flags = with_polymorphic(
...     QualityFlagArray,
...     [SpectroscopicQualityFlags, PhotometricQualityFlags]
... )
>>> query = session.query(poly_flags).filter(
...     poly_flags.observation_id == 12345
... )
>>>
>>> # Access subclass-specific attributes without additional queries
>>> for flag in query:
...     if isinstance(flag, SpectroscopicQualityFlags):
...         print(f"Spectral resolution: {flag.spectral_resolution}")
...     elif isinstance(flag, PhotometricQualityFlags):
...         print(f"Sky background: {flag.sky_background_level}")
>>> # Filter by polymorphic type
>>> spectro_only = session.query(QualityFlagArray).filter_by(
...     type="spectroscopic_quality"
... ).all()

Notes

The combination of (type, observation_id, target_id) must be unique, preventing duplicate quality flag arrays for the same context. NULL values in target_id are treated as equal, so only one observation-wide quality flag array (with NULL target_id) is allowed per type and observation_id combination.

Quality flag bit definitions are mission and type-specific. Subclasses should document their specific bit meanings and may add helper methods for flag interpretation.

See also

Observation

Parent observation model

Target

Associated target for target-specific flags

Target Models

class lightcurvedb.models.Mission(**kwargs)

Bases: LCDBModel, NameAndDescriptionMixin, CreatedOnMixin

Represents a space mission or survey program.

A Mission defines the top-level context for astronomical observations, including time system definitions and associated catalogs. Examples include TESS (Transiting Exoplanet Survey Satellite).

id

Unique identifier for the mission

Type:

UUID

name

Unique name of the mission (e.g., “TESS”)

Type:

str

description

Detailed description of the mission

Type:

str

time_unit

Unit of time measurement (e.g., “day”)

Type:

str

time_epoch

Reference epoch for time calculations

Type:

Decimal

time_epoch_scale

Time scale for the epoch (e.g., “tdb”)

Type:

str

time_epoch_format

Format of the epoch specification

Type:

str

time_format_name

Unique name for the mission’s time format

Type:

str

catalogs

Associated catalogs for this mission

Type:

list[MissionCatalog]

Examples

>>> mission = Mission(name="TESS",
...                   description="Transiting Exoplanet Survey Satellite")
created_on: orm.Mapped[datetime.datetime]
name: orm.Mapped[str]
class lightcurvedb.models.MissionCatalog(**kwargs)

Bases: LCDBModel, NameAndDescriptionMixin, CreatedOnMixin

A catalog of astronomical targets associated with a mission.

MissionCatalog represents a specific catalog within a mission context, such as the TESS Input Catalog (TIC). It serves as a container for organizing targets observed by the mission.

id

Primary key identifier

Type:

int

host_mission_id

Foreign key to the parent Mission

Type:

UUID

name

Unique catalog name (e.g., “TIC” for TESS Input Catalog)

Type:

str

description

Detailed description of the catalog

Type:

str, optional

host_mission

Parent mission this catalog belongs to

Type:

Mission

targets

Collection of targets in this catalog

Type:

list[Target]

created_on: orm.Mapped[datetime.datetime]
name: orm.Mapped[str]
class lightcurvedb.models.Target(**kwargs)

Bases: LCDBModel

An astronomical target (star, planet, etc.) in a mission catalog.

Target represents an individual astronomical object that is observed during a mission. Each target is uniquely identified within its catalog by a numeric identifier (e.g., TIC ID for TESS targets).

id

Primary key identifier

Type:

int

catalog_id

Foreign key to the MissionCatalog

Type:

int

name

Catalog-specific identifier (e.g., TIC ID)

Type:

int

catalog

The catalog this target belongs to

Type:

MissionCatalog

datasets

Processed lightcurve datasets for this target

Type:

list[DataSet]

target_specific_times

Time series specific to this target

Type:

list[TargetSpecificTime]

quality_flag_arrays

Target-specific quality flags

Type:

list[QualityFlagArray]

Notes

The combination of catalog_id and name must be unique, ensuring no duplicate targets within a catalog.