API documentation

tdt.util

Functions for loading the zBUS, PA5 and RPcoX drivers and connecting to the specified device. In addition to loading the appropriate ActiveX driver, some minimal configuration is done.

Network-aware proxies of the zBUS and RPcoX drivers have been written for TDTPy. To connect to TDT hardware that is running on a remote computer, both the connect_zbus() and connect_rpcox() functions take the address of the server via a tuple (hostname, port):

connect_rpcox('RZ6', address=(tdt_server.cns.nyu.edu, 3333))
tdt.util.connect_zbus(interface='GB', address=None)

Connect to the zBUS interface and set the zBUS A and zBUS B triggers to low

Parameters:
  • interface ({'GB', 'USB'}) – Type of interface (depends on the card that you have from TDT). See the TDT ActiveX documentation for clarification on which interface you would be using if you are still unsure.
  • address ({None, (hostname, port)}) – If None, loads the ActiveX drivers directly, otherwise connects to the remote server specified by the hostname, port tuple.
tdt.util.connect_rpcox(name, interface='GB', device_id=1, address=None)

Connect to the specifed device using the RPcoX driver

Note that the appropriate RPcoX.Connect method is called so you do not need to perform that step in your code.

Parameters:
  • name ({'RZ6', 'RZ5', 'RP2', .. (any valid device string) }) – Name of device (as defined by the corresponding RPcoX.Connect* method).
  • interface ({'GB', 'USB'}) – Type of interface (depends on the card that you have from TDT). See the TDT ActiveX documentation for clarification on which interface you would be using if you are still unsure.
  • device_id (int (default 1)) – Id of device in the rack. Only applicable if you have more than one of the same device (e.g. two RX6 devices).
  • address ({None, (hostname, port)}) – If None, loads the ActiveX drivers directly, otherwise connects to the remote server specified by the hostname, port tuple.
tdt.util.connect_pa5(interface='GB', device_id=1, address=None)

Connect to the PA5

Note

The network-aware proxy code should be considered alpha stage. Although it appears to work in our tests, we have not deployed this in our data aqcuisition experiments.

tdt.DSPProject

class tdt.DSPProject(address=None, interface='GB')

Used to manage loading circuits to multiple DSPs. Mainly a convenience method.

load_circuit(circuit_name, device_name, device_id=1, **kw)

Load the circuit to the specified device

Parameters:
  • circuit_name (str) – Path to circuit to load
  • device_name (str) – Name of TDT System3 device to load circuit to
  • device_id (number) – ID of device
Returns:

circuit – The circuit.

Return type:

instance of DSPCircuit

start()

Start all circuits that have been loaded

stop()

Stop all circuits that have been loaded

trigger(trigger, mode='pulse')

Fire a zBUS trigger

Parameters:
  • trigger ({'A', 'B'}) – Fire the specified trigger. If integer, this corresponds to RPco.X.SoftTrg. If ‘A’ or ‘B’, this fires the corresponding zBUS trigger.
  • mode ({'pulse', 'high', 'low'}) – Indicates the corresponding mode to set the zBUS trigger to
  • that due to a bug in the TDT ActiveX library for versions greater (Note) –
  • 56, we have no way of ensuring that zBUS trigger A or B were (than) –
  • fired.

tdt.DSPCircuit

class tdt.DSPCircuit(circuit_name, device_name, interface='GB', device_id=1, load=True, start=False, fs=None, address=None, latch_trigger=None)

Wrapper around the TDT ActiveX object, RPCo.X.

Provides several stringent checks and convenience methods to minimize programming errors and typos.

circuit_name : string
Path to circuit file.
device_name : string
Device to load circuit to.
interface : {‘GB’, ‘USB’}
Interface to use (see TDT’s ActiveX documentation on the Connect* methods for more information). You almost certainly want ‘GB’ (which is the default value).
device_id : number
ID of device
load : boolean (optional)
Load circuit to specified device. Default is True. Set to False if you just want to get a list of the tags available in the circuit.
start : boolean (optional)
Start (i.e. run) the circuit after loading it. Default is False.
address : two-tuple (str, int)
Connect to the address specified as a two-tuple in (host, port) format using the network-aware proxy of TDT’s driver. If None, defaults to the TDT implementation of the RPcoX and zBUSx drivers.
latch_trigger : {None, 1, 2, 3, 4}
Trigger used for latching values when we need to capture a snapshot of some tags at a given point in time. This is used by DSPBuffer to eliminate race conditions when reading the value of the cycle and index tags. If the tags are not latched, then it’s possible to read the index tag, then by the time the cycle tag is read the index has wrapped around to the beginning of the buffer.
cget_tag(name, tag_unit, val_unit)

Enhanced version of get_tag that returns value in requested unit

Parameters:
  • name (str) – Tag name
  • tag_unit (str) – Unit of tag
  • val_unit (str) – Requested unit
convert(value, src_unit, dest_unit)

Converts value to desired unit give the sampling frequency of the DSP.

