diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d579b9a074657960670aa4eedd0dcf8c2bc73fed..e9fe349ea93f5abb4e30e39fbdcea9ee1dc81754 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -24,6 +24,7 @@ stages:
   artifacts:
     paths:
       - report.xml
+      - htmlcov
     expire_in: 1 day
   script:
     - ./ci/test.py
diff --git a/ci/test.py b/ci/test.py
index c6d90a39d599fc668a6a1ed525c2a940ddeeec4f..cce250734d5cf4fa9724c3155a4714ea22c129e4 100755
--- a/ci/test.py
+++ b/ci/test.py
@@ -34,7 +34,7 @@ if __name__ == "__main__":
             "--prompt",
             "ci",
             ".venv",
-        ],
+        ]
     )
 
     check_call(
@@ -44,9 +44,16 @@ if __name__ == "__main__":
             "pip",
             "install",
             str(sorted(Path("dist").glob("*.whl"))[-1].resolve()),
-        ],
+        ]
     )
 
     check_call(
-        [python_venv_executable(), "-m", "pytest", "--junitxml=report.xml"],
+        [
+            python_venv_executable(),
+            "-m",
+            "pytest",
+            "--junitxml=report.xml",
+            "--cov=src",
+            "--cov-report=html",
+        ]
     )
diff --git a/examples/example_basic.ipynb b/examples/example_basic.ipynb
index 5445fe80256a9ee78bc0ae8e3c439135750b41b8..e737a4c023bb58873e9331b73d68a8af40ad8fda 100644
--- a/examples/example_basic.ipynb
+++ b/examples/example_basic.ipynb
@@ -14,155 +14,160 @@
       "['fish_1', 'fish_2', 'fish_3', 'obstacle_1', 'robot']\n",
       "\n",
       "All poses\n",
-      "[[[8.86584103e-01 2.35670820e-01 5.41754842e-01 4.49850202e-01]\n",
-      "  [8.15511882e-01 4.78223324e-01 6.29803419e-01 1.12592392e-01]\n",
-      "  [1.53732300e-01 7.24954247e-01 9.38574493e-01 4.65665817e-01]\n",
-      "  [9.10354614e-01 4.47880208e-01 3.81429136e-01 9.67544317e-01]\n",
-      "  [6.07822955e-01 5.20158827e-01 8.17965686e-01 8.42760384e-01]]\n",
+      "[[[5.56598067e-01 2.42021829e-01 2.45265663e-01 2.95294344e-01]\n",
+      "  [9.83367860e-01 4.36241180e-01 5.68063319e-01 8.96367550e-01]\n",
+      "  [8.71030211e-01 9.32705551e-02 8.51928890e-01 9.48658109e-01]\n",
+      "  ...\n",
+      "  [6.94550753e-01 6.52826130e-01 6.08456850e-01 4.88614887e-01]\n",
+      "  [4.84500438e-01 1.14949882e-01 6.08556986e-01 7.93362781e-02]\n",
+      "  [9.54909027e-01 3.18913072e-01 4.58294243e-01 7.45387852e-01]]\n",
       "\n",
-      " [[2.29353935e-01 8.80753636e-01 7.94585168e-01 2.22074524e-01]\n",
-      "  [6.13970399e-01 1.33511815e-02 2.89155185e-01 2.65219092e-01]\n",
-      "  [6.62197351e-01 6.47982001e-01 9.46004018e-02 6.59599364e-01]\n",
-      "  [4.86104101e-01 4.23153102e-01 1.39821902e-01 3.11809748e-01]\n",
-      "  [8.03322852e-01 9.52799857e-01 3.89638603e-01 6.43237352e-01]]\n",
+      " [[7.51943365e-02 9.95502114e-01 5.04003823e-01 8.36720586e-01]\n",
+      "  [8.18848014e-01 4.04324770e-01 5.49858093e-01 3.51742476e-01]\n",
+      "  [1.66903093e-01 1.78061739e-01 2.81622916e-01 8.88221264e-01]\n",
+      "  ...\n",
+      "  [7.69020915e-01 6.33118331e-01 4.15713340e-01 4.24170971e-01]\n",
+      "  [7.64205098e-01 7.78579533e-01 7.44598091e-01 3.30398619e-01]\n",
+      "  [4.45223182e-01 9.25011218e-01 2.36187894e-02 7.62242600e-02]]\n",
       "\n",
