create_figure_2.py 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. import os
  2. import pandas as pd
  3. import numpy as np
  4. import matplotlib.pylab as plt
  5. import seaborn as sns
  6. import mr_utilities
  7. from scipy import stats
  8. mycol = ['darkgreen', 'mediumaquamarine', 'silver', 'darkblue','steelblue']
  9. def cm2inch(value):
  10. return value/2.54
  11. def mt_examples(patient, save_path, fit_method, kmin, kmax,
  12. windowsize, windowstep, dt):
  13. recordings = mr_utilities.list_preictrecordings(patient)[0]
  14. fig, ax = plt.subplots(2, 1, figsize=(cm2inch(13.5), cm2inch(5)))
  15. binnings = ['right', 'left']
  16. quantity = 'm'
  17. t_onset = 600 # seizure onset at the end of each 10 min recording
  18. for irec, rec in enumerate(recordings):
  19. for ibin, binning in enumerate(binnings):
  20. mt_file = '{}{}/mt_results_{}_{}_kmin{}_kmax{}_winsize{}_' \
  21. 'winstep{}_dt{}.pkl'.format(save_path, rec, binning,
  22. fit_method, kmin, kmax, windowsize, windowstep, dt)
  23. if not os.path.isfile(mt_file):
  24. print('{} not existing'.format(mt_file))
  25. continue
  26. # -----------------------------------------------------------------#
  27. # read m(t) data
  28. # -----------------------------------------------------------------#
  29. mt_frame = pd.read_pickle(mt_file)
  30. mt_frame = mr_utilities.exclude_inconsistencies(mt_frame)
  31. if mt_frame.empty:
  32. continue
  33. kmin = mt_frame.kmin.unique()[0]
  34. kmax = mt_frame.kmax.unique()[0]
  35. fit_method = mt_frame.fit_method.unique()[0]
  36. winsize = mt_frame.windowsize.unique()[0]
  37. t0_list = mt_frame.t0.tolist()
  38. qt = mt_frame[quantity].tolist()
  39. t0_list = [t0_ms * 0.001 for t0_ms in t0_list]
  40. half_win_sec = int((winsize / 2) / 1000 * dt)
  41. t_middle = [t0 + half_win_sec for t0 in t0_list]
  42. # -----------------------------------------------------------------#
  43. # Plotting
  44. # -----------------------------------------------------------------#
  45. ax[ibin].plot(t_middle, qt, '-', linewidth=1,
  46. label='Rec {}'.format(irec+1), color=mycol[irec])
  47. ax[ibin].axhline(y=1, color='black', linestyle='--', alpha=0.3)
  48. ax[ibin].set_ylabel(r"$\hat{m}$")
  49. ax[ibin].set_xlim(
  50. (t0_list[0] - 10, t0_list[-1] + 2 * half_win_sec + 10))
  51. binning_focus = mr_utilities.binning_focus(binning, int(patient))
  52. if binning_focus == 'focal':
  53. focus_label = 'ipsi'
  54. else:
  55. focus_label = 'contra'
  56. ax[ibin].set_title("{}".format(focus_label), loc='left')
  57. ax[0].legend(loc='center left', bbox_to_anchor=(1.04, -0.2),
  58. fontsize='small')
  59. ax[0].xaxis.grid(False)
  60. ax[1].xaxis.grid(False)
  61. ax[1].set_xlabel("time (s)")
  62. ax[0].annotate("", xy=(t_onset, 1), xytext=(t_onset, 1.1),
  63. arrowprops=dict(arrowstyle="->", color='black'))
  64. ax[1].annotate("", xy=(t_onset, 1), xytext=(t_onset, 1.04),
  65. arrowprops=dict(arrowstyle="->", color='black'))
  66. ax[0].annotate("seizure\n onset", xy=(t_onset, 1),
  67. xytext=(t_onset, 1.03))
  68. sns.despine()
  69. plt.subplots_adjust(bottom=None, right=None,
  70. wspace=0.3, hspace=1.3, left=None, top=None)
  71. plt.savefig('{}/Fig2_mt_patient{}.pdf'.format(save_path, patient),
  72. bbox_inches='tight')
  73. plt.close()
  74. def boxplot_mx(result_path, x, ksteps, fit_method, Engel=False):
  75. # -----------------------------------------------------------------#
  76. # Read and filter data
  77. # -----------------------------------------------------------------#
  78. mx_results = '{}mt_{}_results_allrecords_kmin{}_kmax{}_{}.pkl'.format(
  79. result_path, x, ksteps[0], ksteps[1], fit_method)
  80. mx_allresults = pd.read_pickle(mx_results)
  81. mx_allresults = mr_utilities.exclude_inconsistencies(mx_allresults)
  82. x = mx_allresults['partno'].max()
  83. mx_allresults['logepsilon'] = mx_allresults.apply(lambda row: np.log(
  84. 1-row['m']), axis=1)
  85. mx_allresults['epsilon'] = mx_allresults.apply(lambda row: 1-row['m'],
  86. axis=1)
  87. measure = 'epsilon'
  88. patients1a = [1, 6, 8, 9, 10, 11, 16, 17, 18, 19]
  89. if Engel:
  90. mx_allresults = mx_allresults[(mx_allresults['patient'].isin(patients1a))]
  91. # -----------------------------------------------------------------#
  92. # write estimates to lists
  93. # -----------------------------------------------------------------#
  94. focal_diff_list = []
  95. contralateral_diff_list = []
  96. all_last_contra = []
  97. all_first_contra = []
  98. all_last_focal = []
  99. all_first_focal = []
  100. for ir, recording in enumerate(mx_allresults['recording'].unique()):
  101. mx_recording = mx_allresults[mx_allresults['recording'] == recording]
  102. mx_focal = mx_recording[mx_recording['binning_focus'] == 'focal']
  103. mx_contralateral = mx_recording[
  104. mx_recording['binning_focus'] == 'contra-lateral']
  105. if not mx_focal[mx_focal['partno'] == 1].empty and not mx_focal[
  106. mx_focal['partno'] == x].empty:
  107. m_focal_first = mx_focal[mx_focal['partno'] == 1][
  108. measure].item()
  109. m_focal_last = mx_focal[mx_focal['partno'] == x][measure].item()
  110. focal_diff_log = np.log(m_focal_last) - np.log(m_focal_first)
  111. focal_diff_list.append(focal_diff_log)
  112. all_first_focal.append(m_focal_first)
  113. all_last_focal.append(m_focal_last)
  114. if not mx_contralateral[mx_contralateral['partno'] == 1].empty \
  115. and not mx_contralateral[
  116. mx_contralateral['partno'] == x].empty:
  117. m_contralateral_first = \
  118. mx_contralateral[mx_contralateral['partno'] == 1][measure].item()
  119. m_contralateral_last = \
  120. mx_contralateral[mx_contralateral['partno'] == x][measure].item()
  121. contralateral_diff_log = np.log(m_contralateral_last) - \
  122. np.log(m_contralateral_first)
  123. contralateral_diff_list.append(contralateral_diff_log)
  124. all_first_contra.append(m_contralateral_first)
  125. all_last_contra.append(m_contralateral_last)
  126. # -----------------------------------------------------------------#
  127. # Wilcoxon paired test
  128. # -----------------------------------------------------------------#
  129. stat, p_contra_w = stats.wilcoxon(contralateral_diff_list)
  130. stat, p_focal_w = stats.wilcoxon(focal_diff_list)
  131. # -----------------------------------------------------------------#
  132. # Create dataframe for plotting
  133. # -----------------------------------------------------------------#
  134. quantity = measure
  135. data1 = {
  136. quantity: all_first_focal,
  137. 'rec_type': ['10 - 5 min' for _ in range(len(all_first_focal))],
  138. 'binning_focus': ['SOZ' for _ in range(len(all_first_focal))]
  139. }
  140. df = pd.DataFrame(data1)
  141. data2 = pd.DataFrame({
  142. quantity: all_last_focal,
  143. 'rec_type': ['5 - 0 min' for _ in range(len(all_last_focal))],
  144. 'binning_focus': ['SOZ' for _ in range(len(all_last_focal))]
  145. })
  146. df = df.append(data2, ignore_index=True)
  147. data3 = pd.DataFrame({
  148. quantity: all_first_contra,
  149. 'rec_type': ['10 - 5 min' for _ in range(len(all_first_contra))],
  150. 'binning_focus': ['nSOZ' for _ in range(len(all_first_contra))]
  151. })
  152. df = df.append(data3, ignore_index=True)
  153. data4 = pd.DataFrame({
  154. quantity: all_last_contra,
  155. 'rec_type': ['5 - 0 min' for _ in range(len(all_last_contra))],
  156. 'binning_focus': ['nSOZ' for _ in range(len(all_last_contra))]
  157. })
  158. df = df.append(data4, ignore_index=True)
  159. # -----------------------------------------------------------------#
  160. # Plotting
  161. # -----------------------------------------------------------------#
  162. fig, ax = plt.subplots(1, 1, figsize=(cm2inch(5.5), cm2inch(4.5)))
  163. g = sns.boxplot(ax=ax, x='binning_focus', y=quantity, hue='rec_type',
  164. data=df, hue_order = ['10 - 5 min', '5 - 0 min'], order=[
  165. 'SOZ', 'nSOZ'], dodge=True, color='slategray', palette=[
  166. 'lightgray', 'slategray'], linewidth=1.1, width=0.6)
  167. g.set_yscale("log")
  168. plt.grid(axis='x', b=False)
  169. plt.rcParams['legend.title_fontsize'] = 9
  170. plt.legend(loc="upper left", ncol=1,
  171. fontsize='x-small', bbox_to_anchor=(0, 1.7), title='time to '
  172. 'seizure onset')
  173. n_f_pre = len(all_first_focal)
  174. n_f_inter = len(all_last_focal)
  175. n_c_pre = len(all_first_contra)
  176. n_c_inter = len(all_last_contra)
  177. ax.set_xticklabels(['ipsi\n({}, {})'.format(n_f_pre, n_f_inter),
  178. 'contra\n({}, {})'.format(n_c_pre, n_c_inter)])
  179. # -----------------------------------------------------------------#
  180. # quantity labels
  181. # -----------------------------------------------------------------#
  182. quantity_label = r'$\hat{m}$'
  183. ymax = 1e-3
  184. ymin = 1
  185. ax.set_ylim(ymin, ymax)
  186. T = [1, 1e-1, 1e-2, 1e-3]
  187. ax.set_yticks(T)
  188. ax.set_yticklabels([0, 0.9, 0.99, 0.999])
  189. # -----------------------------------------------------------------#
  190. # annotate p-values
  191. # -----------------------------------------------------------------#
  192. y_max = 2.4*ymax
  193. ax.annotate("", xy=(-0.2, y_max), xycoords='data',
  194. xytext=(0.2, y_max), textcoords='data',
  195. arrowprops=dict(arrowstyle="-", ec='black',
  196. connectionstyle="bar,fraction=0.2"))
  197. ax.text(-0.25, y_max*0.6, 'p={:.3f}'.format(p_focal_w), fontsize=8)
  198. ax.annotate("", xy=(0.8, y_max), xycoords='data',
  199. xytext=(1.2, y_max), textcoords='data',
  200. arrowprops=dict(arrowstyle="-", ec='black',
  201. connectionstyle="bar,fraction=0.2"))
  202. ax.text(0.75, y_max*0.6, 'p={:.3f}'.format(p_contra_w), fontsize=8)
  203. ax.set_ylim(ymin, ymax)
  204. plt.ylabel(quantity_label)
  205. plt.xlabel('')
  206. sns.despine()
  207. # -----------------------------------------------------------------#
  208. # Saving
  209. # -----------------------------------------------------------------#
  210. plotfile_mx = '{}Fig2_2parts_Engel{}.pdf'.format(result_path, Engel)
  211. plt.savefig(plotfile_mx, bbox_inches='tight')
  212. def pointplot_mx_regions_Engel(result_path, x, ksteps, fit_method):
  213. # -----------------------------------------------------------------#
  214. # Read and filter data
  215. # -----------------------------------------------------------------#
  216. mx_results = '{}mt_{}_results_allrecords_kmin{}_kmax{}_{}.pkl'.format(
  217. result_path, x, ksteps[0], ksteps[1], fit_method)
  218. mx_allresults = pd.read_pickle(mx_results)
  219. mx_allresults = mr_utilities.exclude_inconsistencies(mx_allresults)
  220. x = mx_allresults['partno'].max()
  221. mx_allresults['epsilon'] = mx_allresults.apply(lambda row: 1-row['m'],
  222. axis=1)
  223. measure = 'epsilon'
  224. def give_region(row):
  225. return row['binning'][1:]
  226. mx_allresults['region'] = mx_allresults.apply(lambda row: give_region(row),
  227. axis=1)
  228. # -----------------------------------------------------------------#
  229. # write paired estimates to lists
  230. # -----------------------------------------------------------------#
  231. fig, ax = plt.subplots(1, 1, figsize=(cm2inch(10*1.2), cm2inch(4*1.2)))
  232. df = None
  233. patients1a = [1, 6, 8, 9, 10, 11, 16, 17, 18, 19]
  234. mx_allresults = mx_allresults[(mx_allresults['patient'].isin(patients1a))]
  235. regions = ['H', 'A', 'PHC', 'EC']
  236. labels = []
  237. for i, reg in enumerate(regions):
  238. mx_region = mx_allresults[mx_allresults['region'] == reg]
  239. recordings = mx_region.recording.unique()
  240. all_first_focal = []
  241. all_last_focal = []
  242. all_first_contra = []
  243. all_last_contra = []
  244. recID = []
  245. for recording in recordings:
  246. mx_recording = mx_region[mx_region['recording'] == recording]
  247. mx_focal = mx_recording[mx_recording['binning_focus'] == 'focal']
  248. mx_contralateral = mx_recording[
  249. mx_recording['binning_focus'] == 'contra-lateral']
  250. if not mx_focal[mx_focal['partno'] == 1].empty and not mx_focal[
  251. mx_focal['partno'] == x].empty:
  252. m_focal_first = mx_focal[mx_focal['partno'] == 1][
  253. measure].item()
  254. m_focal_last = mx_focal[mx_focal['partno'] == x][measure].item()
  255. all_first_focal.append(m_focal_first)
  256. all_last_focal.append(m_focal_last)
  257. recID.append(recording)
  258. if not mx_contralateral[mx_contralateral['partno'] == 1].empty \
  259. and not \
  260. mx_contralateral[
  261. mx_contralateral['partno'] == x].empty:
  262. m_contralateral_first = mx_contralateral[mx_contralateral[
  263. 'partno'] == 1][measure].item()
  264. m_contralateral_last = mx_contralateral[mx_contralateral[
  265. 'partno'] == x][measure].item()
  266. all_first_contra.append(m_contralateral_first)
  267. all_last_contra.append(m_contralateral_last)
  268. # -----------------------------------------------------------------#
  269. # Create dataframe for plotting
  270. # -----------------------------------------------------------------#
  271. quantity = measure
  272. if df is None:
  273. data1 = {
  274. 'region': reg,
  275. quantity: all_first_focal,
  276. 'recording': recID,
  277. 'rec_type': ['10 - 5 min' for _ in range(len(all_first_focal))],
  278. 'binning_focus': ['SOZ' for _ in range(len(all_first_focal))]
  279. }
  280. df = pd.DataFrame(data1)
  281. else:
  282. data1 = pd.DataFrame({
  283. 'region': reg,
  284. quantity: all_first_focal,
  285. 'recording': recID,
  286. 'rec_type': ['10 - 5 min' for _ in range(len(all_last_focal))],
  287. 'binning_focus': ['SOZ' for _ in range(len(all_last_focal))]
  288. })
  289. df = df.append(data1, ignore_index=True)
  290. data2 = pd.DataFrame({
  291. 'region': reg,
  292. quantity: all_last_focal,
  293. 'recording': recID,
  294. 'rec_type': ['5 - 0 min' for _ in range(len(all_last_focal))],
  295. 'binning_focus': ['SOZ' for _ in range(len(all_last_focal))]
  296. })
  297. df = df.append(data2, ignore_index=True)
  298. n_f_first = len(all_first_focal)
  299. n_f_last = len(all_last_focal)
  300. labels.append('{}\n({}, {})'.format(reg, n_f_first, n_f_last))
  301. x0 = (-0.2+i) * np.ones(len(all_first_focal))
  302. x1 = (0.2+i) * np.ones(len(all_last_focal))
  303. plt.plot([x0, x1], [all_first_focal, all_last_focal],
  304. color='grey', linewidth=0.5, linestyle='--')
  305. # -----------------------------------------------------------------#
  306. # Plotting
  307. # -----------------------------------------------------------------#
  308. df = df[df['binning_focus'] == 'SOZ']
  309. g = sns.stripplot(ax=ax, x='region', y=quantity, hue='rec_type',
  310. data=df, hue_order=['10 - 5 min', '5 - 0 min'],
  311. dodge=True, order=regions, jitter=False,
  312. color='slategray', palette=['slategray', 'darkblue'],
  313. size=2.5, alpha=0.7)
  314. ax.set_yscale("log")
  315. ax.grid(axis='x', b=False)
  316. plt.rcParams['legend.title_fontsize'] = 9
  317. plt.legend(loc='center left', bbox_to_anchor=(1, 0.5),
  318. fontsize='x-small', title='time to seizure onset')
  319. ax.set_xticklabels(labels)
  320. # -----------------------------------------------------------------#
  321. # quantity labels
  322. # -----------------------------------------------------------------#
  323. quantity_label = r'$\hat{m}$'
  324. ymax = 1e-3
  325. ymin = 1
  326. ax.set_ylim(ymin, ymax)
  327. T = [1, 1e-1, 1e-2, 1e-3]
  328. ax.set_yticks(T)
  329. ax.set_yticklabels([0, 0.9, 0.99, 0.999])
  330. # -----------------------------------------------------------------#
  331. # Annotate p-values of pairwise comparison
  332. # -----------------------------------------------------------------#
  333. ax.set_ylim(ymin, ymax)
  334. plt.ylabel(quantity_label)
  335. plt.xlabel('brain area')
  336. sns.despine()
  337. # -----------------------------------------------------------------#
  338. # Saving
  339. # -----------------------------------------------------------------#
  340. plotfile_mx = '{}Fig2_2parts_regions_Engel1a.pdf'.format(result_path)
  341. plt.savefig(plotfile_mx, bbox_inches='tight')
  342. def boxplot_mx_regions(result_path, x, ksteps, fit_method, Engel=False):
  343. # -----------------------------------------------------------------#
  344. # Read and filter data
  345. # -----------------------------------------------------------------#
  346. mx_results = '{}mt_{}_results_allrecords_kmin{}_kmax{}_{}.pkl'.format(
  347. result_path, x, ksteps[0], ksteps[1], fit_method)
  348. mx_allresults = pd.read_pickle(mx_results)
  349. mx_allresults = mr_utilities.exclude_inconsistencies(mx_allresults)
  350. x = mx_allresults['partno'].max()
  351. mx_allresults['epsilon'] = mx_allresults.apply(lambda row:
  352. 1-row['m'], axis=1)
  353. measure = 'epsilon'
  354. def give_region(row):
  355. return row['binning'][1:]
  356. mx_allresults['region'] = mx_allresults.apply(lambda row: give_region(row),
  357. axis=1)
  358. if Engel:
  359. patients1a = [1, 6, 8, 9, 10, 11, 16, 17, 18, 19]
  360. mx_allresults = mx_allresults[
  361. (mx_allresults['patient'].isin(patients1a))]
  362. # -----------------------------------------------------------------#
  363. # write estimates to lists
  364. # -----------------------------------------------------------------#
  365. df = None
  366. regions = ['H', 'A', 'PHC', 'EC']
  367. labels = []
  368. pvals = dict()
  369. for reg in regions:
  370. mx_region = mx_allresults[mx_allresults['region'] == reg]
  371. recordings = mx_region.recording.unique()
  372. focal_diff_list = []
  373. contralateral_diff_list = []
  374. all_first_focal = []
  375. all_last_focal = []
  376. all_first_contra = []
  377. all_last_contra = []
  378. recID = []
  379. for recording in recordings:
  380. mx_recording = mx_region[mx_region['recording'] == recording]
  381. mx_focal = mx_recording[mx_recording['binning_focus'] == 'focal']
  382. mx_contralateral = mx_recording[
  383. mx_recording['binning_focus'] == 'contra-lateral']
  384. if not mx_focal[mx_focal['partno'] == 1].empty and not mx_focal[
  385. mx_focal['partno'] == x].empty:
  386. m_focal_first = mx_focal[mx_focal['partno'] == 1][
  387. measure].item()
  388. m_focal_last = mx_focal[mx_focal['partno'] == x][measure].item()
  389. focal_diff_log = np.log(m_focal_last) - np.log(m_focal_first)
  390. all_first_focal.append(m_focal_first)
  391. all_last_focal.append(m_focal_last)
  392. focal_diff_list.append(focal_diff_log)
  393. recID.append(recording)
  394. if not mx_contralateral[mx_contralateral['partno'] == 1].empty \
  395. and not mx_contralateral[mx_contralateral['partno'] == x].empty:
  396. m_contralateral_first = mx_contralateral[mx_contralateral['partno'] == 1][measure].item()
  397. m_contralateral_last = mx_contralateral[mx_contralateral['partno'] == x][measure].item()
  398. contralateral_diff_log = np.log(m_contralateral_last) - \
  399. np.log(m_contralateral_first)
  400. all_first_contra.append(m_contralateral_first)
  401. all_last_contra.append(m_contralateral_last)
  402. contralateral_diff_list.append(contralateral_diff_log)
  403. # -----------------------------------------------------------------#
  404. # Wilcoxon paired test
  405. # -----------------------------------------------------------------#
  406. stat, p_contra_w = stats.wilcoxon(contralateral_diff_list)
  407. stat, p_focal_w = stats.wilcoxon(focal_diff_list)
  408. pvals[reg] = p_focal_w
  409. # -----------------------------------------------------------------#
  410. # Create dataframe for plotting
  411. # -----------------------------------------------------------------#
  412. quantity = measure
  413. if df is None:
  414. data1 = {
  415. 'region': reg,
  416. quantity: all_first_focal,
  417. 'recording': recID,
  418. 'rec_type': ['10 - 5 min' for _ in range(len(all_first_focal))],
  419. 'binning_focus': ['SOZ' for _ in range(len(all_first_focal))]
  420. }
  421. df = pd.DataFrame(data1)
  422. else:
  423. data1 = pd.DataFrame({
  424. 'region': reg,
  425. quantity: all_first_focal,
  426. 'recording': recID,
  427. 'rec_type': ['10 - 5 min' for _ in range(len(all_last_focal))],
  428. 'binning_focus': ['SOZ' for _ in range(len(all_last_focal))]
  429. })
  430. df = df.append(data1, ignore_index=True)
  431. data2 = pd.DataFrame({
  432. 'region': reg,
  433. quantity: all_last_focal,
  434. 'recording': recID,
  435. 'rec_type': ['5 - 0 min' for _ in range(len(all_last_focal))],
  436. 'binning_focus': ['SOZ' for _ in range(len(all_last_focal))]
  437. })
  438. df = df.append(data2, ignore_index=True)
  439. data3 = pd.DataFrame({
  440. 'region': reg,
  441. quantity: all_first_contra,
  442. 'recording': ['-' for _ in range(len(all_first_contra))],
  443. 'rec_type': ['10 - 5 min' for _ in range(len(all_first_contra))],
  444. 'binning_focus': ['nSOZ' for _ in range(len(all_first_contra))]
  445. })
  446. df = df.append(data3, ignore_index=True)
  447. data4 = pd.DataFrame({
  448. 'region': reg,
  449. quantity: all_last_contra,
  450. 'recording': ['-' for _ in range(len(all_first_contra))],
  451. 'rec_type': ['5 - 0 min' for _ in range(len(all_last_contra))],
  452. 'binning_focus': ['nSOZ' for _ in range(len(all_last_contra))]
  453. })
  454. df = df.append(data4, ignore_index=True)
  455. n_f_first = len(all_first_focal)
  456. n_f_last = len(all_last_focal)
  457. labels.append('{}\n({}, {})'.format(reg, n_f_first, n_f_last))
  458. # -----------------------------------------------------------------#
  459. # Plotting
  460. # -----------------------------------------------------------------#
  461. fig, ax = plt.subplots(1, 1, figsize=(cm2inch(10*1.2), cm2inch(4*1.2)))
  462. df = df[df['binning_focus'] == 'SOZ']
  463. g = sns.boxplot(ax=ax, x='region', y=quantity, hue='rec_type',
  464. data=df, hue_order=['10 - 5 min', '5 - 0 min'],
  465. order=regions, dodge=True, color='slategray', palette=[
  466. 'lightgray','slategray'], linewidth=1.1, width=0.8)
  467. g.set_yscale("log")
  468. ax.grid(axis='x', b=False)
  469. plt.rcParams['legend.title_fontsize'] = 9
  470. plt.legend(loc='center left', bbox_to_anchor=(1, 0.5),
  471. fontsize='x-small', title='time to seizure onset')
  472. ax.set_xticklabels(labels)
  473. # -----------------------------------------------------------------#
  474. # quantity labels
  475. # -----------------------------------------------------------------#
  476. quantity_label = r'$\hat{m}$'
  477. ymax = 1e-3
  478. ymin = 1
  479. ax.set_ylim(ymin, ymax)
  480. T = [1, 1e-1, 1e-2, 1e-3]
  481. ax.set_yticks(T)
  482. ax.set_yticklabels([0, 0.9, 0.99, 0.999])
  483. # -----------------------------------------------------------------#
  484. # Annotate p-values of pairwise comparison
  485. # -----------------------------------------------------------------#
  486. y_max = 1.3 * ymax
  487. y_min = ymin
  488. for ir, region in enumerate(regions):
  489. if not np.isnan(pvals[region]):
  490. ax.annotate("", xy=(-0.2 + ir * 1.0, 2.0 * y_max), xycoords='data',
  491. xytext=(0.2 + ir * 1.0, 2.0 * y_max),
  492. textcoords='data',
  493. arrowprops=dict(arrowstyle="-", ec='black',
  494. connectionstyle="bar,fraction=0.3"))
  495. ax.text(-0.35 + ir * 1.0, 0.9*y_max * 1. - abs(y_max - y_min) *
  496. 0.0, 'p' + '={:.3f}'.format(pvals[region]), fontsize=8.5)
  497. ax.set_ylim(ymin, ymax)
  498. plt.ylabel(quantity_label)
  499. plt.xlabel('brain area')
  500. sns.despine()
  501. # -----------------------------------------------------------------#
  502. # Saving
  503. # -----------------------------------------------------------------#
  504. plotfile_mx = '{}Fig2_2parts_regions_Engel{}.pdf'.format(result_path,
  505. Engel)
  506. plt.savefig(plotfile_mx, bbox_inches='tight')
  507. def binning_label(patient, soz):
  508. focifile = '../Data/patients.txt'
  509. f = open(focifile, 'r')
  510. foci = [line.rstrip('\n').split('\t') for line in f.readlines()]
  511. focus = 'NA'
  512. for i, idf in enumerate(foci[1:]):
  513. if int(idf[0]) == int(patient):
  514. focus = idf[1]
  515. if soz == "SOZ":
  516. if focus == "L":
  517. binning = "left"
  518. elif focus == "R":
  519. binning = "right"
  520. else:
  521. raise Exception("No clear focus found.")
  522. elif soz == "nSOZ":
  523. if focus == "L":
  524. binning = "right"
  525. elif focus == "R":
  526. binning = "left"
  527. else:
  528. raise Exception("No clear focus found.")
  529. return binning
  530. def get_mt(patient, recording, soz, save_path, fit_method, kmin, kmax,
  531. windowsize, windowstep, dt):
  532. binning = binning_label(patient, soz)
  533. mt_file = '{}{}/mt_results_{}_{}_kmin{}_kmax{}_winsize{}_winstep{}_dt{}.pkl'.format(
  534. save_path, recording, binning, fit_method, kmin, kmax,
  535. windowsize, windowstep, dt)
  536. if not os.path.isfile(mt_file):
  537. raise Exception('{} not existing'.format(mt_file))
  538. # -----------------------------------------------------------------#
  539. # read m(t) data
  540. # -----------------------------------------------------------------#
  541. mt_frame = pd.read_pickle(mt_file)
  542. original_length = len(mt_frame.m.tolist())
  543. rejected_inconsistencies = ['H_nonzero', 'H_linear', 'not_converged']
  544. for incon in rejected_inconsistencies:
  545. if not mt_frame.empty:
  546. mt_frame = mt_frame[[incon not in mt_frame[
  547. 'inconsistencies'].tolist()[i] for i in range(
  548. len(mt_frame['inconsistencies'].tolist()))]]
  549. if len(mt_frame.m.tolist()) < 0.95 * original_length or len(
  550. mt_frame.m.tolist()) < 200: # in general, the recording should be
  551. # 260 windows long. if it is much shorter, it is unclear where to
  552. # divide it.
  553. raise Exception('Too many inconsistencies')
  554. mt_list = mt_frame.m.tolist()
  555. return mt_list
  556. def mad(data):
  557. return np.median(np.abs(data-np.median(data)))
  558. def variance_mt(save_path, data_path, fit_method, kmin, kmax,
  559. windowsize, windowstep, dt, logepsilon=True, Engel=False):
  560. patients = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  561. 15, 16, 17, 18, 19, 20]
  562. if Engel:
  563. patients = [1, 6, 8, 9, 10, 11, 16, 17, 18, 19]
  564. laterality = ["SOZ", "nSOZ"]
  565. # -----------------------------------------------------------------#
  566. # Extract m(t) values an compute variances
  567. # -----------------------------------------------------------------#
  568. df = None
  569. for j, soz in enumerate(laterality):
  570. variance_first = []
  571. variance_last = []
  572. diff_list = []
  573. for ir, patient in enumerate(patients):
  574. recordings = mr_utilities.list_preictrecordings(patient)[0]
  575. for irec, rec in enumerate(recordings):
  576. try:
  577. m_list = get_mt(patient, rec, soz, data_path, fit_method,
  578. kmin, kmax, windowsize, windowstep, dt)
  579. m_first = m_list[:int(len(m_list)/2)]
  580. m_last = m_list[-int(len(m_list) / 2):]
  581. if logepsilon:
  582. m_first = [np.log(1 - m) for m in m_first]
  583. m_last = [np.log(1 - m) for m in m_last]
  584. variance_first.append(mad(m_first))
  585. variance_last.append(mad(m_last))
  586. diff_list.append(mad(m_first)-mad(m_last))
  587. except Exception:
  588. # If too many window estimates were excluded in the
  589. # function get_mt(), an exception will be risen.
  590. # We will simply continue with the remaining recordings.
  591. continue
  592. # -----------------------------------------------------------------#
  593. # create boxplot of variance
  594. # -----------------------------------------------------------------#
  595. stat, p = stats.wilcoxon(diff_list)
  596. print('p-value:'+str(p))
  597. quantity = 'variance'
  598. data1 = pd.DataFrame({
  599. quantity: variance_first,
  600. 'rec_type': ['10 - 5 min' for _ in range(len(variance_first))],
  601. 'binning_focus': [soz for _ in range(len(variance_first))],
  602. 'pval': [p for _ in range(len(variance_last))]
  603. })
  604. if df is None:
  605. df = data1
  606. else:
  607. df = df.append(data1, ignore_index=True)
  608. data2 = pd.DataFrame({
  609. quantity: variance_last,
  610. 'rec_type': ['5 - 0 min' for _ in range(len(variance_last))],
  611. 'binning_focus': [soz for _ in range(len(variance_last))],
  612. 'pval': [p for _ in range(len(variance_last))]
  613. })
  614. df = df.append(data2, ignore_index=True)
  615. # -----------------------------------------------------------------#
  616. # Plotting
  617. # -----------------------------------------------------------------#
  618. fig, ax = plt.subplots(1, 1, figsize=(cm2inch(5.5), cm2inch(4.5)))
  619. g = sns.boxplot(ax=ax, x='binning_focus', y='variance', hue='rec_type',
  620. data=df, hue_order=['10 - 5 min', '5 - 0 min'], order=[
  621. 'SOZ', 'nSOZ'], dodge=True, color='slategray', palette=[
  622. 'lightgray', 'slategray'], linewidth=1.1, width=0.6)
  623. g.set_yscale("log")
  624. plt.grid(axis='x', b=False)
  625. plt.rcParams['legend.title_fontsize'] = 9
  626. plt.legend(loc="upper left", ncol=1, fontsize='x-small',
  627. bbox_to_anchor=(0, 1.7), title='time to seizure onset')
  628. n_f_pre = len(df[(df['binning_focus'] == 'SOZ') &
  629. (df['rec_type'] == '5 - 0 min')].index)
  630. n_f_inter = len(df[(df['binning_focus'] == 'SOZ') &
  631. (df['rec_type'] == '10 - 5 min')].index)
  632. n_c_pre = len(df[(df['binning_focus'] == 'nSOZ') &
  633. (df['rec_type'] == '5 - 0 min')].index)
  634. n_c_inter = len(df[(df['binning_focus'] == 'nSOZ') &
  635. (df['rec_type'] == '10 - 5 min')].index)
  636. ax.set_xticklabels(['ipsi\n({}, {})'.format(n_f_pre, n_f_inter),
  637. 'contra\n({}, {})'.format(n_c_pre, n_c_inter)])
  638. # -----------------------------------------------------------------#
  639. # annotate p-values
  640. # -----------------------------------------------------------------#
  641. y_max = 2.4 * np.max(variance_first)
  642. y_min = 0.4 * np.min(variance_first)
  643. ax.annotate("", xy=(-0.2, y_max), xycoords='data',
  644. xytext=(0.2, y_max), textcoords='data',
  645. arrowprops=dict(arrowstyle="-", ec='black',
  646. connectionstyle="bar,fraction=0.2"))
  647. ax.text(-0.2, y_max + abs(y_max - y_min) * 0.1,
  648. 'p={:.3f}'.format(df[df['binning_focus'] == 'SOZ'].pval.tolist()[
  649. 0]), fontsize=8)
  650. ax.annotate("", xy=(0.8, y_max), xycoords='data', xytext=(1.2, y_max),
  651. textcoords='data', arrowprops=dict(arrowstyle="-", ec='black',
  652. connectionstyle="bar,fraction=0.2"))
  653. ax.text(0.8, y_max + abs(y_max - y_min) * 0.1,
  654. 'p={:.3f}'.format(df[df['binning_focus'] == 'nSOZ'].pval.tolist(
  655. )[0]), fontsize=8)
  656. plt.xlabel('')
  657. sns.despine()
  658. plt.ylabel(r'Variability in $\hat{m}$')
  659. plt.yscale('log')
  660. plt.savefig('{}Fig2_variance_mt.pdf'.format(save_path), bbox_inches='tight')
  661. plt.show()
  662. def timeresolved_example():
  663. result_path = '../Results/preictal/singleunits/'
  664. ksteps = (1, 400)
  665. kmin = ksteps[0]
  666. kmax = ksteps[1]
  667. windowsize = 20000
  668. windowstep = 500
  669. dt = 4
  670. patients = [13]
  671. for patient in patients:
  672. mt_examples(patient, result_path, 'offset', kmin, kmax,
  673. windowsize, windowstep, dt)
  674. def boxplot_2parts_hemispheres():
  675. x = 2
  676. ksteps = (1, 400)
  677. fit_method = 'offset'
  678. result_path = '../Results/preictal/singleunits/'
  679. boxplot_mx(result_path, x, ksteps, fit_method, Engel=False)
  680. boxplot_mx(result_path, x, ksteps, fit_method, Engel=True)
  681. def boxplot_2parts_regions():
  682. x = 2
  683. ksteps = (1, 400)
  684. fit_method = 'offset'
  685. result_path = '../Results/preictal/singleunits_regions/'
  686. boxplot_mx_regions(result_path, x, ksteps, fit_method, Engel=False)
  687. pointplot_mx_regions_Engel(result_path, x, ksteps, fit_method)
  688. def visualize_mt_variance():
  689. save_path = '../Results/preictal/singleunits/'
  690. data_path = '../Results/preictal/singleunits/'
  691. variance_mt(save_path, data_path, fit_method='offset', kmin=1, kmax=400,
  692. windowsize=20000, windowstep=500, dt=4,
  693. Engel=False, logepsilon=True)
  694. def main():
  695. timeresolved_example()
  696. boxplot_2parts_hemispheres()
  697. boxplot_2parts_regions()
  698. visualize_mt_variance()
  699. if __name__ == '__main__':
  700. main()