Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX: Fix connectivity plots #62

Merged
merged 14 commits into from
Oct 4, 2023
12 changes: 6 additions & 6 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ body:
attributes:
label: What happened?
description: Describe the bug
placeholder: terrible things happening
placeholder: <terrible things happening>
- type: textarea
attributes:
label: Steps to reproduce
description: What steps made the bug appear? Please describe the steps as detailed as possible
placeholder: things I did/buttons I clicked
placeholder: <things I did/buttons I clicked>
- type: textarea
attributes:
label: Error Traceback
description: Please copy the full error traceback into here (either from the dialog that popped up or the terminal)
placeholder: error-traceback
label: Error Traceback (if present)
description: Please copy the full error traceback into here if present (either from the dialog that popped up or the terminal)
placeholder: <error-traceback>
render: python
- type: markdown
attributes:
Expand All @@ -29,5 +29,5 @@ body:
attributes:
label: System-Info
description: Please paste the results from the aforementioned command in here.
placeholder: sys-info
placeholder: <sys-info>
render: shell
11 changes: 5 additions & 6 deletions .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@ jobs:
qt : 'PySide6'
name: Run tests on ${{ matrix.os }} - ${{matrix.python}} - ${{ matrix.qt }}
runs-on: ${{ matrix.os }}-latest
env:
DISPLAY: ':99.0'
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
# Set up headless display for windows and linux
- name: Setup headless display
uses: pyvista/setup-headless-display-action@main
Expand All @@ -44,7 +42,7 @@ jobs:
run: |
python -m pip install --upgrade pip
python -m pip install ${{ matrix.qt }}
python -m pip install -ve .[tests]
python -m pip install -ve ".[tests]"
- name: Get testing version
run: |
mkdir -p mne/datasets
Expand All @@ -56,8 +54,9 @@ jobs:
key: ${{ env.TESTING_VERSION }}
path: ~/mne_data
name: 'Cache testing data'
- run: python -c 'import mne; print(mne.datasets.testing.data_path(verbose=True))'
name: 'Download sample data'
- name: 'Download testing, sample and fsaverage data'
run: |
python -c 'import mne; mne.datasets.testing.data_path(); mne.datasets.sample.data_path(); mne.datasets.fetch_fsaverage()'
- name: Show system information
run: mne sys_info
- run: pytest
Expand Down
1 change: 0 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ repos:
rev: 23.9.1
hooks:
- id: black
args: [ --quiet ]

