diff --git a/dartwrf/assim_synth_obs.py b/dartwrf/assim_synth_obs.py
index 3396f82d542abc84030fc5590b1bb980b87ede78..17c62c99b22c8f27d9378ede51fca7d26bed710c 100755
--- a/dartwrf/assim_synth_obs.py
+++ b/dartwrf/assim_synth_obs.py
@@ -78,29 +78,29 @@ def set_DART_nml(just_prior_values=False):
     append_file(cluster.dartrundir + "/input.nml", rttov_nml)
 
 
-def link_nature_to_dart_truth(time):
-    """Set a symlink from the WRFout file to be used as nature to the run_DART folder
-    
-    Args:
-        time (dt.datetime): Time at which observations will be made
-    """
-
-    # get wrfout_d01 from nature run
-    shutil.copy(time.strftime(exp.nature+'/'+wrfout_format), 
-                cluster.dartrundir + "/wrfout_d01")
-
-    # DART may need a wrfinput file as well, which serves as a template for dimension sizes
-    symlink(cluster.dartrundir + "/wrfout_d01", 
+def _prepare_DART_grid_template():
+    # DART needs a wrfinput file as a template for the grid
+    # No data will be read from this file, but the grid information must match exactly.
+    symlink(cluster.dartrundir + "/prior_ens1/wrfout_d01", 
             cluster.dartrundir + "/wrfinput_d01")
-    print("linked", time.strftime(exp.nature+'/'+wrfout_format),
-          "to", cluster.dartrundir + "/wrfout_d01")
 
 
 def prepare_nature_dart(time):
-    print("linking nature to DART & georeferencing")
-    link_nature_to_dart_truth(time)
-    wrfout_add_geo.run(cluster.geo_em, cluster.dartrundir + "/wrfout_d01")
+    """Prepares DART nature (wrfout_d01) if available
 
+    Args:
+        time (dt.datetime): Time at which observations will be made
+    """
+
+    f_wrfout_nature = time.strftime(exp.nature+'/'+wrfout_format)
+    if os.path.exists(f_wrfout_nature):
+        print("linking nature to DART & georeferencing")
+        shutil.copy(f_wrfout_nature, cluster.dartrundir + "/wrfout_d01")
+        print("linked", f_wrfout_nature, "to", cluster.dartrundir + "/wrfout_d01")
+
+        wrfout_add_geo.run(cluster.geo_em, cluster.dartrundir + "/wrfout_d01")
+    else:  # if nature is not available due to any reason
+        print('-> has no nature, not copying nature')
 
 def prepare_prior_ensemble(assim_time, prior_init_time, prior_valid_time, prior_path_exp):
     """Prepares DART files for running filter
@@ -183,6 +183,8 @@ def run_perfect_model_obs(nproc=12, verbose=True):
             "\n look for " + cluster.dartrundir + "/log.perfect_model_obs")
 
 def filter(nproc=12):
+    _prepare_DART_grid_template()
+
     print("time now", dt.datetime.now())
     print("running filter")
     os.chdir(cluster.dartrundir)
@@ -438,7 +440,7 @@ def get_obsseq_out(time):
     if exp.use_existing_obsseq != False: 
         f_obsseq = time.strftime(exp.use_existing_obsseq)
         copy(f_obsseq, cluster.dartrundir+'/obs_seq.out')
-        print(f_obsseq, 'copied to', cluster.dartrundir+'/obs_seq.out')
+        # print(f_obsseq, 'copied to', cluster.dartrundir+'/obs_seq.out')
         oso = obsseq.ObsSeq(cluster.dartrundir + "/obs_seq.out")
     else:
         # decision to NOT use existing obs_seq.out file
diff --git a/dartwrf/obsseq.py b/dartwrf/obsseq.py
index 9f7dca5624f38d70f84df56820a4c741235f11f6..bb583aeb5a3ea06360cfcf69a2aa4f584a981cdd 100755
--- a/dartwrf/obsseq.py
+++ b/dartwrf/obsseq.py
@@ -1,13 +1,43 @@
-"""Read, modify and save DART obs_seq files.
-
-Not usable for creating obs_seq, since it does not know which metadata is necessary for each type
+"""Read, modify and save DART obs_seq.out/obs_seq.final files in DART format.
+
+Examples:
+    Load an obs seq file with
+    >>> from dartwrf.obs.obsseq import ObsSeq
+    >>> osf = ObsSeq('path/to/obs_seq.final')
+    
+    The content is a pandas.DataFrame with all observations (rows) 
+    >>> osf.df
+    observations     truth  prior ensemble mean  posterior ensemble mean  ...  kind                                           metadata             time  variance
+    0        0.292800  0.289466             0.360284                 0.330799  ...   262  [ visir\n,    180.000000000000        45.00000...  (50400, 148864)    0.0009
+    1        0.292800  0.289466             0.398444                 0.380152  ...   262  [ visir\n,    180.000000000000        45.00000...  (50400, 148864)    0.0009
+    2        0.310016  0.289466             0.355061                 0.369988  ...   262  [ visir\n,    180.000000000000        45.00000...  (50400, 148864)    0.0009
+    3        0.297182  0.289466             0.305424                 0.302489  ...   262  [ visir\n,    180.000000000000        45.00000...  (50400, 148864)    0.0009
+    4        0.292800  0.293797             0.306238                 0.303252  ...   262  [ visir\n,    180.000000000000        45.00000...  (50400, 148864)    0.0009
+    ..            ...       ...                  ...                      ...  ...   ...                                                ...              ...       ...
+    956      0.762274  0.796486             0.664451                 0.833559  ...   262  [ visir\n,    180.000000000000        45.00000...  (50400, 148864)    0.0009
+    957      0.525743  0.500751             0.534391                 0.653267  ...   262  [ visir\n,    180.000000000000        45.00000...  (50400, 148864)    0.0009
+    958      0.341627  0.348115             0.405534                 0.447314  ...   262  [ visir\n,    180.000000000000        45.00000...  (50400, 148864)    0.0009
+    959      0.826649  0.835491             0.374459                 0.785951  ...   262  [ visir\n,    180.000000000000        45.00000...  (50400, 148864)    0.0009
+    960      0.320477  0.343154             0.303468                 0.325203  ...   262  [ visir\n,    180.000000000000        45.00000...  (50400, 148864)    0.0009
+    [961 rows x 93 columns]
+
+    To get arrays of prior and posterior use
+    >>> osf.df.get_prior_Hx()
+    >>> osf.df.get_posterior_Hx()
+
+    After modifying the contents, write them in DART format
+    >>> osf.to_dart('path/to/obs_seq.final')
+
+Note:
+    Can not create obs_seq from scratch, since it does not know which metadata is necessary for each observation type
 """
 
-import os, sys, shutil, warnings
+import os, warnings
 import numpy as np
 import pandas as pd
 
-def plot_box(m, lat, lon, label="", **kwargs):
+
+def _plot_box(m, lat, lon, label="", **kwargs):
     """"Draw bounding box
 
     Args:
@@ -35,15 +65,13 @@ def plot_box(m, lat, lon, label="", **kwargs):
         **kwargs
     )
 
-
-def degrees_to_rad(degr):
+def _degrees_to_rad(degr):
     """Convert to DART convention = radians"""
     if degr < 0:
         degr += 360
     return degr / 360 * 2 * np.pi
 
-
-def rad_to_degrees(rad):
+def _rad_to_degrees(rad):
     """Convert to degrees from DART convention (radians)"""
     assert rad >= 0, "no negative radians allowed"
     degr = rad / np.pi * 180
@@ -54,12 +82,8 @@ def rad_to_degrees(rad):
     return degr
 
 
-
-
 class ObsRecord(pd.DataFrame):
-    """Content of obsseq.ObsSeq instances
-    provides additional methods for pd.DataFrame
-    created inside an ObsSeq instance
+    """Basically a pd.DataFrame with additional methods
     """
     @property
     def _constructor(self):
@@ -68,18 +92,31 @@ class ObsRecord(pd.DataFrame):
         return ObsRecord
 
     def get_prior_Hx(self):
-        """Return prior Hx array (n_obs, n_ens)"""
+        """Retrieve H(x_prior) for all ensemble members
+        
+        Returns:
+            np.array (n_obs, n_ens)
+        """
         return self._get_model_Hx('prior')
 
     def get_posterior_Hx(self):
-        """Return posterior Hx array (n_obs, n_ens)"""
+        """Retrieve H(x_posterior) for all ensemble members
+        
+        Returns:
+            np.array (n_obs, n_ens)
+        """
         return self._get_model_Hx('posterior')
 
     def get_truth_Hx(self):
+        """Retrieve H(x_truth)
+
+        Returns:
+            np.array (n_obs,)
+        """
         return self['truth'].values
 
     def _get_model_Hx(self, what):
-        """Return ensemble member info
+        """Retrieve a subset of the obs-sequence table, e.g. H(x_prior)
 
         Args:
             self (pd.DataFrame):      usually self.self
@@ -106,6 +143,11 @@ class ObsRecord(pd.DataFrame):
         return Hx.values
 
     def get_lon_lat(self):
+        """Retrieve longitude and latitude of observations
+
+        Returns:
+            pd.DataFrame (n_obs, 2)
+        """
         lats = np.empty(len(self), np.float32)
         lons = lats.copy()
 
@@ -113,20 +155,20 @@ class ObsRecord(pd.DataFrame):
             x, y, z, z_coord = values
 
             # convert radian to degrees lon/lat
-            lon = rad_to_degrees(x)
-            lat = rad_to_degrees(y)
+            lon = _rad_to_degrees(x)
+            lat = _rad_to_degrees(y)
             lons[i] = lon
             lats[i] = lat
 
         return pd.DataFrame(index=self.index, data=dict(lat=lats, lon=lons))
 
-    def get_from_cartesian_grid(self, i, j, k):
+    def _get_from_cartesian_grid(self, i, j, k):
         """Get the observation using cartesian grid indices (ix, iy, iz)
         """
         # find indices of observations within pandas.DataFrame
         return self.iloc[self.i_obs_grid[i, j, k].ravel()]
 
-    def determine_nlayers(self):
+    def _determine_nlayers(self):
         nlayers = 1  # first guess
         from config.cfg import exp
 
@@ -203,7 +245,7 @@ class ObsRecord(pd.DataFrame):
             print("window (#obs in x/y)=", win_obs)
 
         # superob in case of multiple layers, only implemented for single obstype
-        nlayers = self.determine_nlayers()
+        nlayers = self._determine_nlayers()
         
         # indices of observations (starting from 0)
         i_obs_grid = self.index.values  
@@ -237,7 +279,7 @@ class ObsRecord(pd.DataFrame):
                         print("obs indices box=", i_obs_grid[i : i + win_obs, j : j + win_obs, k])
 
                     # find observations within superob window
-                    obs_box = self.get_from_cartesian_grid(slice(i, i + win_obs),
+                    obs_box = self._get_from_cartesian_grid(slice(i, i + win_obs),
                                                            slice(j, j + win_obs),
                                                            k)
 
@@ -245,10 +287,10 @@ class ObsRecord(pd.DataFrame):
                     # save boundary of box to list, for plotting later
                     eps = dx_obs_lat_deg/2  # for plotting
                     eps2 = eps*0.8  # for plotting
-                    lat1, lon1 = self.get_from_cartesian_grid(i, j, k).get_lon_lat().values[0]
-                    lat2, lon2 = self.get_from_cartesian_grid(i+win_obs-1, j, k).get_lon_lat().values[0]
-                    lat3, lon3 = self.get_from_cartesian_grid(i, j+win_obs-1, k).get_lon_lat().values[0]
-                    lat4, lon4 = self.get_from_cartesian_grid(i+win_obs-1, j+win_obs-1, k).get_lon_lat().values[0]
+                    lat1, lon1 = self._get_from_cartesian_grid(i, j, k).get_lon_lat().values[0]
+                    lat2, lon2 = self._get_from_cartesian_grid(i+win_obs-1, j, k).get_lon_lat().values[0]
+                    lat3, lon3 = self._get_from_cartesian_grid(i, j+win_obs-1, k).get_lon_lat().values[0]
+                    lat4, lon4 = self._get_from_cartesian_grid(i+win_obs-1, j+win_obs-1, k).get_lon_lat().values[0]
 
                     boxes.append(([lat1-eps2, lat2+eps2, lat3-eps2, lat4+eps2],
                                 [lon1-eps, lon2-eps, lon3+eps, lon4+eps]))
@@ -315,18 +357,20 @@ class ObsSeq(object):
     """
 
     def __init__(self, filepath):
+        self.filepath = filepath
         self.ascii = open(filepath, "r").readlines()
 
-        self.get_preamble_content()
-        self.read_preamble()
+        self._get_preamble_content()
+        self._read_preamble()
 
         self.df = ObsRecord(self.to_pandas())
 
     def __str__(self):
         return self.df.__str__()
 
-    def get_preamble_content(self):
+    def _get_preamble_content(self):
         """Split the obs_seq.out file into two parts
+
         1) First lines of obs_seq.out file until the first observation message
         2) Observation contents
         """
@@ -339,7 +383,7 @@ class ObsSeq(object):
         self.preamble = self.ascii[:i]
         self.content = self.ascii[i:]
 
-    def read_preamble(self):
+    def _read_preamble(self):
         """Defines 
         self.obstypes (tuple(kind_nr, kind_descriptor)) for each obs type
         """
@@ -394,7 +438,7 @@ class ObsSeq(object):
 
         self.keys_for_values = keys
 
-    def obs_to_dict(self):
+    def _obs_to_dict(self):
         """Convert an obs_seq.out file to a dictionary"""
         obs_begin_str = "OBS  "
 
@@ -492,10 +536,45 @@ class ObsSeq(object):
         list_of_obsdict = obs_list_to_dict(obs_list)
         return list_of_obsdict
 
+    def append_obsseq(self, list_of_obsseq):
+        """Append a list of ObsSeq objects
+        
+        Args:
+            list_of_obsseq (list of ObsSeq())
+            
+        """
+        from dartwrf.config.obskind import obs_kind_nrs # dictionary string => DART internal indices
+        inverted_obs_kind_nrs = {v: k for k, v in obs_kind_nrs.items()}
+
+        for a in list_of_obsseq:
+            if not isinstance(a, ObsSeq):
+                raise ValueError('Input must be of type ObsSeq!')
+
+        # combine data of all inputs + self
+        list_of_obsseq_df = [self.df,]
+        list_of_obsseq_df.extend([a.df for a in list_of_obsseq])
+
+        combi_df = pd.concat(list_of_obsseq_df,
+                            ignore_index=True  # we use a new observation index now
+                            )
+
+        n_obstypes = combi_df.kind.nunique()
+        list_kinds = combi_df.kind.unique()
+
+        obstypes = []
+        for kind in list_kinds:
+            obstypes.append((kind, inverted_obs_kind_nrs[kind]))
+
+        oso3 = self
+        oso3.df = combi_df 
+        oso3.obstypes = obstypes 
+        return oso3
+
+
     def to_pandas(self):
         """Create pd.DataFrame with rows=observations
         """
-        obs_dict_list = self.obs_to_dict()
+        obs_dict_list = self._obs_to_dict()
 
         # convert to pandas.DataFrame
         # each observation is one line
@@ -649,7 +728,7 @@ class ObsSeq(object):
         m.drawcoastlines(color="white")
         m.drawcountries(color="white")
 
-        plot_box(m, lat, lon, label="domain", color="green", lw=1) #4)
+        _plot_box(m, lat, lon, label="domain", color="green", lw=1) #4)
 
         # OBSERVATIONS
         original_df = self.df.attrs['df_pre_superob']
@@ -693,7 +772,7 @@ class ObsSeq(object):
             for lats, lons in self.df.attrs['boxes']:
                 lats, lons = np.meshgrid(lats, lons)
 
-                plot_box(m, lats, lons, label=label, color="white", lw=0.1) #1)
+                _plot_box(m, lats, lons, label=label, color="white", lw=0.1) #1)
                 label = ''
 
         plt.legend()
diff --git a/dartwrf/workflows.py b/dartwrf/workflows.py
index 3b2dc3877f867bdbd14ff24a81bb62243db64129..5d2257bcca39fbb6d3d6cf593922ac465da13abd 100644
--- a/dartwrf/workflows.py
+++ b/dartwrf/workflows.py
@@ -169,7 +169,7 @@ class WorkFlows(object):
         return id
 
     def run_ENS(self, begin, end, depends_on=None, first_minute=False, 
-                input_is_restart=True, output_restart_interval=720):
+                input_is_restart=True, output_restart_interval=720, hist_interval=5, radt=5):
         """Run the forecast ensemble
 
         Args:
