Pharmacon

July 14, 2026 · View on GitHub

Pharmacon logo

Pharmacon

A Molecular Dynamics Simulation Analysis Toolkit

A unified command-line toolkit for analyzing molecular-dynamics trajectories and static structures — persisting results as signed, self-describing HDF5 artifacts and producing publication-ready plots.

Developed by Kyriakos Georgiou · 2026

Important

If you use Pharmacon in your research, please cite:

Georgiou, K.; Kolocouris, A. Pharmacon: A Molecular Dynamics Simulation Analysis Toolkit. Journal of Chemical Information and Modeling (2026) · DOI: 10.1021/acs.jcim.6c00837

Python Status Version License Docs Powered by MDAnalysis Powered by RDKit HDF5 h5py NumPy SciPy Matplotlib NetworkX Rich configobj argparse hashlib


Table of Contents


Overview

Pharmacon is a pure-Python, command-line toolkit for analyzing molecular dynamics (MD) simulations of biomacromolecules. It folds the many tedious, time-consuming steps of MD post-processing into a single, automated, and reproducible git-style workflow — making routine analysis faster, more accessible, and easier to reproduce.

Supported MD engines. Pharmacon reads trajectories from the most widely used simulation packages out of the box:

Amber  ·  GROMACS  ·  CHARMM  ·  NAMD  ·  OpenMM

It is built on MDAnalysis for trajectory handling and NumPy for data processing.

What it does. From a single pharmacon command you can:

  • Quantify structural change and flexibility — RMSD, RMSF, distances, and angles
  • Profile non-covalent interactions — protein–ligand and protein–protein (9 interaction types) plus dedicated hydrogen-bond analysis
  • Explore conformational space with PCA — projections, scree plots, and free-energy / probability surfaces
  • Extract amino-acid sequences and compute small-molecule descriptors & fingerprints
  • Aggregate replicate runs with merge, then render publication-ready plots

Every result is persisted as a signed, self-describing HDF5 artifact (.pta / .psa), so analyses stay reproducible and inspectable long after the run — readable with h5py, h5dump, or any HDF5 viewer.

As a proof of concept, Pharmacon was benchmarked against other toolkits on MD simulations of several protein complexes — three membrane proteins and one soluble complex — reproducing their intermolecular-interaction and geometric measures (see the citation above).

Project Architecture

Pharmacon is shipped as a single Python package providing a command-line executable pharmacon that can be used to perform a wide range of analyses on MD simulation trajectories, structures, and more. It follows a strict command-line syntax — similar to git commands and subcommands — ensuring proper argument parsing and validation at every level (see CLI Reference).

The project is organized around the following core modules:

ModuleWhat it does
LoggerStructured terminal and file logging with multiple verbosity levels and colored output.
WorkspaceManages working and temporary directories with automatic cleanup on exit.
File I/OReads and writes signed, self-describing HDF5 files (.pta / .psa).
AnalyzerComputes RMSD, distances, angles, PCA, hydrogen bonds, protein-ligand and protein-protein interactions, sequence extraction, and molecular properties.
PlotterGenerates publication-ready figures (heatmaps, stacked columns, pie charts, scatter plots, time series) directly from analysis artifacts.
CLI DispatcherRoutes commands and subcommands to the appropriate analysis, plotting, or export module.
Plot SettingsProvides a fully customizable settings system driven by simple INI configuration files.
FingerprintGenerates deterministic identity tokens and tamper-detection checksums for every output file.
MergeMerges many Trajectory Analysis (.pta) files into one with std data.

Installation

Requires Python ≥ 3.12. Choose one of the three methods below.

The simplest way to install Pharmacon. This pulls a pre-built wheel from the Python Package Index and installs it along with all required dependencies. It is recommended to create a virtual environment first to avoid conflicts with other packages.

python3.12 -m venv venv         # Create a virtual environment
source venv/bin/activate        # Activate the virtual environment

pip install pharmacon           # Install Pharmacon from PyPI

Option 2 — Install with Conda

Recommended if you prefer managing environments and binary dependencies (especially RDKit and MDAnalysis) through Conda. An environment.yml is provided at the root of the repository.

# Create and activate the environment
conda env create -f environment.yml
conda activate pharmacon

# Install Pharmacon into the environment
pip install pharmacon

Or install directly from conda-forge (Not yet supported):

conda install -c conda-forge pharmacon

Option 3 — Install from source (development)

Clone the repository and install in editable mode. This is the recommended approach for contributors or if you want to stay on the latest development version.

git clone https://github.com/k-georgiou/pharmacon.git
cd pharmacon
python -m venv venv && source venv/bin/activate
pip install -e ".[dev]"   # includes pytest

Run the test suite:

python -m pytest

Verify the installation

After installing via any method, confirm that Pharmacon is available:

pharmacon --help     # Prints the CLI help and exit

Quick Start

