<commit_before>"""
tests knn module
"""

import os
from glob import glob

import numpy as np

import hvc.audiofileIO
from hvc.features import knn


class TestKNN:
    """
    unit tests that specifically test functions
    for getting features for k-Nearest Neighbors
    """

    def test_duration(self, test_data_dir):
        """test duration
        """
        songfiles_dir = os.path.join(test_data_dir,
                                 os.path.normpath('cbins/gy6or6/032412/*.cbin'))
        songfiles_list = glob(songfiles_dir)
        first_song = songfiles_list[0]
        first_song_notmat = first_song + '.not.mat'
        notmat_dict = hvc.evfuncs.load_notmat(first_song_notmat)

        dur = knn.duration(notmat_dict['onsets']/1000,
                           notmat_dict['offsets']/1000,
                           np.ones(notmat_dict['onsets'].shape).astype(bool))
<commit_msg>flesh out / rewrite tests/unit_test/test_knn.py<commit_after>"""
tests knn module
"""

import os
from glob import glob

import pytest
import numpy as np

import hvc.audiofileIO
import hvc.evfuncs
from hvc.parse.ref_spect_params import refs_dict
from hvc.features import knn


@pytest.fixture
def notmat_dict(test_data_dir):
    songfiles_dir = os.path.join(test_data_dir,
                                 os.path.normpath('cbins/gy6or6/032412/*.cbin'))
    songfiles_list = glob(songfiles_dir)
    first_song = songfiles_list[0]
    notmat_dict = hvc.evfuncs.load_notmat(first_song)
    return notmat_dict


@pytest.fixture
def some_syllables(test_data_dir):
    songfiles_dir = os.path.join(test_data_dir,
                                 os.path.normpath('cbins/gy6or6/032412/*.cbin'))
    songfiles_list = glob(songfiles_dir)
    first_song = songfiles_list[0]
    annot_dict = hvc.utils.annotation.notmat_to_annot_dict(notmat=first_song + '.not.mat')

    spect_params = refs_dict['evsonganaly']
    spect_maker = hvc.audiofileIO.Spectrogram(**spect_params)
    raw_song, samp_freq = hvc.evfuncs.load_cbin(first_song)

    some_syllables = hvc.audiofileIO.make_syls(raw_audio=raw_song,
                                               samp_freq=samp_freq,
                                               spect_maker=spect_maker,
                                               onsets_Hz=annot_dict['onsets_Hz'],
                                               offsets_Hz=annot_dict['offsets_Hz'],
                                               labels=annot_dict['labels'])
    return some_syllables


class TestDurationFeatures():
    def _assert_dur_features(self,
                             notmat_dict,
                             dur_type_func):
        """tests to perform on all duration-type features,
        i.e, duration, pre-syllable duration, following-syllable duration,
        silent-gap durations, etc."""
        ftr = dur_type_func(notmat_dict['onsets']/1000,
                            notmat_dict['offsets']/1000,
                            np.ones(notmat_dict['onsets'].shape).astype(bool))

        assert type(ftr) == np.ndarray
        assert ftr.dtype == np.asarray([1.]).dtype 

    def test_duration(self, notmat_dict):
        self._assert_dur_features(notmat_dict, knn.duration)

    def test_pre_duration(self, notmat_dict):
        self._assert_dur_features(notmat_dict, knn.pre_duration)

    def test_foll_duration(self, notmat_dict):
        self._assert_dur_features(notmat_dict, knn.foll_duration)

    def test_pre_gapdur(self, notmat_dict):
        self._assert_dur_features(notmat_dict, knn.pre_gapdur)

    def test_foll_gapdur(self, notmat_dict):
        self._assert_dur_features(notmat_dict, knn.foll_gapdur)


class ScalarFeaturesTestClass:
    def _assert_scalar_features(self,
                                a_list_of_syllables,
                                scalar_type_func):
        """tests to perform on all scalar features extracted from spectrograms"""
        for a_syllable in a_list_of_syllables:
            out = scalar_type_func(a_syllable)
            assert np.isscalar(out)


class TestMeanAmpSmoothRect(ScalarFeaturesTestClass):
    def test_mn_amp_smooth_rect(self, some_syllables):
        self._assert_scalar_features(some_syllables,
                                     knn.mn_amp_smooth_rect)


class TestDeltaAmpSmoothRect(ScalarFeaturesTestClass):
    def test_delta_amp_smooth_rect(self, some_syllables):
        self._assert_scalar_features(some_syllables,
                                     knn.delta_amp_smooth_rect)


class TestMeanSpectralEntropy(ScalarFeaturesTestClass):
    def test_mean_spectral_entropy(self, some_syllables):
        self._assert_scalar_features(some_syllables,
                                     knn.mean_spect_entropy)


class TestDeltaEntropy(ScalarFeaturesTestClass):
    def test_delta_entropy(self, some_syllables):
        self._assert_scalar_features(some_syllables,
                                     knn.delta_entropy)


class TestMeanHiLoRatio(ScalarFeaturesTestClass):
    def test_mean_hi_lo_ratio(self, some_syllables):
        self._assert_scalar_features(some_syllables,
                                     knn.mean_hi_lo_ratio)


{'fraction_non_alphanumeric': 0.0811335403726708, 'fraction_numerical': 0.008540372670807454, 'mean_word_length': 2.392363396971692, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4794858', 'n_tokens_mistral': 1671, 'n_tokens_neox': 1587, 'n_words': 245}