mr_epilepsy_timeresolved.py 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. import numpy as np
  2. import pandas as pd
  3. import mrestimator as mre
  4. import os
  5. import time
  6. import mr_utilities
  7. import math
  8. def analyse_timeresolved_mr(data_path, result_path, recordings,
  9. binnings='all', ksteps=(1,400),
  10. windowsize=20000, windowstep=500,
  11. fit_method="offset"):
  12. for recording in recordings:
  13. outputfile = '{}{}/pkl/activity_SU_4ms.pkl'.format(data_path, recording)
  14. if os.path.isfile(outputfile):
  15. data = pd.read_pickle(outputfile)
  16. else:
  17. print('Error: no datafile for recording {}'.format(recording))
  18. continue
  19. existing_binnings = data['binning'].unique().tolist()
  20. patient = int(data['patient'].unique()[0])
  21. if binnings == 'all':
  22. binnings = existing_binnings
  23. for binning in binnings:
  24. dt = data['dt'].unique()[0]
  25. activity_list = data[data['binning'] == binning]['activity'].tolist()
  26. if len(activity_list) == 0:
  27. continue
  28. if len(activity_list) > 1:
  29. print('Error: Multiple activity entries for binning.')
  30. data = data[~data['activity'].apply(tuple).duplicated()]
  31. activity_list = data[data['binning'] == binning][
  32. 'activity'].tolist()
  33. activity = activity_list[0]
  34. else:
  35. activity = activity_list[0]
  36. t_onset = 600 # in seconds, given 10min recordings
  37. # the recording is significantly less than 10min long,
  38. # it is unclear whether seizure onset is indeed at the end of
  39. # the recording, therefore better skip
  40. if len(activity) < 0.8 * t_onset * 10**3 / dt:
  41. continue
  42. save_path_recording = '{}{}/'.format(result_path, recording)
  43. timeresolved_mr(activity, windowsize, windowstep,
  44. ksteps[0], ksteps[1], fit_method,
  45. save_path_recording, patient, recording,
  46. binning, dt)
  47. print('break to cool cpu...')
  48. time.sleep(30)
  49. def timeresolved_mr(activity, windowsize, windowstep, kmin, kmax,
  50. fit_method, save_path_recording, patient, recording,
  51. binning, dt):
  52. """ performs MR estimation in sliding windows of provided activity and
  53. calls function to store results in pkl file
  54. """
  55. for t in range(0, len(activity) - windowsize, windowstep):
  56. windowed_data = activity[t:t + windowsize]
  57. prepared = mre.input_handler(windowed_data)
  58. rk = mre.coefficients(prepared, dt=dt, dtunit='ms', steps=(kmin, kmax))
  59. try:
  60. fit_res = mre.fit(rk, fitfunc=mr_utilities.string_to_func(
  61. fit_method))
  62. t0 = t * dt
  63. mt_savefile(save_path_recording, patient, recording, binning,
  64. dt, kmin, kmax, fit_method, windowsize, windowstep,
  65. t0=t0, activity=windowed_data, rk=rk, fitres=fit_res)
  66. except (RuntimeError, ValueError):
  67. continue
  68. def mt_savefile(result_path, patient, recording, binning, dt, kmin, kmax,
  69. fit_method, windowsize, windowstep, t0, activity, rk,
  70. fitres):
  71. """ save results of m(t) estimation performed by function
  72. timeresolved_mr to pkl file.
  73. """
  74. datafile = '{}mt_results_{}_{}_kmin{}_kmax{}_winsize{}_winstep{}_dt{}' \
  75. '.pkl'.format(result_path, binning, fit_method, kmin, kmax,
  76. windowsize, windowstep, dt)
  77. if math.isnan(fitres.tau):
  78. inconsistencies = ['not_converged']
  79. else:
  80. inconsistencies = mr_utilities.consistency_checks(activity, rk, fitres)
  81. try:
  82. fano = np.var(activity)/np.mean(activity)
  83. variance = np.var(activity)
  84. except ZeroDivisionError:
  85. fano = np.nan
  86. variance = np.nan
  87. save_res = dict()
  88. save_res['patient'] = patient
  89. save_res['recording'] = recording
  90. save_res['binning'] = binning
  91. save_res['kmin'] = kmin
  92. save_res['kmax'] = kmax
  93. save_res['windowsize'] = windowsize
  94. save_res['windowstep'] = windowstep
  95. save_res['t0'] = t0
  96. save_res['rk'] = [list(rk.coefficients)]
  97. save_res['rk_steps'] = [list(rk.steps)]
  98. save_res['dt'] = dt
  99. save_res['fit_method'] = fit_method
  100. save_res['fit_params'] = [list(fitres.popt)]
  101. save_res['m'] = fitres.mre
  102. save_res['tau'] = fitres.tau
  103. save_res['inconsistencies'] = inconsistencies
  104. save_res['fano'] = fano
  105. save_res['variance'] = variance
  106. save_res['offset'] = fitres.popt[2]
  107. if os.path.isfile(datafile):
  108. mr_results_patient = pd.read_pickle(datafile)
  109. mr_results_patient = mr_results_patient.append(save_res,
  110. ignore_index=True)
  111. else:
  112. mr_results_patient = pd.DataFrame.from_records([save_res])
  113. mr_results_patient.to_pickle(datafile)
  114. def mt_x_parts(x, outputfilename, data_path, result_path, recordings,
  115. binnings='all', ksteps=(1, 400), fit_method ="offset"):
  116. mx_allresults = None
  117. for recording in recordings:
  118. outputfile = '{}{}/{}'.format(data_path, recording, outputfilename)
  119. if os.path.isfile(outputfile):
  120. data = pd.read_pickle(outputfile)
  121. else:
  122. print(' File not found {}'.format(outputfile))
  123. continue
  124. existing_binnings = data['binning'].unique().tolist()
  125. patient = int(data['patient'].unique()[0])
  126. kmin = ksteps[0]
  127. kmax = ksteps[1]
  128. if binnings == 'all':
  129. binnings = existing_binnings
  130. for binning in binnings:
  131. dt = data['dt'].unique()[0]
  132. activity_list = data[data['binning'] == binning]['activity'].tolist()
  133. activity = activity_list[0]
  134. partlength = int(np.floor(len(activity)/x))
  135. tau = []
  136. m = []
  137. binning_focus = mr_utilities.binning_focus(binning, patient)
  138. for i in range(x):
  139. activity_part = activity[i*partlength:(i+1)*partlength]
  140. nspikes = np.sum(np.array(activity_part))
  141. n_nonzero = mr_utilities.count_nonzero(activity_part)
  142. prepared = mre.input_handler(activity_part)
  143. rk = mre.coefficients(prepared, dt=dt, dtunit='ms',
  144. steps=(kmin, kmax))
  145. try:
  146. fit_res = mre.fit(rk,
  147. fitfunc=mr_utilities.string_to_func(
  148. fit_method))
  149. if not math.isnan(fit_res.tau):
  150. tau.append(fit_res.tau)
  151. m.append(fit_res.mre)
  152. inconsistencies = mr_utilities.consistency_checks(
  153. activity_part, rk, fit_res)
  154. fano = np.var(activity_part)/np.mean(activity_part)
  155. variance = np.var(activity_part)
  156. mx_result = {'patient': patient,
  157. 'recording': recording,
  158. 'binning': binning,
  159. 'binning_focus': binning_focus,
  160. 'partno': i+1,
  161. 'm': fit_res.mre,
  162. 'tau': fit_res.tau,
  163. 'fano': fano,
  164. 'variance': variance,
  165. 'offset': fit_res.popt[2],
  166. 'rk': [list(rk.coefficients)],
  167. 'fit_params': [list(fit_res.popt)],
  168. 'nspikes': nspikes,
  169. 'n_nonzero': n_nonzero,
  170. 'inconsistencies': inconsistencies,
  171. 'kmin': kmin,
  172. 'kmax': kmax,
  173. 'fit_method': fit_method}
  174. if mx_allresults is None:
  175. mx_allresults = pd.DataFrame.from_records(
  176. [mx_result])
  177. else:
  178. mx_allresults = mx_allresults.append(
  179. mx_result, ignore_index=True)
  180. except (RuntimeError, ValueError):
  181. continue
  182. datafile_mx = '{}mt_{}_results_allrecords_kmin{}_kmax{}_{}.pkl'.format(
  183. result_path, x, ksteps[0], ksteps[1], fit_method)
  184. if mx_allresults is not None:
  185. mx_allresults.to_pickle(datafile_mx)