53 lines
2.0 KiB
Python
53 lines
2.0 KiB
Python
from typing import Optional
|
|
|
|
import numpy as np
|
|
|
|
|
|
def get_timeline(range_max: int, dtype: Optional[np.dtype] = None) -> np.ndarray:
|
|
"""Returns timeline array for requirements.
|
|
|
|
Parameters
|
|
----------
|
|
range_max : int
|
|
Largest value in range. Assume `range(range_max)`. Commonly that's length of the signal.
|
|
dtype : np.dtype
|
|
Minimal definition type. Returned timeline will have dtype that's the same or with higher byte size.
|
|
|
|
"""
|
|
timeline = np.arange(0, range_max, dtype=dtype)
|
|
if timeline[-1] != range_max - 1:
|
|
inclusive_dtype = smallest_inclusive_dtype(timeline.dtype, range_max)
|
|
timeline = np.arange(0, range_max, dtype=inclusive_dtype)
|
|
return timeline
|
|
|
|
|
|
def smallest_inclusive_dtype(ref_dtype: np.dtype, ref_value) -> np.dtype:
|
|
"""Returns a numpy dtype with the same base as reference dtype (ref_dtype)
|
|
but with the range that includes reference value (ref_value).
|
|
|
|
Parameters
|
|
----------
|
|
ref_dtype : dtype
|
|
Reference dtype. Used to select the base, i.e. int or float, for returned type.
|
|
ref_value : value
|
|
A value which needs to be included in returned dtype. Value will be typically int or float.
|
|
|
|
"""
|
|
# Integer path
|
|
if np.issubdtype(ref_dtype, np.integer):
|
|
for dtype in [np.uint16, np.uint32, np.uint64]:
|
|
if ref_value < np.iinfo(dtype).max:
|
|
return dtype
|
|
max_val = np.iinfo(np.uint32).max
|
|
raise ValueError("Requested too large integer range. Exceeds max( uint64 ) == '{}.".format(max_val))
|
|
|
|
# Integer path
|
|
if np.issubdtype(ref_dtype, np.floating):
|
|
for dtype in [np.float16, np.float32, np.float64]:
|
|
if ref_value < np.finfo(dtype).max:
|
|
return dtype
|
|
max_val = np.finfo(np.float64).max
|
|
raise ValueError("Requested too large integer range. Exceeds max( float64 ) == '{}.".format(max_val))
|
|
|
|
raise ValueError("Unsupported dtype '{}'. Only intX and floatX are supported.".format(ref_dtype))
|