I am developing an educational Bioinformatics framework, I need to know
- Which atoms are absolutely not found in any PDB files?
in the following list -
I am developing an educational Bioinformatics framework, I need to know
in the following list -
It is a question of implementation. For example:
from rdkit import Chem
mol = Chem.MolFromSmiles('[Og]')
pdbblock = Chem.MolToPDBBlock(mol)
import pymol2
with pymol2.PyMOL() as pymol:
pymol.cmd.read_pdbstr(pdbblock, 'Oganesson')
shows that both RDKit and PyMol can deal with oganesson. However, this is just handling the atoms in coordinate space. But as soon as we touch it in molecular mechanics way things blow up:
from rdkit.Chem import AllChem
AllChem.EmbedMolecule(mol) # UFFTYPER: Unrecognized atom type: Og (0)
But generally most molecular mechanics tools struggle with coordinated iron or similar. Take the mangled case of https://www.rcsb.org/ligand/SIR which ought to have been planar...
In the PDB polymeric units and ligands are called chemical components. They have a 3 letter code. The list is easily parsable. The problem is that some lists are incomplete: https://ftp.ebi.ac.uk/pub/databases/pdb/data/component-models/complete/chem_comp_model.cif.gz when read
from pdbecif.mmcif_tools import MMCIF2Dict
models: dict = MMCIF2Dict().parse('chem_comp_model.cif')
has a large number of entries missing because of <reasons>.
So using a more crude approach and simply querying component by component:
with open('chem_comp.list') as fh: # this is from somewhere else in the ftp
chem_resns = *map(str.strip, fh),
import requests
import re
elements = set()
for i in range(len(chem_resns)//100):
response = requests.post('https://www.ebi.ac.uk/pdbe/api/pdb/compound/summary/', ','.join(list(mia)[100*i:100*(i+1)]))
response.raise_for_status()
for resn in response.json().values():
for entry in resn:
if entry['formula'] is None: # the unknown ligand/ions etc.
continue
elements.update(re.findall('[^\d ]+', entry['formula']))
Gives the following elements that are present:
{'Ag',
'Al',
'Am',
'Ar',
'As',
'Au',
'B',
'Ba',
'Be',
'Bi',
'Br',
'C',
'Ca',
'Cd',
'Ce',
'Cf',
'Cl',
'Cm',
'Co',
'Cr',
'Cs',
'Cu',
'D',
'Dy',
'Er',
'Eu',
'F',
'Fe',
'Ga',
'Gd',
'H',
'Hf',
'Hg',
'Ho',
'I',
'In',
'Ir',
'K',
'Kr',
'La',
'Li',
'Lu',
'Mg',
'Mn',
'Mo',
'N',
'Na',
'Nd',
'Ni',
'O',
'Os',
'P',
'Pb',
'Pd',
'Pr',
'Pt',
'Pu',
'Rb',
'Re',
'Rh',
'Ru',
'S',
'Sb',
'Sc',
'Se',
'Si',
'Sm',
'Sn',
'Sr',
'Ta',
'Tb',
'Te',
'Th',
'Ti',
'Tl',
'U',
'V',
'W',
'X',
'Xe',
'Y',
'Yb',
'Zn',
'Zr'}
While those that are absent are:
pt = Chem.GetPeriodicTable()
full = set(map(pt.GetElementSymbol, range(1, 118+1)))
missing = full - elements
for m in sorted(missing, key=pt.GetAtomicNumber):
print(pt.GetAtomicNumber(m), m)
2 He
10 Ne
32 Ge
41 Nb
43 Tc
61 Pm
69 Tm
84 Po
85 At
86 Rn
87 Fr
88 Ra
89 Ac
91 Pa
93 Np
97 Bk
99 Es
100 Fm
101 Md
102 No
103 Lr
104 Rf
105 Db
106 Sg
107 Bh
108 Hs
109 Mt
110 Ds
111 Rg
112 Cn
113 Nh
114 Fl
115 Mc
116 Lv
117 Ts
118 Og