Coverage for python/lsst/analysis/tools/analysisParts/shapeSizeFractional.py: 39%

45 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2022-08-31 11:38 +0000

1from __future__ import annotations 

2 

3from lsst.pex.config import Field 

4from lsst.pipe.tasks.configurableActions import ConfigurableActionField 

5 

6from ..actions.keyedData import KeyedScalars 

7from ..actions.plot.scatterplotWithTwoHists import ScatterPlotStatsAction 

8from ..actions.scalar import CountAction, MedianAction, SigmaMadAction 

9from ..actions.vector import ( 

10 CalcE, 

11 CalcEDiff, 

12 CalcShapeSize, 

13 CoaddPlotFlagSelector, 

14 DownselectVector, 

15 FractionalDifference, 

16 MagColumnNanoJansky, 

17 SnSelector, 

18 StarSelector, 

19 VectorSelector, 

20) 

21from ..interfaces import AnalysisTool, KeyedData, VectorAction 

22 

23 

24class ShapeSizeFractionalScalars(KeyedScalars): 

25 vectorKey = Field[str](doc="Column key to compute scalars") 

26 

27 snFluxType = Field[str](doc="column key for the flux type used in SN selection") 

28 

29 selector = ConfigurableActionField[VectorAction](doc="Selector to use before computing Scalars") 

30 

31 def setDefaults(self): 

32 super().setDefaults() 

33 self.scalarActions.median = MedianAction(vectorKey=self.vectorKey) # type: ignore 

34 self.scalarActions.sigmaMad = SigmaMadAction(vectorKey=self.vectorKey) # type: ignore 

35 self.scalarActions.count = CountAction(vectorKey=self.vectorKey) # type: ignore 

36 self.scalarActions.approxMag = MedianAction(vectorKey=self.snFluxType) # type: ignore 

37 

38 def __call__(self, data: KeyedData, **kwargs) -> KeyedData: 

39 mask = kwargs.get("mask") 

40 selection = self.selector(data, **kwargs) 

41 if mask is not None: 

42 mask &= selection 

43 else: 

44 mask = selection 

45 return super().__call__(data, **kwargs | dict(mask=mask)) 

46 

47 

48class BasePsfResidualMixin(AnalysisTool): 

49 """Shared configuration for `prep` and `process` stages of PSF residuals. 

50 

51 This is a mixin class used by `BasePsfResidualScatterPlot` and 

52 `BasePsfResidualMetric` to share common default configuration. 

53 """ 

54 

55 def setDefaults(self): 

56 super().setDefaults() 

57 self.prep.selectors.flagSelector = CoaddPlotFlagSelector() 

58 self.prep.selectors.snSelector = SnSelector(fluxType="{band}_psfFlux", threshold=100) 

59 

60 self.process.buildActions.mags = MagColumnNanoJansky(vectorKey="{band}_psfFlux") 

61 self.process.buildActions.fracDiff = FractionalDifference( 

62 actionA=CalcShapeSize(colXx="{band}_ixx", colYy="{band}_iyy", colXy="{band}_ixy"), 

63 actionB=CalcShapeSize(colXx="{band}_ixxPSF", colYy="{band}_iyyPSF", colXy="{band}_ixyPSF"), 

64 ) 

65 # Define an eDiff action and let e1Diff and e2Diff differ only in 

66 # component. 

67 self.process.buildActions.eDiff = CalcEDiff( 

68 colA=CalcE(colXx="{band}_ixx", colYy="{band}_iyy", colXy="{band}_ixy"), 

69 colB=CalcE(colXx="{band}_ixxPSF", colYy="{band}_iyyPSF", colXy="{band}_ixyPSF"), 

70 ) 

71 self.process.buildActions.e1Diff = self.process.buildActions.eDiff 

72 self.process.buildActions.e1Diff.component = "1" 

73 self.process.buildActions.e2Diff = self.process.buildActions.eDiff 

74 self.process.buildActions.e2Diff.component = "2" 

75 # pre-compute a stellar selector mask so it can be used in the filter 

76 # actions while only being computed once, alternatively the stellar 

77 # selector could be calculated and applied twice in the filter stage 

78 self.process.buildActions.starSelector = StarSelector() 

79 

80 self.process.filterActions.xStars = DownselectVector( 

81 vectorKey="mags", selector=VectorSelector(vectorKey="starSelector") 

82 ) 

83 # downselect the psfFlux as well 

84 self.process.filterActions.psfFlux = DownselectVector( 

85 vectorKey="{band}_psfFlux", selector=VectorSelector(vectorKey="starSelector") 

86 ) 

87 self.process.filterActions.psfFluxErr = DownselectVector( 

88 vectorKey="{band}_psfFluxErr", selector=VectorSelector(vectorKey="starSelector") 

89 ) 

90 

91 self.process.calculateActions.stars = ScatterPlotStatsAction( 

92 vectorKey="yStars", 

93 ) 

94 # use the downselected psfFlux 

95 self.process.calculateActions.stars.highSNSelector.fluxType = "psfFlux" 

96 self.process.calculateActions.stars.lowSNSelector.fluxType = "psfFlux" 

97 self.process.calculateActions.stars.fluxType = "psfFlux"