Upload files to ''

This commit is contained in:
jacquelinegoebl 2021-07-16 12:07:52 +02:00
parent 3336201c90
commit b810e4bd77
5 changed files with 2408 additions and 0 deletions

152
do_make_pancake.py Normal file
View File

@ -0,0 +1,152 @@
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from IPython import embed
import helper_functions as hf
import os
import datetime
import time
import pandas as pd
if __name__ == '__main__':
###################################################################################################################
# load data
###################################################################################################################
# load all the data of one day
start = time.time()
filename = sorted(os.listdir('../../../data/'))[6]
ident = np.load('../../../data/'+filename+'/all_ident_v.npy', allow_pickle=True)
power = np.load('../../../data/'+filename+'/all_sign_v.npy', allow_pickle=True)
freq = np.load('../../../data/'+filename+'/all_fund_v.npy', allow_pickle=True)
timeidx = np.load('../../../data/'+filename+'/all_idx_v.npy', allow_pickle=True)
realtime = np.load('../../../data/'+filename+'/all_times.npy', allow_pickle=True)
temp = pd.read_csv('../../../data/' + filename + '/temperatures.csv', sep=';')
temp_l = np.array(temp.values.tolist())
aifl = np.load('../data/'+filename+'/aifl2.npy', allow_pickle=True)
end = time.time()
print(end - start)
###################################################################################################################
# parameter and variables
###################################################################################################################
# lists
fish_in_aifl = list(np.unique(np.where(~np.isnan(aifl[:, :, 0]))[1]))
# variables and empty lists
sampling_rate = 1 / np.diff(realtime)[0] # in sec
# ipp
power_means = []
all_ipp = []
all_xtickses = []
all_run_mean = []
all_run_std = []
all_Ctime_gesamt = []
all_max_ch = []
all_hms = []
thresholds = np.full(3, np.nan)
###################################################################################################################
# analysis
###################################################################################################################
for fish_number in fish_in_aifl:
###############################################################################################################
# power cube: 1 dim: different channel for different traces
# 2 dim: time dimension
# 3 dim: again channel but in this direction the power of the traces of one channel are written into
power_cube = np.full([16, len(realtime), 16], np.nan)
for channel in range(16):
fish_IDs = aifl[channel, fish_number, ~np.isnan(aifl[channel, fish_number])]
for len_idx1 in range(len(fish_IDs)):
ID = fish_IDs[len_idx1]
t = timeidx[channel][ident[channel] == ID]
p = power[channel][ident[channel] == ID]
power_cube[channel, t] = p
###############################################################################################################
# interpolated power pancake = ipp, heatmap of the trajectory of the fish over the time (2 dimension) and
# channels (1. dimension)
power_pancake = np.nanmax(power_cube, axis=0)
Ctime = realtime[~np.isnan(power_pancake[:, 0])]
all_Ctime = realtime[int(np.where(realtime == Ctime[0])[0]):int(np.where(realtime == Ctime[-1])[0] + 1)]
Cpancake = power_pancake[~np.isnan(power_pancake[:, 0])]
try:
ipp = np.array(list(map(lambda x: np.interp(all_Ctime, Ctime, x), Cpancake.T))).T
except:
continue
all_ipp.append(ipp)
all_Ctime_gesamt.append(all_Ctime)
###############################################################################################################
# trajectories (channel) of the fish over time by using the maximum power on each time point
max_ch = np.argmax(ipp, axis=1)
all_max_ch.append(max_ch)
###############################################################################################################
# power means of each fish
power_means.append(np.mean(ipp[range(len(max_ch)), max_ch]))
###############################################################################################################
# all x ticks of the fish in datetime format
datetime_v = []
# hour minutes seconds vector
hms = []
dt = datetime.datetime.strptime(filename[-5:], '%H_%M')
for i in list(np.arange(int(np.where(realtime == Ctime[0])[0]), int(np.where(realtime == Ctime[-1])[0] + 1))):
current_time = dt + datetime.timedelta(seconds=realtime[i]) # converts the time point in datetime points
datetime_v.append(current_time)
hms.append(current_time.hour * 60 * 60 + current_time.minute * 60 + current_time.second +
float('0.' + str(current_time.microsecond))) # converts the time points into a second format
x_tickses = mdates.date2num(datetime_v)
all_xtickses.append(x_tickses)
all_hms.append(np.array(hms))
###############################################################################################################
# running mean and std
# run_mean, run_std = hf.running_3binsizes(ipp, sampling_rate)
# TODO: not absolute max, instead average of the three strongest channel
# bin_size = int(np.floor((Ctime[-1]-Ctime[0])/50))
#
# max_ch_mean = np.full([len(max_ch)], np.nan)
# for i in range(int(len(max_ch)-np.floor(bin_size))):
# max_ch_mean[int(i + np.floor(bin_size / 2))] = np.mean(max_ch[i:bin_size + i])
# all_run_mean.append(run_mean)
# all_run_std.append(run_std)
###############################################################################################################
# threshold for the activity -- OUT DATED!!!!!!
# rs = np.array(all_run_std)
#
# for idx in range(3):
# rs1 = np.hstack(rs[:, idx])
# rs1 = rs1[~np.isnan(rs1)]
# rs1 = rs1[rs1>0]
# print(np.percentile(rs1, [5, 95, 50]))
# thresholds[idx] = np.percentile(rs1, 50)
###################################################################################################################
# save
###################################################################################################################
if filename not in os.listdir('../data/'):
os.mkdir('../data/'+filename)
np.save('../data/' + filename + '/all_Ctime_v.npy', all_Ctime_gesamt)
np.save('../data/' + filename + '/all_max_ch.npy', all_max_ch)
# np.save('../data/' + filename + '/all_run_mean.npy', all_run_mean)
# np.save('../data/' + filename + '/all_run_std.npy', all_run_std)
# np.save('../data/' + filename + '/thresholds.npy', thresholds)
np.save('../data/' + filename + '/all_xtickses.npy', all_xtickses)
np.save('../data/' + filename + '/all_ipp.npy', all_ipp)
np.save('../data/' + filename + '/power_means.npy', power_means)
np.save('../data/' + filename + '/all_hms.npy', all_hms)
embed()
quit()

