Coverage for python/lsst/daf/butler/registry/obscore/default_spatial.py: 100%
34 statements
« prev ^ index » next coverage.py v7.3.1, created at 2023-10-02 07:59 +0000
« prev ^ index » next coverage.py v7.3.1, created at 2023-10-02 07:59 +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
36from lsst.sphgeom import ConvexPolygon, LonLat, Region
38from ...core import ddl
39from ._spatial import RegionTypeError, SpatialObsCorePlugin
41if TYPE_CHECKING:
42 from ..interfaces import Database
43 from ._records import Record
45# Columns added/filled by this plugin
46_COLUMNS = (
47 ddl.FieldSpec(name="s_ra", dtype=sqlalchemy.Float, doc="Central right ascension, ICRS (deg)"),
48 ddl.FieldSpec(name="s_dec", dtype=sqlalchemy.Float, doc="Central declination, ICRS (deg)"),
49 ddl.FieldSpec(name="s_fov", dtype=sqlalchemy.Float, doc="Diameter (bounds) of the covered region (deg)"),
50 ddl.FieldSpec(
51 name="s_region",
52 dtype=sqlalchemy.String,
53 length=65535,
54 doc="Sky region covered by the data product (expressed in ICRS frame)",
55 ),
56)
59class DefaultSpatialObsCorePlugin(SpatialObsCorePlugin):
60 """Class for a spatial ObsCore plugin which creates standard spatial
61 obscore columns.
62 """
64 def __init__(self, *, name: str, config: Mapping[str, Any]):
65 self._name = name
67 @classmethod
68 def initialize(cls, *, name: str, config: Mapping[str, Any], db: Database | None) -> SpatialObsCorePlugin:
69 # docstring inherited.
70 return cls(name=name, config=config)
72 def extend_table_spec(self, table_spec: ddl.TableSpec) -> None:
73 # docstring inherited.
74 table_spec.fields.update(_COLUMNS)
76 def make_records(self, region: Region | None) -> Record | None:
77 # docstring inherited.
79 if region is None:
80 return None
82 record: Record = {}
84 # Get spatial parameters from the bounding circle.
85 circle = region.getBoundingCircle()
86 center = LonLat(circle.getCenter())
87 record["s_ra"] = center.getLon().asDegrees()
88 record["s_dec"] = center.getLat().asDegrees()
89 record["s_fov"] = circle.getOpeningAngle().asDegrees() * 2
91 if isinstance(region, ConvexPolygon):
92 poly = ["POLYGON ICRS"]
93 for vertex in region.getVertices():
94 lon_lat = LonLat(vertex)
95 poly += [
96 f"{lon_lat.getLon().asDegrees():.6f}",
97 f"{lon_lat.getLat().asDegrees():.6f}",
98 ]
99 record["s_region"] = " ".join(poly)
100 else:
101 raise RegionTypeError(f"Unexpected region type: {type(region)}")
103 return record