Skip to main content

mdanalysis

Comprehensive guide for MDAnalysis - the Python library for analyzing molecular dynamics trajectories. Use for trajectory loading, RMSD/RMSF calculations, distance/angle/dihedral analysis, atom selections, hydrogen bonds, solvent accessible surface area, protein structure analysis, membrane analysis, and integration with Biopython. Essential for MD simulation analysis.

来源信息

仓库
tondevrel/scientific-agent-skills
最近来源活动
2026年2月1日 04:41
检测到的 SKILL.md 语言
英语
星标
22
分支
2

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
mdanalysis
description
Comprehensive guide for MDAnalysis - the Python library for analyzing molecular dynamics trajectories. Use for trajectory loading, RMSD/RMSF calculations, distance/angle/dihedral analysis, atom selections, hydrogen bonds, solvent accessible surface area, protein structure analysis, membrane analysis, and integration with Biopython. Essential for MD simulation analysis.
version
2.7
license
GPL-2.0
# MDAnalysis - Molecular Dynamics Analysis Python library for reading, writing, and analyzing molecular dynamics trajectories and structural files. ## When to Use - Loading MD trajectories (DCD, XTC, TRR, NetCDF, etc.) - RMSD and RMSF calculations - Distance, angle, and dihedral analysis - Atom selections (VMD-like syntax) - Hydrogen bond analysis - Solvent Accessible Surface Area (SASA) - Protein secondary structure analysis - Membrane system analysis - Water/ion distribution analysis - Trajectory alignment and fitting - Custom trajectory analysis - Converting between file formats ## Reference Documentation **Official docs**: https://www.mdanalysis.org/docs/ **Search patterns**: `MDAnalysis.Universe`, `MDAnalysis.analysis.rms`, `MDAnalysis.analysis.distances` ## Core Principles ### Use MDAnalysis For | Task | Module | Example | |------|--------|---------| | Load trajectory | `Universe` | `Universe(topology, trajectory)` | | RMSD calculation | `analysis.rms` | `RMSD(mobile, ref)` | | Atom selection | `select_atoms` | `u.select_atoms('protein')` | | Distance analysis | `analysis.distances` | `distance_array(pos1, pos2)` | | H-bond analysis | `analysis.hbonds` | `HydrogenBondAnalysis()` | | SASA calculation | `analysis.sasa` | `SASAnalysis()` | | Contacts analysis | `analysis.contacts` | `Contacts()` | | Trajectory writing | `Writer` | `with Writer() as W` | ### Do NOT Use For - Running MD simulations (use GROMACS, AMBER, NAMD) - Force field calculations (use OpenMM, MDTraj) - Quantum chemistry (use PySCF, Qiskit) - Protein structure prediction (use AlphaFold, RosettaFold) - Initial structure building (use Biopython, PyMOL) ## Quick Reference ### Installation ```bash # pip pip install MDAnalysis # With additional analysis modules pip install MDAnalysis[analysis] # conda conda install -c conda-forge mdanalysis # Development version pip install git+https://github.com/MDAnalysis/mdanalysis.git ``` ### Standard Imports ```python # Core imports import MDAnalysis as mda from MDAnalysis import Universe from MDAnalysis.analysis import rms, align, distances # Common analysis modules from MDAnalysis.analysis.rms import RMSD, RMSF from MDAnalysis.analysis.distances import distance_array from MDAnalysis.analysis.hydrogenbonds.hbond_analysis import HydrogenBondAnalysis from MDAnalysis.analysis.dihedrals import Dihedral # Utilities import numpy as np import matplotlib.pyplot as plt ``` ### Basic Pattern - Load and Analyze ```python import MDAnalysis as mda from MDAnalysis.analysis.rms import RMSD # Load trajectory u = mda.Universe('topology.pdb', 'trajectory.dcd') # Select atoms protein = u.select_atoms('protein') ca_atoms = u.select_atoms('protein and name CA') # Calculate RMSD rmsd_analysis = RMSD(protein, protein, select='backbone') rmsd_analysis.run() # Access results rmsd = rmsd_analysis.results.rmsd print(f"RMSD over time: {rmsd[:, 2]}") # Column 2 is RMSD ``` ### Basic Pattern - Atom Selection ```python import MDAnalysis as mda u = mda.Universe('structure.pdb') # Various selections (VMD-like syntax) protein = u.select_atoms('protein') backbone = u.select_atoms('backbone') ca = u.select_atoms('name CA') resid_10 = u.select_atoms('resid 10') within_5A = u.select_atoms('around 5 resid 10') water = u.select_atoms('resname WAT or resname HOH') print(f"Number of protein atoms: {len(protein)}") print(f"Number of CA atoms: {len(ca)}") ``` ## Critical Rules ### ✅ DO - **Close trajectory files** - Use context managers or close explicitly - **Use atom selections efficiently** - Cache selections for reuse - **Check trajectory length** - Verify n_frames before analysis - **Use vectorized operations** - Leverage NumPy for speed - **Align trajectories** - Align before RMSD calculations - **Handle periodic boundaries** - Use PBC-aware distance calculations - **Validate atom groups** - Check empty selections - **Use appropriate frames** - Slice trajectories if needed - **Save intermediate results** - Don't recompute expensive calculations - **Check units** - MDAnalysis uses Angstroms and picoseconds ### ❌ DON'T - **Load entire trajectory in memory** - Stream through frames - **Ignore PBC** - Always consider periodic boundary conditions - **Forget to align** - RMSD without alignment is meaningless - **Use wrong atom names** - Check topology for correct names - **Mix coordinate systems** - Be consistent with units - **Ignore missing atoms** - Handle incomplete residues - **Recompute unnecessarily** - Cache expensive calculations - **Use string selections in loops** - Parse once, reuse - **Forget to unwrap coordinates** - Handle molecules split by PBC - **Ignore memory limits** - Process large trajectories in chunks ## Anti-Patterns (NEVER) ```python import MDAnalysis as mda import numpy as np # ❌ BAD: Loading entire trajectory in memory u = mda.Universe('top.pdb', 'traj.dcd') all_coords = [] for ts in u.trajectory: all_coords.append(u.atoms.positions.copy()) all_coords = np.array(all_coords) # Huge memory usage! # ✅ GOOD: Process frame by frame u = mda.Universe('top.pdb', 'traj.dcd') for ts in u.trajectory: # Process current frame coords = u.atoms.positions # Do analysis... # Move to next frame automatically # ❌ BAD: RMSD without alignment rmsd_values = [] for ts in u.trajectory: rmsd = rms.rmsd(mobile.positions, reference.positions) rmsd_values.append(rmsd) # Wrong! Not aligned! # ✅ GOOD: Align before RMSD from MDAnalysis.analysis.rms import RMSD R = RMSD(mobile, reference, select='backbone') R.run() rmsd_values = R.results.rmsd[:, 2] # ❌ BAD: Creating selection in loop for ts in u.trajectory: ca = u.select_atoms('name CA') # Parsed every frame! # Do something with ca # ✅ GOOD: Create selection once ca = u.select_atoms('name CA') for ts in u.trajectory: # Use ca (automatically updated each frame) positions = ca.positions # ❌ BAD: Ignoring periodic boundaries distance = np.linalg.norm(atom1.position - atom2.position) # ✅ GOOD: PBC-aware distance from MDAnalysis.lib.distances import distance_array dist = distance_array( atom1.position[np.newaxis, :], atom2.position[np.newaxis, :], box=u.dimensions )[0, 0] # ❌ BAD: Not checking for empty selections selection = u.select_atoms('resname XYZ') # Continue without checking if selection is empty! avg_pos = selection.center_of_mass() # May crash! # ✅ GOOD: Validate selections selection = u.select_atoms('resname XYZ') if len(selection) == 0: print("Warning: No atoms found matching selection") else: avg_pos = selection.center_of_mass() ``` ## Loading Trajectories (Universe) ### Basic Universe Creation ```python import MDAnalysis as mda # Single structure file u = mda.Universe('protein.pdb') # Topology + trajectory u = mda.Universe('topology.pdb', 'trajectory.dcd') # Multiple trajectories (concatenated) u = mda.Universe('top.pdb', 'traj1.dcd', 'traj2.dcd', 'traj3.dcd') # Different formats u = mda.Universe('system.gro', 'traj.xtc') # GROMACS u = mda.Universe('system.psf', 'traj.dcd') # CHARMM/NAMD u = mda.Universe('system.prmtop', 'traj.nc') # AMBER # From memory (numpy arrays) coords = np.random.rand(100, 3) # 100 atoms, xyz u = mda.Universe.empty(100, trajectory=True) u.atoms.positions = coords print(f"Number of atoms: {len(u.atoms)}") print(f"Number of frames: {len(u.trajectory)}") print(f"Total time: {u.trajectory.totaltime} ps") ``` ### Trajectory Information ```python import MDAnalysis as mda u = mda.Universe('topology.pdb', 'trajectory.dcd') # Trajectory properties traj = u.trajectory print(f"Number of frames: {traj.n_frames}") print(f"Time step: {traj.dt} ps") print(f"Total time: {traj.totaltime} ps") # Current frame info print(f"Current frame: {traj.frame}") print(f"Current time: {traj.time} ps") print(f"Box dimensions: {u.dimensions}") # [a, b, c, alpha, beta, gamma] # Iterate through frames for i, ts in enumerate(u.trajectory): if i >= 5: break print(f"Frame {ts.frame}: time = {ts.time:.2f} ps") # Jump to specific frame u.trajectory[100] # Go to frame 100 print(f"Now at frame: {u.trajectory.frame}") # Slice trajectory for ts in u.trajectory[::10]: # Every 10th frame print(f"Frame {ts.frame}") ``` ### Working with Multiple Trajectories ```python import MDAnalysis as mda # Load multiple trajectory files u = mda.Universe('top.pdb', 'part1.dcd', 'part2.dcd', 'part3.dcd') print(f"Total frames from all trajectories: {len(u.trajectory)}") # Or use ChainReader explicitly from MDAnalysis.coordinates.chain import ChainReader trajectories = ['part1.dcd', 'part2.dcd', 'part3.dcd'] u = mda.Universe('top.pdb', trajectories, continuous=True) # Access frame indices for i, ts in enumerate(u.trajectory[::100]): print(f"Global frame {i}: actual frame {ts.frame}, time {ts.time:.2f}") ``` ## Atom Selections ### Basic Selection Syntax ```python import MDAnalysis as mda u = mda.Universe('system.pdb') # Protein selections protein = u.select_atoms('protein') backbone = u.select_atoms('backbone') # N, CA, C mainchain = u.select_atoms('backbone or name O') # Specific residues resid_10 = u.select_atoms('resid 10') resid_range = u.select_atoms('resid 10:20') resid_list = u.select_atoms('resid 10 15 20 25') # Residue names water = u.select_atoms('resname WAT or resname HOH') ions = u.select_atoms('resname NA or resname CL') # Atom names ca_atoms = u.select_atoms('name CA') hydrogens = u.select_atoms('name H*') # Wildcards # By element carbons = u.select_atoms('element C') # Segments seg_a = u.select_atoms('segid A') print(f"Protein atoms: {len(protein)}") print(f"Water molecules: {len(water)}") print(f"CA atoms: {len(ca_atoms)}") ``` ### Advanced Selections ```python import MDAnalysis as mda u = mda.Universe('protein_solvent.pdb') # Geometric selections around_10 = u.select_atoms('around 5.0 protein') # Within 5Å of protein within_box = u.select_atoms('prop x < 50 and prop y < 50') # Spatial queries resid_10 = u.select_atoms('resid 10') near_res10 = u.select_atoms('around 10.0 resid 10 and not resid 10') # Combining selections hydrophobic = u.select_atoms( 'resname ALA or resname VAL or resname LEU or ' 'resname ILE or resname PHE or resname TRP or resname MET' ) charged = u.select_atoms( 'resname ARG or resname LYS or resname ASP or resname GLU' ) # Boolean operations not_protein = u.select_atoms('not protein') protein_no_h = u.select_atoms('protein and not name H*') # By property high_bfactor = u.select_atoms('protein and prop beta > 50') # SMARTS matching (requires RDKit) # aromatic = u.select_atoms('smarts c1ccccc1') print(f"Hydrophobic residues: {len(hydrophobic)}") print(f"Charged residues: {len(charged)}") ``` ### Dynamic Selections ```python import MDAnalysis as mda u = mda.Universe('topology.pdb', 'trajectory.dcd') # Regular selection (static) protein = u.select_atoms('protein') # Dynamic selection (updated each frame) # Example: Select water within 3.5Å of protein water_near_protein = u.select_atoms( 'resname WAT and around 3.5 protein', updating=True ) # Track number of nearby water molecules over time water_counts = [] for ts in u.trajectory: # water_near_protein automatically updates water_counts.append(len(water_near_protein)) print(f"Water molecules near protein per frame:") print(f" Min: {min(water_counts)}") print(f" Max: {max(water_counts)}") print(f" Mean: {sum(water_counts)/len(water_counts):.1f}") # Another example: ions near active site active_site = u.select_atoms('resid 100:110') nearby_ions = u.select_atoms( '(resname NA or resname CL) and around 8.0 resid 100:110', updating=True ) for i, ts in enumerate(u.trajectory[::10]):
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看