Fork PyRPL on GitHub

Source code for pyrpl.software_modules.module_managers

"""
Module managers are lightweight software modules that manage the access to
hardware modules. For example, to use the scope:

.. code:: python

     HOSTNAME = "192.168.1.100"
     from pyrpl import Pyrpl
     p = Pyrpl(hostname=HOSTNAME)

     # directly accessing the scope will not *reserve* it
     scope = p.rp.scope
     print(scope.owner)
     scope.duration = 1.

     # using the scope manager changes its ownership
     with p.scopes.pop('username') as scope:
        print(scope.owner)
        scope.duration =0.01
        print(scope.duration)
     # The scope is freed (and reset to its previous state) after the with
     # construct
     print(scope.owner)
     print(scope.duration)

In case several identical modules are available on the FPGA, the first one (
starting from the end of the list) is returned by the module manager:

.. code:: python

     HOSTNAME = "192.168.1.100"
     from pyrpl import Pyrpl
     p = Pyrpl(hostname=HOSTNAME)

     # directly accessing the scope will not *reserve* it
     pid2 = p.rp.pid2
     pid2.owner = 'foo'

     # Pid manager returns the first free pid module (in decreasing order)
     with p.pids.pop('username') as pid:
        print("pid0's owner: ", p.rp.pid0.owner)
        print("pid1's owner: ", p.rp.pid1.owner)
        print("pid2's owner: ", p.rp.pid2.owner)
     print("pid0's owner: ", p.rp.pid0.owner)
     print("pid1's owner: ", p.rp.pid1.owner)
     print("pid2's owner: ", p.rp.pid2.owner)


"""

import logging
logger = logging.getLogger(name=__name__)
from ..widgets.module_widgets import ModuleManagerWidget, AsgManagerWidget, PidManagerWidget, IqManagerWidget, \
    ScopeManagerWidget, IirManagerWidget
from ..modules import Module


[docs]class InsufficientResourceError(ValueError): """ This exception is raised when trying to pop a module while there is none left. """ pass
[docs]class ModuleManager(Module): """ Manages access to hardware modules. It is created from a list of hardware_modules to manage. For HardwareModules, ti is the manager module that is actually displayed in the gui. provides the following functions: - pop(owner): gives the last module in the list that is currently available, and locks it with the string "user" as owner of the hardware module - free(module): frees the module by reseting its user to None. (and enabling back its gui if any). """ _widget_class = ModuleManagerWidget _reserved_modules = [] # list-of # _int with instrument index that should # NOT be available via pop() @property def hardware_module_names(self): """ Looks in RedPitaya.modules to find how many modules are present. :return: list of all module names in redpitaya instance with a name looking like: - some_module - or some_module1, some_module2, some_module3 ... """ return [key for key in self.pyrpl.rp.modules.keys() if key[ :-1]==self.name[:-1] or key==self.name[:-1]] def __init__(self, parent, name=None): super(ModuleManager, self).__init__(parent, name=name) self.all_modules = [getattr(self.pyrpl.rp, name) for name in self.hardware_module_names]
[docs] def pop(self, owner=None): """ returns the first available module (starting from the end of the list) :param owner: (string): name of the module that is reserving the resource leave None if the gui shouldn't be disabled. If no available module left, returns None. To make sure the module will be freed afterwards, use the context manager construct: with pyrpl.mod_mag.pop('owner') as mod: mod.do_something() # module automatically freed at this point """ n = len(self.all_modules) for index in range(n): index = n - index - 1 # count backwards to reserve last module 1st if not index in self._reserved_modules: module = self.all_modules[index] if module.owner is None: module.owner = owner # this changes the module's visibility return module raise InsufficientResourceError('No more ' + self.name + ' left.')
[docs] def free(self, module): if module.owner is not None: module.owner = None
[docs] def n_modules(self): """ returns the total number of modules """ return len(self.all_modules)
[docs] def n_available(self): """ returns the number of modules still available """ total = 0 for index, module in enumerate(self.all_modules): # start with if not index in self._reserved_modules: if module.owner is None: total += 1 return total
@property def c(self): # no config file section for ModuleManagers # otherwise, empty sections such as iqss->iqs would be created return None
[docs]class Asgs(ModuleManager): _widget_class = AsgManagerWidget
[docs]class Pids(ModuleManager): _widget_class = PidManagerWidget
[docs]class Iqs(ModuleManager): _widget_class = IqManagerWidget _reserved_modules = [2] # iq2 is reserved for spectrum_analyzer
[docs]class Scopes(ModuleManager): """ Only one scope, but it should be protected by the slave/owner mechanism. """ _widget_class = ScopeManagerWidget
[docs]class Iirs(ModuleManager): """ Only one iir, but it should be protected by the slave/owner mechanism. """ _widget_class = IirManagerWidget
[docs]class Trigs(ModuleManager): """ Only one trig, but it should be protected by the slave/owner mechanism. """ pass #_widget_class = IirManagerWidget