GithubHelp home page GithubHelp logo

labpy / lantz Goto Github PK

View Code? Open in Web Editor NEW
130.0 130.0 64.0 4.84 MB

Lantz is an automation and instrumentation toolkit with a clean, well-designed and consistent interface. It provides a core of commonly used functionalities for building applications that communicate with scientific instruments allowing rapid application prototyping, development and testing. Lantz benefits from Python’s extensive library flexibility as a glue language to wrap existing drivers and DLLs.

Home Page: http://lantz.readthedocs.org/

License: Other

Python 97.94% CSS 0.90% JavaScript 0.76% Shell 0.30% C 0.10%

lantz's People

Contributors

arnoques avatar caldarolamartin avatar crazyfermions avatar fedebarabas avatar florisla avatar gdavis-xilinx avatar hgrecco avatar jturner314 avatar lennart0901 avatar sfinucane avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lantz's Issues

error when value is a set and has unit

Hi,
I found another bug (I suspect). This time when using a Feat with values and unit keywords, when values is a set.

The following Feat results in the exception below:

@feat(values=set((50,60)), units='Hz')
def test(self):
return int(self.query('Ask:test?'))

If I remove the units='Hz' this works fine. This seems to be because a set of pint seems to convert the set not the values within the set. Exception below:

----> 1 p.lfrequency

/home/jschrod/Downloads/Python/Instrumentation/lantz/lantz/feat.py in get(self, instance, owner)
283
284 def get(self, instance, owner=None):
--> 285 return self.get(instance)
286
287 def set(self, instance, value):

/home/jschrod/Downloads/Python/Instrumentation/lantz/lantz/feat.py in get(self, instance, owner, key)
235 except Exception as e:
236 instance.log_error('While post-processing {} for {}: {}', value, name, e)
--> 237 raise e
238
239 instance.log_info('Got {} for {}', value, name, lantz_feat=(name, str(value)))

/home/jschrod/Downloads/Python/Instrumentation/lantz/lantz/feat.py in get(self, instance, owner, key)
232 instance.log_debug('(raw) Got {} for {}', value, name)
233 try:
--> 234 value = self.post_get(value, instance, key)
235 except Exception as e:
236 instance.log_error('While post-processing {} for {}: {}', value, name, e)

/home/jschrod/Downloads/Python/Instrumentation/lantz/lantz/feat.py in post_get(self, value, instance, key)
193 def post_get(self, value, instance=None, key=MISSING):
194 for processor in _dget(self.get_processors, instance, key):
--> 195 value = processor(value)
196 return value
197

/home/jschrod/Downloads/Python/Instrumentation/lantz/lantz/processors.py in _inner(value)
381
382 def _inner(value):
--> 383 if value not in container:
384 raise ValueError('{!r} not in {}'.format(value, container))
385 return value

TypeError: unhashable type: 'Quantity'

Error importing with colorama in Windows Python x64 3.3.3.0

When importing lantz with colorama installed I get the following error due to the broken colorama dependency. If I rename colorama so lantz doesn't load it everything is fine. As colorama doesn't seem it be in active development any longer this may be an issue for this project going forward.

Operating System: Windows 7 x64
Python Distribution: WinPython x64
Python Version: 3.3.3.0

Readline internal error
Traceback (most recent call last):
  File "C:\WinPython-64bit-3.3.3.0\python-3.3.3.amd64\lib\site-packages\pyreadline\console\console.py", line 768, in hook_wrapper_23
    res = ensure_str(readline_hook(prompt))
  File "C:\WinPython-64bit-3.3.3.0\python-3.3.3.amd64\lib\site-packages\pyreadline\rlmain.py", line 569, in readline
    self.readline_setup(prompt)
  File "C:\WinPython-64bit-3.3.3.0\python-3.3.3.amd64\lib\site-packages\pyreadline\rlmain.py", line 565, in readline_setup
    self._print_prompt()
  File "C:\WinPython-64bit-3.3.3.0\python-3.3.3.amd64\lib\site-packages\pyreadline\rlmain.py", line 466, in _print_prompt
    x, y = c.pos()
  File "C:\WinPython-64bit-3.3.3.0\python-3.3.3.amd64\lib\site-packages\pyreadline\console\console.py", line 261, in pos
    self.GetConsoleScreenBufferInfo(self.hout, byref(info))
ctypes.ArgumentError: argument 2: <class 'TypeError'>: expected LP_CONSOLE_SCREEN_BUFFER_INFO instance instead of pointer to CONSOLE_SCREEN_BUFFER_INFO

Import lantz issue pyqt

I use Anaconda 3.6 64 bit on windows, and I get the following error when I try to import lantz. Can you please help?

import lantz
Traceback (most recent call last):

File "", line 1, in
import lantz

File "C:\ProgramData\Anaconda3\lib\site-packages\lantz_init_.py", line 25, in
from .driver import Driver, Feat, DictFeat, Action, initialize_many, finalize_many

File "C:\ProgramData\Anaconda3\lib\site-packages\lantz\driver.py", line 19, in
from .utils.qt import MetaQObject, SuperQObject, QtCore

File "C:\ProgramData\Anaconda3\lib\site-packages\lantz\utils\qt.py", line 27, in
(QT_API, QT_API_PYSIDE, QT_API_PYQT, QT_MOCK))

RuntimeError: Invalid Qt API 'pyqt5', valid values are: 'pyside', 'pyqt', 'mock'

Error with logging, Style not defined

