Loading [MathJax]/extensions/tex2jax.js
LSST Applications g0d33ba9806+23fb6b1458,g0fba68d861+71b39d8992,g1e78f5e6d3+05b96b9403,g1ec0fe41b4+f8df4a5e9d,g1fd858c14a+1f896281a9,g35bb328faa+fcb1d3bbc8,g4af146b050+32dc2822d5,g4d2262a081+50ddfc6a69,g53246c7159+fcb1d3bbc8,g5a012ec0e7+6ce3c67fb7,g60b5630c4e+23fb6b1458,g67b6fd64d1+b5a8974b5d,g78460c75b0+2f9a1b4bcd,g786e29fd12+cf7ec2a62a,g7b71ed6315+fcb1d3bbc8,g87b7deb4dc+050abbb6d1,g8852436030+17127e6d9c,g89139ef638+b5a8974b5d,g9125e01d80+fcb1d3bbc8,g94187f82dc+23fb6b1458,g989de1cb63+b5a8974b5d,g9f33ca652e+b775bc0ddd,g9f7030ddb1+0d26baa418,ga2b97cdc51+23fb6b1458,ga44b1db4f6+65b51902b9,gabe3b4be73+1e0a283bba,gabf8522325+a9d2faf463,gb1101e3267+1c10e8ebae,gb58c049af0+f03b321e39,gb89ab40317+b5a8974b5d,gcf25f946ba+17127e6d9c,gd6cbbdb0b4+ace4583378,gd9a9a58781+fcb1d3bbc8,gde0f65d7ad+12e49698cc,ge278dab8ac+fa73091e6d,ge410e46f29+b5a8974b5d,gf67bdafdda+b5a8974b5d,gfe06eef73a+62ba25d42b,v29.0.0.rc4
LSST Data Management Base Package
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
_baseDataFrameActions.py
Go to the documentation of this file.
1from __future__ import annotations
2
3__all__ = ("DataFrameAction",)
4
5from lsst.pex.config import Field, ListField
6from typing import Iterable, Any, Mapping
7
8from lsst.pex.config.configurableActions import ConfigurableAction
9
10
12 _actionCache: Mapping[int, Any]
13
14 cache = Field(doc="Controls if the results of this action should be cached,"
15 " only works on frozen actions",
16 dtype=bool, default=False)
17 cacheArgs = ListField(doc="If cache is True, this is a list of argument keys that will be used to "
18 "compute the cache key in addition to the DataFrameId",
19 dtype=str, optional=True)
20
21 def __init_subclass__(cls, **kwargs) -> None:
22 cls._actionCache = {}
23
24 def call_wrapper(function):
25 def inner_wrapper(self, dataFrame, **kwargs):
26 dfId = id(dataFrame)
27 extra = []
28 for name in (self.cacheArgs or tuple()):
29 if name not in kwargs:
30 raise ValueError(f"{name} is not part of call signature and cant be used for "
31 "caching")
32 extra.append(kwargs[name])
33 extra.append(dfId)
34 key = tuple(extra)
35 if self.cache and self._frozen:
36 # look up to see if the value is in cache already
37 if result := self._actionCache.get(key):
38 return result
39 result = function(self, dataFrame, **kwargs)
40 if self.cache and self._frozen:
41 self._actionCache[key] = result
42 return result
43 return inner_wrapper
44 cls.__call__ = call_wrapper(cls.__call__)
45 super().__init_subclass__(**kwargs)
46
47 def __call__(self, dataFrame, **kwargs) -> Iterable[Any]:
48 """This method should return the result of an action performed on a
49 dataframe
50 """
51 raise NotImplementedError("This method should be overloaded in a subclass")
52
53 @property
54 def columns(self) -> Iterable[str]:
55 """This property should return an iterable of columns needed by this action
56 """
57 raise NotImplementedError("This method should be overloaded in a subclass")