Coverage for python/lsst/scarlet/lite/io/component.py: 68%

30 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-07 01:40 -0800

1from __future__ import annotations 

2 

3from abc import ABC, abstractmethod 

4from dataclasses import dataclass 

5from typing import ClassVar 

6 

7from numpy.typing import DTypeLike 

8 

9from ..component import Component 

10from ..observation import Observation 

11from .utils import PersistenceError 

12 

13__all__ = ["ScarletComponentBaseData"] 

14 

15 

16@dataclass(kw_only=True) 

17class ScarletComponentBaseData(ABC): 

18 """Base data for a scarlet component 

19 

20 Attributes 

21 ---------- 

22 component_registry : 

23 A registry of all known component types used for deserialization. 

24 component_type : 

25 The type of component being stored. 

26 version : 

27 The schema version of the exact data class. 

28 """ 

29 

30 component_registry: ClassVar[dict[str, type[ScarletComponentBaseData]]] = {} 

31 component_type: str 

32 version: str 

33 

34 @classmethod 

35 def register(cls) -> None: 

36 """Register a new component type""" 

37 ScarletComponentBaseData.component_registry[cls.component_type] = cls 

38 

39 @abstractmethod 

40 def to_component(self, observation: Observation) -> Component: 

41 """Convert the storage data model into a scarlet Component 

42 

43 Parameters 

44 ---------- 

45 observation : 

46 The observation that the component is associated with 

47 

48 Returns 

49 ------- 

50 component : 

51 A scarlet component extracted from persisted data. 

52 """ 

53 

54 @abstractmethod 

55 def as_dict(self) -> dict: 

56 """Return the object encoded into a dict for JSON serialization 

57 

58 Returns 

59 ------- 

60 result : 

61 The object encoded as a JSON compatible dict 

62 """ 

63 

64 @staticmethod 

65 def from_dict(data: dict, dtype: DTypeLike | None = None) -> ScarletComponentBaseData: 

66 """Reconstruct `ScarletComponentBaseData` from JSON compatible 

67 dict. 

68 

69 Parameters 

70 ---------- 

71 data : 

72 Dictionary representation of the object 

73 dtype : 

74 Datatype of the resulting model. 

75 

76 Returns 

77 ------- 

78 result : 

79 The reconstructed object 

80 """ 

81 component_type = data.get("component_type", "factorized") 

82 # Fix legacy naming 

83 if component_type == "component": 

84 component_type = "cube" 

85 if component_type not in ScarletComponentBaseData.component_registry: 

86 raise PersistenceError(f"Unknown component type: {component_type}") 

87 cls = ScarletComponentBaseData.component_registry[component_type] 

88 return cls.from_dict(data, dtype=dtype)