Coverage for tests/utils.py : 12%

Hot-keys 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
23import scipy.signal
25from lsst.geom import Box2I, Point2I, Extent2I
26from lsst.afw.geom import SpanSet
27from lsst.afw.detection import Footprint, GaussianPsf
30def numpyToStack(images, center, offset):
31 """Convert numpy and python objects to stack objects
32 """
33 cy, cx = center
34 bands, height, width = images.shape
35 x0, y0 = offset
36 bbox = Box2I(Point2I(x0, y0), Extent2I(width, height))
37 spanset = SpanSet(bbox)
38 foot = Footprint(spanset)
39 foot.addPeak(cx+x0, cy+y0, images[:, cy, cx].max())
40 peak = foot.getPeaks()[0]
41 return foot, peak, bbox
44def initData(shape, coords, amplitudes=None, convolve=True):
45 """Initialize data for the tests
46 """
48 B, Ny, Nx = shape
49 K = len(coords)
51 if amplitudes is None:
52 amplitudes = np.ones((K,))
53 assert K == len(amplitudes)
55 _seds = [
56 np.arange(B, dtype=float),
57 np.arange(B, dtype=float)[::-1],
58 np.ones((B,), dtype=float)
59 ]
60 seds = np.array([_seds[n % 3]*amplitudes[n] for n in range(K)], dtype=np.float32)
62 morphs = np.zeros((K, Ny, Nx), dtype=np.float32)
63 for k, coord in enumerate(coords):
64 morphs[k, coord[0], coord[1]] = 1
65 images = seds.T.dot(morphs.reshape(K, -1)).reshape(shape)
67 if convolve:
68 psfRadius = 20
69 psfShape = (2*psfRadius+1, 2*psfRadius+1)
71 targetPsf = GaussianPsf(psfShape[1], psfShape[0], .9)
72 targetPsfImage = targetPsf.computeImage().array
74 psfs = [GaussianPsf(psfShape[1], psfShape[0], 1+.2*b) for b in range(B)]
75 psfImages = np.array([psf.computeImage().array for psf in psfs])
76 psfImages /= psfImages.max(axis=(1, 2))[:, None, None]
78 # Convolve the image with the psf in each channel
79 # Use scipy.signal.convolve without using FFTs as a sanity check
80 images = np.array([scipy.signal.convolve(img, psf, method="direct", mode="same")
81 for img, psf in zip(images, psfImages)])
82 # Convolve the true morphology with the target PSF,
83 # also using scipy.signal.convolve as a sanity check
84 morphs = np.array([scipy.signal.convolve(m, targetPsfImage, method="direct", mode="same")
85 for m in morphs])
86 morphs /= morphs.max()
87 psfImages /= psfImages.sum(axis=(1, 2))[:, None, None]
89 channels = range(len(images))
90 return targetPsfImage, psfImages, images, channels, seds, morphs, targetPsf, psfs