-      " [[9.70978260e-01 6.75936878e-01 6.23196602e-01 8.42264950e-01]\n",
-      "  [4.07079160e-01 8.46290290e-01 5.64092159e-01 3.56871307e-01]\n",
-      "  [4.84096229e-01 8.60232174e-01 1.39015794e-01 7.82253265e-01]\n",
-      "  [1.24170482e-01 2.21511930e-01 8.88282284e-02 4.53450561e-01]\n",
-      "  [1.28404438e-01 2.87771430e-02 4.57022637e-01 9.80571806e-01]]\n",
+      " [[7.73669600e-01 3.54849041e-01 4.21867281e-01 9.16552365e-01]\n",
+      "  [4.73650604e-01 1.79305673e-01 8.38760436e-01 3.96051705e-01]\n",
+      "  [2.01547332e-02 8.12301695e-01 2.78097481e-01 8.67732406e-01]\n",
+      "  ...\n",
+      "  [8.12627971e-01 6.28660858e-01 2.13196307e-01 6.49513781e-01]\n",
+      "  [5.58035910e-01 4.63277161e-01 8.21570277e-01 6.79726541e-01]\n",
+      "  [7.10023165e-01 5.45146585e-01 8.51007760e-01 9.56029415e-01]]\n",
       "\n",
-      " [[5.00000000e+01 5.00000000e+01 0.00000000e+00 0.00000000e+00]\n",
+      " [[5.00000000e+01 5.00000000e+01 1.00000000e+00 0.00000000e+00]\n",
       "  [           nan            nan            nan            nan]\n",
       "  [           nan            nan            nan            nan]\n",
+      "  ...\n",
+      "  [           nan            nan            nan            nan]\n",
       "  [           nan            nan            nan            nan]\n",
       "  [           nan            nan            nan            nan]]\n",
       "\n",
-      " [[0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]\n",
-      "  [0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]\n",
-      "  [0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]\n",
-      "  [0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]\n",
-      "  [           nan            nan            nan            nan]]]\n",
+      " [[5.00000000e+01 5.00000000e+01 5.00000000e+01 5.00000000e+01]\n",
+      "  [5.00000000e+01 5.00000000e+01 5.00000000e+01 5.00000000e+01]\n",
+      "  [5.00000000e+01 5.00000000e+01 5.00000000e+01 5.00000000e+01]\n",
+      "  ...\n",
+      "  [5.00000000e+01 5.00000000e+01 5.00000000e+01 5.00000000e+01]\n",
+      "  [5.00000000e+01 5.00000000e+01 5.00000000e+01 5.00000000e+01]\n",
+      "  [5.00000000e+01 5.00000000e+01 5.00000000e+01 5.00000000e+01]]]\n",
       "\n",
       "Fish poses\n",
-      "[[[0.8865841  0.23567082 0.54175484 0.4498502 ]\n",
-      "  [0.81551188 0.47822332 0.62980342 0.11259239]\n",
-      "  [0.1537323  0.72495425 0.93857449 0.46566582]\n",
-      "  [0.91035461 0.44788021 0.38142914 0.96754432]\n",
-      "  [0.60782295 0.52015883 0.81796569 0.84276038]]\n",
+      "[[[0.55659807 0.24202183 0.24526566 0.29529434]\n",
+      "  [0.98336786 0.43624118 0.56806332 0.89636755]\n",
+      "  [0.87103021 0.09327056 0.85192889 0.94865811]\n",
+      "  ...\n",
+      "  [0.69455075 0.65282613 0.60845685 0.48861489]\n",
+      "  [0.48450044 0.11494988 0.60855699 0.07933628]\n",
+      "  [0.95490903 0.31891307 0.45829424 0.74538785]]\n",
       "\n",
-      " [[0.22935393 0.88075364 0.79458517 0.22207452]\n",
-      "  [0.6139704  0.01335118 0.28915519 0.26521909]\n",
-      "  [0.66219735 0.647982   0.0946004  0.65959936]\n",
-      "  [0.4861041  0.4231531  0.1398219  0.31180975]\n",
-      "  [0.80332285 0.95279986 0.3896386  0.64323735]]\n",
+      " [[0.07519434 0.99550211 0.50400382 0.83672059]\n",
+      "  [0.81884801 0.40432477 0.54985809 0.35174248]\n",
+      "  [0.16690309 0.17806174 0.28162292 0.88822126]\n",
+      "  ...\n",
+      "  [0.76902092 0.63311833 0.41571334 0.42417097]\n",
+      "  [0.7642051  0.77857953 0.74459809 0.33039862]\n",
+      "  [0.44522318 0.92501122 0.02361879 0.07622426]]\n",
       "\n",