Parameters specified in paradigms are typically expressed as frequency and time while many DSP parameters are expressed in number of samples (referenced to the DSP sampling frequency). This function provides a convenience method for converting between conventional values and the ‘digital’ values used by the DSP.

Note that for converting units of time/frequency to n/nPer, we have to coerce the value to a multiple of the DSP period (e.g. the number of ‘ticks’ of the DSP clock).

Appropriate strings for the unit types:

fs
sampling frequency
nPer
number of samples per period
n
number of samples
s
seconds
ms
milliseconds
nPow2
number of samples, coerced to the next greater power of 2 (used for ensuring efficient FFT computation)

Given a DSP clock frequency of 10 kHz:

>>> circuit.convert(0.5, 's', 'n')
5000
>>> circuit.convert(500, 'fs', 'nPer')
20

Given a DSP clock frequency of 97.5 kHz:

>>> circuit.convert(5, 's', 'nPow2')
524288
Parameters:
  • value (numerical (e.g. integer or float)) – Value to be converted
  • src_unit (string) – Unit of the value
  • dest_unit (string) – Destination unit
Returns:

converted unit

Return type:

numerical value

cset_tag(name, value, val_unit, tag_unit)

Enhanced version of set_tag that converts the value

Parameters:
  • name (str) – Name of the parameter tag to write the converted value to
  • value (int or float) – Value to convert
  • val_unit (str) – Unit of value provided
  • tag_unit (str) – Unit parameter tag requires
Returns:

  • Actual value of the tag (i.e. the converted value)
  • Value will be converted from val_unit to tag_unit based on the sampling
  • frequency of the device (if needed). See :module:`convert` for more
  • information.

get_tag(name)

Analogue of RPco.X.GetTagVal

Parameters:
  • name (str) – Name of the parameter tag to read the value from
  • DSPError (Raises) – If the tag does not exist or is not a scalar value (e.g. you cannot use this method with parameter tags linked to a buffer)
inspect()

Determine what tags are available in the microcode

is_connected()

True if connection with hardware is active, False otherwise

is_loaded()

True if microcode is loaded, False otherwise

load()

Clear DSP RAM set all variables to default value

The circuit is reloaded from disk, so any recent edits to the circuit will be reflected in the running program.

print_tag_info()

Prints a list of tags and their current value if they are a scalar (buffer tags are not printed yet)

Used as a convenience method for debugging

set_coefficients(name, data)

Load data to a coefficient or matrix input

Parameters:
  • name (str) – Name of the parameter tag to write the data to
  • data (array-like) – Data to write to tag. Must be 1D format (even for matrices). See RPvds documentation for appropriate ordering of indices for the component.
  • DSPError (Raises) – If the specified parameter tag is not linked to a coefficient input or the length of the data is not equal to the size of the input on the component.
  • that as of 3.10.2011, RPvds' CoefLoad component appears to be (Note) –
  • (per conversation with TDT's tech support -- Mark Hanus and (broken) –
  • Walters) As a workaround, connect a data tag directly to the (Chris) –
  • or >Coef input of the component. (>K) –
set_sort_windows(name, windows)

Utility function for configuring TDT’s SpikeSort component coefficients

Windows should be a list of 3-tuples in the format (time, center volt, half-height)

If the windows overlap in time such that they cannot be converted into a coefficient buffer, and error will be raised.

set_tag(name, value)

Analogue of RPco.X.SetTagVal

Parameters:
  • name (str) – Name of the parameter tag to write the value to
  • value (int or float) – Value to write
  • DSPError (Raises) – If the tag does not exist or is not a scalar value (e.g. you cannot use this method with parameter tags linked to a buffer)
set_tags(**tags)

Convenience function for setting the value of multiple tags

>>> circuit.set_tags(record_duration=5, play_duration=4)
start(pause=0.25)

Analogue of RPco.X.Run

The circuit sometimes requires a couple hundred msec “settle” before we can commence data acquisition

stop()

Analogue of RPco.X.Halt

trigger(trigger, mode='pulse')

Fire a zBUS or software trigger

Parameters:
  • trigger ({1-9, 'A', 'B'}) – Fire the specified trigger. If integer, this corresponds to RPco.X.SoftTrg. If ‘A’ or ‘B’, this fires the corresponding zBUS trigger.
  • mode ({'pulse', 'high', 'low'}) – Relevant only when trigger is ‘A’ or ‘B’. Indicates the corresponding mode to set the zBUS trigger to
  • that due to a bug in the TDT ActiveX library for versions greater (Note) –
  • 56, we have no way of ensuring that zBUS trigger A or B were (than) –
  • fired.

tdt.DSPBuffer

class tdt.DSPBuffer(circuit, data_tag, lock, idx_tag=None, size_tag=None, sf_tag=None, cycle_tag=None, dec_tag=None, block_size=1, src_type='float32', dest_type='float32', channels=1, dec_factor=None, latch_trigger=None)

Given the circuit object and tag name, return a buffer object that serves as a wrapper around a SerStore or SerSource component. See the TDTPy documentation for more detail on buffers.

