Bioactivity and small-molecule data-side catalog. Covers ChEMBL search/lookup, MolTrack compound and batch registration, HitTriage / HitDesign / PeptiHit workflows, and Curves dose-response analysis (IC50/EC50 fitting). Open this skill when the user asks about querying ChEMBL, registering or looking up compounds in MolTrack, running a hit-triage campaign, or fitting/inspecting dose-response curves.
Scanned 9/12/2026
Install to Claude Code
npx -y skills add datagrok-ai/public --skill datagrok-chem-data --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Datagrok Chem Data?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/datagrok-ai-datagrok-chem-data)More formats (shields.io, HTML) on the badges page.
---
name: datagrok-chem-data
description: Bioactivity and small-molecule data-side catalog. Covers ChEMBL search/lookup, MolTrack compound and batch registration, HitTriage / HitDesign / PeptiHit workflows, and Curves dose-response analysis (IC50/EC50 fitting). Open this skill when the user asks about querying ChEMBL, registering or looking up compounds in MolTrack, running a hit-triage campaign, or fitting/inspecting dose-response curves.
---
# datagrok-chem-data
Function catalog for the **data and workflow** half of Datagrok cheminformatics:
Chembl, MolTrack, HitTriage, Curves.
All functions are callable through the `datagrok_exec` tool via
`grok.functions.call('<Package>:<funcName>', {param1, param2, ...})`. For the
data-side packages, results are usually `DG.DataFrame` objects produced by SQL
queries or by Docker services (MolTrack).
For the structure-and-modeling side (Chem, Admetica, Reinvent4, Docking,
Boltz1), see the sibling skill **`datagrok-chem-toolkit`**.
### Param-type conventions used below
Types match Datagrok function declarations: `dataframe`, `column`, `string`,
`int`, `float`, `bool`, `list<T>`, `object`. A column with a required semType
is written `column<semType>` (e.g. `column<Molecule>`). Enum values are listed
inline as `'a' | 'b' | 'c'`. `?` marks optional, `= x` shows the default.
### Namespace casing
The package is referenced as **`Chembl:`** in `grok.functions.call(...)` and
`grok.data.query(...)`. It's branded as "ChEMBL" in UI text, but the function
namespace is namespace-exact lowercase-after-first-letter: `Chembl:foo`,
never `ChEMBL:foo` or `chembl:foo`.
### Always emit an exec block when the intent is clear
If the user asks for a concrete data-side action ("register this compound",
"fit IC50 from this data", "what is the SMILES of aspirin", "list ChEMBL
compounds for organism X") — call `datagrok_exec` with code calling the relevant
function below. Don't answer chemistry/data questions from memory when a
catalog function exists. If a required input (SMILES, payload, mapping JSON)
is missing, emit the block with a clearly-marked placeholder or sensible
default and add a one-line note — don't bail out into a conversational reply.
### Tag legend (used in function tables below)
Same tags as `datagrok-chem-toolkit`'s "Calling conventions" section, plus a
few data-side specific ones. Common values that appear in the **Tags** column:
| Tag | Meaning |
|----------------------|------------------------------------------------------------------------------------------------------------------------------------------|
| `vectorFunc` | Returns a `DG.DataFrame`. Usable inside a `t.columns.addNewCalculated(name, formula)` call and the Add-New-Column dialog. Without it, call via `grok.functions.call`. |
| `transform` | Tagged as a data-sync transform — same behavior as the un-tagged sibling but tracked in project history. |
| `topMenu` | Has a Top-menu path. |
| `app` / `appTreeBrowser` | App entry point / its tree-browser sidebar hook. |
| `panel` | Context-panel widget — `DG.Widget` shown in the right side panel. |
| `demo` | Demo function — opens a tutorial layout. |
| `fileViewer` / `fileHandler` | Registered for a specific file extension. |
| `cellRenderer` | Custom cell renderer. |
| `converter` | Type converter (`meta.role: 'converter'` with an `inputRegexp`). |
| `curveConverter` | Curves package — registers a curve-format converter (`3dx`, `compact-dr`, `pzfx`). |
| `hitTriageDataSource` / `pepTriageDataSource` | HitTriage / PepTriage data source registered for the campaign-ingest picker. |
---
## Cross-package routing — "User wants X → call Y"
| User intent | Function | Package |
|---|---|---|
| ChEMBL substructure search | `Chembl:chemblSubstructureSearchPanel` (panel) or query `Chembl:patternSubstructureSearch` | Chembl |
| ChEMBL similarity search | `Chembl:chemblSimilaritySearchPanel` (panel) or query `Chembl:patternSimilaritySearch` | Chembl |
| ChEMBL ID → SMILES | `Chembl:chemblIdToSmilesTs` | Chembl |
| Get ChEMBL molregno for SMILES | `Chembl:chemblMolregno` | Chembl |
| Pull ChEMBL compounds by organism | `Chembl:getChemblCompoundsByOrganism` | Chembl |
| Open MolTrack | `MolTrack:molTrackApp` | MolTrack |
| Register one compound / batch | `MolTrack:registerMolTrackProperties` (props), `MolTrack:registerBulk` (bulk CSV) | MolTrack |
| Look up compound by corporate ID | `MolTrack:getCompoundByCorporateId` | MolTrack |
| Look up batch by corporate ID | `MolTrack:getBatchByCorporateId` | MolTrack |
| Advanced compound search with structured filter | `MolTrack:advancedSearch` | MolTrack |
| Generic entity search (compounds / batches / assays / runs / results) | `MolTrack:search` | MolTrack |
| List compound / batch / assay schema | `MolTrack:fetchCompoundProperties`, `MolTrack:fetchBatchProperties`, `MolTrack:fetchSchema`, `MolTrack:fetchDirectSchema` | MolTrack |
| Register assay / assay results | `MolTrack:registerAssays` | MolTrack |
| Retrieve all entities of a scope | `MolTrack:retrieveEntity` | MolTrack |
| Start a Hit Triage campaign | `HitTriage:hitTriageApp` | HitTriage |
| Start a Hit Design campaign | `HitTriage:hitDesignApp` | HitTriage |
| Start a PeptiHit campaign | `HitTriage:peptiHitApp` | HitTriage |
| Get demo molecule dataset (100 / 5000 / N) | `HitTriage:demoFileIngest`, `HitTriage:demoFileIngest1`, `HitTriage:demoFileIngest2` | HitTriage |
| Convert raw plate readouts into fit-curve cells | `Curves:dataToCurves` or `Curves:dataToCurvesTopMenu` | Curves |
| Compute IC50 / Hill / AUC / Top / Bottom from dose-response data | `Curves:dataToCurves` (fit) → `Curves:addStatisticsColumn` (extract) | Curves |
| Pull a stat from existing fit cells | `Curves:addStatisticsColumn` | Curves |
| Aggregate fit stats across series | `Curves:addAggrStatisticsColumn` | Curves |
| Open a `.pzfx` GraphPad Prism file | `Curves:previewPzfx` | Curves |
| Compute Minimum Significant Ratio | script `Curves:CalculateMSR` (see Curves Scripts) | Curves |
---
## Chembl package — local ChEMBL search and lookup (`Chembl:...`)
Thin TS layer over SQL queries against a local ChEMBL PostgreSQL connection.
The heavy lifting is in `Chembl/queries/` — these TS functions just expose
useful entry points.
### Programmatic functions
| Function | Tags | What it does |
|---|---|---|
| `chemblIdToSmilesTs(id: string = 'CHEMBL1185')` | `converter` | CHEMBL ID (e.g. `'CHEMBL1185'`) → canonical SMILES. Registered as a `converter` for the `(CHEMBL[0-9]+)` regex — string fields auto-resolve. **Only goes ID → SMILES**; for InChI key / other-ID → ChEMBL ID, use `Chem:mapIdentifiersTransform` from the toolkit skill. |
| `chemblMolregno(table: dataframe, molecules: column<Molecule>)` | — | Appends a `CHEMBL molregno` column to the table by looking up each SMILES in the ChEMBL DB. |
| `getChemblCompoundsByOrganism(maxNumberOfMolecules: int = 1000, organism: string = 'Shigella')` | `hitTriageDataSource` | Pulls compounds active against targets of the given organism. Returns DataFrame. |
| `getChemblCompounds(maxNumberOfMolecules: int = 1000)` | `hitTriageDataSource` | Pulls a generic ChEMBL compound sample. |
| `namesToSmiles(names: list<string>)` (SQL query) | — | The underlying SQL query that powers `Chem:namesToSmiles`. Returns a DataFrame with a `canonical_smiles` column. Invoke via `grok.functions.call('Chembl:namesToSmiles', {names: ['aspirin','ibuprofen',...]})` or via `grok.data.query`. |
### Panels (context-panel widgets)
All entries below have the `panel` tag.
| Panel | What |
|---|---|
| `chemblSubstructureSearchPanel(mol)` | "Databases \| ChEMBL \| Substructure Search (Internal)". |
| `chemblSimilaritySearchPanel(mol)` | "Databases \| ChEMBL \| Similarity Search (Internal)". |
| `chemblSearchWidgetLocalDb(mol: string, substructure: bool = false)` | The underlying widget — call directly to embed in custom UI. |
### Demos
`demoDatabasesChembl()` — opens the "Database Queries" demo. Top menu: Cheminformatics → Database Queries.
### Skipped
- `init` — registers the CHEMBL ID handler at startup.
---
## MolTrack package — small-molecule registration system (`MolTrack:...`)
Docker-backed compound and batch registration with dynamic properties, assay
schema, and a structured search DSL. Backed by the `moltrack` Docker container
and a `moltrack` PostgreSQL connection.
**Entity scope enum** (used by `registerBulk`, `search`, `retrieveEntity`): `'compounds' | 'batches' | 'assays' | 'assay_runs' | 'assay_results'`.
### App and views
| Function | Tags | What it does |
|---|---|---|
| `molTrackApp(path?: string)` | `app` | Opens the MolTrack app. `path` (URL) routes to sub-views: `'Compound' \| 'Batch' \| 'Register' \| 'Search' \| 'Saved Searches' \| 'Bulk' \| 'Assay' \| 'Schema'`. URL params `corporate_compound_id` / `corporate_batch_id` jump to a specific entity. browsePath `Chem`. |
| `molTrackAppTreeBrowser(appNode: object, browseView: object)` | `appTreeBrowser` | Wires the tree-browser sidebar (auto). |
| `initDB()` | — | Initializes all MolTrack schemas + assay data — call once after first deploy. |
### Lookups and metadata
| Function | Tags | What it does |
|---|---|---|
| `getCompoundByCorporateId(corporateValue: string)` | — | Compound JSON by corporate compound ID. |
| `getBatchByCorporateId(corporateValue: string)` | — | Batch JSON by corporate batch ID. |
| `fetchCompoundProperties()` / `fetchBatchProperties()` | — | JSON describing all properties for the `compound` / `batch` scope. Cached monthly. |
| `fetchSchema()` | — | JSON of all dynamic fields. |
| `fetchDirectSchema()` | — | JSON of all static (direct-table-column) fields. |
### Registration
| Function | Tags | What it does |
|---|---|---|
| `registerMolTrackProperties(jsonPayload: string)` | — | Registers compound/batch property definitions. `jsonPayload` is a JSON string defining fields `name`, `value_type`, `entity_type`, `nullable`, etc. |
| `registerAssays(assayPayload: string)` | — | Register assay schema (JSON string with `name`, properties, result types). |
| `registerBulk(csvFile: file, scope: 'compounds' \| 'batches' \| 'assays' \| 'assay_runs' \| 'assay_results', mapping: string, errorHandling: 'reject_all' \| 'reject_row')` | — | Bulk-register rows from CSV. `mapping` is a JSON string `{ csvColumn: moltrackProperty }`. `errorHandling`: `'reject_all'` aborts on any invalid row; `'reject_row'` skips. |
**For "register this compound" intent:** even if the payload isn't fully spelled out, emit an exec block that calls `MolTrack:registerMolTrackProperties` with a placeholder `jsonPayload` string (e.g. `{"name":"...","value_type":"...","entity_type":"compound","nullable":false}`) or `MolTrack:registerBulk` with a placeholder CSV/mapping. Do NOT bail into a conversational reply — surface the function call with TODOs.
### Search
| Function | Tags | What it does |
|---|---|---|
| `search(query: string, entityEndpoint: 'compounds' \| 'batches' \| 'assays' \| 'assay_runs' \| 'assay_results')` | — | Generic search — `query` is a JSON string with `level`, `output`, `filter`, `output_format`. |
| `advancedSearch(outputFields: list<string>, filter: object)` | — | **Most useful programmatic entry.** Returns a DataFrame of compounds. `outputFields` are fully-qualified (`compounds.canonical_smiles`, `compounds.details.<dynamic_prop>`). `filter` is a structured boolean tree. **Operators:** string `'=' \| '!=' \| 'IN' \| 'STARTS WITH' \| 'ENDS WITH' \| 'LIKE' \| 'CONTAINS'`; numeric `'<' \| '>' \| '<=' \| '>=' \| 'RANGE'`; datetime `'BEFORE' \| 'AFTER' \| 'ON'`; molecular (only for `compounds.structure`) `'IS SIMILAR'` (needs `threshold`), `'IS SUBSTRUCTURE OF'`, `'HAS SUBSTRUCTURE'`. Compose with `{operator: 'AND' \| 'OR', conditions: [...]}`. |
| `retrieveEntity(scope: 'compounds' \| 'batches' \| 'assays' \| 'assay_runs' \| 'assay_results')` | — | Returns *all* entities of a scope as a flattened DataFrame. |
| `getMoltrackPropPanelById(id: semantic_value<Grok ID>)` | `panel` | "Databases \| MolTrack" context panel for a `Grok ID` cell. |
### Skipped
- `init` — bootstraps MolTrack queries, semantic types, and schema once per session.
### Queries shipped in `queries/`
- `setup.sql` — schema-init queries; called via `init` (`checkDBInitialized`, etc.).
- `search.sql` — backing query used by the search UI.
---
## HitTriage package — small-mol hit triage workflows (`HitTriage:...`)
Multi-step campaign apps for triaging hits, designing new molecules, and the
peptide-flavored variants.
### Apps (each returns a `DG.ViewBase`)
All entries below have the `app` tag.
| Function | What it does |
|---|---|
| `hitTriageApp()` | **Hit Triage** — end-to-end small-mol triage pipeline. browsePath `Chem`. |
| `hitDesignApp()` | **Hit Design** — design + score new analogs. browsePath `Chem`. |
| `peptiHitApp()` | **PeptiHit** — peptide variant. Internally inits Bio. browsePath `Peptides`. |
| `pepTriageApp()` | **PepTriage** — peptide triage. Internally inits Bio. browsePath `Peptides`. |
### Tree-browser hooks (auto-registered)
`hitTriageAppTreeBrowser`, `hitDesignAppTreeBrowser`, `peptiHitAppTreeBrowser`,
`pepTriageAppTreeBrowser` — populate the campaigns tree in the sidebar.
### Demo data sources
| Function | Tags | What it does |
|---|---|---|
| `demoFileIngest()` | `hitTriageDataSource` | 100-molecule demo dataset. |
| `demoFileIngest1()` | `hitTriageDataSource` | 5000-molecule demo dataset. |
| `demoFileIngest2(numberOfMolecules: int)` | `hitTriageDataSource` | Variable-size demo dataset. |
| `demoPeptideSequences(peptideCount: int)` | `pepTriageDataSource` | Demo HELM peptide sequences for PeptiHit. |
| `demoFileSubmit(df: dataframe, molecules: string)` | — | Demo submit handler (logs row count). |
### Misc
| Function | Tags | What it does |
|---|---|---|
| `registerMoleculesToViD()` | — | Pushes all campaign molecules into MolTrack-managed ViD. |
| `hitDesignVidPanel(vid: semantic_value<HIT_DESIGN_VID>)` | `panel` | "Hit Design V-iD" context panel — shows campaigns for a V-iD. |
| `gasteigerCellRenderer()` | `cellRenderer` | PNG cell renderer for Gasteiger charge images. |
| `htPackageSettingEditor(propList: object)` | — | Hit Triage package settings editor (UI). |
### Skipped (UI plumbing)
Tree-browser callbacks above are not invoked directly by user code.
### Queries shipped in `queries/`
- `locks.sql` — concurrency / lock tracking queries.
- `vid.sql` — campaign V-iD lookups: `getCampaignsByVid`, `getMoleculeByVid`
(used by the `hitDesignVidPanel` panel).
---
## Curves package — dose-response curves (`Curves:...`)
Stores curve data in a single cell (one `DG.Column` of fit chart JSON) and
renders it as a per-cell curve. Includes converters from XML 3DX, compact-DR,
and GraphPad Prism `.pzfx` formats.
**Fit-statistic property enum** (used by `addStatisticsColumn` and `addAggrStatisticsColumn`'s `propName`): keys from the curve `FitStatistics` type — `'rSquared' | 'auc' | 'interceptX' | 'interceptY' | 'slope' | 'top' | 'bottom'`. (IC50 corresponds to `interceptX` for the standard 50% intercept; aliases like `'IC50'` / `'Hill'` / `'AUC'` are recognised at the UI/sigmoid layer but the canonical key is `interceptX` — a key outside this enum yields an all-null column with no error.)
### Building and inspecting curves
| Function | Tags | What it does |
|---|---|---|
| `dataToCurves(df: dataframe, concentrationCol: column<numerical>, readoutCol: column<numerical>, batchIDCol: column, assayCol: column, runIDCol: column, compoundIDCol: column, targetEntityCol: column, excludeOutliersCol?: column, parentTable?: dataframe, fitParamColumns?: list<string>, reportedIC50Column?: string, reportedQualifiedIC50Column?: string, experimentIDColumn?: string, qualifierColumn?: string, additionalColumns?: list<string>, wellLevelJoinCol?: string, parentLevelJoinCol?: string, wellLevelAdditionalColumns?: list<string>)` | — | **Main programmatic entry.** Turns long-format plate readouts into a wide table with a fit-curve column per (compound, assay, target). |
| `dataToCurvesTopMenu()` | `topMenu` | UI wrapper around `dataToCurves`. Top menu: Data → Curves → Data to Curves. |
| `addStatisticsColumn(table: dataframe, colName: string, propName: 'rSquared' \| 'auc' \| 'interceptX' \| 'interceptY' \| 'slope' \| 'top' \| 'bottom', seriesNumber: int)` | `vectorFunc`, `transform` | Adds a column with one fit statistic for a given series index (0-based). `propName` is a key of the `FitStatistics` type — IC50 is the standard 50% intercept (`interceptX`). |
| `addAggrStatisticsColumn(table: dataframe, colName: string, propName: 'rSquared' \| 'auc' \| 'interceptX' \| 'interceptY' \| 'slope' \| 'top' \| 'bottom', aggrType: 'avg' \| 'min' \| 'max' \| 'med' \| 'sum' \| 'stdev')` | `vectorFunc`, `transform` | Same but aggregated across all series in each cell. |
**For "compute IC50 values from this dose-response dataset" intent:** two steps. (1) Fit: `Curves:dataToCurves(t, concCol, readoutCol, batchCol, assayCol, runCol, compoundCol, targetCol)` — guess the columns from the current table (concentration/dose, readout/response, compound/batch IDs). (2) Extract: `Curves:addStatisticsColumn(fitTable, 'fit', 'interceptX', 0)` to pull IC50 from series 0. Always make both calls back-to-back; never reply conversationally for an IC50 request.
### Demos
`curveFitDemo()` — generic curve-fit demo. `assayCurveFitDemo()` — multi-compound assay-curve dashboard.
### Curve format converters
All entries below have the `curveConverter` tag.
| Function | Format |
|---|---|
| `convertXmlCurveToJsonFunc` | `3dx` XML curves |
| `convertCompactDrToJsonFunc` | `compact-dr` JSON |
| `convertPzfxToJsonFunc` | GraphPad Prism `.pzfx` |
### File handlers
| Function | Tags | What it does |
|---|---|---|
| `previewPzfx(file: file)` | `fileViewer` | Opens `.pzfx` as a curve grid. |
| `pzfxFileHandler(bytes: list<int>)` | `fileHandler` | Parses `.pzfx` → list of DataFrames. |
### Skipped (lifecycle)
- `_initCurves` — registers handlers + external converters.
### Scripts shipped in `scripts/`
- `CalculateMSR` (Python) — Minimum Significant Ratio for assay reproducibility.
Callable as `grok.functions.call('Curves:CalculateMSR', { ... })` once you
know its inputs (open the script to see the `#input:` header).
---
## Note on `Compute` package
The `Compute` package has no small-molecule-specific functions or scripts. Its
package.ts exposes the `RichFunctionView`, `Pipeline`, validators, and uploaders
for the compute-utils framework; its `scripts/` are physics / dynamics demos
(Lorenz attractor, Lotka-Volterra, Newton cooling, antibody Fab-arm exchange,
maximal-filter-volume in R, bioreactor utilities). If a small-molecule task
seems to need Compute, you almost certainly want a different package — usually
one of the ones cataloged here or in `datagrok-chem-toolkit`.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!