-      " [[0.97097826 0.67593688 0.6231966  0.84226495]\n",
-      "  [0.40707916 0.84629029 0.56409216 0.35687131]\n",
-      "  [0.48409623 0.86023217 0.13901579 0.78225327]\n",
-      "  [0.12417048 0.22151193 0.08882823 0.45345056]\n",
-      "  [0.12840444 0.02877714 0.45702264 0.98057181]]]\n",
+      " [[0.7736696  0.35484904 0.42186728 0.91655236]\n",
+      "  [0.4736506  0.17930567 0.83876044 0.3960517 ]\n",
+      "  [0.02015473 0.8123017  0.27809748 0.86773241]\n",
+      "  ...\n",
+      "  [0.81262797 0.62866086 0.21319631 0.64951378]\n",
+      "  [0.55803591 0.46327716 0.82157028 0.67972654]\n",
+      "  [0.71002316 0.54514658 0.85100776 0.95602942]]]\n",
       "\n",
       "File structure\n",
-      " version:\t[1 0]\n",
-      " world size:\t[100. 100.]\n",
+      " format_url:\thttps://git.imp.fu-berlin.de/bioroboticslab/robofish/track_format/-/releases/1.0\n",
+      " format_version:\t[1 0]\n",
+      " world_size_cm:\t[100. 100.]\n",
       "| entities\n",
       "|---| fish_1\n",
-      "|---|--- type:\tfish\n",
-      "|---|--- poses:\t Shape (5, 4)\n",
-      "|---|---| time\n",
-      "|---|---|--- monotonic points:\t Shape (5,)\n",
+      "|---|--- category:\tfish\n",
+      "|---|--- orientations:\t Shape (1000, 2)\n",
+      "|---|--- positions:\t Shape (1000, 2)\n",
       "|---| fish_2\n",
-      "|---|--- type:\tfish\n",
-      "|---|--- poses:\t Shape (5, 4)\n",
-      "|---|---| time\n",
-      "|---|---|--- monotonic points:\t Shape (5,)\n",
+      "|---|--- category:\tfish\n",
+      "|---|--- orientations:\t Shape (1000, 2)\n",
+      "|---|--- positions:\t Shape (1000, 2)\n",
       "|---| fish_3\n",
-      "|---|--- type:\tfish\n",
-      "|---|--- poses:\t Shape (5, 4)\n",
-      "|---|---| time\n",
-      "|---|---|--- monotonic points:\t Shape (5,)\n",
+      "|---|--- category:\tfish\n",
+      "|---|--- orientations:\t Shape (1000, 2)\n",
+      "|---|--- positions:\t Shape (1000, 2)\n",
       "|---| obstacle_1\n",
-      "|---|--- type:\tobstacle\n",
+      "|---|--- category:\tobstacle\n",
+      "|---|--- orientations:\t Shape (1, 2)\n",
       "|---|--- outlines:\t Shape (1, 4, 2)\n",
-      "|---|--- poses:\t Shape (1, 4)\n",
-      "|---|---| time\n",
+      "|---|--- positions:\t Shape (1, 2)\n",
       "|---| robot\n",
