예제 #1
0
def wham(dim, react_paths, first_num_imgs, num_cycles, num_bins, wham_conv):

    start_time1 = time.time()

    global KbT

    # The initial string and final string
    first_i = 1
    first_t = first_num_imgs

    #############################READ THE DATA FILES###########################

    # All of the following list has dimension of iteration * images
    res_crdl = []
    res_forcel = []
    datal = []

    for i in range(1, num_cycles+1):
        window_dir = './' + str(i) + '/'
        res_crdf = window_dir + 'newconstr.' + str(i) + '.dat'
        res_crd = read_dat_file(res_crdf)
        res_forcef = window_dir + 'force.' + str(i) + '.dat'
        res_force = read_dat_file(res_forcef)
        n1=len(res_crd)
        n2=len(res_force)
        if n1 == n2:
            res_crdl = res_crdl + res_crd
            res_forcel = res_forcel + res_force
            for j in range(1, n1+1):
                datf = window_dir + 'distperframe' + str(j) + '.dat'
                data = read_dat_file(datf)
                datal.append(data)
        else:
            raise ValueError('The number of distances (%d) and (%d) force constants are '
                             'not the same in the step %d!' %(n1, n2, i))

    # Define the final string
    last_num_imgs = n1
    final_t = len(datal)
    final_i = final_t - last_num_imgs + 1
    string_seq = [first_i, first_t, final_i, final_t]

    # Check the three lists are consistent
    if len(res_crdl) == len(res_forcel):
        if len(res_crdl) == len(datal):
            num_sims = len(res_crdl)
        else:
            raise ValueError('The numbers of equlibrium distances and windows are not consistent!')
    else:
        raise ValueError('The number of equlibrium distances and force constants are not consistent!')

    # Generate the data_dict, which contains all the data
    data_dict = {}
    for i in range(0, num_sims):
        window_datai = window_data(res_crdl[i], res_forcel[i], datal[i], dim)
        data_dict[i+1] = window_datai

    #Plot the first and last string
    plot_string_1D(first_num_imgs, dim, data_dict, first_i, first_t, react_paths, 'First_string.pdf')
    plot_string_1D(last_num_imgs, dim, data_dict, final_i, final_t, react_paths, 'Last_string.pdf')

    #############################THE WHAM CODE#################################
    #Get the biased potentials
    #Ubiasl = get_Ubiasl(data_dict, num_sims, dim)
    Ubiasl = []
    for i in xrange(0, num_sims): #Sum over big N for i
        data_per_sim = len(data_dict[i+1].data)
        for l in xrange(0, data_per_sim): #Sum over small n for l
            for k in xrange(0, num_sims): #Sum over i,l for k
                Ubias = 0.0
                for ii in xrange(0, dim): #Along each dimension
                    equ_dis = data_dict[k+1].equ_dis[ii]
                    constr = data_dict[k+1].constr[ii]
                    samp_dis = data_dict[i+1].data[l,ii]
                    Ubias = Ubias + 0.5 * constr * (samp_dis - equ_dis)**2
                Ubias = exp(-Ubias/KbT)
                Ubiasl.append(Ubias)
    #return Ubiasl

    #WHAM iteration
    Fx_old = [0.0 for i in xrange(num_sims)]
    Fx_prog = []
    iter = 0
    change = 999.0

    while change > wham_conv:
        # This part is based on the equations 12-15 on the paper
        # of Souaille and Roux on Computer Physics Communications
        # 2001, 135, 40-57
        # Another reference:
        # http://membrane.urmc.rochester.edu/sites/default/files/wham/wham_talk.pdf
        expFx_old = [exp(i/KbT) for i in Fx_old]

        Fx = [0.0 for i in xrange(num_sims)] #Initial free energy
        kk=0 #A number to count

        """#The code from the WHAM paper
        for k in xrange(0, num_sims):
            ebfk = 0.0
            for i in xrange(0, num_sims):
                data_per_sim = len(data_dict[i+1].data)
                for l in xrange(0, data_per_sim):
                    bottom = 0.0
                    for j in xrange(0, num_sims):
                        bottom = Ubiasl[kk] * expFx_old[j]
                    ebfk = ebfk + Ubiasl[kk]/bottom"""

        for i in xrange(0, num_sims): #Sum over big N for i
            data_per_sim = len(data_dict[i+1].data) 
            for l in xrange(0, data_per_sim): #Sum over little n for l
                denom = 0.0 # Obtain the denominator
                Ubiasl_j = []
                for j in xrange(num_sims):
                   data_per_sim2 = len(data_dict[j+1].data)
                   #denom = denom + Ubiasl[kk] * expFx_old[j]
                   denom = denom + float(data_per_sim2) * Ubiasl[kk] * expFx_old[j]
                   Ubiasl_j.append(Ubiasl[kk])
                   kk = kk + 1
                denom = 1.0/denom
                for k in xrange(num_sims):
                    Fx[k] = Fx[k] + Ubiasl_j[k] * denom

        #Get the updated probability
        Fx = [-KbT*log(Fx[i]) for i in xrange(num_sims)] #Transfer the probability into free energy
        Fx0 = Fx[0] #Normalize the Fx values
        Fx = [Fx[i]-Fx0 for i in xrange(num_sims)]
        Fx_old = Fx #Assign the Fx as Fx_old
 
        if iter <= 1:
            Fx_prog = Fx_prog + Fx
        else:
            Fx_prog = Fx_prog + Fx
            Fx_last = Fx_prog[-num_sims:]
            Fx_last2 = Fx_prog[-2*num_sims:-num_sims]
            Fx_diff = [abs(Fx_last[i] - Fx_last2[i]) for i in range(0, num_sims)]
            change = max(Fx_diff)
        iter = iter + 1

    expFx = [exp(i/KbT) for i in Fx]
    write_list('Fx.dat', Fx, num_sims)
    write_list('Fx_prog.dat', Fx_prog, num_sims)

    cost_time = time.time() - start_time1
    print("%d Iterations were taken!" %(iter))
    print("It costs %f seconds to finish the WHAM cycle!" %cost_time)
    
    return data_dict, num_sims, string_seq, expFx, Ubiasl
