Repository: GoLP-IST/nata (language: python)

Issue:
Update fft and lineout plugins to follow new API
As `GridDataset` is updated to follow #116, the `.fft()` and `.lineout()` plugins require an update. The `.lineout()` plugin will be updated to provide multidimensional slices, and will hence be renamed to `.slice()`.

These plugins should be provided for:
- `GridArray` (single time step data): FFTs and slices are allowed along all grid axes
- `GridDataset` (multiple time step data): FFTs and slices are allowed along all grid axes except time, i.e. time dependence is always preserved. To perform an FFT of a quantity A(x, t) over both time (t) and x, the `GridDataset` should first be converted to a 2D `GridArray`, and then FFTed.


Discussion / hints:

Fix patch:
diff --git a/examples/GridDataset plugins.ipynb b/examples/GridDataset plugins.ipynb
new file mode 100644
index 0000000..59f596a
--- /dev/null
+++ b/examples/GridDataset plugins.ipynb
@@ -0,0 +1,845 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "2a2e5a1a-2146-4890-b37c-175f9fc9b844",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%load_ext autoreload\n",
+    "%autoreload 2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "b79b59cd-1ebc-4d9f-ab54-743ff4b66011",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import sys\n",
+    "\n",
+    "import numpy as np\n",
+    "import dask.array as da\n",
+    "import matplotlib.pyplot as plt\n",
+    "\n",
+    "from nata.containers import GridDataset\n",
+    "from nata.containers import GridArray\n",
+    "from nata.containers import Axis\n",
+    "from nata.plugins.register import register_container_plugin"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "12934ef1-50b5-45e6-b279-a4a0804999f0",
+   "metadata": {},
+   "source": [
+    "# Slice\n",
+    "\n",
+    "The grid `.slice()` plugin returns a lower dimensionality slice of the original `GridArray` or `GridDataset`."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "e4349b01-bcd5-4204-a997-c5b2d0c00a29",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridArray** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | unnamed |\n",
+       "| **label** | unlabeled |\n",
+       "| **unit**  | '' |\n",
+       "| **shape** | (8, 4, 3) |\n",
+       "| **dtype** | int64 |\n",
+       "| **time**  | 0.0 |\n",
+       "| **axes**  | Axis(axis0), Axis(axis1), Axis(axis2) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridArray<shape=(8, 4, 3), dtype=int64, time=0.0, axes=(Axis(axis0), Axis(axis1), Axis(axis2))>"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "grid = GridArray.from_array(\n",
+    "    np.arange(96).reshape((8, 4, 3))\n",
+    ")\n",
+    "grid"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "95900fb9-ff19-4282-953e-b6d3c042d06c",
+   "metadata": {},
+   "source": [
+    "Both the axis name or its index can be used to select the slicing direction."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "f551fb92-67e4-45a7-a775-5cab27a21147",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(4, 3)"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sliced_grid = grid.slice(constant=\"axis0\", value=0)\n",
+    "sliced_grid.shape"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "4d63c39f-c2a6-469f-8c86-26eff3c2e14f",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(4, 3)"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sliced_grid = grid.slice(constant=0, value=0)\n",
+    "sliced_grid.shape"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d64735b8-7552-4b2d-8082-fc81cebb6cbb",
+   "metadata": {},
+   "source": [
+    "When using axis indices, negative values are also supported."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "8c47b1e1-7f27-4572-a513-b648389a40db",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(8, 4)"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sliced_grid = grid.slice(constant=-1, value=0)\n",
+    "sliced_grid.shape"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "56c4627b-1751-4705-b16c-a25eefe49e0f",
+   "metadata": {},
+   "source": [
+    "When slicing `GridDataset`, time dependence is always preserved."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "306799b6-578b-43f1-8c39-63e517432d17",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridDataset** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | unnamed |\n",
+       "| **label** | unlabeled |\n",
+       "| **unit**  | '' |\n",
+       "| **shape** | (8, 4, 3) |\n",
+       "| **dtype** | int64 |\n",
+       "| **time**  | [0 1 2 3 4 5 6 7] |\n",
+       "| **axes**  | Axis(time), Axis(axis0), Axis(axis1) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridDataset<shape=(8, 4, 3), dtype=int64, time=[0 1 2 3 4 5 6 7], axes=(Axis(time), Axis(axis0), Axis(axis1))>"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "grid = GridDataset.from_array(\n",
+    "    np.arange(96).reshape((8, 4, 3))\n",
+    ")\n",
+    "grid"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "a3e1cce3-041b-4a01-ab6f-b1e247cb562f",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridDataset** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | unnamed |\n",
+       "| **label** | unlabeled |\n",
+       "| **unit**  | '' |\n",
+       "| **shape** | (8, 3) |\n",
+       "| **dtype** | int64 |\n",
+       "| **time**  | [0. 0. 0. 0. 0. 0. 0. 0.] |\n",
+       "| **axes**  | Axis(time), Axis(axis1) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridDataset<shape=(8, 3), dtype=int64, time=[0. 0. 0. 0. 0. 0. 0. 0.], axes=(Axis(time), Axis(axis1))>"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sliced_grid = grid.slice(constant=\"axis0\", value=0)\n",
+    "sliced_grid"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "3abe2cc4-701a-410a-b4cb-1e387f551460",
+   "metadata": {},
+   "source": [
+    "Slices are not allowed along the time axis."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "ab7b8f70-934d-4d5d-96ca-11c86aec235d",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "slice along the time axis `time` is not supported\n"
+     ]
+    }
+   ],
+   "source": [
+    "try:\n",
+    "    grid.slice(constant=\"time\", value=0)\n",
+    "except ValueError:\n",
+    "    print(\"slice along the time axis `time` is not supported\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "ee23d4e4-dc4a-4739-9356-6a62999f234a",
+   "metadata": {},
+   "source": [
+    "Slices are allowed along moving axis as long as the value at which they are taken exists in the corresponding axis for all times."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "id": "eb6032b3-e230-4adf-832d-ad625c208a4e",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridDataset** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | unnamed |\n",
+       "| **label** | unlabeled |\n",
+       "| **unit**  | '' |\n",
+       "| **shape** | (5,) |\n",
+       "| **dtype** | int64 |\n",
+       "| **time**  | [0. 0. 0. 0. 0.] |\n",
+       "| **axes**  | Axis(time) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridDataset<shape=(5,), dtype=int64, time=[0. 0. 0. 0. 0.], axes=(Axis(time))>"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "x = np.arange(10)\n",
+    "grid = GridDataset.from_array(\n",
+    "    np.tile(x, (5, 1)), \n",
+    "    axes=[\n",
+    "        Axis(np.arange(5), name=\"t\"), \n",
+    "        Axis([x, x+1, x+2, x+3, x+4], name=\"x1\"),\n",
+    "    ]\n",
+    ")\n",
+    "grid.slice(constant=\"x1\", value=5)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "df3f98f4-50ad-4fe1-9da8-2099cf8037fa",
+   "metadata": {},
+   "source": [
+    "# Fast Fourier Transform (FFT)\n",
+    "\n",
+    "The grid `.fft()` plugin returns the FFT of the original `GridDataset`."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "07334898-045b-4568-a33e-3e1c0e35fd9e",
+   "metadata": {},
+   "source": [
+    "If the `comp` argument is not provided, `.fft()` returns the absolute value of the FFT."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "id": "088a801a-121a-45d2-92a8-4debdb0e16b0",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridArray** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | dataset |\n",
+       "| **label** | |unlabeled| |\n",
+       "| **unit**  | A |\n",
+       "| **shape** | (101,) |\n",
+       "| **dtype** | float64 |\n",
+       "| **time**  | 0.0 |\n",
+       "| **axes**  | Axis(k_x1) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridArray<shape=(101,), dtype=float64, time=0.0, axes=(Axis(k_x1))>"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "x = np.linspace(0, 10*np.pi, 101)\n",
+    "\n",
+    "grid = GridArray.from_array(\n",
+    "    np.sin(x),\n",
+    "    name=\"dataset\",\n",
+    "    unit=\"A\",\n",
+    "    axes=[\n",
+    "        Axis(x, name=\"x1\", label=\"x_1\", unit=\"a\")\n",
+    "    ]\n",
+    ")\n",
+    "fft_grid = grid.fft()\n",
+    "fft_grid"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "db1a2061-653a-4b33-a96c-a4fa71a4754c",
+   "metadata": {},
+   "source": [
+    "The axes over which the FFT is computed are transformed such thatthe zero frequency bins are centered."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "id": "db2eab77-c970-4348-9d5e-ecc8227f3016",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig, ax = plt.subplots()\n",
+    "\n",
+    "ax.plot(fft_grid.axes[0].to_dask(), fft_grid.to_dask())\n",
+    "ax.set_xlim((-3, 3))\n",
+    "ax.set_xlabel(f\"${fft_grid.axes[0].label}$ [${fft_grid.axes[0].unit}$]\")\n",
+    "ax.set_ylabel(f\"${fft_grid.label}$ [${fft_grid.unit}$]\")\n",
+    "ax.axvline(+1, c=\"k\", ls=\"--\")\n",
+    "ax.axvline(-1, c=\"k\", ls=\"--\")\n",
+    "fig.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "2222f4c3-e1bc-44bb-b582-c245826368f4",
+   "metadata": {},
+   "source": [
+    "If `comp` is provided, `.fft()` returns the corresponding component of the FFT."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "id": "9dd05dad-9244-43e8-b198-0b77033db968",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridArray** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | dataset |\n",
+       "| **label** | \\Im(unlabeled) |\n",
+       "| **unit**  | A |\n",
+       "| **shape** | (101,) |\n",
+       "| **dtype** | float64 |\n",
+       "| **time**  | 0.0 |\n",
+       "| **axes**  | Axis(k_x1) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridArray<shape=(101,), dtype=float64, time=0.0, axes=(Axis(k_x1))>"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "fft_grid = grid.fft(comp=\"imag\")\n",
+    "fft_grid"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "id": "71751d0e-5218-41ee-b0b2-9140427dd36b",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig, ax = plt.subplots()\n",
+    "\n",
+    "ax.plot(fft_grid.axes[0].to_dask(), fft_grid.to_dask())\n",
+    "ax.set_xlim((-3, 3))\n",
+    "ax.set_xlabel(f\"${fft_grid.axes[0].label}$ [${fft_grid.axes[0].unit}$]\")\n",
+    "ax.set_ylabel(f\"${fft_grid.label}$ [${fft_grid.unit}$]\")\n",
+    "ax.axvline(+1, c=\"k\", ls=\"--\")\n",
+    "ax.axvline(-1, c=\"k\", ls=\"--\")\n",
+    "fig.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "8417bd56-6c10-4c69-93c0-598562899e03",
+   "metadata": {},
+   "source": [
+    "When applied to multidimensional grids, the `axes` argument controls the axes over which the FFT is computed. If `axes` is not provided, the FFT is computed over all available grid axes."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "id": "38d84d52-816a-43f1-98bc-63ee8de59c81",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridArray** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | dataset |\n",
+       "| **label** | |unlabeled| |\n",
+       "| **unit**  | '' |\n",
+       "| **shape** | (101, 201) |\n",
+       "| **dtype** | float64 |\n",
+       "| **time**  | 0.0 |\n",
+       "| **axes**  | Axis(k_x1), Axis(k_x2) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridArray<shape=(101, 201), dtype=float64, time=0.0, axes=(Axis(k_x1), Axis(k_x2))>"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "x = np.linspace(0, 10*np.pi, 101)\n",
+    "y = np.linspace(0, 10*np.pi, 201)\n",
+    "\n",
+    "X,Y = np.meshgrid(x, y, indexing=\"ij\")\n",
+    "\n",
+    "grid = GridArray.from_array(\n",
+    "    np.sin(X) + np.sin(2*Y),\n",
+    "    name=\"dataset\",\n",
+    "    axes=[\n",
+    "        Axis(x, name=\"x1\", label=\"x_1\", unit=\"a\"),\n",
+    "        Axis(y, name=\"x2\", label=\"x_2\", unit=\"b\")\n",
+    "    ]\n",
+    ")\n",
+    "fft_grid = grid.fft()\n",
+    "fft_grid"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "id": "e6e6ad8c-50a5-4f9b-904f-ba3ca4478e60",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAARUAAAERCAYAAABVfzP0AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Z1A+gAAAACXBIWXMAAAsTAAALEwEAmpwYAAAQ9ElEQVR4nO3de6ykdX3H8fdn14VdFDSIigINogYhyMVSb7XeQKXE1tp6x1rFZrVXNTWo0GC8tSW0hlZt7SYgUqmGiKhBrFxEqFFAilyWmwFbK0qKiojIctndb/+YWT2se+bM2fObeZ45vF/JSeaZ55k5H87hfPb33H6TqkKSWlnRdQBJy4ulIqkpS0VSU5aKpKYsFUlNWSqSmuplqSRZneSyJFcluTbJe7vOJGk86eN1KkkCPLSq7kqyCvga8NaquqTjaJIW8JCuA2xLDZruruHiquFX/9pP0q/o5e4PQJKVSa4EbgPOq6pLO44kaQy9HKkAVNUm4OAkjwDOSnJAVa2fu02StcBagJWs/PWd2GX6QTW+LLDesWiv3cPPua/uXei32M9jKltLcjxwd1X9/Xzb7JJd6+k5bIqptFh5yOh/w2rjxikl0fa4tC7gzrp9wVLp5e5PkkcNRygkWQO8ELih01CSxtLX3Z/HAp9IspJB8Z1RVWd3nEnSGHpZKlV1NXBI1zkkLV4vd38kzS5LRVJTloqkpiwVSU1ZKpKa6uXZHy1T8d+wBwN/y5KaslQkNWWpSGrKUpHUlKUiqSlLRVJTloqkprxORVOTVQtM0nT/fVNKoklypCKpKUtFUlOWiqSmLBVJTVkqkpqyVCQ15SllTU12WjN6g7vvnk4QTZQjFUlNWSqSmrJUJDVlqUhqylKR1JSlIqmpXp5STrIXcBrwGKCAdVX1j92m0lKdc/UFI9e/+HEHTyeIJqqXpQJsBP6qqq5IsjPwX0nOq6rrug4mabRe7v5U1a1VdcXw8c+A64E9uk0laRy9LJW5kuwNHAJc2nEUSWPo6+4PAEkeBpwJvK2q7tzG+rXAWoDV7DTldJK2pbcjlSSrGBTK6VX12W1tU1XrqurQqjp0FTtON6CkbeplqSQJcDJwfVV9qOs8ksbX192f3wT+ELgmyZXD546tqnO6i6SlOnL/5y6wxU+nkkOT1ctSqaqvAek6h6TF6+Xuj6TZZalIaspSkdSUpSKpKUtFUlOWiqSmenlKWcvT5g33dB1BU+BIRVJTloqkpiwVSU1ZKpKaslQkNWWpSGrKU8qank2buk6gKXCkIqkpS0VSU5aKpKYsFUlNWSqSmrJUJDXlKWVNTW2uriNoChypSGrKUpHUlKUiqSlLRVJTloqkpiwVSU15SlnTU5u7TqAp6O1IJckpSW5Lsr7rLJLG19tSAU4Fjug6hKTF6W2pVNXFwO1d55C0ODN9TCXJWmAtwGp26jiNJOjxSGUcVbWuqg6tqkNXsWPXcSQx46UiqX8sFUlN9bZUknwK+Aawb5Jbkryp60ySFtbbA7VV9ZquM0havN6OVCTNJktFUlOWiqSmLBVJTVkqkprq7dkfLUPlbPoPBo5UJDU11kglya5jbLa5qu5YWhxJs27c3Z8fDL8yYpuVwK8tOZGkmTZuqVxfVYeM2iDJtxrkkTTjxj2m8sxG20ha5sYqlaq6p8U2kpa/RZ/9SfLOSQSRtDwseEwlyRlzF4GDgRMmFUjSbBvnQO2dVfXHWxaS/MsE80iacePs/nxwq+XjJhFE0vKwYKlU1X8DJNltuOzHZkia12IO1J4ysRSSlo3FlMqoq2klCVhcqXiLqaQFOVKR1NRiSuXdE0shadkYu1Sqav2Wx0kemmTlZCJJmmVjlUqSFUlem+SLSW4DbgBuTXJdkhOTPHGyMSXNinFHKhcCT2CwC7R7Ve1VVY8Gng1cApyQ5HUTyihphow7n8rhVXX/1k8OL4Q7EzgzyaqmySTNpLFKZUuhJHkO8AHgkcBVwElVddncbTqVrU5Qpf0UvFmxhJNgo/KMeN+snP/wVXZaM++6c66+YGScI5/8nHnXbd4w/0wWtWnT/G9am0esW+CqhK1/fw9YN//PbtTPZ8Wa1fOuO+eGi0fGOfLAw+ZdV3dvmH/dqJ/P5hE/g1E/uwXUqPfd/jfdanm8ly32r+4U4P3A84DTgJOSvHKR7zGWJEckuTHJTUneNYnvIam9xZbKj6rqvKr6YVX9B/Ai4PjWoYZnlj4K/DawP/CaJPu3/j6S2hv37M9pSd4GfC3J8Um27DbdC0xixrenATdV1Xeq6j7g08BLJ/B9JDU27kjlZGAzsCuDP+6bkpzP4NTyhRPItQfwvTnLtwyfe4Aka5NcnuTy+7l3AjEkLda4B2ovAi7asjwcqTwZOAQ4cDLRxsq1DlgHsEt29d4kqQfG/TCxVP3y0H1VbQTWD7+2uc0SfR/Ya87ynsPnJPXc2Be/JfmLJA/4sLAkOyR5QZJPAH/UMNc3gScleXySHYBXA19o+P6SJiTjDC6SrAaOBo4CHg/cAaxm8KmE5wL/XFVNP0wsyZHAScPvcUpVbT2t5QPskl3r6Zn/ugJJS3NpXcCddfuCF2qNVSoPeMHgytndgA19+uxkS0WarHFLZdzL9H9heOXsrduVStKyN+51Kle02EbS8jfuSGW/JFePWB/g4Q3ySJpx45bKk8fYZsRdVJIeLMa9+O27kw4iaXloPzeApAc1S0VSU5aKpKaWXCpJjkpyTJJdkrywRShJs6vFSOUJwEeAtwNHNHg/STNsSaUynKHt8qq6G3gfcFuTVJJm1lJHKuuArw4f/1ZVnbDE95M04xZ9789WjgdOTrIRuBIYPT25pGVvqSOV9wM3Mpi8/4ylx5E06xZVKkk+sNVTxzAolj8B3tMqlKTZtdiRyh5JXjNnOcD5VfVz4M3tYkmaVYs9pvJm4MtJbmawy/Nx4J0AVeUNhZLGnvj6NOAK4FvAnwH/DmwEfq+qbppcPEmzZtzdn1MZ7Oq8EfgksDfwE+B1SV4+kWSSZtK4Ux98BfjKluXh5/7sBxwEPB34zETSaXkZ9QHssPAHuGsmbNd1KsPP/blm+PXJpokkzTTvUpbUlKUiqSlLRVJTloqkpiwVSU1ZKpKa6l2pJHlFkmuTbE5yaNd5JC1O70oFWA/8Ps7NIs2kpU7S1FxVXQ+Qha6+lNRLvSuVxUiyFlgLsJqdOk4jCToqlSTnA7tvY9VxVfX5cd+nqtYxmCeXXbKrN45IPdBJqVTV4V18X0mT18cDtZJmWO9KJcnLktwCPBP4YpIvd51JjWTF6C8tC707UFtVZwFndZ1D0vbxnwdJTVkqkpqyVCQ1ZalIaspSkdRU787+aPnKitH3c9XmKQXRRDlSkdSUpSKpKUtFUlOWiqSmLBVJTVkqkprylLKmZ+XK0es3bpxODk2UIxVJTVkqkpqyVCQ1ZalIaspSkdSUpSKpKU8pa2pWrFk9cv2me++dUhJNkiMVSU1ZKpKaslQkNWWpSGrKUpHUlKUiqSlLRVJTvbtOJcmJwO8A9wE3A2+sqjs6DaUmzrnuopHrX/y4g6cTRBPVx5HKecABVXUg8G3g3R3nkbQIvSuVqjq3qrbM1nMJsGeXeSQtTu9KZStHA1/qOoSk8XVyTCXJ+cDu21h1XFV9frjNccBG4PQR77MWWAuwmp0mkFTSYnVSKlV1+Kj1Sd4AvAQ4rKpqxPusA9YB7JJd591O0vT08ezPEcAxwHOr6u6u80hanN6VCvARYEfgvCQAl1TVW7qNpBaOPPCwBbb48VRyaLJ6VypV9cSuM0jafn0/+yNpxlgqkpqyVCQ1ZalIaspSkdRU787+aPmquzd0HUFT4EhFUlOWiqSmLBVJTVkqkpqyVCQ1ZalIaspTypqaun/jwhtp5jlSkdSUpSKpKUtFUlOWiqSmLBVJTVkqkpqyVCQ15XUqmp7a3HUCTYEjFUlNWSqSmrJUJDVlqUhqylKR1JSlIqkpS0VSU70rlSTvT3J1kiuTnJvkcV1nkjS+3pUKcGJVHVhVBwNnA8d3nEfSIvSuVKrqzjmLDwWqqyySFi9V/fubTfJB4PXAT4HnV9UP59luLbB2uHgAsH46CceyG/CjrkPM0bc80L9M5hlt36raeaGNOimVJOcDu29j1XFV9fk5270bWF1V7xnjPS+vqkMbxlwS8yysb5nMM9q4eTq5obCqDh9z09OBc4AFS0VSP/TumEqSJ81ZfClwQ1dZJC1eH6c++Lsk+wKbge8CbxnzdesmF2m7mGdhfctkntHGytPLA7WSZlfvdn8kzTZLRVJTy6pU+naJf5ITk9wwzHRWkkd0nOcVSa5NsjlJZ6cqkxyR5MYkNyV5V1c55uQ5JcltSXpxnVOSvZJcmOS64e/rrR3nWZ3ksiRXDfO8d+QLqmrZfAG7zHn8l8DHOs7zIuAhw8cnACd0nGc/YF/gq8ChHWVYCdwM7APsAFwF7N/xz+U5wFOB9V3mmJPnscBTh493Br7d5c8ICPCw4eNVwKXAM+bbflmNVKpnl/hX1blVteVTyS8B9uw4z/VVdWOXGYCnATdV1Xeq6j7g0wwuHehMVV0M3N5lhrmq6taqumL4+GfA9cAeHeapqrpruLhq+DXv39ayKhUYXOKf5HvAUfTrZsSjgS91HaIH9gC+N2f5Fjr8g+m7JHsDhzAYHXSZY2WSK4HbgPOqat48M1cqSc5Psn4bXy8FqKrjqmovBlfj/nnXeYbbHAdsHGbqPI9mQ5KHAWcCb9tqFD51VbWpBjMH7Ak8LckB823bx4vfRqqeXeK/UJ4kbwBeAhxWw53SLvP0wPeBveYs7zl8TnMkWcWgUE6vqs92nWeLqrojyYXAEcxzA+/MjVRG6dsl/kmOAI4Bfreq7u4yS498E3hSkscn2QF4NfCFjjP1SpIAJwPXV9WHepDnUVvOXCZZA7yQEX9by+qK2iRnMji78YtL/Kuqs38Fk9wE7Aj8ePjUJVU17m0Hk8jzMuDDwKOAO4Arq+rFHeQ4EjiJwZmgU6rqg9POsFWeTwHPYzDVwP8B76mqkzvM82zgP4FrGPy/DHBsVZ3TUZ4DgU8w+H2tAM6oqvfNu/1yKhVJ3VtWuz+SumepSGrKUpHUlKUiqSlLRVJTloqkpiwVzaQk+yQ5Oclnus6iB7JUNK8khyX5t+187d5JNgxvQtvy3JokFyVZOeJ1OyS5OMnIW0iGdzm/aavXrhnOpXNfkt22J7eWzlLRKAcB31rC628e3oS2xdHAZ6tq03wvGE6HcAHwKoAkT0ly9lZfj57ntRuG3+8HS8isJZq5Gwo1VQcBpybZEfhXBn+sxy3hxsijgNduWUjycuAdwBrgZ8DLavBplJ8D/pbBzXTXMLghUzPCkYpGOZDB/BlfBs6vqmO3t1CGNw/uU1X/M+fpC6vqGVV1EHAe8Mrh8+uB31jg/R6Z5GPAIcNPslRPOFLRNg1vvd8H+BTw5qr6xhLfcjcGNzHO9YYkr2Jw0+XuwLEwmLtjeFxk5+HMZ7+iqn7M+J8JpSlypKL57MdgmoKNwLzHQBZhA7B6y0KS1zOYWvIFw5HKjcC1c7bfEbinwffVlFkqms9BwNcZzHfy8SSPGc6r8fEkew5noF817ptV1U+AlUm2FMtTgK9X1V1J/gB4FoNb/UnySOBHVXV/0/8iTYWlovkcxGB2+W8D7wTOYLD78r/APzD4tIJnJvn0It7zXODZw8enAn+a5DIGc7B+p6p+Plz3fOCLS/0PUDc8pqJtqqp3zHl8NnD2cM7UfYCNw9nVL07yrEW87UeBtzM46Hstgwm1tvjrOY9fC3T+eUDaPo5UNJbhxWj/xOCP/8okz1vgJZuAh8+9+G34sRMXLnTxG/C54QhpsRnXDL/fKn45Y5qmzJnftN2SPAX4G+DDVXVu13nUD5aKpKbc/ZHUlKUiqSlLRVJTloqkpiwVSU1ZKpKaslQkNWWpSGrKUpHU1P8Df0dBcUCsNPYAAAAASUVORK5CYII=\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig, ax = plt.subplots()\n",
+    "\n",
+    "im = ax.imshow(\n",
+    "    np.transpose(fft_grid.to_dask()), \n",
+    "    extent=(\n",
+    "        np.min(fft_grid.axes[0].to_dask()),\n",
+    "        np.max(fft_grid.axes[0].to_dask()),\n",
+    "        np.min(fft_grid.axes[1].to_dask()),\n",
+    "        np.max(fft_grid.axes[1].to_dask())\n",
+    "    ),\n",
+    "    origin=\"lower\",\n",
+    ")\n",
+    "ax.set_xlim(-3, 3)\n",
+    "ax.set_ylim(-3, 3)\n",
+    "\n",
+    "ax.set_xlabel(f\"${fft_grid.axes[0].label}$ [${fft_grid.axes[0].unit}$]\")\n",
+    "ax.set_ylabel(f\"${fft_grid.axes[1].label}$ [${fft_grid.axes[1].unit}$]\")\n",
+    "\n",
+    "fig.show()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "id": "8bea2da8-438c-44ce-9e54-34866a242dbb",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig, ax = plt.subplots()\n",
+    "\n",
+    "ax.plot(fft_grid.axes[1].to_dask(), fft_grid.to_dask()[50, :])\n",
+    "ax.set_xlim((-3, 3))\n",
+    "ax.axvline(+2, c=\"k\", ls=\"--\")\n",
+    "ax.axvline(-2, c=\"k\", ls=\"--\")\n",
+    "fig.show()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "id": "36fd8ebf-1c1c-4f3c-97bf-0c1e0b3f3422",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig, ax = plt.subplots()\n",
+    "\n",
+    "ax.plot(fft_grid.axes[0].to_dask(), fft_grid.to_dask()[:, 100])\n",
+    "ax.set_xlim((-3, 3))\n",
+    "ax.axvline(+1, c=\"k\", ls=\"--\")\n",
+    "ax.axvline(-1, c=\"k\", ls=\"--\")\n",
+    "fig.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "4d1ff1be-058d-4416-82ec-b0e221e47f8c",
+   "metadata": {},
+   "source": [
+    "If `axes` is provided, the FFT is only computed over the identified grid axes. Both strings (corresponding to axes names) and integers can be provided in `axes`."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "id": "718d38fa-7912-46be-8571-f3f83e51729a",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridArray** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | dataset |\n",
+       "| **label** | |unlabeled| |\n",
+       "| **unit**  | '' |\n",
+       "| **shape** | (101, 201) |\n",
+       "| **dtype** | float64 |\n",
+       "| **time**  | 0.0 |\n",
+       "| **axes**  | Axis(x1), Axis(k_x2) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridArray<shape=(101, 201), dtype=float64, time=0.0, axes=(Axis(x1), Axis(k_x2))>"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "fft_grid = grid.fft(axes=[\"x2\"])\n",
+    "fft_grid"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "id": "32cb35d2-b28d-4f08-8630-3f7935e50273",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig, ax = plt.subplots()\n",
+    "\n",
+    "im = ax.imshow(\n",
+    "    np.transpose(fft_grid.to_numpy()), \n",
+    "    extent=(\n",
+    "        np.min(fft_grid.axes[0].to_dask()),\n",
+    "        np.max(fft_grid.axes[0].to_dask()),\n",
+    "        np.min(fft_grid.axes[1].to_dask()),\n",
+    "        np.max(fft_grid.axes[1].to_dask())\n",
+    "    ),\n",
+    "    origin=\"lower\",\n",
+    ")\n",
+    "ax.set_ylim(-3, 3)\n",
+    "\n",
+    "ax.set_xlabel(f\"${fft_grid.axes[0].label}$ [${fft_grid.axes[0].unit}$]\")\n",
+    "ax.set_ylabel(f\"${fft_grid.axes[1].label}$ [${fft_grid.axes[1].unit}$]\")\n",
+    "\n",
+    "fig.show()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "id": "61e8c409-b326-4206-a156-607fd31ef84e",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridDataset** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | dataset |\n",
+       "| **label** | |S| |\n",
+       "| **unit**  | A |\n",
+       "| **shape** | (3, 101) |\n",
+       "| **dtype** | float64 |\n",
+       "| **time**  | [0. 0. 0.] |\n",
+       "| **axes**  | Axis(time), Axis(k_x1) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridDataset<shape=(3, 101), dtype=float64, time=[0. 0. 0.], axes=(Axis(time), Axis(k_x1))>"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "time = np.arange(3)\n",
+    "x = np.linspace(0, 10*np.pi, 101)\n",
+    "\n",
+    "grid = GridDataset.from_array(\n",
+    "    [np.sin(x), np.sin(2*x), np.sin(3*x)],\n",
+    "    name=\"dataset\",\n",
+    "    label=\"S\",\n",
+    "    unit=\"A\",\n",
+    "    axes=[\n",
+    "        Axis(time),\n",
+    "        Axis(np.tile(x, (3, 1)), name=\"x1\", label=\"x_1\", unit=\"a\")\n",
+    "    ]\n",
+    ")\n",
+    "fft_grid = grid.fft(comp=\"abs\")\n",
+    "fft_grid"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "id": "5c1d683a-3dde-47ec-830e-393e949d9258",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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ocVijQDhGIQingWa23EfrVqyikQkwc+e+1kHpZo4tFJokrUb15KMJDl36bktn8OzmEKpFefkVQquu0PXPxpNLfdRLUZiNIpbCkJ4Vik1W2gvptAX7+PsxWdz96t3szOzs4OSTQxaKTTBjvQOfvPabzhnyTltZQ15FlNo56YDT1NSs0ax6V4KUOY+0pVSSxhFi6Il21IKnoyne2216q/36PpsNyUV4LxjzkMi+fnzP++QVBOHVgpNcN3z1wFw3tHntXWekqUw0esU2jHPYcRSsCa+hETWMJvuugYQj4QQQruPymmlFaeL6z7yZDyNDERTEGrxMRRLTXhMoWAVMCyjpWJ45RzSfQjvPey93PTiTaVEFVXxOyU1MAwag9zy4i287/D3Mbd7blvn6gp3edOnudSKsw2lgIRirnVro0GyhllyBY3lhz/8YdXfCSG8rdcTAOq14qw1niOBe49W27dzXcUn3lJop2z2WM4/9nx+/fqvueXFW1h97Oq2zzdRaKXQIDdtuolsMctfHftXbZ/Lsz7NbbuPyurLTLhSKFZdbLV8+fKav03EwjoltYx6rThrjaen2VztXlcexLzaqZA6lmXTl3HinBO57vnr+OTRnyQajrZ9zolAu48awDANfv78z1k5dyVHTTuqI+f0pKdCq604XTyqlGoULQqmrDqz/d3vfsfvfve7qr/XLTlHU68VZ63xHAnce6UUWrw2wa7+O8HXZjtd1yqxetlqdmd38+vXf92R800E2lJogLtevYs9uT3809v/qWPn9KSnQidiCjDhs7GRLmGVL8d/+id73Kt1DEtq99Eo6rmPao1nKUYTBPeRB2VY2mmwU4k/O+TPOHLKkazduJYPLPqAkj1AtKVQBykl1268liVTl3DSvJM6dl5Peip0JKaABya6/QCq9hCrR1K7j0ZRqxVnPTyN0bTrPop3T3iV1E7GFMAe39XLVvPSgZd4aHvlVeV+o5VCHX6/7fe8MvAKq5et7qhWT0VTE18ky8iACEGkcg2cunjkPnJdP608xMCHvsKKU6sVZyPYLU49WqegeEyh3d4plXj/wvczKzGLn278acfO2Um0UqjD2o1rmZ2czekLxzaNa4+l05by9J6neXzn4x097yjcrmutKjOP3UeV+jM3QjIW1impZWRKMYUWV9x7pWQ7EVMo5sCcGAVWsAqs3biWnmhP2xmH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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig, ax = plt.subplots()\n",
+    "\n",
+    "for fft_grid_i in fft_grid:\n",
+    "    ax.plot(fft_grid_i.axes[0].to_dask(), fft_grid_i.to_dask())\n",
+    "ax.set_xlim((-4, 4))\n",
+    "ax.set_xlabel(f\"${fft_grid.axes[1].label}$ [${fft_grid.axes[1].unit}$]\")\n",
+    "ax.set_ylabel(f\"${fft_grid.label}$ [${fft_grid.unit}$]\")\n",
+    "ax.axvline(+1, c=\"k\", ls=\"--\")\n",
+    "ax.axvline(-1, c=\"k\", ls=\"--\")\n",
+    "fig.show()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "73c26baa-54cd-4f85-beb2-cd452c8e0663",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.9"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/nata/plugins/__init__.py b/nata/plugins/__init__.py
index 2a90892..8257c49 100644
--- a/nata/plugins/__init__.py
+++ b/nata/plugins/__init__.py
@@ -1,4 +1,4 @@
 # -*- coding: utf-8 -*-
 from .grids import *
-from .particles import *
+# from .particles import *
 from .plot import *
diff --git a/nata/plugins/grids/__init__.py b/nata/plugins/grids/__init__.py
index 4d7967e..706b198 100644
--- a/nata/plugins/grids/__init__.py
+++ b/nata/plugins/grids/__init__.py
@@ -1,3 +1,3 @@
 # -*- coding: utf-8 -*-
-from .lineout import *
+from .slice import *
 from .fft import *
diff --git a/nata/plugins/grids/fft.py b/nata/plugins/grids/fft.py
index 48d257f..44bea01 100644
--- a/nata/plugins/grids/fft.py
+++ b/nata/plugins/grids/fft.py
@@ -1,108 +1,231 @@
 # -*- coding: utf-8 -*-
 from typing import Optional
+from typing import Union
 
 import numpy as np
 import numpy.fft as fft
 
+from nata.containers import GridArray
 from nata.containers import GridDataset
-from nata.containers.axis import Axis
+from nata.containers import Axis
+from nata.containers.grid import stack
 from nata.plugins.register import register_container_plugin
 
+def get_fft_axes(
+    grid: Union[GridArray, GridDataset],
+    axes: list,
+    offset: int = 0,
+):
+    # build fft axes
+    if axes is None:
+        # no axes provided, all axes are fft axes
+        fft_axes = [i for i in range(offset, len(grid.axes))]
+    else:
+        # axes provided, determine fft axes
+        fft_axes = []
 
-@register_container_plugin(GridDataset, name="fft")
-def fft_grid_dataset(
-    dataset: GridDataset,
-    type: Optional[str] = "abs",
-) -> GridDataset:
-    """Computes the Fast Fourier Transform (FFT) of a single/multiple\
-       iteration :class:`nata.containers.GridDataset` along all grid axes\
-       using `numpy's fft module`__.
-
-        .. _fft: https://numpy.org/doc/stable/reference/routines.fft.html
-        __ fft_
-
-        Parameters
-        ----------
-        type: ``{'abs', 'real', 'imag', 'full'}``, optional
-            Defines the component of the FFT selected for output. Available
-            values are  ``'abs'`` (default), ``'real'``, ``'imag'`` and
-            ``'full'``, which correspond to the absolute value, real component,
-            imaginary component and full (complex) result of the FFT,
-            respectively.
-
-        Returns
-        ------
-        :class:`nata.containers.GridDataset`:
-            Selected FFT component along all grid axes of ``dataset``.
-
-        Examples
-        --------
-        To obtain the FFT of a :class:`nata.containers.GridDataset`, a simple
-        call to the ``fft()`` method is enough. In the following example, we
-        compute the FFT of a one-dimensional
-        :class:`nata.containers.GridDataset`.
-
-        >>> from nata.containers import GridDataset
-        >>> import numpy as np
-        >>> x = np.linspace(100)
-        >>> arr = np.exp(-(x-len(x)/2)**2)
-        >>> ds = GridDataset(arr[np.newaxis])
-        >>> ds_fft = ds.fft()
+        for axis in axes:
+            if isinstance(axis, str):
+                try:
+                    idx = list(ax.name for ax in grid.axes).index(axis)
+                except ValueError:
+                    raise ValueError(
+                        f"axis '{axis}' could not be found in '{grid.name}'"
+                    )
+            else:
+                if axis >= len(grid.axes) or axis < -len(grid.axes):
+                    raise ValueError(f"invalid axis index '{axis}'")
+                idx = axis
+
+            fft_axes.append(idx)
+
+    return fft_axes
+
+@register_container_plugin(GridArray, name="fft")
+def fft_grid_array(
+    grid: GridArray,
+    axes: Optional[list] = None,
+    comp: str = "abs",
+) -> GridArray:
+    """Computes the Fast Fourier Transform (FFT) of a
+    :class:`nata.containers.GridArray` using `numpy's fft module`__.
+
+     .. _fft: https://numpy.org/doc/stable/reference/routines.fft.html
+     __ fft_
+
+     The axes over which the FFT is computed are transformed such that
+     the zero frequency bins are centered.
+
+     Parameters
+     ----------
+     axes: ``list``, optional
+         List of integers and/or strings that identify the axes over which
+         to compute the FFT.
+     comp: ``{'abs', 'real', 'imag', 'full'}``, optional
+         Defines the component of the FFT selected for output. Available
+         values are  ``'abs'`` (default), ``'real'``, ``'imag'`` and
+         ``'full'``, which correspond to the absolute value, real component,
+         imaginary component and full (complex) result of the FFT,
+         respectively.
+
+     Returns
+     ------
+     :class:`nata.containers.GridArray`:
+         Selected FFT component of ``grid``.
+
+     Examples
+     --------
+     Obtain the FFT of a one-dimensional array.
+
+     >>> from nata.containers import GridArray
+     >>> import numpy as np
+     >>> x = np.arange(100)
+     >>> grid = GridArray.from_array(np.exp(-(x-len(x)/2)**2))
+     >>> fft_grid = grid.fft()
+
+     # TODO: add an image here with a plot of the FFT
+
+     Compute the FFT over the first axis of a two-dimensional array.
+
+     >>> from nata.containers import GridArray
+     >>> import numpy as np
+     >>> x = np.linspace(0, 10*np.pi)
+     >>> y = np.linspace(0, 10*np.pi)
+     >>> X, Y = np.meshgrid(x, y, indexing="ij")
+     >>> grid = GridArray.from_array(np.sin(X) + np.sin(2*Y))
+     >>> fft_grid = grid.fft(axes=[0])
+
+     # TODO: add an image here with a plot of the FFT
 
     """
 
-    fft_data = np.array(dataset)
-    fft_axes = np.arange(len(dataset.grid_shape)) + 1
+    if grid.ndim < 1:
+        raise ValueError("fft is not available for 0 dimensional GridArrays")
 
-    fft_data = fft.fftn(
-        fft_data if len(dataset) > 1 else fft_data[np.newaxis], axes=fft_axes
-    )
+    # build fft axes
+    fft_axes = get_fft_axes(grid, axes)
+
+    # build new axes
+    new_axes = []
+
+    for idx, axis in enumerate(grid.axes):
+        if idx in fft_axes:
+            # axis is fft axis, determine its fourier counterpart
+            delta = (
+                (
+                    np.max(axis.to_dask())
+                    - np.min(axis.to_dask())
+                )
+                / axis.shape[-1]
+                / (2.0 * np.pi)
+            )
+            
+            axis_data = fft.fftshift(fft.fftfreq(axis.shape[-1], delta))
+            
+            new_axes.append(
+                Axis(
+                    axis_data,
+                    name=f"k_{axis.name}",
+                    label=f"k_{{{axis.label}}}",
+                    unit=f"({axis.unit})^{{-1}}" if axis.unit else "",
+                )
+            )
+        else:
+            # axis is not fft axis, stays the same
+            new_axes.append(axis)
+
+    # do the data fft
+    fft_data = fft.fftn(grid.to_dask(), axes=fft_axes)
     fft_data = fft.fftshift(fft_data, axes=fft_axes)
 
-    if type == "real":
+    # get only selected component
+    if comp == "abs":
+        fft_data = np.abs(fft_data)
+        label = f"|{grid.label}|"
+    elif comp == "real":
         fft_data = np.real(fft_data)
-        label = f"Re(FFT({dataset.label}))"
-        name = f"fftr_{dataset.name}"
-    elif type == "imag":
+        label = f"\\Re({grid.label})"
+    elif comp == "imag":
         fft_data = np.imag(fft_data)
-        label = f"Im(FFT({dataset.label}))"
-        name = f"ffti_{dataset.name}"
-    elif type == "abs":
-        fft_data = np.abs(fft_data)
-        label = f"|FFT({dataset.label})|"
-        name = f"ffta_{dataset.name}"
+        label = f"\\Im({grid.label})"
+    elif comp == "full":
+        label = f"{grid.label}"
     else:
-        label = f"FFT({dataset.label})"
-        name = f"fft_{dataset.name}"
-
-    axes = []
-    for a in dataset.axes["grid_axes"]:
-        delta = [
-            (np.max(a_ts) - np.min(a_ts)) / len(np.array(a_ts)) / (2.0 * np.pi)
-            for a_ts in a
-        ]
-        axis_data = fft.fftshift(
-            [
-                fft.fftfreq(len(np.array(a_ts)), delta[idx])
-                for idx, a_ts in enumerate(a)
-            ],
-            axes=-1,
-        )
-        axes.append(
-            Axis(
-                axis_data,
-                name=f"k_{a.name}",
-                label=f"k_{{{a.label}}}",
-                unit=f"1/({a.unit})",
-            )
-        )
+        raise ValueError(f"invalid fft component '{comp}'")
 
-    return GridDataset(
+    # build return grid
+    return GridArray.from_array(
         fft_data,
-        name=name,
+        name=grid.name,
         label=label,
-        unit=dataset.unit,
-        grid_axes=axes,
-        time=dataset.axes["time"],
-        iteration=dataset.axes["iteration"],
+        unit=grid.unit,
+        axes=new_axes,
     )
+
+@register_container_plugin(GridDataset, name="fft")
+def fft_grid_dataset(
+    grid: GridDataset,
+    axes: Optional[list] = None,
+    comp: str = "abs",
+) -> GridDataset:
+    """Computes the Fast Fourier Transform (FFT) of a
+    :class:`nata.containers.GridDataset` using `numpy's fft module`__. FFTs
+    are not allowed along the time axis. In other words, `GridDataset` FFTs
+    always preserve the time dependence. To do FFTs over the time axis,
+    consider converting `grid` to a `GridArray` using the `streak()` plugin.
+
+     .. _fft: https://numpy.org/doc/stable/reference/routines.fft.html
+     __ fft_
+
+     The axes over which the FFT is computed are transformed such that
+     the zero frequency bins are centered.
+
+     Parameters
+     ----------
+     axes: ``list``, optional
+         List of integers and/or strings that identify the axes over which
+         to compute the FFT. Must not include to the time axis.
+     comp: ``{'abs', 'real', 'imag', 'full'}``, optional
+         Defines the component of the FFT selected for output. Available
+         values are  ``'abs'`` (default), ``'real'``, ``'imag'`` and
+         ``'full'``, which correspond to the absolute value, real component,
+         imaginary component and full (complex) result of the FFT,
+         respectively.
+
+     Returns
+     ------
+     :class:`nata.containers.GridDataset`:
+         Selected FFT component of ``grid``.
+
+     Examples
+     --------
+     Obtain the FFT of a one-dimensional dataset with time dependence.
+     
+     >>> from nata.containers import GridDataset
+     >>> import numpy as np
+     >>> time = np.arange(3)
+     >>> x = np.linspace(0, 10*np.pi, 101)
+     >>> grid = GridDataset.from_array(
+             [np.sin(x), np.sin(2*x), np.sin(3*x)],
+             axes=[
+                 Axis(time),
+                 Axis(np.tile(x, (3, 1)))
+             ]
+         )
+     >>> fft_grid = grid.fft()
+
+     # TODO: add an image here with a plot of the FFT
+
+    """
+
+    if grid.ndim < 2:
+        raise ValueError("fft is not available for 0 dimensional GridDatasets")
+
+    # build fft axes
+    fft_axes = get_fft_axes(grid, axes, 1)
+
+    if 0 in fft_axes:
+        raise ValueError(f"fft along the time axis is not supported")
+
+    # apply fft to individual grid arrays and stack them
+    return stack([i_grid.fft(axes=[idx - 1 for idx in fft_axes], comp=comp) for i_grid in grid])
\ No newline at end of file
diff --git a/nata/plugins/grids/lineout.py b/nata/plugins/grids/lineout.py
deleted file mode 100644
index fc9672b..0000000
--- a/nata/plugins/grids/lineout.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# -*- coding: utf-8 -*-
-from typing import Union
-
-import numpy as np
-
-from nata.containers import GridDataset
-from nata.plugins.register import register_container_plugin
-
-
-@register_container_plugin(GridDataset, name="lineout")
-def lineout_grid_dataset(
-    dataset: GridDataset, fixed: Union[str, int], value: float,
-) -> GridDataset:
-    """Takes a lineout across a two-dimensional, single/multiple iteration\
-       :class:`nata.containers.GridDataset`:
-
-        Parameters
-        ----------
-
-        fixed: :class:``str`` or :class:``int``
-            Selection of the axes along which the taken lineout is constant.
-
-            * if it is a string, then it must match the ``name`` property of an
-              existing grid axis in ``dataset``.
-            * if it is an integer, then it must match the index of a grid axis
-              in ``dataset`` (i.e. `0` or `1`).
-
-        value: scalar
-            Value between the minimum and maximum of the axes selected through
-            ``fixed`` over which the lineout is taken.
-
-        Returns
-        ------
-        :class:`nata.containers.GridDataset`:
-            One-dimensional :class:`nata.containers.GridDataset`.
-
-        Examples
-        --------
-        The following example shows how to obtain a lineout from a
-        two-dimensional :class:`nata.containers.GridDataset`. Since no axes are
-        attributed to the dataset in this example, they are automatically
-        generated with no names, and ``fixed`` must be an integer.
-
-        >>> from nata.containers import GridDataset
-        >>> import numpy as np
-        >>> arr = np.arange(25).reshape((5,5))
-        >>> ds = GridDataset(arr[np.newaxis])
-        >>> lo = ds.lineout(fixed=0, value=2)
-        >>> lo.data
-        array([10, 11, 12, 13, 14])
-
-    """
-    if len(dataset.grid_shape) != 2:
-        raise ValueError(
-            "Grid lineouts are only supported for two-dimensional grid datasets"
-        )
-
-    # get handle for grid axes
-    axes = dataset.axes["grid_axes"]
-
-    if isinstance(fixed, str):
-        ax_idx = -1
-        # get index based on
-        for key, ax in enumerate(axes):
-            if ax.name == fixed:
-                ax_idx = key
-                break
-        if ax_idx < 0:
-            raise ValueError(
-                f"Axis `{fixed}` could not be found in dataset `{dataset}`"
-            )
-    else:
-        ax_idx = fixed
-
-    # build axis values
-    axis = axes[ax_idx]
-
-    if value < np.min(axis) or value > np.max(axis):
-        raise ValueError(f"Out of range value for fixed `{fixed}`")
-
-    values = np.array(axis)
-    idx = (np.abs(values - value)).argmin()
-
-    data = np.array(dataset)
-
-    # get lineout
-    if ax_idx == 0:
-        lo_data = data[:, idx, :] if len(dataset) > 1 else data[idx, :]
-        lo_axis = axes[1]
-
-    elif ax_idx == 1:
-        lo_data = data[:, :, idx] if len(dataset) > 1 else data[:, idx]
-        lo_axis = axes[0]
-
-    return GridDataset(
-        lo_data if len(dataset) > 1 else lo_data[np.newaxis],
-        name=f"{dataset.name}_lineout",
-        label=dataset.label,
-        unit=dataset.unit,
-        grid_axes=[lo_axis],
-        time=dataset.axes["time"],
-        iteration=dataset.axes["iteration"],
-    )
diff --git a/nata/plugins/grids/slice.py b/nata/plugins/grids/slice.py
new file mode 100644
index 0000000..0c90ce8
--- /dev/null
+++ b/nata/plugins/grids/slice.py
@@ -0,0 +1,155 @@
+# -*- coding: utf-8 -*-
+from typing import Union
+
+import numpy as np
+import dask.array as da
+
+from nata.containers import GridArray
+from nata.containers import GridDataset
+from nata.containers.grid import stack
+from nata.plugins.register import register_container_plugin
+
+def get_slice_axis(
+    grid: Union[GridArray, GridDataset],
+    constant: Union[str, int],
+):
+    if isinstance(constant, str):
+        try:
+            slice_axis = list(ax.name for ax in grid.axes).index(constant)
+        except ValueError:
+            raise ValueError(
+                f"axis '{constant}' could not be found in '{grid.name}'"
+            )
+    else:
+        if constant >= len(grid.axes) or constant < -len(grid.axes):
+            raise ValueError(f"invalid axis index '{constant}'")
+        slice_axis = constant
+
+    return slice_axis
+
+@register_container_plugin(GridArray, name="slice")
+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.
+
+    Parameters
+    ----------
+    constant: ``str`` or ``int``
+        Name or index that defines the axis taken to be constant in the slice.
+    comp: ``float``
+        Value of the axis at which the slice is taken.
+
+    Returns
+    ------
+    :class:`nata.containers.GridArray`:
+        Slice of ``grid``.
+
+    Examples
+    --------
+    Obtain a slice of a two-dimensional array.
+
+    >>> 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],
+    )
+
+
+@register_container_plugin(GridDataset, name="slice")
+def slice_grid_dataset(
+    grid: GridDataset,
+    constant: Union[str, int],
+    value: float,
+) -> GridDataset:
+    """Takes a slice of a `GridDataset` at a constant value of a given axis.
+    Slices are not allowed along the time axis. In other words, `GridDataset`
+    slices always preserve the time dependence. To do slices over the time
+    axis, consider converting `grid` to a `GridArray` using the `streak()`
+    plugin.
+
+    Parameters
+    ----------
+    constant: ``str`` or ``int``
+        Name or index that defines the axis taken to be constant in the slice.
+        Must not refer to the time axis.
+    comp: ``float``
+        Value of the axis at which the slice is taken.
+
+    Returns
+    ------
+    :class:`nata.containers.GridDataset`:
+        Slice of ``grid``.
+
+    Examples
+    --------
+    Obtain a slice of a one-dimensional dataset with time dependence.
+
+    >>> from nata.containers import GridDataset
+    >>> from nata.containers import Axis
+    >>> import numpy as np
+    >>> time, x = np.arange(5), np.tile(np.arange(4), (5,1))
+    >>> data = np.arange(20).reshape((5, 4))
+    >>> grid = GridDataset.from_array(data, axes=[Axis(time), Axis(x)])
+    >>> grid.to_numpy()
+    array([[ 0,  1,  2,  3],
+           [ 4,  5,  6,  7],
+           [ 8,  9, 10, 11],
+           [12, 13, 14, 15],
+           [16, 17, 18, 19]])
+    >>> grid.slice(constant=1, value=0).to_numpy()
+    array([ 0,  4,  8, 12, 16]) # the first column
+
+    """
+
+    if grid.ndim < 2:
+        raise ValueError("slice is not available for 0 dimensional GridDatasets")
+
+    # get slice axis
+    slice_axis = get_slice_axis(grid, constant)
+
+    axis = grid.axes[slice_axis]
+
+    if axis is grid.time:
+        raise ValueError(f"slice along the time axis is not supported")
+    
+    if np.any(value < np.min(axis.to_dask(), axis=-1)) or np.any(value >= np.max(axis.to_dask(), axis=-1)):
+        raise ValueError(f"out of range value for axis '{constant}'")
+
+    # apply slice to individual grid arrays and stack them
+    return stack([i_grid.slice(constant=slice_axis-1, value=value) for i_grid in grid])
\ No newline at end of file
diff --git a/nata/plugins/plot/__init__.py b/nata/plugins/plot/__init__.py
index 675899c..d9f7e76 100644
--- a/nata/plugins/plot/__init__.py
+++ b/nata/plugins/plot/__init__.py
@@ -1,4 +1,4 @@
 # -*- coding: utf-8 -*-
 from .grid import *
-from .particle import *
-from .collection import *
+# from .particle import *
+# from .collection import *
diff --git a/nata/plugins/register.py b/nata/plugins/register.py
index 3019e8a..794281c 100644
--- a/nata/plugins/register.py
+++ b/nata/plugins/register.py
@@ -29,7 +29,7 @@ def _parse_register_args(callable_or_container, **kwargs):
 
 
 def register_container_plugin(
-    callable_or_container=None, container=None, name: Optional[str] = None
+    callable_or_container=None, container=None, name: Optional[str] = None, plugin_type: str = "method"
 ):
     """Decorator for registering a plugin for a container."""
     arguments = _parse_register_args(
@@ -46,7 +46,7 @@ def wrapper(self, *args, **kwargs):
             return func(self, *args, **kwargs)
 
         container.register_plugin(
-            function_name if function_name else func.__name__, wrapper
+            function_name if function_name else func.__name__, wrapper, plugin_type=plugin_type
         )
         return func
 


Test patch:
diff --git a/tests/plugins/fft_test.py b/tests/plugins/fft_test.py
new file mode 100644
index 0000000..deda8a3
--- /dev/null
+++ b/tests/plugins/fft_test.py
@@ -0,0 +1,110 @@
+# -*- coding: utf-8 -*-
+import numpy as np
+import numpy.fft as fft
+import pytest
+
+from nata.containers import Axis
+from nata.containers import GridArray
+from nata.containers import GridDataset
+
+
+def test_array_fft_invalid_ndim():
+
+    with pytest.raises(ValueError, match="0 dimensional GridArrays"):
+        GridArray.from_array(1).fft()
+
+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(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(np.arange(10))] * 2,
+            ).fft(axes=[invalid_axis])
+
+
+def test_array_fft_shape_1d():
+    x = np.arange(10)
+
+    for axes in [
+        [Axis(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
+
+
+def test_array_fft_shape_2d():
+    x = np.arange(10)
+    data = np.arange(100).reshape((10, 10))
+
+    for axes in [
+        [Axis(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
+
+
+def test_array_fft_comps_1d():
+    x = np.linspace(0, 10 * np.pi, 101)
+    grid = GridArray.from_array(np.sin(x), axes=[Axis(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))
+
+
+def test_array_fft_peak_1d():
+    x = np.linspace(0, 10 * np.pi, 101)
+    grid = GridArray.from_array(np.sin(x), axes=[Axis(x)])
+    fft_grid = grid.fft()
+
+    assert (
+        fft_grid.to_dask().argmax() == (np.abs(fft_grid.axes[0].to_dask() + 1)).argmin()
+    )
+
+def test_dataset_fft_peak_1d():
+    time = np.arange(1, 3)
+    x = np.linspace(0, 10*np.pi, 101)
+
+    k_modes = np.arange(len(time))+1
+
+    grid = GridDataset.from_array(
+        [np.sin(k_i*x) for k_i in k_modes],
+        axes=[
+            Axis(time),
+            Axis(np.tile(x, (len(time), 1)))
+        ]
+    )
+    fft_grid = grid.fft()
+
+    for k_i, fft_grid_i in zip(k_modes, fft_grid):
+        assert (
+            fft_grid_i.to_dask().argmax() == (np.abs(fft_grid_i.axes[0].to_dask() + k_i)).argmin()
+        )
+
+def test_dataset_fft_selection():
+    grid = GridDataset.from_array(np.arange(12).reshape((4, 3)))
+
+    with pytest.raises(ValueError, match=f"fft along the time axis is not supported"):
+        grid.fft(axes=[0])
+
+def test_dataset_fft_invalid_ndim():
+
+    with pytest.raises(ValueError, match="0 dimensional GridDatasets"):
+        GridDataset.from_array(np.arange(5)).fft()
\ No newline at end of file
diff --git a/tests/plugins/slice_test.py b/tests/plugins/slice_test.py
new file mode 100644
index 0000000..6d51eb6
--- /dev/null
+++ b/tests/plugins/slice_test.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+import numpy as np
+import pytest
+
+from nata.containers import Axis
+from nata.containers import GridArray
+from nata.containers import GridDataset
+
+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))
+
+
+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)
+
+
+def test_array_slice_invalid_ndim():
+
+    with pytest.raises(ValueError, match="0 dimensional GridArrays"):
+        GridArray.from_array(1).slice(constant="axis0", value=0)
+
+
+def test_dataset_slice_dimensionality():
+    data = np.arange(96).reshape((8, 4, 3))
+    grid = GridDataset.from_array(data)
+
+    sliced_grid = grid.slice(constant="axis0", value=0)
+
+    assert sliced_grid.ndim == 2
+    assert sliced_grid.axes[0].name == grid.axes[0].name
+    assert sliced_grid.axes[1].name == grid.axes[2].name
+
+    np.testing.assert_array_equal(sliced_grid, data[:,0,:])
+
+def test_dataset_slice_selection():
+    grid = GridDataset.from_array(np.arange(12).reshape((4, 3)))
+
+    with pytest.raises(ValueError, match=f"slice along the time axis is not supported"):
+        grid.slice(constant=grid.time.name, value=0)
+
+def test_dataset_slice_invalid_ndim():
+
+    with pytest.raises(ValueError, match="0 dimensional GridDatasets"):
+        GridDataset.from_array(np.arange(5)).slice(constant="axis0", value=1)
\ No newline at end of file