Coverage for python/lsst/ap/association/trailedSourceFilter.py: 58%

27 statements  

« prev     ^ index     » next       coverage.py v7.5.1, created at 2024-05-07 03:43 -0700

1# This file is part of ap_association. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

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 GNU General Public License 

20# along with this program. If not, see <https://www.gnu.org/licenses/>. 

21 

22__all__ = ("TrailedSourceFilterTask", "TrailedSourceFilterConfig") 

23 

24import os 

25import numpy as np 

26 

27import lsst.pex.config as pexConfig 

28import lsst.pipe.base as pipeBase 

29from lsst.utils.timer import timeMethod 

30from lsst.ap.association.transformDiaSourceCatalog import UnpackApdbFlags 

31import lsst.utils as utils 

32 

33 

34class TrailedSourceFilterConfig(pexConfig.Config): 

35 """Config class for TrailedSourceFilterTask. 

36 """ 

37 

38 max_trail_length = pexConfig.Field( 

39 dtype=float, 

40 doc="Length of long trailed sources to remove from the input catalog, " 

41 "in arcseconds per second. Default comes from DMTN-199, which " 

42 "requires removal of sources with trails longer than 10 " 

43 "degrees/day, which is 36000/3600/24 arcsec/second, or roughly" 

44 "0.416 arcseconds per second.", 

45 default=36000/3600.0/24.0, 

46 ) 

47 

48 

49class TrailedSourceFilterTask(pipeBase.Task): 

50 """Find trailed sources in DIASources and filter them as per DMTN-199 

51 guidelines. 

52 

53 This task checks the length of trailLength in the DIASource catalog using 

54 a given arcsecond/second rate from max_trail_length and the exposure time. 

55 The two values are used to calculate the maximum allowed trail length and 

56 filters out any trail longer than the maximum. The max_trail_length is 

57 outlined in DMTN-199 and determines the default value. 

58 """ 

59 

60 ConfigClass = TrailedSourceFilterConfig 

61 _DefaultName = "trailedSourceFilter" 

62 

63 @timeMethod 

64 def run(self, dia_sources, exposure_time): 

65 """Remove trailed sources longer than ``config.max_trail_length`` from 

66 the input catalog. 

67 

68 Parameters 

69 ---------- 

70 dia_sources : `pandas.DataFrame` 

71 New DIASources to be checked for trailed sources. 

72 exposure_time : `float` 

73 Exposure time from difference image. 

74 

75 Returns 

76 ------- 

77 result : `lsst.pipe.base.Struct` 

78 Results struct with components. 

79 

80 - ``diaSources`` : DIASource table that is free from unwanted 

81 trailed sources. (`pandas.DataFrame`) 

82 

83 - ``longTrailedDiaSources`` : DIASources that have trails which 

84 exceed max_trail_length/second*exposure_time (seconds). 

85 (`pandas.DataFrame`) 

86 """ 

87 

88 if "flags" in dia_sources.columns: 

89 flag_map = os.path.join(utils.getPackageDir("ap_association"), "data/association-flag-map.yaml") 

90 unpacker = UnpackApdbFlags(flag_map, "DiaSource") 

91 flags = unpacker.unpack(dia_sources["flags"], "flags") 

92 trail_edge_flags = flags["ext_trailedSources_Naive_flag_edge"] 

93 else: 

94 trail_edge_flags = dia_sources["trail_flag_edge"] 

95 

96 trail_mask = self._check_dia_source_trail(dia_sources, exposure_time, trail_edge_flags) 

97 

98 return pipeBase.Struct( 

99 diaSources=dia_sources[~trail_mask].reset_index(drop=True), 

100 longTrailedDiaSources=dia_sources[trail_mask].reset_index(drop=True)) 

101 

102 def _check_dia_source_trail(self, dia_sources, exposure_time, trail_edge_flags): 

103 """Find DiaSources that have long trails. 

104 

105 Return a mask of sources with lengths greater than 

106 ``config.max_trail_length`` multiplied by the exposure time in seconds 

107 or have ext_trailedSources_Naive_flag_edge set. 

108 

109 Parameters 

110 ---------- 

111 dia_sources : `pandas.DataFrame` 

112 Input DIASources to check for trail lengths. 

113 exposure_time : `float` 

114 Exposure time from difference image. 

115 trail_edge_flags : 'numpy.ndArray' 

116 Boolean array of trail_flag_edge flags from the DIASources. 

117 

118 Returns 

119 ------- 

120 trail_mask : `pandas.DataFrame` 

121 Boolean mask for DIASources which are greater than the 

122 cutoff length or have the edge flag set. 

123 """ 

124 trail_mask = (dia_sources.loc[:, "trailLength"].values[:] 

125 >= (self.config.max_trail_length*exposure_time)) 

126 

127 trail_mask[np.where(trail_edge_flags)] = True 

128 

129 return trail_mask