sync with work

This commit is contained in:
weygoldt 2023-04-07 12:09:21 +02:00
parent 1c87f282ad
commit 4076cf074e
No known key found for this signature in database
2 changed files with 70 additions and 37 deletions

View File

@ -234,12 +234,16 @@ class ChirpPlotBuffer:
)
# plot filtered and rectified envelope
# ax4.plot(
# self.time, self.baseline_envelope * waveform_scaler, c=ps.gblue1, lw=lw
# )
ax4.plot(
self.time, self.baseline_envelope * waveform_scaler, c=ps.gblue1, lw=lw
self.time, self.baseline_envelope, c=ps.gblue1, lw=lw
)
ax4.scatter(
(self.time)[self.baseline_peaks],
(self.baseline_envelope * waveform_scaler)[self.baseline_peaks],
# (self.baseline_envelope * waveform_scaler)[self.baseline_peaks],
(self.baseline_envelope)[self.baseline_peaks],
edgecolors=ps.black,
facecolors=ps.red,
zorder=10,
@ -249,10 +253,12 @@ class ChirpPlotBuffer:
)
# plot envelope of search signal
ax5.plot(self.time, self.search_envelope * waveform_scaler, c=ps.gblue2, lw=lw)
# ax5.plot(self.time, self.search_envelope * waveform_scaler, c=ps.gblue2, lw=lw)
ax5.plot(self.time, self.search_envelope, c=ps.gblue2, lw=lw)
ax5.scatter(
(self.time)[self.search_peaks],
(self.search_envelope * waveform_scaler)[self.search_peaks],
# (self.search_envelope * waveform_scaler)[self.search_peaks],
(self.search_envelope)[self.search_peaks],
edgecolors=ps.black,
facecolors=ps.red,
zorder=10,
@ -489,6 +495,28 @@ def array_center(array: np.ndarray) -> float:
return array[int(len(array) / 2)]
def has_chirp(baseline_frequency: np.ndarray, peak_height: float) -> bool:
"""
Check if a fish has a chirp.
Parameters
----------
baseline_frequency : np.ndarray
Baseline frequency of the fish.
peak_height : float
Minimal peak height of a chirp on the instant. freq.
Returns
-------
bool: True if the fish has a chirp, False otherwise.
"""
peaks, _ = find_peaks(baseline_frequency, height=peak_height)
if len(peaks) > 0:
return True
else:
return False
def find_searchband(
current_frequency: np.ndarray,
percentiles_ids: np.ndarray,
@ -655,16 +683,16 @@ def chirpdetection(datapath: str, plot: str, debug: str = "false") -> None:
raw_time = np.arange(data.raw.shape[0]) / data.raw_rate
# good chirp times for data: 2022-06-02-10_00
window_start_index = (3 * 60 * 60 + 6 * 60 + 43.5) * data.raw_rate
window_duration_index = 60 * data.raw_rate
# window_start_index = (3 * 60 * 60 + 6 * 60 + 43.5) * data.raw_rate
# window_duration_index = 60 * data.raw_rate
# t0 = 0
# dt = data.raw.shape[0]
# window_start_seconds = (23495 + ((28336-23495)/3)) * data.raw_rate
# window_duration_seconds = (28336 - 23495) * data.raw_rate
# window_start_index = 0
# window_duration_index = data.raw.shape[0]
window_start_index = 0
window_duration_index = data.raw.shape[0]
# generate starting points of rolling window
window_start_indices = np.arange(
@ -825,6 +853,7 @@ def chirpdetection(datapath: str, plot: str, debug: str = "false") -> None:
samplerate=data.raw_rate,
cutoff_frequency=config.search_envelope_cutoff,
)
search_envelope = search_envelope_unfiltered
# compute instantaneous frequency of the baseline band to find
@ -843,30 +872,28 @@ def chirpdetection(datapath: str, plot: str, debug: str = "false") -> None:
smoothing_window=config.baseline_frequency_smoothing,
)
# bandpass filter the instantaneous frequency to remove slow
# fluctuations. Just as with the baseline envelope, we then
# compute the envelope of the signal to remove the oscillations
# around the peaks
# baseline_frequency_samplerate = np.mean(
# np.diff(baseline_frequency_time)
# )
# Take the absolute of the instantaneous frequency to invert
# troughs into peaks. This is nessecary since the narrow
# pass band introduces these anomalies. Also substract by the
# median to set it to 0.
baseline_frequency_filtered = np.abs(
baseline_frequency - np.median(baseline_frequency)
)
# baseline_frequency_filtered = highpass_filter(
# signal=baseline_frequency_filtered,
# samplerate=baseline_frequency_samplerate,
# cutoff=config.baseline_frequency_highpass_cutoff,
# )
# Now check if there are strong dips in the signal amplitude
# in the rolling window. These result in frequency anomalies,
# which would be detected as chirps on the frequency trace.
# baseline_frequency_filtered = envelope(
# signal=-baseline_frequency_filtered,
# samplerate=baseline_frequency_samplerate,
# cutoff_frequency=config.baseline_frequency_envelope_cutoff,
# )
# check if there is at least one superthreshold peak on the
# instantaneous and exit the loop if not. This is used to
# prevent windows that do definetely not include a chirp
# to enter normalization, where small changes due to noise
# would be amplified
if not has_chirp(baseline_frequency, config.baseline_frequency_peakheight):
continue
# CUT OFF OVERLAP ---------------------------------------------
@ -877,6 +904,7 @@ def chirpdetection(datapath: str, plot: str, debug: str = "false") -> None:
no_edges = np.arange(
int(window_edge), len(baseline_envelope) - int(window_edge)
)
current_raw_time = current_raw_time[no_edges]
baselineband = baselineband[no_edges]
baseline_envelope_unfiltered = baseline_envelope_unfiltered[no_edges]
@ -905,11 +933,11 @@ def chirpdetection(datapath: str, plot: str, debug: str = "false") -> None:
# normalize all three feature arrays to the same range to make
# peak detection simpler
# baseline_envelope = minmaxnorm([baseline_envelope])[0]
# search_envelope = minmaxnorm([search_envelope])[0]
# baseline_frequency_filtered = minmaxnorm(
# [baseline_frequency_filtered]
# )[0]
baseline_envelope = minmaxnorm([baseline_envelope])[0]
search_envelope = minmaxnorm([search_envelope])[0]
baseline_frequency_filtered = minmaxnorm(
[baseline_frequency_filtered]
)[0]
# PEAK DETECTION ----------------------------------------------
@ -1110,7 +1138,7 @@ def chirpdetection(datapath: str, plot: str, debug: str = "false") -> None:
if __name__ == "__main__":
# datapath = "/home/weygoldt/Data/uni/chirpdetection/GP2023_chirp_detection/data/mount_data/2020-05-13-10_00/"
datapath = "../data/2022-06-02-10_00/"
# datapath = "/home/weygoldt/Data/uni/efishdata/2016-colombia/fishgrid/2016-04-09-22_25/"
# datapath = "/home/weygoldt/Data/uni/chirpdetection/GP2023_chirp_detection/data/mount_data/2020-03-13-10_00/"
chirpdetection(datapath, plot="save", debug="false")
datapath = "../data/2022-06-02-10_00/"
chirpdetection(datapath, plot="show", debug="false")

View File

@ -22,19 +22,24 @@ search_res: 1 # search window resolution
default_search_freq: 60 # search here if no need for a search frequency
minimal_bandwidth: 10 # minimal bandpass filter width for baseline
search_bandwidth: 10 # minimal bandpass filter width for search frequency
baseline_frequency_smoothing: 10 # instantaneous frequency smoothing
baseline_frequency_smoothing: 3 # instantaneous frequency smoothing
# Feature processing parameters -----------------------------------------------
baseline_frequency_peakheight: 5 # the min peak height of the baseline instfreq
baseline_envelope_cutoff: 25 # envelope estimation cutoff
baseline_envelope_bandpass_lowf: 2 # envelope badpass lower cutoff
baseline_envelope_bandpass_highf: 100 # envelope bandbass higher cutoff
search_envelope_cutoff: 10 # search envelope estimation cufoff
# Peak detecion parameters ----------------------------------------------------
baseline_prominence: 0.00005 # peak prominence threshold for baseline envelope
search_prominence: 0.000004 # peak prominence threshold for search envelope
frequency_prominence: 2 # peak prominence threshold for baseline freq
# baseline_prominence: 0.00005 # peak prominence threshold for baseline envelope
# search_prominence: 0.000004 # peak prominence threshold for search envelope
# frequency_prominence: 2 # peak prominence threshold for baseline freq
baseline_prominence: 0.3 # peak prominence threshold for baseline envelope
search_prominence: 0.3 # peak prominence threshold for search envelope
frequency_prominence: 0.3 # peak prominence threshold for baseline freq
# Classify events as chirps if they are less than this time apart
chirp_window_threshold: 0.02