mdanalysis/mdanalysis

MDAnalysis is a Python library to analyze molecular dynamics simulations.

1,566 stars Python 8 components

12 hidden assumptions · 8-stage pipeline · 8 components

Like any codebase, this scientific computing makes assumptions it never checks — most are routine. The ones worth your attention are below.

Loads molecular dynamics trajectories and analyzes atom coordinates using NumPy arrays

Users create a Universe by loading topology and trajectory files through format-specific parsers that extract molecular structure and coordinate data. The Universe provides AtomGroups for atom selection, which are passed to analysis classes that inherit from AnalysisBase. During analysis execution, the system iterates through trajectory frames, applies analysis algorithms to atomic coordinates, and accumulates results in time-series arrays accessible after completion.

Under the hood, the system uses 2 feedback loops, 3 data pools, 3 control points to manage its runtime behavior.

A 8-component scientific computing. 453 files analyzed. Data flows through 8 distinct pipeline stages.

Hidden Assumptions

Most of what this code assumes is routine. These 3 are the ones most likely to cause trouble here. The rest are minor; they're under "Show everything".

Worth your attention first

If atom counts differ, NumPy broadcasting will fail with dimension mismatch errors, or if counts match but atom ordering differs, the alignment will compute rotation matrices based on wrong atom correspondences, producing meaningless RMSD values and incorrect structural alignments

Worth your attention first

If trajectory coordinates are in nanometers but reference structure is in Angstroms (common with different MD packages), contact fractions will be completely wrong - a 4.5 Angstrom cutoff becomes 4.5 nanometers, missing most real contacts and detecting spurious long-range contacts

Worth your attention first

If _single_frame() calls trajectory.next() or changes the current frame, the iteration logic breaks, causing frames to be skipped or processed multiple times, leading to incorrect time-series data in results.times and analysis metrics

Show everything (9 more)
Resource

All AtomGroup objects and analysis parameters can be successfully pickled for inter-process communication - the multiprocessing backend serializes the entire analysis state to worker processes

If this fails: If AtomGroups contain unpicklable objects (like lambda functions in custom selections or certain topology attributes), multiprocessing will fail with PicklingError, forcing fallback to serial execution without warning the user about the performance degradation

package/MDAnalysis/analysis/backends.py:BackendMultiprocessing
Temporal

Trajectory frames are accessed in sequential order during analysis - caching mechanisms expect forward iteration and may not handle random access efficiently

If this fails: If analysis algorithms jump between non-consecutive frames (like comparing frame 1000 to frame 10), the trajectory cache becomes ineffective, causing repeated disk I/O that can slow analysis by 10-100x for large trajectory files

package/MDAnalysis/coordinates/base.py:TrajectoryReader
Scale

Atomic coordinate arrays will fit in available memory as contiguous NumPy arrays - positions property returns the full coordinate array of shape (n_atoms, 3) for all atoms in the group

If this fails: For large systems (>1M atoms), coordinate arrays can exceed 24GB memory, causing MemoryError crashes during analysis. This hits protein complexes, membrane systems, and solvated systems without warning as array size scales with system complexity

package/MDAnalysis/core/groups.py:AtomGroup.positions
Ordering

Atom ordering in GRO topology files matches the coordinate ordering in trajectory frames - parser creates atom index mappings based on file order without validation

If this fails: If topology and trajectory files have atoms in different orders (possible when files are generated by different tools or preprocessing steps), AtomGroup.positions will return coordinates for wrong atoms, making all spatial analysis incorrect while appearing to work normally

package/MDAnalysis/topology/GROParser.py:parse
Environment

GRO files use standard GROMACS formatting conventions with exact column positions - coordinate parsing depends on fixed-width format assumptions

If this fails: If GRO files are created by non-GROMACS tools with slightly different formatting (different precision, spacing, or column alignment), coordinate parsing will silently read wrong values, corrupting all subsequent analysis without raising parse errors

package/MDAnalysis/coordinates/GRO.py:GROReader
Domain

Periodic boundary conditions (PBC) are consistently applied or ignored across all distance calculations - algorithms assume box dimensions in trajectory frames represent the same coordinate system convention

If this fails: If some trajectory frames have PBC information in different conventions (box matrix vs box vectors) or missing PBC data, distance calculations become inconsistent across frames, causing spurious jumps in contact analysis, RMSD, and other spatial measurements

package/MDAnalysis/lib/distances.py:distance_functions
Contract

The mobile and reference AtomGroups passed to analysis classes belong to compatible Universe objects with the same topology structure - atom indices and properties should correspond between universes

