Python utilities

Data file handling

qmt.Struct([data])

Wrapper around a Python dict that makes it behave similar to Matlab structs, including support for .mat files.

qmt.toJson(obj[, method, indent, sort_keys])

Versatile and fast json-encoding function that can handle numpy array and qmt.Struct.

Plotting

qmt.setupDebugPlots([mode, filename, ...])

Sets up how debug plots are created when functions are called with plot=True.

qmt.extendXlim(ax[, left, right])

Extends xlim of matplotlib axes.

qmt.extendYlim(ax[, bottom, top])

Extends ylim of matplotlib axes.

Webapp framework

qmt.Webapp([path, config, data, show, quiet])

Runs webapps.

qmt.AbstractDataSource(Ts)

Base class for all data source classes used in the qmt.Webapp online data processing loop.

qmt.ProcessDataSource(target, Ts, *args[, ...])

This data source runs a function in a separate process using the multiprocessing module and allows for the integration of blocking processing code (e.g., simulations) that does not work well in combination with async code.

qmt.ProcessDataSourceConnection(pipe)

Helper for qmt.ProcessDataSource.

qmt.WebappProcessConnection(webapp)

Helper for Webapp.runInProcess().

qmt.ClockDataSource(Ts)

This data sources generates samples at a fixed interval, containing only the time.

qmt.PlaybackDataSource(data)

Data source that generates samples from recorded/generated data similar to the playback mode in webapps.

qmt.DummyImuDataSource(Ts[, N])

Data source that generates fake IMU data.

qmt.dataSourceFromJson(jsonString[, ...])

Create a data source object from a JSON object containing the class name and parameters.

Matlab interface

qmt.matlab

Global object that provides access to Matlab.

qmt.utils.transplant.MatlabWrapper

Provides access to the qmt Matlab functions.

Data synchronization

qmt.SyncMapper(syncInfo)

Converts timestamps and indices for different data streams based on specified time/index mappings.

Other utilities

qmt.parallel(items[, ordered, workers, ...])

Simple utility to perform parallel processing.

qmt.setDefaults(params, defaults[, ...])

Helper function to facilitate handling of multiple optional parameters that are passed in a dictionary.

qmt.startStopInd(booleanArray)

Determines start and end indices of true phases in a boolean array.

Data file handling

class qmt.Struct(data=None, **kwargs)[source]

Wrapper around a Python dict that makes it behave similar to Matlab structs, including support for .mat files.

Dots are used as separators to easily create and access nested structures:

data = Struct()
data['foo.bar.baz'] = 42

Creates a new Struct object.

Parameters:
  • data – dict, list, other Struct or any data type that can be converted to a dict

  • kwargs – kwargs passed to the dict constuctor

allKeys()[source]

Returns all valid keys, including the leaf elements but also all intermediate Structs.

Returns:

iterable

createArrays()[source]

Turn all lists that only contain numbers into numpy arrays.

property data

Provides access to the underlying dict (or in some special cases list) object holding the actual data.

Returns:

dict (or list)

diff(ref, exact=False, rtol=1e-07, atol=0, verbose=False, plot=False)[source]

Print differences between this struct and another given struct.

Parameters:
  • ref – other Struct object

  • exact – if set to true, rtol and atol are set to zero

  • rtol – relative tolerance for comparing numpy arrays (with np.testing.assert_allclose)

  • atol – absolute tolerance for comparing numpy arrays (with np.testing.assert_allclose)

  • verbose – enables printing of more detailed output

  • plot – if set to True, a plot is created for all numpy arrays that have the same shape but different data

Returns:

None

get(key, default=None)[source]

Gets an item by key and returns a default value if the item does not exist.

Parameters:
  • key – the key to look up

  • default – default value to return if item does not exist

Returns:

self[key] or default

keys()[source]

Returns the top-level keys.

Returns:

iterable

leafKeys()[source]

Returns the keys of all leaf elements, i.e. all entries that are not Structs but hold actual data.

Returns:

iterable

classmethod load(filename, squeeze=True, verify=True)[source]

