Example #1
0
def test_parameters():
    """Test Yank parameters initialization."""

    # Check that both Yank and Repex parameters are accepted
    Yank(store_directory='test',
         restraint_type='harmonic',
         nsteps_per_iteration=1)
Example #2
0
def driver():
    # Initialize command-line argument parser.

    usage = """
    USAGE

    %prog --ligand_prmtop PRMTOP --receptor_prmtop PRMTOP { {--ligand_crd CRD | --ligand_mol2 MOL2} {--receptor_crd CRD | --receptor_pdb PDB} | {--complex_crd CRD | --complex_pdb PDB} } [-v | --verbose] [-i | --iterations ITERATIONS] [-o | --online] [-m | --mpi] [--restraints restraint-type] [--doctests] [--randomize_ligand]

    EXAMPLES

    # Specify AMBER prmtop/crd files for ligand and receptor.
    %prog --ligand_prmtop ligand.prmtop --receptor_prmtop receptor.prmtop --ligand_crd ligand.crd --receptor_crd receptor.crd --iterations 1000

    # Specify (potentially multi-conformer) mol2 file for ligand and (potentially multi-model) PDB file for receptor.
    %prog --ligand_prmtop ligand.prmtop --receptor_prmtop receptor.prmtop --ligand_mol2 ligand.mol2 --receptor_pdb receptor.pdb --iterations 1000

    # Specify (potentially multi-model) PDB file for complex, along with flat-bottom restraints (instead of harmonic).
    %prog --ligand_prmtop ligand.prmtop --receptor_prmtop receptor.prmtop --complex_pdb complex.pdb --iterations 1000 --restraints flat-bottom

    # Specify (potentially multi-model) PDB file for complex, along with flat-bottom restraints (instead of harmonic); randomize ligand positions/orientations at start.
    %prog --ligand_prmtop ligand.prmtop --receptor_prmtop receptor.prmtop --complex_pdb complex.pdb --iterations 1000 --restraints flat-bottom --randomize_ligand

    NOTES

    In atom ordering, receptor comes before ligand atoms.

    """

    # Parse command-line arguments.
    from optparse import OptionParser
    parser = OptionParser(usage=usage)
    parser.add_option("--ligand_prmtop", dest="ligand_prmtop_filename", default=None, help="ligand Amber parameter file", metavar="LIGAND_PRMTOP")
    parser.add_option("--receptor_prmtop", dest="receptor_prmtop_filename", default=None, help="receptor Amber parameter file", metavar="RECEPTOR_PRMTOP")    
    parser.add_option("--ligand_crd", dest="ligand_crd_filename", default=None, help="ligand Amber crd file", metavar="LIGAND_CRD")
    parser.add_option("--receptor_crd", dest="receptor_crd_filename", default=None, help="receptor Amber crd file", metavar="RECEPTOR_CRD")
    parser.add_option("--ligand_mol2", dest="ligand_mol2_filename", default=None, help="ligand mol2 file (can contain multiple conformations)", metavar="LIGAND_MOL2")
    parser.add_option("--receptor_pdb", dest="receptor_pdb_filename", default=None, help="receptor PDB file (can contain multiple MODELs)", metavar="RECEPTOR_PDB")
    parser.add_option("--complex_prmtop", dest="complex_prmtop_filename", default=None, help="complex Amber parameter file", metavar="COMPLEX_PRMTOP")
    parser.add_option("--complex_crd", dest="complex_crd_filename", default=None, help="complex Amber crd file", metavar="COMPLEX_CRD")
    parser.add_option("--complex_pdb", dest="complex_pdb_filename", default=None, help="complex PDB file (can contain multiple MODELs)", metavar="COMPLEX_PDB")
    parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="verbosity flag")
    parser.add_option("-i", "--iterations", dest="niterations", default=None, help="number of iterations", metavar="ITERATIONS")
    parser.add_option("-o", "--online", dest="online_analysis", default=False, help="perform online analysis")
    parser.add_option("-m", "--mpi", action="store_true", dest="mpi", default=False, help="use mpi if possible")
    parser.add_option("--restraints", dest="restraint_type", default=None, help="specify ligand restraint type: 'harmonic' or 'flat-bottom' (default: 'harmonic')")
    parser.add_option("--output", dest="output_directory", default=None, help="specify output directory---must be unique for each calculation (default: current directory)")
    parser.add_option("--doctests", action="store_true", dest="doctests", default=False, help="run doctests first (default: False)")
    parser.add_option("--randomize_ligand", action="store_true", dest="randomize_ligand", default=False, help="randomize ligand positions and orientations (default: False)")
    parser.add_option("--ignore_signal", action="append", dest="ignore_signals", default=[], help="signals to trap and ignore (default: None)")

    # Parse command-line arguments.
    (options, args) = parser.parse_args()
    
    if options.doctests:
        print "Running doctests for all modules..."
        import doctest
        # TODO: Test all modules
        import yank, oldrepex, alchemy, analyze, utils
        (failure_count, test_count) = doctest.testmod(verbose=options.verbose)
        if failure_count == 0:
            print "All doctests pass."
            sys.exit(0)
        else:
            print "WARNING: There were %d doctest failures." % failure_count
            sys.exit(1)

    # Check arguments for validity.
    if not (options.ligand_prmtop_filename and options.receptor_prmtop_filename):
        parser.error("ligand and receptor prmtop files must be specified")        
    if not (bool(options.ligand_mol2_filename) ^ bool(options.ligand_crd_filename) ^ bool(options.complex_pdb_filename) ^ bool(options.complex_crd_filename)):
        parser.error("Ligand coordinates must be specified through only one of --ligand_crd, --ligand_mol2, --complex_crd, or --complex_pdb.")
    if not (bool(options.receptor_pdb_filename) ^ bool(options.receptor_crd_filename) ^ bool(options.complex_pdb_filename) ^ bool(options.complex_crd_filename)):
        parser.error("Receptor coordinates must be specified through only one of --receptor_crd, --receptor_pdb, --complex_crd, or --complex_pdb.")    
    if not (options.complex_prmtop_filename):
        parser.error("Please specify --complex_prmtop [complex_prmtop_filename] argument.")

    # Initialize MPI if requested.
    if options.mpi:
        # Initialize MPI. 
        try:
            from mpi4py import MPI # MPI wrapper
            hostname = os.uname()[1]
            options.mpi = MPI.COMM_WORLD
            if not MPI.COMM_WORLD.rank == 0: 
                options.verbose = False
            MPI.COMM_WORLD.barrier()
            if MPI.COMM_WORLD.rank == 0: print "Initialized MPI on %d processes." % (MPI.COMM_WORLD.size)
        except Exception as e:
            print e
            parser.error("Could not initialize MPI.")

    # Select simulation parameters.
    # TODO: Allow user selection or intelligent automated selection of simulation parameters.
    # NOTE: Simulation paramters are hard-coded for now.
    # NOTE: Simulation parameters will be different for explicit solvent.
    import simtk.openmm.app as app
    nonbondedMethod = app.NoCutoff
    implicitSolvent = app.OBC2
    constraints = app.HBonds
    removeCMMotion = False

    # Create System objects for ligand and receptor.
    ligand_system = app.AmberPrmtopFile(options.ligand_prmtop_filename).createSystem(nonbondedMethod=nonbondedMethod, implicitSolvent=implicitSolvent, constraints=constraints, removeCMMotion=removeCMMotion)
    receptor_system = app.AmberPrmtopFile(options.receptor_prmtop_filename).createSystem(nonbondedMethod=nonbondedMethod, implicitSolvent=implicitSolvent, constraints=constraints, removeCMMotion=removeCMMotion)
    complex_system = app.AmberPrmtopFile(options.complex_prmtop_filename).createSystem(nonbondedMethod=nonbondedMethod, implicitSolvent=implicitSolvent, constraints=constraints, removeCMMotion=removeCMMotion)

    # Determine number of atoms for each system.
    natoms_receptor = receptor_system.getNumParticles()
    natoms_ligand = ligand_system.getNumParticles()
    natoms_complex = complex_system.getNumParticles()
    if (natoms_complex != natoms_ligand + natoms_receptor):
        raise Exception("Number of complex atoms must equal sum of ligand and receptor atoms.")

    # Read ligand and receptor coordinates.
    ligand_coordinates = list()
    receptor_coordinates = list()
    complex_coordinates = list()
    if (options.complex_crd_filename or options.complex_pdb_filename):
        # Read coordinates for whole complex.
        if options.complex_crd_filename:
            coordinates = read_amber_crd(options.complex_crd_filename, natoms_complex, options.verbose)
            complex_coordinates.append(coordinates)
        else:
            try:
                coordinates_list = read_openeye_crd(options.complex_pdb_filename, natoms_complex, options.verbose)
            except:
                coordinates_list = read_pdb_crd(options.complex_pdb_filename, natoms_complex, options.verbose)
            complex_coordinates += coordinates_list
    elif options.ligand_crd_filename:
        coordinates = read_amber_crd(options.ligand_crd_filename, natoms_ligand, options.verbose)
        coordinates = units.Quantity(numpy.array(coordinates / coordinates.unit), coordinates.unit)
        ligand_coordinates.append(coordinates)
    elif options.ligand_mol2_filename:
        coordinates_list = read_openeye_crd(options.ligand_mol2_filename, natoms_ligand, options.verbose)
        ligand_coordinates += coordinates_list
    elif options.receptor_crd_filename:
        coordinates = read_amber_crd(options.receptor_crd_filename, natoms_receptor, options.verbose)
        coordinates = units.Quantity(numpy.array(coordinates / coordinates.unit), coordinates.unit)
        receptor_coordinates.append(coordinates)
    elif options.receptor_pdb_filename:
        try:
            coordinates_list = read_openeye_crd(options.receptor_pdb_filename, natoms_receptor, options.verbose)
        except:
            coordinates_list = read_pdb_crd(options.receptor_pdb_filename, natoms_receptor, options.verbose)
        receptor_coordinates += coordinates_list

    # Assemble complex coordinates if we haven't read any.
    if len(complex_coordinates)==0:
        for x in receptor_coordinates:
            for y in ligand_coordinates:
                z = units.Quantity(numpy.zeros([natoms_complex,3]), units.angstroms)
                z[0:natoms_receptor,:] = x[:,:]
                z[natoms_receptor:natoms_complex,:] = y[:,:]
                complex_coordinates.append(z)

    # Initialize YANK object.
    from yank import Yank
    yank = Yank(receptor=receptor_system, ligand=ligand_system, complex=complex_system, complex_coordinates=complex_coordinates, output_directory=options.output_directory, verbose=options.verbose)

    # Configure YANK object with command-line parameter overrides.
    if options.niterations is not None:
        yank.niterations = int(options.niterations)
    if options.verbose:
        yank.verbose = options.verbose
    if options.online_analysis:
        yank.online_analysis = options.online_analysis
    if options.restraint_type is not None:
        yank.restraint_type = options.restraint_type
    if options.randomize_ligand:
        yank.randomize_ligand = True 

    # Hard-coded cpuid:gpuid for Exxact 4xGPU nodes
    # TODO: Replace this with something automated
    cpuid_gpuid_mapping = { 0:0, 1:1, 2:2, 3:3 } 
    ncpus_per_node = None

    # Run calculation.
    if options.mpi:
        # Run MPI version.
        yank.run_mpi(options.mpi, cpuid_gpuid_mapping=cpuid_gpuid_mapping, ncpus_per_node=ncpus_per_node)
    else:
        # Run serial version.
        yank.run()

    # Run analysis.
    results = yank.analyze()

    # Print/write results.
    print results