# Discover pharmacon commands
pharmacon --help

# Discover subcommands for a given command
pharmacon trajectory --help

# Discover subcommand flags for a given subcommand
pharmacon trajectory rmsd --help

Command Layout

Pharmacon follows a git-style command structure where each top-level command groups a family of related subcommands. The general syntax is:

pharmacon <command> <subcommand> [options]

trajectory — Trajectory Analysis

Analyzes molecular-dynamics trajectories frame by frame. Each subcommand reads a topology and trajectory file and writes results to a signed .pta file.

SubcommandDescription
rmsdRoot Mean Square Deviation against a reference frame for one or more atom selections.
rmsfPer-atom Root Mean Square Fluctuation over a trajectory for one or more atom selections.
distancesPairwise or group-to-group distance time series.
anglesThree-atom, vector, and dihedral angle time series.
h-bondsHydrogen-bond detection across a trajectory.
pl-interactionsProtein–ligand non-covalent interactions (9 interaction types).
pp-interactionsProtein–protein non-covalent interactions (same 9 types).
pcaPrincipal Component Analysis on selected atoms.
average-stAverage structure over a specified frame range.

structure — Static Structure Analysis

Analyzes a single topology or structure file without requiring a trajectory. Results are written to a .psa file.

SubcommandDescription
sequenceExtract amino-acid sequences from a topology, organized by chain.
propertiesCompute molecular descriptors and fingerprints for small molecules.

merge — Replicate Aggregation

Combines multiple .pta files produced from the same topology (e.g. independent replicate runs) into a single merged artifact. Merged files replace per-frame datasets with aggregate summary tables. The merge operation verifies that all inputs share the same blueprint before proceeding.

SubcommandDescription
resultsMerge many .pta replicates into one aggregated file.

plot — Visualization

Renders publication-ready plots directly from analysis artifacts. The plotter auto-discovers which analysis groups are present in the file and dispatches to the appropriate rendering functions. Plot appearance can be fully customized via INI configuration files.

SubcommandDescription
ptaRender every compatible plot type for every group in a .pta file.

export — Data Export

Converts analysis files to flat file formats for use in external tools such as spreadsheets, R, pandas, or bioinformatics pipelines.

SubcommandDescription
ptaExport .pta tables to CSV or TSV.
psaExport .psa tables to CSV, TSV, or FASTA.

dump — Artifact Inspection

Prints file metadata and the internal group/dataset tree to the terminal. Useful for verifying that an artifact is intact, checking which analyses it contains, and inspecting run parameters without opening an HDF5 viewer.

SubcommandDescription
ptaDump .pta metadata and group tree.
psaDump .psa metadata and table contents.

Analyzer Module

The analyzer module is the computational core of Pharmacon. It contains all analysis algorithms as standalone, stateless routines that operate on MDAnalysis selections and return raw numerical results. The module currently supports the following analysis types:

RMSD

Computes the Root Mean Square Deviation of atomic positions relative to a reference frame. Supports multiple selections per run (e.g. backbone C-alpha, ligand heavy atoms), with fitting group for alignment. Results are stored per-frame in the .pta file and can be plotted as time series.

RMSF

Computes the per-atom Root Mean Square Fluctuation — the time-averaged positional fluctuation of each atom about its mean position. Supports multiple selections per run (e.g. backbone C-alpha, ligand heavy atoms) with a dedicated fitting group for in-memory alignment. Alignment defaults to a two-pass scheme (align to the initial frame, build the average structure, then re-align to it), or can target a single reference frame via -r. Per-selection RMSF values plus aggregate statistics are stored in the .pta file and can be plotted as RMSF profiles.

Non-Covalent Interactions (Protein–Ligand & Protein–Protein)

Detects and quantifies nine types of non-covalent interactions on a per-frame basis across a trajectory:

  • Hydrophobic contacts — distance-based detection between non-polar atoms.
  • Hydrogen bonds — donor–hydrogen–acceptor geometry with distance and angle criteria.
  • Ionic / salt-bridge interactions — oppositely charged groups within a distance cutoff.
  • Halogen bonds — C–X···A geometry with angle validation.
  • Metal contacts — coordination between metal ions and nearby electronegative atoms.
  • Water bridges (1st degree) — a single bridging water molecule mediating a hydrogen-bond chain between two groups.
  • Water bridges (2nd degree) — two bridging water molecules forming an extended hydrogen-bond network. (Not Yet Implemented)
  • Pi–cation interactions — aromatic ring to charged group, with distance and angle thresholds.
  • Pi–stacking interactions — parallel or T-shaped aromatic ring pairs, classified by geometry.

Further information on distance cutoffs and interaction types can be found in the Pharmacon paper (see the citation above; DOI: 10.1021/acs.jcim.6c00837).

Each interaction record includes full atom metadata (name, residue, chain, segment) for both partners, plus interaction-specific geometric details (distances, angles, orientation). Atom-type detection leverages RDKit SMARTS pattern matching for accurate classification.