Loads a mat/json/yaml file into a new Struct object.

Parameters:
  • filename – filename of the mat/json/yaml file

  • squeeze – whether unix matrix dimensions should be squeezed for mat files

  • verify – enables verification of the length of compressed data segments for mat files

Returns:

a new Struct object with the data from the file

save(filename, compress=True, indent=None, sort_keys=False, makedirs=False)[source]

Saves the data to a mat or json file.

Parameters:
  • filename – filename of the output file (will be overwritten if it exists)

  • compress – enable compression (for mat files)

  • indent – enable indentation (for json files)

  • sort_keys – sort keys (for json files)

  • makedirs – recursively create parent directories if they do not exist

Returns:

None

update(other, overwrite=True)[source]

Updates this struct with all values of the given struct, similar to the update method of dict. Unless the overwrite parameter is set to False, existing values are overwritten.

Parameters:
  • other – other Struct object

  • overwrite – if set to False, a ValueError is raised if data would be overwritten

Returns:

None

qmt.toJson(obj, method='orjson', indent=None, sort_keys=False)[source]

Versatile and fast json-encoding function that can handle numpy array and qmt.Struct. Uses the fast orjson library by default.

Parameters:
  • obj – object to be encoded (list, dict, or qmt.Struct)

  • method – json encoder to use, values: ‘orjson’ (default) or ‘json’

  • indent – indent output (with orjson, indentation is always 2 spaces and enabled if indent evalues to True)

  • sort_keys – enables sorting of dictionary keys

Returns:

encoded json as bytes (with method=orjson, default) or string (with method=json)

Plotting

qmt.setupDebugPlots(mode=<object object>, filename=<object object>, autoclose=<object object>, figsize=<object object>, figsize_cm=<object object>, dpi=<object object>, title=<object object>)[source]

Sets up how debug plots are created when functions are called with plot=True.

Parameters:
  • mode

    Sets the mode in which debug plots work. Possible modes:

    • show (default): figure is created and plt.show() is called automatically

    • create: figure is only created but not saved or shown

    • save: figure is automatically saved to file using savefig

    • pdfpages: figures are written to a multipages PDF file

  • filename – filename of the output file, can contain a format string like {i:03d} for an auto-increasing counter

  • autoclose – if set to True (default), figures will automatically be closed in save and pdfpages mode

  • figsize – figure size in inches

  • figsize_cm – figure size in cm

  • dpi – dpi of the figure

  • title – custom title that some plot functions may add to the plot (e.g. to identify different data sets)

Returns:

None

qmt.extendXlim(ax, left=None, right=None)[source]

Extends xlim of matplotlib axes.

This function is useful for safely setting axes limits without the risk of accidentally cutting off data. Make sure to plot all data before calling this function so that the automatic xlim range is set.

Parameters:
  • ax – matplotlib axes

  • left – lower x-axis limit (if set to None, this limit will not be adjusted)

  • right – upper x-axis limit (if set to None, this limit will not be adjusted)

Returns:

None

qmt.extendYlim(ax, bottom=None, top=None)[source]

Extends ylim of matplotlib axes.

This function is useful for safely setting axes limits without the risk of accidentally cutting off data. Make sure to plot all data before calling this function so that the automatic ylim range is set.

Parameters:
  • ax – matplotlib axes

  • bottom – lower y-axis limit (if set to None, this limit will not be adjusted)

  • top – upper y-axis limit (if set to None, this limit will not be adjusted)

Returns:

None

Webapp framework

class qmt.Webapp(path=None, config=None, data=None, show='window', quiet=False)[source]

Runs webapps.

There are two different viewers for different use cases that are used based on the show property. The default PySide-based viewer (‘window’ or ‘webapp’) uses the QtWebEngine to show the webapp in a window and a QtWebChannel for real-time communication between Python code and the webapp. The aiohttp-based viewer (‘chromium’, ‘iframe’, or ‘none’) opens a local web server and uses websockets for real-time communication.

