Source code for qiskit_experiments.calibration_management.parameter_value

# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Data class for parameter values."""

from dataclasses import dataclass
from datetime import datetime
from typing import Union

from qiskit_experiments.exceptions import CalibrationError


[docs]@dataclass class ParameterValue: """A data class to store parameter values.""" # Value assumed by the parameter value: Union[int, float, complex] = None # Data time when the value of the parameter was generated date_time: datetime = datetime.fromtimestamp(0) # A bool indicating if the parameter is valid valid: bool = True # The experiment from which the value of this parameter was generated. exp_id: str = None # The group of calibrations to which this parameter belongs group: str = "default" def __post_init__(self): """ Ensure that the variables in self have the proper types. This allows us to give strings to self.__init__ as input which is useful when loading serialized parameter values. """ if isinstance(self.valid, str): if self.valid == "True": self.valid = True else: self.valid = False if isinstance(self.value, str): self.value = self._validated_value(self.value) if isinstance(self.date_time, str): base_fmt = "%Y-%m-%d %H:%M:%S.%f" zone_fmts = ["%z", "", "Z"] for time_zone in zone_fmts: date_format = base_fmt + time_zone try: self.date_time = datetime.strptime(self.date_time, date_format) break except ValueError: pass else: formats = list(base_fmt + zone for zone in zone_fmts) raise CalibrationError( f"Cannot parse {self.date_time} in either of {formats} formats." ) self.date_time = self.date_time.astimezone() if not isinstance(self.value, (int, float, complex)): raise CalibrationError(f"Values {self.value} must be int, float or complex.") if not isinstance(self.date_time, datetime): raise CalibrationError(f"Datetime {self.date_time} must be a datetime.") if not isinstance(self.valid, bool): raise CalibrationError(f"Valid {self.valid} is not a boolean.") if self.exp_id and not isinstance(self.exp_id, str): raise CalibrationError(f"Experiment id {self.exp_id} is not a string.") if not isinstance(self.group, str): raise CalibrationError(f"Group {self.group} is not a string.") @staticmethod def _validated_value(value: str) -> Union[int, float, complex]: """ Convert the string representation of value to the correct type. Args: value: The string to convert to either an int, float, or complex. Returns: value converted to either int, float, or complex. Raises: CalibrationError: If the conversion fails. """ try: return int(value) except ValueError: pass try: return float(value) except ValueError: pass try: return complex(value) except ValueError as val_err: raise CalibrationError( f"Could not convert {value} to int, float, or complex." ) from val_err