sofar 1.1.4__py2.py3-none-any.whl → 1.2.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sofar/__init__.py +4 -4
- sofar/io.py +18 -10
- sofar/sofa.py +42 -25
- sofar/sofa_conventions/conventions/AnnotatedEmitterAudio_0.2.csv +46 -0
- sofar/sofa_conventions/conventions/AnnotatedEmitterAudio_0.2.json +353 -0
- sofar/sofa_conventions/conventions/AnnotatedReceiverAudio_0.2.csv +46 -0
- sofar/sofa_conventions/conventions/AnnotatedReceiverAudio_0.2.json +353 -0
- sofar/sofa_conventions/conventions/deprecated/AnnotatedEmitterAudio_0.1.csv +46 -0
- sofar/sofa_conventions/conventions/deprecated/AnnotatedEmitterAudio_0.1.json +351 -0
- sofar/sofa_conventions/conventions/deprecated/AnnotatedReceiverAudio_0.1.csv +46 -0
- sofar/sofa_conventions/conventions/deprecated/AnnotatedReceiverAudio_0.1.json +351 -0
- sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.1.csv +47 -0
- sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.1.json +366 -0
- sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.2.csv +51 -0
- sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.2.json +397 -0
- sofar/sofa_conventions/rules/deprecations.json +2 -1
- sofar/sofa_conventions/rules/rules.json +21 -2
- sofar/sofa_conventions/rules/upgrade.json +36 -0
- sofar/sofastream.py +296 -0
- sofar/update_conventions.py +108 -85
- sofar/utils.py +1 -1
- {sofar-1.1.4.dist-info → sofar-1.2.0.dist-info}/LICENSE +4 -1
- sofar-1.2.0.dist-info/METADATA +93 -0
- {sofar-1.1.4.dist-info → sofar-1.2.0.dist-info}/RECORD +34 -19
- {sofar-1.1.4.dist-info → sofar-1.2.0.dist-info}/WHEEL +1 -1
- tests/conftest.py +27 -0
- tests/test_io.py +9 -5
- tests/test_sofa.py +1 -1
- tests/test_sofa_upgrade_conventions.py +10 -1
- tests/test_sofa_verify.py +1 -1
- tests/test_sofastream.py +126 -0
- tests/test_utils.py +18 -8
- sofar-1.1.4.dist-info/METADATA +0 -91
- {sofar-1.1.4.dist-info → sofar-1.2.0.dist-info}/AUTHORS.rst +0 -0
- {sofar-1.1.4.dist-info → sofar-1.2.0.dist-info}/top_level.txt +0 -0
@@ -1,9 +1,14 @@
|
|
1
|
-
sofar/__init__.py,sha256=
|
2
|
-
sofar/io.py,sha256=
|
3
|
-
sofar/sofa.py,sha256=
|
4
|
-
sofar/
|
5
|
-
sofar/
|
1
|
+
sofar/__init__.py,sha256=nhW1fJLKRZkqICK1YYBXF8P3iUsYxMF_511AQbl7DD4,619
|
2
|
+
sofar/io.py,sha256=6IYxnVXaaZ__c5nswbG1zcoCYlyCordvFlAff0vNSH0,16055
|
3
|
+
sofar/sofa.py,sha256=Yv79CuDjy3P-_INE9GHSWsSpaLt6dQx8FnypmgD-gbU,69152
|
4
|
+
sofar/sofastream.py,sha256=4aJ4U3RWE-tW7ORPXY9nmWnCXHQyFmmNMtcAfzhF-8s,9893
|
5
|
+
sofar/update_conventions.py,sha256=sw-RZp9wkeh_-b93dHVdo-1WXuR984azVByf3I-gKU4,17981
|
6
|
+
sofar/utils.py,sha256=T0IZ5RTsOEHHooNwoWAE_r-rA_tU6mCfHog9wGqxDXU,10755
|
6
7
|
sofar/sofa_conventions/VERSION,sha256=IuQRql5P3qfPUQuJwuh-RX5TvI_Wd4bDdSm8VLNQqds,34
|
8
|
+
sofar/sofa_conventions/conventions/AnnotatedEmitterAudio_0.2.csv,sha256=q1fOy9QqskNjsV2b-rn9GDTThOo-AUKGORMmXSgp83w,2348
|
9
|
+
sofar/sofa_conventions/conventions/AnnotatedEmitterAudio_0.2.json,sha256=lznoLbG6HYvPAZ-alVoWgfBXHFDeMb0PNnyOWoag3-Y,8420
|
10
|
+
sofar/sofa_conventions/conventions/AnnotatedReceiverAudio_0.2.csv,sha256=MHBEkaSfiHm-d-8EAqL40M-0wt8couJfO2Q-Ff4SoEs,2360
|
11
|
+
sofar/sofa_conventions/conventions/AnnotatedReceiverAudio_0.2.json,sha256=2Wf1XgP4BNhI1lNlgnFabX6mUC2pT0IGLW92mjY82hY,8432
|
7
12
|
sofar/sofa_conventions/conventions/FreeFieldDirectivityTF_1.1.csv,sha256=Wait37FTh6ROKgpX7-JsVM-ohtKfsdHjxVL5vN7uTTs,5510
|
8
13
|
sofar/sofa_conventions/conventions/FreeFieldDirectivityTF_1.1.json,sha256=sm8Pj_Z1n1tW2jYlu00eikR3yCcANEm_Kw5Eq9jrbw4,13138
|
9
14
|
sofar/sofa_conventions/conventions/FreeFieldHRIR_1.0.csv,sha256=C_fc7wHjBLc2krPja33sQaDSZDvlr80GSsgOj904GBY,2479
|
@@ -36,6 +41,10 @@ sofar/sofa_conventions/conventions/SingleRoomMIMOSRIR_1.0.csv,sha256=2OzG5t9rYzD
|
|
36
41
|
sofar/sofa_conventions/conventions/SingleRoomMIMOSRIR_1.0.json,sha256=5tjPriXZk8WEIr15i41L7hQRwAxzw_gA0nxWkZfe_7g,14346
|
37
42
|
sofar/sofa_conventions/conventions/SingleRoomSRIR_1.0.csv,sha256=l7aeLNxbOyXgfQIjCo3QzpRpBonMp9ssfhps4fejHxc,4199
|
38
43
|
sofar/sofa_conventions/conventions/SingleRoomSRIR_1.0.json,sha256=gVwyzGni9e3w5wehnxe6Oe5knO2Np5doHYLzRsfrlfc,14491
|
44
|
+
sofar/sofa_conventions/conventions/deprecated/AnnotatedEmitterAudio_0.1.csv,sha256=pHwICgmCtMNdGBHPItuydYuX32myAEqCWtGSKBJR8_s,2355
|
45
|
+
sofar/sofa_conventions/conventions/deprecated/AnnotatedEmitterAudio_0.1.json,sha256=p-WppnTuOaEFj0WlKxiM47H92pmHkIFZ9jX6TV0iLQE,8403
|
46
|
+
sofar/sofa_conventions/conventions/deprecated/AnnotatedReceiverAudio_0.1.csv,sha256=A8doF2goKhvf1QumQOx-k_MsZKVJRHZiRbYCAXjxrTI,2367
|
47
|
+
sofar/sofa_conventions/conventions/deprecated/AnnotatedReceiverAudio_0.1.json,sha256=dzSUPEqXT0BG0TeTa7r4zZJS01le1dJTdftBOgUXV18,8415
|
39
48
|
sofar/sofa_conventions/conventions/deprecated/FreeFieldDirectivityTF_1.0.csv,sha256=Ha6178_LxRod-L2UcI7SX3o6Cf1YRFs1zgIpn0kd0rA,5125
|
40
49
|
sofar/sofa_conventions/conventions/deprecated/FreeFieldDirectivityTF_1.0.json,sha256=GcOb3cbv63C7S4cJ7IVvU7NAAd1h8mA7RHaAFQ_jqz8,12627
|
41
50
|
sofar/sofa_conventions/conventions/deprecated/GeneralFIRE_1.0.csv,sha256=2_ed7Y0CGJmCx9V3X7L4gipJ94nLzH7Jl9fXXtI7rLQ,1988
|
@@ -56,20 +65,26 @@ sofar/sofa_conventions/conventions/deprecated/SingleRoomDRIR_0.2.csv,sha256=JsPE
|
|
56
65
|
sofar/sofa_conventions/conventions/deprecated/SingleRoomDRIR_0.2.json,sha256=oR-qubagKs28ICI7243Ep2zX0AFn_8lvYPNPseg16O8,8097
|
57
66
|
sofar/sofa_conventions/conventions/deprecated/SingleRoomDRIR_0.3.csv,sha256=l6PAKjsNuaFHVUlT4rVdZY9Pj7nh_jF8d82i5YSbkss,1999
|
58
67
|
sofar/sofa_conventions/conventions/deprecated/SingleRoomDRIR_0.3.json,sha256=ccCvFNWYwATIRCPxQke73ckogc2Y3hBP97_JOtPusns,8097
|
59
|
-
sofar/sofa_conventions/
|
60
|
-
sofar/sofa_conventions/
|
68
|
+
sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.1.csv,sha256=Vjx7u0MaYsUFbzKPKgAWxeT9iqqNC5gF_P6RqG-dd78,2397
|
69
|
+
sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.1.json,sha256=XE2ai8ybHxzrWKDUooE7LpBoiFS3pf-5RiG17Jy08E0,8650
|
70
|
+
sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.2.csv,sha256=svRCzuJl_wR8Y1LUS7O_N1KkWtxTB8lrhQXBi7uif60,2727
|
71
|
+
sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.2.json,sha256=g64b-uuzPlm_nXvoRgMxcydDTq5LSsX3mmeFN-tl6-w,9531
|
72
|
+
sofar/sofa_conventions/rules/deprecations.json,sha256=adYMivYOicwuAUFAsoiDcGHdhre5ZqNOhIe9BX2mM7M,534
|
73
|
+
sofar/sofa_conventions/rules/rules.json,sha256=45fbAzUczWYSpZZj7A15psx2Rh77xz56eT2CagKrwts,23096
|
61
74
|
sofar/sofa_conventions/rules/unit_aliases.json,sha256=QXgOfpe8bnmUybVhSSj3nIUYw50CAVehh7sdFNPFl0k,212
|
62
|
-
sofar/sofa_conventions/rules/upgrade.json,sha256=
|
75
|
+
sofar/sofa_conventions/rules/upgrade.json,sha256=0o9sTQELnEUXl_teZLjO1Azx7yqrTHmYzT8_7VB9LtM,6025
|
63
76
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
77
|
+
tests/conftest.py,sha256=3J_BsyJ-_L5145UY_17pb56AptLZr62QFt-zhzE0OE8,738
|
64
78
|
tests/test_deprecations.py,sha256=coHOEq5XUquYxRge8XKeg005M84wcgSHTEE--CoEar4,584
|
65
|
-
tests/test_io.py,sha256=
|
66
|
-
tests/test_sofa.py,sha256=
|
67
|
-
tests/test_sofa_upgrade_conventions.py,sha256=
|
68
|
-
tests/test_sofa_verify.py,sha256=
|
69
|
-
tests/
|
70
|
-
|
71
|
-
sofar-1.
|
72
|
-
sofar-1.
|
73
|
-
sofar-1.
|
74
|
-
sofar-1.
|
75
|
-
sofar-1.
|
79
|
+
tests/test_io.py,sha256=ndXn3IYFzs8OZDbeFkSBSFy7411PYwDsChPnS5zlZdE,12014
|
80
|
+
tests/test_sofa.py,sha256=lYHVwJFnAD5qqIHkHk84ErAa2ZXblhNPgKnLjAIcw3M,11315
|
81
|
+
tests/test_sofa_upgrade_conventions.py,sha256=hveRnbmPpWFYUSuAmhbRRL5ixbNLN4XoVMAPM6D2aA0,3725
|
82
|
+
tests/test_sofa_verify.py,sha256=5eQivsNoJh3oXwMud61egbsLBvPorFp739kPSwJU-U0,15835
|
83
|
+
tests/test_sofastream.py,sha256=HWbYrWktONIttFzoKC8n3DGkeUocdq5qf1XDbrv-B2k,3865
|
84
|
+
tests/test_utils.py,sha256=afzboGH-gUxc3tUb4yKRzH-y60bDHTqNZnco6Can4yE,8814
|
85
|
+
sofar-1.2.0.dist-info/AUTHORS.rst,sha256=JGcf9PJwl0w14PgTRjI3HXpcwDbkGbUN4mkYoZ8smL8,164
|
86
|
+
sofar-1.2.0.dist-info/LICENSE,sha256=OOdX8H69BDppTN8KCBp8l2_yDbH6sW-YuSEKDgZPuL4,1079
|
87
|
+
sofar-1.2.0.dist-info/METADATA,sha256=J5XgYBeTxVURL4SIvzUlBjdFrUvbLAdKs83_86RUs18,4086
|
88
|
+
sofar-1.2.0.dist-info/WHEEL,sha256=qUzzGenXXuJTzyjFah76kDVqDvnk-YDzY00svnrl84w,109
|
89
|
+
sofar-1.2.0.dist-info/top_level.txt,sha256=2JSMmeQ5zeMumFynTJU1oODh09wxSiN3gFpsY-bNsSo,12
|
90
|
+
sofar-1.2.0.dist-info/RECORD,,
|
tests/conftest.py
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
import pytest
|
2
|
+
import numpy as np
|
3
|
+
import sofar as sf
|
4
|
+
|
5
|
+
|
6
|
+
# Temporary SOFA-file
|
7
|
+
@pytest.fixture
|
8
|
+
def temp_sofa_file(tmp_path_factory):
|
9
|
+
"""
|
10
|
+
Temporary small SOFA file.
|
11
|
+
To be used when data needs to be read from a SOFA file for testing.
|
12
|
+
Contains custom data for "Data_IR", "GLOBAL_RoomType" and
|
13
|
+
"Data_SamplingRate_Units".
|
14
|
+
|
15
|
+
Returns
|
16
|
+
-------
|
17
|
+
filename : SOFA file
|
18
|
+
Filename of temporary SOFA file
|
19
|
+
"""
|
20
|
+
|
21
|
+
filename = tmp_path_factory.mktemp("data") / "test_sofastream.sofa"
|
22
|
+
sofa = sf.Sofa("SimpleFreeFieldHRIR")
|
23
|
+
sofa.Data_IR = np.array([[0, 1], [2, 3], [4, 5]])
|
24
|
+
sofa.GLOBAL_RoomType = "free field"
|
25
|
+
sofa.Data_SamplingRate_Units = "hertz"
|
26
|
+
sf.write_sofa(filename, sofa)
|
27
|
+
return filename
|
tests/test_io.py
CHANGED
@@ -13,6 +13,7 @@ from pytest import raises
|
|
13
13
|
import numpy as np
|
14
14
|
import numpy.testing as npt
|
15
15
|
from netCDF4 import Dataset
|
16
|
+
from packaging.version import parse
|
16
17
|
|
17
18
|
|
18
19
|
def test_read_write_sofa(capfd):
|
@@ -165,11 +166,14 @@ def test_roundtrip(mandatory):
|
|
165
166
|
for name, version in names_versions:
|
166
167
|
print(f"Testing: {name} {version}")
|
167
168
|
|
168
|
-
|
169
|
-
|
169
|
+
# writing deprecated and proposed conventions is not tested
|
170
|
+
if name in deprecations["GLOBAL:SOFAConventions"] or \
|
171
|
+
parse(version) < parse('1.0'):
|
170
172
|
sofa = sf.Sofa(name, mandatory, version, verify=False)
|
171
|
-
|
172
|
-
|
173
|
+
# non stable conventions are not verified
|
174
|
+
if parse(version) >= parse('1.0'):
|
175
|
+
with pytest.warns(UserWarning, match="deprecations"):
|
176
|
+
sofa.verify(mode="read")
|
173
177
|
else:
|
174
178
|
# test full round-trip for other conventions
|
175
179
|
file = os.path.join(temp_dir.name, name + ".sofa")
|
@@ -182,7 +186,7 @@ def test_roundtrip(mandatory):
|
|
182
186
|
|
183
187
|
def test_roundtrip_multidimensional_string_variable():
|
184
188
|
"""
|
185
|
-
Test writing and reading multidimensional string variables (
|
189
|
+
Test writing and reading multidimensional string variables (Writing
|
186
190
|
string variables with one dimension is done in the other roundtrip test).
|
187
191
|
"""
|
188
192
|
|
tests/test_sofa.py
CHANGED
@@ -252,7 +252,7 @@ def test_add_entry():
|
|
252
252
|
# variable without dimensions
|
253
253
|
with raises(ValueError, match="dimensions must be provided"):
|
254
254
|
sofa.add_variable("TemperatureCelsius", 25.1, "double", None)
|
255
|
-
# invalid
|
255
|
+
# invalid dimensions
|
256
256
|
with pytest.warns(UserWarning, match="Added custom dimension T"):
|
257
257
|
sofa.add_variable("TemperatureCelsius", [25.1, 25.2], "double", "T")
|
258
258
|
# attribute with missing variable
|
@@ -85,10 +85,15 @@ def test_upgrade_conventions(path, capfd):
|
|
85
85
|
out, _ = capfd.readouterr()
|
86
86
|
|
87
87
|
# don't verify conventions that might require user action after
|
88
|
-
if os.path.basename(path) in [
|
88
|
+
if os.path.basename(path) in [
|
89
|
+
"FreeFieldDirectivityTF_1.0.json",
|
90
|
+
"SingleTrackedAudio_0.1.json",
|
91
|
+
"SingleTrackedAudio_0.2.json"]:
|
89
92
|
# FreeFieldDirectivityTF_1.0
|
90
93
|
# - optional dependency GLOBAL_EmitterDescription
|
91
94
|
# might need to be added
|
95
|
+
# SingleTrackedAudio_0.x
|
96
|
+
# - can be updated to multiple conventions depending on the content
|
92
97
|
verify = False
|
93
98
|
else:
|
94
99
|
verify = True
|
@@ -98,5 +103,9 @@ def test_upgrade_conventions(path, capfd):
|
|
98
103
|
sofa.upgrade_convention(target, verify=verify)
|
99
104
|
out, _ = capfd.readouterr()
|
100
105
|
assert "Upgrading" in out
|
106
|
+
elif deprecated:
|
107
|
+
sofa.upgrade_convention()
|
108
|
+
out, _ = capfd.readouterr()
|
109
|
+
assert "is missing upgrade rules" in out
|
101
110
|
else:
|
102
111
|
assert not deprecated
|
tests/test_sofa_verify.py
CHANGED
@@ -11,7 +11,7 @@ import warnings
|
|
11
11
|
# get verification rules
|
12
12
|
_, unit_aliases, _, _ = sf.Sofa._verification_rules()
|
13
13
|
|
14
|
-
# directory containing the
|
14
|
+
# directory containing the verification data
|
15
15
|
basedir = os.path.join(os.path.dirname(__file__), "..", "sofar",
|
16
16
|
"sofa_conventions", "data")
|
17
17
|
|
tests/test_sofastream.py
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
from sofar import SofaStream
|
2
|
+
from tempfile import TemporaryDirectory
|
3
|
+
from pytest import raises
|
4
|
+
import netCDF4
|
5
|
+
import numpy as np
|
6
|
+
import os
|
7
|
+
import sofar as sf
|
8
|
+
|
9
|
+
|
10
|
+
def test_sofastream_output(temp_sofa_file):
|
11
|
+
|
12
|
+
with SofaStream(temp_sofa_file) as file:
|
13
|
+
obj = file
|
14
|
+
var = file.Data_IR
|
15
|
+
var_data = var[:]
|
16
|
+
var_attr = file.Data_SamplingRate_Units
|
17
|
+
att_data = file.GLOBAL_RoomType
|
18
|
+
|
19
|
+
# check SofaStream instance
|
20
|
+
isinstance(obj, SofaStream)
|
21
|
+
# check returned variable type
|
22
|
+
isinstance(var, netCDF4._netCDF4.Variable)
|
23
|
+
# variable values
|
24
|
+
isinstance(var_data, np.ma.core.MaskedArray)
|
25
|
+
np.testing.assert_array_equal(var_data.squeeze(),
|
26
|
+
np.array([[0, 1], [2, 3], [4, 5]]))
|
27
|
+
assert var_attr == 'hertz'
|
28
|
+
# attribute values
|
29
|
+
isinstance(att_data, str)
|
30
|
+
assert att_data == "free field"
|
31
|
+
|
32
|
+
|
33
|
+
def test_sofastream_attribute_error(temp_sofa_file):
|
34
|
+
|
35
|
+
with SofaStream(temp_sofa_file) as file:
|
36
|
+
with raises(AttributeError,
|
37
|
+
match="Wrong_Attribute is not contained in SOFA-file"):
|
38
|
+
file.Wrong_Attribute
|
39
|
+
|
40
|
+
|
41
|
+
def test_sofastream_inspect(capfd, temp_sofa_file):
|
42
|
+
|
43
|
+
tempdir = TemporaryDirectory()
|
44
|
+
inspect_file = os.path.join(tempdir.name, "info.txt")
|
45
|
+
|
46
|
+
with SofaStream(temp_sofa_file) as file:
|
47
|
+
file.inspect(inspect_file)
|
48
|
+
out, _ = capfd.readouterr()
|
49
|
+
|
50
|
+
sofa = sf.read_sofa(temp_sofa_file)
|
51
|
+
sofa.inspect()
|
52
|
+
out_sofa, _ = capfd.readouterr()
|
53
|
+
|
54
|
+
assert out_sofa == out
|
55
|
+
|
56
|
+
# check text file
|
57
|
+
with open(inspect_file, "r") as out_inspect:
|
58
|
+
text = out_inspect.readlines()
|
59
|
+
assert out == "".join(text)
|
60
|
+
|
61
|
+
|
62
|
+
def test_list_dimensions(capfd, tmp_path_factory):
|
63
|
+
|
64
|
+
filename = tmp_path_factory.mktemp("data") / "test_sofastream_dim.sofa"
|
65
|
+
|
66
|
+
# test FIR Data
|
67
|
+
sofa = sf.Sofa("GeneralFIR")
|
68
|
+
sf.write_sofa(filename, sofa)
|
69
|
+
with SofaStream(filename) as file:
|
70
|
+
file.list_dimensions
|
71
|
+
out, _ = capfd.readouterr()
|
72
|
+
assert "N = 1 samples" in out
|
73
|
+
|
74
|
+
# test TF Data
|
75
|
+
sofa = sf.Sofa("GeneralTF")
|
76
|
+
sf.write_sofa(filename, sofa)
|
77
|
+
with SofaStream(filename) as file:
|
78
|
+
file.list_dimensions
|
79
|
+
out, _ = capfd.readouterr()
|
80
|
+
assert "N = 1 frequencies" in out
|
81
|
+
|
82
|
+
# test SOS Data
|
83
|
+
sofa = sf.Sofa("SimpleFreeFieldHRSOS")
|
84
|
+
sf.write_sofa(filename, sofa)
|
85
|
+
with SofaStream(filename) as file:
|
86
|
+
file.list_dimensions
|
87
|
+
out, _ = capfd.readouterr()
|
88
|
+
assert "N = 6 SOS coefficients" in out
|
89
|
+
|
90
|
+
# test non spherical harmonics data
|
91
|
+
sofa = sf.Sofa("GeneralFIR")
|
92
|
+
sf.write_sofa(filename, sofa)
|
93
|
+
with SofaStream(filename) as file:
|
94
|
+
file.list_dimensions
|
95
|
+
out, _ = capfd.readouterr()
|
96
|
+
assert "E = 1 emitter" in out
|
97
|
+
assert "R = 1 receiver" in out
|
98
|
+
|
99
|
+
# test spherical harmonics data
|
100
|
+
sofa.EmitterPosition_Type = "spherical harmonics"
|
101
|
+
sofa.ReceiverPosition_Type = "spherical harmonics"
|
102
|
+
sofa.EmitterPosition_Units = "degree, degree, metre"
|
103
|
+
sofa.ReceiverPosition_Units = "degree, degree, metre"
|
104
|
+
sf.write_sofa(filename, sofa)
|
105
|
+
with SofaStream(filename) as file:
|
106
|
+
file.list_dimensions
|
107
|
+
out, _ = capfd.readouterr()
|
108
|
+
assert "E = 1 emitter spherical harmonics coefficients" in out
|
109
|
+
assert "R = 1 receiver spherical harmonics coefficients" in out
|
110
|
+
|
111
|
+
|
112
|
+
def test_get_dimensions(tmp_path_factory):
|
113
|
+
"""Test getting the size of dimensions"""
|
114
|
+
filename = tmp_path_factory.mktemp("data") / "test_sofastream_dim.sofa"
|
115
|
+
|
116
|
+
# test FIR Data
|
117
|
+
sofa = sf.Sofa("GeneralFIR")
|
118
|
+
sf.write_sofa(filename, sofa)
|
119
|
+
|
120
|
+
with SofaStream(filename) as file:
|
121
|
+
size = file.get_dimension('N')
|
122
|
+
assert size == 1
|
123
|
+
|
124
|
+
# test wrong dimension error
|
125
|
+
with raises(ValueError, match="Q is not a valid dimension"):
|
126
|
+
file.get_dimension("Q")
|
tests/test_utils.py
CHANGED
@@ -98,22 +98,32 @@ def test_update_conventions(capfd):
|
|
98
98
|
# first run to test if conventions were updated
|
99
99
|
sf.update_conventions(conventions_path=work_dir, assume_yes=True)
|
100
100
|
out, _ = capfd.readouterr()
|
101
|
-
assert "
|
102
|
-
assert "
|
103
|
-
assert "
|
101
|
+
assert "add convention: GeneralTF_2.0" in out
|
102
|
+
assert os.path.isfile(os.path.join(work_dir, "GeneralTF_2.0.csv"))
|
103
|
+
assert "update convention: GeneralFIR_1.0" in out
|
104
|
+
assert "deprecate convention: MultiSpeakerBRIR_0.3" in out
|
104
105
|
assert not os.path.isfile(
|
105
106
|
os.path.join(work_dir, "MultiSpeakerBRIR_0.3.csv"))
|
106
107
|
assert not os.path.isfile(
|
107
108
|
os.path.join(work_dir, "MultiSpeakerBRIR_0.3.json"))
|
108
|
-
assert
|
109
|
-
|
109
|
+
assert os.path.isfile(
|
110
|
+
os.path.join(work_dir, "deprecated", "MultiSpeakerBRIR_0.3.csv"))
|
111
|
+
assert os.path.isfile(
|
112
|
+
os.path.join(work_dir, "deprecated", "MultiSpeakerBRIR_0.3.json"))
|
113
|
+
assert "update deprecated convention: SimpleFreeFieldHRIR_0.4" in out
|
114
|
+
assert "add deprecated convention: SimpleFreeFieldTF_0.4" in out
|
115
|
+
assert os.path.isfile(
|
116
|
+
os.path.join(work_dir, "deprecated", "SimpleFreeFieldTF_0.4.csv"))
|
117
|
+
assert os.path.isfile(
|
118
|
+
os.path.join(work_dir, "deprecated", "SimpleFreeFieldTF_0.4.json"))
|
110
119
|
|
111
120
|
# second run to make sure that up to date conventions are not overwritten
|
112
121
|
sf.update_conventions(conventions_path=work_dir, assume_yes=True)
|
113
122
|
out, _ = capfd.readouterr()
|
114
|
-
assert "
|
115
|
-
assert "
|
116
|
-
assert "
|
123
|
+
assert "add" not in out
|
124
|
+
assert "update" not in out
|
125
|
+
assert "deprecate" not in out
|
126
|
+
assert "already up to date" in out
|
117
127
|
|
118
128
|
|
119
129
|
def test__compile_conventions():
|
sofar-1.1.4.dist-info/METADATA
DELETED
@@ -1,91 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: sofar
|
3
|
-
Version: 1.1.4
|
4
|
-
Summary: Maybe the most complete python package for SOFA files so far
|
5
|
-
Home-page: https://pyfar.org/
|
6
|
-
Download-URL: https://pypi.org/project/sofar/
|
7
|
-
Author: The pyfar developers
|
8
|
-
Author-email: info@pyfar.org
|
9
|
-
License: MIT license
|
10
|
-
Project-URL: Bug Tracker, https://github.com/pyfar/sofar/issues
|
11
|
-
Project-URL: Documentation, https://sofar.readthedocs.io/
|
12
|
-
Project-URL: Source Code, https://github.com/pyfar/sofar
|
13
|
-
Keywords: sofar
|
14
|
-
Classifier: Development Status :: 4 - Beta
|
15
|
-
Classifier: Intended Audience :: Science/Research
|
16
|
-
Classifier: License :: OSI Approved :: MIT License
|
17
|
-
Classifier: Natural Language :: English
|
18
|
-
Classifier: Programming Language :: Python :: 3
|
19
|
-
Classifier: Programming Language :: Python :: 3.8
|
20
|
-
Classifier: Programming Language :: Python :: 3.9
|
21
|
-
Classifier: Programming Language :: Python :: 3.10
|
22
|
-
Classifier: Programming Language :: Python :: 3.11
|
23
|
-
Classifier: Programming Language :: Python :: 3.12
|
24
|
-
Requires-Python: >=3.8
|
25
|
-
License-File: LICENSE
|
26
|
-
License-File: AUTHORS.rst
|
27
|
-
Requires-Dist: netCDF4
|
28
|
-
Requires-Dist: numpy >=1.14.0
|
29
|
-
Requires-Dist: beautifulsoup4
|
30
|
-
Requires-Dist: requests
|
31
|
-
Requires-Dist: packaging
|
32
|
-
|
33
|
-
======
|
34
|
-
Readme
|
35
|
-
======
|
36
|
-
|
37
|
-
Sofar is maybe the most complete Python package for the SOFA file format so
|
38
|
-
far. SOFA files store spatially distributed acoustic data such as impulse
|
39
|
-
responses or transfer functions. They are defined by the AES69-2022 standard
|
40
|
-
(see references). These are the key features of sofar
|
41
|
-
|
42
|
-
* Uses a complete definition of the AES69-2022 standard (see references) maintained at `sofa_conventions`_
|
43
|
-
* Read, edit, and write SOFA files
|
44
|
-
* Add custom attributes to SOFA files
|
45
|
-
* Full Verification of the content of a SOFA files against AES69-2022
|
46
|
-
* Upgrade data that uses outdated SOFA conventions
|
47
|
-
* Open license allows unrestricted use
|
48
|
-
* sofar is tested using continuous integration on
|
49
|
-
|
50
|
-
Installation
|
51
|
-
============
|
52
|
-
|
53
|
-
Use pip to install sofar
|
54
|
-
|
55
|
-
.. code-block:: console
|
56
|
-
|
57
|
-
$ pip install sofar
|
58
|
-
|
59
|
-
(Requires Python >= 3.8)
|
60
|
-
|
61
|
-
Getting Started
|
62
|
-
===============
|
63
|
-
|
64
|
-
Check out `read the docs`_ for example use cases a quick introduction to SOFA
|
65
|
-
and sofar, and the complete documentation. A more detailed introduction to SOFA
|
66
|
-
is given by Majdak et. al. 2022 (see references below) Packages related to
|
67
|
-
sofar are listed at `pyfar.org`_. For more information on the SOFA file format
|
68
|
-
visit `sofaconventions.org`_.
|
69
|
-
|
70
|
-
Contributing
|
71
|
-
============
|
72
|
-
|
73
|
-
Refer to the `contribution guidelines`_ for more information.
|
74
|
-
|
75
|
-
.. _sofa_conventions : https://github.com/pyfar/sofa_conventions
|
76
|
-
.. _contribution guidelines: https://github.com/pyfar/sofar/blob/develop/CONTRIBUTING.rst
|
77
|
-
.. _pyfar.org: https://pyfar.org
|
78
|
-
.. _read the docs: https://sofar.readthedocs.io/en/stable
|
79
|
-
.. _sofaconventions.org: https://sofaconventions.org
|
80
|
-
|
81
|
-
References
|
82
|
-
==========
|
83
|
-
|
84
|
-
AES69-2022: *AES standard for file exchange - Spatial acoustic data file
|
85
|
-
format*, Audio Engineering Society, Inc., New York, NY, USA.
|
86
|
-
(https://www.aes.org/publications/standards/search.cfm?docID=99)
|
87
|
-
|
88
|
-
P. Majdak, F. Zotter, F. Brinkmann, J. De Muynke, M. Mihocic, and M.
|
89
|
-
Noisternig, "Spatially Oriented Format for Acoustics 2.1: Introduction and
|
90
|
-
Recent Advances", *J. Audio Eng. Soc.*, vol. 70, no. 7/8, pp. 565-584,
|
91
|
-
Jul. 2022. DOI: https://doi.org/10.17743/jaes.2022.0026
|
File without changes
|
File without changes
|