Skip to content

Commit

Permalink
InstrumentParameter -> StandardParameter, instrument is optional
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcjohnson committed Feb 22, 2016
1 parent e396059 commit c73f8c5
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 20 deletions.
4 changes: 2 additions & 2 deletions docs/objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Normal text the container includes and uses this object

- Station
- Instrument: IPInstrument, VisaInstrument, MockInstrument
- **Parameter**: InstrumentParameter
- **Parameter**: StandardParameter
- Validator: Anything, Strings, Numbers, Ints, Enum, MultiType
- **SweepValues**: SweepFixedValues, AdaptiveSweep
- Function
Expand Down Expand Up @@ -50,7 +50,7 @@ a serialized communication channel with an apparatus.
A representation of one particular state variable.

Most `Parameter`s are part of an `Instrument`, using the subclass
`InstrumentParameter` which links it to specific commands sent to a specific
`StandardParameter` which links it to specific commands sent to a specific
instrument. But you can also create `Parameter`s that execute arbitrary functions,
for example to combine several gate voltages in a diagonal sweep. Parameters can
have setters and/or getters (they must define at least a setter OR a getter but
Expand Down
2 changes: 1 addition & 1 deletion qcodes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@
from qcodes.instrument.mock import MockInstrument

from qcodes.instrument.function import Function
from qcodes.instrument.parameter import Parameter, InstrumentParameter
from qcodes.instrument.parameter import Parameter, StandardParameter
from qcodes.instrument.sweep_values import SweepFixedValues, AdaptiveSweep
15 changes: 8 additions & 7 deletions qcodes/instrument/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from qcodes.utils.metadata import Metadatable
from qcodes.utils.sync_async import wait_for_async
from qcodes.utils.helpers import DelegateAttributes
from .parameter import InstrumentParameter
from .parameter import StandardParameter
from .function import Function


Expand All @@ -20,30 +20,31 @@ def __init__(self, name, **kwargs):
# anyway threading.Lock is unpicklable on Windows
# self.lock = threading.Lock()

def add_parameter(self, name, parameter_class=InstrumentParameter,
def add_parameter(self, name, parameter_class=StandardParameter,
**kwargs):
'''
binds one InstrumentParameter to this instrument.
binds one Parameter to this instrument.
instrument subclasses can call this repeatedly in their __init__
for every real parameter of the instrument.
In this sense, parameters are the state variables of the instrument,
anything the user can set and/or get
`name` is how the InstrumentParameter will be stored within
`name` is how the Parameter will be stored within
instrument.parameters and also how you address it using the
shortcut methods:
instrument.set(param_name, value) etc.
`parameter_class` can be used to construct the parameter out of
something other than InstrumentParameter
something other than StandardParameter
kwargs: see InstrumentParameter (or `parameter_class`)
kwargs: see StandardParameter (or `parameter_class`)
'''
if name in self.parameters:
raise KeyError('Duplicate parameter name {}'.format(name))
self.parameters[name] = parameter_class(self, name, **kwargs)
self.parameters[name] = parameter_class(name=name, instrument=self,
**kwargs)

def add_function(self, name, **kwargs):
'''
Expand Down
22 changes: 12 additions & 10 deletions qcodes/instrument/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,13 @@ def __getitem__(self, keys):
return SweepFixedValues(self, keys)


class InstrumentParameter(Parameter):
class StandardParameter(Parameter):
'''
defines one measurement parameter
instrument: an instrument that handles this parameter
name: the local name of this parameter
instrument: an instrument that handles this parameter
default None
get_cmd: a string or function to get this parameter
async_get_cmd: a function to use for async get, or for both sync
Expand Down Expand Up @@ -221,7 +222,7 @@ class InstrumentParameter(Parameter):
max_val_age: max time (in seconds) to trust a saved value from
this parameter as the starting point of a sweep
'''
def __init__(self, instrument, name,
def __init__(self, name, instrument=None,
get_cmd=None, async_get_cmd=None, get_parser=None,
parse_function=None, val_mapping=None,
set_cmd=None, async_set_cmd=None, set_parser=None,
Expand Down Expand Up @@ -295,8 +296,8 @@ def get_async(self):
def _set_get(self, get_cmd, async_get_cmd, get_parser):
self._get, self._get_async = syncable_command(
param_count=0, cmd=get_cmd, acmd=async_get_cmd,
exec_str=self._instrument.ask,
aexec_str=self._instrument.ask_async,
exec_str=self._instrument.ask if self._instrument else None,
aexec_str=self._instrument.ask_async if self._instrument else None,

This comment has been minimized.

Copy link
@alexcjohnson

alexcjohnson Feb 22, 2016

Author Contributor

@damazter this (and the same below) is all we need to make instrument optional. I should add a usage note though that without an instrument you can't use the string forms of get_cmd and set_cmd...

This comment has been minimized.

Copy link
@AdriaanRol

AdriaanRol Feb 22, 2016

Contributor

@alexcjohnson, or you could make it throw an exception if someone attempts to do that when instr is None

This comment has been minimized.

Copy link
@alexcjohnson

alexcjohnson Feb 22, 2016

Author Contributor

I think it does - looks like it's going to be an obtuse NoCommandError('not enough information to construct this command') though, perhaps I can emit something more helpful...

output_parser=get_parser, no_cmd_function=no_func)

if self._get is not no_func:
Expand All @@ -307,8 +308,9 @@ def _set_set(self, set_cmd, async_set_cmd, set_parser):
# in self.set_sweep, when we choose a swept or non-swept setter.
self._set, self._set_async = syncable_command(
param_count=1, cmd=set_cmd, acmd=async_set_cmd,
exec_str=self._instrument.write,
aexec_str=self._instrument.write_async,
exec_str=self._instrument.write if self._instrument else None,
aexec_str=(self._instrument.write_async if self._instrument
else None),
input_parser=set_parser, no_cmd_function=no_func)

if self._set is not no_func:
Expand Down Expand Up @@ -424,17 +426,17 @@ class ManualParameter(Parameter):
'''
defines one parameter that reflects a manual setting / configuration
name: the local name of this parameter
instrument: the instrument this applies to. Not actually used for
anything, just required so this class can be used with
Instrument.add_parameter(name, parameter_class=ManualParameter)
name: the local name of this parameter
initial_value: optional starting value. Default is None, which is the
only invalid value allowed (and None is only allowed as an initial
value, it cannot be set later)
'''
def __init__(self, instrument, name, initial_value=None, **kwargs):
def __init__(self, name, instrument=None, initial_value=None, **kwargs):
super().__init__(name=name, **kwargs)
if initial_value is not None:
self.validate(initial_value)
Expand Down

0 comments on commit c73f8c5

Please sign in to comment.