OSCR

Distinct Roles of Deep and Superficial Cortical Layers in Tone Prediction, Comparison, and Adaptation in Human Auditory Cortices.

Code ↔ Paper

13 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 13 matches
  1. [1] § Results › Superficial layers represent shared expectation-stimulus preference dynamics ↔ finalized/PredAdapt_fMRI/ses2_regressions/ROI_and_layer_analysis.ipynb, lines 841–949 · score 0.78 · Planum Polare, Planum Temporale, posterior STG, FDR corrected, repetition suppression, Heschl
  2. [2] § Results › Distinct laminar profiles of expectations trending towards deep layers and layer-uniform repetition suppression ↔ finalized/PredAdapt_fMRI/ses2_regressions/ROI_and_layer_analysis.ipynb, lines 841–949 · score 0.77 · Planum Polare, Planum Temporale, posterior STG, FDR corrected, Heschl, gyrus
  3. [3] § Methods › Calibration of the auditory loudness waveform ↔ projects/PredAdapt_MEG/psychtoolbox_exp/mainpredsound_MEG.m, lines 83–152 · score 0.68 · piecewise cubic interpolation, equal loudness curve, intensity, tones, stimulus
  4. [4] § Methods › Functional data analysis › Preprocessing and alignment of functional data ↔ finalized/PredAdapt_fMRI/preproc_fmri/bv_preproc/functional_plot.py, lines 445–570 · score 0.67 · distortion correction, motion correction, preprocessing, Topup, FSL, slice
  5. [5] § Methods › Calibration of the auditory loudness waveform ↔ finalized/PredAdapt_fMRI/psychtoolbox_exp/mainpredsound.m, lines 83–144 · score 0.66 · piecewise cubic interpolation, loudness curve, intensity, tones, stimulus
  6. [6] § Methods › Functional data analysis › Preprocessing and alignment of functional data ↔ finalized/PredAdapt_fMRI/preproc_fmri/bv_preproc/functional.py, lines 197–290 · score 0.63 · motion correction, preprocessing, rotations, translations, Topup, BrainVoyager
  7. [7] § Results ↔ finalized/PredAdapt_fMRI/ses2_modelstims/DREX/run_DREX_model.m, lines 1–55 · score 0.60 · context hypotheses, REX model, predictive distribution, mixtures, belief, window
  8. [8] § Results › Distinct laminar profiles of expectations trending towards deep layers and layer-uniform repetition suppression ↔ finalized/AssociativeLearning/analysis/Laminar_UnivariateAndStats.ipynb, lines 344–454 · score 0.54 · aSTG, FDR corrected, pSTG, laminar, PT, HG
  9. [9] § Methods › Stimulus modelling ↔ finalized/PredAdapt_fMRI/psychtoolbox_exp/settings_tonotopy.m, lines 1–46 · score 0.54 · inter stimulus interval, ISI, offsets, onsets, duration, TR
  10. [10] § Results › Superficial layers represent shared expectation-stimulus preference dynamics ↔ finalized/AssociativeLearning/analysis/Laminar_UnivariateAndStats.ipynb, lines 778–901 · score 0.54 · aSTG, FDR corrected, pSTG, interactions, PT, HG
  11. [11] § Results › Superficial layers represent shared expectation-stimulus preference dynamics ↔ finalized/AssociativeLearning/analysis/Laminar_UnivariateAndStats.ipynb, lines 44–61 · score 0.53 · aSTG, pSTG, middle layers, deep layers, surface, PT
  12. [12] § Methods › Stimulus modelling ↔ projects/PredAdapt_MEG/psychtoolbox_exp/settings_localizer.m, lines 1–45 · score 0.52 · inter stimulus interval, ISI, offsets, onsets, duration, repetition
  13. [13] § Methods › Computational modelling › D-REX model ↔ finalized/PredAdapt_fMRI/ses2_modelstims/DREX/run_DREX_model.m, lines 1–55 · score 0.51 · Gaussian Mixture Model, GMM, REX, sequences, probability

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