143
do_match_eod_waveform.py Normal file
View File

@ -0,0 +1,143 @@
import sys
import os
import numpy as np
from tqdm import tqdm
import matplotlib.pyplot as plt
from thunderfish.dataloader import open_data
from thunderfish.eodanalysis import eod_waveform
from IPython import embed
import matplotlib.gridspec as gridspec
def plot_mean_eod(EOD, fish_number, ax):
ax.plot(EOD.T[0], EOD.T[1], color='firebrick', lw=2)
ax.fill_between(EOD.T[0], EOD.T[1] + EOD.T[2],
EOD.T[1] - EOD.T[2],
color='firebrick', alpha=0.7)
def calc_mean_eod(t0, f, data, dt = 10):
channel_list = np.arange(data.channels)
samplerate = data.samplerate
start_i = t0 * samplerate
end_i = t0 * samplerate + dt * samplerate + 1
t = np.arange(0, dt, 1 / f)
mean_EODs = []
for c in channel_list:
mean_eod, eod_times = eod_waveform(data[start_i:end_i, c], samplerate, t)
# TODO: unfilter function
mean_EODs.append(mean_eod)
max_size = list(map(lambda x: np.max(x.T[1]) - np.min(x.T[1]), mean_EODs))
EOD = mean_EODs[np.argmax(max_size)]
return EOD
def main(folder, filename):
# folder = path_to_files
data = open_data(os.path.join(folder, 'traces-grid1.raw'), -1, 60.0, 10.0)
power_means = np.load('../data/' + filename + '/power_means.npy', allow_pickle=True)
all_q10 = np.load('../data/' + filename + '/fish_freq_q10.npy', allow_pickle=True)
all_t = np.load('../data/' + filename + '/eod_times_new_new.npy', allow_pickle=True)
all_f = np.load('../data/' + filename + '/eod_freq_new_new.npy', allow_pickle=True)
# all_fish = np.load('../data/' + filename + '/eod_fishnumber.npy', allow_pickle=True)
name = []
for fish_number in range(len(power_means)):
# print('fish:' + fish_number)
if 400 <= all_q10[fish_number, 2] <= 600:
# print(len(all_t[fish_number]))
fig = plt.figure(constrained_layout=True)
gs_pic = np.sqrt(len(all_t[fish_number]))
gs = gridspec.GridSpec(int(np.ceil(gs_pic)), int(np.ceil(gs_pic)), figure=fig)
# max_std = []
# EODs = []
c = 0
for t, f in zip(all_t[fish_number], all_f[fish_number]):
EOD = calc_mean_eod(t, f, data)
ax = fig.add_subplot(gs[c])
ax.plot(EOD.T[0], EOD.T[1], color='firebrick', lw=2)
ax.fill_between(EOD.T[0], EOD.T[1] + EOD.T[2],
EOD.T[1] - EOD.T[2],
color='firebrick', alpha=0.7)
ax.set_xticks([])
ax.set_yticks([])
fig.add_subplot(ax)
c+=1
fig.suptitle(all_q10[fish_number, 2])
plt.show()
in_str = input('Which fish? 1 = Eigen, 2 = Apt')
if in_str == '1':
name.append('Eigenmannia')
elif in_str == '2':
name.append('Apteronotus')
else:
name.append('unknown')
elif all_q10[fish_number, 2] < 500:
name.append('Eigenmannia')
elif all_q10[fish_number, 2] > 600:
name.append('Apteronotus')
return name
def plot_eod_for_material_and_methods(folder, filename):
data = open_data(os.path.join(folder, 'traces-grid1.raw'), -1, 60.0, 10.0)
power_means = np.load('../data/' + filename + '/power_means.npy', allow_pickle=True)
all_q10 = np.load('../data/' + filename + '/fish_freq_q10.npy', allow_pickle=True)
all_t = np.load('../data/' + filename + '/eod_times_new_new.npy', allow_pickle=True)
all_f = np.load('../data/' + filename + '/eod_freq_new_new.npy', allow_pickle=True)
# all_fish = np.load('../data/' + filename + '/eod_fishnumber.npy', allow_pickle=True)
name = []
for fish_number in range(len(power_means)):
# print('fish:' + fish_number)
if 400 <= all_q10[fish_number, 2] <= 600:
# print(len(all_t[fish_number]))
fig = plt.figure(constrained_layout=True)
gs_pic = np.sqrt(len(all_t[fish_number]))
gs = gridspec.GridSpec(int(np.ceil(gs_pic)), int(np.ceil(gs_pic)), figure=fig)
# max_std = []
# EODs = []
c = 0
for t, f in zip(all_t[fish_number], all_f[fish_number]):
EOD = calc_mean_eod(t, f, data)
ax = fig.add_subplot(gs[c])
ax.plot(EOD.T[0], EOD.T[1], color='firebrick', lw=2)
ax.fill_between(EOD.T[0], EOD.T[1] + EOD.T[2],
EOD.T[1] - EOD.T[2],
color='firebrick', alpha=0.7)
ax.set_xticks([])
ax.set_yticks([])
fig.add_subplot(ax)
c += 1
fig.suptitle(all_q10[fish_number, 2])
plt.show()
if __name__ == '__main__':
for index, filename_idx in enumerate([0, 2, 3, 5]):
filename = sorted(os.listdir('../../../data/mount_data/sanmartin/softgrid_1x16/'))[filename_idx]
folder = '../../../data/mount_data/sanmartin/softgrid_1x16/'+filename
print('new file: ' + filename)
name = main(folder, filename)
if filename not in os.listdir('../data/'):
os.mkdir('../data/' + filename)
np.save('../data/' + filename + '/fish_species.npy', name)

