Skip to content

Commit

Permalink
Merge pull request #3956 from jenshnielsen/dataset/create_run_from_de…
Browse files Browse the repository at this point in the history
…scription

Directly use rundescriber to create run when exporting datasets to a new database file
  • Loading branch information
jenshnielsen committed Feb 24, 2022
2 parents 989be87 + ca2ae42 commit 72090cb
Show file tree
Hide file tree
Showing 9 changed files with 285 additions and 114 deletions.
1 change: 1 addition & 0 deletions docs/changes/newsfragments/3956.improved
@@ -0,0 +1 @@
Datasets now correctly preserve the shape information when exported to another database.
10 changes: 1 addition & 9 deletions qcodes/dataset/dataset_helpers.py
Expand Up @@ -17,14 +17,6 @@ def _add_run_to_runs_table(
target_exp_id: int,
create_run_table: bool = True,
) -> Optional[str]:
if dataset._parameters is not None:
param_names = dataset._parameters.split(",")
else:
param_names = []
parspecs_dict = {
p.name: p for p in new_to_old(dataset.description.interdeps).paramspecs
}
parspecs = [parspecs_dict[p] for p in param_names]
metadata = dataset.metadata
snapshot_raw = dataset._snapshot_raw
captured_run_id = dataset.captured_run_id
Expand All @@ -35,13 +27,13 @@ def _add_run_to_runs_table(
target_exp_id,
name=dataset.name,
guid=dataset.guid,
parameters=parspecs,
metadata=metadata,
captured_run_id=captured_run_id,
captured_counter=captured_counter,
parent_dataset_links=parent_dataset_links,
create_run_table=create_run_table,
snapshot_raw=snapshot_raw,
description=dataset.description,
)
mark_run_complete(target_conn, target_run_id)
_rewrite_timestamps(
Expand Down
34 changes: 24 additions & 10 deletions qcodes/dataset/descriptions/dependencies.py
Expand Up @@ -4,8 +4,18 @@
which parameters depend on each other is handled here.
"""
from copy import deepcopy
from typing import (Any, Dict, FrozenSet, Iterable, List, Optional, Sequence,
Set, Tuple, Type)
from typing import (
Any,
Dict,
FrozenSet,
Iterable,
List,
Optional,
Sequence,
Set,
Tuple,
Type,
)

from .param_spec import ParamSpec, ParamSpecBase
from .versioning.rundescribertypes import InterDependencies_Dict
Expand Down Expand Up @@ -59,13 +69,17 @@ def __init__(self,

deps_error = self.validate_paramspectree(dependencies)
if deps_error is not None:
old_error = deps_error[0](deps_error[1])
raise ValueError('Invalid dependencies') from old_error
try:
raise deps_error[0](deps_error[1])
except Exception as old_error:
raise ValueError("Invalid dependencies") from old_error

inffs_error = self.validate_paramspectree(inferences)
if inffs_error is not None:
old_error = inffs_error[0](inffs_error[1])
raise ValueError('Invalid inferences') from old_error
try:
raise inffs_error[0](inffs_error[1])
except Exception as old_error:
raise ValueError("Invalid inferences") from old_error

link_error = self._validate_double_links(dependencies, inferences)
if link_error is not None:
Expand All @@ -74,10 +88,10 @@ def __init__(self,

for ps in standalones:
if not isinstance(ps, ParamSpecBase):
base_error = TypeError('Standalones must be a sequence of '
'ParamSpecs')

raise ValueError('Invalid standalones') from base_error
try:
raise TypeError("Standalones must be a sequence of ParamSpecs")
except TypeError as base_error:
raise ValueError("Invalid standalones") from base_error

self._remove_duplicates(dependencies)
self._remove_duplicates(inferences)
Expand Down
2 changes: 1 addition & 1 deletion qcodes/dataset/descriptions/rundescriber.py
Expand Up @@ -38,6 +38,7 @@ def __init__(self, interdeps: InterDependencies_,
self._verify_interdeps_shape(interdeps, shapes)

self._interdeps = interdeps

self._shapes = shapes
self._version = 3

Expand All @@ -53,7 +54,6 @@ def shapes(self) -> Shapes:
def interdeps(self) -> InterDependencies_:
return self._interdeps


@staticmethod
def _verify_interdeps_shape(interdeps: InterDependencies_,
shapes: Shapes) -> None:
Expand Down
51 changes: 37 additions & 14 deletions qcodes/dataset/descriptions/versioning/converters.py
Expand Up @@ -9,8 +9,12 @@

from ..dependencies import InterDependencies_
from ..param_spec import ParamSpec, ParamSpecBase
from .rundescribertypes import (RunDescriberV0Dict, RunDescriberV1Dict,
RunDescriberV2Dict, RunDescriberV3Dict)
from .rundescribertypes import (
RunDescriberV0Dict,
RunDescriberV1Dict,
RunDescriberV2Dict,
RunDescriberV3Dict,
)
from .v0 import InterDependencies


Expand Down Expand Up @@ -57,26 +61,45 @@ def new_to_old(idps: InterDependencies_) -> InterDependencies:

paramspecs: Dict[str, ParamSpec] = {}


# first the independent parameters
for indeps in idps.dependencies.values():
for indep in indeps:
paramspecs.update({indep.name: ParamSpec(name=indep.name,
paramtype=indep.type,
label=indep.label,
unit=indep.unit)})
paramspecs.update(
{
indep.name: ParamSpec(
name=indep.name,
paramtype=indep.type,
label=indep.label,
unit=indep.unit,
)
}
)

for inffs in idps.inferences.values():
for inff in inffs:
paramspecs.update({inff.name: ParamSpec(name=inff.name,
paramtype=inff.type,
label=inff.label,
unit=inff.unit)})
paramspecs.update(
{
inff.name: ParamSpec(
name=inff.name,
paramtype=inff.type,
label=inff.label,
unit=inff.unit,
)
}
)

for ps_base in idps._paramspec_to_id.keys():
paramspecs.update({ps_base.name: ParamSpec(name=ps_base.name,
paramtype=ps_base.type,
label=ps_base.label,
unit=ps_base.unit)})
paramspecs.update(
{
ps_base.name: ParamSpec(
name=ps_base.name,
paramtype=ps_base.type,
label=ps_base.label,
unit=ps_base.unit,
)
}
)

for ps, indeps in idps.dependencies.items():
for indep in indeps:
Expand Down
41 changes: 33 additions & 8 deletions qcodes/dataset/descriptions/versioning/serialization.py
Expand Up @@ -31,17 +31,32 @@
"""
import io
import json
from typing import Callable, Dict, Tuple, cast, Any
from typing import Any, Callable, Dict, Tuple, cast

from qcodes.utils.helpers import YAML

from .. import rundescriber as current
from .converters import (v0_to_v1, v0_to_v2, v0_to_v3, v1_to_v0, v1_to_v2,
v1_to_v3, v2_to_v0, v2_to_v1, v2_to_v3, v3_to_v0,
v3_to_v1, v3_to_v2)
from .rundescribertypes import (RunDescriberDicts, RunDescriberV0Dict,
RunDescriberV1Dict, RunDescriberV2Dict,
RunDescriberV3Dict)
from .converters import (
v0_to_v1,
v0_to_v2,
v0_to_v3,
v1_to_v0,
v1_to_v2,
v1_to_v3,
v2_to_v0,
v2_to_v1,
v2_to_v3,
v3_to_v0,
v3_to_v1,
v3_to_v2,
)
from .rundescribertypes import (
RunDescriberDicts,
RunDescriberV0Dict,
RunDescriberV1Dict,
RunDescriberV2Dict,
RunDescriberV3Dict,
)

STORAGE_VERSION = 3
# the version of :class:`RunDescriber` object that is used by the data storage
Expand Down Expand Up @@ -129,7 +144,17 @@ def from_json_to_current(json_str: str) -> current.RunDescriber:
"""
Deserialize a JSON string into a RunDescriber of the current version
"""
return from_dict_to_current(json.loads(json_str))

data = json.loads(json_str)
# json maps both list and tuple to list
# since we always expects shapes to be a tuple
# convert it back to a tuple here
shapes = data.get("shapes", None)
if shapes is not None:
for name, shapelist in shapes.items():
shapes[name] = tuple(shapelist)

return from_dict_to_current(data)


# YAML
Expand Down

0 comments on commit 72090cb

Please sign in to comment.