Example #3
0
    #receptor_system.addForce(force)

    # Create complex coordinates.
    import simtk.unit as units
    complex_coordinates = units.Quantity(numpy.zeros([2, 3], numpy.float64),
                                         units.angstroms)
    complex_coordinates[1, 0] = 10.0 * units.angstroms

    # Create temporary directory for testing.
    import tempfile
    output_directory = tempfile.mkdtemp()

    # Initialize YANK object.
    from yank import Yank
    yank = Yank(receptor=receptor_system,
                ligand=ligand_system,
                complex_coordinates=[complex_coordinates],
                output_directory=output_directory)
    yank.solvent_protocol = yank.vacuum_protocol
    yank.complex_protocol = yank.vacuum_protocol
    yank.restraint_type = 'flat-bottom'
    yank.temperature = temperature
    yank.niterations = 100
    yank.platform = openmm.Platform.getPlatformByName("Reference")

    # Run the simulation.
    yank.run()

    #
    # Analyze the data.
    #
Example #4
0
def notest_LennardJonesPair(box_width_nsigma=6.0):
    """
    Compute binding free energy of two Lennard-Jones particles and compare to numerical result.

    Parameters
    ----------
    box_width_nsigma : float, optional, default=6.0
        Box width is set to this multiple of Lennard-Jones sigma.

    """

    NSIGMA_MAX = 6.0  # number of standard errors tolerated for success

    # Create Lennard-Jones pair.
    thermodynamic_state = ThermodynamicState(temperature=300.0 * unit.kelvin)
    kT = kB * thermodynamic_state.temperature
    sigma = 3.5 * unit.angstroms
    epsilon = 6.0 * kT
    test = testsystems.LennardJonesPair(sigma=sigma, epsilon=epsilon)
    system, positions = test.system, test.positions
    binding_free_energy = test.get_binding_free_energy(thermodynamic_state)

    # Create temporary directory for testing.
    import tempfile
    store_dir = tempfile.mkdtemp()

    # Initialize YANK object.
    options = dict()
    options['restraint_type'] = None
    options['number_of_iterations'] = 10
    options['platform'] = openmm.Platform.getPlatformByName(
        "Reference")  # use Reference platform for speed
    options['mc_rotation'] = False
    options['mc_displacement'] = True
    options['mc_displacement_sigma'] = 1.0 * unit.nanometer
    options['timestep'] = 2 * unit.femtoseconds
    options['nsteps_per_iteration'] = 50

    # Override receptor mass to keep it stationary.
    #system.setParticleMass(0, 0)

    # Override box vectors.
    box_edge = 6 * sigma
    a = unit.Quantity((box_edge, 0 * unit.angstrom, 0 * unit.angstrom))
    b = unit.Quantity((0 * unit.angstrom, box_edge, 0 * unit.angstrom))
    c = unit.Quantity((0 * unit.angstrom, 0 * unit.angstrom, box_edge))
    system.setDefaultPeriodicBoxVectors(a, b, c)

    # Override positions
    positions[0, :] = box_edge / 2
    positions[1, :] = box_edge / 4

    phase = 'complex-explicit'

    # Alchemical protocol.
    from yank.alchemy import AlchemicalState
    alchemical_states = list()
    lambda_values = [0.0, 0.25, 0.50, 0.75, 1.0]
    for lambda_value in lambda_values:
        alchemical_state = AlchemicalState()
        alchemical_state['lambda_electrostatics'] = lambda_value
        alchemical_state['lambda_sterics'] = lambda_value
        alchemical_states.append(alchemical_state)
    protocols = dict()
    protocols[phase] = alchemical_states

    # Create phases.
    systems = {phase: system}
    positions = {phase: positions}
    phases = [phase]
    atom_indices = {'complex-explicit': {'ligand': [1]}}

    # Create new simulation.
    yank = Yank(store_dir, **options)
    yank.create(phases,
                systems,
                positions,
                atom_indices,
                thermodynamic_state,
                protocols=protocols)

    # Run the simulation.
    yank.run()

    # Analyze the data.
    results = yank.analyze()
    standard_state_correction = results[phase]['standard_state_correction']
    Delta_f = results[phase]['Delta_f_ij'][0, 1] - standard_state_correction
    dDelta_f = results[phase]['dDelta_f_ij'][0, 1]
    nsigma = abs(binding_free_energy / kT - Delta_f) / dDelta_f

    # Check results against analytical results.
    # TODO: Incorporate standard state correction
    output = "\n"
    output += "Analytical binding free energy                                  : %10.5f +- %10.5f kT\n" % (
        binding_free_energy / kT, 0)
    output += "Computed binding free energy (with standard state correction)   : %10.5f +- %10.5f kT (nsigma = %3.1f)\n" % (
        Delta_f, dDelta_f, nsigma)
    output += "Computed binding free energy (without standard state correction): %10.5f +- %10.5f kT (nsigma = %3.1f)\n" % (
        Delta_f + standard_state_correction, dDelta_f, nsigma)
    output += "Standard state correction alone                                 : %10.5f           kT\n" % (
        standard_state_correction)
    print output

    #if (nsigma > NSIGMA_MAX):
    #    output += "\n"
    #    output += "Computed binding free energy differs from true binding free energy.\n"
    #    raise Exception(output)

    return [Delta_f, dDelta_f]
