Scheduled service maintenance on November 22


On Friday, November 22, 2024, between 06:00 CET and 18:00 CET, GIN services will undergo planned maintenance. Extended service interruptions should be expected. We will try to keep downtimes to a minimum, but recommend that users avoid critical tasks, large data uploads, or DOI requests during this time.

We apologize for any inconvenience.

Validation_stability.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. #!/usr/bin/env python
  2. # coding: utf-8
  3. # ### Link to the file with meta information on recordings
  4. # In[14]:
  5. #import matplotlib.pyplot as plt
  6. #plt.rcParams["figure.figsize"] = (20,3)
  7. database_path = '/media/andrey/My Passport/GIN/backup_Anesthesia_CA1/meta_data/meta_recordings - anesthesia.xlsx'
  8. # ### Select the range of recordings for the analysis (see "Number" row in the meta data file)
  9. # In[4]:
  10. rec = [x for x in range(0,189)]
  11. #rec = [1,2]
  12. # In[1]:
  13. import numpy as np
  14. import numpy.ma as ma
  15. import matplotlib.pyplot as plt
  16. import matplotlib.ticker as ticker
  17. import pandas as pd
  18. import seaborn as sns
  19. import pickle
  20. import os
  21. sns.set()
  22. sns.set_style("whitegrid")
  23. from scipy.signal import medfilt
  24. from scipy.stats import skew, kurtosis, zscore
  25. from scipy import signal
  26. from sklearn.linear_model import LinearRegression, TheilSenRegressor
  27. plt.rcParams['figure.figsize'] = [16, 8]
  28. color_awake = (0,191/255,255/255)
  29. color_mmf = (245/255,143/255,32/255)
  30. color_keta = (181./255,34./255,48./255)
  31. color_iso = (143./255,39./255,143./255)
  32. custom_palette ={'keta':color_keta, 'iso':color_iso,'fenta':color_mmf,'awa':color_awake}
  33. # In[2]:
  34. from capipeline import *
  35. # ### Run the analysis
  36. # /media/andrey/My Passport/GIN/Anesthesia_CA1/validation/calcium_imaging
  37. # It creates a data frame *df_estimators* that contains basic information regarding stability of the recordings, such as
  38. #
  39. # - total number of identified neurons,
  40. # - traces and neuropils median inntensities for each ROI
  41. # - their standard deviation
  42. # - skewness of the signal
  43. # - estamation of their baseline (defined as a bottom quartile of signal intensities)
  44. # - their temporal stability (defined as the ratio between median signals of all ROIs in the first and the second parts of the recording)
  45. # In[5]:
  46. df_estimators = pd.DataFrame()
  47. for r in rec:
  48. Traces, Npils, n_accepted_and_rejected = traces_and_npils(r, database_path, concatenation=False)
  49. print("Shape: " + str(Traces.shape[0]) + " N_accept_reject: " + str(n_accepted_and_rejected))
  50. animal = get_animal_from_recording(r, database_path)
  51. condition = get_condition(r, database_path)
  52. print("#" + str(r) + " " + str(animal) + " " + str(condition) + " ")
  53. Traces_median = ma.median(Traces, axis=1)
  54. Npils_median = ma.median(Npils, axis=1)
  55. Traces_std = ma.std(Npils, axis=1)
  56. Npils_std = ma.std(Npils, axis=1)
  57. Traces_skewness = skew(Traces,axis=1)
  58. Npils_skewness = skew(Npils,axis=1)
  59. baseline = np.quantile(Traces,0.25,axis=1)
  60. num_cells = np.shape(Traces)[0]
  61. decay_isol = np.zeros((num_cells))
  62. fs = 30
  63. for neuron in np.arange(num_cells):
  64. if np.all(np.isnan(Traces[neuron])):
  65. decay_isol[neuron] = np.nan
  66. else:
  67. _, _, _, decay_neuron_isolated10, _ = deconvolve(np.double(Traces[neuron, ]),
  68. penalty = 0, optimize_g = 10)
  69. decay_isol[neuron] = - 1 / (fs * np.log(decay_neuron_isolated10))
  70. recording_length = int(Traces.shape[1])
  71. half = int(recording_length/2)
  72. print(recording_length)
  73. m1 = ma.median(Traces[:,:half])
  74. m2 = ma.median(Traces[:,half:])
  75. print("Stability:",m2/m1*100)
  76. norm_9000 = 9000/recording_length # normalize to 9000 frames (5 min recording)
  77. traces_median_half_vs_half = norm_9000*(m2-m1)*100/m1 + 100
  78. print("Stability (9000 frames normalization)",traces_median_half_vs_half)
  79. df_e = pd.DataFrame({ "animal":animal,
  80. "recording":r,
  81. "condition":condition,
  82. "number.neurons":Traces.shape[0],
  83. "traces.median":Traces_median,
  84. "npils.median":Npils_median,
  85. "traces.std":Traces_std,
  86. "npils.std":Npils_std,
  87. "traces.skewness":Traces_skewness,
  88. "npils.skewness":Npils_skewness,
  89. "decay":decay_isol,
  90. "baseline.quantile.25":baseline,
  91. "median.stability":traces_median_half_vs_half # in percent
  92. })
  93. df_estimators = pd.concat([df_estimators,df_e])
  94. print("*****")
  95. # ### Save the result of the analysis
  96. # In[7]:
  97. df_estimators.to_pickle("./calcium_imaging_stability_validation.pkl")
  98. # ### Load the result of the analysis
  99. # In[8]:
  100. df_estimators = pd.read_pickle("./calcium_imaging_stability_validation.pkl")
  101. df_estimators['neuronID'] = df_estimators.index
  102. df_estimators["animal_cat"] = df_estimators["animal"].astype("category")
  103. # ### Plot
  104. # In[9]:
  105. parameters = ["animal",'number.neurons','traces.median','traces.skewness','decay','median.stability']
  106. labels = ["Animal \n ID",'Extracted \n ROIs','Median, \n A.U.','Skewness','Decay time, \n s','1st/2nd \n ratio, %']
  107. number_subplots = len(parameters)
  108. #recordings_ranges = [[0,31],[32,55],[56,95],[96,133],[134,160],[161,188]]
  109. #recordings_ranges = [[0,55],[56,133],[134,188]]
  110. #recordings_ranges = [[0,133],[134,188]] #test
  111. recordings_ranges = [[0,188]]
  112. for rmin,rmax in recordings_ranges:
  113. f, axes = plt.subplots(number_subplots, 1, figsize=(8, 4.5)) # sharex=Truerex=True
  114. sns.despine(left=True)
  115. for i, param in enumerate(parameters):
  116. lw = 0.8
  117. #else:
  118. sns.boxplot(x='recording', y=param, data=df_estimators[(df_estimators.recording>=rmin)&(df_estimators.recording<=rmax)], width=0.9, dodge=False, showfliers = False,hue='condition', palette=custom_palette,ax=axes[i],linewidth=lw)
  119. if (i == 0):
  120. param = "animal_cat"
  121. print(np.unique(df_estimators[param]))
  122. axes[i].set_yticks(np.unique(df_estimators[param]))
  123. sns.swarmplot(x='recording', y=param, data=df_estimators[(df_estimators.recording>=rmin)&(df_estimators.recording<=rmax)&(df_estimators['neuronID'] == 0)],dodge=False, s=1, edgecolor='black', linewidth=1, hue='condition', palette=custom_palette, ax=axes[i])
  124. #ax.set(ylabel="")
  125. if i > 1:
  126. axes[i].set_ylim([0.0,2000.0])
  127. if i > 2:
  128. axes[i].set_ylim([0.0,10.0])
  129. if i > 3:
  130. axes[i].set_ylim([0.0,1.0])
  131. if i > 4:
  132. axes[i].set_ylim([80,120])
  133. axes[i].get_xaxis().set_visible(True)
  134. else:
  135. axes[i].get_xaxis().set_visible(False)
  136. if i < number_subplots-1:
  137. axes[i].xaxis.label.set_visible(False)
  138. if i==0:
  139. axes[i].set_title("Validation: stability check (recordings #%d-#%d)" % (rmin,rmax), fontsize=6, pad=20)
  140. axes[i].set_ylabel(labels[i], fontsize=8,labelpad=5)
  141. axes[i].set_xlabel("Recording", fontsize=8,labelpad=5)
  142. #axes[i].axis('off')
  143. axes[i].xaxis.set_tick_params(labelsize=6)
  144. axes[i].yaxis.set_tick_params(labelsize=6)
  145. axes[i].get_legend().remove()
  146. axes[i].xaxis.set_major_locator(ticker.MultipleLocator(20))
  147. axes[i].xaxis.set_major_formatter(ticker.ScalarFormatter())
  148. #plt.legend(loc='upper right',fontsize=8)
  149. #plt.legend(bbox_to_anchor=(1.01, 1), loc=2, borderaxespad=0.,fontsize=9)
  150. plt.savefig("Validation_stability_check_rec_#%d-#%d).png" % (rmin,rmax),dpi=300)
  151. plt.savefig("Validation_stability_check_rec_#%d-#%d).svg" % (rmin,rmax))
  152. #plt.show()
  153. # In[13]:
  154. sns.displot(data=df_estimators, x="median.stability", hue = 'condition',palette=custom_palette, kind="kde")
  155. plt.xlim([80,120])
  156. plt.xlabel("Stability, %", fontsize = 25)
  157. plt.title("Validation: summary on stability (recordings #%d-#%d)" % (min(rec),max(rec)), fontsize = 20, pad=20)
  158. plt.grid(False)
  159. plt.savefig("Validation_summary_stability_recordings_#%d-#%d)" % (min(rec),max(rec)))
  160. #plt.show()
  161. # In[62]:
  162. df_estimators["median.stability"].describe()