Coverage for python/lsst/meas/extensions/scarlet/source.py: 27%

26 statements  

« prev     ^ index     » next       coverage.py v7.1.0, created at 2023-02-05 18:26 -0800

1# This file is part of meas_extensions_scarlet. 

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 

22import numpy as np 

23from scarlet.bbox import Box 

24 

25from lsst.geom import Point2I 

26import lsst.log 

27import lsst.afw.detection as afwDet 

28 

29__all__ = ["modelToHeavy"] 

30 

31logger = lsst.log.Log.getLogger("meas.extensions.scarlet.source") 

32 

33 

34def modelToHeavy(source, filters, xy0=Point2I(), observation=None, dtype=np.float32): 

35 """Convert the model to a `MultibandFootprint` 

36 

37 Parameters 

38 ---------- 

39 source : `scarlet.Component` 

40 The source to convert to a `HeavyFootprint`. 

41 filters : `iterable` 

42 A "list" of names for each filter. 

43 xy0 : `lsst.geom.Point2I` 

44 `(x,y)` coordinates of the bounding box containing the 

45 `HeavyFootprint`. If `observation` is not `None` then 

46 this parameter is updated with the position of the new model 

47 observation : `scarlet.Observation` 

48 The scarlet observation, used to convolve the image with 

49 the origin PSF. If `observation`` is `None` then the 

50 `HeavyFootprint` will exist in the model frame. 

51 dtype : `numpy.dtype` 

52 The data type for the returned `HeavyFootprint`. 

53 

54 Returns 

55 ------- 

56 mHeavy : `lsst.detection.MultibandFootprint` 

57 The multi-band footprint containing the model for the source. 

58 """ 

59 if observation is not None: 

60 # We want to convolve the model with the observed PSF, 

61 # which means we need to grow the model box by the PSF to 

62 # account for all of the flux after convolution. 

63 # FYI: The `scarlet.Box` class implements the `&` operator 

64 # to take the intersection of two boxes. 

65 

66 # Get the PSF size and radii to grow the box 

67 py, px = observation.psf.get_model().shape[1:] 

68 dh = py // 2 

69 dw = px // 2 

70 shape = (source.bbox.shape[0], source.bbox.shape[1] + py, source.bbox.shape[2] + px) 

71 origin = (source.bbox.origin[0], source.bbox.origin[1] - dh, source.bbox.origin[2] - dw) 

72 # Create the larger box to fit the model + PSf 

73 bbox = Box(shape, origin=origin) 

74 # Only use the portion of the convolved model that fits in the image 

75 overlap = bbox & source.frame.bbox 

76 # Load the full multiband model in the larger box 

77 model = source.model_to_box(overlap) 

78 # Convolve the model with the PSF in each band 

79 # Always use a real space convolution to limit artifacts 

80 model = observation.renderer.convolve(model, convolution_type="real").astype(dtype) 

81 # Update xy0 with the origin of the sources box 

82 xy0 = Point2I(overlap.origin[-1] + xy0.x, overlap.origin[-2] + xy0.y) 

83 else: 

84 model = source.get_model().astype(dtype) 

85 mHeavy = afwDet.MultibandFootprint.fromArrays(filters, model, xy0=xy0) 

86 peakCat = afwDet.PeakCatalog(source.detectedPeak.table) 

87 peakCat.append(source.detectedPeak) 

88 for footprint in mHeavy: 

89 footprint.setPeakCatalog(peakCat) 

90 return mHeavy