lsst.skymap g037fbe16b5+d85c0663ba
packers.py
Go to the documentation of this file.
1# This file is part of skymap.
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 program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
21
22__all__ = ("SkyMapDimensionPacker",)
23
24from lsst.daf.butler import DimensionPacker, DimensionGraph, DataCoordinate
25
26
27class SkyMapDimensionPacker(DimensionPacker):
28 """A `DimensionPacker` for tract, patch and optionally band,
29 given a SkyMap.
30
31 Parameters
32 ----------
33 fixed : `lsst.daf.butler.DataCoordinate`
34 Expanded data ID that must include at least the skymap dimension.
35 dimensions : `lsst.daf.butler.DimensionGraph`
36 The dimensions of data IDs packed by this instance. Must include
37 skymap, tract, and patch, and may include band.
38 """
39
40 SUPPORTED_FILTERS = (
41 [None]
42 + list("ugrizyUBGVRIZYJHK") # split string into single chars
43 + [f"N{d}" for d in (387, 515, 656, 816, 921, 1010)] # HSC narrow-bands
44 )
45 """band names supported by this packer.
46
47 New filters should be added to the end of the list to maximize
48 compatibility with existing IDs.
49 """
50
51 @classmethod
52 def getIntFromFilter(cls, name):
53 """Return an integer that represents the band with the given
54 name.
55 """
56 try:
57 return cls.SUPPORTED_FILTERSSUPPORTED_FILTERS.index(name)
58 except ValueError:
59 raise NotImplementedError(f"band '{name}' not supported by this ID packer.")
60
61 @classmethod
62 def getFilterNameFromInt(cls, num):
63 """Return an band name from its integer representation.
64 """
65 return cls.SUPPORTED_FILTERSSUPPORTED_FILTERS[num]
66
67 @classmethod
69 return len(cls.SUPPORTED_FILTERSSUPPORTED_FILTERS)
70
71 @classmethod
72 def configure(cls, dimensions):
73 # Docstring inherited from DataIdPacker.configure
74 assert dimensions.given == ["skymap"]
75 assert dimensions.required.issuperset(["tract", "patch"])
76 metadata = {"skymap": ["tract_max", "patch_nx_max", "patch_ny_max"]}
77 kwds = {}
78 return metadata, kwds
79
80 def __init__(self, fixed: DataCoordinate, dimensions: DimensionGraph):
81 super().__init__(fixed, dimensions)
82 record = fixed.records["skymap"]
83 self._skyMapName_skyMapName = record.name
84 self._patchMax_patchMax = record.patch_nx_max * record.patch_ny_max
85 self._tractPatchMax_tractPatchMax = self._patchMax_patchMax*record.tract_max
86 if "band" in dimensions:
87 self._filterMax_filterMax = self.getMaxIntForFiltersgetMaxIntForFilters()
88 else:
89 self._filterMax_filterMax = None
90
91 @property
92 def maxBits(self) -> int:
93 # Docstring inherited from DataIdPacker.maxBits
94 packedMax = self._tractPatchMax_tractPatchMax
95 if self._filterMax_filterMax is not None:
96 packedMax *= self._filterMax_filterMax
97 return packedMax.bit_length()
98
99 def _pack(self, dataId: DataCoordinate) -> int:
100 # Docstring inherited from DataIdPacker.pack
101 packed = dataId["patch"] + self._patchMax_patchMax*dataId["tract"]
102 if self._filterMax_filterMax is not None:
103 packed += self.getIntFromFiltergetIntFromFilter(dataId["band"])*self._tractPatchMax_tractPatchMax
104 return packed
105
106 def unpack(self, packedId: int) -> DataCoordinate:
107 # Docstring inherited from DataIdPacker.unpack
108 d = {"skymap": self._skyMapName_skyMapName}
109 if self._filterMax_filterMax is not None:
110 d["band"] = self.getFilterNameFromIntgetFilterNameFromInt(packedId // self._tractPatchMax_tractPatchMax)
111 packedId %= self._tractPatchMax_tractPatchMax
112 d["tract"] = packedId // self._patchMax_patchMax
113 d["patch"] = packedId % self._patchMax_patchMax
114 return DataCoordinate.standardize(d, graph=self.dimensions)
def __init__(self, DataCoordinate fixed, DimensionGraph dimensions)
Definition: packers.py:80
DataCoordinate unpack(self, int packedId)
Definition: packers.py:106