Coverage for python/lsst/cell_coadds/_single_cell_coadd.py: 69%

45 statements  

« prev     ^ index     » next       coverage.py v7.5.0, created at 2024-04-30 03:57 -0700

1# This file is part of cell_coadds. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://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 <https://www.gnu.org/licenses/>. 

21 

22from __future__ import annotations 

23 

24__all__ = ("SingleCellCoadd",) 

25 

26from collections.abc import Iterable 

27from typing import TYPE_CHECKING 

28 

29from lsst.afw.image import ImageD, ImageF 

30from lsst.geom import Box2I 

31 

32from ._common_components import CommonComponents, CommonComponentsProperties 

33from ._image_planes import ViewImagePlanes 

34from .typing_helpers import ImageLike 

35 

36if TYPE_CHECKING: 36 ↛ 37line 36 didn't jump to line 37, because the condition on line 36 was never true

37 from ._identifiers import CellIdentifiers, ObservationIdentifiers 

38 from ._image_planes import ImagePlanes, OwnedImagePlanes 

39 

40 

41class SingleCellCoadd(CommonComponentsProperties): 

42 """A single coadd cell, built only from input images that completely 

43 overlap that cell. 

44 

45 Parameters 

46 ---------- 

47 outer : `OwnedImagePlanes` 

48 The actual coadded images. 

49 psf : `ImageD` 

50 The coadded PSF image. 

51 inner_bbox : `Box2I` 

52 The bounding box of the inner region of this cell; must be disjoint 

53 with but adjacent to all other cell inner regions. 

54 inputs : `Iterable` [`ObservationIdentifiers`] 

55 Identifiers of observations that contributed to this cell. 

56 common : `CommonComponents` 

57 Image attributes common to all cells in a patch. 

58 identifiers : `CellIdentifiers` 

59 Struct of identifiers for this cell. 

60 

61 Notes 

62 ----- 

63 At present we assume a single PSF image per cell is sufficient to capture 

64 spatial variability, which seems adequate given the results we have so far 

65 and the cell sizes we intend to use. 

66 """ 

67 

68 def __init__( 

69 self, 

70 outer: OwnedImagePlanes, 

71 *, 

72 psf: ImageD, 

73 inner_bbox: Box2I, 

74 inputs: Iterable[ObservationIdentifiers], 

75 common: CommonComponents, 

76 identifiers: CellIdentifiers, 

77 ): 

78 assert outer.bbox.contains( 

79 inner_bbox 

80 ), f"Cell inner bbox {inner_bbox} is not contained by outer bbox {outer.bbox}." 

81 self._outer = outer 

82 self._psf = psf 

83 self._inner_bbox = inner_bbox 

84 self._inner = ViewImagePlanes(outer, bbox=inner_bbox, make_view=self._make_view) 

85 self._common = common 

86 # Remove any duplicate elements in the input, sorted them and make 

87 # them an immutable sequence. 

88 # TODO: Remove the conditioning in DM-40563. 

89 self._inputs = tuple(sorted(set(inputs))) if inputs else () 

90 self._identifiers = identifiers 

91 

92 @property 

93 def inner(self) -> ImagePlanes: 

94 """Image planes within the inner region of this cell that is disjoint 

95 with all other cell inner regions. 

96 """ 

97 return self._inner 

98 

99 @property 

100 def outer(self) -> ImagePlanes: 

101 """Image planes within the full outer region of this cell.""" 

102 return self._outer 

103 

104 @property 

105 def psf_image(self) -> ImageF: 

106 """The coadded PSF image.""" 

107 return self._psf 

108 

109 @property 

110 # TODO: Remove the conditioning in DM-40563. 

111 def inputs(self) -> tuple[ObservationIdentifiers, ...] | tuple[()]: 

112 """Identifiers for the input images that contributed to this cell, 

113 sorted by their `packed` attribute. 

114 """ 

115 return self._inputs 

116 

117 @property 

118 def visit_count(self) -> int: 

119 """Number of visits that contributed to this cell.""" 

120 return len(self.inputs) 

121 

122 @property 

123 def identifiers(self) -> CellIdentifiers: 

124 """Struct of unique identifiers for this cell.""" 

125 # This overrides the patch-level property from 

126 # CommonComponentsProperties to provide cell-level information. 

127 return self._identifiers 

128 

129 @property 

130 def common(self) -> CommonComponents: 

131 # Docstring inherited. 

132 return self._common 

133 

134 def _make_view(self, image: ImageLike) -> ImageLike: 

135 return image[self._inner_bbox]