Coverage for python / lsst / daf / butler / dimensions / _skypix.py: 49%
76 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-06 08:30 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-06 08:30 +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__ = (
31 "SkyPixDimension",
32 "SkyPixSystem",
33)
35from collections.abc import Iterator, Mapping
36from types import MappingProxyType
37from typing import TYPE_CHECKING, cast
39from lsst.sphgeom import PixelizationABC
41from .._named import NamedValueAbstractSet, NamedValueSet
42from .._topology import TopologicalFamily, TopologicalRelationshipEndpoint, TopologicalSpace
43from ..column_spec import IntColumnSpec
44from ._elements import Dimension, KeyColumnSpec, MetadataColumnSpec
46if TYPE_CHECKING:
47 from ..queries.tree import DimensionFieldReference
48 from ._group import DimensionGroup
51class SkyPixSystem(TopologicalFamily):
52 """Class for hierarchical pixelization of the sky.
54 A `TopologicalFamily` that represents a hierarchical pixelization of the
55 sky.
57 Parameters
58 ----------
59 name : `str`
60 Name of the system.
61 maxLevel : `int`
62 Maximum level (inclusive) of the hierarchy.
63 PixelizationClass : `type` (`lsst.sphgeom.PixelizationABC` subclass)
64 Class whose instances represent a particular level of this
65 pixelization.
66 """
68 def __init__(
69 self,
70 name: str,
71 *,
72 maxLevel: int,
73 PixelizationClass: type[PixelizationABC],
74 ):
75 super().__init__(name, TopologicalSpace.SPATIAL)
76 self.maxLevel = maxLevel
77 self.PixelizationClass = PixelizationClass
78 self._members: dict[int, SkyPixDimension] = {}
79 for level in range(maxLevel + 1):
80 self._members[level] = SkyPixDimension(self, level)
82 def choose(self, dimensions: DimensionGroup) -> SkyPixDimension:
83 # Docstring inherited from TopologicalFamily.
84 best: SkyPixDimension | None = None
85 for endpoint_name in dimensions.skypix:
86 endpoint = dimensions.universe[endpoint_name]
87 if endpoint not in self:
88 continue
89 assert isinstance(endpoint, SkyPixDimension)
90 if best is None or best.level < endpoint.level:
91 best = endpoint
92 if best is None:
93 raise RuntimeError(f"No recognized endpoints for {self.name} in {dimensions}.")
94 return best
96 def __getitem__(self, level: int) -> SkyPixDimension:
97 return self._members[level]
99 def __iter__(self) -> Iterator[SkyPixDimension]:
100 return iter(self._members.values())
102 def __len__(self) -> int:
103 return len(self._members)
105 def make_column_reference(self, endpoint: TopologicalRelationshipEndpoint) -> DimensionFieldReference:
106 from ..queries.tree import DimensionFieldReference
108 return DimensionFieldReference(element=cast(SkyPixDimension, endpoint), field="region")
111class SkyPixDimension(Dimension):
112 """Special dimension for sky pixelizations.
114 A special `Dimension` subclass for hierarchical pixelizations of the
115 sky at a particular level.
117 Unlike most other dimensions, skypix dimension records are not stored in
118 the database, as these records only contain an integer pixel ID and a
119 region on the sky, and each of these can be computed directly from the
120 other.
122 Parameters
123 ----------
124 system : `SkyPixSystem`
125 Pixelization system this dimension belongs to.
126 level : `int`
127 Integer level of this pixelization (smaller numbers are coarser grids).
128 """
130 def __init__(self, system: SkyPixSystem, level: int):
131 self.system = system
132 self.level = level
133 self.pixelization = system.PixelizationClass(level)
135 @property
136 def name(self) -> str:
137 return f"{self.system.name}{self.level}"
139 @property
140 def required(self) -> NamedValueAbstractSet[Dimension]:
141 # Docstring inherited from DimensionElement.
142 return NamedValueSet({self}).freeze()
144 @property
145 def implied(self) -> NamedValueAbstractSet[Dimension]:
146 # Docstring inherited from DimensionElement.
147 return NamedValueSet().freeze()
149 @property
150 def topology(self) -> Mapping[TopologicalSpace, TopologicalFamily]:
151 # Docstring inherited from TopologicalRelationshipEndpoint
152 return MappingProxyType({TopologicalSpace.SPATIAL: self.system})
154 @property
155 def metadata_columns(self) -> NamedValueAbstractSet[MetadataColumnSpec]:
156 # Docstring inherited from DimensionElement.
157 return NamedValueSet().freeze()
159 @property
160 def documentation(self) -> str:
161 # Docstring inherited from DimensionElement.
162 return f"Level {self.level} of the {self.system.name!r} sky pixelization system."
164 def hasTable(self) -> bool:
165 # Docstring inherited from DimensionElement.hasTable.
166 return False
168 @property
169 def has_own_table(self) -> bool:
170 # Docstring inherited from DimensionElement.
171 return False
173 @property
174 def unique_keys(self) -> NamedValueAbstractSet[KeyColumnSpec]:
175 # Docstring inherited from DimensionElement.
176 return NamedValueSet([IntColumnSpec(name="id", nullable=False)]).freeze()
178 # Class attributes below are shadowed by instance attributes, and are
179 # present just to hold the docstrings for those instance attributes.
181 system: SkyPixSystem
182 """Pixelization system this dimension belongs to (`SkyPixSystem`).
183 """
185 level: int
186 """Integer level of this pixelization (smaller numbers are coarser grids).
187 """
189 pixelization: PixelizationABC
190 """Pixelization instance that can compute regions from IDs and IDs from
191 points (`sphgeom.PixelizationABC`).
192 """