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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

#!/usr/bin/env python 

 

import numpy 

import matplotlib.figure as figure 

from matplotlib.backends.backend_agg import FigureCanvasAgg as FigCanvas 

from matplotlib.patches import Rectangle 

 

import lsst.afw.geom as afwGeom 

import lsst.afw.image as afwImage 

import lsst.afw.detection as afwDet 

from lsst.log import Log 

import lsst.meas.algorithms as measAlg 

import lsst.meas.deblender.baseline as measDeb 

 

 

def randomCoords(nSrc, grid=False, minSep=0.15, maxSep=0.25): 

 

if grid: 

# 3 in a row is a known failure, so ignore nSrc 

xy = ( 

(0.33, 0.33), 

(0.33, 0.67), 

(0.67, 0.33), 

(0.67, 0.67), 

) 

nSrc = len(xy) 

else: 

i = 0 

x = numpy.array([numpy.random.uniform(maxSep, 1.0-maxSep)]) 

y = numpy.array([numpy.random.uniform(maxSep, 1.0-maxSep)]) 

nMax = 10 

 

# keep trying to add sources until we have nSrc 

while (i < nSrc - 1): 

smin = 0.0 

iTry = 0 

_x, _y = None, None 

while ((smin < minSep or smin > maxSep) and iTry < nMax): 

_x, _y = numpy.random.uniform(maxSep, 1.0-maxSep, 2) 

dx = x - _x 

dy = y - _y 

s = numpy.sqrt(dx*dx + dy*dy) 

smin = s.min() 

print(smin, iTry) 

iTry += 1 

if _x and _y: 

x = numpy.append(x, _x) 

y = numpy.append(y, _y) 

i += 1 

xy = list(zip(x, y)) 

 

return xy 

 

 

def makeFakeImage(nx, ny, xys, fluxes, fwhms): 

 

mimg = afwImage.MaskedImageF(nx, ny) 

img = mimg.getImage().getArray() 

var = mimg.getVariance().getArray() 

var[:, :] = 1.0 

 

nSrc = len(xys) 

 

n = min([nx, ny]) 

 

for i in range(nSrc): 

x, y = nx*xys[i][0], ny*xys[i][1] 

src = measAlg.DoubleGaussianPsf(n, n, fwhms[i], fwhms[i], 0.03) 

pimg = src.computeImage(afwGeom.Point2D(x, y)) 

pbox = pimg.getBBox(afwImage.PARENT) 

pbox.clip(mimg.getBBox()) 

pimg = pimg.Factory(pimg, pbox, afwImage.PARENT) 

xlo, xhi = pbox.getMinX(), pbox.getMaxX() + 1 

ylo, yhi = pbox.getMinY(), pbox.getMaxY() + 1 

img[ylo:yhi, xlo:xhi] += fluxes[i]*pimg.getArray() 

 

return mimg 

 

 

def detect(mimg): 

 

thresh = afwDet.createThreshold(10., 'value', True) 

fpSet = afwDet.FootprintSet(mimg, thresh, 'DETECTED', 1) 

fps = fpSet.getFootprints() 

print('found', len(fps), 'footprints') 

for fp in fps: 

print('peaks:', len(fp.getPeaks())) 

for pk in fp.getPeaks(): 

print(' ', pk.getIx(), pk.getIy()) 

return fps[0] if fps else None 

 

 

def makePortionFigure(deblend, origMimg, origMimgB, pedestal=0.0): 

 

portions = [] 

centers = [] 

boxes = [] 

for i, peak in enumerate(deblend.peaks): 

# make an image matching the size of the original 

portionedImg = afwImage.ImageF(origMimg.getBBox()) 

 

# get the heavy footprint for the flux aportioned to this peak 

heavyFoot = peak.getFluxPortion() 

footBox = heavyFoot.getBBox() 

pk = peak.peak 

centers.append((pk.getIx(), pk.getIy())) 

boxes.append(((footBox.getMinX(), footBox.getMinY()), footBox.getWidth(), footBox.getHeight())) 

print(i, peak, pk.getIx(), pk.getIy(), footBox, "skip:", peak.skip) 

 

# make a sub-image for this peak, and put the aportioned flux into it 

portionedSubImg = afwImage.ImageF(portionedImg, footBox) 

portionedSubImg += pedestal 

heavyFoot.insert(portionedSubImg) 

 

portions.append(portionedImg) 

 

fig = figure.Figure(figsize=(8, 10)) 

FigCanvas(fig) 

 

g = int(numpy.ceil(numpy.sqrt(len(deblend.peaks)))) 

gx, gy = g, g+1 

 

def makeAx(ax, im, title): 

im = im.getArray() 

a = ax.imshow(im, cmap='gray') 

cb = fig.colorbar(a) 

ax.set_title(title, size='small') 

ax.set_xlim((0, im.shape[0])) 

ax.set_ylim((0, im.shape[1])) 

for t in ax.get_xticklabels() + ax.get_yticklabels() + cb.ax.get_yticklabels(): 

t.set_size('x-small') 

return ax 

 

# show the originals 

makeAx(fig.add_subplot(gy, gx, 1), origMimg.getImage(), "Orig") 

makeAx(fig.add_subplot(gy, gx, 2), origMimgB.getImage(), "Missing Src") 

 

# show each aportioned image 

i = gy 

for i_p in range(len(portions)): 

im = portions[i_p] 

ax = makeAx(fig.add_subplot(gy, gx, i), im, "") 

xy, w, h = boxes[i_p] 

ax.add_patch(Rectangle(xy, w, h, fill=False, edgecolor='#ff0000')) 

for x, y in centers: 

ax.plot(x, y, '+', color='#00ff00') 

i += 1 

 

return fig 

 

 

def main(): 

 

log = Log.getLogger('foo') 

log.setLevel(Log.INFO) 

 

ny, nx = 256, 256 

 

fwhm0 = 5.0 

psf = measAlg.DoubleGaussianPsf(21, 21, fwhm0) 

flux = 1.0e6 

 

# make two sets of fake data, seconds set is missing a source 

nSrc = 4 

xy = randomCoords(nSrc) 

fluxs = [flux]*(nSrc-1) + [0.7*flux] 

mimg = makeFakeImage(nx, ny, xy, fluxs, [3.0*fwhm0]*nSrc) 

mimg.writeFits("foo.fits") 

 

nSrcB = nSrc - 4 

mimgB = makeFakeImage(nx, ny, xy[0:nSrcB], fluxs[0:nSrcB], [3.0*fwhm0]*nSrcB) 

mimgB.writeFits("fooB.fits") 

 

# Run the detection 

fp = detect(mimg) 

 

# deblend mimgB (missing a peak) using the fp with the extra peak 

deb = measDeb.deblend(fp, mimgB, psf, fwhm0, verbose=True, rampFluxAtEdge=True, log=log) 

print("Deblended peaks: ", len(deb.peaks)) 

 

fig = makePortionFigure(deb, mimg, mimgB) 

fig.savefig("test.png") 

 

 

if __name__ == '__main__': 

main()