Skip to content
This repository was archived by the owner on Feb 7, 2024. It is now read-only.
Open
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
246 changes: 246 additions & 0 deletions acoustics/weighting_noaa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
"""
Weighting_NOAA
==============

NOAA weightings as defined
in `Technical Guidance for Assessing the Effects of Anthropogenic Sound on Marine Mammal Hearing'
<https://www.fisheries.noaa.gov/resource/document/technical-guidance-assessing-effects-anthropogenic-sound-marine-mammal>`_.


"""
import numpy as np

from acoustics.bands import third

THIRD_OCTAVE_NOAA_LF_WEIGHTING = np.array([
-24.0, -21.8, -19.9, -18.0, -16.0, -14.0, -12.2, -10.3, -8.5, -6.9, -5.4, -4.0, -2.9, -2.0, -1.3, -0.8, -0.5, -0.3,
-0.1, -0.1, -0.0, 0.0, -0.0, -0.0, -0.1, -0.3, -0.5, -0.8, -1.3, -2.0, -3.0, -4.5, -6.3, -8.6, -11.3, -14.6,
-17.9, -21.4, -25.3, -29.0, -32.8, -37.0, -40.8
])
"""
NOAA LF-weighting filter for 1/3-octave band center frequencies, as specified by :attr:`acoustics.bands.third(12.5,200000)`.
"""

THIRD_OCTAVE_NOAA_MF_WEIGHTING = np.array([
-89.9, -86.5, -83.4, -80.3, -77.1, -73.8, -70.7, -67.4, -64.1, -61.0, -57.9, -54.5, -51.4, -48.3, -45.1, -41.8,
-38.7, -35.5, -32.2, -29.1, -26.1, -22.7, -19.7, -16.8, -13.9, -11.1, -8.6, -6.3, -4.4, -2.9, -1.7, -0.8, -0.3,
-0.0, -0.0, -0.2, -0.6, -1.4, -2.6, -4.1, -6.0, -8.7, -11.5
])
"""
NOAA MF-weighting filter for 1/3-octave band center frequencies, as specified by :attr:`acoustics.bands.third(12.5,200000)`.
"""

THIRD_OCTAVE_NOAA_HF_WEIGHTING = np.array([
-106.0, -102.1, -98.7, -95.2, -91.6, -87.8, -84.3, -80.7, -77.0, -73.5, -70.0, -66.1, -62.7, -59.2, -55.6, -51.8,
-48.3, -44.7, -41.0, -37.5, -34.1, -30.3, -26.9, -23.5, -20.1, -16.6, -13.6, -10.6, -7.9, -5.7, -3.8, -2.2, -1.2,
-0.5, -0.1, 0.0, -0.1, -0.5, -1.3, -2.3, -3.8, -5.9, -8.3
])
"""
NOAA HF-weighting filter for 1/3-octave band center frequencies, as specified by :attr:`acoustics.bands.third(12.5,200000)`.
"""

THIRD_OCTAVE_NOAA_PW_WEIGHTING = np.array([
-42.9, -40.7, -38.8, -36.9, -34.9, -32.8, -30.8, -28.8, -26.8, -24.8, -22.9, -20.8, -18.9, -16.9, -15.0, -13.0,
-11.1, -9.3, -7.5, -5.9, -4.5, -3.1, -2.1, -1.3, -0.7, -0.3, -0.1, -0.0, -0.1, -0.3, -0.7, -1.5, -2.5, -3.9, -5.7,
-8.1, -10.8, -13.9, -17.4, -20.9, -24.5, -28.6, -32.4
])
"""
NOAA PW-weighting filter for 1/3-octave band center frequencies, as specified by :attr:`acoustics.bands.third(12.5,200000)`.
"""

THIRD_OCTAVE_NOAA_OW_WEIGHTING = np.array([
-74.4, -70.1, -66.2, -62.4, -58.4, -54.2, -50.4, -46.4, -42.2, -38.4, -34.6, -30.4, -26.6, -23.0, -19.3, -15.7,
-12.5, -9.5, -6.9, -4.9, -3.3, -2.0, -1.1, -0.6, -0.2, -0.0, -0.0, -0.1, -0.3, -0.7, -1.3, -2.4, -3.7, -5.4, -7.6,
-10.4, -13.3, -16.7, -20.4, -24.0, -27.7, -31.8, -35.6
])
"""
NOAA OW-weighting filter for 1/3-octave band center frequencies, as specified by :attr:`acoustics.bands.third(12.5,200000)`.
"""


