Skip to content

MyoGen 0.9.0

Choose a tag to compare

@RaulSimpetru RaulSimpetru released this 19 Apr 06:39
· 57 commits to main since this release

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