Repository: pyfar/pyfar (python)

Issue:
Implement true constants.
True constants such as 

- atmospheric pressure
- reference sound pressure p_0
- reference sound power W_0
- ...

can be implemented as global variables in the constants module.

Pull request:
add True constants like np.pi to pyfar.constants
closes #772:
- adds various constants used in acoustics
- needed to add it in the init file, otherwise the documentation was not possible in a docstring (no idea why) Sphinx could not do it.

we can collect more ideas for constants on pyfar.constants.

Patch:
diff --git a/docs/modules/pyfar.constants.rst b/docs/modules/pyfar.constants.rst
index d75577f0..f3823489 100644
--- a/docs/modules/pyfar.constants.rst
+++ b/docs/modules/pyfar.constants.rst
@@ -1,6 +1,21 @@
 pyfar.constants
 ===============
 
+Module for constants and physical properties of air.
+
+**Constants**:
+
+.. held in alphabetical order
+.. autodata:: pyfar.constants.absolute_zero_celsius
+.. autodata:: pyfar.constants.reference_air_density
+.. autodata:: pyfar.constants.reference_air_impedance
+.. autodata:: pyfar.constants.reference_air_temperature_celsius
+.. autodata:: pyfar.constants.reference_atmospheric_pressure
+.. autodata:: pyfar.constants.reference_sound_power
+.. autodata:: pyfar.constants.reference_sound_pressure
+.. autodata:: pyfar.constants.reference_speed_of_sound
+
+
 .. automodule:: pyfar.constants
    :members:
    :undoc-members:
diff --git a/pyfar/constants/__init__.py b/pyfar/constants/__init__.py
index 09be3565..a429abd7 100644
--- a/pyfar/constants/__init__.py
+++ b/pyfar/constants/__init__.py
@@ -1,5 +1,6 @@
-"""Module for constants and physical properties of air."""
+# Module for constants and physical properties of air.  # noqa: D104
 
