docs: def save_run(filename, sampler, compression=True, clobber=False):
      """
      Save the sampler chain, data table, parameter labels, metadata blobs, and
      run information to a hdf5 file.
  
      The data table and parameter labels stored in the sampler will also be
      saved to the hdf5 file.
  
      Parameters
      ----------
      filename : str
          Filename for hdf5 file. If the filename extension is not 'h5' or
          'hdf5', the suffix '_chain.h5' will be appended to the filename.
  
      sampler : `emcee.EnsembleSampler` instance
          Sampler instance for which chain and run information is saved.
  
      compression : bool, optional
          Whether gzip compression is applied to the dataset on write. Default is
          True.
  
      clobber : bool, optional
          Whether to overwrite the output filename if it exists.
      """
  
      if filename.split(".")[-1] not in ["h5", "hdf5"]:
          filename += "_chain.h5"
  
      if os.path.exists(filename) and not clobber:
          log.warning(
              "Not writing file because file exists and clobber is False"
          )
          return
  
      f = h5py.File(filename, "w")
      group = f.create_group("sampler")
      group.create_dataset("chain", data=sampler.chain, compression=compression)
      group.create_dataset(
          "lnprobability", data=sampler.lnprobability, compression=compression
      )
  
      # blobs
      blob = sampler.blobs[-1][0]
      for idx, item in enumerate(blob):
          if isinstance(item, u.Quantity):
              # scalar or array quantity
              units = [item.unit.to_string()]
          elif isinstance(item, float):
              units = [""]
          elif isinstance(item, tuple) or isinstance(item, list):
              arearrs = np.all([isinstance(x, np.ndarray) for x in item])
              if arearrs:
                  units = []
                  for x in item:
                      if isinstance(x, u.Quantity):
                          units.append(x.unit.to_string())
                      else:
                          units.append("")
          else:
              log.warning(
                  "blob number {0} has unknown format and cannot be saved "
                  "in HDF5 file"
              )
              continue
  
          # traverse blobs list. This will probably be slow and there should be a
          # better way
          blob = []
          for step in sampler.blobs:
              for walkerblob in step:
                  blob.append(walkerblob[idx])
          blob = u.Quantity(blob).value
  
          blobdataset = group.create_dataset(
              "blob{0}".format(idx), data=blob, compression=compression
          )
          if len(units) > 1:
              for j, unit in enumerate(units):
                  blobdataset.attrs["unit{0}".format(j)] = unit
          else:
              blobdataset.attrs["unit"] = units[0]
  
      if hasattr(sampler, "data"):
          data = group.create_dataset(
              "data",
              data=Table(sampler.data).as_array(),
              compression=compression,
          )
  
          for col in sampler.data.colnames:
              f["sampler/data"].attrs[col + "unit"] = str(sampler.data[col].unit)
  
          for key in sampler.data.meta:
              val = sampler.data.meta[key]
              try:
                  data.attrs[key] = val
              except TypeError:
                  try:
                      data.attrs[key] = str(val)
                  except:
                      warnings.warn(
                          "Attribute `{0}` of type {1} of the data table"
                          " of the sampler cannot be written to HDF5 files"
                          "- skipping".format(key, type(val)),
                          AstropyUserWarning,
                      )
  
      # add all run info to group attributes
      if hasattr(sampler, "run_info"):
          for key in sampler.run_info.keys():
              val = sampler.run_info[key]
              try:
                  group.attrs[key] = val
              except TypeError:
                  group.attrs[key] = str(val)
  
      # add other sampler info to the attrs
      group.attrs["acceptance_fraction"] = np.mean(sampler.acceptance_fraction)
  
      # add labels as individual attrs (there might be a better way)
      for i, label in enumerate(sampler.labels):
          group.attrs["label{0}".format(i)] = label
  
      f.close()