LSSTApplications  17.0+124,17.0+14,17.0+73,18.0.0+37,18.0.0+80,18.0.0-4-g68ffd23+4,18.1.0-1-g0001055+12,18.1.0-1-g03d53ef+5,18.1.0-1-g1349e88+55,18.1.0-1-g2505f39+44,18.1.0-1-g5315e5e+4,18.1.0-1-g5e4b7ea+14,18.1.0-1-g7e8fceb+4,18.1.0-1-g85f8cd4+48,18.1.0-1-g8ff0b9f+4,18.1.0-1-ga2c679d+1,18.1.0-1-gd55f500+35,18.1.0-10-gb58edde+2,18.1.0-11-g0997b02+4,18.1.0-13-gfe4edf0b+12,18.1.0-14-g259bd21+21,18.1.0-19-gdb69f3f+2,18.1.0-2-g5f9922c+24,18.1.0-2-gd3b74e5+11,18.1.0-2-gfbf3545+32,18.1.0-26-g728bddb4+5,18.1.0-27-g6ff7ca9+2,18.1.0-3-g52aa583+25,18.1.0-3-g8ea57af+9,18.1.0-3-gb69f684+42,18.1.0-3-gfcaddf3+6,18.1.0-32-gd8786685a,18.1.0-4-gf3f9b77+6,18.1.0-5-g1dd662b+2,18.1.0-5-g6dbcb01+41,18.1.0-6-gae77429+3,18.1.0-7-g9d75d83+9,18.1.0-7-gae09a6d+30,18.1.0-9-gc381ef5+4,w.2019.45
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)
A floating-point coordinate rectangle geometry.
Definition: Box.h:413
def run(self, sources, skyMap, tractInfo, patchInfo, includeDeblend=True)