Using lantz 0.3 on Windows (Python 3.4.3 :: Anaconda 2.2.0 (32-bit).

When I try to use logging,

from lantz.log import log_to_screen, DEBUG
log_to_screen(DEBUG)

I get an error on every log print

--- Logging error ---
Traceback (most recent call last):
File "C:\Anaconda3\lib\logging__init__.py", line 978, in emit
msg = self.format(record)
File "C:\Anaconda3\lib\logging__init__.py", line 828, in format
return fmt.format(record)
File "C:\Anaconda3\lib\site-packages\lantz\log.py", line 148, in color_format
parts[0] = bef + self.colorize(dur, record) + aft
File "C:\Anaconda3\lib\site-packages\lantz\log.py", line 136, in colorize
return color + message + Style.RESET_ALL
NameError: name 'Style' is not defined
Call stack:
File "k2308.py", line 88, in
print(inst.output_enable[1])
File "C:\Anaconda3\lib\site-packages\lantz\driver.py", line 355, in exit
self.finalize()
File "C:\Anaconda3\lib\site-packages\lantz\messagebased.py", line 332, in fina
lize
super().finalize()
File "C:\Anaconda3\lib\site-packages\lantz\action.py", line 129, in call
instance.log_info('{} returned {}', name, out)
File "C:\Anaconda3\lib\site-packages\lantz\driver.py", line 304, in log_info
self.log(logging.INFO, msg, _args, *_kwargs)
File "C:\Anaconda3\lib\site-packages\lantz\driver.py", line 296, in log
logger.log(level, msg, *args, extra=self.log_extra)
Message: '{} returned {}'
Arguments: ('finalize', None)

If I import colorama manually, it imports fine, and Style is present.

Driver refresh() fails with DictFeats

This error occurs when trying to refresh() a driver with DictFeats:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.5/site-packages/lantz/feat.py", line 487, in __repr__
    return repr(self.df.value[self.instance])
  File "/usr/lib/python3.5/weakref.py", line 365, in __getitem__
    return self.data[ref(key)]
KeyError: <weakref at 0x7f6d12c9fa98; to 'DriverName' at 0x7f6d202fc558>

If I initialize all of the DictFeats (simply by reading from at least one key for each one), then everything works fine.

This modification to _DictFeatAccesor works around the problem, although I'm not sure if it is a good solution:

def __repr__(self):
    if self.instance in self.df.value.keys():
        return repr(self.df.value[self.instance])
    else:
        return ""

In case of DictFeat, DriverTestWidget.update_on_change() has no effect

Context: I ran start_test_app on an instance of a custom driver which contained a DictFeat and unchecked its "Update on change" checkbox. It had no effect on the behavior of the widget.

Probable origin: In case of a DictFeat, LabeledFeatWidget._widget is a DictFeatWidget, which doesn't have a value_to_feat method. As a result, when DriverTestWidget.update_on_change() runs widget._widget._update_on_change = new_state, the _update_on_change property of DictFeatWidget is updated instead of the _update_on_change property of DictFeatWidget._value_widget.

Probable fix: add an if isinstance(widget._widget, DictFeatWidget) statement to DriverTestWidget.update_on_change()

Proposed fix: rewrite DriverTestWidget.update_on_change() as

def update_on_change(self, new_state):
        """Set the 'update_on_change' flag to new_state in each writable widget
        within this widget. If True, the driver will be updated after each change.
        """

        for widget in self.writable_widgets:
            if isinstance(widget._widget, DictFeatWidget):
                widget._widget._value_widget._update_on_change = new_state
            else:
                widget._widget._update_on_change = new_state

VisaDriver fails without a library_path keyword

In package lance.visa, line 37
library_path = kwargs.get('library_path', None)
should be:
library_path = kwargs.get('library_path', '')
to conform with the default of the visa.ResourceManager.init().

Or, to be less brittle:
library_path = kwargs.get('library_path', None)
if library_path:
manager = visa.ResourceManager(library_path)
else:
manager = visa.ResourceManager()

Docstring of Feat/DictFeats with arguments

If you have a feat with an argument:

@feat(values={0: 1})
def feat(self):
"""doc""""
return

The docstring is not taken in account, as rebuild calls _dochelper.

Also the key of DictFeat is not taken into account.

Maybe rebuild should be called more often?

how to set path to visa driver

I am trying out Lantz, but it fails with a timeout when accessing my instrument.
When using pyvisa it works but I have to set the path to the visa driver in the resource manager. How do I tell Lantz which visa driver to use?

Or in other words: No documentation exists (or I cannot find it) to specify in Lantz the path to the driver that pyvisa should use.

TCPDriver MRO is broken

Here's my encounter (and the issue exposed therein):

>>> from lantz.drivers.examples import LantzSignalGeneratorTCP
>>> inst = LantzSignalGeneratorTCP('localhost', 5678)
>>> inst.initialize()
>>> print(inst.idn)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\WinPython-32bit-3.3.2.3\python-3.3.2\lib\site-packages\lantz\feat.py", line 303, in __get__
    return self.get(instance)
  File "C:\WinPython-32bit-3.3.2.3\python-3.3.2\lib\site-packages\lantz\feat.py", line 246, in get
    raise e
  File "C:\WinPython-32bit-3.3.2.3\python-3.3.2\lib\site-packages\lantz\feat.py", line 241, in get
    value = self.fget(instance)
  File "C:\WinPython-32bit-3.3.2.3\python-3.3.2\lib\site-packages\lantz\drivers\examples\fungen.py", line 36, in idn
    return self.query('?IDN')
  File "C:\WinPython-32bit-3.3.2.3\python-3.3.2\lib\site-packages\lantz\drivers\examples\fungen.py", line 29, in query
    answer = super().query(command, send_args=send_args, recv_args=recv_args)
  File "C:\WinPython-32bit-3.3.2.3\python-3.3.2\lib\site-packages\lantz\driver.py", line 561, in query
    self.send(command, *send_args)
  File "C:\WinPython-32bit-3.3.2.3\python-3.3.2\lib\site-packages\lantz\driver.py", line 513, in send
    return self.raw_send(message)
  File "C:\WinPython-32bit-3.3.2.3\python-3.3.2\lib\site-packages\lantz\driver.py", line 490, in raw_send
    raise NotImplemented
TypeError: exceptions must derive from BaseException

So... let's have a look at the MRO for inst:

>>> type(inst).mro()
[<class 'lantz.drivers.examples.fungen.LantzSignalGeneratorTCP'>, <class 'lantz.drivers.examples.fungen.LantzSignalGenerator'>, <class 'lantz.network.TCPDriver'>, <class 'lantz.driver.TextualMixin'>, <class 'lantz.network.TCPRawDriver'>, <class 'lantz.driver.Driver'>, <class 'object'>]

ahhhh... the more abstract TextualMixin comes before the more concrete TCPRawDriver. Let's look at the definition of TCPDriver:

lantz.network.TCPDriver

class TCPDriver(TextualMixin, TCPRawDriver):
...

The above code yields the broken MRO... to fix it, we can simply change it to the following:

class TCPDriver(TCPRawDriver, TextualMixin):
...

Now... let's give it another try:

>>> from lantz.drivers.examples import LantzSignalGeneratorTCP
>>> inst = LantzSignalGeneratorTCP('localhost', 5678)
>>> inst.initialize()
>>> print(inst.idn)
FunctionGenerator Serial #12345
>>> type(inst).mro()
[<class 'lantz.drivers.examples.fungen.LantzSignalGeneratorTCP'>, <class 'lantz.drivers.examples.fungen.LantzSignalGenerator'>, <class 'lantz.network.TCPDriver'>, <class 'lantz.network.TCPRawDriver'>, <class 'lantz.driver.Driver'>, <class 'lantz.driver.TextualMixin'>, <class 'object'>]
>>> inst.finalize()

Voila! :) Now... I would modify my fork and submit a pull request... BUT, I am still not sure if TextualMixin is in an appropriate position in the MRO. This does work for me for now, though. Please advise if there are any unforeseen repercussions from this modification!

