Applies a KL parameterization transform from basis factors to model
    input arrays.  Companion function to kl_setup()

    Parameters
    ----------
    par_file : str
        the csv file to get factor values from.  Must contain
        the following columns: name, new_val, org_val
    basis_file : str
        the binary file that contains the reduced basis

    par_to_file_dict : dict
        a mapping from KL parameter prefixes to array file names.

    Note
    ----
    This is the companion function to kl_setup.

    This function should be called during the forward run

    Example
    -------
    ``>>>import pyemu``

    ``>>>pyemu.helpers.kl_apply("kl.dat","basis.dat",{"hk":"hk_layer_1.dat",(100,100))``

def kl_apply(par_file, basis_file,par_to_file_dict,arr_shape):
    """ Applies a KL parameterization transform from basis factors to model
    input arrays.  Companion function to kl_setup()

    Parameters
    ----------
    par_file : str
        the csv file to get factor values from.  Must contain
        the following columns: name, new_val, org_val
    basis_file : str
        the binary file that contains the reduced basis

    par_to_file_dict : dict
        a mapping from KL parameter prefixes to array file names.

    Note
    ----
    This is the companion function to kl_setup.

    This function should be called during the forward run

    Example
    -------
    ``>>>import pyemu``

    ``>>>pyemu.helpers.kl_apply("kl.dat","basis.dat",{"hk":"hk_layer_1.dat",(100,100))``


    """
    df = pd.read_csv(par_file)
    assert "name" in df.columns
    assert "org_val" in df.columns
    assert "new_val" in df.columns

    df.loc[:,"prefix"] = df.name.apply(lambda x: x[:-4])
    for prefix in df.prefix.unique():
        assert prefix in par_to_file_dict.keys(),"missing prefix:{0}".\
            format(prefix)
    basis = pyemu.Matrix.from_binary(basis_file)
    assert basis.shape[1] == arr_shape[0] * arr_shape[1]
    arr_min = 1.0e-10 # a temp hack

    #means = df.loc[df.name.apply(lambda x: x.endswith("mean")),:]
    #print(means)
    df = df.loc[df.name.apply(lambda x: not x.endswith("mean")),:]
    for prefix,filename in par_to_file_dict.items():
        factors = pyemu.Matrix.from_dataframe(df.loc[df.prefix==prefix,["new_val"]])
        factors.autoalign = False
        basis_prefix = basis[:factors.shape[0],:]
        arr = (factors.T * basis_prefix).x.reshape(arr_shape)
        #arr += means.loc[means.prefix==prefix,"new_val"].values
        arr[arr<arr_min] = arr_min
        np.savetxt(filename,arr,fmt="%20.8E")