sofar 1.2.1__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.
- docs/Makefile +20 -0
- docs/api_reference.rst +20 -0
- docs/conf.py +167 -0
- docs/contributing.rst +1 -0
- docs/history.rst +1 -0
- docs/index.rst +4 -0
- docs/make.bat +36 -0
- docs/readme.rst +1 -0
- docs/resources/conventions.py +162 -0
- docs/resources/working_with_sofa_HRIR_lateral.png +0 -0
- docs/resources/working_with_sofa_source_horizontal.png +0 -0
- docs/resources/working_with_sofa_source_lateral.png +0 -0
- docs/sofar.rst +82 -0
- sofar/__init__.py +28 -0
- sofar/io.py +427 -0
- sofar/sofa.py +1835 -0
- sofar/sofa_conventions/VERSION +1 -0
- 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/FreeFieldDirectivityTF_1.1.csv +59 -0
- sofar/sofa_conventions/conventions/FreeFieldDirectivityTF_1.1.json +444 -0
- sofar/sofa_conventions/conventions/FreeFieldHRIR_1.0.csv +43 -0
- sofar/sofa_conventions/conventions/FreeFieldHRIR_1.0.json +333 -0
- sofar/sofa_conventions/conventions/FreeFieldHRTF_1.0.csv +44 -0
- sofar/sofa_conventions/conventions/FreeFieldHRTF_1.0.json +340 -0
- sofar/sofa_conventions/conventions/GeneralFIR-E_2.0.csv +37 -0
- sofar/sofa_conventions/conventions/GeneralFIR-E_2.0.json +270 -0
- sofar/sofa_conventions/conventions/GeneralFIR_1.0.csv +40 -0
- sofar/sofa_conventions/conventions/GeneralFIR_1.0.json +295 -0
- sofar/sofa_conventions/conventions/GeneralSOS_1.0.csv +40 -0
- sofar/sofa_conventions/conventions/GeneralSOS_1.0.json +306 -0
- sofar/sofa_conventions/conventions/GeneralTF-E_1.0.csv +38 -0
- sofar/sofa_conventions/conventions/GeneralTF-E_1.0.json +277 -0
- sofar/sofa_conventions/conventions/GeneralTF_1.0.csv +38 -0
- sofar/sofa_conventions/conventions/GeneralTF_1.0.json +277 -0
- sofar/sofa_conventions/conventions/GeneralTF_2.0.csv +38 -0
- sofar/sofa_conventions/conventions/GeneralTF_2.0.json +277 -0
- sofar/sofa_conventions/conventions/SimpleFreeFieldHRIR_1.0.csv +47 -0
- sofar/sofa_conventions/conventions/SimpleFreeFieldHRIR_1.0.json +369 -0
- sofar/sofa_conventions/conventions/SimpleFreeFieldHRSOS_1.0.csv +43 -0
- sofar/sofa_conventions/conventions/SimpleFreeFieldHRSOS_1.0.json +349 -0
- sofar/sofa_conventions/conventions/SimpleFreeFieldHRTF_1.0.csv +44 -0
- sofar/sofa_conventions/conventions/SimpleFreeFieldHRTF_1.0.json +340 -0
- sofar/sofa_conventions/conventions/SimpleFreeFieldSOS_1.0.csv +43 -0
- sofar/sofa_conventions/conventions/SimpleFreeFieldSOS_1.0.json +349 -0
- sofar/sofa_conventions/conventions/SimpleHeadphoneIR_1.0.csv +51 -0
- sofar/sofa_conventions/conventions/SimpleHeadphoneIR_1.0.json +396 -0
- sofar/sofa_conventions/conventions/SingleRoomMIMOSRIR_1.0.csv +78 -0
- sofar/sofa_conventions/conventions/SingleRoomMIMOSRIR_1.0.json +601 -0
- sofar/sofa_conventions/conventions/SingleRoomSRIR_1.0.csv +78 -0
- sofar/sofa_conventions/conventions/SingleRoomSRIR_1.0.json +601 -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/FreeFieldDirectivityTF_1.0.csv +58 -0
- sofar/sofa_conventions/conventions/deprecated/FreeFieldDirectivityTF_1.0.json +437 -0
- sofar/sofa_conventions/conventions/deprecated/GeneralFIRE_1.0.csv +37 -0
- sofar/sofa_conventions/conventions/deprecated/GeneralFIRE_1.0.json +270 -0
- sofar/sofa_conventions/conventions/deprecated/MultiSpeakerBRIR_0.3.csv +48 -0
- sofar/sofa_conventions/conventions/deprecated/MultiSpeakerBRIR_0.3.json +376 -0
- sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldHRIR_0.4.csv +43 -0
- sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldHRIR_0.4.json +333 -0
- sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldTF_0.4.csv +44 -0
- sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldTF_0.4.json +340 -0
- sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldTF_1.0.csv +44 -0
- sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldTF_1.0.json +340 -0
- sofar/sofa_conventions/conventions/deprecated/SimpleHeadphoneIR_0.1.csv +51 -0
- sofar/sofa_conventions/conventions/deprecated/SimpleHeadphoneIR_0.1.json +396 -0
- sofar/sofa_conventions/conventions/deprecated/SimpleHeadphoneIR_0.2.csv +51 -0
- sofar/sofa_conventions/conventions/deprecated/SimpleHeadphoneIR_0.2.json +396 -0
- sofar/sofa_conventions/conventions/deprecated/SingleRoomDRIR_0.2.csv +47 -0
- sofar/sofa_conventions/conventions/deprecated/SingleRoomDRIR_0.2.json +360 -0
- sofar/sofa_conventions/conventions/deprecated/SingleRoomDRIR_0.3.csv +47 -0
- sofar/sofa_conventions/conventions/deprecated/SingleRoomDRIR_0.3.json +360 -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 +13 -0
- sofar/sofa_conventions/rules/rules.json +819 -0
- sofar/sofa_conventions/rules/unit_aliases.json +11 -0
- sofar/sofa_conventions/rules/upgrade.json +226 -0
- sofar/sofa_conventions/write_upgrade_rules.py +139 -0
- sofar/sofa_conventions/write_verification_data.py +313 -0
- sofar/sofa_conventions/write_verification_rules.py +356 -0
- sofar/sofastream.py +301 -0
- sofar/update_conventions.py +449 -0
- sofar/utils.py +316 -0
- sofar-1.2.1.dist-info/LICENSE +22 -0
- sofar-1.2.1.dist-info/METADATA +136 -0
- sofar-1.2.1.dist-info/RECORD +105 -0
- sofar-1.2.1.dist-info/WHEEL +5 -0
- sofar-1.2.1.dist-info/top_level.txt +3 -0
- tests/__init__.py +0 -0
- tests/conftest.py +27 -0
- tests/test_deprecations.py +19 -0
- tests/test_io.py +349 -0
- tests/test_sofa.py +353 -0
- tests/test_sofa_upgrade_conventions.py +111 -0
- tests/test_sofa_verify.py +480 -0
- tests/test_sofastream.py +127 -0
- tests/test_utils.py +250 -0
sofar/utils.py
ADDED
@@ -0,0 +1,316 @@
|
|
1
|
+
"""Contains util functions to work with sofar and Sofa objects."""
|
2
|
+
import os
|
3
|
+
import glob
|
4
|
+
import numpy as np
|
5
|
+
import numpy.testing as npt
|
6
|
+
import warnings
|
7
|
+
import sofar as sf
|
8
|
+
|
9
|
+
|
10
|
+
def version():
|
11
|
+
"""Return version of sofar and SOFA conventions."""
|
12
|
+
|
13
|
+
sofa_conventions = os.path.join(
|
14
|
+
os.path.dirname(__file__), "sofa_conventions", 'VERSION')
|
15
|
+
with open(sofa_conventions) as file:
|
16
|
+
sofa_conventions = file.readline().strip()
|
17
|
+
|
18
|
+
return (f"sofar v{sf.__version__} implementing "
|
19
|
+
f"SOFA standard {sofa_conventions}")
|
20
|
+
|
21
|
+
|
22
|
+
def _verify_convention_and_version(version, convention):
|
23
|
+
"""
|
24
|
+
Verify if convention and version exist. Raise a Value error if it does not.
|
25
|
+
|
26
|
+
Parameters
|
27
|
+
----------
|
28
|
+
version : str
|
29
|
+
The version to be checked
|
30
|
+
convention : str
|
31
|
+
The name of the convention to be checked
|
32
|
+
"""
|
33
|
+
|
34
|
+
# check if the convention exists
|
35
|
+
if convention not in _get_conventions("name"):
|
36
|
+
raise ValueError(
|
37
|
+
f"Convention '{convention}' does not exist")
|
38
|
+
|
39
|
+
name_version = _get_conventions("name_version")
|
40
|
+
|
41
|
+
# check which version is wanted
|
42
|
+
version_exists = False
|
43
|
+
for versions in name_version:
|
44
|
+
# check if convention and version match
|
45
|
+
if versions[0] == convention \
|
46
|
+
and str(float(versions[1])) == version:
|
47
|
+
version_exists = True
|
48
|
+
|
49
|
+
if not version_exists:
|
50
|
+
raise ValueError((
|
51
|
+
f"{convention} v{version} is not a valid SOFA Convention."
|
52
|
+
"If you are trying to read the data use "
|
53
|
+
"sofar.read_sofa_as_netcdf(). Call sofar.list_conventions() for a "
|
54
|
+
"list of valid Conventions"))
|
55
|
+
|
56
|
+
|
57
|
+
def list_conventions():
|
58
|
+
"""
|
59
|
+
List available SOFA conventions by printing to the console.
|
60
|
+
"""
|
61
|
+
print(_get_conventions("string"))
|
62
|
+
|
63
|
+
|
64
|
+
def _get_conventions(return_type, conventions_path=None):
|
65
|
+
"""
|
66
|
+
Get available SOFA conventions.
|
67
|
+
|
68
|
+
Parameters
|
69
|
+
----------
|
70
|
+
return_type : string, optional
|
71
|
+
``'path'``
|
72
|
+
Return a list with the full paths and filenames of the convention
|
73
|
+
files (json files)
|
74
|
+
``'path_source'``
|
75
|
+
Return a list with the full paths and filenames of the source
|
76
|
+
convention files from API_MO (csv files)
|
77
|
+
``'name'``
|
78
|
+
Return a list of the convention names without version
|
79
|
+
``'name_version'``
|
80
|
+
Return a list of tuples containing the convention name and version.
|
81
|
+
``'string'``
|
82
|
+
Returns a string that lists the names and versions of all
|
83
|
+
conventions.
|
84
|
+
conventions_path : str, optional
|
85
|
+
The path to the the `conventions` folder containing the csv and json
|
86
|
+
files.
|
87
|
+
|
88
|
+
Returns
|
89
|
+
-------
|
90
|
+
See parameter `return_type`.
|
91
|
+
"""
|
92
|
+
# directory containing the SOFA conventions
|
93
|
+
if conventions_path is None:
|
94
|
+
conventions_path = os.path.join(
|
95
|
+
os.path.dirname(__file__), "sofa_conventions", 'conventions')
|
96
|
+
|
97
|
+
reg_str = "*.csv" if return_type == "path_source" else "*.json"
|
98
|
+
|
99
|
+
# SOFA convention files
|
100
|
+
standardized = list(glob.glob(os.path.join(conventions_path, reg_str)))
|
101
|
+
deprecated = list(
|
102
|
+
glob.glob(os.path.join(conventions_path, "deprecated", reg_str)))
|
103
|
+
paths = standardized + deprecated
|
104
|
+
|
105
|
+
conventions_str = "Available SOFA conventions:\n"
|
106
|
+
|
107
|
+
conventions = []
|
108
|
+
versions = []
|
109
|
+
for path in paths:
|
110
|
+
fileparts = os.path.basename(path).split(sep="_")
|
111
|
+
conventions += [fileparts[0]]
|
112
|
+
versions += [fileparts[1][:-5]]
|
113
|
+
conventions_str += f"{conventions[-1]} (Version {versions[-1]})\n"
|
114
|
+
|
115
|
+
if return_type is None:
|
116
|
+
return
|
117
|
+
elif return_type.startswith("path"):
|
118
|
+
return paths
|
119
|
+
elif return_type == "name":
|
120
|
+
return conventions
|
121
|
+
elif return_type == "name_version":
|
122
|
+
return list(zip(conventions, versions))
|
123
|
+
elif return_type == "string":
|
124
|
+
return conventions_str
|
125
|
+
else:
|
126
|
+
raise ValueError(f"return_type {return_type} is invalid")
|
127
|
+
|
128
|
+
|
129
|
+
def equals(sofa_a, sofa_b, verbose=True, exclude=None):
|
130
|
+
"""
|
131
|
+
Compare two SOFA objects against each other.
|
132
|
+
|
133
|
+
Parameters
|
134
|
+
----------
|
135
|
+
sofa_a : Sofa
|
136
|
+
SOFA object
|
137
|
+
sofa_b : Sofa
|
138
|
+
SOFA object
|
139
|
+
verbose : bool, optional
|
140
|
+
Print differences to the console. The default is True.
|
141
|
+
exclude : str, optional
|
142
|
+
Specify what fields should be excluded from the comparison
|
143
|
+
|
144
|
+
``'GLOBAL'``
|
145
|
+
Exclude all global attributes, i.e., fields starting with 'GLOBAL:'
|
146
|
+
``'DATE'``
|
147
|
+
Exclude date attributes, i.e., fields that contain 'Date'
|
148
|
+
``'ATTR'``
|
149
|
+
Exclude all attributes, i.e., fields that contain ':'
|
150
|
+
|
151
|
+
The default is None, which does not exclude anything.
|
152
|
+
|
153
|
+
Returns
|
154
|
+
-------
|
155
|
+
is_identical : bool
|
156
|
+
``True`` if sofa_a and sofa_b are identical, ``False`` otherwise.
|
157
|
+
"""
|
158
|
+
|
159
|
+
is_identical = True
|
160
|
+
|
161
|
+
# get and filter keys
|
162
|
+
# ('_*' are SOFA object private variables, '__' are netCDF attributes)
|
163
|
+
keys_a = [k for k in sofa_a.__dict__.keys() if not k.startswith("_")]
|
164
|
+
keys_b = [k for k in sofa_b.__dict__.keys() if not k.startswith("_")]
|
165
|
+
|
166
|
+
if exclude is not None:
|
167
|
+
if exclude.upper() == "GLOBAL":
|
168
|
+
keys_a = [k for k in keys_a if not k.startswith("GLOBAL_")]
|
169
|
+
keys_b = [k for k in keys_b if not k.startswith("GLOBAL_")]
|
170
|
+
elif exclude.upper() == "ATTR":
|
171
|
+
keys_a = [k for k in keys_a if
|
172
|
+
sofa_a._convention[k]["type"] != "attribute"]
|
173
|
+
keys_b = [k for k in keys_b if
|
174
|
+
sofa_b._convention[k]["type"] != "attribute"]
|
175
|
+
elif exclude.upper() == "DATE":
|
176
|
+
keys_a = [k for k in keys_a if "Date" not in k]
|
177
|
+
keys_b = [k for k in keys_b if "Date" not in k]
|
178
|
+
else:
|
179
|
+
raise ValueError(
|
180
|
+
f"exclude is {exclude} but must be GLOBAL, DATE, or ATTR")
|
181
|
+
|
182
|
+
# check for equal length
|
183
|
+
if len(keys_a) != len(keys_b):
|
184
|
+
return _equals_raise_warning((
|
185
|
+
f"not identical: sofa_a has {len(keys_a)} attributes for "
|
186
|
+
f"comparison and sofa_b has {len(keys_b)}."), verbose)
|
187
|
+
|
188
|
+
# check if the keys match
|
189
|
+
if set(keys_a) != set(keys_b):
|
190
|
+
return _equals_raise_warning(
|
191
|
+
"not identical: sofa_a and sofa_b do not have the ame attributes",
|
192
|
+
verbose)
|
193
|
+
|
194
|
+
# compare the data inside the SOFA object
|
195
|
+
for key in keys_a:
|
196
|
+
|
197
|
+
# get data and types
|
198
|
+
a = getattr(sofa_a, key)
|
199
|
+
b = getattr(sofa_b, key)
|
200
|
+
type_a = sofa_a._convention[key]["type"]
|
201
|
+
type_b = sofa_b._convention[key]["type"]
|
202
|
+
|
203
|
+
# compare attributes
|
204
|
+
if type_a == "attribute" and type_b == "attribute":
|
205
|
+
|
206
|
+
# compare
|
207
|
+
if a != b:
|
208
|
+
is_identical = _equals_raise_warning(
|
209
|
+
f"not identical: different values for {key}", verbose)
|
210
|
+
|
211
|
+
# compare double variables
|
212
|
+
elif type_a == "double" and type_b == "double":
|
213
|
+
|
214
|
+
try:
|
215
|
+
npt.assert_allclose(np.squeeze(a), np.squeeze(b))
|
216
|
+
except AssertionError:
|
217
|
+
is_identical = _equals_raise_warning(
|
218
|
+
"not identical: different values for {key}", verbose)
|
219
|
+
|
220
|
+
# compare string variables
|
221
|
+
elif type_a == "string" and type_b == "string":
|
222
|
+
try:
|
223
|
+
assert np.all(
|
224
|
+
np.squeeze(a).astype("S") == np.squeeze(b).astype("S"))
|
225
|
+
except AssertionError:
|
226
|
+
is_identical = _equals_raise_warning(
|
227
|
+
"not identical: different values for {key}", verbose)
|
228
|
+
else:
|
229
|
+
is_identical = _equals_raise_warning(
|
230
|
+
(f"not identical: {key} has different data types "
|
231
|
+
f"({type_a}, {type_b})"), verbose)
|
232
|
+
|
233
|
+
return is_identical
|
234
|
+
|
235
|
+
|
236
|
+
def _equals_raise_warning(message, verbose):
|
237
|
+
if verbose:
|
238
|
+
warnings.warn(message, stacklevel=2)
|
239
|
+
return False
|
240
|
+
|
241
|
+
|
242
|
+
def _atleast_nd(array, ndim):
|
243
|
+
"""
|
244
|
+
Get numpy array with specified number of dimensions. Dimensions are
|
245
|
+
appended at the end if ndim > 3.
|
246
|
+
"""
|
247
|
+
try:
|
248
|
+
array = array.copy()
|
249
|
+
except AttributeError:
|
250
|
+
array = array
|
251
|
+
|
252
|
+
if ndim == 1:
|
253
|
+
array = np.atleast_1d(array)
|
254
|
+
if ndim == 2:
|
255
|
+
array = np.atleast_2d(array)
|
256
|
+
if ndim >= 3:
|
257
|
+
array = np.atleast_3d(array)
|
258
|
+
for _ in range(ndim - array.ndim):
|
259
|
+
array = array[..., np.newaxis]
|
260
|
+
return array
|
261
|
+
|
262
|
+
|
263
|
+
def _nd_newaxis(array, ndim):
|
264
|
+
"""Append dimensions to the end of an array until array.ndim == ndim."""
|
265
|
+
array = np.array(array)
|
266
|
+
|
267
|
+
for _ in range(ndim - array.ndim):
|
268
|
+
array = array[..., np.newaxis]
|
269
|
+
return array
|
270
|
+
|
271
|
+
|
272
|
+
def _complete_sofa(convention="GeneralTF"):
|
273
|
+
"""
|
274
|
+
Generate SOFA file with all required data for testing verification rules.
|
275
|
+
"""
|
276
|
+
|
277
|
+
sofa = sf.Sofa(convention)
|
278
|
+
# Listener meta data
|
279
|
+
sofa.add_variable("ListenerView", [1, 0, 0], "double", "IC")
|
280
|
+
sofa.add_attribute("ListenerView_Type", "cartesian")
|
281
|
+
sofa.add_attribute("ListenerView_Units", "metre")
|
282
|
+
sofa.add_variable("ListenerUp", [0, 0, 1], "double", "IC")
|
283
|
+
# Receiver meta data
|
284
|
+
sofa.add_variable("ReceiverView", [1, 0, 0], "double", "IC")
|
285
|
+
sofa.add_attribute("ReceiverView_Type", "cartesian")
|
286
|
+
sofa.add_attribute("ReceiverView_Units", "metre")
|
287
|
+
sofa.add_variable("ReceiverUp", [0, 0, 1], "double", "IC")
|
288
|
+
# Source meta data
|
289
|
+
sofa.add_variable("SourceView", [1, 0, 0], "double", "IC")
|
290
|
+
sofa.add_attribute("SourceView_Type", "cartesian")
|
291
|
+
sofa.add_attribute("SourceView_Units", "metre")
|
292
|
+
sofa.add_variable("SourceUp", [0, 0, 1], "double", "IC")
|
293
|
+
# Emitter meta data
|
294
|
+
sofa.add_variable("EmitterView", [1, 0, 0], "double", "IC")
|
295
|
+
sofa.add_attribute("EmitterView_Type", "cartesian")
|
296
|
+
sofa.add_attribute("EmitterView_Units", "metre")
|
297
|
+
sofa.add_variable("EmitterUp", [0, 0, 1], "double", "IC")
|
298
|
+
sofa.add_attribute("GLOBAL_EmitterDescription", "what an emitter")
|
299
|
+
sofa.add_variable("EmitterDescriptions", ["emitter array"], "string", "MS")
|
300
|
+
# Room meta data
|
301
|
+
sofa.add_attribute("GLOBAL_RoomShortName", "Hall")
|
302
|
+
sofa.add_attribute("GLOBAL_RoomDescription", "Wooden floor")
|
303
|
+
sofa.add_attribute("GLOBAL_RoomLocation", "some where nice")
|
304
|
+
sofa.add_variable("RoomTemperature", 0, "double", "I")
|
305
|
+
sofa.add_attribute("RoomTemperature_Units", "kelvin")
|
306
|
+
sofa.add_attribute("GLOBAL_RoomGeometry", "some/file")
|
307
|
+
sofa.add_variable("RoomVolume", 200, "double", "I")
|
308
|
+
sofa.add_attribute("RoomVolume_Units", "cubic metre")
|
309
|
+
sofa.add_variable("RoomCornerA", [0, 0, 0], "double", "IC")
|
310
|
+
sofa.add_variable("RoomCornerB", [1, 1, 1], "double", "IC")
|
311
|
+
sofa.add_variable("RoomCorners", 0, "double", "I")
|
312
|
+
sofa.add_attribute("RoomCorners_Type", "cartesian")
|
313
|
+
sofa.add_attribute("RoomCorners_Units", "metre")
|
314
|
+
|
315
|
+
sofa.verify()
|
316
|
+
return sofa
|
@@ -0,0 +1,22 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2021, The pyfar developers
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
@@ -0,0 +1,136 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: sofar
|
3
|
+
Version: 1.2.1
|
4
|
+
Summary: Maybe the most complete python package for SOFA files so far.
|
5
|
+
Author-email: The pyfar developers <info@pyfar.org>
|
6
|
+
License: MIT License
|
7
|
+
|
8
|
+
Copyright (c) 2021, The pyfar developers
|
9
|
+
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
12
|
+
in the Software without restriction, including without limitation the rights
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
15
|
+
furnished to do so, subject to the following conditions:
|
16
|
+
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
18
|
+
copies or substantial portions of the Software.
|
19
|
+
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
26
|
+
SOFTWARE.
|
27
|
+
|
28
|
+
|
29
|
+
Project-URL: Tracker, https://github.com/pyfar/sofar/issues
|
30
|
+
Project-URL: Documentation, https://sofar.readthedocs.io/
|
31
|
+
Project-URL: Download, https://pypi.org/project/sofar/
|
32
|
+
Project-URL: Homepage, https://pyfar.org/
|
33
|
+
Project-URL: Source, https://github.com/pyfar/sofar
|
34
|
+
Project-URL: Changelog, https://github.com/pyfar/sofar/blob/main/HISTORY.rst
|
35
|
+
Keywords: acoustics,pyfar
|
36
|
+
Classifier: Development Status :: 4 - Beta
|
37
|
+
Classifier: Intended Audience :: Science/Research
|
38
|
+
Classifier: License :: OSI Approved :: MIT License
|
39
|
+
Classifier: Natural Language :: English
|
40
|
+
Classifier: Programming Language :: Python :: 3
|
41
|
+
Classifier: Programming Language :: Python :: 3.8
|
42
|
+
Classifier: Programming Language :: Python :: 3.9
|
43
|
+
Classifier: Programming Language :: Python :: 3.10
|
44
|
+
Classifier: Programming Language :: Python :: 3.11
|
45
|
+
Classifier: Programming Language :: Python :: 3.12
|
46
|
+
Requires-Python: >=3.8
|
47
|
+
Description-Content-Type: text/markdown
|
48
|
+
License-File: LICENSE
|
49
|
+
Requires-Dist: netCDF4
|
50
|
+
Requires-Dist: numpy>=1.14.0
|
51
|
+
Requires-Dist: beautifulsoup4
|
52
|
+
Requires-Dist: requests
|
53
|
+
Provides-Extra: deploy
|
54
|
+
Requires-Dist: twine; extra == "deploy"
|
55
|
+
Requires-Dist: wheel; extra == "deploy"
|
56
|
+
Requires-Dist: build; extra == "deploy"
|
57
|
+
Requires-Dist: setuptools; extra == "deploy"
|
58
|
+
Requires-Dist: bump-my-version; extra == "deploy"
|
59
|
+
Provides-Extra: tests
|
60
|
+
Requires-Dist: pytest; extra == "tests"
|
61
|
+
Requires-Dist: pytest-cov; extra == "tests"
|
62
|
+
Requires-Dist: watchdog; extra == "tests"
|
63
|
+
Requires-Dist: ruff==0.8.2; extra == "tests"
|
64
|
+
Requires-Dist: coverage; extra == "tests"
|
65
|
+
Provides-Extra: docs
|
66
|
+
Requires-Dist: sphinx; extra == "docs"
|
67
|
+
Requires-Dist: autodocsumm>=0.2.14; extra == "docs"
|
68
|
+
Requires-Dist: pydata-sphinx-theme; extra == "docs"
|
69
|
+
Requires-Dist: sphinx_mdinclude; extra == "docs"
|
70
|
+
Requires-Dist: sphinx-design; extra == "docs"
|
71
|
+
Requires-Dist: sphinx-favicon; extra == "docs"
|
72
|
+
Requires-Dist: sphinx-reredirects; extra == "docs"
|
73
|
+
Provides-Extra: dev
|
74
|
+
Requires-Dist: sofar[deploy,docs,tests]; extra == "dev"
|
75
|
+
|
76
|
+
<h1 align="center">
|
77
|
+
<img src="https://github.com/pyfar/gallery/raw/main/docs/resources/logos/pyfar_logos_fixed_size_sofar.png" width="300">
|
78
|
+
</h1><br>
|
79
|
+
|
80
|
+
[](https://badge.fury.io/py/sofar)
|
81
|
+
[](https://sofar.readthedocs.io/en/latest/?badge=latest)
|
82
|
+
[](https://circleci.com/gh/pyfar/sofar)
|
83
|
+
[](https://mybinder.org/v2/gh/pyfar/gallery/main?labpath=docs/gallery/interactive/sofar_introduction.ipynb)
|
84
|
+
|
85
|
+
Sofar is maybe the most complete Python package for the SOFA file format so
|
86
|
+
far. SOFA files store spatially distributed acoustic data such as impulse
|
87
|
+
responses or transfer functions. They are defined by the AES69-2022 standard
|
88
|
+
(see references). These are the key features of sofar
|
89
|
+
|
90
|
+
- Read, edit, and write SOFA files
|
91
|
+
- Add custom attributes to SOFA files
|
92
|
+
- Full Verification of the content of a SOFA files against AES69-2022
|
93
|
+
- Upgrade data that uses outdated SOFA conventions
|
94
|
+
- Open license allows unrestricted use
|
95
|
+
- sofar is tested using continuous integration on
|
96
|
+
- Uses a complete definition of the AES69-2022 standard (see references) maintained at [sofa_conventions](https://github.com/pyfar/sofa_conventions)
|
97
|
+
|
98
|
+
Getting Started
|
99
|
+
===============
|
100
|
+
|
101
|
+
The [sofar and SOFA notebook](https://pyfar-gallery.readthedocs.io/en/latest/gallery/interactive/sofar_introduction.html)
|
102
|
+
gives an overview of the most important sofar functionality and is a good starting point. For processing and visualizing data
|
103
|
+
inside SOFA files, we recommend the [pyfar package](https://pyfar.readthedocs.io) that can read SOFA files through
|
104
|
+
`pyfar.io.read_sofa` and the in-depth examples contained in the
|
105
|
+
[pyfar example gallery](https://pyfar-gallery.readthedocs.io/en/latest/examples_gallery.html). Check out
|
106
|
+
[read the docs](https://sofar.readthedocs.io) for a complete documentation of sofar. A more detailed introduction to the SOFA
|
107
|
+
file format is given by Majdak et. al. 2022 (see references below). All information is also bundled at [pyfar.org](https://pyfar.org).
|
108
|
+
|
109
|
+
Installation
|
110
|
+
============
|
111
|
+
|
112
|
+
Use pip to install sofar
|
113
|
+
|
114
|
+
pip install sofar
|
115
|
+
|
116
|
+
|
117
|
+
(Requires Python >= 3.8)
|
118
|
+
|
119
|
+
If the installation fails, please check out the [help section](https://pyfar-gallery.readthedocs.io/en/latest/help).
|
120
|
+
|
121
|
+
Contributing
|
122
|
+
============
|
123
|
+
|
124
|
+
Refer to the [contribution guidelines](https://sofar.readthedocs.io/en/stable/contributing.html) for more information.
|
125
|
+
|
126
|
+
References
|
127
|
+
==========
|
128
|
+
|
129
|
+
AES69-2022: *AES standard for file exchange - Spatial acoustic data file
|
130
|
+
format*, Audio Engineering Society, Inc., New York, NY, USA.
|
131
|
+
(https://www.aes.org/publications/standards/search.cfm?docID=99)
|
132
|
+
|
133
|
+
P. Majdak, F. Zotter, F. Brinkmann, J. De Muynke, M. Mihocic, and M.
|
134
|
+
Noisternig, "Spatially Oriented Format for Acoustics 2.1: Introduction and
|
135
|
+
Recent Advances", *J. Audio Eng. Soc.*, vol. 70, no. 7/8, pp. 565-584,
|
136
|
+
Jul. 2022. DOI: https://doi.org/10.17743/jaes.2022.0026
|
@@ -0,0 +1,105 @@
|
|
1
|
+
docs/Makefile,sha256=OYY1k1pc-qybE8cc8J65Uumpst0kiq55ct3gjLaWeJU,606
|
2
|
+
docs/api_reference.rst,sha256=s3tvYCr2vktN05sSyIhzt1BNktV13SnfU-Cz4fDmf5o,705
|
3
|
+
docs/conf.py,sha256=JLiZhmxpMXTnK3KPposuhV96J5smR5xzgONt-aTCn_M,5299
|
4
|
+
docs/contributing.rst,sha256=h9XHQ0lx_ySKgXQmwqhJQLPD7VElHdyu1ruKfYWvrYA,33
|
5
|
+
docs/history.rst,sha256=6GtKybnFdujxXakMcb0LHcrFsWwqRh8JJ_xhO_Qxqdg,28
|
6
|
+
docs/index.rst,sha256=TNHSWTiFrI_R7vn1E2XM2RTx3YEg8KuSzwAY9ttDdWc,37
|
7
|
+
docs/make.bat,sha256=wLZX2GGllVCJQSJ93BGGGHkLEsy6JC_I7u6xRKG3CtA,803
|
8
|
+
docs/readme.rst,sha256=ctYl-VOckbYAd-QhoWKIKS2C1kErl9plJWaPraZkfjY,28
|
9
|
+
docs/sofar.rst,sha256=uJ_NCeXUJKFURnuQCZbKON7JwbbTdAFSlrb--symugo,1479
|
10
|
+
docs/resources/conventions.py,sha256=4ewEa-AGBkem-VWbfUbXWMy6UUv3DFu2cGETPo89GCc,6052
|
11
|
+
docs/resources/working_with_sofa_HRIR_lateral.png,sha256=VpNNtT52Jsl6ymrY9bs1mbNWyCg9S0Ewi1I0CSHB4aE,42425
|
12
|
+
docs/resources/working_with_sofa_source_horizontal.png,sha256=rKvTCt4j_JtR1JGHPSu1pIySNTAH-PRog0hMOjBQXLM,125698
|
13
|
+
docs/resources/working_with_sofa_source_lateral.png,sha256=H1VhLtBOjJV6m62fN2vrMzoq6NTOYLmLUfIQLHqL49I,140443
|
14
|
+
sofar/__init__.py,sha256=ADa6pEg3ehw9Zy6ExRztvtCjrcwDkU4DUBrlQ3v12jE,688
|
15
|
+
sofar/io.py,sha256=kN8BcofSYb2Ew5NfBEN-C72wxep9Qw9s5Dmpypprnp8,16053
|
16
|
+
sofar/sofa.py,sha256=yIl00ekMthqJPmpiujfM-Hlb4IuqOpcGPQcIRJA8DW0,69887
|
17
|
+
sofar/sofastream.py,sha256=OAHC4nzzR7a4uksUeMawYGMzCNBQQg2gk7PK20Rn6xo,9988
|
18
|
+
sofar/update_conventions.py,sha256=XKylP9n7vRiJUOg4HBZXmDut_MbgNZ9-HZUs52xACtc,18137
|
19
|
+
sofar/utils.py,sha256=_3dH_fUBLmVlD6DD4Zc7akXk-lTY0DAPJzS4DnX0iyo,10838
|
20
|
+
sofar/sofa_conventions/VERSION,sha256=IuQRql5P3qfPUQuJwuh-RX5TvI_Wd4bDdSm8VLNQqds,34
|
21
|
+
sofar/sofa_conventions/write_upgrade_rules.py,sha256=7I2UlOwtuYfpV3L14zehZH0TZ2Kz9cxYz1fxgfg124w,4805
|
22
|
+
sofar/sofa_conventions/write_verification_data.py,sha256=vIE7UQRGlUziCeNv3kwV5CtELXh9h-_AWFsbEsn-g1M,10767
|
23
|
+
sofar/sofa_conventions/write_verification_rules.py,sha256=oOrgDA7tOgnymtXmDih7s7XiRj28Xkj--A8ihaOFRM0,13871
|
24
|
+
sofar/sofa_conventions/conventions/AnnotatedEmitterAudio_0.2.csv,sha256=q1fOy9QqskNjsV2b-rn9GDTThOo-AUKGORMmXSgp83w,2348
|
25
|
+
sofar/sofa_conventions/conventions/AnnotatedEmitterAudio_0.2.json,sha256=lznoLbG6HYvPAZ-alVoWgfBXHFDeMb0PNnyOWoag3-Y,8420
|
26
|
+
sofar/sofa_conventions/conventions/AnnotatedReceiverAudio_0.2.csv,sha256=MHBEkaSfiHm-d-8EAqL40M-0wt8couJfO2Q-Ff4SoEs,2360
|
27
|
+
sofar/sofa_conventions/conventions/AnnotatedReceiverAudio_0.2.json,sha256=2Wf1XgP4BNhI1lNlgnFabX6mUC2pT0IGLW92mjY82hY,8432
|
28
|
+
sofar/sofa_conventions/conventions/FreeFieldDirectivityTF_1.1.csv,sha256=Wait37FTh6ROKgpX7-JsVM-ohtKfsdHjxVL5vN7uTTs,5510
|
29
|
+
sofar/sofa_conventions/conventions/FreeFieldDirectivityTF_1.1.json,sha256=sm8Pj_Z1n1tW2jYlu00eikR3yCcANEm_Kw5Eq9jrbw4,13138
|
30
|
+
sofar/sofa_conventions/conventions/FreeFieldHRIR_1.0.csv,sha256=C_fc7wHjBLc2krPja33sQaDSZDvlr80GSsgOj904GBY,2479
|
31
|
+
sofar/sofa_conventions/conventions/FreeFieldHRIR_1.0.json,sha256=-777Wo-fgKq844AwxIlompmIF9rHLRXWIAJjgaqADdU,8127
|
32
|
+
sofar/sofa_conventions/conventions/FreeFieldHRTF_1.0.csv,sha256=BbE417cDQ6eQ8UFl3MVWv9SatQ2OHZ7UF7u_ZCfCoBk,2222
|
33
|
+
sofar/sofa_conventions/conventions/FreeFieldHRTF_1.0.json,sha256=aN7x7UU-HkT5a-cVmJ29IXP1h_8DFsyInsbWFm65oVk,7996
|
34
|
+
sofar/sofa_conventions/conventions/GeneralFIR-E_2.0.csv,sha256=daSPbImANSYn5rIHQkn6fdD3kE0Z-wq9iyCGfMEroGY,1998
|
35
|
+
sofar/sofa_conventions/conventions/GeneralFIR-E_2.0.json,sha256=ERs0oQrZL2JLQOcFE7umPIOIMqm2pQy_lOA8UPtLg18,6615
|
36
|
+
sofar/sofa_conventions/conventions/GeneralFIR_1.0.csv,sha256=HInvJ980U9wtu2QUT9JZ3rUlR7Qfi2yzgZb4j3q6n58,2011
|
37
|
+
sofar/sofa_conventions/conventions/GeneralFIR_1.0.json,sha256=dmVz1aTMv-9EKO9NwzTbWq-QU-uOa9d-zhS4ScKhDLU,7054
|
38
|
+
sofar/sofa_conventions/conventions/GeneralSOS_1.0.csv,sha256=3JzYYRULpd8WmCC0Mze6wTzr7PluwEjy6lxt74VDsow,2130
|
39
|
+
sofar/sofa_conventions/conventions/GeneralSOS_1.0.json,sha256=3FYXzhcb2jJFjlKFlF60Uv_82boZUNbfSVlS54It8xM,7357
|
40
|
+
sofar/sofa_conventions/conventions/GeneralTF-E_1.0.csv,sha256=lztME1Skiac-Bj1OctWuQ05_THozrPzil6a01F9PufI,2015
|
41
|
+
sofar/sofa_conventions/conventions/GeneralTF-E_1.0.json,sha256=bQZn8O67anSvZJgo7PkIP9TaPprBlhqPmzpp6dy8LQY,6757
|
42
|
+
sofar/sofa_conventions/conventions/GeneralTF_1.0.csv,sha256=RD1aXHuRIECKkHDZm0cLyRp-m32-hg_hRxNegdJnttc,1956
|
43
|
+
sofar/sofa_conventions/conventions/GeneralTF_1.0.json,sha256=mPbpQcfEeJt2lKJODGgEgusDOzLU3HbmD3Fr6LbXnt0,6696
|
44
|
+
sofar/sofa_conventions/conventions/GeneralTF_2.0.csv,sha256=8fpM1wnY4YL9DbIwstrU5UCokh9rheiookSJYSMqKR8,1957
|
45
|
+
sofar/sofa_conventions/conventions/GeneralTF_2.0.json,sha256=pn6V2AVJum8y0L0cpn3Kt5ostsmErjcF41_XeiPdk88,6699
|
46
|
+
sofar/sofa_conventions/conventions/SimpleFreeFieldHRIR_1.0.csv,sha256=gZ_jA2hAdetCxgV3P-I9T3QTG7hNwogon0r1pKpv8iM,2239
|
47
|
+
sofar/sofa_conventions/conventions/SimpleFreeFieldHRIR_1.0.json,sha256=ScZn_Jf9AI1o6gyFcdl5xFzdnvSfuMcdyG9GH5eOdDc,8446
|
48
|
+
sofar/sofa_conventions/conventions/SimpleFreeFieldHRSOS_1.0.csv,sha256=YXI6K_HiGH6wVTr3QIUhhtKQRKD3uUaj56D6xzCYUzE,2303
|
49
|
+
sofar/sofa_conventions/conventions/SimpleFreeFieldHRSOS_1.0.json,sha256=dG_O9QiWYrB8IkZD-z3W1GUJw8E_c7NT5CN4xOmhhwk,8254
|
50
|
+
sofar/sofa_conventions/conventions/SimpleFreeFieldHRTF_1.0.csv,sha256=x7fyeLrub2clGMszUtv6v9lg2cF8hI-FzeAqJEimXyc,2015
|
51
|
+
sofar/sofa_conventions/conventions/SimpleFreeFieldHRTF_1.0.json,sha256=HFNW4_1A3t1M6geUTUVLZrf7sAmhy59T47d__YXdylM,7791
|
52
|
+
sofar/sofa_conventions/conventions/SimpleFreeFieldSOS_1.0.csv,sha256=YphFfFEwTSosaYOTbUv2gz-Pb5yrQv7AFVZuXh-WUjM,2298
|
53
|
+
sofar/sofa_conventions/conventions/SimpleFreeFieldSOS_1.0.json,sha256=SILNWPWs3JFVtnDvKDpyZ3RBGboD8SWaqmaT83EUb7w,8249
|
54
|
+
sofar/sofa_conventions/conventions/SimpleHeadphoneIR_1.0.csv,sha256=7B_ijKN7AVftugYTvCCM8n76ofs8gCWkBvFc_9D-STk,3103
|
55
|
+
sofar/sofa_conventions/conventions/SimpleHeadphoneIR_1.0.json,sha256=pUUme-CuoipR06Yi26yfntWwMMWs7wrriqseg6NPK2M,9863
|
56
|
+
sofar/sofa_conventions/conventions/SingleRoomMIMOSRIR_1.0.csv,sha256=2OzG5t9rYzDrywP__99ylHmyAM9Mjx758jO5dudv0Jc,4053
|
57
|
+
sofar/sofa_conventions/conventions/SingleRoomMIMOSRIR_1.0.json,sha256=5tjPriXZk8WEIr15i41L7hQRwAxzw_gA0nxWkZfe_7g,14346
|
58
|
+
sofar/sofa_conventions/conventions/SingleRoomSRIR_1.0.csv,sha256=l7aeLNxbOyXgfQIjCo3QzpRpBonMp9ssfhps4fejHxc,4199
|
59
|
+
sofar/sofa_conventions/conventions/SingleRoomSRIR_1.0.json,sha256=gVwyzGni9e3w5wehnxe6Oe5knO2Np5doHYLzRsfrlfc,14491
|
60
|
+
sofar/sofa_conventions/conventions/deprecated/AnnotatedEmitterAudio_0.1.csv,sha256=pHwICgmCtMNdGBHPItuydYuX32myAEqCWtGSKBJR8_s,2355
|
61
|
+
sofar/sofa_conventions/conventions/deprecated/AnnotatedEmitterAudio_0.1.json,sha256=p-WppnTuOaEFj0WlKxiM47H92pmHkIFZ9jX6TV0iLQE,8403
|
62
|
+
sofar/sofa_conventions/conventions/deprecated/AnnotatedReceiverAudio_0.1.csv,sha256=A8doF2goKhvf1QumQOx-k_MsZKVJRHZiRbYCAXjxrTI,2367
|
63
|
+
sofar/sofa_conventions/conventions/deprecated/AnnotatedReceiverAudio_0.1.json,sha256=dzSUPEqXT0BG0TeTa7r4zZJS01le1dJTdftBOgUXV18,8415
|
64
|
+
sofar/sofa_conventions/conventions/deprecated/FreeFieldDirectivityTF_1.0.csv,sha256=Ha6178_LxRod-L2UcI7SX3o6Cf1YRFs1zgIpn0kd0rA,5125
|
65
|
+
sofar/sofa_conventions/conventions/deprecated/FreeFieldDirectivityTF_1.0.json,sha256=GcOb3cbv63C7S4cJ7IVvU7NAAd1h8mA7RHaAFQ_jqz8,12627
|
66
|
+
sofar/sofa_conventions/conventions/deprecated/GeneralFIRE_1.0.csv,sha256=2_ed7Y0CGJmCx9V3X7L4gipJ94nLzH7Jl9fXXtI7rLQ,1988
|
67
|
+
sofar/sofa_conventions/conventions/deprecated/GeneralFIRE_1.0.json,sha256=y3A1fhyS4XUAIbEGv92pwrYp01HutgIKajI4WmJYYKQ,6603
|
68
|
+
sofar/sofa_conventions/conventions/deprecated/MultiSpeakerBRIR_0.3.csv,sha256=E_jW15CNWUsp5W9Uw2EbNNyvDxDMFvs-CAELDmYtp0I,2560
|
69
|
+
sofar/sofa_conventions/conventions/deprecated/MultiSpeakerBRIR_0.3.json,sha256=PBC2SOliEORqJpuSweO77_tePFBVVoJ6zZ_COUNrZME,8884
|
70
|
+
sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldHRIR_0.4.csv,sha256=WQRiDw51jZK9yGyfCtUVGpKbi0FMl-BtG2yn-5s5AME,2093
|
71
|
+
sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldHRIR_0.4.json,sha256=sGWA33puXRpPmoMOZfBT0SgbLGIJIACNcxsJdACmKKY,7704
|
72
|
+
sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldTF_0.4.csv,sha256=lHINbpcuvHBNsAOL6KGWPy3SMEHorFcovgafXivBt0w,1989
|
73
|
+
sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldTF_0.4.json,sha256=RIAUjtb5QvLn3dny_b4uxdsHXD0nkxbK49w4RiJslJI,7770
|
74
|
+
sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldTF_1.0.csv,sha256=nzm1DDWj3blCljLFQZ1K2OU_GKgkW9x0Ow638aL_cys,2028
|
75
|
+
sofar/sofa_conventions/conventions/deprecated/SimpleFreeFieldTF_1.0.json,sha256=aXc5prNxJslNt6ESYACRHhzUxMWa80rDhvChRxGSoDM,7770
|
76
|
+
sofar/sofa_conventions/conventions/deprecated/SimpleHeadphoneIR_0.1.csv,sha256=eADQZ2qv5odeUMQsgc8YZQQA5sRN-2M3Ym5LnGrbI_E,3153
|
77
|
+
sofar/sofa_conventions/conventions/deprecated/SimpleHeadphoneIR_0.1.json,sha256=5AUrkT4s-FMFkqbVEiak7YKugtzwb0iU7o3XuYbNtYs,9870
|
78
|
+
sofar/sofa_conventions/conventions/deprecated/SimpleHeadphoneIR_0.2.csv,sha256=sBlw9J3Clix0b7aPRo-uQntM43pqBlqSG00OHJ_i7OM,3153
|
79
|
+
sofar/sofa_conventions/conventions/deprecated/SimpleHeadphoneIR_0.2.json,sha256=fHK0c3DUTvAUxOAKC1LuJZlxSyKoSjF0HpJkkpUYCyA,9870
|
80
|
+
sofar/sofa_conventions/conventions/deprecated/SingleRoomDRIR_0.2.csv,sha256=JsPEm-KgQ_b_2nGzVys4jnJTSedSQtcoOk1x31ycqLE,2045
|
81
|
+
sofar/sofa_conventions/conventions/deprecated/SingleRoomDRIR_0.2.json,sha256=oR-qubagKs28ICI7243Ep2zX0AFn_8lvYPNPseg16O8,8097
|
82
|
+
sofar/sofa_conventions/conventions/deprecated/SingleRoomDRIR_0.3.csv,sha256=l6PAKjsNuaFHVUlT4rVdZY9Pj7nh_jF8d82i5YSbkss,1999
|
83
|
+
sofar/sofa_conventions/conventions/deprecated/SingleRoomDRIR_0.3.json,sha256=ccCvFNWYwATIRCPxQke73ckogc2Y3hBP97_JOtPusns,8097
|
84
|
+
sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.1.csv,sha256=Vjx7u0MaYsUFbzKPKgAWxeT9iqqNC5gF_P6RqG-dd78,2397
|
85
|
+
sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.1.json,sha256=XE2ai8ybHxzrWKDUooE7LpBoiFS3pf-5RiG17Jy08E0,8650
|
86
|
+
sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.2.csv,sha256=svRCzuJl_wR8Y1LUS7O_N1KkWtxTB8lrhQXBi7uif60,2727
|
87
|
+
sofar/sofa_conventions/conventions/deprecated/SingleTrackedAudio_0.2.json,sha256=g64b-uuzPlm_nXvoRgMxcydDTq5LSsX3mmeFN-tl6-w,9531
|
88
|
+
sofar/sofa_conventions/rules/deprecations.json,sha256=adYMivYOicwuAUFAsoiDcGHdhre5ZqNOhIe9BX2mM7M,534
|
89
|
+
sofar/sofa_conventions/rules/rules.json,sha256=45fbAzUczWYSpZZj7A15psx2Rh77xz56eT2CagKrwts,23096
|
90
|
+
sofar/sofa_conventions/rules/unit_aliases.json,sha256=QXgOfpe8bnmUybVhSSj3nIUYw50CAVehh7sdFNPFl0k,212
|
91
|
+
sofar/sofa_conventions/rules/upgrade.json,sha256=0o9sTQELnEUXl_teZLjO1Azx7yqrTHmYzT8_7VB9LtM,6025
|
92
|
+
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
93
|
+
tests/conftest.py,sha256=3J_BsyJ-_L5145UY_17pb56AptLZr62QFt-zhzE0OE8,738
|
94
|
+
tests/test_deprecations.py,sha256=mIlI1utzIiisKrerd9gZjxVLy2N5l2Jtg9dpWuJ0o7M,610
|
95
|
+
tests/test_io.py,sha256=Xpg9Or9z-91lm6n9-fZXVoyx5CZpgWZ7unJ0wtN3-0Q,12112
|
96
|
+
tests/test_sofa.py,sha256=YcG1BlA2_6IrE9RvcHcUh2k_XtoRP8nWjLiMbgkqUK0,11450
|
97
|
+
tests/test_sofa_upgrade_conventions.py,sha256=bZbatBojTSRkJDFK-VCohkZqvVV7j8cOBC2qVzNFYU4,3726
|
98
|
+
tests/test_sofa_verify.py,sha256=D0_mcv5h-4OE198URWWOuFrp4bpqrLWQZ7wOP80PbYI,16074
|
99
|
+
tests/test_sofastream.py,sha256=tdTX6qxaUY3bX5pVcHpJxASuLj2k2aqtL1Qyu7hPc24,3905
|
100
|
+
tests/test_utils.py,sha256=edpDH6AqwlBp3l8hw_4THLN4yhHfp8Ih61pVyIAiAVU,8825
|
101
|
+
sofar-1.2.1.dist-info/LICENSE,sha256=OOdX8H69BDppTN8KCBp8l2_yDbH6sW-YuSEKDgZPuL4,1079
|
102
|
+
sofar-1.2.1.dist-info/METADATA,sha256=WXrHLyWVmwqHGsDP-wVZFcAsSa6o_bHUey9GkQzx4kQ,6433
|
103
|
+
sofar-1.2.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
104
|
+
sofar-1.2.1.dist-info/top_level.txt,sha256=5YyQsRMOJOaaykMzffbmmHklMAiAw8g1BWOcLxiN110,17
|
105
|
+
sofar-1.2.1.dist-info/RECORD,,
|
tests/__init__.py
ADDED
File without changes
|
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
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import pytest
|
2
|
+
from packaging import version
|
3
|
+
import re
|
4
|
+
import sofar as sf
|
5
|
+
|
6
|
+
|
7
|
+
# deprecate in 1.3.0 ----------------------------------------------------------
|
8
|
+
def test_pad_zero_modi():
|
9
|
+
with pytest.warns(
|
10
|
+
UserWarning,
|
11
|
+
match=re.escape('Sofa.info() will be deprecated in sofar 1.3.0')):
|
12
|
+
sofa = sf.Sofa('GeneralTF')
|
13
|
+
sofa.info()
|
14
|
+
|
15
|
+
if version.parse(sf.__version__) >= version.parse('1.3.0'):
|
16
|
+
sofa = sf.Sofa('GeneralTF')
|
17
|
+
with pytest.raises(AttributeError, match='has no attribute'):
|
18
|
+
# remove Sofa.info() from pyfar 1.3.0!
|
19
|
+
sofa.info()
|