LSSTApplications  10.0+286,10.0+36,10.0+46,10.0-2-g4f67435,10.1+152,10.1+37,11.0,11.0+1,11.0-1-g47edd16,11.0-1-g60db491,11.0-1-g7418c06,11.0-2-g04d2804,11.0-2-g68503cd,11.0-2-g818369d,11.0-2-gb8b8ce7
LSSTDataManagementBasePackage
cleanBadPoints.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 # Copyright 2008, 2009, 2010 LSST Corporation.
4 #
5 # This product includes software developed by the
6 # LSST Project (http://www.lsst.org/).
7 #
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the LSST License Statement and
19 # the GNU General Public License along with this program. If not,
20 # see <http://www.lsstcorp.org/LegalNotices/>.
21 #
22 
23 
24 import os
25 import numpy as np
26 
27 import lsst.afw.detection as det
28 
29 import sipLib as sip
30 
31 
32 def clean(srcMatch, wcs, order=3, nsigma=3):
33  """Remove bad points from srcMatch
34 
35  Input:
36  srcMatch : std::vector<det::SourceMatch>
37  order: Order of polynomial to use in robust fitting
38  nsigma: Sources more than this far away from the robust best fit
39  polynomial are removed
40 
41  Return:
42  std::vector<det::SourceMatch> of the good data points
43  """
44 
45  N = len(srcMatch)
46  catX = np.zeros(N)
47  #catY = np.zeros(N)
48  for i in range(N):
49  x,y = wcs.skyToPixel(srcMatch[i].first.getCoord())
50  catX[i] = x
51  #catY[i] = y
52 
53  ## FIXME -- why does this only use X?
54 
55  x = np.array([s.second.getX() for s in srcMatch])
56  dx = x - catX
57  sigma = np.zeros_like(dx) + 0.1
58 
59  idx = indicesOfGoodPoints(x, dx, sigma, order=order, nsigma=nsigma)
60 
61  clean = []
62  for i in idx:
63  clean.append(srcMatch[i])
64  return clean
65 
66 
67 
68 def indicesOfGoodPoints(x, y, s, order=1, nsigma=3, maxiter=100):
69  """Return a list of indices in the range [0, len(x)]
70  of points that lie less than nsigma away from the robust
71  best fit polynomial
72  """
73 
74  #Indices of elements of x sorted in order of increasing value
75  idx = x.argsort()
76  newidx=[]
77  for niter in xrange(maxiter):
78  rx = chooseRx(x, idx, order)
79  ry = chooseRy(y, idx, order)
80  rs = np.ones((len(rx)))
81 
82  lsf = sip.LeastSqFitter1dPoly(list(rx), list(ry), list(rs), order)
83  fit = map(lambda x: lsf.valueAt(x), rx)
84  f = map(lambda x: lsf.valueAt(x), x)
85 
86  sigma = (y-f).std()
87  deviance = np.fabs( (y - f) /sigma)
88  newidx = np.flatnonzero(deviance < nsigma)
89 
90  if False:
91  import matplotlib.pyplot as mpl
92  mpl.plot(x, y, 'ks')
93  mpl.plot(rx, ry, 'b-')
94  mpl.plot(rx, ry, 'bs')
95  mpl.plot(rx, fit, 'ms')
96  mpl.plot(rx, fit, 'm-')
97  #mpl.plot(x[newidx], y[newidx], 'rs')
98  mpl.show()
99 
100  # If we haven't culled any points we're finished cleaning
101  if len(newidx) == len(idx):
102  break
103 
104  # We get here because we either a) stopped finding bad points
105  # or b) ran out of iterations. Either way, we just return our
106  # list of indices of good points.
107  return newidx
108 
109 
110 def chooseRx(x, idx, order):
111  """Create order+1 values of the ordinate based on the median of groups of elements of x"""
112  rSize = len(idx)/float(order+1) #Note, a floating point number
113  rx = np.zeros((order+1))
114 
115  for i in range(order+1):
116  rng = range(int(rSize*i), int(rSize*(i+1)))
117  rx[i] = np.mean(x[idx[rng]])
118  return rx
119 
120 
121 def chooseRy(y, idx, order):
122  """Create order+1 values of the ordinate based on the median of groups of elements of y"""
123  rSize = len(idx)/float(order+1) #Note, a floating point number
124  ry = np.zeros((order+1))
125 
126  for i in range(order+1):
127  rng = range(int(rSize*i), int(rSize*(i+1)))
128  ry[i] = np.median(y[idx[rng]])
129  return ry
130 
STL namespace.