예제 #1
0
def test_copy(name1, name2):
    ps_indep = ParamSpec(name1, "numeric")
    ps = ParamSpec(name2, "numeric", depends_on=[ps_indep, 'other_param'])
    ps_copy = ps.copy()

    assert ps_copy == ps
    assert hash(ps_copy) == hash(ps)

    att_names = [
        "name", "type", "label", "unit", "_inferred_from", "_depends_on"
    ]

    attributes = {}
    for att in att_names:
        val = getattr(ps, att)
        valc = getattr(ps_copy, att)
        assert val == valc
        attributes[att] = val

    # Modifying the copy should not change the original
    for att in att_names:
        if not att.startswith('_'):
            setattr(ps_copy, att, attributes[att] + "_modified")
        else:
            setattr(ps_copy, att, attributes[att] + ['bob'])
        assert getattr(ps, att) == attributes[att]

    assert ps_copy != ps
    assert hash(ps_copy) != hash(ps)
예제 #2
0
def test_wrong_input_raises():

    for pspecs in [['p1', 'p2', 'p3'],
                   [ParamSpec('p1', paramtype='numeric'), 'p2'],
                   ['p1', ParamSpec('p2', paramtype='text')]]:

        with pytest.raises(ValueError):
            InterDependencies(pspecs)
예제 #3
0
def test_not_eq_for_list_attr():
    """
    test that two paramspecs that differ only
    in list attrs are different
    """

    p1 = ParamSpec(name='foo', paramtype='numeric', depends_on=['a', 'b'])
    p2 = ParamSpec(name='foo', paramtype='numeric', depends_on=['c', 'd'])
    assert p1 != p2
예제 #4
0
def test_atomic_creation(experiment):
    """"
    Test that dataset creation is atomic. Test for
    https://github.com/QCoDeS/Qcodes/issues/1444
    """
    def just_throw(*args):
        raise RuntimeError("This breaks adding metadata")

    # first we patch add_data_to_dynamic_columns to throw an exception
    # if create_data is not atomic this would create a partial
    # run in the db. Causing the next create_run to fail
    with patch("qcodes.dataset.sqlite.queries.add_data_to_dynamic_columns",
               new=just_throw):
        x = ParamSpec("x", "numeric")
        t = ParamSpec("t", "numeric")
        y = ParamSpec("y", "numeric", depends_on=["x", "t"])
        with pytest.raises(
                RuntimeError,
                match="Rolling back due to unhandled exception") as e:
            mut_queries.create_run(
                experiment.conn,
                experiment.exp_id,
                name="testrun",
                guid=generate_guid(),
                parameters=[x, t, y],
                metadata={"a": 1},
            )
    assert error_caused_by(e, "This breaks adding metadata")
    # since we are starting from an empty database and the above transaction
    # should be rolled back there should be no runs in the run table
    runs = mut_conn.transaction(experiment.conn,
                                'SELECT run_id FROM runs').fetchall()
    assert len(runs) == 0
    with shadow_conn(experiment.path_to_db) as new_conn:
        runs = mut_conn.transaction(new_conn,
                                    'SELECT run_id FROM runs').fetchall()
        assert len(runs) == 0

    # if the above was not correctly rolled back we
    # expect the next creation of a run to fail
    mut_queries.create_run(experiment.conn,
                           experiment.exp_id,
                           name='testrun',
                           guid=generate_guid(),
                           parameters=[x, t, y],
                           metadata={'a': 1})

    runs = mut_conn.transaction(experiment.conn,
                                'SELECT run_id FROM runs').fetchall()
    assert len(runs) == 1

    with shadow_conn(experiment.path_to_db) as new_conn:
        runs = mut_conn.transaction(new_conn,
                                    'SELECT run_id FROM runs').fetchall()
        assert len(runs) == 1
예제 #5
0
def test_base_version(paramspecs):

    kwargs = paramspecs[0]

    ps = ParamSpec(**kwargs)
    ps_base = ParamSpecBase(name=kwargs['name'],
                            paramtype=kwargs['paramtype'],
                            label=kwargs['label'],
                            unit=kwargs['unit'])

    assert ps.base_version() == ps_base
예제 #6
0
def version_0_objects():
    """
    The ParamSpecs that the dictionaries above represent
    """
    ps = []
    ps.append(ParamSpec('dmm_v1', paramtype='numeric', label='Gate v1',
                        unit='V', inferred_from=[],
                        depends_on=['dac_ch1', 'dac_ch2']))
    ps.append(ParamSpec('some_name', paramtype='array',
                        label='My Array ParamSpec', unit='Ars',
                        inferred_from=['p1', 'p2'], depends_on=[]))
    return ps
