예제 #1
0
def test_array_fft_invalid_axis():

    for invalid_axis in [2, -3]:
        with pytest.raises(ValueError, match="invalid axis index"):
            GridArray.from_array(
                np.arange(100).reshape((10, 10)),
                axes=[Axis.from_array(np.arange(10))] * 2,
            ).fft(axes=[invalid_axis])

    for invalid_axis in ["axis2", "abc"]:
        with pytest.raises(ValueError, match="could not be found"):
            GridArray.from_array(
                np.arange(100).reshape((10, 10)),
                axes=[Axis.from_array(np.arange(10))] * 2,
            ).fft(axes=[invalid_axis])
예제 #2
0
def slice_grid_array(
    grid: GridArray,
    constant: Union[str, int],
    value: float,
) -> GridArray:
    """
    Takes a slice of a `GridArray` at a constant value of a given axis.

    Arguments:
        constant:
            Name or index that defines the axis taken to be constant in the slice.
        value:
            Value of the axis at which the slice is taken.

    Returns:
        Slice of ``grid``.

    Examples:
        Obtain a slice of a two-dimensional array.

        ```pycon
        >>> from nata.containers import GridArray
        >>> from nata.containers import Axis
        >>> import numpy as np
        >>> x = np.arange(5)
        >>> data = np.arange(25).reshape((5, 5))
        >>> grid = GridArray.from_array(data, axes=[Axis(x), Axis(x)])
        >>> grid.slice(constant=0, value=1).to_numpy()
        array([5, 6, 7, 8, 9]) # the second column
        >>> grid.slice(constant=1, value=1).to_numpy()
        array([ 1,  6, 11, 16, 21]) # the second row
        ```
    """

    if grid.ndim < 1:
        raise ValueError("slice is not available for 0 dimensional GridArrays")

    # get slice axis
    slice_axis = get_slice_axis(grid, constant)

    axis = grid.axes[slice_axis]

    if value < np.min(axis.to_dask()) or value >= np.max(axis.to_dask()):
        raise ValueError(f"out of range value for axis '{constant}'")

    # get index of nearest neighbour
    slice_idx = (np.abs(axis.to_dask() - value)).argmin(axis=-1)

    # build data slice
    data_slice = [slice(None)] * len(grid.axes)
    data_slice[slice_axis] = slice_idx

    return GridArray.from_array(
        grid.to_dask()[tuple(data_slice)],
        name=grid.name,
        label=grid.label,
        unit=grid.unit,
        axes=[ax for key, ax in enumerate(grid.axes) if ax is not axis],
        time=grid.time,
    )
예제 #3
0
def test_array_fft_peak_1d():
    x = np.linspace(0, 10 * np.pi, 101)
    grid = GridArray.from_array(np.sin(x), axes=[Axis.from_array(x)])
    fft_grid = grid.fft()

    assert (fft_grid.to_dask().argmax() == (np.abs(fft_grid.axes[0].to_dask() +
                                                   1)).argmin())
예제 #4
0
def test_array_transpose_data():

    data = np.arange(7 * 6 * 5).reshape((7, 6, 5))
    grid = GridArray.from_array(data)

    tr_grid = grid.transpose(axes=[1, 2, 0])

    np.testing.assert_array_equal(tr_grid, np.transpose(data, axes=[1, 2, 0]))
예제 #5
0
def test_GridArray_repr():
    grid = GridArray.from_array(np.arange(12, dtype=np.int32).reshape((4, 3)))
    expected_repr = ("GridArray<"
                     "shape=(4, 3), "
                     "dtype=int32, "
                     "time=None, "
                     "axes=(Axis(axis0), Axis(axis1))"
                     ">")
    assert repr(grid) == expected_repr
예제 #6
0
def test_GridArray_ufunc_proxy():
    grid = GridArray.from_array([1, 2])

    # creation of new object
    np.testing.assert_array_equal(grid + 1, [2, 3])

    # in-place operation
    grid += 1
    np.testing.assert_array_equal(grid, [2, 3])
