diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 29d0df44bab93b42b8ec7c3a1b37cd3ee2152ea9..072e1668ab9a3129600f6b2a38c9756d6bb6f250 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,6 +1,6 @@
 # Official language image. Look for the different tagged releases at:
 # https://hub.docker.com/r/library/python/tags/
-image: python:3.7
+image: python:3.8
 
 stages:
   - test
diff --git a/lisainstrument/instrument.py b/lisainstrument/instrument.py
index f5a63ad8357d5358c657c14a75fc1cfab02cc484..54c7e71619a152814ad19d33721445dbaf386f53 100644
--- a/lisainstrument/instrument.py
+++ b/lisainstrument/instrument.py
@@ -169,18 +169,27 @@ class Instrument:
         self.version = meta.__version__
         self.simulated = False
 
+        # Check orbit dataset
+        if orbit_dataset not in ['tcb/ltt', 'tps/ppr']:
+            raise ValueError(f"invalid orbit dataset '{orbit_dataset}'")
+
         # Measurement sampling
         if t0 == 'orbits':
             if isinstance(orbits, str) and orbits != 'static':
                 logger.debug("Reading initial time from orbit file '%s'", orbits)
                 with File(orbits, 'r') as orbitf:
-                    if orbit_dataset == 'tcb/ltt':
-                        attr = 't0'
-                    elif orbit_dataset == 'tps/ppr':
-                        attr = 'tau0'
+                    version = Version(orbitf.attrs['version'])
+                    logger.debug("Using orbit file version %s", version)
+                    # Warn for orbit file development version
+                    if version.is_devrelease:
+                        logger.warning("You are using an orbit file in a development version")
+                    # Switch between various orbit file standards
+                    if version in SpecifierSet('== 1.*', True):
+                        self.t0 = float(orbitf.attrs['t0' if orbit_dataset == 'tcb/ltt' else 'tau0'])
+                    elif version in SpecifierSet('== 2.*', True):
+                        self.t0 = float(orbitf.attrs['t0'])
                     else:
-                        raise ValueError(f"invalid orbit dataset '{orbit_dataset}'")
-                    self.t0 = float(orbitf.attrs[attr])
+                        raise ValueError(f"unsupported orbit file version '{version}'")
             else:
                 self.t0 = 0.0
         else:
@@ -197,7 +206,19 @@ class Instrument:
             if isinstance(orbits, str) and orbits != 'static':
                 logger.debug("Reading telemetry initial time from orbit file '%s'", orbits)
                 with File(orbits, 'r') as orbitf:
-                    self.telemetry_t0 = float(orbitf.attrs['t0'])
+                    version = Version(orbitf.attrs['version'])
+                    logger.debug("Using orbit file version %s", version)
+                    # Warn for orbit file development version
+                    if version.is_devrelease:
+                        logger.warning("You are using an orbit file in a development version")
+                    # Switch between various orbit file standards
+                    if version in SpecifierSet('== 1.*', True):
+                        self.telemetry_t0 = float(orbitf.attrs['t0'])
+                    elif version in SpecifierSet('== 2.*', True):
+                        self.telemetry_t0 = float(orbitf.attrs['t0'])
+                    else:
+                        raise ValueError(f"unsupported orbit file version '{version}'")
+
             else:
                 self.telemetry_t0 = 0.0
         else:
@@ -501,10 +522,14 @@ class Instrument:
             with File(self.orbit_file, 'r') as orbitf:
                 version = Version(orbitf.attrs['version'])
                 logger.debug("Using orbit file version %s", version)
+                # Warn for orbit file development version
                 if version.is_devrelease:
                     logger.warning("You are using an orbit file in a development version")
-                if version in SpecifierSet('~= 1.0', True):
+                # Switch between various orbit file standards
+                if version in SpecifierSet('== 1.*', True):
                     self.init_orbits_file_1_0(orbitf)
+                elif version in SpecifierSet('== 2.*', True):
+                    self.init_orbits_file_2_0(orbitf)
                 else:
                     raise ValueError(f"unsupported orbit file version '{version}'")
         else:
@@ -518,7 +543,7 @@ class Instrument:
             self.orbit_dataset = None
 
     def init_orbits_file_1_0(self, orbitf):
-        """Initialize orbits from an orbit file version ~= 1.0."""
+        """Initialize orbits from an orbit file version == 1.*."""
 
         def pprs(mosa):
             if self.orbit_dataset == 'tcb/ltt':
@@ -562,6 +587,33 @@ class Instrument:
             logger.error("Missing orbit information at \n%s", self.physics_t)
             raise ValueError("missing orbit information, use longer orbit file or adjust sampling") from error
 
+    def init_orbits_file_2_0(self, orbitf):
+        """Initialize orbits from an orbit file version == 2.*."""
+
+        # Prepare common interpolation method
+        times = orbitf.attrs['t0'] + np.arange(orbitf.attrs['size']) * orbitf.attrs['dt']
+        interpolate = lambda data, t: InterpolatedUnivariateSpline(times, data, ext='raise')(t)
+        index = {'12': 0, '23': 1, '31': 2, '13': 3, '32': 4, '21': 5}
+
+        # Interpolate necessary orbital quantities,
+        # show a helpful error message if orbit file is too short
+        try:
+            logger.debug("Interpolating proper pseudo-ranges")
+            dataset = orbitf['tcb/ltt'] if self.orbit_dataset == 'tcb/ltt' else orbitf['tps/ppr']
+            self.pprs = ForEachMOSA(lambda mosa: interpolate(dataset[:, index[mosa]], self.physics_t))
+            logger.debug("Interpolating proper pseudo-range derivatives")
+            dataset = orbitf['tcb/d_ltt'] if self.orbit_dataset == 'tcb/ltt' else orbitf['tps/d_ppr']
+            self.d_pprs = ForEachMOSA(lambda mosa: interpolate(dataset[:, index[mosa]], self.physics_t))
+            logger.debug("Interpolating proper time deviation from TCB")
+            if self.orbit_dataset == 'tcb/ltt':
+                self.tps_proper_time_deviations = ForEachSC(lambda sc: 0)
+            else:
+                dataset = orbitf['tcb/delta_tau']
+                self.tps_proper_time_deviations = ForEachSC(lambda sc: interpolate(dataset[:, sc - 1], self.physics_t))
+        except ValueError as error:
+            logger.error("Missing orbit information at \n%s", self.physics_t)
+            raise ValueError("missing orbit information, use longer orbit file or adjust sampling") from error
+
     def init_gws(self, gws):
         """Initialize gravitational-wave responses."""
         if isinstance(gws, str):
