45 Commits

Author SHA1 Message Date
wendtalexander
e217766159 python versions 2023-03-02 12:01:12 +01:00
wendtalexander
c28c227291 adding stuff 2023-01-26 10:02:58 +01:00
wendtalexander
7b74a7c024 Merge branch 'master' into chirp_simulation 2023-01-25 23:31:01 +01:00
wendtalexander
6ddb9bda7a Merge branch 'master' of https://whale.am28.uni-tuebingen.de/git/raab/GP2023_chirp_detection 2023-01-25 23:13:55 +01:00
wendtalexander
62f5266a46 add will cox 2023-01-25 23:13:53 +01:00
weygoldt
449bc130a0 ??? 2023-01-25 21:55:44 +01:00
weygoldt
534215f2e4 ??? 2023-01-25 21:54:54 +01:00
wendtalexander
bdf1ae47a6 adding main.pdf to git ignore 2023-01-25 21:29:13 +01:00
weygoldt
81a7d9907b wilcoxon test 2023-01-25 21:27:41 +01:00
weygoldt
2ee5a350fd wilcoxon test 2023-01-25 21:26:52 +01:00
wendtalexander
15d2cc49f3 refactor file 2023-01-25 20:59:45 +01:00
wendtalexander
f5c922c4ff Merge branch 'master' of https://whale.am28.uni-tuebingen.de/git/raab/GP2023_chirp_detection 2023-01-25 20:49:28 +01:00
wendtalexander
a57fa14ed6 changing plot 2023-01-25 20:49:27 +01:00
weygoldt
6b4f3a42cc ??? 2023-01-25 20:48:15 +01:00
weygoldt
1de3e944c5 ??? 2023-01-25 20:47:02 +01:00
wendtalexander
6e9ef51652 changing color 2023-01-25 20:24:02 +01:00
wendtalexander
80b4b8fcf2 finishing chirps in chasing 2023-01-25 20:09:46 +01:00
wendtalexander
d5b23481ad adding plot in chasing 2023-01-25 19:57:44 +01:00
wendtalexander
c089ef354d removing frequency ax 2023-01-25 18:16:18 +01:00
wendtalexander
0047c8672a removing ax 2023-01-25 18:14:44 +01:00
wendtalexander
136553e34e removing frequency plot 2023-01-25 18:14:10 +01:00
wendtalexander
44b5da9aac adding pearson r 2023-01-25 18:13:30 +01:00
wendtalexander
d4ee13d56b Merge branch 'master' of https://whale.am28.uni-tuebingen.de/git/raab/GP2023_chirp_detection 2023-01-25 17:47:02 +01:00
wendtalexander
7f17de2748 adding plot changes 2023-01-25 17:47:00 +01:00
weygoldt
bbff7fd80c resolving master merge 2023-01-25 17:34:33 +01:00
weygoldt
eaa91e1655 kdes work but scale is wrong 2023-01-25 17:29:26 +01:00
wendtalexander
cdcf9564df finish function 2023-01-25 13:59:13 +01:00
wendtalexander
a5ae0a3032 adding new scirpt for chirp vs size 2023-01-25 13:54:33 +01:00
wendtalexander
79388dbcad Merge branch 'master' of https://whale.am28.uni-tuebingen.de/git/raab/GP2023_chirp_detection 2023-01-25 13:44:15 +01:00
wendtalexander
08c7913c95 adding subplots cm 2023-01-25 13:44:14 +01:00
weygoldt
9e5ec1d70b Merge branch 'master' of https://whale.am28.uni-tuebingen.de/git/raab/GP2023_chirp_detection 2023-01-25 10:19:23 +01:00
weygoldt
a6b7ed2c6c merging diverged 2023-01-25 10:19:19 +01:00
b88b2b6247 adjusted check of length of on- and offests after correction 2023-01-25 10:18:27 +01:00
wendtalexander
798884fd01 Merge branch 'master' of https://whale.am28.uni-tuebingen.de/git/raab/GP2023_chirp_detection 2023-01-25 10:16:29 +01:00
wendtalexander
af088f5726 trying different stuff 2023-01-25 10:16:28 +01:00
0b109e8c5e tabula rasa 2023-01-25 09:18:05 +01:00
6fd3323c6c inserted two functions from CTCPTC stuff 2023-01-25 09:12:04 +01:00
wendtalexander
4b5aec2e65 adding plots to poster 2023-01-24 23:39:38 +01:00
wendtalexander
c070192996 making things worse 2023-01-24 23:16:36 +01:00
89823fdc28 different bootstrap approaches 2023-01-24 20:50:07 +01:00
wendtalexander
ad9cf9c785 adding plot 2023-01-24 20:45:58 +01:00
wendtalexander
0ade3b101a plotting true zeros 2023-01-17 09:07:50 +01:00
wendtalexander
3c5ab4381e Merge branch 'master' into chirp_simulation 2023-01-16 20:10:12 +01:00
wendtalexander
990e858d02 checking the instantaneos_frequency 2023-01-16 20:07:38 +01:00
wendtalexander
133aff26a1 adding thunderfish chirp simulation 2023-01-15 16:12:45 +01:00
21 changed files with 1627 additions and 446 deletions

1
.gitignore vendored
View File

@@ -14,6 +14,7 @@ output
__pycache__/ __pycache__/
*.py[cod] *.py[cod]
*$py.class *$py.class
poster/main.pdf
# C extensions # C extensions
*.so *.so

1
.python-version Normal file
View File

@@ -0,0 +1 @@
chirp

View File

@@ -1,24 +1,37 @@
from modules.filters import create_chirp, bandpass_filter import numpy as np
import matplotlib.pyplot as plt
from chirpdetection import instantaneos_frequency
from IPython import embed from IPython import embed
# create chirp import matplotlib.pyplot as plt
from thunderfish import fakefish
time, signal, ampl, freq = create_chirp(chirptimes=[0.05, 0.2501, 0.38734, 0.48332, 0.73434, 0.823424], ) from modules.filters import bandpass_filter
from modules.datahandling import instantaneous_frequency
from modules.simulations import create_chirp
# filter signal with bandpass_filter
signal = bandpass_filter(signal, 1/0.00001, 495, 505)
# trying thunderfish fakefish chirp simulation ---------------------------------
samplerate = 44100
freq, ampl = fakefish.chirps(eodf=500, chirp_contrast=0.2)
data = fakefish.wavefish_eods(fish='Alepto', frequency=freq, phase0=3, samplerate=samplerate)
# filter signal with bandpass_filter
data_filterd = bandpass_filter(data*ampl+1, samplerate, 0.01, 1.99)
embed() embed()
exit() data_freq_time, data_freq = instantaneous_frequency(data, samplerate, 5)
fig, axs = plt.subplots(2, 1, figsize=(10, 10))
axs[0].plot(time, signal)
# plot instatneous frequency
baseline_freq_time, baseline_freq = instantaneos_frequency(signal, 1/0.00001) fig, ax = plt.subplots(4, 1, figsize=(20 / 2.54, 12 / 2.54), sharex=True)
axs[1].plot(baseline_freq_time[1:], baseline_freq[1:])
ax[0].plot(np.arange(len(data))/samplerate, data*ampl)
#ax[0].scatter(true_zero, np.zeros_like(true_zero), color='red')
ax[1].plot(np.arange(len(data_filterd))/samplerate, data_filterd)
ax[2].plot(np.arange(len(freq))/samplerate, freq)
ax[3].plot(data_freq_time, data_freq)
plt.show() plt.show()
embed()

View File