See Webapps for 3D visualization, Webapps, and the files webapp_example_script.py and webapp_example_notebook.ipynb in the examples folder for information on how to use existing webapps and Webapp development for information on how to create custom webapps.

For playback of stored data from .mat or .json files, there is a command-line utility called qmt-webapp. Run qmt-webapp -h to see how to use it.

Parameters:
  • path – path to the webapp. Can either be the path to a folder containing an index.html file, a path to a html file or a special path (e.g. /view/imubox, /demo/euler-angles).

  • config – configuration for the webapp (qmt.Struct, dict or filename)

  • data – data for offline playback (qmt.Struct, dict or filename)

  • show – how to display the webapp, one of (‘window’, ‘widget’, ‘chromium’, ‘iframe’, ‘none’)

  • quiet – if set to True, disable most log output

async arun()[source]

Async method to run the webapp.

await webapp.arun() will run the webapp in the current event loop and return after it is closed.

Returns:

None

property autoIncrementPort

If set to True (default), automatically increment the port number if another server is already running the specified port (aiohttp only).

property chromiumExecutable

Custom path to Chromium or Chrome executable that is run when show is set to ‘chromium’ (aiohttp only).

By default, several standard paths are searched on Windows. On other platforms, ‘chromium-browser’ is used.

property config

Holds the current configuration as a Struct.

Can be set to a qmt.Struct, dict or filename. Setting the config while the webapp is running causes a ‘setConfig’ command to be sent.

property connected

Read-only property, True if there is at least one client connected to the websocket

property data

Holds the current data as a Struct.

Can be set to a qmt.Struct, dict or filename. Setting the data while the webapp is running causes a ‘setData’ command to be sent.

property devServerUrl

Custom URL to load to support using a development server (PySide viewer only).

This URL is loaded instead of the default qmt://app/. The websocket/webchannel connection will automatically work with the Backend class, but by default, the webapps will try to load data and config from the dev server and not from the Python code. To load data and config from Python, use:

webapp.devServerUrl = 'http://localhost:3000/?config=qmt://app/config.json&data=qmt://app/data.json'
property dirname

Read-only property, returns the path to the directory containing the webapp.

property host

Hostname for the webserver, default: ‘127.0.0.1’ (aiohttp only)

property icon

Path to application icon (PySide viewer only).

Set this property to a path to an image file (or some other value understood by the QIcon construction) to replace the default application icon.

property iframeHeight

Height of the iframe embedded in Jupyter notebooks, default: ‘500’ (aiohttp only).

property iframeWidth

Width of the iframe embedded in Jupyter notebooks, default: ‘100%’ (aiohttp only).

static initialize()[source]

Initialize the PySide viewer.

This function is automatically called when a webapp is started. However, the initialization has to happen before a QApplication instance is created. In a custom PySide application or when other code creates a QApplication (e.g., matplotlib with the Qt5Agg backend), it is necessary to call qmt.Webapp.initialize() before this happens.

property jsLogLevel

Logging level for JavaScript messages (PySide viewer only).

Possible values are ‘info’, ‘warning’, ‘error’, and ‘disabled’.

JavaScript log messages are captured and redicted to a js logger. By default, only warnings and errors are shown. To also print output from console.log, set this property to ‘info’.

An alternative (and more powerful) way to get JavaScript logging output is to use the developer tools. Set the environment variable QTWEBENGINE_REMOTE_DEBUGGING=5000 and then open http://localhost:5000/ in a Chromium-based browser. For more information, see https://doc.qt.io/qt-5/qtwebengine-debugging.html.

logToFile(filename)[source]

Setup logging of all data sent and received over the websocket to a jsonl file.

Parameters:

filename – filename ending with ‘.jsonl’

Returns:

None

property noLib

If set to True, do not serve the special paths /lib-qmt, /view, and /demo.

on(event, callback)[source]

Register a callback that is notified on events.

Parameters:
  • event – string describing events, one of (‘message’, ‘params’, ‘command’, ‘connected’, ‘disconnected’)

  • callback – coroutine or function that will be called with the webapp as first argument and event-specific data as second argument

Returns:

None