Hydrogen Bonds

Dedicated hydrogen-bond analysis that can be run independently from the full interaction analysis. Uses the same donor–acceptor detection and geometric criteria, but produces a focused output containing only hydrogen-bond records. Usefull when the hydrogen bonding network is the only thing of interest.

Principal Component Analysis (PCA)

Performs PCA on atomic coordinates across a trajectory to identify the dominant modes of conformational motion. Outputs include eigenvalues (explained variance ratios), eigenvectors (principal components), and per-frame projections onto the selected components. Results support scatter plots, time-series projections, variance-ratio scree plots, free-energy surface (FES) heatmaps, and probability density heatmaps.

Distances

Computes pairwise or group-to-group distance time series between user-defined atom selections across a trajectory. Supports minimum-distance, maximum-distance, center-of-mass, and center-of-geometry modes with periodic boundary condition (PBC) awareness.

Angles

Measures geometric angles across a trajectory. Three measurement types are supported: three-atom angles (A–B–C), vector angles between two pairs of atoms (AB vs CD), and dihedral / torsion angles (A–B–C–D). All calculations are PBC-aware when box dimensions are available. Angle selections are defined using MDAnalysis selection strings in one of the following forms:

  • Three-atom angle — select three atoms (e.g. "index 10 or index 11 or index 12"). Pharmacon measures the angle formed at the central atom.
  • Vector angle — define two vectors using the arrow syntax '->' (e.g. "index 10 or index 100 -> index 300 or index 301"). Pharmacon computes the angle between the two resulting vectors.
  • Dihedral angle — select four atoms (e.g. "index 10 or index 11 or index 12 or index 13"). Pharmacon measures the torsion angle around the central bond.

Average Structure

Computes the per-atom mean coordinates over a specified frame range of a trajectory, with optional alignment to a reference frame. The resulting average structure can be written out as a coordinate file for visualization or further analysis.

Sequence Extraction

Extracts amino-acid sequences from a topology file, organized by chain. Outputs include single-letter and three-letter representations along with residue ID mappings. Supports FASTA export for downstream bioinformatics workflows.

Molecular Properties

Computes structural and chemical descriptors for small molecules using RDKit, including molecular weight, LogP, topological polar surface area (TPSA), rotatable bond count, ring count, aromaticity, stereocenter count, net charge, element composition, molecular volume, and fragment counts. Also generates molecular fingerprints (Morgan/ECFP, topological torsion, atom pair, MACCS keys) for similarity searching and machine-learning applications.


Periodic Boundary Conditions (PBC)

Most MD engines write trajectories in which solute molecules diffuse across the edges of the simulation box, get wrapped back through the opposite face, or end up split between periodic images. Distances, angles, and contacts measured on such raw frames are physically meaningless unless the box geometry is taken into account. Pharmacon handles this in two complementary ways: geometry-aware calculations that consult the box at every frame, and an opt-in transformation pipeline that rewrites coordinates before the analysis sees them.

PBC-aware calculations

The trajectory analyzers that measure geometric quantities — distances, angles, h-bonds, pl-interactions, pp-interactions — read the per-frame unit-cell dimensions from the trajectory and use the minimum-image convention when box information is available. Concretely, this means a hydrogen-bond donor in the primary image and an acceptor in a neighbouring image are still detected as a single contact at the correct distance, without any user intervention.

If the trajectory has no box dimensions (e.g. a stripped .dcd or a gas-phase run), Pharmacon falls back to plain Euclidean geometry and logs the fact at DEBUG level.

The -at / --add-transformations flag

PBC-aware distances handle the measurement side, but they cannot help when a molecule is visually broken across box faces (e.g. a protein straddling the box boundary), when downstream tools require whole molecules (RDKit SMARTS matching, RMSD fitting, average-structure export), or when the ligand drifts out of the protein's primary image. For these cases most trajectory subcommands that consume coordinates (all except rmsd and rmsf) accept:

-at, --add-transformations    Apply PBC unwrapping transformations to the
                              MDAnalysis Universe before analysis.
                              (default: False)

When the flag is set, Pharmacon attaches an on-the-fly transformation pipeline to the MDAnalysis Universe in pharmacon.utils.mda.create_universe(). The pipeline is built and applied in a fixed order:

  1. unwrapMDAnalysis.transformations.unwrap(u.atoms). Makes every molecule whole by reversing the wrapping that the MD engine applied on write. Required before any per-molecule operation (RMSD fit, COM/COG distance, SMARTS perception).
  2. center_in_boxcenter_in_box(ref, center="geometry"). Re-centers the system on the geometric centre of the protein (falling back to all atoms if no protein selection exists). This keeps the receptor stationary in the primary image and prevents it from drifting toward a box face over long simulations.
  3. wrapMDAnalysis.transformations.wrap(u.atoms, compound="atoms"). After unwrapping and centering, wraps everything back into the primary image so that downstream distance/contact searches stay numerically well-behaved.

