Coverage for python / lsst / images / psfs / _base.py: 58%

32 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-18 09:00 +0000

1# This file is part of lsst-images. 

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# Use of this source code is governed by a 3-clause BSD-style 

10# license that can be found in the LICENSE file. 

11 

12from __future__ import annotations 

13 

14__all__ = ("PointSpreadFunction",) 

15 

16from abc import ABC, abstractmethod 

17from typing import Any 

18 

19from .._geom import Bounds, Box 

20from .._image import Image 

21 

22 

23class PointSpreadFunction(ABC): 

24 """Base class for point-spread function models.""" 

25 

26 @property 

27 @abstractmethod 

28 def bounds(self) -> Bounds: 

29 """The region where this PSF model is valid.""" 

30 raise NotImplementedError() 

31 

32 @property 

33 @abstractmethod 

34 def kernel_bbox(self) -> Box: 

35 """Bounding box of all images returned by `compute_kernel_image`.""" 

36 raise NotImplementedError() 

37 

38 @abstractmethod 

39 def compute_kernel_image(self, *, x: float, y: float) -> Image: 

40 """Evaluate the PSF model into an image suitable for convolution. 

41 

42 Parameters 

43 ---------- 

44 x 

45 Column position coordinate to evaluate at. 

46 y 

47 Row position coordinate to evaluate at. 

48 

49 Returns 

50 ------- 

51 Image 

52 An image of the PSF, centered on the center of the center pixel, 

53 which is defined to be ``(0, 0)`` by the image's origin. 

54 """ 

55 raise NotImplementedError() 

56 

57 @abstractmethod 

58 def compute_stellar_image(self, *, x: float, y: float) -> Image: 

59 """Evaluate the PSF model into an image suitable for comparison with 

60 the image of an astrophysical point source. 

61 

62 Parameters 

63 ---------- 

64 x 

65 Column position coordinate to evaluate at. 

66 y 

67 Row position coordinate to evaluate at. 

68 

69 Returns 

70 ------- 

71 Image 

72 An image of the PSF, centered on the given coordinates, just like 

73 the postage stamp of a star would be. 

74 """ 

75 raise NotImplementedError() 

76 

77 @abstractmethod 

78 def compute_stellar_bbox(self, *, x: float, y: float) -> Box: 

79 """Return the bounding box of the image that would be returned by 

80 `compute_stellar_image`. 

81 

82 Parameters 

83 ---------- 

84 x 

85 Column position coordinate to evaluate at. 

86 y 

87 Row position coordinate to evaluate at. 

88 

89 Returns 

90 ------- 

91 Box 

92 The bounding box of the image that would be returned by 

93 `compute_stellar_image` at the given point. 

94 """ 

95 raise NotImplementedError() 

96 

97 @classmethod 

98 def from_legacy(cls, legacy_psf: Any, bounds: Bounds) -> PointSpreadFunction: 

99 """Make a PSF object from a legacy `lsst.afw.detection.Psf` instance. 

100 

101 Parameters 

102 ---------- 

103 legacy_psf 

104 Legacy PSF object. 

105 bounds 

106 The region where this PSF model is valid. 

107 

108 Returns 

109 ------- 

110 PointSpreadFunction 

111 A `PointSpreadFunction` instance. 

112 

113 Notes 

114 ----- 

115 This base class method is a factory dispatch function that 

116 automatically selects the right `PointSpreadFunction` subclass to 

117 use. When that is already known, a subclass `from_legacy` method can 

118 be called instead. 

119 """ 

120 from lsst.afw.detection import Psf 

121 from lsst.meas.extensions.piff.piffPsf import PiffPsf 

122 

123 match legacy_psf: 

124 case PiffPsf(): 

125 from ._piff import PiffWrapper 

126 

127 return PiffWrapper.from_legacy(legacy_psf, bounds) 

128 case Psf(): 

129 from ._legacy import LegacyPointSpreadFunction 

130 

131 return LegacyPointSpreadFunction.from_legacy(legacy_psf, bounds) 

132 case _: 

133 raise TypeError(f"{type(legacy_psf).__name__!r} is not a recognized legacy PSF type.")