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

116 statements  

« prev     ^ index     » next       coverage.py v7.5.1, created at 2024-05-16 04:38 -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 "MultiplyVector", 

28 "DivideVector", 

29 "SquareVector", 

30 "SqrtVector", 

31 "RaiseFromBaseVector", 

32 "RaiseToPowerVector", 

33 "Log10Vector", 

34 "FractionalDifference", 

35 "CosVector", 

36 "SinVector", 

37) 

38 

39import logging 

40 

41import numpy as np 

42from lsst.pex.config import Field 

43from lsst.pex.config.configurableActions import ConfigurableActionField 

44 

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

46from ...math import cos, divide, log10, sin, sqrt 

47 

48_LOG = logging.getLogger(__name__) 

49 

50 

51class ConstantValue(VectorAction): 

52 """Return a constant scalar value.""" 

53 

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

55 

56 def getInputSchema(self) -> KeyedDataSchema: 

57 return () 

58 

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

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

61 

62 

63class AddVector(VectorAction): 

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

65 

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

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

68 

69 def getInputSchema(self) -> KeyedDataSchema: 

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

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

72 

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

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

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

76 return vecA + vecB 

77 

78 

79class SubtractVector(VectorAction): 

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

81 

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

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

84 

85 def getInputSchema(self) -> KeyedDataSchema: 

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

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

88 

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

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

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

92 return vecA - vecB 

93 

94 

95class MultiplyVector(VectorAction): 

96 """Calculate (A*B)""" 

97 

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

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

100 

101 def getInputSchema(self) -> KeyedDataSchema: 

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

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

104 

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

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

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

108 return vecA * vecB 

109 

110 

111class DivideVector(VectorAction): 

112 """Calculate (A/B)""" 

113 

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

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

116 

117 def getInputSchema(self) -> KeyedDataSchema: 

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

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

120 

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

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

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

124 return divide(vecA, vecB) 

125 

126 

127class SqrtVector(VectorAction): 

128 """Calculate sqrt(A)""" 

129 

130 actionA = ConfigurableActionField(doc="Action which supplies vector A", dtype=VectorAction) 

131 

132 def getInputSchema(self) -> KeyedDataSchema: 

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

134 

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

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

137 return sqrt(vecA) 

138 

139 

140class SquareVector(VectorAction): 

141 """Calculate A**2""" 

142 

143 actionA = ConfigurableActionField(doc="Action which supplies vector A", dtype=VectorAction) 

144 

145 def getInputSchema(self) -> KeyedDataSchema: 

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

147 

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

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

150 return vecA * vecA 

151 

152 

153class RaiseFromBaseVector(VectorAction): 

154 """Calculate n**A""" 

155 

156 actionA = ConfigurableActionField(doc="Action which supplies vector A", dtype=VectorAction) 

157 base = Field[float](doc="The base value to raise to the power of vector values") 

158 

159 def getInputSchema(self) -> KeyedDataSchema: 

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

161 

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

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

164 return self.base**vecA 

165 

166 

167class RaiseToPowerVector(VectorAction): 

168 """Calculate A**n""" 

169 

170 actionA = ConfigurableActionField(doc="Action which supplies vector A", dtype=VectorAction) 

171 power = Field[float](doc="The power to raise the vector to") 

172 

173 def getInputSchema(self) -> KeyedDataSchema: 

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

175 

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

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

178 return vecA**self.power 

179 

180 

181class Log10Vector(VectorAction): 

182 """Calculate log10(A)""" 

183 

184 actionA = ConfigurableActionField(doc="Action which supplies vector A", dtype=VectorAction) 

185 

186 def getInputSchema(self) -> KeyedDataSchema: 

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

188 

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

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

191 return log10(vecA) 

192 

193 

194class FractionalDifference(VectorAction): 

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

196 

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

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

199 

200 def getInputSchema(self) -> KeyedDataSchema: 

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

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

203 

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

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

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

207 return divide(vecA - vecB, vecB) 

208 

209 

210class CosVector(VectorAction): 

211 """Calculate cos(A)""" 

212 

213 actionA = ConfigurableActionField(doc="Action which supplies vector A", dtype=VectorAction) 

214 

215 def getInputSchema(self) -> KeyedDataSchema: 

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

217 

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

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

220 return cos(vecA) 

221 

222 

223class SinVector(VectorAction): 

224 """Calculate sin(A)""" 

225 

226 actionA = ConfigurableActionField(doc="Action which supplies vector A", dtype=VectorAction) 

227 

228 def getInputSchema(self) -> KeyedDataSchema: 

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

230 

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

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

233 return sin(vecA)