def noaa_lf_weighting(first, last):
"""
Select frequency weightings between ``first`` and ``last``
centerfrequencies from NOAA LF-weighting.
Possible values for these frequencies are third-octave frequencies
between 12.5 Hz and 200,000 Hz (including them).

Parameters
----------
first : scalar
First third-octave centerfrequency.

last : scalar
Last third-octave centerfrequency.

Returns
-------
NumPy array with NOAA LF-weighting between ``first`` and ``last``
centerfrequencies.
"""
return _weighting("noaa_lf", first, last)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should make this public so we can remove all duplicate code.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a different frequency range defined in the two files. Could you please indicate where you want the public method located and how you imagine it should look like?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi there,

Just following back on this old PR: Could I kindly get you to elaborate on your comment so I can amend my code and we can complete this request?



def noaa_mf_weighting(first, last):
"""
Select frequency weightings between ``first`` and ``last``
centerfrequencies from NOAA MF-weighting.
Possible values for these frequencies are third-octave frequencies
between 12.5 Hz and 200,000 Hz (including them).

Parameters
----------
first : scalar
First third-octave centerfrequency.

last : scalar
Last third-octave centerfrequency.

Returns
-------
NumPy array with NOAA MF-weighting between ``first`` and ``last``
centerfrequencies.
"""
return _weighting("noaa_mf", first, last)


def noaa_hf_weighting(first, last):
"""
Select frequency weightings between ``first`` and ``last``
centerfrequencies from NOAA HF-weighting.
Possible values for these frequencies are third-octave frequencies
between 12.5 Hz and 200,000 Hz (including them).

Parameters
----------
first : scalar
First third-octave centerfrequency.

last : scalar
Last third-octave centerfrequency.

Returns
-------
NumPy array with NOAA HF-weighting between ``first`` and ``last``
centerfrequencies.
"""
return _weighting("noaa_hf", first, last)


def noaa_pw_weighting(first, last):
"""
Select frequency weightings between ``first`` and ``last``
centerfrequencies from NOAA PW-weighting.
Possible values for these frequencies are third-octave frequencies
between 12.5 Hz and 200,000 Hz (including them).

Parameters
----------
first : scalar
First third-octave centerfrequency.

last : scalar
Last third-octave centerfrequency.

Returns
-------
NumPy array with NOAA PW-weighting between ``first`` and ``last``
centerfrequencies.
"""
return _weighting("noaa_pw", first, last)



def noaa_ow_weighting(first, last):
"""
Select frequency weightings between ``first`` and ``last``
centerfrequencies from NOAA OW-weighting.
Possible values for these frequencies are third-octave frequencies
between 12.5 Hz and 200,000 Hz (including them).

Parameters
----------
first : scalar
First third-octave centerfrequency.

last : scalar
Last third-octave centerfrequency.

Returns
-------
NumPy array with NOAA OW-weighting between ``first`` and ``last``
centerfrequencies.
"""
return _weighting("noaa_ow", first, last)


def _weighting(filter_type, first, last):
third_oct_bands = third(12.5, 200000.0).tolist()
low = third_oct_bands.index(first)
high = third_oct_bands.index(last)

if filter_type == "noaa_lf":
freq_weightings = THIRD_OCTAVE_NOAA_LF_WEIGHTING

elif filter_type == "noaa_mf":
freq_weightings = THIRD_OCTAVE_NOAA_MF_WEIGHTING

elif filter_type == "noaa_hf":
freq_weightings = THIRD_OCTAVE_NOAA_HF_WEIGHTING

elif filter_type == "noaa_pw":
freq_weightings = THIRD_OCTAVE_NOAA_PW_WEIGHTING

elif filter_type == "noaa_ow":
freq_weightings = THIRD_OCTAVE_NOAA_OW_WEIGHTING

return freq_weightings[low:high + 1]


def noaa_lf(levels, first, last):
"""Apply NOAA LF-weighting to unweighted signal.
"""
return levels + noaa_lf_weighting(first, last)


def noaa_mf(levels, first, last):
"""Apply NOAA MF-weighting to unweighted signal.
"""
return levels + noaa_mf_weighting(first, last)


def noaa_hf(levels, first, last):
"""Apply NOAA HF-weighting to unweighted signal.
"""
return levels + noaa_hf_weighting(first, last)


def noaa_pw(levels, first, last):
"""Apply NOAA PW-weighting to unweighted signal.
"""
return levels + noaa_pw_weighting(first, last)


def noaa_ow(levels, first, last):
"""Apply NOAA OW-weighting to unweighted signal.
"""
return levels + noaa_ow_weighting(first, last)