@@ -1,55 +1,62 @@
import os import os
import numpy as np import numpy as np
import pandas as pd import pandas as pd
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from tqdm import tqdm from tqdm import tqdm
from IPython import embed from IPython import embed
from pandas import read_csv from pandas import read_csv
from modules.logger import makeLogger from modules.logger import makeLogger
from modules.plotstyle import PlotStyle from modules.plotstyle import PlotStyle
from modules.datahandling import causal_kde1d, acausal_kde1d from modules.datahandling import causal_kde1d, acausal_kde1d, flatten
logger = makeLogger(__name__) logger = makeLogger(__name__)
ps = PlotStyle() ps = PlotStyle()
class Behavior: class Behavior:
"""Load behavior data from csv file as class attributes """Load behavior data from csv file as class attributes
Attributes Attributes
---------- ----------
behavior: 0: chasing onset, 1: chasing offset, 2: physical contact behavior: 0: chasing onset, 1: chasing offset, 2: physical contact
behavior_type: behavior_type:
behavioral_category: behavioral_category:
comment_start: comment_start:
comment_stop: comment_stop:
dataframe: pandas dataframe with all the data dataframe: pandas dataframe with all the data
duration_s: duration_s:
media_file: media_file:
observation_date: observation_date:
observation_id: observation_id:
start_s: start time of the event in seconds start_s: start time of the event in seconds
stop_s: stop time of the event in seconds stop_s: stop time of the event in seconds
total_length: total_length:
""" """
def __init__(self, folder_path: str) -> None: def __init__(self, folder_path: str) -> None:
print(f'{folder_path}') print(f'{folder_path}')
LED_on_time_BORIS = np.load(os.path.join(folder_path, 'LED_on_time.npy'), allow_pickle=True) LED_on_time_BORIS = np.load(os.path.join(
self.time = np.load(os.path.join(folder_path, "times.npy"), allow_pickle=True) folder_path, 'LED_on_time.npy'), allow_pickle=True)
csv_filename = [f for f in os.listdir(folder_path) if f.endswith('.csv')][0] # check if there are more than one csv file self.time = np.load(os.path.join(
folder_path, "times.npy"), allow_pickle=True)
csv_filename = [f for f in os.listdir(folder_path) if f.endswith(
'.csv')][0] # check if there are more than one csv file
self.dataframe = read_csv(os.path.join(folder_path, csv_filename)) self.dataframe = read_csv(os.path.join(folder_path, csv_filename))
self.chirps = np.load(os.path.join(folder_path, 'chirps.npy'), allow_pickle=True) self.chirps = np.load(os.path.join(
self.chirps_ids = np.load(os.path.join(folder_path, 'chirp_ids.npy'), allow_pickle=True) folder_path, 'chirps.npy'), allow_pickle=True)
self.chirps_ids = np.load(os.path.join(
folder_path, 'chirp_ids.npy'), allow_pickle=True)
for k, key in enumerate(self.dataframe.keys()): for k, key in enumerate(self.dataframe.keys()):
key = key.lower() key = key.lower()
if ' ' in key: if ' ' in key:
key = key.replace(' ', '_') key = key.replace(' ', '_')
if '(' in key: if '(' in key:
key = key.replace('(', '') key = key.replace('(', '')
key = key.replace(')', '') key = key.replace(')', '')
setattr(self, key, np.array(self.dataframe[self.dataframe.keys()[k]])) setattr(self, key, np.array(
self.dataframe[self.dataframe.keys()[k]]))
last_LED_t_BORIS = LED_on_time_BORIS[-1] last_LED_t_BORIS = LED_on_time_BORIS[-1]
real_time_range = self.time[-1] - self.time[0] real_time_range = self.time[-1] - self.time[0]
@@ -58,6 +65,7 @@ class Behavior:
self.start_s = (self.start_s - shift) / factor self.start_s = (self.start_s - shift) / factor
self.stop_s = (self.stop_s - shift) / factor self.stop_s = (self.stop_s - shift) / factor
""" """
1 - chasing onset 1 - chasing onset
2 - chasing offset 2 - chasing offset
@@ -87,16 +95,17 @@ temporal encpding needs to be corrected ... not exactly 25FPS.
def correct_chasing_events( def correct_chasing_events(
category: np.ndarray, category: np.ndarray,
timestamps: np.ndarray timestamps: np.ndarray
) -> tuple[np.ndarray, np.ndarray]: ) -> tuple[np.ndarray, np.ndarray]:
onset_ids = np.arange( onset_ids = np.arange(
len(category))[category == 0] len(category))[category == 0]
offset_ids = np.arange( offset_ids = np.arange(
len(category))[category == 1] len(category))[category == 1]
wrong_bh = np.arange(len(category))[category!=2][:-1][np.diff(category[category!=2])==0] wrong_bh = np.arange(len(category))[
category != 2][:-1][np.diff(category[category != 2]) == 0]
if onset_ids[0] > offset_ids[0]: if onset_ids[0] > offset_ids[0]:
offset_ids = np.delete(offset_ids, 0) offset_ids = np.delete(offset_ids, 0)
help_index = offset_ids[0] help_index = offset_ids[0]
@@ -105,7 +114,6 @@ def correct_chasing_events(
category = np.delete(category, wrong_bh) category = np.delete(category, wrong_bh)
timestamps = np.delete(timestamps, wrong_bh) timestamps = np.delete(timestamps, wrong_bh)
# Check whether on- or offset is longer and calculate length difference # Check whether on- or offset is longer and calculate length difference
if len(onset_ids) > len(offset_ids): if len(onset_ids) > len(offset_ids):
len_diff = len(onset_ids) - len(offset_ids) len_diff = len(onset_ids) - len(offset_ids)
@@ -115,21 +123,22 @@ def correct_chasing_events(
logger.info(f'Offsets are greater than onsets by {len_diff}') logger.info(f'Offsets are greater than onsets by {len_diff}')
elif len(onset_ids) == len(offset_ids): elif len(onset_ids) == len(offset_ids):
logger.info('Chasing events are equal') logger.info('Chasing events are equal')
return category, timestamps return category, timestamps
def event_triggered_chirps( def event_triggered_chirps(
event: np.ndarray, event: np.ndarray,
chirps:np.ndarray, chirps: np.ndarray,
time_before_event: int, time_before_event: int,
time_after_event: int, time_after_event: int,
dt: float, dt: float,
width: float, width: float,
)-> tuple[np.ndarray, np.ndarray, np.ndarray]: ) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
event_chirps = [] # chirps that are in specified window around event event_chirps = [] # chirps that are in specified window around event
centered_chirps = [] # timestamps of chirps around event centered on the event timepoint # timestamps of chirps around event centered on the event timepoint
centered_chirps = []
for event_timestamp in event: for event_timestamp in event:
start = event_timestamp - time_before_event start = event_timestamp - time_before_event
@@ -138,25 +147,28 @@ def event_triggered_chirps(
event_chirps.append(chirps_around_event) event_chirps.append(chirps_around_event)
if len(chirps_around_event) == 0: if len(chirps_around_event) == 0:
continue continue
else: else:
centered_chirps.append(chirps_around_event - event_timestamp) centered_chirps.append(chirps_around_event - event_timestamp)
time = np.arange(-time_before_event, time_after_event, dt) time = np.arange(-time_before_event, time_after_event, dt)
# Kernel density estimation with some if's # Kernel density estimation with some if's
if len(centered_chirps) == 0: if len(centered_chirps) == 0:
centered_chirps = np.array([]) centered_chirps = np.array([])
centered_chirps_convolved = np.zeros(len(time)) centered_chirps_convolved = np.zeros(len(time))
else: else:
centered_chirps = np.concatenate(centered_chirps, axis=0) # convert list of arrays to one array for plotting # convert list of arrays to one array for plotting
centered_chirps_convolved = (acausal_kde1d(centered_chirps, time, width)) / len(event) centered_chirps = np.concatenate(centered_chirps, axis=0)
centered_chirps_convolved = (acausal_kde1d(
centered_chirps, time, width)) / len(event)
return event_chirps, centered_chirps, centered_chirps_convolved return event_chirps, centered_chirps, centered_chirps_convolved
def main(datapath: str): def main(datapath: str):
foldernames = [datapath + x + '/' for x in os.listdir(datapath) if os.path.isdir(datapath + x)] foldernames = [
datapath + x + '/' for x in os.listdir(datapath) if os.path.isdir(datapath + x)]
nrecording_chirps = [] nrecording_chirps = []
nrecording_chirps_fish_ids = [] nrecording_chirps_fish_ids = []
@@ -171,7 +183,7 @@ def main(datapath: str):
continue continue
bh = Behavior(folder) bh = Behavior(folder)
# Chirps are already sorted # Chirps are already sorted
category = bh.behavior category = bh.behavior
timestamps = bh.start_s timestamps = bh.start_s
@@ -192,14 +204,13 @@ def main(datapath: str):
nrecording_chasing_offsets.append(chasing_offsets) nrecording_chasing_offsets.append(chasing_offsets)
physical_contacts = timestamps[category == 2] physical_contacts = timestamps[category == 2]
nrecording_physicals.append(physical_contacts) nrecording_physicals.append(physical_contacts)
# Define time window for chirps around event analysis # Define time window for chirps around event analysis
time_before_event = 30 time_before_event = 30
time_after_event = 60 time_after_event = 60
dt = 0.01 dt = 0.01
width = 1.5 # width of kernel for all recordings, currently gaussian kernel width = 1.5 # width of kernel for all recordings, currently gaussian kernel
recording_width = 2 # width of kernel for each recording recording_width = 2 # width of kernel for each recording
time = np.arange(-time_before_event, time_after_event, dt) time = np.arange(-time_before_event, time_after_event, dt)
##### Chirps around events, all fish, all recordings ##### ##### Chirps around events, all fish, all recordings #####
@@ -212,7 +223,7 @@ def main(datapath: str):
nrecording_shuffled_convolved_offset_chirps = [] nrecording_shuffled_convolved_offset_chirps = []
nrecording_shuffled_convolved_physical_chirps = [] nrecording_shuffled_convolved_physical_chirps = []
nbootstrapping = 10 nbootstrapping = 100
for i in range(len(nrecording_chirps)): for i in range(len(nrecording_chirps)):
chirps = nrecording_chirps[i] chirps = nrecording_chirps[i]
@@ -221,14 +232,18 @@ def main(datapath: str):
physical_contacts = nrecording_physicals[i] physical_contacts = nrecording_physicals[i]
# Chirps around chasing onsets # Chirps around chasing onsets
_, centered_chasing_onset_chirps, cc_chasing_onset_chirps = event_triggered_chirps(chasing_onsets, chirps, time_before_event, time_after_event, dt, recording_width) _, centered_chasing_onset_chirps, cc_chasing_onset_chirps = event_triggered_chirps(
chasing_onsets, chirps, time_before_event, time_after_event, dt, recording_width)
# Chirps around chasing offsets # Chirps around chasing offsets
_, centered_chasing_offset_chirps, cc_chasing_offset_chirps = event_triggered_chirps(chasing_offsets, chirps, time_before_event, time_after_event, dt, recording_width) _, centered_chasing_offset_chirps, cc_chasing_offset_chirps = event_triggered_chirps(
chasing_offsets, chirps, time_before_event, time_after_event, dt, recording_width)
# Chirps around physical contacts # Chirps around physical contacts
_, centered_physical_chirps, cc_physical_chirps = event_triggered_chirps(physical_contacts, chirps, time_before_event, time_after_event, dt, recording_width) _, centered_physical_chirps, cc_physical_chirps = event_triggered_chirps(
physical_contacts, chirps, time_before_event, time_after_event, dt, recording_width)
nrecording_centered_onset_chirps.append(centered_chasing_onset_chirps) nrecording_centered_onset_chirps.append(centered_chasing_onset_chirps)
nrecording_centered_offset_chirps.append(centered_chasing_offset_chirps) nrecording_centered_offset_chirps.append(
centered_chasing_offset_chirps)
nrecording_centered_physical_chirps.append(centered_physical_chirps) nrecording_centered_physical_chirps.append(centered_physical_chirps)
## Shuffled chirps ## ## Shuffled chirps ##
@@ -236,112 +251,159 @@ def main(datapath: str):
nshuffled_offset_chirps = [] nshuffled_offset_chirps = []
nshuffled_physical_chirps = [] nshuffled_physical_chirps = []
for j in tqdm(range(nbootstrapping)): # for j in tqdm(range(nbootstrapping)):
# Calculate interchirp intervals; add first chirp timestamp in beginning to get equal lengths # # Calculate interchirp intervals; add first chirp timestamp in beginning to get equal lengths
interchirp_intervals = np.append(np.array([chirps[0]]), np.diff(chirps)) # interchirp_intervals = np.append(np.array([chirps[0]]), np.diff(chirps))
np.random.shuffle(interchirp_intervals) # np.random.shuffle(interchirp_intervals)
shuffled_chirps = np.cumsum(interchirp_intervals) # shuffled_chirps = np.cumsum(interchirp_intervals)
# Shuffled chasing onset chirps # # Shuffled chasing onset chirps
_, _, cc_shuffled_onset_chirps = event_triggered_chirps(chasing_onsets, shuffled_chirps, time_before_event, time_after_event, dt, recording_width) # _, _, cc_shuffled_onset_chirps = event_triggered_chirps(chasing_onsets, shuffled_chirps, time_before_event, time_after_event, dt, recording_width)
nshuffled_onset_chirps.append(cc_shuffled_onset_chirps) # nshuffled_onset_chirps.append(cc_shuffled_onset_chirps)
# Shuffled chasing offset chirps # # Shuffled chasing offset chirps
_, _, cc_shuffled_offset_chirps = event_triggered_chirps(chasing_offsets, shuffled_chirps, time_before_event, time_after_event, dt, recording_width) # _, _, cc_shuffled_offset_chirps = event_triggered_chirps(chasing_offsets, shuffled_chirps, time_before_event, time_after_event, dt, recording_width)
nshuffled_offset_chirps.append(cc_shuffled_offset_chirps) # nshuffled_offset_chirps.append(cc_shuffled_offset_chirps)
# Shuffled physical contact chirps # # Shuffled physical contact chirps
_, _, cc_shuffled_physical_chirps = event_triggered_chirps(physical_contacts, shuffled_chirps, time_before_event, time_after_event, dt, recording_width) # _, _, cc_shuffled_physical_chirps = event_triggered_chirps(physical_contacts, shuffled_chirps, time_before_event, time_after_event, dt, recording_width)
nshuffled_physical_chirps.append(cc_shuffled_physical_chirps) # nshuffled_physical_chirps.append(cc_shuffled_physical_chirps)
rec_shuffled_q5_onset, rec_shuffled_median_onset, rec_shuffled_q95_onset = np.percentile( # rec_shuffled_q5_onset, rec_shuffled_median_onset, rec_shuffled_q95_onset = np.percentile(
nshuffled_onset_chirps, (5, 50, 95), axis=0) # nshuffled_onset_chirps, (5, 50, 95), axis=0)
rec_shuffled_q5_offset, rec_shuffled_median_offset, rec_shuffled_q95_offset = np.percentile( # rec_shuffled_q5_offset, rec_shuffled_median_offset, rec_shuffled_q95_offset = np.percentile(
nshuffled_offset_chirps, (5, 50, 95), axis=0) # nshuffled_offset_chirps, (5, 50, 95), axis=0)
rec_shuffled_q5_physical, rec_shuffled_median_physical, rec_shuffled_q95_physical = np.percentile( # rec_shuffled_q5_physical, rec_shuffled_median_physical, rec_shuffled_q95_physical = np.percentile(
nshuffled_physical_chirps, (5, 50, 95), axis=0) # nshuffled_physical_chirps, (5, 50, 95), axis=0)
#### Recording plots #### # #### Recording plots ####
fig, ax = plt.subplots(1, 3, figsize=(28*ps.cm, 16*ps.cm, ), constrained_layout=True, sharey='all') # fig, ax = plt.subplots(1, 3, figsize=(28*ps.cm, 16*ps.cm, ), constrained_layout=True, sharey='all')
ax[0].set_xlabel('Time[s]') # ax[0].set_xlabel('Time[s]')
# Plot chasing onsets # # Plot chasing onsets
ax[0].set_ylabel('Chirp rate [Hz]') # ax[0].set_ylabel('Chirp rate [Hz]')
ax[0].plot(time, cc_chasing_onset_chirps, color=ps.yellow, zorder=2) # ax[0].plot(time, cc_chasing_onset_chirps, color=ps.yellow, zorder=2)
ax0 = ax[0].twinx() # ax0 = ax[0].twinx()
ax0.eventplot(centered_chasing_onset_chirps, linelengths=0.2, colors=ps.gray, alpha=0.25, zorder=1) # ax0.eventplot(centered_chasing_onset_chirps, linelengths=0.2, colors=ps.gray, alpha=0.25, zorder=1)
ax0.vlines(0, 0, 1.5, ps.white, 'dashed') # ax0.vlines(0, 0, 1.5, ps.white, 'dashed')
ax[0].set_zorder(ax0.get_zorder()+1) # ax[0].set_zorder(ax0.get_zorder()+1)
ax[0].patch.set_visible(False) # ax[0].patch.set_visible(False)
ax0.set_yticklabels([]) # ax0.set_yticklabels([])
ax0.set_yticks([]) # ax0.set_yticks([])
ax[0].fill_between(time, rec_shuffled_q5_onset, rec_shuffled_q95_onset, color=ps.gray, alpha=0.5) # ######## median - q5, median + q95
ax[0].plot(time, rec_shuffled_median_onset, color=ps.black) # ax[0].fill_between(time, rec_shuffled_q5_onset, rec_shuffled_q95_onset, color=ps.gray, alpha=0.5)
# ax[0].plot(time, rec_shuffled_median_onset, color=ps.black)
# Plot chasing offets # # Plot chasing offets
ax[1].set_xlabel('Time[s]') # ax[1].set_xlabel('Time[s]')
ax[1].plot(time, cc_chasing_offset_chirps, color=ps.orange, zorder=2) # ax[1].plot(time, cc_chasing_offset_chirps, color=ps.orange, zorder=2)
ax1 = ax[1].twinx() # ax1 = ax[1].twinx()
ax1.eventplot(centered_chasing_offset_chirps, linelengths=0.2, colors=ps.gray, alpha=0.25, zorder=1) # ax1.eventplot(centered_chasing_offset_chirps, linelengths=0.2, colors=ps.gray, alpha=0.25, zorder=1)
ax1.vlines(0, 0, 1.5, ps.white, 'dashed') # ax1.vlines(0, 0, 1.5, ps.white, 'dashed')
ax[1].set_zorder(ax1.get_zorder()+1) # ax[1].set_zorder(ax1.get_zorder()+1)
ax[1].patch.set_visible(False) # ax[1].patch.set_visible(False)
ax1.set_yticklabels([]) # ax1.set_yticklabels([])
ax1.set_yticks([]) # ax1.set_yticks([])
ax[1].fill_between(time, rec_shuffled_q5_offset, rec_shuffled_q95_offset, color=ps.gray, alpha=0.5) # ax[1].fill_between(time, rec_shuffled_q5_offset, rec_shuffled_q95_offset, color=ps.gray, alpha=0.5)
ax[1].plot(time, rec_shuffled_median_offset, color=ps.black) # ax[1].plot(time, rec_shuffled_median_offset, color=ps.black)
# Plot physical contacts # # Plot physical contacts
ax[2].set_xlabel('Time[s]') # ax[2].set_xlabel('Time[s]')
ax[2].plot(time, cc_physical_chirps, color=ps.maroon, zorder=2) # ax[2].plot(time, cc_physical_chirps, color=ps.maroon, zorder=2)
ax2 = ax[2].twinx() # ax2 = ax[2].twinx()
ax2.eventplot(centered_physical_chirps, linelengths=0.2, colors=ps.gray, alpha=0.25, zorder=1) # ax2.eventplot(centered_physical_chirps, linelengths=0.2, colors=ps.gray, alpha=0.25, zorder=1)
ax2.vlines(0, 0, 1.5, ps.white, 'dashed') # ax2.vlines(0, 0, 1.5, ps.white, 'dashed')
ax[2].set_zorder(ax2.get_zorder()+1) # ax[2].set_zorder(ax2.get_zorder()+1)
ax[2].patch.set_visible(False) # ax[2].patch.set_visible(False)
ax2.set_yticklabels([]) # ax2.set_yticklabels([])
ax2.set_yticks([]) # ax2.set_yticks([])
ax[2].fill_between(time, rec_shuffled_q5_physical, rec_shuffled_q95_physical, color=ps.gray, alpha=0.5) # ax[2].fill_between(time, rec_shuffled_q5_physical, rec_shuffled_q95_physical, color=ps.gray, alpha=0.5)
ax[2].plot(time, rec_shuffled_median_physical, ps.black) # ax[2].plot(time, rec_shuffled_median_physical, ps.black)
fig.suptitle(f'Recording: {i}') # fig.suptitle(f'Recording: {i}')
plt.show() # # plt.show()
# plt.close() # plt.close()
nrecording_shuffled_convolved_onset_chirps.append(nshuffled_onset_chirps) # nrecording_shuffled_convolved_onset_chirps.append(nshuffled_onset_chirps)
nrecording_shuffled_convolved_offset_chirps.append(nshuffled_offset_chirps) # nrecording_shuffled_convolved_offset_chirps.append(nshuffled_offset_chirps)
nrecording_shuffled_convolved_physical_chirps.append(nshuffled_physical_chirps) # nrecording_shuffled_convolved_physical_chirps.append(nshuffled_physical_chirps)
#### New shuffle approach ####
bootstrap_onset = []
bootstrap_offset = []
bootstrap_physical = []
# New bootstrapping approach
for n in range(nbootstrapping):
diff_onset = np.diff(
np.sort(flatten(nrecording_centered_onset_chirps)))
diff_offset = np.diff(
np.sort(flatten(nrecording_centered_offset_chirps)))
diff_physical = np.diff(
np.sort(flatten(nrecording_centered_physical_chirps)))
np.random.shuffle(diff_onset)
shuffled_onset = np.cumsum(diff_onset)
np.random.shuffle(diff_offset)
shuffled_offset = np.cumsum(diff_offset)
np.random.shuffle(diff_physical)
shuffled_physical = np.cumsum(diff_physical)
kde_onset (acausal_kde1d(shuffled_onset, time, width))/(27*100)
kde_offset = (acausal_kde1d(shuffled_offset, time, width))/(27*100)
kde_physical = (acausal_kde1d(shuffled_physical, time, width))/(27*100)
bootstrap_onset.append(kde_onset)
bootstrap_offset.append(kde_offset)
bootstrap_physical.append(kde_physical)
# New shuffle approach q5, q50, q95
onset_q5, onset_median, onset_q95 = np.percentile(
bootstrap_onset, [5, 50, 95], axis=0)
offset_q5, offset_median, offset_q95 = np.percentile(
bootstrap_offset, [5, 50, 95], axis=0)
physical_q5, physical_median, physical_q95 = np.percentile(
bootstrap_physical, [5, 50, 95], axis=0)
# vstack um 1. Dim zu cutten # vstack um 1. Dim zu cutten
nrecording_shuffled_convolved_onset_chirps = np.vstack(nrecording_shuffled_convolved_onset_chirps) # nrecording_shuffled_convolved_onset_chirps = np.vstack(nrecording_shuffled_convolved_onset_chirps)
nrecording_shuffled_convolved_offset_chirps = np.vstack(nrecording_shuffled_convolved_offset_chirps) # nrecording_shuffled_convolved_offset_chirps = np.vstack(nrecording_shuffled_convolved_offset_chirps)
nrecording_shuffled_convolved_physical_chirps = np.vstack(nrecording_shuffled_convolved_physical_chirps) # nrecording_shuffled_convolved_physical_chirps = np.vstack(nrecording_shuffled_convolved_physical_chirps)
shuffled_q5_onset, shuffled_median_onset, shuffled_q95_onset = np.percentile(
nrecording_shuffled_convolved_onset_chirps, (5, 50, 95), axis=0)
shuffled_q5_offset, shuffled_median_offset, shuffled_q95_offset = np.percentile(
nrecording_shuffled_convolved_offset_chirps, (5, 50, 95), axis=0)
shuffled_q5_physical, shuffled_median_physical, shuffled_q95_physical = np.percentile(
nrecording_shuffled_convolved_physical_chirps, (5, 50, 95), axis=0)
# Flatten all chirps # shuffled_q5_onset, shuffled_median_onset, shuffled_q95_onset = np.percentile(
# nrecording_shuffled_convolved_onset_chirps, (5, 50, 95), axis=0)
# shuffled_q5_offset, shuffled_median_offset, shuffled_q95_offset = np.percentile(
# nrecording_shuffled_convolved_offset_chirps, (5, 50, 95), axis=0)
# shuffled_q5_physical, shuffled_median_physical, shuffled_q95_physical = np.percentile(
# nrecording_shuffled_convolved_physical_chirps, (5, 50, 95), axis=0)
# Flatten all chirps
all_chirps = np.concatenate(nrecording_chirps).ravel() # not centered all_chirps = np.concatenate(nrecording_chirps).ravel() # not centered
# Flatten event timestamps # Flatten event timestamps
all_onsets = np.concatenate(nrecording_chasing_onsets).ravel() # not centered all_onsets = np.concatenate(
all_offsets = np.concatenate(nrecording_chasing_offsets).ravel() # not centered nrecording_chasing_onsets).ravel() # not centered
all_physicals = np.concatenate(nrecording_physicals).ravel() # not centered all_offsets = np.concatenate(
nrecording_chasing_offsets).ravel() # not centered
all_physicals = np.concatenate(
nrecording_physicals).ravel() # not centered
# Flatten all chirps around events # Flatten all chirps around events
all_onset_chirps = np.concatenate(nrecording_centered_onset_chirps).ravel() # centered all_onset_chirps = np.concatenate(
all_offset_chirps = np.concatenate(nrecording_centered_offset_chirps).ravel() # centered nrecording_centered_onset_chirps).ravel() # centered
all_physical_chirps = np.concatenate(nrecording_centered_physical_chirps).ravel() # centered all_offset_chirps = np.concatenate(
nrecording_centered_offset_chirps).ravel() # centered
all_physical_chirps = np.concatenate(
nrecording_centered_physical_chirps).ravel() # centered
# Convolute all chirps # Convolute all chirps
# Divide by total number of each event over all recordings # Divide by total number of each event over all recordings
all_onset_chirps_convolved = (acausal_kde1d(all_onset_chirps, time, width)) / len(all_onsets) all_onset_chirps_convolved = (acausal_kde1d(
all_offset_chirps_convolved = (acausal_kde1d(all_offset_chirps, time, width)) / len(all_offsets) all_onset_chirps, time, width)) / len(all_onsets)
all_physical_chirps_convolved = (acausal_kde1d(all_physical_chirps, time, width)) / len(all_physicals) all_offset_chirps_convolved = (acausal_kde1d(
all_offset_chirps, time, width)) / len(all_offsets)
all_physical_chirps_convolved = (acausal_kde1d(
all_physical_chirps, time, width)) / len(all_physicals)
# Plot all events with all shuffled # Plot all events with all shuffled
fig, ax = plt.subplots(1, 3, figsize=(28*ps.cm, 16*ps.cm, ), constrained_layout=True, sharey='all') fig, ax = plt.subplots(1, 3, figsize=(
28*ps.cm, 16*ps.cm, ), constrained_layout=True, sharey='all')
# offsets = np.arange(1,28,1) # offsets = np.arange(1,28,1)
ax[0].set_xlabel('Time[s]') ax[0].set_xlabel('Time[s]')
@@ -349,49 +411,62 @@ def main(datapath: str):
ax[0].set_ylabel('Chirp rate [Hz]') ax[0].set_ylabel('Chirp rate [Hz]')
ax[0].plot(time, all_onset_chirps_convolved, color=ps.yellow, zorder=2) ax[0].plot(time, all_onset_chirps_convolved, color=ps.yellow, zorder=2)
ax0 = ax[0].twinx() ax0 = ax[0].twinx()
nrecording_centered_onset_chirps = np.asarray(nrecording_centered_onset_chirps, dtype=object) nrecording_centered_onset_chirps = np.asarray(
ax0.eventplot(np.array(nrecording_centered_onset_chirps), linelengths=0.5, colors=ps.gray, alpha=0.25, zorder=1) nrecording_centered_onset_chirps, dtype=object)
ax0.eventplot(np.array(nrecording_centered_onset_chirps),
linelengths=0.5, colors=ps.gray, alpha=0.25, zorder=1)
ax0.vlines(0, 0, 1.5, ps.white, 'dashed') ax0.vlines(0, 0, 1.5, ps.white, 'dashed')
ax[0].set_zorder(ax0.get_zorder()+1) ax[0].set_zorder(ax0.get_zorder()+1)
ax[0].patch.set_visible(False) ax[0].patch.set_visible(False)
ax0.set_yticklabels([]) ax0.set_yticklabels([])
ax0.set_yticks([]) ax0.set_yticks([])
ax[0].fill_between(time, shuffled_q5_onset, shuffled_q95_onset, color=ps.gray, alpha=0.5) # ax[0].fill_between(time, shuffled_q5_onset, shuffled_q95_onset, color=ps.gray, alpha=0.5)
ax[0].plot(time, shuffled_median_onset, color=ps.black) # ax[0].plot(time, shuffled_median_onset, color=ps.black)
ax[0].fill_between(time, onset_q5, onset_q95, color=ps.gray, alpha=0.5)
ax[0].plot(time, onset_median, color=ps.black)
# Plot chasing offets # Plot chasing offets
ax[1].set_xlabel('Time[s]') ax[1].set_xlabel('Time[s]')
ax[1].plot(time, all_offset_chirps_convolved, color=ps.orange, zorder=2) ax[1].plot(time, all_offset_chirps_convolved, color=ps.orange, zorder=2)
ax1 = ax[1].twinx() ax1 = ax[1].twinx()
nrecording_centered_offset_chirps = np.asarray(nrecording_centered_offset_chirps, dtype=object) nrecording_centered_offset_chirps = np.asarray(
ax1.eventplot(np.array(nrecording_centered_offset_chirps), linelengths=0.5, colors=ps.gray, alpha=0.25, zorder=1) nrecording_centered_offset_chirps, dtype=object)
ax1.eventplot(np.array(nrecording_centered_offset_chirps),
linelengths=0.5, colors=ps.gray, alpha=0.25, zorder=1)
ax1.vlines(0, 0, 1.5, ps.white, 'dashed') ax1.vlines(0, 0, 1.5, ps.white, 'dashed')
ax[1].set_zorder(ax1.get_zorder()+1) ax[1].set_zorder(ax1.get_zorder()+1)
ax[1].patch.set_visible(False) ax[1].patch.set_visible(False)
ax1.set_yticklabels([]) ax1.set_yticklabels([])
ax1.set_yticks([]) ax1.set_yticks([])
ax[1].fill_between(time, shuffled_q5_offset, shuffled_q95_offset, color=ps.gray, alpha=0.5) # ax[1].fill_between(time, shuffled_q5_offset, shuffled_q95_offset, color=ps.gray, alpha=0.5)
ax[1].plot(time, shuffled_median_offset, color=ps.black) # ax[1].plot(time, shuffled_median_offset, color=ps.black)
ax[1].fill_between(time, offset_q5, offset_q95, color=ps.gray, alpha=0.5)
ax[1].plot(time, offset_median, color=ps.black)
# Plot physical contacts # Plot physical contacts
ax[2].set_xlabel('Time[s]') ax[2].set_xlabel('Time[s]')
ax[2].plot(time, all_physical_chirps_convolved, color=ps.maroon, zorder=2) ax[2].plot(time, all_physical_chirps_convolved, color=ps.maroon, zorder=2)
ax2 = ax[2].twinx() ax2 = ax[2].twinx()
nrecording_centered_physical_chirps = np.asarray(nrecording_centered_physical_chirps, dtype=object) nrecording_centered_physical_chirps = np.asarray(
ax2.eventplot(np.array(nrecording_centered_physical_chirps), linelengths=0.5, colors=ps.gray, alpha=0.25, zorder=1) nrecording_centered_physical_chirps, dtype=object)
ax2.eventplot(np.array(nrecording_centered_physical_chirps),
linelengths=0.5, colors=ps.gray, alpha=0.25, zorder=1)
ax2.vlines(0, 0, 1.5, ps.white, 'dashed') ax2.vlines(0, 0, 1.5, ps.white, 'dashed')
ax[2].set_zorder(ax2.get_zorder()+1) ax[2].set_zorder(ax2.get_zorder()+1)
ax[2].patch.set_visible(False) ax[2].patch.set_visible(False)
ax2.set_yticklabels([]) ax2.set_yticklabels([])
ax2.set_yticks([]) ax2.set_yticks([])
ax[2].fill_between(time, shuffled_q5_physical, shuffled_q95_physical, color=ps.gray, alpha=0.5) # ax[2].fill_between(time, shuffled_q5_physical, shuffled_q95_physical, color=ps.gray, alpha=0.5)
ax[2].plot(time, shuffled_median_physical, ps.black) # ax[2].plot(time, shuffled_median_physical, ps.black)
ax[2].fill_between(time, physical_q5, physical_q95,
color=ps.gray, alpha=0.5)
ax[2].plot(time, physical_median, ps.black)
fig.suptitle('All recordings') fig.suptitle('All recordings')
plt.show() plt.show()
# plt.close() plt.close()
embed() embed()
# chasing_durations = [] # chasing_durations = []
# # Calculate chasing duration to evaluate a nice time window for kernel density estimation # # Calculate chasing duration to evaluate a nice time window for kernel density estimation
# for onset, offset in zip(chasing_onsets, chasing_offsets): # for onset, offset in zip(chasing_onsets, chasing_offsets):
@@ -403,7 +478,6 @@ def main(datapath: str):
# plt.show() # plt.show()
# plt.close() # plt.close()
# # Associate chirps to individual fish # # Associate chirps to individual fish
# fish1 = chirps[chirps_fish_ids == fish_ids[0]] # fish1 = chirps[chirps_fish_ids == fish_ids[0]]
# fish2 = chirps[chirps_fish_ids == fish_ids[1]] # fish2 = chirps[chirps_fish_ids == fish_ids[1]]
@@ -412,7 +486,6 @@ def main(datapath: str):
# Convolution over all recordings # Convolution over all recordings
# Rasterplot for each recording # Rasterplot for each recording
# #### Chirps around events, winner VS loser, one recording #### # #### Chirps around events, winner VS loser, one recording ####
# # Load file with fish ids and winner/loser info # # Load file with fish ids and winner/loser info
# meta = pd.read_csv('../data/mount_data/order_meta.csv') # meta = pd.read_csv('../data/mount_data/order_meta.csv')
@@ -421,7 +494,7 @@ def main(datapath: str):
# fish2 = current_recording['rec_id2'].values # fish2 = current_recording['rec_id2'].values
# # Implement check if fish_ids from meta and chirp detection are the same??? # # Implement check if fish_ids from meta and chirp detection are the same???
# winner = current_recording['winner'].values # winner = current_recording['winner'].values
# if winner == fish1: # if winner == fish1:
# loser = fish2 # loser = fish2
# elif winner == fish2: # elif winner == fish2:
@@ -505,7 +578,6 @@ def main(datapath: str):
# ax5.set_yticks([]) # ax5.set_yticks([])
# plt.show() # plt.show()
# plt.close() # plt.close()
# for i in range(len(fish_ids)): # for i in range(len(fish_ids)):
# fish = fish_ids[i] # fish = fish_ids[i]
@@ -515,7 +587,6 @@ def main(datapath: str):
#### Chirps around events, only losers, one recording #### #### Chirps around events, only losers, one recording ####
if __name__ == '__main__': if __name__ == '__main__':
# Path to the data # Path to the data
datapath = '../data/mount_data/' datapath = '../data/mount_data/'

View File

@@ -7,21 +7,12 @@ from IPython import embed
# check rec ../data/mount_data/2020-03-25-10_00/ starting at 3175 # check rec ../data/mount_data/2020-03-25-10_00/ starting at 3175
def main(datapaths): def get_valid_datasets(dataroot):
for path in datapaths:
chirpdetection(path, plot='show')
if __name__ == '__main__':
dataroot = '../data/mount_data/'
datasets = sorted([name for name in os.listdir(dataroot) if os.path.isdir( datasets = sorted([name for name in os.listdir(dataroot) if os.path.isdir(
os.path.join(dataroot, name))]) os.path.join(dataroot, name))])
valid_datasets = [] valid_datasets = []
for dataset in datasets: for dataset in datasets:
path = os.path.join(dataroot, dataset) path = os.path.join(dataroot, dataset)
@@ -43,9 +34,25 @@ if __name__ == '__main__':
datapaths = [os.path.join(dataroot, dataset) + datapaths = [os.path.join(dataroot, dataset) +
'/' for dataset in valid_datasets] '/' for dataset in valid_datasets]
return datapaths, valid_datasets
def main(datapaths):
for path in datapaths:
chirpdetection(path, plot='show')
if __name__ == '__main__':
dataroot = '../data/mount_data/'
datapaths, valid_datasets= get_valid_datasets(dataroot)
recs = pd.DataFrame(columns=['recording'], data=valid_datasets) recs = pd.DataFrame(columns=['recording'], data=valid_datasets)
recs.to_csv('../recs.csv', index=False) recs.to_csv('../recs.csv', index=False)
datapaths = ['../data/mount_data/2020-03-25-10_00/'] # datapaths = ['../data/mount_data/2020-03-25-10_00/']
main(datapaths) main(datapaths)
# window 1524 + 244 in dataset index 4 is nice example # window 1524 + 244 in dataset index 4 is nice example

View File

@@ -1,13 +1,10 @@
import numpy as np import numpy as np
import os
import os
import numpy as np
from IPython import embed from IPython import embed
from pandas import read_csv from pandas import read_csv
from modules.logger import makeLogger from modules.logger import makeLogger
from modules.datahandling import causal_kde1d, acausal_kde1d, flatten
logger = makeLogger(__name__) logger = makeLogger(__name__)
@@ -18,46 +15,60 @@ class Behavior:
Attributes Attributes
---------- ----------
behavior: 0: chasing onset, 1: chasing offset, 2: physical contact behavior: 0: chasing onset, 1: chasing offset, 2: physical contact
behavior_type: behavior_type:
behavioral_category: behavioral_category:
comment_start: comment_start:
comment_stop: comment_stop:
dataframe: pandas dataframe with all the data dataframe: pandas dataframe with all the data
duration_s: duration_s:
media_file: media_file:
observation_date: observation_date:
observation_id: observation_id:
start_s: start time of the event in seconds start_s: start time of the event in seconds
stop_s: stop time of the event in seconds stop_s: stop time of the event in seconds
total_length: total_length:
""" """
def __init__(self, folder_path: str) -> None: def __init__(self, folder_path: str) -> None:
LED_on_time_BORIS = np.load(os.path.join(folder_path, 'LED_on_time.npy'), allow_pickle=True) LED_on_time_BORIS = np.load(os.path.join(
folder_path, 'LED_on_time.npy'), allow_pickle=True)
csv_filename = [f for f in os.listdir(folder_path) if f.endswith('.csv')][0] csv_filename = os.path.split(folder_path[:-1])[-1]
logger.info(f'CSV file: {csv_filename}') csv_filename = '-'.join(csv_filename.split('-')[:-1]) + '.csv'
# embed()
# csv_filename = [f for f in os.listdir(
# folder_path) if f.endswith('.csv')][0]
# logger.info(f'CSV file: {csv_filename}')
self.dataframe = read_csv(os.path.join(folder_path, csv_filename)) self.dataframe = read_csv(os.path.join(folder_path, csv_filename))
self.chirps = np.load(os.path.join(folder_path, 'chirps.npy'), allow_pickle=True) self.chirps = np.load(os.path.join(
self.chirps_ids = np.load(os.path.join(folder_path, 'chirp_ids.npy'), allow_pickle=True) folder_path, 'chirps.npy'), allow_pickle=True)
self.chirps_ids = np.load(os.path.join(
folder_path, 'chirp_ids.npy'), allow_pickle=True)
self.ident = np.load(os.path.join(folder_path, 'ident_v.npy'), allow_pickle=True) self.ident = np.load(os.path.join(
self.idx = np.load(os.path.join(folder_path, 'idx_v.npy'), allow_pickle=True) folder_path, 'ident_v.npy'), allow_pickle=True)
self.freq = np.load(os.path.join(folder_path, 'fund_v.npy'), allow_pickle=True) self.idx = np.load(os.path.join(
self.time = np.load(os.path.join(folder_path, "times.npy"), allow_pickle=True) folder_path, 'idx_v.npy'), allow_pickle=True)
self.spec = np.load(os.path.join(folder_path, "spec.npy"), allow_pickle=True) self.freq = np.load(os.path.join(
folder_path, 'fund_v.npy'), allow_pickle=True)
self.time = np.load(os.path.join(
folder_path, "times.npy"), allow_pickle=True)
self.spec = np.load(os.path.join(
folder_path, "spec.npy"), allow_pickle=True)
for k, key in enumerate(self.dataframe.keys()): for k, key in enumerate(self.dataframe.keys()):
key = key.lower() key = key.lower()
if ' ' in key: if ' ' in key:
key = key.replace(' ', '_') key = key.replace(' ', '_')
if '(' in key: if '(' in key:
key = key.replace('(', '') key = key.replace('(', '')
key = key.replace(')', '') key = key.replace(')', '')
setattr(self, key, np.array(self.dataframe[self.dataframe.keys()[k]])) setattr(self, key, np.array(
self.dataframe[self.dataframe.keys()[k]]))
last_LED_t_BORIS = LED_on_time_BORIS[-1] last_LED_t_BORIS = LED_on_time_BORIS[-1]
real_time_range = self.time[-1] - self.time[0] real_time_range = self.time[-1] - self.time[0]
factor = 1.034141 factor = 1.034141
@@ -67,33 +78,92 @@ class Behavior:
def correct_chasing_events( def correct_chasing_events(
category: np.ndarray, category: np.ndarray,
timestamps: np.ndarray timestamps: np.ndarray
) -> tuple[np.ndarray, np.ndarray]: ) -> tuple[np.ndarray, np.ndarray]:
onset_ids = np.arange( onset_ids = np.arange(
len(category))[category == 0] len(category))[category == 0]
offset_ids = np.arange( offset_ids = np.arange(
len(category))[category == 1] len(category))[category == 1]
woring_bh = np.arange(len(category))[category!=2][:-1][np.diff(category[category!=2])==0] wrong_bh = np.arange(len(category))[
category != 2][:-1][np.diff(category[category != 2]) == 0]
if category[category != 2][-1] == 0:
wrong_bh = np.append(
wrong_bh,
np.arange(len(category))[category != 2][-1])
if onset_ids[0] > offset_ids[0]: if onset_ids[0] > offset_ids[0]:
offset_ids = np.delete(offset_ids, 0) offset_ids = np.delete(offset_ids, 0)
help_index = offset_ids[0] help_index = offset_ids[0]
woring_bh = np.append(woring_bh, help_index) wrong_bh = np.append(wrong_bh[help_index])
category = np.delete(category, woring_bh) category = np.delete(category, wrong_bh)
timestamps = np.delete(timestamps, woring_bh) timestamps = np.delete(timestamps, wrong_bh)
new_onset_ids = np.arange(
len(category))[category == 0]
new_offset_ids = np.arange(
len(category))[category == 1]
# Check whether on- or offset is longer and calculate length difference # Check whether on- or offset is longer and calculate length difference
if len(onset_ids) > len(offset_ids):
len_diff = len(onset_ids) - len(offset_ids) if len(new_onset_ids) > len(new_offset_ids):
logger.info(f'Onsets are greater than offsets by {len_diff}') embed()
elif len(onset_ids) < len(offset_ids): logger.warning('Onsets are greater than offsets')
len_diff = len(offset_ids) - len(onset_ids) elif len(new_onset_ids) < len(new_offset_ids):
logger.info(f'Offsets are greater than onsets by {len_diff}') logger.warning('Offsets are greater than onsets')
elif len(onset_ids) == len(offset_ids): elif len(new_onset_ids) == len(new_offset_ids):
logger.info('Chasing events are equal') # logger.info('Chasing events are equal')
pass
return category, timestamps
return category, timestamps def center_chirps(
events: np.ndarray,
chirps: np.ndarray,
time_before_event: int,
time_after_event: int,
# dt: float,
# width: float,
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
event_chirps = [] # chirps that are in specified window around event
# timestamps of chirps around event centered on the event timepoint
centered_chirps = []
for event_timestamp in events:
start = event_timestamp - time_before_event
stop = event_timestamp + time_after_event
chirps_around_event = [c for c in chirps if (c >= start) & (c <= stop)]
if len(chirps_around_event) == 0:
continue
centered_chirps.append(chirps_around_event - event_timestamp)
event_chirps.append(chirps_around_event)
centered_chirps = np.sort(flatten(centered_chirps))
event_chirps = np.sort(flatten(event_chirps))
if len(centered_chirps) != len(event_chirps):
raise ValueError(
'Non centered chirps and centered chirps are not equal')
# time = np.arange(-time_before_event, time_after_event, dt)
# # Kernel density estimation with some if's
# if len(centered_chirps) == 0:
# centered_chirps = np.array([])
# centered_chirps_convolved = np.zeros(len(time))
# else:
# # convert list of arrays to one array for plotting
# centered_chirps = np.concatenate(centered_chirps, axis=0)
# centered_chirps_convolved = (acausal_kde1d(
# centered_chirps, time, width)) / len(event)
return centered_chirps

View File

@@ -108,9 +108,10 @@ def PlotStyle() -> None:
@classmethod @classmethod
def set_boxplot_color(cls, bp, color): def set_boxplot_color(cls, bp, color):
plt.setp(bp["boxes"], color=color) plt.setp(bp["boxes"], color=color)
plt.setp(bp["whiskers"], color=color) plt.setp(bp["whiskers"], color=white)
plt.setp(bp["caps"], color=color) plt.setp(bp["caps"], color=white)
plt.setp(bp["medians"], color=color) plt.setp(bp["medians"], color=white)
@classmethod @classmethod
def label_subplots(cls, labels, axes, fig): def label_subplots(cls, labels, axes, fig):

View File

@@ -0,0 +1,277 @@
import numpy as np
from extract_chirps import get_valid_datasets
import os
import numpy as np
import matplotlib.pyplot as plt
from thunderfish.powerspectrum import decibel
from IPython import embed
from pandas import read_csv
from modules.logger import makeLogger
from modules.plotstyle import PlotStyle
from modules.behaviour_handling import Behavior, correct_chasing_events
ps = PlotStyle()
logger = makeLogger(__name__)
def get_chirp_winner_loser(folder_name, Behavior, order_meta_df):
foldername = folder_name.split('/')[-2]
winner_row = order_meta_df[order_meta_df['recording'] == foldername]
winner = winner_row['winner'].values[0].astype(int)
winner_fish1 = winner_row['fish1'].values[0].astype(int)
winner_fish2 = winner_row['fish2'].values[0].astype(int)
if winner > 0:
if winner == winner_fish1:
winner_fish_id = winner_row['rec_id1'].values[0]
loser_fish_id = winner_row['rec_id2'].values[0]
elif winner == winner_fish2:
winner_fish_id = winner_row['rec_id2'].values[0]
loser_fish_id = winner_row['rec_id1'].values[0]
chirp_winner = len(
Behavior.chirps[Behavior.chirps_ids == winner_fish_id])
chirp_loser = len(
Behavior.chirps[Behavior.chirps_ids == loser_fish_id])
return chirp_winner, chirp_loser
else:
return np.nan, np.nan
def get_chirp_size(folder_name, Behavior, order_meta_df, id_meta_df):
foldername = folder_name.split('/')[-2]
folder_row = order_meta_df[order_meta_df['recording'] == foldername]
fish1 = folder_row['fish1'].values[0].astype(int)
fish2 = folder_row['fish2'].values[0].astype(int)
groub = folder_row['group'].values[0].astype(int)
size_fish1_row = id_meta_df[(id_meta_df['group'] == groub) & (
id_meta_df['fish'] == fish1)]
size_fish2_row = id_meta_df[(id_meta_df['group'] == groub) & (
id_meta_df['fish'] == fish2)]
size_winners = [size_fish1_row[col].values[0]
for col in ['l1', 'l2', 'l3']]
mean_size_winner = np.nanmean(size_winners)
size_losers = [size_fish2_row[col].values[0] for col in ['l1', 'l2', 'l3']]
mean_size_loser = np.nanmean(size_losers)
if mean_size_winner > mean_size_loser:
size_diff = mean_size_winner - mean_size_loser
winner_fish_id = folder_row['rec_id1'].values[0]
loser_fish_id = folder_row['rec_id2'].values[0]
elif mean_size_winner < mean_size_loser:
size_diff = mean_size_loser - mean_size_winner
winner_fish_id = folder_row['rec_id2'].values[0]
loser_fish_id = folder_row['rec_id1'].values[0]
else:
size_diff = np.nan
winner_fish_id = np.nan
loser_fish_id = np.nan
chirp_diff = len(Behavior.chirps[Behavior.chirps_ids == winner_fish_id]) - len(
Behavior.chirps[Behavior.chirps_ids == loser_fish_id])
return size_diff, chirp_diff
def get_chirp_freq(folder_name, Behavior, order_meta_df):
foldername = folder_name.split('/')[-2]
folder_row = order_meta_df[order_meta_df['recording'] == foldername]
fish1 = folder_row['rec_id1'].values[0].astype(int)
fish2 = folder_row['rec_id2'].values[0].astype(int)
chirp_freq_fish1 = np.nanmedian(
Behavior.freq[Behavior.ident == fish1])
chirp_freq_fish2 = np.nanmedian(
Behavior.freq[Behavior.ident == fish2])
if chirp_freq_fish1 > chirp_freq_fish2:
freq_diff = chirp_freq_fish1 - chirp_freq_fish2
winner_fish_id = folder_row['rec_id1'].values[0]
loser_fish_id = folder_row['rec_id2'].values[0]
elif chirp_freq_fish1 < chirp_freq_fish2:
freq_diff = chirp_freq_fish2 - chirp_freq_fish1
winner_fish_id = folder_row['rec_id2'].values[0]
loser_fish_id = folder_row['rec_id1'].values[0]
chirp_diff = len(Behavior.chirps[Behavior.chirps_ids == winner_fish_id]) - len(
Behavior.chirps[Behavior.chirps_ids == loser_fish_id])
return freq_diff, chirp_diff
def main(datapath: str):
foldernames = [
datapath + x + '/' for x in os.listdir(datapath) if os.path.isdir(datapath+x)]
foldernames, _ = get_valid_datasets(datapath)
path_order_meta = (
'/').join(foldernames[0].split('/')[:-2]) + '/order_meta.csv'
order_meta_df = read_csv(path_order_meta)
order_meta_df['recording'] = order_meta_df['recording'].str[1:-1]
path_id_meta = (
'/').join(foldernames[0].split('/')[:-2]) + '/id_meta.csv'
id_meta_df = read_csv(path_id_meta)
chirps_winner = []
size_diffs = []
size_chirps_diffs = []
chirps_loser = []
freq_diffs = []
freq_chirps_diffs = []
for foldername in foldernames:
# behabvior is pandas dataframe with all the data
if foldername == '../data/mount_data/2020-05-12-10_00/':
continue
bh = Behavior(foldername)
# chirps are not sorted in time (presumably due to prior groupings)
# get and sort chirps and corresponding fish_ids of the chirps
category = bh.behavior
timestamps = bh.start_s
# Correct for doubles in chasing on- and offsets to get the right on-/offset pairs
# Get rid of tracking faults (two onsets or two offsets after another)
category, timestamps = correct_chasing_events(category, timestamps)
# winner_chirp, loser_chirp = get_chirp_winner_loser(
# foldername, bh, order_meta_df)
# chirps_winner.append(winner_chirp)
# chirps_loser.append(loser_chirp)
# size_diff, chirp_diff = get_chirp_size(
# foldername, bh, order_meta_df, id_meta_df)
# size_diffs.append(size_diff)
# size_chirps_diffs.append(chirp_diff)
# freq_diff, freq_chirps_diff = get_chirp_freq(
# foldername, bh, order_meta_df)
# freq_diffs.append(freq_diff)
# freq_chirps_diffs.append(freq_chirps_diff)
folder_name = foldername.split('/')[-2]
winner_row = order_meta_df[order_meta_df['recording'] == folder_name]
winner = winner_row['winner'].values[0].astype(int)
winner_fish1 = winner_row['fish1'].values[0].astype(int)
winner_fish2 = winner_row['fish2'].values[0].astype(int)
groub = winner_row['group'].values[0].astype(int)
size_rows = id_meta_df[id_meta_df['group'] == groub]
if winner == winner_fish1:
winner_fish_id = winner_row['rec_id1'].values[0]
loser_fish_id = winner_row['rec_id2'].values[0]
size_winners = []
for l in ['l1', 'l2', 'l3']:
size_winner = size_rows[size_rows['fish']
== winner_fish1][l].values[0]
size_winners.append(size_winner)
mean_size_winner = np.nanmean(size_winners)
size_losers = []
for l in ['l1', 'l2', 'l3']:
size_loser = size_rows[size_rows['fish']
== winner_fish2][l].values[0]
size_losers.append(size_loser)
mean_size_loser = np.nanmean(size_losers)
size_diffs.append(mean_size_winner - mean_size_loser)
elif winner == winner_fish2:
winner_fish_id = winner_row['rec_id2'].values[0]
loser_fish_id = winner_row['rec_id1'].values[0]
size_winners = []
for l in ['l1', 'l2', 'l3']:
size_winner = size_rows[size_rows['fish']
== winner_fish2][l].values[0]
size_winners.append(size_winner)
mean_size_winner = np.nanmean(size_winners)
size_losers = []
for l in ['l1', 'l2', 'l3']:
size_loser = size_rows[size_rows['fish']
== winner_fish1][l].values[0]
size_losers.append(size_loser)
mean_size_loser = np.nanmean(size_losers)
size_diffs.append(mean_size_winner - mean_size_loser)
else:
continue
print(foldername)
all_fish_ids = np.unique(bh.chirps_ids)
chirp_winner = len(bh.chirps[bh.chirps_ids == winner_fish_id])
chirp_loser = len(bh.chirps[bh.chirps_ids == loser_fish_id])
freq_winner = np.nanmedian(bh.freq[bh.ident == winner_fish_id])
freq_loser = np.nanmedian(bh.freq[bh.ident == loser_fish_id])
chirps_winner.append(chirp_winner)
chirps_loser.append(chirp_loser)
size_chirps_diffs.append(chirp_winner - chirp_loser)
freq_diffs.append(freq_winner - freq_loser)
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(
22*ps.cm, 12*ps.cm), width_ratios=[1.5, 1, 1])
plt.subplots_adjust(left=0.098, right=0.945, top=0.94, wspace=0.343)
scatterwinner = 1.15
scatterloser = 1.85
chirps_winner = np.asarray(chirps_winner)[~np.isnan(chirps_winner)]
chirps_loser = np.asarray(chirps_loser)[~np.isnan(chirps_loser)]
bplot1 = ax1.boxplot(chirps_winner, positions=[
1], showfliers=False, patch_artist=True)
bplot2 = ax1.boxplot(chirps_loser, positions=[
2], showfliers=False, patch_artist=True)
ax1.scatter(np.ones(len(chirps_winner)) *
scatterwinner, chirps_winner, color='r')
ax1.scatter(np.ones(len(chirps_loser)) *
scatterloser, chirps_loser, color='r')
ax1.set_xticklabels(['winner', 'loser'])
ax1.text(0.1, 0.9, f'n = {len(chirps_winner)}',
transform=ax1.transAxes, color=ps.white)
for w, l in zip(chirps_winner, chirps_loser):
ax1.plot([scatterwinner, scatterloser], [w, l],
color='r', alpha=0.5, linewidth=0.5)
ax1.set_ylabel('Chirps [n]', color=ps.white)
colors1 = ps.red
ps.set_boxplot_color(bplot1, colors1)
colors1 = ps.orange
ps.set_boxplot_color(bplot2, colors1)
ax2.scatter(size_diffs, size_chirps_diffs, color='r')
ax2.set_xlabel('Size difference [mm]')
ax2.set_ylabel('Chirps [n]')
ax3.scatter(freq_diffs, size_chirps_diffs, color='r')
# ax3.scatter(freq_diffs, freq_chirps_diffs, color='r')
ax3.set_xlabel('Frequency difference [Hz]')
ax3.set_yticklabels([])
ax3.set
plt.savefig('../poster/figs/chirps_winner_loser.pdf')
plt.show()
if __name__ == '__main__':
# Path to the data
datapath = '../data/mount_data/'
main(datapath)

View File

@@ -1,160 +0,0 @@
import numpy as np
import os
import numpy as np
import matplotlib.pyplot as plt
from thunderfish.powerspectrum import decibel
from IPython import embed
from pandas import read_csv
from modules.logger import makeLogger
from modules.plotstyle import PlotStyle
from modules.behaviour_handling import Behavior, correct_chasing_events
ps = PlotStyle()
logger = makeLogger(__name__)
def main(datapath: str):
foldernames = [
datapath + x + '/' for x in os.listdir(datapath) if os.path.isdir(datapath+x)]
path_order_meta = (
'/').join(foldernames[0].split('/')[:-2]) + '/order_meta.csv'
order_meta_df = read_csv(path_order_meta)
order_meta_df['recording'] = order_meta_df['recording'].str[1:-1]
path_id_meta = (
'/').join(foldernames[0].split('/')[:-2]) + '/id_meta.csv'
id_meta_df = read_csv(path_id_meta)
chirps_winner = []
size_diff = []
chirps_diff = []
chirps_loser = []
freq_diff = []
for foldername in foldernames:
# behabvior is pandas dataframe with all the data
if foldername == '../data/mount_data/2020-05-12-10_00/':
continue
bh = Behavior(foldername)
# chirps are not sorted in time (presumably due to prior groupings)
# get and sort chirps and corresponding fish_ids of the chirps
category = bh.behavior
timestamps = bh.start_s
# Correct for doubles in chasing on- and offsets to get the right on-/offset pairs
# Get rid of tracking faults (two onsets or two offsets after another)
category, timestamps = correct_chasing_events(category, timestamps)
folder_name = foldername.split('/')[-2]
winner_row = order_meta_df[order_meta_df['recording'] == folder_name]
winner = winner_row['winner'].values[0].astype(int)
winner_fish1 = winner_row['fish1'].values[0].astype(int)
winner_fish2 = winner_row['fish2'].values[0].astype(int)
groub = winner_row['group'].values[0].astype(int)
size_rows = id_meta_df[id_meta_df['group'] == groub]
if winner == winner_fish1:
winner_fish_id = winner_row['rec_id1'].values[0]
loser_fish_id = winner_row['rec_id2'].values[0]
size_winners = []
for l in ['l1', 'l2', 'l3']:
size_winner = size_rows[size_rows['fish']== winner_fish1][l].values[0]
size_winners.append(size_winner)
mean_size_winner = np.nanmean(size_winners)
size_losers = []
for l in ['l1', 'l2', 'l3']:
size_loser = size_rows[size_rows['fish']== winner_fish2][l].values[0]
size_losers.append(size_loser)
mean_size_loser = np.nanmean(size_losers)
size_diff.append(mean_size_winner - mean_size_loser)
elif winner == winner_fish2:
winner_fish_id = winner_row['rec_id2'].values[0]
loser_fish_id = winner_row['rec_id1'].values[0]
size_winners = []
for l in ['l1', 'l2', 'l3']:
size_winner = size_rows[size_rows['fish']== winner_fish2][l].values[0]
size_winners.append(size_winner)
mean_size_winner = np.nanmean(size_winners)
size_losers = []
for l in ['l1', 'l2', 'l3']:
size_loser = size_rows[size_rows['fish']== winner_fish1][l].values[0]
size_losers.append(size_loser)
mean_size_loser = np.nanmean(size_losers)
size_diff.append(mean_size_winner - mean_size_loser)
else:
continue
print(foldername)
all_fish_ids = np.unique(bh.chirps_ids)
chirp_winner = len(bh.chirps[bh.chirps_ids == winner_fish_id])
chirp_loser = len(bh.chirps[bh.chirps_ids == loser_fish_id])
freq_winner = np.nanmedian(bh.freq[bh.ident==winner_fish_id])
freq_loser = np.nanmedian(bh.freq[bh.ident==loser_fish_id])
chirps_winner.append(chirp_winner)
chirps_loser.append(chirp_loser)
chirps_diff.append(chirp_winner - chirp_loser)
freq_diff.append(freq_winner - freq_loser)
fish1_id = all_fish_ids[0]
fish2_id = all_fish_ids[1]
print(winner_fish_id)
print(all_fish_ids)
fig, (ax1, ax2, ax3) = plt.subplots(1,3, figsize=(10,5))
scatterwinner = 1.15
scatterloser = 1.85
bplot1 = ax1.boxplot(chirps_winner, positions=[
1], showfliers=False, patch_artist=True)
bplot2 = ax1.boxplot(chirps_loser, positions=[
2], showfliers=False, patch_artist=True)
ax1.scatter(np.ones(len(chirps_winner))*scatterwinner, chirps_winner, color='r')
ax1.scatter(np.ones(len(chirps_loser))*scatterloser, chirps_loser, color='r')
ax1.set_xticklabels(['winner', 'loser'])
ax1.text(0.9, 0.9, f'n = {len(chirps_winner)}', transform=ax1.transAxes, color= ps.white)
for w, l in zip(chirps_winner, chirps_loser):
ax1.plot([scatterwinner, scatterloser], [w, l], color='r', alpha=0.5, linewidth=0.5)
colors1 = ps.red
ps.set_boxplot_color(bplot1, colors1)
colors1 = ps.orange
ps.set_boxplot_color(bplot2, colors1)
ax1.set_ylabel('Chirpscounts [n]')
ax2.scatter(size_diff, chirps_diff, color='r')
ax2.set_xlabel('Size difference [mm]')
ax2.set_ylabel('Chirps difference [n]')
ax3.scatter(freq_diff, chirps_diff, color='r')
ax3.set_xlabel('Frequency difference [Hz]')
ax3.set_yticklabels([])
ax3.set
plt.savefig('../poster/figs/chirps_winner_loser.pdf')
plt.show()
if __name__ == '__main__':
# Path to the data
datapath = '../data/mount_data/'
main(datapath)

319
code/plot_chirp_size.py Normal file
View File

@@ -0,0 +1,319 @@
import numpy as np
from extract_chirps import get_valid_datasets
import os
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import pearsonr, spearmanr, wilcoxon
from thunderfish.powerspectrum import decibel
from IPython import embed
from pandas import read_csv
from modules.logger import makeLogger
from modules.plotstyle import PlotStyle
from modules.behaviour_handling import Behavior, correct_chasing_events
ps = PlotStyle()
logger = makeLogger(__name__)
def get_chirp_winner_loser(folder_name, Behavior, order_meta_df):
foldername = folder_name.split('/')[-2]
winner_row = order_meta_df[order_meta_df['recording'] == foldername]
winner = winner_row['winner'].values[0].astype(int)
winner_fish1 = winner_row['fish1'].values[0].astype(int)
winner_fish2 = winner_row['fish2'].values[0].astype(int)
if winner > 0:
if winner == winner_fish1:
winner_fish_id = winner_row['rec_id1'].values[0]
loser_fish_id = winner_row['rec_id2'].values[0]
elif winner == winner_fish2:
winner_fish_id = winner_row['rec_id2'].values[0]
loser_fish_id = winner_row['rec_id1'].values[0]
chirp_winner = len(
Behavior.chirps[Behavior.chirps_ids == winner_fish_id])
chirp_loser = len(
Behavior.chirps[Behavior.chirps_ids == loser_fish_id])
return chirp_winner, chirp_loser
else:
return np.nan, np.nan
def get_chirp_size(folder_name, Behavior, order_meta_df, id_meta_df):
foldername = folder_name.split('/')[-2]
folder_row = order_meta_df[order_meta_df['recording'] == foldername]
fish1 = folder_row['fish1'].values[0].astype(int)
fish2 = folder_row['fish2'].values[0].astype(int)
winner = folder_row['winner'].values[0].astype(int)
groub = folder_row['group'].values[0].astype(int)
size_fish1_row = id_meta_df[(id_meta_df['group'] == groub) & (
id_meta_df['fish'] == fish1)]
size_fish2_row = id_meta_df[(id_meta_df['group'] == groub) & (
id_meta_df['fish'] == fish2)]
size_winners = [size_fish1_row[col].values[0]
for col in ['l1', 'l2', 'l3']]
size_fish1 = np.nanmean(size_winners)
size_losers = [size_fish2_row[col].values[0] for col in ['l1', 'l2', 'l3']]
size_fish2 = np.nanmean(size_losers)
if winner == fish1:
if size_fish1 > size_fish2:
size_diff_bigger = size_fish1 - size_fish2
size_diff_smaller = size_fish2 - size_fish1
elif size_fish1 < size_fish2:
size_diff_bigger = size_fish1 - size_fish2
size_diff_smaller = size_fish2 - size_fish1
else:
size_diff_bigger = np.nan
size_diff_smaller = np.nan
winner_fish_id = np.nan
loser_fish_id = np.nan
return size_diff_bigger, size_diff_smaller, winner_fish_id, loser_fish_id
winner_fish_id = folder_row['rec_id1'].values[0]
loser_fish_id = folder_row['rec_id2'].values[0]
elif winner == fish2:
if size_fish2 > size_fish1:
size_diff_bigger = size_fish2 - size_fish1
size_diff_smaller = size_fish1 - size_fish2
elif size_fish2 < size_fish1:
size_diff_bigger = size_fish2 - size_fish1
size_diff_smaller = size_fish1 - size_fish2
else:
size_diff_bigger = np.nan
size_diff_smaller = np.nan
winner_fish_id = np.nan
loser_fish_id = np.nan
return size_diff_bigger, size_diff_smaller, winner_fish_id, loser_fish_id
winner_fish_id = folder_row['rec_id2'].values[0]
loser_fish_id = folder_row['rec_id1'].values[0]
else:
size_diff_bigger = np.nan
size_diff_smaller = np.nan
winner_fish_id = np.nan
loser_fish_id = np.nan
return size_diff_bigger, size_diff_smaller, winner_fish_id, loser_fish_id
chirp_winner = len(
Behavior.chirps[Behavior.chirps_ids == winner_fish_id])
chirp_loser = len(
Behavior.chirps[Behavior.chirps_ids == loser_fish_id])
return size_diff_bigger, chirp_winner, size_diff_smaller, chirp_loser
def get_chirp_freq(folder_name, Behavior, order_meta_df):
foldername = folder_name.split('/')[-2]
folder_row = order_meta_df[order_meta_df['recording'] == foldername]
fish1 = folder_row['fish1'].values[0].astype(int)
fish2 = folder_row['fish2'].values[0].astype(int)
fish1_freq = folder_row['rec_id1'].values[0].astype(int)
fish2_freq = folder_row['rec_id2'].values[0].astype(int)
winner = folder_row['winner'].values[0].astype(int)
chirp_freq_fish1 = np.nanmedian(
Behavior.freq[Behavior.ident == fish1_freq])
chirp_freq_fish2 = np.nanmedian(
Behavior.freq[Behavior.ident == fish2_freq])
if winner == fish1:
# if chirp_freq_fish1 > chirp_freq_fish2:
# freq_diff_higher = chirp_freq_fish1 - chirp_freq_fish2
# freq_diff_lower = chirp_freq_fish2 - chirp_freq_fish1
# elif chirp_freq_fish1 < chirp_freq_fish2:
# freq_diff_higher = chirp_freq_fish1 - chirp_freq_fish2
# freq_diff_lower = chirp_freq_fish2 - chirp_freq_fish1
# else:
# freq_diff_higher = np.nan
# freq_diff_lower = np.nan
# winner_fish_id = np.nan
# loser_fish_id = np.nan
winner_fish_id = folder_row['rec_id1'].values[0]
winner_fish_freq = chirp_freq_fish1
loser_fish_id = folder_row['rec_id2'].values[0]
loser_fish_freq = chirp_freq_fish2
elif winner == fish2:
# if chirp_freq_fish2 > chirp_freq_fish1:
# freq_diff_higher = chirp_freq_fish2 - chirp_freq_fish1
# freq_diff_lower = chirp_freq_fish1 - chirp_freq_fish2
# elif chirp_freq_fish2 < chirp_freq_fish1:
# freq_diff_higher = chirp_freq_fish2 - chirp_freq_fish1
# freq_diff_lower = chirp_freq_fish1 - chirp_freq_fish2
# else:
# freq_diff_higher = np.nan
# freq_diff_lower = np.nan
# winner_fish_id = np.nan
# loser_fish_id = np.nan
winner_fish_id = folder_row['rec_id2'].values[0]
winner_fish_freq = chirp_freq_fish2
loser_fish_id = folder_row['rec_id1'].values[0]
loser_fish_freq = chirp_freq_fish1
else:
winner_fish_freq = np.nan
loser_fish_freq = np.nan
winner_fish_id = np.nan
loser_fish_id = np.nan
chirp_winner = len(
Behavior.chirps[Behavior.chirps_ids == winner_fish_id])
chirp_loser = len(
Behavior.chirps[Behavior.chirps_ids == loser_fish_id])
return winner_fish_freq, chirp_winner, loser_fish_freq, chirp_loser
def main(datapath: str):
foldernames = [
datapath + x + '/' for x in os.listdir(datapath) if os.path.isdir(datapath+x)]
foldernames, _ = get_valid_datasets(datapath)
path_order_meta = (
'/').join(foldernames[0].split('/')[:-2]) + '/order_meta.csv'
order_meta_df = read_csv(path_order_meta)
order_meta_df['recording'] = order_meta_df['recording'].str[1:-1]
path_id_meta = (
'/').join(foldernames[0].split('/')[:-2]) + '/id_meta.csv'
id_meta_df = read_csv(path_id_meta)
chirps_winner = []
size_diffs_winner = []
size_diffs_loser = []
size_chirps_winner = []
size_chirps_loser = []
freq_diffs_higher = []
freq_diffs_lower = []
freq_chirps_winner = []
freq_chirps_loser = []
chirps_loser = []
freq_diffs = []
freq_chirps_diffs = []
for foldername in foldernames:
# behabvior is pandas dataframe with all the data
if foldername == '../data/mount_data/2020-05-12-10_00/':
continue
bh = Behavior(foldername)
# chirps are not sorted in time (presumably due to prior groupings)
# get and sort chirps and corresponding fish_ids of the chirps
category = bh.behavior
timestamps = bh.start_s
# Correct for doubles in chasing on- and offsets to get the right on-/offset pairs
# Get rid of tracking faults (two onsets or two offsets after another)
category, timestamps = correct_chasing_events(category, timestamps)
winner_chirp, loser_chirp = get_chirp_winner_loser(
foldername, bh, order_meta_df)
chirps_winner.append(winner_chirp)
chirps_loser.append(loser_chirp)
size_diff_bigger, chirp_winner, size_diff_smaller, chirp_loser = get_chirp_size(
foldername, bh, order_meta_df, id_meta_df)
freq_winner, chirp_freq_winner, freq_loser, chirp_freq_loser = get_chirp_freq(
foldername, bh, order_meta_df)
freq_diffs_higher.append(freq_winner)
freq_diffs_lower.append(freq_loser)
freq_chirps_winner.append(chirp_freq_winner)
freq_chirps_loser.append(chirp_freq_loser)
if np.isnan(size_diff_bigger):
continue
size_diffs_winner.append(size_diff_bigger)
size_diffs_loser.append(size_diff_smaller)
size_chirps_winner.append(chirp_winner)
size_chirps_loser.append(chirp_loser)
size_winner_pearsonr = pearsonr(size_diffs_winner, size_chirps_winner)
size_loser_pearsonr = pearsonr(size_diffs_loser, size_chirps_loser)
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(
21*ps.cm, 10*ps.cm), width_ratios=[1, 0.8, 0.8], sharey=True)
plt.subplots_adjust(left=0.11, right=0.948, top=0.905, wspace=0.343, bottom=0.145)
scatterwinner = 1.15
scatterloser = 1.85
chirps_winner = np.asarray(chirps_winner)[~np.isnan(chirps_winner)]
chirps_loser = np.asarray(chirps_loser)[~np.isnan(chirps_loser)]
stat = wilcoxon(chirps_winner, chirps_loser)
print(stat)
bplot1 = ax1.boxplot(chirps_winner, positions=[
0.9], showfliers=False, patch_artist=True)
bplot2 = ax1.boxplot(chirps_loser, positions=[
2.1], showfliers=False, patch_artist=True)
ax1.scatter(np.ones(len(chirps_winner)) *
scatterwinner, chirps_winner, color=ps.red)
ax1.scatter(np.ones(len(chirps_loser)) *
scatterloser, chirps_loser, color=ps.orange)
ax1.set_xticklabels(['winner', 'loser'])
ax1.text(1, 2000, f'{len(chirps_winner)}', color='gray')
ax1.text(1.8, 2000, f'{len(chirps_loser)}', color='gray')
for w, l in zip(chirps_winner, chirps_loser):
ax1.plot([scatterwinner, scatterloser], [w, l],
color=ps.white, alpha=1, linewidth=0.5)
ax1.set_ylabel('chirpcount', color=ps.white)
ax1.set_xlabel('outcome', color=ps.white)
colors1 = ps.red
ps.set_boxplot_color(bplot1, colors1)
colors1 = ps.orange
ps.set_boxplot_color(bplot2, colors1)
ax2.scatter(size_diffs_winner, size_chirps_winner,
color=ps.red, label=f'winner')
ax2.scatter(size_diffs_loser, size_chirps_loser,
color=ps.orange, label='loser')
ax2.text(-1, 2000, f'{len(size_chirps_winner)}', color= 'gray')
ax2.text(1, 2000, f'{len(size_chirps_loser)}', color= 'gray')
ax2.set_xlabel('size difference [cm]')
# ax2.set_xticks(np.arange(-10, 10.1, 2))
ax3.scatter(freq_diffs_higher, freq_chirps_winner, color=ps.red)
ax3.scatter(freq_diffs_lower, freq_chirps_loser, color=ps.orange)
ax3.text(600, 2000, f'n = {len(freq_chirps_winner)}', color='gray')
ax3.text(650, 2000, f'{len(freq_chirps_loser)}', color='gray')
ax3.set_xlabel('absolut frequency [Hz]')
handles, labels = ax2.get_legend_handles_labels()
fig.legend(handles, labels, loc='upper center', ncol=2)
# pearson r
plt.savefig('../poster/figs/chirps_winner_loser.pdf')
plt.show()
if __name__ == '__main__':
# Path to the data
datapath = '../data/mount_data/'
main(datapath)

