diff --git a/.gitattributes b/.gitattributes index 1691f22..44bbd3c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,4 @@ *.png filter=lfs diff=lfs merge=lfs -text *.jpg filter=lfs diff=lfs merge=lfs -text +*.frd filter=lfs diff=lfs merge=lfs -text +*.zma filter=lfs diff=lfs merge=lfs -text diff --git a/src/python/akustik/speaker/dats.py b/src/python/akustik/speaker/dats.py index 103c73a..df4b199 100644 --- a/src/python/akustik/speaker/dats.py +++ b/src/python/akustik/speaker/dats.py @@ -11,25 +11,7 @@ from akustik.plot.style import default_styles -def read_dats_frequency_response(path): - return pd.read_csv( - path, - sep="\t", - header=None, - names=["Frequency", "SPL", "Phase"] - ) - - -def read_dats_impedance_response(path): - return pd.read_csv( - path, - sep="\t", - header=None, - names=["Frequency", "Impedance", "Phase"] - ) - - -def axes_style(ax: Axes, fmin, fmax): +def _axes_style(ax: Axes, fmin, fmax): formatter = ScalarFormatter() formatter.set_scientific(False) ax.xaxis.set_major_formatter(formatter) @@ -49,13 +31,36 @@ def max_impedance(Z: np.ndarray, f: np.ndarray): return Z[Zmax_index], f[Zmax_index] -def ensure_absolute_path(paths): - paths = [pathlib.Path(path).absolute() for path in paths] - return paths +def read_dats_frequency_response(path): + return pd.read_csv( + path, + sep="\t", + header=None, + names=["Frequency", "SPL", "Phase"] + ) + + +def read_dats_impedance_response(path): + return pd.read_csv( + path, + sep="\t", + header=None, + names=["Frequency", "Impedance", "Phase"] + ) + + +def read_dats_folder(folder): + folder = pathlib.Path(folder) + frd_files = glob.glob(str(folder/"FRD"/"*.frd")) + zma_files = glob.glob(str(folder/"ZMA"/"*.zma")) + + name = pathlib.Path(zma_files[0]).stem + frd = read_dats_frequency_response(frd_files[0]) + zma = read_dats_impedance_response(zma_files[0]) + return name, frd, zma def main(dats_dirs, fmin, fmax): - dats_dirs = ensure_absolute_path(dats_dirs) data = { "name": [], "acoustic": { @@ -70,24 +75,20 @@ def main(dats_dirs, fmin, fmax): }, } - for dats_dir in dats_dirs: - frd_files = glob.glob(str(dats_dir/"FRD"/"*.frd")) - zma_files = glob.glob(str(dats_dir/"ZMA"/"*.zma")) - - FR = read_dats_frequency_response(frd_files[0]) - IR = read_dats_impedance_response(zma_files[0]) + for folder in dats_dirs: + name, frd, zma = read_dats_folder(folder) - data["name"].append(pathlib.Path(zma_files[0]).stem) - data["acoustic"]["freq"].append(FR["Frequency"].to_numpy()) - data["acoustic"]["spl"].append(FR["SPL"].to_numpy()) - data["acoustic"]["phase"].append(FR["Phase"].to_numpy()) - data["electric"]["freq"].append(IR["Frequency"].to_numpy()) - data["electric"]["impedance"].append(IR["Impedance"].to_numpy()) - data["electric"]["phase"].append(IR["Phase"].to_numpy()) + data["name"].append(name) + data["acoustic"]["freq"].append(frd["Frequency"].to_numpy()) + data["acoustic"]["spl"].append(frd["SPL"].to_numpy()) + data["acoustic"]["phase"].append(frd["Phase"].to_numpy()) + data["electric"]["freq"].append(zma["Frequency"].to_numpy()) + data["electric"]["impedance"].append(zma["Impedance"].to_numpy()) + data["electric"]["phase"].append(zma["Phase"].to_numpy()) Re = 3.24 - Z: np.ndarray = IR["Impedance"].to_numpy() - f: np.ndarray = IR["Frequency"].to_numpy() + Z: np.ndarray = zma["Impedance"].to_numpy() + f: np.ndarray = zma["Frequency"].to_numpy() assert f.shape == Z.shape Zmax, freq = max_impedance(Z, f) @@ -137,8 +138,8 @@ def plot(ax: Axes, x, y): plot(ax, data["electric"]["freq"], data["electric"]["phase"]) ax.set_ylabel('Phase [Degree]') - axes_style(axs[0][0], fmin, fmax) - axes_style(axs[1][0], fmin, fmax) - axes_style(axs[0][1], fmin, fmax) - axes_style(axs[1][1], fmin, fmax) + _axes_style(axs[0][0], fmin, fmax) + _axes_style(axs[1][0], fmin, fmax) + _axes_style(axs[0][1], fmin, fmax) + _axes_style(axs[1][1], fmin, fmax) plt.show() diff --git a/src/python/tests/data/dats/README.md b/src/python/tests/data/dats/README.md new file mode 100644 index 0000000..816b250 --- /dev/null +++ b/src/python/tests/data/dats/README.md @@ -0,0 +1,3 @@ +# Dayton Audio Test System (DATS) + +Folders are downloaded from the main [Dayton Audio](https://daytonaudio.com) website. Unused files are removed. diff --git a/src/python/tests/data/dats/RSS390HF-4/FRD/RSS390HF-4@0.frd b/src/python/tests/data/dats/RSS390HF-4/FRD/RSS390HF-4@0.frd new file mode 100644 index 0000000..ee3b08b --- /dev/null +++ b/src/python/tests/data/dats/RSS390HF-4/FRD/RSS390HF-4@0.frd @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b73f180fda6e74486d547e76a2e3e8fc00494fe20daed49a493465b063b5c08d +size 9006 diff --git a/src/python/tests/data/dats/RSS390HF-4/ZMA/RSS390HF-4.zma b/src/python/tests/data/dats/RSS390HF-4/ZMA/RSS390HF-4.zma new file mode 100644 index 0000000..1646827 --- /dev/null +++ b/src/python/tests/data/dats/RSS390HF-4/ZMA/RSS390HF-4.zma @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4fc8f78df878ca8a15852f4808494a1eae6eb2f8093a43425738df63c5c7a69b +size 10301 diff --git a/src/python/tests/test_speaker_dats.py b/src/python/tests/test_speaker_dats.py new file mode 100644 index 0000000..e3571fb --- /dev/null +++ b/src/python/tests/test_speaker_dats.py @@ -0,0 +1,18 @@ +import numpy as np + +from akustik.speaker.dats import ( + max_impedance, + read_dats_folder, +) + + +def test_max_sound_pressure(): + folder = "src/python/tests/data/dats/RSS390HF-4" + name, frd, zma = read_dats_folder(folder) + assert name == "RSS390HF-4" + assert frd.shape == (416, 3) + assert zma.shape == (344, 3) + + Z: np.ndarray = zma["Impedance"].to_numpy() + f: np.ndarray = zma["Frequency"].to_numpy() + assert np.allclose(max_impedance(Z, f), (21.173, 19.585))