LSST Applications g013ef56533+63812263fb,g083dd6704c+a047e97985,g199a45376c+0ba108daf9,g1fd858c14a+fde7a7a78c,g210f2d0738+db0c280453,g262e1987ae+abed931625,g29ae962dfc+058d1915d8,g2cef7863aa+aef1011c0b,g35bb328faa+8c5ae1fdc5,g3fd5ace14f+64337f1634,g47891489e3+f459a6810c,g53246c7159+8c5ae1fdc5,g54cd7ddccb+890c8e1e5d,g5a60e81ecd+d9e514a434,g64539dfbff+db0c280453,g67b6fd64d1+f459a6810c,g6ebf1fc0d4+8c5ae1fdc5,g7382096ae9+36d16ea71a,g74acd417e5+c70e70fbf6,g786e29fd12+668abc6043,g87389fa792+8856018cbb,g89139ef638+f459a6810c,g8d7436a09f+1b779678e3,g8ea07a8fe4+81eaaadc04,g90f42f885a+34c0557caf,g97be763408+9583a964dd,g98a1a72a9c+028271c396,g98df359435+530b675b85,gb8cb2b794d+4e54f68785,gbf99507273+8c5ae1fdc5,gc2a301910b+db0c280453,gca7fc764a6+f459a6810c,gd7ef33dd92+f459a6810c,gdab6d2f7ff+c70e70fbf6,ge410e46f29+f459a6810c,ge41e95a9f2+db0c280453,geaed405ab2+e3b4b2a692,gf9a733ac38+8c5ae1fdc5,w.2025.43
LSST Data Management Base Package
Loading...
Searching...
No Matches
model_data.py
Go to the documentation of this file.
1from __future__ import annotations
2
3import json
4from typing import Any
5
6import numpy as np
7from numpy.typing import DTypeLike
8
9from .blend import ScarletBlendBaseData
10from .migration import PRE_SCHEMA, MigrationRegistry, migration
11from .utils import PersistenceError, decode_metadata, encode_metadata
12
13__all__ = ["ScarletModelData"]
14
15CURRENT_SCHEMA = "1.0.0"
16MODEL_TYPE = "scarlet_model"
17MigrationRegistry.set_current(MODEL_TYPE, CURRENT_SCHEMA)
18
19
21 """A container that propagates scarlet models for an entire catalog.
22
23 Attributes
24 ----------
25 blends :
26 Map from parent IDs in the source catalog
27 to scarlet model data for each parent ID (blend).
28 metadata :
29 Metadata associated with the model,
30 for example the order of bands.
31 model_type :
32 The type of model being stored.
33 version :
34 The schema version of the ScarletModelData.
35 """
36
37 model_type: str = MODEL_TYPE
38 blends: dict[int, ScarletBlendBaseData]
39 metadata: dict[str, Any] | None
40 version: str = CURRENT_SCHEMA
41
43 self,
44 blends: dict[int, ScarletBlendBaseData] | None = None,
45 metadata: dict[str, Any] | None = None,
46 ):
47 """Initialize an instance"""
48 self.metadata = metadata
49 if blends is None:
50 blends = {}
51 self.blends = blends
52
53 def as_dict(self) -> dict:
54 """Return the object encoded into a dict for JSON serialization
55
56 Returns
57 -------
58 result :
59 The object encoded as a JSON compatible dict
60 """
61 result = {
62 "model_type": self.model_type,
63 "blends": {bid: blend_data.as_dict() for bid, blend_data in self.blends.items()},
64 "metadata": encode_metadata(self.metadata),
65 "version": self.version,
66 }
67 return result
68
69 def json(self) -> str:
70 """Serialize the data model to a JSON formatted string
71
72 Returns
73 -------
74 result : `str`
75 The result of the object converted into a JSON format
76 """
77 result = self.as_dict()
78 return json.dumps(result)
79
80 @classmethod
82 cls, data: dict, dtype: DTypeLike = np.float32, **kwargs: dict[str, Any]
83 ) -> ScarletModelData:
84 """Reconstruct `ScarletModelData` from JSON compatible dict.
85
86 Parameters
87 ----------
88 data :
89 Dictionary representation of the object
90 dtype :
91 Datatype of the resulting model.
92 kwargs :
93 Additional keyword arguments.
94
95 Returns
96 -------
97 result :
98 The reconstructed object
99 """
100 data = MigrationRegistry.migrate(cls.model_type, data)
101 blends: dict[int, ScarletBlendBaseData] | None = {}
102 for bid, blend in data.get("blends", {}).items():
103 if "blend_type" not in blend:
104 # Assume that this is a legacy model
105 blend["blend_type"] = "blend"
106 try:
107 blend_data = ScarletBlendBaseData.from_dict(blend, dtype=dtype)
108 except KeyError:
109 raise PersistenceError(f"Unknown blend type: {blend['blend_type']} for blend ID: {bid}")
110 blends[int(bid)] = blend_data # type: ignore
111
112 return cls(
113 blends=blends,
114 metadata=decode_metadata(data["metadata"]),
115 **kwargs,
116 )
117
118 @classmethod
119 def parse_obj(cls, data: dict) -> ScarletModelData:
120 """Construct a ScarletModelData from python decoded JSON object.
121
122 Parameters
123 ----------
124 data :
125 The result of json.load(s) on a JSON persisted ScarletModelData
126
127 Returns
128 -------
129 result :
130 The `ScarletModelData` that was loaded the from the input object
131 """
132 return cls.from_dict(data, dtype=np.float32)
133
134
135@migration(MODEL_TYPE, PRE_SCHEMA)
136def _to_1_0_0(data: dict) -> dict:
137 """Migrate a pre-schema model to schema version 1.0.0
138
139 Parameters
140 ----------
141 data :
142 The data to migrate.
143 Returns
144 -------
145 result :
146 The migrated data.
147 """
148 if "psfShape" in data:
149 # Support legacy models before metadata was used
150 data["metadata"] = {
151 "model_psf": data["psf"],
152 "model_psf_shape": data["psfShape"],
153 "array_keys": ["model_psf"],
154 }
155 data["version"] = "1.0.0"
156 return data
ScarletModelData from_dict(cls, dict data, DTypeLike dtype=np.float32, **dict[str, Any] kwargs)
Definition model_data.py:83
__init__(self, dict[int, ScarletBlendBaseData]|None blends=None, dict[str, Any]|None metadata=None)
Definition model_data.py:46
ScarletModelData parse_obj(cls, dict data)