async onCommand(command)[source]

Handles commands received over the websocket.

You can override this method or register a callback with webapp.on('command', f).

Parameters:

command – command (will always be a list)

Returns:

None

async onConnected(numberOfConnections)[source]

Called when a client connects to the websocket.

You can override this method or register a callback with webapp.on('connected', f).

Parameters:

numberOfConnections – current number of connections

Returns:

None

async onDisconnected(numberOfConnections)[source]

Called when a client disconnects to the websocket.

You can override this method or register a callback with webapp.on('disconnected', f).

Parameters:

numberOfConnections – current number of connections

Returns:

None

async onMessage(message)[source]

Handles all messages received over the websocket.

You can override this method or register a callback with webapp.on('message', f).

Parameters:

message – message as decoded json object (i.e. should be either dict or list)

Returns:

None

async onParams(params)[source]

Handles parameters received over the websocket.

You can override this method or register a callback with webapp.on('params', f).

Parameters:

params – parameter dict

Returns:

None

property path

Path of the webapp. Can either be the path to a folder containing an index.html file, a path to a html file or a special path (e.g. /view/imubox, /demo/euler-angles). When reading this property, a standard absolute file path will always be returned.

property port

Port for the webserver, default: 8000 (aiohttp only)

run()[source]

Runs the webapp.

If no asyncio event loop is running, this function will block until the webapp is closed. If an event loop is running (e.g. in Jupyter notebooks), the webapp will start in the background and this function immediately returns.

Returns:

None

runCommand(command)[source]

Runs a command as if it were received over the websocket.

Parameters:

command – command, must be a list

Returns:

None

runInProcess()[source]

Runs the webapp in a separate process.

The attributes of the current class are transferred to a new process (with the multiprocessing module) and a new Webapp instance is created and started in this process. The returned connection object can be used to communicate with the webapp.

Returns:

qmt.WebappProcessConnection object

sendCommand(command)[source]

Sends a command to the webapp via the websocket.

Parameters:

command – command, must be a list

Returns:

None

sendMessage(message)[source]

Sends an arbitrary message over the websocket.

Parameters:

message – arbitrary object that can be encoded as JSON

Returns:

None

sendSample(sample)[source]

Sends a sample to the webapp via the websocket.

Parameters:

sample – sample dict

Returns:

None

setParams(params)[source]

Sets parameters as if they were received over the websocket.

Parameters:

params – parameter dict

Returns:

None

setupOnlineLoop(source, block=None)[source]

Setup the online data processing loop. When webapp.run() is called after setting this, the source will be polled for samples. Each sample is sent to the processing block (if it is not None) and the output samples are sent to the websocket.

Parameters:
Returns:

None

property show

Determines how the webapp should be displayed.

Possible values are ‘window’, ‘widget’, ‘chromium’, ‘iframe’, and ‘none’.

window

Uses the PySide-based viewer and opens the webapp in a window. Does not open a local web server, but serves files internally using a custom scheme and uses a QtWebChannel for real-time communication.

widget

Uses the PySide-based viewer but does not show the window. Use this to integrate the webapp in a custom application.

chromium

Uses the aiohttp-based viewer and starts a chromium browser window in app mode (without any toolbars). The aiohttp-based viewer opens a local web server and uses a websocket for real-time communication.

iframe

Uses the aiohttp-based viewer and creates an iframe in a Jupyter notebook.

none

Only starts the aiohttp-based web server.

property stopOnDisconnect

If set to True (default), the server is automatically stopped once the websocket connection is closed and not immediately reconnected (aiohttp only).

property stopOnWindowClose

If set to True, the server is automatically stopped when the browser window process terminates (aiohttp only).

Note that this is not used by default because (a) chromium immediately exists when another instance is already running and (b) it does not work for iframes embedded in Jupyter notebooks.

class qmt.AbstractDataSource(Ts)[source]

Base class for all data source classes used in the qmt.Webapp online data processing loop.

The data source provides samples that are then (optionally) processed and sent via the websocket. To implement a custom data source, you must implement either poll or apoll or samples. Which method to implement depends on what works best for the given problem.