1438
eventdetection.py Normal file

File diff suppressed because it is too large Load Diff

545
helper_functions.py Normal file
View File

@ -0,0 +1,545 @@
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.gridspec as gridspec
from IPython import embed
# fill aifl with the IDs
def fill_aifl(id0, id1, aifl, Ch, Ch_connect, matrix_fish_counter, time, frequency, identity, faifl):
""" his function checks where to adds the two identities to the aifl
3 cases:
1: both ids do not exist in aifl - new fish and both ids are added to that fish number
2: both ids already exist in aifl - check whether the ids exist in the same fish number -- old fish
- if not the same number the traces of both fish numbers are plotted and than
by input of the person either but together as on fish number or added to the faifl
3: one of the ids exist in aifl - add the other id to the same fish number
Parameters
----------
id0: int
ID of the first trace
id1: int
ID of the second trace
aifl: 3-D array
all identity fish list; 1_D: channel; 2_D: fish number; 3_D: fish identities
Ch: int
first channel
Ch_connect: int
channel of id1 and to which we connect
matrix_fish_counter: int
counter where the new fish should be registered
time: 2-D array
loaded time array; 1_D: channel; 2_D: arbitrary time points [int]
frequency: 2-D array
loaded frequency array; 1_D: channel; 2_D: frequencies [Hz]
identity: 2-D array
loaded ident array; 1_D: channel; 2_D: identities [int]
faifl: 2-D array
false all identity fish list; 1_D: number of how many false enteries in the aifl exist
2_D: channels and fish number that are falsely connected;
4 columns: Ch, fishN0, Ch_connect, fishN1
Returns
-------
matrix_fish_counter: int
updated counter
aifl: 3-D array
updated aifl
faifl 2-D array
updated faifl
"""
# fish number
fishN0 = np.where(aifl[Ch][:][:] == id0)
fishN1 = np.where(aifl[Ch_connect][:][:] == id1)
# when none of the IDs existes -- new fish
if aifl[Ch][fishN0].size == 0 and aifl[Ch_connect][fishN1].size == 0:
aifl[Ch][matrix_fish_counter][0] = id0
aifl[Ch_connect][matrix_fish_counter][0] = id1
matrix_fish_counter += 1
print('new fish - ', matrix_fish_counter-1)
# what happens when both IDs already exist in the channels
elif aifl[Ch][fishN0].size != 0 and aifl[Ch_connect][fishN1].size != 0:
try:
# both IDs are already together as one fish
if fishN0[0] == fishN1[0]:
print('old fish')
# the IDs are in two different fish, we have to check is the fish should be merged
# plotting to identify by eye
# then input if the traces should be merged:
# yes/no/false --- if the merge before was already false
else:
print('confused fish', fishN0[0][0], fishN1[0][0])
a1 = aifl[:, fishN0[0], :]
a2 = aifl[:, fishN1[0], :]
for i in range(a1.shape[0]):
if a2[i, 0, ~np.isnan(a2[i, 0, :])].size != 0:
append_counter = 1
for j in range(a2[i, 0, ~np.isnan(a2[i, 0, :])].size):
print(a2[i][0][j])
nan_pos = np.where(a1[i, 0, ~np.isnan(a1[i, 0, :])])[0]
if nan_pos.size != 0:
aifl[i, fishN0[0], nan_pos[-1] + append_counter] = a2[i, 0, j]
append_counter += 1
else:
aifl[i, fishN0[0], 0] = a2[i, 0, j]
aifl[:, fishN1[0], :] = np.nan
# plot_confused_fish(time, frequency, identity, aifl, id0, id1, Ch, Ch_connect)
# go_signal = input('Are the traces matching? [y/n/f]')
#
# # if the merge before was already false and the fish_number is already in the faifl
# if np.any(faifl[:, [1, 3]] == fishN0[0][0]) or np.any(faifl[:, [1, 3]] == fishN1[0][0]):
# print('Traces are not matching')
# faifl = np.append(faifl, [[Ch, fishN0[0][0], Ch_connect, fishN1[0][0]]], axis=0)
# # go_signal = yes: merge the two fish to one
# elif go_signal == 'y':
# a1 = aifl[:, fishN0[0], :]
# a2 = aifl[:, fishN1[0], :]
#
# for i in range(a1.shape[0]):
# if a2[i, 0, ~np.isnan(a2[i, 0, :])].size != 0:
# append_counter = 1
# for j in range(a2[i, 0, ~np.isnan(a2[i, 0, :])].size):
# print(a2[i][0][j])
# nan_pos = np.where(a1[i, 0, ~np.isnan(a1[i, 0, :])])[0]
# if nan_pos.size != 0:
# aifl[i, fishN0[0], nan_pos[-1] + append_counter] = a2[i, 0, j]
# append_counter += 1
# else:
# aifl[i, fishN0[0], 0] = a2[i, 0, j]
# aifl[:, fishN1[0], :] = np.nan
#
# # go_signal = false: do not merge and put the fish_number into the faifl
# elif go_signal == 'f':
# faifl = np.append(faifl, [[Ch, fishN0[0][0], Ch_connect, fishN1[0][0]]], axis=0)
#
# # go_signal = everything else/no: no merge
# else:
# print('no merge')
except:
embed()
quit()
# if one of the fish does exist but the other one not:
# if fish0 exists assign fish1 the same fish_number
elif aifl[Ch][fishN0].size != 0:
aifl = add_id_to_aifl(aifl, Ch_connect, id1, fishN0)
# if fish1 exists assign fish0 the same fish_number
elif aifl[Ch_connect][fishN1].size != 0:
aifl = add_id_to_aifl(aifl, Ch, id0, fishN1)
return matrix_fish_counter, aifl, faifl
def add_id_to_aifl(aifl, Ch, ID, fishN):
""" adds the ID to the fishN in aifl
Parameters
----------
aifl: 3-D array
all identity fish list; 1_D: channel; 2_D: fish number; 3_D: fish identities
Ch: int
Channel
ID: int
the fishID which is added to aifl
fishN: int
the fish number to which we add the ID
Returns
-------
aifl: 3-D array
all identity fish list; 1_D: channel; 2_D: fish number; 3_D: fish identities
with the new ID at the fishN
"""
nan_pos = np.where(aifl[Ch][fishN[0]][~np.isnan(aifl[Ch][fishN[0]])])[0]
if nan_pos.size != 0:
aifl[Ch][fishN[0][0]][nan_pos[-1] + 1] = ID
else:
aifl[Ch][fishN[0][0]][0] = ID
return aifl
def plot_confused_fish(time, frequency, identity, aifl, id0, id1, Ch, Ch_next):
""" plots the two traces which should be connected but already exists in two different fish numbers in the aifl
it plots all the traces of this channel and the next of both fish numbers
plot both traces in question: fish0 -- red; fish1 -- blue
plot the existing traces of the fish_numbers in question
plot traces of fish0 in channel and channel+1 in grey and black
plot traces of fish1 in channel and channel+1 in green and yellow
Parameters
----------
time: 2-D array
loaded time array; 1_D: channel; 2_D: arbitrary time points [int]
frequency: 2-D array
loaded frequency array; 1_D: channel; 2_D: frequencies [Hz]
identity: 2-D array
loaded ident array; 1_D: channel; 2_D: identities [int]
aifl: 3-D array
all identity fish list; 1_D: channel; 2_D: fish number; 3_D: fish identities
id0: int
identity of the first trace
id1: int
identity of the second trace
Ch: int
current channel
Ch_next: int
next channel to which we connect
Returns
-------
nothing
"""
# parameter
t0 = time[Ch][identity[Ch] == id0]
f0 = frequency[Ch][identity[Ch] == id0]
t1 = time[Ch_next][identity[Ch_next] == id1]
f1 = frequency[Ch_next][identity[Ch_next] == id1]
fishN0 = np.where(aifl[Ch][:][:] == id0)
fishN1 = np.where(aifl[Ch_next][:][:] == id1)
# ToDo: ich hab das == True entfernt, wenns nicht mehr läuft zurück ändern
# ~np.isnan(aifl[connect_channel][where_id1[0]]) == True
for plotidx0 in range(len(np.where(~np.isnan(aifl[Ch][fishN0[0]]))[1])):
plt.plot(time[Ch][identity[Ch] == aifl[Ch][fishN0[0][0]][plotidx0]],
frequency[Ch][identity[Ch] == aifl[Ch][fishN0[0][0]][plotidx0]],
'grey', LineWidth=6, alpha=0.5)
for plotidx00 in range(len(np.where(~np.isnan(aifl[Ch_next][fishN0[0]]))[1])):
plt.plot(time[Ch_next][identity[Ch_next] == aifl[Ch_next][fishN0[0][0]][plotidx00]],
frequency[Ch_next][
identity[Ch_next] == aifl[Ch_next][fishN0[0][0]][plotidx00]],
'black', LineWidth=5, alpha=0.5)
for plotidx1 in range(len(np.where(~np.isnan(aifl[Ch_next][fishN1[0]]))[1])):
plt.plot(time[Ch_next][identity[Ch_next] == aifl[Ch_next][fishN1[0][0]][plotidx1]],
frequency[Ch_next][
identity[Ch_next] == aifl[Ch_next][fishN1[0][0]][plotidx1]],
'green', LineWidth=4, alpha=0.5)
for plotidx11 in range(len(np.where(~np.isnan(aifl[Ch][fishN1[0]]))[1])):
plt.plot(time[Ch][identity[Ch] == aifl[Ch][fishN1[0][0]][plotidx11]],
frequency[Ch][identity[Ch] == aifl[Ch][fishN1[0][0]][plotidx11]],
'yellow', LineWidth=3, alpha=0.5)
plt.plot(t0, f0, 'red', LineWidth=2)
plt.plot(t1, f1, 'blue', LineWidth=1)
plt.title('ch {}: fish {}; ch {}: fish {}'.format(Ch, fishN0[0][0], Ch_next, fishN1[0][0]))
plt.show()
def plot_together(time, frequency, identity, aifl, fishN, farbe):
""" plots all the frequency-time traces of all identities of one fish
Parameters
----------
time: 2-D array
loaded time array; 1_D: channel; 2_D: arbitrary time points [int]
frequency: 2-D array
loaded frequency array; 1_D: channel; 2_D: frequencies [Hz]
identity: 2-D array
loaded ident array; 1_D: channel; 2_D: identities [int]
aifl: 3-D array
all identity fish list; 1_D: channel; 2_D: fish number; 3_D: fish identities
fishN: int
number of the fish for aifl
farbe: str
hex color for the plot
Returns
-------
nothing
"""
fig = plt.figure(figsize=(16, 14))
fig.suptitle('fish {}'.format(fishN))
for channel_idx in range(16):
fish1 = aifl[channel_idx, fishN, ~np.isnan(aifl[channel_idx, fishN])]
r1 = len(fish1)
print(fish1)
for len_idx1 in range(r1):
plt.plot(time[channel_idx][identity[channel_idx] == fish1[len_idx1]],
frequency[channel_idx][identity[channel_idx] == fish1[len_idx1]],
Linewidth=1, label=str(channel_idx) + ',' + str(fish1[len_idx1]), color=farbe)
# plt.subplots_adjust(bottom=0.2)
ax = plt.gca()
legend_without_duplicate_labels(fig, ax)
plt.show()
return ax
def plot_all_channels(time, frequency, identity, aifl, fishN1, fishN2=None):
""" plots all the traces of each channel in a different subfigures
Parameters
----------
time: 2-D array
loaded time array; 1_D: channel; 2_D: arbitrary time points [int]
frequency: 2-D array
loaded frequency array; 1_D: channel; 2_D: frequencies [Hz]
identity: 2-D array
loaded ident array; 1_D: channel; 2_D: identities [int]
aifl: 3-D array
all identity fish list; 1_D: channel; 2_D: fish number; 3_D: fish identities
fishN1: int
fish number of the first fish
fishN2: int; optional
fish number of the second fish
Returns
-------
nothing
"""
xcounter = 0
ycounter = 0
fig1, axs1 = plt.subplots(nrows=4, ncols=4, sharex=True, sharey=True, figsize=(16, 14))
fig1.suptitle('fish {}; fish {}'.format(fishN1, fishN2))
for channel_idx in range(16):
fish1 = aifl[channel_idx, fishN1, ~np.isnan(aifl[channel_idx, fishN1])]
r1 = len(fish1)
print(fish1)
for len_idx1 in range(r1):
axs1[ycounter, xcounter].plot(time[channel_idx][identity[channel_idx] == fish1[len_idx1]],
frequency[channel_idx][identity[channel_idx] == fish1[len_idx1]],
'gray', Linewidth=3)
# if fishN2 is given
if fishN2 is not None:
fish2 = aifl[channel_idx, fishN2, ~np.isnan(aifl[channel_idx, fishN2])]
r2 = len(fish2)
for len_idx2 in range(r2):
axs1[ycounter, xcounter].plot(time[channel_idx][identity[channel_idx] == fish2[len_idx2]],
frequency[channel_idx][identity[channel_idx] == fish2[len_idx2]],
'blue', Linewidth=1)
if xcounter == 3:
xcounter = 0
ycounter = ycounter + 1
else:
xcounter = xcounter + 1
plt.show()
def legend_without_duplicate_labels(fig, ax):
""" creats a legend without duplicated labels
Parameters
----------
fig: figure handle
ax: ax handle
"""
handles, labels = ax.get_legend_handles_labels()
unique = [(h, l) for lwdl_idx, (h, l) in enumerate(zip(handles, labels)) if l not in labels[:lwdl_idx]]
ax.legend(*zip(*unique), bbox_to_anchor=(1, 0.4), loc="center right", bbox_transform=fig.transFigure, ncol=1)
def running_3binsizes(ipp, sampling_rate):
"""
Parameters
----------
ipp: 2-D array
interpolated power pancake; power of the signal over time for each channel
1_D: channel; 2_D: power of the signal over time
sampling_rate: int
sampling rate of the recordings
Returns
-------
run_mean: 2-D array
running mean with different bin sizes,
first dimension: mean, second: bin size (from the running function)
run_std: 2-D array
running std with different bin sizes,
first dimension: std, second: bin size (from the running function, same bin size as mean)
"""
# lists
running_mean = []
running_std = []
# max power in which channel of ipp
max_ch = np.argmax(ipp, axis=1)
# bin sizes
bin1 = int(np.floor(15 * 60 / sampling_rate))
bin2 = int(np.floor(30 * 60 / sampling_rate))
bin3 = int(np.floor(60 * 60 / sampling_rate))
# steps with steps 1/2 of bin size
steps1 = np.arange(0, int(len(max_ch) - bin1), 7.5 * 60)
steps2 = np.arange(0, int(len(max_ch) - bin2), 15 * 60)
steps3 = np.arange(0, int(len(max_ch) - bin2), 30 * 60)
# make running mean, std and sem
for bins, step in zip([bin1, bin2, bin3], [steps1, steps2, steps3]):
bin_mean = np.full([len(max_ch)], np.nan)
bin_std = np.full([len(max_ch)], np.nan)
# for i in range(int(len(max_ch) - bins)):
for i in step:
i = int(i)
bin_mean[int(i + np.floor(bins / 2))] = np.mean(max_ch[i:bins + i])
bin_std[int(i + np.floor(bins / 2))] = np.std(max_ch[i:bins + i])
running_mean.append(bin_mean)
running_std.append(bin_std)
return running_mean, running_std
def running_variablebinsize(ipp, sampling_rate):
''' calculates the running mean and running std of the interpolated power pancake
with two different bin sizes and a step size half of the bin size
Parameters
----------
ipp: 2-D array
interpolated power pancake; power of the signal over time for each channel
1_D: channel; 2_D: power of the signal over time
sampling_rate: int
sampling rate of the recordings
Returns
-------
running_mean: 2-D array
running mean over the time axis with two different bin sizes and step sizes, which are also
dependent on the length of the time trace;
1_D: different bin size [2]; 2_D: MEAN, (with steps half of the bin size)
running_std: 2-D array
running std over the time axis with two different bin sizes and step sizes, which are also
dependent on the length of the time trace;
1_D: different bin size [2]; 2_D: STD, (with steps half of the bin size)
'''
# lists
running_mean = []
running_std = []
# max power in which channel of ipp
max_ch = np.argmax(ipp, axis=1)
# calculate bin sizes
if len(ipp) <= 1800 / sampling_rate: # all time traces < 30 min
bin1 = int(np.floor(60 / sampling_rate))
bin2 = int(np.floor(2 * 60 / sampling_rate))
steps1 = np.arange(0, int(len(max_ch) - bin1), 0.5 * 60)
steps2 = np.arange(0, int(len(max_ch) - bin2), 1 * 60)
elif len(ipp) <= 14400 / sampling_rate: # all time traces < 4 h
bin1 = int(np.floor(10 * 60 / sampling_rate))
bin2 = int(np.floor(20 * 60 / sampling_rate))
steps1 = np.arange(0, int(len(max_ch) - bin1), 5 * 60)
steps2 = np.arange(0, int(len(max_ch) - bin2), 10 * 60)
elif len(ipp) > 14400 / sampling_rate: # all time traces > 4 h
bin1 = int(np.floor(60 * 60 / sampling_rate))
bin2 = int(np.floor(180 * 60 / sampling_rate))
steps1 = np.arange(0, int(len(max_ch) - bin1), 30 * 60)
steps2 = np.arange(0, int(len(max_ch) - bin2), 90 * 60)
# make running mean, std and sem
for bins, step in zip([bin1, bin2], [steps1, steps2]):
bin_mean = np.full([len(max_ch)], np.nan)
bin_std = np.full([len(max_ch)], np.nan)
# for i in range(int(len(max_ch) - bins)):
for i in step:
i = int(i)
bin_mean[int(i + np.floor(bins / 2))] = np.mean(max_ch[i:bins + i])
bin_std[int(i + np.floor(bins / 2))] = np.std(max_ch[i:bins + i])
running_mean.append(bin_mean)
running_std.append(bin_std)
running_mean = np.array(running_mean)
running_std = np.array(running_std)
return running_mean, running_std
def plot_running(x, run_mean, run_std, threshold, fish, farbe, fs, fs_ticks, lw):
"""
Parameters
----------
x: 1-D array
x axis points in date time format
run_mean: 2-D array
running mean with different bin sizes,
first dimension: mean, second: bin size (from the running function)
run_std: 2-D array
running std with different bin sizes,
first dimension: std, second: bin size (from the running function, same bin size as mean)
threshold: 1-D array
threshold for the activity phases dependent on the run mean,
length of array same as how many bin sizes where calculated
fish: int
title for the figure
farbe: 1-D list
list with all available colors from the matplotlib.colors in hex-color code
fs: int; fontsize
fs_ticks: int; fontsize of ticks
lw: int; line width
Returns
-------
"""
fig = plt.figure(figsize=(16, 14))
spec = gridspec.GridSpec(ncols=2, nrows=2, figure=fig)
ax1 = fig.add_subplot(spec[0, 0])
ax2 = fig.add_subplot(spec[0, 1])
ax3 = fig.add_subplot(spec[1, 0])
ax4 = fig.add_subplot(spec[1, 1])
plt.suptitle('fish {}'.format(fish), fontsize=fs + 2)
ax_cntr = 0
for ax in [ax1, ax2, ax3]:
non_nan = np.arange(len(run_mean[ax_cntr]))[~np.isnan(run_mean[ax_cntr])]
ax.plot(x[fish][non_nan], run_mean[ax_cntr][non_nan], '.', color=farbe[ax_cntr + 4])
ax.fill_between(x[fish][non_nan], run_mean[ax_cntr][non_nan] + run_std[ax_cntr][non_nan],
run_mean[ax_cntr][non_nan] - run_std[ax_cntr][non_nan],
facecolor=farbe[ax_cntr + 4], alpha=0.5)
ax4.plot(x[fish][non_nan], run_std[ax_cntr][non_nan], color=farbe[ax_cntr + 4],
label=threshold[ax_cntr])
ax4.plot([x[fish][non_nan][0], x[fish][non_nan][-1]],
[threshold[ax_cntr], threshold[ax_cntr]],
color=farbe[ax_cntr + 4])
ax_cntr += 1
ax.set_ylim([0, 15])
ax.invert_yaxis()
for ax in [ax1, ax2, ax3, ax4]:
ax.tick_params(width=lw - 2)
ax.tick_params(axis='both', which='major', labelsize=fs_ticks)
ax.xaxis_date()
date_format = mdates.DateFormatter('%H:%M')
ax.xaxis.set_major_formatter(date_format)
fig.autofmt_xdate()
ax1.set_xlabel('time [h]', fontsize=fs)
ax1.set_ylabel('channel', fontsize=fs)
plt.legend()