예제 #7
0
def test_array_fft_comps_1d():
    x = np.linspace(0, 10 * np.pi, 101)
    grid = GridArray.from_array(np.sin(x), axes=[Axis.from_array(x)])

    for comp, fn in zip(["full", "real", "imag", "abs"],
                        [lambda x: x, np.real, np.imag, np.abs]):
        fft_grid = grid.fft(comp=comp)
        fft_data = fft.fftshift(fft.fftn(grid.to_dask()))
        np.testing.assert_array_equal(fft_grid.to_dask(), fn(fft_data))
예제 #8
0
def test_GridArray_getitem(case):
    arr = np.array(case["arr"])
    indexing = case["indexing"]
    expected_arr = case["expected_arr"] if "expected_arr" in case else arr[
        indexing]
    expected_axes = case["expected_axes"] if "expected_axes" in case else None

    grid = GridArray.from_array(arr)
    subgrid = grid[indexing]
    expected_grid = GridArray.from_array(expected_arr, axes=expected_axes)

    for ax, expected_ax in zip(subgrid.axes, expected_grid.axes):
        assert ax.name == expected_ax.name
        assert ax.label == expected_ax.label
        assert ax.unit == expected_ax.unit
        np.testing.assert_array_equal(ax, expected_ax)

    np.testing.assert_array_equal(subgrid, expected_grid)
예제 #9
0
def test_array_slice_dimensionality():
    grid = GridArray.from_array(np.arange(96).reshape((8, 4, 3)))

    sliced_grid = grid.slice(constant="axis0", value=0)

    assert sliced_grid.ndim == 2
    assert sliced_grid.axes[0].name == grid.axes[1].name
    assert sliced_grid.axes[1].name == grid.axes[2].name

    np.testing.assert_array_equal(sliced_grid, np.arange(12).reshape(4, 3))
예제 #10
0
def test_array_transpose_axes():

    data = np.zeros((7, 6, 5))
    grid = GridArray.from_array(data)

    tr_grid = grid.transpose(axes=[1, 2, 0])

    assert tr_grid.axes[0] is grid.axes[1]
    assert tr_grid.axes[1] is grid.axes[2]
    assert tr_grid.axes[2] is grid.axes[0]
예제 #11
0
def test_array_fft_shape_1d():
    x = np.arange(10)

    for axes in [
        [Axis.from_array(x)],
            # [Axis([x] * 2)],
    ]:
        grid = GridArray.from_array(x, axes=axes)

        assert grid.fft().shape == grid.shape
        assert grid.fft().axes[0].shape == grid.axes[0].shape
예제 #12
0
def test_array_fft_shape_2d():
    x = np.arange(10)
    data = np.arange(100).reshape((10, 10))

    for axes in [
        [Axis.from_array(x)] * 2,
            # [Axis([x] * 2)] * 2,
    ]:
        grid = GridArray.from_array(data, axes=axes)

        assert grid.fft().shape == grid.shape
        assert grid.fft().axes[0].shape == grid.axes[0].shape
예제 #13
0
def test_array_slice_selection():
    grid = GridArray.from_array(np.arange(100).reshape((10, 10)))

    with pytest.raises(ValueError, match="out of range value"):
        grid.slice(constant="axis0", value=-1)

    with pytest.raises(ValueError, match="could not be found"):
        grid.slice(constant="axis2", value=0)

    with pytest.raises(ValueError, match="invalid axis index"):
        grid.slice(constant=2, value=0)

    with pytest.raises(ValueError, match="invalid axis index"):
        grid.slice(constant=-3, value=0)
예제 #14
0
def test_array_transpose_shape():

    data = np.zeros((7, 6, 5))
    grid = GridArray.from_array(data)

    for tr_axes in [
            None,
        [0, 1, 2],
        [0, 2, 1],
        [2, 1, 0],
        [1, 2, 0],
    ]:
        tr_grid = grid.transpose(axes=tr_axes)
        assert tr_grid.shape == np.transpose(data, axes=tr_axes).shape