The transformations are lazy: they are attached once to u.trajectory and re-evaluated on every frame iteration, so memory usage stays flat regardless of trajectory length. If the pipeline cannot be applied (e.g. missing bond topology required by unwrap), Pharmacon logs a warning and continues with the untransformed trajectory rather than aborting the run — the flag is treated as a convenience, not a hard requirement.

When to enable --add-transformations

SituationRecommendation
Trajectory already imaged / centered by the MD engineLeave off (default)
Protein visibly split across box edges in the input trajectoryEnable
Ligand drifts out of the primary box during a long runEnable
PCA or average-structure on a periodic systemEnable
Protein–ligand or protein–protein interactions with periodic ligandsEnable
Box dimensions are missing from the trajectoryHas no effect — pipeline is silently skipped

The flag is idempotent on already-imaged trajectories: re-running with -at on a clean trajectory simply re-applies the same identity pass and produces the same results.

Warning

The on-the-fly unwrap → center → wrap pipeline runs on every frame iteration, every time you launch an analysis. On long trajectories or workflows that touch the same trajectory repeatedly (RMSD, PCA, then PL-interactions, then H-bonds, …) this overhead is paid over and over again and can heavily affect calculation speed — sometimes dominating the total runtime.

Tip

For best performance, pre-process the trajectory once with your MD engine's native tooling, then feed the cleaned-up trajectory to Pharmacon without -at. Native tools are implemented in C/Fortran, operate frame-by-frame in a single streaming pass, and write the result to disk — so the cost is paid exactly once.

Examples of native equivalents:

  • GROMACSgmx trjconv -pbc whole, then gmx trjconv -center -pbc mol -ur compact (or -pbc nojump for unwrapped trajectories).
  • Amber / cpptrajautoimage followed by center and image familiar.
  • CHARMM / NAMD (VMD) — the pbctools plugin: pbc unwrap, pbc wrap -center com -centersel "protein" -compound res.
  • MDAnalysis (Python) — write a short script that mirrors the same unwrap → center_in_box → wrap chain and dumps the result with a MDAnalysis.coordinates.XTC.XTCWriter.

Note

Not sure how to do this with your engine of choice? It is perfectly fine to just pass -at and let Pharmacon handle it for you — the result is numerically identical, you just have to wait a bit longer for the analysis to finish. The flag exists exactly for this case.

Subcommands that accept -at

The flag is exposed on the trajectory subcommands that consume coordinates (all except rmsd and rmsf):

  • pharmacon trajectory distances
  • pharmacon trajectory angles
  • pharmacon trajectory h-bonds
  • pharmacon trajectory pl-interactions
  • pharmacon trajectory pp-interactions
  • pharmacon trajectory pca
  • pharmacon trajectory average-st

Example:

pharmacon trajectory pl-interactions \
    -p out.dms -x out.xtc -o pli.pta \
    -prt "chainid R" -lig "resname LIG" \
    -w "resname T3P and around 5 resname LIG" \
    --add-transformations \
    --workers 10

The add_transformations setting is persisted in the resulting .pta file's root-level metadata, so a downstream consumer can verify which PBC treatment a given artifact was produced under without re-reading the original trajectory.


File Formats

Pharmacon persists every analysis result as a signed, self-describing HDF5 artifact. There are two concrete formats — .pta for trajectory analysis and .psa for structure analysis — both implemented on top of the shared PharmaconHDF5File base class in pharmacon.fileio.base. Under the hood they are plain HDF5 files and can be opened with h5py, h5dump, HDFView, or any HDF5-aware library; the Pharmacon-specific metadata lives in HDF5 attributes and a predictable group hierarchy.

Common root-level attributes

Every Pharmacon artifact (.pta or .psa) carries the same base metadata block on the root group. These are set automatically at write time from pharmacon.constants.BASE_PHARMACON_META plus the command that produced the file.

AttributeTypeMeaning
pharmacon_versionstrVersion of Pharmacon that wrote the file (e.g. "1.0.0").
schema_versionstrSchema contract version for on-disk layout.
file_typestrPharmaconHDF5Types.TRAJECTORY_ANALYSIS or …STRUCTURE_ANALYSIS.
commandstrHigh-level command label (e.g. "Trajectory Analysis").
subcommandstrSpecific subcommand (rmsd, pl-interactions, sequence, …).
descriptionstrHuman-readable one-liner describing the run.
created_atstrISO-8601 UTC timestamp at which the file was opened for writing.
signaturestrPHARMACON::<COMMAND>::<SUBCOMMAND>::<chunked-SHA256-prefix> identity token.
fingerprintstr128-bit BLAKE2b hex digest over the same payload (tamper-check hint).
blueprintstrDeterministic digest of the run inputs — used by pharmacon merge to refuse incompatible inputs.
artifact_tokenstrHMAC-style token bound to the blueprint.
artifact_token_versionstrToken scheme version (currently "1").
artifact_statusstr"SUCCESS" iff run() finished cleanly.
artifact_status_codestrExit code of the run ("0" on success).
completedstr"True" once the writer has closed the file with all groups fully populated.
is_mergedstr"True" if the file was produced by pharmacon merge results.

