Use configure to parse a protobuf JSON DeviceConfiguration. The command validates that the file has a .json suffix, prints the parsed configuration, and displays the status returned by the device.
synapsectl -u $DEVICE configure device-config.jsonThe device must be stopped before it can be configured. A successful configuration prepares the signal chain but does not start it.
Start
Start the currently configured signal chain:
synapsectl -u $DEVICE startConfigure and start in one command:
synapsectl -u $DEVICE start device-config.jsonWhen a configuration path is supplied, synapsectl calls Configure first and calls Start only if configuration succeeds. Any Application nodes in the signal chain start their selected Synapse Apps as part of the chain.
Stop
synapsectl -u $DEVICE stopCalling Stop will stop the whole signal chain, including Apps controlled by Application nodes.
JSON Configuration
A JSON signal-chain configuration is the protobuf JSON representation of the Synapse API's DeviceConfiguration message. It contains:
nodes: the operations in the signal chain. Every node has a unique numericid, atypefromNodeType, and the configuration message associated with that type.connections: the directed edges. Each edge identifies its source withsrcNodeIdand destination withdstNodeId.
Node and field names follow the Protocol Buffers JSON representation defined in the synapse-api repository. Use the Node Reference to choose node types and fields. Every connection must refer to IDs in nodes, and connected node inputs and outputs must be compatible.
Construct a Configuration
- Choose the acquisition, processing, application, stimulation, and storage operations required by the pipeline.
- Add one entry to
nodesfor each operation and assign every node a uniqueid. - Fill in the node-specific message. Source and stimulation nodes bind to a device-defined peripheral ID.
- Add one
connectionsentry for every directed edge in the DAG. - Pass the file to
configureorstart. The device validates the node fields, peripherals, connectivity, and available resources.
Virtual Broadband Source
This configuration acquires two simulated electrode channels from virtual peripheral 1000. It has no edges because the source output is consumed through its Tap.
{
"nodes": [
{
"type": "kBroadbandSource",
"id": 1,
"broadbandSource": {
"peripheralId": 1000,
"bitWidth": 12,
"sampleRateHz": 10000,
"gain": 1,
"signal": {
"electrode": {
"channels": [
{ "id": 0, "electrodeId": 0, "referenceId": 520 },
{ "id": 1, "electrodeId": 1, "referenceId": 520 }
],
"lowCutoffHz": 57,
"highCutoffHz": 4365
}
}
}
}
],
"connections": []
}Filter and Save
This configuration binds hardware peripheral 100 to a Broadband Source, passes its output through a bandpass Spectral Filter, and writes the filtered frames to Storage Device 1.
{
"nodes": [
{
"type": "kBroadbandSource",
"id": 1,
"broadbandSource": {
"peripheralId": 100,
"bitWidth": 12,
"sampleRateHz": 32000,
"gain": 1,
"signal": {
"electrode": {
"channels": [
{ "id": 0, "electrodeId": 122, "referenceId": 513 },
{ "id": 1, "electrodeId": 126, "referenceId": 513 }
],
"lowCutoffHz": 57,
"highCutoffHz": 13489
}
}
}
},
{
"type": "kSpectralFilter",
"id": 2,
"spectralFilter": {
"method": "kBandPass",
"lowCutoffHz": 300,
"highCutoffHz": 6000
}
},
{
"type": "kDiskWriter",
"id": 3,
"diskWriter": {
"filename": "filtered_recording",
"storageDeviceId": 1
}
}
],
"connections": [
{ "srcNodeId": 1, "dstNodeId": 2 },
{ "srcNodeId": 2, "dstNodeId": 3 }
]
}Example Signal Chains
Filter, Detect, and Save
This signal chain acquires data from a hardware peripheral, applies a high-pass filter, passes the filtered data through a threshold-crossing detector, and saves the resulting data to disk.
A kHighPass filter takes its corner from lowCutoffHz, and the detector reports a spike when a filtered sample crosses thresholdUV, capturing samplesPerSpike samples for each waveform.
{
"nodes": [
{
"type": "kBroadbandSource",
"id": 1,
"broadbandSource": {
"peripheralId": 100,
"bitWidth": 12,
"sampleRateHz": 32000,
"gain": 1,
"signal": {
"electrode": {
"channels": [
{ "id": 0, "electrodeId": 120, "referenceId": 513 },
{ "id": 1, "electrodeId": 122, "referenceId": 513 },
{ "id": 2, "electrodeId": 124, "referenceId": 513 },
{ "id": 3, "electrodeId": 126, "referenceId": 513 }
],
"lowCutoffHz": 57,
"highCutoffHz": 13489
}
}
}
},
{
"type": "kSpectralFilter",
"id": 2,
"spectralFilter": {
"method": "kHighPass",
"lowCutoffHz": 300
}
},
{
"type": "kSpikeDetector",
"id": 3,
"spikeDetector": {
"thresholder": { "thresholdUV": 50 },
"samplesPerSpike": 32
}
},
{
"type": "kDiskWriter",
"id": 4,
"diskWriter": {
"filename": "detected_spikes",
"storageDeviceId": 1
}
}
],
"connections": [
{ "srcNodeId": 1, "dstNodeId": 2 },
{ "srcNodeId": 2, "dstNodeId": 3 },
{ "srcNodeId": 3, "dstNodeId": 4 }
]
}Save Raw and Filtered Data
This branching signal chain sends one Broadband Source output directly to a Disk Writer and another through a Spectral Filter to a second Disk Writer.
One node's output can feed several downstream nodes: node 1 appears as the source in two connections, so the same broadband frames reach both the raw Disk Writer and the filter. Each Disk Writer needs its own filename.
{
"nodes": [
{
"type": "kBroadbandSource",
"id": 1,
"broadbandSource": {
"peripheralId": 100,
"bitWidth": 12,
"sampleRateHz": 32000,
"gain": 1,
"signal": {
"electrode": {
"channels": [
{ "id": 0, "electrodeId": 120, "referenceId": 513 },
{ "id": 1, "electrodeId": 122, "referenceId": 513 }
],
"lowCutoffHz": 57,
"highCutoffHz": 13489
}
}
}
},
{
"type": "kDiskWriter",
"id": 2,
"diskWriter": {
"filename": "raw_recording",
"storageDeviceId": 1
}
},
{
"type": "kSpectralFilter",
"id": 3,
"spectralFilter": {
"method": "kBandPass",
"lowCutoffHz": 300,
"highCutoffHz": 6000
}
},
{
"type": "kDiskWriter",
"id": 4,
"diskWriter": {
"filename": "filtered_recording",
"storageDeviceId": 1
}
}
],
"connections": [
{ "srcNodeId": 1, "dstNodeId": 2 },
{ "srcNodeId": 1, "dstNodeId": 3 },
{ "srcNodeId": 3, "dstNodeId": 4 }
]
}Process Data with a Synapse App
This signal chain reads data from a Broadband Source and feeds it into a custom Synapse App.
The Application node's name must match an App already deployed on the device, which you can confirm with synapsectl -u $DEVICE apps list. Anything under parameters is defined by the App rather than by Synapse; the device passes the values through for the App to read at startup.
{
"nodes": [
{
"type": "kBroadbandSource",
"id": 1,
"broadbandSource": {
"peripheralId": 100,
"bitWidth": 12,
"sampleRateHz": 32000,
"gain": 1,
"signal": {
"electrode": {
"channels": [
{ "id": 0, "electrodeId": 120, "referenceId": 513 },
{ "id": 1, "electrodeId": 122, "referenceId": 513 }
],
"lowCutoffHz": 57,
"highCutoffHz": 13489
}
}
}
},
{
"type": "kApplication",
"id": 2,
"application": {
"name": "synapse-example-app",
"parameters": {
"smoothing_ms": 25,
"output_scale": 1.5,
"publish_logs": true
}
}
}
],
"connections": [
{ "srcNodeId": 1, "dstNodeId": 2 }
]
}