Skip to content

Commit

Permalink
MAINT: Use explicitly public APIs (#521)
Browse files Browse the repository at this point in the history
Co-authored-by: Daniel McCloy <[email protected]>
  • Loading branch information
larsoner and drammock authored Aug 22, 2023
1 parent b518247 commit c7cf346
Show file tree
Hide file tree
Showing 14 changed files with 93 additions and 87 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/macos_conda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ jobs:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: conda-incubator/setup-miniconda@v2
- uses: mamba-org/setup-micromamba@v1
with:
activate-environment: 'mne-nirs'
python-version: ${{ env.PYTHON_VERSION }}
environment-file: ${{ env.CONDA_ENV }}
environment-name: 'mne-nirs'
create-args: >-
python=${{ env.PYTHON_VERSION }}
name: 'Setup conda'
- shell: bash -el {0}
run: |
Expand Down
50 changes: 25 additions & 25 deletions examples/general/plot_10_hrf_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
design_matrix = make_first_level_design_matrix(raw, stim_dur=5.0,
drift_order=1,
drift_model='polynomial')
fig, ax1 = plt.subplots(figsize=(10, 6), nrows=1, ncols=1)
fig, ax1 = plt.subplots(figsize=(10, 6), constrained_layout=True)
fig = plot_design_matrix(design_matrix, ax=ax1)


Expand Down Expand Up @@ -98,20 +98,20 @@ def print_results(glm_est, truth):
# and plot the noisy data and the GLM fitted model.
# We print the response estimate and see that is close, but not exactly correct,
# we observe the mean square error is similar to the added noise.
# Note that the clean data plot is so similar to the GLM estimate that it is hard to see unless zoomed in.
# Note that the clean data plot is so similar to the GLM estimate that it is hard to see unless zoomed in.

# First take a copy of noise free data for comparison
raw_noise_free = raw.copy()

raw._data += np.random.normal(0, np.sqrt(1e-11), raw._data.shape)
glm_est = run_glm(raw, design_matrix)

plt.plot(raw.times, raw_noise_free.get_data().T * 1e6)
plt.plot(raw.times, raw.get_data().T * 1e6, alpha=0.3)
plt.plot(raw.times, glm_est.theta()[0][0] * design_matrix["A"].values * 1e6)
plt.xlabel("Time (s)")
plt.ylabel("Haemoglobin (uM)")
plt.legend(["Clean Data", "Noisy Data", "GLM Estimate"])
fig, ax = plt.subplots(constrained_layout=True)
ax.plot(raw.times, raw_noise_free.get_data().T * 1e6)
ax.plot(raw.times, raw.get_data().T * 1e6, alpha=0.3)
ax.plot(raw.times, glm_est.theta()[0][0] * design_matrix["A"].values * 1e6)
ax.set(xlabel="Time (s)", ylabel="Haemoglobin (μM)")
ax.legend(["Clean Data", "Noisy Data", "GLM Estimate"])

print_results(glm_est, amp)

Expand All @@ -138,12 +138,12 @@ def print_results(glm_est, truth):
drift_model='polynomial')
glm_est = run_glm(raw, design_matrix)

plt.plot(raw.times, raw_noise_free.get_data().T * 1e6)
plt.plot(raw.times, raw.get_data().T * 1e6, alpha=0.3)
plt.plot(raw.times, glm_est.theta()[0][0] * design_matrix["A"].values * 1e6)
plt.xlabel("Time (s)")
plt.ylabel("Haemoglobin (uM)")
plt.legend(["Clean Data", "Noisy Data", "GLM Estimate"])
fig, ax = plt.subplots(constrained_layout=True)
ax.plot(raw.times, raw_noise_free.get_data().T * 1e6)
ax.plot(raw.times, raw.get_data().T * 1e6, alpha=0.3)
ax.plot(raw.times, glm_est.theta()[0][0] * design_matrix["A"].values * 1e6)
ax.set(xlabel="Time (s)", ylabel="Haemoglobin (μM)")
ax.legend(["Clean Data", "Noisy Data", "GLM Estimate"])