예제 #15
0
def test_array_transpose_invalid_axes():

    grid = GridArray.from_array(np.arange(7 * 6).reshape((7, 6)))

    for invalid_axes in [
        [0],
        [1, 1],
        ["axis0", "axis0"],
    ]:
        with pytest.raises(ValueError, match="invalid transpose axes"):
            grid.transpose(axes=invalid_axes)

    for invalid_axis in [2, -3]:
        with pytest.raises(ValueError, match="invalid axis index"):
            grid.transpose(axes=[invalid_axis])
예제 #16
0
def transpose_grid_array(
    grid: GridArray,
    axes: Optional[list] = None,
) -> GridArray:
    """Reverses or permutes the axes of a `GridArray`.

    Parameters
    ----------
    axes: ``list``, optional
         List of integers and/or strings that identify the permutation of the
         axes. The i'th axis of the returned `GridArray` will correspond to the
         axis numbered/labeled axes[i] of the input. If not specified, the
         order of the axes is reversed.

    Returns
    ------
    :class:`nata.containers.GridArray`:
        Transpose of ``grid``.

    Examples
    --------
    Transpose a three-dimensional array.

    >>> from nata.containers import GridArray
    >>> import numpy as np
    >>> data = np.arange(96).reshape((8, 4, 3))
    >>> grid = GridArray.from_array(data)
    >>> grid.transpose().shape
    (3, 4, 8)
    >>> grid.transpose(axes=[0,2,1]).shape
    (8, 3, 4)

    """

    # get transpose axes
    tr_axes = get_transpose_axes(grid, axes)

    if len(set(tr_axes)) is not grid.ndim:
        raise ValueError("invalid transpose axes")

    return GridArray.from_array(
        da.transpose(grid.to_dask(), axes=tr_axes),
        name=grid.name,
        label=grid.label,
        unit=grid.unit,
        axes=[grid.axes[axis] for axis in tr_axes],
        time=grid.time,
    )
예제 #17
0
def test_GridArray_repr_markdown_():
    grid = GridArray.from_array(np.arange(12, dtype=np.int32).reshape((4, 3)))
    expected_markdown = """
    | **GridArray** | |
    | ---: | :--- |
    | **name**  | unnamed |
    | **label** | unlabeled |
    | **unit**  | '' |
    | **shape** | (4, 3) |
    | **dtype** | int32 |
    | **time**  | None |
    | **axes**  | Axis(axis0), Axis(axis1) |

    """

    assert grid._repr_markdown_() == dedent(expected_markdown)
예제 #18
0
def streak_grid_array(grid: GridDataset, ) -> GridArray:
    """Converts a `GridDataset` to a `GridArray`. Only `GridDataset` with axes
    that do not change over time are supported.

    Returns
    ------
    :class:`nata.containers.GridArray`:
        Streak of ``grid``.

    Examples
    --------
    Convert a one-dimensional dataset with time dependence to a two-dimensional
    array.

    >>> from nata.containers import GridDataset
    >>> import numpy as np
    >>> data = np.arange(5*7).reshape((5, 7))
    >>> grid = GridDataset.from_array(data)
    >>> stk_grid = grid.streak()
    >>> stk_grid.shape
    (5, 7)
    >>> [axis.shape for axis in stk_grid.axes]
    [(5,), (7,)]

    """

    if grid.ndim < 2:
        raise ValueError(
            "streak is not available for 0 dimensional GridDatasets")

    for axis in grid.axes[1:]:
        for i, axis_i in enumerate(axis):
            if np.any(axis_i.to_dask() != axis[0].to_dask()):
                raise ValueError("invalid axes for streak")

    return GridArray.from_array(
        grid.to_dask(),
        name=grid.name,
        label=grid.label,
        unit=grid.unit,
        axes=[grid.time] + [axis[0] for axis in grid.axes[1:]],
    )