Parameters:

Ts – sampling time in seconds, or None if the data source does not produce samples at regular times

property Ts

Sampling time in seconds, or None if the data source does not produce samples at regular times.

async apoll()[source]

Asynchronous poll method that returns the next sample. If no sample is available, the method must wait without blocking the event loop.

Returns:

sample dict (must contain ‘t’ with time in seconds)

command(command)[source]

This method is called when a command is received over the websocket. If the data source decides to handle a command, it should return True and this command will not be sent to the data processing block.

Commands should for example be used to control playback of recorded data or initiate connecting to sensors. Command names for data sources should be chosen in a way that minimizes possible name clashes with commands used for data processing.

The default implementation just returns False.

Parameters:

command – command as a list

Returns:

True if command was handled by the data source, else False

poll()[source]

This method is used to poll the data source. It should either return a sample or, if no sample is available, return None.

Returns:

sample dict (must contain ‘t’ with time in seconds) or None if no sample is available

async samples()[source]

Asynchronous generator that yields samples as they become available.

setParams(params)[source]

This method is called when a parameter dict is received over the websocket. Parameters are first passed to the data source and then to the data processing block.

The default implementation does nothing.

Parameters:

params – parameter dict

Returns:

None

async setup()[source]

This (async) method is called once at the start and can be used to perform setup that uses the asyncio loop.

Data sources should not use asyncio.get_event_loop() in __init__ because the event loop might still change.

class qmt.ProcessDataSource(target, Ts, *args, pollTime=0.01, **kwargs)[source]

This data source runs a function in a separate process using the multiprocessing module and allows for the integration of blocking processing code (e.g., simulations) that does not work well in combination with async code.

The target function is started in a separate process as target(conn, Ts, *args, **kwargs), where conn is a ProcessDataSourceConnection instance that can be used to communicate with the webapp.

Parameters:
  • target – target function to run in separate process

  • Ts – sampling time in seconds (pass None if irregular or not relevant for further processing)

  • args – positional arguments to pass to the target function

  • pollTime – poll time for the multiprocessing pipe in seconds (only used on Windows)

  • kwargs – keyword arguments to pass to the target function

async setup()[source]

This (async) method is called once at the start and can be used to perform setup that uses the asyncio loop.

Data sources should not use asyncio.get_event_loop() in __init__ because the event loop might still change.

class qmt.ProcessDataSourceConnection(pipe)[source]

Helper for qmt.ProcessDataSource. An instance of this class passed to the target process and can be used to communicate with the webapp.

getCommands()[source]

Iterator to get new received commands.

Commands are deleted from the internal FIFO once they are read. Regularly loop over this iterator to receive and handle all new commands.

getParams(clear=False)[source]

Returns a dictionary containing the received parameters.

Parameters:

clear – If True, the parameter dictionary is cleared after returning the parameters (allows for the detection which parameters were sent since the last call to this function).

Returns:

dict with parameters received over websocket

property raiseInterruptOnClose

Set this property to True to raise a KeyboardInterrupt when the connection is closed.

If this is not set, isClosed() needs to be called regularly to detect when the connection is closed.

sendCommand(command)[source]

Sends a command to the webapp via the websocket.

Parameters:

command – command (as list)

Returns:

None

sendSample(sample)[source]

Sends a sample to the webapp via the websocket.

Parameters:

sample – sample dict

Returns:

None

class qmt.WebappProcessConnection(webapp)[source]

Helper for Webapp.runInProcess(). An instance of this class is returned and can be used to communicate with the webapp. See the base class qmt.ProcessDataSourceConnection for documentation on most methods.

shutdown()[source]

Shut down the webapp.

class qmt.ClockDataSource(Ts)[source]

This data sources generates samples at a fixed interval, containing only the time.

Use this class in combination with a data processing block to create animations.

Parameters:

Ts – sample time at which to generate samples

class qmt.PlaybackDataSource(data)[source]

Data source that generates samples from recorded/generated data similar to the playback mode in webapps.