@@ -179,6 +179,8 @@ class WorkFlows(object):
             first_minute (bool, optional): if True, run the first minute of the forecast
             input_is_restart (bool, optional): if True, start WRF from WRFrst file (restart mode)
             output_restart_interval (int, optional): interval in minutes between output of WRFrst files
+            hist_interval (int, optional): interval in minutes between output of WRF history files
+            radt (int, optional): time step of radiation scheme
 
         Returns:
             str: job ID of the submitted job
@@ -189,12 +191,13 @@ class WorkFlows(object):
             args = [self.cluster.python, self.cluster.scripts_rundir+'/prepare_namelist.py',
                     begin.strftime('%Y-%m-%d_%H:%M'), end.strftime('%Y-%m-%d_%H:%M'),
                     str(hist_interval), '--radt='+str(radt), '--restart='+restart_flag,]
+
             if output_restart_interval:
                 args.append('--restart_interval='+str(int(float(output_restart_interval))))
 
-            return self.cluster.run_job(' '.join(args), "preWRF", cfg_update=dict(time="2"), depends_on=[depends_on])
+            return self.cluster.run_job(' '.join(args), "preWRF", 
+                        cfg_update=dict(time="2"), depends_on=[depends_on])
         
-
         id = depends_on
         restart_flag = '.false.' if not input_is_restart else '.true.'
         wrf_cmd = script_to_str(self.cluster.run_WRF
@@ -202,13 +205,13 @@ class WorkFlows(object):
                 ).replace('<cluster.wrf_rundir_base>', self.cluster.wrf_rundir_base
                 ).replace('<cluster.wrf_modules>', self.cluster.wrf_modules)
 
