Hide keyboard shortcuts

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/>. 

21 

22import numpy as np 

23import scipy.signal 

24 

25from lsst.geom import Box2I, Point2I, Extent2I 

26from lsst.afw.geom import SpanSet 

27from lsst.afw.detection import Footprint, GaussianPsf 

28 

29 

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 

42 

43 

44def initData(shape, coords, amplitudes=None, convolve=True): 

45 """Initialize data for the tests 

46 """ 

47 

48 B, Ny, Nx = shape 

49 K = len(coords) 

50 

51 if amplitudes is None: 

52 amplitudes = np.ones((K,)) 

53 assert K == len(amplitudes) 

54 

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) 

61 

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) 

66 

67 if convolve: 

68 psfRadius = 20 

69 psfShape = (2*psfRadius+1, 2*psfRadius+1) 

70 

71 targetPsf = GaussianPsf(psfShape[1], psfShape[0], .9) 

72 targetPsfImage = targetPsf.computeImage().array 

73 

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] 

77 

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] 

88 

89 channels = range(len(images)) 

90 return targetPsfImage, psfImages, images, channels, seds, morphs, targetPsf, psfs