The data struct must have a time vector named ‘t’. Samples are generated from all elements in the data that have the same length as ‘t’.

Parameters:

data – qmt.Struct, dict or filename of a file that can be loaded with qmt.Struct.load()

class qmt.DummyImuDataSource(Ts, N=1)[source]

Data source that generates fake IMU data.

For every virtual IMU, a fake sensor movement is generated from random orientations, and raw measurement data is derived from this. Noise and a constant bias are added. The generated data is not meant to be realistic in terms of error characteristics, but reasonable enough to be useful for some testing and development tasks where real hardware would otherwise be required.

Parameters:
  • Ts – sample time at which to generate samples

  • N – number of virtual IMUs

qmt.dataSourceFromJson(jsonString, classes=None, autoImport=True)[source]

Create a data source object from a JSON object containing the class name and parameters.

The JSON object must contain a class entry with the name or path of a qmt.AbstractDataSource subclass. Custom classes can be defined in the optional classes parameter. Unless autoImport is set to false, external packages are automatically imported, i.e., the user can specify “my_package.MyCustomDataSource” and “my_package” will be automatically imported. This can be useful to decouple the processing code from the hardware backend, but the jsonString should not come from untrusted user input.

This function is used by the qmt-webapp CLI tool, e.g.:

qmt-webapp --datasource '{"class": "qmt.DummyImuDataSource", "Ts": 0.01, "N": 3}' /view/imubox
Parameters:
  • jsonString – json string (or dict) defining the data source class and arguments

  • classes – optional dictionary defining custom class names

  • autoImport – enables automatic import of modules based on the given class name

Returns:

data source object

Matlab interface

qmt.matlab = <qmt.utils.transplant.MatlabWrapper object>

Global object that provides access to Matlab.

class qmt.utils.transplant.MatlabWrapper[source]

Provides access to the qmt Matlab functions. A Matlab instance is automatically started in background on the first access. If there is no matlab executable in your path, call init() manually.

See Matlab interface for more details.

exit()[source]

Quits Matlab.

init(**kwargs)[source]

Starts Matlab and sets up the path for the qmt functions. If there is no matlab executable in your path, call this function manually and provide the full path to Matlab:

qmt.matlab.init(executable='/usr/local/MATLAB/R2017b/bin/matlab')
Parameters:

kwargs – Parameters passed to transplant.

Returns:

None

property instance

Gives access to the Transplant Matlab class that can be used to call other Matlab functions and execute arbitrary Matlab code.

m = qmt.matlab.instance
m.version()
m.eval('1234*(0.1+0.1+0.1-0.3)^(1/10)')

Data synchronization

class qmt.SyncMapper(syncInfo)[source]

Converts timestamps and indices for different data streams based on specified time/index mappings.

syncInfo is a dict data structure specifying the available recordings and the sync mappings. example using YAML syntax and only using the fields used by this class more fields may be added for other applications):

data:
    imu_data:
        rate: 200
    video1_part1:
        rate: 25
    video1_part2:
        rate: 25
    video2:
        rate: 50
sync:
    - [video1_part1, t, 0, video2, t, 1.85]
    - [video1_part2, t, 0, video2, t, 1145.2]
    - [video2, t, 0, imu_data, t, 0]

The mapping should be an undirected connected graph without any cycles. An exception is thrown if the graph is not connected, i.e. if one or more mappings are missing. Cycles (e.g. adding [video1_part1, t, 0, imu_data, t, 0] to the example) are not detected and may lead to inconsistent data.

Currently, only one sync mapping can be provided for each data set and the rate has to be known. In the future, support for estimating the rate based on multiple measurements may be added.

map(nameFrom, modeFrom, valFrom, nameTo, modeTo)[source]

Maps a timestamp/index from one data stream to a timestamp/index of another data stream.

Example call to get the index in imu_data corresponding to 25 s of video1_part2: sync.map(‘video1_part2’, ‘t’, 25.0, ‘imu_data’, ‘ind’)

resample(nameFrom, signal, nameTo, N, method='auto')[source]

