create_supp_figures.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. import os
  2. import pandas as pd
  3. import mrestimator as mre
  4. import numpy as np
  5. import matplotlib.pylab as plt
  6. import seaborn as sns
  7. import matplotlib.gridspec as gridspec
  8. from scipy import stats as sps
  9. import mr_utilities
  10. def cm2inch(value):
  11. return value/2.54
  12. mycol = ['darkgreen', 'mediumaquamarine', 'slategray', 'darkblue','steelblue',
  13. 'firebrick', 'purple', 'orange', "red", "violet", "darkred",
  14. "darkviolet", "green", "salmon", "black", 'darkgreen',
  15. 'mediumaquamarine', 'silver', 'darkblue','steelblue', 'firebrick',
  16. 'purple', 'orange', "red", "violet", "darkred", "darkviolet"]
  17. def distribution_A_recordings(resultpath):
  18. data_path = '../Data/preictal/'
  19. recordings = [dI for dI in os.listdir(data_path) if os.path.isdir(
  20. os.path.join(data_path, dI))]
  21. A_mean = []
  22. A_nonzero = []
  23. A_nonzero_frac = []
  24. for recording in recordings:
  25. outputfile = '{}{}/activity_SU_4ms.pkl'.format(data_path, recording)
  26. if not os.path.isfile(outputfile):
  27. print("No binning data for recording ", recording)
  28. continue
  29. data = pd.read_pickle(outputfile)
  30. binnings = data['binning'].tolist()
  31. for binning in binnings:
  32. activity = data[data['binning'] == binning]['activity'].tolist()[0]
  33. A_mean.append(np.mean(activity))
  34. A_nonzero.append(mr_utilities.count_nonzero(activity))
  35. A_nonzero_frac.append(mr_utilities.count_nonzero(activity) /
  36. len(activity) * 100)
  37. A_mean_Hz = [A_m*(1000/4) for A_m in A_mean]
  38. A_mean = A_mean_Hz
  39. quantile = 0.50
  40. A_mean_50 = np.quantile(A_mean, quantile)
  41. A_nonzero_50 = np.quantile(A_nonzero, quantile)
  42. A_nonzero_frac_50 = np.quantile(A_nonzero_frac, quantile)
  43. quantile = 0.25
  44. A_mean_25 = np.quantile(A_mean, quantile)
  45. A_nonzero_25 = np.quantile(A_nonzero, quantile)
  46. A_nonzero_frac_25 = np.quantile(A_nonzero_frac, quantile)
  47. sns.set(style='white')
  48. fig, ax = plt.subplots(1, 3, figsize=((cm2inch(21), cm2inch(2.8))))
  49. bins = np.arange(0, np.max(A_mean), 20)
  50. ax[0].hist(A_mean, alpha=0.6, color='darkblue')
  51. ax[0].set_xlabel(r'population firing rate R (Hz)')
  52. ax[0].set_ylabel(r'# recordings')
  53. ax[0].text(0.8, 0.8, r'$q_{50}$'+'={:.1f} Hz'.format(A_mean_50),
  54. horizontalalignment='center', verticalalignment='center',
  55. transform=ax[0].transAxes, color='green', fontsize=11)
  56. ax[0].text(0.8, 0.65, r'$q_{25}$'+'={:.1f} Hz'.format(A_mean_25),
  57. horizontalalignment='center', verticalalignment='center',
  58. transform=ax[0].transAxes, color='green', fontsize=11)
  59. bins = np.arange(0, np.max(A_nonzero), 20)
  60. ax[1].hist(A_nonzero, alpha=0.6, color='darkblue')
  61. ax[1].set_xlabel(r'$n_{A_t\neq 0}$')
  62. ax[1].text(0.8, 0.8, r'$q_{50}$'+'={:.0f}'.format(A_nonzero_50),
  63. horizontalalignment='center', verticalalignment='center',
  64. transform=ax[1].transAxes, color='green', fontsize=11)
  65. ax[1].text(0.8, 0.65, r'$q_{25}$'+'={:.0f}'.format(A_nonzero_25),
  66. horizontalalignment='center', verticalalignment='center',
  67. transform=ax[1].transAxes, color='green', fontsize=11)
  68. bins = np.arange(0, np.max(A_nonzero_frac), 20)
  69. ax[2].hist(A_nonzero_frac, alpha=0.6, color='darkblue')
  70. ax[2].set_xlabel(r'$n_{A_t\neq 0}$ / $n_{A_t}$ (%)')
  71. ax[2].text(0.7, 0.8, r'$q_{50}$'+'={:.1f} %'.format(A_nonzero_frac_50),
  72. horizontalalignment='center',
  73. verticalalignment='center', transform=ax[2].transAxes,
  74. color='green', fontsize=11)
  75. ax[2].text(0.7, 0.65, r'$q_{25}$'+'={:.1f} %'.format(A_nonzero_frac_25),
  76. horizontalalignment='center',
  77. verticalalignment='center', transform=ax[2].transAxes,
  78. color='green', fontsize=11)
  79. ax[0].tick_params(top='off', bottom='on', left='on', right='off',
  80. labelleft='on',labelbottom='on')
  81. ax[1].tick_params(top='off', bottom='on', left='on', right='off',
  82. labelleft='on', labelbottom='on')
  83. ax[2].tick_params(top='off', bottom='on', left='on', right='off',
  84. labelleft='on', labelbottom='on')
  85. sns.despine()
  86. plt.subplots_adjust(bottom=None, right=None,
  87. wspace=0.6, hspace=0.3, left=0.15, top=1.2)
  88. figfile = '{}S4_recording_statistics.pdf'.format(resultpath)
  89. plt.savefig(figfile, bbox_inches='tight')
  90. plt.show()
  91. def mt_all_supp(save_path,fit_method, kmin, kmax, windowsize, windowstep, dt):
  92. patients = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
  93. 18, 19, 20]
  94. fig = plt.figure(figsize=(cm2inch(2*13.5), cm2inch(1.2*10*5)))
  95. outer = gridspec.GridSpec(10, 2, wspace=0.2, hspace=0.9)
  96. laterality = ["SOZ", "nSOZ"]
  97. for ip, patient in enumerate(patients):
  98. inner = gridspec.GridSpecFromSubplotSpec(2, 1, subplot_spec=outer[ip],
  99. wspace=0.1, hspace=0.9)
  100. for j, soz in enumerate(laterality):
  101. ax = plt.Subplot(fig, inner[j])
  102. ax = mt_plot(ax, patient, soz, save_path,fit_method, kmin, kmax,
  103. windowsize, windowstep, dt,
  104. excludeInconsistencies=True)
  105. if j == 0:
  106. ax.set_title('Patient {}'.format(int(patient)), fontsize=12)
  107. ax.tick_params(top='off', bottom='on', left='off',
  108. right='off', labelleft='on',
  109. labelbottom='off')
  110. ax.set_xlabel('')
  111. fig.add_subplot(ax)
  112. sns.despine(fig)
  113. plt.savefig(
  114. '{}/S6_allmt_{}_{}_winsize{}_winstep{}_kmin{}_kmax{}.pdf'.format(
  115. save_path, patient, fit_method,
  116. windowsize, windowstep, kmin, kmax), bbox_inches='tight')
  117. plt.savefig(
  118. '{}/S6_allmt_{}_{}_winsize{}_winstep{}_kmin{}_kmax{}.png'.format(
  119. save_path, patient, fit_method,
  120. windowsize, windowstep, kmin, kmax), bbox_inches='tight', dpi=350)
  121. plt.savefig(
  122. '{}/S6_allmt_{}_{}_winsize{}_winstep{}_kmin{}_kmax{}.svg'.format(
  123. save_path, patient, fit_method,
  124. windowsize, windowstep, kmin, kmax), bbox_inches='tight')
  125. plt.show()
  126. plt.close()
  127. def binning_label(patient, soz):
  128. focifile = '../Data/patients.txt'
  129. f = open(focifile, 'r')
  130. foci = [line.rstrip('\n').split('\t') for line in f.readlines()]
  131. focus = 'NA'
  132. for i, idf in enumerate(foci[1:]):
  133. if int(idf[0]) == int(patient):
  134. focus = idf[1]
  135. if soz == "SOZ":
  136. if focus == "L":
  137. binning = "left"
  138. elif focus == "R":
  139. binning = "right"
  140. else:
  141. raise Exception("No clear focus found.")
  142. elif soz == "nSOZ":
  143. if focus == "L":
  144. binning = "right"
  145. elif focus == "R":
  146. binning = "left"
  147. else:
  148. raise Exception("No clear focus found.")
  149. return binning
  150. def mt_plot(ax, patient, soz, save_path, fit_method, kmin, kmax,
  151. windowsize, windowstep, dt, excludeInconsistencies=True):
  152. recordings = mr_utilities.list_preictrecordings(patient)[0]
  153. binning = binning_label(patient, soz)
  154. for irec, rec in enumerate(recordings):
  155. mt_file = '{}{}/mt_results_{}_{}_kmin{}_kmax{}_winsize{}_winstep{}' \
  156. '_dt{}.pkl'.format(save_path, rec, binning, fit_method, kmin,
  157. kmax, windowsize, windowstep, dt)
  158. if not os.path.isfile(mt_file):
  159. print('{} not existing'.format(mt_file))
  160. continue
  161. # -----------------------------------------------------------------#
  162. # read m(t) data
  163. # -----------------------------------------------------------------#
  164. mt_frame = pd.read_pickle(mt_file)
  165. if excludeInconsistencies:
  166. original_length = len(mt_frame.m.tolist())
  167. rejected_inconsistencies = ['H_nonzero', 'H_linear',
  168. 'not_converged']
  169. for incon in rejected_inconsistencies:
  170. if not mt_frame.empty:
  171. mt_frame = mt_frame[[incon not in mt_frame[
  172. 'inconsistencies'].tolist()[i] for i in range(
  173. len(mt_frame['inconsistencies'].tolist()))]]
  174. if len(mt_frame.m.tolist()) < 0.95 * original_length:
  175. continue
  176. kmin = mt_frame.kmin.unique()[0]
  177. kmax = mt_frame.kmax.unique()[0]
  178. fit_method = mt_frame.fit_method.unique()[0]
  179. winsize = mt_frame.windowsize.unique()[0]
  180. t0_list = mt_frame.t0.tolist()
  181. mt = mt_frame.m.tolist()
  182. t0_list = [t0_ms * 0.001 for t0_ms in t0_list]
  183. half_win_sec = int((winsize / 2) / 1000 * dt)
  184. t_middle = [t0 + half_win_sec for t0 in t0_list]
  185. # -----------------------------------------------------------------#
  186. # Plotting
  187. # -----------------------------------------------------------------#
  188. ax.plot(t_middle, mt, '.', label='Rec {}'.format(irec + 1),
  189. color=mycol[irec], markersize=0.5)
  190. ax.axhline(y=1, color='black', linestyle='--', alpha=0.3)
  191. ax.set_ylabel(r"$\hat{m}$")
  192. ax.set_xlim((t0_list[0] - 10, t0_list[-1] + 2 * half_win_sec + 10))
  193. binning_focus = mr_utilities.binning_focus(binning, int(patient))
  194. if binning_focus == 'focal':
  195. focus_label = 'ipsi'
  196. else:
  197. focus_label = 'contra'
  198. ax.set_title("{}".format(focus_label), loc='left')
  199. ax.set_xlim((-10, 610))
  200. handles, labels = ax.get_legend_handles_labels()
  201. if len(labels) == 0:
  202. if soz == 'SOZ':
  203. ax.set_title("ipsi", loc='left')
  204. if soz == 'nSOZ':
  205. ax.set_title("contra", loc='left')
  206. ax.axhline(y=1, color='black', linestyle='--', alpha=0.3)
  207. ax.set_ylabel(r"$\hat{m}$")
  208. ax.set_ylim((0.8, 1.05))
  209. ax.set_xlim((-10, 610))
  210. ax.xaxis.grid(False)
  211. ax.set_xlabel("time (s)")
  212. ax.tick_params(top='off', bottom='off', left='off', right='off',
  213. labelleft='on', labelbottom='off')
  214. ax.tick_params(top='off', bottom='on', left='off', right='off',
  215. labelleft='on', labelbottom='on')
  216. sns.despine()
  217. return ax
  218. def windowsize_analysis_recs(data_path, recording, binning, outputfilename,
  219. resultpath):
  220. outputfile = '{}{}/{}'.format(data_path, recording, outputfilename)
  221. if not os.path.isfile(outputfile):
  222. print("No binning data for recording ", recording)
  223. print(outputfile)
  224. return
  225. data = pd.read_pickle(outputfile)
  226. dt = data['dt'].unique()[0]
  227. activity = data[data['binning'] == binning]['activity'].tolist()[0]
  228. winstep = 100
  229. ksteps = (1, 400)
  230. windowsize = np.arange(2500, 40000, 2500)
  231. N_estimates = len(activity) - np.max(windowsize)
  232. tau_estimate = []
  233. tau_conf = []
  234. m_estimate = []
  235. m_conf = []
  236. for Lw in windowsize:
  237. tau_L = []
  238. m_L = []
  239. for iw in range(0, N_estimates, winstep):
  240. activity_window = activity[iw:iw+Lw]
  241. input = mre.input_handler(activity_window)
  242. rk = mre.coefficients(input, steps=ksteps, dt=dt)
  243. fitres_offset = mre.fit(rk, fitfunc=mre.f_exponential_offset)
  244. tau_L.append(fitres_offset.tau)
  245. m_L.append(fitres_offset.mre)
  246. conf_int_off = sps.mstats.mquantiles(tau_L, prob=[0.025, 0.975],
  247. alphap=0, betap=1, axis=None,
  248. limit=())
  249. conf_int_off = [abs(np.mean(tau_L) - ci) for ci in conf_int_off]
  250. tau_conf.append(conf_int_off)
  251. tau_estimate.append(np.mean(tau_L))
  252. conf_int_off = sps.mstats.mquantiles(m_L, prob=[0.025, 0.975],
  253. alphap=0, betap=1, axis=None,
  254. limit=())
  255. conf_int_off = [abs(np.mean(m_L) - ci) for ci in conf_int_off]
  256. m_conf.append(conf_int_off)
  257. m_estimate.append(np.mean(m_L))
  258. windowsize_seconds = [w * 4 / 1000 for w in windowsize]
  259. fig, ax = plt.subplots(1, 1, figsize=((cm2inch(9), cm2inch(0.9 * 4))))
  260. ax.scatter(windowsize_seconds, tau_estimate,
  261. label=r'$\hat{\tau}_{offset}$', c='steelblue',
  262. marker='.', s=9)
  263. ax.errorbar(windowsize_seconds, tau_estimate,
  264. yerr=np.transpose(np.array(tau_conf)),
  265. linestyle="None", c='steelblue', elinewidth=0.9,
  266. capsize=2.5)
  267. ax.set_ylim((-10, 800))
  268. T = [20, 40, 60, 80, 100, 120, 140]
  269. ax.set_xticks(T)
  270. ax.set_xlabel('window size (s)')
  271. ax.set_ylabel(r'$\hat{\tau}$ (ms)')
  272. sns.despine()
  273. plt.subplots_adjust(bottom=None, right=None,
  274. wspace=0.4, hspace=0.3, left=0.15, top=1.2)
  275. figfile = '{}S5_estimates_winsizes_rec_{}_{}.pdf'.format(
  276. resultpath, recording, binning)
  277. plt.savefig(figfile, bbox_inches='tight')
  278. fig, ax = plt.subplots(1, 1, figsize=((cm2inch(9), cm2inch(0.9 * 4))))
  279. ax.scatter(windowsize_seconds, m_estimate,
  280. label=r'$\hat{\tau}_{offset}$', c='royalblue',
  281. marker='.', s=9)
  282. ax.errorbar(windowsize_seconds, m_estimate,
  283. yerr=np.transpose(np.array(m_conf)),
  284. linestyle="None", c='royalblue', elinewidth=0.9,
  285. capsize=2.5)
  286. T = [20, 40, 60, 80, 100, 120, 140]
  287. ax.set_xticks(T)
  288. ax.set_ylim((0.5, 1.25))
  289. ax.set_xlabel('window size (s)')
  290. ax.set_ylabel(r'$\hat{m}$')
  291. sns.despine()
  292. plt.subplots_adjust(bottom=None, right=None,
  293. wspace=0.4, hspace=0.3, left=0.15, top=1.2)
  294. figfile = '{}S5_estimates_m_winsizes_rec_{}_{}.pdf'.format(
  295. resultpath, recording, binning)
  296. plt.savefig(figfile, bbox_inches='tight')
  297. plt.show()
  298. def windowsize_analysis():
  299. binning = 'left'
  300. outputfilename = 'activity_SU_4ms.pkl'
  301. resultpath = '../Results/preictal/singleunits/'
  302. data_path = '../Data/interictal/'
  303. recording = '13ref'
  304. windowsize_analysis_recs(data_path, recording, binning, outputfilename,
  305. resultpath)
  306. data_path = '../Data/preictal/'
  307. recording = '13_02'
  308. windowsize_analysis_recs(data_path, recording, binning, outputfilename,
  309. resultpath)
  310. def all_mt():
  311. result_path = '../Results/preictal/singleunits/'
  312. ksteps = (1, 400)
  313. kmin = ksteps[0]
  314. kmax=ksteps[1]
  315. windowsize = 20000
  316. windowstep = 500
  317. dt = 4
  318. mt_all_supp(result_path, 'offset', kmin, kmax, windowsize, windowstep, dt)
  319. def example_autocorrelations(patient, pkl_file_inter, pkl_file_pre,
  320. resultpath, **kwargs):
  321. mr_results_pre = pd.read_pickle(pkl_file_pre)
  322. mr_results_inter = pd.read_pickle(pkl_file_inter)
  323. mr_results_pre['rectype'] = 'preictal'
  324. mr_results_inter['rectype'] = 'interictal'
  325. mr_results = pd.concat([mr_results_pre, mr_results_inter],
  326. ignore_index=True)
  327. conditions = list()
  328. for key in kwargs.keys():
  329. conditions.append(mr_results[key] == kwargs[key])
  330. if len(conditions) > 0:
  331. mr_results = mr_results[mr_utilities.conjunction(*conditions)]
  332. mr_results = mr_results[mr_results['patient'] == patient]
  333. binning_foci = ['focal', 'contra-lateral']
  334. kmin = mr_results.kmin.unique()[0]
  335. kmax = mr_results.kmax.unique()[0]
  336. sns.set(style="white")
  337. fig, ax = plt.subplots(2, 4, figsize=(cm2inch(24), cm2inch(6)))
  338. fit_method = 'offset'
  339. mr_rec_pre = mr_results[mr_results['rectype'] == 'preictal']
  340. pre_recordings_choice = mr_rec_pre.recording.unique()[:3]
  341. for si, soz in enumerate(binning_foci):
  342. # plot interictal in first position
  343. mr_rec_inter = mr_results[mr_results['rectype'] == 'interictal']
  344. mr_rec_inter = mr_rec_inter[mr_rec_inter['binning_focus'] == soz]
  345. rk = mr_rec_inter['rk'].item()[0]
  346. k_steps = mr_rec_inter['rk_steps'].item()
  347. dt = mr_rec_inter['dt'].item()
  348. time_steps = np.array(k_steps[0]) * dt
  349. ax[si, 0].plot(time_steps, rk, '-', linewidth=0.8,
  350. c='slategray', alpha=0.4)
  351. fitfunc = mr_utilities.string_to_func(fit_method)
  352. fitparams = mr_rec_inter['fit_params'].item()
  353. fitparams = tuple(fitparams[0])
  354. m = mr_rec_inter['m'].item()
  355. ax[si, 0].plot(time_steps, fitfunc(time_steps, *fitparams),
  356. label=r'$m$ = {:.2f}'.format(m), color='slategray')
  357. ax[si, 0].tick_params(top='off', bottom='on', left='on',
  358. right='off', labelleft='on', labelbottom='on')
  359. ax[si, 0].set_xlabel(r"time lag $k$ (ms)")
  360. ax[si, 0].legend(loc=1, fontsize='x-small')
  361. ax[si, 0].ticklabel_format(axis='y', style='sci', scilimits=(-1, 1),
  362. useMathText=True)
  363. # plot 3 preictal recordings next to it
  364. mr_rec_pre = mr_results[mr_results['rectype'] == 'preictal']
  365. mr_rec_pre = mr_rec_pre[mr_rec_pre['binning_focus'] == soz]
  366. for irec, rec in enumerate(pre_recordings_choice):
  367. mr_rec = mr_rec_pre[mr_rec_pre['recording'] == rec]
  368. rk = mr_rec['rk'].item()[0]
  369. k_steps = mr_rec['rk_steps'].item()
  370. dt = mr_rec['dt'].item()
  371. time_steps = np.array(k_steps[0]) * dt
  372. ax[si, irec+1].plot(time_steps, rk, '-', linewidth=0.8,
  373. c='darkblue', alpha=0.4)
  374. fitfunc = mr_utilities.string_to_func(fit_method)
  375. fitparams = mr_rec['fit_params'].item()
  376. fitparams = tuple(fitparams[0])
  377. m = mr_rec['m'].item()
  378. ax[si, irec+1].plot(time_steps, fitfunc(time_steps, *fitparams),
  379. label=r'$m$ = {:.2f}'.format(m), color='darkblue')
  380. ax[si, irec+1].tick_params(top='off', bottom='on', left='on',
  381. right='off', labelleft='on',labelbottom='on')
  382. ax[si, irec+1].set_xlabel(r"time lag $k$ (ms)")
  383. ax[si, irec+1].legend(loc=1, fontsize='x-small')
  384. ax[si, irec+1].ticklabel_format(axis='y', style='sci',
  385. scilimits=(-1, 1), useMathText=True)
  386. ax[0, 0].set_ylabel("ACF")
  387. ax[1, 0].set_ylabel("ACF")
  388. plt.subplots_adjust(bottom=None, right=None,
  389. wspace=0.5, hspace=1, left=0.15, top=1.2)
  390. sns.despine(fig)
  391. resultpath_rec = '{}S1_autocorrelations_kmin{}_kmax{}_patient{}.pdf'.format(resultpath, kmin, kmax, patient)
  392. plt.savefig(resultpath_rec, bbox_inches='tight')
  393. resultpath_rec = '{}S1_autocorrelations_kmin{}_kmax{}_patient{}.png'.format(resultpath, kmin, kmax, patient)
  394. plt.savefig(resultpath_rec, bbox_inches='tight', dpi=300)
  395. resultpath_rec = '{}S1_autocorrelations_kmin{}_kmax{}_patient{}.svg'.format(resultpath, kmin, kmax, patient)
  396. plt.savefig(resultpath_rec, bbox_inches='tight')
  397. plt.close()
  398. def create_example_ACF_plot():
  399. pkl_file_pre = '../Results/preictal/singleunits/mr_results.pkl'
  400. pkl_file_inter = '../Results/interictal/singleunits/mr_results.pkl'
  401. resultpath = '../Results/preictal/singleunits/'
  402. ksteps = (1, 400)
  403. patient = 12
  404. example_autocorrelations(patient, pkl_file_inter, pkl_file_pre,
  405. resultpath, kmin=ksteps[0], kmax=ksteps[1])
  406. patient = 13
  407. example_autocorrelations(patient, pkl_file_inter, pkl_file_pre,
  408. resultpath, kmin=ksteps[0], kmax=ksteps[1])
  409. def main():
  410. #create_example_ACF_plot()
  411. #windowsize_analysis()
  412. all_mt()
  413. if __name__ == '__main__':
  414. main()