diff --git a/src/qibolab/_core/parameters.py b/src/qibolab/_core/parameters.py index 1ad0957cd..dba5aa3db 100644 --- a/src/qibolab/_core/parameters.py +++ b/src/qibolab/_core/parameters.py @@ -169,6 +169,21 @@ def _dump_configs(obj: dict[ComponentId, Config]) -> dict[str, dict]: return {k: a.dump_python(v) for k, v in obj.items()} +def _setvalue(d: dict, path: str, val: Any): + steps = path.split(".") + current = d + for step in steps[:-1]: + try: + current = current[int(step)] + except ValueError: + current = current[step] + + current[steps[-1]] = val + + +Update = dict[str, Any] + + class Parameters(Model): """Serializable parameters.""" @@ -179,3 +194,11 @@ class Parameters(Model): PlainSerializer(_dump_configs), ] = Field(default_factory=dict) native_gates: NativeGates = Field(default_factory=NativeGates) + + def replace(self, update: Update) -> "Parameters": + """Update parameters' values.""" + d = self.model_dump() + for path, val in update.items(): + _setvalue(d, path, val) + + return self.model_validate(d) diff --git a/src/qibolab/_core/platform/platform.py b/src/qibolab/_core/platform/platform.py index 218fbdb0e..ff1bbe73d 100644 --- a/src/qibolab/_core/platform/platform.py +++ b/src/qibolab/_core/platform/platform.py @@ -12,7 +12,7 @@ from ..execution_parameters import ExecutionParameters from ..identifier import ChannelId, QubitId, QubitPairId, Result from ..instruments.abstract import Controller, Instrument, InstrumentId -from ..parameters import NativeGates, Parameters, Settings, update_configs +from ..parameters import NativeGates, Parameters, Settings, Update, update_configs from ..pulses import PulseId from ..qubits import Qubit from ..sequence import PulseSequence @@ -168,6 +168,10 @@ def config(self, name: str) -> Config: # pylint: disable=unsubscriptable-object return self.parameters.configs[name] + def update(self, update: Update): + """Update platform's parameters.""" + self.parameters = self.parameters.replace(update) + def connect(self): """Connect to all instruments.""" if not self.is_connected: diff --git a/tests/test_parameters.py b/tests/test_parameters.py index 5cc956a9d..5cc461c1f 100644 --- a/tests/test_parameters.py +++ b/tests/test_parameters.py @@ -5,6 +5,8 @@ from qibolab._core.components.configs import Config from qibolab._core.native import Native, TwoQubitNatives from qibolab._core.parameters import ConfigKinds, Parameters, TwoQubitContainer +from qibolab._core.platform.load import create_platform +from qibolab._core.pulses.pulse import Pulse def test_two_qubit_container(): @@ -77,3 +79,28 @@ def test_within_parameters(self): reloaded = Parameters.model_validate(dump) assert reloaded == pars + + +def test_update(): + dummy = create_platform("dummy") + dummy.update({}) + + assert isinstance(dummy.parameters.native_gates.single_qubit[1].RX[0][1], Pulse) + assert dummy.natives.single_qubit[1].RX[0][1].amplitude > 0 + dummy.update({"native_gates.single_qubit.1.RX.0.1.amplitude": -0.5}) + assert dummy.natives.single_qubit[1].RX[0][1].amplitude < 0 + + assert dummy.settings.nshots != 1234567890 + dummy.update({"settings.nshots": 1234567890}) + assert dummy.settings.nshots == 1234567890 + + dummy.update( + { + "settings.nshots": 42, + "native_gates.single_qubit.1.RX.0.1.amplitude": -0.123, + "native_gates.single_qubit.1.RX.0.1.duration": 456.7, + } + ) + assert dummy.settings.nshots == 42 + assert dummy.natives.single_qubit[1].RX[0][1].amplitude == -0.123 + assert dummy.natives.single_qubit[1].RX[0][1].duration == 456.7