Molekülstrukturen mit Python und RDKit zeichnen
Für die Filament-Übersicht brauchte ich Strukturbilder der Monomere -- Milchsäure, Styrol, Caprolactam und Co. Statt Bilder aus dem Internet zu klauen (Lizenzstress, unterschiedlicher Stil), einfach selbst generiert: mit Python und RDKit.
Was ist RDKit?
RDKit ist eine Open-Source-Cheminformatik-Bibliothek, die in Pharma und Chemie weit verbreitet ist. Kann Moleküle parsen, analysieren, vergleichen und zeichnen. Für uns interessant: aus einer Textbeschreibung (SMILES) eine saubere 2D-Strukturformel als SVG erzeugen.
Installation
pip install rdkit
Das Paket ist ~30 MB groß und bringt alles mit.
SMILES -- Moleküle als Text
SMILES (Simplified Molecular Input Line Entry System) beschreibt Moleküle als kurze Textstrings. Die Regeln sind schnell gelernt:
- Atome werden als Elementsymbol geschrieben:
C,N,O,S,Cl... - Kohlenstoff und Wasserstoff können implizit sein:
Csteht für Methan (CH₄),CCfür Ethan (C₂H₆) - Doppelbindungen:
=→C=Cist Ethylen - Dreifachbindungen:
#→C#Nist Blausäure (HCN) - Ringe: Ziffern markieren Ringschlüsse →
c1ccccc1ist Benzol (aromatisch, Kleinbuchstaben) - Verzweigungen: Klammern →
CC(=O)Oist Essigsäure - Stereochemie:
@/@@für Chiralität,//\für cis/trans
Beispiele der Filament-Monomere:
| Monomer | SMILES |
|---|---|
| Milchsäure | C[C@@H](O)C(=O)O |
| Lactid | C[C@@H]1OC(=O)[C@H](C)OC1=O |
| Styrol | C=Cc1ccccc1 |
| Acrylnitril | C=CC#N |
| 1,3-Butadien | C=CC=C |
| ε-Caprolactam | O=C1CCCCCN1 |
| Bisphenol A | Oc1ccc(C(C)(C)c2ccc(O)cc2)cc1 |
SMILES für gängige Moleküle findest du auf PubChem -- einfach den Namen suchen und unter "Canonical SMILES" nachschauen.
SVG erzeugen -- Minimalbeispiel
from rdkit import Chem
from rdkit.Chem import AllChem, Draw
from rdkit.Chem.Draw import rdMolDraw2D
# SMILES parsen
mol = Chem.MolFromSmiles('C=Cc1ccccc1') # Styrol
AllChem.Compute2DCoords(mol) # 2D-Layout berechnen
# SVG rendern
drawer = rdMolDraw2D.MolDraw2DSVG(400, 300)
drawer.DrawMolecule(mol)
drawer.FinishDrawing()
svg = drawer.GetDrawingText()
# Speichern
with open('styrol.svg', 'w') as f:
f.write(svg)
Das erzeugt eine saubere SVG-Datei mit der Skelettformel von Styrol -- skaliert auf jede Größe, scharf auf jedem Display. Fertig.
Mehrere Moleküle auf einmal
Für die Filament-Seite hab ich ein kleines Script geschrieben, das alle Monomere in einem Rutsch generiert:
from rdkit import Chem
from rdkit.Chem import AllChem
from rdkit.Chem.Draw import rdMolDraw2D
from pathlib import Path
output_dir = Path('img/filamente')
output_dir.mkdir(parents=True, exist_ok=True)
monomers = {
'milchsaeure': ('C[C@@H](O)C(=O)O', 'Milchsäure'),
'lactid': ('C[C@@H]1OC(=O)[C@H](C)OC1=O', 'Lactid'),
'styrol': ('C=Cc1ccccc1', 'Styrol'),
'acrylnitril': ('C=CC#N', 'Acrylnitril'),
'butadien': ('C=CC=C', '1,3-Butadien'),
'caprolactam': ('O=C1CCCCCN1', 'ε-Caprolactam'),
'terephthalsaeure': ('OC(=O)c1ccc(C(=O)O)cc1', 'Terephthalsäure'),
'ethylenglykol': ('OCCO', 'Ethylenglykol'),
'hexamethylendiamin': ('NCCCCCCN', 'Hexamethylendiamin'),
'adipinsaeure': ('OC(=O)CCCCC(=O)O', 'Adipinsäure'),
'bisphenol_a': ('Oc1ccc(C(C)(C)c2ccc(O)cc2)cc1', 'Bisphenol A'),
'mdi': ('O=C=Nc1ccc(Cc2ccc(N=C=O)cc2)cc1', 'MDI'),
'butylacrylat': ('CCCCOC(=O)C=C', 'Butylacrylat'),
}
for filename, (smiles, title) in monomers.items():
mol = Chem.MolFromSmiles(smiles)
AllChem.Compute2DCoords(mol)
drawer = rdMolDraw2D.MolDraw2DSVG(400, 300)
opts = drawer.drawOptions()
opts.padding = 0.15
opts.bondLineWidth = 2.0
drawer.DrawMolecule(mol)
drawer.FinishDrawing()
(output_dir / f'{filename}.svg').write_text(drawer.GetDrawingText())
print(f'{filename}.svg -- {title}')
Darstellung anpassen
Der Drawer hat jede Menge Stellschrauben über drawOptions():
opts = drawer.drawOptions()
opts.bondLineWidth = 2.5 # dickere Linien
opts.padding = 0.2 # mehr Rand
opts.addAtomIndices = True # Atom-Nummern anzeigen (für Debugging)
opts.addStereoAnnotation = True # Stereochemie-Labels (R/S)
opts.backgroundColour = (1,1,1,0) # transparenter Hintergrund
Breite und Höhe werden beim Erstellen des Drawers festgelegt: MolDraw2DSVG(breite, höhe).
Warum SVG?
- Skalierbar -- sieht auf Retina-Displays und beim Zoomen immer scharf aus
- Klein -- typisch 3--15 KB pro Molekül, viel kleiner als PNG
- Editierbar -- SVG ist XML, du kannst Farben oder Schriften nachträglich anpassen
- Web-nativ -- Browser rendern SVG direkt, kein
<canvas>oder Plugin nötig
RDKit kann auch PNG (MolDraw2DCairo), aber für Webseiten ist SVG die bessere Wahl.
Weiterführendes
- RDKit Dokumentation -- offizielle Doku
- RDKit Cookbook -- Rezepte für häufige Aufgaben
- PubChem -- SMILES und Eigenschaften für Millionen von Molekülen
- OpenSMILES Spezifikation -- SMILES-Syntax im Detail