nidaq driver is very rudimentary

The NIDaqmx driver to talk with daq cards from national instruments is not working. Some functions a written, but untested.

There are some nidaq wrappers written already, but non of them is running with python 3 out of the box.

I like pylibnidaq, because it has a more or less "high-leve" api; https://code.google.com/p/pylibnidaqmx/
I just made some adjustments to to source, so that this project runs on python3:
https://code.google.com/p/pylibnidaqmx/issues/detail?id=39

Can someone comment how we could implement this wrapper in the lantz framework? The cleanest solution would just be to import this module, however, I can imagine that in order to get is neatly in the lantz framework, some additional tweaks are necesary.

DriverTestWidget.widgets_values_as_dict() broken

Context: I ran start_test_app on an instance of a custom driver which contained a DictFeat and clicked its "Update" button. The following error occurred:

Traceback (most recent call last):

  File "C:\Anaconda3\lib\site-packages\lantz\ui\widgets.py", line 508, in <lambda>
    update.clicked.connect(lambda x: target.update(self.widgets_values_as_dict()))

  File "C:\Anaconda3\lib\site-packages\lantz\ui\widgets.py", line 585, in widgets_values_as_dict
    for widget in self.writable_widgets}

  File "C:\Anaconda3\lib\site-packages\lantz\ui\widgets.py", line 585, in <dictcomp>
    for widget in self.writable_widgets}

AttributeError: 'LabeledFeatWidget' object has no attribute '_feat'

Probable origin: LabeledFeatWidget object has no attribute _feat, as opposed to the MixinWidget it contains.

Probable fix: Refer to the widget contained in LabeledFeatWidget instead. Also in case of a DictFeatWidget, refer to its value_widget and change return dictionary values to dictionaries as suitable for a DictFeat.

Proposed fix: rewrite DriverTestWidget.widgets_values_as_dict() as

       def widgets_values_as_dict(self):
        """Return a dictionary mapping each writable feat name to the current
        value of the widget.
        """
       return ({widget._widget._value_widget._feat.name: 
                      {widget._widget._value_widget._feat_key:
                       widget._widget.value()}
                    for widget in self.writable_widgets} 
                   if isinstance(widget._widget, DictFeatWidget)
                   else {widget._widget._feat.name: widget._widget.value()
                            for widget in self.writable_widgets})

Create a driver with a different resource manager

I am trying to create a message based drivers using the pyvisa-py backend.
I am obviously missing something, somewhere.
How can I define the backend resource manager that will be used in lantz?

I tried to create a class for my driver something looking like:
class LantzSignalGenerator(MessageBasedDriver):
"""Lantz Signal Generator.
"""

DEFAULTS = {'ASRL': {'read_termination': '\n', 'baud_rate': 9600}}
__resource_manager = visa.ResourceManager("@py")

.....

and I have the error:
Traceback (most recent call last):
File "mydriver.py", line 20, in
inst = LantzSignalGenerator('ASRL/dev/ttyACM0::INSTR')
File "/home/bizarri/bin/miniconda3/lib/python3.4/site-packages/lantz/messagebased.py", line 299, in init
self.resource_manager = get_resource_manager()
File "/home/bizarri/bin/miniconda3/lib/python3.4/site-packages/lantz/messagebased.py", line 40, in get_resource_manager
_resource_manager = visa.ResourceManager()
File "/home/bizarri/bin/miniconda3/lib/python3.4/site-packages/pyvisa/highlevel.py", line 1488, in __new

visa_library = open_visa_library(visa_library)
File "/home/bizarri/bin/miniconda3/lib/python3.4/site-packages/pyvisa/highlevel.py", line 1460, in open_visa_library
return cls(argument)
File "/home/bizarri/bin/miniconda3/lib/python3.4/site-packages/pyvisa/highlevel.py", line 96, in new
raise OSError('Could not open VISA library:\n' + '\n'.join(errs))
OSError: Could not open VISA library:

