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
« 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
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)
39import logging
41import numpy as np
42from lsst.pex.config import Field
43from lsst.pex.config.configurableActions import ConfigurableActionField
45from ...interfaces import KeyedData, KeyedDataSchema, Vector, VectorAction
46from ...math import cos, divide, log10, sin, sqrt
48_LOG = logging.getLogger(__name__)
51class ConstantValue(VectorAction):
52 """Return a constant scalar value."""
54 value = Field[float](doc="A single constant value", optional=False)
56 def getInputSchema(self) -> KeyedDataSchema:
57 return ()
59 def __call__(self, data: KeyedData, **kwargs) -> Vector:
60 return np.array([self.value])
63class AddVector(VectorAction):
64 """Calculate (A+B)."""
66 actionA = ConfigurableActionField[VectorAction](doc="Action which supplies vector A")
67 actionB = ConfigurableActionField[VectorAction](doc="Action which supplies vector B")
69 def getInputSchema(self) -> KeyedDataSchema:
70 yield from self.actionA.getInputSchema() # type: ignore
71 yield from self.actionB.getInputSchema() # type: ignore
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
79class SubtractVector(VectorAction):
80 """Calculate (A-B)."""
82 actionA = ConfigurableActionField[VectorAction](doc="Action which supplies vector A")
83 actionB = ConfigurableActionField[VectorAction](doc="Action which supplies vector B")
85 def getInputSchema(self) -> KeyedDataSchema:
86 yield from self.actionA.getInputSchema() # type: ignore
87 yield from self.actionB.getInputSchema() # type: ignore
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
95class MultiplyVector(VectorAction):
96 """Calculate (A*B)"""
98 actionA = ConfigurableActionField[VectorAction](doc="Action which supplies vector A")
99 actionB = ConfigurableActionField[VectorAction](doc="Action which supplies vector B")
101 def getInputSchema(self) -> KeyedDataSchema:
102 yield from self.actionA.getInputSchema() # type: ignore
103 yield from self.actionB.getInputSchema() # type: ignore
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
111class DivideVector(VectorAction):
112 """Calculate (A/B)"""
114 actionA = ConfigurableActionField[VectorAction](doc="Action which supplies vector A")
115 actionB = ConfigurableActionField[VectorAction](doc="Action which supplies vector B")
117 def getInputSchema(self) -> KeyedDataSchema:
118 yield from self.actionA.getInputSchema() # type: ignore
119 yield from self.actionB.getInputSchema() # type: ignore
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)
127class SqrtVector(VectorAction):
128 """Calculate sqrt(A)"""
130 actionA = ConfigurableActionField(doc="Action which supplies vector A", dtype=VectorAction)
132 def getInputSchema(self) -> KeyedDataSchema:
133 yield from self.actionA.getInputSchema() # type: ignore
135 def __call__(self, data: KeyedData, **kwargs) -> Vector:
136 vecA = self.actionA(data, **kwargs) # type: ignore
137 return sqrt(vecA)
140class SquareVector(VectorAction):
141 """Calculate A**2"""
143 actionA = ConfigurableActionField(doc="Action which supplies vector A", dtype=VectorAction)
145 def getInputSchema(self) -> KeyedDataSchema:
146 yield from self.actionA.getInputSchema() # type: ignore
148 def __call__(self, data: KeyedData, **kwargs) -> Vector:
149 vecA = self.actionA(data, **kwargs) # type: ignore
150 return vecA * vecA
153class RaiseFromBaseVector(VectorAction):
154 """Calculate n**A"""
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")
159 def getInputSchema(self) -> KeyedDataSchema:
160 yield from self.actionA.getInputSchema() # type: ignore
162 def __call__(self, data: KeyedData, **kwargs) -> Vector:
163 vecA = self.actionA(data, **kwargs) # type: ignore
164 return self.base**vecA
167class RaiseToPowerVector(VectorAction):
168 """Calculate A**n"""
170 actionA = ConfigurableActionField(doc="Action which supplies vector A", dtype=VectorAction)
171 power = Field[float](doc="The power to raise the vector to")
173 def getInputSchema(self) -> KeyedDataSchema:
174 yield from self.actionA.getInputSchema() # type: ignore
176 def __call__(self, data: KeyedData, **kwargs) -> Vector:
177 vecA = self.actionA(data, **kwargs) # type: ignore
178 return vecA**self.power
181class Log10Vector(VectorAction):
182 """Calculate log10(A)"""
184 actionA = ConfigurableActionField(doc="Action which supplies vector A", dtype=VectorAction)
186 def getInputSchema(self) -> KeyedDataSchema:
187 yield from self.actionA.getInputSchema() # type: ignore
189 def __call__(self, data: KeyedData, **kwargs) -> Vector:
190 vecA = self.actionA(data, **kwargs) # type: ignore
191 return log10(vecA)
194class FractionalDifference(VectorAction):
195 """Calculate (A-B)/B."""
197 actionA = ConfigurableActionField[VectorAction](doc="Action which supplies vector A")
198 actionB = ConfigurableActionField[VectorAction](doc="Action which supplies vector B")
200 def getInputSchema(self) -> KeyedDataSchema:
201 yield from self.actionA.getInputSchema() # type: ignore
202 yield from self.actionB.getInputSchema() # type: ignore
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)
210class CosVector(VectorAction):
211 """Calculate cos(A)"""
213 actionA = ConfigurableActionField(doc="Action which supplies vector A", dtype=VectorAction)
215 def getInputSchema(self) -> KeyedDataSchema:
216 yield from self.actionA.getInputSchema() # type: ignore
218 def __call__(self, data: KeyedData, **kwargs) -> Vector:
219 vecA = self.actionA(data, **kwargs) # type: ignore
220 return cos(vecA)
223class SinVector(VectorAction):
224 """Calculate sin(A)"""
226 actionA = ConfigurableActionField(doc="Action which supplies vector A", dtype=VectorAction)
228 def getInputSchema(self) -> KeyedDataSchema:
229 yield from self.actionA.getInputSchema() # type: ignore
231 def __call__(self, data: KeyedData, **kwargs) -> Vector:
232 vecA = self.actionA(data, **kwargs) # type: ignore
233 return sin(vecA)