def load_hypothesis_xvol(filename, name=''): ''' Load excluded volumes from a hypothesis.xvol file. ''' from epymol import m2io from chempy import Atom, models if not name: name = _name_from_filename(filename, '.xvol') reader = m2io.M2IOReader(filename) try: table = reader.find_block('f_m_table').m_row col_radius = table.keys.index('r_m_phase_radius') cols_xyz = [ table.keys.index(n) for n in ['r_m_phase_x', 'r_m_phase_y', 'r_m_phase_z'] ] except (AttributeError, IndexError): print(' Error: could not find table') return model = models.Indexed() for row in table: atom = Atom() atom.coord = [row[i] for i in cols_xyz] atom.vdw = row[col_radius] atom.trgb = 0x00FFFF00 atom.visible = 0x2 # spheres model.add_atom(atom) pymol.cmd.load_model(model, name)
def load_rigimol_inp(filename, oname, _self=cmd): ''' DESCRIPTION Load the structures from a RigiMOL "inp" file. ''' import shlex from chempy import Atom, Bond, models parsestate = '' model = None state = 0 for line in open(filename): lex = shlex.shlex(line, posix=True) lex.whitespace_split = True lex.quotes = '"' a = list(lex) if not a: continue if a[0] == '+': if a[1] == 'NAME': assert a[2:] == [ 'RESI', 'RESN', 'CHAIN', 'SEGI', 'X', 'Y', 'Z', 'B' ] parsestate = 'ATOMS' model = models.Indexed() elif a[1] == 'FROM': assert a[2:] == ['TO'] parsestate = 'BONDS' else: parsestate = '' elif a[0] == '|': if parsestate == 'ATOMS': atom = Atom() atom.coord = [float(x) for x in a[6:9]] atom.name = a[1] atom.resi = a[2] atom.resn = a[3] atom.chain = a[4] atom.segi = a[5] atom.b = a[9] atom.symbol = '' model.add_atom(atom) elif parsestate == 'BONDS': bnd = Bond() bnd.index = [int(a[1]), int(a[2])] model.add_bond(bnd) elif a[0] == 'end': if parsestate in ('ATOMS', 'BONDS'): state += 1 _self.load_model(model, oname, state=state) parsestate = ''
def _create_molecule(n, mydata, resolution, created): model = models.Indexed() name = _get_molecule_name(n.get_name(), resolution) if name in created: name = name + "-2" print n, name, resolution th = RMF.TraverseHelper(n, name, resolution) created[name] = (th, model) print "creating molecule", name cgol = [] _create_atoms(th, mydata, model, cgol, created) frame = n.get_file().get_current_frame().get_index() + 1 if len(cgol) > 0: print cgol cmd.load_cgo(cgol, name + "-graphics", frame)
def load_xvol(oname): lines = get_blob('s_phasehypo_ExcludedVolumes').splitlines() if len(lines) < 2: return model = models.Indexed() for line in lines[1:]: row = [float(c) for c in line.split()] atom = Atom() atom.coord = row[:3] atom.vdw = row[3] atom.trgb = 0x0033E5F2 atom.visible = 0x2 # spheres model.add_atom(atom) pymol.cmd.load_model(model, oname, zoom=zoom)
def test(self): from chempy import Atom, Bond, models m = models.Indexed() for i in range(2): a = Atom() a.coord = [float(i), 0., 0.] m.add_atom(a) b = Bond() b.index = [0, 1] b.order = 0 m.add_bond(b) cmd.load_model(m, 'foo') cmd.set('valence') cmd.show('sticks')
def gen_model(mol): from chempy import models from chempy import Atom from chempy import Bond # print('generating model') model = models.Indexed() i = 1 for at in mol['atoms']: atom = Atom() atom.name = at['name'] atom.resi = at['residue'] atom.resi_number = int(at['residue']) atom.segi = at['segment'] atom.symbol = at['element'] atom.coord = [float(at["x"]), float(at["y"]), float(at["z"])] model.add_atom(atom) # model.update_index() # model.update_index() for b in mol['bonds']: bond = Bond() bond.index = [int(b['atom1']) - 1, int(b['atom2']) - 1] model.add_bond(bond) return model
def load_cml(filename, object='', discrete=0, multiplex=1, zoom=-1, quiet=1, _self=cmd): ''' DESCRIPTION Load a CML formatted structure file ''' from chempy import Atom, Bond, models multiplex, discrete = int(multiplex), int(discrete) try: root = etree.fromstring(_self.file_read(filename)) except etree.XMLSyntaxError: raise CmdException("File doesn't look like XML") if root.tag != 'cml': raise CmdException('not a CML file') molecule_list = root.findall('./molecule') if len(molecule_list) < 2: multiplex = 0 elif not multiplex: discrete = 1 for model_num, molecule_node in enumerate(molecule_list, 1): model = models.Indexed() atom_idx = {} for atom_node in molecule_node.findall('./atomArray/atom'): atom = Atom() atom.name = atom_node.get('id', '') if 'x3' in atom_node.attrib: atom.coord = [float(atom_node.get(a)) for a in ['x3', 'y3', 'z3']] elif 'x2' in atom_node.attrib: atom.coord = [float(atom_node.get(a)) for a in ['x2', 'y2']] + [0.0] else: print(' Warning: no coordinates for atom', atom.name) continue atom.symbol = atom_node.get('elementType', '') atom.formal_charge = int(atom_node.get('formalCharge', 0)) atom_idx[atom.name] = len(model.atom) model.add_atom(atom) for bond_node in molecule_node.findall('./bondArray/bond'): refs = bond_node.get('atomsRefs2', '').split() if len(refs) == 2: bnd = Bond() bnd.index = [int(atom_idx[ref]) for ref in refs] bnd.order = int(bond_node.get('order', 1)) model.add_bond(bnd) # object name if not object: object = os.path.basename(filename).split('.', 1)[0] # load models as objects or states if multiplex: oname = molecule_node.get('id') or _self.get_unused_name('unnamed') model_num = 1 else: oname = object _self.load_model(model, oname, state=model_num, zoom=zoom, discrete=discrete)
def sidechaincenters(object='scc', selection='all', method='bahar1996', name='PS1', *, _self=cmd): ''' DESCRIPTION Creates an object with sidechain representing pseudoatoms for each residue in selection. Two methods are available: (1) Sidechain interaction centers as defined by Bahar and Jernigan 1996 http://www.ncbi.nlm.nih.gov/pubmed/9080182 (2) Sidechain centroids, the pseudoatom is the centroid of all atoms except hydrogens and backbone atoms (N, C and O). NOTE With method "bahar1996", if a residue has all relevant sidechain center atoms missing (for example a MET without SD), it will be missing in the created pseudoatom object. With method "centroid", if you want to exclude C-alpha atoms from sidechains, modify the selection like in this example: sidechaincenters newobject, all and (not name CA or resn GLY), method=2 USAGE sidechaincenters object [, selection [, method ]] ARGUMENTS object = string: name of object to create selection = string: atoms to consider {default: (all)} method = string: bahar1996 or centroid {default: bahar1996} name = string: atom name of pseudoatoms {default: PS1} SEE ALSO pseudoatom ''' from chempy import Atom, cpv, models atmap = dict() if method in ['bahar1996', '1', 1]: modelAll = _self.get_model('(%s) and resn %s' % (selection, '+'.join(sidechaincenteratoms))) for at in modelAll.atom: if at.name in sidechaincenteratoms[at.resn]: atmap.setdefault((at.segi, at.chain, at.resn, at.resi), []).append(at) elif method in ['centroid', '2', 2]: modelAll = _self.get_model('(%s) and polymer and not (hydro or name C+N+O)' % selection) for at in modelAll.atom: atmap.setdefault((at.segi, at.chain, at.resn, at.resi), []).append(at) else: raise CmdException('unknown method: {}'.format(method)) model = models.Indexed() for centeratoms in atmap.values(): center = cpv.get_null() for at in centeratoms: center = cpv.add(center, at.coord) center = cpv.scale(center, 1./len(centeratoms)) atom = Atom() atom.coord = center atom.index = model.nAtom + 1 atom.name = name for key in [ 'segi', 'chain', 'resi_number', 'resi', 'resn', 'hetatm', 'ss', 'b', ]: setattr(atom, key, getattr(at, key)) model.add_atom(atom) model.update_index() if object in _self.get_object_list(): _self.delete(object) _self.load_model(model, object) return model
def load_3d(filename, object=''): ''' DESCRIPTION Load a survex 3d cave survey as "molecule" http://survex.com http://trac.survex.com/browser/trunk/doc/3dformat.htm ''' from chempy import Atom, Bond, models from struct import unpack if object == '': object = os.path.splitext(os.path.basename(filename))[0] f = open(filename, 'rb') line = f.readline() # File ID if not line.startswith('Survex 3D Image File'): print(" Error: not a Survex 3D File") raise CmdException line = f.readline() # File format version assert line[0] == 'v' ff_version = int(line[1:]) line = f.readline().decode('latin1') # Survex title line = f.readline() # Timestamp class Station: def __init__(self): self.labels = [] self.adjacent = [] self.lrud = None self.flag = 0 def connect(self, other): self.adjacent.append(other) def is_surface(self): return self.flag & 0x01 def is_underground(self): return self.flag & 0x02 def is_entrance(self): return self.flag & 0x04 def is_exported(self): return self.flag & 0x08 def is_fixed(self): return self.flag & 0x10 class Survey(dict): def __init__(self): self.prev = None self.curr_label = '' self.labelmap = {} def get(self, xyz): return dict.setdefault(self, tuple(xyz), Station()) def line(self, xyz): s = self.get(xyz) self.prev.connect(s) self.prev = s def move(self, xyz): s = self.get(xyz) self.prev = s def label(self, xyz, flag=0): s = self.get(xyz) s.labels.append(self.curr_label) self.labelmap[s.labels[-1]] = s if flag > 0: s.flag = flag def lrud(self, lrud): s = self.labelmap[self.curr_label] s.lrud = lrud survey = Survey() def read_xyz(): return unpack('<iii', f.read(12)) def read_len(): len = read_byte() if len == 0xfe: len += unpack('<H', f.read(2))[0] elif len == 0xff: len += unpack('<I', f.read(4))[0] return len def read_label(): len = read_len() if len > 0: survey.curr_label += skip_bytes(len) def skip_bytes(n): return f.read(n) def read_byte(): byte = f.read(1) if len(byte) != 1: return -1 return ord(byte) while 1: byte = read_byte() if byte == -1: break if byte == 0x00: # STOP survey.curr_label = '' elif byte <= 0x0e: # TRIM # FIXME: according to doc, trim 16 bytes, but img.c does 17! (i, n) = (-17, 0) while n < byte: i -= 1 if survey.curr_label[i] == '.': n += 1 survey.curr_label = survey.curr_label[:i + 1] elif byte <= 0x0f: # MOVE xyz = read_xyz() survey.move(xyz) elif byte <= 0x1f: # TRIM survey.curr_label = survey.curr_label[:15 - byte] elif byte <= 0x20: # DATE if ff_version < 7: skip_bytes(4) else: skip_bytes(2) elif byte <= 0x21: # DATE if ff_version < 7: skip_bytes(8) else: skip_bytes(3) elif byte <= 0x22: # Error info skip_bytes(5 * 4) elif byte <= 0x23: # DATE skip_bytes(4) elif byte <= 0x24: # DATE continue elif byte <= 0x2f: # Reserved continue elif byte <= 0x31: # XSECT read_label() lrud = unpack('<hhhh', f.read(8)) survey.lrud(lrud) elif byte <= 0x33: # XSECT read_label() lrud = unpack('<iiii', f.read(16)) survey.lrud(lrud) elif byte <= 0x3f: # Reserved continue elif byte <= 0x7f: # LABEL read_label() xyz = read_xyz() survey.label(xyz, byte & 0x3f) elif byte <= 0xbf: # LINE read_label() xyz = read_xyz() survey.line(xyz) elif byte <= 0xff: # Reserved continue model = models.Indexed() for (xyz, s) in survey.items(): l0, _, l1 = s.labels[0].rpartition('.') resi, name = l1[:5], l1[5:] segi, chain, resn = l0[-8:-4], l0[-4:-3], l0[-3:] atom = Atom() atom.coord = [i / 100.0 for i in xyz] atom.segi = segi atom.chain = chain atom.resn = resn atom.name = name atom.resi = resi atom.b = atom.coord[2] atom.label = s.labels[0] if s.lrud is not None: atom.vdw = sum(s.lrud) / 400.0 model.add_atom(atom) s2i = dict((s, i) for (i, s) in enumerate(survey.values())) for (s, i) in s2i.items(): for o in s.adjacent: bnd = Bond() bnd.index = [i, s2i[o]] model.add_bond(bnd) cmd.load_model(model, object, 1) cmd.show_as('lines', object) cmd.spectrum('b', 'rainbow', object)
def peptide_rebuild(name, selection='all', cycles=1000, state=1, quiet=1, *, _self=cmd): ''' DESCRIPTION Rebuild the peptide from selection. All atoms which are present in selection will be kept fixed, while atoms missing in selection are placed by sculpting. USAGE peptide_rebuild name [, selection [, cycles [, state ]]] SEE ALSO stub2ala, add_missing_atoms, peptide_rebuild_modeller ''' from chempy import fragments, feedback, models cycles, state, quiet = int(cycles), int(state), int(quiet) # suppress feedback for model merging feedback['actions'] = False # work with named selection namedsele = _self.get_unused_name('_') _self.select(namedsele, '{} & present'.format(selection), 0) identifiers = [] _self.iterate(namedsele + ' and polymer and guide and alt +A', 'identifiers.append([segi,chain,resi,resv,resn])', space=locals()) model = models.Indexed() for (segi,chain,resi,resv,resn) in identifiers: try: fname = resn.lower() if resn != 'MSE' else 'met' frag = fragments.get(fname) except IOError: print(' Warning: unknown residue: ' + resn) continue for a in frag.atom: a.segi = segi a.chain = chain a.resi = resi a.resi_number = resv a.resn = resn model.merge(frag) if not quiet: print(' Loading model...') _self.load_model(model, name, 1, zoom=0) if _self.get_setting_boolean('auto_remove_hydrogens'): _self.remove(name + ' and hydro') _self.protect(name + ' in ' + namedsele) _self.sculpt_activate(name) _self.update(name, namedsele, 1, state) _self.delete(namedsele) if not quiet: print(' Sculpting...') _self.set('sculpt_field_mask', 0x003, name) # bonds and angles only _self.sculpt_iterate(name, 1, int(cycles / 4)) _self.set('sculpt_field_mask', 0x09F, name) # local + torsions _self.sculpt_iterate(name, 1, int(cycles / 4)) _self.set('sculpt_field_mask', 0x0FF, name) # ... + vdw _self.sculpt_iterate(name, 1, int(cycles / 2)) _self.sculpt_deactivate(name) _self.deprotect(name) _self.unset('sculpt_field_mask', name) if not quiet: print(' Connecting peptide...') pairs = _self.find_pairs(name + ' and name C', name + ' and name N', 1, 1, 2.0) for pair in pairs: _self.bond(*pair) _self.h_fix(name) if not quiet: print(' peptide_rebuild: done')
def load_3d(filename, object=''): ''' DESCRIPTION Load a survex 3d cave survey as "molecule" http://survex.com ''' from chempy import Atom, Bond, models if object == '': import os object = os.path.splitext(os.path.basename(filename))[0] f = open(filename, 'rb') line = f.readline() # File ID if not line.startswith('Survex 3D Image File'): print " Error: not a Survex 3D File" raise CmdException line = f.readline() # File format version assert line[0] == 'v' ff_version = int(line[1:]) line = unicode(f.readline(), 'latin1') # Survex title line = f.readline() # Timestamp class Station(tuple): def __new__(cls, xyz): return tuple.__new__(cls, xyz) def __init__(self, xyz): self.labels = [] self.adjacent = [] def connect(self, other): self.adjacent.append(other) class Survey(dict): def __init__(self): self.prev = None self.curr_label = '' def get(self, xyz): s = Station(xyz) return dict.setdefault(self, s, s) def line(self, xyz): s = self.get(xyz) self.prev.connect(s) self.prev = s def move(self, xyz): s = self.get(xyz) self.prev = s def label(self, xyz): s = survey.get(xyz) s.labels.append(self.curr_label) def __repr__(self): return 'Survey(' + repr(self.keys())[1:-1] + ')' survey = Survey() def read_xyz(): x = read_int(4, 1) y = read_int(4, 1) z = read_int(4, 1) return [ x, y, z ] def read_int(len, sign): int = 0 for i in range(len): int |= read_byte() << (8 * i) if sign and (int >> (8 * len - 1)): int -= (1 << 8 * len) return int def read_len(): len = read_byte() if len == 0xfe: len += read_int(2, 0) elif len == 0xff: len = read_int(4, 0) return len def read_label(): len = read_len() if len > 0: survey.curr_label += skip_bytes(len) def skip_bytes(n): return f.read(n) def read_byte(): byte = f.read(1) if len(byte) != 1: return -1 return ord(byte) while 1: byte = read_byte() if byte == -1: break if byte == 0x00: # STOP survey.curr_label = '' elif byte <= 0x0e: # TRIM (i,n) = (-16,0) while n < byte: i -= 1 if survey.curr_label[i] == '.': n += 1 survey.curr_label = survey.curr_label[:i + 1] elif byte <= 0x0f: # MOVE xyz = read_xyz() survey.move(xyz) elif byte <= 0x1f: # TRIM survey.curr_label = survey.curr_label[:15 - byte] elif byte <= 0x20: # DATE if ff_version < 7: skip_bytes(4) else: skip_bytes(2) elif byte <= 0x21: # DATE if ff_version < 7: skip_bytes(8) else: skip_bytes(3) elif byte <= 0x22: # Error info skip_bytes(5 * 4) elif byte <= 0x23: # DATE skip_bytes(4) elif byte <= 0x24: # DATE continue elif byte <= 0x2f: # Reserved continue elif byte <= 0x31: # XSECT read_label() skip_bytes(4 * 2) elif byte <= 0x33: # XSECT read_label() skip_bytes(4 * 4) elif byte <= 0x3f: # Reserved continue elif byte <= 0x7f: # LABEL read_label() xyz = read_xyz() survey.label(xyz) elif byte <= 0xbf: # LINE read_label() xyz = read_xyz() survey.line(xyz) elif byte <= 0xff: # Reserved continue model = models.Indexed() for s in survey: l0, _, l1 = s.labels[0].rpartition('.') resi, name = l1[:5], l1[5:] # segi, chain, resn = l0[:4],l0[-4:-3], l0[-3:] segi, chain, resn = l0[-8:-4], l0[-4:-3], l0[-3:] atom = Atom() atom.coord = [i/100.0 for i in s] atom.segi = segi atom.chain = chain atom.resn = resn atom.name = name atom.resi = resi atom.b = atom.coord[2] model.add_atom(atom) s2i = dict((s,i) for (i,s) in enumerate(survey)) for s in survey: for o in s.adjacent: bnd = Bond() bnd.index = [s2i[s], s2i[o]] model.add_bond(bnd) cmd.load_model(model, object, 1) cmd.show_as('lines', object) cmd.spectrum('b', 'rainbow', object)
def _to_chempy(data, use_auth=True): ''' Construct a "chempy" model (molecule) from decoded MMTF data. ''' from itertools import islice from chempy import models, Atom, Bond def add_bond(i1, i2, order, offset=0): bond = Bond() bond.order = order bond.index = [i1 + offset, i2 + offset] model.add_bond(bond) coord_iter = data.get_table_iter([ 'xCoordList', 'yCoordList', 'zCoordList', ]) atom_iter = data.get_table_iter([ 'bFactorList', 'occupancyList', 'altLocList', 'atomIdList', ], [0.0, 1.0, '', -1]) group_iter = data.get_table_iter([ 'groupTypeList', 'sequenceIndexList', 'groupIdList', 'insCodeList', 'secStructList', ]) chain_list_iter = enumerate( data.get_table_iter([ 'chainIdList', 'chainNameList', 'groupsPerChain', ])) groupList = data.get('groupList') symmetry = ( data.get('unitCell', None), as_str(data.get('spaceGroup', '')), ) model_output = [] for n_chains in data.get_iter('chainsPerModel'): model = models.Indexed() model_output.append(model) if symmetry[0] is not None: model.cell, model.spacegroup = symmetry for (chain_idx, (segi, chain, n_groups)) in islice(chain_list_iter, n_chains): for (groupType, label_seq_id, auth_seq_id, ins_code, ss_info) in \ islice(group_iter, n_groups): group = groupList[groupType] resn = as_str(group[b'groupName']) group_bond_iter = izip( group[b'bondAtomList'][0::2], group[b'bondAtomList'][1::2], group[b'bondOrderList'], ) offset = len(model.atom) for (i1, i2, order) in group_bond_iter: add_bond(i1, i2, order, offset) group_atom_iter = izip( group[b'atomNameList'], group[b'elementList'], group[b'formalChargeList'], ) for (name, elem, formal_charge) in group_atom_iter: atom = Atom() (atom.b, atom.q, atom.alt, atom.id) = next(atom_iter) atom.coord = next(coord_iter) atom.symbol = as_str(elem) atom.name = as_str(name) atom.resn = resn atom.hetatm = label_seq_id == -1 atom.formal_charge = formal_charge atom.segi = segi atom.chain = chain atom.ss = ss_map.get(ss_info, '') if use_auth or label_seq_id is None: atom.resi = auth_seq_id atom.ins_code = ins_code or '' else: atom.resi = label_seq_id + 1 model.add_atom(atom) model_atom_max = 0 model_atom_min = 0 model_iter = iter(model_output) bondAtomList_iter = data.get_iter('bondAtomList') for order in data.get_iter('bondOrderList'): i1 = next(bondAtomList_iter) i2 = next(bondAtomList_iter) if i1 >= model_atom_max or i2 >= model_atom_max: model = next(model_iter) model_atom_min = model_atom_max model_atom_max += len(model.atom) add_bond(i1, i2, order, -model_atom_min) return model_output