Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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# 

23import numpy 

24from lsst.pex.config import Config, Field, ListField 

25from lsst.pipe.base import Task 

26from lsst.geom import Box2D 

27 

28 

29class 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 

36class SetPrimaryFlagsTask(Task): 

37 """Add isPrimaryKey to a given schema. 

38 

39 Parameters 

40 ---------- 

41 schema : `lsst.afw.table.Schema` 

42 The input schema. 

43 isSingleFrame : `bool` 

44 Flag specifying if task is operating with single frame imaging. 

45 kwargs : 

46 Keyword arguments passed to the task. 

47 """ 

48 

49 ConfigClass = SetPrimaryFlagsConfig 

50 

51 def __init__(self, schema, isSingleFrame=False, **kwargs): 

52 Task.__init__(self, **kwargs) 

53 self.schema = schema 

54 self.isSingleFrame = isSingleFrame 

55 if not self.isSingleFrame: 

56 primaryDoc = ("true if source has no children and is in the inner region of a coadd patch " 

57 "and is in the inner region of a coadd tract " 

58 "and is not \"detected\" in a pseudo-filter (see config.pseudoFilterList)") 

59 self.isPatchInnerKey = self.schema.addField( 

60 "detect_isPatchInner", type="Flag", 

61 doc="true if source is in the inner region of a coadd patch", 

62 ) 

63 self.isTractInnerKey = self.schema.addField( 

64 "detect_isTractInner", type="Flag", 

65 doc="true if source is in the inner region of a coadd tract", 

66 ) 

67 else: 

68 primaryDoc = "true if source has no children and is not a sky source" 

69 self.isPrimaryKey = self.schema.addField( 

70 "detect_isPrimary", type="Flag", 

71 doc=primaryDoc, 

72 ) 

73 

74 def run(self, sources, skyMap=None, tractInfo=None, patchInfo=None, 

75 includeDeblend=True): 

76 """Set is-patch-inner, is-tract-inner and is-primary flags on sources. 

77 For coadded imaging, the is-primary flag returns True when an object 

78 has no children, is in the inner region of a coadd patch, is in the 

79 inner region of a coadd trach, and is not detected in a pseudo-filter 

80 (e.g., a sky_object). 

81 For single frame imaging, the is-primary flag returns True when a 

82 source has no children and is not a sky source. 

83 

84 Parameters 

85 ---------- 

86 sources : `lsst.afw.table.SourceCatalog` 

87 A sourceTable. Reads in centroid fields and an nChild field. 

88 Writes is-patch-inner, is-tract-inner, and is-primary flags. 

89 skyMap : `lsst.skymap.BaseSkyMap` 

90 Sky tessellation object 

91 tractInfo : `lsst.skymap.TractInfo` 

92 Tract object 

93 patchInfo : `lsst.skymap.PatchInfo` 

94 Patch object 

95 includeDeblend : `bool` 

96 Include deblend information in isPrimary? 

97 """ 

98 nChildKey = None 

99 if includeDeblend: 99 ↛ 103line 99 didn't jump to line 103, because the condition on line 99 was never false

100 nChildKey = self.schema.find(self.config.nChildKeyName).key 

101 

102 # coadd case 

103 if not self.isSingleFrame: 

104 # set inner flags for each source and set primary flags for sources with no children 

105 # (or all sources if deblend info not available) 

106 innerFloatBBox = Box2D(patchInfo.getInnerBBox()) 

107 

108 # When the centroider fails, we can still fall back to the peak, but we don't trust 

109 # that quite as much - so we use a slightly smaller box for the patch comparison. 

110 # That's trickier for the tract comparison, so we just use the peak without extra 

111 # care there. 

112 shrunkInnerFloatBBox = Box2D(innerFloatBBox) 

113 shrunkInnerFloatBBox.grow(-1) 

114 

115 pseudoFilterKeys = [] 

116 for filt in self.config.pseudoFilterList: 

117 try: 

118 pseudoFilterKeys.append(self.schema.find("merge_peak_%s" % filt).getKey()) 

119 except Exception: 

120 self.log.warn("merge_peak is not set for pseudo-filter %s" % filt) 

121 

122 tractId = tractInfo.getId() 

123 for source in sources: 

124 centroidPos = source.getCentroid() 

125 if numpy.any(numpy.isnan(centroidPos)): 125 ↛ 126line 125 didn't jump to line 126, because the condition on line 125 was never true

126 continue 

127 if source.getCentroidFlag(): 

128 # Use a slightly smaller box to guard against bad centroids (see above) 

129 isPatchInner = shrunkInnerFloatBBox.contains(centroidPos) 

130 else: 

131 isPatchInner = innerFloatBBox.contains(centroidPos) 

132 source.setFlag(self.isPatchInnerKey, isPatchInner) 

133 

134 skyPos = source.getCoord() 

135 sourceInnerTractId = skyMap.findTract(skyPos).getId() 

136 isTractInner = sourceInnerTractId == tractId 

137 source.setFlag(self.isTractInnerKey, isTractInner) 

138 

139 if nChildKey is None or source.get(nChildKey) == 0: 

140 for pseudoFilterKey in pseudoFilterKeys: 

141 if source.get(pseudoFilterKey): 

142 isPseudo = True 

143 break 

144 else: 

145 isPseudo = False 

146 

147 source.setFlag(self.isPrimaryKey, isPatchInner and isTractInner and not isPseudo) 

148 

149 # single frame case 

150 else: 

151 hasSkySources = True if "sky_source" in sources.schema else False 

152 for source in sources: 

153 hasNoChildren = True if nChildKey is None or source.get(nChildKey) == 0 else False 

154 isSkySource = False 

155 if hasSkySources: 

156 if source["sky_source"]: 

157 isSkySource = True 

158 source.setFlag(self.isPrimaryKey, hasNoChildren and not isSkySource)