-      "|---|--- type:\trobot\n",
-      "|---|--- poses:\t Shape (4, 4)\n",
-      "|---|---| time\n",
-      "|---|---|--- monotonic step:\t40\n",
+      "|---|--- category:\trobot\n",
+      "|---|--- orientations:\t Shape (1000, 2)\n",
+      "|---|--- positions:\t Shape (1000, 2)\n",
+      "| samplings\n",
+      "|--- default:\t25 hz\n",
+      "|---| 25 hz\n",
+      "|---|--- frequency_hz:\t25.0\n",
       "\n"
      ]
     }
    ],
    "source": [
-    "#! /usr/bin/env python3\n",
-    "\n",
     "import robofish.io\n",
     "import numpy as np\n",
-    "from pathlib import Path\n",
-    "import os\n",
-    "\n",
     "\n",
-    "# Helper function to enable relative paths from this file\n",
-    "def full_path(path):\n",
-    "    return (Path(os.path.abspath(\"__file__\")).parent / path).resolve()\n",
     "\n",
-    "\n",
-    "if __name__ == \"__main__\":\n",
+    "def create_example_file(path):\n",
     "    # Create a new io file object with a 100x100cm world\n",
-    "    sf = robofish.io.File(world_size=[100, 100])\n",
+    "    sf = robofish.io.File(world_size_cm=[100, 100], frequency_hz=25.0)\n",
     "\n",
     "    # create a simple obstacle, fixed in place, fixed outline\n",
-    "    obstacle_pose = [[50, 50, 0, 0]]\n",
     "    obstacle_outline = [[[-10, -10], [-10, 0], [0, 0], [0, -10]]]\n",
     "    obstacle_name = sf.create_entity(\n",
-    "        \"obstacle\", poses=obstacle_pose, outlines=obstacle_outline\n",
+    "        \"obstacle\", positions=[[50, 50]], orientations=[[0]], outlines=obstacle_outline\n",
     "    )\n",
     "\n",
-    "    # create a robofish with 100 timesteps and 40ms between the timesteps. If we would not give a name, the name would be generated to be robot_1.\n",
-    "    robofish_timesteps = 4\n",
-    "    robofish_poses = np.zeros((robofish_timesteps, 4))\n",
-    "    sf.create_entity(\"robot\", robofish_poses, name=\"robot\", monotonic_step=40)\n",
+    "    # create a robofish with 1000 timesteps. If we would not give a name, the name would be generated to be robot_1.\n",
+    "    robofish_timesteps = 1000\n",
+    "    robofish_poses = np.ones((robofish_timesteps, 4)) * 50\n",
+    "    robot = sf.create_entity(\"robot\", robofish_poses, name=\"robot\")\n",
     "\n",
     "    # create multiple fishes with timestamps. Since we don't specify names, but only the type \"fish\" the fishes will be named [\"fish_1\", \"fish_2\", \"fish_3\"]\n",
     "    agents = 3\n",
-    "    timesteps = 5\n",
-    "    timestamps = np.linspace(0, timesteps + 1, timesteps)\n",
+    "    timesteps = 1000\n",
+    "    # timestamps = np.linspace(0, timesteps + 1, timesteps)\n",
     "    agent_poses = np.random.random((agents, timesteps, 4))\n",
     "\n",
-    "    fish_names = sf.create_multiple_entities(\n",
-    "        \"fish\", agent_poses, monotonic_points=timestamps\n",
-    "    )\n",
+    "    fishes = sf.create_multiple_entities(\"fish\", agent_poses)\n",
     "\n",
     "    # This would throw an exception if the file was invalid\n",
     "    sf.validate()\n",
     "\n",
     "    # Save file validates aswell\n",
-    "    example_file = full_path(\"example.hdf5\")\n",
-    "    sf.save(example_file)\n",
+    "\n",
+    "    sf.save_as(path)\n",
     "\n",
     "    # Closing and opening files (just for demonstration)\n",
     "    sf.close()\n",
-    "    sf = robofish.io.File(path=example_file)\n",
+    "    sf = robofish.io.File(path=path)\n",
     "\n",
     "    print(\"\\nEntity Names\")\n",
     "    print(sf.entity_names)\n",
     "\n",
-    "    # Get an array with all poses. As the length of poses varies per agent, it\n",
-    "    # is filled up with nans. The result is not interpolated and the time scales\n",
-    "    # per agent are different. It is planned to create a warning in the case of\n",
-    "    # different time scales and have another function, which generates an\n",
-    "    # interpolated array.\n",
+    "    # Get an array with all poses. As the length of poses varies per agent, it is filled up with nans.\n",
     "    print(\"\\nAll poses\")\n",
-    "    print(sf.select_poses())\n",
+    "    print(sf.entity_poses)\n",
     "\n",
     "    print(\"\\nFish poses\")\n",
-    "    print(sf.select_poses(lambda e: e.category == \"fish\"))\n",
+    "    print(sf.select_entity_poses(lambda e: e.category == \"fish\"))\n",
     "\n",
     "    print(\"\\nFile structure\")\n",
-    "    print(sf)\n"
+    "    print(sf)\n",
+    "\n",
+    "\n",
+    "if __name__ == \"__main__\":\n",
+    "    create_example_file(\"example.hdf5\")\n"
    ]
   }
  ],
