function read_dat(rep::String, g1::String="G5", g2::String="G5")
    p = joinpath(path, rep, "info")
    f = filter(x-> contains(x, ".dat"), readdir(p))
    f = joinpath(p, f[1])
    return read_mesons(f, g1, g2)
end
function read_dat(rep::Vector{String}, g1::String="G5", g2::String="G5")
    p = joinpath.(path, rep, "info")
    f = [filter(x-> contains(x, ".dat"), readdir(p[k]))[1] for k = 1:length(p)] 
    f = joinpath.(p, f)
    return read_mesons(f, g1, g2)
end
function read_rew(rep::String)
    p = joinpath(path, rep, "rew")
    f = filter(x-> contains(x, ".dat"), readdir(p))
    f = joinpath(p, f[1])
    try
        return read_ms1(f)
    catch
        return read_ms1(f, v="1.4")
    end
end
read_rew(rep::Vector{String}) = read_rew.(rep)

function get_mu(mu_list::Vector{Vector{Float64}}, deg::Bool)
    mu_sorted = unique(sort(minimum.(mu_list)))

    mul = mu_sorted[1]
    deg ? mus = 0.0 : mus = mu_sorted[2]
    muh = unique(maximum.(mu_list))
    muh = filter(x-> x > mul && x > mus, muh)

    return mul, mus, muh
end

function get_ll(mu_list, obs::Vector{uwreal}, deg::Bool)
    mul, mus, muh = get_mu(mu_list, deg)
    for k = 1:length(mu_list)
        mu = mu_list[k]
        if mul in mu && mu[1] == mu[2] #l-l
            return obs[k]
        end
    end
end

function get_ls(mu_list, obs::Vector{uwreal}, deg::Bool)
    mul, mus, muh = get_mu(mu_list, deg)
    for k = 1:length(mu_list)
        mu = mu_list[k]
        if mul in mu && mus in mu && mu[1] != mu[2] #l-s
            return obs[k]
        end
    end
end

function get_ss(mu_list, obs::Vector{uwreal}, deg::Bool)
    mul, mus, muh = get_mu(mu_list, deg)
    for k = 1:length(mu_list)
        mu = mu_list[k]
        if mus in mu && mu[1] == mu[2] #s-s
            return obs[k]
        end
    end
end

function get_lh(mu_list, obs::Vector{uwreal}, deg::Bool)
    mul, mus, muh = get_mu(mu_list, deg)
    obs_lh = Vector{uwreal}(undef, 0)
    for k = 1:length(mu_list)
        mu = mu_list[k]
        if mul in mu && mu[1] != mu[2] && !(mus in mu) #l-h
            push!(obs_lh, obs[k])
        end
    end
    return obs_lh
end

function get_sh(mu_list, obs::Vector{uwreal}, deg::Bool)
    mul, mus, muh = get_mu(mu_list, deg)
    obs_sh = Vector{uwreal}(undef, 0)
    for k = 1:length(mu_list)
        mu = mu_list[k]
        if mus in mu && mu[1] != mu[2] && !(mul in mu)#s-h
            push!(obs_sh, obs[k])
        end
    end
    return obs_sh
end

function get_hh(mu_list, obs::Vector{uwreal}, deg::Bool)
    mul, mus, muh = get_mu(mu_list, deg)
    obs_hh = Vector{uwreal}(undef, 0)
    for k = 1:length(mu_list)
        mu = mu_list[k]
        if mu[1] == mu[2] && !(mul in mu) && !(mus in mu)
            push!(obs_hh, obs[k])
        end
    end
    return obs_hh
end
function select_plateau(ens::String, mu_list, deg::Bool)
    mul, mus, muh = get_mu(mu_list, deg)
    f = readdlm(path_plat)
    head = String.(f[:, 1])

    delim = findall(x-> contains(x, "#"), head)
    edelim = findfirst(x-> contains(x, ens), head)
    cdelim = findfirst(x-> x.== edelim, delim)

    del = delim[cdelim]+1 : delim[cdelim+1]-1

    plat = Vector{Vector{Int64}}(undef, 0)
    plat_ = Int64.(f[del, 2:3])
    head_ = String.(f[del, 1])
    
    for k = 1:length(mu_list)
        mu = mu_list[k]
        if mul in mu && mu[1] != mu[2] && !(mus in mu)  #heavy-light
            n = findfirst(x-> contains(x, "lh"), head_)
            push!(plat, [plat_[n, 1], plat_[n, 2]])
        elseif mul in mu && mu[1] == mu[2] #light-light
            n = findfirst(x-> contains(x, "ll"), head_)
            push!(plat, [plat_[n, 1], plat_[n, 2]])
        elseif mul in mu && mus in mu#strange-light
            n = findfirst(x-> contains(x, "ls"), head_)
            push!(plat, [plat_[n, 1], plat_[n, 2]])
        elseif mus in mu && mu[1] != mu[2] && !(mul in mu)#heavy-strange
            n = findfirst(x-> contains(x, "sh"), head_)
            push!(plat, [plat_[n, 1], plat_[n, 2]])
        elseif mus in mu && mu[1] == mu[2] && !(mul in mu)#strange-strange
            n = findfirst(x-> contains(x, "ss"), head_)
            push!(plat, [plat_[n, 1], plat_[n, 2]])
        elseif !(mul in mu) && !(mus in mu) #heavy-heavy
            n = findfirst(x-> contains(x, "hh"), head_)
            push!(plat, [plat_[n, 1], plat_[n, 2]])
        end
    end
    return plat
end
function comp_meff(pp_obs::Vector{juobs.Corr}, deg::Bool, ens::String; pl::Bool=false)
    mu_list = getfield.(pp_obs, :mu)
    plat = select_plateau(ens, mu_list, deg)
    return meff.(pp_obs, plat, pl=pl)
end
function comp_pcac(a0p_obs::Vector{juobs.Corr}, pp_obs::Vector{juobs.Corr}, deg::Bool, ens::String; pl::Bool=false)
    mu_list = getfield.(pp_obs, :mu)
    plat = select_plateau(ens, mu_list, deg)
    return mpcac.(a0p_obs, pp_obs, plat, pl=pl)
end
function comp_f(pp_obs::Vector{juobs.Corr}, m::Vector{uwreal}, deg::Bool, ens::String; pl::Bool=false)
    mu_list = getfield.(pp_obs, :mu)
    plat = select_plateau(ens, mu_list, deg)
    return dec_const_pcvc.(pp_obs, plat, m, pl=pl)
end

function match_muc(muh, m_lh, m_lh_star, target)
    M = (m_lh .+ 3 .* m_lh_star) ./ 4

    par, chi2exp = lin_fit(muh, M)
    muh_target = x_lin_fit(par, target)
    return muh_target
end
function match_muc(muh, m_lh, m_sh, m_lh_star, m_sh_star, target)
    M = (2 .* m_lh .+ 6 .* m_lh_star .+ m_sh .+ 3 .* m_sh_star) ./ 12

    par, chi2exp = lin_fit(muh, M)
    muh_target = x_lin_fit(par, target)
    return muh_target
end