A template for your lab-specific Stimpack configuration: rig configs, protocols, custom stimuli, and device drivers.
Stimpack documentation and quick start
Worth reading before writing protocols, since they cover the things a labpack gets wrong quietly: modules and targeting (an untargeted call goes to the server's root node, not to every module), checking a labpack, and how a run ended.
Stimpack itself ships no lab-specific configuration. You make your own copy of this repo, rename and edit the pieces below, and point stimpack at it — stimpack then loads your modules dynamically at runtime.
-
Press Use this template at the top of this page to create your lab's own repository, then clone it. (You can make it private — rig configs, data paths and experimenter names usually should be. A fork of a public repo cannot be private; a template copy can.)
git clone https://github.com/<your-org>/<your-labpack> cd <your-labpack> -
Rename the Python package for your lab, then install it (Python >= 3.10;
stimpackcomes as a dependency):python scripts/rename_package.py smithlab_pack # --dry-run first, to see what it will touch pip install -e .Add hardware drivers only if the rig needs them:
pip install -e .[nidaq]or.[labjack].The package here is called
template_labpackso it can be installed side by side with an existing labpack. Renaming it means yours can be too — and that a traceback says whose code it is in. The script updates the four places that have to agree: the package directory,name/packagesinsetup.py, thefrom template_labpack...imports, and themodule_pathsentries in every config.Stimpack never imports your labpack by name. It resolves the directory recorded in
path_to_labpack.txtand loads your modules by file path, so the name is yours to choose. -
Launch the GUI (
stimpack) and use Labpack Dir in the startup dialog to point at this directory. The choice is remembered inpath_to_labpack.txtin stimpack's user config dir. -
Copy
configs/example_config.yamltoconfigs/<yourlab>_config.yamland edit it. It appears in the startup dialog's config dropdown.
pip install -e .[test]
pytestA labpack holds the rig-specific code, so it holds the rig-specific mistakes, and those are the ones
that cost an experiment. More is testable without hardware than it looks: tests/ ships with a
worked example that checks the projector's pattern LUT against TI's documentation without a
projector. See tests/README.md.
GitHub Actions runs them on 3.10 to 3.12 (.github/workflows/test.yml).
A template copy shares no git history with this repo, so there is no git pull from it. When
stimpack changes how labpacks talk to it, the way to find out is to run stimpack's labpack check
against your copy rather than to diff against the template:
stimpack --check-labpack # validates this labpack against the installed stimpack
| Path | What it is / what to edit |
|---|---|
configs/*.yaml |
Rig configs: experimenter, subject metadata fields, per-rig settings, and module_paths. Start here. |
template_labpack/protocol/base_protocol.py |
Lab-wide protocol base. Put helpers shared by all your protocols here. |
template_labpack/protocol/JohnDoe_protocol.py |
Example protocols. Rename to <you>_protocol.py and write your own; every BaseProtocol subclass appears in the GUI dropdown. |
template_labpack/visual_stim/example/ |
Custom stimuli, shapes, trajectories and distributions. These are exec'd on the server; subclasses of stimpack's BaseProgram / Trajectory / Distribution become usable by name. |
template_labpack/device/daq.py |
DAQ drivers (NI, LabJack) and the DAQonServer proxy used when the DAQ lives on the rig machine. Referenced by the trigger: string in a rig config. |
template_labpack/device/dlpc350.py |
TI DLPC350 projectors (LightCrafter 4500 and the optical engines built on it). Sets pattern mode, LED currents, and can display the three colour channels of a frame as successive patterns — a 120 Hz link driving the DMD at 360 Hz. |
template_labpack/device/locomotion/ |
Locomotion managers (e.g. FicTrac). Subclass stimpack's LocoClosedLoopManager and implement _parse_line. |
template_labpack/client.py, template_labpack/data.py |
Empty passthroughs over stimpack's BaseClient / BaseData — override here if you need custom client behavior or a different data layout. |
server/example_server.py |
Example rig server: screen geometry, locomotion, DAQ. Copy one per rig. |
server/base_server.py |
Lab-wide server base; forwards everything to stimpack's BaseServer. |
tests/ |
Your tests. Hardware drivers can be stubbed and the bytes they would send checked against the manufacturer's documentation, with no rig attached — see tests/README.md. |
-
Custom stimuli must be listed under
module_paths.visual_stimin your config. An older layout usedserver_options.visual_stim_module_paths; current stimpack does not read that key, so stimuli listed there are never loaded and referencing them fails with "0 stimulus candidates". -
Protocols reference stimuli by class name, not by import, e.g.
self.epoch_stim_parameters = {'name': 'MovingPatch', ...}. The name is resolved on the server against every loadedBaseProgramsubclass — so a stimulus is available as soon as its module is loaded, with no registration step. -
Binding: stimpack's server binds loopback (
127.0.0.1) by default, because the RPC control channel is unauthenticated. For a remote client, set the rig's address explicitly in that rig's server script and firewall the port to the trusted rig network. -
One protocol, several rigs. The server tells the client which modules it has, so a protocol can adapt instead of assuming the hardware:
if self.has_module('voltage_out') and self.epoch_protocol_parameters['opto_amp'] > 0: multicall.target('voltage_out').setup_pulse_wave_stream_out( channels_config={'name': self.opto['channel'], 'high': amp, 'low': 0.0}, ...)
voltage_outis the module for anything driven by an output voltage — optogenetics, odor, reward, shock. (target('daq')still works and maps to it, with a one-time deprecation warning.)has_module()returns True when the server hasn't advertised, so adopting it changes nothing until the server reports. What is wired to that voltage — an LED, a valve, on which channel — is lab-specific: keep it in your ownrig_configkeys, as with the commented‑outopto:example.