Jupyter notebook · 1,858 lines · 88 KB · no license · 3 matches

  1. # %% [markdown]
  2. # # <center> $\Large{\text{Univariate Analysis}}$ <br> Laminar Level (1.96 Sound) </center>
  3. # %%
  4. %autoreload 2
  5. # %%
  6. import sys
  7. import itertools
  8. from glob import glob
  9. from tqdm import tqdm
  10. import seaborn as sns
  11. import numpy as np
  12. import matplotlib.pyplot as plt
  13. import pandas as pd
  14. import bvbabel
  15. import matlab.engine
  16. import scipy.io as sio
  17. from scipy.stats import ttest_rel, ttest_1samp, friedmanchisquare
  18. import statsmodels.api as sm
  19. from statsmodels.formula.api import ols
  20. from statsmodels.stats.multitest import fdrcorrection
  21. import scikit_posthocs as sp
  22. sys.path.insert(0, '/mnt/hdd2/associative_learning/notebooks/toolbox/')
  23. from fmri_toolbox import FMRIToolbox
  24. # matlab and seaborn config
  25. import matplotlib as mpl
  26. mpl.rcParams['text.usetex'] = True
  27. sns.set(style="whitegrid")
  28. import matplotlib.lines as mlines
  29. import matplotlib.gridspec as gridspec
  30. def add_significance(ax, x1, x2, y, h, text):
  31. if text=='ns': return
  32. ax.plot([x1, x1, x2, x2], [y, y+h, y+h, y], lw=1.5, color='black')
  33. ax.text((x1 + x2) * .5, y + h, text, ha='center', va='bottom', color='black', fontsize=20)
  34. plt.rcParams['text.usetex'] = True
  35. # %% [markdown]
  36. # - Layer 1 (D) Deep
  37. # - Layer 2 (M) Middle
  38. # - Layer 3 (S) Surface
  39. # %% [markdown]
  40. # ### Load data
  41. # %%
  42. data_dir = f'/mnt/hdd2/associative_learning/analysis/estimates/single_trial_gm_mask'
  43. mask_dir = '/mnt/hdd2/associative_learning/masks/drawn_regions/'
  44. tbx = FMRIToolbox(data_dir, mask_dir=mask_dir)
  45. subjects = ['S04', 'S05', 'S06', 'S07', 'S08', 'S09', 'S10', 'S11', 'S12', 'S15', 'S17']
  46. regions = ['PP','HG', 'PT', 'aSTG', 'pSTG', 'pMTG', 'parsOrbitalis', 'parsTriangularis', 'TPOj']
  47. hemispheres = ['LH', 'RH']
  48. # load dataset
  49. dataset = tbx.load_dataset(subjects, hemispheres, regions, extract_layers=True)
  50. # %% [markdown]
  51. # ### Plot voxel counts
  52. # %%
  53. fig = plt.figure(figsize=(14,4))
  54. palette = sns.color_palette()
  55. palette1 = sns.color_palette("muted")
  56. palette2 = sns.color_palette("pastel")
  57. regions_layers_list = np.array([[region + ' (D)', region + ' (M)', region + ' (S)'] for region in regions]).ravel()
  58. ax = plt.subplot(1,2,1)
  59. voxel_counts_lh_l1 = {region:np.mean([dataset[subject]['LH'][region]['betas']['L1'].shape[0] for subject in subjects]) for region in regions}
  60. voxel_counts_lh_l1_se = {region:np.std([dataset[subject]['LH'][region]['betas']['L1'].shape[0] for subject in subjects]) for region in regions}
  61. voxel_counts_lh_l1_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_lh_l1_se.values()]
  62. voxel_counts_lh_l2 = {region:np.mean([dataset[subject]['LH'][region]['betas']['L2'].shape[0] for subject in subjects]) for region in regions}
  63. voxel_counts_lh_l2_se = {region:np.std([dataset[subject]['LH'][region]['betas']['L2'].shape[0] for subject in subjects]) for region in regions}
  64. voxel_counts_lh_l2_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_lh_l2_se.values()]
  65. voxel_counts_lh_l3 = {region:np.mean([dataset[subject]['LH'][region]['betas']['L3'].shape[0] for subject in subjects]) for region in regions}
  66. voxel_counts_lh_l3_se = {region:np.std([dataset[subject]['LH'][region]['betas']['L3'].shape[0] for subject in subjects]) for region in regions}
  67. voxel_counts_lh_l3_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_lh_l3_se.values()]
  68. x_positions1 = np.arange(len(voxel_counts_lh_l1))
  69. ax.bar(x=x_positions1, height=voxel_counts_lh_l1.values(), capsize=2, width=0.3, color=palette, yerr=voxel_counts_lh_l1_ci)
  70. x_positions2 = x_positions1 + 0.3
  71. ax.bar(x=x_positions2, height=voxel_counts_lh_l2.values(), capsize=2, width=0.3, color=palette1, yerr=voxel_counts_lh_l2_ci)
  72. x_positions3 = x_positions1 + 0.6
  73. ax.bar(x=x_positions3, height=voxel_counts_lh_l3.values(), capsize=2, width=0.3, color=palette2, yerr=voxel_counts_lh_l3_ci)
  74. ax.set_xticks(np.sort(np.concatenate([x_positions1, x_positions2, x_positions3])), regions_layers_list)
  75. plt.xticks(rotation=90)
  76. ax.set_title('LH')
  77. ##############
  78. ax = plt.subplot(1,2,2)
  79. voxel_counts_lh_l1 = {region:np.mean([dataset[subject]['RH'][region]['betas']['L1'].shape[0] for subject in subjects]) for region in regions}
  80. voxel_counts_lh_l1_se = {region:np.std([dataset[subject]['RH'][region]['betas']['L1'].shape[0] for subject in subjects]) for region in regions}
  81. voxel_counts_lh_l1_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_lh_l1_se.values()]
  82. voxel_counts_lh_l2 = {region:np.mean([dataset[subject]['RH'][region]['betas']['L2'].shape[0] for subject in subjects]) for region in regions}
  83. voxel_counts_lh_l2_se = {region:np.std([dataset[subject]['RH'][region]['betas']['L2'].shape[0] for subject in subjects]) for region in regions}
  84. voxel_counts_lh_l2_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_lh_l2_se.values()]
  85. voxel_counts_lh_l3 = {region:np.mean([dataset[subject]['RH'][region]['betas']['L3'].shape[0] for subject in subjects]) for region in regions}
  86. voxel_counts_lh_l3_se = {region:np.std([dataset[subject]['RH'][region]['betas']['L3'].shape[0] for subject in subjects]) for region in regions}
  87. voxel_counts_lh_l3_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_lh_l3_se.values()]
  88. x_positions1 = np.arange(len(voxel_counts_lh_l1))
  89. ax.bar(x=x_positions1, height=voxel_counts_lh_l1.values(), capsize=2, width=0.3, color=palette, yerr=voxel_counts_lh_l1_ci)
  90. ax.bar(x=x_positions2, height=voxel_counts_lh_l2.values(), capsize=2, width=0.3, color=palette1, yerr=voxel_counts_lh_l2_ci)
  91. ax.bar(x=x_positions3, height=voxel_counts_lh_l3.values(), capsize=2, width=0.3, color=palette2, yerr=voxel_counts_lh_l3_ci)
  92. ax.set_xticks(np.sort(np.concatenate([x_positions1, x_positions2, x_positions3])), regions_layers_list)
  93. plt.xticks(rotation=90)
  94. ax.set_title('RH')
  95. plt.suptitle('Voxel Counts')
  96. plt.show()
  97. # %% [markdown]
  98. # ### Perform T-Tests
  99. # %%
  100. tbx.utils.calculate_tstats(dataset, trials='sound')
  101. # %% [markdown]
  102. # ### Check voxels count using one threshold
  103. # %%
  104. t_threshold = 1.96
  105. tbx.utils.select_voxels(dataset, selection={'method': 'tstat', 'strategy': 't_val', 'threshold':t_threshold, 'drop_negative':True})
  106. # %%
  107. fig = plt.figure(figsize=(14,4))
  108. palette = sns.color_palette()
  109. palette1 = sns.color_palette("muted")
  110. palette2 = sns.color_palette("pastel")
  111. regions_layers_list = np.array([[region + ' (D)', region + ' (M)', region + ' (S)'] for region in regions]).ravel()
  112. ax = plt.subplot(1,2,1)
  113. voxel_counts_lh_l1 = {region:np.nanmean([dataset[subject]['LH'][region]['betas_selected']['L1'].shape[0] for subject in subjects]) for region in regions}
  114. voxel_counts_lh_l1_min = {region:np.nanmin([dataset[subject]['LH'][region]['betas_selected']['L1'].shape[0] for subject in subjects]) for region in regions}
  115. voxel_counts_lh_l1_se = {region:np.std([dataset[subject]['LH'][region]['betas_selected']['L1'].shape[0] for subject in subjects]) for region in regions}
  116. voxel_counts_lh_l1_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_lh_l1_se.values()]
  117. voxel_counts_lh_l2 = {region:np.nanmean([dataset[subject]['LH'][region]['betas_selected']['L2'].shape[0] for subject in subjects]) for region in regions}
  118. voxel_counts_lh_l2_min = {region:np.nanmin([dataset[subject]['LH'][region]['betas_selected']['L2'].shape[0] for subject in subjects]) for region in regions}
  119. voxel_counts_lh_l2_se = {region:np.std([dataset[subject]['LH'][region]['betas_selected']['L2'].shape[0] for subject in subjects]) for region in regions}
  120. voxel_counts_lh_l2_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_lh_l2_se.values()]
  121. voxel_counts_lh_l3 = {region:np.nanmean([dataset[subject]['LH'][region]['betas_selected']['L3'].shape[0] for subject in subjects]) for region in regions}
  122. voxel_counts_lh_l3_min = {region:np.nanmin([dataset[subject]['LH'][region]['betas_selected']['L3'].shape[0] for subject in subjects]) for region in regions}
  123. voxel_counts_lh_l3_se = {region:np.std([dataset[subject]['LH'][region]['betas_selected']['L3'].shape[0] for subject in subjects]) for region in regions}
  124. voxel_counts_lh_l3_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_lh_l3_se.values()]
  125. x_positions1 = np.arange(len(voxel_counts_lh_l1))
  126. ax.bar(x=x_positions1, height=voxel_counts_lh_l1.values(), capsize=2, width=0.3, color=palette[0], yerr=voxel_counts_lh_l1_ci)
  127. x_positions2 = x_positions1 + 0.3
  128. ax.bar(x=x_positions2, height=voxel_counts_lh_l2.values(), capsize=2, width=0.3, color=palette1[0], yerr=voxel_counts_lh_l2_ci)
  129. x_positions3 = x_positions1 + 0.6
  130. ax.bar(x=x_positions3, height=voxel_counts_lh_l3.values(), capsize=2, width=0.3, color=palette2[0], yerr=voxel_counts_lh_l3_ci)
  131. ax.set_xticks(np.sort(np.concatenate([x_positions1, x_positions2, x_positions3])), regions_layers_list)
  132. plt.xticks(rotation=90)
  133. ax.set_title('LH')
  134. ##############
  135. regions_layers_list = np.array([[region + ' (D)', region + ' (M)', region + ' (S)'] for region in regions]).ravel()
  136. ax = plt.subplot(1,2,2)
  137. voxel_counts_rh_l1 = {region:np.nanmean([dataset[subject]['RH'][region]['betas_selected']['L1'].shape[0] for subject in subjects]) for region in regions}
  138. voxel_counts_rh_l1_min = {region:np.nanmin([dataset[subject]['RH'][region]['betas_selected']['L1'].shape[0] for subject in subjects]) for region in regions}
  139. voxel_counts_rh_l1_se = {region:np.std([dataset[subject]['RH'][region]['betas_selected']['L1'].shape[0] for subject in subjects]) for region in regions}
  140. voxel_counts_rh_l1_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_rh_l1_se.values()]
  141. voxel_counts_rh_l2 = {region:np.nanmean([dataset[subject]['RH'][region]['betas_selected']['L2'].shape[0] for subject in subjects]) for region in regions}
  142. voxel_counts_rh_l2_min = {region:np.nanmin([dataset[subject]['RH'][region]['betas_selected']['L2'].shape[0] for subject in subjects]) for region in regions}
  143. voxel_counts_rh_l2_se = {region:np.std([dataset[subject]['RH'][region]['betas_selected']['L2'].shape[0] for subject in subjects]) for region in regions}
  144. voxel_counts_rh_l2_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_rh_l2_se.values()]
  145. voxel_counts_rh_l3 = {region:np.nanmean([dataset[subject]['RH'][region]['betas_selected']['L3'].shape[0] for subject in subjects]) for region in regions}
  146. voxel_counts_rh_l3_min = {region:np.nanmin([dataset[subject]['RH'][region]['betas_selected']['L3'].shape[0] for subject in subjects]) for region in regions}
  147. voxel_counts_rh_l3_se = {region:np.std([dataset[subject]['RH'][region]['betas_selected']['L3'].shape[0] for subject in subjects]) for region in regions}
  148. voxel_counts_rh_l3_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_rh_l3_se.values()]
  149. x_positions1 = np.arange(len(voxel_counts_rh_l1))
  150. ax.bar(x=x_positions1, height=voxel_counts_rh_l1.values(), capsize=2, width=0.3, color=palette[0], yerr=voxel_counts_rh_l1_ci)
  151. ax.bar(x=x_positions2, height=voxel_counts_rh_l2.values(), capsize=2, width=0.3, color=palette1[0], yerr=voxel_counts_rh_l2_ci)
  152. ax.bar(x=x_positions3, height=voxel_counts_rh_l3.values(), capsize=2, width=0.3, color=palette2[0], yerr=voxel_counts_rh_l3_ci)
  153. ax.set_xticks(np.sort(np.concatenate([x_positions1, x_positions2, x_positions3])), regions_layers_list)
  154. plt.xticks(rotation=90)
  155. ax.set_title('RH')
  156. plt.suptitle(r'Voxel Counts after Selection ($F \geq$ ' + str(t_threshold) + ')')
  157. plt.show()
  158. # %% [markdown]
  159. # # Display Percentage of Voxels
  160. # %%
  161. fig = plt.figure(figsize=(14,4))
  162. palette = sns.color_palette()
  163. palette1 = sns.color_palette("muted")
  164. palette2 = sns.color_palette("pastel")
  165. regions_layers_list = np.array([[region + ' (D)', region + ' (M)', region + ' (S)'] for region in regions]).ravel()
  166. ax = plt.subplot(1,2,1)
  167. voxel_counts_lh_l1 = {region:np.nanmean([dataset[subject]['LH'][region]['betas_selected']['L1'].shape[0]*100/dataset[subject]['LH'][region]['betas']['L1'].shape[0] for subject in subjects]) for region in regions}
  168. voxel_counts_lh_l1_se = {region:np.std([dataset[subject]['LH'][region]['betas_selected']['L1'].shape[0]*100/dataset[subject]['LH'][region]['betas']['L1'].shape[0] for subject in subjects]) for region in regions}
  169. voxel_counts_lh_l1_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_lh_l1_se.values()]
  170. voxel_counts_lh_l2 = {region:np.nanmean([dataset[subject]['LH'][region]['betas_selected']['L2'].shape[0]*100/dataset[subject]['LH'][region]['betas']['L2'].shape[0] for subject in subjects]) for region in regions}
  171. voxel_counts_lh_l2_se = {region:np.std([dataset[subject]['LH'][region]['betas_selected']['L2'].shape[0]*100/dataset[subject]['LH'][region]['betas']['L2'].shape[0] for subject in subjects]) for region in regions}
  172. voxel_counts_lh_l2_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_lh_l2_se.values()]
  173. voxel_counts_lh_l3 = {region:np.nanmean([dataset[subject]['LH'][region]['betas_selected']['L3'].shape[0]*100/dataset[subject]['LH'][region]['betas']['L3'].shape[0] for subject in subjects]) for region in regions}
  174. voxel_counts_lh_l3_se = {region:np.std([dataset[subject]['LH'][region]['betas_selected']['L3'].shape[0]*100/dataset[subject]['LH'][region]['betas']['L3'].shape[0] for subject in subjects]) for region in regions}
  175. voxel_counts_lh_l3_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_lh_l3_se.values()]
  176. x_positions1 = np.arange(len(voxel_counts_lh_l1))
  177. ax.bar(x=x_positions1, height=voxel_counts_lh_l1.values(), capsize=2, width=0.3, color=palette[0], yerr=voxel_counts_lh_l1_ci)
  178. x_positions2 = x_positions1 + 0.3
  179. ax.bar(x=x_positions2, height=voxel_counts_lh_l2.values(), capsize=2, width=0.3, color=palette1[0], yerr=voxel_counts_lh_l2_ci)
  180. x_positions3 = x_positions1 + 0.6
  181. ax.bar(x=x_positions3, height=voxel_counts_lh_l3.values(), capsize=2, width=0.3, color=palette2[0], yerr=voxel_counts_lh_l3_ci)
  182. ax.set_xticks(np.sort(np.concatenate([x_positions1, x_positions2, x_positions3])), regions_layers_list)
  183. plt.xticks(rotation=90)
  184. ax.set_title('LH')
  185. ##############
  186. regions_layers_list = np.array([[region + ' (D)', region + ' (M)', region + ' (S)'] for region in regions]).ravel()
  187. ax = plt.subplot(1,2,2)
  188. voxel_counts_rh_l1 = {region:np.nanmean([dataset[subject]['RH'][region]['betas_selected']['L1'].shape[0]*100/dataset[subject]['RH'][region]['betas']['L1'].shape[0] for subject in subjects]) for region in regions}
  189. voxel_counts_rh_l1_se = {region:np.std([dataset[subject]['RH'][region]['betas_selected']['L1'].shape[0]*100/dataset[subject]['RH'][region]['betas']['L1'].shape[0] for subject in subjects]) for region in regions}
  190. voxel_counts_rh_l1_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_rh_l1_se.values()]
  191. voxel_counts_rh_l2 = {region:np.nanmean([dataset[subject]['RH'][region]['betas_selected']['L2'].shape[0]*100/dataset[subject]['RH'][region]['betas']['L2'].shape[0] for subject in subjects]) for region in regions}
  192. voxel_counts_rh_l2_se = {region:np.std([dataset[subject]['RH'][region]['betas_selected']['L2'].shape[0]*100/dataset[subject]['RH'][region]['betas']['L2'].shape[0] for subject in subjects]) for region in regions}
  193. voxel_counts_rh_l2_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_rh_l2_se.values()]
  194. voxel_counts_rh_l3 = {region:np.nanmean([dataset[subject]['RH'][region]['betas_selected']['L3'].shape[0]*100/dataset[subject]['RH'][region]['betas']['L3'].shape[0] for subject in subjects]) for region in regions}
  195. voxel_counts_rh_l3_se = {region:np.std([dataset[subject]['RH'][region]['betas_selected']['L3'].shape[0]*100/dataset[subject]['RH'][region]['betas']['L3'].shape[0] for subject in subjects]) for region in regions}
  196. voxel_counts_rh_l3_ci = [1.96 * (std_dev / np.sqrt(len(subjects))) for std_dev in voxel_counts_rh_l3_se.values()]
  197. x_positions1 = np.arange(len(voxel_counts_rh_l1))
  198. ax.bar(x=x_positions1, height=voxel_counts_rh_l1.values(), capsize=2, width=0.3, color=palette[0], yerr=voxel_counts_rh_l1_ci)
  199. ax.bar(x=x_positions2, height=voxel_counts_rh_l2.values(), capsize=2, width=0.3, color=palette1[0], yerr=voxel_counts_rh_l2_ci)
  200. ax.bar(x=x_positions3, height=voxel_counts_rh_l3.values(), capsize=2, width=0.3, color=palette2[0], yerr=voxel_counts_rh_l3_ci)
  201. ax.set_xticks(np.sort(np.concatenate([x_positions1, x_positions2, x_positions3])), regions_layers_list)
  202. plt.xticks(rotation=90)
  203. ax.set_title('RH')
  204. plt.suptitle(r'Voxel Percentage after Selection ($F \geq$ ' + str(t_threshold) + ')')
  205. plt.show()
  206. # %% [markdown]
  207. # ---
  208. #
  209. # # Plot Mean Activations
  210. # %%
  211. fig, ax = plt.subplots(2, 5, figsize=(12,5))
  212. for region_idx, axis in enumerate(ax.ravel()):
  213. if region_idx==9:continue
  214. activations = {
  215. val: [np.nanmean(dataset[subject]['LH'][regions[region_idx]]['betas_selected'][f'L{idx+1}'].values) for subject in subjects]
  216. for idx, val in enumerate(['D', 'M', 'S'])
  217. }
  218. sns.barplot(activations, ax=axis)
  219. axis.set_title(regions[region_idx])
  220. plt.suptitle('Mean Beta Activations (LH)')
  221. plt.tight_layout()
  222. plt.show()
  223. fig, ax = plt.subplots(2, 5, figsize=(12,5))
  224. for region_idx, axis in enumerate(ax.ravel()):
  225. if region_idx==9:continue
  226. activations = {
  227. val: [np.nanmean(dataset[subject]['RH'][regions[region_idx]]['betas_selected'][f'L{idx+1}'].values) for subject in subjects]
  228. for idx, val in enumerate(['D', 'M', 'S'])
  229. }
  230. sns.barplot(activations, ax=axis)
  231. axis.set_title(regions[region_idx])
  232. plt.suptitle('Mean Beta Activations (RH)')
  233. plt.tight_layout()
  234. plt.show()
  235. # %%
  236. def non_parametric_permutation_ttest(betas):
  237. n_subjects = betas.size
  238. permutation_matrix = np.array(list(itertools.product([1,-1], repeat=n_subjects))).T
  239. permutation_product = betas @ permutation_matrix
  240. p_val = (sum(abs(permutation_product[0]) <= abs(permutation_product[1:-1])) + 1) / (permutation_product.size)
  241. return p_val
  242. # %% [markdown]
  243. # ---
  244. #
  245. # # <center> $\Large\textbf{Congruent vs. Incongruent}$ </center>
  246. #
  247. # **Test the effect of prediction error.**
  248. # %%
  249. regex1 = '_cong$'
  250. regex2 = '_incong$'
  251. layers = ['L1', 'L2', 'L3']
  252. tstats = {}; pvals = {}; set1 = {};set2 = {}
  253. for layer_name, layer_id in zip(['Deep', 'Middle', 'Superficial'], ['L1', 'L2', 'L3']):
  254. tstats[layer_id] = []; pvals[layer_id] = []; df_set1 = {}; df_set2 = {}
  255. for region in regions:
  256. df_set1[region] = []
  257. df_set2[region] = []
  258. for subject in subjects:
  259. stimuli = tbx.utils.extract_stimuli(subject)
  260. betas_l = tbx.utils.extract_condition_betas(stimuli=stimuli,
  261. betas=dataset[subject]['LH'][region]['betas_selected'][layer_id].values.T,
  262. stimulus_type='sound')
  263. betas_r = tbx.utils.extract_condition_betas(stimuli=stimuli,
  264. betas=dataset[subject]['RH'][region]['betas_selected'][layer_id].values.T,
  265. stimulus_type='sound')
  266. df_set1[region].append(np.mean([
  267. np.nanmean(betas_l.filter(regex=regex1).values),
  268. np.nanmean(betas_r.filter(regex=regex1).values)]))
  269. df_set2[region].append(np.mean([
  270. np.nanmean(betas_l.filter(regex=regex2).values),
  271. np.nanmean(betas_r.filter(regex=regex2).values)]))
  272. set1[layer_id] = df_set1
  273. set2[layer_id] = df_set2
  274. all_non_parametric_pvals = np.array([[non_parametric_permutation_ttest(np.subtract(set2[layer][region], set1[layer][region])) for layer in layers] for region in regions])
  275. all_non_parametric_pvals_flat = np.array(all_non_parametric_pvals).ravel()
  276. reject_fdr, p_adjusted = fdrcorrection(all_non_parametric_pvals_flat)
  277. p_adjusted = p_adjusted.reshape(np.array(all_non_parametric_pvals).shape)
  278. # %%
  279. all_layer_pvals = []
  280. for region in regions:
  281. for layerA, layerB in itertools.combinations(layers, 2):
  282. diff_betas_layerA = np.subtract(set2[layerA][region], set1[layerA][region]) # difference within layerA
  283. diff_betas_layerB = np.subtract(set2[layerB][region], set1[layerB][region]) # difference within layerB
  284. all_layer_pvals.append(non_parametric_permutation_ttest(diff_betas_layerA - diff_betas_layerB))
  285. reject_fdr, p_layers_adjusted = fdrcorrection(all_layer_pvals)
  286. all_non_parametric_pvals_for_layers = {}
  287. idx = 0
  288. for region in regions:
  289. all_non_parametric_pvals_for_layers[region] = {}
  290. for layerA, layerB in itertools.combinations(layers, 2):
  291. all_non_parametric_pvals_for_layers[region]['_'.join([layerA, layerB])] = p_layers_adjusted[idx]
  292. idx += 1
  293. fig = plt.figure(figsize=(9, 9))
  294. gs = gridspec.GridSpec(3, 3, height_ratios=[1, 1, 1], hspace=0.6, wspace=0.4)
  295. ax1 = fig.add_subplot(gs[0, 0])
  296. ax2 = fig.add_subplot(gs[0, 1])
  297. ax3 = fig.add_subplot(gs[0, 2])
  298. ax4 = fig.add_subplot(gs[1, 0])
  299. ax5 = fig.add_subplot(gs[1, 1])
  300. ax6 = fig.add_subplot(gs[1, 2])
  301. ax7 = fig.add_subplot(gs[2, 0])
  302. ax8 = fig.add_subplot(gs[2, 1])
  303. ax9 = fig.add_subplot(gs[2, 2])
  304. for idx, axis in enumerate(fig.get_axes()): # regions
  305. means1 = np.array([np.nanmean(set1[layer][regions[idx]]) for layer in layers])
  306. stderr1 = np.array([np.nanstd(set1[layer][regions[idx]]) for layer in layers])/np.sqrt(11)
  307. sns.lineplot(means1, ax=axis, c='b', linewidth=3)
  308. axis.errorbar(x=range(len(means1)), y=means1, yerr=stderr1, fmt='o', capsize=2, c='b')
  309. means2 = np.array([np.nanmean(set2[layer][regions[idx]]) for layer in layers])
  310. stderr2 = np.array([np.nanstd(set2[layer][regions[idx]]) for layer in layers])/np.sqrt(11)
  311. sns.lineplot(means2, ax=axis, c='r', linewidth=3)
  312. axis.errorbar(x=range(len(means2)), y=means2, yerr=stderr2, fmt='o', capsize=2, c='r')
  313. # for x, star in enumerate(tbx.viz.pvals2stars(p_adjusted[idx])):
  314. # if star == 'ns': continue
  315. # axis.text(x, 2.5, '*', ha='center', va='bottom', color='k', weight='bold', fontsize=20)
  316. # # layer statistics
  317. # for layer_comb in all_non_parametric_pvals_for_layers[regions[idx]]:
  318. # lA, lB = layer_comb.split('_')
  319. # xA, xB = int(lA[1])-1, int(lB[1])-1
  320. # p_layer = all_non_parametric_pvals_for_layers[regions[idx]][layer_comb]
  321. # star = tbx.viz.pvals2stars(p_layer)
  322. # if star != 'ns':
  323. # if xA==0 and xB==2:
  324. # axis.plot([xA+.1,xB-.1], [2.2,2.2], c='k')
  325. # axis.text((xB+xA)/2, 2.2, '*', ha='center', va='bottom', color='k', weight='bold', fontsize=20)
  326. # axis.plot([xA+.1, xA+.1], [2.1,2.2], c='k')
  327. # axis.plot([xB-.1, xB-.1], [2.1,2.2], c='k')
  328. # else:
  329. # axis.plot([xA+.1,xB-.1], [2,2], c='k')
  330. # axis.text((xB+xA)/2, 2, '*', ha='center', va='bottom', color='k', weight='bold', fontsize=20)
  331. # axis.plot([xA+.1, xA+.1], [2,1.9], c='k')
  332. # axis.plot([xB-.1, xB-.1], [2,1.9], c='k')
  333. axis.set_xticks([0,1,2], [r'$\textbf{D}$', r'$\textbf{M}$', r'$\textbf{S}$'])
  334. axis.set_ylim([0.5, 2.5])
  335. if idx in [0,3,6]:
  336. axis.set_ylabel(r'$\mathbf{\beta\ (\%)}$', fontsize=20)
  337. axis.set_title(r'$\textbf{'+regions[idx]+r'}$')
  338. # make border thicker when there is an interaction
  339. if regions[idx] in ['pSTG', 'pMTG', 'parsOrbitalis', 'parsTriangularis']:
  340. for spine in axis.spines.values():
  341. spine.set_linewidth(2)
  342. spine.set_color('black')
  343. # add layer interactions
  344. if regions[idx] == 'pSTG':
  345. axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5)
  346. axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5)
  347. axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5)
  348. axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5)
  349. axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5)
  350. axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5)
  351. if regions[idx] == 'pMTG':
  352. axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5)
  353. axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5)
  354. axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5)
  355. axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5)
  356. axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5)
  357. axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5)
  358. if regions[idx] == 'parsOrbitalis':
  359. axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5)
  360. axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5)
  361. axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5)
  362. if regions[idx] == 'parsTriangularis':
  363. axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5)
  364. axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5)
  365. axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5)
  366. # if regions[idx] in ['PP', 'HG', 'PT', 'aSTG', 'TPOj']:
  367. # axis.text(1.95, 2.35, '*', color='k', weight='bold', fontsize=20)
  368. blue_line = mlines.Line2D([], [], color='b', linestyle='-', linewidth=2, label='Valid')
  369. red_line = mlines.Line2D([], [], color='r', linestyle='-', linewidth=2, label='Invalid')
  370. fig.legend(handles=[red_line, blue_line], loc='center', bbox_to_anchor=(.5, 0.02))
  371. # Mean Activations of Congruent vs. Invalid Trials (11 Subjects, Averaged Hemisphere, Non-Parametric FDR Corrected
  372. plt.savefig('./figures/univariate_laminar_cong_incong_nonparametric_fdr_friedman.png', dpi=300, bbox_inches='tight')
  373. plt.show()
  374. # %%
  375. from scipy.stats import ttest_rel
  376. ttest_rel(diff_betas_layerA, diff_betas_layerB)
  377. # %%
  378. region = 'parsOrbitalis'
  379. means_diff = np.array([np.mean(np.array(set2[layer][region]) - np.array(set1[layer][region])) for layer in layers])
  380. stderr_diff = np.array([np.std(np.array(set2[layer][region]) - np.array(set1[layer][region])) for layer in layers])/np.sqrt(11)
  381. sns.lineplot(means_diff, ax=axis, c=palette[-2], linewidth=3)
  382. axis.errorbar(x=range(len(means_diff)), y=means_diff, yerr=stderr_diff, fmt='o', capsize=2, c=palette[-2])
  383. # friedman
  384. diffMeas = np.array([set2[item][region] for item in ['L1', 'L2', 'L3']]) - np.array([set1[item][region] for item in ['L1', 'L2', 'L3']]).astype(np.float64)
  385. friedman = friedmanchisquare(*diffMeas)
  386. print(friedman)
  387. # apply multcompare
  388. eng = matlab.engine.start_matlab()
  389. diffMeas_ml = matlab.double(diffMeas.tolist())
  390. eng.workspace['diffMeas'] = diffMeas_ml
  391. eng.eval("[p,tbl,stats] = friedman(diffMeas',1);", nargout=0)
  392. c = eng.eval("multcompare(stats);", nargout=1)
  393. c_py = np.array(c)
  394. eng.quit()
  395. print(pd.DataFrame(c_py[:,2:], index=['D-M', 'D-S', 'M-S'], columns=['Lower CI', 'Mean rank Diff', 'Upper CI', 'p-value']).to_latex())
  396. # %%
  397. sns.heatmap(diffMeas)
  398. # %%
  399. from pprint import pprint
  400. pprint(diffMeas.T)
  401. # %%
  402. # do manual wilcoxon
  403. region = 'parsOrbitalis'
  404. from scipy.stats import wilcoxon
  405. print(wilcoxon(diffMeas[0], diffMeas[1]))
  406. print(wilcoxon(diffMeas[0], diffMeas[2]))
  407. print(wilcoxon(diffMeas[1], diffMeas[2]))
  408. # %%
  409. regions_selected = ['pSTG', 'pMTG', 'parsOrbitalis', 'parsTriangularis']
  410. palette = sns.color_palette('Grays')
  411. all_layer_pvals = []
  412. for region in regions_selected:
  413. for layerA, layerB in itertools.combinations(layers, 2):
  414. diff_betas_layerA = np.subtract(set2[layerA][region], set1[layerA][region]) # difference within layerA
  415. diff_betas_layerB = np.subtract(set2[layerB][region], set1[layerB][region]) # difference within layerB
  416. all_layer_pvals.append(non_parametric_permutation_ttest(diff_betas_layerA - diff_betas_layerB))
  417. reject_fdr, p_layers_adjusted = fdrcorrection(all_layer_pvals)
  418. all_non_parametric_pvals_for_layers = {}
  419. idx = 0
  420. for region in regions_selected:
  421. all_non_parametric_pvals_for_layers[region] = {}
  422. for layerA, layerB in itertools.combinations(layers, 2):
  423. all_non_parametric_pvals_for_layers[region]['_'.join([layerA, layerB])] = p_layers_adjusted[idx]
  424. idx += 1
  425. fig = plt.figure(figsize=(6, 6))
  426. gs = gridspec.GridSpec(2, 2, height_ratios=[1, 1], hspace=0.6, wspace=0.4)
  427. ax1 = fig.add_subplot(gs[0, 0])
  428. ax2 = fig.add_subplot(gs[0, 1])
  429. ax4 = fig.add_subplot(gs[1, 0])
  430. ax5 = fig.add_subplot(gs[1, 1])
  431. for idx, axis in enumerate(fig.get_axes()): # regions_selected
  432. means_diff = np.array([np.mean(np.array(set2[layer][regions_selected[idx]]) - np.array(set1[layer][regions_selected[idx]])) for layer in layers])
  433. stderr_diff = np.array([np.std(np.array(set2[layer][regions_selected[idx]]) - np.array(set1[layer][regions_selected[idx]])) for layer in layers])/np.sqrt(11)
  434. sns.lineplot(means_diff, ax=axis, c=palette[-2], linewidth=3)
  435. axis.errorbar(x=range(len(means_diff)), y=means_diff, yerr=stderr_diff, fmt='o', capsize=2, c=palette[-2])
  436. # friedman
  437. diffMeas = np.array([set2[item][regions_selected[idx]] for item in ['L1', 'L2', 'L3']]) - np.array([set1[item][regions_selected[idx]] for item in ['L1', 'L2', 'L3']]).astype(np.float64)
  438. friedman = friedmanchisquare(*diffMeas)
  439. print(friedman)
  440. # apply multcompare
  441. eng = matlab.engine.start_matlab()
  442. diffMeas_ml = matlab.double(diffMeas.tolist())
  443. eng.workspace['diffMeas'] = diffMeas_ml
  444. eng.eval("[p,tbl,stats] = friedman(diffMeas',1);", nargout=0)
  445. c = eng.eval("multcompare(stats);", nargout=1)
  446. c_py = np.array(c)
  447. eng.quit()
  448. print(pd.DataFrame(c_py[:,2:], index=['D-M', 'D-S', 'M-S'], columns=['Lower CI', 'Mean rank Diff', 'Upper CI', 'p-value']).to_latex())
  449. if regions_selected[idx] == 'pSTG':
  450. axis.axhline(0.9, 0.05, 0.95, c='gray', linewidth=1.5) # D-S
  451. # axis.axhline(0.85, 0.05, 0.45, c='gray', linewidth=1.5) # D-M
  452. # axis.axhline(0.25, 0.55, 0.95, c='gray', linewidth=1.5) # M-S
  453. if regions_selected[idx] == 'pMTG':
  454. axis.axhline(0.9, 0.05, 0.95, c='gray', linewidth=1.5) # D-S
  455. # axis.axhline(0.85, 0.05, 0.45, c='gray', linewidth=1.5) # D-M
  456. # axis.axhline(0.25, 0.55, 0.95, c='gray', linewidth=1.5) # M-S
  457. if regions_selected[idx] == 'parsOrbitalis':
  458. axis.axhline(0.9, 0.05, 0.95, c='gray', linewidth=1.5) # D-S
  459. axis.axhline(0.85, 0.05, 0.45, c='gray', linewidth=1.5) # D-M
  460. axis.axhline(0.85, 0.55, 0.95, c='gray', linewidth=1.5) # M-S
  461. if regions_selected[idx] == 'parsTriangularis':
  462. axis.axhline(0.9, 0.05, 0.95, c='gray', linewidth=1.5) # D-S
  463. # axis.axhline(0.85, 0.05, 0.45, c='gray', linewidth=1.5) # D-M
  464. # axis.axhline(0.85, 0.55, 0.95, c='gray', linewidth=1.5) # M-S
  465. axis.set_xticks([0,1,2], [r'$\textbf{D}$', r'$\textbf{M}$', r'$\textbf{S}$'])
  466. axis.set_ylim([0.0, 1.])
  467. if idx in [0,2]:
  468. axis.set_ylabel(r'$\mathbf{\Delta\beta\ (\%)}$', fontsize=20)
  469. axis.set_title(r'$\textbf{'+regions_selected[idx]+r'}$')
  470. # blue_line = mlines.Line2D([], [], color='b', linestyle='-', linewidth=2, label='Valid')
  471. # red_line = mlines.Line2D([], [], color='r', linestyle='-', linewidth=2, label='Invalid')
  472. # fig.legend(handles=[red_line, blue_line], loc='center', bbox_to_anchor=(.5, 0.02))
  473. # Mean Activations of Congruent vs. Invalid Trials (11 Subjects, Averaged Hemisphere, Non-Parametric FDR Corrected
  474. plt.savefig('./figures/univariate_laminar_cong_incong_nonparametric_fdr_friedman_posthoc.png', dpi=300, bbox_inches='tight')
  475. plt.show()
  476. # %%
  477. diffs = []
  478. for idx, axis in enumerate(fig.get_axes()): # regions_selected
  479. means_diff = np.array([np.mean(np.array(set2[layer][regions_selected[idx]]) - np.array(set1[layer][regions_selected[idx]])) for layer in layers])
  480. stderr_diff = np.array([np.std(np.array(set2[layer][regions_selected[idx]]) - np.array(set1[layer][regions_selected[idx]])) for layer in layers])/np.sqrt(11)
  481. sns.lineplot(means_diff, ax=axis, c=palette[-2], linewidth=3)
  482. axis.errorbar(x=range(len(means_diff)), y=means_diff, yerr=stderr_diff, fmt='o', capsize=2, c=palette[-2])
  483. # friedman
  484. diffMeas = np.array([set2[item][regions_selected[idx]] for item in ['L1', 'L2', 'L3']]) - np.array([set1[item][regions_selected[idx]] for item in ['L1', 'L2', 'L3']]).astype(np.float64)
  485. print(np.mean(diffMeas, axis=1), '\t', regions_selected[idx])
  486. diffs.append(np.mean(diffMeas, axis=1))
  487. diffs = np.array(diffs)
  488. np.min(diffs), np.max(diffs)
  489. # %%
  490. # (0.16910681941292502, 0.6572449369864031
  491. # (-1.1287472214211116, 0.6597942059690302
  492. # (-0.49109694124622777, -0.08562372760339217
  493. scales = [0.16910681941292502, 0.6572449369864031, -1.1287472214211116, 0.6597942059690302, -0.49109694124622777, -0.08562372760339217]
  494. mincol, maxcol = np.min(scales), np.max(scales)
  495. mincol, maxcol
  496. maxcol = 0.4
  497. mincol = 0.1
  498. # %%
  499. from copy import deepcopy
  500. smp_head, smp_data = bvbabel.smp.read_smp('/mnt/hdd2/associative_learning/paper_draft_v1/paper_draft_ALPHA/templates/group_patches_LH_template.smp')
  501. smp_data[smp_data<6] = 0
  502. smp_data[smp_data>0] = 6
  503. # %%
  504. all_regs
  505. # %%
  506. all_regs = [entry['Name'] for entry in smp_head['Map']]
  507. dep = ['pSTG', 'pMTG', 'parsOrbitalis', 'parsTriangularis']
  508. mid = ['pSTG', 'pMTG', 'parsOrbitalis', 'parsTriangularis']
  509. dep = ['pSTG', 'pMTG', 'parsOrbitalis', 'parsTriangularis']
  510. # Superficial
  511. _, indcs, _ = np.intersect1d(all_regs, dep, return_indices=True)
  512. smp_head_cp = deepcopy(smp_head)
  513. smp_head_cp['Nr maps'] = len(indcs)
  514. smp_head_cp['Map'] = list(np.array(smp_head_cp['Map'])[indcs])
  515. data = deepcopy(smp_data[:, indcs])
  516. for idx, tval in enumerate(diffs[:,0]):
  517. data[:, idx][data[:, idx]==6] = tval
  518. smp_head_cp['Map'][idx]['Threshold min'] = mincol
  519. smp_head_cp['Map'][idx]['Threshold max'] = maxcol
  520. print(smp_head_cp['Map'][idx]['Threshold min'], smp_head_cp['Map'][idx]['Threshold max'])
  521. bvbabel.smp.write_smp('/mnt/hdd2/associative_learning/paper_draft_v1/figures/group_patches_LH_univariate_valid_invalid_dep.smp', smp_head_cp, data)
  522. # Middle
  523. _, indcs, _ = np.intersect1d(all_regs, mid, return_indices=True)
  524. smp_head_cp = deepcopy(smp_head)
  525. smp_head_cp['Nr maps'] = len(indcs)
  526. smp_head_cp['Map'] = list(np.array(smp_head_cp['Map'])[indcs])
  527. data = deepcopy(smp_data[:, indcs])
  528. for idx, tval in enumerate(diffs[:,1]):
  529. data[:, idx][data[:, idx]==6] = tval
  530. smp_head_cp['Map'][idx]['Threshold min'] = mincol
  531. smp_head_cp['Map'][idx]['Threshold max'] = maxcol
  532. print(smp_head_cp['Map'][idx]['Threshold min'], smp_head_cp['Map'][idx]['Threshold max'])
  533. bvbabel.smp.write_smp('/mnt/hdd2/associative_learning/paper_draft_v1/figures/group_patches_LH_univariate_valid_invalid_mid.smp', smp_head_cp, data)
  534. # Deep
  535. _, indcs, _ = np.intersect1d(all_regs, sup, return_indices=True)
  536. smp_head_cp = deepcopy(smp_head)
  537. smp_head_cp['Nr maps'] = len(indcs)
  538. smp_head_cp['Map'] = list(np.array(smp_head_cp['Map'])[indcs])
  539. data = deepcopy(smp_data[:, indcs])
  540. for idx, tval in enumerate(diffs[:,2]):
  541. data[:, idx][data[:, idx]==6] = tval
  542. smp_head_cp['Map'][idx]['Threshold min'] = mincol
  543. smp_head_cp['Map'][idx]['Threshold max'] = maxcol
  544. print(smp_head_cp['Map'][idx]['Threshold min'], smp_head_cp['Map'][idx]['Threshold max'])
  545. bvbabel.smp.write_smp('/mnt/hdd2/associative_learning/paper_draft_v1/figures/group_patches_LH_univariate_valid_invalid_sup.smp', smp_head_cp, data)
  546. # %%
  547. import colorsys
  548. import matplotlib.pyplot as plt
  549. def hex_to_rgb(hex_color):
  550. """Convert hex color to an RGB tuple."""
  551. return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
  552. def generate_gradient_hsv(colors, steps=100):
  553. """
  554. Generate a gradient passing through multiple RGB colors using HSV interpolation.
  555. Parameters:
  556. colors (list of tuples): List of RGB colors [(R, G, B), ...] with values between 0-255.
  557. steps (int): The total number of gradient steps.
  558. Returns:
  559. List of RGB tuples forming the gradient.
  560. """
  561. num_segments = len(colors) - 1
  562. steps_per_segment = steps // num_segments
  563. gradient = []
  564. for i in range(num_segments):
  565. color1 = colors[i]
  566. color2 = colors[i + 1]
  567. hsv1 = colorsys.rgb_to_hsv(color1[0] / 255.0, color1[1] / 255.0, color1[2] / 255.0)
  568. hsv2 = colorsys.rgb_to_hsv(color2[0] / 255.0, color2[1] / 255.0, color2[2] / 255.0)
  569. if abs(hsv2[0] - hsv1[0]) > 0.5:
  570. if hsv1[0] > hsv2[0]:
  571. hsv2 = (hsv2[0] + 1, hsv2[1], hsv2[2])
  572. else:
  573. hsv1 = (hsv1[0] + 1, hsv1[1], hsv1[2])
  574. for j in range(steps_per_segment):
  575. t = j / steps_per_segment
  576. hue = (hsv1[0] + (hsv2[0] - hsv1[0]) * t) % 1
  577. saturation = hsv1[1] + (hsv2[1] - hsv1[1]) * t
  578. value = hsv1[2] + (hsv2[2] - hsv1[2]) * t
  579. r, g, b = colorsys.hsv_to_rgb(hue, saturation, value)
  580. gradient.append((int(r * 255), int(g * 255), int(b * 255)))
  581. return gradient
  582. def display_gradient(gradient, fn):
  583. """Display the gradient using Matplotlib."""
  584. fig, ax = plt.subplots(figsize=(10, 1))
  585. ax.imshow([gradient], extent=[0, len(gradient), 0, 1], aspect='auto')
  586. ax.set_xticks([])
  587. ax.set_yticks([])
  588. plt.savefig(fn, dpi=300)
  589. plt.show()
  590. # %%
  591. # hex_colors = np.array(['087bed','086ee0','0861d3','0854c7','0848ba','083aae','082ea1','082194','081588','08087b','b50808','bb1b08','c12e08','c84208','ce5408','d46708','db7b08','e18e08','e7a108','edb508'])#[::-1]
  592. hex_colors = np.array(['b50808','bb1b08','c12e08','c84208','ce5408','d46707','db7b08','e18e08','edb507','edb507'])#[::-1]
  593. colors = [hex_to_rgb(hex_color) for hex_color in hex_colors]
  594. steps = 2000
  595. gradient = generate_gradient_hsv(colors, steps)
  596. display_gradient(gradient, '/mnt/hdd2/associative_learning/paper_draft_v1/figures/gradient_valid_invalid.png')
  597. # %% [markdown]
  598. # ---
  599. #
  600. # # <center> $\Large\textbf{Congruent vs. Omitted}$ </center>
  601. #
  602. # **Test the effect of prediction error.**
  603. # %%
  604. regex1 = '_cong$'
  605. regex2 = '^(?!random).*_omis$'
  606. layers = ['L1', 'L2', 'L3']
  607. tstats = {}; pvals = {}; set1 = {};set2 = {}
  608. for layer_name, layer_id in zip(['Deep', 'Middle', 'Superficial'], ['L1', 'L2', 'L3']):
  609. tstats[layer_id] = []; pvals[layer_id] = []; df_set1 = {}; df_set2 = {}
  610. for region in regions:
  611. df_set1[region] = []
  612. df_set2[region] = []
  613. for subject in subjects:
  614. stimuli = tbx.utils.extract_stimuli(subject)
  615. betas_l = tbx.utils.extract_condition_betas(stimuli=stimuli,
  616. betas=dataset[subject]['LH'][region]['betas_selected'][layer_id].values.T,
  617. stimulus_type='sound')
  618. betas_r = tbx.utils.extract_condition_betas(stimuli=stimuli,
  619. betas=dataset[subject]['RH'][region]['betas_selected'][layer_id].values.T,
  620. stimulus_type='sound')
  621. df_set1[region].append(np.mean([
  622. np.nanmean(betas_l.filter(regex=regex1).values),
  623. np.nanmean(betas_r.filter(regex=regex1).values)]))
  624. df_set2[region].append(np.mean([
  625. np.nanmean(betas_l.filter(regex=regex2).values),
  626. np.nanmean(betas_r.filter(regex=regex2).values)]))
  627. set1[layer_id] = df_set1
  628. set2[layer_id] = df_set2
  629. all_non_parametric_pvals = np.array([[non_parametric_permutation_ttest(np.subtract(set2[layer][region], set1[layer][region])) for layer in layers] for region in regions])
  630. all_non_parametric_pvals_flat = np.array(all_non_parametric_pvals).ravel()
  631. reject_fdr, p_adjusted = fdrcorrection(all_non_parametric_pvals_flat)
  632. p_adjusted = p_adjusted.reshape(np.array(all_non_parametric_pvals).shape)
  633. # %%
  634. all_layer_pvals = []
  635. for region in regions:
  636. for layerA, layerB in itertools.combinations(layers, 2):
  637. diff_betas_layerA = np.subtract(set2[layerA][region], set1[layerA][region]) # difference within layerA
  638. diff_betas_layerB = np.subtract(set2[layerB][region], set1[layerB][region]) # difference within layerB
  639. all_layer_pvals.append(non_parametric_permutation_ttest(diff_betas_layerA - diff_betas_layerB))
  640. reject_fdr, p_layers_adjusted = fdrcorrection(all_layer_pvals)
  641. all_non_parametric_pvals_for_layers = {}
  642. idx = 0
  643. for region in regions:
  644. all_non_parametric_pvals_for_layers[region] = {}
  645. for layerA, layerB in itertools.combinations(layers, 2):
  646. all_non_parametric_pvals_for_layers[region]['_'.join([layerA, layerB])] = p_layers_adjusted[idx]
  647. idx += 1
  648. fig = plt.figure(figsize=(9, 9))
  649. gs = gridspec.GridSpec(3, 3, height_ratios=[1, 1, 1], hspace=0.6, wspace=0.4)
  650. ax1 = fig.add_subplot(gs[0, 0])
  651. ax2 = fig.add_subplot(gs[0, 1])
  652. ax3 = fig.add_subplot(gs[0, 2])
  653. ax4 = fig.add_subplot(gs[1, 0])
  654. ax5 = fig.add_subplot(gs[1, 1])
  655. ax6 = fig.add_subplot(gs[1, 2])
  656. ax7 = fig.add_subplot(gs[2, 0])
  657. ax8 = fig.add_subplot(gs[2, 1])
  658. ax9 = fig.add_subplot(gs[2, 2])
  659. for idx, axis in enumerate(fig.get_axes()): # regions
  660. means1 = np.array([np.nanmean(set1[layer][regions[idx]]) for layer in layers])
  661. stderr1 = np.array([np.nanstd(set1[layer][regions[idx]]) for layer in layers])/np.sqrt(11)
  662. sns.lineplot(means1, ax=axis, c='b', linewidth=3)
  663. axis.errorbar(x=range(len(means1)), y=means1, yerr=stderr1, fmt='o', capsize=2, c='b')
  664. means2 = np.array([np.nanmean(set2[layer][regions[idx]]) for layer in layers])
  665. stderr2 = np.array([np.nanstd(set2[layer][regions[idx]]) for layer in layers])/np.sqrt(11)
  666. sns.lineplot(means2, ax=axis, c='r', linewidth=3)
  667. axis.errorbar(x=range(len(means2)), y=means2, yerr=stderr2, fmt='o', capsize=2, c='r')
  668. axis.set_xticks([0,1,2], [r'$\textbf{D}$', r'$\textbf{M}$', r'$\textbf{S}$'])
  669. axis.set_ylim([0.5, 2.5])
  670. if idx in [0,3,6]:
  671. axis.set_ylabel(r'$\mathbf{\beta\ (\%)}$', fontsize=20)
  672. axis.set_title(r'$\textbf{'+regions[idx]+r'}$')
  673. # make border thicker when there is an interaction
  674. if regions[idx] in ['PP', 'HG', 'PT', 'aSTG', 'pSTG', 'parsOrbitalis', 'parsTriangularis', 'TPOj']:
  675. for spine in axis.spines.values():
  676. spine.set_linewidth(2)
  677. spine.set_color('black')
  678. # add layer interactions
  679. if regions[idx] == 'PP':
  680. # axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  681. axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  682. # axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  683. axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  684. axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  685. axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  686. if regions[idx] == 'HG':
  687. axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  688. axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  689. axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  690. axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  691. axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  692. # axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  693. if regions[idx] == 'PT':
  694. axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  695. axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  696. axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  697. # axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  698. # axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  699. # axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  700. if regions[idx] == 'aSTG':
  701. # axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  702. axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  703. # axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  704. # axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  705. # axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  706. # axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  707. if regions[idx] == 'pSTG':
  708. axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  709. # axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  710. axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  711. axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  712. axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  713. axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  714. if regions[idx] == 'parsOrbitalis':
  715. # axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  716. # axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  717. # axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  718. axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  719. axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  720. axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  721. if regions[idx] == 'parsTriangularis':
  722. # axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  723. # axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  724. axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  725. axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  726. axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  727. axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  728. if regions[idx] == 'TPOj':
  729. # axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  730. # axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  731. axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  732. # axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  733. # axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  734. # axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  735. # if regions[idx] in ['pMTG']:
  736. # axis.text(1.95, 2.35, '*', color='k', weight='bold', fontsize=20)
  737. blue_line = mlines.Line2D([], [], color='b', linestyle='-', linewidth=2, label='Valid')
  738. red_line = mlines.Line2D([], [], color='r', linestyle='-', linewidth=2, label='Omitted (Predictable)')
  739. fig.legend(handles=[red_line, blue_line], loc='center', bbox_to_anchor=(.5, 0.02))
  740. # Mean Activations of Congruent vs. Invalid Trials (11 Subjects, Averaged Hemisphere, Non-Parametric FDR Corrected
  741. plt.savefig('./figures/univariate_laminar_cong_omis_nonparametric_fdr_friedman.png', dpi=300, bbox_inches='tight')
  742. plt.show()
  743. # %%
  744. regions_selected = ['PP', 'HG', 'PT', 'aSTG', 'pSTG', 'parsOrbitalis', 'parsTriangularis', 'TPOj']
  745. palette = sns.color_palette('Grays')
  746. all_layer_pvals = []
  747. for region in regions_selected:
  748. for layerA, layerB in itertools.combinations(layers, 2):
  749. diff_betas_layerA = np.subtract(set2[layerA][region], set1[layerA][region]) # difference within layerA
  750. diff_betas_layerB = np.subtract(set2[layerB][region], set1[layerB][region]) # difference within layerB
  751. all_layer_pvals.append(non_parametric_permutation_ttest(diff_betas_layerA - diff_betas_layerB))
  752. reject_fdr, p_layers_adjusted = fdrcorrection(all_layer_pvals)
  753. all_non_parametric_pvals_for_layers = {}
  754. idx = 0
  755. for region in regions_selected:
  756. all_non_parametric_pvals_for_layers[region] = {}
  757. for layerA, layerB in itertools.combinations(layers, 2):
  758. all_non_parametric_pvals_for_layers[region]['_'.join([layerA, layerB])] = p_layers_adjusted[idx]
  759. idx += 1
  760. fig = plt.figure(figsize=(12, 6))
  761. gs = gridspec.GridSpec(2, 4, height_ratios=[1, 1], hspace=0.6, wspace=0.4)
  762. ax1 = fig.add_subplot(gs[0, 0])
  763. ax2 = fig.add_subplot(gs[0, 1])
  764. ax3 = fig.add_subplot(gs[0, 2])
  765. ax4 = fig.add_subplot(gs[0, 3])
  766. ax5 = fig.add_subplot(gs[1, 0])
  767. ax6 = fig.add_subplot(gs[1, 1])
  768. ax7 = fig.add_subplot(gs[1, 2])
  769. ax8 = fig.add_subplot(gs[1, 3])
  770. for idx, axis in enumerate(fig.get_axes()): # regions_selected
  771. means_diff = np.array([np.nanmean(np.array(set2[layer][regions_selected[idx]]) - np.array(set1[layer][regions_selected[idx]])) for layer in layers])
  772. stderr_diff = np.array([np.nanstd(np.array(set2[layer][regions_selected[idx]]) - np.array(set1[layer][regions_selected[idx]])) for layer in layers])/np.sqrt(11)
  773. sns.lineplot(means_diff, ax=axis, c=palette[-2], linewidth=3)
  774. axis.errorbar(x=range(len(means_diff)), y=means_diff, yerr=stderr_diff, fmt='o', capsize=2, c=palette[-2])
  775. friedman
  776. diffMeas = np.array([set2[item][regions_selected[idx]] for item in ['L1', 'L2', 'L3']]) - np.array([set1[item][regions_selected[idx]] for item in ['L1', 'L2', 'L3']])
  777. friedman = friedmanchisquare(*diffMeas)
  778. print(friedman)
  779. # apply multcompare
  780. eng = matlab.engine.start_matlab()
  781. diffMeas_ml = matlab.double(diffMeas.tolist())
  782. eng.workspace['diffMeas'] = diffMeas_ml
  783. eng.eval("[p,tbl,stats] = friedman(diffMeas',1);", nargout=0)
  784. c = eng.eval("multcompare(stats);", nargout=1)
  785. c_py = np.array(c)
  786. eng.quit()
  787. print(pd.DataFrame(c_py[:,2:], index=['D-M', 'D-S', 'M-S'], columns=['Lower CI', 'Mean rank Diff', 'Upper CI', 'p-value']).to_latex())
  788. if regions_selected[idx] == 'PP':
  789. axis.axhline(0.9, 0.05, 0.95, c='gray', linewidth=1.5) # D-S
  790. # axis.axhline(0.8, 0.05, 0.45, c='gray', linewidth=1.5) # D-M
  791. # axis.axhline(0.8, 0.55, 0.95, c='gray', linewidth=1.5) # M-S
  792. if regions_selected[idx] == 'HG':
  793. axis.axhline(0.9, 0.05, 0.95, c='gray', linewidth=1.5) # D-S
  794. axis.axhline(0.8, 0.05, 0.45, c='gray', linewidth=1.5) # D-M
  795. # axis.axhline(0.8, 0.55, 0.95, c='gray', linewidth=1.5) # M-S
  796. if regions_selected[idx] == 'PT':
  797. axis.axhline(0.9, 0.05, 0.95, c='gray', linewidth=1.5) # D-S
  798. # axis.axhline(0.8, 0.05, 0.45, c='gray', linewidth=1.5) # D-M
  799. axis.axhline(0.8, 0.55, 0.95, c='gray', linewidth=1.5) # M-S
  800. if regions_selected[idx] == 'aSTG':
  801. axis.axhline(0.9, 0.05, 0.95, c='gray', linewidth=1.5) # D-S
  802. # axis.axhline(0.8, 0.05, 0.45, c='gray', linewidth=1.5) # D-M
  803. axis.axhline(0.8, 0.55, 0.95, c='gray', linewidth=1.5) # M-S
  804. if regions_selected[idx] == 'pSTG':
  805. axis.axhline(0.9, 0.05, 0.95, c='gray', linewidth=1.5) # D-S
  806. # axis.axhline(0.8, 0.05, 0.45, c='gray', linewidth=1.5) # D-M
  807. axis.axhline(0.8, 0.55, 0.95, c='gray', linewidth=1.5) # M-S
  808. if regions_selected[idx] == 'parsOrbitalis':
  809. axis.axhline(0.9, 0.05, 0.95, c='gray', linewidth=1.5) # D-S
  810. # axis.axhline(0.8, 0.05, 0.45, c='gray', linewidth=1.5) # D-M
  811. axis.axhline(0.8, 0.55, 0.95, c='gray', linewidth=1.5) # M-S
  812. if regions_selected[idx] == 'parsTriangularis':
  813. axis.axhline(0.9, 0.05, 0.95, c='gray', linewidth=1.5) # D-S
  814. # axis.axhline(0.8, 0.05, 0.45, c='gray', linewidth=1.5) # D-M
  815. # axis.axhline(0.8, 0.55, 0.95, c='gray', linewidth=1.5) # M-S
  816. if regions_selected[idx] == 'TPOj':
  817. axis.axhline(0.9, 0.05, 0.95, c='gray', linewidth=1.5) # D-S
  818. # axis.axhline(0.8, 0.05, 0.45, c='gray', linewidth=1.5) # D-M
  819. # axis.axhline(0.8, 0.55, 0.95, c='gray', linewidth=1.5) # M-S
  820. axis.set_xticks([0,1,2], [r'$\textbf{D}$', r'$\textbf{M}$', r'$\textbf{S}$'])
  821. axis.set_ylim([-1.5, 1.0])
  822. if idx in [0,4]:
  823. axis.set_ylabel(r'$\mathbf{\Delta\beta\ (\%)}$', fontsize=20)
  824. axis.set_title(r'$\textbf{'+regions_selected[idx]+r'}$')
  825. # blue_line = mlines.Line2D([], [], color='b', linestyle='-', linewidth=2, label='Valid')
  826. # red_line = mlines.Line2D([], [], color='r', linestyle='-', linewidth=2, label='Invalid')
  827. # fig.legend(handles=[red_line, blue_line], loc='center', bbox_to_anchor=(.5, 0.02))
  828. # Mean Activations of Congruent vs. Invalid Trials (11 Subjects, Averaged Hemisphere, Non-Parametric FDR Corrected
  829. plt.savefig('./figures/univariate_laminar_cong_omis_nonparametric_fdr_friedman_posthoc.png', dpi=300, bbox_inches='tight')
  830. plt.show()
  831. # %%
  832. diffs = []
  833. for idx, axis in enumerate(fig.get_axes()): # regions_selected
  834. means_diff = np.array([np.mean(np.array(set2[layer][regions_selected[idx]]) - np.array(set1[layer][regions_selected[idx]])) for layer in layers])
  835. stderr_diff = np.array([np.std(np.array(set2[layer][regions_selected[idx]]) - np.array(set1[layer][regions_selected[idx]])) for layer in layers])/np.sqrt(11)
  836. sns.lineplot(means_diff, ax=axis, c=palette[-2], linewidth=3)
  837. axis.errorbar(x=range(len(means_diff)), y=means_diff, yerr=stderr_diff, fmt='o', capsize=2, c=palette[-2])
  838. # friedman
  839. diffMeas = np.array([set2[item][regions_selected[idx]] for item in ['L1', 'L2', 'L3']]) - np.array([set1[item][regions_selected[idx]] for item in ['L1', 'L2', 'L3']]).astype(np.float64)
  840. print(np.mean(diffMeas, axis=1), '\t', regions_selected[idx])
  841. diffs.append(np.mean(diffMeas, axis=1))
  842. diffs = np.array(diffs)
  843. print(diffs.shape)
  844. np.min(diffs), np.max(diffs)
  845. # %%
  846. mincol = 0.1
  847. maxcol = .4
  848. # %%
  849. all_regs = [entry['Name'] for entry in smp_head['Map']]
  850. indcs = np.array([0,1,2,3,4,8,7,6])
  851. selected = ['HG', 'PP', 'PT', 'aSTG', 'pSTG', 'parsOrbitalis', 'parsTriangularis', 'TPOj']
  852. # Superficial
  853. # _, indcs, _ = np.intersect1d(all_regs, selected, return_indices=True)
  854. smp_head_cp = deepcopy(smp_head)
  855. smp_head_cp['Nr maps'] = len(indcs)
  856. smp_head_cp['Map'] = list(np.array(smp_head_cp['Map'])[indcs])
  857. data = deepcopy(smp_data[:, indcs])
  858. for idx, tval in enumerate(diffs[:,0]):
  859. data[:, idx][data[:, idx]==6] = tval
  860. smp_head_cp['Map'][idx]['Threshold min'] = mincol
  861. smp_head_cp['Map'][idx]['Threshold max'] = maxcol
  862. print(smp_head_cp['Map'][idx]['Threshold min'], smp_head_cp['Map'][idx]['Threshold max'])
  863. bvbabel.smp.write_smp('/mnt/hdd2/associative_learning/paper_draft_v1/figures/group_patches_LH_univariate_valid_predomit_dep.smp', smp_head_cp, data)
  864. # Middle
  865. # _, indcs, _ = np.intersect1d(all_regs, selected, return_indices=True)
  866. smp_head_cp = deepcopy(smp_head)
  867. smp_head_cp['Nr maps'] = len(indcs)
  868. smp_head_cp['Map'] = list(np.array(smp_head_cp['Map'])[indcs])
  869. data = deepcopy(smp_data[:, indcs])
  870. for idx, tval in enumerate(diffs[:,1]):
  871. data[:, idx][data[:, idx]==6] = tval
  872. smp_head_cp['Map'][idx]['Threshold min'] = mincol
  873. smp_head_cp['Map'][idx]['Threshold max'] = maxcol
  874. print(smp_head_cp['Map'][idx]['Threshold min'], smp_head_cp['Map'][idx]['Threshold max'])
  875. bvbabel.smp.write_smp('/mnt/hdd2/associative_learning/paper_draft_v1/figures/group_patches_LH_univariate_valid_predomit_mid.smp', smp_head_cp, data)
  876. # Deep
  877. # _, indcs, _ = np.intersect1d(all_regs, selected, return_indices=True)
  878. smp_head_cp = deepcopy(smp_head)
  879. smp_head_cp['Nr maps'] = len(indcs)
  880. smp_head_cp['Map'] = list(np.array(smp_head_cp['Map'])[indcs])
  881. data = deepcopy(smp_data[:, indcs])
  882. for idx, tval in enumerate(diffs[:,2]):
  883. data[:, idx][data[:, idx]==6] = tval
  884. smp_head_cp['Map'][idx]['Threshold min'] = mincol
  885. smp_head_cp['Map'][idx]['Threshold max'] = maxcol
  886. print(smp_head_cp['Map'][idx]['Threshold min'], smp_head_cp['Map'][idx]['Threshold max'])
  887. bvbabel.smp.write_smp('/mnt/hdd2/associative_learning/paper_draft_v1/figures/group_patches_LH_univariate_valid_predomit_sup.smp', smp_head_cp, data)
  888. # %%
  889. def display_gradient(gradient, fn, figsize=(10, 1)):
  890. """Display the gradient using Matplotlib."""
  891. fig, ax = plt.subplots(figsize=figsize)
  892. ax.imshow([gradient], extent=[0, len(gradient), 0, 1], aspect='auto')
  893. ax.set_xticks([])
  894. ax.set_yticks([])
  895. plt.savefig(fn, dpi=300)
  896. plt.show()
  897. # %%
  898. steps = 2000
  899. fig, ax = plt.subplots(1,2, figsize=(10,1))
  900. plt.subplots_adjust(wspace=0.01)
  901. hex_colors = np.array(['b50808','bb1b08','c12e08','c84208','ce5408','d46708','db7b08','e18e08','e7a108','edb508'])#[::-1]
  902. colors = [hex_to_rgb(hex_color) for hex_color in hex_colors]
  903. gradient = generate_gradient_hsv(colors, steps)
  904. fn = '/mnt/hdd2/associative_learning/paper_draft_v1/figures/gradient_valid_predomit.png'
  905. ax[1].imshow([gradient], extent=[0, len(gradient), 0, 1], aspect='auto')
  906. ax[1].set_xticks([])
  907. ax[1].set_yticks([])
  908. hex_colors = np.array(['087bed','086ee0','0861d3','0854c7','0848ba','083aae','082ea1','082194','081588','08087b'])
  909. colors = [hex_to_rgb(hex_color) for hex_color in hex_colors]
  910. gradient = generate_gradient_hsv(colors, steps)
  911. ax[0].imshow([gradient], extent=[0, len(gradient), 0, 1], aspect='auto')
  912. ax[0].set_xticks([])
  913. ax[0].set_yticks([])
  914. plt.savefig(fn, dpi=300)
  915. plt.show()
  916. # %% [markdown]
  917. # ---
  918. #
  919. # # <center> $\Large\textbf{Congruent vs. Random}$ </center>
  920. #
  921. # **Test the effect of prediction.**
  922. # %%
  923. regex1 = '_cong$'
  924. regex2 = 'MANUAL'
  925. set1 = {};set2 = {}
  926. for layer_name, layer_id in zip(['Deep', 'Middle', 'Superficial'], ['L1', 'L2', 'L3']):
  927. tstats[layer_id] = []; pvals[layer_id] = []; df_set1 = {}; df_set2 = {}
  928. for region in regions:
  929. df_set1[region] = []
  930. df_set2[region] = []
  931. for subject in subjects:
  932. stimuli = tbx.utils.extract_stimuli(subject)
  933. betas_l = tbx.utils.extract_condition_betas(stimuli=stimuli,
  934. betas=dataset[subject]['LH'][region]['betas_selected'][layer_id].values.T,
  935. stimulus_type='sound')
  936. betas_r = tbx.utils.extract_condition_betas(stimuli=stimuli,
  937. betas=dataset[subject]['RH'][region]['betas_selected'][layer_id].values.T,
  938. stimulus_type='sound')
  939. df_set1[region].append(np.mean([
  940. np.nanmean(betas_l.filter(regex=regex1).values),
  941. np.nanmean(betas_r.filter(regex=regex1).values)]))
  942. df_set2[region].append(np.mean([
  943. np.nanmean(betas_l.filter(regex='^random').filter(regex='^(?!.*_omis$)').values),
  944. np.nanmean(betas_r.filter(regex='^random').filter(regex='^(?!.*_omis$)').values)]))
  945. set1[layer_id] = df_set1
  946. set2[layer_id] = df_set2
  947. all_non_parametric_pvals = np.array([[non_parametric_permutation_ttest(np.subtract(set2[layer][region], set1[layer][region])) for layer in layers] for region in regions])
  948. all_non_parametric_pvals_flat = np.array(all_non_parametric_pvals).ravel()
  949. reject_fdr, p_adjusted = fdrcorrection(all_non_parametric_pvals_flat)
  950. p_adjusted = p_adjusted.reshape(np.array(all_non_parametric_pvals).shape)
  951. # %%
  952. all_layer_pvals = []
  953. for region in regions:
  954. for layerA, layerB in itertools.combinations(layers, 2):
  955. diff_betas_layerA = np.subtract(set2[layerA][region], set1[layerA][region]) # difference within layerA
  956. diff_betas_layerB = np.subtract(set2[layerB][region], set1[layerB][region]) # difference within layerB
  957. all_layer_pvals.append(non_parametric_permutation_ttest(diff_betas_layerA - diff_betas_layerB))
  958. reject_fdr, p_layers_adjusted = fdrcorrection(all_layer_pvals)
  959. all_non_parametric_pvals_for_layers = {}
  960. idx = 0
  961. for region in regions:
  962. all_non_parametric_pvals_for_layers[region] = {}
  963. for layerA, layerB in itertools.combinations(layers, 2):
  964. all_non_parametric_pvals_for_layers[region]['_'.join([layerA, layerB])] = p_layers_adjusted[idx]
  965. idx += 1
  966. fig = plt.figure(figsize=(9, 9))
  967. gs = gridspec.GridSpec(3, 3, height_ratios=[1, 1, 1], hspace=0.6, wspace=0.4)
  968. ax1 = fig.add_subplot(gs[0, 0])
  969. ax2 = fig.add_subplot(gs[0, 1])
  970. ax3 = fig.add_subplot(gs[0, 2])
  971. ax4 = fig.add_subplot(gs[1, 0])
  972. ax5 = fig.add_subplot(gs[1, 1])
  973. ax6 = fig.add_subplot(gs[1, 2])
  974. ax7 = fig.add_subplot(gs[2, 0])
  975. ax8 = fig.add_subplot(gs[2, 1])
  976. ax9 = fig.add_subplot(gs[2, 2])
  977. for idx, axis in enumerate(fig.get_axes()): # regions
  978. means1 = np.array([np.nanmean(set1[layer][regions[idx]]) for layer in layers])
  979. stderr1 = np.array([np.nanstd(set1[layer][regions[idx]]) for layer in layers])/np.sqrt(11)
  980. sns.lineplot(means1, ax=axis, c='b', linewidth=3)
  981. axis.errorbar(x=range(len(means1)), y=means1, yerr=stderr1, fmt='o', capsize=2, c='b')
  982. means2 = np.array([np.nanmean(set2[layer][regions[idx]]) for layer in layers])
  983. stderr2 = np.array([np.nanstd(set2[layer][regions[idx]]) for layer in layers])/np.sqrt(11)
  984. sns.lineplot(means2, ax=axis, c='r', linewidth=3)
  985. axis.errorbar(x=range(len(means2)), y=means2, yerr=stderr2, fmt='o', capsize=2, c='r')
  986. axis.set_xticks([0,1,2], [r'$\textbf{D}$', r'$\textbf{M}$', r'$\textbf{S}$'])
  987. axis.set_ylim([0.5, 2.5])
  988. if idx in [0,3,6]:
  989. axis.set_ylabel(r'$\mathbf{\beta\ (\%)}$', fontsize=20)
  990. axis.set_title(r'$\textbf{'+regions[idx]+r'}$')
  991. # make border thicker when there is an interaction
  992. # if regions[idx] in ['PP', 'HG', 'PT', 'aSTG', 'pSTG', 'parsOrbitalis', 'parsTriangularis', 'TPOj']:
  993. # for spine in axis.spines.values():
  994. # spine.set_linewidth(2)
  995. # spine.set_color('black')
  996. # add layer interactions
  997. # if regions[idx] == 'PP':
  998. # axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  999. # axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  1000. # axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  1001. # axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  1002. # axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  1003. # axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  1004. if regions[idx] in ['PP']:
  1005. axis.text(1.95, 2.35, '*', color='k', weight='bold', fontsize=20)
  1006. blue_line = mlines.Line2D([], [], color='b', linestyle='-', linewidth=2, label='Valid')
  1007. red_line = mlines.Line2D([], [], color='r', linestyle='-', linewidth=2, label='Unpredictable')
  1008. fig.legend(handles=[red_line, blue_line], loc='center', bbox_to_anchor=(.5, 0.02))
  1009. # Mean Activations of Congruent vs. Invalid Trials (11 Subjects, Averaged Hemisphere, Non-Parametric FDR Corrected
  1010. plt.savefig('./figures/univariate_laminar_cong_rand_nonparametric_fdr_friedman.png', dpi=300, bbox_inches='tight')
  1011. plt.show()
  1012. # %%
  1013. diffs = []
  1014. for idx, axis in enumerate(fig.get_axes()): # regions_selected
  1015. means_diff = np.array([np.mean(np.array(set2[layer][regions_selected[idx]]) - np.array(set1[layer][regions_selected[idx]])) for layer in layers])
  1016. stderr_diff = np.array([np.std(np.array(set2[layer][regions_selected[idx]]) - np.array(set1[layer][regions_selected[idx]])) for layer in layers])/np.sqrt(11)
  1017. sns.lineplot(means_diff, ax=axis, c=palette[-2], linewidth=3)
  1018. axis.errorbar(x=range(len(means_diff)), y=means_diff, yerr=stderr_diff, fmt='o', capsize=2, c=palette[-2])
  1019. # friedman
  1020. diffMeas = np.array([set2[item][regions_selected[idx]] for item in ['L1', 'L2', 'L3']]) - np.array([set1[item][regions_selected[idx]] for item in ['L1', 'L2', 'L3']]).astype(np.float64)
  1021. print(np.mean(diffMeas, axis=1), '\t', regions_selected[idx])
  1022. diffs.append(np.mean(diffMeas, axis=1))
  1023. diffs = np.array(diffs)
  1024. np.min(diffs), np.max(diffs)
  1025. # %% [markdown]
  1026. # ---
  1027. #
  1028. # # <center> $\Large\textbf{Omitted Predictable vs. Omitted Random}$ </center>
  1029. #
  1030. # **Test the effect of prediction.**
  1031. # %%
  1032. regex1 = '^(?!random).*_omis$'
  1033. regex2 = '^random.*_omis$'
  1034. set1 = {};set2 = {}
  1035. for layer_name, layer_id in zip(['Deep', 'Middle', 'Superficial'], ['L1', 'L2', 'L3']):
  1036. tstats[layer_id] = []; pvals[layer_id] = []; df_set1 = {}; df_set2 = {}
  1037. for region in regions:
  1038. df_set1[region] = []
  1039. df_set2[region] = []
  1040. for subject in subjects:
  1041. stimuli = tbx.utils.extract_stimuli(subject)
  1042. betas_l = tbx.utils.extract_condition_betas(stimuli=stimuli,
  1043. betas=dataset[subject]['LH'][region]['betas_selected'][layer_id].values.T,
  1044. stimulus_type='sound')
  1045. betas_r = tbx.utils.extract_condition_betas(stimuli=stimuli,
  1046. betas=dataset[subject]['RH'][region]['betas_selected'][layer_id].values.T,
  1047. stimulus_type='sound')
  1048. df_set1[region].append(np.mean([
  1049. np.nanmean(betas_l.filter(regex=regex1).values),
  1050. np.nanmean(betas_r.filter(regex=regex1).values)]))
  1051. df_set2[region].append(np.mean([
  1052. np.nanmean(betas_l.filter(regex=regex2).values),
  1053. np.nanmean(betas_r.filter(regex=regex2).values)]))
  1054. set1[layer_id] = df_set1
  1055. set2[layer_id] = df_set2
  1056. all_non_parametric_pvals = np.array([[non_parametric_permutation_ttest(np.subtract(set2[layer][region], set1[layer][region])) for layer in layers] for region in regions])
  1057. all_non_parametric_pvals_flat = np.array(all_non_parametric_pvals).ravel()
  1058. reject_fdr, p_adjusted = fdrcorrection(all_non_parametric_pvals_flat)
  1059. p_adjusted = p_adjusted.reshape(np.array(all_non_parametric_pvals).shape)
  1060. # %%
  1061. all_layer_pvals = []
  1062. for region in regions:
  1063. for layerA, layerB in itertools.combinations(layers, 2):
  1064. diff_betas_layerA = np.subtract(set2[layerA][region], set1[layerA][region]) # difference within layerA
  1065. diff_betas_layerB = np.subtract(set2[layerB][region], set1[layerB][region]) # difference within layerB
  1066. all_layer_pvals.append(non_parametric_permutation_ttest(diff_betas_layerA - diff_betas_layerB))
  1067. reject_fdr, p_layers_adjusted = fdrcorrection(all_layer_pvals)
  1068. all_non_parametric_pvals_for_layers = {}
  1069. idx = 0
  1070. for region in regions:
  1071. all_non_parametric_pvals_for_layers[region] = {}
  1072. for layerA, layerB in itertools.combinations(layers, 2):
  1073. all_non_parametric_pvals_for_layers[region]['_'.join([layerA, layerB])] = p_layers_adjusted[idx]
  1074. idx += 1
  1075. fig = plt.figure(figsize=(9, 9))
  1076. gs = gridspec.GridSpec(3, 3, height_ratios=[1, 1, 1], hspace=0.6, wspace=0.4)
  1077. ax1 = fig.add_subplot(gs[0, 0])
  1078. ax2 = fig.add_subplot(gs[0, 1])
  1079. ax3 = fig.add_subplot(gs[0, 2])
  1080. ax4 = fig.add_subplot(gs[1, 0])
  1081. ax5 = fig.add_subplot(gs[1, 1])
  1082. ax6 = fig.add_subplot(gs[1, 2])
  1083. ax7 = fig.add_subplot(gs[2, 0])
  1084. ax8 = fig.add_subplot(gs[2, 1])
  1085. ax9 = fig.add_subplot(gs[2, 2])
  1086. for idx, axis in enumerate(fig.get_axes()): # regions
  1087. means1 = np.array([np.nanmean(set1[layer][regions[idx]]) for layer in layers])
  1088. stderr1 = np.array([np.nanstd(set1[layer][regions[idx]]) for layer in layers])/np.sqrt(11)
  1089. sns.lineplot(means1, ax=axis, c='b', linewidth=3)
  1090. axis.errorbar(x=range(len(means1)), y=means1, yerr=stderr1, fmt='o', capsize=2, c='b')
  1091. means2 = np.array([np.nanmean(set2[layer][regions[idx]]) for layer in layers])
  1092. stderr2 = np.array([np.nanstd(set2[layer][regions[idx]]) for layer in layers])/np.sqrt(11)
  1093. sns.lineplot(means2, ax=axis, c='r', linewidth=3)
  1094. axis.errorbar(x=range(len(means2)), y=means2, yerr=stderr2, fmt='o', capsize=2, c='r')
  1095. axis.set_xticks([0,1,2], [r'$\textbf{D}$', r'$\textbf{M}$', r'$\textbf{S}$'])
  1096. axis.set_ylim([0., 2.5])
  1097. if idx in [0,3,6]:
  1098. axis.set_ylabel(r'$\mathbf{\beta\ (\%)}$', fontsize=20)
  1099. axis.set_title(r'$\textbf{'+regions[idx]+r'}$')
  1100. # make border thicker when there is an interaction
  1101. if regions[idx] in ['HG', 'pSTG', 'pMTG']:
  1102. for spine in axis.spines.values():
  1103. spine.set_linewidth(2)
  1104. spine.set_color('black')
  1105. # add layer interactions
  1106. if regions[idx] == 'HG':
  1107. axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  1108. axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  1109. # axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  1110. axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  1111. axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  1112. axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  1113. if regions[idx] == 'pSTG':
  1114. axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  1115. # axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  1116. axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  1117. # axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  1118. axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  1119. # axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  1120. if regions[idx] == 'pMTG':
  1121. axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  1122. axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  1123. axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  1124. # axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  1125. # axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  1126. # axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  1127. blue_line = mlines.Line2D([], [], color='b', linestyle='-', linewidth=2, label='Omitted (Predictable)')
  1128. red_line = mlines.Line2D([], [], color='r', linestyle='-', linewidth=2, label='Omitted (Unpredictable)')
  1129. fig.legend(handles=[red_line, blue_line], loc='center', bbox_to_anchor=(.5, 0.))
  1130. # Mean Activations of Congruent vs. Invalid Trials (11 Subjects, Averaged Hemisphere, Non-Parametric FDR Corrected
  1131. # plt.savefig('./results/univariate_laminar_congomit_randomit_nonparametric_fdr.png', dpi=300, bbox_inches='tight')
  1132. plt.savefig('./figures/univariate_laminar_congomis_randomis_nonparametric_fdr_friedman.png', dpi=300, bbox_inches='tight')
  1133. plt.show()
  1134. # %%
  1135. regions_selected = ['HG', 'pSTG', 'pMTG']
  1136. palette = sns.color_palette('Grays')
  1137. all_layer_pvals = []
  1138. for region in regions_selected:
  1139. for layerA, layerB in itertools.combinations(layers, 2):
  1140. diff_betas_layerA = np.subtract(set2[layerA][region], set1[layerA][region]) # difference within layerA
  1141. diff_betas_layerB = np.subtract(set2[layerB][region], set1[layerB][region]) # difference within layerB
  1142. all_layer_pvals.append(non_parametric_permutation_ttest(diff_betas_layerA - diff_betas_layerB))
  1143. reject_fdr, p_layers_adjusted = fdrcorrection(all_layer_pvals)
  1144. all_non_parametric_pvals_for_layers = {}
  1145. idx = 0
  1146. for region in regions_selected:
  1147. all_non_parametric_pvals_for_layers[region] = {}
  1148. for layerA, layerB in itertools.combinations(layers, 2):
  1149. all_non_parametric_pvals_for_layers[region]['_'.join([layerA, layerB])] = p_layers_adjusted[idx]
  1150. idx += 1
  1151. fig = plt.figure(figsize=(9, 6))
  1152. gs = gridspec.GridSpec(2, 3, height_ratios=[1, 1], hspace=0.6, wspace=0.4)
  1153. ax1 = fig.add_subplot(gs[0, 0])
  1154. ax2 = fig.add_subplot(gs[0, 1])
  1155. ax3 = fig.add_subplot(gs[0, 2])
  1156. for idx, axis in enumerate(fig.get_axes()): # regions_selected
  1157. # means_diff = np.array([np.nanmean(np.array(set2[layer][regions_selected[idx]]) - np.array(set1[layer][regions_selected[idx]])) for layer in layers])
  1158. # stderr_diff = np.array([np.nanstd(np.array(set2[layer][regions_selected[idx]]) - np.array(set1[layer][regions_selected[idx]])) for layer in layers])/np.sqrt(11)
  1159. means_diff = np.array([np.nanmean(np.array(set1[layer][regions_selected[idx]]) - np.array(set2[layer][regions_selected[idx]])) for layer in layers])
  1160. stderr_diff = np.array([np.nanstd(np.array(set1[layer][regions_selected[idx]]) - np.array(set2[layer][regions_selected[idx]])) for layer in layers])/np.sqrt(11)
  1161. sns.lineplot(means_diff, ax=axis, c=palette[-2], linewidth=3)
  1162. axis.errorbar(x=range(len(means_diff)), y=means_diff, yerr=stderr_diff, fmt='o', capsize=2, c=palette[-2])
  1163. friedman
  1164. diffMeas = np.array([set2[item][regions_selected[idx]] for item in ['L1', 'L2', 'L3']]) - np.array([set1[item][regions_selected[idx]] for item in ['L1', 'L2', 'L3']])
  1165. friedman = friedmanchisquare(*diffMeas)
  1166. print(friedman)
  1167. # apply multcompare
  1168. eng = matlab.engine.start_matlab()
  1169. diffMeas_ml = matlab.double(diffMeas.tolist())
  1170. eng.workspace['diffMeas'] = diffMeas_ml
  1171. eng.eval("[p,tbl,stats] = friedman(diffMeas',1);", nargout=0)
  1172. c = eng.eval("multcompare(stats);", nargout=1)
  1173. c_py = np.array(c)
  1174. eng.quit()
  1175. print(pd.DataFrame(c_py[:,2:], index=['D-M', 'D-S', 'M-S'], columns=['Lower CI', 'Mean rank Diff', 'Upper CI', 'p-value']).to_latex())
  1176. if regions_selected[idx] == 'HG':
  1177. axis.axhline(0.9, 0.05, 0.95, c='gray', linewidth=1.5) # D-S
  1178. # axis.axhline(2.3-2.3+0.2, 0.05, 0.45, c='gray', linewidth=1.5) # D-M
  1179. # axis.axhline(2.3-2.3+0.2, 0.55, 0.95, c='gray', linewidth=1.5) # M-S
  1180. if regions_selected[idx] == 'pSTG':
  1181. axis.axhline(0.9, 0.05, 0.95, c='gray', linewidth=1.5) # D-S
  1182. # axis.axhline(2.3-2.3+0.2, 0.05, 0.45, c='gray', linewidth=1.5) # D-M
  1183. axis.axhline(0.85, 0.55, 0.95, c='gray', linewidth=1.5) # M-S
  1184. if regions_selected[idx] == 'pMTG':
  1185. axis.axhline(0.9, 0.05, 0.95, c='gray', linewidth=1.5) # D-S
  1186. # axis.axhline(2.3-2.3+0.2, 0.05, 0.45, c='gray', linewidth=1.5) # D-M
  1187. # axis.axhline(2.3-2.3+0.2, 0.55, 0.95, c='gray', linewidth=1.5) # M-S
  1188. axis.set_xticks([0,1,2], [r'$\textbf{D}$', r'$\textbf{M}$', r'$\textbf{S}$'])
  1189. axis.set_ylim([0.0, 1.0])
  1190. if idx in [0,4]:
  1191. axis.set_ylabel(r'$\mathbf{\Delta\beta\ (\%)}$', fontsize=20)
  1192. axis.set_title(r'$\textbf{'+regions_selected[idx]+r'}$')
  1193. # blue_line = mlines.Line2D([], [], color='b', linestyle='-', linewidth=2, label='Valid')
  1194. # red_line = mlines.Line2D([], [], color='r', linestyle='-', linewidth=2, label='Invalid')
  1195. # fig.legend(handles=[red_line, blue_line], loc='center', bbox_to_anchor=(.5, 0.02))
  1196. # Mean Activations of Congruent vs. Invalid Trials (11 Subjects, Averaged Hemisphere, Non-Parametric FDR Corrected
  1197. plt.savefig('./figures/univariate_laminar_congomis_randomis_nonparametric_fdr_friedman_posthoc.png', dpi=300, bbox_inches='tight')
  1198. plt.show()
  1199. # %%
  1200. diffs = []
  1201. for idx, axis in enumerate(fig.get_axes()): # regions_selected
  1202. means_diff = np.array([np.mean(np.array(set2[layer][regions_selected[idx]]) - np.array(set1[layer][regions_selected[idx]])) for layer in layers])
  1203. stderr_diff = np.array([np.std(np.array(set2[layer][regions_selected[idx]]) - np.array(set1[layer][regions_selected[idx]])) for layer in layers])/np.sqrt(11)
  1204. sns.lineplot(means_diff, ax=axis, c=palette[-2], linewidth=3)
  1205. axis.errorbar(x=range(len(means_diff)), y=means_diff, yerr=stderr_diff, fmt='o', capsize=2, c=palette[-2])
  1206. # friedman
  1207. diffMeas = np.array([set2[item][regions_selected[idx]] for item in ['L1', 'L2', 'L3']]) - np.array([set1[item][regions_selected[idx]] for item in ['L1', 'L2', 'L3']]).astype(np.float64)
  1208. print(np.mean(diffMeas, axis=1), '\t', regions_selected[idx])
  1209. diffs.append(np.mean(diffMeas, axis=1))
  1210. diffs = np.array(diffs) * -1
  1211. np.min(diffs), np.max(diffs)
  1212. # %%
  1213. mincol, maxcol
  1214. # %%
  1215. all_regs = [entry['Name'] for entry in smp_head['Map']]
  1216. indcs = np.array([0,4,5])
  1217. selected = ['HG', 'pSTG', 'pMTG']
  1218. # Superficial
  1219. # _, indcs, _ = np.intersect1d(all_regs, selected, return_indices=True)
  1220. smp_head_cp = deepcopy(smp_head)
  1221. smp_head_cp['Nr maps'] = len(indcs)
  1222. smp_head_cp['Map'] = list(np.array(smp_head_cp['Map'])[indcs])
  1223. data = deepcopy(smp_data[:, indcs])
  1224. for idx, tval in enumerate(diffs[:,0]):
  1225. data[:, idx][data[:, idx]==6] = tval
  1226. smp_head_cp['Map'][idx]['Threshold min'] = mincol
  1227. smp_head_cp['Map'][idx]['Threshold max'] = maxcol
  1228. print(smp_head_cp['Map'][idx]['Threshold min'], smp_head_cp['Map'][idx]['Threshold max'])
  1229. bvbabel.smp.write_smp('/mnt/hdd2/associative_learning/paper_draft_v1/figures/group_patches_LH_univariate_predomit_unpredomit_dep.smp', smp_head_cp, data)
  1230. # Middle
  1231. # _, indcs, _ = np.intersect1d(all_regs, selected, return_indices=True)
  1232. smp_head_cp = deepcopy(smp_head)
  1233. smp_head_cp['Nr maps'] = len(indcs)
  1234. smp_head_cp['Map'] = list(np.array(smp_head_cp['Map'])[indcs])
  1235. data = deepcopy(smp_data[:, indcs])
  1236. for idx, tval in enumerate(diffs[:,1]):
  1237. data[:, idx][data[:, idx]==6] = tval
  1238. smp_head_cp['Map'][idx]['Threshold min'] = mincol
  1239. smp_head_cp['Map'][idx]['Threshold max'] = maxcol
  1240. print(smp_head_cp['Map'][idx]['Threshold min'], smp_head_cp['Map'][idx]['Threshold max'])
  1241. bvbabel.smp.write_smp('/mnt/hdd2/associative_learning/paper_draft_v1/figures/group_patches_LH_univariate_predomit_unpredomit_mid.smp', smp_head_cp, data)
  1242. # Deep
  1243. # _, indcs, _ = np.intersect1d(all_regs, selected, return_indices=True)
  1244. smp_head_cp = deepcopy(smp_head)
  1245. smp_head_cp['Nr maps'] = len(indcs)
  1246. smp_head_cp['Map'] = list(np.array(smp_head_cp['Map'])[indcs])
  1247. data = deepcopy(smp_data[:, indcs])
  1248. for idx, tval in enumerate(diffs[:,2]):
  1249. data[:, idx][data[:, idx]==6] = tval
  1250. smp_head_cp['Map'][idx]['Threshold min'] = mincol
  1251. smp_head_cp['Map'][idx]['Threshold max'] = maxcol
  1252. print(smp_head_cp['Map'][idx]['Threshold min'], smp_head_cp['Map'][idx]['Threshold max'])
  1253. bvbabel.smp.write_smp('/mnt/hdd2/associative_learning/paper_draft_v1/figures/group_patches_LH_univariate_predomit_unpredomit_sup.smp', smp_head_cp, data)
  1254. # %%
  1255. # %%
  1256. # %%
  1257. # %% [markdown]
  1258. # ---
  1259. #
  1260. # # <center> $\Large\textbf{Unpredictable vs. Omitted (Unpredictable)}$ </center>
  1261. #
  1262. # **Test the effect of prediction.**
  1263. # %%
  1264. regex1 = 'MANUAL' #'^random.*_(?!omis)$'
  1265. regex2 = '^random.*_omis$'
  1266. set1 = {};set2 = {}
  1267. for layer_name, layer_id in zip(['Deep', 'Middle', 'Superficial'], ['L1', 'L2', 'L3']):
  1268. tstats[layer_id] = []; pvals[layer_id] = []; df_set1 = {}; df_set2 = {}
  1269. for region in regions:
  1270. df_set1[region] = []
  1271. df_set2[region] = []
  1272. for subject in subjects:
  1273. stimuli = tbx.utils.extract_stimuli(subject)
  1274. betas_l = tbx.utils.extract_condition_betas(stimuli=stimuli,
  1275. betas=dataset[subject]['LH'][region]['betas_selected'][layer_id].values.T,
  1276. stimulus_type='sound')
  1277. betas_r = tbx.utils.extract_condition_betas(stimuli=stimuli,
  1278. betas=dataset[subject]['RH'][region]['betas_selected'][layer_id].values.T,
  1279. stimulus_type='sound')
  1280. df_set1[region].append(np.mean([
  1281. np.nanmean(betas_l.filter(regex='^random').filter(regex='^(?!.*_omis$)').values),
  1282. np.nanmean(betas_r.filter(regex='^random').filter(regex='^(?!.*_omis$)').values)]))
  1283. df_set2[region].append(np.mean([
  1284. np.nanmean(betas_l.filter(regex=regex2).values),
  1285. np.nanmean(betas_r.filter(regex=regex2).values)]))
  1286. set1[layer_id] = df_set1
  1287. set2[layer_id] = df_set2
  1288. all_non_parametric_pvals = np.array([[non_parametric_permutation_ttest(np.subtract(set2[layer][region], set1[layer][region])) for layer in layers] for region in regions])
  1289. all_non_parametric_pvals_flat = np.array(all_non_parametric_pvals).ravel()
  1290. reject_fdr, p_adjusted = fdrcorrection(all_non_parametric_pvals_flat)
  1291. p_adjusted = p_adjusted.reshape(np.array(all_non_parametric_pvals).shape)
  1292. # %%
  1293. all_layer_pvals = []
  1294. for region in regions:
  1295. for layerA, layerB in itertools.combinations(layers, 2):
  1296. diff_betas_layerA = np.subtract(set2[layerA][region], set1[layerA][region]) # difference within layerA
  1297. diff_betas_layerB = np.subtract(set2[layerB][region], set1[layerB][region]) # difference within layerB
  1298. all_layer_pvals.append(non_parametric_permutation_ttest(diff_betas_layerA - diff_betas_layerB))
  1299. reject_fdr, p_layers_adjusted = fdrcorrection(all_layer_pvals)
  1300. all_non_parametric_pvals_for_layers = {}
  1301. idx = 0
  1302. for region in regions:
  1303. all_non_parametric_pvals_for_layers[region] = {}
  1304. for layerA, layerB in itertools.combinations(layers, 2):
  1305. all_non_parametric_pvals_for_layers[region]['_'.join([layerA, layerB])] = p_layers_adjusted[idx]
  1306. idx += 1
  1307. fig = plt.figure(figsize=(9, 9))
  1308. gs = gridspec.GridSpec(3, 3, height_ratios=[1, 1, 1], hspace=0.6, wspace=0.4)
  1309. ax1 = fig.add_subplot(gs[0, 0])
  1310. ax2 = fig.add_subplot(gs[0, 1])
  1311. ax3 = fig.add_subplot(gs[0, 2])
  1312. ax4 = fig.add_subplot(gs[1, 0])
  1313. ax5 = fig.add_subplot(gs[1, 1])
  1314. ax6 = fig.add_subplot(gs[1, 2])
  1315. ax7 = fig.add_subplot(gs[2, 0])
  1316. ax8 = fig.add_subplot(gs[2, 1])
  1317. ax9 = fig.add_subplot(gs[2, 2])
  1318. for idx, axis in enumerate(fig.get_axes()): # regions
  1319. means1 = np.array([np.nanmean(set1[layer][regions[idx]]) for layer in layers])
  1320. stderr1 = np.array([np.nanstd(set1[layer][regions[idx]]) for layer in layers])/np.sqrt(11)
  1321. sns.lineplot(means1, ax=axis, c='b', linewidth=3)
  1322. axis.errorbar(x=range(len(means1)), y=means1, yerr=stderr1, fmt='o', capsize=2, c='b')
  1323. means2 = np.array([np.nanmean(set2[layer][regions[idx]]) for layer in layers])
  1324. stderr2 = np.array([np.nanstd(set2[layer][regions[idx]]) for layer in layers])/np.sqrt(11)
  1325. sns.lineplot(means2, ax=axis, c='r', linewidth=3)
  1326. axis.errorbar(x=range(len(means2)), y=means2, yerr=stderr2, fmt='o', capsize=2, c='r')
  1327. axis.set_xticks([0,1,2], [r'$\textbf{D}$', r'$\textbf{M}$', r'$\textbf{S}$'])
  1328. axis.set_ylim([0., 2.5])
  1329. if idx in [0,3,6]:
  1330. axis.set_ylabel(r'$\mathbf{\beta\ (\%)}$', fontsize=20)
  1331. axis.set_title(r'$\textbf{'+regions[idx]+r'}$')
  1332. # make border thicker when there is an interaction
  1333. if regions[idx] in ['PT', 'HG', 'aSTG', 'pSTG', 'pMTG', 'parsOrbitalis', 'TPOj']:
  1334. for spine in axis.spines.values():
  1335. spine.set_linewidth(2)
  1336. spine.set_color('black')
  1337. # add layer interactions
  1338. if regions[idx] == 'HG':
  1339. axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  1340. axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  1341. axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  1342. axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  1343. axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  1344. axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  1345. if regions[idx] == 'PT':
  1346. axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  1347. axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  1348. axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  1349. axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  1350. axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  1351. # axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  1352. # if regions[idx] == 'aSTG':
  1353. # axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  1354. # axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  1355. # axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  1356. # axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  1357. # axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  1358. # axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  1359. if regions[idx] == 'pSTG':
  1360. axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  1361. axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  1362. axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  1363. # axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  1364. axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  1365. # axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  1366. if regions[idx] == 'pMTG':
  1367. axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  1368. axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  1369. axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  1370. # axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  1371. # axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  1372. # axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  1373. if regions[idx] == 'parsOrbitalis':
  1374. # axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  1375. axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  1376. axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  1377. axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  1378. axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  1379. axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  1380. if regions[idx] == 'TPOj':
  1381. # axis.axhline(2.4, 0.05, 0.95, c='b', linewidth=1.5) # D-S
  1382. axis.axhline(2.3, 0.05, 0.45, c='b', linewidth=1.5) # D-M
  1383. # axis.axhline(2.3, 0.55, 0.95, c='b', linewidth=1.5) # M-S
  1384. # axis.axhline(2.2, 0.05, 0.95, c='r', linewidth=1.5) # D-S
  1385. # axis.axhline(2.1, 0.05, 0.45, c='r', linewidth=1.5) # D-M
  1386. # axis.axhline(2.1, 0.55, 0.95, c='r', linewidth=1.5) # M-S
  1387. blue_line = mlines.Line2D([], [], color='b', linestyle='-', linewidth=2, label='Unpredictable')
  1388. red_line = mlines.Line2D([], [], color='r', linestyle='-', linewidth=2, label='Omitted (Unpredictable)')
  1389. fig.legend(handles=[red_line, blue_line], loc='center', bbox_to_anchor=(.5, 0.))
  1390. # Mean Activations of Congruent vs. Invalid Trials (11 Subjects, Averaged Hemisphere, Non-Parametric FDR Corrected
  1391. # plt.savefig('./results/univariate_laminar_congomit_randomit_nonparametric_fdr.png', dpi=300, bbox_inches='tight')
  1392. plt.savefig('./figures/univariate_laminar_rand_randomis_nonparametric_fdr_friedman.png', dpi=300, bbox_inches='tight')
  1393. plt.show()
  1394. # %%
  1395. # friedman
  1396. pvals = []
  1397. stats = []
  1398. for roi in regions:
  1399. cong = np.array([set1[item][roi] for item in ['L1', 'L2', 'L3']])
  1400. incong = np.array([set2[item][roi] for item in ['L1', 'L2', 'L3']])
  1401. statistic, pvalue = friedmanchisquare(*(incong-cong))
  1402. pvals.append(pvalue)
  1403. stats.append(statistic)
  1404. # print(f'{roi:<16}: statistic={statistic:0.8f}, \t pvalue={pvalue:0.8f}', end='\t')
  1405. # if pvalue < 0.05:
  1406. # print('*')
  1407. # else:
  1408. # print()
  1409. data = [{'ROI':roi, 'stat':f'{stats[idx]:0.8f}', 'p':f'{pvals[idx]:0.8f}'} for idx, roi in enumerate(regions)]
  1410. headers = data[0].keys()
  1411. latex_table_uncorrected = (
  1412. # "\\begin{table}[h!]\n"
  1413. # "\\centering\n"
  1414. "\\caption{Friedman}\n"
  1415. "\\begin{tabular}{" + " ".join(["l"] * len(headers)) + "}\n"
  1416. "\\toprule\n"
  1417. )
  1418. latex_table_uncorrected += " & ".join(headers) + " \\\\\n\\midrule\n"
  1419. for row in data:
  1420. # if float(row['p']) < 0.05:
  1421. # latex_table_uncorrected += " & ".join('\\textbf{'+str(row[h])+'}' for h in headers) + " \\\\\n"
  1422. # else:
  1423. latex_table_uncorrected += " & ".join(str(row[h]) for h in headers) + " \\\\\n"
  1424. latex_table_uncorrected += (
  1425. "\\bottomrule\n"
  1426. "\\end{tabular}\n"
  1427. # "\\end{table}"
  1428. )
  1429. #%%%%%%%%%%%%%
  1430. rejections, pvals_corrected = fdrcorrection(pvals)
  1431. for idx, roi in enumerate(regions):
  1432. statistic = stats[idx]
  1433. pvalue = pvals_corrected[idx]
  1434. # print(f'{roi:<16}: statistic={statistic:0.8f}, \t pvalue={pvalue:0.8f}', end='\t')
  1435. # if pvalue < 0.05:
  1436. # print('*')
  1437. # else:
  1438. # print()
  1439. data = [{'ROI':roi, 'stat':f'{stats[idx]:0.8f}', 'p':f'{pvals_corrected[idx]:0.8f}'} for idx, roi in enumerate(regions)]
  1440. headers = data[0].keys()
  1441. latex_table = (
  1442. # "\\begin{table}[h!]\n"
  1443. # "\\centering\n"
  1444. "\\caption{Friedman (FDR)}\n"
  1445. "\\begin{tabular}{" + " ".join(["l"] * len(headers)) + "}\n"
  1446. "\\toprule\n"
  1447. )
  1448. latex_table += " & ".join(headers) + " \\\\\n\\midrule\n"
  1449. for row in data:
  1450. # if float(row['p']) < 0.05:
  1451. # latex_table += " & ".join('\\textbf{'+str(row[h])+'}' for h in headers) + " \\\\\n"
  1452. # else:
  1453. latex_table += " & ".join(str(row[h]) for h in headers) + " \\\\\n"
  1454. latex_table += (
  1455. "\\bottomrule\n"
  1456. "\\end{tabular}\n"
  1457. # "\\end{table}"
  1458. )
  1459. print('''\\begin{table}[htbp]
  1460. \\centering''')
  1461. print('\\begin{minipage}{0.45\\textwidth}')
  1462. print(latex_table_uncorrected)
  1463. print('\\end{minipage}')
  1464. print('\\hfill\\begin{minipage}{0.45\\textwidth}')
  1465. print(latex_table)
  1466. print('\\end{minipage}')
  1467. print('\\end{table}')
  1468. print()
  1469. # %%
  1470. # interactions
  1471. inter = ['PT', 'HG', 'aSTG', 'pSTG', 'pMTG', 'parsOrbitalis', 'TPOj']
  1472. # anova
  1473. all_results = []
  1474. for roi in inter:
  1475. cong = np.array([set1[item][roi] for item in ['L1', 'L2', 'L3']])
  1476. incong = np.array([set2[item][roi] for item in ['L1', 'L2', 'L3']])
  1477. result = {
  1478. 'D-M (cong)': non_parametric_permutation_ttest(cong[0,:]-cong[1,:]),
  1479. 'D-S (cong)': non_parametric_permutation_ttest(cong[0,:]-cong[2,:]),
  1480. 'M-S (cong)': non_parametric_permutation_ttest(cong[1,:]-cong[2,:]),
  1481. 'D-M (incong)': non_parametric_permutation_ttest(incong[0,:]-incong[1,:]),
  1482. 'D-S (incong)': non_parametric_permutation_ttest(incong[0,:]-incong[2,:]),
  1483. 'M-S (incong)': non_parametric_permutation_ttest(incong[1,:]-incong[2,:])
  1484. }
  1485. all_results.append(list(result.values()))
  1486. # correct and print
  1487. rej, pcorr = fdrcorrection(np.array(all_results).ravel())
  1488. pcorr = pcorr.reshape(len(inter), 6)
  1489. for idx, roi in enumerate(inter):
  1490. cong = np.array([set1[item][roi] for item in ['L1', 'L2', 'L3']])
  1491. incong = np.array([set2[item][roi] for item in ['L1', 'L2', 'L3']])
  1492. result = {
  1493. 'D-M (cong)': non_parametric_permutation_ttest(cong[0,:]-cong[1,:]),
  1494. 'D-S (cong)': non_parametric_permutation_ttest(cong[0,:]-cong[2,:]),
  1495. 'M-S (cong)': non_parametric_permutation_ttest(cong[1,:]-cong[2,:]),
  1496. 'D-M (incong)': non_parametric_permutation_ttest(incong[0,:]-incong[1,:]),
  1497. 'D-S (incong)': non_parametric_permutation_ttest(incong[0,:]-incong[2,:]),
  1498. 'M-S (incong)': non_parametric_permutation_ttest(incong[1,:]-incong[2,:])
  1499. }
  1500. stats = {
  1501. 'D-M (cong)': np.round(ttest_rel(cong[0,:],cong[1,:]).statistic, 6),
  1502. 'D-S (cong)': np.round(ttest_rel(cong[0,:],cong[2,:]).statistic, 6),
  1503. 'M-S (cong)': np.round(ttest_rel(cong[1,:],cong[2,:]).statistic, 6),
  1504. 'D-M (incong)': np.round(ttest_rel(incong[0,:],incong[1,:]).statistic, 6),
  1505. 'D-S (incong)': np.round(ttest_rel(incong[0,:],incong[2,:]).statistic, 6),
  1506. 'M-S (incong)': np.round(ttest_rel(incong[1,:],incong[2,:]).statistic, 6)
  1507. }
  1508. print('''\\begin{table}[htbp]
  1509. \\centering
  1510. \\caption{Layer Effects for separate conditions (\\textbf{''' + roi + '''})}
  1511. \\label{tab:my_label}''')
  1512. print('\\begin{minipage}{0.45\\textwidth}')
  1513. print('\\caption{Uncorrected}')
  1514. print(pd.DataFrame([list(stats.values()), list(result.values())], columns=result.keys(),index=['t', 'p']).T.to_latex(index=True))
  1515. print('\\end{minipage}')
  1516. print('\\begin{minipage}{0.45\\textwidth}')
  1517. print('\\caption{FDR}')
  1518. print(pd.DataFrame([list(stats.values()), pcorr[idx]], columns=result.keys(), index=['t', 'q']).T.to_latex(index=True))
  1519. print('\\end{minipage}')
  1520. print('\\end{table}')
  1521. print()
  1522. # %% [markdown]
  1523. # ---

