Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deprecating separation module #382

Merged
merged 7 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .coveragerc

This file was deleted.

11 changes: 11 additions & 0 deletions mir_eval/separation.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# -*- coding: utf-8 -*-
"""
.. warning::
The mir_eval.separation module is deprecated in mir_eval version 0.8, and will be removed.
We recommend that you migrate your code to use an alternative package such as sigsep-museval
https://sigsep.github.io/sigsep-mus-eval/


Source separation algorithms attempt to extract recordings of individual
sources from a recording of a mixture of sources. Evaluation methods for
source separation compare the extracted sources from reference sources and
Expand Down Expand Up @@ -141,6 +147,7 @@ def _any_source_silent(sources):
)


@util.deprecated(version="0.8", version_removed="0.9")
def bss_eval_sources(reference_sources, estimated_sources, compute_permutation=True):
"""
Ordering and measurement of the separation quality for estimated source
Expand Down Expand Up @@ -251,6 +258,7 @@ def bss_eval_sources(reference_sources, estimated_sources, compute_permutation=T
return (sdr, sir, sar, popt)


@util.deprecated(version="0.8", version_removed="0.9")
def bss_eval_sources_framewise(
reference_sources,
estimated_sources,
Expand Down Expand Up @@ -362,6 +370,7 @@ def bss_eval_sources_framewise(
return sdr, sir, sar, perm


@util.deprecated(version="0.8", version_removed="0.9")
def bss_eval_images(reference_sources, estimated_sources, compute_permutation=True):
"""Compute the bss_eval_images function from the
BSS_EVAL Matlab toolbox.
Expand Down Expand Up @@ -496,6 +505,7 @@ def bss_eval_images(reference_sources, estimated_sources, compute_permutation=Tr
return (sdr, isr, sir, sar, popt)


@util.deprecated(version="0.8", version_removed="0.9")
def bss_eval_images_framewise(
reference_sources,
estimated_sources,
Expand Down Expand Up @@ -841,6 +851,7 @@ def _safe_db(num, den):
return 10 * np.log10(num / den)


@util.deprecated(version="0.8", version_removed="0.9")
def evaluate(reference_sources, estimated_sources, **kwargs):
"""Compute all metrics for the given reference and estimated signals.

Expand Down
21 changes: 21 additions & 0 deletions mir_eval/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import os
import inspect
import warnings
from decorator import decorator

import numpy as np

Expand Down Expand Up @@ -939,3 +941,22 @@ def midi_to_hz(midi):
Frequency/frequencies in Hz corresponding to `midi`
"""
return 440.0 * (2.0 ** ((midi - 69.0) / 12.0))


def deprecated(*, version, version_removed):
"""Mark a function as deprecated.

Using the decorated (old) function will result in a warning.
"""

def __wrapper(func, *args, **kwargs):
"""Warn the user, and then proceed."""
warnings.warn(
f"{func.__module__}.{func.__name__}\n\tDeprecated as of mir_eval version {version}."
f"\n\tIt will be removed in mir_eval version {version_removed}.",
category=FutureWarning,
stacklevel=3, # Would be 2, but the decorator adds a level
)
return func(*args, **kwargs)

return decorator(__wrapper)
9 changes: 8 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
[tool:pytest]
addopts = --cov-report term-missing --cov mir_eval --cov-report=xml --mpl --mpl-baseline-path=baseline_images/test_display

[coverage:report]
show_missing = True

[coverage:run]
omit =
separation.py

[pydocstyle]
# convention = numpy
# Below is equivalent to numpy convention + D400 and D205
Expand Down Expand Up @@ -48,13 +55,13 @@ keywords = audio music mir dsp
install_requires =
numpy >= 1.15.4
scipy >= 1.4.0
decorator

[options.extras_require]
display =
matplotlib >= 3.3.0
tests =
matplotlib >= 3.3.0
decorator
pytest
pytest-cov
pytest-mpl
18 changes: 10 additions & 8 deletions tests/test_display.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def test_display_segment():
mir_eval.display.segments(intervals, labels, text=False)

# Draw a legend
plt.legend()
plt.legend(loc="upper right")
return plt.gcf()


Expand Down Expand Up @@ -126,7 +126,7 @@ def test_display_labeled_intervals_compare():
)
mir_eval.display.labeled_intervals(est_int, est_labels, alpha=0.5, label="Estimate")

plt.legend()
plt.legend(loc="upper right")
return plt.gcf()


Expand Down Expand Up @@ -198,7 +198,7 @@ def test_display_hierarchy_nolabel():
# Plot reference and estimate with a common label set
mir_eval.display.hierarchy([int0, int1], [lab0, lab1])

plt.legend()
plt.legend(loc="upper right")
return plt.gcf()


Expand All @@ -218,7 +218,7 @@ def test_display_hierarchy_label():
# Plot reference and estimate with a common label set
mir_eval.display.hierarchy([int0, int1], [lab0, lab1], levels=["Large", "Small"])

plt.legend()
plt.legend(loc="upper right")
return plt.gcf()


Expand All @@ -238,7 +238,7 @@ def test_display_pitch_hz():
# Plot pitches on a Hz scale
mir_eval.display.pitch(ref_times, ref_freqs, unvoiced=True, label="Reference")
mir_eval.display.pitch(est_times, est_freqs, unvoiced=True, label="Estimate")
plt.legend()
plt.legend(loc="upper left")
return plt.gcf()


Expand Down Expand Up @@ -323,7 +323,7 @@ def test_display_multipitch_midi():
mir_eval.display.multipitch(ref_t, ref_p, midi=True, alpha=0.5, label="Reference")
mir_eval.display.multipitch(est_t, est_p, midi=True, alpha=0.5, label="Estimate")

plt.legend()
plt.legend(loc="upper left")
return plt.gcf()


Expand Down Expand Up @@ -392,6 +392,7 @@ def test_display_ticker_midi_zoom():
tolerance=6,
)
@pytest.mark.xfail(OLD_FT, reason=f"freetype version < {FT_VERSION}", strict=False)
@pytest.mark.skip()
def test_display_separation():
plt.figure()

Expand All @@ -410,6 +411,7 @@ def test_display_separation():
tolerance=6,
)
@pytest.mark.xfail(OLD_FT, reason=f"freetype version < {FT_VERSION}", strict=False)
@pytest.mark.skip()
def test_display_separation_label():
plt.figure()

Expand All @@ -419,7 +421,7 @@ def test_display_separation_label():

mir_eval.display.separation([x0, x1, x2], fs=fs, labels=["Alice", "Bob", "Carol"])

plt.legend()
plt.legend(loc="upper right")
return plt.gcf()


Expand All @@ -439,7 +441,7 @@ def test_display_events():
# Plot both with labels
mir_eval.display.events(beats_ref, label="reference")
mir_eval.display.events(beats_est, label="estimate")
plt.legend()
plt.legend(loc="upper right")
return plt.gcf()


Expand Down
8 changes: 6 additions & 2 deletions tests/test_separation.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
assert len(ref_files) == len(est_files) == len(sco_files) > 0
file_sets = list(zip(ref_files, est_files, sco_files))

# Skip separation tests since deprecation
pytest.skip(allow_module_level=True)


@pytest.fixture
def separation_data(request):
Expand Down Expand Up @@ -119,8 +122,9 @@ def test_empty_input(metric):
# And that the metric returns empty arrays
assert np.allclose(metric(*args), np.array([]))

assert "reference_sources is empty" in str(record[0].message)
assert "estimated_sources is empty" in str(record[1].message)
# These warning counters are now offset by 1 because of the deprecation message
assert "reference_sources is empty" in str(record[1].message)
assert "estimated_sources is empty" in str(record[2].message)


@pytest.mark.parametrize(
Expand Down
Loading