예제 #7
0
def test_convert_to_dict():
    p1 = ParamSpec('p1', 'numeric', 'paramspec one', 'no unit',
                   depends_on=['some', 'thing'], inferred_from=['bab', 'bob'])

    ser = p1._to_dict()

    assert ser['name'] == p1.name
    assert ser['paramtype'] == p1.type
    assert ser['label'] == p1.label
    assert ser['unit'] == p1.unit
    assert ser['depends_on'] == p1._depends_on
    assert ser['inferred_from'] == p1._inferred_from
예제 #8
0
def test_repr(name):
    okay_types = ['array', 'numeric', 'text']

    for okt in okay_types:
        if name.isidentifier():
            ps = ParamSpec(name, okt)
            expected_repr = (f"ParamSpec('{name}', '{okt}', '', '', "
                             "inferred_from=[], depends_on=[])")
            assert ps.__repr__() == expected_repr
        else:
            with pytest.raises(ValueError):
                ps = ParamSpec(name, okt)
예제 #9
0
def test_depends_on(name1, name2, name3):
    ps2 = ParamSpec(name2, "numeric")
    ps3 = ParamSpec(name3, "numeric")

    ps1 = ParamSpec(name1, "numeric", depends_on=[ps2, ps3, 'foo'])

    assert ps1.depends_on == f"{ps2.name}, {ps3.name}, foo"
    assert ps1.depends_on_ == [ps2.name, ps3.name, "foo"]

    with pytest.raises(ValueError,
                       match=f"ParamSpec {name1} got string foo as depends_on. "
                       "It needs a Sequence of ParamSpecs or strings"):
        ParamSpec(name1, "numeric", depends_on='foo')
예제 #10
0
def test_inferred_from(name1, name2, name3):
    ps2 = ParamSpec(name2, "numeric")
    ps3 = ParamSpec(name3, "numeric")

    ps1 = ParamSpec(name1, "numeric", inferred_from=[ps2, ps3, 'bar'])

    assert ps1.inferred_from == f"{ps2.name}, {ps3.name}, bar"
    assert ps1.inferred_from_ == [ps2.name, ps3.name, "bar"]

    with pytest.raises(ValueError,
                       match=f"ParamSpec {name1} got string foo as "
                       f"inferred_from. "
                       "It needs a Sequence of ParamSpecs or strings"):
        ParamSpec(name1, "numeric", inferred_from='foo')
예제 #11
0
def test_not_eq_for_str_attr():
    """
    test that two paramspecs that differ only
    in str attrs are different
    """

    p1 = ParamSpec(name='foo',
                   label='myfoo',
                   paramtype='numeric',
                   depends_on=['a', 'b'])
    p2 = ParamSpec(name='foo',
                   label='someotherfoo',
                   paramtype='numeric',
                   depends_on=['a', 'b'])
    assert p1 != p2
예제 #12
0
def new_to_old(idps: InterDependencies_) -> InterDependencies:
    """
    Create a new InterDependencies object (old style) from an existing
    InterDependencies_ object (new style). Leaves the original object
    unchanged. Only meant to be used for ensuring backwards-compatibility
    until we update sqlite module to forget about ParamSpecs
    """

    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)
            })

    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)
            })

    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)
        })

    for ps, indeps in idps.dependencies.items():
        for indep in indeps:
            paramspecs[ps.name]._depends_on.append(indep.name)
    for ps, inffs in idps.inferences.items():
        for inff in inffs:
            paramspecs[ps.name]._inferred_from.append(inff.name)

    return InterDependencies(*tuple(paramspecs.values()))
예제 #13
0
파일: v0.py 프로젝트: tomasstankevic/Qcodes
 def _from_dict(cls, ser: Dict[str, Any]) -> 'InterDependencies':
     """
     Create an InterDependencies object from a dictionary
     """
     paramspecs = [ParamSpec._from_dict(sps) for sps in ser['paramspecs']]
     idp = cls(*paramspecs)
     return idp
