a function to setup extracting time-series from a binary modflow
    head save (or equivalent format - ucn, sub, etc).  Writes
    an instruction file and a _set_ csv

    Parameters
    ----------
    hds_file : str
        binary filename
    kij_dict : dict
        dictionary of site_name: [k,i,j] pairs
    prefix : str
        string to prepend to site_name when forming obsnme's.  Default is None
    include_path : bool
        flag to prepend hds_file path. Useful for setting up
        process in separate directory for where python is running.
    model : flopy.mbase
        a flopy model.  If passed, the observation names will have the datetime of the
        observation appended to them.  If None, the observation names will have the
        stress period appended to them. Default is None.
    postprocess_inact : float
        Inactive flag in heads/ucn file e.g. mt.btn.cinit

    Returns
    -------



    Note
    ----
    This function writes hds_timeseries.config that must be in the same
    dir where apply_hds_timeseries() is called during the forward run

    assumes model time units are days!!!

def setup_hds_timeseries(hds_file,kij_dict,prefix=None,include_path=False,
                         model=None, postprocess_inact=None):
    """a function to setup extracting time-series from a binary modflow
    head save (or equivalent format - ucn, sub, etc).  Writes
    an instruction file and a _set_ csv

    Parameters
    ----------
    hds_file : str
        binary filename
    kij_dict : dict
        dictionary of site_name: [k,i,j] pairs
    prefix : str
        string to prepend to site_name when forming obsnme's.  Default is None
    include_path : bool
        flag to prepend hds_file path. Useful for setting up
        process in separate directory for where python is running.
    model : flopy.mbase
        a flopy model.  If passed, the observation names will have the datetime of the
        observation appended to them.  If None, the observation names will have the
        stress period appended to them. Default is None.
    postprocess_inact : float
        Inactive flag in heads/ucn file e.g. mt.btn.cinit

    Returns
    -------



    Note
    ----
    This function writes hds_timeseries.config that must be in the same
    dir where apply_hds_timeseries() is called during the forward run

    assumes model time units are days!!!

    """

    try:
        import flopy
    except Exception as e:
        print("error importing flopy, returning {0}".format(str(e)))
        return

    assert os.path.exists(hds_file),"head save file not found"
    if hds_file.lower().endswith(".ucn"):
        try:
            hds = flopy.utils.UcnFile(hds_file)
        except Exception as e:
            raise Exception("error instantiating UcnFile:{0}".format(str(e)))
    else:
        try:
            hds = flopy.utils.HeadFile(hds_file)
        except Exception as e:
            raise Exception("error instantiating HeadFile:{0}".format(str(e)))

    nlay,nrow,ncol = hds.nlay,hds.nrow,hds.ncol

    #if include_path:
    #    pth = os.path.join(*[p for p in os.path.split(hds_file)[:-1]])
    #    config_file = os.path.join(pth,"{0}_timeseries.config".format(hds_file))
    #else:
    config_file = "{0}_timeseries.config".format(hds_file)
    print("writing config file to {0}".format(config_file))

    f_config = open(config_file,'w')
    if model is not None:
        if model.dis.itmuni != 4:
            warnings.warn("setup_hds_timeseries only supports 'days' time units...",PyemuWarning)
        f_config.write("{0},{1},d\n".format(os.path.split(hds_file)[-1],model.start_datetime))
        start = pd.to_datetime(model.start_datetime)
    else:
        f_config.write("{0},none,none\n".format(os.path.split(hds_file)[-1]))
    f_config.write("site,k,i,j\n")
    dfs = []

    for site,(k,i,j) in kij_dict.items():
        assert k >= 0 and k < nlay, k
        assert i >= 0 and i < nrow, i
        assert j >= 0 and j < ncol, j
        site = site.lower().replace(" ",'')
        df = pd.DataFrame(data=hds.get_ts((k,i,j)),columns=["totim",site])

        if model is not None:
            dts = start + pd.to_timedelta(df.totim,unit='d')
            df.loc[:,"totim"] = dts
        #print(df)
        f_config.write("{0},{1},{2},{3}\n".format(site,k,i,j))
        df.index = df.pop("totim")
        dfs.append(df)

    f_config.close()
    df = pd.concat(dfs,axis=1)
    df.to_csv(hds_file+"_timeseries.processed",sep=' ')
    if model is not None:
        t_str = df.index.map(lambda x: x.strftime("%Y%m%d"))
    else:
        t_str = df.index.map(lambda x: "{0:08.2f}".format(x))

    ins_file = hds_file+"_timeseries.processed.ins"
    print("writing instruction file to {0}".format(ins_file))
    with open(ins_file,'w') as f:
        f.write('pif ~\n')
        f.write("l1 \n")
        for t in t_str:
            f.write("l1 w ")
            for site in df.columns:
                if prefix is not None:
                    obsnme = "{0}_{1}_{2}".format(prefix,site,t)
                else:
                    obsnme = "{0}_{1}".format(site, t)
                f.write(" !{0}!".format(obsnme))
            f.write('\n')
    if postprocess_inact is not None:
        _setup_postprocess_hds_timeseries(hds_file, df, config_file, prefix=prefix, model=model)
    bd = '.'
    if include_path:
        bd = os.getcwd()
        pth = os.path.join(*[p for p in os.path.split(hds_file)[:-1]])
        os.chdir(pth)
    config_file = os.path.split(config_file)[-1]
    try:
        df = apply_hds_timeseries(config_file, postprocess_inact=postprocess_inact)
    except Exception as e:
        os.chdir(bd)
        raise Exception("error in apply_hds_timeseries(): {0}".format(str(e)))
    os.chdir(bd)

    #df = _try_run_inschek(ins_file,ins_file.replace(".ins",""))
    df = try_process_ins_file(ins_file,ins_file.replace(".ins",""))
    if df is not None:
        df.loc[:,"weight"] = 0.0
        if prefix is not None:
            df.loc[:,"obgnme"] = df.index.map(lambda x: '_'.join(x.split('_')[:2]))
        else:
            df.loc[:, "obgnme"] = df.index.map(lambda x: x.split('_')[0])
    frun_line = "pyemu.gw_utils.apply_hds_timeseries('{0}',{1})\n".format(config_file, postprocess_inact)
    return frun_line,df