diff --git a/requirements.txt b/requirements.txt
index a2effaaa13c6344e12b6952613a1f9c347bbd39d..fed2532098f4e7e6f7b135ce7399839e1778747d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,29 +1,59 @@
-astroid==2.8.4
-attrs==21.2.0
-cycler==0.10.0
-h5py==3.5.0
+alabaster==0.7.12
+astroid==2.11.2
+attrs==21.4.0
+Babel==2.9.1
+certifi==2021.10.8
+charset-normalizer==2.0.12
+cycler==0.11.0
+dill==0.3.4
+docutils==0.17.1
+fonttools==4.31.2
+h5py==3.6.0
+idna==3.3
+imagesize==1.3.0
+importlib-metadata==4.11.3
 iniconfig==1.1.1
-isort==5.9.3
-kiwisolver==1.3.2
-lazy-object-proxy==1.6.0
-matplotlib==3.4.3
-mccabe==0.6.1
-mypy==0.931
+isort==5.10.1
+Jinja2==3.1.1
+kiwisolver==1.4.1
+lazy-object-proxy==1.7.1
+markdown-it-py==2.0.1
+MarkupSafe==2.1.1
+matplotlib==3.5.1
+mccabe==0.7.0
+mdit-py-plugins==0.3.0
+mdurl==0.1.0
+mypy==0.942
 mypy-extensions==0.4.3
-numpy==1.21.3
-packaging==21.0
-Pillow==8.4.0
-platformdirs==2.4.0
+myst-parser==0.17.0
+numpy==1.22.3
+packaging==21.3
+Pillow==9.0.1
+platformdirs==2.5.1
 pluggy==1.0.0
-py==1.10.0
-pylint==2.11.1
-pyparsing==3.0.3
+py==1.11.0
+Pygments==2.11.2
+pylint==2.13.2
+pyparsing==3.0.7
 pyplnoise==1.3
-pytest==6.2.5
+pytest==7.1.1
 python-dateutil==2.8.2
-scipy==1.7.1
+pytz==2022.1
+PyYAML==6.0
+requests==2.27.1
+scipy==1.8.0
 six==1.16.0
-toml==0.10.2
-tomli==2.0.0
-typing-extensions==3.10.0.2
-wrapt==1.13.2
+snowballstemmer==2.2.0
+Sphinx==4.5.0
+sphinx-rtd-theme==1.0.0
+sphinxcontrib-applehelp==1.0.2
+sphinxcontrib-devhelp==1.0.2
+sphinxcontrib-htmlhelp==2.0.0
+sphinxcontrib-jsmath==1.0.1
+sphinxcontrib-qthelp==1.0.3
+sphinxcontrib-serializinghtml==1.1.5
+tomli==2.0.1
+typing_extensions==4.1.1
+urllib3==1.26.9
+wrapt==1.14.0
+zipp==3.7.0
diff --git a/setup.py b/setup.py
index b77e59f67edbbd7665d0e2ce01dc80bd2ee0e23f..9ca88e6ebbec5dc3f0319bcc083f12c1b7dce966 100644
--- a/setup.py
+++ b/setup.py
@@ -2,21 +2,22 @@
 # -*- coding: utf-8 -*-
 # pylint: disable=line-too-long,missing-module-docstring,exec-used
 
+from typing import Dict
 import setuptools
 
 
-with open("README.md", "r") as fh:
+with open("README.md", 'r', encoding='utf-8') as fh:
     long_description = fh.read()
 
-meta = {}
-with open("lisainstrument/meta.py") as file:
-    exec(file.read(), meta)
+META: Dict[str, str] = {}
+with open("lisainstrument/meta.py", 'r', encoding='utf-8') as file:
+    exec(file.read(), META)
 
 setuptools.setup(
     name='lisainstrument',
-    version=meta['__version__'],
-    author=meta['__author__'],
-    author_email=meta['__email__'],
+    version=META['__version__'],
+    author=META['__author__'],
+    author_email=META['__email__'],
     description='LISA Instrument simulates instrumental noises, propagates laser beams, generates measurements and the on-board processing to deliver simulated telemetry data.',
     long_description=long_description,
     long_description_content_type="text/markdown",
diff --git a/tests/keplerian-orbits.h5 b/tests/keplerian-orbits.h5
index ade477424203e5e1f2015c2d58a6dfaef3348059..62a26d635d7ff122a75018939adcf76b672ca77f 100644
--- a/tests/keplerian-orbits.h5
+++ b/tests/keplerian-orbits.h5
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:ec0cdae40a86b353090b2dcea731a38848c0c80f4b6fec88f9d46bee953fd877
-size 1984888
+oid sha256:6c7939ebd5fa11413b25a22f215cafbf88c2b790ba81e94993acb1ca936b46a7
+size 234272