View File

@@ -0,0 +1,84 @@
import numpy as np
import os
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import pearsonr, spearmanr
from thunderfish.powerspectrum import decibel
from IPython import embed
from pandas import read_csv
from modules.logger import makeLogger
from modules.plotstyle import PlotStyle
from modules.behaviour_handling import Behavior, correct_chasing_events
from modules.datahandling import flatten
ps = PlotStyle()
logger = makeLogger(__name__)
def main(datapath: str):
foldernames = [
datapath + x + '/' for x in os.listdir(datapath) if os.path.isdir(datapath+x)]
time_precents = []
chirps_percents = []
for foldername in foldernames:
# behabvior is pandas dataframe with all the data
if foldername == '../data/mount_data/2020-05-12-10_00/':
continue
bh = Behavior(foldername)
category = bh.behavior
timestamps = bh.start_s
# Correct for doubles in chasing on- and offsets to get the right on-/offset pairs
# Get rid of tracking faults (two onsets or two offsets after another)
category, timestamps = correct_chasing_events(category, timestamps)
chasing_onset = timestamps[category == 0]
chasing_offset = timestamps[category == 1]
if len(chasing_onset) != len(chasing_offset):
embed()
chirps_in_chasings = []
for onset, offset in zip(chasing_onset, chasing_offset):
chirps_in_chasing = [c for c in bh.chirps if (c > onset) & (c < offset)]
chirps_in_chasings.append(chirps_in_chasing)
try:
time_chasing = np.sum(chasing_offset[chasing_offset<3*60*60] - chasing_onset[chasing_onset<3*60*60])
except:
time_chasing = np.sum(chasing_offset[chasing_offset<3*60*60] - chasing_onset[chasing_onset<3*60*60][:-1])
time_chasing_percent = (time_chasing/(3*60*60))*100
chirps_chasing = np.asarray(flatten(chirps_in_chasings))
chirps_chasing_new = chirps_chasing[chirps_chasing<3*60*60]
chirps_percent = (len(chirps_chasing_new)/len(bh.chirps[bh.chirps<3*60*60]))*100
time_precents.append(time_chasing_percent)
chirps_percents.append(chirps_percent)
fig, ax = plt.subplots(1, 1, figsize=(14*ps.cm, 10*ps.cm))
ax.boxplot([time_precents, chirps_percents])
ax.set_xticklabels(['Time Chasing', 'Chirps in Chasing'])
ax.set_ylabel('Percent')
ax.scatter(np.ones(len(time_precents))*1.25, time_precents, color=ps.white)
ax.scatter(np.ones(len(chirps_percents))*1.75, chirps_percents, color=ps.white)
for i in range(len(time_precents)):
ax.plot([1.25, 1.75], [time_precents[i], chirps_percents[i]], color=ps.white)
ax.text(0.99, 0.99, f'{len(time_precents)} fish', transform=ax.transAxes)
plt.savefig('../poster/figs/chirps_in_chasing.pdf')
plt.show()
if __name__ == '__main__':
# Path to the data
datapath = '../data/mount_data/'
main(datapath)