acquire(trigger, handshake_tag, end_condition=None, trials=1, intertrial_interval=0, poll_interval=0.1, reset_read=True)

Fire trigger and acquire resulting block of data

Data will be continuously spooled while the status of the handshake_tag is being monitored, so a single acquisition block can be larger than the size of the buffer; however, be sure to set poll_interval to a duration that is sufficient to to download data before it is overwritten.

Parameters:
  • trigger – Trigger that starts data acquistion (can be A, B, or 1-9)
  • handshake_tag – Tag indicating status of data acquisition
  • end_condition – If None, any change to the value of handshake_tag after trigger is fired indicates data acquisition is complete. Otherwise, data acquisition is done when the value of handshake_tag equals the end_condition. end_condition may be a Python callable that takes the value of the handshake tag and returns a boolean indicating whether acquisition is complete or not.
  • trials – Number of trials to collect
  • intertrial_interval – Time to pause in between trials
  • poll_interval – Time to pause in between polling hardware
  • reset_read – Should the read index be reset at the beginning of each acquisition sweep? If data is written starting at the first index of the buffer, then this should be True. If data is written continuously to the buffer with no reset of the index in between sweeps, then this should be False.
Returns:

acquired_trials – A 3-dimensional array in the format (trial, channel, sample).

Return type:

ndarray

Examples

>>> buffer.acquire(1, 'sweep_done')
>>> buffer.acquire(1, 'sweep_done', True)
acquire_samples(trigger, samples, trials=1, intertrial_interval=0, poll_interval=0.1, reset_read=True)

Fire trigger and acquire n samples

available(offset=None)

Number of empty slots available for writing

Parameters:offset ({None, int}) – If specified, return number of samples relative to offset. Offset is relative to beginning of acquisition.
blocks_pending()

Number of filled blocks waiting to be read

clear()

Set buffer to zero

Due to a bug in the TDT ActiveX library, RPco.X.ZeroTag does not work on certain hardware configurations. TDT (per conversation with Chris Walters and Nafi Yasar) have indicated that they will not fix this bug. They have also indicated that they may deprecate ZeroTag in future versions of the ActiveX library.

As a workaround, this method zeros out the buffer by writing a stream of zeros.

find_tag(tag, default_prefix, required, name)

Locates tag that tracks a feature of the buffer

Parameters:
  • tag ({None, str}) – Name provided by the end-user code
  • default_prefix (str) – Prefix to append to the data tag name to create the default tag name for the feature.
  • required (bool) – If the tag is required and it is missing, raise an error. Otherwise, return None.
  • name (str) – What the tag represents. Used by the logging and exception machinery to create a useful message.
Returns:

tag_name – Name of tag. If no tag found and it is not required, return None.

Return type:

{None, str}

Raises:

ValueError – If tag cannot be found and it is required.

get_tag(tag, default, name)

Returns value of tag that tracks a feature of the buffer

Parameters:
  • tag ({None, str}) – Name provided by the end-user code
  • default ({int, float}) – Default value of feature if tag is missing.
  • name (str) – What the tag represents. Used by the logging and exception machinery to create a useful message.
Returns:

value – Value of tag. If no tag is present, default is returned.

Return type:

{int, float}

pending()

Number of filled slots waiting to be read

read(samples=None)
Parameters:samples (int) – Number of samples to read. If None, read all samples acquired since last call to read.
reset_read(index=None)

Reset the read index

tdt.convert

exception tdt.convert.SamplingRateError(fs, requested_fs)

Indicates that the conversion of frequency to sampling rate could not be performed.

tdt.convert.convert(src_unit, dest_unit, value, dsp_fs)

Converts value to desired unit give the sampling frequency of the DSP.

Parameters specified in paradigms are typically expressed as frequency and time while many DSP parameters are expressed in number of samples (referenced to the DSP sampling frequency). This function provides a convenience method for converting between conventional values and the ‘digital’ values used by the DSP.

Note that for converting units of time/frequency to n/nPer, we have to coerce the value to a multiple of the DSP period (e.g. the number of ‘ticks’ of the DSP clock).

Appropriate strings for the unit types:

fs
sampling frequency
nPer
number of samples per period
n
number of samples
s
seconds
ms
milliseconds
nPow2
number of samples, coerced to the next greater power of 2 (used for ensuring efficient FFT computation)
>>> convert('s', 'n', 0.5, 10000)
5000
>>> convert('fs', 'nPer', 500, 10000)
20
>>> convert('s', 'nPow2', 5, 97.5e3)
524288
Parameters:
  • src_unit (string) –
  • dest_unit (string) – Destination unit
  • value (numerical (e.g. integer or float)) – Value to be converted
Returns:

converted unit

Return type:

numerical value

tdt.convert.ispow2(n)

True if n is a power of 2, False otherwise

>>> ispow2(5)
False
>>> ispow2(4)
True
tdt.convert.nextpow2(n)

Given n, return the nearest power of two that is >= n

>>> nextpow2(1)
1
>>> nextpow2(2)
2
>>> nextpow2(5)
8
>>> nextpow2(17)
32