0
# Interoperability and Converters
1
2
MDAnalysis provides comprehensive conversion capabilities to facilitate interoperability with other molecular modeling and cheminformatics packages. The converters module enables seamless translation between MDAnalysis objects and external library formats.
3
4
## Overview
5
6
The converters module supports bidirectional conversion between MDAnalysis and:
7
- **RDKit**: Cheminformatics toolkit for molecular manipulation
8
- **ParmEd**: Parameter/topology editor for molecular simulations
9
- **OpenMM**: High-performance molecular simulation toolkit
10
11
Each converter provides both parser capabilities (reading external formats into MDAnalysis) and converter capabilities (exporting MDAnalysis data to external formats).
12
13
## Core Imports
14
15
```python
16
import MDAnalysis.converters as converters
17
18
# Specific converter imports
19
from MDAnalysis.converters import RDKit, RDKitParser
20
from MDAnalysis.converters import ParmEd, ParmEdParser
21
from MDAnalysis.converters import OpenMM, OpenMMParser
22
23
# Base converter class
24
from MDAnalysis.converters.base import ConverterBase
25
```
26
27
## Capabilities
28
29
### RDKit Integration
30
31
Conversion between MDAnalysis and RDKit molecule objects for cheminformatics workflows.
32
33
```python { .api }
34
class RDKitReader:
35
"""
36
Coordinate reader for RDKit molecule objects.
37
38
Allows reading coordinates from RDKit Mol objects into MDAnalysis.
39
"""
40
41
def __init__(self, filename, **kwargs):
42
"""
43
Create RDKit coordinate reader.
44
45
Parameters
46
----------
47
filename : rdkit.Chem.rdchem.Mol
48
RDKit molecule object
49
**kwargs
50
Additional reader options
51
"""
52
53
class RDKitParser:
54
"""
55
Topology parser for RDKit molecule objects.
56
57
Extracts topology information from RDKit Mol objects.
58
"""
59
60
def __init__(self, filename, **kwargs):
61
"""
62
Create RDKit topology parser.
63
64
Parameters
65
----------
66
filename : rdkit.Chem.rdchem.Mol
67
RDKit molecule object
68
**kwargs
69
Additional parser options
70
"""
71
72
class RDKitConverter(ConverterBase):
73
"""
74
Convert MDAnalysis AtomGroup to RDKit Mol object.
75
"""
76
77
lib = "RDKIT"
78
79
def convert(self, obj, cache=dict(), NoImplicitHs=True,
80
max_iter=200, force=True):
81
"""
82
Convert AtomGroup or Universe to RDKit Mol object.
83
84
Parameters
85
----------
86
obj : AtomGroup or Universe
87
MDAnalysis object to convert
88
cache : dict, optional
89
Cache for conversion optimization
90
NoImplicitHs : bool, optional
91
Whether to exclude implicit hydrogens (default True)
92
max_iter : int, optional
93
Maximum iterations for bond perception (default 200)
94
force : bool, optional
95
Whether to force conversion even with warnings (default True)
96
97
Returns
98
-------
99
rdkit.Chem.rdchem.Mol
100
RDKit molecule object
101
102
Examples
103
--------
104
>>> mol = protein.convert_to("RDKIT")
105
>>> mol = u.atoms.convert_to("RDKIT", NoImplicitHs=False)
106
"""
107
```
108
109
### ParmEd Integration
110
111
Conversion with ParmEd for advanced parameter and topology manipulation.
112
113
```python { .api }
114
class ParmEdParser:
115
"""
116
Topology parser for ParmEd Structure objects.
117
118
Reads topology information from ParmEd Structure into MDAnalysis.
119
"""
120
121
def __init__(self, filename, **kwargs):
122
"""
123
Create ParmEd topology parser.
124
125
Parameters
126
----------
127
filename : parmed.Structure
128
ParmEd Structure object
129
**kwargs
130
Additional parser options
131
"""
132
133
class ParmEdReader:
134
"""
135
Coordinate reader for ParmEd Structure objects.
136
137
Reads coordinates from ParmEd Structure into MDAnalysis.
138
"""
139
140
def __init__(self, filename, **kwargs):
141
"""
142
Create ParmEd coordinate reader.
143
144
Parameters
145
----------
146
filename : parmed.Structure
147
ParmEd Structure object
148
**kwargs
149
Additional reader options
150
"""
151
152
class ParmEdConverter(ConverterBase):
153
"""
154
Convert MDAnalysis objects to ParmEd Structure.
155
"""
156
157
lib = "PARMED"
158
159
def convert(self, obj, box=None):
160
"""
161
Convert AtomGroup or Universe to ParmEd Structure.
162
163
Parameters
164
----------
165
obj : AtomGroup or Universe
166
MDAnalysis object to convert
167
box : array-like, optional
168
Box dimensions [a, b, c, alpha, beta, gamma]
169
170
Returns
171
-------
172
parmed.Structure
173
ParmEd Structure object
174
175
Examples
176
--------
177
>>> struct = protein.convert_to("PARMED")
178
>>> struct = u.atoms.convert_to("PARMED", box=u.dimensions)
179
"""
180
```
181
182
### OpenMM Integration
183
184
Conversion with OpenMM for high-performance molecular dynamics simulations.
185
186
```python { .api }
187
class OpenMMParser:
188
"""
189
Topology parser for OpenMM objects.
190
191
Extracts topology from OpenMM Topology and System objects.
192
"""
193
194
def __init__(self, filename, **kwargs):
195
"""
196
Create OpenMM topology parser.
197
198
Parameters
199
----------
200
filename : simtk.openmm.app.Topology or tuple
201
OpenMM Topology object or (Topology, positions) tuple
202
**kwargs
203
Additional parser options
204
"""
205
206
class OpenMMReader:
207
"""
208
Coordinate reader for OpenMM Simulation objects.
209
210
Reads coordinates from OpenMM trajectories and states.
211
"""
212
213
def __init__(self, filename, **kwargs):
214
"""
215
Create OpenMM coordinate reader.
216
217
Parameters
218
----------
219
filename : simtk.openmm.app.Simulation or tuple
220
OpenMM Simulation object or (Topology, positions) tuple
221
**kwargs
222
Additional reader options
223
"""
224
225
class OpenMMAppConverter(ConverterBase):
226
"""
227
Convert MDAnalysis objects to OpenMM App objects.
228
"""
229
230
lib = "OPENMM"
231
232
def convert(self, obj, positions=True):
233
"""
234
Convert to OpenMM Topology and positions.
235
236
Parameters
237
----------
238
obj : AtomGroup or Universe
239
MDAnalysis object to convert
240
positions : bool, optional
241
Whether to include positions (default True)
242
243
Returns
244
-------
245
tuple
246
(openmm.app.Topology, positions) tuple
247
248
Examples
249
--------
250
>>> topology, positions = protein.convert_to("OPENMM")
251
"""
252
```
253
254
### Base Converter Framework
255
256
Foundation classes for implementing custom converters.
257
258
```python { .api }
259
class ConverterBase:
260
"""
261
Base class for all converters.
262
263
Provides the framework for converting MDAnalysis objects to external formats.
264
"""
265
266
lib = None # Override with target library name
267
268
def convert(self, obj):
269
"""
270
Convert MDAnalysis object to target format.
271
272
Parameters
273
----------
274
obj : AtomGroup or Universe
275
Object to convert
276
277
Returns
278
-------
279
Converted object in target library format
280
"""
281
raise NotImplementedError("Subclasses must implement convert method")
282
283
def __repr__(self):
284
"""String representation of converter."""
285
return f"<{self.__class__.__name__}>"
286
```
287
288
## Usage Examples
289
290
### RDKit Workflows
291
292
```python
293
import MDAnalysis as mda
294
from rdkit import Chem
295
296
# Load RDKit molecule into MDAnalysis
297
mol = Chem.MolFromSmiles('CCO')
298
mol = Chem.AddHs(mol)
299
AllChem.EmbedMolecule(mol)
300
301
u = mda.Universe(mol)
302
print(f"Universe: {u}")
303
print(f"Atoms: {u.atoms.n_atoms}")
304
305
# Convert back to RDKit
306
rdkit_mol = u.atoms.convert_to("RDKIT")
307
smiles = Chem.MolToSmiles(rdkit_mol)
308
print(f"SMILES: {smiles}")
309
310
# Work with conformers
311
multi_conf_mol = Chem.MolFromMol2File("conformers.mol2", removeHs=False)
312
u_conf = mda.Universe(multi_conf_mol)
313
print(f"Conformers: {len(u_conf.trajectory)}")
314
315
# Process each conformer
316
for ts in u_conf.trajectory:
317
rdkit_conf = u_conf.atoms.convert_to("RDKIT")
318
# Perform RDKit calculations on each frame
319
```
320
321
### ParmEd Integration
322
323
```python
324
import MDAnalysis as mda
325
import parmed as pmd
326
327
# Load from ParmEd Structure
328
struct = pmd.load_file('system.prmtop', 'trajectory.nc')
329
u = mda.Universe(struct)
330
331
# Modify in MDAnalysis
332
protein = u.select_atoms('protein')
333
protein.atoms.masses *= 1.1 # Modify masses
334
335
# Convert back to ParmEd
336
modified_struct = u.atoms.convert_to("PARMED")
337
338
# Use ParmEd tools
339
modified_struct.strip(':WAT') # Remove water
340
modified_struct.save('protein_only.pdb')
341
342
# Parameter manipulation
343
for atom in modified_struct.atoms:
344
if atom.element_name == 'H':
345
atom.charge *= 0.9 # Scale hydrogen charges
346
```
347
348
### OpenMM Simulation Setup
349
350
```python
351
import MDAnalysis as mda
352
from simtk.openmm.app import *
353
from simtk.openmm import *
354
from simtk.unit import *
355
356
# Load system in MDAnalysis
357
u = mda.Universe('system.pdb')
358
359
# Convert to OpenMM
360
topology, positions = u.atoms.convert_to("OPENMM")
361
362
# Set up OpenMM simulation
363
forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml')
364
system = forcefield.createSystem(topology,
365
nonbondedMethod=PME,
366
nonbondedCutoff=1*nanometer)
367
368
integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 2*femtoseconds)
369
simulation = Simulation(topology, system, integrator)
370
simulation.context.setPositions(positions)
371
372
# Run simulation
373
simulation.minimizeEnergy()
374
simulation.step(1000)
375
376
# Convert back to MDAnalysis for analysis
377
state = simulation.context.getState(getPositions=True)
378
positions = state.getPositions()
379
u_sim = mda.Universe((topology, positions))
380
```
381
382
### Cross-Platform Workflows
383
384
```python
385
import MDAnalysis as mda
386
from rdkit import Chem
387
import parmed as pmd
388
389
# Start with SMILES
390
smiles = 'CC(=O)NC1=CC=C(C=C1)O' # Acetaminophen
391
mol = Chem.MolFromSmiles(smiles)
392
mol = Chem.AddHs(mol)
393
AllChem.EmbedMolecule(mol)
394
395
# RDKit -> MDAnalysis
396
u = mda.Universe(mol)
397
398
# Add missing topology information
399
u.add_TopologyAttr('masses')
400
u.add_TopologyAttr('charges')
401
402
# MDAnalysis -> ParmEd for parameter assignment
403
struct = u.atoms.convert_to("PARMED")
404
405
# Use ParmEd for advanced parameterization
406
# struct.load_parameters(some_parameter_set)
407
408
# ParmEd -> MDAnalysis for analysis
409
u_param = mda.Universe(struct)
410
411
# Perform MDAnalysis-based analysis
412
com = u_param.atoms.center_of_mass()
413
rgyr = u_param.atoms.radius_of_gyration()
414
415
# MDAnalysis -> OpenMM for simulation
416
topology, positions = u_param.atoms.convert_to("OPENMM")
417
# Continue with OpenMM simulation setup...
418
```
419
420
### Custom Converter Implementation
421
422
```python
423
from MDAnalysis.converters.base import ConverterBase
424
425
class CustomLibraryConverter(ConverterBase):
426
lib = "CUSTOMLIB"
427
428
def convert(self, obj, **kwargs):
429
"""Convert to custom library format."""
430
# Extract MDAnalysis data
431
positions = obj.positions
432
masses = obj.masses if hasattr(obj, 'masses') else None
433
434
# Create custom library object
435
custom_obj = CustomLibrary.Molecule()
436
custom_obj.set_coordinates(positions)
437
if masses is not None:
438
custom_obj.set_masses(masses)
439
440
return custom_obj
441
442
# Register converter
443
# Converter automatically registers via metaclass
444
```
445
446
## Format Compatibility
447
448
| Library | Parser | Reader | Converter | Dependencies |
449
|---------|--------|--------|-----------|--------------|
450
| RDKit | ✓ | ✓ | ✓ | rdkit-pypi |
451
| ParmEd | ✓ | ✓ | ✓ | parmed |
452
| OpenMM | ✓ | ✓ | ✓ | openmm |
453
454
## Conversion Considerations
455
456
### Data Fidelity
457
- **Bond perception**: Automatic bond detection may differ between libraries
458
- **Stereochemistry**: Chirality information may not be preserved
459
- **Aromaticity**: Aromatic bond representation varies between libraries
460
- **Formal charges**: Charge assignment methods differ
461
462
### Performance
463
- Large systems may require significant memory during conversion
464
- Bond perception algorithms can be computationally expensive
465
- Caching mechanisms available for repeated conversions
466
467
### Error Handling
468
```python
469
try:
470
rdkit_mol = atoms.convert_to("RDKIT")
471
except Exception as e:
472
print(f"Conversion failed: {e}")
473
# Fallback to alternative method or simplified representation
474
```
475
476
### Validation
477
```python
478
# Validate conversion by round-trip
479
original_atoms = u.atoms
480
rdkit_mol = original_atoms.convert_to("RDKIT")
481
u2 = mda.Universe(rdkit_mol)
482
roundtrip_atoms = u2.atoms
483
484
# Compare key properties
485
assert original_atoms.n_atoms == roundtrip_atoms.n_atoms
486
assert np.allclose(original_atoms.positions, roundtrip_atoms.positions, atol=1e-3)
487
```
488
489
## Integration with Analysis Workflows
490
491
The converters seamlessly integrate with MDAnalysis analysis capabilities:
492
493
```python
494
from MDAnalysis.analysis import rms
495
496
# RDKit conformer analysis
497
mol = Chem.SDMolSupplier('conformers.sdf', removeHs=False)
498
u = mda.Universe(mol)
499
500
# Standard MDAnalysis analysis
501
R = rms.RMSD(u, u, select='name CA')
502
R.run()
503
504
# Convert results back for RDKit processing
505
for i, rmsd_val in enumerate(R.results.rmsd):
506
u.trajectory[i]
507
current_mol = u.atoms.convert_to("RDKIT")
508
# Use RDKit tools on each conformer
509
```