Exemple #1
0
 def time(self, val):
     if viscid.is_datetime_like(val):
         val = viscid.as_timedelta(self.basetime - viscid.as_datetime64(val))
         val = val.total_seconds()
     elif viscid.is_timedelta_like(val, conservative=True):
         val = viscid.as_timedelta(val).total_seconds()
     elif val is not None:
         self.set_info('time', float(val))
Exemple #2
0
 def time(self, val):
     if viscid.is_datetime_like(val):
         val = viscid.as_timedelta(self.basetime -
                                   viscid.as_datetime64(val))
         val = val.total_seconds()
     elif viscid.is_timedelta_like(val, conservative=True):
         val = viscid.as_timedelta(val).total_seconds()
     elif val is not None:
         self.set_info('time', float(val))
Exemple #3
0
def convert_timelike(value):
    if value in (None, ''):
        return None
    elif viscid.is_datetime_like(value, conservative=True):
        return viscid.as_datetime64(value)
    elif viscid.is_timedelta_like(value, conservative=True):
        return viscid.as_timedelta64(value)
    else:
        return value
Exemple #4
0
    def as_floating_t(self, t, none_passthrough=False):
        t_as_s = None
        try:
            t = vutil.str_to_value(t)

            if viscid.is_timedelta_like(t, conservative=True):
                t_as_s = viscid.as_timedelta(t).total_seconds()
            elif viscid.is_datetime_like(t, conservative=True):
                delta_t = viscid.as_datetime64(t) - self.basetime
                t_as_s = viscid.as_timedelta(delta_t).total_seconds()
            elif not isinstance(t, (int, np.integer, type(None))):
                t_as_s = float(t)
        except AttributeError:
            if t is None:
                if none_passthrough:
                    pass
                else:
                    t = 0.0
            else:
                t_as_s = float(t)

        return t_as_s
Exemple #5
0
    def as_floating_t(self, t, none_passthrough=False):
        t_as_s = None
        try:
            t = vutil.str_to_value(t)

            if viscid.is_timedelta_like(t, conservative=True):
                t_as_s = viscid.as_timedelta(t).total_seconds()
            elif viscid.is_datetime_like(t, conservative=True):
                delta_t = viscid.as_datetime64(t) - self.basetime
                t_as_s = viscid.as_timedelta(delta_t).total_seconds()
            elif not isinstance(t, (int, np.integer, type(None))):
                t_as_s = float(t)
        except AttributeError:
            if t is None:
                if none_passthrough:
                    pass
                else:
                    t = 0.0
            else:
                t_as_s = float(t)

        return t_as_s
Exemple #6
0
def extract_index(arr, start=None, stop=None, step=None, endpoint=True,
                  tol=100):
    """Get integer indices for slice parts

    If start, stop, or step are strings, they are either cast to
    integers or used for a float lookup if they have a trailing 'f'.

    An example float lookup is::
        >>> [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]['0.2f:0.6f:2']
        [0.2, 0.4, 0.6]

    The rules for float lookup endpoints are:
        - The slice will never include an element whose value in arr
          is < start (or > if the slice is backward)
        - The slice will never include an element whose value in arr
          is > stop (or < if the slice is backward)
        - !! The slice WILL INCLUDE stop if you don't change endpoint.
          This is different from normal slicing, but
          it's more natural when specifying a slice as a float.
          To this end, an epsilon tolerance can be given to
          determine what's close enough.
        - TODO: implement floating point steps, this is tricky
          since arr need not be uniformly spaced, so step is
          ambiguous in this case

    Args:
        arr (ndarray): filled with floats to do the lookup
        start (None, int, str): like slice().start
        stop (None, int, str): like slice().stop
        step (None, int): like slice().step
        endpoint (bool): iff True then include stop in the slice.
            Set to False to get python slicing symantics when it
            comes to excluding stop, but fair warning, python
            symantics feel awkward here. Consider the case
            [0.1, 0.2, 0.3][:0.25]. If you think this should include
            0.2, then leave keep endpoint=True.
        tol (int): number of machine epsilons to consider
            "close enough"

    Returns:
        start, stop, step after floating point vals have been
        converted to integers
    """
    float_err_msg = ("Slicing by floats is no longer supported. If you "
                     "want to slice by location, suffix the value with "
                     "'f', as in 'x = 0f'.")
    arr = np.asarray(arr)
    try:
        epsilon = tol * np.finfo(arr.dtype).eps
    except ValueError:
        # array is probably of type numpy.int*
        epsilon = 0.01

    _step = 1 if step is None else int(step)
    epsilon_step = epsilon if _step > 0 else -epsilon

    start = convert_timelike(start)
    stop = convert_timelike(stop)

    start = convert_deprecated_floats(start, "start")
    stop = convert_deprecated_floats(stop, "stop")

    # print("?!? |{0}|  |{1}|".format(start, stop))

    startstop = [start, stop]
    eps_sign = [1, -1]

    # if start or stop is not an int, try to make it one
    for i in range(2):
        byval = None
        s = startstop[i]
        _epsilon_step = epsilon_step

        if viscid.is_datetime_like(s, conservative=True):
            byval = s.astype(arr.dtype)
            _epsilon_step = 0
        elif viscid.is_timedelta_like(s, conservative=True):
            byval = s.astype(arr.dtype)
            _epsilon_step = 0
        else:
            try:
                s = s.strip()
                if len(s) == 0:
                    startstop[i] = None
                elif s[-1] == 'f':
                    byval = float(s[:-1])
            except AttributeError:
                pass

        if byval is not None:
            if _epsilon_step:
                diff = arr - byval + (eps_sign[i] * _epsilon_step)
            else:
                diff = arr - byval
            zero = np.array([0]).astype(diff.dtype)[0]

            # FIXME: there is far too much decision making here
            if i == 0:
                # start
                if _step > 0:
                    diff = np.ma.masked_less(diff, zero)
                else:
                    diff = np.ma.masked_greater(diff, zero)

                if np.ma.count(diff) == 0:
                    # start value is past the wrong end of the array
                    if _step > 0:
                        startstop[i] = len(arr)
                    else:
                        # start = -len(arr) - 1
                        # having a value < -len(arr) won't play
                        # nice with make_fwd_slice, but in this
                        # case, the slice will have no data, so...
                        return 0, 0, step
                else:
                    startstop[i] = int(np.argmin(np.abs(diff)))
            else:
                # stop
                if _step > 0:
                    diff = np.ma.masked_greater(diff, zero)
                    if np.ma.count(diff) == 0:
                        # stop value is past the wong end of the array
                        startstop[i] = 0
                    else:
                        startstop[i] = int(np.argmin(np.abs(diff)))
                        if endpoint:
                            startstop[i] += 1
                else:
                    diff = np.ma.masked_less(diff, zero)
                    if np.ma.count(diff) == 0:
                        # stop value is past the wrong end of the array
                        startstop[i] = len(arr)
                    else:
                        startstop[i] = int(np.argmin(np.abs(diff)))
                        if endpoint:
                            if startstop[i] > 0:
                                startstop[i] -= 1
                            else:
                                # 0 - 1 == -1 which would wrap to the end of
                                # of the array... instead, just make it None
                                startstop[i] = None
    start, stop = startstop

    # turn start, stop, step into indices
    sss = [start, stop, step]
    for i, s in enumerate(sss):
        if s is None:
            pass
        elif isinstance(s, string_types):
            sss[i] = int(s)
        else:
            sss[i] = s.__index__()
    return sss