Coverage for python/lsst/analysis/tools/actions/vector/mathActions.py: 58%

64 statements  

« prev     ^ index     » next       coverage.py v7.2.5, created at 2023-05-23 04:22 -0700

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__ = ( 

24 "ConstantValue", 

25 "AddVector", 

26 "SubtractVector", 

27 "DivideVector", 

28 "MultiplyVector", 

29 "FractionalDifference", 

30) 

31 

32import logging 

33 

34import numpy as np 

35from lsst.pex.config import Field 

36from lsst.pex.config.configurableActions import ConfigurableActionField 

37 

38from ...interfaces import KeyedData, KeyedDataSchema, Vector, VectorAction 

39 

40_LOG = logging.getLogger(__name__) 

41 

42 

43class ConstantValue(VectorAction): 

44 """Return a constant scalar value.""" 

45 

46 value = Field[float](doc="A single constant value", optional=False) 

47 

48 def getInputSchema(self) -> KeyedDataSchema: 

49 return () 

50 

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

52 return np.array([self.value]) 

53 

54 

55class AddVector(VectorAction): 

56 """Calculate (A+B).""" 

57 

58 actionA = ConfigurableActionField[VectorAction](doc="Action which supplies vector A") 

59 actionB = ConfigurableActionField[VectorAction](doc="Action which supplies vector B") 

60 

61 def getInputSchema(self) -> KeyedDataSchema: 

62 yield from self.actionA.getInputSchema() # type: ignore 

63 yield from self.actionB.getInputSchema() # type: ignore 

64 

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

66 vecA = self.actionA(data, **kwargs) # type: ignore 

67 vecB = self.actionB(data, **kwargs) # type: ignore 

68 return vecA + vecB 

69 

70 

71class SubtractVector(VectorAction): 

72 """Calculate (A-B).""" 

73 

74 actionA = ConfigurableActionField[VectorAction](doc="Action which supplies vector A") 

75 actionB = ConfigurableActionField[VectorAction](doc="Action which supplies vector B") 

76 

77 def getInputSchema(self) -> KeyedDataSchema: 

78 yield from self.actionA.getInputSchema() # type: ignore 

79 yield from self.actionB.getInputSchema() # type: ignore 

80 

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

82 vecA = self.actionA(data, **kwargs) # type: ignore 

83 vecB = self.actionB(data, **kwargs) # type: ignore 

84 return vecA - vecB 

85 

86 

87class MultiplyVector(VectorAction): 

88 """Calculate (A*B)""" 

89 

90 actionA = ConfigurableActionField[VectorAction](doc="Action which supplies vector A") 

91 actionB = ConfigurableActionField[VectorAction](doc="Action which supplies vector B") 

92 

93 def getInputSchema(self) -> KeyedDataSchema: 

94 yield from self.actionA.getInputSchema() # type: ignore 

95 yield from self.actionB.getInputSchema() # type: ignore 

96 

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

98 vecA = self.actionA(data, **kwargs) # type: ignore 

99 vecB = self.actionB(data, **kwargs) # type: ignore 

100 return vecA * vecB 

101 

102 

103class DivideVector(VectorAction): 

104 """Calculate (A/B)""" 

105 

106 actionA = ConfigurableActionField[VectorAction](doc="Action which supplies vector A") 

107 actionB = ConfigurableActionField[VectorAction](doc="Action which supplies vector B") 

108 

109 def getInputSchema(self) -> KeyedDataSchema: 

110 yield from self.actionA.getInputSchema() # type: ignore 

111 yield from self.actionB.getInputSchema() # type: ignore 

112 

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

114 vecA = self.actionA(data, **kwargs) # type: ignore 

115 vecB = self.actionB(data, **kwargs) # type: ignore 

116 return vecA / vecB 

117 

118 

119class FractionalDifference(VectorAction): 

120 """Calculate (A-B)/B.""" 

121 

122 actionA = ConfigurableActionField[VectorAction](doc="Action which supplies vector A") 

123 actionB = ConfigurableActionField[VectorAction](doc="Action which supplies vector B") 

124 

125 def getInputSchema(self) -> KeyedDataSchema: 

126 yield from self.actionA.getInputSchema() # type: ignore 

127 yield from self.actionB.getInputSchema() # type: ignore 

128 

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

130 vecA = self.actionA(data, **kwargs) # type: ignore 

131 vecB = self.actionB(data, **kwargs) # type: ignore 

132 return (vecA - vecB) / vecB