Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@


# Temporary SOFA-file
@pytest.fixture
@pytest.fixture()
def temp_sofa_file(tmp_path_factory):
"""
Temporary small SOFA file.
Expand Down
86 changes: 86 additions & 0 deletions tests/test_conventions_dimensions_consistency.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""
This tests for consistent dimensions in the convention files.

All dimensions must be of the same length. E.g., the set of dimensions 'M, ME'
is invalid and should be 'MI, 'ME'.

This cannot be done as part of Sofa.verify, because it would make it impossible
to read SOFA files written with deprecated conventions that are containing
inconsistent dimensions.
"""
import sofar as sf
import numpy as np
import pytest
import json

convention_paths = sf.utils._get_conventions('path')


def check_dimensions_consistency(convention_path):
"""
Check for consistent dimensions.

Parameters
----------
convention_path : str
path to the SOFA convention to be checked. Must be a json file.

Raises
------
ValueError if one or more inconsistent dimensions are found.
"""

with open(convention_path, "r") as file:
convention = json.load(file)

name = convention['GLOBAL:SOFAConventions']['default'] + ' v' + \
convention['GLOBAL:SOFAConventionsVersion']['default']

errors = []

for key, value in convention.items():

dimensions = value['dimensions']

if dimensions is None:
continue

dim_length = [len(dim) for dim in dimensions.split(", ")]
if len(np.unique(dim_length)) > 1:

# get verbose string for error message containing the number of
# dimensions and the actual dimensions, e.g., 2 (MR), 3 (MRE)
dim_length_string = []
for length, dim in zip(dim_length, dimensions.split(", ")):
dim_length_string.append(f'{length} ({dim})')

errors.append(f'{key}: {", ".join(dim_length_string)}')

# raise error at the end in case there are multiple inconsistencies
if len(errors):
raise ValueError((f'Found dimensions of unequal length for {name}: '
f'{"; ".join(errors)}'))


@pytest.mark.parametrize('convention_path', convention_paths)
def test_dimensions_consistency(convention_path):
"""
Check up to date conventions and skip deprecated.
This must not raise errors.
"""

if 'deprecated' in convention_path:
return 0

check_dimensions_consistency(convention_path)


def test_dimensions_consistency_error():
"""Check selected deprecated convention. This must raise and error."""

for convention_path in convention_paths:
if convention_path.endswith('FreeFieldDirectivityTF_1.0.json'):
break

with pytest.raises(ValueError, match='Found dimensions of unequal length'):
check_dimensions_consistency(convention_path)
5 changes: 3 additions & 2 deletions tests/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,13 @@ def test_roundtrip_multidimensional_string_variable():
# add dummy matrix that contains 4 measurements
sofa.Data_IR = np.zeros((4, 2, 10))
# add (4, 1) string variable
sofa.SourceManufacturer = [["someone"], ["else"], ["did"], ["this"]]
sofa.SourceManufacturers = [["someone"], ["else"], ["did"], ["this"]]
# remove other string variables for simplicity
delattr(sofa, "SourceModel")
delattr(sofa, "SourceModels")
delattr(sofa, "ReceiverDescriptions")
delattr(sofa, "EmitterDescriptions")
delattr(sofa, "MeasurementDate")
delattr(sofa, "SourceURIs")

# read write and assert
sf.write_sofa(file, sofa)
Expand Down
6 changes: 3 additions & 3 deletions tests/test_sofa.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,13 +303,13 @@ def test_delete_entry():

sofa = sf.Sofa("SimpleHeadphoneIR")
assert hasattr(sofa, "GLOBAL_History")
assert hasattr(sofa, "SourceManufacturer")
assert hasattr(sofa, "SourceManufacturers")
# delete one optional attribute and variable
sofa.delete("GLOBAL_History")
sofa.delete("SourceManufacturer")
sofa.delete("SourceManufacturers")
# check if data were removed
assert not hasattr(sofa, "GLOBAL_History")
assert not hasattr(sofa, "SourceManufacturer")
assert not hasattr(sofa, "SourceManufacturers")


def test__get_size_and_shape_of_string_var():
Expand Down
12 changes: 6 additions & 6 deletions tests/test_sofa_verify.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,18 +227,18 @@ def test_data_types(capfd):

# test invalid data for netCDF string variable
sofa = sf.Sofa("SimpleHeadphoneIR")
sofa.SourceModel = 1
with pytest.raises(ValueError, match="- SourceModel must be string"):
sofa.SourceModels = 1
with pytest.raises(ValueError, match="- SourceModels must be string"):
sofa.verify()

sofa.SourceModel = np.array(1)
with pytest.raises(ValueError, match="- SourceModel must be U or S"):
sofa.SourceModels = np.array(1)
with pytest.raises(ValueError, match="- SourceModels must be U or S"):
sofa.verify()

# test valid data
sofa.SourceModel = ["test"]
sofa.SourceModels = ["test"]
sofa.verify()
sofa.SourceModel = np.array(["test"])
sofa.SourceModels = np.array(["test"])
sofa.verify()


Expand Down
8 changes: 4 additions & 4 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,10 @@ def test_equals_global_parameters():
("1", "2", "GLOBAL_SOFAConventionsVersion", True),
([[1, 2]], [1, 2], "Data_IR", False),
([[1, 2]], [1, 3], "Data_IR", True),
("HD 650", ["HD 650"], "SourceModel", False),
("HD 650", np.array(["HD 650"], dtype="U"), "SourceModel", False),
("HD 650", np.array(["HD 650"], dtype="S"), "SourceModel", False),
("HD 650", "HD-650", "SourceModel", True),
("HD 650", ["HD 650"], "SourceModels", False),
("HD 650", np.array(["HD 650"], dtype="U"), "SourceModels", False),
("HD 650", np.array(["HD 650"], dtype="S"), "SourceModels", False),
("HD 650", "HD-650", "SourceModels", True),
])
def test_equals_attribute_values(value_a, value_b, attribute, fails):

Expand Down