Skip to content

Releases: NsquaredLab/MyoGen

MyoGen 0.10.1

01 Jun 09:36

Choose a tag to compare

MyoGen 0.10.1 is a patch release that fixes a NumPy 2.0 regression introduced in 0.10.0.

If you drive descending-drive or afferent cells with single-sample neo AnalogSignal slices on NumPy 2.x, please upgrade — 0.10.0 raised TypeError: only 0-dimensional arrays can be converted to Python scalars in that documented usage pattern. Users passing plain floats were unaffected.

pip install --upgrade myogen   # or: uv add myogen

Fixed

  • NumPy 2.0 regression driving descending-drive / afferent cells. DD.integrate, DD_Gamma.integrate and AffIa.integrate now coerce their input to a scalar via np.asarray(y).item(), so driving a cell with a neo AnalogSignal slice (shape (1,)) works again under NumPy 2.0. Previously this raised TypeError: only 0-dimensional arrays can be converted to Python scalars (NumPy 2.0 no longer auto-casts a single-element array to a Python scalar), which broke the descending-drive example gallery. Covered by a regression test.
  • Docs gallery build. Corrected a wrong bin_spike_trains import (myogen.utilsmyogen.utils.binning) in the Watanabe visualization example, made the noise parameter-sweep example sphinx-gallery-safe (Path("./results") instead of Path(__file__)), and excluded the noise-calibration example from gallery execution since it requires a private iEMG recording that isn't available in CI.

Full changelog: https://github.com/NsquaredLab/MyoGen/blob/v0.10.1/CHANGELOG.md

Compare: v0.10.0...v0.10.1

MyoGen 0.10.0

01 Jun 05:10

Choose a tag to compare

MyoGen 0.10.0 is out! This is the first release with Python 3.13 and NumPy 2.x support, a new device-calibratable iEMG noise model, and optional GPU acceleration for SFAP computation. We also removed the elephant/viziphant dependency chain, making the core install lighter and easier to maintain.

pip install --upgrade myogen   # or: uv add myogen

Added

  • Device-calibratable iEMG noise model.
    Added a new myogen.utils.emg_noise module for generating colored intramuscular-EMG noise with parameters that can be calibrated from real recordings. Two new gallery examples demonstrate the workflow:

    • examples/01_basic/15_calibrate_noise_from_real.py
    • examples/01_basic/16_noise_parameter_sweep.py
  • Optional GPU acceleration for SFAP computation.
    Single-fiber action-potential and surface-EMG bioelectric computations can now run on NVIDIA GPUs via the new [gpu] optional extra using CuPy. A new use_gpu tri-state option — auto / on / off — selects the backend and falls back to NumPy when CuPy or a CUDA device is unavailable. The GPU-aware code paths prevent NumPy and CuPy arrays from being mixed accidentally.
    Contributed by @veylantis in #11.

  • Top-level simulator re-exports.
    ForceModelVectorized and the biomechanics classes are now importable directly from myogen.simulator.

  • Synaptic-delay control.
    Added connect_to_muscle(delay__ms=...) and an end-to-end synaptic_delay parameter for controlling conduction/synaptic delays through the spinal network.

  • Expanded regression test suite.
    Added tests covering unit safety, ForceModel/ForceModelVectorized parity, EMG accuracy, determinism, and NWB round-trips.

Changed

  • Python 3.13 support.
    requires-python is now widened to >=3.12,<3.14, a Python :: 3.13 classifier has been added, and the CI test and wheel matrices now cover Python 3.13.

  • NumPy 2.x support.
    With elephant removed, the previous numpy<2.0 pin is gone. The runtime requirement is now relaxed to numpy>=1.26, while the build system compiles the Cython extensions against NumPy 2.x. The compiled extensions were verified against both NumPy 2.x and NumPy 1.26.

  • Updated Linux wheel baseline.
    Linux wheels now target manylinux_2_28 instead of manylinux2014. This allows the SciPy build cap to be lifted, but it also means that EOL CentOS/RHEL 7 systems are no longer supported by the prebuilt Linux wheels.

  • ForceModelVectorized API alignment.
    Completed the contraction_time_range_factor rename and extracted shared helper functions so that ForceModel and ForceModelVectorized expose a more consistent interface.

  • Modernized typing.
    Replaced deprecated typing.Dict/List/Tuple/Callable annotations with PEP-585 builtin generics. The biomechanics __degrees argument was also renamed to __deg.

  • Packaging cleanup.
    The wheel now ships source files only, runtime dependencies are pinned more tightly, and the NEURON-home lookup helper was deduplicated.

  • CI and wheel builds.
    Wheels are now built for CPython 3.12 and 3.13 on Linux and macOS arm64. The macOS Intel build was dropped, and all GitHub Actions were updated to Node 24-compatible versions.

Removed

  • Removed the elephant and viziphant dependencies.
    Spike binning via elephant.conversion.BinnedSpikeTrain has been replaced by a dependency-free myogen.utils.bin_spike_trains helper. The replacement was verified to match the previous implementation across grid, edge, fractional, and sparse cases.

    elephant.statistics.isi in utils/helper.py has been replaced by numpy.diff, which is equivalent for sorted spike trains. The examples now compute firing rates, PSTHs, and rasters natively, with the previous viziphant raster replaced by a small matplotlib helper.

    The [elephant] optional extra and the elephant/viziphant dev/docs dependencies have therefore been removed. import myogen, the test suite, and the documentation build no longer require elephant.

