LSSTApplications  16.0-10-g0ee56ad+5,16.0-11-ga33d1f2+5,16.0-12-g3ef5c14+3,16.0-12-g71e5ef5+18,16.0-12-gbdf3636+3,16.0-13-g118c103+3,16.0-13-g8f68b0a+3,16.0-15-gbf5c1cb+4,16.0-16-gfd17674+3,16.0-17-g7c01f5c+3,16.0-18-g0a50484+1,16.0-20-ga20f992+8,16.0-21-g0e05fd4+6,16.0-21-g15e2d33+4,16.0-22-g62d8060+4,16.0-22-g847a80f+4,16.0-25-gf00d9b8+1,16.0-28-g3990c221+4,16.0-3-gf928089+3,16.0-32-g88a4f23+5,16.0-34-gd7987ad+3,16.0-37-gc7333cb+2,16.0-4-g10fc685+2,16.0-4-g18f3627+26,16.0-4-g5f3a788+26,16.0-5-gaf5c3d7+4,16.0-5-gcc1f4bb+1,16.0-6-g3b92700+4,16.0-6-g4412fcd+3,16.0-6-g7235603+4,16.0-69-g2562ce1b+2,16.0-8-g14ebd58+4,16.0-8-g2df868b+1,16.0-8-g4cec79c+6,16.0-8-gadf6c7a+1,16.0-8-gfc7ad86,16.0-82-g59ec2a54a+1,16.0-9-g5400cdc+2,16.0-9-ge6233d7+5,master-g2880f2d8cf+3,v17.0.rc1
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:294
def run(self, sources, skyMap, tractInfo, patchInfo, includeDeblend=True)