LSSTApplications  17.0+11,17.0+34,17.0+56,17.0+57,17.0+59,17.0+7,17.0-1-g377950a+33,17.0.1-1-g114240f+2,17.0.1-1-g4d4fbc4+28,17.0.1-1-g55520dc+49,17.0.1-1-g5f4ed7e+52,17.0.1-1-g6dd7d69+17,17.0.1-1-g8de6c91+11,17.0.1-1-gb9095d2+7,17.0.1-1-ge9fec5e+5,17.0.1-1-gf4e0155+55,17.0.1-1-gfc65f5f+50,17.0.1-1-gfc6fb1f+20,17.0.1-10-g87f9f3f+1,17.0.1-11-ge9de802+16,17.0.1-16-ga14f7d5c+4,17.0.1-17-gc79d625+1,17.0.1-17-gdae4c4a+8,17.0.1-2-g26618f5+29,17.0.1-2-g54f2ebc+9,17.0.1-2-gf403422+1,17.0.1-20-g2ca2f74+6,17.0.1-23-gf3eadeb7+1,17.0.1-3-g7e86b59+39,17.0.1-3-gb5ca14a,17.0.1-3-gd08d533+40,17.0.1-30-g596af8797,17.0.1-4-g59d126d+4,17.0.1-4-gc69c472+5,17.0.1-6-g5afd9b9+4,17.0.1-7-g35889ee+1,17.0.1-7-gc7c8782+18,17.0.1-9-gc4bbfb2+3,w.2019.22
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.afw.geom import Box2D
27 
28 
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)
A floating-point coordinate rectangle geometry.
Definition: Box.h:305
def run(self, sources, skyMap, tractInfo, patchInfo, includeDeblend=True)