Coverage for python / lsst / daf / butler / registry / obscore / default_spatial.py: 0%
34 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-28 08:36 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-28 08:36 +0000
1# This file is part of daf_butler.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This software is dual licensed under the GNU General Public License and also
10# under a 3-clause BSD license. Recipients may choose which of these licenses
11# to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12# respectively. If you choose the GPL option then the following text applies
13# (but note that there is still no warranty even if you opt for BSD instead):
14#
15# This program is free software: you can redistribute it and/or modify
16# it under the terms of the GNU General Public License as published by
17# the Free Software Foundation, either version 3 of the License, or
18# (at your option) any later version.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program. If not, see <http://www.gnu.org/licenses/>.
28from __future__ import annotations
30__all__ = ["DefaultSpatialObsCorePlugin"]
32from collections.abc import Mapping
33from typing import TYPE_CHECKING, Any
35import sqlalchemy
37from lsst.sphgeom import ConvexPolygon, LonLat, Region
39from ... import ddl
40from ._spatial import RegionTypeError, SpatialObsCorePlugin
42if TYPE_CHECKING:
43 from ..interfaces import Database
44 from ._records import Record
46# Columns added/filled by this plugin
47_COLUMNS = (
48 ddl.FieldSpec(name="s_ra", dtype=sqlalchemy.Float, doc="Central right ascension, ICRS (deg)"),
49 ddl.FieldSpec(name="s_dec", dtype=sqlalchemy.Float, doc="Central declination, ICRS (deg)"),
50 ddl.FieldSpec(name="s_fov", dtype=sqlalchemy.Float, doc="Diameter (bounds) of the covered region (deg)"),
51 ddl.FieldSpec(
52 name="s_region",
53 dtype=sqlalchemy.String,
54 length=65535,
55 doc="Sky region covered by the data product (expressed in ICRS frame)",
56 ),
57)
60class DefaultSpatialObsCorePlugin(SpatialObsCorePlugin):
61 """Class for a spatial ObsCore plugin which creates standard spatial
62 obscore columns.
64 Parameters
65 ----------
66 name : `str`
67 The name.
68 config : `~collections.abc.Mapping` [`str`, `~typing.Any`]
69 ObsCore configuration.
70 """
72 def __init__(self, *, name: str, config: Mapping[str, Any]):
73 self._name = name
75 @classmethod
76 def initialize(cls, *, name: str, config: Mapping[str, Any], db: Database | None) -> SpatialObsCorePlugin:
77 # docstring inherited.
78 return cls(name=name, config=config)
80 def extend_table_spec(self, table_spec: ddl.TableSpec) -> None:
81 # docstring inherited.
82 table_spec.fields.update(_COLUMNS)
84 def make_records(self, region: Region | None) -> Record | None:
85 # docstring inherited.
87 if region is None:
88 return None
90 record: Record = {}
92 # Get spatial parameters from the bounding circle.
93 circle = region.getBoundingCircle()
94 center = LonLat(circle.getCenter())
95 record["s_ra"] = center.getLon().asDegrees()
96 record["s_dec"] = center.getLat().asDegrees()
97 record["s_fov"] = circle.getOpeningAngle().asDegrees() * 2
99 if isinstance(region, ConvexPolygon):
100 poly = ["POLYGON ICRS"]
101 for vertex in region.getVertices():
102 lon_lat = LonLat(vertex)
103 poly += [
104 f"{lon_lat.getLon().asDegrees():.6f}",
105 f"{lon_lat.getLat().asDegrees():.6f}",
106 ]
107 record["s_region"] = " ".join(poly)
108 else:
109 raise RegionTypeError(f"Unexpected region type: {type(region)}")
111 return record