-
         # first minute forecast (needed for validating a radiance assimilation)
         if first_minute:
-            hist_interval = 1  # to get an output after 1 minute
-            radt = 1  # to get a cloud fraction CFRAC after 1 minute
             id = prepare_WRF_inputfiles(begin, begin+dt.timedelta(minutes=1), 
-                    hist_interval=hist_interval, radt=radt, output_restart_interval=output_restart_interval, depends_on=id)
+                    hist_interval=1,  # to get an output after 1 minute
+                    radt = 1,  # to get a cloud fraction CFRAC after 1 minute
+                    output_restart_interval=output_restart_interval, 
+                    depends_on=id)
 
             id = self.cluster.run_job(wrf_cmd, "WRF-"+exp.expname, 
                                       cfg_update={"array": "1-"+str(self.cluster.size_jobarray), "ntasks": "10", "nodes": "1",
@@ -216,7 +219,12 @@ class WorkFlows(object):
                                       depends_on=[id])
 
         # forecast for the whole forecast duration       
-        id = prepare_WRF_inputfiles(depends_on=id)
+        id = prepare_WRF_inputfiles(begin, end, 
+                                    hist_interval=hist_interval, 
+                                    radt=radt,
+                                    output_restart_interval=output_restart_interval,
+                                    depends_on=id)
+
         time_in_simulation_hours = (end-begin).total_seconds()/3600
         runtime_wallclock_mins_expected = int(8+time_in_simulation_hours*9)  # usually below 9 min/hour
         id = self.cluster.run_job(wrf_cmd, "WRF-"+exp.expname, 
diff --git a/free_forecast.py b/free_forecast.py
index 8cee19bdffdbf327acc72970a2f70728b4d0bb38..79362cd72afc621e1041a767e125505d2bd35560 100755
--- a/free_forecast.py
+++ b/free_forecast.py
@@ -130,7 +130,7 @@ if False:  # to continue a free run after spinup
     prior_init_time = dt.datetime(2008, 7, 30, 13)
     prior_valid_time = dt.datetime(2008, 7, 30, 13,30)
 
-    id = w.w.prepare_IC_from_prior(prior_path_exp, prior_init_time, prior_valid_time, 
+    id = w.prepare_IC_from_prior(prior_path_exp, prior_init_time, prior_valid_time, 
             # new_start_time=start, # <---------- to overwrite start time
             depends_on=id)
 
diff --git a/tests/obs_seq.T2m+WV73.out b/tests/obs_seq.T2m+WV73.out
new file mode 100644
index 0000000000000000000000000000000000000000..d1d71cb457b5b2ce5a04857f13a0c42d49ce4b62
--- /dev/null
+++ b/tests/obs_seq.T2m+WV73.out
@@ -0,0 +1,73 @@
+ obs_sequence
+ obs_kind_definitions
+     2
+         102 SYNOP_TEMPERATURE
+         261 MSG_4_SEVIRI_TB
+ num_copies:            2  num_qc:            1
+ num_obs:           4     max_num_obs:            4
+ observations
+ truth
+ Quality Control
+ first:            1  last:            2
+OBS         1
+301.509009144877
+301.0021510973083
+0.0
+        -1           2          -1
+obdef
+loc3d
+6.250862521029294    0.7617386402731844    2.0    -1
+kind
+         102
+
+ 46800     148864
+ 1.0
+OBS         2
+299.99534143331243
+301.376166801592
+0.0
+        -1           3          -1
+obdef
+loc3d
+6.255199745180597    0.7618054856165454    2.0    -1
+kind
+         102
+
+ 46800     148864
+ 1.0
+OBS         3
+252.2826500887255
+251.26893399358806
+0.0
+        -1           4          -1
+obdef
+loc3d
+6.250862521029294    0.7617386402731844    -888888.0    -2
+kind
+         261
+ visir
+   180.00000000000000        45.000000000000000        207.05673522605844        28.897810301100350
+          12           4          21           6
+  -888888.00000000000
+           1
+
+ 46800     148864
+ 4.0
+OBS         4
+252.2114425561486
+254.97309329270772
+0.0
+         3           -1          -1
+obdef
+loc3d
+6.255199745180597    0.7618054856165454    -888888.0    -2
+kind
+         261
+ visir
+   180.00000000000000        45.000000000000000        207.05673522605844        28.897810301100350
+          12           4          21           6
+  -888888.00000000000
+           2
+
+ 46800     148864
+ 4.0
diff --git a/tests/obs_seq.T2m.out b/tests/obs_seq.T2m.out
new file mode 100644
index 0000000000000000000000000000000000000000..3628d4f3142d431aaa2718fee8ddb83f642d943a
--- /dev/null
+++ b/tests/obs_seq.T2m.out
@@ -0,0 +1,36 @@
+ obs_sequence
+ obs_kind_definitions
+     1
+         102 SYNOP_TEMPERATURE
+ num_copies:            2  num_qc:            1
+ num_obs:           2     max_num_obs:            2
+ observations
+ truth
+ Quality Control
+ first:            1  last:            2
+OBS         1
+301.509009144877
+301.0021510973083
+0.0
+        -1           2          -1
+obdef
+loc3d
+6.250862521029294    0.7617386402731844    2.0    -1
+kind
+         102
+
+ 46800     148864
+ 1.0
+OBS         2
+299.99534143331243
+301.376166801592
+0.0
+        1           -1          -1
+obdef
+loc3d
+6.255199745180597    0.7618054856165454    2.0    -1
+kind
+         102
+
+ 46800     148864
+ 1.0
diff --git a/tests/obs_seq.WV73.out b/tests/obs_seq.WV73.out
new file mode 100644
index 0000000000000000000000000000000000000000..5e34f208e30325b9094a058926a279f4b9e9b1f6
--- /dev/null
+++ b/tests/obs_seq.WV73.out
@@ -0,0 +1,46 @@
+ obs_sequence
+ obs_kind_definitions
+     1
+         261 MSG_4_SEVIRI_TB
+ num_copies:            2  num_qc:            1
+ num_obs:           2     max_num_obs:            2
+ observations
+ truth
+ Quality Control
+ first:            1  last:            2
+OBS         1
+252.2826500887255
+251.26893399358806
+0.0
+        -1           2          -1
+obdef
+loc3d
+6.250862521029294    0.7617386402731844    -888888.0    -2
+kind
+         261
+ visir
+   180.00000000000000        45.000000000000000        207.05673522605844        28.897810301100350
+          12           4          21           6
+  -888888.00000000000
+           1
+
+ 46800     148864
+ 4.0
+OBS         2
+252.2114425561486
+254.97309329270772
+0.0
+         1           -1          -1
+obdef
+loc3d
+6.255199745180597    0.7618054856165454    -888888.0    -2
+kind
+         261
+ visir
+   180.00000000000000        45.000000000000000        207.05673522605844        28.897810301100350
+          12           4          21           6
+  -888888.00000000000
+           2
+
+ 46800     148864
+ 4.0
diff --git a/tests/obs_seq.combi-expected.out b/tests/obs_seq.combi-expected.out
new file mode 100644
index 0000000000000000000000000000000000000000..f68ecb37223e6726eaa1534bab29802e78e9e4d8
--- /dev/null
+++ b/tests/obs_seq.combi-expected.out
@@ -0,0 +1,77 @@
+ obs_sequence 
+ obs_kind_definitions 
+     2
+         102 SYNOP_TEMPERATURE
+         261 MSG_4_SEVIRI_TB
+ num_copies:            2  num_qc:            1
+ num_obs:           4   max_num_obs:            4
+ observations 
+ truth 
+ Quality Control 
+ first:            1  last:            4
+OBS         1 
+301.509009144877 
+301.0021510973083 
+0.0 
+        -1           2          -1 
+obdef 
+loc3d 
+6.250862521029294    0.7617386402731844    2.0    -1 
+kind 
+         102 
+
+ 
+ 46800     148864 
+ 1.0
+OBS         2 
+299.99534143331243 
+301.376166801592 
+0.0 
+        -1           3          -1 
+obdef 
+loc3d 
+6.255199745180597    0.7618054856165454    2.0    -1 
+kind 
+         102 
+
+ 
+ 46800     148864 
+ 1.0
+OBS         3 
+252.2826500887255 
+251.26893399358806 
+0.0 
+        -1           4          -1 
+obdef 
+loc3d 
+6.250862521029294    0.7617386402731844    -888888.0    -2 
+kind 
+         261 
+ visir
+   180.00000000000000        45.000000000000000        207.05673522605844        28.897810301100350
+          12           4          21           6
+  -888888.00000000000
+           1
+
+ 
+ 46800     148864 
+ 4.0
+OBS         4 
+252.2114425561486 
+254.97309329270772 
+0.0 
+          3           -1          -1 
+obdef 
+loc3d 
+6.255199745180597    0.7618054856165454    -888888.0    -2 
+kind 
+         261 
+ visir
+   180.00000000000000        45.000000000000000        207.05673522605844        28.897810301100350
+          12           4          21           6
+  -888888.00000000000
+           2
+
+ 
+ 46800     148864 
+ 4.0
\ No newline at end of file
diff --git a/tests/test_obsseq.py b/tests/test_obsseq.py
index 96d7dbe013b9d5a15ca6bf6fbcf9e43ac5286a01..b94786256b355e4475ed8700459a54bc57166a12 100644
--- a/tests/test_obsseq.py
+++ b/tests/test_obsseq.py
@@ -52,6 +52,43 @@ def test_superob():
 
     from IPython import embed; embed()
 
+def test_concat_obsseq():
+    """Test the concatenation of two obs_seq.out files"""
+
+
+
+    f1 = './obs_seq.T2m.out'
+    f2 = './obs_seq.WV73.out'
+    f_output = './obs_seq.combi.out'
+    f_expected = './obs_seq.combi-expected.out'
+
+    oso1 = obsseq.ObsSeq(f1)
+    oso2 = obsseq.ObsSeq(f2)
+
+    # #oso3 = oso1
+    # combi_df = pd.concat([oso1.df, oso2.df],
+    #                     ignore_index=True  # we use a new observation index now
+    #                     )
+
+    # n_obstypes = combi_df.kind.nunique()
+    # list_kinds = combi_df.kind.unique()
+
+    # obstypes = []
+    # for kind in list_kinds:
+    #     obstypes.append((kind, inverted_obs_kind_nrs[kind]))
+
+    # oso3 = oso1
+    # oso3.df = combi_df #setattr(oso3, 'df', combi_df)
+    # oso3.obstypes = obstypes #setattr(oso3, 'obstypes', obstypes)
+
+    oso3 = oso1.append_obsseq([oso2, ])
+    oso3.to_dart(f_output)
+
+    import filecmp
+    assert filecmp.cmp(f_output, f_expected)
+
+    os.remove(f_output)
+
+
 if __name__ == '__main__':
-    test_superob()
-    pass
+    test_concat_obsseq()
\ No newline at end of file