Example #5
0
def test_unknown_parameters():
    """Test whether Yank raises exception on wrong initialization."""
    Yank(store_directory='test', wrong_parameter=False)
Example #6
0
def driver():
    # Initialize command-line argument parser.
    verbose = True
    usage = """
    USAGE

    %prog --ligand_prmtop PRMTOP --receptor_prmtop PRMTOP { {--ligand_crd CRD | --ligand_mol2 MOL2} {--receptor_crd CRD | --receptor_pdb PDB} | {--complex_crd CRD | --complex_pdb PDB} } [-v | --verbose] [-i | --iterations ITERATIONS] [-o | --online] [-m | --mpi] [--restraints restraint-type] [--doctests] [--randomize_ligand]

    EXAMPLES

    # Specify AMBER prmtop/crd files for ligand and receptor.
    %prog --ligand_prmtop ligand.prmtop --receptor_prmtop receptor.prmtop --ligand_crd ligand.crd --receptor_crd receptor.crd --iterations 1000

    # Specify (potentially multi-conformer) mol2 file for ligand and (potentially multi-model) PDB file for receptor.
    %prog --ligand_prmtop ligand.prmtop --receptor_prmtop receptor.prmtop --ligand_mol2 ligand.mol2 --receptor_pdb receptor.pdb --iterations 1000

    # Specify (potentially multi-model) PDB file for complex, along with flat-bottom restraints (instead of harmonic).
    %prog --ligand_prmtop ligand.prmtop --receptor_prmtop receptor.prmtop --complex_pdb complex.pdb --iterations 1000 --restraints flat-bottom

    # Specify (potentially multi-model) PDB file for complex, along with flat-bottom restraints (instead of harmonic); randomize ligand positions/orientations at start.
    %prog --ligand_prmtop ligand.prmtop --receptor_prmtop receptor.prmtop --complex_pdb complex.pdb --iterations 1000 --restraints flat-bottom --randomize_ligand

    NOTES

    In atom ordering, receptor comes before ligand atoms.

    """

    # Parse command-line arguments.
    from optparse import OptionParser
    parser = OptionParser(usage=usage)
    parser.add_option(
        "--ligand_mol2",
        dest="ligand_mol2_filename",
        default=None,
        help="ligand mol2 file (can contain multiple conformations)",
        metavar="LIGAND_MOL2")
    parser.add_option("--receptor_pdb",
                      dest="receptor_pdb_filename",
                      default=None,
                      help="receptor PDB file (can contain multiple MODELs)",
                      metavar="RECEPTOR_PDB")
    parser.add_option("--complex_pdb",
                      dest="complex_pdb_filename",
                      default=None,
                      help="complex PDB file (can contain multiple MODELs)",
                      metavar="COMPLEX_PDB")
    parser.add_option("-v",
                      "--verbose",
                      action="store_true",
                      dest="verbose",
                      default=False,
                      help="verbosity flag")
    parser.add_option("-i",
                      "--iterations",
                      dest="niterations",
                      default=None,
                      help="number of iterations",
                      metavar="ITERATIONS")
    parser.add_option("-o",
                      "--online",
                      dest="online_analysis",
                      default=False,
                      help="perform online analysis")
    parser.add_option("-m",
                      "--mpi",
                      action="store_true",
                      dest="mpi",
                      default=False,
                      help="use mpi if possible")
    parser.add_option(
        "--restraints",
        dest="restraint_type",
        default=None,
        help=
        "specify ligand restraint type: 'harmonic' or 'flat-bottom' (default: 'harmonic')"
    )
    parser.add_option(
        "--output",
        dest="output_directory",
        default=None,
        help=
        "specify output directory---must be unique for each calculation (default: current directory)"
    )
    parser.add_option("--doctests",
                      action="store_true",
                      dest="doctests",
                      default=False,
                      help="run doctests first (default: False)")
    parser.add_option(
        "--randomize_ligand",
        action="store_true",
        dest="randomize_ligand",
        default=False,
        help="randomize ligand positions and orientations (default: False)")
    parser.add_option("--ignore_signal",
                      action="append",
                      dest="ignore_signals",
                      default=[],
                      help="signals to trap and ignore (default: None)")
    parser.add_option("--platform",
                      dest="platform",
                      default="CPU",
                      help="The platform to use when running simulations")
    parser.add_option(
        "--gpus_per_node",
        dest="gpus_per_node",
        type='int',
        default=None,
        help=
        "number of GPUs per node to use for complex simulations during MPI calculations"
    )

    # Parse command-line arguments.
    (options, args) = parser.parse_args()

    if options.doctests:
        print "Running doctests for all modules..."
        import doctest
        # TODO: Test all modules
        import yank, oldrepex, alchemy, analyze, utils
        (failure_count, test_count) = doctest.testmod(verbose=options.verbose)
        if failure_count == 0:
            print "All doctests pass."
            sys.exit(0)
        else:
            print "WARNING: There were %d doctest failures." % failure_count
            sys.exit(1)

    # Check arguments for validity.
    if not (options.ligand_mol2_filename):
        parser.error("Please supply a ligand in mol2 format")
    if not (options.receptor_pdb_filename):
        parser.error("Please supply the receptor in pdb format")
    if not (options.complex_pdb_filename):
        print("Will combine ligand and receptor")

    # Initialize MPI if requested.
    if options.mpi:
        # Initialize MPI.
        try:
            from mpi4py import MPI  # MPI wrapper
            hostname = os.uname()[1]
            options.mpi = MPI.COMM_WORLD
            if not MPI.COMM_WORLD.rank == 0:
                options.verbose = False
            MPI.COMM_WORLD.barrier()
            if MPI.COMM_WORLD.rank == 0:
                print "Initialized MPI on %d processes." % (
                    MPI.COMM_WORLD.size)
        except Exception as e:
            print e
            parser.error("Could not initialize MPI.")

    # Select simulation parameters.
    # TODO: Allow user selection or intelligent automated selection of simulation parameters.
    # NOTE: Simulation paramters are hard-coded for now.
    # NOTE: Simulation parameters will be different for explicit solvent.
    import simtk.openmm.app as app
    nonbondedMethod = app.NoCutoff
    implicitSolvent = app.OBC2
    constraints = app.HBonds
    removeCMMotion = False

    #make ligand, receptor, complex objects
    ligand = Mol2SystemBuilder(options.ligand_mol2_filename, "ligand")
    receptor = BiomoleculePDBSystemBuilder(options.receptor_pdb_filename,
                                           "receptor")
    complex = ComplexSystemBuilder(ligand, receptor, "complex")

    # DEBUG: Write out ligand, receptor, and complex system objects.
    debug = False
    if debug:

        def write_file(outfile, contents):
            outfile = open(outfile, 'w')
            outfile.write(contents)
            outfile.close()

        for name in ['receptor', 'ligand', 'complex']:
            system = vars()[name].system
            serialized_system = system.__getstate__()
            filename = name + '.system.xml'
            print "Writing serialized %s to %s..." % (name, filename)
            write_file(filename, serialized_system)

    # Initialize YANK object.

    from yank import Yank
    yank = Yank(receptor=receptor.system,
                ligand=ligand.system,
                complex=complex.system,
                complex_positions=[complex.coordinates_as_quantity],
                output_directory=options.output_directory,
                verbose=options.verbose)

    # Configure YANK object with command-line parameter overrides.
    if options.niterations is not None:
        yank.niterations = int(options.niterations)
    if options.verbose:
        yank.verbose = options.verbose
    if options.online_analysis:
        yank.online_analysis = options.online_analysis
    if options.restraint_type is not None:
        yank.restraint_type = options.restraint_type
    if options.randomize_ligand:
        yank.randomize_ligand = True
    if options.platform:
        yank.platform = openmm.Platform.getPlatformByName(options.platform)

    # Hard-coded cpuid:gpuid for Exxact 4xGPU nodes
    # TODO: Replace this with something automated
# cpuid_gpuid_mapping = { 0:0, 1:1, 2:2, 3:3 }
#ncpus_per_node = None

# Run calculation.brbz
    if options.mpi:
        # Run MPI version.
        yank.run_mpi(options.mpi, options.gpus_per_node)
    else:
        # Run serial version.
        yank.run()

    # Run analysis.
    results = yank.analyze()

    # Print/write results.
    print results