@@ -187,4 +192,4 @@
  },
  "nbformat": 4,
  "nbformat_minor": 4
-}
\ No newline at end of file
+}
diff --git a/examples/example_basic.py b/examples/example_basic.py
index dec8e3be1c7997b33b36f9868f0df8b0c6c3fbe6..b9e356c7547a37cdfc66e75f8f93269bb4365a1c 100755
--- a/examples/example_basic.py
+++ b/examples/example_basic.py
@@ -1,7 +1,6 @@
 #! /usr/bin/env python3
 
 import robofish.io
-from robofish.io import utils
 import numpy as np
 
 
diff --git a/setup.py b/setup.py
index 5be2fe4573c17f9dbb776058058ea0e38c4674aa..7999f5ac38332788fb314af928b99b67c06040d7 100644
--- a/setup.py
+++ b/setup.py
@@ -14,9 +14,15 @@ entry_points = {
     ]
 }
 
+
 def source_version():
     version_parts = (
-        run(["git", "describe", "--tags", "--dirty"], check=True, stdout=PIPE, encoding="utf-8")
+        run(
+            ["git", "describe", "--tags", "--dirty"],
+            check=True,
+            stdout=PIPE,
+            encoding="utf-8",
+        )
         .stdout.strip()
         .split("-")
     )
@@ -36,12 +42,20 @@ def source_version():
 
     return version
 
+
 setup(
     name="robofish-io",
     version=source_version(),
     author="",
     author_email="",
-    install_requires=["h5py>=3", "numpy", "seaborn", "pandas", "deprecation"],
+    install_requires=[
+        "h5py>=3",
+        "numpy",
+        "seaborn",
+        "pandas",
+        "deprecation",
+        "testbook",
+    ],
     classifiers=[
         "Development Status :: 3 - Alpha",
         "Intended Audience :: Science/Research",
diff --git a/src/robofish/io/entity.py b/src/robofish/io/entity.py
index 8ef557c3d7d0bdcdd010f47055a121ca3452114f..f791a125e2e7ef9f22c539e9b9810061e444de88 100644
--- a/src/robofish/io/entity.py
+++ b/src/robofish/io/entity.py
@@ -98,7 +98,7 @@ class Entity(h5py.Group):
         else:
             if poses is not None:
 
-                assert poses.shape[1] == 3 or poses.shape[1] == 4
+                assert poses.shape[1] in [3, 4]
                 positions = poses[:, :2]
                 orientations = poses[:, 2:]
             if orientations is not None and orientations.shape[1] == 1:
diff --git a/tests/robofish/evaluate/test_app_evaluate.py b/tests/robofish/evaluate/test_app_evaluate.py
index 58ca278882b1756830fd66b7a37a4cb823d8199a..2a7fe486a95c961f41f591ea7c8ab533db6b2ccf 100644
--- a/tests/robofish/evaluate/test_app_evaluate.py
+++ b/tests/robofish/evaluate/test_app_evaluate.py
@@ -22,7 +22,7 @@ def test_app_validate():
             self.names = None
             self.save_path = graphics_out
 
-    # TODO: Get rid of deprecated get_poses function
+    # TODO: Get rid of deprecation
     with pytest.warns(DeprecationWarning):
         app.evaluate(DummyArgs("speed"))
     graphics_out.unlink()
diff --git a/tests/robofish/io/test_examples.py b/tests/robofish/io/test_examples.py
index 1d0379fb1b06448e5f733c3690ff48a4f623592c..deb626a6faa1d3675b00fb7bf18ecff39488022e 100644
--- a/tests/robofish/io/test_examples.py
+++ b/tests/robofish/io/test_examples.py
@@ -1,12 +1,13 @@
 import robofish.io
 from robofish.io import utils
 from pathlib import Path
+from testbook import testbook
 import sys
 
 
 sys.path.append(str(utils.full_path(__file__, "../../../examples/")))
 
-
+ipynb_path = utils.full_path(__file__, "../../../examples/example_basic.ipynb")
 path = utils.full_path(__file__, "../../../examples/tmp_example.hdf5")
 if path.exists():
     path.unlink()
@@ -24,3 +25,9 @@ def test_example_basic():
 
     example_basic.create_example_file(path)
     path.unlink()
+
+
+def test_example_basic_ipynb():
+    # Executing the notebook should not lead to an exception
+    with testbook(str(ipynb_path), execute=True) as tb:
+        pass