Coverage for python/lsst/analysis/tools/analysisMetrics/photometricRepeatabilityMetrics.py: 27%

30 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2022-11-09 03:50 -0800

1# This file is part of analysis_tools. 

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/>. 

21from __future__ import annotations 

22 

23__all__ = ("StellarPhotometricRepeatabilityMetric",) 

24 

25from ..actions.scalar.scalarActions import FracThreshold, MedianAction 

26from ..actions.vector import ( 

27 BandSelector, 

28 MagColumnNanoJansky, 

29 MultiCriteriaDownselectVector, 

30 PerGroupStatistic, 

31 Sn, 

32 ThresholdSelector, 

33) 

34from ..interfaces import AnalysisMetric 

35 

36 

37class StellarPhotometricRepeatabilityMetric(AnalysisMetric): 

38 """Compute photometric repeatability from multiple measurements of a set of 

39 stars. First, a set of per-source quality criteria are applied. Second, 

40 the individual source measurements are grouped together by object index 

41 and per-group quantities are computed (e.g., a representative S/N for the 

42 group based on the median of associated per-source measurements). Third, 

43 additional per-group criteria are applied. Fourth, summary statistics are 

44 computed for the filtered groups. 

45 """ 

46 

47 fluxType: str = "psfFlux" 

48 

49 def setDefaults(self): 

50 super().setDefaults() 

51 

52 # Apply per-source selection criteria 

53 self.prep.selectors.bandSelector = BandSelector() 

54 

55 # Compute per-group quantities 

56 self.process.buildActions.perGroupSn = PerGroupStatistic() 

57 self.process.buildActions.perGroupSn.buildAction = Sn(fluxType=f"{self.fluxType}") 

58 self.process.buildActions.perGroupSn.func = "median" 

59 self.process.buildActions.perGroupExtendedness = PerGroupStatistic() 

60 self.process.buildActions.perGroupExtendedness.buildAction.vectorKey = "extendedness" 

61 self.process.buildActions.perGroupExtendedness.func = "median" 

62 self.process.buildActions.perGroupCount = PerGroupStatistic() 

63 self.process.buildActions.perGroupCount.buildAction.vectorKey = f"{self.fluxType}" 

64 self.process.buildActions.perGroupCount.func = "count" 

65 # Use mmag units 

66 self.process.buildActions.perGroupStdev = PerGroupStatistic() 

67 self.process.buildActions.perGroupStdev.buildAction = MagColumnNanoJansky( 

68 vectorKey=f"{self.fluxType}", 

69 returnMillimags=True, 

70 ) 

71 self.process.buildActions.perGroupStdev.func = "std" 

72 

73 # Filter on per-group quantities 

74 self.process.filterActions.perGroupStdevFiltered = MultiCriteriaDownselectVector( 

75 vectorKey="perGroupStdev" 

76 ) 

77 self.process.filterActions.perGroupStdevFiltered.selectors.count = ThresholdSelector( 

78 vectorKey="perGroupCount", 

79 op="ge", 

80 threshold=3, 

81 ) 

82 self.process.filterActions.perGroupStdevFiltered.selectors.sn = ThresholdSelector( 

83 vectorKey="perGroupSn", 

84 op="ge", 

85 threshold=200, 

86 ) 

87 self.process.filterActions.perGroupStdevFiltered.selectors.extendedness = ThresholdSelector( 

88 vectorKey="perGroupExtendedness", 

89 op="le", 

90 threshold=0.5, 

91 ) 

92 

93 # Compute summary statistics on filtered groups 

94 self.process.calculateActions.photRepeatStdev = MedianAction(vectorKey="perGroupStdevFiltered") 

95 self.process.calculateActions.photRepeatOutlier = FracThreshold( 

96 vectorKey="perGroupStdevFiltered", 

97 op="ge", 

98 threshold=15.0, 

99 percent=True, 

100 ) 

101 

102 self.produce.units = { # type: ignore 

103 "photRepeatStdev": "mmag", 

104 "photRepeatOutlier": "percent", 

105 } 

106 self.produce.newNames = { 

107 "photRepeatStdev": "{band}_stellarPhotRepeatStdev", 

108 "photRepeatOutlier": "{band}_stellarPhotRepeatOutlierFraction", 

109 }