Coverage for python/lsst/meas/extensions/scarlet/source.py: 27%
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
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/>.
22import numpy as np
23from scarlet.bbox import Box
25from lsst.geom import Point2I
26import lsst.log
27import lsst.afw.detection as afwDet
29__all__ = ["modelToHeavy"]
31logger = lsst.log.Log.getLogger("meas.extensions.scarlet.source")
34def modelToHeavy(source, filters, xy0=Point2I(), observation=None, dtype=np.float32):
35 """Convert the model to a `MultibandFootprint`
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`.
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.
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