print_results(glm_est, amp)

Expand Down Expand Up @@ -171,11 +171,11 @@ def print_results(glm_est, truth):
drift_model='polynomial')
glm_est = run_glm(raw, design_matrix)

plt.plot(raw.times, raw.get_data().T * 1e6, alpha=0.3)
plt.plot(raw.times, glm_est.theta()[0][0] * design_matrix["A"].values * 1e6)
plt.xlabel("Time (s)")
plt.ylabel("Haemoglobin (uM)")
plt.legend(["Noisy Data", "GLM Estimate"])
fig, ax = plt.subplots(constrained_layout=True)
ax.plot(raw.times, raw.get_data().T * 1e6, alpha=0.3)
ax.plot(raw.times, glm_est.theta()[0][0] * design_matrix["A"].values * 1e6)
ax.set(xlabel="Time (s)", ylabel="Haemoglobin (μM)")
ax.legend(["Noisy Data", "GLM Estimate"])

print_results(glm_est, amp)

Expand All @@ -193,12 +193,12 @@ def print_results(glm_est, truth):

glm_est = run_glm(raw, design_matrix, noise_model='ar5')

fig, axes = plt.subplots(nrows=1, ncols=1, figsize=(15, 6))
plt.plot([-0.58853134, -0.29575669, -0.52246482, 0.38735476, 0.02428681],
axes=axes) # actual values from model above
plt.plot(glm_est.model()[0].rho * -1.0, axes=axes) # estimates
plt.legend(["Simulation AR coefficients", "Estimated AR coefficients"])
plt.xlabel("Coefficient")
fig, ax = plt.subplots(figsize=(15, 6), constrained_layout=True)
# actual values from model above
ax.plot([-0.58853134, -0.29575669, -0.52246482, 0.38735476, 0.02428681])
ax.plot(glm_est.model()[0].rho * -1.0) # estimates
ax.legend(["Simulation AR coefficients", "Estimated AR coefficients"])
ax.set_xlabel("Coefficient")


# %%
Expand Down
21 changes: 10 additions & 11 deletions examples/general/plot_11_hrf_measured.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,10 @@
# line is raised for the duration of the stimulus/condition.

s = mne_nirs.experimental_design.create_boxcar(raw_haemo)
fig, axes = plt.subplots(nrows=1, ncols=1, figsize=(15, 6))
plt.plot(raw_haemo.times, s, axes=axes)
plt.legend(["Control", "Left", "Right"], loc="upper right")
plt.xlabel("Time (s)");
fig, ax = plt.subplots(figsize=(15, 6), constrained_layout=True)
ax.plot(raw_haemo.times, s)
ax.legend(["Control", "Left", "Right"], loc="upper right")
ax.set_xlabel("Time (s)");


# %%
Expand Down Expand Up @@ -203,7 +203,7 @@
# The next columns illustrate the drift and constant components.
# The last columns illustrate the short channel signals.

fig, ax1 = plt.subplots(figsize=(10, 6), nrows=1, ncols=1)
fig, ax1 = plt.subplots(figsize=(10, 6), constrained_layout=True)
fig = plot_design_matrix(design_matrix, ax=ax1)


Expand All @@ -227,13 +227,12 @@
# name. Note however, that this is just for visualisation and does not affect
# the results below.

fig, ax = plt.subplots(constrained_layout=True)
s = mne_nirs.experimental_design.create_boxcar(raw_intensity, stim_dur=5.0)
plt.plot(raw_intensity.times, s[:, 1])
plt.plot(design_matrix['Tapping_Left'])
plt.xlim(180, 300)
plt.legend(["Stimulus", "Expected Response"])
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
ax.plot(raw_intensity.times, s[:, 1])
ax.plot(design_matrix['Tapping_Left'])
ax.legend(["Stimulus", "Expected Response"])
ax.set(xlim=(180, 300), xlabel="Time (s)", ylabel="Amplitude")