예제 #14
0
def test_new_to_old(some_paramspecbases):

    (ps1, ps2, ps3, ps4) = some_paramspecbases

    idps_new = InterDependencies_(dependencies={ps1: (ps2, ps3)},
                                  standalones=(ps4, ))

    paramspec1 = ParamSpec(name=ps1.name,
                           paramtype=ps1.type,
                           label=ps1.label,
                           unit=ps1.unit,
                           depends_on=[ps2.name, ps3.name])
    paramspec2 = ParamSpec(name=ps2.name,
                           paramtype=ps2.type,
                           label=ps2.label,
                           unit=ps2.unit)
    paramspec3 = ParamSpec(name=ps3.name,
                           paramtype=ps3.type,
                           label=ps3.label,
                           unit=ps3.unit)
    paramspec4 = ParamSpec(name=ps4.name,
                           paramtype=ps4.type,
                           label=ps4.label,
                           unit=ps4.unit)
    idps_old_expected = InterDependencies(paramspec2, paramspec3, paramspec1,
                                          paramspec4)

    assert new_to_old(idps_new) == idps_old_expected

    #

    idps_new = InterDependencies_(inferences={ps1: (ps2, ps3)},
                                  standalones=(ps4, ))

    paramspec1 = ParamSpec(name=ps1.name,
                           paramtype=ps1.type,
                           label=ps1.label,
                           unit=ps1.unit,
                           inferred_from=[ps2.name, ps3.name])
    paramspec2 = ParamSpec(name=ps2.name,
                           paramtype=ps2.type,
                           label=ps2.label,
                           unit=ps2.unit)
    paramspec3 = ParamSpec(name=ps3.name,
                           paramtype=ps3.type,
                           label=ps3.label,
                           unit=ps3.unit)
    paramspec4 = ParamSpec(name=ps4.name,
                           paramtype=ps4.type,
                           label=ps4.label,
                           unit=ps4.unit)
    idps_old_expected = InterDependencies(paramspec2, paramspec3, paramspec1,
                                          paramspec4)

    assert new_to_old(idps_new) == idps_old_expected
예제 #15
0
def test_creation(name, sp1, sp2, inff1, inff2, paramtype):
    invalid_types = ['np.array', 'ndarray', 'lala', '', Number,
                     ndarray, 0, None]
    for inv_type in invalid_types:
        with pytest.raises(ValueError):
            ParamSpec(name, inv_type)

    if not inff1.isidentifier():
        inff1 = 'inff1'

    if not sp1.isidentifier():
        sp1 = 'sp1'

    if not name.isidentifier():
        with pytest.raises(ValueError):
            ps = ParamSpec(name, paramtype[0], label=None, unit='V',
                           inferred_from=(inff1, inff2),
                           depends_on=(sp1, sp2))
        name = 'name'

    ps = ParamSpec(name, paramtype[1], label=None, unit='V',
                   inferred_from=(inff1, inff2),
                   depends_on=(sp1, sp2))

    assert ps.inferred_from == f'{inff1}, {inff2}'
    assert ps.depends_on == f'{sp1}, {sp2}'

    ps1 = ParamSpec(sp1, paramtype[2])
    p1 = ParamSpec(name, paramtype[3], depends_on=(ps1, sp2))
    assert p1.depends_on == ps.depends_on

    ps2 = ParamSpec(inff1, paramtype[4])
    p2 = ParamSpec(name, paramtype[5], inferred_from=(ps2, inff2))
    assert p2.inferred_from == ps.inferred_from
예제 #16
0
def test_hash(paramspecs):
    p1 = ParamSpec(**paramspecs[0])
    p2 = ParamSpec(**paramspecs[1])

    # call __hash__
    p1_h = hash(p1)
    p2_h = hash(p2)

    # make a set
    p_set = {p1, p2}

    # test that the hash equality follows object equality
    if p1 == p2:
        assert p1_h == p2_h
        assert 1 == len(p_set)
    else:
        assert p1_h != p2_h
        assert 2 == len(p_set)
예제 #17
0
파일: conftest.py 프로젝트: H6O3/Qcodes
def some_paramspecs():
    """
    Some different paramspecs for testing. The idea is that we just add a
    new group of paramspecs as the need arises
    """

    groups = {}

    # A valid group. Corresponding to a heatmap with a text label at each point
    first = {}
    first['ps1'] = ParamSpec('ps1',
                             paramtype='numeric',
                             label='Raw Data 1',
                             unit='V')
    first['ps2'] = ParamSpec('ps2',
                             paramtype='array',
                             label='Raw Data 2',
                             unit='V')
    first['ps3'] = ParamSpec('ps3',
                             paramtype='text',
                             label='Axis 1',
                             unit='',
                             inferred_from=[first['ps1']])
    first['ps4'] = ParamSpec('ps4',
                             paramtype='numeric',
                             label='Axis 2',
                             unit='V',
                             inferred_from=[first['ps2']])
    first['ps5'] = ParamSpec('ps5',
                             paramtype='numeric',
                             label='Signal',
                             unit='Conductance',
                             depends_on=[first['ps3'], first['ps4']])
    first['ps6'] = ParamSpec('ps6',
                             paramtype='text',
                             label='Goodness',
                             unit='',
                             depends_on=[first['ps3'], first['ps4']])
    groups[1] = first

    # a small, valid group
    second = {}
    second['ps1'] = ParamSpec('ps1',
                              paramtype='numeric',
                              label='setpoint',
                              unit='Hz')
    second['ps2'] = ParamSpec('ps2',
                              paramtype='numeric',
                              label='signal',
                              unit='V',
                              depends_on=[second['ps1']])
    groups[2] = second

    return groups
