lsst.meas.astrom  14.0-7-g0d69b06+3
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 from __future__ import absolute_import, division, print_function
23 
24 __all__ = ["clean"]
25 
26 from builtins import range
27 
28 import numpy as np
29 
30 from . import LeastSqFitter1dPoly
31 
32 
33 def clean(srcMatch, wcs, order=3, nsigma=3):
34  """Remove bad points from srcMatch
35 
36  Input:
37  srcMatch : list of det::SourceMatch
38  order: Order of polynomial to use in robust fitting
39  nsigma: Sources more than this far away from the robust best fit
40  polynomial are removed
41 
42  Return:
43  list of det::SourceMatch of the good data points
44  """
45 
46  N = len(srcMatch)
47  catX = np.zeros(N)
48  # catY = np.zeros(N)
49  for i in range(N):
50  x, y = wcs.skyToPixel(srcMatch[i].first.getCoord())
51  catX[i] = x
52  # catY[i] = y
53 
54  # TODO -- why does this only use X?
55 
56  x = np.array([s.second.getX() for s in srcMatch])
57  dx = x - catX
58  sigma = np.zeros_like(dx) + 0.1
59 
60  idx = indicesOfGoodPoints(x, dx, sigma, order=order, nsigma=nsigma)
61 
62  clean = []
63  for i in idx:
64  clean.append(srcMatch[i])
65  return clean
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 range(maxiter):
78  rx = chooseRx(x, idx, order)
79  ry = chooseRy(y, idx, order)
80  rs = np.ones((len(rx)))
81 
82  lsf = LeastSqFitter1dPoly(list(rx), list(ry), list(rs), order)
83  fit = [lsf.valueAt(value) for value in rx]
84  f = [lsf.valueAt(value) for value in 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 plt
92  plt.plot(x, y, 'ks')
93  plt.plot(rx, ry, 'b-')
94  plt.plot(rx, ry, 'bs')
95  plt.plot(rx, fit, 'ms')
96  plt.plot(rx, fit, 'm-')
97  # plt.plot(x[newidx], y[newidx], 'rs')
98  plt.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 = list(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 = list(range(int(rSize*i), int(rSize*(i+1))))
128  ry[i] = np.median(y[idx[rng]])
129  return ry
STL namespace.
def indicesOfGoodPoints(x, y, s, order=1, nsigma=3, maxiter=100)
def clean(srcMatch, wcs, order=3, nsigma=3)