0
# Auxiliary Data Handling
1
2
MDAnalysis provides comprehensive support for reading and handling auxiliary data alongside molecular dynamics trajectories. Auxiliary data refers to time-series data that accompanies trajectories but is not stored in the regular trajectory file format.
3
4
## Overview
5
6
Auxiliary data in MDAnalysis allows for:
7
- Reading time-series data from external files (XVG, EDR formats)
8
- Automatic alignment with trajectory timesteps
9
- On-the-fly calculation of representative values
10
- Integration with trajectory iteration and analysis workflows
11
12
## Core Imports
13
14
```python
15
import MDAnalysis.auxiliary as aux
16
17
# Direct imports for specific formats
18
from MDAnalysis.auxiliary import XVG, EDR
19
from MDAnalysis.auxiliary.core import auxreader, get_auxreader_for
20
21
# Base classes
22
from MDAnalysis.auxiliary.base import AuxReader, AuxStep, AuxFileReader
23
```
24
25
## Capabilities
26
27
### Auxiliary Reader Factory Functions
28
29
Functions for automatically selecting and creating appropriate auxiliary readers.
30
31
```python { .api }
32
def get_auxreader_for(auxdata=None, format=None):
33
"""
34
Return the appropriate auxiliary reader class for auxiliary data.
35
36
Parameters
37
----------
38
auxdata : str or file-like, optional
39
Auxiliary data source (filename, file object, etc.)
40
format : str, optional
41
Known format of auxiliary data ('XVG', 'EDR', etc.)
42
43
Returns
44
-------
45
AuxReader class
46
Appropriate auxiliary reader class for the format
47
48
Examples
49
--------
50
>>> Reader = get_auxreader_for('data.xvg')
51
>>> Reader = get_auxreader_for(format='XVG-F')
52
"""
53
54
def auxreader(auxdata, format=None, **kwargs):
55
"""
56
Create an auxiliary reader instance for auxiliary data.
57
58
Parameters
59
----------
60
auxdata : str or file-like
61
Auxiliary data source (filename, file object, etc.)
62
format : str, optional
63
Format of auxiliary data if known
64
**kwargs
65
Additional options passed to auxiliary reader
66
67
Returns
68
-------
69
AuxReader instance
70
Configured auxiliary reader for the data
71
72
Examples
73
--------
74
>>> aux = auxreader('pullforce.xvg', dt=2.0)
75
>>> aux = auxreader('energy.edr', format='EDR')
76
"""
77
```
78
79
### XVG Format Support
80
81
Support for Gromacs XVG files with multiple reading strategies.
82
83
```python { .api }
84
class XVGReader(AuxReader):
85
"""
86
Auxiliary reader for XVG files (Gromacs output format).
87
88
Reads entire file into memory on initialization for fast access.
89
"""
90
91
def __init__(self, filename, **kwargs):
92
"""
93
Create XVG auxiliary reader.
94
95
Parameters
96
----------
97
filename : str
98
Path to XVG file
99
**kwargs
100
Additional auxiliary reader options:
101
- dt : float, time step between data points
102
- initial_time : float, time of first data point
103
- time_selector : int, column index for time data
104
- data_selector : int or list, column index(es) for data
105
"""
106
107
class XVGFileReader(AuxFileReader):
108
"""
109
File-based XVG reader with lower memory footprint.
110
111
Reads data step-by-step from file rather than loading all into memory.
112
"""
113
114
def __init__(self, filename, **kwargs):
115
"""
116
Create file-based XVG auxiliary reader.
117
118
Parameters
119
----------
120
filename : str
121
Path to XVG file
122
**kwargs
123
Additional auxiliary reader options
124
"""
125
```
126
127
### EDR Format Support
128
129
Support for Gromacs EDR (energy) files.
130
131
```python { .api }
132
class EDRReader(AuxReader):
133
"""
134
Auxiliary reader for EDR files (Gromacs energy format).
135
136
Requires optional dependency: pyedr
137
"""
138
139
def __init__(self, filename, **kwargs):
140
"""
141
Create EDR auxiliary reader.
142
143
Parameters
144
----------
145
filename : str
146
Path to EDR file
147
**kwargs
148
Additional auxiliary reader options
149
"""
150
```
151
152
### Base Auxiliary Classes
153
154
Core classes that all auxiliary readers inherit from.
155
156
```python { .api }
157
class AuxReader:
158
"""
159
Base class for auxiliary data readers.
160
"""
161
162
def __init__(self, auxdata, **kwargs):
163
"""
164
Initialize auxiliary reader.
165
166
Parameters
167
----------
168
auxdata
169
Source of auxiliary data
170
auxname : str, optional
171
Name for auxiliary data in trajectory
172
represent_ts_as : str, optional
173
Method for calculating representative values ('closest', 'average')
174
cutoff : float, optional
175
Cutoff time for auxiliary step assignment (ps)
176
dt : float, optional
177
Time step between auxiliary data points (ps)
178
initial_time : float, optional
179
Time of first auxiliary step (ps)
180
time_selector : optional
181
Key for selecting time from auxiliary data
182
data_selector : optional
183
Key(s) for selecting data values from auxiliary data
184
"""
185
186
def __len__(self):
187
"""Return number of auxiliary steps."""
188
189
def __iter__(self):
190
"""Iterate over auxiliary steps."""
191
192
def __getitem__(self, key):
193
"""Access specific auxiliary step(s)."""
194
195
def next(self):
196
"""Advance to next auxiliary step."""
197
198
def rewind(self):
199
"""Return to first auxiliary step."""
200
201
def update_ts(self, ts):
202
"""
203
Update trajectory timestep with auxiliary data.
204
205
Parameters
206
----------
207
ts : Timestep
208
Trajectory timestep to update
209
210
Returns
211
-------
212
Timestep
213
Updated timestep with auxiliary data
214
"""
215
216
def step_to_frame(self, step, ts, return_time_diff=False):
217
"""
218
Convert auxiliary step number to trajectory frame.
219
220
Parameters
221
----------
222
step : int
223
Auxiliary step number
224
ts : Timestep
225
Trajectory timestep for reference
226
return_time_diff : bool, optional
227
Whether to return time difference
228
229
Returns
230
-------
231
int or tuple
232
Frame number, optionally with time difference
233
"""
234
235
def get_description(self):
236
"""
237
Get description dictionary for recreating auxiliary.
238
239
Returns
240
-------
241
dict
242
Dictionary of attributes needed to recreate auxiliary
243
"""
244
245
class AuxStep:
246
"""
247
Container for auxiliary data at a single step.
248
"""
249
250
@property
251
def step(self):
252
"""Current auxiliary step (0-based)."""
253
254
@property
255
def time(self):
256
"""Time of current step (ps)."""
257
258
@property
259
def data(self):
260
"""Auxiliary data values for current step."""
261
262
@property
263
def _data(self):
264
"""Raw data for current step (all columns/values)."""
265
266
class AuxFileReader(AuxReader):
267
"""
268
Base class for file-based auxiliary readers.
269
270
Extends AuxReader with file handling capabilities.
271
"""
272
273
def close(self):
274
"""Close auxiliary file."""
275
276
def _reopen(self):
277
"""Close and reopen auxiliary file."""
278
```
279
280
## Usage Examples
281
282
### Basic Auxiliary Data Reading
283
284
```python
285
import MDAnalysis as mda
286
from MDAnalysis.auxiliary import auxreader
287
288
# Load auxiliary data
289
aux = auxreader('pullforce.xvg')
290
291
# Iterate through auxiliary steps
292
for auxstep in aux:
293
print(f"Step {auxstep.step}: Time {auxstep.time}, Data {auxstep.data}")
294
295
# Access specific steps
296
aux[100] # Go to step 100
297
aux[100:200:10] # Steps 100-200 with step size 10
298
```
299
300
### Adding Auxiliary Data to Trajectories
301
302
```python
303
import MDAnalysis as mda
304
305
# Create universe
306
u = mda.Universe('topology.pdb', 'trajectory.xtc')
307
308
# Add auxiliary data to trajectory
309
u.trajectory.add_auxiliary('pullforce', 'pull_force.xvg')
310
u.trajectory.add_auxiliary('energy', 'energy.edr')
311
312
# Access auxiliary data during trajectory iteration
313
for ts in u.trajectory:
314
pullforce_value = ts.aux.pullforce
315
energy_value = ts.aux.energy
316
print(f"Frame {ts.frame}: Pull force = {pullforce_value}")
317
```
318
319
### Auxiliary Data Management
320
321
```python
322
# Check auxiliary attributes
323
dt = u.trajectory.get_aux_attribute('pullforce', 'dt')
324
n_steps = u.trajectory.get_aux_attribute('pullforce', 'n_steps')
325
326
# Modify auxiliary settings
327
u.trajectory.set_aux_attribute('pullforce', 'data_selector', [1, 2])
328
329
# Rename auxiliary
330
u.trajectory.rename_aux('pullforce', 'pullf')
331
332
# Remove auxiliary
333
u.trajectory.remove_auxiliary('energy')
334
```
335
336
### Iteration Control with Auxiliary Data
337
338
```python
339
# Iterate only over frames with auxiliary data
340
for ts in u.trajectory.iter_as_aux('pullforce'):
341
# Guaranteed to have auxiliary data (no np.nan values)
342
force = ts.aux.pullforce
343
344
# Iterate over auxiliary data independently
345
for auxstep in u.trajectory.iter_auxiliary('pullforce', start=100, step=10):
346
# Every 10th auxiliary step starting from 100
347
process_auxiliary_data(auxstep)
348
```
349
350
### Auxiliary Data Format-Specific Options
351
352
```python
353
# XVG with specific time and data columns
354
xvg_aux = auxreader('data.xvg', time_selector=0, data_selector=[1, 2, 3])
355
356
# EDR energy file
357
edr_aux = auxreader('ener.edr', format='EDR')
358
359
# Low-memory XVG reading
360
xvg_file_aux = auxreader('large_data.xvg', format='XVG-F')
361
362
# Custom time step and initial time
363
custom_aux = auxreader('custom.dat', dt=0.5, initial_time=1000.0)
364
```
365
366
### Recreating Auxiliary Readers
367
368
```python
369
# Get description for later recreation
370
description = aux.get_description()
371
372
# Recreate auxiliary from description
373
new_aux = auxreader(**description)
374
375
# Get descriptions for all trajectory auxiliaries
376
descriptions = u.trajectory.get_aux_descriptions()
377
378
# Reload auxiliaries to new trajectory
379
for desc in descriptions:
380
new_u.trajectory.add_auxiliary(**desc)
381
```
382
383
## Supported File Formats
384
385
| Format | Class | Extension | Description |
386
|--------|-------|-----------|-------------|
387
| XVG | XVGReader | .xvg | Gromacs XVG files (default, memory-based) |
388
| XVG-F | XVGFileReader | .xvg | Gromacs XVG files (file-based, low memory) |
389
| EDR | EDRReader | .edr | Gromacs energy files (requires pyedr) |
390
391
## Integration with Analysis
392
393
Auxiliary data integrates seamlessly with MDAnalysis analysis workflows:
394
395
```python
396
from MDAnalysis.analysis.base import AnalysisBase
397
398
class AuxiliaryAnalysis(AnalysisBase):
399
def __init__(self, atomgroup, aux_name):
400
super().__init__(atomgroup.universe.trajectory)
401
self.atomgroup = atomgroup
402
self.aux_name = aux_name
403
404
def _single_frame(self):
405
# Access auxiliary data in analysis
406
aux_value = self._ts.aux[self.aux_name]
407
com = self.atomgroup.center_of_mass()
408
return aux_value, com
409
410
# Run analysis with auxiliary data
411
analysis = AuxiliaryAnalysis(protein, 'pullforce')
412
analysis.run()
413
```