def dA_endpoint_MBAR(polymorphs='p1 p2', Molecules=72, Independent=4, Temp=200):
    # Setting constants
    kJ_to_kcal = 1/4.184  # Converting kJ to kcal
    kB = 0.0019872041  # boltzman constant in kcal/(mol*K)

    # Getting the polymorph names
    polymorphs = polymorphs.split()

    # Place to store the free energy differences
    dA = np.zeros(len(polymorphs))
    ddA = np.zeros(len(polymorphs))

    for i, poly in enumerate(polymorphs):
        if os.path.isfile(poly + '/interactions/100/PROD.edr') and os.path.isfile(poly + '/interactions/100/END.edr'):
            # Loading in the difference between the endpoint and production files
            dU = panedr.edr_to_df(poly + '/interactions/100/END.edr')['Potential'].values - panedr.edr_to_df(poly + '/interactions/100/PROD.edr')['Potential'].values

            # Converting the energy differences to go into pymbar
            dW = dU / Molecules * kJ_to_kcal / (kB * Temp)

            # Getting the energy differences with MBAR using Exponential Averaging
            da = np.array(pymbar.EXP(dW)) * kB * Temp

            dA[i] = -da[0]
            ddA[i] = da[1]
        else:
            dA[i] = np.nan
            ddA[i] = np.nan

    # Check to see if there are any nan values
    if np.any(dA == np.nan):
        dA[:] = 0.
        ddA[:] = 0.

    return dA, ddA
예제 #2
0
 def one_endpoint_perturbation(self):
     hybrid_reduced_potentials = np.array(
         self._lambda_one_reduced_potentials)
     nonalchemical_reduced_potentials = np.array(
         self._lambda_zero_reduced_potentials)
     [df, ddf] = pymbar.EXP(nonalchemical_reduced_potentials -
                            hybrid_reduced_potentials)
     return [df, ddf]
예제 #3
0
def calculate_cross_variance(all_results):
    """
    Calculates the overlap (df and ddf) between the non-alchemical state at lambda=0 to the hybrid state at lambda=1 and visa versa
    These ensembles are not expected to have good overlap, as they are of explicitly different system, but provides a benchmark of appropriate dissimilarity
    """
    if len(all_results) != 4:
        return
    else:
        non_a = all_results[0]
        hybrid_a = all_results[1]
        non_b = all_results[2]
        hybrid_b = all_results[3]
    print('CROSS VALIDATION')
    [df, ddf] = pymbar.EXP(non_a - hybrid_b)
    print('df: {}, ddf: {}'.format(df, ddf))
    [df, ddf] = pymbar.EXP(non_b - hybrid_a)
    print('df: {}, ddf: {}'.format(df, ddf))
    return
