def run_MCMC_new(which_par,niter,save_title, renorm_var):
    """
    Functions that runs the MCMC for a given set of parameters

    Keyword Arguments:
    which_par -- a list of indices, corresponding to the order defined above, exemple [0,2] means ombh2,tau if order is [ombh2,omch2,tau,As,ns,H0]
    niter -- number of iterations in MCMC
    renorm_var -- factor multipling the variance, to play around for better acceptance rate.
    """
    cov_new_temp = cov_new[which_par,:][:,which_par] * renorm_var
    string_temp = strings[which_par]
    titles_temp = titles[which_par]
    x_mean_temp = x_mean[which_par]
    priors_central_temp = priors_central[which_par]
    priors_invvar_temp = priors_invvar[which_par]
    print titles_temp
    # generate first guess parameters
    guess_param = PS2P.prop_dist_form_params(x_mean_temp,cov_new_temp)
    print "initial guess = ", guess_param
    # generate first fluctuation map
    dd2 = cb.update_dic(dd,guess_param,string_temp)
    cl = cb.generate_spectrum(dd2)[:,1]
    cl[:2] = 1.e-35
    renorm = CG.renorm_term(cl,bl,nl)
    fluc = hp.almxfl(CG.generate_w1term(cl[:lmax+1],bl[:lmax+1],nl[:lmax+1]) + CG.generate_w0term(cl[:lmax+1]),renorm)
    mf = hp.almxfl(CG.generate_mfterm(dlm,cl[:lmax+1],bl[:lmax+1],nl[:lmax+1]),renorm)
    # the core of the MCMC
    testss = np.array(MH.MCMC_log_Jeff_new(guess_param, JJi.target_new,PS2P.prop_dist_form_params, PS2P.prop_func_form_params,niter,PS2P.Gaussian_priors_func,[[dlm,string_temp,dd,nl[:lmax+1],bl[:lmax+1]],[cl[:lmax+1],fluc,mf]],[x_mean_temp*0,np.matrix(cov_new_temp)],[priors_central_temp,priors_invvar_temp]))
    np.save("chain_%s_%s_%d_%d.npy"%(save_title,str(which_par).replace(',','').replace('[','').replace(']','').replace(' ',''),np.random.randint(0,100000),niter),testss)
    return testss
def Step_MC(guess, *arg):
    """
    Keyword Arguments:
    x -- the vector of params

    *args are:
    arg[0] -- a target class object
    arg[1] -- Cl_old, fluc_lm_old
    """
    ##print guess, arg
    dlm,strings,params,nl,bl = arg[0]
    Cl_old, fluc_lm_GS,mf_old = arg[1]
    dd = cb.update_dic(params,guess,strings)
    #generate new spectrum from new params
    lmax = len(Cl_old)
    Cl_new = cb.generate_spectrum(dd)[:lmax,1]
    # avoid dividing by 0
    Cl_new[:2] = 1.e-35
    #print "new = ",Cl_new[50]
    #print "old = ",Cl_old[50]
    # renormalization, i.e. lhs part of eq (24) and (25)
    renorm = CG.renorm_term(Cl_new,bl,nl)
    # generate mean field map using new PS
    mf_lm_new = hp.almxfl(CG.generate_mfterm(dlm,Cl_new,bl,nl),renorm)
    # get deterministic fluctuation map (new rescaling with noise)
    fluc_lm_determ = hp.almxfl(fluc_lm_GS,np.sqrt((1./Cl_old))/np.sqrt((1./Cl_new)))
    # get GS fluctuation map "for next iteration"
    fluc_lm_GS_next = hp.almxfl(CG.generate_w1term(Cl_new,bl,nl)+CG.generate_w0term(Cl_new),renorm)
    # Chi2 part of the likelihood
    return fluc_lm_determ,mf_lm_new, fluc_lm_GS_next, Cl_new
def target_distrib(guess, *arg):
    """
    Keyword Arguments:
    x -- the vector of params

    *args are:
    arg[0] -- a target class object
    arg[1] -- Cl_old, fluc_lm_old
    """
    #print guess, arg
    dlm,strings,params,nl,bl = arg[0]
    Cl_old, fluc_lm_old = arg[1]
    dd = cb.update_dic(params,guess,strings)
    Cl_new = cb.generate_spectrum(dd)[:,1]
    Cl_new[:2] = 1.e-35
    #print "new = ",Cl_new[50]
    #print "old = ",Cl_old[50]
    renorm = CG.renorm_term(Cl_new,bl,nl)
    mf_lm_new = hp.almxfl(CG.generate_mfterm(dlm,Cl_new,bl,nl),renorm)
    fluc_lm_type2 = hp.almxfl(CG.generate_w1term(Cl_new,bl,nl)+CG.generate_w0term(Cl_new),renorm)
    #print "new = ",fluc_lm_type2[50]
    #print "old = ",fluc_lm_old[50]
    fluc_lm_determ = hp.almxfl(fluc_lm_old,np.sqrt(Cl_new/Cl_old))
    tt1 = -1/2.*np.real(np.vdot((dlm-hp.almxfl(mf_lm_new,bl)).T,hp.almxfl((dlm-hp.almxfl(mf_lm_new,bl)),1/nl)))
    #print tt1
    tt2 = -1/2. *np.real(np.vdot((mf_lm_new).T,hp.almxfl((mf_lm_new),1./Cl_new)))
    #print tt2
    tt3 = -1/2. *np.real(np.vdot((fluc_lm_determ).T,hp.almxfl((fluc_lm_determ),1/nl*bl**2)))
    #print tt3
    #tt4 = - 1./2 *(np.arange(1,np.size(Cl_new)+1)*np.log(Cl_new)).sum()
    ##print tt4
    return [tt1,tt2,tt3],Cl_new,fluc_lm_type2