130
match_oofl.py Normal file
View File

@ -0,0 +1,130 @@
import numpy as np
import matplotlib.pyplot as plt
from IPython import embed
import helper_functions as hf
if __name__ == '__main__':
###################################################################################################################
# load data
###################################################################################################################
# load all the data of one day
ident = np.load('../../../data/2019-10-07-18_28/all_ident_v.npy', allow_pickle=True)
# power = np.load('../../../data/2019-10-07-18_28/all_sign_v.npy', allow_pickle=True)
freq = np.load('../../../data/2019-10-07-18_28/all_fund_v.npy', allow_pickle=True)
timeidx = np.load('../../../data/2019-10-07-18_28/all_idx_v.npy', allow_pickle=True)
aifl = np.load('../data/aifl.npy', allow_pickle=True)
oofl = np.load('../data/oofl2.npy', allow_pickle=True)
faifl = np.load('../data/faifl.npy', allow_pickle=True)
faifl = np.delete(faifl, [0], axis=0)
uni_ident_list = []
for index in range(len(ident)):
uni_ident = np.unique(ident[index][~np.isnan(ident[index])])
uni_ident_list.append(uni_ident)
for k in range(len(oofl)-len(oofl[np.where(oofl[:, 0] == 15)[0][0]:, :])):
channel = int(oofl[k, 0])
# find for each identity the first and last time stamp in the given channel and the next
# channel 0
t_Ch0 = np.empty((1, 2))
id0 = oofl[k,1]
t = timeidx[channel][ident[channel] == id0]
t_Ch0[0][0] = t[0]
t_Ch0[0][1] = t[-1]
# channel 1
t_Ch1 = np.empty((len(uni_ident_list[channel + 1]), 2))
for index in range(len(uni_ident_list[channel + 1])):
id1 = uni_ident_list[channel + 1][index]
t1 = timeidx[channel + 1][ident[channel + 1] == id1]
t_Ch1[index, 0] = t1[0]
t_Ch1[index, 1] = t1[-1]
# parameters
jitter_time = 5
tolerance_time = 120
false_count = 0
true_count = 0
for i in range(len(t_Ch0)):
for j in range(len(t_Ch1)):
t0 = timeidx[channel][ident[channel] == id0]
f0 = freq[channel][ident[channel] == id0]
id1 = uni_ident_list[channel + 1][j]
t1 = timeidx[channel + 1][ident[channel + 1] == id1]
f1 = freq[channel + 1][ident[channel + 1] == id1]
t00 = t_Ch0[i][0] - jitter_time
t0n = t_Ch0[i][1] + jitter_time
t10 = t_Ch1[j][0] - jitter_time
t1n = t_Ch1[j][1] + jitter_time
window_times = sorted(np.array([t00, t0n, t10, t1n]))[1:3]
sort_it = False
case = np.nan
if (t00 <= t10) and (t00 <= t1n) and (t0n >= t1n):
sort_it = True
case = 1
elif (t10 <= t00) and (t10 <= t0n) and (t1n >= t0n):
sort_it = True
case = 2
elif (t00 <= t10) and (t0n >= t10) and (t0n <= t1n):
sort_it = True
case = 3
elif (t10 <= t00) and (t1n >= t00) and (t1n <= t0n):
sort_it = True
case = 4
else:
false_count += 1
pass
# if t_Ch0[i][0] - jitter_time <= t_Ch1[j][0] <= t_Ch0[i][1] + jitter_time:
if sort_it:
true_count+=1
f0_box_min = np.median(f0[np.isclose(t0, window_times[0], atol=tolerance_time)])
f0_box_max = np.median(f0[np.isclose(t0, window_times[1], atol=tolerance_time)])
f1_box_min = np.median(f1[np.isclose(t1, window_times[0], atol=tolerance_time)])
f1_box_max = np.median(f1[np.isclose(t1, window_times[1], atol=tolerance_time)])
if f0_box_min.size > 0 and f1_box_min.size > 0:
fdiff0 = abs(f0_box_min - f1_box_min)
if fdiff0 <= 10:
plt.plot(timeidx[channel][ident[channel] == id0],
freq[channel][ident[channel] == id0], label=id0)
plt.plot(timeidx[channel + 1][ident[channel + 1] == id1],
freq[channel + 1][ident[channel + 1] == id1], label=id1)
plt.legend()
plt.show()
embed()
#hf.fill_aifl(id0, id1, aifl, channel, 4, timeidx, freq, ident, faifl)
else:
continue
elif f0_box_max.size > 0 and f1_box_max.size > 0:
fdiff1 = abs(f0_box_max - f1_box_max)
if fdiff1 <= 10:
plt.plot(timeidx[channel][ident[channel] == id0],
freq[channel][ident[channel] == id0], label=id0)
plt.plot(timeidx[channel + 1][ident[channel + 1] == id1],
freq[channel + 1][ident[channel + 1] == id1], label=id1)
plt.legend()
plt.show()
embed()
#hf.fill_aifl(id0,id1,aifl,channel,4,timeidx,freq, ident,faifl)
else:
continue
oofl = []
counter = 0
for idx in range(len(uni_ident_list)):
for j in range(len(uni_ident_list[idx])):
if not np.any(aifl[idx] == uni_ident_list[idx][j]):
oofl.append([idx, uni_ident_list[idx][j]])
counter = counter + 1
embed()
quit()