+from typing import Final
 
 from .speed_of_sound import (
     speed_of_sound_simple,
@@ -8,3 +9,157 @@ from .speed_of_sound import (
 __all__ = [
     'speed_of_sound_simple',
 ]
+
+
+reference_atmospheric_pressure: Final[float] = 101325.0
+r"""
+Reference atmospheric pressure :math:`P_\text{atm}` in Pascal [#]_.
+
+.. math::
+    P_\text{atm} = 101325 \, \text{Pa}
+
+Returns
+-------
+float
+    Reference atmospheric pressure in Pascal.
+
+References
+----------
+.. [#] https://en.wikipedia.org/wiki/Atmospheric_pressure
+
+"""
+
+
+absolute_zero_celsius: Final[float] = -273.15
+r"""
+Absolute zero temperature :math:`\mathrm{t_0}` in degree Celsius [#]_.
+
+.. math::
+    t_0 = -273.15 \text{°C}
+
+Returns
+-------
+t_0 : float
+    Absolute zero temperature in degree Celsius.
+
+References
+----------
+.. [#]  https://en.wikipedia.org/wiki/Absolute_zero
+"""
+
+
+reference_sound_pressure: Final[float] = 20e-6
+r"""
+Reference sound pressure :math:`p_\text{ref}` in Pascal [#]_.
+
+.. math::
+    p_\text{ref} = 20 \, \mathrm{\mu Pa}
+
+Returns
+-------
+p_ref : float
+    Reference sound pressure in Pascal.
+
+References
+----------
+.. [#] https://asastandards.org/terms/reference-value-for-sound-pressure-2/
+
+"""
+
+reference_sound_power: Final[float] = 1e-12
+r"""
+Reference sound power :math:`P_\text{ref}` in Watt [#]_.
+
+.. math::
+    P_\text{ref} = 1 \, \text{pW} = 10^{-12} \, \text{W}
+
+Returns
+-------
+P_ref : float
+    Reference sound power in Watt.
+
+References
+----------
+.. [#] https://asastandards.org/terms/sound-power-level/
+
+"""
+
+reference_air_temperature_celsius: Final[float] = 20
+r"""
+Reference air temperature :math:`t_\text{ref}` in degree Celsius [#]_.
+
+.. math::
+    t_\text{ref} = 20 \text{°C}
+
+Returns
+-------
+t_ref : float
+    Reference air temperature in degree Celsius.
+
+References
+----------
+.. [#] ISO 9613-1:1993, Acoustics -- Attenuation of sound during
+       propagation outdoors -- Part 1: Calculation of the absorption of
+       sound by the atmosphere.
+"""
+
+reference_speed_of_sound: Final[float] = 343.2
+r"""
+Reference speed of sound :math:`c_\text{ref}` in m/s for 20°C and dry air [#]_.
+
+.. math::
+    c_\text{ref} = 343.2 \, \text{m/s}
+
+Returns
+-------
+c_ref : float
+    Reference speed of sound in m/s.
+
+References
+----------
+.. [#] ISO 9613-1:1993, Acoustics -- Attenuation of sound during
+       propagation outdoors -- Part 1: Calculation of the absorption of
+       sound by the atmosphere.
+"""
+
+
+reference_air_density: Final[float] = 1.204
+r"""
+Reference air density in :math:`\text{kg}/\text{m}^3` at reference
+atmospheric pressure and 20°C [#]_.
+
+.. math::
+
+    \rho_\text{atm} = 1.204 \, \frac{\text{kg}}{\text{m}^3}
+
+
+Returns
+-------
+float
+    Reference air density in :math:`\text{kg}/\text{m}^3`.
+
+References
+----------
+.. [#] https://en.wikipedia.org/wiki/Density_of_air
+
+"""
+
+
+reference_air_impedance: Final[float] = (
+    reference_speed_of_sound * reference_air_density)
+r"""
+Reference air impedance :math:`Z_\text{ref}` in Pa s/m is calculated based on
+:py:attr:`reference_speed_of_sound` and
+:py:attr:`standard_air_density`.
+
+.. math::
+
+    Z_\text{ref} = \rho_\text{atm} \cdot c_\text{ref} \approx 413.2
+    \, \text{Pa s/m}
+
+Returns
+-------
+Z_ref : float
+    Reference air impedance in Pa s/m.
+
+"""
diff --git a/pyfar/constants/speed_of_sound.py b/pyfar/constants/speed_of_sound.py
index c428c167..75379772 100644
--- a/pyfar/constants/speed_of_sound.py
+++ b/pyfar/constants/speed_of_sound.py
@@ -1,5 +1,6 @@
 """File containing all speed of sound calculation functions."""
 import numpy as np
+import pyfar as pf
 
 
 def speed_of_sound_simple(temperature):
@@ -11,11 +12,17 @@ def speed_of_sound_simple(temperature):
 
     .. math::
 
-        c = 343.2 \cdot \sqrt{\frac{t + 273.15}{t_0 + 273.15}} \mathrm{m/s}
+        c(t) = c_\text{ref} \cdot \sqrt{\frac{t - t_0}{t_\text{ref} - t_0}}
 
     where:
         - :math:`t` is the air temperature (°C)
-        - :math:`t_0=20\mathrm{°C}` is the reference air temperature (°C)
+        - :math:`t_\text{ref}=20\mathrm{°C}` is the reference air temperature
+          (°C), see
+          :py:attr:`reference_air_temperature_celsius`
+        - :math:`t_0=-273.15` °C is the absolute zero temperature (°C), see
+          :py:attr:`absolute_zero_celsius`
+        - :math:`c=343.2` m/s is the speed of sound at the reference
+          temperature, see :py:attr:`reference_speed_of_sound`
 
     Parameters
     ----------
@@ -41,5 +48,7 @@ def speed_of_sound_simple(temperature):
     temperature = np.array(temperature, dtype=float) if isinstance(
         temperature, list) else temperature
 
-    t_0 = 20
-    return 343.2*np.sqrt((temperature+273.15)/(t_0+273.15))
+    t_ref = pf.constants.reference_air_temperature_celsius
+    t_0 = pf.constants.absolute_zero_celsius
+    c_ref = pf.constants.reference_speed_of_sound
+    return c_ref*np.sqrt((temperature-t_0)/(t_ref-t_0))


Test patch:
diff --git a/tests/test_constants.py b/tests/test_constants.py
new file mode 100644
index 00000000..4232beb7
--- /dev/null
+++ b/tests/test_constants.py
@@ -0,0 +1,31 @@
+import pyfar as pf
+import numpy as np
+
+def test_reference_atmospheric_pressure():
+    assert pf.constants.reference_atmospheric_pressure == 101325.0
+
+def test_absolute_zero_celsius():
+    assert pf.constants.absolute_zero_celsius == -273.15
+
+def test_reference_sound_power():
+    assert pf.constants.reference_sound_power == 1e-12
+
+def test_reference_sound_pressure():
+    assert pf.constants.reference_sound_pressure == 20e-6
+
+def test_reference_air_temperature():
+    assert pf.constants.reference_air_temperature_celsius == 20
+
+def test_reference_speed_of_sound():
+    assert pf.constants.reference_speed_of_sound == 343.2
+
+def test_reference_air_density():
+    assert pf.constants.reference_air_density == 1.204
+
+def test_reference_air_impedance_approximation():
+    assert np.round(pf.constants.reference_air_impedance, 1) == 413.2
+
+def test_reference_air_impedance():
+    c_ref = pf.constants.reference_speed_of_sound
+    rho_atm = pf.constants.reference_air_density
+    assert pf.constants.reference_air_impedance == c_ref * rho_atm