Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
I
IPI_annot
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Maxence Ferrari
IPI_annot
Commits
d13ecd0e
Commit
d13ecd0e
authored
4 years ago
by
ferrari
Browse files
Options
Downloads
Patches
Plain Diff
Initial commit
parent
cc5ba9fa
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
global_ipi.py
+246
-0
246 additions, 0 deletions
global_ipi.py
with
246 additions
and
0 deletions
global_ipi.py
0 → 100644
+
246
−
0
View file @
d13ecd0e
import
argparse
import
numpy
as
np
import
matplotlib.pyplot
as
plt
import
scipy.signal
as
sg
from
scipy
.
stats
import
gaussian_kde
from
fractions
import
Fraction
import
os
import
sys
from
pydub
import
AudioSegment
import
soundfile
as
sf
from
matplotlib.widgets
import
Button
,
Cursor
,
RadioButtons
,
AxesWidget
def
norm
(
x
,
axis
=
None
,
eps
=
1e-18
):
return
(
x
-
x
.
mean
(
axis
,
keepdims
=
axis
is
not
None
))
/
(
x
.
std
(
axis
,
keepdims
=
axis
is
not
None
)
+
eps
)
def
norm_abs
(
x
,
axis
=
None
,
eps
=
1e-18
):
return
(
x
-
x
.
mean
(
axis
,
keepdims
=
axis
is
not
None
))
/
(
np
.
abs
(
x
).
max
(
axis
,
keepdims
=
axis
is
not
None
)
+
eps
)
def
read
(
file_path
,
always_2d
=
True
):
try
:
return
sf
.
read
(
file_path
,
always_2d
=
always_2d
)
except
Exception
as
e
:
return
load_anysound
(
file_path
)
def
load_anysound
(
file_path
):
tmp
=
AudioSegment
.
from_file
(
file_path
)
return
np
.
array
(
tmp
.
get_array_of_samples
()).
reshape
(
-
1
,
tmp
.
channels
),
tmp
.
frame_rate
def
load_file
(
in_path
,
channel
,
low
,
high
):
print
(
f
'
Loading and processing
{
in_path
}
'
)
song
,
sr
=
read
(
in_path
,
always_2d
=
True
)
song
=
song
[:,
channel
]
sos
=
sg
.
butter
(
3
,
[
low
,
high
],
'
bandpass
'
,
fs
=
sr
,
output
=
'
sos
'
)
song
=
sg
.
sosfiltfilt
(
sos
,
song
)
print
(
'
Done processing
'
)
return
song
,
sr
class
MyRadioButtons
(
RadioButtons
):
def
__init__
(
self
,
ax
,
labels
,
active
=
0
,
activecolor
=
'
blue
'
,
size
=
49
,
orientation
=
"
vertical
"
,
**
kwargs
):
"""
Add radio buttons to an `~.axes.Axes`.
Parameters
----------
ax : `~matplotlib.axes.Axes`
The axes to add the buttons to.
labels : list of str
The button labels.
active : int
The index of the initially selected button.
activecolor : color
The color of the selected button.
size : float
Size of the radio buttons
orientation : str
The orientation of the buttons:
'
vertical
'
(default), or
'
horizontal
'
.
Further parameters are passed on to `Legend`.
"""
AxesWidget
.
__init__
(
self
,
ax
)
self
.
_activecolor
=
activecolor
axcolor
=
ax
.
get_facecolor
()
self
.
value_selected
=
None
ax
.
set_xticks
([])
ax
.
set_yticks
([])
ax
.
set_navigate
(
False
)
circles
=
[]
for
i
,
label
in
enumerate
(
labels
):
if
i
==
active
:
self
.
value_selected
=
label
facecolor
=
self
.
activecolor
else
:
facecolor
=
axcolor
p
=
ax
.
scatter
([],[],
s
=
size
,
marker
=
"
o
"
,
edgecolor
=
'
black
'
,
facecolor
=
facecolor
)
circles
.
append
(
p
)
if
orientation
==
"
horizontal
"
:
kwargs
.
update
(
ncol
=
len
(
labels
),
mode
=
"
expand
"
)
kwargs
.
setdefault
(
"
frameon
"
,
False
)
self
.
box
=
ax
.
legend
(
circles
,
labels
,
loc
=
"
center
"
,
**
kwargs
)
self
.
labels
=
self
.
box
.
texts
self
.
circles
=
self
.
box
.
legendHandles
for
c
in
self
.
circles
:
c
.
set_picker
(
5
)
self
.
cnt
=
0
self
.
observers
=
{}
self
.
connect_event
(
'
pick_event
'
,
self
.
_clicked
)
def
_clicked
(
self
,
event
):
if
self
.
ignore
(
event
)
or
event
.
mouseevent
.
button
!=
1
or
event
.
mouseevent
.
inaxes
!=
self
.
ax
:
return
if
event
.
artist
in
self
.
circles
:
self
.
set_active
(
self
.
circles
.
index
(
event
.
artist
))
@property
def
activecolor
(
self
):
if
hasattr
(
self
.
_activecolor
,
'
__getitem__
'
)
and
not
isinstance
(
self
.
_activecolor
,
str
):
return
self
.
_activecolor
[
int
(
self
.
value_selected
[
-
1
])]
else
:
return
self
.
_activecolor
def
main
(
args
):
song
,
sr
=
load_file
(
args
.
input
,
args
.
channel
,
args
.
low
,
args
.
high
)
mean
=
np
.
ones
(
int
(
6e-3
*
sr
))
mean
/=
len
(
mean
)
pos
,
prev
=
sg
.
find_peaks
(
np
.
log10
(
np
.
correlate
(
song
**
2
,
mean
,
'
same
'
))[
int
(
sr
*
17e-3
):
int
(
-
sr
*
17e-3
)],
distance
=
int
(
sr
*
20e-3
),
wlen
=
int
(
sr
*
20e-3
),
prominence
=
0
)
pos
+=
int
(
sr
*
17e-3
)
prev
=
prev
[
'
prominences
'
]
kde
=
gaussian_kde
(
prev
,
0.02
)
pointers
=
{
'
mask
'
:
prev
>
0.65
}
all_clicks
=
song
[
pos
[:,
None
]
+
np
.
arange
(
int
(
-
sr
*
17e-3
),
int
(
sr
*
17e-3
))]
fine_pos
=
np
.
argmax
(
all_clicks
[:,
int
(
sr
*
10e-3
):
int
(
sr
*
24e-3
)],
-
1
)
+
int
(
sr
*
10e-3
)
fine_pos_glob
=
fine_pos
+
pos
+
int
(
-
sr
*
17e-3
)
all_clicks
=
norm_abs
(
all_clicks
[
np
.
arange
(
len
(
all_clicks
))[:,
None
],
fine_pos
[:,
None
]
+
np
.
arange
(
int
(
-
sr
*
10e-3
),
int
(
sr
*
10e-3
))],
-
1
)
all_autocorr
=
norm_abs
(
np
.
vstack
([
np
.
correlate
(
c
,
c
,
'
same
'
)
for
c
in
all_clicks
]),
-
1
)[:,
int
(
sr
*
10e-3
):]
all_cepstrum
=
np
.
fft
.
ifftshift
(
np
.
abs
(
np
.
fft
.
irfft
(
np
.
log10
(
np
.
abs
(
np
.
fft
.
rfft
(
all_clicks
,
axis
=-
1
))
+
1e-18
),
axis
=-
1
)),
axes
=-
1
)[:,
int
(
sr
*
10e-3
):]
all_cepstrum
/=
all_cepstrum
.
max
(
-
1
,
keepdims
=
True
)
+
1e-18
fig
=
plt
.
figure
(
'
IPI of
'
+
args
.
input
.
rsplit
(
'
/
'
,
1
)[
-
1
],
figsize
=
[
16
,
9
],
constrained_layout
=
True
)
gs
=
fig
.
add_gridspec
(
12
,
20
)
full_sig
=
plt
.
subplot
(
gs
[:
2
,
:])
full_sig
.
plot
(
np
.
arange
(
len
(
song
))
/
sr
,
song
,
c
=
'
k
'
)
scat
=
full_sig
.
scatter
(
fine_pos_glob
[
pointers
[
'
mask
'
]]
/
sr
,
song
[
fine_pos_glob
[
pointers
[
'
mask
'
]]],
50
,
marker
=
'
x
'
,
c
=
'
r
'
)
full_sig
.
set_xlim
(
0
,
len
(
song
)
/
sr
)
pointers
[
'
clicks
'
]
=
all_clicks
[
pointers
[
'
mask
'
]]
pointers
[
'
autocorr
'
]
=
all_autocorr
[
pointers
[
'
mask
'
]]
pointers
[
'
cepstrum
'
]
=
all_cepstrum
[
pointers
[
'
mask
'
]]
raster
=
plt
.
subplot
(
gs
[
2
:
-
1
,
:
-
6
])
im
=
raster
.
imshow
(
pointers
[
'
clicks
'
].
T
,
aspect
=
'
auto
'
,
origin
=
'
lower
'
,
cmap
=
'
jet
'
,
extent
=
[
0
,
len
(
pointers
[
'
clicks
'
]),
-
10
,
10
])
mean_raster
=
plt
.
subplot
(
gs
[
2
:
-
1
,
-
6
:
-
4
])
line
,
=
mean_raster
.
plot
(
pointers
[
'
clicks
'
].
sum
(
0
),
np
.
arange
(
int
(
-
sr
*
10e-3
),
int
(
sr
*
10e-3
))
/
sr
*
1e3
)
mean_raster
.
set_ylim
(
-
10
,
10
)
r_button_ax
=
plt
.
subplot
(
gs
[
-
1
:,
:
5
])
r_button
=
MyRadioButtons
(
r_button_ax
,
[
'
signal
'
,
'
autocorr
'
,
'
cepstrum
'
],
orientation
=
'
horizontal
'
,
size
=
666
)
r_button_ax
.
axis
(
'
off
'
)
spec_ax
=
plt
.
subplot
(
gs
[
2
:
-
1
,
-
4
:])
spec
=
spec_ax
.
specgram
(
pointers
[
'
clicks
'
].
mean
(
0
),
Fs
=
sr
,
NFFT
=
128
,
noverlap
=
127
,
cmap
=
'
jet
'
)[
-
1
]
spec
.
set_clim
(
spec
.
get_clim
()[
1
]
-
80
,
spec
.
get_clim
()[
1
])
def
change_graph
(
label
):
if
label
==
'
signal
'
:
im
.
set_data
(
pointers
[
'
clicks
'
].
T
)
im
.
set_clim
(
pointers
[
'
clicks
'
].
min
(),
pointers
[
'
clicks
'
].
max
())
im
.
set_extent
([
0
,
len
(
pointers
[
'
clicks
'
]),
-
10
,
10
])
raster
.
set_xlim
(
0
,
len
(
pointers
[
'
clicks
'
]))
line
.
set_xdata
(
pointers
[
'
clicks
'
].
sum
(
0
))
line
.
set_ydata
(
np
.
arange
(
int
(
-
sr
*
10e-3
),
int
(
sr
*
10e-3
))
/
sr
*
1e3
)
mean_raster
.
set_ylim
(
-
10
,
10
)
elif
label
==
'
autocorr
'
:
im
.
set_data
(
pointers
[
'
autocorr
'
].
T
)
im
.
set_clim
(
pointers
[
'
autocorr
'
].
min
(),
pointers
[
'
autocorr
'
].
max
())
im
.
set_extent
([
0
,
len
(
pointers
[
'
clicks
'
]),
0
,
10
])
line
.
set_xdata
(
pointers
[
'
autocorr
'
].
sum
(
0
))
line
.
set_ydata
(
np
.
arange
(
0
,
int
(
sr
*
10e-3
))
/
sr
*
1e3
)
mean_raster
.
set_ylim
(
0
,
10
)
elif
label
==
'
cepstrum
'
:
im
.
set_data
(
pointers
[
'
cepstrum
'
].
T
)
im
.
set_clim
(
0
,
2
*
np
.
nanstd
(
pointers
[
'
cepstrum
'
]))
im
.
set_extent
([
0
,
len
(
pointers
[
'
clicks
'
]),
0
,
10
])
line
.
set_xdata
(
np
.
nansum
(
pointers
[
'
cepstrum
'
],
0
))
line
.
set_ydata
(
np
.
arange
(
0
,
int
(
sr
*
10e-3
))
/
sr
*
1e3
)
mean_raster
.
set_ylim
(
0
,
10
)
plt
.
draw
()
def
resize
(
event
):
fig
.
set_constrained_layout
(
True
)
plt
.
draw
()
plt
.
pause
(
0.2
)
fig
.
set_constrained_layout
(
False
)
r_button
.
on_clicked
(
change_graph
)
resize_b_ax
=
plt
.
subplot
(
gs
[
-
1
:,
5
:
7
])
resize_b
=
Button
(
resize_b_ax
,
'
Resize plot
'
)
resize_b
.
on_clicked
(
resize
)
hist_ax
=
plt
.
subplot
(
gs
[
-
1
:,
7
:
-
4
])
hist_ax
.
plot
(
np
.
linspace
(
0
,
prev
.
max
()
+
0.5
,
1024
),
kde
(
np
.
linspace
(
0
,
prev
.
max
()
+
0.5
,
1024
)))
hist_ax
.
set_xlim
(
0
,
prev
.
max
()
+
0.5
)
hist_ax
.
set_ylim
(
0
,
kde
(
np
.
linspace
(
0
,
prev
.
max
()
+
0.5
,
1024
)).
std
()
*
3.3
)
vlined
=
hist_ax
.
axvline
(
0.65
,
c
=
'
k
'
)
vlineu
=
hist_ax
.
axvline
(
0.65
,
c
=
'
k
'
)
down
=
[
0.65
]
def
onclick_down
(
event
):
if
event
.
inaxes
!=
hist_ax
:
return
down
[
0
]
=
event
.
xdata
def
onclick_up
(
event
):
if
event
.
inaxes
!=
hist_ax
:
return
if
abs
(
event
.
xdata
-
down
[
0
])
<
0.025
:
pointers
[
'
mask
'
]
=
prev
>
event
.
xdata
vlined
.
set_xdata
(
event
.
xdata
)
vlineu
.
set_xdata
(
event
.
xdata
)
elif
event
.
xdata
>
down
[
0
]:
pointers
[
'
mask
'
]
=
(
prev
>
down
[
0
])
&
(
prev
<
event
.
xdata
)
vlined
.
set_xdata
(
down
[
0
])
vlineu
.
set_xdata
(
event
.
xdata
)
else
:
pointers
[
'
mask
'
]
=
(
prev
<
down
[
0
])
&
(
prev
>
event
.
xdata
)
vlineu
.
set_xdata
(
down
[
0
])
vlined
.
set_xdata
(
event
.
xdata
)
pointers
[
'
clicks
'
]
=
all_clicks
[
pointers
[
'
mask
'
]]
pointers
[
'
autocorr
'
]
=
all_autocorr
[
pointers
[
'
mask
'
]]
pointers
[
'
cepstrum
'
]
=
all_cepstrum
[
pointers
[
'
mask
'
]]
scat
.
set_offsets
(
np
.
vstack
((
fine_pos_glob
[
pointers
[
'
mask
'
]]
/
sr
,
song
[
fine_pos_glob
[
pointers
[
'
mask
'
]]])).
T
)
spectro
=
np
.
flipud
(
20
*
np
.
log10
(
plt
.
mlab
.
specgram
(
pointers
[
'
clicks
'
].
mean
(
0
),
Fs
=
sr
,
NFFT
=
128
,
noverlap
=
127
)[
0
]))
spec
.
set_data
(
spectro
)
spec
.
set_clim
(
spectro
.
max
()
-
80
,
spectro
.
max
())
change_graph
(
r_button
.
value_selected
)
cur
=
Cursor
(
hist_ax
,
horizOn
=
False
,
vertOn
=
True
,
useblit
=
True
,
c
=
'
r
'
)
cur
.
connect_event
(
'
button_press_event
'
,
onclick_down
)
cur
.
connect_event
(
'
button_release_event
'
,
onclick_up
)
plt
.
draw
()
plt
.
pause
(
0.2
)
fig
.
set_constrained_layout
(
False
)
plt
.
show
()
return
0
if
__name__
==
'
__main__
'
:
parser
=
argparse
.
ArgumentParser
(
formatter_class
=
argparse
.
ArgumentDefaultsHelpFormatter
)
parser
.
add_argument
(
"
input
"
,
type
=
str
,
help
=
"
Input file
"
)
parser
.
add_argument
(
"
--channel
"
,
type
=
int
,
default
=
0
,
help
=
"
Sound channel to be analysed. Indices start from 0
"
)
parser
.
add_argument
(
"
--low
"
,
type
=
int
,
default
=
2_000
,
help
=
"
Low frequency cut of the bandpass
"
)
parser
.
add_argument
(
"
--high
"
,
type
=
int
,
default
=
20_000
,
help
=
"
High frequency cut of the bandpass
"
)
args
=
parser
.
parse_args
()
sys
.
exit
(
main
(
args
))
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment