Python utilities
Data file handling
|
Wrapper around a Python dict that makes it behave similar to Matlab structs, including support for .mat files. |
|
Versatile and fast json-encoding function that can handle numpy array and qmt.Struct. |
Plotting
|
Sets up how debug plots are created when functions are called with |
|
Extends xlim of matplotlib axes. |
|
Extends ylim of matplotlib axes. |
Webapp framework
|
Runs webapps. |
Base class for all data source classes used in the |
|
|
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. |
Helper for |
|
|
Helper for |
This data sources generates samples at a fixed interval, containing only the time. |
|
|
Data source that generates samples from recorded/generated data similar to the playback mode in webapps. |
|
Data source that generates fake IMU data. |
|
Create a data source object from a JSON object containing the class name and parameters. |
Matlab interface
Global object that provides access to Matlab. |
|
Provides access to the qmt Matlab functions. |
Data synchronization
|
Converts timestamps and indices for different data streams based on specified time/index mappings. |
Other utilities
|
Simple utility to perform parallel processing. |
|
Helper function to facilitate handling of multiple optional parameters that are passed in a dictionary. |
|
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
- property data
Provides access to the underlying
dict(or in some special caseslist) 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
- 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 counterautoclose – 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
showproperty. 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.pyandwebapp_example_notebook.ipynbin theexamplesfolder 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. Runqmt-webapp -hto 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
showis 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 theBackendclass, 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
jslogger. By default, only warnings and errors are shown. To also print output fromconsole.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=5000and 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.WebappProcessConnectionobject
- 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:
source –
qmt.AbstractDataSourceinstanceblock – optional
qmt.Blockinstance
- 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.Webapponline 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
pollorapollorsamples. 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
- 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), whereconnis aProcessDataSourceConnectioninstance 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
- 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.
- 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 classqmt.ProcessDataSourceConnectionfor documentation on most methods.
- 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
classentry with the name or path of a qmt.AbstractDataSource subclass. Custom classes can be defined in the optionalclassesparameter. UnlessautoImportis 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-webappCLI 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
matlabexecutable in your path, callinit()manually.See Matlab interface for more details.
- init(**kwargs)[source]
Starts Matlab and sets up the path for the qmt functions. If there is no
matlabexecutable 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 (
signalsampled innameFrom) to match data sampled in a different data stream (nameTo, consisting ofNsamples). 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
multiprocessingpackage 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
fnkey with the function to be called in the worker process. Arguments that are passed to the function can be specified by settingargsto a tuple and/or by settingkwargsto a dict. Optionally, anamecan 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.
iis the original index in theitemslist,itemisitems[i]andresis the return value of the executed functionfn. Unlessorderedis 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
workersto 1, the use ofmultiprocessingis 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