In addition, each subcommand adds its own attributes (e.g. begin, end, step, total_frames, ligand, protein, water, disable_hbonds, …) so a file is fully reproducible from its metadata alone.

Signature, fingerprint, and blueprint — what's the difference?

These three tokens look similar but answer different questions:

  • signature — a stable identity string built by pharmacon.utils.fingerprint.create_pharmacon_signature(). It is a SHA-256 of PHARMACON::<format>::<version>::<command>::<subcommand>::<salt>, prefix- chunked for readability (e.g. PHARMACON::TRAJECTORY ANALYSIS::PL-INTERACTIONS::9E11-C28C-85DE-…). Two files with the same signature were produced by the same command+subcommand flavour of Pharmacon. Useful for routing plots and export logic.
  • fingerprint — a 128-bit BLAKE2b over the same payload. Same determinism, different hash family: acts as a cheap tamper-check hint for the identity block.
  • blueprint — generated by pharmacon.utils.identifiers, hashes the actual inputs (topology, trajectory, selections, flags). Two files share a blueprint only if they were run against equivalent inputs. pharmacon merge results uses this to refuse merging incompatible replicates.

None of these are cryptographic signatures — they are integrity hints, not authentication.

Pharmacon Trajectory Analysis (.pta)

A .pta file stores one or more analysis groups at the root, each containing per-frame datasets. The concrete layout depends on the subcommand that wrote the file, but the general pattern is:

pl_interactions.pta
├── @ pharmacon_version, signature, fingerprint, blueprint,
│     command="Trajectory Analysis", subcommand="pl-interactions",
│     begin, end, step, total_frames, ligand, protein, water, …
└── pl_interactions/                       ← analysis group
    ├── @ completed=True
    ├── frame_0/
    │   └── interactions        ← variable-length JSON-row dataset
    ├── frame_1/
    │   └── interactions
    ├── …
    ├── frame_500/
    │   └── interactions
    └── modes/                   ← optional aggregated views
        ├── mode1/table
        ├── mode2/table
        └── mode3/table

Typical top-level group names (one per analysis):

SubcommandRoot group(s)Per-frame dataset(s)
rmsdrmsdframe_<N>/rmsd
rmsfrmsfper-selection RMSF arrays + statistics
anglesanglesframe_<N>/angles
distancesdistancesframe_<N>/distances
h-bondshydrogen_bondsframe_<N>/interactions
pl-interactionspl_interactionsframe_<N>/interactions
pp-interactionspp_interactionsframe_<N>/interactions
pcapcacomponents, projections, variance_ratio

Interaction row schema

The interactions dataset for pl-interactions, pp-interactions, and h-bonds is a variable-length array of JSON-encoded rows with a fixed 21-column core schema (PharmaconPTAFile.INTERACTION_COLUMNS):

ColumnDescription
frame_numberFrame index in the source trajectory.
interactionInteraction type tag (see below).
atom1_*9 fields for the first partner: index, name, id, type, element, resname, resid, chainid, segid.
atom2_*9 fields for the second partner, same schema as atom1_*.
detailsDict of interaction-specific extra fields (see table below).

PharmaconPTAFile.INTERACTION_DETAIL_SCHEMA declares the details fields per interaction type:

Interaction tagdetails fields
HYDROPHOBICdistance, is_hydrogen
HYDROGEN-BONDdistance, angle_dha, angle_hax, orientation
IONICdistance, orientation
HALOGEN-BONDdistance, angle_cxa, angle_xay, orientation
METAL-CONTACTdistance, role, orientation
WATER-BRIDGE-116 fields — one bridging water + two distances + two angle pairs + orientation
WATER-BRIDGE-228 fields — two bridging waters + three distances + three angle pairs + orientation (reserved — not yet implemented)
PI-CATIONdistance, theta, orientation
PI-STACKINGdistance, angle, stacking_type, orientation

Aggregated interaction views: modes/ and modes_merged/

For interaction analyses, Pharmacon additionally writes mode tables next to the per-frame data:

  • modes/mode<N>/table — per-file aggregated tables (residue × frame, residue × interaction type, residue × ligand atom, …) computed at write time so plotters don't have to re-walk every frame.
  • modes_merged/<mode_name>/table — present only on files produced by pharmacon merge results. Contains the aggregate across every merged replicate. Merged files intentionally drop per-frame datasets in favour of these tables.

