Source code for irfpy.util.span

''' Module related to span (interval).

.. codeauthor:: Yoshifumi Futaana

The code depends on ``sympy`` package.  Version 1.5.1 is recommended (2020-03-27).
'''
import sympy

from irfpy.util import timeinterval
from irfpy.util import version as _v

_v.recommends("1.5.1", sympy.__version__, "sympy")

def _get_empty_set():
    try:
        e = sympy.EmptySet()
    except TypeError:
        e = sympy.EmptySet

    return e


[docs]def array2interval(true_false_array, sorted_array=None): ''' Two arrays are converted to ``interval.IntervalSet``. :param true_false_array: An array that contains ``true`` and ``false``. :param sorted_array: An array that contains number. Each component should be comparable each other. The array should be sorted from small to large. In case of ``None``, index is used. >>> tfarr = [False, False, False, True, True, True, True, False, True, True, True] >>> numarr = [1.5, 2.8, 2.9, 3.5, 3.8, 3.9, 5.1, 5.8, 5.9, 6.1, 6.3] In the above case, 3.5 (index 3) to 5.1 (index 6) and 5.9 to 6.3 (last 3 elements) is true, so that >>> intrv = array2interval(tfarr, numarr) >>> print((3.4 in intrv), (3.5 in intrv)) False True >>> print((5.1 in intrv), (5.2 in intrv)) True False >>> print((5.8 in intrv), (5.9 in intrv)) False True >>> print((6.3 in intrv), (6.4 in intrv)) True False If only ``true_false_array`` is given, the index (3-6 and 8-10) is used. >>> intrv = array2interval(tfarr) >>> print((2 in intrv), (3 in intrv)) False True >>> print((6 in intrv), (7 in intrv)) True False >>> print((7 in intrv), (8 in intrv)) False True >>> print((10 in intrv), (11 in intrv)) True False ''' if sorted_array is None: sorted_array = list(range(len(true_false_array))) if len(true_false_array) != len(sorted_array): raise ValueError('Given arrays have different length. (%d and %d)' % (len(true_false_array), len(sorted_array))) n = len(true_false_array) idx0 = None prevtf = true_false_array[0] if prevtf: idx0 = 0 intervalset = _get_empty_set() for i in range(1, n): nowtf = true_false_array[i] if nowtf: if prevtf: pass else: idx0 = i else: if prevtf: intvl = sympy.Interval(sorted_array[idx0], sorted_array[i - 1]) intervalset += intvl idx0 = None else: pass prevtf = nowtf if idx0 is not None: # Still in the true span intvl = sympy.Interval(sorted_array[idx0], sorted_array[-1]) intervalset += intvl return intervalset
[docs]def timearray2interval(true_false_array, time_array): """ :param true_false_array: List of "True" or "False" :type true_false_array: list of boolean :param time_array: List of ``datetime.datetime``. :type time_array: list of ``datetime.datetime`` :return: The time interval corresponding to the true_false_array. :rtype: :class:`irfpy.util.timeinterval.timeinterval` """ if len(true_false_array) != len(time_array): raise ValueError('Given arrays have different length. (%d and %d)' % (len(true_false_array), len(time_array))) n = len(true_false_array) idx0 = None prevtf = true_false_array[0] if prevtf: idx0 = 0 intervalset = timeinterval.empty_interval() for i in range(1, n): nowtf = true_false_array[i] if nowtf: if prevtf: pass else: idx0 = i else: if prevtf: intvl = timeinterval.timeinterval(time_array[idx0], time_array[i - 1]) intervalset += intvl idx0 = None else: pass prevtf = nowtf if idx0 is not None: # Still in the true span intvl = timeinterval.timeinterval(time_array[idx0], time_array[-1]) intervalset += intvl return intervalset