An object-oriented toolkit to analyze molecular dynamics trajectories.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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.
Auxiliary data in MDAnalysis allows for:
import MDAnalysis.auxiliary as aux
# Direct imports for specific formats
from MDAnalysis.auxiliary import XVG, EDR
from MDAnalysis.auxiliary.core import auxreader, get_auxreader_for
# Base classes
from MDAnalysis.auxiliary.base import AuxReader, AuxStep, AuxFileReaderFunctions for automatically selecting and creating appropriate auxiliary readers.
def get_auxreader_for(auxdata=None, format=None):
"""
Return the appropriate auxiliary reader class for auxiliary data.
Parameters
----------
auxdata : str or file-like, optional
Auxiliary data source (filename, file object, etc.)
format : str, optional
Known format of auxiliary data ('XVG', 'EDR', etc.)
Returns
-------
AuxReader class
Appropriate auxiliary reader class for the format
Examples
--------
>>> Reader = get_auxreader_for('data.xvg')
>>> Reader = get_auxreader_for(format='XVG-F')
"""
def auxreader(auxdata, format=None, **kwargs):
"""
Create an auxiliary reader instance for auxiliary data.
Parameters
----------
auxdata : str or file-like
Auxiliary data source (filename, file object, etc.)
format : str, optional
Format of auxiliary data if known
**kwargs
Additional options passed to auxiliary reader
Returns
-------
AuxReader instance
Configured auxiliary reader for the data
Examples
--------
>>> aux = auxreader('pullforce.xvg', dt=2.0)
>>> aux = auxreader('energy.edr', format='EDR')
"""Support for Gromacs XVG files with multiple reading strategies.
class XVGReader(AuxReader):
"""
Auxiliary reader for XVG files (Gromacs output format).
Reads entire file into memory on initialization for fast access.
"""
def __init__(self, filename, **kwargs):
"""
Create XVG auxiliary reader.
Parameters
----------
filename : str
Path to XVG file
**kwargs
Additional auxiliary reader options:
- dt : float, time step between data points
- initial_time : float, time of first data point
- time_selector : int, column index for time data
- data_selector : int or list, column index(es) for data
"""
class XVGFileReader(AuxFileReader):
"""
File-based XVG reader with lower memory footprint.
Reads data step-by-step from file rather than loading all into memory.
"""
def __init__(self, filename, **kwargs):
"""
Create file-based XVG auxiliary reader.
Parameters
----------
filename : str
Path to XVG file
**kwargs
Additional auxiliary reader options
"""Support for Gromacs EDR (energy) files.
class EDRReader(AuxReader):
"""
Auxiliary reader for EDR files (Gromacs energy format).
Requires optional dependency: pyedr
"""
def __init__(self, filename, **kwargs):
"""
Create EDR auxiliary reader.
Parameters
----------
filename : str
Path to EDR file
**kwargs
Additional auxiliary reader options
"""Core classes that all auxiliary readers inherit from.
class AuxReader:
"""
Base class for auxiliary data readers.
"""
def __init__(self, auxdata, **kwargs):
"""
Initialize auxiliary reader.
Parameters
----------
auxdata
Source of auxiliary data
auxname : str, optional
Name for auxiliary data in trajectory
represent_ts_as : str, optional
Method for calculating representative values ('closest', 'average')
cutoff : float, optional
Cutoff time for auxiliary step assignment (ps)
dt : float, optional
Time step between auxiliary data points (ps)
initial_time : float, optional
Time of first auxiliary step (ps)
time_selector : optional
Key for selecting time from auxiliary data
data_selector : optional
Key(s) for selecting data values from auxiliary data
"""
def __len__(self):
"""Return number of auxiliary steps."""
def __iter__(self):
"""Iterate over auxiliary steps."""
def __getitem__(self, key):
"""Access specific auxiliary step(s)."""
def next(self):
"""Advance to next auxiliary step."""
def rewind(self):
"""Return to first auxiliary step."""
def update_ts(self, ts):
"""
Update trajectory timestep with auxiliary data.
Parameters
----------
ts : Timestep
Trajectory timestep to update
Returns
-------
Timestep
Updated timestep with auxiliary data
"""
def step_to_frame(self, step, ts, return_time_diff=False):
"""
Convert auxiliary step number to trajectory frame.
Parameters
----------
step : int
Auxiliary step number
ts : Timestep
Trajectory timestep for reference
return_time_diff : bool, optional
Whether to return time difference
Returns
-------
int or tuple
Frame number, optionally with time difference
"""
def get_description(self):
"""
Get description dictionary for recreating auxiliary.
Returns
-------
dict
Dictionary of attributes needed to recreate auxiliary
"""
class AuxStep:
"""
Container for auxiliary data at a single step.
"""
@property
def step(self):
"""Current auxiliary step (0-based)."""
@property
def time(self):
"""Time of current step (ps)."""
@property
def data(self):
"""Auxiliary data values for current step."""
@property
def _data(self):
"""Raw data for current step (all columns/values)."""
class AuxFileReader(AuxReader):
"""
Base class for file-based auxiliary readers.
Extends AuxReader with file handling capabilities.
"""
def close(self):
"""Close auxiliary file."""
def _reopen(self):
"""Close and reopen auxiliary file."""import MDAnalysis as mda
from MDAnalysis.auxiliary import auxreader
# Load auxiliary data
aux = auxreader('pullforce.xvg')
# Iterate through auxiliary steps
for auxstep in aux:
print(f"Step {auxstep.step}: Time {auxstep.time}, Data {auxstep.data}")
# Access specific steps
aux[100] # Go to step 100
aux[100:200:10] # Steps 100-200 with step size 10import MDAnalysis as mda
# Create universe
u = mda.Universe('topology.pdb', 'trajectory.xtc')
# Add auxiliary data to trajectory
u.trajectory.add_auxiliary('pullforce', 'pull_force.xvg')
u.trajectory.add_auxiliary('energy', 'energy.edr')
# Access auxiliary data during trajectory iteration
for ts in u.trajectory:
pullforce_value = ts.aux.pullforce
energy_value = ts.aux.energy
print(f"Frame {ts.frame}: Pull force = {pullforce_value}")# Check auxiliary attributes
dt = u.trajectory.get_aux_attribute('pullforce', 'dt')
n_steps = u.trajectory.get_aux_attribute('pullforce', 'n_steps')
# Modify auxiliary settings
u.trajectory.set_aux_attribute('pullforce', 'data_selector', [1, 2])
# Rename auxiliary
u.trajectory.rename_aux('pullforce', 'pullf')
# Remove auxiliary
u.trajectory.remove_auxiliary('energy')# Iterate only over frames with auxiliary data
for ts in u.trajectory.iter_as_aux('pullforce'):
# Guaranteed to have auxiliary data (no np.nan values)
force = ts.aux.pullforce
# Iterate over auxiliary data independently
for auxstep in u.trajectory.iter_auxiliary('pullforce', start=100, step=10):
# Every 10th auxiliary step starting from 100
process_auxiliary_data(auxstep)# XVG with specific time and data columns
xvg_aux = auxreader('data.xvg', time_selector=0, data_selector=[1, 2, 3])
# EDR energy file
edr_aux = auxreader('ener.edr', format='EDR')
# Low-memory XVG reading
xvg_file_aux = auxreader('large_data.xvg', format='XVG-F')
# Custom time step and initial time
custom_aux = auxreader('custom.dat', dt=0.5, initial_time=1000.0)# Get description for later recreation
description = aux.get_description()
# Recreate auxiliary from description
new_aux = auxreader(**description)
# Get descriptions for all trajectory auxiliaries
descriptions = u.trajectory.get_aux_descriptions()
# Reload auxiliaries to new trajectory
for desc in descriptions:
new_u.trajectory.add_auxiliary(**desc)| Format | Class | Extension | Description |
|---|---|---|---|
| XVG | XVGReader | .xvg | Gromacs XVG files (default, memory-based) |
| XVG-F | XVGFileReader | .xvg | Gromacs XVG files (file-based, low memory) |
| EDR | EDRReader | .edr | Gromacs energy files (requires pyedr) |
Auxiliary data integrates seamlessly with MDAnalysis analysis workflows:
from MDAnalysis.analysis.base import AnalysisBase
class AuxiliaryAnalysis(AnalysisBase):
def __init__(self, atomgroup, aux_name):
super().__init__(atomgroup.universe.trajectory)
self.atomgroup = atomgroup
self.aux_name = aux_name
def _single_frame(self):
# Access auxiliary data in analysis
aux_value = self._ts.aux[self.aux_name]
com = self.atomgroup.center_of_mass()
return aux_value, com
# Run analysis with auxiliary data
analysis = AuxiliaryAnalysis(protein, 'pullforce')
analysis.run()Install with Tessl CLI
npx tessl i tessl/pypi-mdanalysis