def make_namd_from_pdb(pdb, psf, out_pdb): """ Creates charmm .pdb and .psf file. Can only make NAMD generate CHARMM topology files, not OPLS ones - that requires XPLOR but I don't care. Still, if OPLS topology files are provided - can still run. """ def is_non_water_hetatm(line): if not line.startswith("HETATM"): return False if line[17:20] != 'HOH': return True return False in_pdb = util.temp_fname('.pdb') txt = open(pdb, 'r').read() txt = pdbtext.strip_other_nmr_models(txt) txt = pdbtext.strip_lines(txt, is_non_water_hetatm) txt = pdbtext.strip_lines(txt, lambda l: l.startswith('ANISOU')) txt = pdbtext.strip_lines(txt, lambda l: l.startswith('CONECT')) txt = pdbtext.strip_lines(txt, lambda l: l.startswith('MASTER')) txt = pdbtext.strip_alternative_atoms(txt) txt = pdbtext.strip_hydrogens(txt) txt = pdbtext.renumber_residues(txt) f = open(in_pdb, 'w') f.write(txt) f.close() name = psf.replace('.psf', '') psfgen_in = name + ".psfgen.in" psfgen_out = name + ".psfgen.out" replace = { 'pdb': in_pdb, 'out_pdb': out_pdb, 'psf': psf, 'module_dir': module_dir, 'topology': 'parms/charmm22.topology' } template = _psfgen_template soup = Soup(in_pdb) chains = soup.chains() water_names = ['WAT', "TIP", "TIP3", "HOH"] waters = [chain for chain in chains if chain.n_residue() > 0 and chain.residue(0).type in water_names] chains = [chain for chain in chains if chain.n_residue() > 0 and chain.residue(0).type not in water_names] if len(waters) > 0: template = template.replace("# insert water", _water_psfgen_template) water_pdb = name + ".waters.pdb" water_soup = Soup() for water in waters: water_soup.insert_chain(water) water_soup.write_pdb(water_pdb) replace['water_pdb'] = water_pdb chains_template = "" for i, chain in enumerate(chains): id = 'ch%d' % i pdb = name + '.' + id + '.pdb' chain_soup = Soup() chain_soup.append_chain(chain) chain_soup.write_pdb(pdb) chain_replace = { 'chain_id': id, 'chain_pdb': pdb } chain_template = _chain_psfgen_template chains_template += util.replace_dict(chain_template, chain_replace) template = template.replace("# insert protein", chains_template) template = util.replace_dict(template, replace) open(psfgen_in, "w").write(template) os.system("psfgen %s > %s" % (psfgen_in, psfgen_out)) os.remove(in_pdb)
def convert_pdb_to_amber(pdb, top, crd, solvent_buffer=0.0): """Convert a .pdb file into amber .top and .crd file.""" script = "# generate %s and %s files from %s\n" % (top, crd, pdb) script += "\n" script += "# load in amber force field\n" script += "source leaprc.ff96\n" script += "\n" script += "# use AMBER6 GB radii for igb=1, gbparm=2\n" script += "set default PBradii amber6\n" # strip pdb and then load into soup bare_pdb = util.temp_fname('.pdb') txt = open(pdb, 'r').read() txt = pdbtext.strip_other_nmr_models(txt) txt = pdbtext.strip_lines(txt, lambda l: l.startswith('HETATM')) txt = pdbtext.strip_lines(txt, lambda l: l.startswith('ANISOU')) txt = pdbtext.strip_lines(txt, lambda l: l.startswith('CONECT')) txt = pdbtext.strip_lines(txt, lambda l: l.startswith('MASTER')) txt = pdbtext.strip_alternative_atoms(txt) txt = pdbtext.strip_hydrogens(txt) txt = pdbtext.renumber_residues(txt) open(bare_pdb, 'w').write(txt) soup = pdbstruct.Soup(bare_pdb) os.remove(bare_pdb) script += "\n" residues = [r.type for r in soup.residues()] if 'PHD' in residues: script += "\n" script += "# non-standard amino acid PHD" script += "source leaprc.gaff\n" script += "loadAmberPrep %s/parms/phd.prepin\n" % module_dir script += "loadAmberParams %s/parms/phd.frcmod\n" % module_dir for chain in soup.chains(): if isinstance(chain, pdbstruct.Protein): if not chain.is_capped(): chain.charge_c_end() in_pdb = pdb.replace('.pdb', '.tleap.pdb') soup.write_pdb(in_pdb) script += "\n" script += " # insert protein\n" script += "pdb = loadpdb %s\n" % in_pdb script += "check pdb\n" script += "\n" script += " # disulfide bonds\n" n = len(soup.residues()) for i in range(n): for j in range(i+1, n): if soup.residue(i).type in 'CYS' and soup.residue(j).type in 'CYS': p1 = soup.residue(i).atom('SG').pos p2 = soup.residue(j).atom('SG').pos if vector3d.pos_distance(p1, p2) < 3.0: soup.residue(i).type = 'CYX' for atom in soup.residue(i).atoms(): atom.res_type = 'CYX' soup.residue(j).type = 'CYX' for atom in soup.residue(j).atoms(): atom.res_type = 'CYX' script += "bond pdb.%d.SG pdb.%d.SG\n" % (i+1, j+1) soup.write_pdb(in_pdb) if solvent_buffer > 0.0: script += "\n" script += " # add explicit waters\n" script += "solvateBox pdb TIP3PBOX %f iso\n" % solvent_buffer script += "\n" script += "\n" script += " # write files\n" script += "saveAmberParm pdb %s %s\n" % (top, crd) script += "\n" script += "quit\n" script += "\n" name = crd.replace('.crd', '') tleap_in = name + ".tleap.in" open(tleap_in, "w").write(script) tleap_out = name + ".tleap.out" os.system("tleap -f %s > %s" % (tleap_in, tleap_out)) convert_amber_to_pdb(top, crd, name + '.pdb') os.remove("leap.log")