예제 #4
0
def run_endpoint_perturbation(lambda_thermodynamic_state,
                              nonalchemical_thermodynamic_state,
                              initial_hybrid_sampler_state,
                              mc_move,
                              n_iterations,
                              factory,
                              lambda_index=0,
                              print_work=False,
                              write_system=False,
                              write_state=False,
                              write_trajectories=False):
    """

    Parameters
    ----------
    lambda_thermodynamic_state : ThermodynamicState
        The thermodynamic state corresponding to the hybrid system at a lambda endpoint
    nonalchemical_thermodynamic_state : ThermodynamicState
        The nonalchemical thermodynamic state for the relevant endpoint
    initial_hybrid_sampler_state : SamplerState
        Starting positions for the sampler. Must be compatible with lambda_thermodynamic_state
    mc_move : MCMCMove
        The MCMove that will be used for sampling at the lambda endpoint
    n_iterations : int
        The number of iterations
    factory : HybridTopologyFactory
        The hybrid topology factory
    lambda_index : int, optional, default=0
        The index, 0 or 1, at which to retrieve nonalchemical positions
    print_work : bool, optional, default=False
        If True, will print work values
    write_system : bool, optional, default=False
        If True, will write alchemical and nonalchemical System XML files
    write_state : bool, optional, default=False
        If True, write alchemical (hybrid) State XML files each iteration
    write_trajectories : bool, optional, default=False
        If True, will write trajectories

    Returns
    -------
    df : float
        Free energy difference between alchemical and nonalchemical systems, estimated with EXP
    ddf : float
        Standard deviation of estimate, corrected for correlation, from EXP estimator.
    """
    import mdtraj as md

    #run an initial minimization:
    mcmc_sampler = mcmc.MCMCSampler(lambda_thermodynamic_state,
                                    initial_hybrid_sampler_state, mc_move)
    mcmc_sampler.minimize(max_iterations=20)
    new_sampler_state = mcmc_sampler.sampler_state

    if write_system:
        with open(f'hybrid{lambda_index}-system.xml', 'w') as outfile:
            outfile.write(
                openmm.XmlSerializer.serialize(
                    lambda_thermodynamic_state.system))
        with open(f'nonalchemical{lambda_index}-system.xml', 'w') as outfile:
            outfile.write(
                openmm.XmlSerializer.serialize(
                    nonalchemical_thermodynamic_state.system))

    #initialize work array
    w = np.zeros([n_iterations])
    non_potential = np.zeros([n_iterations])
    hybrid_potential = np.zeros([n_iterations])

    #run n_iterations of the endpoint perturbation:
    hybrid_trajectory = unit.Quantity(
        np.zeros([
            n_iterations,
            lambda_thermodynamic_state.system.getNumParticles(), 3
        ]), unit.nanometers)  # DEBUG
    nonalchemical_trajectory = unit.Quantity(
        np.zeros([
            n_iterations,
            nonalchemical_thermodynamic_state.system.getNumParticles(), 3
        ]), unit.nanometers)  # DEBUG
    for iteration in range(n_iterations):
        # Generate a new sampler state for the hybrid system
        mc_move.apply(lambda_thermodynamic_state, new_sampler_state)

        # Compute the hybrid reduced potential at the new sampler state
        hybrid_context, integrator = cache.global_context_cache.get_context(
            lambda_thermodynamic_state)
        new_sampler_state.apply_to_context(hybrid_context,
                                           ignore_velocities=True)
        hybrid_reduced_potential = lambda_thermodynamic_state.reduced_potential(
            hybrid_context)

        if write_state:
            state = hybrid_context.getState(getPositions=True,
                                            getParameters=True)
            state_xml = openmm.XmlSerializer.serialize(state)
            with open(f'state{iteration}_l{lambda_index}.xml', 'w') as outfile:
                outfile.write(state_xml)

        # Construct a sampler state for the nonalchemical system
        if lambda_index == 0:
            nonalchemical_positions = factory.old_positions(
                new_sampler_state.positions)
        elif lambda_index == 1:
            nonalchemical_positions = factory.new_positions(
                new_sampler_state.positions)
        else:
            raise ValueError(
                "The lambda index needs to be either one or zero for this to be meaningful"
            )
        nonalchemical_sampler_state = SamplerState(
            nonalchemical_positions, box_vectors=new_sampler_state.box_vectors)

        if write_trajectories:
            state = hybrid_context.getState(getPositions=True)
            hybrid_trajectory[iteration, :, :] = state.getPositions(
                asNumpy=True)
            nonalchemical_trajectory[iteration, :, :] = nonalchemical_positions

        # Compute the nonalchemical reduced potential
        nonalchemical_context, integrator = cache.global_context_cache.get_context(
            nonalchemical_thermodynamic_state)
        nonalchemical_sampler_state.apply_to_context(nonalchemical_context,
                                                     ignore_velocities=True)
        nonalchemical_reduced_potential = nonalchemical_thermodynamic_state.reduced_potential(
            nonalchemical_context)

        # Compute and store the work
        w[iteration] = nonalchemical_reduced_potential - hybrid_reduced_potential
        non_potential[iteration] = nonalchemical_reduced_potential
        hybrid_potential[iteration] = hybrid_reduced_potential

        if print_work:
            print(
                f'{iteration:8d} {hybrid_reduced_potential:8.3f} {nonalchemical_reduced_potential:8.3f} => {w[iteration]:8.3f}'
            )

    if write_trajectories:
        if lambda_index == 0:
            nonalchemical_mdtraj_topology = md.Topology.from_openmm(
                factory._topology_proposal.old_topology)
        elif lambda_index == 1:
            nonalchemical_mdtraj_topology = md.Topology.from_openmm(
                factory._topology_proposal.new_topology)
        md.Trajectory(
            hybrid_trajectory / unit.nanometers,
            factory.hybrid_topology).save(f'hybrid{lambda_index}.pdb')
        md.Trajectory(nonalchemical_trajectory / unit.nanometers,
                      nonalchemical_mdtraj_topology).save(
                          f'nonalchemical{lambda_index}.pdb')

    # Analyze data and return results
    [t0, g, Neff_max] = timeseries.detectEquilibration(w)
    w_burned_in = w[t0:]
    [df, ddf] = pymbar.EXP(w_burned_in)
    ddf_corrected = ddf * np.sqrt(g)
    results = [df, ddf_corrected, t0, Neff_max]

    return results, non_potential, hybrid_potential
예제 #5
0
        fname = 'graph' + str(i) + 'to' + str(j) + '.pdf'
        plt.savefig(fname)

N_k = npoints*np.ones([nstates],int)