Fixed

  • Surface EMG

    • Added exact Laplacian spatial filtering.
    • Corrected the FFT bin grid.
    • Improved handling of singular electrode inter-electrode distances.
    • Added RNG worker pre-generation for reproducible parallel draws.
    • Fixed an off-by-one error in the np.arange temporal-resampling grid.
  • Intramuscular EMG

    • Corrected shift_padding tail handling.
    • Corrected the shift_sfaps sign convention.
    • Added NumPy-2.0-safe scalar extraction.
  • RNG determinism

    • set_random_seed now resets per-cell ID counters.
    • The Hill durType=2 path is now seeded.
    • NWB exports are deterministic by default.
  • Other fixes

    • Group II afferent rectification is now applied per region instead of after summation.
    • Fixed a min_radial_dist unit mismatch in calc_sfaps. Contributed by @veylantis in #10.
    • Fixed a continuous_saver f-string bug that mangled a log message.
    • Replaced the removed np.trapz with scipy.integrate.trapezoid for NumPy 2.0 compatibility.
    • Corrected raster row offsets and PSTH right-edge binning in the examples.

New contributors

This release includes contributions from two first-time contributors — thank you both!

  • @veylantis contributed the calc_sfaps unit-mismatch fix in #10 and implemented the optional CuPy GPU acceleration for SFAP computation in #11.
  • @joaohbbittar suggested dropping the elephant dependency and relaxing the numpy<2.0 pin, which motivated two of this release’s headline changes: #15 and #16.

See everyone in the contributors list.

Full changelog: https://github.com/NsquaredLab/MyoGen/blob/main/CHANGELOG.md
Compare: v0.9.0...v0.10.0

MyoGen 0.9.0

19 Apr 06:39

Choose a tag to compare

This release fixes a long-standing reproducibility bug in the RNG architecture, introduces a proper accessor API for seeding, makes elephant a genuine optional dependency, and bundles the unified fiber-simulation pipeline with its validation test suite. Existing user code that imports myogen.RANDOM_GENERATOR or myogen.SEED continues to work but now emits a DeprecationWarning.

Highlights

  • RNG reproducibility fixset_random_seed() now propagates to every module and every seed-derived generator. New public accessors: myogen.get_random_generator(), myogen.get_random_seed(), myogen.derive_subseed(*labels).
  • elephant is now an optional extra — core install is elephant-free. Install with the extra if you need firing-rate statistics, NaN-safe ISI, or the viziphant raster plot example: pip install myogen[elephant].
  • NaN guards in firing-rate statisticscalculate_firing_rate_statistics no longer returns NaN for FR_std with a single active unit or for per-neuron CV_ISI with exactly two spikes.
  • Unified fiber-simulation pipeline — new simulate_fiber_hybrid (time-domain Rosenfalck source + frequency-domain volume conductor), an intramuscular Green's-function kernel, several Bessel / IFFT / electrode-coordinate correctness fixes, and a 26-case validation test suite against Hyser PhysioNet and the Avrillon/Caillet/Farina MU dictionary.
  • Figures, docs, tests — distribution plots replace bar graphs in three examples; new per-muscle VL/VM/FDI supplementary figure generator; NEURON 8.2.7 referenced consistently (including the correct Windows installer filename); tests/ directory bootstrapped with 40 passing tests; new tests CI workflow runs pytest on every PR.

Migration notes

  • Deprecated symbols. myogen.RANDOM_GENERATOR and myogen.SEED now resolve via a module-level __getattr__ that emits a DeprecationWarning. Replace
    from myogen import RANDOM_GENERATOR, SEED
    x = RANDOM_GENERATOR.normal()
    with
    from myogen import get_random_generator, get_random_seed
    x = get_random_generator().normal()
    The accessor reads the module-global at call time, so subsequent set_random_seed() calls are honoured (the direct import captured a stale reference).
  • RNG output changes. derive_subseed(*labels) replaces the previous SEED + (class_id+1)*(global_id+1) formula used at three sites in myogen/simulator/neuron/cells.py and the KMeans random_state in myogen/simulator/core/emg/intramuscular/motor_unit_sim.py. The old formula collided on swapped factors — e.g. (0, 5) and (1, 2) both resolved to +6. Consequence: for a given global seed, random draws differ from 0.8.5 and earlier. If you need byte-level reproduction of pre-0.9.0 outputs, pin that version.
  • elephant/viziphant optional. If you were relying on them being installed as core dependencies, switch to pip install myogen[elephant].

Full details

v0.8.5

15 Jan 23:01

Choose a tag to compare

Full Changelog: v0.8.4...v0.8.5

v0.8.4

06 Jan 18:25

Choose a tag to compare

Full Changelog: v0.8.2...v0.8.4

v0.8.3 (Preprint Version)

01 Jan 22:29

Choose a tag to compare

v0.8.2

28 Dec 20:05

Choose a tag to compare

Full Changelog: v0.8.1...v0.8.2

v0.8.1

28 Dec 16:03

Choose a tag to compare

Full Changelog: v0.7.0...v0.8.1

v0.7.0

24 Dec 13:17

Choose a tag to compare

Full Changelog: v0.6.11...v0.7.0

v0.6.12

17 Dec 04:19

Choose a tag to compare

Full Changelog: v0.6.11...v0.6.12