def test_entity_reset(self): eh=mol.CreateEntity() eh2=mol.CreateEntity() go=gfx.Entity("foo",eh) go.Reset(eh) go.Reset("rnum=1") go.Reset(entity=eh2) go.Reset(eh.Select("rnum=2")) go.Reset(eh,"rnum=3",mol.MATCH_RESIDUES) go.Reset("rnum=4",eh2)
def test_CBeta(self): # test if the dst residues contain cbeta, unless they are glycines tpl = io.LoadPDB('testfiles/cbeta.pdb') new_hdl = mol.CreateEntity() ed = new_hdl.EditXCS() c = ed.InsertChain('A') ed.AppendResidue(c, 'MET') ed.AppendResidue(c, 'GLY') ed.AppendResidue(c, 'GLY') ed.AppendResidue(c, 'HIS') err, has_cbeta = mol.alg.CopyConserved(tpl.residues[0], new_hdl.residues[0], ed) self.assertTrue(has_cbeta) self.assertTrue(err) err, has_cbeta = mol.alg.CopyConserved(tpl.residues[1], new_hdl.residues[1], ed) self.assertFalse(has_cbeta) self.assertTrue(err) err, has_cbeta = mol.alg.CopyConserved(tpl.residues[2], new_hdl.residues[2], ed) self.assertFalse(has_cbeta) self.assertTrue(err) err, has_cbeta = mol.alg.CopyConserved(tpl.residues[3], new_hdl.residues[3], ed) self.assertTrue(has_cbeta) self.assertTrue(err) residues = new_hdl.residues self.assertEqual(len(residues), 4) self.assertTrue(residues[0].FindAtom("CB").IsValid()) self.assertFalse(residues[1].FindAtom("CB").IsValid()) self.assertFalse(residues[2].FindAtom("CB").IsValid()) self.assertTrue(residues[3].FindAtom("CB").IsValid())
def test_CopyResidue(self): tpl = io.LoadPDB('testfiles/cbeta.pdb') new_hdl = mol.CreateEntity() ed = new_hdl.EditXCS() c = ed.InsertChain('A') ed.AppendResidue(c, 'MET') ed.AppendResidue(c, 'GLY') ed.AppendResidue(c, 'GLY') ed.AppendResidue(c, 'HIS') ed.AppendResidue(c, 'HIS') ed.AppendResidue(c, 'GLY') ed.AppendResidue(c, 'HIS') ed.AppendResidue(c, 'MET') # MET to MET err = mol.alg.CopyResidue(tpl.residues[0], new_hdl.residues[0], ed) self.assertTrue(err) #GLY to GLY err = mol.alg.CopyResidue(tpl.residues[1], new_hdl.residues[1], ed) self.assertTrue(err) # GLY to GLY err = mol.alg.CopyResidue(tpl.residues[2], new_hdl.residues[2], ed) self.assertTrue(err) #now we copy a HIS to a HIS err = mol.alg.CopyResidue(tpl.residues[3], new_hdl.residues[3], ed) self.assertTrue(err) # copy a GLY to a HIS err, has_cbeta = mol.alg.CopyNonConserved(tpl.residues[1], new_hdl.residues[4], ed) self.assertFalse(has_cbeta) # copy a MET to a GLY err = mol.alg.CopyResidue(tpl.residues[0], new_hdl.residues[5], ed) self.assertFalse(err) # copy a MET to a HIS err = mol.alg.CopyResidue(tpl.residues[0], new_hdl.residues[6], ed) self.assertFalse(err) # copy a GLY to a MET with adding CB err = mol.alg.CopyResidue(tpl.residues[1], new_hdl.residues[7], ed) self.assertFalse(err) residues = new_hdl.residues self.assertEqual(len(residues), 8) # MET to MET self.assertTrue(residues[0].FindAtom("CB").IsValid()) #GLY to GLY self.assertFalse(residues[1].FindAtom("CB").IsValid()) #now we copy a GLY to a GLY self.assertFalse(residues[2].FindAtom("CB").IsValid()) #now we copy a HIS to a HIS self.assertTrue(residues[3].FindAtom("CB").IsValid()) #now we copy a GLY to a HIS without adding CB self.assertFalse(residues[4].FindAtom("CB").IsValid()) #now we copy a MET to a GLY self.assertFalse(residues[5].FindAtom("CB").IsValid()) # copy a MET to a HIS self.assertTrue(residues[6].FindAtom("CB").IsValid()) # copy a GLY to a MET with adding CB self.assertTrue(residues[7].FindAtom("CB").IsValid())
def _ParseModifiedPDB(filename): """Read mpdb file produced by antechamber and return tuple of: - EntityHandle with connectivity, atom types (property 'type') and charges - Residue name as extracted from the mpdb file A RuntimeError is raised if the file can contains multiple residues. """ eh = mol.CreateEntity() rname = '' edi = eh.EditXCS(mol.BUFFERED_EDIT) chain = edi.InsertChain('A') bond_list = [] # get all atoms and bonds from file with open(filename, 'r') as in_file: for line in in_file: # atom or connectivity # -> fixed column format assumed for both if line.startswith('ATOM'): aname = line[12:17].strip() # extract res. name and ensure uniqueness if not rname: rname = line[17:20].strip() r = edi.AppendResidue(chain, rname) elif rname != line[17:20].strip(): raise RuntimeError("More than one residue in file " + filename +\ ". Cannot parse!") # extract and store type and charge charge = float(line[54:66]) atype = line[78:80].strip() a = edi.InsertAtom(r, aname, geom.Vec3()) a.SetStringProp('type', atype) a.SetCharge(charge) elif line.startswith('CONECT'): ai1 = int(line[6:11]) # max. 4 bond partners... for i in range(4): try: j = 11 + 5 * i ai2 = int(line[j:j + 5]) # only unique bonds added to list s = set([ai1, ai2]) if not s in bond_list: bond_list.append(s) except: # exception thrown for empty strings or non-integers # -> skip continue # set all bonds in entity for indices in bond_list: indices = list(indices) a1 = r.atoms[indices[0] - 1] a2 = r.atoms[indices[1] - 1] edi.Connect(a1, a2) # finalize edi.UpdateICS() return eh, rname
def testPyWrap(self): class MyProc(conop.Processor): def __init__(self): conop.Processor.__init__(self) self.count =0 def DoProcess(self, diag, ent): self.count+=1 p = MyProc() ent = mol.CreateEntity() p.Process(ent) self.assertEqual(p.count, 1)
def test_(self): if not has_numpy: return entity = mol.CreateEntity() ed = entity.EditXCS() ch = ed.InsertChain("X") re = ed.AppendResidue(ch, "ALA") a0 = ed.InsertAtom(re, "A", geom.Vec3(0, 0, 0)) self.assertEqual(a0.GetIndex(), 0) a1 = ed.InsertAtom(re, "B", geom.Vec3(1, 0, 0)) self.assertEqual(a1.GetIndex(), 1) a2 = ed.InsertAtom(re, "C", geom.Vec3(2, 0, 0)) self.assertEqual(a2.GetIndex(), 2) a3 = ed.InsertAtom(re, "D", geom.Vec3(3, 0, 0)) self.assertEqual(a3.GetIndex(), 3) self.assertTrue(dd(a0.pos, geom.Vec3(0, 0, 0))) self.assertTrue(dd(a1.pos, geom.Vec3(1, 0, 0))) self.assertTrue(dd(a2.pos, geom.Vec3(2, 0, 0))) self.assertTrue(dd(a3.pos, geom.Vec3(3, 0, 0))) ed.SetAtomTransformedPos( entity.GetAtomList(), numpy.array([[0, 1, 0], [0, 2, 0], [0, 3, 0], [0, 4, 0]], dtype=numpy.float32)) self.assertTrue(dd(a0.pos, geom.Vec3(0, 1, 0))) self.assertTrue(dd(a1.pos, geom.Vec3(0, 2, 0))) self.assertTrue(dd(a2.pos, geom.Vec3(0, 3, 0))) self.assertTrue(dd(a3.pos, geom.Vec3(0, 4, 0))) na = entity.positions self.assertTrue(dd(v2v(na[0]), geom.Vec3(0, 1, 0))) self.assertTrue(dd(v2v(na[1]), geom.Vec3(0, 2, 0))) self.assertTrue(dd(v2v(na[2]), geom.Vec3(0, 3, 0))) self.assertTrue(dd(v2v(na[3]), geom.Vec3(0, 4, 0))) ed.SetAtomTransformedPos([3, 99, 2], numpy.array( [[0, 0, -3], [-1, -1, -1], [0, 0, -2]], dtype=numpy.float32)) self.assertTrue(dd(a0.pos, geom.Vec3(0, 1, 0))) self.assertTrue(dd(a1.pos, geom.Vec3(0, 2, 0))) self.assertTrue(dd(a2.pos, geom.Vec3(0, 0, -2))) self.assertTrue(dd(a3.pos, geom.Vec3(0, 0, -3)))
def test_starts_from_last_water_rnum(self): m = mol.CreateEntity() e = m.EditXCS(mol.BUFFERED_EDIT) c = e.InsertChain("A") e.SetChainType(c, mol.CHAINTYPE_WATER) e.AppendResidue(c, "HOH") pdbizer = mol.alg.PDBize() transformations = geom.Mat4List() transformations.append(geom.Mat4()) seqs = seq.CreateSequenceList() pdbizer.Add(m.Select(''), transformations, seqs) pdbizer.Add(m.Select(''), transformations, seqs) pdbized = pdbizer.Finish() self.assertEqual([c.name for c in pdbized.chains], ["-"]) residues = pdbized.residues self.assertEqual( [r.number for r in residues], [mol.ResNum(1, 'A'), mol.ResNum(1, 'B')])
def test_CBetaFail(self): # make sure that we can handle cases where CB reconstruction fails # NOTES: # - SNN is (since June 2011) labeled as a modified ASN but has a weird # backbone structure without any overlap in atom names with ASN # -> we hence expect it to a) always fall back to CopyNonConserved # and b) fail to copy any atoms (and hence also fail to) # - SNN also removes N of following residue which is expected to have an # incomplete backbone which would make it impossible to create a CB pos. # source of file: residues A.198 and A.199 from PDB ID 2YHW tpl = io.LoadPDB('testfiles/cbeta_fail.pdb') new_hdl = mol.CreateEntity() ed = new_hdl.EditXCS() c = ed.InsertChain('A') ed.AppendResidue(c, 'GLY') ed.AppendResidue(c, 'ALA') ed.AppendResidue(c, 'ASN') ed.AppendResidue(c, 'GLY') ed.AppendResidue(c, 'ALA') # SNN to GLY err = mol.alg.CopyResidue(tpl.residues[0], new_hdl.residues[0], ed) self.assertFalse(err) self.assertEqual(new_hdl.residues[0].atom_count, 0) # SNN to ALA err = mol.alg.CopyResidue(tpl.residues[0], new_hdl.residues[1], ed) self.assertFalse(err) self.assertEqual(new_hdl.residues[1].atom_count, 0) # SNN to ASN err = mol.alg.CopyResidue(tpl.residues[0], new_hdl.residues[2], ed) self.assertFalse(err) self.assertEqual(new_hdl.residues[2].atom_count, 0) # GLY to GLY err = mol.alg.CopyResidue(tpl.residues[1], new_hdl.residues[3], ed) self.assertTrue(err) self.assertEqual(new_hdl.residues[3].atom_count, 3) self.assertFalse(new_hdl.residues[3].FindAtom("CB").IsValid()) # GLY to ALA err = mol.alg.CopyResidue(tpl.residues[1], new_hdl.residues[4], ed) self.assertFalse(err) self.assertEqual(new_hdl.residues[4].atom_count, 3) self.assertFalse(new_hdl.residues[4].FindAtom("CB").IsValid())
def test_numbers_water_molecules_with_ins_codes(self): m = mol.CreateEntity() e = m.EditXCS(mol.BUFFERED_EDIT) c = e.InsertChain("A") e.SetChainType(c, mol.CHAINTYPE_WATER) for i in range(27): e.AppendResidue(c, "HOH") pdbizer = mol.alg.PDBize() transformations = geom.Mat4List() transformations.append(geom.Mat4()) seqs = seq.CreateSequenceList() pdbizer.Add(m.Select(''), transformations, seqs) pdbized = pdbizer.Finish() self.assertEqual([c.name for c in pdbized.chains], ["-"]) residues = pdbized.residues for i in range(26): self.assertEqual(residues[i].number.num, 1) self.assertEqual(residues[i].number.ins_code, chr(ord('A') + i)) self.assertEqual(residues[26].number.num, 2) self.assertEqual(residues[26].number.ins_code, 'A')
def test_fastModified(self): # phoshoserine: test if we correctly strip off modifications tpl = io.LoadPDB('testfiles/sep.pdb') new_hdl = mol.CreateEntity() ed = new_hdl.EditXCS() c = ed.InsertChain('A') ed.AppendResidue(c, 'SER') err, has_cbeta = mol.alg.CopyConserved(tpl.residues[0], new_hdl.residues[0], ed) self.assertTrue(err) self.assertTrue(has_cbeta) residues = new_hdl.residues self.assertEqual(len(residues), 1) self.assertEqual(len(residues[0].atoms), 6) self.assertTrue(new_hdl.FindAtom("A", mol.ResNum(1), "N").IsValid()) self.assertTrue(new_hdl.FindAtom("A", mol.ResNum(1), "CA").IsValid()) self.assertTrue(new_hdl.FindAtom("A", mol.ResNum(1), "C").IsValid()) self.assertTrue(new_hdl.FindAtom("A", mol.ResNum(1), "O").IsValid()) self.assertTrue(new_hdl.FindAtom("A", mol.ResNum(1), "CB").IsValid()) self.assertTrue(new_hdl.FindAtom("A", mol.ResNum(1), "OG").IsValid())
def LoadPDB(filename, restrict_chains="", no_hetatms=None, fault_tolerant=None, load_multi=False, quack_mode=None, join_spread_atom_records=None, calpha_only=None, profile='DEFAULT', remote=False, remote_repo='pdb', dialect=None, seqres=False, bond_feasibility_check=None): """ Load PDB file from disk and return one or more entities. Several options allow to customize the exact behaviour of the PDB import. For more information on these options, see :doc:`profile`. Residues are flagged as ligand if they are mentioned in a HET record. :param restrict_chains: If not an empty string, only chains listed in the string will be imported. :param fault_tolerant: Enable/disable fault-tolerant import. If set, overrides the value of :attr:`IOProfile.fault_tolerant`. :param no_hetatms: If set to True, HETATM records will be ignored. Overrides the value of :attr:`IOProfile.no_hetatms` :param load_multi: If set to True, a list of entities will be returned instead of only the first. This is useful when dealing with multi-PDB files. :param join_spread_atom_records: If set, overrides the value of :attr:`IOProfile.join_spread_atom_records`. :param remote: If set to True, the method tries to load the pdb from the remote repository given as *remote_repo*. The filename is then interpreted as the entry id as further specified for the *remote_repo* parameter. :param remote_repo: Remote repository to fetch structure if *remote* is True. Must be one in ['pdb', 'smtl', 'pdb_redo']. In case of 'pdb' and 'pdb_redo', the entry must be given as lower case pdb id, which loads the deposited assymetric unit (e.g. '1ake'). In case of 'smtl', the entry must also specify the desired biounit (e.g. '1ake.1'). :rtype: :class:`~ost.mol.EntityHandle` or a list thereof if `load_multi` is True. :param dialect: Specifies the particular dialect to use. If set, overrides the value of :attr:`IOProfile.dialect` :param seqres: Whether to read SEQRES records. If set to True, the loaded entity and seqres entry will be returned as a tuple. :type dialect: :class:`str` :raises: :exc:`~ost.io.IOException` if the import fails due to an erroneous or inexistent file """ def _override(val1, val2): if val2 != None: return val2 else: return val1 if isinstance(profile, str): prof = profiles[profile].Copy() elif isinstance(profile, IOProfile): prof = profile.Copy() else: raise TypeError('profile must be of type string or IOProfile, '+\ 'instead of %s'%type(profile)) if dialect not in ( None, 'PDB', 'CHARMM', ): raise ValueError('dialect must be PDB or CHARMM') prof.calpha_only = _override(prof.calpha_only, calpha_only) prof.no_hetatms = _override(prof.no_hetatms, no_hetatms) prof.dialect = _override(prof.dialect, dialect) prof.quack_mode = _override(prof.quack_mode, quack_mode) if prof.processor: prof.processor.check_bond_feasibility = _override( prof.processor.check_bond_feasibility, bond_feasibility_check) prof.fault_tolerant = _override(prof.fault_tolerant, fault_tolerant) prof.join_spread_atom_records = _override(prof.join_spread_atom_records, join_spread_atom_records) tmp_file = None # avoid getting out of scope if remote: if remote_repo not in ['pdb', 'smtl', 'pdb_redo']: raise IOError("remote_repo must be in ['pdb', 'smtl', 'pdb_redo']") from ost.io.remote import RemoteGet tmp_file = RemoteGet(filename, from_repo=remote_repo) filename = tmp_file.name conop_inst = conop.Conopology.Instance() if prof.processor: if prof.dialect == 'PDB': prof.processor.dialect = conop.PDB_DIALECT elif prof.dialect == 'CHARMM': prof.processor.dialect = conop.CHARMM_DIALECT reader = PDBReader(filename, prof) reader.read_seqres = seqres try: if load_multi: ent_list = [] while reader.HasNext(): ent = mol.CreateEntity() reader.Import(ent, restrict_chains) if prof.processor: prof.processor.Process(ent) ent_list.append(ent) if len(ent_list) == 0: raise IOError("File '%s' doesn't contain any entities" % filename) return ent_list else: ent = mol.CreateEntity() if reader.HasNext(): reader.Import(ent, restrict_chains) if prof.processor: prof.processor.Process(ent) else: raise IOError("File '%s' doesn't contain any entities" % filename) if seqres: return ent, reader.seqres return ent except: raise
def LoadMMCIF(filename, fault_tolerant=None, calpha_only=None, profile='DEFAULT', remote=False, seqres=False, info=False): """ Load MMCIF file from disk and return one or more entities. Several options allow to customize the exact behaviour of the MMCIF import. For more information on these options, see :doc:`profile`. Residues are flagged as ligand if they are mentioned in a HET record. :param fault_tolerant: Enable/disable fault-tolerant import. If set, overrides the value of :attr:`IOProfile.fault_tolerant`. :param remote: If set to True, the method tries to load the pdb from the remote pdb repository www.pdb.org. The filename is then interpreted as the pdb id. :rtype: :class:`~ost.mol.EntityHandle` (or tuple if *seqres* or *info* are True). :param seqres: Whether to read SEQRES records. If True, a :class:`~ost.seq.SequenceList` object is returned as the second item. The sequences in the list are named according to the mmCIF chain name. This feature requires a default :class:`compound library <ost.conop.CompoundLib>` to be defined and accessible via :func:`~ost.conop.GetDefaultLib` or an empty list is returned. :param info: Whether to return an info container with the other output. If True, a :class:`MMCifInfo` object is returned as last item. :raises: :exc:`~ost.io.IOException` if the import fails due to an erroneous or non-existent file. """ def _override(val1, val2): if val2 != None: return val2 else: return val1 if isinstance(profile, str): prof = profiles[profile].Copy() else: prof = profile.Copy() prof.calpha_only = _override(prof.calpha_only, calpha_only) prof.fault_tolerant = _override(prof.fault_tolerant, fault_tolerant) if remote: from ost.io.remote import RemoteGet tmp_file = RemoteGet(filename, from_repo='cif') filename = tmp_file.name try: ent = mol.CreateEntity() reader = MMCifReader(filename, ent, prof) reader.read_seqres = seqres # NOTE: to speed up things, we could introduce a restrict_chains parameter # similar to the one in LoadPDB. Here, it would have to be a list/set # of chain-name-strings. #if reader.HasNext(): reader.Parse() if prof.processor: prof.processor.Process(ent) #else: # raise IOError("File doesn't contain any entities") if seqres and info: return ent, reader.seqres, reader.info if seqres: return ent, reader.seqres if info: return ent, reader.info return ent except: raise
def test_gfxobj_conv(self): e=mol.CreateEntity() gfx.Scene().Add(gfx.Entity("foo2",e)) gfx.Scene()["foo2"].SetColor(gfx.YELLOW)