mbar = pymbar.MBAR(u_kln,N_k,relative_tolerance=1.0e-10,verbose=True)
(Delta_f_ij_estimated, dDelta_f_ij_estimated) = mbar.getFreeEnergyDifferences()
print Delta_f_ij_estimated
print dDelta_f_ij_estimated

# check these in the case of two.
# try exponential averaging, to see if there is a difference. Seems to work.

if len(dirnames) == 2:
    wf = -(u_kln[0,1:,]-u_kln[0,0,:])
    (df_forward,ddf_forward) = pymbar.EXP(wf)
    print('EXP forward %10.4f +/- %7.4f' % (df_forward, ddf_forward))
    wr = -(u_kln[1,1:,]-u_kln[1,0,:])
    (df_rev, ddf_rev) = pymbar.EXP(wr)
    print('EXP reverse %10.4f +/- %7.4f' % (df_rev, ddf_rev))
    
    pdb.set_trace()
    
    (df_bar, ddf_bar) = pymbar.BAR(-wf,wr)
    print('BAR reverse %10.4f +/- %7.4f' % (-df_bar, ddf_bar))
    
    # plots the overlap in energy betwen two.  Looks good!
    if plot:
        plt.clf()
        plt.hist(wf.T, facecolor='red')
        plt.hist(wr.T, facecolor='blue')
예제 #6
0
def run_endpoint_perturbation(lambda_thermodynamic_state,
                              nonalchemical_thermodynamic_state,
                              initial_hybrid_sampler_state,
                              mc_move,
                              n_iterations,
                              factory,
                              lambda_index=0):
    """

    Parameters
    ----------
    lambda_thermodynamic_state : ThermodynamicState
        The thermodynamic state corresponding to the hybrid system at a lambda endpoint
    nonalchemical_thermodynamic_state : ThermodynamicState
        The nonalchemical thermodynamic state for the relevant endpoint
    initial_hybrid_sampler_state : SamplerState
        Starting positions for the sampler. Must be compatible with lambda_thermodynamic_state
    mc_move : MCMCMove
        The MCMove that will be used for sampling at the lambda endpoint
    n_iterations : int
        The number of iterations
    factory : HybridTopologyFactory
        The hybrid topology factory
    lambda_index : int, optional default 0
        The index, 0 or 1, at which to retrieve nonalchemical positions

    Returns
    -------
    df : float
        Free energy difference between alchemical and nonalchemical systems, estimated with EXP
    ddf : float
        Standard deviation of estimate, corrected for correlation, from EXP estimator.
    """
    #run an initial minimization:
    mcmc_sampler = mcmc.MCMCSampler(lambda_thermodynamic_state,
                                    initial_hybrid_sampler_state, mc_move)
    mcmc_sampler.minimize(max_iterations=20)
    new_sampler_state = mcmc_sampler.sampler_state

    #initialize work array
    w = np.zeros([n_iterations])

    #run n_iterations of the endpoint perturbation:
    for iteration in range(n_iterations):
        mc_move.apply(lambda_thermodynamic_state, new_sampler_state)

        #compute the reduced potential at the new state
        hybrid_context, integrator = cache.global_context_cache.get_context(
            lambda_thermodynamic_state)
        new_sampler_state.apply_to_context(hybrid_context,
                                           ignore_velocities=True)
        hybrid_reduced_potential = lambda_thermodynamic_state.reduced_potential(
            hybrid_context)

        #generate a sampler state for the nonalchemical system
        if lambda_index == 0:
            nonalchemical_positions = factory.old_positions(
                new_sampler_state.positions)
        elif lambda_index == 1:
            nonalchemical_positions = factory.new_positions(
                new_sampler_state.positions)
        else:
            raise ValueError(
                "The lambda index needs to be either one or zero for this to be meaningful"
            )

        nonalchemical_sampler_state = SamplerState(
            nonalchemical_positions, box_vectors=new_sampler_state.box_vectors)

        #compute the reduced potential at the nonalchemical system as well:
        nonalchemical_context, integrator = cache.global_context_cache.get_context(
            nonalchemical_thermodynamic_state)
        nonalchemical_sampler_state.apply_to_context(nonalchemical_context,
                                                     ignore_velocities=True)
        nonalchemical_reduced_potential = nonalchemical_thermodynamic_state.reduced_potential(
            nonalchemical_context)

        w[iteration] = nonalchemical_reduced_potential - hybrid_reduced_potential

    [t0, g, Neff_max] = timeseries.detectEquilibration(w)
    print(Neff_max)
    w_burned_in = w[t0:]

    [df, ddf] = pymbar.EXP(w_burned_in)
    ddf_corrected = ddf * np.sqrt(g)

    return [df, ddf_corrected, Neff_max]