import numpy as np
import pandas as pd
import plotly as plt
Spinorama manual
Abstract
How to use the library step by step!
How to use the library?
How to load the data?
Start by loading some classical libraries:
Then some specific functions from Spinorama:
from spinorama.load_spl_hv_txt import parse_graph_spl_hv_txt
from spinorama.load import filter_graphs
from spinorama.constant_paths import MEAN_MIN, MEAN_MAX, DEFAULT_FREQ_RANGE
Loading a dataset in text format
The parser expect to find 72 files in this directory:
- name of the files matches *_H angle.txt for horizontal measurements with angle between -170 and 180 in 10 degrees increment
- name of the files matches *_V angle.txt for vertical measurements with angle between -170 and 180 in 10 degrees increment
= 'Ascend Acoustics Sierra-2EX V2'
speaker dir = f'../datas/measurements/{speaker}/vendor'
='spl_hv_txt'
mformat
# read horizontal and vertical data
# spl_H and spl_V are dataframe
= parse_graph_spl_hv_txt(dir, 'H')
_, spl_H = parse_graph_spl_hv_txt(dir, 'V')
_, spl_V
# put them in a convenient dictionnary of dataframe
= filter_graphs(speaker, spl_H, spl_V, MEAN_MIN, MEAN_MAX, mformat=mformat, mdistance=1) df
Computing with the data
Computing the spinorama (CEA2034)
from spinorama.compute_cea2034 import compute_cea2034
# compute the spin
= compute_cea2034(df['SPL Horizontal_unmelted'], df['SPL Vertical_unmelted']) spin
Computing classical values for this speaker
from spinorama.compute_estimates import estimates
# compute the spin
= compute_cea2034(df['SPL Horizontal_unmelted'], df['SPL Vertical_unmelted'])
spin = estimates(spin, df['SPL Horizontal_unmelted'], df['SPL Vertical_unmelted'])
properties print('Reference point (Hz) at which the SPL value dropped by 3 dB with respect to the average of the on-axis measurement between [{}, {}]: {:5.1f} Hz'.format(
'ref_from'],
properties['ref_to'],
properties['ref_3dB'],
properties[
))print('Directivity in degrees at which the SPL value dropped by 6 d with respect to the on-axis measurementB: {:5.1f} deg'.format(properties['dir_horizontal_p']))
properties
Reference point (Hz) at which the SPL value dropped by 3 dB with respect to the average of the on-axis measurement between [300.0, 5000.0]: 58.6 Hz
Directivity in degrees at which the SPL value dropped by 6 d with respect to the on-axis measurementB: 80.0 deg
{'ref_3dB': np.float64(58.6),
'ref_6dB': np.float64(51.3),
'ref_9dB': np.float64(43.9),
'ref_12dB': np.float64(39.6),
'ref_from': 300.0,
'ref_to': 5000.0,
'ref_level': np.float64(-0.3),
'ref_band': np.float64(2.7),
'sensitivity_delta': np.float64(-0.26316630303028626),
'dir_horizontal_p': 80.0,
'dir_horizontal_m': -70.0,
'dir_horizontal': 75.0,
'dir_vertical_p': 10.0,
'dir_vertical_m': -20.0,
'dir_vertical': 15.0}
Compute the harmann/olive score
Compute the PIR (Predicted In-Room Response)
from spinorama.compute_cea2034 import estimated_inroom_hv
= estimated_inroom_hv(df['SPL Horizontal_unmelted'], df['SPL Vertical_unmelted']) pir
Compute the PIR (Predicted In-Room Response)
from spinorama.load import graph_melt, graph_unmelt
from spinorama.compute_cea2034 import compute_cea2034, estimated_inroom_hv
from spinorama.compute_scores import speaker_pref_rating
= compute_cea2034(df['SPL Horizontal_unmelted'], df['SPL Vertical_unmelted'])
spin = estimated_inroom_hv(df['SPL Horizontal_unmelted'], df['SPL Vertical_unmelted'])
pir = speaker_pref_rating(graph_melt(spin), graph_melt(pir), rounded=True)
scores scores
{'nbd_on_axis': 0.359,
'nbd_listening_window': 0.321,
'nbd_sound_power': 0.297,
'nbd_pred_in_room': 0.282,
'sm_pred_in_room': 0.876,
'sm_sound_power': 0.943,
'pref_score_wsub': 7.97,
'lfx_hz': 43,
'lfq': 0.829,
'pref_score': 5.9,
'aad_on_axis': 0.454}
Plotting the data
Example of the parameters you can change to adapt the layout to your liking. See plotly documentation for all the options
= dict(
my_layout =700,
width=400,
height=dict(
title=0.5,
x=1.0,
y="center",
xanchor="top",
yanchor=speaker,
text=dict(
font=18,
size
),
),=dict(
legend=1.2,
x=1,
y="center",
xanchor="v",
orientation=dict(
font=10,
size
),
),=dict(
font=10
size
),=dict(
margin=0,
l=0,
r=30,
b=30,
t=4
pad
), )
All the plot functions are in:
import spinorama.plot as plot
CEA2034 plot (aka spinorama plot)
= plot.plot_spinorama(
plot_spin =spin,
spin=plot.plot_params_default,
params=None,
minmax_slopes=False,
is_normalized=DEFAULT_FREQ_RANGE
valid_freq_range
)
plot_spin.update_layout(my_layout) plot_spin
Normalized CEA2034 plot
= plot.plot_spinorama(
plot_spin =spin,
spin=plot.plot_params_default,
params=None,
minmax_slopes=True,
is_normalized=DEFAULT_FREQ_RANGE
valid_freq_range
)
plot_spin.update_layout(my_layout) plot_spin
On Axis plot
= plot.plot_graph(df['On Axis_unmelted'], plot.plot_params_default, DEFAULT_FREQ_RANGE)
plot_onaxis
plot_onaxis.update_layout(my_layout) plot_onaxis
If you also want to see regression lines:
= plot.plot_graph_flat(df['On Axis_unmelted'], "On Axis", plot.plot_params_default, DEFAULT_FREQ_RANGE)
plot_onaxis
plot_onaxis.update_layout(my_layout) plot_onaxis
Early reflection plot
= plot.plot_graph(df['Early Reflections_unmelted'], plot.plot_params_default, DEFAULT_FREQ_RANGE)
plot_er
plot_er.update_layout(my_layout) plot_er
Predicted In-Room Response (aka PIR) plot
= plot.plot_graph_regression(
plot_pir =df['Estimated In-Room Response_unmelted'],
df='Estimated In-Room Response',
measurement=plot.plot_params_default,
params=None,
minmax_slopes=False,
is_normalized=DEFAULT_FREQ_RANGE
valid_freq_range
)
plot_pir.update_layout(my_layout) plot_pir
Directivity plots
There are various ways to represent directivity plots:
Contour plots
= plot.plot_contour(df['SPL Horizontal_unmelted'], plot.contour_params_default, DEFAULT_FREQ_RANGE)
plot_contour_h
plot_contour_h.update_layout(my_layout) plot_contour_h
The same one, normalized to on axis:
= plot.plot_contour(df['SPL Horizontal_normalized_unmelted'], plot.contour_params_default, DEFAULT_FREQ_RANGE)
plot_contour_h
plot_contour_h.update_layout(my_layout) plot_contour_h
3D Contour plots
= plot.plot_contour_3d(df['SPL Horizontal_unmelted'], plot.contour_params_default, DEFAULT_FREQ_RANGE)
plot_contour_h
plot_contour_h.update_layout(my_layout) plot_contour_h
The same one, normalized to on axis:
= plot.plot_contour_3d(df['SPL Horizontal_normalized_unmelted'], plot.contour_params_default, DEFAULT_FREQ_RANGE)
plot_contour_h
plot_contour_h.update_layout(my_layout) plot_contour_h
Radar plots
= plot.plot_radar(df['SPL Horizontal_unmelted'], plot.radar_params_default, DEFAULT_FREQ_RANGE)
plot_contour_h
plot_contour_h.update_layout(my_layout) plot_contour_h
= plot.plot_radar(df['SPL Vertical_unmelted'], plot.radar_params_default, DEFAULT_FREQ_RANGE)
plot_contour_h
plot_contour_h.update_layout(my_layout) plot_contour_h