View File

@@ -1,9 +1,9 @@
import numpy as np import numpy as np
import os import os
import numpy as np import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from thunderfish.powerspectrum import decibel from thunderfish.powerspectrum import decibel
from IPython import embed from IPython import embed
@@ -12,20 +12,24 @@ from modules.logger import makeLogger
from modules.plotstyle import PlotStyle from modules.plotstyle import PlotStyle
from modules.behaviour_handling import Behavior, correct_chasing_events from modules.behaviour_handling import Behavior, correct_chasing_events
from extract_chirps import get_valid_datasets
ps = PlotStyle() ps = PlotStyle()
logger = makeLogger(__name__) logger = makeLogger(__name__)
def main(datapath: str): def main(datapath: str):
foldernames = [datapath + x + '/' for x in os.listdir(datapath) if os.path.isdir(datapath+x)] foldernames = [
for foldername in foldernames: datapath + x + '/' for x in os.listdir(datapath) if os.path.isdir(datapath+x)]
foldernames, _ = get_valid_datasets(datapath)
for foldername in foldernames[1:2]:
# foldername = foldernames[0]
if foldername == '../data/mount_data/2020-05-12-10_00/': if foldername == '../data/mount_data/2020-05-12-10_00/':
continue continue
# behabvior is pandas dataframe with all the data # behabvior is pandas dataframe with all the data
bh = Behavior(foldername) bh = Behavior(foldername)
# 2020-06-11-10
category = bh.behavior category = bh.behavior
timestamps = bh.start_s timestamps = bh.start_s
# Correct for doubles in chasing on- and offsets to get the right on-/offset pairs # Correct for doubles in chasing on- and offsets to get the right on-/offset pairs
@@ -33,45 +37,49 @@ def main(datapath: str):
category, timestamps = correct_chasing_events(category, timestamps) category, timestamps = correct_chasing_events(category, timestamps)
# split categories # split categories
chasing_onset = (timestamps[category == 0]/ 60) /60 chasing_onset = (timestamps[category == 0] / 60) / 60
chasing_offset = (timestamps[category == 1]/ 60) /60 chasing_offset = (timestamps[category == 1] / 60) / 60
physical_contact = (timestamps[category == 2] / 60) /60 physical_contact = (timestamps[category == 2] / 60) / 60
all_fish_ids = np.unique(bh.chirps_ids) all_fish_ids = np.unique(bh.chirps_ids)
fish1_id = all_fish_ids[0] fish1_id = all_fish_ids[0]
fish2_id = all_fish_ids[1] fish2_id = all_fish_ids[1]
# Associate chirps to inidividual fish # Associate chirps to inidividual fish
fish1 = (bh.chirps[bh.chirps_ids == fish1_id] / 60) /60 fish1 = (bh.chirps[bh.chirps_ids == fish1_id] / 60) / 60
fish2 = (bh.chirps[bh.chirps_ids == fish2_id] / 60) /60 fish2 = (bh.chirps[bh.chirps_ids == fish2_id] / 60) / 60
fish1_color = ps.red fish1_color = ps.purple
fish2_color = ps.orange fish2_color = ps.lavender
fig, ax = plt.subplots(4, 1, figsize=(10, 5), height_ratios=[0.5, 0.5, 0.5, 6], sharex=True) fig, ax = plt.subplots(5, 1, figsize=(
# marker size 21*ps.cm, 10*ps.cm), height_ratios=[0.5, 0.5, 0.5, 0.2, 6], sharex=True)
s = 200 # marker size
ax[0].scatter(physical_contact, np.ones(len(physical_contact)), color='firebrick', marker='|', s=s) s = 80
ax[1].scatter(chasing_onset, np.ones(len(chasing_onset)), color='green', marker='|', s=s ) ax[0].scatter(physical_contact, np.ones(
ax[2].scatter(fish1, np.ones(len(fish1))-0.25, color=fish1_color, marker='|', s=s) len(physical_contact)), color=ps.maroon, marker='|', s=s)
ax[2].scatter(fish2, np.zeros(len(fish2))+0.25, color=fish2_color, marker='|', s=s) ax[1].scatter(chasing_onset, np.ones(len(chasing_onset)),
color=ps.orange, marker='|', s=s)
ax[2].scatter(fish1, np.ones(len(fish1))-0.25,
color=fish1_color, marker='|', s=s)
ax[2].scatter(fish2, np.zeros(len(fish2))+0.25,
color=fish2_color, marker='|', s=s)
freq_temp = bh.freq[bh.ident==fish1_id] freq_temp = bh.freq[bh.ident == fish1_id]
time_temp = bh.time[bh.idx[bh.ident==fish1_id]] time_temp = bh.time[bh.idx[bh.ident == fish1_id]]
ax[3].plot((time_temp/ 60) /60, freq_temp, color=fish1_color) ax[4].plot((time_temp / 60) / 60, freq_temp, color=fish1_color)
freq_temp = bh.freq[bh.ident==fish2_id] freq_temp = bh.freq[bh.ident == fish2_id]
time_temp = bh.time[bh.idx[bh.ident==fish2_id]] time_temp = bh.time[bh.idx[bh.ident == fish2_id]]
ax[3].plot((time_temp/ 60) /60, freq_temp, color=fish2_color) ax[4].plot((time_temp / 60) / 60, freq_temp, color=fish2_color)
#ax[3].imshow(decibel(bh.spec), extent=[bh.time[0]/60/60, bh.time[-1]/60/60, 0, 2000], aspect='auto', origin='lower') # ax[3].imshow(decibel(bh.spec), extent=[bh.time[0]/60/60, bh.time[-1]/60/60, 0, 2000], aspect='auto', origin='lower')
# Hide grid lines # Hide grid lines
ax[0].grid(False) ax[0].grid(False)
ax[0].set_frame_on(False) ax[0].set_frame_on(False)
ax[0].set_xticks([]) ax[0].set_xticks([])
ax[0].set_yticks([]) ax[0].set_yticks([])
ps.hide_ax(ax[0]) ps.hide_ax(ax[0])
ax[0].yaxis.set_label_coords(-0.1, 0.5)
ax[1].grid(False) ax[1].grid(False)
ax[1].set_frame_on(False) ax[1].set_frame_on(False)
@@ -85,22 +93,26 @@ def main(datapath: str):
ax[2].set_xticks([]) ax[2].set_xticks([])
ps.hide_ax(ax[2]) ps.hide_ax(ax[2])
ax[4].axvspan(3, 6, 0, 5, facecolor='grey', alpha=0.5)
ax[4].set_xticks(np.arange(0, 6.1, 0.5))
ps.hide_ax(ax[3])
labelpad = 30
fsize = 12
ax[0].set_ylabel('contact', rotation=0,
labelpad=labelpad, fontsize=fsize)
ax[1].set_ylabel('chasing', rotation=0,
labelpad=labelpad, fontsize=fsize)
ax[2].set_ylabel('chirps', rotation=0,
labelpad=labelpad, fontsize=fsize)
ax[4].set_ylabel('EODf')
ax[3].axvspan(3, 6, 0, 5, facecolor='grey', alpha=0.5) ax[4].set_xlabel('time [h]')
ax[3].set_xticks(np.arange(0, 6.1, 0.5)) # ax[0].set_title(foldername.split('/')[-2])
labelpad = 40
ax[0].set_ylabel('Physical contact', rotation=0, labelpad=labelpad)
ax[1].set_ylabel('Chasing events', rotation=0, labelpad=labelpad)
ax[2].set_ylabel('Chirps', rotation=0, labelpad=labelpad)
ax[3].set_ylabel('EODf')
ax[3].set_xlabel('Time [h]')
ax[0].set_title(foldername.split('/')[-2])
# 2020-03-31-9_59 # 2020-03-31-9_59
plt.subplots_adjust(left=0.158, right=0.987, top=0.918)
# plt.savefig('../poster/figs/timeline.pdf')
plt.show() plt.show()
embed()
# plot chirps # plot chirps

471
code/plot_kdes.py Normal file
View File

@@ -0,0 +1,471 @@
from extract_chirps import get_valid_datasets
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from tqdm import tqdm
from IPython import embed
from pandas import read_csv
from modules.logger import makeLogger
from modules.datahandling import flatten, causal_kde1d, acausal_kde1d
from modules.behaviour_handling import (
Behavior, correct_chasing_events, center_chirps)
from modules.plotstyle import PlotStyle
logger = makeLogger(__name__)
ps = PlotStyle()
def bootstrap(data, nresamples, kde_time, kernel_width, event_times, time_before, time_after):
bootstrapped_kdes = []
data = data[data <= 3*60*60] # only night time
# diff_data = np.diff(np.sort(data), prepend=0)
# if len(data) != 0:
# mean_chirprate = (len(data) - 1) / (data[-1] - data[0])
for i in tqdm(range(nresamples)):
# np.random.shuffle(diff_data)
# bootstrapped_data = np.cumsum(diff_data)
bootstrapped_data = data + np.random.randn(len(data)) * 10
bootstrap_data_centered = center_chirps(
bootstrapped_data, event_times, time_before, time_after)
bootstrapped_kde = acausal_kde1d(
bootstrap_data_centered, time=kde_time, width=kernel_width)
# bootstrapped_kdes = list(np.asarray(
# bootstrapped_kdes) / len(event_times))
bootstrapped_kdes.append(bootstrapped_kde)
return bootstrapped_kdes
def jackknife(data, nresamples, subsetsize, kde_time, kernel_width, event_times, time_before, time_after):
jackknife_kdes = []
data = data[data <= 3*60*60] # only night time
subsetsize = int(len(data) * subsetsize)
diff_data = np.diff(np.sort(data), prepend=0)
for i in tqdm(range(nresamples)):
bootstrapped_data = np.random.sample(data, subsetsize, replace=False)
bootstrapped_data = np.cumsum(diff_data)
bootstrap_data_centered = center_chirps(
bootstrapped_data, event_times, time_before, time_after)
bootstrapped_kde = acausal_kde1d(
bootstrap_data_centered, time=kde_time, width=kernel_width)
# bootstrapped_kdes = list(np.asarray(
# bootstrapped_kdes) / len(event_times))
jackknife_kdes.append(bootstrapped_kde)
return jackknife_kdes
def get_chirp_winner_loser(folder_name, Behavior, order_meta_df):
foldername = folder_name.split('/')[-2]
winner_row = order_meta_df[order_meta_df['recording'] == foldername]
winner = winner_row['winner'].values[0].astype(int)
winner_fish1 = winner_row['fish1'].values[0].astype(int)
winner_fish2 = winner_row['fish2'].values[0].astype(int)
if winner > 0:
if winner == winner_fish1:
winner_fish_id = winner_row['rec_id1'].values[0]
loser_fish_id = winner_row['rec_id2'].values[0]
elif winner == winner_fish2:
winner_fish_id = winner_row['rec_id2'].values[0]
loser_fish_id = winner_row['rec_id1'].values[0]
chirp_winner = Behavior.chirps[Behavior.chirps_ids == winner_fish_id]
chirp_loser = Behavior.chirps[Behavior.chirps_ids == loser_fish_id]
return chirp_winner, chirp_loser
return None, None
def main(dataroot):
foldernames, _ = get_valid_datasets(dataroot)
plot_all = True
time_before = 60
time_after = 60
dt = 0.001
kernel_width = 1
kde_time = np.arange(-time_before, time_after, dt)
nbootstraps = 2
meta_path = (
'/').join(foldernames[0].split('/')[:-2]) + '/order_meta.csv'
meta = pd.read_csv(meta_path)
meta['recording'] = meta['recording'].str[1:-1]
winner_onsets = []
winner_offsets = []
winner_physicals = []
loser_onsets = []
loser_offsets = []
loser_physicals = []
winner_onsets_boot = []
winner_offsets_boot = []
winner_physicals_boot = []
loser_onsets_boot = []
loser_offsets_boot = []
loser_physicals_boot = []
onset_count = 0
offset_count = 0
physical_count = 0
# Iterate over all recordings and save chirp- and event-timestamps
for folder in tqdm(foldernames):
foldername = folder.split('/')[-2]
# logger.info('Loading data from folder: {}'.format(foldername))
broken_folders = ['../data/mount_data/2020-05-12-10_00/']
if folder in broken_folders:
continue
bh = Behavior(folder)
category, timestamps = correct_chasing_events(bh.behavior, bh.start_s)
category = category[timestamps < 3*60*60] # only night time
timestamps = timestamps[timestamps < 3*60*60] # only night time
winner, loser = get_chirp_winner_loser(folder, bh, meta)
if winner is None:
continue
onsets = (timestamps[category == 0])
offsets = (timestamps[category == 1])
physicals = (timestamps[category == 2])
onset_count += len(onsets)
offset_count += len(offsets)
physical_count += len(physicals)
winner_onsets.append(center_chirps(
winner, onsets, time_before, time_after))
winner_offsets.append(center_chirps(
winner, offsets, time_before, time_after))
winner_physicals.append(center_chirps(
winner, physicals, time_before, time_after))
loser_onsets.append(center_chirps(
loser, onsets, time_before, time_after))
loser_offsets.append(center_chirps(
loser, offsets, time_before, time_after))
loser_physicals.append(center_chirps(
loser, physicals, time_before, time_after))
# bootstrap
# chirps = [winner, winner, winner, loser, loser, loser]
winner_onsets_boot.append(bootstrap(
winner,
nresamples=nbootstraps,
kde_time=kde_time,
kernel_width=kernel_width,
event_times=onsets,
time_before=time_before,
time_after=time_after))
winner_offsets_boot.append(bootstrap(
winner,
nresamples=nbootstraps,
kde_time=kde_time,
kernel_width=kernel_width,
event_times=offsets,
time_before=time_before,
time_after=time_after))
winner_physicals_boot.append(bootstrap(
winner,
nresamples=nbootstraps,
kde_time=kde_time,
kernel_width=kernel_width,
event_times=physicals,
time_before=time_before,
time_after=time_after))
loser_onsets_boot.append(bootstrap(
loser,
nresamples=nbootstraps,
kde_time=kde_time,
kernel_width=kernel_width,
event_times=onsets,
time_before=time_before,
time_after=time_after))
loser_offsets_boot.append(bootstrap(
loser,
nresamples=nbootstraps,
kde_time=kde_time,
kernel_width=kernel_width,
event_times=offsets,
time_before=time_before,
time_after=time_after))
loser_physicals_boot.append(bootstrap(
loser,
nresamples=nbootstraps,
kde_time=kde_time,
kernel_width=kernel_width,
event_times=physicals,
time_before=time_before,
time_after=time_after))
if plot_all:
winner_onsets_conv = acausal_kde1d(
winner_onsets[-1], kde_time, kernel_width)
winner_offsets_conv = acausal_kde1d(
winner_offsets[-1], kde_time, kernel_width)
winner_physicals_conv = acausal_kde1d(
winner_physicals[-1], kde_time, kernel_width)
loser_onsets_conv = acausal_kde1d(
loser_onsets[-1], kde_time, kernel_width)
loser_offsets_conv = acausal_kde1d(
loser_offsets[-1], kde_time, kernel_width)
loser_physicals_conv = acausal_kde1d(
loser_physicals[-1], kde_time, kernel_width)
fig, ax = plt.subplots(2, 3, figsize=(
21*ps.cm, 10*ps.cm), sharey=True, sharex=True)
ax[0, 0].set_title(
f"{foldername}, onsets {len(onsets)}, offsets {len(offsets)}, physicals {len(physicals)},winner {len(winner)}, looser {len(loser)} , onsets")
ax[0, 0].plot(kde_time, winner_onsets_conv/len(onsets))
ax[0, 1].plot(kde_time, winner_offsets_conv/len(offsets))
ax[0, 2].plot(kde_time, winner_physicals_conv/len(physicals))
ax[1, 0].plot(kde_time, loser_onsets_conv/len(onsets))
ax[1, 1].plot(kde_time, loser_offsets_conv/len(offsets))
ax[1, 2].plot(kde_time, loser_physicals_conv/len(physicals))
# # plot bootstrap lines
for kde in winner_onsets_boot[-1]:
ax[0, 0].plot(kde_time, kde/len(onsets),
color='gray')
for kde in winner_offsets_boot[-1]:
ax[0, 1].plot(kde_time, kde/len(offsets),
color='gray')
for kde in winner_physicals_boot[-1]:
ax[0, 2].plot(kde_time, kde/len(physicals),
color='gray')
for kde in loser_onsets_boot[-1]:
ax[1, 0].plot(kde_time, kde/len(onsets),
color='gray')
for kde in loser_offsets_boot[-1]:
ax[1, 1].plot(kde_time, kde/len(offsets),
color='gray')
for kde in loser_physicals_boot[-1]:
ax[1, 2].plot(kde_time, kde/len(physicals),
color='gray')
# plot bootstrap percentiles
# ax[0, 0].fill_between(
# kde_time,
# np.percentile(winner_onsets_boot[-1], 5, axis=0),
# np.percentile(winner_onsets_boot[-1], 95, axis=0),
# color='gray',
# alpha=0.5)
# ax[0, 1].fill_between(
# kde_time,
# np.percentile(winner_offsets_boot[-1], 5, axis=0),
# np.percentile(
# winner_offsets_boot[-1], 95, axis=0),
# color='gray',
# alpha=0.5)
# ax[0, 2].fill_between(
# kde_time,
# np.percentile(
# winner_physicals_boot[-1], 5, axis=0),
# np.percentile(
# winner_physicals_boot[-1], 95, axis=0),
# color='gray',
# alpha=0.5)
# ax[1, 0].fill_between(
# kde_time,
# np.percentile(loser_onsets_boot[-1], 5, axis=0),
# np.percentile(loser_onsets_boot[-1], 95, axis=0),
# color='gray',
# alpha=0.5)
# ax[1, 1].fill_between(
# kde_time,
# np.percentile(loser_offsets_boot[-1], 5, axis=0),
# np.percentile(loser_offsets_boot[-1], 95, axis=0),
# color='gray',
# alpha=0.5)
# ax[1, 2].fill_between(
# kde_time,
# np.percentile(
# loser_physicals_boot[-1], 5, axis=0),
# np.percentile(
# loser_physicals_boot[-1], 95, axis=0),
# color='gray',
# alpha=0.5)
# ax[0, 0].plot(kde_time, np.median(winner_onsets_boot[-1], axis=0),
# color='black', linewidth=2)
# ax[0, 1].plot(kde_time, np.median(winner_offsets_boot[-1], axis=0),
# color='black', linewidth=2)
# ax[0, 2].plot(kde_time, np.median(winner_physicals_boot[-1], axis=0),
# color='black', linewidth=2)
# ax[1, 0].plot(kde_time, np.median(loser_onsets_boot[-1], axis=0),
# color='black', linewidth=2)
# ax[1, 1].plot(kde_time, np.median(loser_offsets_boot[-1], axis=0),
# color='black', linewidth=2)
# ax[1, 2].plot(kde_time, np.median(loser_physicals_boot[-1], axis=0),
# color='black', linewidth=2)
ax[0, 0].set_xlim(-30, 30)
plt.show()
winner_onsets = np.sort(flatten(winner_onsets))
winner_offsets = np.sort(flatten(winner_offsets))
winner_physicals = np.sort(flatten(winner_physicals))
loser_onsets = np.sort(flatten(loser_onsets))
loser_offsets = np.sort(flatten(loser_offsets))
loser_physicals = np.sort(flatten(loser_physicals))
winner_onsets_conv = acausal_kde1d(
winner_onsets, kde_time, kernel_width)
winner_offsets_conv = acausal_kde1d(
winner_offsets, kde_time, kernel_width)
winner_physicals_conv = acausal_kde1d(
winner_physicals, kde_time, kernel_width)
loser_onsets_conv = acausal_kde1d(
loser_onsets, kde_time, kernel_width)
loser_offsets_conv = acausal_kde1d(
loser_offsets, kde_time, kernel_width)
loser_physicals_conv = acausal_kde1d(
loser_physicals, kde_time, kernel_width)
winner_onsets_conv = winner_onsets_conv / onset_count
winner_offsets_conv = winner_offsets_conv / offset_count
winner_physicals_conv = winner_physicals_conv / physical_count
loser_onsets_conv = loser_onsets_conv / onset_count
loser_offsets_conv = loser_offsets_conv / offset_count
loser_physicals_conv = loser_physicals_conv / physical_count
winner_onsets_boot = np.concatenate(
winner_onsets_boot)
winner_offsets_boot = np.concatenate(
winner_offsets_boot)
winner_physicals_boot = np.concatenate(
winner_physicals_boot)
loser_onsets_boot = np.concatenate(
loser_onsets_boot)
loser_offsets_boot = np.concatenate(
loser_offsets_boot)
loser_physicals_boot = np.concatenate(
loser_physicals_boot)
percs = [5, 50, 95]
winner_onsets_boot_quarts = np.percentile(
winner_onsets_boot, percs, axis=0)
winner_offsets_boot_quarts = np.percentile(
winner_offsets_boot, percs, axis=0)
winner_physicals_boot_quarts = np.percentile(
winner_physicals_boot, percs, axis=0)
loser_onsets_boot_quarts = np.percentile(
loser_onsets_boot, percs, axis=0)
loser_offsets_boot_quarts = np.percentile(
loser_offsets_boot, percs, axis=0)
loser_physicals_boot_quarts = np.percentile(
loser_physicals_boot, percs, axis=0)
fig, ax = plt.subplots(2, 3, figsize=(
21*ps.cm, 10*ps.cm), sharey=True, sharex=True)
ax[0, 0].plot(kde_time, winner_onsets_conv)
ax[0, 1].plot(kde_time, winner_offsets_conv)
ax[0, 2].plot(kde_time, winner_physicals_conv)
ax[1, 0].plot(kde_time, loser_onsets_conv)
ax[1, 1].plot(kde_time, loser_offsets_conv)
ax[1, 2].plot(kde_time, loser_physicals_conv)
ax[0, 0].plot(kde_time, winner_onsets_boot_quarts[1], c=ps.black)
ax[0, 1].plot(kde_time, winner_offsets_boot_quarts[1], c=ps.black)
ax[0, 2].plot(kde_time, winner_physicals_boot_quarts[1], c=ps.black)
ax[1, 0].plot(kde_time, loser_onsets_boot_quarts[1], c=ps.black)
ax[1, 1].plot(kde_time, loser_offsets_boot_quarts[1], c=ps.black)
ax[1, 2].plot(kde_time, loser_physicals_boot_quarts[1], c=ps.black)
# for kde in winner_onsets_boot:
# ax[0, 0].plot(kde_time, kde,
# color='gray')
# for kde in winner_offsets_boot:
# ax[0, 1].plot(kde_time, kde,
# color='gray')
# for kde in winner_physicals_boot:
# ax[0, 2].plot(kde_time, kde,
# color='gray')
# for kde in loser_onsets_boot:
# ax[1, 0].plot(kde_time, kde,
# color='gray')
# for kde in loser_offsets_boot:
# ax[1, 1].plot(kde_time, kde,
# color='gray')
# for kde in loser_physicals_boot:
# ax[1, 2].plot(kde_time, kde,
# color='gray')
ax[0, 0].fill_between(kde_time,
winner_onsets_boot_quarts[0],
winner_onsets_boot_quarts[2],
color=ps.gray,
alpha=0.5)
ax[0, 1].fill_between(kde_time,
winner_offsets_boot_quarts[0],
winner_offsets_boot_quarts[2],
color=ps.gray,
alpha=0.5)
ax[0, 2].fill_between(kde_time,
loser_physicals_boot_quarts[0],
loser_physicals_boot_quarts[2],
color=ps.gray,
alpha=0.5)
ax[1, 0].fill_between(kde_time,
loser_onsets_boot_quarts[0],
loser_onsets_boot_quarts[2],
color=ps.gray,
alpha=0.5)
ax[1, 1].fill_between(kde_time,
loser_offsets_boot_quarts[0],
loser_offsets_boot_quarts[2],
color=ps.gray,
alpha=0.5)
ax[1, 2].fill_between(kde_time,
loser_physicals_boot_quarts[0],
loser_physicals_boot_quarts[2],
color=ps.gray,
alpha=0.5)
plt.show()
if __name__ == '__main__':
main('../data/mount_data/')

BIN
poster/figs/algorithm1.pdf Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
poster/figs/efishlogo.pdf Normal file

Binary file not shown.

BIN
poster/figs/timeline.pdf Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -7,7 +7,7 @@ blockverticalspace=2mm, colspace=20mm, subcolspace=0mm]{tikzposter} %Default val
\begin{document} \begin{document}
\renewcommand{\baselinestretch}{1} \renewcommand{\baselinestretch}{1}
\title{\parbox{1500pt}{Detection of transient communication signals in weakly electric fish}} \title{\parbox{1500pt}{Bypassing time-frequency uncertainty in the detection of transient communication signals in weakly electric fish}}
\author{Sina Prause, Alexander Wendt, and Patrick Weygoldt} \author{Sina Prause, Alexander Wendt, and Patrick Weygoldt}
\institute{Supervised by Till Raab \& Jan Benda, Neuroethology Lab, University of Tuebingen} \institute{Supervised by Till Raab \& Jan Benda, Neuroethology Lab, University of Tuebingen}
\usetitlestyle[]{sampletitle} \usetitlestyle[]{sampletitle}
@@ -16,19 +16,25 @@ blockverticalspace=2mm, colspace=20mm, subcolspace=0mm]{tikzposter} %Default val
\begin{columns} \begin{columns}
\column{0.4} \column{0.4}
\myblock[TranspBlock]{Introduction}{ \myblock[GrayBlock]{Introduction}{
The time-frequency tradeoff makes reliable signal detecion and simultaneous The time-frequency tradeoff makes reliable signal detecion and simultaneous
sender identification of freely interacting individuals impossible. sender identification by simple Fourier decomposition in freely interacting
This profoundly limits our current understanding of chirps to experiments weakly electric fish impossible. This profoundly limits our current
understanding of chirps to experiments
with single - or physically separated - individuals. with single - or physically separated - individuals.
% \begin{tikzfigure}[] % \begin{tikzfigure}[]
% \label{griddrawing} % \label{griddrawing}
% \includegraphics[width=1\linewidth]{figs/introplot} % \includegraphics[width=0.8\linewidth]{figs/introplot}
% \end{tikzfigure} % \end{tikzfigure}
} }
\myblock[TranspBlock]{Chirp detection}{ \myblock[TranspBlock]{Chirp detection}{
\begin{tikzfigure}[] \begin{tikzfigure}[]
\label{fig:example_a} \label{fig:alg1}
\includegraphics[width=0.9\linewidth]{figs/algorithm1}
\end{tikzfigure}
\vspace{2cm}
\begin{tikzfigure}[]
\label{fig:alg2}
\includegraphics[width=1\linewidth]{figs/algorithm} \includegraphics[width=1\linewidth]{figs/algorithm}
\end{tikzfigure} \end{tikzfigure}
\vspace{0cm} \vspace{0cm}
@@ -38,9 +44,29 @@ blockverticalspace=2mm, colspace=20mm, subcolspace=0mm]{tikzposter} %Default val
\myblock[TranspBlock]{Chirps during competition}{ \myblock[TranspBlock]{Chirps during competition}{
\begin{tikzfigure}[] \begin{tikzfigure}[]
\label{fig:example_b} \label{fig:example_b}
\includegraphics[width=0.5\linewidth]{example-image-b} \includegraphics[width=\linewidth]{figs/timeline.pdf}
\end{tikzfigure} \end{tikzfigure}
\noindent \noindent
\begin{itemize}
\setlength\itemsep{0.5em}
\item Two fish compete for one hidding place in one tank,
\item Experiment had a 3 hour long darkphase and a 3 hour long light phase.
\end{itemize}
\noindent
\begin{tikzfigure}[]
\label{fig:example_b}
\includegraphics[width=\linewidth]{figs/chirps_winner_loser.pdf}
\end{tikzfigure}
\begin{itemize}
\setlength\itemsep{0.5em}
\item Fish who won the competition chirped more often than the fish who lost.
\item
\end{itemize}
} }
\myblock[TranspBlock]{Interactions at modulations}{ \myblock[TranspBlock]{Interactions at modulations}{
@@ -50,19 +76,7 @@ blockverticalspace=2mm, colspace=20mm, subcolspace=0mm]{tikzposter} %Default val
\includegraphics[width=0.5\linewidth]{example-image-c} \includegraphics[width=0.5\linewidth]{example-image-c}
\end{tikzfigure} \end{tikzfigure}
\begin{multicols}{2}
\begin{itemize}
\setlength\itemsep{0.5em}
\item $\Delta$EOD$f$ does not appear to decrease during synchronous modulations ().
\item Individuals that rise their EOD$f$ first appear to rise their frequency higher compared to reactors (\textbf{B}).
\vfill
\null
\columnbreak
\item Synchronized fish keep distances below 1 m (\textbf{C}) but distances over 3 m also occur (see \textbf{movie}).
\item Spatial interactions increase \textbf{after} the start of a synchronous modulation (\textbf{D}).
\end{itemize}
\end{multicols}
\vspace{-1cm}
} }
\myblock[GrayBlock]{Conclusion}{ \myblock[GrayBlock]{Conclusion}{

View File

@@ -34,7 +34,7 @@
\centering \centering
% \vspace{1cm} % \vspace{1cm}
\hspace{-10cm} \hspace{-10cm}
\includegraphics[width=\linewidth]{example-image-a} \includegraphics[width=0.8\linewidth]{figs/efishlogo.pdf}
\end{minipage}} \end{minipage}}
% \begin{minipage}[c]{0.2\paperwidth} % \begin{minipage}[c]{0.2\paperwidth}
% \vspace{1cm}\hspace{1cm} % \vspace{1cm}\hspace{1cm}