Plotters respect is_merged: plot types that require per-frame data (e.g. the PLI timeline heatmap) are silently skipped on merged files.

Pharmacon Structure Analysis (.psa)

A .psa file is the structure-level counterpart to .pta, produced by the pharmacon structure … subcommands. It inherits the entire .pta API via PharmaconPSAFile(PharmaconPTAFile) and adds structure-specific groups:

3eml.psa
├── @ pharmacon_version, signature, fingerprint,
│     command="Structure Analysis", subcommand="sequence",
│     topology_file, selection, n_chains, …
└── sequence/                ← one group per analysis
    ├── @ completed=True
    └── A/                   ← per-chain subgroup
        ├── aa1_seq          ← 1-letter amino-acid sequence
        ├── aa3_list         ← 3-letter residue list
        └── resid_seq        ← residue ID sequence
SubcommandRoot group(s)Notable datasets
sequencesequence<chain>/aa1_seq, <chain>/aa3_list, <chain>/resid_seq
propertiespropertiesproperties_table, fingerprints/<kind>, optional metadata sidecar

PSAFile exposes helpers for FASTA export, parquet fingerprint dumps, CSV property exports, and an ML-ready joined export — see pharmacon.fileio.psa.PharmaconPSAFile for the full writer/reader API.

Inspecting a Pharmacon artifact

# Pharmacon's own dumper (pretty panels, validity badge, metadata tables)
pharmacon dump pta -i run.pta
pharmacon dump psa -i structure.psa

Or inline with h5py:

import h5py

with h5py.File("run.pta", "r") as f:
    print(dict(f.attrs))                         # root metadata
    print(list(f.keys()))                        # analysis groups

Pharmacon INI plot-settings files

A configobj-style INI file whose top-level sections match aliases on PlotSettingsBase subclasses. Example:

[PTA-UNIFIED]
fig_size_width = 12
fig_dpi        = 300
enable_grid    = true

[PLI-STACKED-COLUMN-1]
fig_format  = svg
font_family = DejaVu Sans
bar_width   = 0.9

For ready-to-use templates covering every plot type with all available variables, see examples/plot_ini/ and the accompanying examples/README.md.


CLI Reference

Pharmacon uses a hierarchical command structure. Every invocation starts with pharmacon, followed by a command (the analysis family), a subcommand (the specific task), and any required or optional flags.

General syntax

pharmacon                                      # show top-level help
pharmacon <command> --help                     # show help for a command group
pharmacon <command> <subcommand> --help        # show help for a specific task
pharmacon <command> <subcommand> [options]     # run a task

Examples:

pharmacon --help                               # list all available commands
pharmacon trajectory --help                    # list trajectory subcommands
pharmacon trajectory rmsd --help               # show all RMSD options
pharmacon trajectory rmsd -p top.prmtop -x md.xtc -f "protein and name CA" \
                          -sel "protein and name CA" -n "backbone_ca" -o rmsd.pta

Shared flags

Most subcommands accept the following common flags. Not every flag applies to every command — use --help on any subcommand to see its exact options.

Input / output:

FlagMeaning
-p, --topologyPath to the topology file (.prmtop, .pdb, .gro, .psf, …).
-x, --trajectoryPath to the trajectory file (.xtc, .trr, .dcd, .nc, …).
-i, --inputInput artifact file (.pta or .psa) — used by plot, export, and dump commands.
-o, --outputOutput file or directory.
--overwriteReplace existing output without prompting.

Atom selections (trajectory subcommands):

FlagMeaning
-sel, --selectionsOne or more MDAnalysis selection strings (e.g. "protein and name CA").
-n, --namesLabel for each selection (used in output headers and plot legends).
-f, --fitting-groupAtom selection for structural alignment before analysis.
-r, --reference-frameFrame index to use as the alignment reference (default: 0).

Interaction-specific selections (for pl-interactions / pp-interactions):

FlagMeaning
-prt, --proteinMDAnalysis selection string for the receptor / protein group.
-lig, --ligandMDAnalysis selection string for the ligand group.
-w, --waterMDAnalysis selection string for water molecules (needed for water-bridge detection).

Caution

Always scope the water selection dynamically around the binding site / interface. Prefer -w "resname WAT and around 5 resname LIG" over a global -w "resname WAT". A global selection forces Pharmacon to test every water molecule in the box for bridging on every frame, which can dramatically increase runtime. Restricting waters to the neighbourhood of the interaction site yields identical results for the relevant bridges at a fraction of the cost. (Adjust WAT/LIG and the around cutoff to match your system.)

Distance-specific selections (for distances):

FlagMeaning
-sel1, --selection1First atom group(s) for distance calculation.
-sel2, --selection2Second atom group(s) for distance calculation.
-m, --methodDistance method per pair: MIN, MAX, COM (center of mass), or COG (center of geometry).

Frame range:

