HomeMAL' // MANUFACTORUM
datacrypt
Localizer / tests / test_pipeline.py
tests/test_pipeline.py1.8 KB
import numpy as np
import pytest

from localizer.pipeline import Localizer
from localizer.config import PipelineConfig
from fixtures import synth_database_dir, synth_brir, SAMPLE_RATE


@pytest.fixture(scope="module")
def localizer(tmp_path_factory):
    db_dir = synth_database_dir(tmp_path_factory.mktemp("db"))
    return Localizer.from_database_path(db_dir, config=PipelineConfig())


def test_database_loaded(localizer):
    assert localizer.database.num_templates == 12
    assert set(localizer.database.azimuths.astype(int)) >= {-90, 0, 30, 90}


@pytest.mark.parametrize("true_az", [-90, -60, -30, 0, 30, 60, 90, 120])
def test_specialized_lateral_angle(localizer, true_az):
    result = localizer.analyze(synth_brir(true_az))
    # The lateral angle should match the true source's lateral fold within one DB step.
    from localizer.database import lateral_angle

    expected_lateral = lateral_angle(true_az)
    assert abs(result.specialized.lateral_angle - expected_lateral) <= 30


@pytest.mark.parametrize("true_az", [-60, -30, 30, 60])
def test_front_hemisphere(localizer, true_az):
    # Clearly frontal sources (exclude ±90 and ±180 which are ambiguous).
    result = localizer.analyze(synth_brir(true_az))
    assert result.specialized.front is True


@pytest.mark.parametrize("true_az", [-150, -120, 120, 150])
def test_back_hemisphere(localizer, true_az):
    result = localizer.analyze(synth_brir(true_az))
    assert result.specialized.front is False


def test_both_approaches_present(localizer):
    result = localizer.analyze(synth_brir(45))
    assert set(result.approaches) == {"global", "specialized"}
    summary = result.summary()
    assert "specialized" in summary and "global" in summary


def test_summary_is_json_serializable(localizer):
    import json

    result = localizer.analyze(synth_brir(-30))
    json.dumps(result.summary())  # must not raise