Observatory Hierarchy ===================== .. verified:: 2025-11-25 :reviewer: Christof Buchbender The observatory hierarchy models the physical hardware that produces astronomical data. This is a relatively stable part of the database - these entities change infrequently (when new instruments are installed, for example). Starting the hierarchy with the observatory entity prepares the database and related components for re-use with other future observatories. For CCAT the observatory entry could be omitted, and the telescope, instrument, and module entities would be used directly. The Hierarchy ------------- The hierarchy follows this structure: .. mermaid:: graph TB OBS[Observatory] TEL[Telescope] INST[Instrument] MOD[InstrumentModule] CONFIG[InstrumentModuleConfiguration] OBS -->|has many| TEL TEL -->|has many| INST INST -->|has many| MOD MOD -->|has many| CONFIG style OBS fill:#e1f5ff style TEL fill:#e1f5ff style INST fill:#e1f5ff style MOD fill:#e1f5ff style CONFIG fill:#e1f5ff Observatory ----------- :py:class:`~ccat_ops_db.models.Observatory` groups telescopes that belong to the same facility or organization. **Example**: CCAT Observatory For complete attribute details, see :py:class:`~ccat_ops_db.models.Observatory`. Telescope --------- :py:class:`~ccat_ops_db.models.Telescope` represents a physical telescope at a specific location. **Example**: Fred Young Submillimeter Telescope (FYST) at 5,600m elevation on Cerro Chajnantor For complete attribute details, see :py:class:`~ccat_ops_db.models.Telescope`. Instrument ---------- :py:class:`~ccat_ops_db.models.Instrument` represents a scientific instrument mounted on a telescope. The ``available`` flag indicates if the instrument is currently operational or installed, allowing tracking of instrument commissioning and maintenance periods. **Examples**: * CHAI (heterodyne array) * Prime-Cam (continuum camera) For complete attribute details, see :py:class:`~ccat_ops_db.models.Instrument`. InstrumentModule ---------------- :py:class:`~ccat_ops_db.models.InstrumentModule` represents a sub-component of an instrument that produces data. The module level is where data production happens - each :py:class:`~ccat_ops_db.models.RawDataFile` is associated with a specific :py:class:`~ccat_ops_db.models.InstrumentModule`. **Examples for CHAI**: * LFA (64 pixels, 455-495 GHz) * HFA (64 pixels, 800-820 GHz) * Mini-CHAI (1 pixel dual-band) **Examples for Prime-Cam**: * 280 GHz module (10,350 detectors) * 350 GHz module (10,350 detectors) * 850 GHz module (41,400 detectors) For complete attribute details, see :py:class:`~ccat_ops_db.models.InstrumentModule`. Configuration Layer ------------------- InstrumentModuleConfiguration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :py:class:`~ccat_ops_db.models.InstrumentModuleConfiguration` captures the specific settings used for an observation with a particular module. It is polymorphic with subclasses for different instrument types: :py:class:`~ccat_ops_db.models.ChaiModuleConfiguration` for CHAI heterodyne observations and :py:class:`~ccat_ops_db.models.PrimeCamModuleConfiguration` for Prime-Cam continuum observations. For complete attribute details, see :py:class:`~ccat_ops_db.models.InstrumentModuleConfiguration`. ChaiModuleConfiguration ^^^^^^^^^^^^^^^^^^^^^^^ :py:class:`~ccat_ops_db.models.ChaiModuleConfiguration` is specific to CHAI heterodyne observations. **Example**: Observing CO(4-3) line at 461.041 GHz with the LFA array For complete attribute details, see :py:class:`~ccat_ops_db.models.ChaiModuleConfiguration`. PrimeCamModuleConfiguration ^^^^^^^^^^^^^^^^^^^^^^^^^^^ :py:class:`~ccat_ops_db.models.PrimeCamModuleConfiguration` is specific to Prime-Cam continuum observations. **Example**: Observing at 280 GHz with specific detector readout settings For complete attribute details, see :py:class:`~ccat_ops_db.models.PrimeCamModuleConfiguration`. Why This Structure? ------------------- **Separation of Hardware and Configuration** The separation of hardware (Observatory/Telescope/Instrument/Module) from configuration (InstrumentModuleConfiguration) allows the same hardware to be used in different ways. For example, the same CHAI LFA module can observe different spectral lines in different observations. **Module-Level Data Production** The module level is critical because different modules can observe simultaneously (e.g., CHAI's LFA and HFA arrays). Each module produces its own data files, which are tracked separately. **Availability Tracking** The ``available`` flags on :py:class:`~ccat_ops_db.models.Instrument` and :py:class:`~ccat_ops_db.models.InstrumentModule` allow tracking of instrument/module commissioning and maintenance periods. This way e.g. the scheduler can look up all available instruments and modules to consider for scheduling observations. **Configuration Links to Observations** The configuration layer ties hardware to observations - each :py:class:`~ccat_ops_db.models.ExecutedObsUnit` has associated :py:class:`~ccat_ops_db.models.InstrumentModuleConfiguration` objects that record exactly how the hardware was used. Code Examples ------------- Querying for all available instruments on FYST:: from ccat_ops_db import init_ccat_ops_db from ccat_ops_db.models import Telescope, Instrument session, engine = init_ccat_ops_db() fyst = session.query(Telescope).filter_by(name="FYST").first() available_instruments = session.query(Instrument).filter_by( telescope_id=fyst.id, available=True ).all() Finding which modules produced data for a specific observation:: from ccat_ops_db.models import ExecutedObsUnit, InstrumentModule, RawDataPackage executed_obs = session.query(ExecutedObsUnit).filter_by(id=obs_id).first() modules = session.query(InstrumentModule).join(RawDataPackage).filter_by( executed_obs_unit_id=executed_obs.id ).distinct().all() Looking up the configuration used for a particular observation:: from ccat_ops_db.models import ObsUnit, InstrumentModuleConfiguration, ChaiModuleConfiguration obs_unit = session.query(ObsUnit).filter_by(name="my_obs").first() configs = obs_unit.instrument_module_configurations for config in configs: if isinstance(config, ChaiModuleConfiguration): print(f"Observing line: {config.line.name}") Related Documentation --------------------- * Complete API reference: :doc:`../api_reference/models` * Observation model: :doc:`observation_model` * Data model: :doc:`data_model`