Basics¶
This example gallery contains tutorials demonstrating core functionality and workflow patterns. These examples cover the essential building blocks, from motor-unit recruitment to EMG signal generation.
Note
The gallery is source-only by default: examples are rendered from source but
are not executed during a normal documentation build. Thumbnails and
screenshots may reflect a prior verified run, so run an example locally to
reproduce its outputs. Maintainers can opt into execution with
MKDOCS_GALLERY_PLOT=true.
The examples are self-contained and can be run independently, though they may depend on each other for context. Following the numbered order provides the best learning experience.
Profiles¶
Examples 01, 03, 04, 05, 06 and 08 simulate the first dorsal interosseous (FDI)
with the fdi_semg profile card (myogen/profiles/fdi_semg.yaml): every
validated setting in one place, each value with its source.
from myogen import load_profile
card = load_profile() # fdi_semg
run = card.simulate([(1, 0, 0), (4, 0, 25), (4, 25, 25), (4, 25, 0), (1, 0, 0)]) # % MVC
muscle = card.muscle()
semg = card.surface_emg(muscle, electrode_arrays) # your electrodes
- Override a value with a keyword, e.g.
card.muscle(fat_thickness__mm=3 * pq.mm). The override stays on that card object for every later build (card.thresholds(n_units=60)thencard.muscle()builds 60 units); passing the card value again clears it. Use a freshload_profile()for the card as is. - Other keywords (electrodes, sampling, units to simulate, ...) pass through to the class and are
listed under
keywordsin the built object'sprofile_record. - Notes: when an overridden value is one the drive calibration or the λ fit
depends on, the card prints a note (once per card and field per run) saying what else to check.
Silence them with
warnings.simplefilter("ignore", myogen.ProfileNote). - Record:
card.record()lists the card, its version and every override; built objects carry it asprofile_record, spike and surface-EMG blocks as themyogen_profileannotation. - Seeds: each builder draws its build from its own seed (the card's
seeds, orseed=; recorded asseed), so a build does not depend on what ran before it, and then gives your generator and seed back. This differs from the rest of MyoGen, where library code never seeds and the script owns the seed (oneset_random_seedcall, or the default 180319, for the whole script). - What reproduces: on any platform,
card.thresholds()andcard.muscle()give the validated thresholds and fibres (each fibre's motor unit, diameter and conduction velocity).card.simulate()gives the same spikes up to NEURON's floating point, which differs between platforms: spike times can shift by a time step, and a unit can gain or lose a spike near the end of a run (in the library's test run, Linux fires 2001 spikes where macOS and Windows fire 2000). sEMG from a card therefore matches the validation within its limits, not bit for bit. - Sampling: generate sEMG at 2048 Hz (the
SurfaceEMGdefault) and iEMG at 10240 Hz. The card's validation (benchmarks/profiles/validate_card.py) records sEMG at 10240 Hz only to score the 20-2000 Hz band of its Delsys comparator. load_profile("fdi_semg.published")gives each component as its source paper describes it (for comparison with those papers and older MyoGen results).
Download all examples in Python source code: 01_basic_python.zip
Download all examples in Jupyter notebooks: 01_basic_jupyter.zip