From 3174d738e663d046f54bc070b578d09455868591 Mon Sep 17 00:00:00 2001 From: Nikolai Kapralov <4dvlup@gmail.com> Date: Mon, 28 Oct 2024 12:36:10 +0100 Subject: [PATCH 1/3] MAINT: rename the RTD config file --- readthedocs.yaml => .readthedocs.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename readthedocs.yaml => .readthedocs.yaml (100%) diff --git a/readthedocs.yaml b/.readthedocs.yaml similarity index 100% rename from readthedocs.yaml rename to .readthedocs.yaml From 654107be709e01c01eda882134cddcfe57269058 Mon Sep 17 00:00:00 2001 From: Nikolai Kapralov <4dvlup@gmail.com> Date: Mon, 28 Oct 2024 12:45:37 +0100 Subject: [PATCH 2/3] MAINT: use ruff for linting and formatting --- .github/workflows/python-style.yml | 17 +++++++++++++++++ .pre-commit-config.yaml | 20 ++++++++++++++++++++ examples/snr_adjustment.py | 1 - pyproject.toml | 4 +++- src/meegsim/_check.py | 2 +- src/meegsim/sources.py | 2 +- src/meegsim/utils.py | 6 +++--- tests/test_configuration.py | 8 ++++---- tests/test_simulate.py | 6 +++--- tests/test_sources.py | 5 ++--- 10 files changed, 54 insertions(+), 17 deletions(-) create mode 100644 .github/workflows/python-style.yml create mode 100644 .pre-commit-config.yaml diff --git a/.github/workflows/python-style.yml b/.github/workflows/python-style.yml new file mode 100644 index 0000000..9cd3dfb --- /dev/null +++ b/.github/workflows/python-style.yml @@ -0,0 +1,17 @@ +name: Python Style + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +permissions: + contents: read + +jobs: + ruff: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: astral-sh/ruff-action@v1 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..827b782 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,20 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: + +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-added-large-files + +- repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.7.1 + hooks: + # Run the linter. + - id: ruff + args: [ --fix ] + # Run the formatter. + - id: ruff-format \ No newline at end of file diff --git a/examples/snr_adjustment.py b/examples/snr_adjustment.py index debc10b..5621207 100644 --- a/examples/snr_adjustment.py +++ b/examples/snr_adjustment.py @@ -3,7 +3,6 @@ """ import mne -import numpy as np import matplotlib.pyplot as plt from pathlib import Path diff --git a/pyproject.toml b/pyproject.toml index e1276c2..aeeebc9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,8 +31,10 @@ Issues = "https://github.com/ctrltz/meegsim/issues" dev = [ "harmoni", "mock", + "pre-commit", "pytest", - "pytest-cov" + "pytest-cov", + "ruff" ] docs = [ "intersphinx-registry", diff --git a/src/meegsim/_check.py b/src/meegsim/_check.py index d93a8f6..7cbcc9a 100644 --- a/src/meegsim/_check.py +++ b/src/meegsim/_check.py @@ -252,7 +252,7 @@ def check_names(names, n_sources, existing): raise ValueError(f"Expected all names to be strings, got {actual_type}: {name}") if not name: - raise ValueError(f"All names should not be empty") + raise ValueError("All names should not be empty") if name.startswith('auto'): raise ValueError(f"Name {name} should not start with auto, this prefix " diff --git a/src/meegsim/sources.py b/src/meegsim/sources.py index 0814536..de28ee5 100644 --- a/src/meegsim/sources.py +++ b/src/meegsim/sources.py @@ -8,7 +8,7 @@ import numpy as np import mne -from .utils import vertices_to_mne, get_sfreq, _extract_hemi +from .utils import vertices_to_mne, _extract_hemi class _BaseSource: diff --git a/src/meegsim/utils.py b/src/meegsim/utils.py index af1559c..0710492 100644 --- a/src/meegsim/utils.py +++ b/src/meegsim/utils.py @@ -119,9 +119,9 @@ def _extract_hemi(src): if src['id'] == FIFF.FIFFV_MNE_SURF_RIGHT_HEMI: return 'rh' - raise ValueError(f"Unexpected ID for the provided surface source space. " - f"Please check the code that was used to generate and/or " - f"manipulate the src, it should not change the 'id' field.") + raise ValueError("Unexpected ID for the provided surface source space. " + "Please check the code that was used to generate and/or " + "manipulate the src, it should not change the 'id' field.") def get_sfreq(times): diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 997300b..1f90831 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -105,12 +105,12 @@ def test_sourceconfiguration_to_raw(apply_forward_mock): apply_forward_mock.assert_called() stc = apply_forward_mock.call_args.args[1] assert np.all(stc.data == 1e-6), \ - f"Default scaling factor was not applied correctly" - assert raw == 0, f"Output of apply_forward_raw should not be changed" + "Default scaling factor was not applied correctly" + assert raw == 0, "Output of apply_forward_raw should not be changed" raw = sc.to_raw([], [], scaling_factor=10) apply_forward_mock.assert_called() stc = apply_forward_mock.call_args.args[1] assert np.all(stc.data == 10), \ - f"Custom scaling factor was not applied correctly" - assert raw == 0, f"Output of apply_forward_raw should not be changed" + "Custom scaling factor was not applied correctly" + assert raw == 0, "Output of apply_forward_raw should not be changed" diff --git a/tests/test_simulate.py b/tests/test_simulate.py index 3f49466..3d5d455 100644 --- a/tests/test_simulate.py +++ b/tests/test_simulate.py @@ -46,7 +46,7 @@ def test_sourcesimulator_add_point_sources(): assert len(sim._sources) == 8, \ f"Expected eight sources to be created, got {len(sim._sources)}" assert all([name in sim._sources for name in custom_names]), \ - f"Provided source names were not used properly" + "Provided source names were not used properly" # Add one group with already existing names with pytest.raises(ValueError): @@ -92,7 +92,7 @@ def test_sourcesimulator_add_patch_sources(): assert len(sim._sources) == 4, \ f"Expected four sources to be created, got {len(sim._sources)}" assert all([name in sim._sources for name in custom_names]), \ - f"Provided source names were not used properly" + "Provided source names were not used properly" # Add one group with already existing names with pytest.raises(ValueError): @@ -354,7 +354,7 @@ def test_simulate(): src, times=times, fwd=None, random_state=0) assert len(simulate_mock.call_args_list) == 3, \ - f"Expected three calls of PointSourceGroup.simulate method" + "Expected three calls of PointSourceGroup.simulate method" random_states = [kall.kwargs['random_state'] == 0 for kall in simulate_mock.call_args_list] diff --git a/tests/test_sources.py b/tests/test_sources.py index 20ddee6..6c76f0a 100644 --- a/tests/test_sources.py +++ b/tests/test_sources.py @@ -1,4 +1,3 @@ -import unittest from unittest.mock import MagicMock, patch import numpy as np @@ -61,7 +60,7 @@ def test_pointsource_to_stc(src_idx, vertno): assert vertno in stc.vertices[src_idx], \ f"Expected the vertex to be put in src {src_idx}, but it is not there" assert np.allclose(stc.data, waveform), \ - f"The source waveform should not change during conversion to stc" + "The source waveform should not change during conversion to stc" @pytest.mark.parametrize("tstep", [0.01, 0.025, 0.05]) @@ -220,7 +219,7 @@ def test_patchsource_to_stc(src_idx, vertno): assert np.all(vertno in stc.vertices[src_idx]), \ f"Expected all vertno to be put in src {src_idx}" assert np.allclose(stc.data, waveform), \ - f"The source waveform should not change during conversion to stc" + "The source waveform should not change during conversion to stc" def test_patchsource_to_stc_bad_src_raises(): From 0019e615508d836e76901d3d52fab6ffdc07ea94 Mon Sep 17 00:00:00 2001 From: Nikolai Kapralov <4dvlup@gmail.com> Date: Mon, 28 Oct 2024 12:50:44 +0100 Subject: [PATCH 3/3] REF: remove the outdated usage example --- examples/usage.py | 42 ------------------------------------------ 1 file changed, 42 deletions(-) delete mode 100644 examples/usage.py diff --git a/examples/usage.py b/examples/usage.py deleted file mode 100644 index 1de1aca..0000000 --- a/examples/usage.py +++ /dev/null @@ -1,42 +0,0 @@ -""" -Planned usage - as a first milestone, it would be nice to get this script to work. -""" - -import numpy as np - -from functools import partial - -from meegsim import SourceConfiguration -from meegsim.location import select_random, select_random_in_labels -from meegsim.waveform import narrowband_oscillation - - -# Users can create such shortcuts if needed -alpha_oscillation = partial(narrowband_oscillation, - fmin=8, fmax=12, order=2) - -sc = SourceConfiguration(src, sfreq, duration, random_state=0) - -# Point sources of alpha -alpha_vertices = select_random_in_labels(src, labels) -sc.add_point_sources(alpha_vertices, waveform=alpha_oscillation, snr=1, - names=['m1-left', 's1-left', 'm1-right', 's1-right']) - -# Point sources with 1/f noise, separate function allows marking these sources as noise for SNR calculations -sc.add_noise_sources(select_random, location_params=dict(n=1000)) - -# TODO: add patch sources -sc.add_patch_sources() - -# Coupling is a dictionary with connectivity edges as keys and coupling parameters as values -coupling = { - ('m1-left', 's1-left'): dict(kappa=1, dphi=np.pi/2), - ('m1-left', 'm1-right'): dict(kappa=0.5, dphi=np.pi/4) -} -sc.set_coupling(coupling, coupling_fun='ppc_von_mises') - -# Project to sensor space, optionally get corresponding stc -raw, stc = sc.simulate_raw(fwd, return_stc=True) - -# Quick access of ground truth waveforms for sources of interest -gt = sc.get_waveforms(['m1-left', 'm1-right']) \ No newline at end of file