예제 #18
0
def _2to3_get_paramspecs(
    conn: ConnectionPlus,
    layout_ids: List[int],
    layouts: Mapping[int, Tuple[str, str, str, str]],
    dependencies: Mapping[int, Sequence[int]],
    deps: Sequence[int],
    indeps: Sequence[int],
    result_table_name: str,
) -> Dict[int, ParamSpec]:

    paramspecs: Dict[int, ParamSpec] = {}

    the_rest = set(layout_ids).difference(set(deps).union(set(indeps)))

    # We ensure that we first retrieve the ParamSpecs on which other ParamSpecs
    # depend, then the dependent ParamSpecs and finally the rest

    for layout_id in list(indeps) + list(deps) + list(the_rest):
        (name, label, unit, inferred_from_str) = layouts[layout_id]
        # get the data type
        sql = f'PRAGMA TABLE_INFO("{result_table_name}")'
        c = transaction(conn, sql)
        paramtype = None
        for row in c.fetchall():
            if row['name'] == name:
                paramtype = row['type']
                break
        if paramtype is None:
            raise TypeError(f"Could not determine type of {name} during the"
                            f"db upgrade of {result_table_name}")

        inferred_from: List[str] = []
        depends_on: List[str] = []

        # this parameter depends on another parameter
        if layout_id in deps:
            setpoints = dependencies[layout_id]
            depends_on = [paramspecs[idp].name for idp in setpoints]

        if inferred_from_str != '':
            inferred_from = inferred_from_str.split(', ')

        paramspec = ParamSpec(name=name,
                              paramtype=paramtype,
                              label=label, unit=unit,
                              depends_on=depends_on,
                              inferred_from=inferred_from)
        paramspecs[layout_id] = paramspec

    return paramspecs
예제 #19
0
    def _extend_with_paramspec(self, ps: ParamSpec) -> 'InterDependencies_':
        """
        Create a new InterDependencies_ object extended with the provided
        ParamSpec. A helper function for DataSet's add_parameter function.
        Note that this function will only work as expected if the ParamSpecs
        are extended into the InterDependencies_ in the "logical order", i.e.
        independent ParamSpecs before dependent ones.
        """
        base_ps = ps.base_version()

        old_standalones = set(self.standalones.copy())
        new_standalones: Tuple[ParamSpecBase, ...]

        if len(ps.depends_on_) > 0:
            deps_list = [
                self._id_to_paramspec[name] for name in ps.depends_on_
            ]
            new_deps = {base_ps: tuple(deps_list)}
            old_standalones = old_standalones.difference(set(deps_list))
        else:
            new_deps = {}

        if len(ps.inferred_from_) > 0:
            inffs_list = [
                self._id_to_paramspec[name] for name in ps.inferred_from_
            ]
            new_inffs = {base_ps: tuple(inffs_list)}
            old_standalones = old_standalones.difference(set(inffs_list))
        else:
            new_inffs = {}

        if new_deps == new_inffs == {}:
            new_standalones = (base_ps, )
        else:
            old_standalones = old_standalones.difference({base_ps})
            new_standalones = ()

        new_deps.update(self.dependencies.copy())
        new_inffs.update(self.inferences.copy())
        new_standalones = tuple(list(new_standalones) + list(old_standalones))

        new_idps = InterDependencies_(dependencies=new_deps,
                                      inferences=new_inffs,
                                      standalones=new_standalones)

        return new_idps