Resamples data (signal sampled in nameFrom) to match data sampled in a different data stream (nameTo, consisting of N samples). By default, slerp is used when the input is in shape (M, 4) and linear interpolation is used otherwise.

Parameters:
  • nameFrom – name of the original data stream

  • signal – data, shape (M, P)

  • nameTo – name of the target data stream

  • N – number of samples of the target data

  • method – ‘vecInterp’/’quatInterp’/’auto’

Returns:

(N, P) resampled signal

Other utilities

qmt.parallel(items, ordered=False, workers=None, chunksize=1, verbose=False)[source]

Simple utility to perform parallel processing.

This is a simple wrapper around the multiprocessing package and meant to make usage simpler for a common application scenario in which a list of function calls (with potentially different functions and parameters) is distributed to multiple worker processes.

The main parameter is a list of items. Each item corresponds to one function call and is a dictionary that must have an fn key with the function to be called in the worker process. Arguments that are passed to the function can be specified by setting args to a tuple and/or by setting kwargs to a dict. Optionally, a name can be set for the item which is used only for the debug output. The item may contain other keys which are ignored by this function (but they will still be sent to the worker process, so adding large data should be avoided).

This function is a generator that yields a tuple (i, item, res) for each element of items. i is the original index in the items list, item is items[i] and res is the return value of the executed function fn. Unless ordered is set to True, results are not necessarily returned in the original order.

The following minimal working example shows how to use this utility:

import time

def slowFunction(t):
    time.sleep(t)
    return t

# create list of items to be processed
items = [{'fn': slowFunction, 'kwargs': {'t': t}} for t in [5, 10, 4, 2, 8, 3]]

for i, item, res in parallel(items, verbose=True):
    print(i, item, res)

By default, the number of workers is automatically chosen to match the number of CPU cores. By setting workers to 1, the use of multiprocessing is disabled, making debugging and profiling much easier.

How to best split a slow task into multiple function calls (i.e., items) depends on the specific problem. A good rule of thumb is that each item should at least take a few seconds (to avoid that overhead plays a large role) while on the other hand the number of items should be significantly larger than the number of CPU cores (to avoid that the time in which some CPU cores are idle at the end plays a large role). Also, consider splitting the items in a way that makes combining the results as easy and fast as possible. In many cases, when processing experimental data with several trials/recordings, having one item per trial (and loading the trial data locally in the target function) is a good idea.

Parameters:
  • items – list of items to process (each item is a dict as described above and corresponds to one function call)

  • ordered – set to True to force the results to be returned in the same order as the items list

  • workers – number of worker processes to use (when set to the default of None, the number of CPU cores is used)

  • chunksize – chunk size passed to multiprocessing (the default of 1 works well unless there are lots of items)

  • verbose – enables output of status information

Returns:

generator that yields (i, item, res) for each element of items (in arbitrary order unless ordered==True)

qmt.setDefaults(params, defaults, mandatory=None, check=True)[source]

Helper function to facilitate handling of multiple optional parameters that are passed in a dictionary. Default values are set for missing parameters and, if check is True, an error is raised if unexpected parameters are passed or some non-optional parameters are missing.

The input dictionary is not modified.

>>> qmt.setDefaults(dict(mandatory1=42, optional2=3), dict(optional1=1, optional2=2), ['mandatory1'])
{'mandatory1': 42, 'optional2': 3, 'optional1': 1}
Parameters:
  • params – dict with parameter values or None

  • defaults – dict with default parameter values

  • mandatory – optional list of mandatory parameter names that need to be contained in parames

  • check – enables checking of the passed parameter names

Returns:

dict with parameter values after applying default values

qmt.startStopInd(booleanArray)[source]

Determines start and end indices of true phases in a boolean array.

>>> qmt.startStopInd([0, 0, 1, 1, 1, 0, 0, 1, 0, 0])
(array([2, 7]), array([5, 8]))
Parameters:

booleanArray – 1D boolean array

Returns:

  • starts: array with start indices of true phases

  • stops: array with stop indices of true phases