__all__ = [
'THIRD_OCTAVE_NOAA_LF_WEIGHTING',
'THIRD_OCTAVE_NOAA_MF_WEIGHTING',
'THIRD_OCTAVE_NOAA_HF_WEIGHTING',
'THIRD_OCTAVE_NOAA_PW_WEIGHTING',
'THIRD_OCTAVE_NOAA_OW_WEIGHTING',
'noaa_lf_weighting',
'noaa_mf_weighting',
'noaa_hf_weighting',
'noaa_pw_weighting',
'noaa_ow_weighting',
'noaa_lf',
'noaa_mf',
'noaa_hf',
'noaa_pw',
'noaa_ow',
]
65 changes: 65 additions & 0 deletions tests/test_weighting_noaa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import pytest
import numpy as np
from numpy.testing import assert_array_equal, assert_array_almost_equal

from acoustics.weighting_noaa import noaa_lf, noaa_mf, noaa_hf, noaa_pw, noaa_ow


def setup_module(weighting_noaa):
weighting_noaa.levels = 100 * np.ones(43)
weighting_noaa.lowest = 12.5
weighting_noaa.highest = 200000


def test_noaa_lf():
generated = noaa_lf(levels, lowest, highest)
real = np.array([
76.0, 78.2, 80.1, 82.0, 84.0, 86.0, 87.8, 89.7, 91.5, 93.1, 94.6, 96.0, 97.1, 98.0, 98.7, 99.2, 99.5, 99.7,
99.9, 99.9, 100.0, 100.0, 100.0, 100.0, 99.9, 99.7, 99.5, 99.2, 98.7, 98.0, 97.0, 95.5, 93.7, 91.4, 88.7, 85.4,
82.1, 78.6, 74.7, 71.0, 67.2, 63.0, 59.2
])
assert_array_almost_equal(real, generated)


def test_noaa_mf():
generated = noaa_mf(levels, lowest, highest)
real = np.array([
10.1, 13.5, 16.6, 19.7, 22.9, 26.2, 29.3, 32.6, 35.9, 39.0, 42.1, 45.5, 48.6, 51.7, 54.9, 58.2, 61.3, 64.5,
67.8, 70.9, 73.9, 77.3, 80.3, 83.2, 86.1, 88.9, 91.4, 93.7, 95.6, 97.1, 98.3, 99.2, 99.7, 100.0, 100.0, 99.8,
99.4, 98.6, 97.4, 95.9, 94.0, 91.3, 88.5
])
assert_array_almost_equal(real, generated)


def test_noaa_hf():
generated = noaa_hf(levels, lowest, highest)
real = np.array([
-6.0, -2.1, 1.3, 4.8, 8.4, 12.2, 15.7, 19.3, 23.0, 26.5, 30.0, 33.9, 37.3, 40.8, 44.4, 48.2, 51.7,
55.3, 59.0, 62.5, 65.9, 69.7, 73.1, 76.5, 79.9, 83.4, 86.4, 89.4, 92.1, 94.3, 96.2, 97.8, 98.8,
99.5, 99.9, 100.0, 99.9, 99.5, 98.7, 97.7, 96.2, 94.1, 91.7
])
assert_array_almost_equal(real, generated)


def test_noaa_pw():
generated = noaa_pw(levels, lowest, highest)
real = np.array([
57.1, 59.3, 61.2, 63.1, 65.1, 67.2, 69.2, 71.2, 73.2, 75.2, 77.1, 79.2, 81.1, 83.1, 85.0, 87.0, 88.9, 90.7,
92.5, 94.1, 95.5, 96.9, 97.9, 98.7, 99.3, 99.7, 99.9, 100.0, 99.9, 99.7, 99.3, 98.5, 97.5, 96.1, 94.3, 91.9,
89.2, 86.1, 82.6, 79.1, 75.5, 71.4, 67.6
])
assert_array_almost_equal(real, generated)


def test_noaa_ow():
generated = noaa_ow(levels, lowest, highest)
real = np.array([
25.6, 29.9, 33.8, 37.6, 41.6, 45.8, 49.6, 53.6, 57.8, 61.6, 65.4, 69.6, 73.4, 77.0, 80.7, 84.3, 87.5, 90.5,
93.1, 95.1, 96.7, 98.0, 98.9, 99.4, 99.8, 100.0, 100.0, 99.9, 99.7, 99.3, 98.7, 97.6, 96.3, 94.6, 92.4, 89.6,
86.7, 83.3, 79.6, 76.0, 72.3, 68.2, 64.4
])
assert_array_almost_equal(real, generated)


def teardown_module(weighting):
pass