コード例 #1
0
def set_matches(fname, libs, reslist, orphaned_res, mol, force=False):
    '''
    Find whether any units defined by a lib are required; if they are, update
    the liblist to include that lib and remove the units it defines from
    orphaned_res
    '''
    units = util.get_units(fname)
    matches = set(units).intersection(reslist)
    #TODO: make this work for prep and check bonds as well as atoms.
    #require that atom names and connectivity match before adding lib
    libatoms = []
    ext = os.path.splitext(fname)[-1][0:4]
    if ext != 'prep':
        with open(fname, 'r') as f:
            atomcopy = False
            for line in f:
                if line.startswith('!'):
                    if line.split()[0].split('.')[-1] == 'atoms':
                        atomcopy = True
                    else:
                        atomcopy = False
                elif atomcopy:
                    aname = line.split()[0].strip('"')
                    if not aname.startswith("H"):  #ignore hydrogen
                        libatoms.append(aname)
    molatoms = set([name.strip() for name in mol.mol_data['atomname']])

    if not set(libatoms).issubset(molatoms) or ext == 'prep' and not force:
        matches = set([])
        print(
            "Unit(s) %s defines atoms that differ from undefined residue: %s" %
            (' '.join(units), ' '.join(set(libatoms) - molatoms)))
    if matches:
        #redefine a unit iff found in a user-provided lib, but warn the user about the
        #duplication. don't redefine if found locally.
        if not matches.intersection(orphaned_res) and not force:
            print('Unit %s found in %s defined previously, \
            skipping to avoid redefinition\n' %
                  (' '.join(match for match in matches), fname))
        else:
            if not matches.intersection(orphaned_res):
                print('Unit %s found in %s defined previously, \
                adding user-provided lib but redefinition may cause problems\n' \
                % (' '.join(match for match in matches), fname))
            libs.add(fname)
            frcmod = util.get_base(fname) + '.frcmod'
            if os.path.isfile(frcmod):
                libs.add(frcmod)
            orphaned_res -= matches
コード例 #2
0
def do_antechamber(fname, net_charge, ff, molname, base=''):
    '''
    Run antechamber and get correctly named versions of the following: mol2
    with bcc charges, frcmod, lib, prmtop, inpcrd
    '''
    if not base: base = util.get_base(fname)
    ext = os.path.splitext(fname)[-1]
    ext = ext.lstrip('.')
    mol2 = base + '_amber.mol2'
    #TODO: known issues with phosphates (see PDB: 2PQC) when getting the net
    #charge from Gasteiger charges computed with Open Babel
    try:
        command = antechamber['-i', fname, '-fi', ext, '-o', mol2, '-fo',
                              'mol2', '-c', 'bcc', '-nc',
                              str(net_charge), '-s', '2']
        runfile.writeln(command)
        command()
    except Exception as e:
        passed = False
        charges = []
        if net_charge != 0:
            charges.append(0)
        if net_charge != -1:
            charges.append(-1)
        for charge in charges:
            try:
                command = antechamber['-i', fname, '-fi', ext, '-o', mol2,
                                      '-fo', 'mol2', '-c', 'bcc', '-nc',
                                      str(charge), '-s', '2']
                runfile.writeln(command)
                command()
                passed = True
                break
            except Exception as e:
                pass
        if not passed:
            print('Antechamber failed. Check {0} structure. Aborting...\n'.
                  format(fname))
            sys.exit()

    frcmod = base + '.frcmod'
    parmchk['-i', mol2, '-f', 'mol2', '-o', frcmod]()
    make_amber_parm(mol2, base, ff, molname=molname, frcmod=frcmod)
コード例 #3
0
    #pdb4amber seems to delete mercury (HG) along with hydrogens; for now my
    #hacky fix is to store the relevant atom info if mercury is present and add
    #the mercury back in after stripping...I'm preemptively doing this for
    #hafnium too
    metal_info = {}

    #if any structure was not provided in PDB format, we will attempt to create
    #one from what was provided using obabel, choosing a filename that will not
    #overwrite anything in the directory (optionally)
    for structure in args.structures:
        net_charge = None
        #the "structure" string in the args.structure list will be updated so
        #that it corresponds to the PDB we should use for subsequent steps
        assert os.path.isfile(structure), '%s does not exist\n' % structure
        #"base" is the base filename (no extension) from which others will be derived
        base = util.get_base(structure)
        ext = os.path.splitext(structure)[-1]
        if 'pdb' not in ext:
            #if it's a mol2, store the net_charge from the input because
            #conversion to a pdb and back to a mol2 with openbabel is not
            #guaranteed to result in the same partial charges
            if args.net_charge:
                net_charge = args.net_charge
            elif 'mol2' in ext:
                net_charge = util.get_charge(structure)
            outpdb = base + '.pdb'
            if not args.overwrite:
                outpdb = util.get_fname(outpdb)
            try:
                obabel[structure, '-O', outpdb, '-xn']()
            except Exception as e:
