Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ManualParameter and tests #39

Merged
merged 6 commits into from
Feb 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
17 changes: 9 additions & 8 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 All @@ -63,7 +64,7 @@ def add_function(self, name, **kwargs):
'''
if name in self.functions:
raise KeyError('Duplicate function name {}'.format(name))
self.functions[name] = Function(self, name, **kwargs)
self.functions[name] = Function(name=name, instrument=self, **kwargs)

def snapshot_base(self, update=False):
if update:
Expand Down
83 changes: 45 additions & 38 deletions qcodes/instrument/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,45 @@


class Function(Metadatable):
def __init__(self, instrument, name, call_cmd=None, async_call_cmd=None,
'''
defines a function (with arbitrary parameters) that this instrument
can execute.

You execute this function object like a normal function, or use its
.call method; or call it async with the .call_async method.

name: the local name of this parameter
instrument: an instrument that handles this function
default None

call_cmd: command to execute on instrument
- a string (with positional fields to .format, "{}" or "{0}" etc)
you can only use a string if an instrument is provided,
this string will be passed to instrument.write
- a function (with parameter count matching parameters list)
async_call_cmd: an async function to use for call_async, or for both
sync and async if call_cmd is missing or None.

parameters: list of Validator objects,
one for each parameter to the Function

parameter_parser: function to transform the input parameter(s)
to encoded value(s) sent to the instrument.
If there are multiple arguments, this function should accept all
the arguments in order, and return a tuple of values.
return_parser: function to transform the response from the instrument
to the final output value.
may be a type casting function like `int` or `float`.
If None (default), will not wait for or read any response
NOTE: parsers only apply if call_cmd is a string. The function forms
of call_cmd and async_call_cmd should do their own parsing.

parse_function: DEPRECATED - use return_parser instead
'''
def __init__(self, name, instrument=None,
call_cmd=None, async_call_cmd=None,
parameters=[], parameter_parser=None, return_parser=None,
parse_function=None, **kwargs):
'''
defines a function (with arbitrary parameters) that this instrument
can execute.

You execute this function object like a normal function, or use its
.call method; or call it async with the .call_async method.

instrument: an instrument that handles this function
name: the local name of this parameter

call_cmd: command to execute on instrument
- a string (with positional fields to .format, "{}" or "{0}" etc)
- a function (with parameter count matching parameters list)
async_call_cmd: an async function to use for call_async, or for both
sync and async if call_cmd is missing or None.

parameters: list of Validator objects,
one for each parameter to the Function

parameter_parser: function to transform the input parameter(s)
to encoded value(s) sent to the instrument.
If there are multiple arguments, this function should accept all
the arguments in order, and return a tuple of values.
return_parser: function to transform the response from the instrument
to the final output value.
may be a type casting function like `int` or `float`.
If None (default), will not wait for or read any response
NOTE: parsers only apply if call_cmd is a string. The function forms
of call_cmd and async_call_cmd should do their own parsing.

parse_function: DEPRECATED - use return_parser instead
'''
super().__init__(**kwargs)

self._instrument = instrument
Expand All @@ -63,11 +67,14 @@ def _set_params(self, parameters):

def _set_call(self, call_cmd, async_call_cmd,
parameter_parser, return_parser):
ask_or_write = self._instrument.write
ask_or_write_async = self._instrument.write_async
if isinstance(call_cmd, str) and return_parser:
ask_or_write = self._instrument.ask
ask_or_write_async = self._instrument.ask_async
if self._instrument:
ask_or_write = self._instrument.write
ask_or_write_async = self._instrument.write_async
if isinstance(call_cmd, str) and return_parser:
ask_or_write = self._instrument.ask
ask_or_write_async = self._instrument.ask_async
else:
ask_or_write, ask_or_write_async = None, None

self._call, self._call_async = syncable_command(
param_count=self._param_count,
Expand Down
Loading