FlagMeaning
-b, --beginFirst frame to process (default: 0).
-e, --endLast frame to process (default: last frame in trajectory).
-s, --stepProcess every Nth frame (default: 1).

PBC / transformations:

FlagMeaning
-at, --add-transformationsApply PBC unwrapping transformations to the MDAnalysis Universe before analysis.

Parallelization:

FlagMeaningApplies to
--workersNumber of parallel workers for frame processing (default: 1).pl-interactions, pp-interactions, h-bonds
--parallelNumber of parallel workers for frame processing (default: 1).pca

Interaction toggles (for pl-interactions / pp-interactions):

FlagMeaning
--disable-hydrophobicSkip hydrophobic contact detection.
--disable-hbondsSkip hydrogen-bond detection.
--disable-pi-stackingSkip pi-stacking detection.
--disable-pi-cationSkip pi-cation detection.
--disable-ionicSkip ionic / salt-bridge detection.
--disable-water-bridgesSkip water-bridge detection.
--disable-halogenSkip halogen-bond detection.
--disable-metalSkip metal-contact detection.

PCA-specific:

FlagMeaning
-c, --componentsNumber of principal components to compute (default: 3).

Logging:

FlagMeaning
-l, --logPath to the log file.
-fl, --file-logging-levelVerbosity of the log file: TRACE, DEBUG, INFO, WARNING, ERROR, CRITICAL.
-tl, --terminal-logging-levelVerbosity of terminal output (same levels as above).

Plot-specific flags (for pharmacon plot pta):

FlagMeaning
-c, --configPath to a Pharmacon INI file with plot-settings overrides.
-mw, --maxwarningsMaximum coercion warnings per plot before skipping it (default: 0).

Getting help at every level

You can append --help at any point in the command chain to see what is available. Pharmacon will display a Rich-formatted help panel with all accepted flags, their types, defaults, and a brief description.

pharmacon --help                               # all commands
pharmacon trajectory --help                    # all trajectory subcommands
pharmacon trajectory pl-interactions --help    # all PLI options
pharmacon plot pta --help                      # all plotting options
pharmacon export psa --help                    # all PSA export options

Usage Examples

RMSD + plotting

pharmacon trajectory rmsd \
    -p protein.prmtop -x md.nc \
    -sel "protein and name CA" "resname LIG and not name H*" \
    -n "bb_ca" "ligand_heavy" \
    -f "protein and name CA" \
    -r 0 -b 0 -e 10000 -s 10 \
    -o rmsd.pta

pharmacon plot pta -i rmsd.pta -o plots/ --overwrite

Protein–ligand interactions across replicates

# Analyze each replicate separately
for rep in rep1 rep2 rep3; do
  pharmacon trajectory pl-interactions \
      -p $rep/topo.prmtop -x $rep/md.nc \
      -lig "resname LIG" -prt "protein" \
      -o $rep/pli.pta
done

# Merge into one aggregated artifact
pharmacon merge results -i rep1/pli.pta rep2/pli.pta rep3/pli.pta \
                        -o pli_merged.pta

# Plot the merged artifact (per-frame-only plots are auto-skipped)
pharmacon plot pta -i pli_merged.pta -o plots/merged/ --overwrite \
                   -c my_plot_theme.ini

PCA on a trajectory

pharmacon trajectory pca \
    -p protein.prmtop -x md.nc \
    -sel "protein and name CA" -c 5 \
    -o pca.pta

pharmacon plot pta -i pca.pta -o pca_plots/ --overwrite
# -> pca_plots/{pca_timeseries, pca_scatter, pca_variance_ratio,
#               pca_probability, pca_heatmap_fes}.png

Dump + export

pharmacon dump   pta -i rmsd.pta                 # pretty-print metadata + tree
pharmacon export pta -i rmsd.pta -o rmsd.csv --format csv

Plot Configuration via INI

Every plot-settings dataclass registers one or more aliases via its alias: ClassVar[Tuple[str, ...]] field. The INI section header must match one of those aliases (case-insensitive). Unknown sections are reported as a warning but do not abort the run.

# ── Shared figure theme ──
[PTA-UNIFIED]
fig_dpi          = 300
fig_format       = svg
font_family      = DejaVu Sans
enable_grid      = true
grid_style       = dashed
grid_alpha       = 0.4

# ── Per-plot overrides ──
[PLI-STACKED-COLUMN-1]
bar_width        = 0.9
bar_alpha        = 0.85
color_hydrophobic = "#b39ddb"

[PLI-HEATMAP-2]
cmap             = viridis
threshold        = 0.05

[PCA-SCATTER]
cmap             = plasma
scatter_size     = 14
disable_colorbar = false

Each override goes through the dataclass' _validate_fields(), which may coerce an unsupported value (e.g. an unknown color name) and emit a warning. The --maxwarnings / -mw flag controls how many such warnings a plot may accumulate before it is skipped entirely.


Example INI Configs

