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

# 

# LSST Data Management System 

# Copyright 2008, 2009, 2010 LSST Corporation. 

# 

# This product includes software developed by the 

# LSST Project (http://www.lsst.org/). 

# 

# This program is free software: you can redistribute it and/or modify 

# it under the terms of the GNU General Public License as published by 

# the Free Software Foundation, either version 3 of the License, or 

# (at your option) any later version. 

# 

# This program is distributed in the hope that it will be useful, 

# but WITHOUT ANY WARRANTY; without even the implied warranty of 

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

# GNU General Public License for more details. 

# 

# You should have received a copy of the LSST License Statement and 

# the GNU General Public License along with this program. If not, 

# see <http://www.lsstcorp.org/LegalNotices/>. 

# 

 

__all__ = ["clean"] 

 

 

import numpy as np 

 

from . import LeastSqFitter1dPoly 

 

 

def clean(srcMatch, wcs, order=3, nsigma=3): 

"""Remove bad points from srcMatch 

 

Input: 

srcMatch : list of det::SourceMatch 

order: Order of polynomial to use in robust fitting 

nsigma: Sources more than this far away from the robust best fit 

polynomial are removed 

 

Return: 

list of det::SourceMatch of the good data points 

""" 

 

N = len(srcMatch) 

catX = np.zeros(N) 

# catY = np.zeros(N) 

for i in range(N): 

x, y = wcs.skyToPixel(srcMatch[i].first.getCoord()) 

catX[i] = x 

# catY[i] = y 

 

# TODO -- why does this only use X? 

 

x = np.array([s.second.getX() for s in srcMatch]) 

dx = x - catX 

sigma = np.zeros_like(dx) + 0.1 

 

idx = indicesOfGoodPoints(x, dx, sigma, order=order, nsigma=nsigma) 

 

clean = [] 

for i in idx: 

clean.append(srcMatch[i]) 

return clean 

 

 

def indicesOfGoodPoints(x, y, s, order=1, nsigma=3, maxiter=100): 

"""Return a list of indices in the range [0, len(x)] 

of points that lie less than nsigma away from the robust 

best fit polynomial 

""" 

 

# Indices of elements of x sorted in order of increasing value 

idx = x.argsort() 

newidx = [] 

for niter in range(maxiter): 

rx = chooseRx(x, idx, order) 

ry = chooseRy(y, idx, order) 

rs = np.ones((len(rx))) 

 

lsf = LeastSqFitter1dPoly(list(rx), list(ry), list(rs), order) 

fit = [lsf.valueAt(value) for value in rx] 

f = [lsf.valueAt(value) for value in x] 

 

sigma = (y-f).std() 

deviance = np.fabs((y - f) / sigma) 

newidx = np.flatnonzero(deviance < nsigma) 

 

if False: 

import matplotlib.pyplot as plt 

plt.plot(x, y, 'ks') 

plt.plot(rx, ry, 'b-') 

plt.plot(rx, ry, 'bs') 

plt.plot(rx, fit, 'ms') 

plt.plot(rx, fit, 'm-') 

# plt.plot(x[newidx], y[newidx], 'rs') 

plt.show() 

 

# If we haven't culled any points we're finished cleaning 

if len(newidx) == len(idx): 

break 

 

# We get here because we either a) stopped finding bad points 

# or b) ran out of iterations. Either way, we just return our 

# list of indices of good points. 

return newidx 

 

 

def chooseRx(x, idx, order): 

"""Create order+1 values of the ordinate based on the median of groups of elements of x""" 

rSize = len(idx)/float(order+1) # Note, a floating point number 

rx = np.zeros((order+1)) 

 

for i in range(order+1): 

rng = list(range(int(rSize*i), int(rSize*(i+1)))) 

rx[i] = np.mean(x[idx[rng]]) 

return rx 

 

 

def chooseRy(y, idx, order): 

"""Create order+1 values of the ordinate based on the median of groups of elements of y""" 

rSize = len(idx)/float(order+1) # Note, a floating point number 

ry = np.zeros((order+1)) 

 

for i in range(order+1): 

rng = list(range(int(rSize*i), int(rSize*(i+1)))) 

ry[i] = np.median(y[idx[rng]]) 

return ry