Repository: mne-tools/mne-python

Issue:
BUG: `inverse_sparse` with `weights_min=None`
Doing:
```
stc_mxne = mixed_norm(
    evoked.copy().crop(0, 0.4), fwd, cov, alpha,
    weights=stc_dspm, weights_min=8., active_set_size=10,
    n_mxne_iter=n_mxne_iter, verbose=True)
```
is fine, but removing `weights_min=8.` (which takes it to the default `None`) yields:
```
  File "/Users/larsoner/python/mne-python/mne/inverse_sparse/mxne_inverse.py", line 358, in mixed_norm
    weights, weights_min)
  File "/Users/larsoner/python/mne-python/mne/inverse_sparse/mxne_inverse.py", line 65, in _prepare_gain
    forward, gain, source_weighting, weights, weights_min)
  File "</Users/larsoner/python/mne-python/mne/externals/decorator.py:decorator-gen-372>", line 2, in _prepare_weights
  File "/Users/larsoner/python/mne-python/mne/utils/_logging.py", line 89, in wrapper
    return function(*args, **kwargs)
  File "/Users/larsoner/python/mne-python/mne/inverse_sparse/mxne_inverse.py", line 29, in _prepare_weights
    if weights_min > weights_max:
TypeError: '<' not supported between instances of 'float' and 'NoneType'
```


Discussion:
@agramfort I see a few options, not sure which is preferable:

- enforce that if someone passes `weights` they must pass `weights_min`
- if `weights_min is None` then use some automatic criterion (e.g. 50th percentile / include half of all verts?)
- set `weights_min=0.` by default (but then if someone passes `weights` it will be effectively ignored, so not a great option)
weights_min=0. is fine with me


Resolving patch:
diff --git a/mne/inverse_sparse/mxne_inverse.py b/mne/inverse_sparse/mxne_inverse.py
--- a/mne/inverse_sparse/mxne_inverse.py
+++ b/mne/inverse_sparse/mxne_inverse.py
@@ -236,7 +236,7 @@ def make_stc_from_dipoles(dipoles, src, verbose=None):
 @verbose
 def mixed_norm(evoked, forward, noise_cov, alpha, loose='auto', depth=0.8,
                maxit=3000, tol=1e-4, active_set_size=10, pca=None,
-               debias=True, time_pca=True, weights=None, weights_min=None,
+               debias=True, time_pca=True, weights=None, weights_min=0.,
                solver='auto', n_mxne_iter=1, return_residual=False,
                return_as_dipoles=False, dgap_freq=10, rank=None,
                verbose=None):
@@ -467,7 +467,7 @@ def _window_evoked(evoked, size):
 @verbose
 def tf_mixed_norm(evoked, forward, noise_cov,
                   loose='auto', depth=0.8, maxit=3000,
-                  tol=1e-4, weights=None, weights_min=None, pca=True,
+                  tol=1e-4, weights=None, weights_min=0., pca=True,
                   debias=True, wsize=64, tstep=4, window=0.02,
                   return_residual=False, return_as_dipoles=False,
                   alpha=None, l1_ratio=None, dgap_freq=10, rank=None,


Test patch:
diff --git a/mne/inverse_sparse/tests/test_mxne_inverse.py b/mne/inverse_sparse/tests/test_mxne_inverse.py
--- a/mne/inverse_sparse/tests/test_mxne_inverse.py
+++ b/mne/inverse_sparse/tests/test_mxne_inverse.py
@@ -114,6 +114,7 @@ def test_mxne_inverse_standard():
     with pytest.warns(None):  # CD
         stc, _ = mixed_norm(evoked_l21, forward, cov, alpha, loose=loose,
                             depth=depth, maxit=300, tol=1e-8,
+                            weights=stc_dspm,  # gh-6382
                             active_set_size=10, return_residual=True,
                             solver='cd')
     assert_array_almost_equal(stc.times, evoked_l21.times, 5)