def get_mbar(args, beta_k, Z, U_kn, N_k, u_kln): if args.cpt: if os.path.exists('%s/f_k.npy' % args.direc): print 'Reading in free energies from %s/f_k.npy' % args.direc f_k = numpy.load('%s/f_k.npy' % args.direc) mbar = pymbar.MBAR(u_kln, N_k, initial_f_k=f_k, maximum_iterations=0, verbose=True, use_optimized=1) return mbar print 'Using WHAM to generate historgram-based initial guess of dimensionless free energies f_k...' beta_k = numpy.array(beta_k.tolist() * len(Z)) f_k = wham.histogram_wham(beta_k, U_kn, N_k) print 'Initializing MBAR...' mbar = pymbar.MBAR(u_kln, N_k, initial_f_k=f_k, use_optimized=1, verbose=True) mbar_file = '%s/f_k.npy' % args.direc print 'Saving free energies to %s' % mbar_file saving = True if saving: numpy.save(mbar_file, mbar.f_k) return mbar
def test_protocols(): ''' Test that free energy is moderately equal to analytical solution, independent of solver protocols ''' # Importing the hacky fix to asert that free energies are moderately correct from pymbar.tests.test_mbar import z_scale_factor name, u_kn, N_k, s_n, test = load_oscillators(50, 100, provide_test=True) fa = test.analytical_free_energies() fa = fa[1:] - fa[0] with suppress_derivative_warnings_for_tests(): # scipy.optimize.minimize methods, same ones that are checked for in mbar_solvers.py # subsampling_protocols = ['adaptive', 'L-BFGS-B', 'dogleg', 'CG', 'BFGS', 'Newton-CG', 'TNC', 'trust-ncg', 'SLSQP'] # scipy.optimize.root methods. Omitting methods which do not use the Jacobian. Adding the custom adaptive protocol. solver_protocols = ['adaptive', 'hybr', 'lm', 'L-BFGS-B', 'dogleg', 'CG', 'BFGS', 'Newton-CG', 'TNC', 'trust-ncg', 'SLSQP'] for solver_protocol in solver_protocols: # Solve MBAR with zeros for initial weights mbar = pymbar.MBAR(u_kn, N_k, solver_protocol=({'method': solver_protocol},)) # Solve MBAR with the correct f_k used for the inital weights mbar = pymbar.MBAR(u_kn, N_k, initial_f_k=mbar.f_k, solver_protocol=({'method': solver_protocol},)) results = mbar.getFreeEnergyDifferences(return_dict=True) fe = results['Delta_f'][0,1:] fe_sigma = results['dDelta_f'][0,1:] z = (fe - fa) / fe_sigma eq(z / z_scale_factor, np.zeros(len(z)), decimal=0)
def get_mbar(beta_k, U_kn, N_k, u_kln): print 'Initializing mbar...' #f_k = wham.histogram_wham(beta_k, U_kn, N_k) try: f_k = numpy.loadtxt('f.k.out') assert(len(f_k)==len(beta_k)) mbar = pymbar.MBAR(u_kln, N_k, initial_f_k = f_k, verbose=True) except: mbar = pymbar.MBAR(u_kln, N_k, verbose=True) #mbar = pymbar.MBAR(u_kln, N_k, initial_f_k = f_k, verbose=True) return mbar
def test_protocols(): '''Test that free energy is moderatley equal to analytical solution, independent of solver protocols''' #Supress the warnings when jacobian and Hessian information is not used in a specific solver import warnings warnings.filterwarnings('ignore', '.*does not use the jacobian.*') warnings.filterwarnings('ignore', '.*does not use Hessian.*') from pymbar.tests.test_mbar import z_scale_factor # Importing the hacky fix to asert that free energies are moderatley correct name, u_kn, N_k, s_n, test = load_oscillators(50, 100, provide_test=True) fa = test.analytical_free_energies() fa = fa[1:] - fa[0] #scipy.optimize.minimize methods, same ones that are checked for in mbar_solvers.py subsampling_protocols = [ "L-BFGS-B", "dogleg", "CG", "BFGS", "Newton-CG", "TNC", "trust-ncg", "SLSQP" ] solver_protocols = [ 'hybr', 'lm' ] #scipy.optimize.root methods. Omitting methods which do not use the Jacobian for subsampling_protocol in subsampling_protocols: for solver_protocol in solver_protocols: #Solve MBAR with zeros for initial weights mbar = pymbar.MBAR(u_kn, N_k, subsampling_protocol=({ 'method': subsampling_protocol }, ), solver_protocol=({ 'method': solver_protocol }, )) #Solve MBAR with the correct f_k used for the inital weights mbar = pymbar.MBAR(u_kn, N_k, initial_f_k=mbar.f_k, subsampling_protocol=({ 'method': subsampling_protocol }, ), solver_protocol=({ 'method': solver_protocol }, )) fe, fe_sigma, Theta_ij = mbar.getFreeEnergyDifferences() fe, fe_sigma = fe[0, 1:], fe_sigma[0, 1:] z = (fe - fa) / fe_sigma eq(z / z_scale_factor, np.zeros(len(z)), decimal=0) #Clear warning filters warnings.resetwarnings()
def _test(data_generator): name, U, N_k, s_n = data_generator() print(name) mbar = pymbar.MBAR(U, N_k) results1 = mbar.getFreeEnergyDifferences(uncertainty_method="svd", return_dict=True) fij1_t, dfij1_t = mbar.getFreeEnergyDifferences(uncertainty_method="svd", return_dict=False) results2 = mbar.getFreeEnergyDifferences(uncertainty_method="svd-ew", return_dict=True) fij1 = results1['Delta_f'] dfij1 = results1['dDelta_f'] fij2 = results2['Delta_f'] dfij2 = results2['dDelta_f'] # Check to make sure the returns from with and w/o dict are the same eq(fij1, fij1_t) eq(dfij1, dfij1_t) eq(pymbar.mbar_solvers.mbar_gradient(U, N_k, mbar.f_k), np.zeros(N_k.shape), decimal=8) eq(np.exp(mbar.Log_W_nk).sum(0), np.ones(len(N_k)), decimal=10) eq(np.exp(mbar.Log_W_nk).dot(N_k), np.ones(U.shape[1]), decimal=10) eq(pymbar.mbar_solvers.self_consistent_update(U, N_k, mbar.f_k), mbar.f_k, decimal=10) # Test against old MBAR code. with suppress_derivative_warnings_for_tests(): mbar0 = pymbar.old_mbar.MBAR(U, N_k) fij0, dfij0 = mbar0.getFreeEnergyDifferences(uncertainty_method="svd") eq(mbar.f_k, mbar0.f_k, decimal=8) eq(np.exp(mbar.Log_W_nk), np.exp(mbar0.Log_W_nk), decimal=5) eq(fij0, fij1, decimal=8) eq(dfij0, dfij1, decimal=8) eq(fij0, fij2, decimal=8) eq(dfij0, dfij2, decimal=8)
def _test(data_generator): try: name, U, N_k, s_n = data_generator() except IOError as exc: raise(SkipTest("Cannot load dataset; skipping test. Try downloading pymbar-datasets GitHub repository and setting PYMBAR-DATASETS environment variable. Error was '%s'" % exc)) except ImportError as exc: raise(SkipTest("Error importing pytables to load dataset; skipping test. Error was '%s'" % exc)) print(name) mbar = pymbar.MBAR(U, N_k) fij1, dfij1, Theta_ij = mbar.getFreeEnergyDifferences(uncertainty_method="svd") fij2, dfij2, Theta_ij = mbar.getFreeEnergyDifferences(uncertainty_method="svd-ew") eq(pymbar.mbar_solvers.mbar_gradient(U, N_k, mbar.f_k), np.zeros(N_k.shape), decimal=8) eq(np.exp(mbar.Log_W_nk).sum(0), np.ones(len(N_k)), decimal=10) eq(np.exp(mbar.Log_W_nk).dot(N_k), np.ones(U.shape[1]), decimal=10) eq(pymbar.mbar_solvers.self_consistent_update(U, N_k, mbar.f_k), mbar.f_k, decimal=10) # Test against old MBAR code. mbar0 = pymbar.old_mbar.MBAR(U, N_k) fij0, dfij0 = mbar0.getFreeEnergyDifferences(uncertainty_method="svd") eq(mbar.f_k, mbar0.f_k, decimal=8) eq(np.exp(mbar.Log_W_nk), np.exp(mbar0.Log_W_nk), decimal=5) eq(fij0, fij1, decimal=8) eq(dfij0, dfij1, decimal=8) eq(fij0, fij2, decimal=8) eq(dfij0, dfij2, decimal=8)
def _construct_mbar_object(self, reference_reduced_potentials): """Constructs a new `pymbar.MBAR` object for a given set of reference and target reduced potentials Parameters ------- reference_reduced_potentials: numpy.ndarray The reference reduced potentials. Returns ------- pymbar.MBAR The constructed `MBAR` object. """ frame_counts = np.array( [len(observables) for observables in self._reference_observables] ) # Construct the mbar object. mbar = pymbar.MBAR( reference_reduced_potentials, frame_counts, verbose=False, relative_tolerance=1e-12, ) return mbar
def _test(data_generator): name, U, N_k, s_n = data_generator() print(name) mbar = pymbar.MBAR(U, N_k) fij1, dfij1, Theta_ij = mbar.getFreeEnergyDifferences( uncertainty_method="svd") fij2, dfij2, Theta_ij = mbar.getFreeEnergyDifferences( uncertainty_method="svd-ew") eq(pymbar.mbar_solvers.mbar_gradient(U, N_k, mbar.f_k), np.zeros(N_k.shape), decimal=8) eq(np.exp(mbar.Log_W_nk).sum(0), np.ones(len(N_k)), decimal=10) eq(np.exp(mbar.Log_W_nk).dot(N_k), np.ones(U.shape[1]), decimal=10) eq(pymbar.mbar_solvers.self_consistent_update(U, N_k, mbar.f_k), mbar.f_k, decimal=10) # Test against old MBAR code. mbar0 = pymbar.old_mbar.MBAR(U, N_k) fij0, dfij0 = mbar0.getFreeEnergyDifferences(uncertainty_method="svd") eq(mbar.f_k, mbar0.f_k, decimal=8) eq(np.exp(mbar.Log_W_nk), np.exp(mbar0.Log_W_nk), decimal=5) eq(fij0, fij1, decimal=8) eq(dfij0, dfij1, decimal=8) eq(fij0, fij2, decimal=8) eq(dfij0, dfij2, decimal=8)
def calc_mbar(u_kn, N_k, teff=1, temp=298): #data = concat_arr(arr1, arr2, idx1, idx2) #cols = 'dF(kcal/mol) se_dF(kcal/mol) dH se_dH TdS se_TdS dF_fwd dF_bwd dE_fwd dE_bwd sd_dE_fwd sd_dE_bwd p_A(traj_B) p_B(traj_A) eig_overlap'.split() cols = 'dF(kcal/mol) se_dF(kcal/mol) dH TdS se_dH dF_fwd dF_bwd dE_fwd dE_bwd sd_dE_fwd sd_dE_bwd overlap'.split( ) if u_kn is None: return cols kt = temp * 8.314 / 4184 mbar = pymbar.MBAR(u_kn, N_k) #results = mbar.getFreeEnergyDifferences() results = mbar.computeEntropyAndEnthalpy() overlap = mbar.computeOverlap() #msg1 = get_index_summary(idx1) #msg2 = get_index_summary(idx2) es_fwd = (u_kn[1, 0:N_k[0]] - u_kn[0, 0:N_k[0]]) es_bwd = (u_kn[0, N_k[0]:sum(N_k[0:2])] - u_kn[1, N_k[0]:sum(N_k[0:2])]) de_fwd = np.mean(es_fwd) * kt de_bwd = np.mean(es_bwd) * kt fwd, sd_fwd = exp_ave(es_fwd, ener_unit=kt) bwd, sd_bwd = exp_ave(es_bwd, ener_unit=kt) ghs = [] # free energy, enthalpy, entropy for i in range(3): ghs.append(kt * results[i * 2][0, 1]) ghs.append(kt * results[i * 2 + 1][0, 1] * np.sqrt(teff)) #return ghs[0], ghs[1], ghs[2], ghs[3], ghs[4], ghs[5], fwd, -bwd, de_fwd, -de_bwd, sd_fwd, sd_bwd, overlap['matrix'][0, 1], overlap['matrix'][1, 0], overlap['scalar'] return ghs[0], ghs[1], ghs[2], ghs[4], ghs[ 3], fwd, -bwd, de_fwd, -de_bwd, sd_fwd, sd_bwd, overlap['scalar']
def _bootstrap_function(self, **observables: ObservableArray) -> Observable: """Re-weights a set of reference observables to the target state. Parameters ------- observables The observables to reweight, in addition to the reference and target reduced potentials. """ reference_reduced_potentials = observables.pop( "reference_reduced_potentials") target_reduced_potentials = observables.pop( "target_reduced_potentials") # Construct the mbar object using the specified reference reduced potentials. # These may be the input values or values which have been sampled during # bootstrapping, hence why it is not precomputed once. mbar = pymbar.MBAR( reference_reduced_potentials.value.to( unit.dimensionless).magnitude.T, self.frame_counts, verbose=False, relative_tolerance=1e-12, ) # Compute the MBAR weights. weights = self._compute_weights(mbar, target_reduced_potentials) return self._reweight_observables(weights, mbar, target_reduced_potentials, **observables)
def _compute_effective_samples( self, reference_reduced_potentials: ObservableArray) -> float: """Compute the effective number of samples which contribute to the final re-weighted estimate. Parameters ---------- reference_reduced_potentials An 2D array containing the reduced potentials of each configuration evaluated at each reference state. Returns ------- The effective number of samples. """ # Construct an MBAR object so that the number of effective samples can # be computed. mbar = pymbar.MBAR( reference_reduced_potentials.value.to( unit.dimensionless).magnitude.T, self.frame_counts, verbose=False, relative_tolerance=1e-12, ) weights = (self._compute_weights( mbar, self.target_reduced_potentials).value.to( unit.dimensionless).magnitude) effective_samples = 1.0 / np.sum(weights**2) return float(effective_samples)
def calculate_PMF(self, nbins): #dz = self.com_dist - self.centers[..., np.newaxis] # deviation from restrained position self.com_bin = np.zeros_like(self.com_dist, dtype=int) # [umbrella, residue, config] self.histo = np.zeros([self.nres, self.K, nbins], dtype=int) self.bin_centers = np.zeros([self.nres, nbins]) self.results = [] for i in range(self.nres): print('Calculating PMF for Residue %d' % i, flush=True) # left edge of bins maxi = np.amax(self.com_dist[:, i, :]) mini = np.amin(self.com_dist[:, i, :]) delta = (maxi - mini) / nbins bins = np.linspace(mini, maxi - delta, nbins) # some reasonable bounds self.bin_centers[i, :] = bins + 0.5*delta bins += delta # for proper output from np.digitize for k in range(self.K): for n in range(self.N[k, i]): dz = self.com_dist[k, i, n] - self.centers[:, i] self.u_kln[i, k, :, n] = self.u_kn[k, i, n] + 0.5 * self.beta * self.spring_constant * dz**2 self.com_bin[k, i, n] = np.digitize(self.com_dist[k, i, n], bins) self.histo[i, k, :] = [np.sum(self.com_bin[k, i, :self.N[k, i]] == a) for a in range(nbins)] mbar = pymbar.MBAR(self.u_kln[i, ...], self.N[:, i]) self.results.append(mbar.computePMF(self.u_kn[:, i, :], self.com_bin[:, i, :], nbins))
def compute_free_energy_profiles_vs_T(coordinate,coordmin,coordmax,dcoord,tempsfile): """Compute potential of mean force along a coordinate as a function of temperature""" bin_edges = np.arange(coordmin,coordmax + dcoord,dcoord) bin_centers = 0.5*(bin_edges[1:] + bin_edges[:-1]) dirs = [ x.rstrip("\n") for x in open(tempsfile,"r").readlines() ] unique_Tlist, sorted_dirs = get_unique_Tlist(dirs) print "Loading u_kn" wantT, sub_indices, E, u_kn, N_k = get_ukn(unique_Tlist,sorted_dirs) beta = np.array([ 1./(kb*x) for x in wantT ]) print "solving mbar" mbar = pymbar.MBAR(u_kn,N_k) # Compute bin expectations at all temperatures. Free energy profile. print "computing expectations" A_indicators = get_binned_observables(bin_edges,coordinate,sorted_dirs,sub_indices) coordname = coordinate.split(".")[0] if not os.path.exists("pymbar_%s" % coordname): os.mkdir("pymbar_%s" % coordname) os.chdir("pymbar_%s" % coordname) Tndxs = np.argsort(wantT) sortT = wantT[Tndxs] np.savetxt("outputT",wantT[Tndxs]) np.savetxt("bin_edges",bin_edges) np.savetxt("bin_centers",bin_centers) plt.figure() # Compute pmf at each temperature. for i in range(len(wantT)): Tstr = "%.2f" % wantT[Tndxs[i]] #x = (max(sortT) - sortT[i])/(max(sortT) - min(sortT)) # Reverse color ordering x = (sortT[i] - min(sortT))/(max(sortT) - min(sortT)) # Color from blue to red A_ind_avg, dA_ind_avg, d2A_ind_avg = mbar.computeMultipleExpectations(A_indicators,u_kn[Tndxs[i],:]) pmf = -np.log(A_ind_avg) min_pmf = min(pmf) pmf -= min_pmf pmf_err_lower = -np.log(A_ind_avg - dA_ind_avg) - min_pmf pmf_err_upper = -np.log(A_ind_avg + dA_ind_avg) - min_pmf np.savetxt("free_%s" % Tstr, np.array([pmf,pmf_err_lower,pmf_err_upper]).T) plt.plot(bin_centers,pmf,lw=2,label=Tstr,color=cubecmap(x)) plt.xlabel("%s" % coordname,fontsize=18) plt.ylabel("F(%s)" % coordname,fontsize=18) plt.savefig("Fvs%s_all.png" % coordname) plt.savefig("Fvs%s_all.pdf" % coordname) plt.savefig("Fvs%s_all.eps" % coordname) os.chdir("..")
def get_mbar(args, beta_k, Z, U_kn, N_k, u_kln): print 'Reading in free energies from %s/f_k.npy' % args.direc f_k = numpy.load('%s/f_k.npy' % args.direc) mbar = pymbar.MBAR(u_kln, N_k, initial_f_k=f_k, verbose=True, use_optimized=1) return mbar
def get_mbar(E_no_bias, qtanh, umb_params, N_k): # calculate dimensionless energy for every frame in every thermodynamic # state (umbrella). The first state is the unbiased state. u_kn = np.zeros((n_biases + 1, E_no_bias.shape[0])) for i in range(n_biases): qtanh_center = umb_params[i][0] kumb = umb_params[i][1] Ebias_k = 0.5 * kumb * ((qtanh - qtanh_center)**2) u_kn[i, :] = beta * (E_no_bias + Ebias_k) u_kn[-1, :] = beta * E_no_bias mbar = pymbar.MBAR(u_kn, N_k) return mbar
def _test(data_generator): name, U, N_k, s_n = data_generator() print(name) mbar = pymbar.MBAR(U, N_k) eq(pymbar.mbar_solvers.mbar_gradient(U, N_k, mbar.f_k), np.zeros(N_k.shape), decimal=8) eq(np.exp(mbar.Log_W_nk).sum(0), np.ones(len(N_k)), decimal=10) eq(np.exp(mbar.Log_W_nk).dot(N_k), np.ones(U.shape[1]), decimal=10) eq(pymbar.mbar_solvers.self_consistent_update(U, N_k, mbar.f_k), mbar.f_k, decimal=10) # Test against old MBAR code. with suppress_derivative_warnings_for_tests(): mbar0 = pymbar.old_mbar.MBAR(U, N_k) eq(mbar.f_k, mbar0.f_k, decimal=8) eq(np.exp(mbar.Log_W_nk), np.exp(mbar0.Log_W_nk), decimal=5)
def calculate(self, temp=300.): """Calculate the free energy difference and return a PMF object. Parameters ---------- temp: float, optional temperature of calculation """ beta = 1. / (sim.boltz * temp) mbar = pymbar.MBAR( np.array(self.data) * beta, [len(dat[0]) for dat in self.data]) FEs = mbar.getFreeEnergyDifferences( compute_uncertainty=False)[0] / beta return PMF(self.lambdas, [FEs[0, i] for i in range(len(self.data))])
def _run_mbar(u_kln, N_k): K = len(N_k) f_k_BAR = np.zeros(K) for k in range(K - 2): w_F = u_kln[k, k + 1, :N_k[k]] - u_kln[k, k, :N_k[k]] w_R = u_kln[k + 1, k, :N_k[k + 1]] - u_kln[k + 1, k + 1, :N_k[k + 1]] f_k_BAR[k + 1] = pymbar.BAR(w_F, w_R, relative_tolerance=0.000001, verbose=False, compute_uncertainty=False) f_k_BAR = np.cumsum(f_k_BAR) mbar = pymbar.MBAR(u_kln, N_k, verbose=True, initial_f_k=f_k_BAR) return mbar
def _do_MBAR(self, u_nk, N_k, solver_protocol): mbar = pymbar.MBAR(u_nk.T, N_k, relative_tolerance=self.relative_tolerance, initial_f_k=self.initial_f_k, solver_protocol=(solver_protocol, )) self.logger.info( "Solved MBAR equations with method %r and " "maximum_iterations=%d, relative_tolerance=%g", solver_protocol['method'], solver_protocol['options']['maximum_iterations'], self.relative_tolerance) # set attributes out = mbar.getFreeEnergyDifferences(return_theta=True) return mbar, out
def run_mbar(u_kln, N_k): """ :param u_kln: 3d numpy array, reduced potential energy :param N_k: 1d numpy array, number of samples at state k :return: mbar, an object of pymbar.MBAR """ K = len(N_k) f_k_BAR = np.zeros(K) for k in range(K-2): w_F = u_kln[ k, k+1, :N_k[k] ] - u_kln[ k, k, :N_k[k] ] w_R = u_kln[ k+1, k, :N_k[k+1] ] - u_kln[ k+1, k+1, :N_k[k+1] ] f_k_BAR[k+1] = pymbar.BAR(w_F, w_R, relative_tolerance=0.000001, \ verbose=False, compute_uncertainty=False) f_k_BAR = np.cumsum(f_k_BAR) mbar = pymbar.MBAR(u_kln, N_k, verbose = True, initial_f_k = f_k_BAR) return mbar
def estimatewithMBAR(reltol=relative_tolerance, regular_estimate=False): """Computes the MBAR free energy given the reduced potential and the number of relevant entries in it.""" MBAR = pymbar.MBAR(u_kln, N_k, verbose = verbose, method = 'adaptive', relative_tolerance = reltol, initialize = initialize_with) # Get matrix of dimensionless free energy differences and uncertainty estimate. (Deltaf_ij, dDeltaf_ij) = MBAR.getFreeEnergyDifferences(uncertainty_method='svd-ew') if (verbose): print "The overlap matrix is..." O = MBAR.computeOverlap('matrix') for k in range(K): line = '' for l in range(K): line += ' %5.2f ' % O[k, l] print line if regular_estimate: return (Deltaf_ij, dDeltaf_ij) return (Deltaf_ij[0,K-1]/beta_report, dDeltaf_ij[0,K-1]/beta_report)
def _compute_integral(self, window_results): full_trace = [] frame_counts = numpy.empty(len(window_results)) for index, result in enumerate(window_results): trace, _, _ = result full_trace.append(trace) frame_counts[index] = len(trace) full_trace = numpy.vstack(full_trace) reduced_potentials = numpy.empty( (len(self._lambda_values), len(full_trace))) for lambda_index, lambda_value in enumerate(self._lambda_values): # TODO: Vectorize this. for trace_index in range(len(full_trace)): reduced_potentials[ lambda_index, trace_index] = -LambdaSimulation.evaluate_log_p( self._model, full_trace[trace_index][1:], lambda_value, self._reference_model, ) mbar = pymbar.MBAR(reduced_potentials, frame_counts) delta_f, d_delta_f = mbar.getFreeEnergyDifferences() self._overlap_matrix = mbar.computeOverlap()["matrix"] print("==============================") print("Overlap matrix:\n") pprint.pprint(self._overlap_matrix) print("==============================") return delta_f[-1, 0], d_delta_f[-1, 0]
def calculate(self, temp=300.): """Calculate the free energy difference and return a PMF object. Parameters ---------- temp: float, optional temperature of calculation, default 300 K """ N = self.data[0].shape[-1] N_sims = len(self.data) N_Bs = len(self.Bs) N_lams = len(self.lambdas) beta = 1 / (kB * temp) u_kn = np.zeros(shape=(N_sims, N*N_sims)) ns = np.zeros(N*N_sims) for dat, B_sim, lam_sim in zip( self.data, self._data_Bs, self._data_lambdas): # due to globbing simulation data will not have been # read in a logical order, need the below indices to # determine the proper position for each set of data i_B = self.Bs.index(B_sim) i_lam = self.lambdas.index(lam_sim) ns = dat[-1] # water occupancy data es = dat[:-1] # simulation energies for i in range(N_lams): for j, B in enumerate(self.Bs): mu = self.B_to_chemical_potential(B, temp) u_kn[i*N_Bs+j, (i_lam*N_Bs+i_B)*N: (i_lam*N_Bs+i_B+1)*N] =\ beta*(es[i] + ns * mu) samples = np.array([N] * N_sims) mbar = pymbar.MBAR(u_kn, samples) free_energies = mbar.getFreeEnergyDifferences( compute_uncertainty=False, return_theta=False)[0] / beta # free energy order seems to be reversed with respect to B values closest = np.argmin([abs(B - self.equilibrium_B(temp)) for B in self.Bs[::-1]]) return feb.PMF( self.lambdas, free_energies[0].reshape([N_lams, N_Bs])[:, closest])
for n in range(N_k[k]): bin_kn[k, n] = int((z_kn[k, n] - z_min) / delta) ### Evaluate reduced energies in all umbrellas print "Evaluating reduced potential energies..." for k in range(K): for n in range(N_k[k]): # Compute deviation from umbrella center dz = z_kn[k, n] - z0_k # Compute energy of snapshot n from simulation k in umbrella potential u_kln[k, :, n] = u_kn[k, n] + beta_k[k] * (K_k / 2.0) * dz**2 ### Initialize MBAR. print "Running MBAR..." mbar = pymbar.MBAR(u_kln, N_k, verbose=True, method='adaptive') ### Compute PMF in unbiased potential (in units of kT). (f_i, df_i) = mbar.computePMF(u_kn, bin_kn, nbins) ### Write out PMF. print "\n\nPMF (in units of Angs, kT)" print "%8s %8s %8s" % ('bin', 'f', 'df') for i in range(nbins): print "%8.6f %8.6f %8.6f" % (bin_center_i[i], f_i[i], df_i[i]) ### Convert units: x (A --> nm), y (kT --> kcal/mol). xs = [item / 10 for item in bin_center_i] ys = [item * 0.6120 for item in f_i] ss = [item * 0.6120 for item in df_i]
O_k, k_k) x_n, u_kn, N_k_output, s_n = test.sample(N_k, mode='u_kn') return name, u_kn, N_k_output, s_n def load_exponentials(n_states, n_samples): name = "%dx%d exponentials" % (n_states, n_samples) rates = np.linspace(1, 3, n_states) N_k = (np.ones(n_states) * n_samples).astype('int') test = pymbar.testsystems.exponential_distributions.ExponentialTestCase( rates) x_n, u_kn, N_k_output, s_n = test.sample(N_k, mode='u_kn') return name, u_kn, N_k_output, s_n mbar_gens = {"new": lambda u_kn, N_k: pymbar.MBAR(u_kn, N_k)} systems = [ lambda: load_exponentials(25, 100), lambda: load_exponentials(100, 100), lambda: load_exponentials(250, 250), lambda: load_oscillators(25, 100), lambda: load_oscillators(100, 100), lambda: load_oscillators(250, 250), lambda: load_oscillators(500, 100), lambda: load_oscillators(1000, 50), lambda: load_oscillators(2000, 20), lambda: load_oscillators(4000, 10), lambda: load_exponentials(500, 100), lambda: load_exponentials(1000, 50), lambda: load_exponentials(2000, 20), lambda: load_oscillators(4000, 10), load_gas_data, load_8proteins_data ] timedata = [] for version, mbar_gen in mbar_gens.items(): for sysgen in systems: name, u_kn, N_k, s_n = sysgen()
u_n = numpy.zeros([niterations], numpy.float64) for iteration in range(niterations): u_n[iteration] = 0.0 for state in range(nstates): u_n[iteration] += u_kln[state,state,iteration] # Detect equilibration. [nequil, g, Neff] = detect_equilibration(u_n) u_n = u_n[nequil:] u_kln = u_kln[:,:,nequil:] # Subsample data. indices = timeseries.subsampleCorrelatedData(u_n, g=g) u_n = u_n[indices] u_kln = u_kln[:,:,indices] N_k = len(indices) * numpy.ones([nstates], numpy.int32) # Analyze with MBAR. mbar = pymbar.MBAR(u_kln, N_k) [Delta_f_ij, dDelta_f_ij] = mbar.getFreeEnergyDifferences() # Compare with analytical. f_i_analytical = numpy.zeros([nstates], numpy.float64) for (state_index, state) in enumerate(simulation.states): values = computeHarmonicOscillatorExpectations(K, mass, state.temperature) f_i_analytical[state_index] = values['free energies']['potential'] Delta_f_ij_analytical = numpy.zeros([nstates, nstates], numpy.float64) for i in range(nstates): for j in range(nstates): Delta_f_ij_analytical[i,j] = f_i_analytical[j] - f_i_analytical[i] # Show difference. #print "estimated" #print Delta_f_ij #print dDelta_f_ij
def load_exponentials(n_states, n_samples): name = "%dx%d exponentials" % (n_states, n_samples) rates = np.linspace(1, 3, n_states) N_k = (np.ones(n_states) * n_samples).astype('int') test = pymbar.testsystems.exponential_distributions.ExponentialTestCase( rates) x_n, u_kn, N_k_output, s_n = test.sample(N_k, mode='u_kn') return name, u_kn, N_k_output, s_n solver_protocol = None mbar_gens = { "new": lambda u_kn, N_k, x_kindices: pymbar.MBAR(u_kn, N_k, x_kindices=x_kindices) } #mbar_gens = {"old":lambda u_kn, N_k, x_kindices: pymbar.old_mbar.MBAR(u_kn, N_k)} #mbar_gens = {"new":lambda u_kn, N_k, x_kindices: pymbar.MBAR(u_kn, N_k, x_kindices=x_kindices), "old":lambda u_kn, N_k, x_kindices: pymbar.old_mbar.MBAR(u_kn, N_k)} systems = [ lambda: load_exponentials(25, 100), lambda: load_exponentials(100, 100), lambda: load_exponentials(250, 250), lambda: load_oscillators(25, 100), lambda: load_oscillators(100, 100), lambda: load_oscillators(250, 250), load_gas_data, load_8proteins_data, load_k69_data ] timedata = [] for version, mbar_gen in mbar_gens.items(): for sysgen in systems: name, u_kn, N_k, s_n = sysgen() time0 = time.time()
else: Upot[k, l, 0:Neff[k]] = np.sum( beta * rfc[l, 0:R] * ((val[0:Neff[k], k, 0:R] - req[l, 0:R])**2), axis=1) val = [] prg = [100] for p in range(len(prg)): Nprg = Neff * prg[p] / 100 ## Test integers out only print "Running MBAR on %.0f percent of the data ... " % (prg[p]) mbar = pymbar.MBAR(Upot, Nprg, verbose=True, method='adaptive', initialize='BAR') print "Calculate Free Energy Differences Between States" [Deltaf, dDeltaf] = mbar.getFreeEnergyDifferences() min = np.argmin(Deltaf[0]) # Write to file print "Free Energy Differences (in units of kcal/mol)" print "%9s %8s %8s %12s %12s" % ('bin', 'f', 'df', 'deq', 'dfc') datfile = open('allsp-' + aur + '.%03.0f.dat' % prg[p], 'w') for k in range(K): if aur == 't' or aur == 'r' or aur == 'o' or aur == 'p' or aur == 'b' or aur == 'l': print "%10.5f %10.5f %10.5f %12.7f %12.7f" % (
# Initialize MBAR with Newton-Raphson if (n==0): # only print this information the first time print "" print "Initializing MBAR:" print "--K = number of Temperatures with data = %d" % (originalK) print "--L = number of total Temperatures = %d" % (K) print "--N = number of Energies per Temperature = %d" % (numpy.max(Nall_k)) # Use Adaptive Method (Both Newton-Raphson and Self-Consistent, testing which is better) if (n==0): initial_f_k = None # start from zero else: initial_f_k = mbar.f_k # start from the previous final free energies to speed convergence mbar = pymbar.MBAR(u_kln, Nall_k, verbose=False, relative_tolerance=1e-12, initial_f_k=initial_f_k) #------------------------------------------------------------------------ # Compute Expectations for E_kt and E2_kt as E_expect and E2_expect #------------------------------------------------------------------------ print "" print "Computing Expectations for E..." E_kln = u_kln # not a copy, we are going to write over it, but we don't need it any more. for k in range(K): E_kln[:,k,:]*=beta_k[k]**(-1) # get the 'unreduced' potential -- we can't take differences of reduced potentials because the beta is different. (E_expect, dE_expect) = mbar.computeExpectations(E_kln, state_dependent = True) #print(E_expect.shape) #print(Temp_k.shape) allE_expect[:,n] = E_expect[:] # expectations for the differences, which we need for numerical derivatives
else: # if the s matrix matches the data, find where there are nonzero entries km_list = [ ] # get list of locations of nonzero S for building probability distr for k in range(0, K): for m in range(0, M): if smat[k][m] != 0: km_list.append([k, m]) s = [smat[k][m] for k, m in km_list] # reformat matrix into a list else: s = [] if not s: # if s is empty/was not loaded properly, use pymbar to get apprx. free energies, then FS iterations for s # reduced potentials for pymbar u_kn = [[(U[i] - mu[j] * N[i]) / T[j] for i in range(0, sum(n))] for j in range(0, J)] mbar = pymbar.MBAR(u_kn, n) # perform MBAR method results = mbar.getFreeEnergyDifferences( ) # find free energy difference matrix f1 = [-i for i in results[0][0] ] # get negative differences relative to first state point # empty matrix with K rows, M columns for counts of observations c = [[0 for i in range(0, M)] for j in range(0, K)] f = f1.copy() # free energies from pymbar fnew = [0] * J # empty vector for iterations/error calculation # count (U,N) points in each bin for i in range(0, len(dat)): k = int((U[i] - U_min) / dU) m = int((N[i] - N_min) / dN)