Device Configuration
To record with SciFi, you will need to first specify the recording configuration using a Synapse JSON file. This settings file specifies the nodes in the signal chain, how each node is configured, and how and in what order the nodes are connected.
Nodes in the signal chain can be arranged in linear or branching configurations, and each node has its own configuration settings. For example, the kBroadbandSource
node ingests n channels of broadband data at a specified sampling rate and bit depth. The input source is identified by peripheral_id
. Other nodes have their own node-specific configuration settings.
Axon GPIO Configuration
External event inputs from peripheral Axon devices are specified using the GPIO
type flag when specifying your channel inputs. Axon GPIOs support TTL signaling with a maximum input voltage of +5V, and a HIGH/LOW threshold of +1.5V. GPIOs are acquired alongside neural data from the same Axon adapter using the same sampling rate. This ensures sub-millisecond synchronization precision.
Currently, Axon GPIOs can only be used to receive data and are only available on the Axon Omnetics adapter.
Example Configuration
The configuration example below shows a basic setup where the source node ("src_node_id": 2
) ingests four channels of neural data and two GPIO channels acquired using the Axon Omnetics adapter. All channels from this source are sampled at 32 kHz. The neural data channels ("type": "ELECTRODE"
) are acquired using 12 bit width and are filtered using the specified high- and low-pass filter corner frequencies (high_cutoff_hz
and low_cutoff_hz
, respectively). Acquired data can be streamed out with Taps via the downstream kStreamOut
node.
{
"nodes": [
{
"type": "kStreamOut",
"id": 1,
"stream_out": {
}
},
{
"type": "kBroadbandSource",
"id": 2,
"broadband_source": {
"peripheral_id": 100,
"sample_rate_hz": 32000,
"bit_width": 12,
"signal": {
"electrode": {
"channels": [
{"id": 0, "electrode_id": 122, "reference_id": 520, "type": "ELECTRODE"}, {"id": 4, "electrode_id": 110, "reference_id": 520}, {"id": 5, "electrode_id": 114, "reference_id": 520}, {"id": 6, "electrode_id": 104, "reference_id": 520}, {"id": 7, "electrode_id": 108, "reference_id": 520}, {"id": 8, "electrode_id": 98, "reference_id": 520}, {"id": 9, "electrode_id": 66, "reference_id": 520}, {"id": 10, "electrode_id": 92, "reference_id": 520},
{"id": 1, "electrode_id": 126, "reference_id": 520, "type": "ELECTRODE"}, {"id": 11, "electrode_id": 60, "reference_id": 520}, {"id": 12, "electrode_id": 86, "reference_id": 520}, {"id": 13, "electrode_id": 54, "reference_id": 520}, {"id": 14, "electrode_id": 80, "reference_id": 520}, {"id": 15, "electrode_id": 48, "reference_id": 520}, {"id": 16, "electrode_id": 74, "reference_id": 520}, {"id": 17, "electrode_id": 38, "reference_id": 520},
{"id": 2, "electrode_id": 116, "reference_id": 520, "type": "ELECTRODE"}, {"id": 18, "electrode_id": 68, "reference_id": 520}, {"id": 19, "electrode_id": 36, "reference_id": 520}, {"id": 20, "electrode_id": 62, "reference_id": 520}, {"id": 21, "electrode_id": 0, "reference_id": 520}, {"id": 22, "electrode_id": 56, "reference_id": 520}, {"id": 23, "electrode_id": 4, "reference_id": 520}, {"id": 24, "electrode_id": 50, "reference_id": 520},
{"id": 3, "electrode_id": 120, "reference_id": 520, "type": "ELECTRODE"}, {"id": 25, "electrode_id": 12, "reference_id": 520}, {"id": 26, "electrode_id": 44, "reference_id": 520}, {"id": 27, "electrode_id": 14, "reference_id": 520}, {"id": 28, "electrode_id": 42, "reference_id": 520}, {"id": 29, "electrode_id": 20, "reference_id": 520}, {"id": 30, "electrode_id": 32, "reference_id": 520}, {"id": 31, "electrode_id": 26, "reference_id": 520}],
{"id": 32, "electrode_id": 0, "type": "GPIO"}
{"id": 33, "electrode_id": 1, "type": "GPIO"}
],
"low_cutoff_hz": 4,
"high_cutoff_hz": 20400
}
}
}
}
],
"connections": [
{
"src_node_id": 2,
"dst_node_id": 1
}
]
}
Note: ELECTRODE
is the default setting for type
and is therefor optional for electrode inputs from Axon devices. It is shown for illustrative purposes in the configuration shown above.
Please refer to the Synapse peripheral documentation for a complete list of configuration options.
Synapse API
The Synapse API command line interface (CLI) synapsectl
is used to control the SciFi headstage, and also controls client functions such as build and deployment of Synapse Apps to SciFi. The -h
or --help
option can be used to output a list of the available synapsectl
commands.
$ synapsectl --help
usage: synapsectl [-h] [--uri URI] [--version] [--verbose]
{discover,info,query,start,stop,configure,logs,read,plot,file,taps,deploy,build} ...
Synapse Device Manager
options:
-h, --help show this help message and exit
--uri URI, -u URI The device identifier to connect to. Can either be the IP address or name
--version show program's version number and exit
--verbose, -v Enable verbose output
Commands:
{discover,info,query,start,stop,configure,logs,read,plot,file,taps,deploy,build}
discover Discover Synapse devices on the network
info Get device information
query Execute a query on the device
start Start the device or an application
stop Stop the device or an application
configure Write a configuration to the device
logs Get logs from the device
read Read from a device's StreamOut node
plot Plot recorded synapse data
file File commands
taps Interact with taps on the network
deploy Deploy an application to a Synapse device
build Cross-compile and package an application into a .deb without deploying
Synapse Apps
Synapse Apps are fully customizable standalone applications that can be deployed to your Synapse device. Apps allow you to run your custom neural processing algorithms on-device within a node in the signal chain to minimize latency. They read in data from other nodes in the signal chain, and Taps are used to output data to a local client running synapsectl
.
Configuration files can be uploaded to the Synapse device while starting a Synapse App.
synapsectl -u "device uri" start <path to config>.json
For more information about writing and using apps running on your Synapse-compatible headstage, see the App API.
Measure Impedance
Query Construction
In order to request an impedance measurement from a Synapse device, you will need to construct and format an “Impedance Query” message to send to the SciFi in the form of a JSON file:
{
"query_type": "kImpedance",
"impedance_query": {
"electrode_ids": [1, 2, 3, 4, 5]
}
}
Your list of electrode IDs can be as long as you’d like.
Run the Test
Use the following command to begin the measurement:
synapsectl -u $DEVICE_IP query $QUERY_JSON_PATH
The command may take a few minutes if your list of electrode IDs is large.
After the measurement finishes, an output is generated with a status message (typically blank) and a list of each electrode measurement measured by magnitude (Ohms) and phase (degrees). The output file is saved in a CSV format and titled impedance_measurements_$DATE_$TIMESTAMP.csv
.
status {
}
impedance_response {
measurements {
electrode_id: 1
magnitude: 13414576.0
phase: -210.17554
}
measurements {
electrode_id: 2
magnitude: 28159914.0
phase: -184.9782
}
measurements {
electrode_id: 3
magnitude: 12796945.0
phase: -168.97946
}
measurements {
electrode_id: 4
magnitude: 31529048.0
phase: -248.70753
}
measurements {
electrode_id: 5
magnitude: 1768543.4
phase: -147.09204
}
}