If this fails: If analysis receives AtomGroups from different topology sources (e.g., comparing protein from one simulation to different protein variant), atom index references become invalid, leading to accessing wrong atoms or IndexError crashes during coordinate operations

package/MDAnalysis/analysis/base.py:AnalysisBase.__init__
Temporal

Analysis results accumulate in frame order and the results.times array corresponds directly to the frame indices processed - time values are assumed to be monotonically increasing

If this fails: If trajectory frames have non-monotonic timestamps (from concatenated simulations with overlapping times, or restarted runs), the time series analysis becomes meaningless for temporal correlation calculations, and plotting results against time produces confusing non-linear time axes

package/MDAnalysis/analysis/base.py:Results
Scale

The testsuite GRO file size is representative of typical usage patterns for benchmarking - performance measurements use a fixed small test system

If this fails: Benchmark results may not reflect real-world performance for large systems (>100K atoms) where memory allocation patterns, I/O bottlenecks, and parsing complexity scale non-linearly, potentially misleading users about expected performance on production datasets

benchmarks/benchmarks/GRO.py:time_create_GRO_universe

Open the standalone hidden-assumptions report for mdanalysis →

How Data Flows Through the System

Users create a Universe by loading topology and trajectory files through format-specific parsers that extract molecular structure and coordinate data. The Universe provides AtomGroups for atom selection, which are passed to analysis classes that inherit from AnalysisBase. During analysis execution, the system iterates through trajectory frames, applies analysis algorithms to atomic coordinates, and accumulates results in time-series arrays accessible after completion.

  1. Load trajectory files — Format-specific parsers (GROParser, PDBParser, etc.) read molecular dynamics files to extract topology information (atom names, connectivity, residues) and coordinate data, creating TopologyData and TrajectoryFrame objects that represent the molecular system
  2. Create Universe — Universe.__init__() combines topology and trajectory data into a unified interface, setting up the coordinate reader, establishing atom-residue relationships, and preparing the system for frame iteration and analysis [TopologyData → Universe]
  3. Atom selection — Users apply selection strings (e.g., 'protein and name CA') to Universe.select_atoms(), which parses the query and returns AtomGroup objects containing the matching atoms with their properties and coordinate access methods [Universe → AtomGroup]
  4. Create analysis objects — Analysis classes (Contacts, AlignTraj, RMSD) are instantiated with AtomGroup arguments and analysis parameters, inheriting from AnalysisBase to gain trajectory iteration and results storage capabilities [AtomGroup → AnalysisBase]
  5. Analysis execution — AnalysisBase.run() iterates through trajectory frames, calling _single_frame() for each timestep to compute analysis metrics (distances, angles, contacts) using NumPy operations on atomic coordinates, with optional parallelization via BackendMultiprocessing [AnalysisBase → AnalysisResults]
  6. Access coordinate frames — During analysis, TrajectoryReader provides TrajectoryFrame objects containing positions, velocities, and box dimensions for each timestep, allowing algorithms to access current atomic coordinates through AtomGroup.positions arrays [Universe → TrajectoryFrame]
  7. Analysis calculations — Individual analysis algorithms compute structural properties by applying mathematical operations to coordinate arrays - distance calculations use lib.distances functions, alignment uses QCP algorithm for rotation matrices, contacts use distance thresholds [TrajectoryFrame → AnalysisResults]
  8. Results storage — Computed metrics are accumulated in AnalysisResults containers with time-series arrays (rmsd, contact_fractions, etc.) that can be accessed as analysis.results.attribute_name after run() completion [AnalysisResults]

Data Models

The data structures that flow between stages — the contracts that hold the system together.

Universe package/MDAnalysis/core/universe.py
container with atoms: AtomGroup, trajectory: TrajectoryReader, dimensions: ndarray[6] (box dimensions), and topology information including bonds, angles, dihedrals
Created by parsing topology and coordinate files, provides interface to iterate through trajectory frames and access atomic data throughout analysis workflows
AtomGroup package/MDAnalysis/core/groups.py
collection with positions: ndarray[N, 3], masses: ndarray[N], names: ndarray[N] (dtype=str), residues: ResidueGroup, and selection methods returning new AtomGroups
Created through atom selection strings or indexing operations on Universe, provides NumPy array access to atomic properties and coordinates for analysis computations
AnalysisResults package/MDAnalysis/analysis/base.py
dictionary-like container with times: ndarray[n_frames], computed metrics as ndarrays (e.g., rmsd: ndarray[n_frames], distances: ndarray[n_frames, n_pairs]), and metadata
Populated during AnalysisBase.run() execution by calling _single_frame() for each trajectory frame, stores time-series data accessible after analysis completion
TrajectoryFrame package/MDAnalysis/coordinates/base.py
snapshot with positions: ndarray[N, 3], velocities: ndarray[N, 3] (optional), forces: ndarray[N, 3] (optional), dimensions: ndarray[6] (box), time: float, frame: int
Created by TrajectoryReader when iterating through frames, represents single time snapshot of molecular system with all atomic coordinates and simulation metadata
TopologyData package/MDAnalysis/topology/core.py
structured data with atoms: dict (names, types, masses, charges), bonds: ndarray[n_bonds, 2], angles: ndarray[n_angles, 3], residues: dict (names, numbers), and connectivity information
Extracted from topology files (PSF, TPR, PDB) by format-specific parsers, provides static structural information about molecular connectivity and atom properties

