LSSTApplications  1.1.2+25,10.0+13,10.0+132,10.0+133,10.0+224,10.0+41,10.0+8,10.0-1-g0f53050+14,10.0-1-g4b7b172+19,10.0-1-g61a5bae+98,10.0-1-g7408a83+3,10.0-1-gc1e0f5a+19,10.0-1-gdb4482e+14,10.0-11-g3947115+2,10.0-12-g8719d8b+2,10.0-15-ga3f480f+1,10.0-2-g4f67435,10.0-2-gcb4bc6c+26,10.0-28-gf7f57a9+1,10.0-3-g1bbe32c+14,10.0-3-g5b46d21,10.0-4-g027f45f+5,10.0-4-g86f66b5+2,10.0-4-gc4fccf3+24,10.0-40-g4349866+2,10.0-5-g766159b,10.0-5-gca2295e+25,10.0-6-g462a451+1
LSSTDataManagementBasePackage
diaCatalogSourceSelector.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 import numpy as np
23 import lsst.pex.config as pexConfig
24 import lsst.afw.display.ds9 as ds9
25 import lsst.meas.algorithms as measAlg
26 import lsst.pex.logging as pexLog
27 
28 class DiaCatalogSourceSelectorConfig(pexConfig.Config):
29  # Selection cuts on the input source catalog
30  fluxLim = pexConfig.Field(
31  doc = "specify the minimum psfFlux for good Kernel Candidates",
32  dtype = float,
33  default = 0.0,
34  check = lambda x: x >= 0.0,
35  )
36  fluxMax = pexConfig.Field(
37  doc = "specify the maximum psfFlux for good Kernel Candidates (ignored if == 0)",
38  dtype = float,
39  default = 0.0,
40  check = lambda x: x >= 0.0,
41  )
42  badPixelFlags = pexConfig.ListField(
43  doc = "Kernel candidate objects may not have any of these bits set",
44  dtype = str,
45  default = ["flags.pixel.edge", "flags.pixel.interpolated.center", "flags.pixel.saturated.center", "flags.badcentroid"],
46  )
47  # Selection cuts on the reference catalog
48  selectStar = pexConfig.Field(
49  doc = "Select objects that are flagged as stars",
50  dtype = bool,
51  default = True
52  )
53  selectGalaxy = pexConfig.Field(
54  doc = "Select objects that are flagged as galaxies",
55  dtype = bool,
56  default = False
57  )
58  includeVariable = pexConfig.Field(
59  doc = "Include objects that are known to be variable",
60  dtype = bool,
61  default = False
62  )
63  grMin = pexConfig.Field(
64  doc = "Minimum g-r color for selection (inclusive)",
65  dtype = float,
66  default = 0.0
67  )
68  grMax = pexConfig.Field(
69  doc = "Maximum g-r color for selection (inclusive)",
70  dtype = float,
71  default = 3.0
72  )
73 
74 class CheckSource(object):
75  """A functor to check whether a source has any flags set that should cause it to be labeled bad."""
76 
77  def __init__(self, table, fluxLim, fluxMax, badPixelFlags):
78  self.keys = [table.getSchema().find(name).key for name in badPixelFlags]
79  self.fluxLim = fluxLim
80  self.fluxMax = fluxMax
81 
82  def __call__(self, source):
83  for k in self.keys:
84  if source.get(k):
85  return False
86  if self.fluxLim != None and source.getPsfFlux() < self.fluxLim: # ignore faint objects
87  return False
88  if self.fluxMax != 0.0 and source.getPsfFlux() > self.fluxMax: # ignore bright objects
89  return False
90  return True
91 
93  ConfigClass = DiaCatalogSourceSelectorConfig
94 
95  def __init__(self, config=None):
96  """Construct a source selector that uses a reference catalog
97 
98  @param[in] config: An instance of ConfigClass
99  """
100  if not config:
101  config = DiaCatalogSourceSelector.ConfigClass()
102  self.config = config
103  self.log = pexLog.Log(pexLog.Log.getDefaultLog(),
104  'lsst.ip.diffim.DiaCatalogSourceSelector', pexLog.Log.INFO)
105 
106  def selectSources(self, exposure, sources, matches=None):
107  """Return a list of Sources for Kernel candidates
108 
109  @param[in] exposure: the exposure containing the sources
110  @param[in] sources: a source list containing sources that may be candidates
111  @param[in] matches: a match vector as produced by meas_astrom; not optional
112  (passing None just allows us to handle the exception better here
113  than in calling code)
114 
115  @return kernelCandidateSourceList: a list of sources to be used as kernel candidates
116 
117  """
118  import lsstDebug
119  display = lsstDebug.Info(__name__).display
120  displayExposure = lsstDebug.Info(__name__).displayExposure
121  pauseAtEnd = lsstDebug.Info(__name__).pauseAtEnd
122 
123  if matches is None:
124  raise RuntimeError(
125  "Cannot use catalog source selector without running astrometry."
126  )
127 
128  mi = exposure.getMaskedImage()
129 
130  if display:
131  if displayExposure:
132  ds9.mtv(mi, title="Kernel candidates", frame=lsstDebug.frame)
133  #
134  # Look for flags in each Source
135  #
136  isGoodSource = CheckSource(sources, self.config.fluxLim, self.config.fluxMax, self.config.badPixelFlags)
137 
138  #
139  # Go through and find all the acceptable candidates in the catalogue
140  #
141  kernelCandidateSourceList = []
142 
143  doColorCut = True
144  with ds9.Buffering():
145  refSchema = matches[0][0].schema
146  rRefFluxField = measAlg.getRefFluxField(refSchema, "r")
147  gRefFluxField = measAlg.getRefFluxField(refSchema, "g")
148  for ref, source, d in matches:
149  if not isGoodSource(source):
150  symb, ctype = "+", ds9.RED
151  else:
152  isStar = not ref.get("resolved")
153  isVar = not ref.get("photometric")
154  gMag = None
155  rMag = None
156  if doColorCut:
157  try:
158  gMag = -2.5 * np.log10(ref.get(gRefFluxField))
159  rMag = -2.5 * np.log10(ref.get(rRefFluxField))
160  except KeyError:
161  self.log.warn("Cannot cut on color info; fields 'g' and 'r' do not exist")
162  doColorCut = False
163  isRightColor = True
164  else:
165  isRightColor = (gMag-rMag) >= self.config.grMin and (gMag-rMag) <= self.config.grMax
166 
167  isRightType = (self.config.selectStar and isStar) or (self.config.selectGalaxy and not isStar)
168  isRightVar = (self.config.includeVariable) or (self.config.includeVariable is isVar)
169  if isRightType and isRightVar and isRightColor:
170  kernelCandidateSourceList.append(source)
171  symb, ctype = "+", ds9.GREEN
172  else:
173  symb, ctype = "o", ds9.BLUE
174 
175  if display and displayExposure:
176  ds9.dot(symb, source.getX() - mi.getX0(), source.getY() - mi.getY0(),
177  size=4, ctype=ctype, frame=lsstDebug.frame)
178 
179  if display:
180  lsstDebug.frame += 1
181  if pauseAtEnd:
182  raw_input("Continue? y[es] p[db] ")
183 
184  return kernelCandidateSourceList
185 
186 measAlg.starSelectorRegistry.register("diacatalog", DiaCatalogSourceSelector)
187 
a place to record messages and descriptions of the state of processing.
Definition: Log.h:154