# Ruff
- repo: https://github.com/astral-sh/ruff-pre-commit
Expand Down
18 changes: 9 additions & 9 deletions mne_pipeline_hd/extra/functions.csv
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ source_estimate;;MEEG;Compute;Inverse;False;False;;operations;basic;meeg,inverse
apply_morph;;MEEG;Compute;Inverse;False;False;;operations;basic;meeg,morph_to
label_time_course;;MEEG;Compute;Inverse;False;False;;operations;basic;meeg,target_labels,target_parcellation,extract_mode
ecd_fit;;MEEG;Compute;Inverse;False;False;;operations;basic;meeg,ecd_times,ecd_positions,ecd_orientations,t_epoch
src_connectivity;;MEEG;Compute;Inverse;False;False;;operations;basic;meeg,target_labels,target_parcellation,inverse_method,lambda2,con_methods,con_fmin,con_fmax,n_jobs
src_connectivity;;MEEG;Compute;Inverse;False;False;;operations;basic;meeg,target_labels,target_parcellation,inverse_method,lambda2,con_methods,con_frequencies,con_time_window,n_jobs
grand_avg_evokeds;;Group;Compute;Grand-Average;False;False;;operations;basic;group,ga_interpolate_bads,ga_drop_bads
grand_avg_tfr;;Group;Compute;Grand-Average;False;False;;operations;basic;group
grand_avg_morphed;;Group;Compute;Grand-Average;False;False;;operations;basic;group,morph_to
Expand Down Expand Up @@ -61,21 +61,21 @@ plot_evoked_white;;MEEG;Plot;Evoked;True;False;;plot;basic;meeg,show_plots
plot_evoked_image;;MEEG;Plot;Evoked;True;False;;plot;basic;meeg,show_plots
plot_compare_evokeds;;MEEG;Plot;Evoked;True;False;;plot;basic;meeg,show_plots
plot_gfp;;MEEG;Plot;Evoked;True;False;;plot;basic;meeg,show_plots
plot_stc;Plot Source-Estimate;MEEG;Plot;Inverse;True;True;;plot;basic;meeg,target_labels,target_parcellation,label_colors,stc_surface,stc_hemi,stc_views,stc_time,stc_clim,stc_background,stc_roll,stc_azimuth,stc_elevation,backend_3d
plot_stc_interactive;;MEEG;Plot;Inverse;True;True;;plot;basic;meeg,stc_surface,stc_hemi,stc_views,stc_time,stc_clim,stc_background,stc_roll,stc_azimuth,stc_elevation,backend_3d
plot_stc;Plot Source-Estimate;MEEG;Plot;Inverse;True;True;;plot;basic;meeg,target_labels,target_parcellation,label_colors,stc_surface,stc_hemi,stc_views,stc_time,stc_clim,stc_roll,stc_azimuth,stc_elevation,backend_3d
plot_stc_interactive;;MEEG;Plot;Inverse;True;True;;plot;basic;meeg,stc_surface,stc_hemi,stc_views,stc_time,stc_clim,stc_roll,stc_azimuth,stc_elevation,backend_3d
plot_labels;;FSMRI;Plot;Inverse;True;True;;plot;basic;fsmri,target_labels,target_parcellation,label_colors,stc_hemi,stc_surface,stc_views,backend_3d
plot_animated_stc;Plot Source-Estimate Video;MEEG;Plot;Inverse;True;True;;plot;basic;meeg,target_labels,target_parcellation,label_colors,stc_surface,stc_hemi,stc_views,stc_time,stc_clim,stc_background,stc_roll,stc_azimuth,stc_elevation,stc_animation_span,stc_animation_dilat,backend_3d
plot_animated_stc;Plot Source-Estimate Video;MEEG;Plot;Inverse;True;True;;plot;basic;meeg,target_labels,target_parcellation,label_colors,stc_surface,stc_hemi,stc_views,stc_time,stc_clim,stc_roll,stc_azimuth,stc_elevation,stc_animation_span,stc_animation_dilat,backend_3d
plot_snr;;MEEG;Plot;Inverse;True;False;;plot;basic;meeg,show_plots
plot_label_time_course;;MEEG;Plot;Inverse;True;False;;plot;basic;meeg,show_plots
plot_ecd;;MEEG;Plot;Inverse;True;True;;plot;basic;meeg
plot_src_connectivity;;MEEG;Plot;Time-Frequency;True;False;;plot;basic;meeg,target_labels,target_parcellation,con_fmin,con_fmax,show_plots
plot_src_connectivity;;MEEG;Plot;Time-Frequency;True;False;;plot;basic;meeg,show_plots
plot_grand_avg_evokeds;;Group;Plot;Grand-Average;True;False;;plot;basic;group,show_plots
plot_grand_avg_tfr;;Group;Plot;Grand-Average;True;False;;plot;basic;group,show_plots
plot_grand_avg_stc;;Group;Plot;Grand-Average;True;True;;plot;basic;group,target_labels,target_parcellation,label_colors,stc_surface,stc_hemi,stc_views,stc_time,stc_clim,stc_background,stc_roll,stc_azimuth,stc_elevation,backend_3d
plot_grand_avg_stc_anim;;Group;Plot;Grand-Average;True;True;;plot;basic;group,target_labels,target_parcellation,label_colors,stc_surface,stc_hemi,stc_views,stc_time,stc_clim,stc_background,stc_roll,stc_azimuth,stc_elevation,stc_animation_span,stc_animation_dilat,backend_3d
plot_grand_average_stc_interactive;;Group;Plot;Grand-Average;True;True;;plot;basic;group,stc_surface,stc_hemi,stc_views,stc_time,stc_clim,stc_background,stc_roll,stc_azimuth,stc_elevation,backend_3d
plot_grand_avg_stc;;Group;Plot;Grand-Average;True;True;;plot;basic;group,target_labels,target_parcellation,label_colors,stc_surface,stc_hemi,stc_views,stc_time,stc_clim,stc_roll,stc_azimuth,stc_elevation,backend_3d
plot_grand_avg_stc_anim;;Group;Plot;Grand-Average;True;True;;plot;basic;group,target_labels,target_parcellation,label_colors,stc_surface,stc_hemi,stc_views,stc_time,stc_clim,stc_roll,stc_azimuth,stc_elevation,stc_animation_span,stc_animation_dilat,backend_3d
plot_grand_average_stc_interactive;;Group;Plot;Grand-Average;True;True;;plot;basic;group,label_colors,stc_surface,stc_hemi,stc_views,stc_time,stc_clim,stc_roll,stc_azimuth,stc_elevation,backend_3d
plot_grand_avg_ltc;;Group;Plot;Grand-Average;True;False;;plot;basic;group,show_plots
plot_grand_avg_connect;;Group;Plot;Grand-Average;True;False;;plot;basic;group,con_fmin,con_fmax,target_labels,target_parcellation,morph_to,show_plots,connectivity_vmin,connectivity_vmax
plot_grand_avg_connect;;Group;Plot;Grand-Average;True;False;;plot;basic;group,morph_to,show_plots,connectivity_vmin,connectivity_vmax
plot_ica_components;Plot ICA-Components;MEEG;Plot;ICA;True;False;;plot;basic;meeg,show_plots,close_func
plot_ica_sources;Plot ICA-Sources;MEEG;Plot;ICA;True;False;;plot;basic;meeg,ica_source_data,show_plots,close_func
plot_ica_overlay;Plot ICA-Overlay;MEEG;Plot;ICA;True;False;;plot;basic;meeg,ica_overlay_data,show_plots
Expand Down
12 changes: 6 additions & 6 deletions mne_pipeline_hd/extra/parameters.csv
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,17 @@ stc_time;;Inverse;0;;Initial time for Source Estimate Plots;FloatGui;
stc_clim;;Inverse;'auto';;Colorbar Limits for Source Estimate Plots;MultiTypeGui;{'type_selection': True, 'types': ['str', 'dict']}
stc_background;;Inverse;'black';;Background for Source Estimate Plots;MultiTypeGui;{'type_selection': False}
stc_roll;;Inverse;0;;Roll for view in for Source Estimate Plots;IntGui;{'max_val': 360}
stc_azimuth;;Inverse;0;;Azimuth for view for Source Estimate Plots;IntGui;{'max_val': 360}
stc_elevation;;Inverse;0;;Elevation for view for Source Estimate Plots;IntGui;{'max_val': 360}
stc_azimuth;;Inverse;70;;Azimuth for view for Source Estimate Plots;IntGui;{'max_val': 360}
stc_elevation;;Inverse;60;;Elevation for view for Source Estimate Plots;IntGui;{'max_val': 360}
stc_animation_span;;Inverse;(0,0.5);s;time-span for stc-animation[s];TupleGui;
stc_animation_dilat;;Inverse;20;;time-dilation for stc-animation;IntGui;
target_parcellation;Target Parcellation;Inverse;aparc;;The parcellation to use.;StringGui;
target_labels;Target Labels;Inverse;[];;;LabelGui;
label_colors;;Inverse;{};;Set custom colors for labels.;ColorGui;{'keys': 'target_labels', 'none_select':True}
extract_mode;Label-Extraction-Mode;Inverse;mean_flip;;mode for extracting label-time-course from Source-Estimate;ComboGui;{'options': ['max', 'mean', 'mean_flip', 'pca_flip']}
con_methods;;Connectivity;['coh'];;methods for connectivity plots;CheckListGui;{'options': ['coh', 'cohy', 'imcoh', 'plv', 'ciplv', 'ppc', 'pli', 'pli2_unbiased', 'wpli', 'wpli2_debiased']}
con_fmin;;Connectivity;30;;fmin for connectivity plot;IntGui;
con_fmax;;Connectivity;80;;fmax for connectivity plot;IntGui;
extract_mode;Label-Extraction-Mode;Inverse;auto;;mode for extracting label-time-course from Source-Estimate;ComboGui;{'options': ['auto', 'max', 'mean', 'mean_flip', 'pca_flip']}
con_methods;;Connectivity;['coh'];;methods for connectivity;CheckListGui;{'options': ['coh', 'cohy', 'imcoh', 'plv', 'ciplv', 'ppc', 'pli', 'pli2_unbiased', 'wpli', 'wpli2_debiased']}
con_frequencies;;Connectivity;(30, 80);;frequencies for connectivity;TupleGui;{'none_select': True, 'step': 1}
con_time_window;;Connectivity;(0, 0.5);;time-window for connectivity;TupleGui;{'none_select': True, 'step': 0.001}
ecd_times;;Inverse;{};;;DictGui;
ecd_positions;;Inverse;{};;;DictGui;
ecd_orientations;;Inverse;{};;;DictGui;
Expand Down
87 changes: 32 additions & 55 deletions mne_pipeline_hd/functions/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -1473,8 +1473,8 @@ def src_connectivity(
inverse_method,
lambda2,
con_methods,
con_fmin,
con_fmax,
con_frequencies,
con_time_window,
n_jobs,
):
info = meeg.load_info()
Expand All @@ -1483,54 +1483,27 @@ def src_connectivity(
src = inverse_operator["src"]
labels = meeg.fsmri.get_labels(target_labels, target_parcellation)

con_dict = {}

for trial in [t for t in all_epochs.event_id if t]:
con_dict[trial.split("/")[0]] = {}
epochs = all_epochs[trial.split("/")[0]]
# Compute inverse solution and for each epoch.
# By using "return_generator=True" stcs will be a generator object
# instead of a list.
stcs = mne.minimum_norm.apply_inverse_epochs(
epochs,
inverse_operator,
lambda2,
inverse_method,
pick_ori="normal",
return_generator=True,
)

label_ts = mne.extract_label_time_course(
stcs, labels, src, mode="mean_flip", return_generator=True
if len(labels) == 0:
raise RuntimeError(
"No labels found, check your target_labels and target_parcellation"
)

sfreq = info["sfreq"] # the sampling frequency
con = mne_connectivity.spectral_connectivity_epochs(
label_ts,
method=con_methods,
mode="multitaper",
sfreq=sfreq,
fmin=con_fmin,
fmax=con_fmax,
faverage=True,
mt_adaptive=True,
n_jobs=n_jobs,
if len(meeg.sel_trials) == 0:
raise RuntimeError(
"No trials selected, check your Selected IDs in Preparation/"
)

if not isinstance(con, list):
con = [con]
con_dict = {}

# con is a 3D array, get the connectivity for the first (and only)
# freq. band for each con_method
for method, c in zip(con_methods, con):
con_dict[trial.split("/")[0]][method] = c.get_data(output="dense")[:, :, 0]
for trial in meeg.sel_trials:
con_dict[trial] = {}
epochs = all_epochs[trial]

meeg.save_connectivity(con_dict)
# Crop if necessary
if con_time_window is not None:
epochs = epochs.copy().crop(
tmin=con_time_window[0], tmax=con_time_window[1]
)

for trial in all_epochs.event_id:
con_dict[trial.split("/")[1]] = {}
# epochs = all_epochs[trial.split('/')[1]][:2]
epochs = all_epochs[trial.split("/")[1]]
# Compute inverse solution and for each epoch.
# By using "return_generator=True" stcs will be a generator object
# instead of a list.
Expand All @@ -1543,22 +1516,18 @@ def src_connectivity(
return_generator=True,
)

# Average the source estimates within each label using
# sign-flips to reduce signal cancellations, also here we return a
# generator

label_ts = mne.extract_label_time_course(
stcs, labels, src, mode="mean_flip", return_generator=True
)

sfreq = info["sfreq"] # the sampling frequency
con = mne_connectivity.spectral_connectivity(
con = mne_connectivity.spectral_connectivity_epochs(
label_ts,
method=con_methods,
mode="multitaper",
sfreq=sfreq,
fmin=con_fmin,
fmax=con_fmax,
fmin=con_frequencies[0],
fmax=con_frequencies[1],
faverage=True,
mt_adaptive=True,
n_jobs=n_jobs,
Expand All @@ -1567,10 +1536,17 @@ def src_connectivity(
if not isinstance(con, list):
con = [con]

# con is a 3D array, get the connectivity for the first
# (and only) freq. band for each con_method
# con is a 3D array, get the connectivity for the first (and only)
# freq. band for each con_method
for method, c in zip(con_methods, con):
con_dict[trial.split("/")[1]][method] = c.get_data(output="dense")[:, :, 0]
con_dict[trial][method] = c.get_data(output="dense")[:, :, 0]

# Add target_labels for later identification
con_dict["__info__"] = {
"labels": target_labels,
"parcellation": target_parcellation,
"frequencies": con_frequencies,
}

meeg.save_connectivity(con_dict)

Expand Down Expand Up @@ -1682,6 +1658,7 @@ def grand_avg_connect(group):
meeg = MEEG(name, group.ct)
print(f"Add {name} to grand_average")
con_dict = meeg.load_connectivity()
con_info = con_dict.pop("__info__")
for trial in con_dict:
if trial not in con_average_dict:
con_average_dict[trial] = {}
Expand All @@ -1693,7 +1670,7 @@ def grand_avg_connect(group):
else:
con_average_dict[trial][con_method] = [con_dict[trial][con_method]]

ga_con = {}
ga_con = {"__info__": con_info}
for trial in con_average_dict:
ga_con[trial] = {}
for con_method in con_average_dict[trial]:
Expand Down
Loading