That I interpret as the creation trying to find the "standard" ni backend (not installed).

When I directly changing the backend in Lantz messagebased.py file:

_resource_manager = None

_resource_manager = visa.ResourceManager("@py")

Everything works fine...

In the init of Lantz messagebased.py, it seems that the first thing done to look for the resource_manager via get_resource_manager()
self.__resource_manager = get_resource_manager()
Does it make sense??? Define like this, _resource_manager will always be None?
global _resource_manager
if _resource_manager is None:
_resource_manager = visa.ResourceManager()
return _resource_manager

I am certainly missing something trivial but unfortunately it is beyond my limited understanding of python.

Thanks in advance for your time and help.

Removing Qt from the core

Qt is used in the core for two things.

Threading to provide async methods:

With the recent appearance of asyncio, I do not longer think that this is the way to go. I think we should move to concurrent calls to provide the async method integrating with asyncio as much as possible. Therefore removing Qt is not a problem for this purpose.

Signals and Threading to move drivers

Qt Signals are used to implement the observer pattern. This is used to communicate the core with the gui, not within the core.
Related to Signals. Qt has the concept of thread affinity: each object belongs to a thread. When a signal is emitted, connected slots are executed in the thread of the receiver.

Notice that while the discussion now is for Qt, this is a requirement to make responsive applications with any GUI toolkit. So we need to solve it.

I see three options:
A Add the concept of thread affinity to Python objects and use a pure Python implementation of signals such as this. Then dispatch the calls to the thread of the object owning the registered method.

B Try to import Qt and fallback to a pure Python implementation. GUI apps are only viable when Qt is available.

We tried this in Lantz 0.2. The problem is that Qt Signals are class members that belong to an object (not to the class). This is done using a special metaclass. In addition, Qt Signals requires objects with a thread affinity. In summary: is not just deriving changing the Signal object but also the base class for driver.

C In Qt GUI apps drivers should be wrapped. The wrapper is basically a QtObject that provide a Signal for each Feat and then redirects everything to the wrapped object.

This could be done in several ways:

After driver instantiation:

osci = QtWrapper(MyDriver())

where QtWrapper is provided by the GUI layer to be used.

During driver instantiation in the __new__ method:

osci = MyDriver(gui='qt')

where the gui parameter is standard for all drivers and accepts a string that tells which GUI layer and therefore which Wrapper to use. This could be also done automatically for all drivers by calling at the beginning of your application:

lantz.set_gui('qt')

(when we switch to enaml, we just need that the lantz_enaml package exports its own wrapper)

My view:
A seems to be cleaner, but we will never reach the performance of GUI toolkits. Moreover, we might find problems interacting with them.
B is a mess. We tried and it leads to applications that are difficult to test because their base class changes depending on whether you use Qt or not.
Then we are left with C (in any of its implementations). This allows better testing but forbids the use of signals in applications without a GUI toolkit (I am fine with that)

opinions?

Unable to use lantz.ui.app.Frontend

I'm new to Lantz but I found its features to match the requirements of an experiment I'm currently working on. I'm basing most of my development on the tutorial. I've already written the drivers for my device and wanted to start building a GUI. For that, I started the rich-app tutorial. However, I immediately ran into an error after running the first piece of code:

# We import a helper function to start the app
from lantz.ui.app import start_gui_app

# The block consists of two parts the backend and the frontend
from lantz.ui.blocks import FeatScan, FeatScanUi

# An this you know already
from lantz.drivers.examples import LantzSignalGenerator

with LantzSignalGenerator('TCPIP::localhost::5678::SOCKET') as fungen:

    # Here we instantiate the backend setting 'frequency' as the Feat to scan
    # and specifying in which instrument
    app = FeatScan('frequency', instrument=fungen)

    # Now we use the helper to start the app.
    # It takes a Backend instance and a FrontEnd class
    start_gui_app(app, FeatScanUi)
Traceback (most recent call last):

  File "<ipython-input-14-d6e2c2282680>", line 1, in <module>
    runfile('C:/[...]/test.py', wdir='C:/[...]')

  File "C:\[...]\Anaconda\envs\py34\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 601, in runfile
    execfile(filename, namespace)

  File "C:\[...]\Anaconda\envs\py34\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 80, in execfile
    exec(compile(open(filename, 'rb').read(), filename, 'exec'), namespace)

  File "C:/[...]/Documents/JM/Santec TSL-510/PyControl/test.py", line 20, in <module>
    start_gui_app(app, FeatScanUi)

  File "C:\[...]\Anaconda\envs\py34\lib\site-packages\lantz\ui\app.py", line 242, in start_gui_app
    frontend = frontend_class(backend=backend)

  File "C:\[...]\Anaconda\envs\py34\lib\site-packages\lantz\ui\app.py", line 131, in __init__
    filename = os.path.dirname(inspect.getfile(cls))

  File "C:\[...]\Anaconda\envs\py34\lib\inspect.py", line 524, in getfile
    raise TypeError('{!r} is a built-in class'.format(object))

TypeError: <module 'builtins' (built-in)> is a built-in class

It seems the problem resides on a section of lantz.ui.app.Frontend:

class Frontend(QtGui.QMainWindow, metaclass=_FrontendType):

    frontends = {}

     # a declarative way to indicate the user interface file to use.
    gui = None

    # connect widgets to instruments using connect_setup
    auto_connect = True

    def __init__(self, parent=None, backend=None):
        super().__init__(parent)

        self._backend = None

        if self.gui:
            for cls in self.__class__.__mro__:
                filename = os.path.dirname(inspect.getfile(cls))       # <<<<<< This line!
                filename = os.path.join(filename, self.gui)
                if os.path.exists(filename):
                    logger.debug('{}: loading gui file {}'.format(self, filename))
                    self.widget = QtGui.loadUi(filename)
                    self.setCentralWidget(self.widget)
                    break
            else:
                raise ValueError('{}: loading gui file {}'.format(self, self.gui))

    # ...

