Custom Blocks
Custom blocks are ordinary Python functions decorated with the @block pattern and saved in backend/blocks/user/. They appear in the block library immediately after a server restart, behave identically to built-in blocks, and can be shared with collaborators as plain .py files.
Creating a custom block
Option 1 — Block wizard (recommended)
- Click + New block in the block library panel.
- Fill in the block name, description, input ports, output ports, and parameters in the form.
- Click Generate. SynapChart scaffolds the Python file for you and opens it in the built-in code editor.
- Write your analysis logic between the
# --- User code start ---and# --- User code end ---comments. - Click Save. The server hot-reloads the block — it appears in the library instantly.
Option 2 — Edit the file directly
Create a file in backend/blocks/user/my_block.py following this template:
from __future__ import annotations
from blocks.base import BlockBase, PortDefinition, ParameterDefinition
from neurodata.types import NeuroData
import numpy as np
class MyBlock(BlockBase):
block_type_id = "my_block" # unique snake_case ID
display_name = "My Block" # shown on the canvas
category = "Custom"
description = "One sentence describing what this block does."
is_custom = True
inputs = [
PortDefinition("signal", "NeuroData[raw_signal]", "Input signal."),
]
outputs = [
PortDefinition("result", "NeuroData[raw_signal]", "Processed output."),
]
parameters = [
ParameterDefinition("scale", "float", 1.0, "Scaling factor."),
]
def run(self, inputs: dict, parameters: dict) -> dict:
signal: NeuroData = inputs["signal"]
scale = float(parameters.get("scale", 1.0))
return {
"result": NeuroData(
data_type="raw_signal",
array=signal.array * scale,
sampling_rate=signal.sampling_rate,
timestamps=signal.timestamps,
)
}
Restart the SynapChart server (synapchart) and the block will appear in the Custom category.
What's always in scope inside run()
numpy (as np), NeuroData, and Path are always importable. Any other package must be imported explicitly inside run().
vsRef Channel (example)
vs_ref_channel
An auto-generated example block that selects one channel from a multi-channel signal and subtracts a reference channel — a common re-referencing step in LFP preprocessing.
Ports
| Port | Direction | Type | Description |
|---|---|---|---|
signal |
Input | NeuroData[raw_signal] |
Multi-channel signal (N_samples × N_channels) |
channel |
Output | NeuroData[raw_signal] |
Re-referenced single-channel signal (N_samples,) |
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
channel_index |
int | 0 |
Zero-based index of the channel to extract |
ref_channel_index |
int | 1 |
Zero-based index of the reference channel |
Tips
- Block IDs must be unique. If two files define the same
block_type_idthe second one wins — rename to avoid conflicts. - Sharing blocks. Copy the
.pyfile frombackend/blocks/user/into a collaborator'suser/folder and restart their server. - Dependencies. If your block requires a non-standard package, add it to
requirements.txtand import it insiderun()rather than at the module top level. - Type safety. Connect only compatible port types. The port validator will warn you if types don't match before you run the pipeline.