Laminar_UnivariateAndStats.ipynb at commit 9b91341, no license · at the source

Overview

  1. Department of Cognitive Neuroscience, Maastricht University, Maastricht, The Netherlands
  2. Donders Institute for Brain, Cognition and Behaviour, Radboud University, Nijmegen, The Netherlands
  3. Transdisciplinary Research Area - Life and Health, Center for Artificial Intelligence and Neuroscience, University of Bonn, Bonn, Germany
  4. Department of Neurology, Max Planck Institute for Human Cognitive and Brain Sciences, Leipzig, Germany
  5. Center for Magnetic Resonance Research, University of Minnesota, Minneapolis, MN USA
Journal: Nature communications, volume 17, issue 1, article 8748
Dates: received 26 November 2025; accepted 6 July 2026; published online 17 July 2026
Type: Research article · Language: English
License: CC BY-NC-ND
Identifiers: DOI 10.1038/s41467-026-75662-w · PMID 42469220 · PMCID PMC13493366 · OpenAlex W7169569694
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: human (organism), cognitive (subfield)
Methods: Connectivity, Statistics, Machine learning, Preprocessing, fMRI & imaging, Single-unit activity, calcium imaging, Smoothing, state filtering, decompositions
Keywords: Perception, Neural encoding, Cortex
MeSH: Adaptation, Physiological*, Auditory Cortex*, Auditory Perception*, Acoustic Stimulation, Adult, Brain Mapping, Female, Humans, Magnetic Resonance Imaging, Male, Young Adult (* major topic)
Topic: Multisensory perception and integration (Experimental and Cognitive Psychology, Psychology), according to OpenAlex
Funding: EC | Horizon 2020 Framework Programme (101001270)
Citations: cited by 1 paper (Europe PMC); 67 references in the paper

