44
55from __future__ import annotations
66
7+ import json
78from typing import TYPE_CHECKING
89
910import guidata .dataset as gds
1011import numpy as np
1112from sigima .objects import (
13+ PEAK_PARAMETERIZATION ,
1214 CustomSignalParam ,
1315 Gauss2DParam ,
1416 ImageDatatypes ,
1517 ImageObj ,
1618 NewImageParam ,
1719 NewSignalParam ,
1820 SignalObj ,
21+ convert_legacy_peak_creation_params ,
1922 create_signal ,
23+ validate_peak_creation_params ,
2024)
2125from sigima .objects import create_image_from_param as create_image_headless
2226from sigima .objects import create_signal_from_param as create_signal_headless
2327from sigima .objects .base import BaseProcParam
24- from sigima .objects .signal import DEFAULT_TITLE as SIGNAL_DEFAULT_TITLE
28+ from sigima .objects .signal import (
29+ DEFAULT_TITLE as SIGNAL_DEFAULT_TITLE ,
30+ )
31+ from sigima .objects .signal import (
32+ BaseGaussLorentzVoigtParam ,
33+ )
2534
2635from datalab .config import _
2736
2837if TYPE_CHECKING :
2938 from qtpy import QtWidgets as QW
3039
31- CREATION_PARAMETERS_OPTION = "creation_param_json"
40+ CREATION_PARAMETERS_OPTION = "creation_parameters"
41+ LEGACY_CREATION_PARAMETERS_OPTION = "creation_param_json"
42+ CREATION_PARAMETERS_FORMAT_VERSION = 1
43+
44+
45+ def _decode_dataset_json (dataset_json : str ) -> dict [str , object ]:
46+ """Decode a DataSet JSON payload without instantiating its class."""
47+ try :
48+ payload = json .loads (dataset_json )
49+ except (TypeError , json .JSONDecodeError ) as exc :
50+ raise ValueError ("Invalid creation parameter JSON" ) from exc
51+ if not isinstance (payload , dict ):
52+ raise ValueError ("Creation parameter JSON must contain an object" )
53+ return payload
3254
3355
3456def insert_creation_parameters (obj : SignalObj | ImageObj , param : gds .DataSet ) -> None :
@@ -38,7 +60,17 @@ def insert_creation_parameters(obj: SignalObj | ImageObj, param: gds.DataSet) ->
3860 obj: Object receiving the serialized parameters.
3961 param: Creation parameters.
4062 """
41- obj .set_metadata_option (CREATION_PARAMETERS_OPTION , gds .dataset_to_json (param ))
63+ dataset_json = gds .dataset_to_json (param )
64+ raw_params = _decode_dataset_json (dataset_json )
65+ envelope : dict [str , object ] = {
66+ "format_version" : CREATION_PARAMETERS_FORMAT_VERSION ,
67+ "dataset_json" : dataset_json ,
68+ }
69+ if isinstance (param , BaseGaussLorentzVoigtParam ):
70+ validate_peak_creation_params (raw_params )
71+ envelope ["peak_parameterization" ] = PEAK_PARAMETERIZATION
72+ obj .set_metadata_option (CREATION_PARAMETERS_OPTION , envelope )
73+ obj .metadata .pop (f"__{ LEGACY_CREATION_PARAMETERS_OPTION } " , None )
4274
4375
4476def extract_creation_parameters (obj : SignalObj | ImageObj ) -> gds .DataSet | None :
@@ -50,11 +82,77 @@ def extract_creation_parameters(obj: SignalObj | ImageObj) -> gds.DataSet | None
5082 Returns:
5183 Creation parameters or None if not found.
5284 """
53- try :
54- param_json = obj .get_metadata_option (CREATION_PARAMETERS_OPTION )
55- except ValueError :
85+ options = obj .get_metadata_options ()
86+ has_current = CREATION_PARAMETERS_OPTION in options
87+ has_legacy = LEGACY_CREATION_PARAMETERS_OPTION in options
88+ if has_current and has_legacy :
89+ raise ValueError ("Conflicting creation parameter formats" )
90+ if not has_current and not has_legacy :
5691 return None
57- return gds .json_to_dataset (param_json )
92+
93+ if has_current :
94+ envelope = options [CREATION_PARAMETERS_OPTION ]
95+ if not isinstance (envelope , dict ):
96+ raise ValueError ("Creation parameters must use a versioned envelope" )
97+ version = envelope .get ("format_version" )
98+ if version != CREATION_PARAMETERS_FORMAT_VERSION :
99+ raise ValueError (f"Unsupported creation parameter format: { version !r} " )
100+ dataset_json = envelope .get ("dataset_json" )
101+ if not isinstance (dataset_json , str ):
102+ raise ValueError ("Creation parameter envelope has no dataset_json" )
103+ raw_params = _decode_dataset_json (dataset_json )
104+ is_peak = raw_params .get ("class_name" ) in {
105+ "GaussParam" ,
106+ "LorentzParam" ,
107+ "VoigtParam" ,
108+ }
109+ parameterization = envelope .get ("peak_parameterization" )
110+ if is_peak :
111+ if parameterization != PEAK_PARAMETERIZATION :
112+ raise ValueError (
113+ f"Unsupported peak parameterization: { parameterization !r} "
114+ )
115+ validate_peak_creation_params (raw_params )
116+ elif parameterization is not None :
117+ raise ValueError (
118+ "Peak parameterization set on non-peak creation parameters"
119+ )
120+ return gds .json_to_dataset (dataset_json )
121+
122+ dataset_json = options [LEGACY_CREATION_PARAMETERS_OPTION ]
123+ if not isinstance (dataset_json , str ):
124+ raise ValueError ("Legacy creation parameters must contain DataSet JSON" )
125+ raw_params = _decode_dataset_json (dataset_json )
126+ if raw_params .get ("class_name" ) in {"GaussParam" , "LorentzParam" , "VoigtParam" }:
127+ validate_peak_creation_params (raw_params )
128+ return gds .json_to_dataset (dataset_json )
129+
130+
131+ def convert_legacy_creation_parameters (
132+ obj : SignalObj | ImageObj ,
133+ ) -> gds .DataSet :
134+ """Explicitly convert legacy peak creation metadata to version 2.
135+
136+ The object data is not regenerated; only its reusable creation parameters
137+ are converted and stored under the new metadata option.
138+
139+ Args:
140+ obj: Object carrying historical creation metadata.
141+
142+ Returns:
143+ Converted peak creation parameters.
144+ """
145+ options = obj .get_metadata_options ()
146+ if CREATION_PARAMETERS_OPTION in options :
147+ raise ValueError ("Current creation parameters already exist" )
148+ dataset_json = options .get (LEGACY_CREATION_PARAMETERS_OPTION )
149+ if not isinstance (dataset_json , str ):
150+ raise ValueError ("Object has no legacy creation parameters" )
151+ raw_params = _decode_dataset_json (dataset_json )
152+ converted = convert_legacy_peak_creation_params (raw_params )
153+ param = gds .json_to_dataset (json .dumps (converted ))
154+ insert_creation_parameters (obj , param )
155+ return param
58156
59157
60158def create_signal_from_param (param : NewSignalParam ) -> SignalObj :
0 commit comments