sofar 1.1.3__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.
Files changed (35) hide show
  1. sofar/__init__.py +4 -4
  2. sofar/io.py +18 -10
  3. sofar/sofa.py +53 -37
  4. sofar/sofa_conventions/conventions/AnnotatedEmitterAudio_0.2.csv +46 -0
  5. sofar/sofa_conventions/conventions/AnnotatedEmitterAudio_0.2.json +353 -0
  6. sofar/sofa_conventions/conventions/AnnotatedReceiverAudio_0.2.csv +46 -0
  7. sofar/sofa_conventions/conventions/AnnotatedReceiverAudio_0.2.json +353 -0
  8. sofar/sofa_conventions/conventions/deprecated/AnnotatedEmitterAudio_0.1.csv +46 -0
  9. sofar/sofa_conventions/conventions/deprecated/AnnotatedEmitterAudio_0.1.json +351 -0
  10. sofar/sofa_conventions/conventions/deprecated/AnnotatedReceiverAudio_0.1.csv +46 -0
  11. sofar/sofa_conventions/conventions/deprecated/AnnotatedReceiverAudio_0.1.json +351 -0
  12. sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.1.csv +47 -0
  13. sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.1.json +366 -0
  14. sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.2.csv +51 -0
  15. sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.2.json +397 -0
  16. sofar/sofa_conventions/rules/deprecations.json +2 -1
  17. sofar/sofa_conventions/rules/rules.json +21 -2
  18. sofar/sofa_conventions/rules/upgrade.json +36 -0
  19. sofar/sofastream.py +296 -0
  20. sofar/update_conventions.py +112 -92
  21. sofar/utils.py +1 -1
  22. {sofar-1.1.3.dist-info → sofar-1.2.0.dist-info}/LICENSE +4 -1
  23. sofar-1.2.0.dist-info/METADATA +93 -0
  24. {sofar-1.1.3.dist-info → sofar-1.2.0.dist-info}/RECORD +34 -19
  25. {sofar-1.1.3.dist-info → sofar-1.2.0.dist-info}/WHEEL +1 -1
  26. tests/conftest.py +27 -0
  27. tests/test_io.py +9 -5
  28. tests/test_sofa.py +1 -1
  29. tests/test_sofa_upgrade_conventions.py +10 -1
  30. tests/test_sofa_verify.py +3 -3
  31. tests/test_sofastream.py +126 -0
  32. tests/test_utils.py +18 -8
  33. sofar-1.1.3.dist-info/METADATA +0 -91
  34. {sofar-1.1.3.dist-info → sofar-1.2.0.dist-info}/AUTHORS.rst +0 -0
  35. {sofar-1.1.3.dist-info → sofar-1.2.0.dist-info}/top_level.txt +0 -0
@@ -1,9 +1,14 @@
1
- sofar/__init__.py,sha256=AARVq-KAV2huia8cGZpzHZGUjMtJ1H1yGU_vg6RKn98,595
2
- sofar/io.py,sha256=XdkfG6jo4RI8JqUgXEfx2ka06_CfffPJXs0HqeMSri0,15761
3
- sofar/sofa.py,sha256=QVr0UKr-aqo2K7_PEHtXk9VuvrjE36QgcYIqFJ6KBrc,68255
4
- sofar/update_conventions.py,sha256=36ba0cAVtKppJCrsEhP2aiv1DGEtxNx06hsUAERDlwM,16753
5
- sofar/utils.py,sha256=0JwYLLyVu1ZcAfUQKSucywcQPlHB2Ojez7fxIXhuaFw,10754
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/rules/deprecations.json,sha256=hyq112XNfojROZsAEbcV7EOLin-xaTiNi4o4WdplS74,453
60
- sofar/sofa_conventions/rules/rules.json,sha256=iH8e5UUVRQcGZ_AoULk4A2IiAT1yK7R2CvRQyCMYhYA,22501
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=viHPPqBaPblE-fY8BOuVUraQYrBhckrS3w5XKqHCTIE,5167
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=xMBdWP3vdnk_6aYAhg30nEgGvPfYm30a1qouGHIwRNo,11808
66
- tests/test_sofa.py,sha256=DpiI517T-gLoajy9nQCHT7ouxM40JwirsqkVMFT5cWo,11314
67
- tests/test_sofa_upgrade_conventions.py,sha256=HqIuvFFub1_HCH6qHTLPcPyBZ2ayDKzmZR7RwnTxo_o,3377
68
- tests/test_sofa_verify.py,sha256=BW-j7B-81PXqTSKFa4LnkAGfUnIoc-yssuMwGt0UQTM,15830
69
- tests/test_utils.py,sha256=yT290xCaeDW4l3DHUeFGiVmLe9xMguETN1NAGRTJ-X4,8307
70
- sofar-1.1.3.dist-info/AUTHORS.rst,sha256=JGcf9PJwl0w14PgTRjI3HXpcwDbkGbUN4mkYoZ8smL8,164
71
- sofar-1.1.3.dist-info/LICENSE,sha256=qdGH_RUPveBBfGYShm6OIBd6bRJdwp3fDCpjMsowmqA,1068
72
- sofar-1.1.3.dist-info/METADATA,sha256=T7R1WvTW7qDQbXm0QiwfJntqDRDb9Z3YepqjEyEa1aw,3242
73
- sofar-1.1.3.dist-info/WHEEL,sha256=-G_t0oGuE7UD0DrSpVZnq1hHMBV9DD2XkS5v7XpmTnk,110
74
- sofar-1.1.3.dist-info/top_level.txt,sha256=2JSMmeQ5zeMumFynTJU1oODh09wxSiN3gFpsY-bNsSo,12
75
- sofar-1.1.3.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: setuptools (74.1.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any
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
- if name in deprecations["GLOBAL:SOFAConventions"]:
169
- # deprecated conventions can not be written
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
- with pytest.warns(UserWarning, match="deprecations"):
172
- sofa.verify(mode="read")
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 (Wringting
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 dimensins
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 ["FreeFieldDirectivityTF_1.0.json"]:
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 verificatin data
14
+ # directory containing the verification data
15
15
  basedir = os.path.join(os.path.dirname(__file__), "..", "sofar",
16
16
  "sofa_conventions", "data")
17
17
 
@@ -192,11 +192,11 @@ def test_data_types(capfd):
192
192
  sofa.verify()
193
193
 
194
194
  sofa.Data_IR = "1"
195
- with raises(ValueError, match="- Data_IR must be int, float"):
195
+ with raises(ValueError, match="- Data_IR must be int or float"):
196
196
  sofa.verify()
197
197
 
198
198
  sofa.Data_IR = 1+1j
199
- with raises(ValueError, match="- Data_IR must be int, float"):
199
+ with raises(ValueError, match="- Data_IR must be int or float"):
200
200
  sofa.verify()
201
201
 
202
202
  # test invalid data with issue_handling "print" and "return"
@@ -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 "added convention: GeneralTF_2.0" in out
102
- assert "updated convention: GeneralFIR_1.0" in out
103
- assert "deprecated convention: MultiSpeakerBRIR_0.3" in out
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 "updated deprecated convention: SimpleFreeFieldHRIR_0.4" in out
109
- assert "added deprecated convention: SimpleFreeFieldTF_0.4" in out
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 "added" not in out
115
- assert "updated" not in out
116
- assert "deprecated" not in out
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():
@@ -1,91 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: sofar
3
- Version: 1.1.3
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/latest
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