Abstract

The abstract is not reproduced here: the paper's license (CC BY-NC-ND) does not allow it. Read it in the paper, at the publisher or on Europe PMC.

Repositories

Its files are read in the Code ↔ Paper reader above, with 13 matches between paragraphs and lines of code.

mesoscopic-computational-audition-lab/researchprojects

License: none: the authors keep all their rights
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 9b91341b5f6d97f089846c761d11751b7accf187, 3 July 2026
Languages: MATLAB (251), Python (82), Jupyter (48)
Size: 796 files, 381 scripts
Software Heritage: not archived
Found in: “Code availability”
Holds: README, 48 notebooks
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: NumPy (60 files), Psychtoolbox (46 files), Matplotlib (37 files), SciPy (37 files), pandas (36 files), seaborn (28 files), scikit-learn (14 files), statsmodels (11 files), NiBabel (8 files), pydicom (6 files), Statistics and Machine Learning Toolbox (5 files), Nilearn (3 files), scikit-posthocs (2 files), FSL (1 file), ggplot2 (1 file), imageio (1 file), MNE-Python (1 file), Nighres (1 file), Pillow (1 file), Pingouin (1 file), tidyverse (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
165 files

mesoScopic-Computational-AuditioN-lab

License: none: the authors keep all their rights
State: the link answers, verified on 27 September 2026
Evidence: the link answers
Software Heritage: not checked
Found in: “Code availability”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 27 September 2026: the link answers (HTTP 200)
  • 27 September 2026: the link answers (HTTP 200)

Code availability statement

The paper has a code availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:

Read it in the paper: doi.org/10.1038/s41467-026-75662-w.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 2 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 164 scripts, each with its path and the digest of its content;
  • 13 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

Datasets cited

Code and data availability statement

The paper has a code and data availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:

Read it in the paper: doi.org/10.1038/s41467-026-75662-w.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 27 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 4 authors, 3 keywords, 11 MeSH terms, 1 funder, 63 references.

Cite

This paper

van Haren, J. J. G., de Lange, F. P., Kotz, S. A., & De Martino, F. (2026). Distinct Roles of Deep and Superficial Cortical Layers in Tone Prediction, Comparison, and Adaptation in Human Auditory Cortices. Nature communications, 17(1), 8748. https://doi.org/10.1038/s41467-026-75662-w

BibTeX

@article{vanharen2026distinct,
author = {van Haren, Jorie J G and de Lange, Floris P and Kotz, Sonja A and De Martino, Federico},
title = {{Distinct Roles of Deep and Superficial Cortical Layers in Tone Prediction, Comparison, and Adaptation in Human Auditory Cortices}},
journal = {Nature communications},
year = {2026},
month = jul,
volume = {17},
number = {1},
pages = {8748},
publisher = {Nature Publishing Group},
issn = {2041-1723},
doi = {10.1038/s41467-026-75662-w},
url = {https://doi.org/10.1038/s41467-026-75662-w},
pmid = {42469220},
pmcid = {PMC13493366}
}

RIS

TY - JOUR
AU - van Haren, Jorie J G
AU - de Lange, Floris P
AU - Kotz, Sonja A
AU - De Martino, Federico
TI - Distinct Roles of Deep and Superficial Cortical Layers in Tone Prediction, Comparison, and Adaptation in Human Auditory Cortices
T2 - Nature communications
J2 - Nat Commun
PY - 2026
DA - 2026/07/17
VL - 17
IS - 1
SP - 8748
SN - 2041-1723
PB - Nature Publishing Group
DO - 10.1038/s41467-026-75662-w
UR - https://doi.org/10.1038/s41467-026-75662-w
LA - en
ER -

CSL-JSON

{
"id": "10.1038/s41467-026-75662-w",
"type": "article-journal",
"title": "Distinct Roles of Deep and Superficial Cortical Layers in Tone Prediction, Comparison, and Adaptation in Human Auditory Cortices",
"container-title": "Nature communications",
"author": [
{
"family": "van Haren",
"given": "Jorie J G"
},
{
"family": "de Lange",
"given": "Floris P"
},
{
"family": "Kotz",
"given": "Sonja A"
},
{
"family": "De Martino",
"given": "Federico"
}
],
"container-title-short": "Nat Commun",
"volume": "17",
"issue": "1",
"page": "8748",
"DOI": "10.1038/s41467-026-75662-w",
"PMID": "42469220",
"PMCID": "PMC13493366",
"ISSN": "2041-1723",
"publisher": "Nature Publishing Group",
"URL": "https://doi.org/10.1038/s41467-026-75662-w",
"language": "en",
"issued": {
"date-parts": [
[
2026,
7,
17
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1038/s41467-026-73540-z [code]
Predictive acoustical processing in human cortical layers.
Journal: Nature communications
In common: Statistics and Machine Learning Toolbox, cognitive, 16 references, author Federico De Martino
[2] doi:10.7554/elife.108408 [code]
Frequency and laminar profile of feature-specific visual activity revealed by interleaved EEG-fMRI.
Journal: eLife
In common: Pingouin, FSL, NiBabel, 7 other tools, 7 references
[3] doi:10.1038/s41467-026-71151-2 [code]
Common and distinct neural correlates of social interaction processing and theory of mind in narratives.
Journal: Nature communications
In common: Psychtoolbox, FSL, Nilearn, 10 other tools, cognitive, 2 references
[4] doi:10.1093/nc/niag029 [code]
A data-driven approach to identifying and evaluating connectivity-based neural correlates of conscious visual perception.
Journal: Neuroscience of consciousness
In common: Pingouin, MNE-Python, FSL, 12 other tools, cognitive
[5] doi:10.1038/s41597-026-07350-9 [code]
An open multi-center MEG-EEG dataset for studying conscious visual perception.
Journal: Scientific data
In common: Pingouin, MNE-Python, FSL, 12 other tools
[6] doi:10.1038/s41597-026-07377-y [code]
An open-access multi-site fMRI dataset for investigating conscious visual perception.
Journal: Scientific data
In common: Pingouin, MNE-Python, FSL, 12 other tools
[7] doi:10.1038/s41467-026-74824-0 [code]
Learning regularities in noise engages both neural predictive activity and representational changes.
Journal: Nature communications
In common: imageio, Pingouin, MNE-Python, 8 other tools, cognitive, 2 references
[8] doi:10.1038/s41597-026-06869-1 [code]
Individual Brain Charting: fifth release of high-resolution fMRI data for cognitive mapping.
Journal: Scientific data
In common: Psychtoolbox, FSL, Nilearn, 8 other tools, 3 references
[9] doi:10.1162/imag.a.1245 [code]
Towards precision EEG connectomics: Evaluating the benefits of dense sampling.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: Pingouin, MNE-Python, FSL, 11 other tools
[10] doi:10.1038/s41586-026-10631-3 [code]
A prognostic human brain network for diffuse midline glioma.
Journal: Nature
In common: pydicom, Psychtoolbox, FSL, 9 other tools, 1 reference

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.