예제 #2
0
def wham_iter(num_sims, wham_conv, data_dict, Ubiasl):

    start_time = time.time()

    #WHAM iteration
    Fx_old = [0.0 for i in xrange(num_sims)]
    Fx_prog = []
    iter = 0
    change = 999.0

    while change > wham_conv:
        # This part is based on the equations 12-15 on the paper
        # of Souaille and Roux on Computer Physics Communications
        # 2001, 135, 40-57
        # Another reference:
        # http://membrane.urmc.rochester.edu/sites/default/files/wham/wham_talk.pdf
        expFx_old = [exp(i / KbT) for i in Fx_old]

        Fx = [0.0 for i in xrange(num_sims)]  #Initial free energy
        kk = 0  #A number to count
        """
        #The code from the WHAM paper
        for k in xrange(0, num_sims):
            ebfk = 0.0
            for i in xrange(0, num_sims):
                data_per_sim = len(data_dict[i+1].data)
                for l in xrange(0, data_per_sim):
                    bottom = 0.0
                    for j in xrange(0, num_sims):
                        bottom = Ubiasl[kk] * expFx_old[j]
                    ebfk = ebfk + Ubiasl[kk]/bottom"""

        for i in xrange(0, num_sims):  #Sum over big N for i
            data_per_sim = len(data_dict[i + 1].data)
            for l in xrange(0, data_per_sim):  #Sum over little n for l
                denom = 0.0  # Obtain the denominator
                Ubiasl_j = []
                for j in xrange(num_sims):
                    data_per_sim2 = len(data_dict[j + 1].data)
                    #denom = denom + Ubiasl[kk] * expFx_old[j]
                    denom = denom + float(
                        data_per_sim2) * Ubiasl[kk] * expFx_old[j]
                    Ubiasl_j.append(Ubiasl[kk])
                    kk = kk + 1
                denom = 1.0 / denom
                for k in xrange(num_sims):
                    Fx[k] = Fx[k] + Ubiasl_j[k] * denom

        #Get the updated probability
        Fx = [-KbT * log(Fx[i]) for i in xrange(num_sims)
              ]  #Transfer the probability into free energy
        Fx0 = Fx[0]  #Normalize the Fx values
        Fx = [Fx[i] - Fx0 for i in xrange(num_sims)]
        Fx_old = Fx  #Assign the Fx as Fx_old

        if iter <= 1:
            Fx_prog = Fx_prog + Fx
        else:
            Fx_prog = Fx_prog + Fx
            Fx_last = Fx_prog[-num_sims:]
            Fx_last2 = Fx_prog[-2 * num_sims:-num_sims]
            Fx_diff = [
                abs(Fx_last[i] - Fx_last2[i]) for i in range(0, num_sims)
            ]
            change = max(Fx_diff)
        iter = iter + 1

    expFx = [exp(i / KbT) for i in Fx]
    write_list('Fx.dat', Fx, num_sims)
    write_list('Fx_prog.dat', Fx_prog, num_sims)

    cost_time = time.time() - start_time
    print("%d Iterations were taken!" % (iter))
    print("It costs %f seconds to finish the WHAM cycle!" % cost_time)

    return expFx