def hydrate(system, opt): """ This function solvates the system by using PDBFixer Parameters: ----------- system: OEMol molecule The system to solvate opt: python dictionary The parameters used to solvate the system Return: ------- oe_mol: OEMol The solvated system """ def BoundingBox(molecule): """ This function calculates the Bounding Box of the passed molecule molecule: OEMol return: bb (numpy array) the calculated bounding box is returned as numpy array: [(xmin,ymin,zmin), (xmax,ymax,zmax)] """ coords = [v for k, v in molecule.GetCoords().items()] np_coords = np.array(coords) min_coord = np_coords.min(axis=0) max_coord = np_coords.max(axis=0) bb = np.array([min_coord, max_coord]) return bb # Create a system copy sol_system = system.CreateCopy() # Calculate system BoundingBox (Angstrom units) BB = BoundingBox(sol_system) # Estimation of the box cube length in A box_edge = 2.0 * opt['solvent_padding'] + np.max(BB[1] - BB[0]) # BB center xc = (BB[0][0]+BB[1][0])/2. yc = (BB[0][1]+BB[1][1])/2. zc = (BB[0][2]+BB[1][2])/2. delta = np.array([box_edge/2., box_edge/2., box_edge/2.]) - np.array([xc, yc, zc]) sys_coord_dic = {k: (v+delta) for k, v in sol_system.GetCoords().items()} sol_system.SetCoords(sys_coord_dic) # Load a fake system to initialize PDBfixer filename = resource_filename('pdbfixer', 'tests/data/test.pdb') fixer = PDBFixer(filename=filename) # Convert between OE and OpenMM topology omm_top, omm_pos = oeommutils.oemol_to_openmmTop(sol_system) chain_names = [] for chain in omm_top.chains(): chain_names.append(chain.id) # Set the correct topology to the fake system fixer.topology = omm_top fixer.positions = omm_pos # Solvate the system fixer.addSolvent(padding=unit.Quantity(opt['solvent_padding'], unit.angstroms), ionicStrength=unit.Quantity(opt['salt_concentration'], unit.millimolar)) # The OpenMM topology produced by the solvation fixer has missing bond # orders and aromaticity. The following section is creating a new openmm # topology made of just water molecules and ions. The new topology is then # converted in an OEMol and added to the passed molecule to produce the # solvated system wat_ion_top = app.Topology() # Atom dictionary between the the PDBfixer topology and the water_ion topology fixer_atom_to_wat_ion_atom = {} for chain in fixer.topology.chains(): if chain.id not in chain_names: n_chain = wat_ion_top.addChain(chain.id) for res in chain.residues(): n_res = wat_ion_top.addResidue(res.name, n_chain) for at in res.atoms(): n_at = wat_ion_top.addAtom(at.name, at.element, n_res) fixer_atom_to_wat_ion_atom[at] = n_at for bond in fixer.topology.bonds(): at0 = bond[0] at1 = bond[1] try: wat_ion_top.addBond(fixer_atom_to_wat_ion_atom[at0], fixer_atom_to_wat_ion_atom[at1], type=None, order=1) except: pass wat_ion_pos = fixer.positions[len(omm_pos):] oe_mol = oeommutils.openmmTop_to_oemol(wat_ion_top, wat_ion_pos) # Setting the box vectors omm_box_vectors = fixer.topology.getPeriodicBoxVectors() box_vectors = utils.PackageOEMol.encodePyObj(omm_box_vectors) oe_mol.SetData(oechem.OEGetTag('box_vectors'), box_vectors) oechem.OEAddMols(oe_mol, sol_system) return oe_mol
# # This is basically the pdbfixer code, but without the amber lines. # modeller = Modeller(fixer.topology, fixer.positions) forcefield = ForceField('amber99sb.xml', 'tip5p.xml') system = forcefield.createSystem(fixer.topology, nonbondedMethod=PME, nonbondedCutoff=0.05 * nanometer, constraints=HBonds) modeller.addSolvent(forcefield, padding=0.05 * nanometer, boxSize=None, boxVectors=None) #modeller.addSolvent(forcefield, padding=0.4*nanometer, boxSize, boxVectors=boxVectors, model='tip5p') # modeller.addSolvent(forcefield, padding=padding, boxSize=boxSize, boxVectors=boxVectors, positiveIon=positiveIon, negativeIon=negativeIon, ionicStrength=ionicStrength) fixer.topology = modeller.topology fixer.positions = modeller.positions proatoms = [atom.element._symbol for atom in modeller.topology.atoms()] procoords = np.array( [fixer.positions[atom.index]._value for atom in modeller.topology.atoms()]) def WriteXYZfile(atoms, coords, nm_="out.xyz"): natom = len(atoms) f = open(nm_, "w") f.write(str(natom) + "\n" + "\n") for i in range(natom): f.write(atoms[i] + " " + str(coords[i][0]) + " " + str(coords[i][1]) + " " + str(coords[i][2]) + "\n")
def solvate(system, opt): """ This function solvates the system by using PDBFixer Parameters: ----------- system: OEMol molecule The system to solvate opt: python dictionary The parameters used to solvate the system Return: ------- oe_mol: OEMol The solvated system """ # Load a fake system to initialize PDBfixer filename = resource_filename('pdbfixer', 'tests/data/test.pdb') fixer = PDBFixer(filename=filename) # Convert between OE and OpenMM topology omm_top, omm_pos = oeommutils.oemol_to_openmmTop(system) chain_names = [] for chain in omm_top.chains(): chain_names.append(chain.id) # Set the correct topology to the fake system fixer.topology = omm_top fixer.positions = omm_pos # Solvate the system fixer.addSolvent(padding=unit.Quantity(opt['solvent_padding'], unit.angstroms), ionicStrength=unit.Quantity(opt['salt_concentration'], unit.millimolar)) # The OpenMM topology produced by the solvation fixer has missing bond # orders and aromaticity. The following section is creating a new openmm # topology made of just water molecules and ions. The new topology is then # converted in an OEMol and added to the passed molecule to produce the # solvated system wat_ion_top = app.Topology() # Atom dictionary between the the PDBfixer topology and the water_ion topology fixer_atom_to_wat_ion_atom = {} for chain in fixer.topology.chains(): if chain.id not in chain_names: n_chain = wat_ion_top.addChain(chain.id) for res in chain.residues(): n_res = wat_ion_top.addResidue(res.name, n_chain) for at in res.atoms(): n_at = wat_ion_top.addAtom(at.name, at.element, n_res) fixer_atom_to_wat_ion_atom[at] = n_at for bond in fixer.topology.bonds(): at0 = bond[0] at1 = bond[1] try: wat_ion_top.addBond(fixer_atom_to_wat_ion_atom[at0], fixer_atom_to_wat_ion_atom[at1], type=None, order=1) except: pass wat_ion_pos = fixer.positions[len(omm_pos):] oe_mol = oeommutils.openmmTop_to_oemol(wat_ion_top, wat_ion_pos) # Setting the box vectors omm_box_vectors = fixer.topology.getPeriodicBoxVectors() box_vectors = utils.PackageOEMol.encodePyObj(omm_box_vectors) oe_mol.SetData(oechem.OEGetTag('box_vectors'), box_vectors) oechem.OEAddMols(oe_mol, system) return oe_mol