docs: def compute_K(dataframe, settings, keep_dir=False):
      """
      Parameters
      ----------
      dataframe: pandas.DataFrame
          dataframe that contains the data
      settings: dict
          with required settings, see below
      keep_dir: path
          if not None, copy modeling dir here
  
  
      settings = {
          'rho': 100,  # resistivity to use for homogeneous model, [Ohm m]
          'elem'
          'elec'
          '2D' : True|False
          'sink_node': '100',
      }
  
      """
      if settings is None:
          print('using default settings')
          settings = get_default_settings()
  
      if not os.path.isfile(settings['elem']):
          raise IOError(
              'elem file not found: {0}'.format(settings['elem'])
          )
  
      if not os.path.isfile(settings['elec']):
          raise IOError(
              'elec file not found: {0}'.format(settings['elec'])
          )
  
      # read grid file and determine nr of cells
      with open(settings['elem'], 'r') as fid:
          fid.readline()
          cell_type, cell_number, edge_number = np.fromstring(
              fid.readline().strip(),
              sep=' ',
              dtype=int,
          )
  
      # generate forward model as a string
      forward_model = '{0}\n'.format(cell_number)
      forward_model += '{0} {1}\n'.format(settings['rho'], 0) * cell_number
  
      full_path_elem = os.path.abspath(settings['elem'])
      full_path_elec = os.path.abspath(settings['elec'])
  
      pwd = os.getcwd()
      with tempfile.TemporaryDirectory() as invdir:
          os.chdir(invdir)
          # create tomodir directory structure
          for dir in [
              'exe',
              'mod',
              'config',
              'inv',
              'grid',
              'rho',
          ]:
              os.makedirs(dir)
  
          # save forward model
          with open('rho/rho.dat', 'w') as fid:
              fid.write(forward_model)
  
          shutil.copy(full_path_elem, 'grid/elem.dat')
          shutil.copy(full_path_elec, 'grid/elec.dat')
  
          print('SETTINGS')
          print(settings)
  
          cfg = CRcfg.crmod_config()
          if settings.get('2D', False):
              # activate 2D mode
              print('2D modeling')
              cfg['2D'] = '0'
              cfg['fictitious_sink'] = 'T'
              cfg['sink_node'] = settings.get('sink_node')
          else:
              cfg['2D'] = 1
  
          cfg.write_to_file('exe/crmod.cfg')
          subprocess.call('cat exe/crmod.cfg', shell=True)
  
          config_orig = _write_config_file('config/config.dat', dataframe)
  
          os.chdir('exe')
          binary = CRbinaries.get('CRMod')
          subprocess.call(binary, shell=True)
          os.chdir('..')
  
          # read in results
          modeled_resistances = np.loadtxt(
              'mod/volt.dat',
              skiprows=1,
          )
  
          # now we have to make sure CRMod didn't change the signs
          changed_sign = (config_orig[:, 1] == modeled_resistances[:, 1])
          modeled_resistances[~changed_sign, 2] *= -1
  
          if settings.get('norm_factor', None) is not None:
              modeled_resistances[:, 2] /= settings.get('norm_factor')
  
          K = settings['rho'] / modeled_resistances[:, 2]
          if isinstance(dataframe, pd.DataFrame):
              dataframe['k'] = K
          if keep_dir is not None and not os.path.isdir(keep_dir):
              shutil.copytree('.', keep_dir)
              print('Copy of modeling dir stored here: {}'.format(keep_dir))
  
      os.chdir(pwd)
      return K