Skip to content

Commit

Permalink
MAINT: Enable vulture (#12569)
Browse files Browse the repository at this point in the history
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
  • Loading branch information
larsoner and autofix-ci[bot] authored Apr 23, 2024
1 parent 0d781c8 commit 7d36247
Show file tree
Hide file tree
Showing 19 changed files with 121 additions and 125 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ jobs:
with:
python-version: '3.12'
- uses: pre-commit/[email protected]
- run: pip install mypy numpy scipy vulture
- run: mypy
- run: vulture

bandit:
name: Bandit
Expand Down
19 changes: 11 additions & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,14 @@ repos:
- tomli
files: ^doc/.*\.(rst|inc)$

# mypy
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.9.0
hooks:
- id: mypy
# Avoid the conflict between mne/__init__.py and mne/__init__.pyi by ignoring the former
exclude: ^mne/(beamformer|channels|commands|datasets|decoding|export|forward|gui|html_templates|inverse_sparse|io|minimum_norm|preprocessing|report|simulation|source_space|stats|time_frequency|utils|viz)?/?__init__\.py$
additional_dependencies: ["numpy==1.26.2"]
# The following are too slow to run on local commits, so let's only run on CIs:
#
# - repo: https://github.com/pre-commit/mirrors-mypy
# rev: v1.9.0
# hooks:
# - id: mypy
#
# - repo: https://github.com/jendrikseipp/vulture
# rev: 'v2.11' # or any later Vulture version
# hooks:
# - id: vulture
7 changes: 7 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ stages:
make check-readme
displayName: make check-readme
condition: always()
- bash: mypy
displayName: mypy
condition: always()
- bash: vulture
displayName: vulture
condition: always()


- stage: Test
condition: and(succeeded(), eq(dependencies.Check.outputs['Skip.result.start_main'], 'true'))
Expand Down
1 change: 1 addition & 0 deletions doc/changes/devel/12569.other.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added `vulture <https://github.com/jendrikseipp/vulture>`__ as a pre-commit hook and removed related dead code, by `Eric Larson`_.
1 change: 1 addition & 0 deletions mne/commands/mne_flash_bem.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

def _vararg_callback(option, opt_str, value, parser):
assert value is None
del opt_str # required for input but not used
value = []

for arg in parser.rargs:
Expand Down
58 changes: 2 additions & 56 deletions mne/inverse_sparse/mxne_optim.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,13 @@ def dgap_l21(M, G, X, active_set, alpha, n_orient):
return gap, p_obj, d_obj, R


@verbose
def _mixed_norm_solver_cd(
M,
G,
alpha,
lipschitz_constant,
maxit=10000,
tol=1e-8,
verbose=None,
init=None,
n_orient=1,
dgap_freq=10,
Expand Down Expand Up @@ -173,15 +171,13 @@ def _mixed_norm_solver_cd(
return X, active_set, p_obj


@verbose
def _mixed_norm_solver_bcd(
M,
G,
alpha,
lipschitz_constant,
maxit=200,
tol=1e-8,
verbose=None,
init=None,
n_orient=1,
dgap_freq=10,
Expand Down Expand Up @@ -667,7 +663,6 @@ def gprime(w):
active_set_size=active_set_size,
dgap_freq=dgap_freq,
solver=solver,
verbose=verbose,
)
else:
X, _active_set, _ = mixed_norm_solver(
Expand All @@ -681,7 +676,6 @@ def gprime(w):
active_set_size=None,
dgap_freq=dgap_freq,
solver=solver,
verbose=verbose,
)
else:
X, _active_set, _ = mixed_norm_solver(
Expand All @@ -695,7 +689,6 @@ def gprime(w):
active_set_size=None,
dgap_freq=dgap_freq,
solver=solver,
verbose=verbose,
)

logger.info("active set size %d" % (_active_set.sum() / n_orient))
Expand Down Expand Up @@ -735,46 +728,6 @@ def gprime(w):
# TF-MxNE


@verbose
def tf_lipschitz_constant(M, G, phi, phiT, tol=1e-3, verbose=None):
"""Compute lipschitz constant for FISTA.
It uses a power iteration method.
"""
n_times = M.shape[1]
n_points = G.shape[1]
iv = np.ones((n_points, n_times), dtype=np.float64)
v = phi(iv)
L = 1e100
for it in range(100):
L_old = L
logger.info("Lipschitz estimation: iteration = %d" % it)
iv = np.real(phiT(v))
Gv = np.dot(G, iv)
GtGv = np.dot(G.T, Gv)
w = phi(GtGv)
L = np.max(np.abs(w)) # l_inf norm
v = w / L
if abs((L - L_old) / L_old) < tol:
break
return L


def safe_max_abs(A, ia):
"""Compute np.max(np.abs(A[ia])) possible with empty A."""
if np.sum(ia): # ia is not empty
return np.max(np.abs(A[ia]))
else:
return 0.0


def safe_max_abs_diff(A, ia, B, ib):
"""Compute np.max(np.abs(A)) possible with empty A."""
A = A[ia] if np.sum(ia) else 0.0
B = B[ib] if np.sum(ia) else 0.0
return np.max(np.abs(A - B))


class _Phi:
"""Have phi stft as callable w/o using a lambda that does not pickle."""

Expand Down Expand Up @@ -1146,15 +1099,14 @@ def _tf_mixed_norm_solver_bcd_(
lipschitz_constant,
phi,
phiT,
*,
w_space=None,
w_time=None,
n_orient=1,
maxit=200,
tol=1e-8,
dgap_freq=10,
perc=None,
timeit=True,
verbose=None,
):
n_sources = G.shape[1]
n_positions = n_sources // n_orient
Expand Down Expand Up @@ -1282,7 +1234,6 @@ def _tf_mixed_norm_solver_bcd_(
return Z, active_set, E, converged


@verbose
def _tf_mixed_norm_solver_bcd_active_set(
M,
G,
Expand All @@ -1291,14 +1242,14 @@ def _tf_mixed_norm_solver_bcd_active_set(
lipschitz_constant,
phi,
phiT,
*,
Z_init=None,
w_space=None,
w_time=None,
n_orient=1,
maxit=200,
tol=1e-8,
dgap_freq=10,
verbose=None,
):
n_sensors, n_times = M.shape
n_sources = G.shape[1]
Expand Down Expand Up @@ -1344,7 +1295,6 @@ def _tf_mixed_norm_solver_bcd_active_set(
maxit=1,
tol=tol,
perc=None,
verbose=verbose,
)

E += E_tmp
Expand Down Expand Up @@ -1380,7 +1330,6 @@ def _tf_mixed_norm_solver_bcd_active_set(
tol=tol,
dgap_freq=dgap_freq,
perc=0.5,
verbose=verbose,
)
active = np.where(active_set[::n_orient])[0]
active_set[active_set] = as_.copy()
Expand Down Expand Up @@ -1535,7 +1484,6 @@ def tf_mixed_norm_solver(
maxit=maxit,
tol=tol,
dgap_freq=dgap_freq,
verbose=None,
)

if np.any(active_set) and debias:
Expand All @@ -1548,7 +1496,6 @@ def tf_mixed_norm_solver(
return X, active_set, E


@verbose
def iterative_tf_mixed_norm_solver(
M,
G,
Expand Down Expand Up @@ -1692,7 +1639,6 @@ def g_time_prime_inv(Z):
maxit=maxit,
tol=tol,
dgap_freq=dgap_freq,
verbose=None,
)

active_set[active_set] = active_set_
Expand Down
2 changes: 1 addition & 1 deletion mne/io/fieldtrip/tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def get_evoked(system):
return epochs.average(picks=np.arange(len(epochs.ch_names)))


def check_info_fields(expected, actual, has_raw_info, ignore_long=True):
def check_info_fields(expected, actual, has_raw_info):
"""
Check if info fields are equal.
Expand Down
2 changes: 1 addition & 1 deletion mne/minimum_norm/inverse.py
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,7 @@ def _assemble_kernel(inv, label, method, pick_ori, use_cps=True, verbose=None):
return K, noise_norm, vertno, source_nn


def _check_ori(pick_ori, source_ori, src, allow_vector=True):
def _check_ori(pick_ori, source_ori, src):
"""Check pick_ori."""
_check_option("pick_ori", pick_ori, [None, "normal", "vector"])
_check_src_normal(pick_ori, src)
Expand Down
2 changes: 1 addition & 1 deletion mne/preprocessing/_csd.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ def compute_bridged_electrodes(
return bridged_idx, ed_matrix

# kernel density estimation
kde = gaussian_kde(ed_flat[ed_flat < lm_cutoff])
kde = gaussian_kde(ed_flat[ed_flat < lm_cutoff], bw_method=bw_method)
with np.errstate(invalid="ignore"):
local_minimum = float(
minimize_scalar(
Expand Down
6 changes: 3 additions & 3 deletions mne/surface.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@ def _safe_query(rr, func, reduce=False, **kwargs):
class _DistanceQuery:
"""Wrapper for fast distance queries."""

def __init__(self, xhs, method="BallTree", allow_kdtree=False):
def __init__(self, xhs, method="BallTree"):
assert method in ("BallTree", "KDTree", "cdist")

# Fastest for our problems: balltree
Expand Down Expand Up @@ -1660,7 +1660,7 @@ def _find_nearest_tri_pts(
else:
use_pt_tris = s.astype(np.int64)
pp, qq, ptt, distt = _nearest_tri_edge(
use_pt_tris, rr[0], pqs[s], dists[s], a, b, c
use_pt_tris, pqs[s], dists[s], a, b, c
)
if np.abs(distt) < np.abs(dist):
p, q, pt, dist = pp, qq, ptt, distt
Expand All @@ -1676,7 +1676,7 @@ def _find_nearest_tri_pts(


@jit()
def _nearest_tri_edge(pt_tris, to_pt, pqs, dist, a, b, c): # pragma: no cover
def _nearest_tri_edge(pt_tris, pqs, dist, a, b, c): # pragma: no cover
"""Get nearest location from a point to the edge of a set of triangles."""
# We might do something intelligent here. However, for now
# it is ok to do it in the hard way
Expand Down
74 changes: 37 additions & 37 deletions mne/time_frequency/tests/test_stft.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,50 +21,50 @@
def test_stft(T, wsize, tstep, f):
"""Test stft and istft tight frame property."""
sfreq = 1000.0 # Hz
if True: # just to minimize diff
# Test with low frequency signal
t = np.arange(T).astype(np.float64)
x = np.sin(2 * np.pi * f * t / sfreq)
x = np.array([x, x + 1.0])
X = stft(x, wsize, tstep)
xp = istft(X, tstep, Tx=T)

freqs = stftfreq(wsize, sfreq=sfreq)
# Test with low frequency signal
t = np.arange(T).astype(np.float64)
x = np.sin(2 * np.pi * f * t / sfreq)
x = np.array([x, x + 1.0])
X = stft(x, wsize, tstep)
xp = istft(X, tstep, Tx=T)

max_freq = freqs[np.argmax(np.sum(np.abs(X[0]) ** 2, axis=1))]
freqs = stftfreq(wsize, sfreq=sfreq)

assert X.shape[1] == len(freqs)
assert np.all(freqs >= 0.0)
assert np.abs(max_freq - f) < 1.0
assert_array_almost_equal(x, xp, decimal=6)
max_freq = freqs[np.argmax(np.sum(np.abs(X[0]) ** 2, axis=1))]

# norm conservation thanks to tight frame property
assert_almost_equal(
np.sqrt(stft_norm2(X)), [linalg.norm(xx) for xx in x], decimal=6
)
assert X.shape[1] == len(freqs)
assert np.all(freqs >= 0.0)
assert np.abs(max_freq - f) < 1.0
assert_array_almost_equal(x, xp, decimal=6)

# Test with random signal
x = np.random.randn(2, T)
wsize = 16
tstep = 8
X = stft(x, wsize, tstep)
xp = istft(X, tstep, Tx=T)
# norm conservation thanks to tight frame property
assert_almost_equal(
np.sqrt(stft_norm2(X)), [linalg.norm(xx) for xx in x], decimal=6
)

freqs = stftfreq(wsize, sfreq=1000)
# Test with random signal
x = np.random.randn(2, T)
wsize = 16
tstep = 8
X = stft(x, wsize, tstep)
xp = istft(X, tstep, Tx=T)

max_freq = freqs[np.argmax(np.sum(np.abs(X[0]) ** 2, axis=1))]
freqs = stftfreq(wsize, sfreq=1000)

assert X.shape[1] == len(freqs)
assert np.all(freqs >= 0.0)
assert_array_almost_equal(x, xp, decimal=6)
max_freq = freqs[np.argmax(np.sum(np.abs(X[0]) ** 2, axis=1))]

# norm conservation thanks to tight frame property
assert_almost_equal(
np.sqrt(stft_norm2(X)), [linalg.norm(xx) for xx in x], decimal=6
)
assert X.shape[1] == len(freqs)
assert np.all(freqs >= 0.0)
assert_array_almost_equal(x, xp, decimal=6)

# Try with empty array
x = np.zeros((0, T))
X = stft(x, wsize, tstep)
xp = istft(X, tstep, T)
assert xp.shape == x.shape
# norm conservation thanks to tight frame property
assert_almost_equal(
np.sqrt(stft_norm2(X)), [linalg.norm(xx) for xx in x], decimal=6
)

# Try with empty array
x = np.zeros((0, T))
X = stft(x, wsize, tstep)
xp = istft(X, tstep, T)
assert xp.shape == x.shape
Loading

0 comments on commit 7d36247

Please sign in to comment.