예제 #20
0
def test_hash_with_deferred_and_inferred_as_paramspecs(paramspecs,
                                                       add_to_1_inf,
                                                       add_to_1_dep,
                                                       add_to_2_inf,
                                                       add_to_2_dep):
    """
    Test that hashing works if 'inferred_from' and/or 'depends_on' contain
    actual ParamSpec instances and not just strings.
    """
    assume(add_to_1_inf or add_to_1_dep or add_to_2_inf or add_to_2_dep)

    # Add ParamSpecs to 'inferred_from' and/or 'depend_on' lists next to
    # strings (that are generated by the main strategy)
    if add_to_1_inf:
        paramspecs[0]['inferred_from'].append(ParamSpec(**paramspecs[2]))
    if add_to_1_dep:
        paramspecs[0]['depends_on'].append(ParamSpec(**paramspecs[3]))
    if add_to_2_inf:
        paramspecs[1]['inferred_from'].append(ParamSpec(**paramspecs[4]))
    if add_to_2_dep:
        paramspecs[1]['depends_on'].append(ParamSpec(**paramspecs[5]))

    p1 = ParamSpec(**paramspecs[0])
    p2 = ParamSpec(**paramspecs[1])

    # call __hash__
    p1_h = hash(p1)
    p2_h = hash(p2)

    # make a set
    p_set = {p1, p2}

    # test that the hash equality follows object equality
    if p1 == p2:
        assert p1_h == p2_h
        assert 1 == len(p_set)
    else:
        assert p1_h != p2_h
        assert 2 == len(p_set)
예제 #21
0
def test_get_dependents(experiment):
    x = ParamSpec('x', 'numeric')
    t = ParamSpec('t', 'numeric')
    y = ParamSpec('y', 'numeric', depends_on=['x', 't'])

    # Make a dataset
    (_, run_id, _) = mut_queries.create_run(experiment.conn,
                                            experiment.exp_id,
                                            name='testrun',
                                            guid=generate_guid(),
                                            parameters=[x, t, y])

    deps = mut_queries._get_dependents(experiment.conn, run_id)

    layout_id = mut_queries._get_layout_id(experiment.conn, 'y', run_id)

    assert deps == [layout_id]

    # more parameters, more complicated dependencies

    x_raw = ParamSpec('x_raw', 'numeric')
    x_cooked = ParamSpec('x_cooked', 'numeric', inferred_from=['x_raw'])
    z = ParamSpec('z', 'numeric', depends_on=['x_cooked'])

    (_, run_id,
     _) = mut_queries.create_run(experiment.conn,
                                 experiment.exp_id,
                                 name='testrun',
                                 guid=generate_guid(),
                                 parameters=[x, t, x_raw, x_cooked, y, z])

    deps = mut_queries._get_dependents(experiment.conn, run_id)

    expected_deps = [
        mut_queries._get_layout_id(experiment.conn, 'y', run_id),
        mut_queries._get_layout_id(experiment.conn, 'z', run_id)
    ]

    assert deps == expected_deps
예제 #22
0
 def make_ps(n):
     ps = ParamSpec(f'p{n}',
                    label=f'Parameter {n}',
                    unit=f'unit {n}',
                    paramtype='numeric')
     return ps
예제 #23
0
def get_paramspec(conn: ConnectionPlus, run_id: int,
                  param_name: str) -> ParamSpec:
    """
    Get the ParamSpec object for the given parameter name
    in the given run

    Args:
        conn: Connection to the database
        run_id: The run id
        param_name: The name of the parameter
    """

    # get table name
    sql = f"""
    SELECT result_table_name FROM runs WHERE run_id = {run_id}
    """
    c = conn.execute(sql)
    result_table_name = one(c, 'result_table_name')

    # get the data type
    sql = f"""
    PRAGMA TABLE_INFO("{result_table_name}")
    """
    c = conn.execute(sql)
    for row in c.fetchall():
        if row['name'] == param_name:
            param_type = row['type']
            break

    # get everything else

    sql = f"""
    SELECT * FROM layouts
    WHERE parameter="{param_name}" and run_id={run_id}
    """
    c = conn.execute(sql)
    resp = many(c, 'layout_id', 'run_id', 'parameter', 'label', 'unit',
                'inferred_from')
    (layout_id, _, _, label, unit, inferred_from_string) = resp

    if inferred_from_string:
        inferred_from = inferred_from_string.split(', ')
    else:
        inferred_from = []

    deps = get_dependencies(conn, layout_id)
    depends_on: Optional[List[str]]
    if len(deps) == 0:
        depends_on = None
    else:
        dps: List[int] = [dp[0] for dp in deps]
        ax_nums: List[int] = [dp[1] for dp in deps]
        depends_on = []
        for _, dp in sorted(zip(ax_nums, dps)):
            sql = f"""
            SELECT parameter FROM layouts WHERE layout_id = {dp}
            """
            c = conn.execute(sql)
            depends_on.append(one(c, 'parameter'))

    parspec = ParamSpec(param_name, param_type, label, unit, inferred_from,
                        depends_on)
    return parspec
예제 #24
0
def test_from_dict(version_0_dicts, version_0_objects):
    for sdict, ps in zip(version_0_dicts, version_0_objects):
        deps = ParamSpec._from_dict(sdict)
        assert ps == deps