pylablib.aux_libs.gui package¶
Subpackages¶
Submodules¶
pylablib.aux_libs.gui.device_thread module¶
-
class
pylablib.aux_libs.gui.device_thread.
DeviceThread
(name=None, devargs=None, devkwargs=None, signal_pool=None)[source]¶ Bases:
pylablib.core.gui.qt.thread.controller.QTaskThread
Expansion of
QTaskThread
equipped to deal with a single device.Parameters: - name – thread name
- devargs – args supplied to method
- devkwargs – keyword args supplied to method
- signal_pool –
SignalPool
for this thread (by default, use the default common pool)
-
device
¶ managed device. Its opening should be specified in an overloaded
connect_device()
method, and it is actually opened by callingopen_device()
method (which also handles status updates and duplicate opening issues)
-
qd
¶ device query accessor, which routes device method call through a command
ctl.qd.method(*args,**kwarg)
is equivalent toctl.device.method(args,kwargs)
called as a query in the device thread
-
qdi
¶ device query accessor, ignores and silences any exceptions (including missing /stopped controller); similar to
.qi
accessor for queries
- Methods to overload:
- setup_task: executed on the thread startup (between synchronization points
"start"
and"run"
) finalize_task: executed on thread cleanup (attempts to execute in any case, including exceptions); by default, close the device connection if it is opened connect_device: create the device class and assign it to.device
attribute; if connection failed, can leave the attributeNone
device_open: re-open currently closed device (by default, call.open
method of the device) device_close: close currently opened device (by default, call.close
method of the device) - Commands:
- open_device: open the device, if not already opened close_device: close the device, if opened get_settings: get device settings get_full_info: get full info of the device
-
finalize_task
()[source]¶ Finalize the thread (always called on thread termination, regardless of the reason)
-
connect_device
()[source]¶ Connect the device and assign it to the
self.device
attribute.Should be overloaded in subclasses. In case of connection error, can leave
self.device
asNone
, which symbolizes connection failure.
-
device_open
()[source]¶ Open the device which has been previously closed.
By default, call
.open
method of the device.
-
device_close
()[source]¶ Close the device which is currently opened.
By default, call
.close
method of the device.
-
open_device
()[source]¶ Open the device by calling
connect_device()
.Return
True
if connection was a success (or the device is already connected) andFalse
otherwise.
-
close_device
()[source]¶ Close the device.
Automatically called on the thread finalization, ususally shouldn’t be called explicitly.
-
setup_full_info_job
(period=2.0, nodes=None)[source]¶ Setup a job which periodically obtains full information (by calling
get_full_info
method) from the deviceUseful if obtaining settings takes a lot of time, and they might be needed by some other thread on a short notice.
Parameters: - period – job period
- node – specifies info nodes to be requested (by default, all available nodes)
-
update_full_info
()[source]¶ Update full info of the device.
A function for a job which is setup in
DeviceThread.setup_full_info_job()
. Normally doesn’t need to be called explicitly.
-
get_full_info
()[source]¶ Get full device info
If the full info job is set up using
DeviceThread.setup_full_info_job()
, use the last cached version of the full info; otherwise, request a new version from the device.
-
class
pylablib.aux_libs.gui.device_thread.
RemoteDeviceThread
(name=None, devargs=None, devkwargs=None, signal_pool=None)[source]¶ Bases:
pylablib.aux_libs.gui.device_thread.DeviceThread
Expansion of
DeviceThread
equipped to deal with a remote device (via RPyC library).All arguments, attributes and commands are the same as in
DeviceThread
.-
rpyc_device
(remote, module, device, *args, **kwargs)[source]¶ Create a remote device on a different PC via RPyC.
Can replace straightforward device creation for remote devices, i.e., instead of
self.device = DeviceModule.DeviceClass(*args,**kwargs)
one would callself.device = self.rpyc_device(host,"DeviceModule","DeviceClass",*args,**kwargs)
.Parameters: - remote – address of the remote host (it should be running RPyC server; see
rpyc.run_device_service()
for details) - module – device class module name
- device – device class name
- args – arguments supplied to the device constructor.
- kwargs – keyword arguments supplied to the device constructor.
- remote – address of the remote host (it should be running RPyC server; see
-
rpyc_obtain
(obj)[source]¶ Obtain (i.e., transfer to the local PC) an object returned by the device.
If current device is local, return obj as is.
-
finalize_task
()[source]¶ Finalize the thread (always called on thread termination, regardless of the reason)
-
update_full_info
()[source]¶ Update full info of the device.
A function for a job which is setup in
DeviceThread.setup_full_info_job()
. Normally doesn’t need to be called explicitly.
-
get_full_info
()[source]¶ Get full device info
If the full info job is set up using
DeviceThread.setup_full_info_job()
, use the last cached version of the full info; otherwise, request a new version from the device.
-
pylablib.aux_libs.gui.gui_contoller module¶
-
class
pylablib.aux_libs.gui.gui_contoller.
IGUIController
[source]¶ Bases:
sphinx.ext.autodoc.importer._MockObject
Basic layout of a controller object which coordinates interaction between different widgets working on the same task.
-
add_widget_desc
(name, params_path=None)[source]¶ Add a widget description under a given name.
If params_path` is not
None
, it specifies path under which the widget is stored in the parameters’ table (by default, same as the widget’s name).
-
set_widget
(name, widget)[source]¶ Set the widget with the given name.
Description with the given name should be created beforehand (see
add_widget_desc()
).
-
pylablib.aux_libs.gui.helpers module¶
-
class
pylablib.aux_libs.gui.helpers.
StreamFormerThread
(name=None, setupargs=None, setupkwargs=None, signal_pool=None)[source]¶ Bases:
pylablib.core.gui.qt.thread.controller.QTaskThread
Thread that combines data from different sources and aligns it in complete rows.
Channels can be added using
add_channel()
function. Every time the new row is complete, it is added to the current block. When the block is complete (determined byblock_period
attribute),on_new_block()
is called. Accumulated data can be accessed withget_data()
andpop_data()
.Parameters: - name – thread name
- devargs – args supplied to method
- devkwargs – keyword args supplied to method
- signal_pool –
SignalPool
for this thread (by default, use the default common pool)
-
block_period
¶ size of a row block which causes
on_new_block()
call
- Commands:
- get_data: get the completed aligned data pop_data: pop the completed aligned data (return the data and remove it from the internal storage) clear_table: clear the table with the completed aligned data clear_all: remove all data (table and all filled channels) configure_channel: configure a channel behavior (enable or disable) get_channel_status: get channel status (number of datapoints in the queue, maximal queue size, etc.) get_source_status: get lengths of signal queues for all the data sources
- Methods to overload:
setup()
: set up the threadcleanup()
: clean up the threadprepare_new_data()
: modify a new data chunk (dictionary of columns) before adding it to the storage
-
prepare_new_data
(columns)[source]¶ Prepare a newly acquired chunk.
column is a dictionary
{name: data}
of newly acquired data, wherename
is a channel name, anddata
is a list of one or more newly acquired values. Returned data should be in the same format. By default, no modifications are made.
-
finalize_task
()[source]¶ Finalize the thread (always called on thread termination, regardless of the reason)
-
class
ChannelQueue
(func=None, max_queue_len=1, required='auto', background=False, enabled=True, fill_on='started', latching=True, expand_list=False, pure_func=True, default=None)[source]¶ Bases:
object
Queue for a single channel.
Manages adding and updating new datapoints. For arguments, see
StreamFormerThread.add_channel()
.-
class
QueueStatus
(queue_len, enabled, max_queue_len)¶ Bases:
tuple
-
enabled
¶
-
max_queue_len
¶
-
queue_len
¶
-
-
add_from_func
(n=1)[source]¶ Fill the queue from the function (if available)
n specifies number of values to add.
-
class
-
add_channel
(name, func=None, max_queue_len=1, enabled=True, required='auto', background=False, fill_on='started', latching=True, expand_list=False, pure_func=True, default=None)[source]¶ Add a new channel to the queue.
Parameters: - name (str) – channel name
- func – function used to get the channel value if no data has been suppled
- max_queue_len (int) – maximal queue length
- enabled (bool) – determines if the channel is enabled by default (disabled channel always returns
None
) - required – determines if the channel is required to receive the value to complete the row;
by default,
False
if func is specified andTrue
otherwise - background – if
required==True
, determines whether receiving a new sample in this channel starts a new row (ifbackground==False
), or if it’s simply added; if all sample-receiving channels havebackground==True
, the func-defined channels will effectively be filled when the row is complete (corresponds tofill_on=="completed"
regardless of its actual value). - fill_on (str) – determines when func is called to get the channel value;
can be either
"started"
(when the new row is created) or"completed"
(when the new row is complete) - latching (bool) – determines value of non-required channel if func is not supplied;
if
True
, it is equal to the last received values; otherwise, it is default - expand_list (bool) – if
True
and the received value is list, assume that it contains several datapoints and add them sequentially (note that this would generally required setting max_queue_len>1, otherwise only the last received value will show up) - pure_func (bool) – if
True
, assume that fast consecutive calls to func return the same result, and the function has no side-effects (in this case, several consecutive calls to func are approximated by a single call result repeated necessary number of times) - default – default channel value
-
subscribe_source
(name, srcs, dsts='any', tags=None, parse=None, filt=None)[source]¶ Subscribe a source signal to a channels.
Called automatically for subscribed channels, so it is rarely called explicitly.
Parameters: - name (str) – channel name
- srcs (str or [str]) – signal source name or list of source names to filter the subscription;
can be
"any"
(any source) or"all"
(only signals specifically having"all"
as a source). - dsts (str or [str]) – signal destination name or list of destination names to filter the subscription;
can be
"any"
(any destination) or"all"
(only source specifically having"all"
as a destination). - tags – signal tag or list of tags to filter the subscription (any tag by default).
- parse – if not
None
, specifies a parsing function which takes 3 arguments (src, tag and value) and returns a dictionary{name: value}
of channel values to add (useful is a single signal contains multiple channel values, e.g., multiple daq channels) The function is called in the signal source thread, so it should be quick and non-blocking - filt (callable) – additional filter function which takes 4 arguments: signal source, signal destination, signal tag, signal value, and checks whether signal passes the requirements.
-
get_data
(nrows=None, columns=None, copy=True)[source]¶ Get accumulated data.
Parameters: - nrows – number of rows to get; by default, all complete rows
- columns – list of channel names to get; by default all channels
- copy (bool) – if
True
, return copy of the internal storage table (otherwise the returned data can increase in size).
Return dictionary
{name: [value]}
of channel value lists (all lists have the same length) if columns are not specified, or a 2D numpy array if the columns are specified.
-
pop_data
(nrows=None, columns=None)[source]¶ Pop accumulated data.
Same as
get_data()
, but removes the returned data from the internal storage.
-
configure_channel
(name, enable=True, required='auto', clear=True)[source]¶ Reconfigure existing channel.
Parameters: - name (str) – channel name
- enabled (bool) – determines if the channel is enabled by default (disabled channel always returns
None
) - required – determines if the channel is required to receive the value to complete the row;
by default,
False
if func is specified andTrue
otherwise - clear (bool) – if
True
, clear all channels after reconfiguring
-
class
pylablib.aux_libs.gui.helpers.
TableAccumulator
(channels, memsize=1000000)[source]¶ Bases:
object
Data accumulator which receives data chunks and adds them into a common table.
Can receive either list of columns, or dictionary of named columns; designed to work with
StreamFormerThread
.Parameters: -
class
ChannelData
(memsize, chunk_size=None)[source]¶ Bases:
object
Single channel data manager.
Manages the internal buffer to keep continuous list, but reduce number of list appends / removals.
-
add_data
(data)[source]¶ Add new data to the table.
Data can either be a list of columns, or a dictionary
{name: [data]}
with named columns.
-
change_channels
(channels)[source]¶ Change channels in the table.
All the accumulated data will be reset.
-
get_data_columns
(channels=None, maxlen=None)[source]¶ Get table data as a list of columns.
Parameters: - channels – list of channels to get; all channels by default
- maxlen – maximal column length (if stored length is larger, return last maxlen rows)
-
class
-
class
pylablib.aux_libs.gui.helpers.
TableAccumulatorThread
(name=None, setupargs=None, setupkwargs=None, signal_pool=None)[source]¶ Bases:
pylablib.core.gui.qt.thread.controller.QTaskThread
Table accumulator thread which provides async access to
TableAccumulator
instance.Parameters: - channels ([str]) – channel names
- data_source (str) – source thread which emits new data signals (typically, a name of
StreamFormerThread
thread) - memsize (int) – maximal number of rows to store
-
setup_task
(channels, data_source, memsize=1000000)[source]¶ Setup the thread (called before the main task loop)
-
start_streaming
(path, source_trigger=False, append=False)[source]¶ Start streaming data to the disk.
Parameters:
-
get_data_sync
(channels=None, maxlen=None, fmt='rows')[source]¶ Get accumulated table data.
Parameters: - channels – list of channels to get; all channels by default
- maxlen – maximal column length (if stored length is larger, return last maxlen rows)
- fmt (str) – return format; can be
"rows"
(list of rows),"columns"
(list of columns), or"dict"
(dictionary of named columns)
pylablib.aux_libs.gui.script_thread module¶
-
exception
pylablib.aux_libs.gui.script_thread.
ScriptStopException
[source]¶ Bases:
Exception
Exception for stopping script execution
-
class
pylablib.aux_libs.gui.script_thread.
ScriptThread
(name=None, setupargs=None, setupkwargs=None, signal_pool=None)[source]¶ Bases:
pylablib.core.gui.qt.thread.controller.QTaskThread
A script thread.
Designed to provide means of writing code which interacts with multiple device threads, but reads similar to a standard single-threaded script. To do that, it provides a mechanism of signal montors: one can suspend execution until a signal with certain properties has been received. This can be used to implement, e.g., waiting until the next stream_format/daq sample or a next camera frame.
Parameters: - name (str) – thread name
- setupargs – args supplied to method
- setupkwargs – keyword args supplied to method
- signal_pool –
SignalPool
for this thread (by default, use the default common pool)
-
executing
¶ shows whether the script is executing right now; useful in
interrupt_script()
to check whether it is while the script is running and is done / stopped by user / terminated (then it would beTrue
), or if the script was waiting to be executed / done executing (then it would beFalse
) Duplicatesinterrupt_reason
attribute (executing==False
if and only ifinterrupt_reason=="shutdown"
)Type: bool
-
stop_request
¶ shows whether stop has been requested from another thread (by calling
stop_execution()
).Type: bool
-
interrupt_reason
¶ shows the reason for calling
interrupt_script()
; can be"done"
(called in the end of regularly executed script),"stopped"
(called if the script is forcibly stopped),"failed"
(called if the thread is shut down while the script is active, e.g., due to error in the script or any other thread, or if the application is closing), or"shutdown"
(called when the script is shut down while being inactive)Type: str
- Methods to overload:
- setup_script: executed on the thread startup (between synchronization points
"start"
and"run"
) finalize_script: executed on thread cleanup (attempts to execute in any case, including exceptions); by default, callinterrupt_script()
run_script: execute the script (can be run several times per script lifetime) interrupt_script: executed when the script is finished or forcibly shut down (including due to exception or application shutdown)
-
process_message
(tag, value)[source]¶ Process a new message.
If the function returns
False
, the message is put in the corresponding queue. Otherwise, the the message is considered to be already, and it gets ‘absorbed’.
-
finalize_script
()[source]¶ Finalize script thread (to be overloaded in subclasses)
By default, calls
interrupt_script()
.
-
interrupt_script
(kind='default')[source]¶ Finalize script execution (the thread is still running, i.e., the script might be started again)
-
check_stop
(check_messages=True)[source]¶ Check if the script stop is requested.
If it is, raise
ScriptStopException
which effectively stops execution past this point (the exception is properly caught and processed elsewhere in the service code). To only check if the stop has been requested without exception raising, usestop_request
attribute. Ifcheck_messages==True
, check for new messages from other threads first.
-
finalize_task
()[source]¶ Finalize the thread (always called on thread termination, regardless of the reason)
-
add_signal_monitor
(mon, srcs='any', dsts='any', tags=None, filt=None)[source]¶ Add a new signal monitor.
The monitoring isn’t started until
start_monitoring()
is called. mon specifies monitor name; the rest of the arguments are the same asSignalPool.subscribe()
-
wait_for_signal_monitor
(mons, timeout=None)[source]¶ Wait for a signal to be received on a given monitor or several monitors
If several monitors are given (mon is a list), wait for a signal on any of them. After waiting is done, pop and return signal value (see
pop_monitored_signal()
).