# %%
Expand Down
11 changes: 9 additions & 2 deletions mne_nirs/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,15 @@ def pytest_configure(config):
ignore:The register_cmap function.*:
ignore:The get_cmap function.*:
ignore:The figure layout has changed.*:UserWarning
# old MNE
ignore:The `pyvista.plotting.plotting` module.*:
# H5py
ignore:`product` is deprecated as of NumPy.*:DeprecationWarning
# seaborn
ignore:is_categorical_dtype is deprecated.*:FutureWarning
ignore:use_inf_as_na option is deprecated.*:FutureWarning
# nilearn
ignore:The provided callable <function sum.*:FutureWarning
# TODO: in an example (should fix eventually)
ignore:The behavior of DataFrame concatenation.*:FutureWarning
""" # noqa: E501
for warning_line in warning_lines.split('\n'):
warning_line = warning_line.strip()
Expand Down
3 changes: 3 additions & 0 deletions mne_nirs/preprocessing/tests/test_mayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
pytest.importorskip('fooof')


# in fooof->scipy.optimize.curve_fit
@pytest.mark.filterwarnings("ignore:divide by zero encountered in divide.*:")
@pytest.mark.filterwarnings("ignore:invalid value encountered in.*:")
def test_mayer():
fnirs_data_folder = mne.datasets.fnirs_motor.data_path()
fnirs_raw_dir = os.path.join(fnirs_data_folder, 'Participant-1')
Expand Down
10 changes: 5 additions & 5 deletions mne_nirs/statistics/_glm_level_first.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
import nilearn.glm
from nilearn.glm.first_level import run_glm as nilearn_glm

try: # remove once MNE 1.0 is required
from mne.io.meas_info import ContainsMixin
try: # remove once MNE 1.6 is required
from mne._fiff.meas_info import ContainsMixin
except ImportError:
from mne.channels.channels import ContainsMixin
from mne.io.meas_info import ContainsMixin
from mne.utils import fill_doc, warn, verbose, check_fname, _validate_type
from mne.io.pick import _picks_to_idx, pick_info
from mne.io.pick import _picks_to_idx
from mne.io.constants import FIFF
from mne import Info
from mne import Info, pick_info

from ..visualisation._plot_GLM_topo import _plot_glm_topo,\
_plot_glm_contrast_topo
Expand Down
4 changes: 3 additions & 1 deletion mne_nirs/statistics/_statsmodels.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#
# License: BSD (3-clause)

from io import StringIO

import pandas as pd
import numpy as np

Expand All @@ -14,7 +16,7 @@ def summary_to_dataframe(summary):
'''
results = summary.tables[1]
if type(results) is not pd.core.frame.DataFrame:
results = summary.tables[1].as_html()
results = StringIO(summary.tables[1].as_html())
results = pd.read_html(results, header=0, index_col=0)[0]
return results

Expand Down
3 changes: 3 additions & 0 deletions mne_nirs/statistics/tests/test_glm_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,9 @@ def test_create_results_glm_contrast():
df = res.to_dataframe()
assert df.shape == (n_channels, 10)

src = np.asarray(df["Source"])
assert src.dtype.kind == "i"


def test_results_glm_io():

Expand Down
15 changes: 5 additions & 10 deletions mne_nirs/tests/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import os
import pytest
import sys
import warnings

from mne.utils import check_version

Expand All @@ -26,14 +25,6 @@ def examples_path():
return path


def run_script_and_check(test_file_path):
with open(test_file_path) as fid, warnings.catch_warnings():
# Ignore deprecation warning caused by
# app.setAttribute(Qt.AA_UseHighDpiPixmaps) in mne-python
warnings.filterwarnings("ignore", category=DeprecationWarning)
return exec(fid.read(), locals(), locals())


requires_mne_1p2 = pytest.mark.skipif(
not check_version('mne', '1.2'), reason='Needs MNE-Python 1.2')
# https://github.com/mne-tools/mne-bids/pull/406
Expand All @@ -53,6 +44,8 @@ def run_script_and_check(test_file_path):


@pytest.mark.filterwarnings('ignore:No bad channels to interpolate.*:')
@pytest.mark.filterwarnings('ignore:divide by zero encountered.*:')
@pytest.mark.filterwarnings('ignore:invalid value encountered.*:')
@pytest.mark.skipif(
sys.platform.startswith('win'), reason='Unstable on Windows')
@pytest.mark.examples
Expand All @@ -76,4 +69,6 @@ def run_script_and_check(test_file_path):
"plot_99_bad.py"]))
def test_examples(fname, requires_pyvista):
test_file_path = examples_path() + fname
run_script_and_check(test_file_path)
with open(test_file_path) as fid:
code = fid.read()
exec(code, locals(), locals())
20 changes: 13 additions & 7 deletions mne_nirs/utils/_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def _tidy_RegressionResults(data, glm_est, design_matrix):
mse_estimates[idx, :] = glm_est[name].MSE[0]
for cond_idx, cond in enumerate(design_matrix.columns):
t_estimates[idx, cond_idx] = glm_est[name].t(
column=cond_idx)
column=cond_idx).item()
p_estimates[idx, cond_idx] = 2 * stats.t.cdf(
-1.0 * np.abs(t_estimates[idx, cond_idx]),
df=df_estimates[idx, cond_idx])
Expand Down Expand Up @@ -171,12 +171,18 @@ def _tidy_long_to_wide(d, expand_output=True):

if expand_output:
try:
d["Source"] = [re.search(r'S(\d+)_D(\d+) (\w+)', ch).group(1)
for ch in d["ch_name"]]
d["Detector"] = [re.search(r'S(\d+)_D(\d+) (\w+)', ch).group(2)
for ch in d["ch_name"]]
d["Chroma"] = [re.search(r'S(\d+)_D(\d+) (\w+)', ch).group(3)
for ch in d["ch_name"]]
d["Source"] = [
int(re.search(r'S(\d+)_D(\d+) (\w+)', ch).group(1))
for ch in d["ch_name"]
]
d["Detector"] = [
int(re.search(r'S(\d+)_D(\d+) (\w+)', ch).group(2))
for ch in d["ch_name"]
]
d["Chroma"] = [
re.search(r'S(\d+)_D(\d+) (\w+)', ch).group(3)
for ch in d["ch_name"]
]
except AttributeError:
warn("Non standard source detector names used")
d["Significant"] = d["p_value"] < 0.05
Expand Down
3 changes: 1 addition & 2 deletions mne_nirs/visualisation/_plot_3d_montage.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@

import numpy as np

from mne import pick_info, pick_types
from mne import pick_info, pick_types, Info
from mne.channels import make_standard_montage
from mne.channels.montage import transform_to_head
from mne.io import Info
from mne.transforms import _get_trans, apply_trans
from mne.utils import _validate_type, _check_option, verbose, logger
from mne.viz import Brain
Expand Down
8 changes: 4 additions & 4 deletions mne_nirs/visualisation/_plot_GLM_topo.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
import matplotlib as mpl
from mpl_toolkits.axes_grid1.axes_divider import make_axes_locatable

from mne import Info
from mne import Info, pick_info
from mne.utils import warn
from mne.channels.layout import _merge_ch_data
from mne.io.pick import _picks_to_idx, _get_channel_types, pick_info
from mne.io.pick import _picks_to_idx
from mne.viz import plot_topomap


Expand All @@ -38,7 +38,7 @@ def _plot_glm_topo(inst, glm_estimates, design_matrix, *,
for idx, name in enumerate(glm_estimates.keys()):
estimates[idx, :] = glm_estimates[name].theta.T

types = np.unique(_get_channel_types(info))
types = np.unique(info.get_channel_types())

if requested_conditions is None:
requested_conditions = design_matrix.columns
Expand Down Expand Up @@ -100,7 +100,7 @@ def _plot_glm_contrast_topo(inst, contrast, figsize=(12, 7), sphere=None):
info = deepcopy(inst if isinstance(inst, Info) else inst.info)

# Extract types. One subplot is created per type (hbo/hbr)
types = np.unique(_get_channel_types(info))
types = np.unique(info.get_channel_types())

# Extract values to plot and rescale to uM
estimates = contrast.effect[0]
Expand Down
2 changes: 1 addition & 1 deletion tools/circleci_dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@


python -m pip install --upgrade pip setuptools wheel
python -m pip install --upgrade --progress-bar off -r requirements.txt -r requirements_testing.txt -r requirements_doc.txt git+https://github.com/mne-tools/mne-python.git@main
python -m pip install --upgrade --progress-bar off -r requirements.txt -r requirements_testing.txt -r requirements_doc.txt git+https://github.com/mne-tools/mne-python.git@main "mne-qt-browser[opengl] @ git+https://github.com/mne-tools/mne-qt-browser.git@main"
python -m pip install -e .
23 changes: 7 additions & 16 deletions tools/github_actions_dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,15 @@ if [ ! -z "$CONDA_ENV" ]; then
else
# Changes here should also go in the interactive_test CircleCI job
python -m pip install $STD_ARGS pip setuptools wheel
echo "Numpy"
pip uninstall -yq numpy
echo "Date utils"
# https://pip.pypa.io/en/latest/user_guide/#possible-ways-to-reduce-backtracking-occurring
pip install $STD_ARGS --pre --only-binary ":all:" python-dateutil pytz joblib threadpoolctl six
echo "pyside6"
pip install $STD_ARGS --pre --only-binary ":all:" pyside6
echo "NumPy/SciPy/pandas etc."
# TODO: Currently missing dipy for 3.10 https://github.com/dipy/dipy/issues/2489
pip install $STD_ARGS --pre --only-binary ":all:" --no-deps --default-timeout=60 -i "https://pypi.anaconda.org/scipy-wheels-nightly/simple" numpy scipy pandas scikit-learn statsmodels dipy
echo "H5py, pillow, matplotlib"
pip install $STD_ARGS --pre --only-binary ":all:" --no-deps -f "https://7933911d6844c6c53a7d-47bd50c35cd79bd838daf386af554a83.ssl.cf2.rackcdn.com" h5py pillow matplotlib
echo "Numba, nilearn"
pip install $STD_ARGS --pre --only-binary ":all:" numba llvmlite nilearn
pip install $STD_ARGS --pre --only-binary ":all:" --default-timeout=60 --extra-index-url "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" numpy scipy scikit-learn pandas matplotlib pillow statsmodels
pip install $STD_ARGS --pre --only-binary ":all:" --no-deps --default-timeout=60 -i "https://pypi.anaconda.org/scipy-wheels-nightly/simple" dipy
echo "H5py"
pip install $STD_ARGS --pre --only-binary ":all:" --no-deps -f "https://7933911d6844c6c53a7d-47bd50c35cd79bd838daf386af554a83.ssl.cf2.rackcdn.com" h5py
echo "nilearn"
pip install $STD_ARGS --pre --only-binary ":all:" nilearn
echo "VTK"
# Have to use our own version until VTK releases a 3.10 build
wget -q https://osf.io/ajder/download -O vtk-9.1.20220406.dev0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
pip install $STD_ARGS --pre --only-binary ":all:" vtk-9.1.20220406.dev0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
pip install $STD_ARGS --pre --only-binary ":all:" vtk
python -c "import vtk"
echo "PyVista"
pip install --progress-bar off git+https://github.com/pyvista/pyvista
Expand Down

0 comments on commit c7cf346

Please sign in to comment.