def smp_to_ins(smp_filename,ins_filename=None,use_generic_names=False,
               gwutils_compliant=False, datetime_format=None,prefix=''):
    """ create an instruction file for an smp file

    Parameters
    ----------
    smp_filename : str
        existing smp file
    ins_filename: str
        instruction file to create.  If None, create
        an instruction file using the smp filename
        with the ".ins" suffix
    use_generic_names : bool
        flag to force observations names to use a generic
        int counter instead of trying to use a datetime str
    gwutils_compliant : bool
        flag to use instruction set that is compliant with the
        pest gw utils (fixed format instructions).  If false,
        use free format (with whitespace) instruction set
    datetime_format : str
        str to pass to datetime.strptime in the smp_to_dataframe() function
    prefix : str
         a prefix to add to the front of the obsnmes.  Default is ''


    Returns
    -------
    df : pandas.DataFrame
        dataframe instance of the smp file with the observation names and
        instruction lines as additional columns

    """
    if ins_filename is None:
        ins_filename = smp_filename+".ins"
    df = smp_to_dataframe(smp_filename,datetime_format=datetime_format)
    df.loc[:,"ins_strings"] = None
    df.loc[:,"observation_names"] = None
    name_groups = df.groupby("name").groups
    for name,idxs in name_groups.items():
        if not use_generic_names and len(name) <= 11:
            onames = df.loc[idxs,"datetime"].apply(lambda x: prefix+name+'_'+x.strftime("%d%m%Y")).values
        else:
            onames = [prefix+name+"_{0:d}".format(i) for i in range(len(idxs))]
        if False in (map(lambda x :len(x) <= 20,onames)):
            long_names = [oname for oname in onames if len(oname) > 20]
            raise Exception("observation names longer than 20 chars:\n{0}".format(str(long_names)))
        if gwutils_compliant:
            ins_strs = ["l1  ({0:s})39:46".format(on) for on in onames]
        else:
            ins_strs = ["l1 w w w  !{0:s}!".format(on) for on in onames]
        df.loc[idxs,"observation_names"] = onames
        df.loc[idxs,"ins_strings"] = ins_strs

    counts = df.observation_names.value_counts()
    dup_sites = [name for name in counts.index if counts[name] > 1]
    if len(dup_sites) > 0:
        raise Exception("duplicate observation names found:{0}"\
                        .format(','.join(dup_sites)))

    with open(ins_filename,'w') as f:
        f.write("pif ~\n")
        [f.write(ins_str+"\n") for ins_str in df.loc[:,"ins_strings"]]
    return df
def smp_to_ins ( smp_filename , ins_filename = None , use_generic_names = False , gwutils_compliant = False , datetime_format = None , prefix = '' ) : if ins_filename is None : ins_filename = smp_filename + ".ins" df = smp_to_dataframe ( smp_filename , datetime_format = datetime_format ) df . loc [ : , "ins_strings" ] = None df . loc [ : , "observation_names" ] = None name_groups = df . groupby ( "name" ) . groups for name , idxs in name_groups . items ( ) : if not use_generic_names and len ( name ) <= 11 : onames = df . loc [ idxs , "datetime" ] . apply ( lambda x : prefix + name + '_' + x . strftime ( "%d%m%Y" ) ) . values else : onames = [ prefix + name + "_{0:d}" . format ( i ) for i in range ( len ( idxs ) ) ] if False in ( map ( lambda x : len ( x ) <= 20 , onames ) ) : long_names = [ oname for oname in onames if len ( oname ) > 20 ] raise Exception ( "observation names longer than 20 chars:\n{0}" . format ( str ( long_names ) ) ) if gwutils_compliant : ins_strs = [ "l1  ({0:s})39:46" . format ( on ) for on in onames ] else : ins_strs = [ "l1 w w w  !{0:s}!" . format ( on ) for on in onames ] df . loc [ idxs , "observation_names" ] = onames df . loc [ idxs , "ins_strings" ] = ins_strs counts = df . observation_names . value_counts ( ) dup_sites = [ name for name in counts . index if counts [ name ] > 1 ] if len ( dup_sites ) > 0 : raise Exception ( "duplicate observation names found:{0}" . format ( ',' . join ( dup_sites ) ) ) with open ( ins_filename , 'w' ) as f : f . write ( "pif ~\n" ) [ f . write ( ins_str + "\n" ) for ins_str in df . loc [ : , "ins_strings" ] ] return df
create an instruction file for an smp file

    Parameters
    ----------
    smp_filename : str
        existing smp file
    ins_filename: str
        instruction file to create.  If None, create
        an instruction file using the smp filename
        with the ".ins" suffix
    use_generic_names : bool
        flag to force observations names to use a generic
        int counter instead of trying to use a datetime str
    gwutils_compliant : bool
        flag to use instruction set that is compliant with the
        pest gw utils (fixed format instructions).  If false,
        use free format (with whitespace) instruction set
    datetime_format : str
        str to pass to datetime.strptime in the smp_to_dataframe() function
    prefix : str
         a prefix to add to the front of the obsnmes.  Default is ''


    Returns
    -------
    df : pandas.DataFrame
        dataframe instance of the smp file with the observation names and
        instruction lines as additional columns