docs: def time_series(timefile, colnames):
      """Read temporal series text file.
  
      If :data:`colnames` is too long, it will be truncated. If it is too short,
      additional numeric column names from 0 to N-1 will be attributed to the N
      extra columns present in :data:`timefile`.
  
      Args:
          timefile (:class:`pathlib.Path`): path of the time.dat file.
          colnames (list of names): names of the variables expected in
              :data:`timefile` (may be modified).
  
      Returns:
          :class:`pandas.DataFrame`:
              Time series, with the variables in columns and the time steps in
              rows.
      """
      if not timefile.is_file():
          return None
      data = pd.read_csv(timefile, delim_whitespace=True, dtype=str,
                         header=None, skiprows=1, index_col=0,
                         engine='c', memory_map=True,
                         error_bad_lines=False, warn_bad_lines=False)
      data = data.apply(pd.to_numeric, raw=True, errors='coerce')
  
      # detect useless lines produced when run is restarted
      rows_to_del = []
      irow = len(data) - 1
      while irow > 0:
          iprev = irow - 1
          while iprev >= 0 and data.index[irow] <= data.index[iprev]:
              rows_to_del.append(iprev)
              iprev -= 1
          irow = iprev
      if rows_to_del:
          rows_to_keep = set(range(len(data))) - set(rows_to_del)
          data = data.take(list(rows_to_keep), convert=False)
  
      ncols = data.shape[1]
      _tidy_names(colnames, ncols)
      data.columns = colnames
  
      return data