Ready-to-copy configuration files for every plot type live in examples/plot_ini/. Each file exposes the full set of variables for its plot with inline comments and default values — use them as templates, edit the fields you care about, and point any pharmacon plot … command at them with -c.

FilePlotSection alias(es)
all_plots.iniMaster file covering every plot(every alias below)
pli_stacked_column_1.iniPLI stacked column (per interaction type)PLI-STACKED-COLUMN-1
pli_stacked_column_2.iniPLI stacked column (backbone vs side-chain)PLI-STACKED-COLUMN-2
pli_heatmap_1.iniPLI heatmap (residue × frame)PLI-HEATMAP-1
pli_heatmap_2.iniPLI heatmap (interaction × frame)PLI-HEATMAP-2
pli_pie_charts_1.iniPLI pie charts (collage)PLI-PIE-CHARTS-1
pli_ligand_monitor.iniResidue × ligand-atom contact heatmapPLI-LIGAND-MONITOR
ppi_timeline_pairs.iniPPI timeline heatmap for top residue-pairsPPI-TIMELINE-PAIRS
ppi_heatmap.iniPPI residue × residue heatmapPPI-HEATMAP
ppi_stacked_column.iniPPI per-pair stacked columnPPI-STACKED-COLUMN
pta_unified.iniUniversal PTA time series (RMSD/RMSF/Rg/SASA/…)PTA-UNIFIED
pca_timeseries.iniPCA projections vs timePCA-TIMESERIES
pca_scatter.iniPCA scatter of two componentsPCA-SCATTER
pca_variance_ratio.iniPCA explained-variance scree plotPCA-VARIANCE-RATIO
pca_fes_heatmap.iniPCA Free-Energy Surface heatmapPCA-FES-HEATMAP
pca_probability_heatmap.iniPCA probability density heatmapPCA-PROBABILITY-HEATMAP

Usage:

# Single-plot config
pharmacon plot pta -i run.pta -c examples/plot_ini/pta_unified.ini

# Master config that covers every plot type
pharmacon plot pta -i run.pta -c examples/plot_ini/all_plots.ini
pharmacon plot pca -i run.pta -c examples/plot_ini/all_plots.ini

Sections not recognised by the invoked subcommand are silently ignored, so all_plots.ini can safely be reused across different plot commands.


Logging & Workspaces

Every subcommand except dump and export accepts:

-l,  --log FILE
-fl, --file-logging-level  {TRACE,DEBUG,INFO,WARNING,ERROR,CRITICAL}
-tl, --terminal-logging-level {TRACE,DEBUG,INFO,WARNING,ERROR,CRITICAL}

Internally, run() always does:

setup_logger(terminal=True, file=True,
             terminal_level=args.terminal_logging_level,
             file_level=args.file_logging_level,
             log_file=args.log)
log = get_logger(__name__)
ws  = PharmaconWorkspace(is_tmp_dir_needed=False)

PharmaconWorkspace respects two environment variables:

VariableDefaultMeaning
PHARMACON_WORKDIR.Base working directory
PHARMACON_TEMPDIRNoneBase directory for per-run scratch space

Any temporary directory created with is_tmp_dir_needed=True is cleaned up via atexit unless cleanup_on_exit=False is passed.


Development

git clone https://github.com/k-georgiou/pharmacon.git
cd pharmacon
python -m venv venv && source venv/bin/activate
pip install -e ".[dev]"   # editable install + pytest
pharmacon --help

Running the test suite:

python -m pytest          # all tests
python -m pytest tests/test_<module>.py   # single file

Adding a new subcommand is a 4-step pattern:

  1. Create src/pharmacon/command_line/<group>/<name>.py with SUBCOMMAND_NAME, SUMMARY, build_parser, validate, run.
  2. Put the heavy lifting in pharmacon.analyzer.<name> so it stays unit-testable.
  3. If the output is a new HDF5 artifact, extend pharmacon.fileio.
  4. If it needs plots, add a settings dataclass to pharmacon.constants.plots and a rendering function to pharmacon.plotter.

Author

Kyriakos Georgiou
Department of Pharmacy, University of Athens
Manuscript: Journal of Chemical Information and Modeling (2026) — DOI: 10.1021/acs.jcim.6c00837
GitHub: https://github.com/k-georgiou/pharmacon

Acknowledgments

Special thanks to Antonios Kolocouris (Department of Pharmacy, University of Athens) for his supervision, scientific guidance, and support throughout the project and the associated manuscript.

License

Pharmacon is licensed under the GNU General Public License v3.0 only (GPL-3.0-only). See LICENSE.txt for the full text, and NOTICE for copyright, citation, and third-party-component information.

Note on copyleft. Pharmacon imports MDAnalysis (GPL-2.0-or-later) at runtime, so any distributed combined work is bound by the GPL terms. If you modify Pharmacon and distribute the result, you must release your changes under GPL-3.0-only.