Skip to content

Commit

Permalink
use new methods and lint
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosholivan committed Dec 5, 2022
1 parent 8859fa7 commit 215ba93
Showing 1 changed file with 45 additions and 44 deletions.
89 changes: 45 additions & 44 deletions musicaiz/features/self_similarity.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ def self_similarity_louie(file: Union[Musa, str, TextIO, Path]) -> np.ndarray:
s: np.ndarray [shape=(n_bars, n_bars)]
The SSM computed from the ``feature_vector``.
"""
musa_obj = __initialization(file)
all_subdiv_notes = group_notes_in_subdivisions_bars(musa_obj)
musa_obj = __initialization(file)
all_subdiv_notes = musa_obj.get_notes_in_beats(0, len(musa_obj.beats) - 1)
bar_highest_subdiv_notes = get_highest_subdivision_bars_notes(all_subdiv_notes)
m = feature_vector(bar_highest_subdiv_notes)
s = _self_similarity(m)
Expand All @@ -128,7 +128,7 @@ def self_similarity_single_measure(
) -> np.ndarray:
"""
Computes the SSM with the selected measure for all the bars.
Parameters
----------
Expand All @@ -137,17 +137,17 @@ def self_similarity_single_measure(
measure: str
The measure or feature used to compute the SSM.
Returns
-------
s: np.ndarray [shape=(n_bars, n_bars)]
The SSM computed from the selected measure.
"""
musa_obj = __initialization(file)
bars = loaders.Musa.group_instrument_bar_notes(musa_obj)
musa_obj = __initialization(file)
bar_measures = []
for bar in bars:
for b in musa_obj.bars:
bar = musa_obj.get_notes_in_bar(b)
bar_measures.append(get_eval_measures(bar, measures=[measure]))
s = np.zeros((len(bar_measures), len(bar_measures)))
for i in range(len(bar_measures)):
Expand All @@ -161,12 +161,12 @@ def self_similarity_single_measure(
m_j = bar_measures[j][measure].flatten()
else:
m_j = bar_measures[j][measure]

# Append zeros to any vector if shapes do not match
if isinstance(m_i, np.ndarray) or isinstance(m_j, np.ndarray):
m_i, m_j = _append_zeros_array(m_i, m_j)
m_i, m_j = _append_zeros_array(m_i, m_j)

s[i,j] = spatial.distance.cosine(m_i, m_j)
s[i, j] = spatial.distance.cosine(m_i, m_j)
return s


Expand All @@ -175,7 +175,7 @@ def self_similarity_measures(
measures: List[str]
) -> np.ndarray:
"""Computes the SSM with the selected measure for all the bars.
Parameters
----------
Expand All @@ -185,14 +185,14 @@ def self_similarity_measures(
measure: str
The list of measures used to compute the SSM. It also accepts ``all`` as a value if
we want to compute the SSM with all the available measures.
Returns
-------
s: np.ndarray [shape=(n_bars, n_bars)]
The SSM computed from the selected measures.
"""
musa_obj = __initialization(file)
musa_obj = __initialization(file)

if isinstance(measures, str) and not measures == "all":
raise ValueError("For input arg `measures` you must provide a list of valid measures or `all`.")
Expand All @@ -201,9 +201,10 @@ def self_similarity_measures(
elif not isinstance(measures, list) and not all(m in _DEFAULT_MEASURES for m in measures):
raise ValueError(f"Measures arg must be a list of valid measures {_DEFAULT_MEASURES}.")

bars = loaders.Musa.group_instrument_bar_notes(musa_obj)
musa_obj = __initialization(file)
bar_measures = []
for bar in bars:
for b in musa_obj.bars:
bar = musa_obj.get_notes_in_bar(b)
bar_measures.append(get_eval_measures(bar, measures=measures))
s = np.zeros((len(bar_measures), len(bar_measures)))
for i in range(len(bar_measures)):
Expand All @@ -219,7 +220,7 @@ def self_similarity_measures(
m_j = bar_measures[j][measure].flatten()
else:
m_j = bar_measures[j][measure]

# Append zeros to any vector if shapes do not match
if isinstance(m_i, np.ndarray) or isinstance(m_j, np.ndarray):
m_i, m_j = _append_zeros_array(m_i, m_j)
Expand Down Expand Up @@ -251,19 +252,19 @@ def plot_ssm(
ssm: np.ndarray [shape=(n_bars, n_bars)]
The SSM.
segments: bool
Plot the sections boundaries over the SSM by computing the
novelty function. Default is False.
threshold: float
The threshold for peak picking in the novelty curve if ``segments=True``.
Default is 0.5.
window: float
The window for peak picking in the novelty curve if ``segments=True``.
Default is 2.
save: Optional[bool]
True if we want to save the output plot in disk. Defaults to True.
Expand All @@ -282,7 +283,7 @@ def plot_ssm(
dpi: int
dpi of the plot. Defaults to ``300``.
Examples
--------
Expand All @@ -302,7 +303,7 @@ def plot_ssm(
plt.savefig(filename + ".png")
if colorbar:
plt.colorbar()
if segments:
if segments:
segment_boundaries = get_segment_boundaries(ssm, threshold, window)
for i in range(len(segment_boundaries)):
plt.axvline(segment_boundaries[i], color='w', linestyle='--', alpha=.5)
Expand All @@ -314,14 +315,14 @@ def plot_ssm(
def _self_similarity(feature_vector: List[List[Note]]) -> np.ndarray:
"""Converts a feature vector with the highest notes per subdivision and bar
in a Self-Similarity Matrix with the cosine distance.
Parameters
----------
feature_vector: List[List[Note]]
A vector with all bars and subdivisions in which each element represents
the note with the highest pitch.
Returns
-------
Expand All @@ -334,7 +335,7 @@ def _self_similarity(feature_vector: List[List[Note]]) -> np.ndarray:
# Flatten lists to convert them in 1D vectors
m_i = list(sum(feature_vector[i] ,()))
m_j = list(sum(feature_vector[j] ,()))
s[i,j] = spatial.distance.cosine(m_i, m_j)
s[i, j] = spatial.distance.cosine(m_i, m_j)
return s


Expand All @@ -348,7 +349,7 @@ def binarize_self_similarity_matrix(
if i == j:
bin_s[i, j] = 1
continue
if ssm[i,j] >= threshold:
if ssm[i, j] >= threshold:
bin_s[i, j] = 1
else:
bin_s[i, j] == 0
Expand Down Expand Up @@ -380,9 +381,9 @@ def feature_vector(bar_highest_subdiv_notes: List[List[Note]]) -> List[List[Note
for i, note in enumerate(bar):
if i + 1 >= len(bar):
break
y = bar[i].pitch - bar[i+1].pitch
y = bar[i].pitch - bar[i + 1].pitch
if bar[i].start_ticks != 0:
x = (bar[i+1].end_ticks - bar[i+1].start_ticks) / (bar[i].end_ticks - bar[i].start_ticks)
x = (bar[i + 1].end_ticks - bar[i + 1].start_ticks) / (bar[i].end_ticks - bar[i].start_ticks)
else:
x = 0
bar_m.append((y, x))
Expand All @@ -402,7 +403,7 @@ def get_novelty_func(
ssm: np.ndarray [shape=(n_bars, n_bars)]
The SSM.
is_normalized: bool
Normalizes the Novelty curve. Defaults is True.
Expand All @@ -413,10 +414,10 @@ def get_novelty_func(
The normalized novelty function as a 1D array.
"""

c = np.linalg.norm(ssm[:,1:] - ssm[:,0:-1], axis=0)
c = np.linalg.norm(ssm[:, 1:] - ssm[:, 0:-1], axis=0)

if is_normalized:
c_norm = (c - c.min()) / (c.max() - c.min()) # normalization of c
c_norm = (c - c.min()) / (c.max() - c.min()) # normalization of c
return c_norm
else:
return c
Expand Down Expand Up @@ -454,28 +455,28 @@ def get_segment_boundaries(
# where boundaries are (this is simple to compute with the rhythm submodule.)
novelty = get_novelty_func(ssm=ssm, is_normalized=True)

#Peaks detection - sliding window
lamda = round(window) #window length
# Peaks detection - sliding window
lamda = round(window) # window length
peaks_position = signal.find_peaks(
novelty,
height=threshold,
distance=lamda,
width=round(threshold)
)[0] #array of peaks
)[0] # array of peaks
peaks_values = signal.find_peaks(
novelty,
height=threshold,
distance=lamda,
width=round(threshold)
)[1]['peak_heights'] #array of peaks
)[1]['peak_heights'] #array of peaks
b = peaks_position

#Adding elements 1 and N' to the begining and end of the array
# Adding elements 1 and N' to the begining and end of the array
if b[0] != 0:
b = np.concatenate([[0], b]) # b: segment boundaries
b = np.concatenate([[0], b]) # b: segment boundaries
if b[-1] != ssm.shape[0] - 1:
b = np.concatenate([b, [ssm.shape[0]-1]])
b = np.concatenate([b, [ssm.shape[0] - 1]])

return b


Expand All @@ -491,7 +492,7 @@ def plot_novelty_from_ssm(
):
"""
Plots the novelty curve from a SSM.
Parameters
----------
Expand All @@ -509,7 +510,7 @@ def plot_novelty_from_ssm(
window: float
The window for peak picking in the novelty curve if ``segments=True``.
Default is 2.
save: Optional[bool]
True if we want to save the output plot in disk. Defaults to True.
Expand All @@ -522,19 +523,19 @@ def plot_novelty_from_ssm(
dpi: int
dpi of the plot. Defaults to ``300``.
"""
#Plot novelty function with boundaries
# Plot novelty function with boundaries
plt.figure(figsize=(50, 10), dpi=dpi)
if title is not None:
plt.title(title)
if save:
plt.savefig(filename + ".png")
plt.title(title)

novelty = get_novelty_func(ssm)
frames = range(len(novelty))
if segments:
if segments:
segment_boundaries = get_segment_boundaries(ssm, threshold, window)
for i in range(len(segment_boundaries)):
plt.axvline(segment_boundaries[i], color='r', linestyle='--')
plt.axvline(segment_boundaries[i], color='r', linestyle='--')
plt.plot(frames, novelty)
plt.show()

0 comments on commit 215ba93

Please sign in to comment.