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
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