<commit_before>#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# CREATED:2016-02-16 15:40:04 by <NAME> <<EMAIL>>
r'''
Namespace conversion
====================

.. autosummary::
    :toctree: generated

    convert
'''

import numpy as np

from copy import deepcopy
from collections import defaultdict
from .exceptions import NamespaceError

# The structure that handles all conversion mappings
__CONVERSION__ = defaultdict(defaultdict)

__all__ = ['convert']

def _conversion(target, source):
    '''A decorator to register namespace conversions.

    Usage
    -----
    >>> @conversion('tag_open', 'tag_.*')
    ... def tag_to_open(annotation):
    ...     annotation.namespace = 'tag_open'
    ...     return annotation
    '''

    def register(func):
        '''This decorator registers func as mapping source to target'''
        __CONVERSION__[target][source] = func
        return func

    return register


def convert(annotation, target_namespace):
    '''Convert a given annotation to the target namespace.

    Parameters
    ----------
    annotation : jams.Annotation
        An annotation object

    target_namespace : str
        The target namespace

    Returns
    -------
    mapped_annotation : jams.Annotation
        if `annotation` already belongs to `target_namespace`, then
        it is returned directly.

        otherwise, `annotation` is copied and automatically converted
        to the target namespace.

    Raises
    ------
    SchemaError
        if the input annotation fails to validate
    
    NamespaceError
        if no conversion is possible

    Examples
    --------
    Convert frequency measurements in Hz to MIDI

    >>> ann_midi = jams.convert(ann_hz, 'pitch_midi')

    And back to Hz

    >>> ann_hz2 = jams.convert(ann_midi, 'pitch_hz')
    '''

    # First, validate the input. If this fails, we can't auto-convert.
    annotation.validate(strict=True)

    # If we're already in the target namespace, do nothing
    if annotation.namespace == target_namespace:
        return annotation

    if target_namespace in __CONVERSION__:
        # Otherwise, make a copy to mangle
        annotation = deepcopy(annotation)

        # Look for a way to map this namespace to the target
        for source in __CONVERSION__[target_namespace]:
            if annotation.search(namespace=source):
                return __CONVERSION__[target_namespace][source](annotation)

    # No conversion possible
    raise NamespaceError('Unable to convert annotation from namespace='
                         '"{0}" to "{1}"'.format(annotation.namespace,
                                                 target_namespace))


@_conversion('pitch_hz', 'pitch_midi')
def midi_to_hz(annotation):
    '''Convert a pitch_midi annotation to pitch_hz'''

    annotation.namespace = 'pitch_hz'
    annotation.data.value = 440 * (2.0 ** ((annotation.data.value - 69.0)/12.0))<commit_msg>added conversion checker<commit_after>#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# CREATED:2016-02-16 15:40:04 by <NAME> <<EMAIL>>
r'''
Namespace conversion
====================

.. autosummary::
    :toctree: generated

    convert
'''

import numpy as np

from copy import deepcopy
from collections import defaultdict
from .exceptions import NamespaceError

# The structure that handles all conversion mappings
__CONVERSION__ = defaultdict(defaultdict)

__all__ = ['convert', 'can_convert']

def _conversion(target, source):
    '''A decorator to register namespace conversions.

    Usage
    -----
    >>> @conversion('tag_open', 'tag_.*')
    ... def tag_to_open(annotation):
    ...     annotation.namespace = 'tag_open'
    ...     return annotation
    '''

    def register(func):
        '''This decorator registers func as mapping source to target'''
        __CONVERSION__[target][source] = func
        return func

    return register


def convert(annotation, target_namespace):
    '''Convert a given annotation to the target namespace.

    Parameters
    ----------
    annotation : jams.Annotation
        An annotation object

    target_namespace : str
        The target namespace

    Returns
    -------
    mapped_annotation : jams.Annotation
        if `annotation` already belongs to `target_namespace`, then
        it is returned directly.

        otherwise, `annotation` is copied and automatically converted
        to the target namespace.

    Raises
    ------
    SchemaError
        if the input annotation fails to validate
    
    NamespaceError
        if no conversion is possible

    Examples
    --------
    Convert frequency measurements in Hz to MIDI

    >>> ann_midi = jams.convert(ann_hz, 'pitch_midi')

    And back to Hz

    >>> ann_hz2 = jams.convert(ann_midi, 'pitch_hz')
    '''

    # First, validate the input. If this fails, we can't auto-convert.
    annotation.validate(strict=True)

    # If we're already in the target namespace, do nothing
    if annotation.namespace == target_namespace:
        return annotation

    if target_namespace in __CONVERSION__:
        # Otherwise, make a copy to mangle
        annotation = deepcopy(annotation)

        # Look for a way to map this namespace to the target
        for source in __CONVERSION__[target_namespace]:
            if annotation.search(namespace=source):
                return __CONVERSION__[target_namespace][source](annotation)

    # No conversion possible
    raise NamespaceError('Unable to convert annotation from namespace='
                         '"{0}" to "{1}"'.format(annotation.namespace,
                                                 target_namespace))


def can_convert(annotation, target_namespace):
    '''Test if an annotation can be mapped to a target namespace

    Parameters
    ----------
    annotation : jams.Annotation
        An annotation object

    target_namespace : str
        The target namespace

    Returns
    -------
    True
        if `annotation` can be automatically converted to
        `target_namespace`

    False
        otherwise
    '''

    # If we're already in the target namespace, do nothing
    if annotation.namespace == target_namespace:
        return True

    if target_namespace in __CONVERSION__:
        # Look for a way to map this namespace to the target
        for source in __CONVERSION__[target_namespace]:
            if annotation.search(namespace=source):
                return True
    return False


@_conversion('pitch_hz', 'pitch_midi')
def midi_to_hz(annotation):
    '''Convert a pitch_midi annotation to pitch_hz'''

    annotation.namespace = 'pitch_hz'
    annotation.data.value = 440 * (2.0 ** ((annotation.data.value - 69.0)/12.0))
{'fraction_non_alphanumeric': 0.10019499025048748, 'fraction_numerical': 0.008699565021748913, 'mean_word_length': 2.546808510638298, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '461770', 'n_tokens_mistral': 1845, 'n_tokens_neox': 1686, 'n_words': 568}