예제 #19
0
def test_GridArray_from_array_raise_invalid_axes():
    # invalid number of axes
    with pytest.raises(ValueError,
                       match="mismatches with dimensionality of data"):
        GridArray.from_array([], axes=[0, 1])

    # axes which are not 1D dimensional
    with pytest.raises(ValueError,
                       match="only 1D axis for GridArray are supported"):
        GridArray.from_array([0, 1], axes=[[[0, 1]]])

    # axis mismatch with shape of data
    with pytest.raises(ValueError,
                       match="inconsistency between data and axis shape"):
        GridArray.from_array([0, 1], axes=[[0, 1, 2, 3]])
예제 #20
0
def test_GridArray_from_array_default():
    grid_arr = GridArray.from_array(da.arange(12, dtype=int).reshape((4, 3)))

    assert grid_arr.shape == (4, 3)
    assert grid_arr.ndim == 2
    assert grid_arr.dtype == int

    assert grid_arr.axes[0].name == "axis0"
    assert grid_arr.axes[0].label == "unlabeled"
    assert grid_arr.axes[0].unit == ""
    assert grid_arr.axes[0].shape == (4, )

    assert grid_arr.axes[1].name == "axis1"
    assert grid_arr.axes[1].label == "unlabeled"
    assert grid_arr.axes[1].unit == ""
    assert grid_arr.axes[1].shape == (3, )

    assert grid_arr.time.name == "time"
    assert grid_arr.time.label == "time"
    assert grid_arr.time.unit == ""

    assert grid_arr.name == "unnamed"
    assert grid_arr.label == "unlabeled"
    assert grid_arr.unit == ""
예제 #21
0
def test_GridArray_change_unit_by_prop():
    grid_arr = GridArray.from_array([])
    assert grid_arr.unit == ""

    grid_arr.unit = "new unit"
    assert grid_arr.unit == "new unit"
예제 #22
0
def test_GridArray_from_array_check_time():
    grid_arr = GridArray.from_array([], time=123)
    np.testing.assert_array_equal(grid_arr.time, 123)
    assert grid_arr.time.name == "time"
    assert grid_arr.time.label == "time"
    assert grid_arr.time.unit == ""
예제 #23
0
def test_GridArray_from_array_check_axes():
    grid_arr = GridArray.from_array([0, 1], axes=[[0, 1]])
    np.testing.assert_array_equal(grid_arr.axes[0], [0, 1])
    assert grid_arr.axes[0].name == "axis0"
    assert grid_arr.axes[0].label == "unlabeled"
    assert grid_arr.axes[0].unit == ""
예제 #24
0
def test_GridArray_from_array_raise_invalid_name():
    with pytest.raises(ValueError,
                       match="'name' has to be a valid identifier"):
        GridArray.from_array([], name="invalid name")
예제 #25
0
def test_GridArray_from_array_raise_invalid_time():
    with pytest.raises(ValueError, match="time axis has to be 0 dimensional"):
        GridArray.from_array([], time=[0, 1, 2])
예제 #26
0
def test_array_fft_invalid_ndim():

    with pytest.raises(ValueError, match="0 dimensional GridArrays"):
        GridArray.from_array(1).fft()
예제 #27
0
def test_GridArray_array_function_proxy():
    grid = GridArray.from_array([1, 2])
    np.testing.assert_array_equal(np.fft.fft(grid), np.fft.fft([1, 2]))
예제 #28
0
def test_GridArray_change_label_by_prop():
    grid_arr = GridArray.from_array([])
    assert grid_arr.label == "unlabeled"

    grid_arr.label = "new label"
    assert grid_arr.label == "new label"
예제 #29
0
def test_GridArray_array():
    grid = GridArray.from_array([1, 2])
    np.testing.assert_array_equal(grid, [1, 2])
예제 #30
0
def test_GridArray_len():
    assert len(GridArray.from_array(np.zeros((3, )))) == 3
    assert len(GridArray.from_array(np.zeros((5, 3)))) == 5

    with pytest.raises(TypeError, match="unsized object"):
        len(GridArray.from_array(np.zeros(())))