Skip to main content
Docs

Search guides and API endpoints, for example “Idempotency-Key” or “submit job”.

    Tools · Computational Biology

    MD Trajectory Analyzer

    Analyze molecular dynamics trajectories: RMSD, radius of gyration, per-residue flexibility, protein–ligand hydrogen bonds, clustering, and a representative structure.

    Updated October 1, 2026

    On this page

    Prices, workflows, and method papersOpen in the app

    The MD Trajectory Analyzer turns a molecular dynamics trajectory into the numbers you usually want from it, using MDAnalysis. It reads the result of an OpenMM MD job directly, or any topology PDB and DCD trajectory you upload. It runs on CPU.

    What it computes

    • Backbone RMSD over time, against the first analyzed frame or the minimized structure (reference): has the structure settled, or is it drifting?
    • Radius of gyration over time: compaction or unfolding.
    • Per-residue RMSF: which parts of the protein move most.
    • Protein–ligand hydrogen-bond occupancy: the share of frames in which each H-bond is present (when there is a ligand).
    • RMSD clustering into n_clusters groups, with a representative structure (and optionally one per cluster).

    Inputs

    Either the OpenMM MD result zip (archive), or a topology PDB plus a trajectory DCD. Options:

    FieldDefaultMeaning
    stride1Analyze every n-th frame
    max_frames2000Cap on analyzed frames (at most 5,000)
    referenceframe0RMSD reference: the first analyzed frame, or minimized (the topology's coordinates)
    rmsd_selectionprotein and name CAAtoms for RMSD and clustering (MDAnalysis selection syntax)
    ligand_selectionresname LIGThe ligand, for hydrogen bonds
    n_clusters5Number of clusters

    Uploaded files are limited to 25 MiB each; in a workflow, an OpenMM MD step's result passes straight in.

    Outputs

    FileContents
    timeseries.csvRMSD and radius of gyration per frame
    rmsf.csvRMSF per residue
    hbond_occupancy.csvProtein–ligand hydrogen bonds and their occupancy
    clusters.csvEach frame's cluster
    representative.pdbThe most representative frame (plus ensemble/*.pdb per cluster)
    analysis_summary.jsonSettings and summary values

    Run the simulation with OpenMM MD; rescore poses with MM-GBSA Rescoring; profile interactions in a single structure with Interaction Profiler.

    Run it from the API

    Submit with Submit a job and the job_type below. Price it first with Estimate job reservation cost: submitting reserves that amount from your wallet, and the charge settles at the actual runtime.

    MD Trajectory Analyzer md-analyze

    Job type
    md-analyze
    Hardware
    cpu (default)
    Typical runtime
    30 min on CPU

    Payload

    Payload fields
    FieldTypeDescription
    archivefile_object
    topologyfile_object
    trajectoryfile_object
    strideinteger

    Default: 1Limits: ≥ 1, ≤ 5000

    max_framesinteger

    Default: 2000Limits: ≥ 1, ≤ 5000

    referencestring

    Default: "frame0"One of: "frame0", "minimized"

    rmsd_selectionstring

    Default: "protein and name CA"Limits: min length 1

    ligand_selectionstring

    Default: "resname LIG"Limits: min length 1

    n_clustersinteger

    Default: 5Limits: ≥ 1, ≤ 50

    File fields take {"name": "x.pdb", "content_b64": "…"} or a stored artifact, {"$artifact": {"id": "art-…", "port": "…"}}. Files are up to 25 MiB each.

    Example

    from cognichem_client import CogniChem
    
    client = CogniChem.from_env()  # reads COGNICHEM_API_KEY
    payload = {
        "topology": {
            "name": "topology.pdb",
            "content_b64": "<file contents, base64>",
        },
        "trajectory": {
            "name": "trajectory.dcd",
            "content_b64": "<file contents, base64>",
        },
        "stride": 1,
        "max_frames": 10,
        "reference": "frame0",
        "n_clusters": 2,
    }
    
    estimate = client.jobs.estimate(job_type="md-analyze", payload=payload, resource="cpu")
    print(f"Reserves ${estimate.cost:.2f}")
    
    job = client.jobs.submit(
        job_name="my-md-analyze-run",
        job_type="md-analyze",
        payload=payload,
        resource="cpu",
    )
    status = client.jobs.wait(job.process_id)
    if status.status == "completed":
        client.jobs.result(job.process_id, save_path=".")

    Sample data from the job catalog; long values are shortened here. Each job_name must be unique among your jobs.

    Workflow inputs

    • Archive · optionalZIP
    • Protein structure · optionalPDB

    Workflow outputs

    • ArchiveZIP
    • StructuresPDB
    • Protein structurePDB
    • TableCSV