Skip to main content
Docs

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

    Tools · Computational Biology

    Lacuna

    Find cryptic binding pockets that open across a normal-mode conformational ensemble, ranked by crypticity, persistence, and druggability, with a docking box and a Boltz-2 pocket constraint for each.

    Updated October 20, 2026

    On this page

    Prices, workflows, and method papersOpen in the app

    Lacuna looks for cryptic pockets: sites that are closed or shallow in the structure you have but open as the protein flexes. A static detector such as the Binding-Site Detector sees one snapshot, so it misses a site that only opens under a hinge or breathing motion. Lacuna samples that motion, follows each cavity through it, and ranks the sites that open. It runs on CPU in seconds to minutes, with no force field, GPU, or model weights to download.

    How it works

    1. Ensemble: an anisotropic network model (springs between nearby Cα atoms) gives the protein's lowest-frequency normal modes. Conformers are sampled along them at increasing amplitude and the displacement is carried to every atom. The input structure is always analyzed as well.
    2. Detection: pockets are detected in every conformer. The default alpha-sphere detector proposes sites only at concavities. The learned surface detector scores the whole probe-accessible surface and reaches sites the geometry discards; the fused option pools both. The surface detectors run on geometry alone here, without a protein language model.
    3. Clustering: matching cavities in different conformers are clustered into one site.
    4. Ranking: sites are ranked with Lacuna's fitted ranker by default, or by crypticity, peak druggability, or persistence alone.

    Sampling is deterministic, so the same structure and settings give the same table.

    MetricMeaning
    Crypticity (0–1)How strongly the site opens relative to the input structure while being druggable when open. A site flagged cryptic clears Lacuna's threshold.
    Persistence (0–1)Fraction of conformers in which the site is open. Cryptic sites are often low.
    Druggability (0–1)Composite of volume, enclosure, hydrophobicity, and aromatic content; max_druggability is the most open state.
    Volume rangeSmallest and largest cavity volume across the ensemble, next to the volume in the input (apo_volume_A3).

    Inputs

    A protein structure as PDB or mmCIF: an experimental structure, a predicted one from ESMFold2 or Boltz-2, an OpenMM MD frame, or a PDB ID. Ligands and waters in the file are ignored; pockets come from protein atoms only. To reach a site at a dimer interface, turn on the biological-assembly option, or upload the RCSB biological assembly if the deposited file has no assembly operators.

    Outputs

    FileContents
    pockets.jsonOne row per site: rank, a cubic AutoDock Vina box (center, size), the metrics above, lining residues, and the conformers the site appears in
    boltz_constraints.jsonA Boltz-2 pocket constraint per site, plus the chain sequences its residue positions refer to
    sites/pocket_N.pdbPseudoatoms at each site's centre and extent, to load beside the protein in a viewer
    reference_ligand.sdfA one-atom placeholder at the top site
    summary.jsonDetector, ranking used, conformer count, and warnings

    Each box is centred on the site centroid. Its edge is twice the radius of a sphere with the site's volume, plus the padding on each side.

    Using the Boltz-2 constraints

    Boltz-2 numbers residues by their position in the sequence you give it, not by PDB residue number. Lacuna writes each chain's sequence (standard residues in file order, so gaps in the model are skipped) and gives each contact as [chain, position] in that sequence.

    1. Open boltz_constraints.json and pick a site from pockets.
    2. Use the sequences in chains for the Boltz-2 protein, or re-index the contacts if your sequence differs (for example, it fills in missing loops).
    3. Give your ligand the id named in binder (L) and add the site's entry to the Boltz-2 constraints list.

    Workflows do not pass these constraints to Boltz-2 automatically yet; the boxes do chain into AutoDock Vina.

    Not covered

    • Molecular dynamics or mixed-solvent ensembles, and Lacuna's experimental Boltz-2 ensemble backend. The elastic-network model captures large, collective motions; side-chain rearrangements that open small sites are beyond it.
    • Sequence-based reranking and sequence-seeded proposals, which need a protein language model.
    • Docking itself, and ligand or binder design.

    In a workflow, the pockets table binds to the boxes input of AutoDock Vina, and the placeholder ligand to DrugFlow or SurfDock where they need a reference ligand. For pockets on a single static structure, use the Binding-Site Detector; to clean up a structure first, the Protein Preparer. For blind docking without a box, see DiffDock.

    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.

    Lacuna lacuna

    Job type
    lacuna
    Hardware
    cpu (default)
    Typical runtime
    1 min on CPU

    Payload

    Payload fields
    FieldTypeDescription
    pdb_idstring

    Limits: pattern ^[0-9A-Za-z]{4}$

    proteinfile_object
    protein_download_formatstring

    Default: "pdb"One of: "pdb", "cif"

    detectorstring

    Default: "alpha"One of: "alpha", "surface", "surface-fusion"

    n_conformersinteger

    Default: 20Limits: ≥ 2, ≤ 50

    top_ninteger

    Default: 5Limits: ≥ 1, ≤ 20

    rank_bystring

    Default: "learned"One of: "learned", "crypticity", "druggability", "balanced", "persistence"

    min_druggabilitynumber

    Default: 0Limits: ≥ 0, ≤ 1

    min_persistencenumber

    Default: 0Limits: ≥ 0, ≤ 1

    min_crypticitynumber

    Default: 0Limits: ≥ 0, ≤ 1

    homodimerboolean

    Default: false

    box_paddingnumber

    Default: 8Limits: ≥ 0, ≤ 20

    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 = {
        "protein": {
            "name": "protein.pdb",
            "content_b64": "<file contents, base64>",
        },
        "detector": "alpha",
        "n_conformers": 4,
        "top_n": 1,
        "box_padding": 8,
    }
    
    estimate = client.jobs.estimate(job_type="lacuna", payload=payload, resource="cpu")
    print(f"Reserves ${estimate.cost:.2f}")
    
    job = client.jobs.submit(
        job_name="my-lacuna-run",
        job_type="lacuna",
        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

    • Protein structurePDB, CIF

    Workflow outputs

    • ArchiveZIP
    • TableJSON
    • MoleculesSDF