septum-mec/actions/stimulus-spike-lfp-response.../data/10-calculate-stimulus-spike...

968 lines
215 KiB
Plaintext
Raw Permalink Normal View History

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Calculate spike-lfp coherence using other tetrode in same drive"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%load_ext autoreload\n",
"%autoreload 2"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"%matplotlib inline\n",
"import spatial_maps as sp\n",
"import septum_mec.analysis.data_processing as dp\n",
"import septum_mec.analysis.registration\n",
"import expipe\n",
"import os\n",
"import pathlib\n",
"import scipy\n",
"import scipy.signal\n",
"import numpy as np\n",
"import exdir\n",
"import pandas as pd\n",
"import optogenetics as og\n",
"import quantities as pq\n",
"import shutil\n",
"from distutils.dir_util import copy_tree\n",
"import elephant as el\n",
"import neo\n",
"from scipy.signal import find_peaks\n",
"from scipy.interpolate import interp1d\n",
"from matplotlib import mlab\n",
"\n",
"from tqdm import tqdm_notebook as tqdm\n",
"from tqdm._tqdm_notebook import tqdm_notebook\n",
"tqdm_notebook.pandas()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data_loader = dp.Data()\n",
"actions = data_loader.actions\n",
"project = data_loader.project"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"output = pathlib.Path('output/stimulus-spike-lfp-response-other-tetrode')\n",
"(output / 'data').mkdir(parents=True, exist_ok=True)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"identify_neurons = actions['identify-neurons']\n",
"# sessions = pd.read_csv(identify_neurons.data_path('sessions'))\n",
"units = pd.read_csv(identify_neurons.data_path('units'))"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"def get_lim(action_id):\n",
" stim_times = data_loader.stim_times(action_id)\n",
" if stim_times is None:\n",
" return [0, np.inf]\n",
" stim_times = np.array(stim_times)\n",
" return [stim_times.min(), stim_times.max()]\n",
"\n",
"def get_mask(lfp, lim):\n",
" return (lfp.times >= lim[0]) & (lfp.times <= lim[1])\n",
"\n",
"def zscore(a):\n",
" return (a - a.mean(0)) / a.std(0)\n",
"\n",
"def compute_stim_freq(action_id):\n",
" stim_times = data_loader.stim_times(action_id)\n",
" if stim_times is None:\n",
" return np.nan\n",
" stim_times = np.array(stim_times)\n",
" return 1 / np.mean(np.diff(stim_times))"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"def signaltonoise(a, axis=0, ddof=0):\n",
" a = np.asanyarray(a)\n",
" m = a.mean(axis)\n",
" sd = a.std(axis=axis, ddof=ddof)\n",
" return np.where(sd == 0, 0, m / sd)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"def compute_energy(p, f, f1, f2):\n",
" if np.isnan(f1) or np.all(np.isnan(p)):\n",
" return np.nan\n",
" mask = (f > f1) & (f < f2)\n",
" df = f[1] - f[0]\n",
" return np.sum(p[mask]) * df"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"def find_theta_peak(p, f, f1, f2):\n",
" if np.all(np.isnan(p)):\n",
" return np.nan, np.nan\n",
" mask = (f > f1) & (f < f2)\n",
" p_m = p[mask]\n",
" f_m = f[mask]\n",
" peaks, _ = find_peaks(p_m)\n",
" idx = np.argmax(p_m[peaks])\n",
" return f_m[peaks[idx]], p_m[peaks[idx]]"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"def compute_half_width(p, f, m_p, m_f):\n",
" if np.isnan(m_p):\n",
" return np.nan, np.nan\n",
" m_p_half = m_p / 2\n",
" half_p = p - m_p_half\n",
" idx_f = np.where(f <= m_f)[0].max()\n",
" idxs_p1, = np.where(np.diff(half_p[:idx_f + 1] > 0) == 1)\n",
" if len(idxs_p1) == 0:\n",
" return np.nan, np.nan\n",
" m1 = idxs_p1.max()\n",
" idxs_p2, = np.where(np.diff(half_p[idx_f:] > 0) == 1)\n",
" m2 = idxs_p2.min() + idx_f\n",
" assert p[m1] < m_p_half < p[m1+1], (p[m1], m_p_half, p[m1+1])\n",
" assert p[m2] > m_p_half > p[m2+1], (p[m2], m_p_half, p[m2+1])\n",
" \n",
" f1 = interp1d([half_p[m1], half_p[m1 + 1]], [f[m1], f[m1 + 1]])(0)\n",
" f2 = interp1d([half_p[m2], half_p[m2 + 1]], [f[m2], f[m2 + 1]])(0)\n",
" return f1, f2"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"# p = np.load('debug_p.npy')\n",
"# f = np.load('debug_f.npy')\n",
"# compute_half_width(p, f, 0.01038941, 30.30187709636872)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"# plt.plot(f, p)\n",
"# plt.xlim(29.9,30.6)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"def compute_stim_peak(p, f, s_f):\n",
" if np.isnan(s_f):\n",
" return np.nan\n",
" return interp1d(f, p)(s_f)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"def compute_spike_lfp_coherence(anas, sptr, NFFT):\n",
"\n",
" sigs, freqs = el.sta.spike_field_coherence(anas, sptr, **{'nperseg': NFFT})\n",
" return sigs, freqs"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"def butter_bandpass(lowcut, highcut, fs, order=5):\n",
" nyq = 0.5 * fs\n",
" low = lowcut / nyq\n",
" high = highcut / nyq\n",
" b, a = scipy.signal.butter(order, [low, high], btype='band')\n",
" return b, a\n",
"\n",
"\n",
"def butter_bandpass_filter(data, lowcut, highcut, fs, order=5):\n",
" b, a = butter_bandpass(lowcut, highcut, fs, order=order)\n",
" y = scipy.signal.filtfilt(b, a, data)\n",
" return y\n",
"\n",
"# def compute_spike_phase_func(lfp, times, return_degrees=False):\n",
"# x_a = hilbert(lfp)\n",
"# x_phase = np.angle(x_a)\n",
"# if return_degrees:\n",
"# x_phase = x_phase * 180 / np.pi\n",
"# return interp1d(times, x_phase)\n",
"\n",
"\n",
"def vonmises_kde(data, kappa=100, n_bins=100):\n",
" from scipy.special import i0\n",
" bins = np.linspace(-np.pi, np.pi, n_bins)\n",
" x = np.linspace(-np.pi, np.pi, n_bins)\n",
" # integrate vonmises kernels\n",
" kde = np.exp(kappa * np.cos(x[:, None] - data[None, :])).sum(1) / (2 * np.pi * i0(kappa))\n",
" kde /= np.trapz(kde, x=bins)\n",
" return bins, kde\n",
"\n",
"\n",
"def spike_phase_score(phase_bins, density):\n",
" import math\n",
" import pycircstat as pc\n",
" ang = pc.mean(phase_bins, w=density)\n",
" vec_len = pc.resultant_vector_length(phase_bins, w=density)\n",
" # ci_lim = pc.mean_ci_limits(head_angle_bins, w=rate)\n",
" return ang, vec_len"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [],
"source": [
"def compute_clean_lfp(anas, width=500, threshold=2):\n",
" anas = np.array(anas)\n",
" idxs, = np.where(abs(anas) > threshold)\n",
" for idx in idxs:\n",
" anas[idx-width:idx+width] = 0 # TODO AR model prediction\n",
" return anas, idxs\n",
"\n",
"\n",
"def compute_clean_spikes(spikes, idxs, times, width=500):\n",
"\n",
" for idx in idxs:\n",
" t0 = times[idx-width]\n",
" stop = idx + width\n",
" if stop > len(times) - 1:\n",
" stop = len(times) - 1 \n",
" t1 = times[stop]\n",
" mask = (spikes > t0) & (spikes < t1)\n",
" spikes = spikes[~mask]\n",
" spikes = spikes[spikes <= times[-1]]\n",
" return spikes\n",
"\n",
"\n",
"def prepare_spike_lfp(anas, sptr, t_start, t_stop):\n",
" t_start = t_start * pq.s if t_start is not None else 0 * pq.s\n",
" sampling_rate = anas.sampling_rate\n",
" units = anas.units\n",
" times = anas.times\n",
" if t_start is not None and t_stop is not None:\n",
" t_stop = t_stop * pq.s\n",
" mask = (times > t_start) & (times < t_stop)\n",
" anas = np.array(anas)[mask,:]\n",
" times = times[mask]\n",
" \n",
" # take best channel from other drive\n",
" best_channel = np.argmax(signaltonoise(anas))\n",
"# best_channel = np.random.choice(anas.shape[1])\n",
" \n",
" cleaned_anas, idxs = compute_clean_lfp(anas[:, best_channel])\n",
" \n",
" cleaned_anas = neo.AnalogSignal(\n",
" signal=cleaned_anas * units, sampling_rate=sampling_rate, t_start=t_start\n",
" )\n",
" \n",
" spike_units = sptr.units\n",
" spike_times = sptr.times\n",
" spike_times = compute_clean_spikes(spike_times, idxs, times)\n",
"\n",
" sptr = neo.SpikeTrain(\n",
" spike_times[(spike_times > t_start) & (spike_times < times[-1])], units=spike_units,\n",
" t_start=t_start, t_stop=times[-1]\n",
" )\n",
"\n",
" return cleaned_anas, sptr, best_channel"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"def compute_spike_phase_func(lfp, times, return_degrees=False):\n",
" from scipy.fftpack import next_fast_len\n",
" x_a = scipy.signal.hilbert(\n",
" lfp, next_fast_len(len(lfp)))[:len(lfp)]\n",
"# x_a = hilbert(lfp)\n",
" x_phase = np.angle(x_a, deg=return_degrees)\n",
" return interp1d(times, x_phase)\n",
"\n",
"\n",
"def compute_spike_phase(lfp, spikes, flim=[6,10]):\n",
" \n",
" sample_rate = lfp.sampling_rate.magnitude\n",
" \n",
" # sometimes the position is recorded after LFP recording is ended\n",
" times = np.arange(lfp.shape[0]) / sample_rate\n",
" \n",
" spikes = np.array(spikes)\n",
" spikes = spikes[(spikes > times.min()) & (spikes < times.max())]\n",
" \n",
" filtered_lfp = butter_bandpass_filter(\n",
" lfp.magnitude.ravel(), *flim, fs=sample_rate, order=3)\n",
"\n",
" spike_phase_func = compute_spike_phase_func(filtered_lfp, times)\n",
" \n",
" return spike_phase_func(spikes), filtered_lfp"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(0, 100)"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1152x648 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1152x648 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.figure(figsize=(16,9))\n",
"lfp = data_loader.lfp('1833-200619-2', 6)\n",
"# lfp = data_loader.lfp('1834-220319-3', 6)\n",
"# lfp = data_loader.lfp('1849-010319-4', 6)\n",
"times = np.arange(lfp.shape[0]) / lfp.sampling_rate.magnitude\n",
"clean_lfp, _ = compute_clean_lfp(lfp.magnitude[:, 0], threshold=2)\n",
"plt.plot(times,lfp[:,0])\n",
"plt.plot(times,clean_lfp)\n",
"\n",
"plt.figure(figsize=(16,9))\n",
"plt.psd(lfp[:,0].ravel(), Fs=1000, NFFT=10000)\n",
"plt.psd(clean_lfp, Fs=1000, NFFT=10000)\n",
"plt.xlim(0,100)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"# plt.figure(figsize=(16,9))\n",
"\n",
"# plt.plot(times,lfp[:,0])\n",
"# # plt.plot(clean_lfp*100)\n",
"# plt.plot(times[:-1], np.diff(lfp[:,0].magnitude.ravel()))\n",
"# plt.xlim(64.5,65.5)\n",
"# # plt.ylim(-250,250)"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [],
"source": [
"drive_0_channel_groups = [0, 1, 2, 3]\n",
"drive_1_channel_groups = [4, 5, 6, 7]"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x7fbc6cf0ef60>]"
]
},
"execution_count": 49,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# action_id_0, channel_0, unit_0 = '1833-200619-1', 6, 163\n",
"# action_id_1, channel_1, unit_1 = '1833-200619-2', 6, 28\n",
"action_id_0, channel_0, unit_0 = '1834-220319-3', 2, 46\n",
"action_id_1, channel_1, unit_1 = '1834-220319-4', 2, 60\n",
" \n",
"\n",
"# lfp_0 = data_loader.lfp(action_id_0, channel_0)\n",
"# lfp_1 = data_loader.lfp(action_id_1, channel_1)\n",
"\n",
"# select best channel among other tetrodes in same drive\n",
"if channel_0 in drive_0_channel_groups:\n",
" lfps = []\n",
" for ch in drive_0_channel_groups:\n",
" if channel_0 != ch:\n",
" lfps.append(data_loader.lfp(action_id_0, ch))\n",
"elif channel_0 in drive_1_channel_groups:\n",
" lfps = []\n",
" for ch in drive_1_channel_groups:\n",
" if channel_0 != ch:\n",
" lfps.append(data_loader.lfp(action_id_0, ch))\n",
"lfps_0 = np.hstack(lfps)\n",
"\n",
"if channel_1 in drive_0_channel_groups:\n",
" lfps = []\n",
" for ch in drive_0_channel_groups:\n",
" if channel_1 != ch:\n",
" lfps.append(data_loader.lfp(action_id_1, ch))\n",
"elif channel_1 in drive_1_channel_groups:\n",
" lfps = []\n",
" for ch in drive_1_channel_groups:\n",
" if channel_1 != ch:\n",
" lfps.append(data_loader.lfp(action_id_0, ch))\n",
"lfps_1 = np.hstack(lfps)\n",
"\n",
"sample_rate_0 = lfp_0.sampling_rate\n",
"sample_rate_1 = lfp_1.sampling_rate\n",
"\n",
"lim_0 = get_lim(action_id_0)\n",
"lim_1 = get_lim(action_id_1)\n",
"\n",
"sptrs_0 = data_loader.spike_trains(action_id_0, channel_0)\n",
"\n",
"sptrs_1 = data_loader.spike_trains(action_id_1, channel_1)\n",
"\n",
"cleaned_lfps_0, sptr_0, best_channel_0 = prepare_spike_lfp(lfp_0, sptrs_0[unit_0], *lim_0)\n",
"\n",
"cleaned_lfps_1, sptr_1, best_channel_1 = prepare_spike_lfp(lfp_1, sptrs_1[unit_1], *lim_1)\n",
"\n",
"coher_0, freq_0 = compute_spike_lfp_coherence(cleaned_lfps_0, sptr_0, 4096)\n",
"\n",
"coher_1, freq_1 = compute_spike_lfp_coherence(cleaned_lfps_1, sptr_1, 4096)\n",
"\n",
"spike_phase_0, filtered_lfp_0 = compute_spike_phase(cleaned_lfps_0, sptrs_0[unit_0], flim=[6,10])\n",
"\n",
"spike_phase_1, filtered_lfp_1 = compute_spike_phase(cleaned_lfps_1, sptrs_1[unit_1], flim=[6,10])\n",
"\n",
"spike_phase_1_stim, filtered_lfp_1_stim = compute_spike_phase(cleaned_lfps_1, sptrs_1[unit_1], flim=[10.5,11.5])\n",
"# spike_phase_1_stim, filtered_lfp_1_stim = compute_spike_phase(cleaned_lfps_1, sptrs_1[unit_1], flim=[29.5,30.5])\n",
"\n",
"plt.figure()\n",
"plt.plot(freq_0, coher_0.ravel())\n",
"plt.plot(freq_1, coher_1.ravel())\n",
"plt.xlim(0,20)\n",
"\n",
"plt.figure()\n",
"bins_0, kde_0 = vonmises_kde(spike_phase_0, 100)\n",
"ang_0, vec_len_0 = spike_phase_score(bins_0, kde_0)\n",
"plt.polar(bins_0, kde_0, color='b')\n",
"plt.polar([ang_0, ang_0], [0, vec_len_0], color='b')\n",
"\n",
"bins_1, kde_1 = vonmises_kde(spike_phase_1, 100)\n",
"ang_1, vec_len_1 = spike_phase_score(bins_1, kde_1)\n",
"plt.polar(bins_1, kde_1, color='r')\n",
"plt.polar([ang_1, ang_1], [0, vec_len_1], color='r')\n",
"\n",
"bins_1_stim, kde_1_stim = vonmises_kde(spike_phase_1_stim, 100)\n",
"ang_1_stim, vec_len_1_stim = spike_phase_score(bins_1_stim, kde_1_stim)\n",
"plt.polar(bins_1_stim, kde_1_stim, color='k')\n",
"plt.polar([ang_1_stim, ang_1_stim], [0, vec_len_1_stim], color='k')"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array(1.) * mV"
]
},
"execution_count": 57,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"lfp_0.units"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 2\n",
"1 2\n",
"3 2\n"
]
}
],
"source": [
"if channel_0 in drive_0_channel_groups:\n",
" lfps = []\n",
" for ch in drive_0_channel_groups:\n",
" if channel_0 != ch:\n",
" lfps.append(data_loader.lfp(action_id_0, ch))\n",
"elif channel_0 in drive_1_channel_groups:\n",
" lfps = []\n",
" for ch in drive_1_channel_groups:\n",
" if channel_0 != ch:\n",
" lfps.append(data_loader.lfp(action_id_0, ch))\n",
"lfps_0 = np.hstack(lfps)\n",
"\n",
"if channel_1 in drive_0_channel_groups:\n",
" lfps = []\n",
" for ch in drive_0_channel_groups:\n",
" if channel_1 != ch:\n",
" lfps.append(data_loader.lfp(action_id_1, ch))\n",
"elif channel_1 in drive_1_channel_groups:\n",
" lfps = []\n",
" for ch in drive_1_channel_groups:\n",
" if channel_1 != ch:\n",
" lfps.append(data_loader.lfp(action_id_0, ch))\n",
"lfps_1 = np.hstack(lfps)"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(908442, 12)"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"lfps.shape"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(2725326, 4)"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"lfps.shape"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"# TODO fix artefact stuff from phase precession"
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [],
"source": [
"NFFT = 8192\n",
"theta_band_f1, theta_band_f2 = 6, 10 \n",
"drive_0_channel_groups = [0, 1, 2, 3]\n",
"drive_1_channel_groups = [4, 5, 6, 7]"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [],
"source": [
"coherence_data, freqency_data = {}, {}\n",
"theta_kde_data, theta_bins_data = {}, {}\n",
"stim_kde_data, stim_bins_data = {}, {}\n",
"\n",
"def process(row):\n",
" action_id = row['action']\n",
" channel_group = row['channel_group']\n",
" unit_name = row['unit_name']\n",
" \n",
" name = f'{action_id}_{channel_group}_{unit_name}'\n",
" \n",
" # select best channel among other tetrodes in same drive\n",
" if channel_group in drive_0_channel_groups:\n",
" lfps = []\n",
" for ch in drive_0_channel_groups:\n",
" if channel_group != ch:\n",
" lfps.append(data_loader.lfp(action_id, ch))\n",
" elif channel_group in drive_1_channel_groups:\n",
" lfps = []\n",
" for ch in drive_1_channel_groups:\n",
" if channel_group != ch:\n",
" lfps.append(data_loader.lfp(action_id, ch))\n",
" \n",
" # merge lfp of other tetrodes into a signle AnalogSignal\n",
" lfp_arrays = np.hstack(lfps).as_array()\n",
" lfp = neo.AnalogSignal(signal=lfp_arrays * lfps[0].units, sampling_rate=lfps[0].sampling_rate,\n",
" t_start=lfps[0].t_start)\n",
" \n",
" sptr = data_loader.spike_train(action_id, channel_group, unit_name)\n",
" \n",
" lim = get_lim(action_id)\n",
" \n",
" cleaned_lfp, sptr, best_channel = prepare_spike_lfp(lfp, sptr, *lim)\n",
" \n",
" p_xys, freq = compute_spike_lfp_coherence(cleaned_lfp, sptr, NFFT=NFFT)\n",
" \n",
" p_xy = p_xys.magnitude.ravel()\n",
" freq = freq.magnitude\n",
" \n",
" theta_f, theta_p_max = find_theta_peak(p_xy, freq, theta_band_f1, theta_band_f2)\n",
" \n",
" theta_energy = compute_energy(p_xy, freq, theta_band_f1, theta_band_f2) # theta band 6 - 10 Hz\n",
" \n",
" theta_half_f1, theta_half_f2 = compute_half_width(p_xy, freq, theta_p_max, theta_f)\n",
" \n",
" theta_half_width = theta_half_f2 - theta_half_f1\n",
" \n",
" theta_half_energy = compute_energy(p_xy, freq, theta_half_f1, theta_half_f2) # theta band 6 - 10 Hz\n",
" \n",
" theta_spike_phase, _ = compute_spike_phase(cleaned_lfp, sptr, flim=[theta_band_f1, theta_band_f2])\n",
" theta_bins, theta_kde = vonmises_kde(theta_spike_phase)\n",
" theta_ang, theta_vec_len = spike_phase_score(theta_bins, theta_kde)\n",
" theta_kde_data.update({name: theta_kde})\n",
" theta_bins_data.update({name: theta_bins})\n",
"\n",
" # stim\n",
" \n",
" stim_freq = compute_stim_freq(action_id)\n",
" \n",
" stim_p_max = compute_stim_peak(p_xy, freq, stim_freq)\n",
" \n",
" stim_half_f1, stim_half_f2 = compute_half_width(p_xy, freq, stim_p_max, stim_freq)\n",
" stim_half_width = stim_half_f2 - stim_half_f1\n",
" \n",
" stim_energy = compute_energy(p_xy, freq, stim_half_f1, stim_half_f2)\n",
" \n",
" if np.isnan(stim_freq):\n",
" stim_spike_phase, stim_bins, stim_kde, stim_ang, stim_vec_len = [np.nan] * 5\n",
" else:\n",
" stim_spike_phase, _ = compute_spike_phase(cleaned_lfp, sptr, flim=[stim_freq - .5, stim_freq + .5])\n",
" stim_bins, stim_kde = vonmises_kde(stim_spike_phase)\n",
" stim_ang, stim_vec_len = spike_phase_score(stim_bins, stim_kde)\n",
" stim_kde_data.update({name: stim_kde})\n",
" stim_bins_data.update({name: stim_bins})\n",
" \n",
" coherence_data.update({name: p_xy})\n",
" freqency_data.update({name: freq})\n",
" \n",
" result = pd.Series({\n",
" 'best_channel': best_channel,\n",
" 'theta_freq': theta_f,\n",
" 'theta_peak': theta_p_max,\n",
" 'theta_energy': theta_energy,\n",
" 'theta_half_f1': theta_half_f1, \n",
" 'theta_half_f2': theta_half_f2,\n",
" 'theta_half_width': theta_half_width,\n",
" 'theta_half_energy': theta_half_energy,\n",
" 'theta_ang': theta_ang, \n",
" 'theta_vec_len': theta_vec_len,\n",
" 'stim_freq': stim_freq,\n",
" 'stim_p_max': stim_p_max,\n",
" 'stim_half_f1': stim_half_f1, \n",
" 'stim_half_f2': stim_half_f2,\n",
" 'stim_half_width': stim_half_width,\n",
" 'stim_energy': stim_energy,\n",
" 'stim_ang': stim_ang, \n",
" 'stim_vec_len': stim_vec_len\n",
" })\n",
" return result"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "6d041e5a55f04f7aaac43018c589217a",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HBox(children=(IntProgress(value=0, max=1284), HTML(value='')))"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/mikkel/.virtualenvs/expipe/lib/python3.6/site-packages/scipy/signal/spectral.py:1577: RuntimeWarning: invalid value encountered in true_divide\n",
" Cxy = np.abs(Pxy)**2 / Pxx / Pyy\n",
"/home/mikkel/.virtualenvs/expipe/lib/python3.6/site-packages/ipykernel_launcher.py:28: RuntimeWarning: invalid value encountered in true_divide\n"
]
}
],
"source": [
"results = units.merge(\n",
" units.progress_apply(process, axis=1), \n",
" left_index=True, right_index=True)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"# coher, freqs = {}, {}\n",
"# for i, row in tqdm(units.iterrows(), total=len(units)):\n",
"# action_id = row['action']\n",
"# channel_group = row['channel_group']\n",
"# unit_name = row['unit_name']\n",
" \n",
"# name = f'{action_id}_{channel_group}_{unit_name}'\n",
" \n",
"# lfp = data_loader.lfp(action_id, channel_group) # TODO consider choosing strongest stim response\n",
" \n",
"# sptr = data_loader.spike_train(action_id, channel_group, unit_name)\n",
" \n",
"# lim = get_lim(action_id)\n",
"\n",
"# p_xys, freq, clean_lfp = compute_spike_lfp(lfp, sptr, *lim, NFFT=NFFT)\n",
" \n",
"# snls = signaltonoise(clean_lfp)\n",
"# best_channel = np.argmax(snls)\n",
"# snl = snls[best_channel]\n",
"# p_xy = p_xys[:,best_channel].magnitude\n",
"# freq = freq.magnitude\n",
" \n",
"# coher.update({name: p_xy})\n",
"# freqs.update({name: freq})"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"pd.DataFrame(coherence_data).to_feather(output / 'data' / 'coherence.feather')\n",
"pd.DataFrame(freqency_data).to_feather(output / 'data' / 'freqs.feather')\n",
"pd.DataFrame(theta_kde_data).to_feather(output / 'data' / 'theta_kde.feather')\n",
"pd.DataFrame(theta_bins_data).to_feather(output / 'data' / 'theta_bins.feather')\n",
"pd.DataFrame(stim_kde_data).to_feather(output / 'data' / 'stim_kde.feather')\n",
"pd.DataFrame(stim_bins_data).to_feather(output / 'data' / 'stim_bins.feather')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Save to expipe"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"action = project.require_action(\"stimulus-spike-lfp-response-other-tetrode\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"action.modules['parameters'] = {\n",
" 'NFFT': NFFT,\n",
" 'theta_band_f1': theta_band_f1,\n",
" 'theta_band_f2': theta_band_f2\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"action.data['results'] = 'results.csv'\n",
"results.to_csv(action.data_path('results'), index=False)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"copy_tree(output, str(action.data_path()))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"septum_mec.analysis.registration.store_notebook(action, \"10-calculate-stimulus-spike-lfp-response-other-tetrode.ipynb\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.8"
}
},
"nbformat": 4,
"nbformat_minor": 4
}