The elements inside Frontend.__class__.__mro__ are:

(lantz.ui.app._FrontendType,
 PyQt4.QtCore.pyqtWrapperType,
 sip.wrappertype,
 type,
 object)

From this it seems the problem is when for cls in self.__class__.__mro__ goes through type and object. I think that since these two classes are built-ins, inspect.getfile(cls) raises the TypeError exception.
I'm not certain if this problem is specific to my system or if it is a general issue. Could it be an incompatibility between lantz and my current libraries? I'm using Python 3.4 and I think that I have every library up-to-date.

Exceptions in the Core

I think is a really good opportunity to think again the exception hierarchy in Lantz.

Right now we have the following errors:

  • InvalidCommand: The command send to the instrument was invalid.
  • LantzTimeoutError: A timeout occurred. Used to have a single error abstracting the differences in lower level libraries
  • InstrumentError: Generic error
  • NotSupportedError: The interface is not supported by this instrument

Maybe it could be reworked as
LantzError: Generic Error

And deriving from this:

  • InvalidCommand
  • TimeoutError
  • InterfaceNotSupported

Another question? Do we need to reraise pyvisa (or other libraries) exceptions?

Remote Network Instrument

This is more of a request of functionality to be added to Lantz more than an issue. There are certain old instruments that run on old and very specifically configured machines which more than one experiment uses. It would be great to be able to create a virtual lantz instrument on this machine and have all the other computers use it through network as if it is a TCPIP instrument.

For example look at Heerese's QTLab: https://github.com/heeres/qtlab

Loggers can't be modified

Once you add a logger ,e.g

lantz.log.log_to_screen(lantz.log.DEBUG)

there's no obvious way to take it out. This could be useful to have more detailed logging in one part of the application and a minimal one in others.

BTW, there's no documentation on loggers.

Cheers,
Pablo

inst.finalize() leaves device in remote mode (using "with inst ...")

(Is this a pull request?) Although I don't know if this something that can or should be fixed, when closing/disconnecting normally from a multimeter (specifically a Keithley 2100 DMM), i.e. not due to an error, the instrument is left in remote mode; when I rerun the script without manually placing the DMM back in "local" mode, it errors "-410 Query INTERRUPTED". If I manually return it to local made (by pressing a button on the front panel), repeated script executions work just the same. Is there a way to check if the instrument requires returning to local mode, and if so, sending the command before shutting everything down? If it can't be checked, is there an easy boolean that would be settable to enable this?

Thanks!

Merging Eapii in Lantz

I will list here all the things we need to do when merging Eapii in Lantz, we can discuss more specific points in other issues :

  • make Lantz base class free from Qt, and solve th issue of signal handling.
  • incorporate Eapii notions of Subsystem and Channel
  • move from Feature and Processors to Eapii IProperty system, while adding logging (do we need timing)

The previous two could nearly be handled backwards by integrating Lantz features into Eapii (I for one would find it easier, mainly would mean handling logging and update, refresh methods)

  • adapt Action to handle not using Processors (might tweak Eapii base meta class to handle it too)
  • if possible make a single signature init for subclass drivers (see Eapii)
  • split the ui part into its own package

Once all those core issues will be tackled we will be able to start porting drivers and adding new ones.

DictFeatWidget fails to initialize when keys are not explicitly set

Context: I ran start_test_app on an instance of a custom driver which contained DictFeats initialized without specifying a keys=() argument. The following error shows up:

Traceback (most recent call last):
  File "C:\Anaconda3\lib\site-packages\lantz\ui\widgets.py", line 528, in __init__
    feat_widget = LabeledFeatWidget(self, target, feat)
  File "C:\Anaconda3\lib\site-packages\lantz\ui\widgets.py", line 415, in __init__
    self._widget = DictFeatWidget(parent, target, feat)
  File "C:\Anaconda3\lib\site-packages\lantz\ui\widgets.py", line 340, in __init__
    wid.feat_key = self._keys[0]
AttributeError: 'DictFeatWidget' object has no attribute '_keys'

Probable origin: In that case, keys default to None so when the DictFeatWidget is created by start_test_app the _keys attribute is not set within the if feat.keys statement before wid.feat_key = self._keys[0] is run, leading to the error.

Probable fix: wid.feat_key = self._keys[0] should only be run when keys exist.

Proposed fix: rewrite DictFeatWidget.__init__ as

def __init__(self, parent, target, feat):
        super().__init__(parent)
        self._feat = feat

        layout = QtGui.QHBoxLayout(self)

        valwid = WidgetMixin.from_feat(feat)
        valwid.bind_feat(feat)
        valwid.lantz_target = target

        if feat.keys:
            keywid = QtGui.QComboBox()
            if isinstance(feat.keys, dict):
                self._keys = list(feat.keys.keys())
            else:
                self._keys = list(feat.keys)

            keywid .addItems([str(key) for key in self._keys])
            keywid .currentIndexChanged.connect(self._combobox_changed)

            valwid.feat_key = self._keys[0]
        else:
            keywid = QtGui.QLineEdit()
            keywid .textChanged.connect(self._lineedit_changed)

        layout.addWidget(keywid )
        self._key_widget = keywid 

        layout.addWidget(valwid )
        self._value_widget = valwid

In case of a DictFeat, LabeledFeatWidget._widget doesn't have a value_to_feat method and communication fails

Context: I ran start_test_app on an instance of a custom driver which contained a DictFeat and clicked on its set button. The following error shows up after closing the Test Panel:

Traceback (most recent call last):

  File "C:\Anaconda3\lib\site-packages\lantz\ui\widgets.py", line 470, in on_set_clicked
    self._widget.value_to_feat()