コード例 #4
0
def reparm(ligands, base):
    print(
        '**Running reparameterization of ligand(s) using open force fields\'s SMIRNOFF with openff 2.0.0**'
    )
    # Load already parm'd system
    in_prmtop = base + '.prmtop'
    in_crd = base + '.inpcrd'

    # Create parmed strucuture
    orig_structure = parmed.amber.AmberParm(in_prmtop, in_crd)

    # Split orig_stucuture into unique structure instances e.g. protein, water, ligand, etc.
    pieces = orig_structure.split()
    for piece in pieces:
        # TODO: Figure out how to know which piece is which
        print(f"There are {len(piece[1])} instance(s) of {piece[0]}")

    # Generate an openff topology for the ligand
    # Openff Molecule does not support mol2 so conversion is needed
    ligs_w_sdf = []
    for ligand in ligands:
        obabel[ligand[0], '-O', util.get_base(ligand[0]) + '.sdf']()
        ligs_w_sdf.append(
            (ligand[0], ligand[1], util.get_base(ligand[0]) + '.sdf'))

    # Keep track of ligands that were successfully reparmed so we know to skip them when putting the pieces back together
    reparmed_pieces = []
    complex_structure = parmed.Structure()
    force_field = ForceField("openff_unconstrained-2.0.0.offxml")

    for lig in ligs_w_sdf:
        # Set up openff topology
        ligand_off_molecule = Molecule(lig[2])
        ligand_pdbfile = PDBFile(lig[0])
        ligand_off_topology = Topology.from_openmm(
            ligand_pdbfile.topology,
            unique_molecules=[ligand_off_molecule],
        )
        # Parameterizing the ligand
        # Find ligand "piece", reparm, add to the new structure
        for piece in pieces:
            new_ligand_structure = None
            # TODO: Figure out how to know which piece is which
            if (ligand_off_molecule.n_atoms == len(piece[0].atoms)):
                if (ligand_off_molecule.n_bonds == len(piece[0].bonds)):
                    if ([
                            atom.atomic_number
                            for atom in ligand_off_molecule.atoms
                    ] == [atom.element for atom in piece[0].atoms]):
                        print('Found ligand piece', piece)
                        try:
                            # Since the method of matching the piece to ligand is imperfect, ligands that are isomers could mess things up.
                            # So try any piece that matches and see if we get an error
                            print('Reparameterizing ligand using SMIRNOFF')
                            ligand_system = force_field.create_openmm_system(
                                ligand_off_topology)
                            new_ligand_structure = parmed.openmm.load_topology(
                                ligand_off_topology.to_openmm(),
                                ligand_system,
                                xyz=piece[0].positions,
                            )
                            # A quick check to make sure things were not messed up during param
                            if check_discrepencies(new_ligand_structure,
                                                   piece):
                                # Add the newly parameterized ligand the complex structure
                                reparmed_pieces.append(piece)
                                new_ligand_structure *= len(piece[1])
                                complex_structure += parmed.amber.AmberParm.from_structure(
                                    new_ligand_structure)
                            break
                        except:
                            pass

    # Stick all the pieces back together
    for piece in pieces:
        if (piece not in reparmed_pieces):
            curr_structure = parmed.Structure()
            curr_structure += piece[0]
            curr_structure *= len(piece[1])
            complex_structure += parmed.amber.AmberParm.from_structure(
                curr_structure)

    # print("Unique atom names:",sorted(list({atom.atom_type.name for atom in complex_structure})),)
    # print("Number of unique atom types:", len({atom.atom_type for atom in complex_structure}))
    # print("Number of unique epsilons:", len({atom.epsilon for atom in complex_structure}))
    # print("Number of unique sigmas:", len({atom.sigma for atom in complex_structure}))

    # # Copy over the original coordinates and box vectors
    complex_structure.coordinates = orig_structure.coordinates
    complex_structure.box_vectors = orig_structure.box_vectors

    # Save the newly parameterized system
    complex_structure.save(base + ".prmtop", overwrite=True)
    complex_structure.save(base + ".inpcrd", overwrite=True)