Holiday syncing :)
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -4,9 +4,11 @@ import numpy as np
|
|||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from itertools import product
|
from itertools import product
|
||||||
from thunderhopper.modeltools import load_data
|
from thunderhopper.modeltools import load_data
|
||||||
|
from misc_functions import get_saturation
|
||||||
from color_functions import load_colors
|
from color_functions import load_colors
|
||||||
from plot_functions import hide_axis, ylimits, xlabel, ylabel, title_subplot,\
|
from plot_functions import hide_axis, ylimits, xlabel, ylabel, title_subplot,\
|
||||||
plot_line, plot_barcode, strip_zeros, time_bar, super_xlabel
|
plot_line, plot_barcode, strip_zeros, time_bar,\
|
||||||
|
letter_subplot, letter_subplots
|
||||||
from IPython import embed
|
from IPython import embed
|
||||||
|
|
||||||
def plot_snippets(axes, time, snippets, ymin=None, ymax=None, **kwargs):
|
def plot_snippets(axes, time, snippets, ymin=None, ymax=None, **kwargs):
|
||||||
@@ -20,52 +22,70 @@ def plot_bi_snippets(axes, time, snippets, **kwargs):
|
|||||||
plot_barcode(ax, time, snippets[:, ..., i], **kwargs)
|
plot_barcode(ax, time, snippets[:, ..., i], **kwargs)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def plot_curves(ax, scales, measures, fill_kwargs={}, **kwargs):
|
||||||
|
if measures.ndim == 1:
|
||||||
|
ax.plot(scales, measures, **kwargs)[0]
|
||||||
|
return measures
|
||||||
|
median_measure = np.median(measures, axis=1)
|
||||||
|
spread_measure = [np.percentile(measures, 25, axis=1),
|
||||||
|
np.percentile(measures, 75, axis=1)]
|
||||||
|
ax.plot(scales, median_measure, **kwargs)[0]
|
||||||
|
ax.fill_between(scales, *spread_measure, **fill_kwargs)
|
||||||
|
return median_measure
|
||||||
|
|
||||||
|
def show_saturation(ax, scales, measures, high=0.95, **kwargs):
|
||||||
|
high_ind = get_saturation(measures, high=high)[1]
|
||||||
|
return ax.plot(scales[high_ind], 0, transform=ax.get_xaxis_transform(),
|
||||||
|
marker='o', ms=10, zorder=6, clip_on=False, **kwargs)
|
||||||
|
|
||||||
# GENERAL SETTINGS:
|
# GENERAL SETTINGS:
|
||||||
target = 'Omocestus_rufipes'
|
target = 'Omocestus_rufipes'
|
||||||
data_paths = glob.glob(f'../data/inv/full/{target}*.npz')
|
data_paths = glob.glob(f'../data/inv/full/{target}*.npz')
|
||||||
stages = ['raw', 'filt', 'env', 'log', 'inv', 'conv', 'bi', 'feat']
|
ref_path = '../data/inv/full/ref_measures.npz'
|
||||||
|
save_path = '../figures/fig_invariance_full.pdf'
|
||||||
|
stages = ['filt', 'env', 'log', 'inv', 'conv', 'feat']
|
||||||
load_kwargs = dict(
|
load_kwargs = dict(
|
||||||
files=stages,
|
files=stages,
|
||||||
keywords=['scales', 'snip', 'measure']
|
keywords=['scales', 'snip', 'measure']
|
||||||
)
|
)
|
||||||
save_path = '../figures/fig_invariance_full.pdf'
|
|
||||||
|
|
||||||
# GRAPH SETTINGS:
|
# GRAPH SETTINGS:
|
||||||
fig_kwargs = dict(
|
fig_kwargs = dict(
|
||||||
figsize=(32/2.54, 16/2.54),
|
figsize=(32/2.54, 20/2.54),
|
||||||
)
|
)
|
||||||
super_grid_kwargs = dict(
|
super_grid_kwargs = dict(
|
||||||
nrows=1,
|
nrows=2,
|
||||||
ncols=3,
|
ncols=1,
|
||||||
wspace=0,
|
wspace=0,
|
||||||
hspace=0,
|
hspace=0,
|
||||||
left=0,
|
left=0,
|
||||||
right=1,
|
right=1,
|
||||||
bottom=0,
|
bottom=0,
|
||||||
top=1
|
top=1,
|
||||||
|
height_ratios=[3, 2]
|
||||||
)
|
)
|
||||||
subfig_specs = dict(
|
subfig_specs = dict(
|
||||||
snip=(slice(None), slice(0, -1)),
|
snip=(0, 0),
|
||||||
big=(slice(None), -1),
|
big=(1, 0),
|
||||||
)
|
)
|
||||||
snip_grid_kwargs = dict(
|
snip_grid_kwargs = dict(
|
||||||
nrows=len(stages),
|
nrows=len(stages),
|
||||||
ncols=None,
|
ncols=None,
|
||||||
wspace=0.1,
|
wspace=0.1,
|
||||||
hspace=0.4,
|
hspace=0.4,
|
||||||
left=0.15,
|
left=0.08,
|
||||||
right=0.95,
|
right=0.95,
|
||||||
bottom=0.08,
|
bottom=0.08,
|
||||||
top=0.95
|
top=0.95
|
||||||
)
|
)
|
||||||
big_grid_kwargs = dict(
|
big_grid_kwargs = dict(
|
||||||
nrows=1,
|
nrows=1,
|
||||||
ncols=1,
|
ncols=3,
|
||||||
wspace=0,
|
wspace=0.2,
|
||||||
hspace=0,
|
hspace=0,
|
||||||
left=0.2,
|
left=snip_grid_kwargs['left'],
|
||||||
right=0.96,
|
right=0.96,
|
||||||
bottom=0.08,
|
bottom=0.2,
|
||||||
top=0.95
|
top=0.95
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -79,9 +99,7 @@ fs = dict(
|
|||||||
bar=16,
|
bar=16,
|
||||||
)
|
)
|
||||||
colors = load_colors('../data/stage_colors.npz')
|
colors = load_colors('../data/stage_colors.npz')
|
||||||
colors['raw'] = "#000000"
|
|
||||||
lw = dict(
|
lw = dict(
|
||||||
raw=0.25,
|
|
||||||
filt=0.25,
|
filt=0.25,
|
||||||
env=0.25,
|
env=0.25,
|
||||||
log=0.25,
|
log=0.25,
|
||||||
@@ -92,25 +110,17 @@ lw = dict(
|
|||||||
big=3
|
big=3
|
||||||
)
|
)
|
||||||
xlabels = dict(
|
xlabels = dict(
|
||||||
snip='time [s]',
|
|
||||||
big='scale $\\alpha$',
|
big='scale $\\alpha$',
|
||||||
)
|
)
|
||||||
ylabels = dict(
|
ylabels = dict(
|
||||||
raw='$x$',
|
|
||||||
filt='$x_{\\text{filt}}$',
|
filt='$x_{\\text{filt}}$',
|
||||||
env='$x_{\\text{env}}$',
|
env='$x_{\\text{env}}$',
|
||||||
log='$x_{\\text{log}}$',
|
log='$x_{\\text{db}}$',
|
||||||
inv='$x_{\\text{inv}}$',
|
inv='$x_{\\text{inv}}$',
|
||||||
conv='$c_i$',
|
conv='$c_i$',
|
||||||
bi='$b_i$',
|
bi='$b_i$',
|
||||||
feat='$f_i$',
|
feat='$f_i$',
|
||||||
big='norm. intensity measure'
|
big=['intensity', 'rel. intensity', 'norm. intensity']
|
||||||
)
|
|
||||||
xlab_snip_kwargs = dict(
|
|
||||||
y=0,
|
|
||||||
fontsize=fs['lab_norm'],
|
|
||||||
ha='center',
|
|
||||||
va='bottom',
|
|
||||||
)
|
)
|
||||||
xlab_big_kwargs = dict(
|
xlab_big_kwargs = dict(
|
||||||
y=0,
|
y=0,
|
||||||
@@ -126,18 +136,17 @@ ylab_snip_kwargs = dict(
|
|||||||
va='center'
|
va='center'
|
||||||
)
|
)
|
||||||
ylab_big_kwargs = dict(
|
ylab_big_kwargs = dict(
|
||||||
x=0,
|
x=-0.12,
|
||||||
fontsize=fs['lab_norm'],
|
fontsize=fs['lab_norm'],
|
||||||
ha='center',
|
ha='center',
|
||||||
va='top',
|
va='bottom',
|
||||||
)
|
)
|
||||||
yloc = dict(
|
yloc = dict(
|
||||||
raw=500,
|
filt=3000,
|
||||||
filt=500,
|
env=1000,
|
||||||
env=250,
|
log=50,
|
||||||
log=25,
|
inv=20,
|
||||||
inv=10,
|
conv=2,
|
||||||
conv=1,
|
|
||||||
feat=1,
|
feat=1,
|
||||||
)
|
)
|
||||||
title_kwargs = dict(
|
title_kwargs = dict(
|
||||||
@@ -148,20 +157,18 @@ title_kwargs = dict(
|
|||||||
fontsize=fs['tit_norm'],
|
fontsize=fs['tit_norm'],
|
||||||
)
|
)
|
||||||
letter_snip_kwargs = dict(
|
letter_snip_kwargs = dict(
|
||||||
x=0.02,
|
x=0,
|
||||||
y=1,
|
yref=0.5,
|
||||||
ha='left',
|
ha='left',
|
||||||
va='top',
|
va='center',
|
||||||
fontsize=fs['letter'],
|
fontsize=fs['letter'],
|
||||||
fontweight='bold'
|
|
||||||
)
|
)
|
||||||
letter_big_kwargs = dict(
|
letter_big_kwargs = dict(
|
||||||
x=0,
|
x=0,
|
||||||
y=1,
|
y=1,
|
||||||
ha='left',
|
ha='left',
|
||||||
va='top',
|
va='bottom',
|
||||||
fontsize=fs['letter'],
|
fontsize=fs['letter'],
|
||||||
fontweight='bold'
|
|
||||||
)
|
)
|
||||||
bar_time = 5
|
bar_time = 5
|
||||||
bar_kwargs = dict(
|
bar_kwargs = dict(
|
||||||
@@ -181,6 +188,8 @@ bar_kwargs = dict(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# PREPARATION:
|
||||||
|
ref_data = dict(np.load(ref_path))
|
||||||
|
|
||||||
# EXECUTION:
|
# EXECUTION:
|
||||||
for data_path in data_paths:
|
for data_path in data_paths:
|
||||||
@@ -188,7 +197,7 @@ for data_path in data_paths:
|
|||||||
|
|
||||||
# Load invariance data:
|
# Load invariance data:
|
||||||
data, config = load_data(data_path, **load_kwargs)
|
data, config = load_data(data_path, **load_kwargs)
|
||||||
t_full = np.arange(data['snip_raw'].shape[0]) / config['rate']
|
t_full = np.arange(data['snip_filt'].shape[0]) / config['rate']
|
||||||
|
|
||||||
# Adjust grid parameters:
|
# Adjust grid parameters:
|
||||||
snip_grid_kwargs['ncols'] = data['example_scales'].size
|
snip_grid_kwargs['ncols'] = data['example_scales'].size
|
||||||
@@ -204,78 +213,91 @@ for data_path in data_paths:
|
|||||||
for i, j in product(range(snip_grid.nrows), range(snip_grid.ncols)):
|
for i, j in product(range(snip_grid.nrows), range(snip_grid.ncols)):
|
||||||
ax = snip_subfig.add_subplot(snip_grid[i, j])
|
ax = snip_subfig.add_subplot(snip_grid[i, j])
|
||||||
ax.set_xlim(t_full[0], t_full[-1])
|
ax.set_xlim(t_full[0], t_full[-1])
|
||||||
|
ax.yaxis.set_major_locator(plt.MultipleLocator(yloc[stages[i]]))
|
||||||
hide_axis(ax, 'bottom')
|
hide_axis(ax, 'bottom')
|
||||||
if i == 0:
|
if i == 0:
|
||||||
title = f'$\\alpha={strip_zeros(data["example_scales"][j])}$'
|
title = title_subplot(ax, f'$\\alpha={strip_zeros(data["example_scales"][j])}$',
|
||||||
title_subplot(ax, title, ref=snip_subfig, **title_kwargs)
|
ref=snip_subfig, **title_kwargs)
|
||||||
if j == 0:
|
if j == 0:
|
||||||
ylabel(ax, ylabels[stages[i]], **ylab_snip_kwargs, transform=snip_subfig.transSubfigure)
|
ylabel(ax, ylabels[stages[i]], **ylab_snip_kwargs, transform=snip_subfig.transSubfigure)
|
||||||
else:
|
else:
|
||||||
hide_axis(ax, 'left')
|
hide_axis(ax, 'left')
|
||||||
if stages[i] != 'bi':
|
|
||||||
ax.yaxis.set_major_locator(plt.MultipleLocator(yloc[stages[i]]))
|
|
||||||
snip_axes[i, j] = ax
|
snip_axes[i, j] = ax
|
||||||
time_bar(snip_axes[-1, -1], **bar_kwargs)
|
time_bar(snip_axes[-1, -1], **bar_kwargs)
|
||||||
|
letter_subplot(snip_subfig, 'a', ref=title, **letter_snip_kwargs)
|
||||||
|
|
||||||
# Prepare single analysis axis:
|
# Prepare analysis axes:
|
||||||
big_subfig = fig.add_subfigure(super_grid[subfig_specs['big']])
|
big_subfig = fig.add_subfigure(super_grid[subfig_specs['big']])
|
||||||
big_grid = big_subfig.add_gridspec(**big_grid_kwargs)
|
big_grid = big_subfig.add_gridspec(**big_grid_kwargs)
|
||||||
big_ax = big_subfig.add_subplot(big_grid[0, 0])
|
big_axes = np.zeros((big_grid.ncols,), dtype=object)
|
||||||
big_ax.set_xlim(data['scales'].min(), data['scales'].max())
|
for i in range(big_grid.ncols):
|
||||||
big_ax.set_xscale('symlog', linthresh=data['scales'][1], linscale=0.5)
|
ax = big_subfig.add_subplot(big_grid[0, i])
|
||||||
big_ax.set_yscale('symlog', linthresh=0.01, linscale=0.1)
|
ax.set_xlim(data['scales'][0], data['scales'][-1])
|
||||||
xlabel(big_ax, xlabels['big'], **xlab_big_kwargs, transform=big_subfig.transSubfigure)
|
ax.set_xscale('symlog', linthresh=data['scales'][1], linscale=0.5)
|
||||||
ylabel(big_ax, ylabels['big'], **ylab_big_kwargs, transform=big_subfig.transSubfigure)
|
ax.set_yscale('symlog', linthresh=0.01, linscale=0.1)
|
||||||
|
xlabel(ax, xlabels['big'], transform=big_subfig, **xlab_big_kwargs)
|
||||||
|
ylabel(ax, ylabels['big'][i], **ylab_big_kwargs)
|
||||||
|
big_axes[i] = ax
|
||||||
|
letter_subplots(big_axes, 'bc', **letter_big_kwargs)
|
||||||
|
|
||||||
# Plot raw snippets:
|
# # Plot filtered snippets:
|
||||||
plot_snippets(snip_axes[0, :], t_full, data['snip_raw'],
|
# plot_snippets(snip_axes[0, :], t_full, data['snip_filt'],
|
||||||
c=colors['raw'], lw=lw['raw'])
|
# c=colors['filt'], lw=lw['filt'])
|
||||||
|
|
||||||
# Plot filtered snippets:
|
# # Plot envelope snippets:
|
||||||
plot_snippets(snip_axes[1, :], t_full, data['snip_filt'],
|
# plot_snippets(snip_axes[1, :], t_full, data['snip_env'],
|
||||||
c=colors['filt'], lw=lw['filt'])
|
# ymin=0, c=colors['env'], lw=lw['env'])
|
||||||
|
|
||||||
# Plot envelope snippets:
|
# # Plot logarithmic snippets:
|
||||||
plot_snippets(snip_axes[2, :], t_full, data['snip_env'],
|
# plot_snippets(snip_axes[2, :], t_full, data['snip_log'],
|
||||||
ymin=0, c=colors['env'], lw=lw['env'])
|
# c=colors['log'], lw=lw['log'])
|
||||||
|
|
||||||
# Plot logarithmic snippets:
|
# # Plot invariant snippets:
|
||||||
plot_snippets(snip_axes[3, :], t_full, data['snip_log'],
|
# plot_snippets(snip_axes[3, :], t_full, data['snip_inv'],
|
||||||
ymax=0, c=colors['log'], lw=lw['log'])
|
# c=colors['inv'], lw=lw['inv'])
|
||||||
|
|
||||||
# Plot invariant snippets:
|
# # Plot kernel response snippets:
|
||||||
plot_snippets(snip_axes[4, :], t_full, data['snip_inv'],
|
# plot_snippets(snip_axes[4, :], t_full, data['snip_conv'],
|
||||||
c=colors['inv'], lw=lw['inv'])
|
# c=colors['conv'], lw=lw['conv'])
|
||||||
|
|
||||||
# Plot kernel response snippets:
|
# # Plot feature snippets:
|
||||||
plot_snippets(snip_axes[5, :], t_full, data['snip_conv'],
|
# plot_snippets(snip_axes[5, :], t_full, data['snip_feat'],
|
||||||
c=colors['conv'], lw=lw['conv'])
|
# ymin=0, ymax=1, c=colors['feat'], lw=lw['feat'])
|
||||||
|
|
||||||
# Plot binary snippets:
|
|
||||||
plot_bi_snippets(snip_axes[6, :], t_full, data['snip_bi'],
|
|
||||||
color=colors['bi'], lw=lw['bi'])
|
|
||||||
|
|
||||||
# Plot feature snippets:
|
|
||||||
plot_snippets(snip_axes[7, :], t_full, data['snip_feat'],
|
|
||||||
ymin=0, ymax=1, c=colors['feat'], lw=lw['feat'])
|
|
||||||
|
|
||||||
# Analysis results:
|
# Analysis results:
|
||||||
|
scales_rel = data['scales'] - data['scales'][0]
|
||||||
|
scales_rel /= scales_rel[-1]
|
||||||
for stage in stages:
|
for stage in stages:
|
||||||
key = f'measure_{stage}'
|
measure = data[f'measure_{stage}']
|
||||||
if stage == 'bi':
|
|
||||||
continue
|
|
||||||
# Min-max normalization:
|
|
||||||
base_ind = np.argmin(data['scales'])
|
|
||||||
data[key] -= data[key][base_ind, ...]
|
|
||||||
data[key] /= data[key].max(axis=0)
|
|
||||||
|
|
||||||
# Condense measure:
|
# Plot unmodified intensity measures:
|
||||||
if stage in ['conv', 'feat']:
|
curve = plot_curves(big_axes[0], data['scales'], measure, c=colors[stage], lw=lw['big'],
|
||||||
data[key] = np.nanmedian(data[key], axis=1)
|
fill_kwargs=dict(color=colors[stage], alpha=0.25))
|
||||||
|
if stage in ['log', 'inv', 'conv', 'feat']:
|
||||||
|
show_saturation(big_axes[0], data['scales'], curve, c=colors[stage])
|
||||||
|
|
||||||
# Plot measure over scales:
|
# # Relate to pure-noise reference:
|
||||||
big_ax.plot(data['scales'], data[key],
|
# norm_measure = measure / ref_data[stage]
|
||||||
c=colors[stage], lw=lw['big'])
|
|
||||||
|
# # Plot noise-related intensity measures:
|
||||||
|
# big_axes[1].plot(data['scales'], norm_measure, c=colors[stage], lw=lw['big'])
|
||||||
|
|
||||||
|
# Normalize measure to [0, 1]:
|
||||||
|
min_measure = measure.min(axis=0)
|
||||||
|
max_measure = measure.max(axis=0)
|
||||||
|
norm_measure = (measure - min_measure) / (max_measure - min_measure)
|
||||||
|
|
||||||
|
# Plot normalized intensity measures:
|
||||||
|
curve = plot_curves(big_axes[1], data['scales'], norm_measure, c=colors[stage], lw=lw['big'],
|
||||||
|
fill_kwargs=dict(color=colors[stage], alpha=0.25))
|
||||||
|
if stage in ['log', 'inv', 'conv', 'feat']:
|
||||||
|
show_saturation(big_axes[1], data['scales'], curve, c=colors[stage])
|
||||||
|
|
||||||
|
# # Plot over relative scales:
|
||||||
|
# plot_curves(big_axes[2], scales_rel, norm_measure, c=colors[stage], lw=lw['big'],
|
||||||
|
# fill_kwargs=dict(color=colors[stage], alpha=0.25))
|
||||||
|
# scales_rel = curve - curve.min()
|
||||||
|
# scales_rel /= scales_rel.max()
|
||||||
|
|
||||||
if save_path is not None:
|
if save_path is not None:
|
||||||
fig.savefig(save_path)
|
fig.savefig(save_path)
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ import matplotlib.pyplot as plt
|
|||||||
from itertools import product
|
from itertools import product
|
||||||
from thunderhopper.filetools import search_files
|
from thunderhopper.filetools import search_files
|
||||||
from thunderhopper.modeltools import load_data
|
from thunderhopper.modeltools import load_data
|
||||||
|
from misc_functions import shorten_species, get_kde, get_saturation
|
||||||
from color_functions import load_colors
|
from color_functions import load_colors
|
||||||
from plot_functions import hide_axis, ylimits, xlabel, ylabel, hide_ticks,\
|
from plot_functions import hide_axis, ylimits, super_xlabel, ylabel, hide_ticks,\
|
||||||
plot_line, strip_zeros, time_bar, zoom_inset,\
|
plot_line, strip_zeros, time_bar, zoom_inset,\
|
||||||
letter_subplot, title_subplot
|
letter_subplot, letter_subplots, title_subplot
|
||||||
from IPython import embed
|
from IPython import embed
|
||||||
|
|
||||||
def add_snip_axes(fig, grid_kwargs):
|
def add_snip_axes(fig, grid_kwargs):
|
||||||
@@ -26,39 +27,86 @@ def plot_snippets(axes, time, snippets, ymin=None, ymax=None, **kwargs):
|
|||||||
handles.extend(plot_line(ax, time, snippet, ymin=ymin, ymax=ymax, **kwargs))
|
handles.extend(plot_line(ax, time, snippet, ymin=ymin, ymax=ymax, **kwargs))
|
||||||
return handles
|
return handles
|
||||||
|
|
||||||
|
def plot_dist_shifted(ax, data, axis, pdf=None, sigma=0.1, which='x',
|
||||||
|
base=None, cap=None, add_pdf=False, shifted=False, **kwargs):
|
||||||
|
if pdf is None:
|
||||||
|
pdf, axis = get_kde(data, sigma, axis)
|
||||||
|
if base is None:
|
||||||
|
base = pdf.min()
|
||||||
|
if cap is None:
|
||||||
|
cap = pdf.max()
|
||||||
|
pdf = (pdf - pdf.min()) / (pdf.max() - pdf.min()) * (cap - base) + base
|
||||||
|
|
||||||
|
if which == 'x':
|
||||||
|
transform = ax.get_xaxis_transform()
|
||||||
|
elif which == 'y':
|
||||||
|
transform = ax.get_yaxis_transform()
|
||||||
|
else:
|
||||||
|
transform = ax.transData
|
||||||
|
|
||||||
|
rng = np.random.default_rng()
|
||||||
|
handles = []
|
||||||
|
for value in data:
|
||||||
|
ind = np.nonzero(axis == value)[0][0]
|
||||||
|
offset = base if not shifted else rng.uniform(base, pdf[ind])
|
||||||
|
variables = (offset, value) if which=='y' else (value, offset)
|
||||||
|
handles.extend(ax.plot(*variables, transform=transform, **kwargs))
|
||||||
|
if add_pdf:
|
||||||
|
variables = (pdf, axis) if which=='y' else (axis, pdf)
|
||||||
|
pdf_handle = ax.plot(*variables, transform=transform, c='k', lw=1)
|
||||||
|
return handles, pdf_handle
|
||||||
|
return handles
|
||||||
|
|
||||||
|
def zalpha(handles, background='w', down=1):
|
||||||
|
twins = []
|
||||||
|
for handle in handles:
|
||||||
|
twin = handle.copy()
|
||||||
|
twin.set(color=background, alpha=1)
|
||||||
|
twin.set_zorder(handle.get_zorder() - down)
|
||||||
|
twins.append(twin)
|
||||||
|
return twins
|
||||||
|
|
||||||
# GENERAL SETTINGS:
|
# GENERAL SETTINGS:
|
||||||
target = 'Omocestus_rufipes'
|
target = 'Omocestus_rufipes'
|
||||||
data_paths = search_files(target, excl='noise', dir='../data/inv/log_hp/')
|
data_paths = search_files(target, excl='noise', dir='../data/inv/log_hp/')
|
||||||
species_paths = search_files('*', incl='noise', dir='../data/inv/log_hp/')
|
ref_path = '../data/inv/log_hp/ref_measures.npz'
|
||||||
|
save_path = '../figures/fig_invariance_log_hp.pdf'
|
||||||
|
target_species = [
|
||||||
|
'Omocestus_rufipes',
|
||||||
|
'Chorthippus_biguttulus',
|
||||||
|
'Chorthippus_mollis',
|
||||||
|
'Chrysochraon_dispar',
|
||||||
|
'Gomphocerippus_rufus',
|
||||||
|
'Pseudochorthippus_parallelus',
|
||||||
|
]
|
||||||
stages = ['env', 'log', 'inv']
|
stages = ['env', 'log', 'inv']
|
||||||
load_kwargs = dict(
|
load_kwargs = dict(
|
||||||
files=stages,
|
files=stages,
|
||||||
keywords=['scales', 'snip', 'measure']
|
keywords=['scales', 'snip', 'measure']
|
||||||
)
|
)
|
||||||
save_path = '../figures/fig_invariance_log_hp.pdf'
|
|
||||||
compute_ratios = True
|
compute_ratios = True
|
||||||
show_diag = True
|
show_diag = True
|
||||||
show_noise = True
|
show_plateaus = True
|
||||||
|
|
||||||
# GRAPH SETTINGS:
|
# GRAPH SETTINGS:
|
||||||
fig_kwargs = dict(
|
fig_kwargs = dict(
|
||||||
figsize=(32/2.54, 16/2.54),
|
figsize=(32/2.54, 32/2.54),
|
||||||
)
|
)
|
||||||
super_grid_kwargs = dict(
|
super_grid_kwargs = dict(
|
||||||
nrows=2,
|
nrows=3,
|
||||||
ncols=3,
|
ncols=1,
|
||||||
wspace=0,
|
wspace=0,
|
||||||
hspace=0,
|
hspace=0,
|
||||||
left=0,
|
left=0,
|
||||||
right=1,
|
right=1,
|
||||||
bottom=0,
|
bottom=0,
|
||||||
top=1
|
top=1,
|
||||||
|
height_ratios=[1, 1, 1]
|
||||||
)
|
)
|
||||||
subfig_specs = dict(
|
subfig_specs = dict(
|
||||||
pure=(0, slice(0, -1)),
|
pure=(0, slice(None)),
|
||||||
noise=(1, slice(0, -1)),
|
noise=(1, slice(None)),
|
||||||
big=(slice(None), -1),
|
big=(2, slice(None)),
|
||||||
)
|
)
|
||||||
block_height = 0.8
|
block_height = 0.8
|
||||||
edge_padding = 0.08
|
edge_padding = 0.08
|
||||||
@@ -67,7 +115,7 @@ pure_grid_kwargs = dict(
|
|||||||
ncols=None,
|
ncols=None,
|
||||||
wspace=0.1,
|
wspace=0.1,
|
||||||
hspace=0.15,
|
hspace=0.15,
|
||||||
left=0.16,
|
left=0.11,
|
||||||
right=0.95,
|
right=0.95,
|
||||||
bottom=1 - block_height - edge_padding,
|
bottom=1 - block_height - edge_padding,
|
||||||
top=1 - edge_padding,
|
top=1 - edge_padding,
|
||||||
@@ -76,23 +124,23 @@ pure_grid_kwargs = dict(
|
|||||||
noise_grid_kwargs = dict(
|
noise_grid_kwargs = dict(
|
||||||
nrows=len(stages),
|
nrows=len(stages),
|
||||||
ncols=None,
|
ncols=None,
|
||||||
wspace=0.1,
|
wspace=pure_grid_kwargs['wspace'],
|
||||||
hspace=0.15,
|
hspace=pure_grid_kwargs['hspace'],
|
||||||
left=0.16,
|
left=pure_grid_kwargs['left'],
|
||||||
right=0.95,
|
right=pure_grid_kwargs['right'],
|
||||||
bottom=edge_padding,
|
bottom=edge_padding,
|
||||||
top=edge_padding + block_height,
|
top=edge_padding + block_height,
|
||||||
height_ratios=[1, 2, 1]
|
height_ratios=[1, 2, 1]
|
||||||
)
|
)
|
||||||
big_grid_kwargs = dict(
|
big_grid_kwargs = dict(
|
||||||
nrows=2,
|
nrows=1,
|
||||||
ncols=1,
|
ncols=3,
|
||||||
wspace=0,
|
wspace=0.3,
|
||||||
hspace=0.3,
|
hspace=0,
|
||||||
left=0.19,
|
left=pure_grid_kwargs['left'],
|
||||||
right=0.96,
|
right=pure_grid_kwargs['right'],
|
||||||
bottom=0.09,
|
bottom=0.05,
|
||||||
top=0.98
|
top=1
|
||||||
)
|
)
|
||||||
anchor_kwargs = dict(
|
anchor_kwargs = dict(
|
||||||
aspect='equal',
|
aspect='equal',
|
||||||
@@ -110,8 +158,14 @@ fs = dict(
|
|||||||
bar=16,
|
bar=16,
|
||||||
)
|
)
|
||||||
colors = load_colors('../data/stage_colors.npz')
|
colors = load_colors('../data/stage_colors.npz')
|
||||||
lw_snippets = 1
|
species_colors = load_colors('../data/species_colors.npz')
|
||||||
lw_big = 3
|
noise_colors = [(0.5, 0.5, 0.5), (0.7, 0.7, 0.7)]
|
||||||
|
lw = dict(
|
||||||
|
snip=1,
|
||||||
|
big=4,
|
||||||
|
spec=2,
|
||||||
|
plateau=1,
|
||||||
|
)
|
||||||
xlabels = dict(
|
xlabels = dict(
|
||||||
big='scale $\\alpha$',
|
big='scale $\\alpha$',
|
||||||
)
|
)
|
||||||
@@ -135,7 +189,7 @@ ylab_snip_kwargs = dict(
|
|||||||
va='center',
|
va='center',
|
||||||
)
|
)
|
||||||
ylab_big_kwargs = dict(
|
ylab_big_kwargs = dict(
|
||||||
x=0.05,
|
x=0,
|
||||||
fontsize=fs['lab_tex'],
|
fontsize=fs['lab_tex'],
|
||||||
ha='center',
|
ha='center',
|
||||||
va='top',
|
va='top',
|
||||||
@@ -160,10 +214,10 @@ letter_snip_kwargs = dict(
|
|||||||
fontsize=fs['letter'],
|
fontsize=fs['letter'],
|
||||||
)
|
)
|
||||||
letter_big_kwargs = dict(
|
letter_big_kwargs = dict(
|
||||||
x=0.05,
|
x=0,
|
||||||
yref=letter_snip_kwargs['yref'],
|
y=1,
|
||||||
ha='left',
|
ha='left',
|
||||||
va='center',
|
va='bottom',
|
||||||
fontsize=fs['letter'],
|
fontsize=fs['letter'],
|
||||||
)
|
)
|
||||||
zoom_inset_bounds = [0.1, 0.2, 0.8, 0.6]
|
zoom_inset_bounds = [0.1, 0.2, 0.8, 0.6]
|
||||||
@@ -204,33 +258,77 @@ bar_kwargs = dict(
|
|||||||
va='center',
|
va='center',
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
leg_kwargs = dict(
|
||||||
|
ncols=2,
|
||||||
|
loc='upper right',
|
||||||
|
bbox_to_anchor=(0, 0.6, 1, 0.4),
|
||||||
|
frameon=False,
|
||||||
|
prop=dict(
|
||||||
|
size=12,
|
||||||
|
style='italic',
|
||||||
|
),
|
||||||
|
borderpad=0,
|
||||||
|
borderaxespad=0,
|
||||||
|
handlelength=1,
|
||||||
|
columnspacing=1,
|
||||||
|
)
|
||||||
diag_kwargs = dict(
|
diag_kwargs = dict(
|
||||||
c=(0.75, 0.75, 0.75),
|
c=(0.75, 0.75, 0.75),
|
||||||
lw=2,
|
lw=2,
|
||||||
ls='--',
|
ls='--',
|
||||||
zorder=1.9,
|
zorder=1.9,
|
||||||
)
|
)
|
||||||
noise_rel_thresh = 0.95
|
plateau_settings = dict(
|
||||||
noise_kwargs = dict(
|
low=0.05,
|
||||||
fc=(0.9, 0.9, 0.9),
|
high=0.95,
|
||||||
|
first=True,
|
||||||
|
last=True,
|
||||||
|
condense=None,
|
||||||
|
)
|
||||||
|
plateau_rect_kwargs = dict(
|
||||||
ec='none',
|
ec='none',
|
||||||
lw=0,
|
lw=0,
|
||||||
zorder=1.5,
|
zorder=1.5,
|
||||||
)
|
)
|
||||||
|
plateau_line_kwargs = dict(
|
||||||
|
lw=lw['plateau'],
|
||||||
|
ls='--',
|
||||||
|
zorder=1,
|
||||||
|
)
|
||||||
|
plateau_dot_kwargs = dict(
|
||||||
|
marker='o',
|
||||||
|
markersize=10,
|
||||||
|
markeredgecolor='k',
|
||||||
|
markeredgewidth=1,
|
||||||
|
# alpha=1,
|
||||||
|
zorder=6,
|
||||||
|
clip_on=False,
|
||||||
|
# base=0,
|
||||||
|
# cap=0.15,
|
||||||
|
# add_pdf=True,
|
||||||
|
)
|
||||||
|
kde_kwargs = dict(
|
||||||
|
sigma=0.1,
|
||||||
|
)
|
||||||
|
|
||||||
# PREPARATION:
|
# PREPARATION:
|
||||||
if compute_ratios:
|
if compute_ratios:
|
||||||
ref_data = load_data('../data/processed/white_noise_sd-1.npz', files=stages)[0]
|
ref_measures = dict(np.load(ref_path))
|
||||||
ref_measures = {k: v.std() for k, v in ref_data.items() if not k.endswith('rate')}
|
|
||||||
|
|
||||||
species_measures = []
|
species_measures = {}
|
||||||
for species_path in species_paths:
|
thresh_inds = np.zeros((len(target_species),), dtype=int)
|
||||||
species_data, _ = load_data(species_path, **load_kwargs)
|
thresh_scales = np.zeros((len(target_species),), dtype=float)
|
||||||
species_measure = species_data['measure_inv']
|
for i, species in enumerate(target_species):
|
||||||
|
path = search_files(species, incl='noise', dir='../data/inv/log_hp/')[0]
|
||||||
|
species_data = load_data(path, **load_kwargs)[0]
|
||||||
|
measure = species_data['measure_inv']
|
||||||
|
scales = species_data['scales']
|
||||||
if compute_ratios:
|
if compute_ratios:
|
||||||
species_measure /= ref_measures['inv']
|
measure /= ref_measures['inv']
|
||||||
species_measures.append(species_measure)
|
species_measures[species] = measure
|
||||||
species_measures = np.array(species_measures).T
|
thresh_inds[i] = get_saturation(measure, **plateau_settings)[1]
|
||||||
|
thresh_scales[i] = scales[thresh_inds[i]]
|
||||||
|
thresh_pdf, pdf_axis = get_kde(thresh_scales, axis=scales, **kde_kwargs)
|
||||||
|
|
||||||
# EXECUTION:
|
# EXECUTION:
|
||||||
for data_path in data_paths:
|
for data_path in data_paths:
|
||||||
@@ -273,7 +371,7 @@ for data_path in data_paths:
|
|||||||
transform=noise_subfig.transSubfigure)
|
transform=noise_subfig.transSubfigure)
|
||||||
for ax, scale in zip(noise_axes[0, :], noise_data['example_scales']):
|
for ax, scale in zip(noise_axes[0, :], noise_data['example_scales']):
|
||||||
noise_title = title_subplot(ax, f'$\\alpha={strip_zeros(scale)}$', **title_kwargs)
|
noise_title = title_subplot(ax, f'$\\alpha={strip_zeros(scale)}$', **title_kwargs)
|
||||||
letter_subplot(noise_subfig, 'c', ref=noise_title, **letter_snip_kwargs)
|
letter_subplot(noise_subfig, 'b', ref=noise_title, **letter_snip_kwargs)
|
||||||
noise_inset = noise_axes[0, 0].inset_axes(zoom_inset_bounds)
|
noise_inset = noise_axes[0, 0].inset_axes(zoom_inset_bounds)
|
||||||
noise_inset.spines[:].set(visible=True, lw=zoom_kwargs['lw'])
|
noise_inset.spines[:].set(visible=True, lw=zoom_kwargs['lw'])
|
||||||
noise_inset.tick_params(**inset_tick_kwargs)
|
noise_inset.tick_params(**inset_tick_kwargs)
|
||||||
@@ -282,51 +380,49 @@ for data_path in data_paths:
|
|||||||
# Prepare analysis axes:
|
# Prepare analysis axes:
|
||||||
big_subfig = fig.add_subfigure(super_grid[subfig_specs['big']])
|
big_subfig = fig.add_subfigure(super_grid[subfig_specs['big']])
|
||||||
big_grid = big_subfig.add_gridspec(**big_grid_kwargs)
|
big_grid = big_subfig.add_gridspec(**big_grid_kwargs)
|
||||||
big_axes = np.zeros((big_grid.nrows,), dtype=object)
|
big_axes = np.zeros((big_grid.ncols,), dtype=object)
|
||||||
for i, scales in enumerate([pure_scales, noise_scales]):
|
for i, scales in enumerate([pure_scales, noise_scales, noise_scales]):
|
||||||
ax = big_subfig.add_subplot(big_grid[i, 0])
|
ax = big_subfig.add_subplot(big_grid[0, i])
|
||||||
ax.set_xlim(scales[0], scales[-1])
|
ax.set_xlim(scales[0], scales[-1])
|
||||||
ax.set_ylim(scales[0], scales[-1])
|
ax.set_ylim(scales[0], scales[-1])
|
||||||
ax.set_xscale('symlog', linthresh=scales[1], linscale=0.5)
|
ax.set_xscale('symlog', linthresh=scales[1], linscale=0.5)
|
||||||
ax.set_yscale('symlog', linthresh=scales[1], linscale=0.5)
|
ax.set_yscale('symlog', linthresh=scales[1], linscale=0.5)
|
||||||
ax.set_aspect(**anchor_kwargs)
|
ax.set_aspect(**anchor_kwargs)
|
||||||
ylabel(ax, ylabels['big'], transform=big_subfig.transSubfigure, **ylab_big_kwargs)
|
if i > 0:
|
||||||
if i == 0:
|
hide_ticks(ax, 'left')
|
||||||
hide_ticks(ax, 'bottom')
|
|
||||||
letter_subplot(big_subfig, 'b', ref=pure_title, **letter_big_kwargs)
|
|
||||||
else:
|
|
||||||
xlabel(ax, xlabels['big'], transform=big_subfig.transSubfigure, **xlab_big_kwargs)
|
|
||||||
letter_subplot(big_subfig, 'd', ref=noise_title, **letter_big_kwargs)
|
|
||||||
big_axes[i] = ax
|
big_axes[i] = ax
|
||||||
|
ylabel(big_axes[0], ylabels['big'], transform=big_subfig.transSubfigure, **ylab_big_kwargs)
|
||||||
|
super_xlabel(xlabels['big'], big_subfig, big_axes[0], big_axes[-1], **xlab_big_kwargs)
|
||||||
|
letter_subplots(big_axes, 'cde', **letter_big_kwargs)
|
||||||
|
|
||||||
# Plot pure-song envelope snippets:
|
# Plot pure-song envelope snippets:
|
||||||
handle = plot_snippets(pure_axes[0, :], t_full, pure_data['snip_env'],
|
handle = plot_snippets(pure_axes[0, :], t_full, pure_data['snip_env'],
|
||||||
ymin=0, c=colors['env'], lw=lw_snippets)[0]
|
ymin=0, c=colors['env'], lw=lw['snip'])[0]
|
||||||
zoom_inset(pure_axes[0, 0], pure_inset, handle, transform=pure_axes[0, 0].transAxes, **zoom_kwargs)
|
zoom_inset(pure_axes[0, 0], pure_inset, handle, transform=pure_axes[0, 0].transAxes, **zoom_kwargs)
|
||||||
|
|
||||||
# Plot pure-song logarithmic snippets:
|
# Plot pure-song logarithmic snippets:
|
||||||
plot_snippets(pure_axes[1, :], t_full, pure_data['snip_log'],
|
plot_snippets(pure_axes[1, :], t_full, pure_data['snip_log'],
|
||||||
c=colors['log'], lw=lw_snippets)
|
c=colors['log'], lw=lw['snip'])
|
||||||
|
|
||||||
# Plot pure-song invariant snippets:
|
# Plot pure-song invariant snippets:
|
||||||
plot_snippets(pure_axes[2, :], t_full, pure_data['snip_inv'],
|
plot_snippets(pure_axes[2, :], t_full, pure_data['snip_inv'],
|
||||||
c=colors['inv'], lw=lw_snippets)
|
c=colors['inv'], lw=lw['snip'])
|
||||||
|
|
||||||
# Plot noise-song envelope snippets:
|
# Plot noise-song envelope snippets:
|
||||||
ymin, ymax = pure_axes[0, 0].get_ylim()
|
ymin, ymax = pure_axes[0, 0].get_ylim()
|
||||||
handle = plot_snippets(noise_axes[0, :], t_full, noise_data['snip_env'],
|
handle = plot_snippets(noise_axes[0, :], t_full, noise_data['snip_env'],
|
||||||
ymin, ymax, c=colors['env'], lw=lw_snippets)[0]
|
ymin, ymax, c=colors['env'], lw=lw['snip'])[0]
|
||||||
zoom_inset(noise_axes[0, 0], noise_inset, handle, transform=noise_axes[0, 0].transAxes, **zoom_kwargs)
|
zoom_inset(noise_axes[0, 0], noise_inset, handle, transform=noise_axes[0, 0].transAxes, **zoom_kwargs)
|
||||||
|
|
||||||
# Plot noise-song logarithmic snippets:
|
# Plot noise-song logarithmic snippets:
|
||||||
ymin, ymax = pure_axes[1, 0].get_ylim()
|
ymin, ymax = pure_axes[1, 0].get_ylim()
|
||||||
plot_snippets(noise_axes[1, :], t_full, noise_data['snip_log'],
|
plot_snippets(noise_axes[1, :], t_full, noise_data['snip_log'],
|
||||||
ymin, ymax, c=colors['log'], lw=lw_snippets)
|
ymin, ymax, c=colors['log'], lw=lw['snip'])
|
||||||
|
|
||||||
# Plot noise-song invariant snippets:
|
# Plot noise-song invariant snippets:
|
||||||
ymin, ymax = pure_axes[2, 0].get_ylim()
|
ymin, ymax = pure_axes[2, 0].get_ylim()
|
||||||
plot_snippets(noise_axes[2, :], t_full, noise_data['snip_inv'],
|
plot_snippets(noise_axes[2, :], t_full, noise_data['snip_inv'],
|
||||||
ymin, ymax, c=colors['inv'], lw=lw_snippets)
|
ymin, ymax, c=colors['inv'], lw=lw['snip'])
|
||||||
|
|
||||||
# Indicate time scale:
|
# Indicate time scale:
|
||||||
time_bar(noise_axes[-1, -1], **bar_kwargs)
|
time_bar(noise_axes[-1, -1], **bar_kwargs)
|
||||||
@@ -342,34 +438,46 @@ for data_path in data_paths:
|
|||||||
noise_data['measure_inv'] /= ref_measures['inv']
|
noise_data['measure_inv'] /= ref_measures['inv']
|
||||||
|
|
||||||
# Plot pure-song measures (ideal):
|
# Plot pure-song measures (ideal):
|
||||||
big_axes[0].plot(pure_scales, pure_data['measure_env'], c=colors['env'], lw=lw_big)
|
big_axes[0].plot(pure_scales, pure_data['measure_env'], c=colors['env'], lw=lw['big'])
|
||||||
big_axes[0].plot(pure_scales, pure_data['measure_log'], c=colors['log'], lw=lw_big)
|
big_axes[0].plot(pure_scales, pure_data['measure_log'], c=colors['log'], lw=lw['big'])
|
||||||
big_axes[0].plot(pure_scales, pure_data['measure_inv'], c=colors['inv'], lw=lw_big)
|
big_axes[0].plot(pure_scales, pure_data['measure_inv'], c=colors['inv'], lw=lw['big'])
|
||||||
|
|
||||||
# Plot noise-song measures (limited):
|
# Plot noise-song measures (limited):
|
||||||
big_axes[1].plot(noise_scales, noise_data['measure_env'], c=colors['env'], lw=lw_big)
|
big_axes[1].plot(noise_scales, noise_data['measure_env'], c=colors['env'], lw=lw['big'])
|
||||||
big_axes[1].plot(noise_scales, noise_data['measure_log'], c=colors['log'], lw=lw_big)
|
big_axes[1].plot(noise_scales, noise_data['measure_log'], c=colors['log'], lw=lw['big'])
|
||||||
big_axes[1].plot(noise_scales, noise_data['measure_inv'], c=colors['inv'], lw=lw_big)
|
big_axes[1].plot(noise_scales, noise_data['measure_inv'], c=colors['inv'], lw=lw['big'])
|
||||||
|
|
||||||
# Plot species measures:
|
|
||||||
big_axes[1].plot(noise_scales, species_measures, 'k', lw=lw_big, zorder=2.1)
|
|
||||||
|
|
||||||
if show_diag:
|
if show_diag:
|
||||||
# Indicate diagonal:
|
# Indicate diagonal:
|
||||||
big_axes[0].plot(pure_scales, pure_scales, **diag_kwargs)
|
big_axes[0].plot(pure_scales, pure_scales, **diag_kwargs)
|
||||||
big_axes[1].plot(noise_scales, noise_scales, **diag_kwargs)
|
big_axes[1].plot(noise_scales, noise_scales, **diag_kwargs)
|
||||||
|
|
||||||
if show_noise:
|
if show_plateaus:
|
||||||
# Indicate noise floor:
|
# Indicate low and high plateaus of noise invariance curve:
|
||||||
if compute_ratios:
|
low_ind, high_ind = get_saturation(noise_data['measure_inv'], **plateau_settings)
|
||||||
span_measure = noise_data['measure_inv'][-1] - ref_measures['inv']
|
big_axes[1].axvspan(noise_scales[0], noise_scales[low_ind],
|
||||||
thresh_measure = ref_measures['inv'] + noise_rel_thresh * span_measure
|
fc=noise_colors[0], **plateau_rect_kwargs)
|
||||||
else:
|
big_axes[1].axvspan(noise_scales[low_ind], noise_scales[high_ind],
|
||||||
span_measure = noise_data['measure_inv'][-1] - noise_data['measure_inv'][0]
|
fc=noise_colors[1], **plateau_rect_kwargs)
|
||||||
thresh_measure = noise_data['measure_inv'][0] + noise_rel_thresh * span_measure
|
|
||||||
thresh_ind = np.nonzero(noise_data['measure_inv'] < thresh_measure)[0][-1]
|
# Plot species-specific noise-song measures:
|
||||||
thresh_scale = noise_scales[thresh_ind]
|
for i, (species, measure) in enumerate(species_measures.items()):
|
||||||
big_axes[1].axvspan(noise_scales[0], thresh_scale, **noise_kwargs)
|
color = species_colors[species]
|
||||||
|
ind, scale = thresh_inds[i], thresh_scales[i]
|
||||||
|
big_axes[2].plot(noise_scales, measure, label=shorten_species(species),
|
||||||
|
c=color, lw=lw['spec'])
|
||||||
|
big_axes[2].plot(scale, 0, c='w', alpha=1, zorder=5.5, **plateau_dot_kwargs,
|
||||||
|
transform=big_axes[2].get_xaxis_transform())
|
||||||
|
handle = big_axes[2].plot(scale, 0, c=color, alpha=0.5, **plateau_dot_kwargs,
|
||||||
|
transform=big_axes[2].get_xaxis_transform())
|
||||||
|
big_axes[2].vlines(scale, big_axes[2].get_ylim()[0], measure[ind],
|
||||||
|
color=color, **plateau_line_kwargs)
|
||||||
|
big_axes[2].legend(**leg_kwargs)
|
||||||
|
|
||||||
|
# handles = plot_dist_shifted(big_axes[2], species_threshs, axis=pdf_axis,
|
||||||
|
# pdf=thresh_pdf, **plateau_dot_kwargs)[0]
|
||||||
|
# [h.set_color(species_colors[s]) for h, s in zip(handles, target_species)]
|
||||||
|
|
||||||
|
|
||||||
if save_path is not None:
|
if save_path is not None:
|
||||||
fig.savefig(save_path, bbox_inches='tight')
|
fig.savefig(save_path, bbox_inches='tight')
|
||||||
|
|||||||
@@ -1,407 +0,0 @@
|
|||||||
import plotstyle_plt
|
|
||||||
import numpy as np
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
from itertools import product
|
|
||||||
from thunderhopper.filetools import search_files
|
|
||||||
from thunderhopper.modeltools import load_data
|
|
||||||
from misc_functions import shorten_species, get_saturation
|
|
||||||
from color_functions import load_colors
|
|
||||||
from plot_functions import hide_axis, ylimits, super_xlabel, ylabel, hide_ticks,\
|
|
||||||
plot_line, strip_zeros, time_bar, zoom_inset,\
|
|
||||||
letter_subplot, letter_subplots, title_subplot
|
|
||||||
from IPython import embed
|
|
||||||
|
|
||||||
def add_snip_axes(fig, grid_kwargs):
|
|
||||||
grid = fig.add_gridspec(**grid_kwargs)
|
|
||||||
axes = np.zeros((grid.nrows, grid.ncols), dtype=object)
|
|
||||||
for i, j in product(range(grid.nrows), range(grid.ncols)):
|
|
||||||
axes[i, j] = fig.add_subplot(grid[i, j])
|
|
||||||
[hide_axis(ax, 'left') for ax in axes[:, 1:].flatten()]
|
|
||||||
[hide_axis(ax, 'bottom') for ax in axes.flatten()]
|
|
||||||
return axes
|
|
||||||
|
|
||||||
def plot_snippets(axes, time, snippets, ymin=None, ymax=None, **kwargs):
|
|
||||||
ymin, ymax = ylimits(snippets, minval=ymin, maxval=ymax, pad=0.05)
|
|
||||||
handles = []
|
|
||||||
for ax, snippet in zip(axes, snippets.T):
|
|
||||||
handles.extend(plot_line(ax, time, snippet, ymin=ymin, ymax=ymax, **kwargs))
|
|
||||||
return handles
|
|
||||||
|
|
||||||
|
|
||||||
# GENERAL SETTINGS:
|
|
||||||
target = 'Omocestus_rufipes'
|
|
||||||
data_paths = search_files(target, excl='noise', dir='../data/inv/log_hp/')
|
|
||||||
target_species = [
|
|
||||||
'Omocestus_rufipes',
|
|
||||||
'Chorthippus_biguttulus',
|
|
||||||
'Chorthippus_mollis',
|
|
||||||
'Chrysochraon_dispar',
|
|
||||||
'Gomphocerippus_rufus',
|
|
||||||
'Pseudochorthippus_parallelus',
|
|
||||||
]
|
|
||||||
stages = ['env', 'log', 'inv']
|
|
||||||
load_kwargs = dict(
|
|
||||||
files=stages,
|
|
||||||
keywords=['scales', 'snip', 'measure']
|
|
||||||
)
|
|
||||||
save_path = '../figures/fig_invariance_log_hp.pdf'
|
|
||||||
compute_ratios = True
|
|
||||||
show_diag = True
|
|
||||||
show_plateaus = True
|
|
||||||
|
|
||||||
# GRAPH SETTINGS:
|
|
||||||
fig_kwargs = dict(
|
|
||||||
figsize=(32/2.54, 32/2.54),
|
|
||||||
)
|
|
||||||
# snip_rows = 1
|
|
||||||
# big_rows = 1
|
|
||||||
super_grid_kwargs = dict(
|
|
||||||
nrows=3,
|
|
||||||
ncols=1,
|
|
||||||
wspace=0,
|
|
||||||
hspace=0,
|
|
||||||
left=0,
|
|
||||||
right=1,
|
|
||||||
bottom=0,
|
|
||||||
top=1,
|
|
||||||
height_ratios=[1, 1, 1]
|
|
||||||
)
|
|
||||||
subfig_specs = dict(
|
|
||||||
pure=(0, slice(None)),
|
|
||||||
noise=(1, slice(None)),
|
|
||||||
big=(2, slice(None)),
|
|
||||||
)
|
|
||||||
block_height = 0.8
|
|
||||||
edge_padding = 0.08
|
|
||||||
pure_grid_kwargs = dict(
|
|
||||||
nrows=len(stages),
|
|
||||||
ncols=None,
|
|
||||||
wspace=0.1,
|
|
||||||
hspace=0.15,
|
|
||||||
left=0.11,
|
|
||||||
right=0.95,
|
|
||||||
bottom=1 - block_height - edge_padding,
|
|
||||||
top=1 - edge_padding,
|
|
||||||
height_ratios=[1, 2, 1]
|
|
||||||
)
|
|
||||||
noise_grid_kwargs = dict(
|
|
||||||
nrows=len(stages),
|
|
||||||
ncols=None,
|
|
||||||
wspace=pure_grid_kwargs['wspace'],
|
|
||||||
hspace=pure_grid_kwargs['hspace'],
|
|
||||||
left=pure_grid_kwargs['left'],
|
|
||||||
right=pure_grid_kwargs['right'],
|
|
||||||
bottom=edge_padding,
|
|
||||||
top=edge_padding + block_height,
|
|
||||||
height_ratios=[1, 2, 1]
|
|
||||||
)
|
|
||||||
big_grid_kwargs = dict(
|
|
||||||
nrows=1,
|
|
||||||
ncols=3,
|
|
||||||
wspace=0.3,
|
|
||||||
hspace=0,
|
|
||||||
left=pure_grid_kwargs['left'],
|
|
||||||
right=pure_grid_kwargs['right'],
|
|
||||||
bottom=0.05,
|
|
||||||
top=1
|
|
||||||
)
|
|
||||||
anchor_kwargs = dict(
|
|
||||||
aspect='equal',
|
|
||||||
adjustable='box',
|
|
||||||
anchor=(0.5, 0.5)
|
|
||||||
)
|
|
||||||
|
|
||||||
# PLOT SETTINGS:
|
|
||||||
fs = dict(
|
|
||||||
lab_norm=16,
|
|
||||||
lab_tex=20,
|
|
||||||
letter=22,
|
|
||||||
tit_norm=16,
|
|
||||||
tit_tex=20,
|
|
||||||
bar=16,
|
|
||||||
)
|
|
||||||
colors = load_colors('../data/stage_colors.npz')
|
|
||||||
species_colors = load_colors('../data/species_colors.npz')
|
|
||||||
noise_colors = [(0.5, 0.5, 0.5), (0.7, 0.7, 0.7)]
|
|
||||||
lw_snippets = 1
|
|
||||||
lw_big = 3
|
|
||||||
xlabels = dict(
|
|
||||||
big='scale $\\alpha$',
|
|
||||||
)
|
|
||||||
ylabels = dict(
|
|
||||||
env='$x_{\\text{env}}$',
|
|
||||||
log='$x_{\\text{dB}}$',
|
|
||||||
inv='$x_{\\text{adapt}}$',
|
|
||||||
big='$\\sigma_{\\alpha}\\,/\\,\\sigma_{\\eta}$',
|
|
||||||
)
|
|
||||||
xlab_big_kwargs = dict(
|
|
||||||
y=0,
|
|
||||||
fontsize=fs['lab_norm'],
|
|
||||||
ha='center',
|
|
||||||
va='bottom',
|
|
||||||
)
|
|
||||||
ylab_snip_kwargs = dict(
|
|
||||||
x=0,
|
|
||||||
fontsize=fs['lab_tex'],
|
|
||||||
rotation=0,
|
|
||||||
ha='left',
|
|
||||||
va='center',
|
|
||||||
)
|
|
||||||
ylab_big_kwargs = dict(
|
|
||||||
x=0,
|
|
||||||
fontsize=fs['lab_tex'],
|
|
||||||
ha='center',
|
|
||||||
va='top',
|
|
||||||
)
|
|
||||||
yloc = dict(
|
|
||||||
env=1000,
|
|
||||||
log=40,
|
|
||||||
inv=20
|
|
||||||
)
|
|
||||||
title_kwargs = dict(
|
|
||||||
x=0.5,
|
|
||||||
y=1,
|
|
||||||
ha='center',
|
|
||||||
va='bottom',
|
|
||||||
fontsize=fs['tit_norm'],
|
|
||||||
)
|
|
||||||
letter_snip_kwargs = dict(
|
|
||||||
x=0,
|
|
||||||
yref=0.5,
|
|
||||||
ha='left',
|
|
||||||
va='center',
|
|
||||||
fontsize=fs['letter'],
|
|
||||||
)
|
|
||||||
letter_big_kwargs = dict(
|
|
||||||
x=0,
|
|
||||||
y=1,
|
|
||||||
ha='left',
|
|
||||||
va='bottom',
|
|
||||||
fontsize=fs['letter'],
|
|
||||||
)
|
|
||||||
zoom_inset_bounds = [0.1, 0.2, 0.8, 0.6]
|
|
||||||
zoom_kwargs = dict(
|
|
||||||
x0=0.45,
|
|
||||||
x1=0.55,
|
|
||||||
y0=0,
|
|
||||||
y1=0.0006,
|
|
||||||
low_left=True,
|
|
||||||
low_right=True,
|
|
||||||
ec='k',
|
|
||||||
lw=1,
|
|
||||||
alpha=1,
|
|
||||||
)
|
|
||||||
inset_tick_kwargs = dict(
|
|
||||||
axis='y',
|
|
||||||
length=3,
|
|
||||||
pad=1,
|
|
||||||
left=False,
|
|
||||||
labelleft=False,
|
|
||||||
right=True,
|
|
||||||
labelright=True,
|
|
||||||
)
|
|
||||||
bar_time = 5
|
|
||||||
bar_kwargs = dict(
|
|
||||||
dur=bar_time,
|
|
||||||
y0=-0.25,
|
|
||||||
y1=-0.1,
|
|
||||||
xshift=1,
|
|
||||||
color='k',
|
|
||||||
lw=0,
|
|
||||||
clip_on=False,
|
|
||||||
text_pos=(-0.1, 0.5),
|
|
||||||
text_str=f'${bar_time}\\,\\text{{s}}$',
|
|
||||||
text_kwargs=dict(
|
|
||||||
fontsize=fs['bar'],
|
|
||||||
ha='right',
|
|
||||||
va='center',
|
|
||||||
)
|
|
||||||
)
|
|
||||||
leg_kwargs = dict(
|
|
||||||
ncols=2,
|
|
||||||
loc='upper right',
|
|
||||||
bbox_to_anchor=(0, 0.6, 1, 0.4),
|
|
||||||
frameon=False,
|
|
||||||
prop=dict(
|
|
||||||
size=12,
|
|
||||||
style='italic',
|
|
||||||
),
|
|
||||||
borderpad=0,
|
|
||||||
borderaxespad=0,
|
|
||||||
handlelength=1,
|
|
||||||
columnspacing=1,
|
|
||||||
)
|
|
||||||
diag_kwargs = dict(
|
|
||||||
c=(0.75, 0.75, 0.75),
|
|
||||||
lw=2,
|
|
||||||
ls='--',
|
|
||||||
zorder=1.9,
|
|
||||||
)
|
|
||||||
plateau_settings = dict(
|
|
||||||
low=0.05,
|
|
||||||
high=0.95,
|
|
||||||
first=True,
|
|
||||||
last=True,
|
|
||||||
condense=None,
|
|
||||||
)
|
|
||||||
plateau_kwargs = dict(
|
|
||||||
ec='none',
|
|
||||||
lw=0,
|
|
||||||
zorder=1.5,
|
|
||||||
)
|
|
||||||
|
|
||||||
# PREPARATION:
|
|
||||||
if compute_ratios:
|
|
||||||
ref_data = load_data('../data/processed/white_noise_sd-1.npz', files=stages)[0]
|
|
||||||
ref_measures = {k: v.std() for k, v in ref_data.items() if not k.endswith('rate')}
|
|
||||||
|
|
||||||
species_measures = {}
|
|
||||||
for species in target_species:
|
|
||||||
path = search_files(species, incl='noise', dir='../data/inv/log_hp/')[0]
|
|
||||||
measure = load_data(path, **load_kwargs)[0]['measure_inv']
|
|
||||||
if compute_ratios:
|
|
||||||
measure /= ref_measures['inv']
|
|
||||||
species_measures[species] = measure
|
|
||||||
|
|
||||||
# EXECUTION:
|
|
||||||
for data_path in data_paths:
|
|
||||||
print(f'Processing {data_path}')
|
|
||||||
|
|
||||||
# Load invariance data:
|
|
||||||
pure_data, config = load_data(data_path, **load_kwargs)
|
|
||||||
noise_data, _ = load_data(data_path.replace('.npz', '_noise.npz'), **load_kwargs)
|
|
||||||
pure_scales, noise_scales = pure_data['scales'], noise_data['scales']
|
|
||||||
t_full = np.arange(pure_data['snip_env'].shape[0]) / config['env_rate']
|
|
||||||
|
|
||||||
# Prepare overall graph:
|
|
||||||
fig = plt.figure(**fig_kwargs)
|
|
||||||
super_grid = fig.add_gridspec(**super_grid_kwargs)
|
|
||||||
fig.canvas.draw()
|
|
||||||
|
|
||||||
# Prepare pure-song snippet axes:
|
|
||||||
pure_grid_kwargs['ncols'] = pure_data['example_scales'].size
|
|
||||||
pure_subfig = fig.add_subfigure(super_grid[subfig_specs['pure']])
|
|
||||||
pure_axes = add_snip_axes(pure_subfig, pure_grid_kwargs)
|
|
||||||
for ax, stage in zip(pure_axes[:, 0], stages):
|
|
||||||
ax.yaxis.set_major_locator(plt.MultipleLocator(yloc[stage]))
|
|
||||||
ylabel(ax, ylabels[stage], **ylab_snip_kwargs,
|
|
||||||
transform=pure_subfig.transSubfigure)
|
|
||||||
for ax, scale in zip(pure_axes[0, :], pure_data['example_scales']):
|
|
||||||
pure_title = title_subplot(ax, f'$\\alpha={strip_zeros(scale)}$', **title_kwargs)
|
|
||||||
letter_subplot(pure_subfig, 'a', ref=pure_title, **letter_snip_kwargs)
|
|
||||||
pure_inset = pure_axes[0, 0].inset_axes(zoom_inset_bounds)
|
|
||||||
pure_inset.spines[:].set(visible=True, lw=zoom_kwargs['lw'])
|
|
||||||
pure_inset.tick_params(**inset_tick_kwargs)
|
|
||||||
hide_ticks(pure_inset, 'bottom', ticks=False)
|
|
||||||
|
|
||||||
# Prepare noise-song snippet axes:
|
|
||||||
noise_grid_kwargs['ncols'] = noise_data['example_scales'].size
|
|
||||||
noise_subfig = fig.add_subfigure(super_grid[subfig_specs['noise']])
|
|
||||||
noise_axes = add_snip_axes(noise_subfig, noise_grid_kwargs)
|
|
||||||
for ax, stage in zip(noise_axes[:, 0], stages):
|
|
||||||
ax.yaxis.set_major_locator(plt.MultipleLocator(yloc[stage]))
|
|
||||||
ylabel(ax, ylabels[stage], **ylab_snip_kwargs,
|
|
||||||
transform=noise_subfig.transSubfigure)
|
|
||||||
for ax, scale in zip(noise_axes[0, :], noise_data['example_scales']):
|
|
||||||
noise_title = title_subplot(ax, f'$\\alpha={strip_zeros(scale)}$', **title_kwargs)
|
|
||||||
letter_subplot(noise_subfig, 'b', ref=noise_title, **letter_snip_kwargs)
|
|
||||||
noise_inset = noise_axes[0, 0].inset_axes(zoom_inset_bounds)
|
|
||||||
noise_inset.spines[:].set(visible=True, lw=zoom_kwargs['lw'])
|
|
||||||
noise_inset.tick_params(**inset_tick_kwargs)
|
|
||||||
hide_ticks(noise_inset, 'bottom', ticks=False)
|
|
||||||
|
|
||||||
# Prepare analysis axes:
|
|
||||||
big_subfig = fig.add_subfigure(super_grid[subfig_specs['big']])
|
|
||||||
big_grid = big_subfig.add_gridspec(**big_grid_kwargs)
|
|
||||||
big_axes = np.zeros((big_grid.ncols,), dtype=object)
|
|
||||||
for i, scales in enumerate([pure_scales, noise_scales, noise_scales]):
|
|
||||||
ax = big_subfig.add_subplot(big_grid[0, i])
|
|
||||||
ax.set_xlim(scales[0], scales[-1])
|
|
||||||
ax.set_ylim(scales[0], scales[-1])
|
|
||||||
ax.set_xscale('symlog', linthresh=scales[1], linscale=0.5)
|
|
||||||
ax.set_yscale('symlog', linthresh=scales[1], linscale=0.5)
|
|
||||||
ax.set_aspect(**anchor_kwargs)
|
|
||||||
big_axes[i] = ax
|
|
||||||
ylabel(big_axes[0], ylabels['big'], transform=big_subfig.transSubfigure, **ylab_big_kwargs)
|
|
||||||
super_xlabel(xlabels['big'], big_subfig, big_axes[0], big_axes[-1], **xlab_big_kwargs)
|
|
||||||
letter_subplots(big_axes, 'cde', **letter_big_kwargs)
|
|
||||||
|
|
||||||
# Plot pure-song envelope snippets:
|
|
||||||
handle = plot_snippets(pure_axes[0, :], t_full, pure_data['snip_env'],
|
|
||||||
ymin=0, c=colors['env'], lw=lw_snippets)[0]
|
|
||||||
zoom_inset(pure_axes[0, 0], pure_inset, handle, transform=pure_axes[0, 0].transAxes, **zoom_kwargs)
|
|
||||||
|
|
||||||
# Plot pure-song logarithmic snippets:
|
|
||||||
plot_snippets(pure_axes[1, :], t_full, pure_data['snip_log'],
|
|
||||||
c=colors['log'], lw=lw_snippets)
|
|
||||||
|
|
||||||
# Plot pure-song invariant snippets:
|
|
||||||
plot_snippets(pure_axes[2, :], t_full, pure_data['snip_inv'],
|
|
||||||
c=colors['inv'], lw=lw_snippets)
|
|
||||||
|
|
||||||
# Plot noise-song envelope snippets:
|
|
||||||
ymin, ymax = pure_axes[0, 0].get_ylim()
|
|
||||||
handle = plot_snippets(noise_axes[0, :], t_full, noise_data['snip_env'],
|
|
||||||
ymin, ymax, c=colors['env'], lw=lw_snippets)[0]
|
|
||||||
zoom_inset(noise_axes[0, 0], noise_inset, handle, transform=noise_axes[0, 0].transAxes, **zoom_kwargs)
|
|
||||||
|
|
||||||
# Plot noise-song logarithmic snippets:
|
|
||||||
ymin, ymax = pure_axes[1, 0].get_ylim()
|
|
||||||
plot_snippets(noise_axes[1, :], t_full, noise_data['snip_log'],
|
|
||||||
ymin, ymax, c=colors['log'], lw=lw_snippets)
|
|
||||||
|
|
||||||
# Plot noise-song invariant snippets:
|
|
||||||
ymin, ymax = pure_axes[2, 0].get_ylim()
|
|
||||||
plot_snippets(noise_axes[2, :], t_full, noise_data['snip_inv'],
|
|
||||||
ymin, ymax, c=colors['inv'], lw=lw_snippets)
|
|
||||||
|
|
||||||
# Indicate time scale:
|
|
||||||
time_bar(noise_axes[-1, -1], **bar_kwargs)
|
|
||||||
|
|
||||||
if compute_ratios:
|
|
||||||
# Relate pure-song measures to zero scale:
|
|
||||||
pure_data['measure_env'] /= ref_measures['env']
|
|
||||||
pure_data['measure_log'] /= ref_measures['log']
|
|
||||||
pure_data['measure_inv'] /= ref_measures['inv']
|
|
||||||
# Relate noise-song measures to zero scale:
|
|
||||||
noise_data['measure_env'] /= ref_measures['env']
|
|
||||||
noise_data['measure_log'] /= ref_measures['log']
|
|
||||||
noise_data['measure_inv'] /= ref_measures['inv']
|
|
||||||
|
|
||||||
# Plot pure-song measures (ideal):
|
|
||||||
big_axes[0].plot(pure_scales, pure_data['measure_env'], c=colors['env'], lw=lw_big)
|
|
||||||
big_axes[0].plot(pure_scales, pure_data['measure_log'], c=colors['log'], lw=lw_big)
|
|
||||||
big_axes[0].plot(pure_scales, pure_data['measure_inv'], c=colors['inv'], lw=lw_big)
|
|
||||||
|
|
||||||
# Plot noise-song measures (limited):
|
|
||||||
big_axes[1].plot(noise_scales, noise_data['measure_env'], c=colors['env'], lw=lw_big)
|
|
||||||
big_axes[1].plot(noise_scales, noise_data['measure_log'], c=colors['log'], lw=lw_big)
|
|
||||||
big_axes[1].plot(noise_scales, noise_data['measure_inv'], c=colors['inv'], lw=lw_big)
|
|
||||||
|
|
||||||
|
|
||||||
if show_diag:
|
|
||||||
# Indicate diagonal:
|
|
||||||
big_axes[0].plot(pure_scales, pure_scales, **diag_kwargs)
|
|
||||||
big_axes[1].plot(noise_scales, noise_scales, **diag_kwargs)
|
|
||||||
|
|
||||||
if show_plateaus:
|
|
||||||
# Indicate low and high plateaus of noise invariance curve:
|
|
||||||
low_ind, high_ind = get_saturation(noise_data['measure_inv'], **plateau_settings)
|
|
||||||
big_axes[1].axvspan(noise_scales[0], noise_scales[low_ind],
|
|
||||||
fc=noise_colors[0], **plateau_kwargs)
|
|
||||||
big_axes[1].axvspan(noise_scales[low_ind], noise_scales[high_ind],
|
|
||||||
fc=noise_colors[1], **plateau_kwargs)
|
|
||||||
|
|
||||||
# Plot species-specific noise-song measures:
|
|
||||||
for species, measure in species_measures.items():
|
|
||||||
label = shorten_species(species)
|
|
||||||
big_axes[2].plot(noise_scales, measure, label=label,
|
|
||||||
c=species_colors[species], lw=lw_big)
|
|
||||||
big_axes[2].legend(**leg_kwargs)
|
|
||||||
|
|
||||||
if save_path is not None:
|
|
||||||
fig.savefig(save_path, bbox_inches='tight')
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
print('Done.')
|
|
||||||
embed()
|
|
||||||
@@ -5,6 +5,7 @@ from itertools import product
|
|||||||
from thunderhopper.filetools import search_files
|
from thunderhopper.filetools import search_files
|
||||||
from thunderhopper.modeltools import load_data
|
from thunderhopper.modeltools import load_data
|
||||||
from thunderhopper.filtertools import find_kern_specs
|
from thunderhopper.filtertools import find_kern_specs
|
||||||
|
from misc_functions import get_saturation
|
||||||
from color_functions import load_colors, shade_colors
|
from color_functions import load_colors, shade_colors
|
||||||
from plot_functions import shift_subplot, hide_axis, ylimits, xlabel, ylabel,\
|
from plot_functions import shift_subplot, hide_axis, ylimits, xlabel, ylabel,\
|
||||||
super_ylabel, plot_line, plot_barcode, strip_zeros,\
|
super_ylabel, plot_line, plot_barcode, strip_zeros,\
|
||||||
@@ -64,7 +65,7 @@ load_kwargs = dict(
|
|||||||
files=stages,
|
files=stages,
|
||||||
keywords=['scales', 'snip', 'measure', 'thresh']
|
keywords=['scales', 'snip', 'measure', 'thresh']
|
||||||
)
|
)
|
||||||
save_path = '../figures/fig_invariance_thresh_lp_single.pdf'
|
save_path = None#'../figures/fig_invariance_thresh_lp_single.pdf'
|
||||||
exclude_zero = True
|
exclude_zero = True
|
||||||
|
|
||||||
# GRAPH SETTINGS:
|
# GRAPH SETTINGS:
|
||||||
@@ -79,7 +80,7 @@ super_grid_kwargs = dict(
|
|||||||
left=0,
|
left=0,
|
||||||
right=1,
|
right=1,
|
||||||
bottom=0,
|
bottom=0,
|
||||||
top=1
|
top=1,
|
||||||
)
|
)
|
||||||
input_rows = 1
|
input_rows = 1
|
||||||
snip_rows = 2
|
snip_rows = 2
|
||||||
@@ -111,10 +112,10 @@ input_grid_kwargs = dict(
|
|||||||
top=0.75,
|
top=0.75,
|
||||||
)
|
)
|
||||||
big_grid_kwargs = dict(
|
big_grid_kwargs = dict(
|
||||||
nrows=1,
|
nrows=2,
|
||||||
ncols=1,
|
ncols=1,
|
||||||
wspace=0,
|
wspace=0,
|
||||||
hspace=0,
|
hspace=0.3,
|
||||||
left=0.17,
|
left=0.17,
|
||||||
right=0.96,
|
right=0.96,
|
||||||
bottom=0.1,
|
bottom=0.1,
|
||||||
@@ -141,7 +142,8 @@ lw = dict(
|
|||||||
big=4,
|
big=4,
|
||||||
)
|
)
|
||||||
xlabels = dict(
|
xlabels = dict(
|
||||||
big='scale $\\alpha$',
|
alpha='scale $\\alpha$',
|
||||||
|
sigma='$\\sigma_{\\text{adapt}}$',
|
||||||
)
|
)
|
||||||
ylabels = dict(
|
ylabels = dict(
|
||||||
inv='$x_{\\text{adapt}}$',
|
inv='$x_{\\text{adapt}}$',
|
||||||
@@ -150,11 +152,17 @@ ylabels = dict(
|
|||||||
feat='$f_i$',
|
feat='$f_i$',
|
||||||
big='$\\mu_f$',
|
big='$\\mu_f$',
|
||||||
)
|
)
|
||||||
xlab_big_kwargs = dict(
|
xlab_alpha_kwargs = dict(
|
||||||
y=0,
|
y=-0.15,
|
||||||
fontsize=fs['lab_norm'],
|
fontsize=fs['lab_norm'],
|
||||||
ha='center',
|
ha='center',
|
||||||
va='bottom',
|
va='top',
|
||||||
|
)
|
||||||
|
xlab_sigma_kwargs = dict(
|
||||||
|
y=-0.12,
|
||||||
|
fontsize=fs['lab_tex'],
|
||||||
|
ha=xlab_alpha_kwargs['ha'],
|
||||||
|
va=xlab_alpha_kwargs['va'],
|
||||||
)
|
)
|
||||||
ylab_snip_kwargs = dict(
|
ylab_snip_kwargs = dict(
|
||||||
x=0.08,
|
x=0.08,
|
||||||
@@ -178,7 +186,7 @@ ylab_big_kwargs = dict(
|
|||||||
ypad = dict(
|
ypad = dict(
|
||||||
inv=0.05,
|
inv=0.05,
|
||||||
conv=0.05,
|
conv=0.05,
|
||||||
big=0.075
|
big=0.1
|
||||||
)
|
)
|
||||||
yloc = dict(
|
yloc = dict(
|
||||||
inv=(2, 200),
|
inv=(2, 200),
|
||||||
@@ -242,6 +250,13 @@ leg_kwargs = dict(
|
|||||||
handlelength=1.5,
|
handlelength=1.5,
|
||||||
columnspacing=1,
|
columnspacing=1,
|
||||||
)
|
)
|
||||||
|
plateau_settings = dict(
|
||||||
|
low=0.05,
|
||||||
|
high=0.95,
|
||||||
|
first=True,
|
||||||
|
last=True,
|
||||||
|
condense=None,
|
||||||
|
)
|
||||||
kern_specs = np.array([
|
kern_specs = np.array([
|
||||||
[1, 0.008],
|
[1, 0.008],
|
||||||
[2, 0.004],
|
[2, 0.004],
|
||||||
@@ -281,6 +296,7 @@ for data_path in data_paths:
|
|||||||
# Reduce to nonzero scales:
|
# Reduce to nonzero scales:
|
||||||
nonzero_inds = scales > 0
|
nonzero_inds = scales > 0
|
||||||
scales = scales[nonzero_inds]
|
scales = scales[nonzero_inds]
|
||||||
|
noise_data['measure_inv'] = noise_data['measure_inv'][nonzero_inds]
|
||||||
noise_data['measure_feat'] = noise_data['measure_feat'][nonzero_inds, :]
|
noise_data['measure_feat'] = noise_data['measure_feat'][nonzero_inds, :]
|
||||||
pure_data['measure_feat'] = pure_data['measure_feat'][nonzero_inds, :]
|
pure_data['measure_feat'] = pure_data['measure_feat'][nonzero_inds, :]
|
||||||
|
|
||||||
@@ -293,7 +309,7 @@ for data_path in data_paths:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Adjust grid parameters to loaded data:
|
# Adjust grid parameters to loaded data:
|
||||||
super_grid_kwargs['nrows'] = snip_rows * thresh_rel.size + 1
|
super_grid_kwargs['nrows'] = snip_rows * thresh_rel.size + input_rows
|
||||||
input_grid_kwargs['ncols'] = plot_scales.size
|
input_grid_kwargs['ncols'] = plot_scales.size
|
||||||
snip_grid_kwargs['ncols'] = plot_scales.size
|
snip_grid_kwargs['ncols'] = plot_scales.size
|
||||||
|
|
||||||
@@ -325,8 +341,6 @@ for data_path in data_paths:
|
|||||||
ax1.yaxis.set_major_locator(plt.MultipleLocator(yloc[stage][0]))
|
ax1.yaxis.set_major_locator(plt.MultipleLocator(yloc[stage][0]))
|
||||||
ax2.yaxis.set_major_locator(plt.MultipleLocator(yloc[stage][1]))
|
ax2.yaxis.set_major_locator(plt.MultipleLocator(yloc[stage][1]))
|
||||||
ylabel(ax1, ylabels[stage], transform=snip_subfig.transSubfigure, **ylab_snip_kwargs)
|
ylabel(ax1, ylabels[stage], transform=snip_subfig.transSubfigure, **ylab_snip_kwargs)
|
||||||
# for ax, scale in zip(axes[0, :], plot_scales):
|
|
||||||
# title_subplot(ax, f'$\\alpha={strip_zeros(scale)}$', ref=snip_subfig, **title_kwargs)
|
|
||||||
if i == thresh_rel.size - 1:
|
if i == thresh_rel.size - 1:
|
||||||
axes[-1, -1].set_xlim(t_full[0], t_full[-1])
|
axes[-1, -1].set_xlim(t_full[0], t_full[-1])
|
||||||
time_bar(axes[-1, -1], **bar_kwargs)
|
time_bar(axes[-1, -1], **bar_kwargs)
|
||||||
@@ -334,17 +348,27 @@ for data_path in data_paths:
|
|||||||
snip_axes.append(axes)
|
snip_axes.append(axes)
|
||||||
letter_subplots(snip_subfigs, 'bcd', **letter_snip_kwargs)
|
letter_subplots(snip_subfigs, 'bcd', **letter_snip_kwargs)
|
||||||
|
|
||||||
# Prepare analysis axis:
|
# Prepare analysis axes:
|
||||||
big_subfig = fig.add_subfigure(super_grid[subfig_specs['big']])
|
big_subfig = fig.add_subfigure(super_grid[subfig_specs['big']])
|
||||||
big_grid = big_subfig.add_gridspec(**big_grid_kwargs)
|
big_grid = big_subfig.add_gridspec(**big_grid_kwargs)
|
||||||
big_ax = big_subfig.add_subplot(big_grid[0, 0])
|
|
||||||
big_ax.set_xlim(scales[0], scales[-1])
|
alpha_ax = big_subfig.add_subplot(big_grid[0, 0])
|
||||||
big_ax.set_xscale('symlog', linthresh=scales[scales > 0][0], linscale=0.5)
|
alpha_ax.set_xlim(scales[0], scales[-1])
|
||||||
ylimits(noise_data['measure_feat'], big_ax, minval=0, pad=ypad['big'])
|
alpha_ax.set_xscale('symlog', linthresh=scales[scales > 0][0], linscale=0.5)
|
||||||
big_ax.yaxis.set_major_locator(plt.MultipleLocator(yloc['big']))
|
ylimits(pure_data['measure_feat'], alpha_ax, minval=0, pad=ypad['big'])
|
||||||
xlabel(big_ax, xlabels['big'], transform=big_subfig.transSubfigure, **xlab_big_kwargs)
|
alpha_ax.yaxis.set_major_locator(plt.MultipleLocator(yloc['big']))
|
||||||
ylabel(big_ax, ylabels['big'], transform=big_subfig.transSubfigure, **ylab_big_kwargs)
|
xlabel(alpha_ax, xlabels['alpha'], **xlab_alpha_kwargs)
|
||||||
letter_subplot(big_subfig, 'e', **letter_big_kwargs, ref=input_subfig)
|
ylabel(alpha_ax, ylabels['big'], transform=big_subfig.transSubfigure, **ylab_big_kwargs)
|
||||||
|
|
||||||
|
sigma_ax = big_subfig.add_subplot(big_grid[1, 0])
|
||||||
|
sigma_ax.set_xlim(noise_data['measure_inv'].min(), noise_data['measure_inv'].max())
|
||||||
|
# sigma_ax.set_xscale('log')
|
||||||
|
sigma_ax.set_xlim(scales[0], scales[-1])
|
||||||
|
sigma_ax.set_xscale('symlog', linthresh=scales[scales > 0][0], linscale=0.5)
|
||||||
|
ylimits(pure_data['measure_feat'], sigma_ax, minval=0, pad=ypad['big'])
|
||||||
|
sigma_ax.yaxis.set_major_locator(plt.MultipleLocator(yloc['big']))
|
||||||
|
xlabel(sigma_ax, xlabels['sigma'], **xlab_sigma_kwargs)
|
||||||
|
ylabel(sigma_ax, ylabels['big'], transform=big_subfig.transSubfigure, **ylab_big_kwargs)
|
||||||
|
|
||||||
# Plot intensity-adapted snippets:
|
# Plot intensity-adapted snippets:
|
||||||
plot_snippets(input_axes, t_full, noise_data['snip_inv'],
|
plot_snippets(input_axes, t_full, noise_data['snip_inv'],
|
||||||
@@ -375,18 +399,25 @@ for data_path in data_paths:
|
|||||||
ymin=0, ymax=1, c=shaded['feat'][i], lw=lw['feat'])
|
ymin=0, ymax=1, c=shaded['feat'][i], lw=lw['feat'])
|
||||||
[set_clip_box(h[0], ax, bounds=[[0, -0.05], [1, 1.05]]) for h, ax in zip(handles, axes[2, :])]
|
[set_clip_box(h[0], ax, bounds=[[0, -0.05], [1, 1.05]]) for h, ax in zip(handles, axes[2, :])]
|
||||||
|
|
||||||
# Plot pure-song analysis results:
|
# Get threshold-specific saturation:
|
||||||
handles = big_ax.plot(scales, pure_data['measure_feat'], lw=lw['big'], ls='dotted')
|
for i in range(thresh_rel.size):
|
||||||
[h.set_color(c) for h, c in zip(handles, shaded['feat'])]
|
ind = get_saturation(noise_data['measure_feat'][:, i], **plateau_settings)[1]
|
||||||
|
|
||||||
# Plot noise-song analysis results:
|
# Plot analysis results:
|
||||||
handles = big_ax.plot(scales, noise_data['measure_feat'], lw=lw['big'])
|
for ax, x in zip([alpha_ax, sigma_ax], [scales, noise_data['measure_inv']]):
|
||||||
[h.set_color(c) for h, c in zip(handles, shaded['feat'])]
|
# Plot pure-song analysis results:
|
||||||
|
handles = ax.plot(x, pure_data['measure_feat'], lw=lw['big'], ls='dotted')
|
||||||
|
[h.set_color(c) for h, c in zip(handles, shaded['feat'])]
|
||||||
|
|
||||||
# Add proxy legend:
|
# Plot noise-song analysis results:
|
||||||
h1 = big_ax.plot([], [], c='k', lw=lw['big'], label='$\\alpha\\cdot s(t) + \\eta(t)$')[0]
|
handles = ax.plot(x, noise_data['measure_feat'], lw=lw['big'])
|
||||||
h2 = big_ax.plot([], [], c='k', lw=lw['big'], ls='dotted', label='$\\alpha\\cdot s(t)$')[0]
|
[h.set_color(c) for h, c in zip(handles, shaded['feat'])]
|
||||||
big_ax.legend(handles=[h1, h2], **leg_kwargs)
|
|
||||||
|
# Add proxy legend:
|
||||||
|
if ax == alpha_ax:
|
||||||
|
h1 = ax.plot([], [], c='k', lw=lw['big'], label='$\\alpha\\cdot s(t) + \\eta(t)$')[0]
|
||||||
|
h2 = ax.plot([], [], c='k', lw=lw['big'], ls='dotted', label='$\\alpha\\cdot s(t)$')[0]
|
||||||
|
ax.legend(handles=[h1, h2], **leg_kwargs)
|
||||||
|
|
||||||
if save_path is not None:
|
if save_path is not None:
|
||||||
fig.savefig(save_path)
|
fig.savefig(save_path)
|
||||||
|
|||||||
131
python/fig_temp.py
Normal file
131
python/fig_temp.py
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
import glob
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from thunderhopper.modeltools import load_data
|
||||||
|
from thunderhopper.filtertools import find_kern_specs
|
||||||
|
from misc_functions import unsort_unique
|
||||||
|
from color_functions import sample_cmap
|
||||||
|
from IPython import embed
|
||||||
|
|
||||||
|
# Settings:
|
||||||
|
target = 'Omocestus_rufipes'
|
||||||
|
data_path = glob.glob(f'../data/inv/full/{target}*.npz')[0]
|
||||||
|
stages = ['conv', 'feat']
|
||||||
|
load_kwargs = dict(
|
||||||
|
files=stages,
|
||||||
|
keywords=['scales', 'measure']
|
||||||
|
)
|
||||||
|
|
||||||
|
# Subset settings:
|
||||||
|
all_types = np.array([1, -1, 2, -2, 3, -3, 4, -4, 5, -5,
|
||||||
|
6, -6, 7, -7, 8, -8, 9, -9, 10, -10]).astype(float)
|
||||||
|
all_sigmas = np.array([0.001, 0.002, 0.004, 0.008, 0.016, 0.032])
|
||||||
|
kerns = None
|
||||||
|
types = np.array([1, -1, 2, -2, 3, -3, 4, -4, 5, -5,
|
||||||
|
6, -6, 7, -7, 8, -8, 9, -9, 10, -10])
|
||||||
|
sigmas = np.array([0.008, 0.016])
|
||||||
|
|
||||||
|
# Plot settings:
|
||||||
|
line_kwargs = dict(
|
||||||
|
linewidth=2,
|
||||||
|
)
|
||||||
|
median_kwargs = dict(
|
||||||
|
linewidth=4,
|
||||||
|
c='k',
|
||||||
|
linestyle='--'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Load invariance data:
|
||||||
|
data, config = load_data(data_path, **load_kwargs)
|
||||||
|
scales = data['scales']
|
||||||
|
|
||||||
|
# Reduce to kernel subset:
|
||||||
|
if any(var is not None for var in [kerns, types, sigmas]):
|
||||||
|
subset_inds = find_kern_specs(config['k_specs'], kerns, types, sigmas)
|
||||||
|
data['measure_conv'] = data['measure_conv'][:, subset_inds]
|
||||||
|
data['measure_feat'] = data['measure_feat'][:, subset_inds]
|
||||||
|
config['kernels'] = config['kernels'][:, subset_inds]
|
||||||
|
config['k_specs'] = config['k_specs'][subset_inds, :]
|
||||||
|
kern_types = unsort_unique(config['k_specs'][:, 0])
|
||||||
|
kern_sigmas = unsort_unique(config['k_specs'][:, 1])
|
||||||
|
|
||||||
|
# Prepare colors:
|
||||||
|
type_colors = {t: c for t, c in zip(all_types, sample_cmap('turbo', all_types.size))}
|
||||||
|
sigma_colors = {s: c for s, c in zip(all_sigmas, sample_cmap('turbo', all_sigmas.size))}
|
||||||
|
|
||||||
|
# Prepare graph:
|
||||||
|
fig, axes = plt.subplots(2, 4, figsize=(16, 16), layout='constrained', sharex=True)
|
||||||
|
axes[0, 0].set_xlim(scales[0], scales[-1])
|
||||||
|
axes[0, 0].set_xscale('log')
|
||||||
|
axes[0, 0].set_ylabel('conv')
|
||||||
|
axes[1, 0].set_ylabel('feat')
|
||||||
|
|
||||||
|
# Condense across kernels:
|
||||||
|
median_conv = np.median(data['measure_conv'], axis=1)
|
||||||
|
median_feat = np.median(data['measure_feat'], axis=1)
|
||||||
|
|
||||||
|
# Coded by type:
|
||||||
|
leg_handles = []
|
||||||
|
for kern_type in kern_types:
|
||||||
|
color = type_colors[kern_type]
|
||||||
|
inds = find_kern_specs(config['k_specs'], types=kern_type)
|
||||||
|
leg_handles.append(axes[0, 0].plot(scales, data['measure_conv'][:, inds],
|
||||||
|
c=color, label=f'{kern_type}', **line_kwargs)[0])
|
||||||
|
axes[0, 0].plot(scales, median_conv, **median_kwargs)
|
||||||
|
axes[1, 0].plot(scales, data['measure_feat'][:, inds], c=color, **line_kwargs)
|
||||||
|
axes[1, 0].plot(scales, median_feat, **median_kwargs)
|
||||||
|
axes[0, 0].legend(handles=leg_handles, loc='upper left')
|
||||||
|
axes[0, 0].set_title('Coded by type')
|
||||||
|
|
||||||
|
# Coded by sigma:
|
||||||
|
leg_handles = []
|
||||||
|
for kern_sigma in kern_sigmas:
|
||||||
|
color = sigma_colors[kern_sigma]
|
||||||
|
inds = find_kern_specs(config['k_specs'], sigmas=kern_sigma)
|
||||||
|
leg_handles.append(axes[0, 1].plot(scales, data['measure_conv'][:, inds],
|
||||||
|
c=color, label=f'{kern_sigma}', **line_kwargs)[0])
|
||||||
|
axes[0, 1].plot(scales, median_conv, **median_kwargs)
|
||||||
|
axes[1, 1].plot(scales, data['measure_feat'][:, inds], c=color, **line_kwargs)
|
||||||
|
axes[1, 1].plot(scales, median_feat, **median_kwargs)
|
||||||
|
axes[0, 1].legend(handles=leg_handles, loc='upper left')
|
||||||
|
axes[0, 1].set_title('Coded by sigma')
|
||||||
|
|
||||||
|
# Normalize measures:
|
||||||
|
data['measure_conv'] -= data['measure_conv'].min(axis=0)
|
||||||
|
data['measure_conv'] /= data['measure_conv'].max(axis=0)
|
||||||
|
data['measure_feat'] -= data['measure_feat'].min(axis=0)
|
||||||
|
data['measure_feat'] /= data['measure_feat'].max(axis=0)
|
||||||
|
|
||||||
|
# Condense across kernels:
|
||||||
|
median_conv = np.median(data['measure_conv'], axis=1)
|
||||||
|
median_feat = np.median(data['measure_feat'], axis=1)
|
||||||
|
|
||||||
|
# Coded by type:
|
||||||
|
leg_handles = []
|
||||||
|
for kern_type in kern_types:
|
||||||
|
color = type_colors[kern_type]
|
||||||
|
inds = find_kern_specs(config['k_specs'], types=kern_type)
|
||||||
|
leg_handles.append(axes[0, 2].plot(scales, data['measure_conv'][:, inds],
|
||||||
|
c=color, label=f'{kern_type}', **line_kwargs)[0])
|
||||||
|
axes[0, 2].plot(scales, median_conv, **median_kwargs)
|
||||||
|
axes[1, 2].plot(scales, data['measure_feat'][:, inds], c=color, **line_kwargs)
|
||||||
|
axes[1, 2].plot(scales, median_feat, **median_kwargs)
|
||||||
|
axes[0, 2].legend(handles=leg_handles, loc='upper left')
|
||||||
|
axes[0, 2].set_title('Coded by type')
|
||||||
|
|
||||||
|
|
||||||
|
# Coded by sigma:
|
||||||
|
leg_handles = []
|
||||||
|
for kern_sigma in kern_sigmas:
|
||||||
|
color = sigma_colors[kern_sigma]
|
||||||
|
inds = find_kern_specs(config['k_specs'], sigmas=kern_sigma)
|
||||||
|
leg_handles.append(axes[0, 3].plot(scales, data['measure_conv'][:, inds],
|
||||||
|
c=color, label=f'{kern_sigma}', **line_kwargs)[0])
|
||||||
|
axes[0, 3].plot(scales, median_conv, **median_kwargs)
|
||||||
|
axes[1, 3].plot(scales, data['measure_feat'][:, inds], c=color, **line_kwargs)
|
||||||
|
axes[1, 3].plot(scales, median_feat, **median_kwargs)
|
||||||
|
axes[0, 3].legend(handles=leg_handles, loc='upper left')
|
||||||
|
axes[0, 3].set_title('Coded by sigma')
|
||||||
|
|
||||||
|
plt.show()
|
||||||
|
embed()
|
||||||
@@ -1,9 +1,20 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
from scipy.stats import gaussian_kde
|
||||||
|
|
||||||
def shorten_species(name):
|
def shorten_species(name):
|
||||||
genus, species = name.split('_')
|
genus, species = name.split('_')
|
||||||
return genus[0] + '. ' + species
|
return genus[0] + '. ' + species
|
||||||
|
|
||||||
|
def unsort_unique(array):
|
||||||
|
values, inds = np.unique(array, return_index=True)
|
||||||
|
return values[np.argsort(inds)]
|
||||||
|
|
||||||
|
def get_kde(data, sigma, axis=None, n=1000, pad=10):
|
||||||
|
if axis is None:
|
||||||
|
axis = np.linspace(data.min() - pad * sigma, data.max() + pad * sigma, n)
|
||||||
|
pdf = gaussian_kde(data, sigma)(axis)
|
||||||
|
return pdf, axis
|
||||||
|
|
||||||
def get_saturation(sigmoid, low=0.05, high=0.95, first=True, last=True,
|
def get_saturation(sigmoid, low=0.05, high=0.95, first=True, last=True,
|
||||||
condense=None):
|
condense=None):
|
||||||
if condense == 'norm' and sigmoid.ndim == 2:
|
if condense == 'norm' and sigmoid.ndim == 2:
|
||||||
@@ -16,17 +27,17 @@ def get_saturation(sigmoid, low=0.05, high=0.95, first=True, last=True,
|
|||||||
low_value = min_value + low * span
|
low_value = min_value + low * span
|
||||||
high_value = min_value + high * span
|
high_value = min_value + high * span
|
||||||
|
|
||||||
low_mask = sigmoid >= low_value
|
low_mask = sigmoid <= low_value
|
||||||
high_mask = sigmoid >= high_value
|
high_mask = sigmoid <= high_value
|
||||||
if sigmoid.ndim == 1:
|
if sigmoid.ndim == 1:
|
||||||
low_ind = np.nonzero(low_mask)[0][0]
|
low_ind = np.nonzero(low_mask)[0][-1]
|
||||||
high_ind = np.nonzero(high_mask)[0][0]
|
high_ind = np.nonzero(high_mask)[0][-1]
|
||||||
elif condense == 'all':
|
elif condense == 'all':
|
||||||
low_ind = np.nonzero(low_mask.all(axis=1))[0][0]
|
low_ind = np.nonzero(low_mask.all(axis=1))[0][-1]
|
||||||
high_ind = np.nonzero(high_mask.all(axis=1))[0][0]
|
high_ind = np.nonzero(high_mask.all(axis=1))[0][-1]
|
||||||
else:
|
else:
|
||||||
low_ind, high_ind = [], []
|
low_ind, high_ind = [], []
|
||||||
for i in range(sigmoid.shape[1]):
|
for i in range(sigmoid.shape[1]):
|
||||||
low_ind.append(np.nonzero(low_mask[:, i])[0][0])
|
low_ind.append(np.nonzero(low_mask[:, i])[0][-1])
|
||||||
high_ind.append(np.nonzero(high_mask[:, i])[0][0])
|
high_ind.append(np.nonzero(high_mask[:, i])[0][-1])
|
||||||
return low_ind, high_ind
|
return low_ind, high_ind
|
||||||
|
|||||||
@@ -4,19 +4,23 @@ import matplotlib.pyplot as plt
|
|||||||
from thunderhopper.modeltools import load_data, save_data
|
from thunderhopper.modeltools import load_data, save_data
|
||||||
from thunderhopper.filetools import crop_paths
|
from thunderhopper.filetools import crop_paths
|
||||||
from thunderhopper.filtertools import find_kern_specs
|
from thunderhopper.filtertools import find_kern_specs
|
||||||
from thunderhopper.model import process_signal
|
from thunderhopper.model import process_signal, convolve_kernels
|
||||||
from IPython import embed
|
from IPython import embed
|
||||||
|
|
||||||
# GENERAL SETTINGS:
|
# GENERAL SETTINGS:
|
||||||
target = 'Omocestus_rufipes'
|
target = 'Omocestus_rufipes'
|
||||||
data_paths = glob.glob(f'../data/processed/{target}*.npz')
|
data_paths = glob.glob(f'../data/processed/{target}*.npz')
|
||||||
stages = ['raw', 'filt', 'env', 'log', 'inv', 'conv', 'bi', 'feat']
|
noise_path = '../data/processed/white_noise_sd-1.npz'
|
||||||
|
stages = ['filt', 'env', 'log', 'inv', 'conv', 'feat']
|
||||||
save_path = '../data/inv/full/'
|
save_path = '../data/inv/full/'
|
||||||
|
|
||||||
# ANALYSIS SETTINGS:
|
# ANALYSIS SETTINGS:
|
||||||
example_scales = np.array([0, 1, 10, 50])
|
example_scales = np.array([0.1, 1, 10, 30, 100, 300])
|
||||||
scales = np.geomspace(0.01, 100, 100)
|
scales = np.geomspace(0.01, 10000, 100)
|
||||||
scales = np.unique(np.concatenate((scales, example_scales)))
|
scales = np.unique(np.concatenate((scales, example_scales)))
|
||||||
|
thresh_rel = 3
|
||||||
|
|
||||||
|
# SUBSET SETTINGS:
|
||||||
kernels = np.array([
|
kernels = np.array([
|
||||||
[1, 0.002],
|
[1, 0.002],
|
||||||
[-1, 0.002],
|
[-1, 0.002],
|
||||||
@@ -29,20 +33,29 @@ kernels = None
|
|||||||
types = None#np.array([-1])
|
types = None#np.array([-1])
|
||||||
sigmas = None#np.array([0.001, 0.002, 0.004, 0.008, 0.016, 0.032])
|
sigmas = None#np.array([0.001, 0.002, 0.004, 0.008, 0.016, 0.032])
|
||||||
|
|
||||||
|
# PREPARATION:
|
||||||
|
noise_data = np.load(noise_path)
|
||||||
|
pure_noise = noise_data['raw']
|
||||||
|
|
||||||
# EXECUTION:
|
# EXECUTION:
|
||||||
for data_path, name in zip(data_paths, crop_paths(data_paths)):
|
for data_path, name in zip(data_paths, crop_paths(data_paths)):
|
||||||
print(f'Processing {name}')
|
print(f'Processing {name}')
|
||||||
|
|
||||||
# Get song recording:
|
# Get song recording (prior to anything):
|
||||||
data, config = load_data(data_path, files='raw')
|
data, config = load_data(data_path, files='raw')
|
||||||
song, rate = data['raw'], config['rate']
|
song, rate = data['raw'], config['rate']
|
||||||
|
|
||||||
|
if thresh_rel is not None:
|
||||||
|
# Get noise-bound kernel-specific thresholds:
|
||||||
|
config['feat_thresh'] = noise_data['conv'].std(axis=0) * thresh_rel
|
||||||
|
|
||||||
# Reduce to kernel subset:
|
# Reduce to kernel subset:
|
||||||
kern_inds = find_kern_specs(config['k_specs'], kernels, types, sigmas)
|
if any(var is not None for var in [kernels, types, sigmas]):
|
||||||
config['kernels'] = config['kernels'][:, kern_inds]
|
kern_inds = find_kern_specs(config['k_specs'], kernels, types, sigmas)
|
||||||
config['k_specs'] = config['k_specs'][kern_inds, :]
|
config['kernels'] = config['kernels'][:, kern_inds]
|
||||||
config['k_props'] = [config['k_props'][i] for i in kern_inds]
|
config['k_specs'] = config['k_specs'][kern_inds, :]
|
||||||
config['feat_thresh'] = config['feat_thresh'][kern_inds]
|
config['k_props'] = [config['k_props'][i] for i in kern_inds]
|
||||||
|
config['feat_thresh'] = config['feat_thresh'][kern_inds]
|
||||||
|
|
||||||
# Get song segment to be analyzed:
|
# Get song segment to be analyzed:
|
||||||
time = np.arange(song.shape[0]) / rate
|
time = np.arange(song.shape[0]) / rate
|
||||||
@@ -52,22 +65,19 @@ for data_path, name in zip(data_paths, crop_paths(data_paths)):
|
|||||||
# Normalize song component:
|
# Normalize song component:
|
||||||
song /= song[segment].std(axis=0)
|
song /= song[segment].std(axis=0)
|
||||||
|
|
||||||
# Get normalized noise:
|
# Get normalized noise component:
|
||||||
rng = np.random.default_rng()
|
noise = pure_noise[:song.shape[0]]
|
||||||
noise = rng.normal(size=song.shape[0])
|
|
||||||
noise /= noise[segment].std()
|
noise /= noise[segment].std()
|
||||||
|
|
||||||
# Prepare snippet storage:
|
# Prepare snippet storage:
|
||||||
shape_low = (song.shape[0], example_scales.size)
|
shape_low = (song.shape[0], example_scales.size)
|
||||||
shape_high = (song.shape[0], config['k_specs'].shape[0], example_scales.size)
|
shape_high = (song.shape[0], config['k_specs'].shape[0], example_scales.size)
|
||||||
snippets = dict(
|
snippets = dict(
|
||||||
snip_raw=np.zeros(shape_low, dtype=float),
|
|
||||||
snip_filt=np.zeros(shape_low, dtype=float),
|
snip_filt=np.zeros(shape_low, dtype=float),
|
||||||
snip_env=np.zeros(shape_low, dtype=float),
|
snip_env=np.zeros(shape_low, dtype=float),
|
||||||
snip_log=np.zeros(shape_low, dtype=float),
|
snip_log=np.zeros(shape_low, dtype=float),
|
||||||
snip_inv=np.zeros(shape_low, dtype=float),
|
snip_inv=np.zeros(shape_low, dtype=float),
|
||||||
snip_conv=np.zeros(shape_high, dtype=float),
|
snip_conv=np.zeros(shape_high, dtype=float),
|
||||||
snip_bi=np.zeros(shape_high, dtype=float),
|
|
||||||
snip_feat=np.zeros(shape_high, dtype=float)
|
snip_feat=np.zeros(shape_high, dtype=float)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -75,7 +85,6 @@ for data_path, name in zip(data_paths, crop_paths(data_paths)):
|
|||||||
shape_low = (scales.size,)
|
shape_low = (scales.size,)
|
||||||
shape_high = (scales.size, config['k_specs'].shape[0])
|
shape_high = (scales.size, config['k_specs'].shape[0])
|
||||||
measures = dict(
|
measures = dict(
|
||||||
measure_raw=np.zeros(shape_low, dtype=float),
|
|
||||||
measure_filt=np.zeros(shape_low, dtype=float),
|
measure_filt=np.zeros(shape_low, dtype=float),
|
||||||
measure_env=np.zeros(shape_low, dtype=float),
|
measure_env=np.zeros(shape_low, dtype=float),
|
||||||
measure_log=np.zeros(shape_low, dtype=float),
|
measure_log=np.zeros(shape_low, dtype=float),
|
||||||
@@ -96,36 +105,18 @@ for data_path, name in zip(data_paths, crop_paths(data_paths)):
|
|||||||
signal=scaled, rate=rate)
|
signal=scaled, rate=rate)
|
||||||
# Store results:
|
# Store results:
|
||||||
for stage in stages:
|
for stage in stages:
|
||||||
key = f'measure_{stage}'
|
mkey, skey = f'measure_{stage}', f'snip_{stage}'
|
||||||
|
|
||||||
# Log snippet data:
|
# Log snippet data:
|
||||||
if scale in example_scales:
|
if scale in example_scales:
|
||||||
scale_ind = np.nonzero(example_scales == scale)[0][0]
|
scale_ind = np.nonzero(example_scales == scale)[0][0]
|
||||||
snippets[f'snip_{stage}'][:, ..., scale_ind] = signals[stage]
|
snippets[skey][:, ..., scale_ind] = signals[stage]
|
||||||
|
|
||||||
# Log intensity measure per stage (excluding binary):
|
# Log intensity measure per stage (excluding binary):
|
||||||
if stage in ['raw', 'filt', 'env', 'log', 'inv', 'conv']:
|
if stage in ['raw', 'filt', 'env', 'log', 'inv', 'conv']:
|
||||||
measures[key][i] = signals[stage][segment, ...].std(axis=0)
|
measures[mkey][i] = signals[stage][segment, ...].std(axis=0)
|
||||||
elif stage == 'feat':
|
elif stage == 'feat':
|
||||||
measures[key][i] = signals[stage][segment, :].mean(axis=0)
|
measures[mkey][i] = signals[stage][segment, :].mean(axis=0)
|
||||||
|
|
||||||
# thresh_y = np.percentile(measures['measure_feat'], 99, axis=0)
|
|
||||||
# kern_types = np.unique()
|
|
||||||
# thresh_x = np.zeros(thresh_y.shape, dtype=float)
|
|
||||||
# for i, thresh in enumerate(thresh_y):
|
|
||||||
# if thresh < 0.1:
|
|
||||||
# thresh_x[i] = scales[-1]
|
|
||||||
# continue
|
|
||||||
# mask = (measures['measure_feat'][:, i] < thresh)
|
|
||||||
# thresh_x[i] = scales[np.nonzero(mask)[0][-1]]
|
|
||||||
# inds = np.argsort(thresh_x)
|
|
||||||
# print(config['k_specs'][inds, :])
|
|
||||||
|
|
||||||
# fig, axes = plt.subplots(1, 2)
|
|
||||||
# axes[0].plot(snippets['snip_feat'][:, inds, -1])
|
|
||||||
# axes[1].plot(scales, measures['measure_feat'][:, inds])
|
|
||||||
# plt.show()
|
|
||||||
# embed()
|
|
||||||
|
|
||||||
# Save analysis results:
|
# Save analysis results:
|
||||||
if save_path is not None:
|
if save_path is not None:
|
||||||
|
|||||||
@@ -7,15 +7,19 @@ from IPython import embed
|
|||||||
# GENERAL SETTINGS:
|
# GENERAL SETTINGS:
|
||||||
target = ['Omocestus_rufipes', '*'][0]
|
target = ['Omocestus_rufipes', '*'][0]
|
||||||
data_paths = search_files(target, excl='noise', dir='../data/processed/')
|
data_paths = search_files(target, excl='noise', dir='../data/processed/')
|
||||||
|
noise_path = '../data/processed/white_noise_sd-1.npz'
|
||||||
save_path = '../data/inv/log_hp/'
|
save_path = '../data/inv/log_hp/'
|
||||||
|
|
||||||
# ANALYSIS SETTINGS:
|
# ANALYSIS SETTINGS:
|
||||||
add_noise = False
|
add_noise = target == '*' or False
|
||||||
save_snippets = target == 'Omocestus_rufipes'
|
save_snippets = target == 'Omocestus_rufipes'
|
||||||
example_scales = np.array([0.1, 1, 10, 30, 100, 300])
|
example_scales = np.array([0.1, 1, 10, 30, 100, 300])
|
||||||
scales = np.geomspace(0.1, 10000, 500)
|
scales = np.geomspace(0.1, 10000, 500)
|
||||||
scales = np.unique(np.concatenate((scales, example_scales)))
|
scales = np.unique(np.concatenate((scales, example_scales)))
|
||||||
|
|
||||||
|
# PREPARATION:
|
||||||
|
pure_noise = np.load(noise_path)['filt']
|
||||||
|
|
||||||
# EXECUTION:
|
# EXECUTION:
|
||||||
for data_path, name in zip(data_paths, crop_paths(data_paths)):
|
for data_path, name in zip(data_paths, crop_paths(data_paths)):
|
||||||
print(f'Processing {name}')
|
print(f'Processing {name}')
|
||||||
@@ -36,9 +40,8 @@ for data_path, name in zip(data_paths, crop_paths(data_paths)):
|
|||||||
mix = song[:, None] * scales[None, :]
|
mix = song[:, None] * scales[None, :]
|
||||||
|
|
||||||
if add_noise:
|
if add_noise:
|
||||||
# Add normalized envelopenoise:
|
# Add normalized noise component:
|
||||||
rng = np.random.default_rng()
|
noise = pure_noise[:song.shape[0]]
|
||||||
noise = rng.normal(scale=1, size=song.shape)
|
|
||||||
noise /= noise[segment].std()
|
noise /= noise[segment].std()
|
||||||
mix += noise[:, None]
|
mix += noise[:, None]
|
||||||
|
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ from thunderhopper.model import convolve_kernels
|
|||||||
from IPython import embed
|
from IPython import embed
|
||||||
|
|
||||||
# GENERAL SETTINGS:
|
# GENERAL SETTINGS:
|
||||||
target = ['Omocestus_rufipes', '*'][1]
|
target = ['Omocestus_rufipes', '*'][0]
|
||||||
data_paths = search_files(target, excl='noise', dir='../data/processed/')
|
data_paths = search_files(target, excl='noise', dir='../data/processed/')
|
||||||
noise_path = '../data/processed/white_noise_sd-1.npz'
|
noise_path = '../data/processed/white_noise_sd-1.npz'
|
||||||
save_path = '../data/inv/thresh_lp/'
|
save_path = '../data/inv/thresh_lp/'
|
||||||
|
|
||||||
# ANALYSIS SETTINGS:
|
# ANALYSIS SETTINGS:
|
||||||
add_noise = True
|
add_noise = False
|
||||||
save_snippets = add_noise and (target == 'Omocestus_rufipes')
|
save_snippets = add_noise and (target == 'Omocestus_rufipes')
|
||||||
plot_results = False
|
plot_results = False
|
||||||
example_scales = np.array([0, 1, 10, 30, 100])
|
example_scales = np.array([0, 1, 10, 30, 100])
|
||||||
@@ -62,8 +62,8 @@ for data_path, name in zip(data_paths, crop_paths(data_paths)):
|
|||||||
thresh_abs = ref_conv[segment, :].std(axis=0, keepdims=True) * thresh_rel[:, None]
|
thresh_abs = ref_conv[segment, :].std(axis=0, keepdims=True) * thresh_rel[:, None]
|
||||||
|
|
||||||
# Prepare measure storage:
|
# Prepare measure storage:
|
||||||
shape = (scales.size, kern_specs.shape[0], thresh_rel.size)
|
measure_inv = np.zeros((scales.size,), dtype=float)
|
||||||
measure_feat = np.zeros(shape, dtype=float)
|
measure_feat = np.zeros((scales.size, kern_specs.shape[0], thresh_rel.size), dtype=float)
|
||||||
if save_snippets:
|
if save_snippets:
|
||||||
# Prepare snippet storage:
|
# Prepare snippet storage:
|
||||||
snip_inv = np.zeros((song.size, example_scales.size), dtype=float)
|
snip_inv = np.zeros((song.size, example_scales.size), dtype=float)
|
||||||
@@ -81,6 +81,9 @@ for data_path, name in zip(data_paths, crop_paths(data_paths)):
|
|||||||
if add_noise:
|
if add_noise:
|
||||||
# Add noise:
|
# Add noise:
|
||||||
scaled_song += noise
|
scaled_song += noise
|
||||||
|
|
||||||
|
# Log input intensity measure:
|
||||||
|
measure_inv[i] = scaled_song[segment].std()
|
||||||
|
|
||||||
# Process mixture:
|
# Process mixture:
|
||||||
scaled_conv = convolve_kernels(scaled_song, config['kernels'], config['k_specs'])
|
scaled_conv = convolve_kernels(scaled_song, config['kernels'], config['k_specs'])
|
||||||
@@ -130,6 +133,7 @@ for data_path, name in zip(data_paths, crop_paths(data_paths)):
|
|||||||
data = dict(
|
data = dict(
|
||||||
scales=scales,
|
scales=scales,
|
||||||
example_scales=example_scales,
|
example_scales=example_scales,
|
||||||
|
measure_inv=measure_inv,
|
||||||
measure_feat=measure_feat,
|
measure_feat=measure_feat,
|
||||||
thresh_rel=thresh_rel,
|
thresh_rel=thresh_rel,
|
||||||
thresh_abs=thresh_abs,
|
thresh_abs=thresh_abs,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from IPython import embed
|
|||||||
|
|
||||||
# General:
|
# General:
|
||||||
save_path = '../data/processed/white_noise'
|
save_path = '../data/processed/white_noise'
|
||||||
stages = ['filt', 'env', 'log', 'inv', 'conv', 'bi', 'feat']
|
stages = ['raw', 'filt', 'env', 'log', 'inv', 'conv', 'bi', 'feat']
|
||||||
sds = [1]
|
sds = [1]
|
||||||
dur = 60
|
dur = 60
|
||||||
|
|
||||||
@@ -23,9 +23,9 @@ types = [1, -1, 2, -2, 3, -3, 4, -4, 5, -5,
|
|||||||
6, -6, 7, -7, 8, -8, 9, -9, 10, -10]
|
6, -6, 7, -7, 8, -8, 9, -9, 10, -10]
|
||||||
config = configuration(env_rate, feat_rate, types=types, sigmas=sigmas)
|
config = configuration(env_rate, feat_rate, types=types, sigmas=sigmas)
|
||||||
config.update({
|
config.update({
|
||||||
'bp_fcut': None,
|
|
||||||
'rate_ratio': None,
|
'rate_ratio': None,
|
||||||
'env_fcut': 250,
|
'env_fcut': 250,
|
||||||
|
'db_ref': 1,
|
||||||
'inv_fcut': 5,
|
'inv_fcut': 5,
|
||||||
'feat_thresh': np.load('../data/kernel_thresholds.npy') * 0.2,
|
'feat_thresh': np.load('../data/kernel_thresholds.npy') * 0.2,
|
||||||
'feat_fcut': 0.5,
|
'feat_fcut': 0.5,
|
||||||
|
|||||||
65
python/save_ref_measures.py
Normal file
65
python/save_ref_measures.py
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import numpy as np
|
||||||
|
from thunderhopper.filters import decibel, sosfilter
|
||||||
|
from thunderhopper.model import convolve_kernels, process_signal
|
||||||
|
from thunderhopper.modeltools import load_data
|
||||||
|
from IPython import embed
|
||||||
|
|
||||||
|
## SETTINGS:
|
||||||
|
|
||||||
|
# General:
|
||||||
|
mode = ['log_hp', 'thresh_lp', 'full'][2]
|
||||||
|
noise_path = '../data/processed/white_noise_sd-1.npz'
|
||||||
|
save_path = '../data/inv/'
|
||||||
|
pad = np.array([0.1, 0.9])
|
||||||
|
|
||||||
|
stages = dict(
|
||||||
|
log_hp=['filt', 'env', 'log', 'inv'],
|
||||||
|
thresh_lp=['inv', 'conv', 'feat'],
|
||||||
|
full=['raw', 'filt', 'env', 'log', 'inv', 'conv', 'feat']
|
||||||
|
)[mode]
|
||||||
|
|
||||||
|
# PROCESSING:
|
||||||
|
|
||||||
|
print(f'Fetching references for {mode} invariance...')
|
||||||
|
|
||||||
|
# Load pure-noise starter representation:
|
||||||
|
noise_data, config = load_data(noise_path, stages[0])
|
||||||
|
starter = noise_data[stages[0]]
|
||||||
|
|
||||||
|
# Prepare buffered measurement segment:
|
||||||
|
pad = (pad * starter.shape[0]).astype(int)
|
||||||
|
segment = np.arange(starter.shape[0])[pad[0]:pad[1]]
|
||||||
|
|
||||||
|
# Normalize starter:
|
||||||
|
starter /= starter[segment].std()
|
||||||
|
|
||||||
|
# Run pipeline:
|
||||||
|
if mode == 'log_hp':
|
||||||
|
data = {'filt': starter}
|
||||||
|
data['env'] = sosfilter(np.abs(data['filt']), config['rate'], config['env_fcut'],
|
||||||
|
'lp', padtype='even', padlen=config['padlen'])
|
||||||
|
data['log'] = decibel(data['env'], ref=1)
|
||||||
|
data['inv'] = sosfilter(data['log'], config['env_rate'], config['inv_fcut'],
|
||||||
|
'hp', padtype='constant', padlen=config['padlen'])
|
||||||
|
elif mode == 'thresh_lp':
|
||||||
|
data = {'inv': starter}
|
||||||
|
data['conv'] = convolve_kernels(data['inv'], config['kernels'], config['k_specs'])
|
||||||
|
data['feat'] = sosfilter((data['conv'] > config['feat_thresh']).astype(float),
|
||||||
|
config['env_rate'], config['feat_fcut'], 'lp',
|
||||||
|
padtype='fixed', padlen=config['padlen'])
|
||||||
|
elif mode == 'full':
|
||||||
|
data = process_signal(config, stages, signal=starter, rate=config['rate'])[0]
|
||||||
|
|
||||||
|
# Get measures:
|
||||||
|
measures = {}
|
||||||
|
for stage in stages:
|
||||||
|
if stage == 'feat':
|
||||||
|
measures[stage] = data[stage][segment, :].mean(axis=0)
|
||||||
|
else:
|
||||||
|
measures[stage] = data[stage][segment, ...].std(axis=0)
|
||||||
|
|
||||||
|
# Save results:
|
||||||
|
np.savez(save_path + f'{mode}/ref_measures.npz', **measures)
|
||||||
|
|
||||||
|
print('Done.')
|
||||||
|
embed()
|
||||||
@@ -16,7 +16,7 @@ if False:
|
|||||||
|
|
||||||
# Interactivity:
|
# Interactivity:
|
||||||
reload_saved = False
|
reload_saved = False
|
||||||
gui = False
|
gui = True
|
||||||
|
|
||||||
# Processing:
|
# Processing:
|
||||||
env_rate = 44100.0
|
env_rate = 44100.0
|
||||||
@@ -29,6 +29,7 @@ config.update({
|
|||||||
'channel': 0,
|
'channel': 0,
|
||||||
'rate_ratio': None,
|
'rate_ratio': None,
|
||||||
'env_fcut': 250,
|
'env_fcut': 250,
|
||||||
|
'db_ref': 1,
|
||||||
'inv_fcut': 5,
|
'inv_fcut': 5,
|
||||||
'feat_thresh': np.load('../data/kernel_thresholds.npy') * 0.2,
|
'feat_thresh': np.load('../data/kernel_thresholds.npy') * 0.2,
|
||||||
'feat_fcut': 0.5,
|
'feat_fcut': 0.5,
|
||||||
|
|||||||
Reference in New Issue
Block a user