AttributeError: 'DictFeatWidget' object has no attribute 'value_to_feat'

Note that there is no runtime error since the value_to_feat method is never called (see Issue "In case of DictFeat, DriverTestWidget.update_on_change() has no effect").

Probable origin: In case of a DictFeat, LabeledFeatWidget._widget is a DictFeatWidget, which doesn't have a value_to_feat method.

Probable fix: add the value_to_feat method to DictFeatWidget

Proposed fix: add to DictFeatWidget

def value_to_feat(self):
        return self._value_widget.value_to_feat()

timeout and the TCPDriver

If I use an instrument 'inst' with the TCPDriver, inst.query('misspelled command') hangs.

The inst.TIMEOUT is not effective because the socket is blocking by default.

Would the proper thing to do be to:

  • control the socket timeout in the instrument class __init__
    • using a float timeout: self.socket.settimeout(my_value)
    • making the socket non-blocking: self.socket.settimeout(0)
  • do one of the above, but add it to the TCPDriver as a default
  • other?

I'm not sure which approach is more Lantz-ish. I could do a PR if modifying a Lantz class is advised.

VISA library path of simulated instrument

Hi,

I've set up a virtual environment for pythn 3.4.3 where I want to use Lantz. Given that I'm on a Debian-based distro right now, I can't trivially install the NI-VISA backend. Because of this, I've given pyvisa-py and pyvisa-sim a go. I'm going through the tutorials and I'm having problems understanding why I am getting an "OSError: Could not open VISA library." I've got to the point in the setup that if I launch in one terminal window:

lantz-sim fungen tcp

and then in another terminal I execute the script:

import visa
rm = visa.ResourceManager('@SiM')
rm.list_resources()

I get no output. I reckon this is good, because if do not launch "lantz-sim fungen tcp" I get the following error after execution of the script:

Traceback (most recent call last):
File "visa_test.py", line 3, in
rm = visa.ResourceManager()
File "/home/nomint/Documents/ProCon_FOSS/lantz_test/lib/python3.4/site-packages/pyvisa /highlevel.py", line 1488, in new
visa_library = open_visa_library(visa_library)
File "/home/nomint/Documents/ProCon_FOSS/lantz_test/lib/python3.4/site-packages/pyvisa /highlevel.py", line 1460, in open_visa_library
return cls(argument)
File "/home/nomint/Documents/ProCon_FOSS/lantz_test/lib/python3.4/site-packages/pyvisa/highlevel.py", line 96, in new
raise OSError('Could not open VISA library:\n' + '\n'.join(errs))
OSError: Could not open VISA library:

This makes sense to me. Yet, if I execute the following code found in the tutorials (with the funcgen simultaneously listening):

from lantz.drivers.examples import LantzSignalGenerator

inst = LantzSignalGenerator('TCPIP::localhost::5678::SOCKET')
inst.initialize()
print(inst.idn)
inst.finalize()

I get the error:
File "test_fungen.py", line 3, in
inst = LantzSignalGenerator('TCPIP::localhost::5678::SOCKET')
File "/home/nomint/Documents/ProCon_FOSS/lantz_test/lib/python3.4/site-packages/lantz/messagebased.py", line 296, in init
self.resource_manager = get_resource_manager()
File "/home/nomint/Documents/ProCon_FOSS/lantz_test/lib/python3.4/site-packages/lantz/messagebased.py", line 39, in get_resource_manager
_resource_manager = visa.ResourceManager()
File "/home/nomint/Documents/ProCon_FOSS/lantz_test/lib/python3.4/site-packages/pyvisa/highlevel.py", line 1488, in __new

visa_library = open_visa_library(visa_library)
File "/home/nomint/Documents/ProCon_FOSS/lantz_test/lib/python3.4/site-packages/pyvisa/highlevel.py", line 1460, in open_visa_library
return cls(argument)
File "/home/nomint/Documents/ProCon_FOSS/lantz_test/lib/python3.4/site-packages/pyvisa/highlevel.py", line 96, in new
raise OSError('Could not open VISA library:\n' + '\n'.join(errs))
OSError: Could not open VISA library:

