LSSTApplications  20.0.0
LSSTDataManagementBasePackage
setPrimaryFlags.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #
3 # LSST Data Management System
4 # Copyright 2008-2016 LSST/AURA
5 #
6 # This product includes software developed by the
7 # LSST Project (http://www.lsst.org/).
8 #
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the LSST License Statement and
20 # the GNU General Public License along with this program. If not,
21 # see <http://www.lsstcorp.org/LegalNotices/>.
22 #
23 import numpy
24 from lsst.pex.config import Config, Field, ListField
25 from lsst.pipe.base import Task
26 from lsst.geom import Box2D
27 
28 
29 class SetPrimaryFlagsConfig(Config):
30  nChildKeyName = Field(dtype=str, default="deblend_nChild",
31  doc="Name of field in schema with number of deblended children")
32  pseudoFilterList = ListField(dtype=str, default=['sky'],
33  doc="Names of filters which should never be primary")
34 
35 
37  ConfigClass = SetPrimaryFlagsConfig
38 
39  def __init__(self, schema, **kwargs):
40  Task.__init__(self, **kwargs)
41  self.schema = schema
42  self.isPatchInnerKey = self.schema.addField(
43  "detect_isPatchInner", type="Flag",
44  doc="true if source is in the inner region of a coadd patch",
45  )
46  self.isTractInnerKey = self.schema.addField(
47  "detect_isTractInner", type="Flag",
48  doc="true if source is in the inner region of a coadd tract",
49  )
50  self.isPrimaryKey = self.schema.addField(
51  "detect_isPrimary", type="Flag",
52  doc="true if source has no children and is in the inner region of a coadd patch "
53  "and is in the inner region of a coadd tract "
54  "and is not \"detected\" in a pseudo-filter (see config.pseudoFilterList)",
55  )
56 
57  def run(self, sources, skyMap, tractInfo, patchInfo, includeDeblend=True):
58  """Set is-primary and related flags on sources
59 
60  @param[in,out] sources a SourceTable
61  - reads centroid fields and an nChild field
62  - writes is-patch-inner, is-tract-inner and is-primary flags
63  @param[in] skyMap sky tessellation object (subclass of lsst.skymap.BaseSkyMap)
64  @param[in] tractInfo tract object (subclass of lsst.skymap.TractInfo)
65  @param[in] patchInfo patch object (subclass of lsst.skymap.PatchInfo)
66  @param[in] includeDeblend include deblend information in isPrimary?
67  """
68  nChildKey = None
69  if includeDeblend:
70  nChildKey = self.schema.find(self.config.nChildKeyName).key
71 
72  # set inner flags for each source and set primary flags for sources with no children
73  # (or all sources if deblend info not available)
74  innerFloatBBox = Box2D(patchInfo.getInnerBBox())
75 
76  # When the centroider fails, we can still fall back to the peak, but we don't trust
77  # that quite as much - so we use a slightly smaller box for the patch comparison.
78  # That's trickier for the tract comparison, so we just use the peak without extra
79  # care there.
80  shrunkInnerFloatBBox = Box2D(innerFloatBBox)
81  shrunkInnerFloatBBox.grow(-1)
82 
83  pseudoFilterKeys = []
84  for filt in self.config.pseudoFilterList:
85  try:
86  pseudoFilterKeys.append(self.schema.find("merge_peak_%s" % filt).getKey())
87  except Exception:
88  self.log.warn("merge_peak is not set for pseudo-filter %s" % filt)
89 
90  tractId = tractInfo.getId()
91  for source in sources:
92  centroidPos = source.getCentroid()
93  if numpy.any(numpy.isnan(centroidPos)):
94  continue
95  if source.getCentroidFlag():
96  # Use a slightly smaller box to guard against bad centroids (see above)
97  isPatchInner = shrunkInnerFloatBBox.contains(centroidPos)
98  else:
99  isPatchInner = innerFloatBBox.contains(centroidPos)
100  source.setFlag(self.isPatchInnerKey, isPatchInner)
101 
102  skyPos = source.getCoord()
103  sourceInnerTractId = skyMap.findTract(skyPos).getId()
104  isTractInner = sourceInnerTractId == tractId
105  source.setFlag(self.isTractInnerKey, isTractInner)
106 
107  if nChildKey is None or source.get(nChildKey) == 0:
108  for pseudoFilterKey in pseudoFilterKeys:
109  if source.get(pseudoFilterKey):
110  isPseudo = True
111  break
112  else:
113  isPseudo = False
114 
115  source.setFlag(self.isPrimaryKey, isPatchInner and isTractInner and not isPseudo)
lsst::log.log.logContinued.warn
def warn(fmt, *args)
Definition: logContinued.py:202
lsst.pipe.tasks.setPrimaryFlags.SetPrimaryFlagsTask.isPrimaryKey
isPrimaryKey
Definition: setPrimaryFlags.py:50
lsst.pipe.tasks.setPrimaryFlags.SetPrimaryFlagsTask.isPatchInnerKey
isPatchInnerKey
Definition: setPrimaryFlags.py:42
lsst.pipe.tasks.setPrimaryFlags.SetPrimaryFlagsTask.schema
schema
Definition: setPrimaryFlags.py:41
lsst.pipe.tasks.setPrimaryFlags.SetPrimaryFlagsTask.isTractInnerKey
isTractInnerKey
Definition: setPrimaryFlags.py:46
lsst.pipe.tasks.setPrimaryFlags.SetPrimaryFlagsTask.run
def run(self, sources, skyMap, tractInfo, patchInfo, includeDeblend=True)
Definition: setPrimaryFlags.py:57
lsst.pipe.base.task.Task.config
config
Definition: task.py:149
lsst.pipe.base.task.Task.log
log
Definition: task.py:148
lsst.pipe.tasks.setPrimaryFlags.SetPrimaryFlagsTask
Definition: setPrimaryFlags.py:36
lsst::geom
Definition: geomOperators.dox:4
lsst.pipe.base.task.Task
Definition: task.py:46
lsst.pipe.tasks.setPrimaryFlags.SetPrimaryFlagsConfig
Definition: setPrimaryFlags.py:29
lsst::geom::Box2D
A floating-point coordinate rectangle geometry.
Definition: Box.h:413
lsst.pipe.base
Definition: __init__.py:1
lsst.pipe.tasks.setPrimaryFlags.SetPrimaryFlagsTask.__init__
def __init__(self, schema, **kwargs)
Definition: setPrimaryFlags.py:39