def solve_CG(params_i,dd):
    dd = cb.update_dic(dd,params_i,strings)
    cl = cb.generate_spectrum(dd)[:,1]
    # define the first guess, the b from eq 25 since the code was design with this at first (might not be best idea ever)
    b_mf = CG.generate_mfterm(dlm_filt,cl[:lmax+1],bl[:lmax+1],nl[:lmax+1])
    b_w1 = CG.generate_w1term(cl[:lmax+1],bl[:lmax+1],nl[:lmax+1])
    b_w0 = CG.generate_w0term(cl[:lmax+1])
    b = b_mf + b_w1 + b_w0
    ###### left hand side factor
    renorm= np.sqrt(cl[:lmax+1])/(1+cl[:lmax+1]*bl[:lmax+1]**2/(nl[:lmax+1]))
    out = hp.almxfl(b,renorm)
    out_mf = hp.almxfl(b_mf,renorm)
    out_w1 = hp.almxfl(b_w1,renorm)
    out_w0 = hp.almxfl(b_w0,renorm)
    return out,out_mf,out_w0,out_w1
def target_distrib_newrescale(guess, *arg):
    """
    Keyword Arguments:
    x -- the vector of params

    *args are:
    arg[0] -- a target class object
    arg[1] -- Cl_old, fluc_lm_old
    """
    ##print guess, arg
    dlm,strings,params,nl,bl = arg[0]
    Cl_old, fluc_lm_old = arg[1]
    dd = cb.update_dic(params,guess,strings)
    #generate new spectrum from new params
    lmax = len(Cl_old)
    Cl_new = cb.generate_spectrum(dd)[:lmax,1]
    # avoid dividing by 0
    Cl_new[:2] = 1.e-35
    #print "new = ",Cl_new[50]
    #print "old = ",Cl_old[50]
    # renormalization, i.e. lhs part of eq (24) and (25)
    renorm = CG.renorm_term(Cl_new,bl,nl)
    # generate mean field map using new PS
    mf_lm_new = hp.almxfl(CG.generate_mfterm(dlm,Cl_new,bl,nl),renorm)
    # generate fluctuation map using new PS, this is actually the 'step 2', with acceptance 1, won't be used anymore in this function
    fluc_lm_type2 = hp.almxfl(CG.generate_w1term(Cl_new,bl,nl)+CG.generate_w0term(Cl_new),renorm)
    #print "new = ",fluc_lm_type2[50]
    #print "old = ",fluc_lm_old[50]
    # get deterministic fluctuation map (new rescaling with noise)
    fluc_lm_determ = hp.almxfl(fluc_lm_old,np.sqrt((1./Cl_old+bl**2/nl))/np.sqrt((1./Cl_new+bl**2/nl)))
    # Chi2 part of the likelihood
    tt1 = -1/2.*np.real(np.vdot((dlm-hp.almxfl(mf_lm_new,bl)).T,hp.almxfl((dlm-hp.almxfl(mf_lm_new,bl)),1/nl)))
    #print tt1
    # "mean field part" of the likelihood
    tt2 = -1/2. *np.real(np.vdot((mf_lm_new).T,hp.almxfl((mf_lm_new),1./Cl_new)))
    #print tt2
    # "fluctuation part" of the likelihood
    tt3 = -1/2. *np.real(np.vdot((fluc_lm_determ).T,hp.almxfl((fluc_lm_determ),1/nl*bl**2+1/Cl_new)))
    #print tt3
    # we return Cl_new and fluc_lm_type2 for next iteration.
    return [tt1,tt2,tt3],Cl_new,fluc_lm_type2
def test_loglike_Ji(guess, *arg):
    """
    Keyword Arguments:
    x -- the vector of params

    *args are:
    arg[0] -- a target class object
    arg[1] -- Cl_old, fluc_lm_old
    """
    ##print guess, arg
    dlm,strings,params,nl,bl,Cl_new = arg[0]
    Cl_old, fluc_lm_old = arg[1]
    Cl_new[:2] = 1.e-35
    Cl_old[:2] = 1.e-35
    renorm = CG.renorm_term(Cl_new,bl,nl)
    mf_lm_new = hp.almxfl(CG.generate_mfterm(dlm,Cl_new,bl,nl),renorm)
    fluc_lm_type2 = hp.almxfl(CG.generate_w1term(Cl_new,bl,nl)+CG.generate_w0term(Cl_new),renorm)
    fluc_lm_determ = hp.almxfl(fluc_lm_old,np.sqrt(Cl_new/Cl_old))
    tt = -1/2.*np.real(np.vdot((dlm-hp.almxfl(mf_lm_new,bl)).T,hp.almxfl((dlm-hp.almxfl(mf_lm_new,bl)),1./nl)))
    tt2 = -1/2. *np.real(np.vdot((mf_lm_new).T,hp.almxfl((mf_lm_new),1./Cl_new)))
    tt3 = -1/2. *np.real(np.vdot((fluc_lm_determ).T,hp.almxfl((fluc_lm_determ),1/nl*bl**2)))

    tt4 = - 1./2 *(np.arange(1,np.size(Cl_new)+1)*np.log(Cl_new)).sum()
    return tt,tt2,tt3,tt4,Cl_new,fluc_lm_type2