I read the "configuring the NI backend" part of the docs, but I'm don't get how to apply that to my case. I have firstly no .pyvisarc file (I reckon I'd just have to create one à la .bashrc) and secondly (and most importantly) don't know where the libvisa is. I went through the pyvisa-py and pyvisa-sim folders and there are only py scripts, so dunno what I should point at. In the actual script there is no longer any '@SiM' argument, so I'm pretty lost right now.

I'd greatly appreciate any help. Looking heavily forward to trying out Lantz!

MRO issue with TCPDriver and QT

Having TCPRawDriver inherit from Driver and having TCPDriver inherit from TCPRawDriver and TextualMixin (in that order) appears to cause an ordering problem in the base-class hierarchy. When the SuperQObject.init() is called, the "super()" emulation winds up trying to call object.init() with _args and *_kwargs, which fails.

Having TCPRawDriver simply act as another mixin appears to solve the problem, requiring TCPDriver to inherit from (TCPRawDriver, TextualMixin, Driver).

Python2

I strongly need to use python2 instead of python3. Is there any possibilities to convert this code into python2 code?

feature request: Quantities in DictFeat

I have a device that returns the unit that is used in the device. This given as a number, and should be converted in a quatitity. I also can set this unit. The logical way would be to use a DictFeat. However, to do this one should make a dict, which does not work with Quantities objects:

    @DictFeat(values={Q_('encodercount'): 0,
                        Q_('motor step'): 1,
                        Q_('millimeter'): 2,
                        Q_('micrometer'): 3,
                        Q_('inches'): 4,
                        Q_('milli-inches'): 5,
                        Q_('micro-inches'): 6,
                        Q_('degree'): 7,
                        Q_('gradian'): 8,
                        Q_('radian'): 9,
                        Q_('milliradian'): 10,
                        Q_('microradian'): 11})
    def units(self):
        return self.parent.query('%SN?' % self.num)

    @units.setter
    def units(self, val):
        self.parent.send('%SN%' % (self.num, val))

Furthermore I want to use this unit as default unit for all my functions in my driver. Is there an easy somultion

ValueError: 'bytesize' is not a valid attribute for type SerialInstrument

Hi,
I'm using the lantz Cobolt0601 driver to control a laser. When using the legacy driver everything works fine. But when changing to the new driver using MessageBasedDriver instead of SerialDriver i get the above error when initializing the laser. If, however, I comment line 23 in Cobolt0601.py where the "bytesize = 8" is everything works fine again.

from lantz.drivers.cobolt.cobolt0601 import Cobolt0601

laser = Cobolt0601('COM10')
laser.initialize() #This line gives error

Is this some compatibility issue or a bug in the code?

Splitting Lantz

The proposal is to leave the current Lantz repo as it is by now and create 3 new repos in LabPy

(Please bikeshed the names of the repos. These names are important as they will become the names of independent packages on PyPI)

lantz_core:

  • action.py
  • errors.py
  • feat.py
  • foreign.py
  • log.py
  • messagebased.py
  • processors.py
  • stats.py

(+ corresponding tests and docs)

lantz_drivers

  • drivers/*

(But removing the legacy folder)
(+ corresponding tests and docs)

lantz_qt

  • ui/*
  • util/*

(+ corresponding tests and docs)

After the core is ready, a new package (lantz_enaml) will be created.

In the future and to help the user, a Lantz package that installs the core, drivers and qt/enaml will be created with a entry points to the docs.

EDIT: What to do with the simulators? Shall we include them in one of these packages or put them in a different one.

lantz import issues

Hello,
I'm new to lantz, not sure if I'm doing something wrong. I believe that I installed everything correctly, but I'm having issues when using the following code:

from lantz import Q_
from lantz import Feat, DictFeat

I get the same response shown below for both:
Traceback (most recent call last):
File "<pyshell#32>", line 1, in
from lantz import Q_
File "C:\Python34\lib\site-packages\lantz_init_.py", line 25, in
from .driver import Driver, Feat, DictFeat, Action, initialize_many, finalize_many
File "C:\Python34\lib\site-packages\lantz\driver.py", line 19, in
from .utils.qt import MetaQObject, SuperQObject, QtCore
File "C:\Python34\lib\site-packages\lantz\utils\qt.py", line 33, in
QtCore, QtGui, QtSvg, QT_API = load_qt(api_opts)
File "C:\Python34\lib\site-packages\lantz\utils\qt_loaders.py", line 364, in load_qt
if not can_import(api):
File "C:\Python34\lib\site-packages\lantz\utils\qt_loaders.py", line 172, in can_import
if not has_binding(api):
File "C:\Python34\lib\site-packages\lantz\utils\qt_loaders.py", line 146, in has_binding
return check_version(mod.version, '1.0.3')
AttributeError: 'module' object has no attribute 'version'

However, I don't get an error when I run this code:

from lantz.log import log_to_screen, DEBUG
log_to_screen(DEBUG)
<logging.Logger object at 0x04B0A9F0>

I appreciate any suggestions.

Thank you,

Interface to adjust inst.query_delay in Lantz driver.

I have left a lot of "Issues" here and in pyvisa (and pyvisa-py). Sorry about that, especially since it seems everyone here is pretty busy; I hope I don't seem unappreciative!

My latest issues is adjusting the delay between the read and write calls that query makes in the Lantz driver. Can this be "accessed" via Lantz? (In a straightforward way?) I've looked through the driver examples, and a fair amount of code here but have found nothing. I'm more of a hardware person, so that could be the reason, but I can usually figure software issues out as long as I don't have to "de-abstract" too much, and thus far my path as taken me all the way down to USBTMC piping (which is way over my level of expertise). Maybe more generally, how can pyvisa methods be extracted to be used in a Lantz driver (everything seems to rely on "query," which is instrument related, but the delay isn't...)?

Thanks again (again, again),

Traceback from lantz.ui.app.start_test_app

I've created a driver for an instrument with two DictFeat's and one Feat. The driver appears to work correctly when used from e.g. an IPython shell.

I'd hoped to be able to leverage the "start_test_app" functionality to auto-generate a simple GUI for the instrument. Unfortunately, I get the following traceback from start_test_app for each of the three features:

11:31:06 DEBUG Could not create control for actuations: class assignment: only for heap types
Traceback (most recent call last):
File "./lantz/ui/widgets.py", line 521, in init
feat_widget = LabeledFeatWidget(self, target, featproxy)
File "./lantz/ui/widgets.py", line 408, in init
self._widget = DictFeatWidget(parent, target, feat)
File "./lantz/ui/widgets.py", line 331, in init
wid = WidgetMixin.from_feat(feat)
File "./lantz/ui/widgets.py", line 281, in from_feat
cls.wrap(widget)
File "./lantz/ui/widgets.py", line 254, in wrap
cls._WRAPPERS.get(type(widget), cls)._wrap(widget)
File "./lantz/ui/widgets.py", line 934, in _wrap
super()._wrap(widget)
File "./lantz/ui/widgets.py", line 247, in _wrap
widget.class = cls
TypeError: class assignment: only for heap types

At the point the exception is raised, type(widget.class is 'PySide.QtGui.QLineEdit') and type(cls) is 'Shiboken.ObjectType', but that's about as far as I've gotten.

My QT environment is PySide atop QT 4.6; should I expect the "test_app" functionality to be working?

Foreign library with cdll instead of windll

I'm building a wrapper for the new Thorlabs Kinesis drivers using from lantz.foreign import LibraryDriver, and found that by default the class Library loads the dll as:

if os.name == 'nt':
    library = ctypes.WinDLL(library)

However, for some reason when I try to call a function, like CC_Open (this is device specific), I get the following error:

Exception: While calling CC_Open with [b'83843619'] (was (b'83843619',)): Procedure probably called with too many arguments (4 bytes in excess)

This is easily solved if i use library = ctypes.CDLL(library).

I imagine that it is not safe to assume the library loader based solely on the operating system, however I don't see a clear way of overriding it; the class Library is able to do so:

class Library(object):
    def __init__(self, library, prefix='', wrapper=None):
        if isinstance(library, str):

just by providing a library that is not a string (i.e. the library already loaded)
But the base class LibraryDriver iterates over names. I don't see a clear solution that wouldn't ruin downstream code.

usbtmc exception with resource busy

Hi,
I'm trying to write a driver for lantz using the usbtmc driver on ubuntu. I just can't seem to create the usb device. I always get a resource busy exception. Find below the traceback:

USBError Traceback (most recent call last)
in ()
----> 1 inst=usbtmc.USBTMCDriver(0x1313,0x8072)

/home/jschrod/Downloads/Python/Instrumentation/lantz/lantz/drivers/usbtmc.py in init(self, vendor, product, serial_number, **kwargs)
141 if self.usb_dev.is_kernel_driver_active(0):
142 self.usb_dev.detach_kernel_driver(0)
--> 143 self.usb_dev.set_configuration()
144
145 print("usbtmc init 7 ")

/home/jschrod/.virtualenvs/instrumctrl_p3/lib/python3.4/site-packages/usb/core.py in set_configuration(self, configuration)
587 the method without parameter is enough to get the device ready.
588 """
--> 589 self._ctx.managed_set_configuration(self, configuration)
590
591 def get_active_configuration(self):

/home/jschrod/.virtualenvs/instrumctrl_p3/lib/python3.4/site-packages/usb/core.py in managed_set_configuration(self, device, config)
90
91 self.managed_open()
---> 92 self.backend.set_configuration(self.handle, cfg.bConfigurationValue)
93
94 # cache the index instead of the object to avoid cyclic references

/home/jschrod/.virtualenvs/instrumctrl_p3/lib/python3.4/site-packages/usb/backend/libusb1.py in set_configuration(self, dev_handle, config_value)
722 @methodtrace(_logger)
723 def set_configuration(self, dev_handle, config_value):
--> 724 _check(self.lib.libusb_set_configuration(dev_handle.handle, config_value))
725
726 @methodtrace(_logger)

/home/jschrod/.virtualenvs/instrumctrl_p3/lib/python3.4/site-packages/usb/backend/libusb1.py in _check(retval)
552 if retval.value < 0:
553 ret = retval.value
--> 554 raise USBError(_str_error[ret], ret, _libusb_errno[ret])
555 return retval
556

USBError: [Errno 16] Resource busy

Note that the kernel driver lines (141,142) were put there by me to check if this is the problem. They did not have any effect.

When I use python-usbtmc from https://github.com/alexforencich/python-usbtmc
it works. I don't really understand why because it seems both codes are very similar (except for the kernel unloading). As a side note, is there a reason why you are not using python-usbtmc? It might be worth merging the two codebases for the usbtmc code.

More flexible Subsystems

The idea comes from the discussion in the python-ivi thread. When building complex instruments having to rebuild the driver hierarchy of subsystem can be tedious and counter productive. The idea would be to mark some Features as being part of a subsystem (how ? perhaps using a context manager in the declaration) and then let the metaclass build the hierarchy itself. Of course we should then provides way to access the hook of the feature directly from the class for subclassing. I think this would make subsystem more user friendly (even if a bit more magical).
This should all be possible but will make the metaclass handling a bit tougher.

@Action doesn't work with lists or tuples

Works
@action(values=set(('auto', '1p', '3p', '10p',)))
def ssa(self, value):
self.query('*ssa {}'.format(value))

Don't work
@action(values=('auto', '1p', '3p', '10p',))
def ssa(self, value):
self.query('*ssa {}'.format(value))

TypeError: MapProcessor argument must be a dict or a callable, not auto

This comes from processors.py>class MapProcessor as it test for dict or set, not list, not tuple.

But in action.py>class Action(object) on can read

:param values: A dictionary to values key to values.
If a list/tuple instead of a dict is given, the value is not
changed but only tested to belong to the container.

Archive repository and link to lantzproject/lantz

As this project has migrated to a new organization and has been inactive for 5 years, this project should be marked as inactive/deprecated in the settings (by archiving the repository). In addition, a comment should be added to the top of the README to notify users of the new project and redirect users to the currently maintained version of this project at https://github.com/lantzproject/lantz

This should similarly be done of the README on PyPI and by adding the Development Status :: 7 - Inactive classifier to the listing.

@hgrecco

Documentation Links Broken

I've just heard of Lantz. Really interested, but the documentation links seem to be either broken or pointing to downed servers. Any alternative sources?

USB to Serial devices

I am using several USB to serial devices. I want to recognize them before connecting (via pyvisa-py). To do that I use the following code:

def find_device_VISA(vid=None, pid=None, vendor=None, serial=None,
                    fmt='ASRL{}::INSTR'):
    '''Find a USB to serial converter and format VISA identifier'''
    tty = find_port.list_devices(vid=vid, pid=pid, vendor=vendor,
                                  serial=serial)[0][3]
    return fmt.format(tty)

Where find_port is in the package: https://github.com/vascotenner/usb-ser-mon/tree/package

Can Lantz provide a more familiar way? Should this be included in lantz? How?

Qt5 support

Currently, qt4 is not being abandoned at verious distributions. Is Lantz Qt5 ready? What should be done to achive this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.