System Behavior

How the system operates at runtime — where data accumulates, what loops, what waits, and what controls what.

Data Pools

TrajectoryCache (buffer)
Caches recently accessed trajectory frames to avoid repeated file I/O when analysis algorithms access the same frames multiple times
TopologyRegistry (registry)
Maps file extensions to appropriate topology parser classes, enabling automatic parser selection based on file format during Universe creation
TestDataFiles (file-store)
Collection of reference molecular dynamics files used for testing parsers and validating analysis results across different file formats and molecular systems

Feedback Loops

Delays

Control Points

Technology Stack

NumPy (compute)
Provides ndarray data structures for atomic coordinates and vectorized mathematical operations for distance calculations, alignment algorithms, and structural analysis
pytest (testing)
Testing framework used throughout the testsuite package to validate file parsers, analysis algorithms, and coordinate transformations with parametrized test cases
multiprocessing (compute)
Enables parallel analysis execution by distributing trajectory frame processing across multiple worker processes for computationally intensive analysis algorithms
Dask (compute)
Alternative parallelization backend that provides distributed computing capabilities with different serialization algorithms compared to standard multiprocessing

Key Components

Package Structure

MDAnalysis (library)
Python library for analyzing molecular dynamics simulation trajectories, providing parsers, coordinate readers, and analysis tools for computational chemistry.
MDAnalysisTests (shared)
Comprehensive test suite for MDAnalysis with benchmarks and validation tests for all analysis modules and file format parsers.

Explore the interactive analysis

See the full architecture map, data flow, and code patterns visualization.

Analyze on CodeSea

Related Scientific Computing Repositories

Frequently Asked Questions

What is mdanalysis used for?

Loads molecular dynamics trajectories and analyzes atom coordinates using NumPy arrays mdanalysis/mdanalysis is a 8-component scientific computing written in Python. Data flows through 8 distinct pipeline stages. The codebase contains 453 files.

How is mdanalysis architected?

mdanalysis is organized into 4 architecture layers: File Format Layer, Core Data Layer, Analysis Layer, Test Layer. Data flows through 8 distinct pipeline stages. This layered structure keeps concerns separated and modules independent.

How does data flow through mdanalysis?

Data moves through 8 stages: Load trajectory files → Create Universe → Atom selection → Create analysis objects → Analysis execution → .... Users create a Universe by loading topology and trajectory files through format-specific parsers that extract molecular structure and coordinate data. The Universe provides AtomGroups for atom selection, which are passed to analysis classes that inherit from AnalysisBase. During analysis execution, the system iterates through trajectory frames, applies analysis algorithms to atomic coordinates, and accumulates results in time-series arrays accessible after completion. This pipeline design reflects a complex multi-stage processing system.

What technologies does mdanalysis use?

The core stack includes NumPy (Provides ndarray data structures for atomic coordinates and vectorized mathematical operations for distance calculations, alignment algorithms, and structural analysis), pytest (Testing framework used throughout the testsuite package to validate file parsers, analysis algorithms, and coordinate transformations with parametrized test cases), multiprocessing (Enables parallel analysis execution by distributing trajectory frame processing across multiple worker processes for computationally intensive analysis algorithms), Dask (Alternative parallelization backend that provides distributed computing capabilities with different serialization algorithms compared to standard multiprocessing). A lean dependency footprint.

What system dynamics does mdanalysis have?

mdanalysis exhibits 3 data pools (TrajectoryCache, TopologyRegistry), 2 feedback loops, 3 control points, 2 delays. The feedback loops handle training-loop and convergence. These runtime behaviors shape how the system responds to load, failures, and configuration changes.

What design patterns does mdanalysis use?

4 design patterns detected: Format Registry Pattern, Template Method Pattern, Facade Pattern, Strategy Pattern.

Analyzed on April 20, 2026 by CodeSea. Written by .