create_figure_2.py 39 KB

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