Drop elephant; add NumPy 2.x and Python 3.13 support#17
Merged
Conversation
…ee helper Add myogen.utils.bin_spike_trains, a dependency-free boolean spike-occupancy binner that exactly reproduces elephant.conversion.BinnedSpikeTrain (including its floating-point tolerance edge-snap and right-edge discard) without emitting the "shifting spikes to the next bin" warnings. Use it at the four spike-binning sites -- surface and intramuscular EMG (dense) and both force models (sparse) -- and remove the elephant import, the HAS_ELEPHANT guard, and the elephant-warning logger-suppression at each. elephant remains an optional extra (still used for firing-rate isi in utils/helper.py). Add an equivalence test asserting bit-identical output to elephant across grid, multi-train, fp-awkward, t_stop-edge, fractional-bin, sub-range-bounds, duplicate-spike and empty-train cases. Closes #16.
…tats calculate_firing_rate_statistics now derives inter-spike intervals with np.diff over the (sorted) spike times -- identical to elephant.statistics.isi for sorted SpikeTrains -- removing the last elephant import from the library. Restructure test_binning into self-contained golden tests (always run) plus elephant-equivalence tests gated on elephant being installed.
Replace elephant.statistics.mean_firing_rate with len/duration, time_histogram with a native numpy PSTH, instantaneous_rate (Gaussian KDE) with scipy gaussian_filter1d, and BinnedSpikeTrain with myogen.utils.bin_spike_trains. The viziphant rasterplot_rates in example 02 is replaced by a small native matplotlib raster (raster + marginal axes).
Remove the [elephant] optional extra and the elephant/viziphant entries from the dev and docs dependency-groups, and update the neo-block docs snippets to compute firing rate natively. import myogen, the test suite, and the docs build no longer require elephant. Add a CHANGELOG entry.
Address review: pass explicit lineoffsets to eventplot so each spike train renders on its own raster row, and drop spikes on the right bin edge (t_stop) before np.histogram so the native PSTH matches the old elephant binning.
With elephant removed (the reason for the cap), relax the runtime numpy requirement to >=1.26 and build the Cython extensions against numpy>=2.0. Wheels built against NumPy 2.0 stay backward-compatible with NumPy 1.x at runtime (verified: the compiled _gto extension imports under both NumPy 2.4 and 1.26). The scipy<1.17 build cap is unrelated (manylinux2014 wheel availability) and is left in place. Relates to #15.
Widen requires-python to >=3.12,<3.14, add the Python 3.13 classifier, and extend the CI test matrix and cibuildwheel build (cp312-* cp313-*) to 3.13. NEURON 8.2.7 already ships cp313 wheels, and the Cython extensions build and import under Python 3.13 against NumPy 2.x (verified locally on macOS arm64).
Now that build_wheels produces both cp312 and cp313 wheels, the test_wheels 'pip install dist/*.whl' tried to install both and pip rejected the wheel for the other ABI. Select the wheel matching the runner's Python tag instead.
…rtifacts v6/v7) Node 20 actions are deprecated (forced to Node 24 on 2026-06-16). Move actions/checkout to v5, actions/setup-python to v6, actions/upload-artifact to v6, and actions/download-artifact to v7 -- the minimal majors that run on Node 24 (artifact v5 and download v6 are still Node 20).
peaceiris/actions-gh-pages@v3 was node16 and softprops/action-gh-release@v1 was node16 (v2 is still node20); move to v4 and v3 respectively, both node24. Inputs are unchanged (github_token/publish_dir for peaceiris, files for softprops). pypa/cibuildwheel and pypa/gh-action-pypi-publish are composite actions and unaffected by the Node 20 deprecation.
scipy >= 1.17 only ships manylinux_2_28 wheels, so the cibuildwheel Linux base moves manylinux2014 -> manylinux_2_28 (glibc >= 2.28; drops EOL CentOS/RHEL 7) and the build-system scipy<1.17 cap is removed. The repair step tags wheels manylinux_2_28, and openblas-devel is dropped from the Linux pre-build deps (only needed for the old scipy source-build fallback, which no longer happens now that scipy installs from a wheel).
…7, py3.13) Regenerate the lockfile for the updated dependency set: elephant and viziphant removed, requires-python widened to >=3.12,<3.14, and numpy/scipy upgraded to 2.4.6 / 1.17.1 now that the <2.0 / <1.17 caps are gone.
np.trapz was removed in NumPy 2.0, which broke fiber_simulation under the upgraded lock (numpy 2.4). scipy.integrate.trapezoid has the same signature and works on both NumPy 1.26 and 2.x. Verified: full suite passes on numpy 2.4.6 / scipy 1.17.1.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A modernization pass unlocked by removing the
elephantdependency.Closes #16. Addresses #15 (numpy<2.0) — the pin is lifted here; the already-published 0.9.0 wheels stay <2.0 until the next release rebuilds them.
1. Remove
elephant(andviziphant) entirelymyogen/utils/bin_spike_trainsreplaceselephant.conversion.BinnedSpikeTrainat all 4 binning sites (surface + intramuscular EMG dense; both force models sparse) — verified bit-identical to elephant, and removes the warning-suppression hack.utils/helper.py:elephant.statistics.isi→numpy.diff(confirmed identical against elephant's source for sorted spike trains).mean_firing_rate→ len/duration,time_histogram→ native numpy PSTH,instantaneous_rate(Gaussian KDE) →scipy.ndimage.gaussian_filter1d,BinnedSpikeTrain→bin_spike_trains,viziphant.rasterplot_rates→ a small native matplotlib raster (the KDE/raster are cosmetic and look slightly different).[elephant]extra and the elephant/viziphant dev & docs deps; updated doc snippets.import myogen, the test suite, and the docs build no longer require elephant.2. NumPy 2.x support
numpy>=1.26,<2.0→numpy>=1.26; build-system now compiles againstnumpy>=2.0.scipy<1.17(build-only, manylinux2014 wheel availability — unrelated to elephant) is intentionally left in place; it does not restrict users.3. Python 3.13 support
requires-python→>=3.12,<3.14,Python :: 3.13classifier, and CI test + wheel matrices extended to 3.13 (cp312-* cp313-*).Verification
ruffclean;import myogenworks elephant-free.Known follow-ups (not in this PR)
_cython/*.soare tracked in git, so wheels package stale-ABI.so(harmless at runtime, bloats wheels) — worth untracking separately.scipy<1.17would need a manylinux2014 → manylinux_2_28 base bump (drops glibc<2.28) — separate CI change.