script2_linelengths_of_snippets_Fig2.py 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Wed Oct 14 11:18:44 2020
  4. @author: kleisp
  5. This is a script for getting matrices of snippets around the stimulation pulses in PACK-expressing mice,
  6. which can later be used for plotting the snippets on top of each other and for line length
  7. calculations.
  8. Note that recordings with 0.1 Hz and 0.05 Hz illumination need to be treated separately
  9. One needs to load dictionaries containing recIDs with corresponding smr filenames for using raw data
  10. Abbreviations:
  11. dict- dictionary
  12. stim- light pulse
  13. pre- before light pulse
  14. post-after light pulse
  15. snipmat- matrix containing snippets
  16. """
  17. import os
  18. os.chdir('C:\EAfiles\MyCode')
  19. from glob import glob
  20. import numpy as np
  21. import pickle
  22. import pandas as pd
  23. from scipy import stats
  24. os.chdir('C:\EAfiles\EAdetection')
  25. import core.ea_management as eam
  26. reload(eam)
  27. #%% (1) define functions to extract snippets before and after the stim
  28. ''' 'pre' or 'post' are the snippet length in seconds, here 2 is used, sr=sampling rate (here 500)'''
  29. # get the spike trace before stimulation (pre):
  30. #stimtime is one element from stimtimes array
  31. def get_spiketrace_pre(stimtimes, datatrace, pre, sr):
  32. cutout_pre = np.int(pre*sr)
  33. stim_index= np.int(stimtimes*sr)
  34. spiketrace = datatrace[stim_index-cutout_pre:stim_index]
  35. return spiketrace
  36. # get the spike trace after(post) stimulation:
  37. def get_spiketrace_post(stimtime, datatrace, post, sr):
  38. cutout_post = np.int(post*sr)
  39. stim_index= np.int(stimtime*sr)
  40. spiketrace = datatrace[stim_index:stim_index+cutout_post]
  41. return spiketrace
  42. #get snippet before each stimulation and insert it into a matrix, called snipmat:
  43. def get_snipmat_pre(datatrace, recID, pre, stimtimes, sr):
  44. cutout_pre = np.int(pre*sr)
  45. N_stim = len(stimtimes) #number of stimuli
  46. snippts = cutout_pre
  47. snipmat = np.zeros((N_stim,snippts))
  48. for tt,stimtime in enumerate(stimtimes):
  49. spiketrace = get_spiketrace_pre(stimtime, datatrace, pre, sr) # instead of datatrace you can use zTrace
  50. snipmat[tt] = spiketrace
  51. return snipmat
  52. #get snippet after each stimulation and insert it into a matrix, called snipmat:
  53. def get_snipmat_post(datatrace, recID, post, stimtimes, sr):
  54. cutout_post = np.int(post*sr)
  55. N_stim = len(stimtimes) #number of stimuli
  56. snippts = cutout_post
  57. snipmat = np.zeros((N_stim,snippts))
  58. for tt,stimtime in enumerate(stimtimes):
  59. spiketrace = get_spiketrace_post(stimtime, datatrace, post, sr) # stimtime is just one timepoint from stimtimes
  60. snipmat[tt] = spiketrace
  61. return snipmat
  62. #%% (2) defining the function to get line length of each snippet(snipmat line length)
  63. def get_snipmat_linelength(snipmat_pre, snipmat_post, linelength_dict_pre, linelength_dict_post, recID):
  64. linelength_list=[]
  65. linelength_s_list=[]
  66. rms_list=[]
  67. count=0
  68. for i in xrange(snipmat_pre.shape[0]):
  69. data=snipmat_pre[i]
  70. N_datapoints=len(data)
  71. duration=N_datapoints/500 #sr=500
  72. linelength = np.sum(np.abs(np.diff(data)))
  73. linelength_list.append(linelength)
  74. linelength_s=linelength/duration
  75. linelength_s_list.append(linelength_s)
  76. count=count+1
  77. linelength_dict_pre[recID]={}
  78. linelength_dict_pre[recID]['sem pre-pulse linelength/second']=stats.sem(linelength_s_list)
  79. linelength_dict_pre[recID]['mean pre-pulse linelength/second']=np.mean(linelength_s_list)
  80. linelength_dict_pre[recID]['mean pre-pulse linelength']=np.mean(linelength_list)
  81. linelength_dict_pre[recID]['pulse number']=count
  82. linelength_list=[]
  83. linelength_s_list=[]
  84. rms_list=[]
  85. count=0
  86. for i in xrange(snipmat_post.shape[0]):
  87. data=snipmat_post[i]
  88. N_datapoints=len(data)
  89. duration=N_datapoints/500
  90. linelength = np.sum(np.abs(np.diff(data)))
  91. linelength_list.append(linelength)
  92. linelength_s=linelength/duration
  93. linelength_s_list.append(linelength_s)
  94. count=count+1
  95. linelength_dict_post[recID]={}
  96. linelength_dict_post[recID]['sem post-pulse linelength/second']=stats.sem(linelength_s_list)
  97. linelength_dict_post[recID]['mean post-pulse linelength/second']=np.mean(linelength_s_list)
  98. linelength_dict_post[recID]['mean post-pulse linelength']=np.mean(linelength_list)
  99. linelength_dict_post[recID]['pulse number']=count
  100. #%% in order to exclude unwanted recordings
  101. pathtobadrecIDs = 'C:\EAfiles\ID_Dateien\\badrecIDs.txt'
  102. badrecIDs = []
  103. with open (pathtobadrecIDs,'r') as f:
  104. badIDs = f.read().splitlines()
  105. badrecIDs = badrecIDs + badIDs
  106. #%% (3) Example of using the script to extract the snipmats
  107. #Saline PACK mice 0.05Hz: get snipmat dicts (for before and after 0.05 Hz pulses) (downsampled data)
  108. os.chdir('C:\EAfiles\EAdetection')
  109. ymlfiles = glob('C:\EAfiles\yml_setup_PK43\*.yml') #takes all yml files from this folder
  110. ymlfile = ymlfiles
  111. lines = np.arange(0, len(ymlfile)) #as many lines as there are ymlfiles
  112. snipmat_005Hz_pre_controls={}
  113. snipmat_005Hz_post_controls={}
  114. sr= 500
  115. pre, post = 2, 2 #2 seconds before and after pulse
  116. for i in lines:
  117. recID = os.path.basename(ymlfile[i]).split('__')[0] #getting the IDs
  118. print (i)
  119. print (recID)
  120. if recID in badrecIDs:
  121. pass
  122. else:
  123. excelpath = 'C:\EAfiles\Excel\\startstop_controls_HCc.xlsx'
  124. df = pd.read_excel(excelpath) #reading an excel file with start and stop times of each recording
  125. df.set_index('recID', inplace=True) #recID
  126. stimstop = int(df.stop[recID]) #stop time
  127. if recID=='PK16_005Hz1_HCc': #adding an exception (can skip this step if you have no exceptions)
  128. stimstart=int(df.start[recID])
  129. else:
  130. stimstart=10 #the stim usually starts at 10s
  131. stimstep=20 #speriod is 20 s
  132. stimtimes=np.arange(stimstart,stimstop,stimstep)
  133. aRec = eam.Rec(init_ymlpath=ymlfile[i])
  134. snipmat_005Hz_pre_controls[recID]={}
  135. data=aRec.raw_data
  136. #z_data=(data-np.mean(data))/np.std(data)
  137. snipmat_pre=get_snipmat_pre(data, recID, pre, stimtimes, sr=500)
  138. snipmat_005Hz_pre_controls[recID]=snipmat_pre
  139. snipmat_005Hz_post_controls[recID]={}
  140. snipmat_post=get_snipmat_post(data, recID, post, stimtimes, sr=500)
  141. snipmat_005Hz_post_controls[recID]=snipmat_post
  142. # save snipmat_dict
  143. filename = 'C:\EAfiles\MyDicts\snipmat_005Hz_pre_controls'
  144. outfile = open(filename, 'wb') #write binary: mit Erlaubnis zu (über)schreiben
  145. pickle.dump(snipmat_005Hz_pre_controls, outfile)
  146. outfile.close()
  147. filename = 'C:\EAfiles\MyDicts\snipmat_005Hz_post_controls'
  148. outfile = open(filename, 'wb') #write binary: mit Erlaubnis zu (über)schreiben
  149. pickle.dump(snipmat_005Hz_post_controls, outfile)
  150. outfile.close()
  151. #%% (4) Example of using the script to create dictionaries with line length before and after 0.05Hz pulses from snipmats above
  152. os.chdir('C:\EAfiles\EAdetection')
  153. ymlfiles = glob('C:\EAfiles\yml_setup_PK43\*.yml') #takes all yml files from this folder
  154. ymlfile = ymlfiles
  155. lines = np.arange(0, len(ymlfile)) #as many lines as there are ymlfiles
  156. linelength_dict_005Hz_pre={}
  157. linelength_dict_005Hz_post={}
  158. filename = 'C:\EAfiles\MyDicts\snipmat_005Hz_pre_controls'
  159. infile = open(filename,'rb') #read binary
  160. snipmat_005Hz_pre_controls = pickle.load(infile)
  161. infile.close()
  162. filename = 'C:\EAfiles\MyDicts\snipmat_005Hz_post_controls'
  163. infile = open(filename,'rb') #read binary
  164. snipmat_005Hz_post_controls = pickle.load(infile)
  165. infile.close()
  166. for i in lines:
  167. recID = os.path.basename(ymlfile[i]).split('__')[0] #getting the IDs
  168. print (i)
  169. print (recID)
  170. if recID in badrecIDs: #template also needs to be excluded
  171. #badrecIDs = ['EPxy_xHz_HCi1','...']
  172. pass
  173. else:
  174. snipmat_pre=snipmat_005Hz_pre_controls[recID]
  175. snipmat_post=snipmat_005Hz_post_controls[recID]
  176. get_snipmat_linelength(snipmat_pre, snipmat_post, linelength_dict_005Hz_pre, linelength_dict_005Hz_post, recID)
  177. filename = 'C:\EAfiles\MyDicts\linelength_dict_005Hz_post'
  178. outfile = open(filename, 'wb') #write binary: mit Erlaubnis zu (über)schreiben
  179. pickle.dump(linelength_dict_005Hz_post, outfile)
  180. outfile.close()
  181. filename = 'C:\EAfiles\MyDicts\linelength_dict_005Hz_pre'
  182. outfile = open(filename, 'wb') #write binary: mit Erlaubnis zu (über)schreiben
  183. pickle.dump(linelength_dict_005Hz_pre, outfile)
  184. outfile.close()
  185. #%% make an excel file of the pre- and post-pulse linelengths (mean and SEM)
  186. recIDs = np.array(linelength_dict_005Hz_pre.keys())
  187. flavour = 'mean pre-pulse linelength/second'
  188. mean_pre_linelengths = np.array([linelength_dict_005Hz_pre[recID][flavour] for recID in linelength_dict_005Hz_pre.keys()])
  189. flavour = 'sem pre-pulse linelength/second'
  190. sem_pre_linelengths = np.array([linelength_dict_005Hz_pre[recID][flavour] for recID in linelength_dict_005Hz_pre.keys()])
  191. flavour = 'mean post-pulse linelength/second'
  192. mean_post_linelengths = np.array([linelength_dict_005Hz_post[recID][flavour] for recID in linelength_dict_005Hz_pre.keys()])
  193. flavour = 'sem post-pulse linelength/second'
  194. sem_post_linelengths = np.array([linelength_dict_005Hz_post[recID][flavour] for recID in linelength_dict_005Hz_pre.keys()])
  195. flavour = 'pulse number'
  196. n_pulses = np.array([linelength_dict_005Hz_pre[recID][flavour] for recID in linelength_dict_005Hz_pre.keys()])
  197. os.chdir('C:\EAfiles\RESULTS')
  198. df_sr=pd.DataFrame(columns=
  199. ['recID',
  200. 'mean pre-pulse [mv/s]',
  201. 'sem pre-pulse [mv/s]',
  202. 'mean post-pulse [mv/s]',
  203. 'sem post-pulse [mv/s]',
  204. 'pulse number'])
  205. df_sr['recID'] = recIDs
  206. df_sr['mean pre-pulse [mv/s]'] = mean_pre_linelengths
  207. df_sr['sem pre-pulse [mv/s]'] = sem_pre_linelengths
  208. df_sr['mean post-pulse [mv/s]'] = mean_post_linelengths
  209. df_sr['sem post-pulse [mv/s]'] = sem_post_linelengths
  210. df_sr['pulse number'] = n_pulses
  211. df_sr.to_excel('Test_snipmat-005Hz-linelengths-control-PK43.xlsx')