What is the expected behavior?
As I wrote here, having a formatted metadata will be useful to extract x and y values, see #23. Currently, xvalue appears as different name in PRs ("delay" in #5 , "meas_basis" in #7, "xdata" in #18 ), so the naming rule is up to person who implements the module. Though this improves readability of metadata, this will be a real headache to write the analysis superclass.
Here I propose to define dataclass with some helper method:
@dataclasses.dataclass
class ExperimentMetadata:
experiment_type: str
qubits: List[int]
exp_id: str = None
def to_dict(self):
return dataclasses.asdict(self)
def check_entry(self, **series_kwargs):
return all(self.to_dict()[key] == value for key, value in series_kwargs.items())
@abstractmethod
def get_x_value(self) -> Any:
We assume we can identify an experiment entry with x_value and series, i.e. x_value is horizontal axis of the graph, while series indicates a label of line. Some experiment may have only series, values can be provided by a method so that we don't need to fill metadata with empty value (still we can guarantee the extraction method proposed in #23 can access to values).
The extraction method may become
def extract_xy_values(exp_data: ExperimentData, **series: str)
since x_value is provided by metadata itself. Series becomes kwargs because it may be defined by a dictionary.
# e.g. QPT
extract_xy_values(exp_data, meas_basis=('X',), prep_basis=('Xp',))
The .check_entry
method will return True
if input kwargs mathces with the metadata.
I assume we can cover almost all typical experiments with below 3 sub types:
No scan:
Discriminator experiment
@dataclasses.dataclass
class DiscriminatorExperiment(ExperimentMetadata):
prep_state: str
def get_x_value(self) -> float:
return None
extract_xy_values(exp_data, prep_state='00')
Process tomography
@dataclasses.dataclass
class TomographyMetadata(ExperimentMetadata):
meas_basis: str
prep_basis: str
def get_x_value(self) -> float:
return None
extract_xy_values(exp_data, meas_basis=('X',), prep_basis=('Xp',))
Line scan:
Interleaved randomized benchmarking
@dataclasses.dataclass
class RBMetadata(ExperimentMetadata):
n_clifford: float
interleaved: bool
def get_x_value(self) -> float:
return self.n_clifford
extract_xy_values(exp_data, interleaved=True)
T1 measurement
@dataclasses.dataclass
class T1Metadata(ExperimentMetadata):
delay: int
def get_x_value(self) -> float:
return self.delay
extract_xy_values(exp_data)
Line scan with multiple series
Hamiltonian tomography
@dataclasses.dataclass
class HamTomographyMetadata(ExperimentMetadata):
pulse_duration: int
meas_basis: str
control_state: int
def get_x_value(self) -> float:
return self.pulse_duration
extract_xy_values(exp_data, meas_basis='X', control_state=0)